Version 2.12.0-133.1.beta

Merge '2.12.0-133.0.dev' into beta
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 041bc3f..0c72699 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,14 +11,14 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2020-10-26T09:42:07.748397",
+  "generated": "2020-12-03T14:26:48.568312",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
       "name": "_fe_analyzer_shared",
       "rootUri": "../pkg/_fe_analyzer_shared",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.6"
     },
     {
       "name": "_fe_analyzer_shared_assigned_variables",
@@ -74,12 +74,6 @@
       "languageVersion": "2.8"
     },
     {
-      "name": "analysis_tool",
-      "rootUri": "../pkg/analysis_tool",
-      "packageUri": "lib/",
-      "languageVersion": "2.1"
-    },
-    {
       "name": "analyzer",
       "rootUri": "../pkg/analyzer",
       "packageUri": "lib/",
@@ -98,10 +92,16 @@
       "languageVersion": "2.3"
     },
     {
+      "name": "analyzer_utilities",
+      "rootUri": "../pkg/analyzer_utilities",
+      "packageUri": "lib/",
+      "languageVersion": "2.1"
+    },
+    {
       "name": "args",
       "rootUri": "../third_party/pkg/args",
       "packageUri": "lib/",
-      "languageVersion": "2.3"
+      "languageVersion": "2.12"
     },
     {
       "name": "async",
@@ -118,7 +118,7 @@
       "name": "bazel_worker",
       "rootUri": "../third_party/pkg/bazel_worker",
       "packageUri": "lib/",
-      "languageVersion": "2.3"
+      "languageVersion": "2.12"
     },
     {
       "name": "benchmark_harness",
@@ -148,7 +148,7 @@
       "name": "cli_util",
       "rootUri": "../third_party/pkg/cli_util",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "clock",
@@ -258,6 +258,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "file",
+      "rootUri": "../third_party/pkg/file/packages/file",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "fixnum",
       "rootUri": "../third_party/pkg/fixnum",
       "packageUri": "lib/",
@@ -267,7 +273,7 @@
       "name": "front_end",
       "rootUri": "../pkg/front_end",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.6"
     },
     {
       "name": "front_end_testcases",
@@ -284,7 +290,7 @@
       "name": "glob",
       "rootUri": "../third_party/pkg/glob",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.12"
     },
     {
       "name": "html",
@@ -361,7 +367,7 @@
       "name": "kernel",
       "rootUri": "../pkg/kernel",
       "packageUri": "lib/",
-      "languageVersion": "2.2"
+      "languageVersion": "2.6"
     },
     {
       "name": "language_versioning_2.7_test",
@@ -495,7 +501,7 @@
       "name": "protobuf",
       "rootUri": "../third_party/pkg/protobuf/protobuf",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "pub",
@@ -507,7 +513,7 @@
       "name": "pub_semver",
       "rootUri": "../third_party/pkg/pub_semver",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "resource",
@@ -530,7 +536,7 @@
       "name": "shelf",
       "rootUri": "../third_party/pkg/shelf",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.12"
     },
     {
       "name": "shelf_packages_handler",
@@ -689,12 +695,6 @@
       "languageVersion": "2.0"
     },
     {
-      "name": "tflite_native",
-      "rootUri": "../third_party/pkg/tflite_native",
-      "packageUri": "lib/",
-      "languageVersion": "2.6"
-    },
-    {
       "name": "typed_data",
       "rootUri": "../third_party/pkg/typed_data",
       "packageUri": "lib/",
@@ -704,7 +704,7 @@
       "name": "usage",
       "rootUri": "../third_party/pkg/usage",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "vector_math",
@@ -764,7 +764,7 @@
       "name": "yaml",
       "rootUri": "../third_party/pkg/yaml",
       "packageUri": "lib/",
-      "languageVersion": "2.4"
+      "languageVersion": "2.12"
     }
   ]
 }
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index ee25f1b..5be83bf 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -7,7 +7,6 @@
 * Dart core libraries ("dart:async", "dart:io", etc.)
 * Dart VM
 * dart2js
-* dartfix
 * dev_compiler
 
 Some other pieces of the Dart ecosystem are maintained elsewhere. Please
diff --git a/.packages b/.packages
index 22dab41..d31bc9b 100644
--- a/.packages
+++ b/.packages
@@ -10,10 +10,10 @@
 _js_interop_checks:pkg/_js_interop_checks/lib
 analysis_server:pkg/analysis_server/lib
 analysis_server_client:pkg/analysis_server_client/lib
-analysis_tool:pkg/analysis_tool/lib
 analyzer:pkg/analyzer/lib
 analyzer_cli:pkg/analyzer_cli/lib
 analyzer_plugin:pkg/analyzer_plugin/lib
+analyzer_utilities:pkg/analyzer_utilities/lib
 args:third_party/pkg/args/lib
 async:third_party/pkg/async/lib
 async_helper:pkg/async_helper/lib
@@ -107,7 +107,6 @@
 test_reflective_loader:third_party/pkg/test_reflective_loader/lib
 test_runner:pkg/test_runner/lib
 testing:pkg/testing/lib
-tflite_native:third_party/pkg/tflite_native/lib
 typed_data:third_party/pkg/typed_data/lib
 usage:third_party/pkg/usage/lib
 vector_math:third_party/pkg/vector_math/lib
diff --git a/BUILD.gn b/BUILD.gn
index d59ce8e..3962d40 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -68,6 +68,12 @@
   }
 }
 
+# A separate target and not included in group("runtime"). This way the target\
+# "runtime" does not get many executables extra as build output.
+group("run_ffi_unit_tests") {
+  deps = [ "runtime/bin/ffi_unit_test:run_ffi_unit_tests" ]
+}
+
 group("runtime_kernel") {
   if (targetting_fuchsia) {
     # Fuchsia has run_vm_tests marked testonly.
@@ -107,10 +113,6 @@
   deps = [ "utils/dartfmt" ]
 }
 
-group("dartfix") {
-  deps = [ "utils/dartfix" ]
-}
-
 group("analysis_server") {
   deps = [ "utils/analysis_server" ]
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4700f9d..b0d0877 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,11 @@
   constructors, a name which can be associated with the port and displayed in
   tooling.
 
+#### `dart:collection`
+
+* `LinkedList` made it explicit that elements are compared by identity,
+  and updated `contains` to take advantage of this.
+
 ### Dart VM
 
 *   **Breaking Change** [#42312][]: `Dart_WeakPersistentHandle`s will no longer
@@ -56,8 +61,15 @@
 
 #### Linter
 
-Updated the Linter to `0.1.124`, which includes:
+Updated the Linter to `0.1.126`, which includes:
 
+* fixed false negatives for `prefer_collection_literals` when a LinkedHashSet or
+  LinkedHashMap instantiation is passed as the argument to a function in any
+  position other than the first.
+* fixed false negatives for `prefer_collection_literals` when a LinkedHashSet or
+  LinkedHashMap instantiation is used in a place with a static type other than
+  Set or Map.
+* (Internal): test updates to the new `PhysicalResourceProvider` API.
 * Fixed false positives in `prefer_constructors_over_static_methods`.
 * Updates to `package_names` to allow leading underscores.
 * Fixed NPEs in `unnecessary_null_checks`.
@@ -103,19 +115,28 @@
 * The top level `pub` executable has been deprecated. Use `dart pub` instead.
   See [dart tool][].
 * New command `dart pub add` that adds  new dependencies to your `pubspec.yaml`.
-  
+
   And a corresponding `dart pub remove` that removes dependencies.
 * New option `dart pub outdated --mode=null-safety` that will analyze your
   dependencies for null-safety.
 * `dart pub publish` will now check your pubspec keys for likely typos.
 * New command `dart pub login` that logs in to pub.dev.
 * The `--server` option to `dart pub publish` and `dart pub uploader` have been
-  deprecated. Use `publish_to` in your `pubspec.yaml` or set the 
+  deprecated. Use `publish_to` in your `pubspec.yaml` or set the
   `$PUB_HOSTED_URL` environment variable.
 
 [#44072]: https://github.com/dart-lang/sdk/issues/44072
 [dart tool]: https://dart.dev/tools/dart-tool
 
+## 2.10.4 - 2020-11-12
+
+This is a patch release that fixes a crash in the Dart VM (issues [#43941][],
+[flutter/flutter#43620][], and [Dart-Code/Dart-Code#2814][]).
+
+[#43941]: https://github.com/dart-lang/sdk/issues/43941
+[flutter/flutter#43620]: https://github.com/flutter/flutter/issues/43620
+[Dart-Code/Dart-Code#2814]: https://github.com/Dart-Code/Dart-Code/issues/2814
+
 ## 2.10.3 - 2020-10-29
 
 This is a patch release that fixes the following issues:
diff --git a/DEPS b/DEPS
index 739fc9d..cd9bba0 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
   # has.
-  "co19_rev": "de1f3498dff1091b7ca715eb7f831e24ec1a8c64",
+  "co19_rev": "d8e25398102add0ac1e732850928bd44c78f2447",
   "co19_2_rev": "e48b3090826cf40b8037648f19d211e8eab1b4b6",
 
   # The internal benchmarks to use. See go/dart-benchmarks-internal
@@ -65,12 +65,12 @@
   # Scripts that make 'git cl format' work.
   "clang_format_scripts_rev": "c09c8deeac31f05bd801995c475e7c8070f9ecda",
 
-  "gperftools_revision": "e9ab4c53041ac62feefbbb076d326e9a77dd1567",
+  "gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
 
   # Revisions of /third_party/* dependencies.
-  "args_tag": "1.6.0",
+  "args_rev": "139140125126661fac88c9aa5882165936d01c91",
   "async_rev": "695b3ac280f107c84adf7488743abfdfaaeea68f",
-  "bazel_worker_rev": "26680d5e249b249c7216ab2fed0ac8ed4ee285c5",
+  "bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
   "benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
   "boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
   "boringssl_gen_rev": "429ccb1877f7987a6f3988228bc2440e61293499",
@@ -78,13 +78,13 @@
   "browser-compat-data_tag": "v1.0.22",
   "charcode_rev": "bcd8a12c315b7a83390e4865ad847ecd9344cba2",
   "chrome_rev" : "19997",
-  "cli_util_rev" : "335ed165887d0ec97c2a09173ebf22dcf56a6c4e",
+  "cli_util_rev" : "50cc840b146615899e97b892578848401b2028d5",
   "clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3",
   "collection_rev": "e4bb038ce2d8e66fb15818aa40685c68d53692ab",
   "convert_rev": "dd3bd28f63be7cb8ab961f38bc73229e4473b555",
-  "crypto_rev": "f7c48b334b1386bc5ab0f706fbcd6df8496a87fc",
+  "crypto_rev": "a5ec902dda5a635a35c6b363ec64458cf84c5872",
   "csslib_rev": "6f77b3dcee957d3e2d5083f666221a220e9ed1f1",
-  "dart2js_info_rev" : "0632a623b08e1f601c7eba99e0186a581ae799e9",
+  "dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
 
   # Note: Updates to dart_style have to be coordinated with the infrastructure
   # team so that the internal formatter in `tools/sdks/dart-sdk/bin/dartfmt`
@@ -98,57 +98,58 @@
   #     and land the review.
   #
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
-"dart_style_tag": "1.3.9",  # Please see the note above before updating.
+"dart_style_tag": "1.3.10",  # Please see the note above before updating.
 
   "chromedriver_tag": "83.0.4103.39",
-  "dartdoc_rev" : "6935dcd8f2d78cf1797e6365b4b71505e6579659",
-  "ffi_rev": "a90bd424116fb6f416337db67425171f2dc4c98f",
+  "dartdoc_rev" : "d79877d0764ce23ffea7055049f8da5dffce0308",
+  "ffi_rev": "a5d4232cd38562c75a3ed847baa340e399538028",
   "fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
-  "glob_rev": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
+  "file_rev": "0e09370f581ab6388d46fda4cdab66638c0171a1",
+  "glob_rev": "7c0ef8d4fa086f6b185c4dd724b700e7d7ad8f79",
   "html_rev": "22f17e97fedeacaa1e945cf84d8016284eed33a6",
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
-  "http_multi_server_rev" : "ea269f79321d659208402088f3297e8920a88ee6",
+  "http_multi_server_rev" : "f1d1c9c024a293ab0a0e16f8b7632e87c708b448",
   "http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
   "http_retry_tag": "0.1.1",
-  "http_rev": "a8efbef05a58919dc7aa2dab42198334f2459ffb",
+  "http_rev": "1617b728fc48f64fb0ed7dc16078c03adcc64179",
   "http_throttle_tag" : "1.0.2",
   "icu_rev" : "79326efe26e5440f530963704c3c0ff965b3a4ac",
   "idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
   "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
-  "json_rpc_2_rev": "8f189db8f0c299187a0e8fa959dba7e9b0254be5",
-  "linter_tag": "0.1.124",
-  "logging_rev": "9d2a7fdd05b09bc06474881152b5baaf38fd1329",
+  "json_rpc_2_rev": "b8dfe403fd8528fd14399dee3a6527b55802dd4d",
+  "linter_tag": "0.1.126",
+  "logging_rev": "e2f633b543ef89c54688554b15ca3d7e425b86a2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_rev": "6f89681d59541ddb1cf3a58efbdaa2304ffc3f51",
   "matcher_rev": "9cae8faa7868bf3a88a7ba45eb0bd128e66ac515",
-  "mime_tag": "0.9.7",
+  "mime_rev": "07635f7774447503248fbc6afb3911e9000a477e",
   "mockito_rev": "d39ac507483b9891165e422ec98d9fb480037c8b",
   "mustache_rev": "664737ecad027e6b96d0d1e627257efa0e46fcb1",
   "oauth2_tag": "1.6.0",
   "package_config_rev": "9c586d04bd26fef01215fd10e7ab96a3050cfa64",
   "path_rev": "62ecd5a78ffe5734d14ed0df76d20309084cd04a",
-  "pedantic_rev": "24b38df72430d7e21cb4257828580becb9a39c72",
+  "pedantic_rev": "a884ea2db943b8756cc94385990bd750aec06928",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
-  "pool_rev": "eedbd5fde84f9a1a8da643b475305a81841da599",
-  "protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
-  "pub_rev": "c00d4b4abf5b4ff265a7ce6282b748551f1b5b1f",
-  "pub_semver_tag": "v1.4.4",
+  "pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
+  "protobuf_rev": "0d03fd588df69e9863e2a2efc0059dee8f18d5b2",
+  "pub_rev": "228e69e53862879c283c42b98086aa7536012a66",
+  "pub_semver_rev": "10569a1e867e909cf5db201f73118020453e5db8",
   "resource_rev": "6b79867d0becf5395e5819a75720963b8298e9a7",
   "root_certificates_rev": "7e5ec82c99677a2e5b95ce296c4d68b0d3378ed8",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
-  "shelf_static_rev": "v0.2.8",
+  "shelf_static_rev": "a6168f162df88b0eef7e328629bf020122d5039e",
   "shelf_packages_handler_tag": "2.0.0",
   "shelf_proxy_tag": "0.1.0+7",
-  "shelf_rev": "289309adc6c39aab0a63db676d550c517fc1cc2d",
-  "shelf_web_socket_tag": "0.2.2+3",
+  "shelf_rev": "5a77d25861db91db4343b19dfe213b8992e0a837",
+  "shelf_web_socket_rev": "8050a55b16faa5052a3e5d7dcdc170c59b6644f2",
   "source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
   "source_span_rev": "49ff31eabebed0da0ae6634124f8ba5c6fbf57f1",
-  "sse_tag": "e5cf68975e8e87171a3dc297577aa073454a91dc",
+  "sse_tag": "9a486d058a17e880afa9cc1c3c0dd8bad726bcbc",
   "stack_trace_tag": "6788afc61875079b71b3d1c3e65aeaa6a25cbc2f",
-  "stagehand_tag": "v3.3.9",
+  "stagehand_tag": "v3.3.11",
   "stream_channel_tag": "d7251e61253ec389ee6e045ee1042311bced8f1d",
   "string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",
   "sync_http_rev": "a85d7ec764ea485cbbc49f3f3e7f1b43f87a1c74",
@@ -157,16 +158,15 @@
   "term_glyph_rev": "6a0f9b6fb645ba75e7a00a4e20072678327a0347",
   "test_reflective_loader_tag": "0.1.9",
   "test_rev": "e37a93bbeae23b215972d1659ac865d71287ff6a",
-  "tflite_native_rev": "0.4.0+1",
   "typed_data_tag": "f94fc57b8e8c0e4fe4ff6cfd8290b94af52d3719",
-  "usage_tag": "3.4.0",
+  "usage_tag": "16fbfd90c58f16e016a295a880bc722d2547d2c9",
   "vector_math_rev": "0c9f5d68c047813a6dcdeb88ba7a42daddf25025",
   "watcher_rev": "64e254eba16f56d41f10d72c0b1cb24e130e1f8b",
   "webdriver_rev": "5a8d6805d9cf8a3cbb4fcd64849b538b7491e50e",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_rev": "490061ef0e22d3c8460ad2802f9948219365ad6b",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
-  "yaml_rev": "e5de429147a6b0fcb7e8ddb3c8e4674dc5dd0ecc",
+  "yaml_rev": "cca02c9e4f6826d62644901ed65c6d72b90a0713",
   "zlib_rev": "c44fb7248079cc3d5563b14b3f758aee60d6b415",
   "crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
   "minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
@@ -301,7 +301,7 @@
       "@" + Var("gperftools_revision"),
 
   Var("dart_root") + "/third_party/pkg/args":
-      Var("dart_git") + "args.git" + "@" + Var("args_tag"),
+      Var("dart_git") + "args.git" + "@" + Var("args_rev"),
   Var("dart_root") + "/third_party/pkg/async":
       Var("dart_git") + "async.git" + "@" + Var("async_rev"),
   Var("dart_root") + "/third_party/pkg/bazel_worker":
@@ -336,6 +336,9 @@
       Var("dart_git") + "ffi.git" + "@" + Var("ffi_rev"),
   Var("dart_root") + "/third_party/pkg/fixnum":
       Var("dart_git") + "fixnum.git" + "@" + Var("fixnum_rev"),
+  Var("dart_root") + "/third_party/pkg/file":
+      Var("dart_git") + "external/github.com/google/file.dart/"
+      + "@" + Var("file_rev"),
   Var("dart_root") + "/third_party/pkg/glob":
       Var("dart_git") + "glob.git" + "@" + Var("glob_rev"),
   Var("dart_root") + "/third_party/pkg/html":
@@ -368,7 +371,7 @@
   Var("dart_root") + "/third_party/pkg/matcher":
       Var("dart_git") + "matcher.git" + "@" + Var("matcher_rev"),
   Var("dart_root") + "/third_party/pkg/mime":
-      Var("dart_git") + "mime.git" + "@" + Var("mime_tag"),
+      Var("dart_git") + "mime.git" + "@" + Var("mime_rev"),
   Var("dart_root") + "/third_party/pkg/mockito":
       Var("dart_git") + "mockito.git" + "@" + Var("mockito_rev"),
   Var("dart_root") + "/third_party/pkg/mustache":
@@ -389,7 +392,7 @@
   Var("dart_root") + "/third_party/pkg/protobuf":
        Var("dart_git") + "protobuf.git" + "@" + Var("protobuf_rev"),
   Var("dart_root") + "/third_party/pkg/pub_semver":
-      Var("dart_git") + "pub_semver.git" + "@" + Var("pub_semver_tag"),
+      Var("dart_git") + "pub_semver.git" + "@" + Var("pub_semver_rev"),
   Var("dart_root") + "/third_party/pkg/pub":
       Var("dart_git") + "pub.git" + "@" + Var("pub_rev"),
   Var("dart_root") + "/third_party/pkg/resource":
@@ -405,7 +408,7 @@
       Var("dart_git") + "shelf_static.git" + "@" + Var("shelf_static_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_web_socket":
       Var("dart_git") + "shelf_web_socket.git" +
-      "@" + Var("shelf_web_socket_tag"),
+      "@" + Var("shelf_web_socket_rev"),
   Var("dart_root") + "/third_party/pkg/source_maps":
       Var("dart_git") + "source_maps.git" + "@" + Var("source_maps_rev"),
   Var("dart_root") + "/third_party/pkg/source_span":
@@ -431,8 +434,6 @@
       Var("dart_git") + "term_glyph.git" + "@" + Var("term_glyph_rev"),
   Var("dart_root") + "/third_party/pkg/test":
       Var("dart_git") + "test.git" + "@" + Var("test_rev"),
-  Var("dart_root") + "/third_party/pkg/tflite_native":
-      Var("dart_git") + "tflite_native.git" + "@" + Var("tflite_native_rev"),
   Var("dart_root") + "/third_party/pkg/test_descriptor":
       Var("dart_git") + "test_descriptor.git" + "@" + Var("test_descriptor_tag"),
   Var("dart_root") + "/third_party/pkg/test_process":
diff --git a/benchmarks/Omnibus/dart/Omnibus.dart b/benchmarks/Omnibus/dart/Omnibus.dart
new file mode 100644
index 0000000..a59342a
--- /dev/null
+++ b/benchmarks/Omnibus/dart/Omnibus.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// A benchmark that contains several other benchmarks.
+//
+// With no arguments, run all benchmarks once.
+// With arguments, run only the specified benchmarks in command-line order.
+//
+//     -N: run benchmarks N times, defaults to once.
+
+import '../../ListCopy/dart/ListCopy.dart' as lib_ListCopy;
+import '../../BigIntParsePrint/dart/BigIntParsePrint.dart'
+    as lib_BigIntParsePrint;
+import '../../MD5/dart/md5.dart' as lib_MD5;
+import '../../RuntimeType/dart/RuntimeType.dart' as lib_RuntimeType;
+import '../../SHA1/dart/sha1.dart' as lib_SHA1;
+import '../../SHA256/dart/sha256.dart' as lib_SHA256;
+import '../../SkeletalAnimation/dart/SkeletalAnimation.dart'
+    as lib_SkeletalAnimation;
+import '../../SkeletalAnimationSIMD/dart/SkeletalAnimationSIMD.dart'
+    as lib_SkeletalAnimationSIMD;
+import '../../TypedDataDuplicate/dart/TypedDataDuplicate.dart'
+    as lib_TypedDataDuplicate;
+import '../../Utf8Decode/dart/Utf8Decode.dart' as lib_Utf8Decode;
+import '../../Utf8Encode/dart/Utf8Encode.dart' as lib_Utf8Encode;
+
+final Map<String, Function()> benchmarks = {
+  'ListCopy': lib_ListCopy.main,
+  'BigIntParsePrint': lib_BigIntParsePrint.main,
+  'MD5': lib_MD5.main,
+  'RuntimeType': lib_RuntimeType.main,
+  'SHA1': lib_SHA1.main,
+  'SHA256': lib_SHA256.main,
+  'SkeletalAnimation': lib_SkeletalAnimation.main,
+  'SkeletalAnimationSIMD': lib_SkeletalAnimationSIMD.main,
+  'TypedDataDuplicate': lib_TypedDataDuplicate.main,
+  'Utf8Decode': () => lib_Utf8Decode.main([]),
+  'Utf8Encode': () => lib_Utf8Encode.main([]),
+};
+
+main(List<String> originalArguments) {
+  List<String> args = List.of(originalArguments);
+
+  int repeats = 1;
+
+  for (final arg in args.toList()) {
+    int? count = int.tryParse(arg);
+    if (count != null && count < 0) {
+      repeats = 0 - count;
+      args.remove(arg);
+    }
+  }
+
+  List<Function()> mains = [];
+
+  for (final name in args.toList()) {
+    final function = benchmarks[name];
+    if (function == null) {
+      print("Unknown benchmark: '$name'");
+    } else {
+      mains.add(function);
+      args.remove(name);
+    }
+  }
+  if (args.isNotEmpty) return; // We will have printed an error.
+
+  if (mains.isEmpty) mains = benchmarks.values.toList();
+
+  for (var i = 0; i < repeats; i++) {
+    for (final function in mains) {
+      function();
+    }
+  }
+}
diff --git a/benchmarks/Omnibus/dart2/Omnibus.dart b/benchmarks/Omnibus/dart2/Omnibus.dart
new file mode 100644
index 0000000..72587cd
--- /dev/null
+++ b/benchmarks/Omnibus/dart2/Omnibus.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// @dart=2.10
+//
+// A benchmark that contains several other benchmarks.
+//
+// With no arguments, run all benchmarks once.
+// With arguments, run only the specified benchmarks in command-line order.
+//
+//     -N: run benchmarks N times, defaults to once.
+
+import '../../ListCopy/dart/ListCopy.dart' as lib_ListCopy;
+import '../../BigIntParsePrint/dart/BigIntParsePrint.dart'
+    as lib_BigIntParsePrint;
+import '../../MD5/dart/md5.dart' as lib_MD5;
+import '../../RuntimeType/dart/RuntimeType.dart' as lib_RuntimeType;
+import '../../SHA1/dart/sha1.dart' as lib_SHA1;
+import '../../SHA256/dart/sha256.dart' as lib_SHA256;
+import '../../SkeletalAnimation/dart/SkeletalAnimation.dart'
+    as lib_SkeletalAnimation;
+import '../../SkeletalAnimationSIMD/dart/SkeletalAnimationSIMD.dart'
+    as lib_SkeletalAnimationSIMD;
+import '../../TypedDataDuplicate/dart/TypedDataDuplicate.dart'
+    as lib_TypedDataDuplicate;
+import '../../Utf8Decode/dart/Utf8Decode.dart' as lib_Utf8Decode;
+import '../../Utf8Encode/dart/Utf8Encode.dart' as lib_Utf8Encode;
+
+final Map<String, Function()> benchmarks = {
+  'ListCopy': lib_ListCopy.main,
+  'BigIntParsePrint': lib_BigIntParsePrint.main,
+  'MD5': lib_MD5.main,
+  'RuntimeType': lib_RuntimeType.main,
+  'SHA1': lib_SHA1.main,
+  'SHA256': lib_SHA256.main,
+  'SkeletalAnimation': lib_SkeletalAnimation.main,
+  'SkeletalAnimationSIMD': lib_SkeletalAnimationSIMD.main,
+  'TypedDataDuplicate': lib_TypedDataDuplicate.main,
+  'Utf8Decode': () => lib_Utf8Decode.main([]),
+  'Utf8Encode': () => lib_Utf8Encode.main([]),
+};
+
+main(List<String> originalArguments) {
+  List<String> args = List.of(originalArguments);
+
+  int repeats = 1;
+
+  for (final arg in args.toList()) {
+    int count = int.tryParse(arg);
+    if (count != null && count < 0) {
+      repeats = 0 - count;
+      args.remove(arg);
+    }
+  }
+
+  List<Function()> mains = [];
+
+  for (final name in args.toList()) {
+    final function = benchmarks[name];
+    if (function == null) {
+      print("Unknown benchmark: '$name'");
+    } else {
+      mains.add(function);
+      args.remove(name);
+    }
+  }
+  if (args.isNotEmpty) return; // We will have printed an error.
+
+  if (mains.isEmpty) mains = benchmarks.values.toList();
+
+  for (var i = 0; i < repeats; i++) {
+    for (final function in mains) {
+      function();
+    }
+  }
+}
diff --git a/benchmarks/OmnibusDeferred/dart/OmnibusDeferred.dart b/benchmarks/OmnibusDeferred/dart/OmnibusDeferred.dart
new file mode 100644
index 0000000..e31cfb6
--- /dev/null
+++ b/benchmarks/OmnibusDeferred/dart/OmnibusDeferred.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// A benchmark that contains several other benchmarks.
+//
+// With no arguments, run all benchmarks once.
+// With arguments, run only the specified benchmarks in command-line order.
+//
+//     -N: run benchmarks N times, defaults to once.
+
+import '../../ListCopy/dart/ListCopy.dart' deferred as lib_ListCopy;
+import '../../BigIntParsePrint/dart/BigIntParsePrint.dart'
+    deferred as lib_BigIntParsePrint;
+import '../../MD5/dart/md5.dart' deferred as lib_MD5;
+import '../../RuntimeType/dart/RuntimeType.dart' deferred as lib_RuntimeType;
+import '../../SHA1/dart/sha1.dart' deferred as lib_SHA1;
+import '../../SHA256/dart/sha256.dart' deferred as lib_SHA256;
+import '../../SkeletalAnimation/dart/SkeletalAnimation.dart'
+    deferred as lib_SkeletalAnimation;
+import '../../SkeletalAnimationSIMD/dart/SkeletalAnimationSIMD.dart'
+    deferred as lib_SkeletalAnimationSIMD;
+import '../../TypedDataDuplicate/dart/TypedDataDuplicate.dart'
+    deferred as lib_TypedDataDuplicate;
+import '../../Utf8Decode/dart/Utf8Decode.dart' deferred as lib_Utf8Decode;
+import '../../Utf8Encode/dart/Utf8Encode.dart' deferred as lib_Utf8Encode;
+
+class Lib {
+  final Future Function() load;
+  final void Function() main;
+  Lib(this.load, this.main);
+}
+
+final Map<String, Lib> benchmarks = {
+  'ListCopy': Lib(
+    lib_ListCopy.loadLibrary,
+    () => lib_ListCopy.main(),
+  ),
+  'BigIntParsePrint': Lib(
+    lib_BigIntParsePrint.loadLibrary,
+    () => lib_BigIntParsePrint.main(),
+  ),
+  'MD5': Lib(
+    lib_MD5.loadLibrary,
+    () => lib_MD5.main(),
+  ),
+  'RuntimeType': Lib(
+    lib_RuntimeType.loadLibrary,
+    () => lib_RuntimeType.main(),
+  ),
+  'SHA1': Lib(
+    lib_SHA1.loadLibrary,
+    () => lib_SHA1.main(),
+  ),
+  'SHA256': Lib(
+    lib_SHA256.loadLibrary,
+    () => lib_SHA256.main(),
+  ),
+  'SkeletalAnimation': Lib(
+    lib_SkeletalAnimation.loadLibrary,
+    () => lib_SkeletalAnimation.main(),
+  ),
+  'SkeletalAnimationSIMD': Lib(
+    lib_SkeletalAnimationSIMD.loadLibrary,
+    () => lib_SkeletalAnimationSIMD.main(),
+  ),
+  'TypedDataDuplicate': Lib(
+    lib_TypedDataDuplicate.loadLibrary,
+    () => lib_TypedDataDuplicate.main(),
+  ),
+  'Utf8Decode': Lib(
+    lib_Utf8Decode.loadLibrary,
+    () => lib_Utf8Decode.main([]),
+  ),
+  'Utf8Encode': Lib(
+    lib_Utf8Encode.loadLibrary,
+    () => lib_Utf8Encode.main([]),
+  ),
+};
+
+main(List<String> originalArguments) async {
+  List<String> args = List.of(originalArguments);
+
+  int repeats = 1;
+
+  for (final arg in args.toList()) {
+    int? count = int.tryParse(arg);
+    if (count != null && count < 0) {
+      repeats = 0 - count;
+      args.remove(arg);
+    }
+  }
+
+  bool preload = args.remove('--preload');
+
+  List<Lib> libs = [];
+
+  for (final name in args.toList()) {
+    final lib = benchmarks[name];
+    if (lib == null) {
+      print("Unknown benchmark: '$name'");
+    } else {
+      libs.add(lib);
+      args.remove(name);
+    }
+  }
+  if (args.isNotEmpty) return; // We will have printed an error.
+
+  if (libs.isEmpty) libs = benchmarks.values.toList();
+
+  if (preload) {
+    for (final lib in libs) await lib.load();
+  }
+
+  for (var i = 0; i < repeats; i++) {
+    for (final lib in libs) {
+      if (!preload) await lib.load();
+      lib.main();
+    }
+  }
+}
diff --git a/benchmarks/OmnibusDeferred/dart2/OmnibusDeferred.dart b/benchmarks/OmnibusDeferred/dart2/OmnibusDeferred.dart
new file mode 100644
index 0000000..20a28bf
--- /dev/null
+++ b/benchmarks/OmnibusDeferred/dart2/OmnibusDeferred.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// @dart=2.10
+//
+// A benchmark that contains several other benchmarks.
+//
+// With no arguments, run all benchmarks once.
+// With arguments, run only the specified benchmarks in command-line order.
+//
+//     -N: run benchmarks N times, defaults to once.
+
+import '../../ListCopy/dart/ListCopy.dart' deferred as lib_ListCopy;
+import '../../BigIntParsePrint/dart/BigIntParsePrint.dart'
+    deferred as lib_BigIntParsePrint;
+import '../../MD5/dart/md5.dart' deferred as lib_MD5;
+import '../../RuntimeType/dart/RuntimeType.dart' deferred as lib_RuntimeType;
+import '../../SHA1/dart/sha1.dart' deferred as lib_SHA1;
+import '../../SHA256/dart/sha256.dart' deferred as lib_SHA256;
+import '../../SkeletalAnimation/dart/SkeletalAnimation.dart'
+    deferred as lib_SkeletalAnimation;
+import '../../SkeletalAnimationSIMD/dart/SkeletalAnimationSIMD.dart'
+    deferred as lib_SkeletalAnimationSIMD;
+import '../../TypedDataDuplicate/dart/TypedDataDuplicate.dart'
+    deferred as lib_TypedDataDuplicate;
+import '../../Utf8Decode/dart/Utf8Decode.dart' deferred as lib_Utf8Decode;
+import '../../Utf8Encode/dart/Utf8Encode.dart' deferred as lib_Utf8Encode;
+
+class Lib {
+  final Future Function() load;
+  final void Function() main;
+  Lib(this.load, this.main);
+}
+
+final Map<String, Lib> benchmarks = {
+  'ListCopy': Lib(
+    lib_ListCopy.loadLibrary,
+    () => lib_ListCopy.main(),
+  ),
+  'BigIntParsePrint': Lib(
+    lib_BigIntParsePrint.loadLibrary,
+    () => lib_BigIntParsePrint.main(),
+  ),
+  'MD5': Lib(
+    lib_MD5.loadLibrary,
+    () => lib_MD5.main(),
+  ),
+  'RuntimeType': Lib(
+    lib_RuntimeType.loadLibrary,
+    () => lib_RuntimeType.main(),
+  ),
+  'SHA1': Lib(
+    lib_SHA1.loadLibrary,
+    () => lib_SHA1.main(),
+  ),
+  'SHA256': Lib(
+    lib_SHA256.loadLibrary,
+    () => lib_SHA256.main(),
+  ),
+  'SkeletalAnimation': Lib(
+    lib_SkeletalAnimation.loadLibrary,
+    () => lib_SkeletalAnimation.main(),
+  ),
+  'SkeletalAnimationSIMD': Lib(
+    lib_SkeletalAnimationSIMD.loadLibrary,
+    () => lib_SkeletalAnimationSIMD.main(),
+  ),
+  'TypedDataDuplicate': Lib(
+    lib_TypedDataDuplicate.loadLibrary,
+    () => lib_TypedDataDuplicate.main(),
+  ),
+  'Utf8Decode': Lib(
+    lib_Utf8Decode.loadLibrary,
+    () => lib_Utf8Decode.main([]),
+  ),
+  'Utf8Encode': Lib(
+    lib_Utf8Encode.loadLibrary,
+    () => lib_Utf8Encode.main([]),
+  ),
+};
+
+main(List<String> originalArguments) async {
+  List<String> args = List.of(originalArguments);
+
+  int repeats = 1;
+
+  for (final arg in args.toList()) {
+    int count = int.tryParse(arg);
+    if (count != null && count < 0) {
+      repeats = 0 - count;
+      args.remove(arg);
+    }
+  }
+
+  bool preload = args.remove('--preload');
+
+  List<Lib> libs = [];
+
+  for (final name in args.toList()) {
+    final lib = benchmarks[name];
+    if (lib == null) {
+      print("Unknown benchmark: '$name'");
+    } else {
+      libs.add(lib);
+      args.remove(name);
+    }
+  }
+  if (args.isNotEmpty) return; // We will have printed an error.
+
+  if (libs.isEmpty) libs = benchmarks.values.toList();
+
+  if (preload) {
+    for (final lib in libs) await lib.load();
+  }
+
+  for (var i = 0; i < repeats; i++) {
+    for (final lib in libs) {
+      if (!preload) await lib.load();
+      lib.main();
+    }
+  }
+}
diff --git a/pkg/README.md b/pkg/README.md
new file mode 100644
index 0000000..474a204
--- /dev/null
+++ b/pkg/README.md
@@ -0,0 +1,43 @@
+# Package validation
+
+The packages in `pkg/` are automatically validated on the LUCI CI bots. The
+validation is largely done by the `tools/package_deps` package; it can be tested
+locally via:
+
+```
+dart tools/package_deps/bin/package_deps.dart
+```
+
+## Packages which are published
+
+There are several packages developed in `pkg/` which are published to pub.
+Validation of these packages is particularly important because the pub tools are
+not used for these packages during development; we get our dependency versions
+from the DEPS file. Its very easy for the dependencies specified in a package's
+pubspec file to get out of date wrt the packages and versions actually used.
+
+In order to better ensure we're publishing correct packages, we validate some
+properties of the pubspec files on our CI system. These validations include:
+
+- that the dependencies listed in the pubspec are used in the package
+- that all the packages used by the source are listed in the pubspec
+- that we don't use relative path deps to pkg/ or third_party/ packages
+
+## Packages which are not published
+
+For packages in pkg/ which we do not intend to be published, we put the
+following comment in the pubspec.yaml file:
+
+```
+# This package is not intended for consumption on pub.dev. DO NOT publish.
+publish_to: none
+```
+
+These pubspecs are still validated by the package validation tool. The contents
+are more informational as the pubspecs for these packages are not consumed by
+the pub tool or ecosystem.
+
+We validate:
+- that the dependencies listed in the pubspec are used in the package
+- that all the packages used by the source are listed in the pubspec
+- that a reference to a pkg/ package is done via a relative path dependency
diff --git a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
index bd8e297..2e138d8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:meta/meta.dart';
+
 import 'customized_codes.dart';
 
 /// An error code associated with an [AnalysisError].
@@ -14,6 +16,11 @@
    */
   final String name;
 
+  /**
+   * The unique name of this error code.
+   */
+  final String uniqueName;
+
   final String _message;
 
   final String _correction;
@@ -35,24 +42,34 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ErrorCode(this.name, String message,
-      [String correction, this.hasPublishedDocs = false])
-      : isUnresolvedIdentifier = false,
+  const ErrorCode({
+    String correction,
+    this.hasPublishedDocs = false,
+    this.isUnresolvedIdentifier: false,
+    @required String message,
+    @required this.name,
+    @required this.uniqueName,
+  })  : _correction = correction,
         _message = message,
-        _correction = correction;
+        assert(hasPublishedDocs != null),
+        assert(isUnresolvedIdentifier != null);
 
-  /**
-   * Initialize a newly created error code to have the given [name]. The message
-   * associated with the error will be created from the given [message]
-   * template. The correction associated with the error will be created from the
-   * given [correction] template.
-   */
-  const ErrorCode.temporary(this.name, String message,
-      {String correction,
-      this.isUnresolvedIdentifier: false,
-      this.hasPublishedDocs = false})
-      : _message = message,
-        _correction = correction;
+  @Deprecated('Use the default constructor')
+  const ErrorCode.temporary2({
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    @required String message,
+    @required String name,
+    @required String uniqueName,
+  }) : this(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName,
+        );
 
   /**
    * The template used to create the correction to be displayed for this error,
@@ -82,11 +99,6 @@
   ErrorType get type;
 
   /**
-   * The unique name of this error code.
-   */
-  String get uniqueName => "$runtimeType.$name";
-
-  /**
    * Return a URL that can be used to access documentation for diagnostics with
    * this code, or `null` if there is no published documentation.
    */
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index e7603a2..9752d91 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -1286,9 +1286,6 @@
   /// variable that is no longer in scope.
   final Map<Variable, VariableModel<Variable, Type> /*!*/ > variableInfo;
 
-  /// Variable model for variables that have never been seen before.
-  final VariableModel<Variable, Type> _freshVariableInfo;
-
   /// The empty map, used to [join] variables.
   final Map<Variable, VariableModel<Variable, Type>> _emptyVariableMap = {};
 
@@ -1302,8 +1299,7 @@
         );
 
   @visibleForTesting
-  FlowModel.withInfo(this.reachable, this.variableInfo)
-      : _freshVariableInfo = new VariableModel.fresh() {
+  FlowModel.withInfo(this.reachable, this.variableInfo) {
     assert(reachable != null);
     assert(() {
       for (VariableModel<Variable, Type> value in variableInfo.values) {
@@ -1376,17 +1372,15 @@
   /// A local variable is [initialized] if its declaration has an initializer.
   /// A function parameter is always initialized, so [initialized] is `true`.
   FlowModel<Variable, Type> declare(Variable variable, bool initialized) {
-    VariableModel<Variable, Type> newInfoForVar = _freshVariableInfo;
-    if (initialized) {
-      newInfoForVar = newInfoForVar.initialize();
-    }
+    VariableModel<Variable, Type> newInfoForVar =
+        new VariableModel.fresh(assigned: initialized);
 
     return _updateVariableInfo(variable, newInfoForVar);
   }
 
   /// Gets the info for the given [variable], creating it if it doesn't exist.
   VariableModel<Variable, Type> infoFor(Variable variable) =>
-      variableInfo[variable] ?? _freshVariableInfo;
+      variableInfo[variable] ?? new VariableModel.fresh();
 
   /// Builds a [FlowModel] based on `this`, but extending the `tested` set to
   /// include types from [other].  This is used at the bottom of certain kinds
@@ -1423,36 +1417,6 @@
     }
   }
 
-  /// Updates the state to indicate that variables that are not definitely
-  /// unassigned in the [other], are also not definitely unassigned in the
-  /// result.
-  FlowModel<Variable, Type> joinUnassigned(FlowModel<Variable, Type> other) {
-    Map<Variable, VariableModel<Variable, Type>> newVariableInfo;
-
-    void markNotUnassigned(Variable variable) {
-      VariableModel<Variable, Type> info = variableInfo[variable];
-      if (info == null) return;
-
-      VariableModel<Variable, Type> newInfo = info.markNotUnassigned();
-      if (identical(newInfo, info)) return;
-
-      (newVariableInfo ??=
-          new Map<Variable, VariableModel<Variable, Type>>.from(
-              variableInfo))[variable] = newInfo;
-    }
-
-    for (Variable variable in other.variableInfo.keys) {
-      VariableModel<Variable, Type> otherInfo = other.variableInfo[variable];
-      if (!otherInfo.unassigned) {
-        markNotUnassigned(variable);
-      }
-    }
-
-    if (newVariableInfo == null) return this;
-
-    return new FlowModel<Variable, Type>.withInfo(reachable, newVariableInfo);
-  }
-
   /// Updates the state to reflect a control path that is known to have
   /// previously passed through some [other] state.
   ///
@@ -2090,11 +2054,10 @@
 
   /// Creates a [VariableModel] representing a variable that's never been seen
   /// before.
-  VariableModel.fresh()
+  VariableModel.fresh({this.assigned = false})
       : promotedTypes = null,
         tested = const [],
-        assigned = false,
-        unassigned = true,
+        unassigned = !assigned,
         writeCaptured = false;
 
   /// Returns a new [VariableModel] in which any promotions present have been
@@ -2107,25 +2070,6 @@
         null, tested, assigned, false, writeCaptured);
   }
 
-  /// Returns a new [VariableModel] reflecting the fact that the variable was
-  /// just initialized.
-  VariableModel<Variable, Type> initialize() {
-    if (promotedTypes == null && tested.isEmpty && assigned && !unassigned) {
-      return this;
-    }
-    return new VariableModel<Variable, Type>(
-        null, const [], true, false, writeCaptured);
-  }
-
-  /// Returns a new [VariableModel] reflecting the fact that the variable is
-  /// not definitely unassigned.
-  VariableModel<Variable, Type> markNotUnassigned() {
-    if (!unassigned) return this;
-
-    return new VariableModel<Variable, Type>(
-        promotedTypes, tested, assigned, false, writeCaptured);
-  }
-
   /// Returns an updated model reflect a control path that is known to have
   /// previously passed through some [other] state.  See [FlowModel.restrict]
   /// for details.
@@ -2949,11 +2893,8 @@
 
   @override
   void ifNullExpression_end() {
-    // TODO(paulberry): CFE sometimes calls ifNullExpression_end and
-    // nullAwareAccess_end out of order, so as a workaround we cast to the
-    // common base class.  See https://github.com/dart-lang/sdk/issues/43725.
-    _SimpleContext<Variable, Type> context =
-        _stack.removeLast() as _SimpleContext<Variable, Type>;
+    _IfNullExpressionContext<Variable, Type> context =
+        _stack.removeLast() as _IfNullExpressionContext<Variable, Type>;
     _current = _merge(_current, context._previous);
   }
 
@@ -3123,11 +3064,8 @@
 
   @override
   void nullAwareAccess_end() {
-    // TODO(paulberry): CFE sometimes calls ifNullExpression_end and
-    // nullAwareAccess_end out of order, so as a workaround we cast to the
-    // common base class.  See https://github.com/dart-lang/sdk/issues/43725.
-    _SimpleContext<Variable, Type> context =
-        _stack.removeLast() as _SimpleContext<Variable, Type>;
+    _NullAwareAccessContext<Variable, Type> context =
+        _stack.removeLast() as _NullAwareAccessContext<Variable, Type>;
     _current = _merge(_current, context._previous);
   }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart b/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
index d4928a5..a33410d 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
@@ -184,7 +184,7 @@
 String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
     UnescapeErrorListener listener) {
   // Can't use Uint8List or Uint16List here, the code units may be larger.
-  List<int> result = new List<int>(codeUnits.length);
+  List<int> result = new List<int>.filled(codeUnits.length, null);
   int resultOffset = 0;
 
   for (int i = 0; i < codeUnits.length; i++) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
index e9d29da..6462add 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -518,7 +518,7 @@
 }
 
 class StackImpl implements Stack {
-  List<Object> array = new List<Object>(/* length = */ 8);
+  List<Object> array = new List<Object>.filled(/* length = */ 8, null);
   int arrayLength = 0;
 
   bool get isNotEmpty => arrayLength > 0;
@@ -581,14 +581,14 @@
 
   List<Object> get values {
     final int length = arrayLength;
-    final List<Object> list = new List<Object>(length);
+    final List<Object> list = new List<Object>.filled(length, null);
     list.setRange(/* start = */ 0, length, array);
     return list;
   }
 
   void _grow() {
     final int length = array.length;
-    final List<Object> newArray = new List<Object>(length * 2);
+    final List<Object> newArray = new List<Object>.filled(length * 2, null);
     newArray.setRange(/* start = */ 0, length, array, /* skipCount = */ 0);
     array = newArray;
   }
@@ -597,7 +597,7 @@
 class DebugStack implements Stack {
   Stack realStack = new StackImpl();
   Stack stackTraceStack = new StackImpl();
-  List<StackTrace> latestStacktraces = new List<StackTrace>();
+  List<StackTrace> latestStacktraces = <StackTrace>[];
 
   @override
   Object operator [](int index) {
@@ -654,13 +654,14 @@
 
   List<T> pop(Stack stack, int count, [NullValue nullValue]) {
     if (count == 0) return null;
-    return stack.popList(count, new List<T>(count), nullValue);
+    return stack.popList(count, new List<T>.filled(count, null), nullValue);
   }
 
   List<T> popPadded(Stack stack, int count, int padding,
       [NullValue nullValue]) {
     if (count + padding == 0) return null;
-    return stack.popList(count, new List<T>(count + padding), nullValue);
+    return stack.popList(
+        count, new List<T>.filled(count + padding, null), nullValue);
   }
 }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
index df1e467..7868ae5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
@@ -331,7 +331,7 @@
 /// implementation does this by rewriting the previous token to point to the
 /// inserted token. It also allows to undo these changes.
 class UndoableTokenStreamRewriter extends TokenStreamRewriter {
-  List<TokenStreamChange> _changes = new List<TokenStreamChange>();
+  List<TokenStreamChange> _changes = <TokenStreamChange>[];
 
   void undo() {
     for (int i = _changes.length - 1; i >= 0; i--) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
index 2d539c0..5e87329 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
@@ -5,94 +5,8 @@
 import '../base/errors.dart';
 import '../messages/codes.dart';
 import 'error_token.dart';
-import 'token_constants.dart';
 import 'token.dart' show Token, TokenType;
-
-/**
- * The error codes used for errors detected by the scanner.
- */
-class ScannerErrorCode extends ErrorCode {
-  /**
-   * Parameters:
-   * 0: the token that was expected but not found
-   */
-  static const ScannerErrorCode EXPECTED_TOKEN =
-      const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'.");
-
-  /**
-   * Parameters:
-   * 0: the illegal character
-   */
-  static const ScannerErrorCode ILLEGAL_CHARACTER =
-      const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'.");
-
-  static const ScannerErrorCode MISSING_DIGIT =
-      const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
-
-  static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
-      'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
-
-  static const ScannerErrorCode MISSING_IDENTIFIER =
-      const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
-
-  static const ScannerErrorCode MISSING_QUOTE =
-      const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \").");
-
-  /**
-   * Parameters:
-   * 0: the path of the file that cannot be read
-   */
-  static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
-      'UNABLE_GET_CONTENT', "Unable to get content of '{0}'.");
-
-  static const ScannerErrorCode UNEXPECTED_DOLLAR_IN_STRING =
-      const ScannerErrorCode(
-          'UNEXPECTED_DOLLAR_IN_STRING',
-          "A '\$' has special meaning inside a string, and must be followed by "
-              "an identifier or an expression in curly braces ({}).",
-          correction: "Try adding a backslash (\\) to escape the '\$'.");
-
-  /**
-   * Parameters:
-   * 0: the unsupported operator
-   */
-  static const ScannerErrorCode UNSUPPORTED_OPERATOR = const ScannerErrorCode(
-      'UNSUPPORTED_OPERATOR', "The '{0}' operator is not supported.");
-
-  static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
-      const ScannerErrorCode(
-          'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
-          correction: "Try terminating the comment with '*/', or "
-              "removing any unbalanced occurrences of '/*'"
-              " (because comments nest in Dart).");
-
-  static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
-      const ScannerErrorCode(
-          'UNTERMINATED_STRING_LITERAL', "Unterminated string literal.");
-
-  /**
-   * Initialize a newly created error code to have the given [name]. The message
-   * associated with the error will be created from the given [message]
-   * template. The correction associated with the error will be created from the
-   * given [correction] template.
-   */
-  const ScannerErrorCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
-
-  @override
-  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
-
-  @override
-  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
-}
-
-/**
- * Used to report a scan error at the given offset.
- * The [errorCode] is the error code indicating the nature of the error.
- * The [arguments] are any arguments needed to complete the error message.
- */
-typedef ReportError(
-    ScannerErrorCode errorCode, int offset, List<Object> arguments);
+import 'token_constants.dart';
 
 /**
  *  Translates the given error [token] into an analyzer error and reports it
@@ -190,3 +104,94 @@
     // Otherwise keep looking.
   }
 }
+
+/**
+ * Used to report a scan error at the given offset.
+ * The [errorCode] is the error code indicating the nature of the error.
+ * The [arguments] are any arguments needed to complete the error message.
+ */
+typedef ReportError(
+    ScannerErrorCode errorCode, int offset, List<Object> arguments);
+
+/**
+ * The error codes used for errors detected by the scanner.
+ */
+class ScannerErrorCode extends ErrorCode {
+  /**
+   * Parameters:
+   * 0: the token that was expected but not found
+   */
+  static const ScannerErrorCode EXPECTED_TOKEN =
+      const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'.");
+
+  /**
+   * Parameters:
+   * 0: the illegal character
+   */
+  static const ScannerErrorCode ILLEGAL_CHARACTER =
+      const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'.");
+
+  static const ScannerErrorCode MISSING_DIGIT =
+      const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
+
+  static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
+      'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
+
+  static const ScannerErrorCode MISSING_IDENTIFIER =
+      const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
+
+  static const ScannerErrorCode MISSING_QUOTE =
+      const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \").");
+
+  /**
+   * Parameters:
+   * 0: the path of the file that cannot be read
+   */
+  static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
+      'UNABLE_GET_CONTENT', "Unable to get content of '{0}'.");
+
+  static const ScannerErrorCode UNEXPECTED_DOLLAR_IN_STRING =
+      const ScannerErrorCode(
+          'UNEXPECTED_DOLLAR_IN_STRING',
+          "A '\$' has special meaning inside a string, and must be followed by "
+              "an identifier or an expression in curly braces ({}).",
+          correction: "Try adding a backslash (\\) to escape the '\$'.");
+
+  /**
+   * Parameters:
+   * 0: the unsupported operator
+   */
+  static const ScannerErrorCode UNSUPPORTED_OPERATOR = const ScannerErrorCode(
+      'UNSUPPORTED_OPERATOR', "The '{0}' operator is not supported.");
+
+  static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
+      const ScannerErrorCode(
+          'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
+          correction: "Try terminating the comment with '*/', or "
+              "removing any unbalanced occurrences of '/*'"
+              " (because comments nest in Dart).");
+
+  static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
+      const ScannerErrorCode(
+          'UNTERMINATED_STRING_LITERAL', "Unterminated string literal.");
+
+  /**
+   * Initialize a newly created error code to have the given [name]. The message
+   * associated with the error will be created from the given [message]
+   * template. The correction associated with the error will be created from the
+   * given [correction] template.
+   */
+  const ScannerErrorCode(String name, String message, {String correction})
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'ScannerErrorCode.$name',
+        );
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+
+  @override
+  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
index b4620e3..05f07e0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
@@ -20,7 +20,8 @@
   static KeywordState _KEYWORD_STATE;
   static KeywordState get KEYWORD_STATE {
     if (_KEYWORD_STATE == null) {
-      List<String> strings = new List<String>(analyzer.Keyword.values.length);
+      List<String> strings =
+          new List<String>.filled(analyzer.Keyword.values.length, null);
       for (int i = 0; i < analyzer.Keyword.values.length; i++) {
         strings[i] = analyzer.Keyword.values[i].lexeme;
       }
@@ -38,7 +39,7 @@
       int start, List<String> strings, int offset, int length) {
     bool isLowercase = true;
 
-    List<KeywordState> table = new List<KeywordState>($z - $A + 1);
+    List<KeywordState> table = new List<KeywordState>.filled($z - $A + 1, null);
     assert(length != 0);
     int chunk = 0;
     int chunkStart = -1;
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart
index 2b127b7..7370bdf 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart
@@ -34,7 +34,7 @@
   int _count = 0;
 
   /// The table itself.
-  List<Node> _nodes = new List<Node>(INITIAL_SIZE);
+  List<Node> _nodes = new List<Node>.filled(INITIAL_SIZE, null);
 
   static String decode(List<int> data, int start, int end, bool asciiOnly) {
     String s;
@@ -64,7 +64,7 @@
 
   rehash() {
     int newSize = _size * 2;
-    List<Node> newNodes = new List<Node>(newSize);
+    List<Node> newNodes = new List<Node>.filled(newSize, null);
     for (int i = 0; i < _size; i++) {
       Node t = _nodes[i];
       while (t != null) {
@@ -117,7 +117,7 @@
 
   clear() {
     _size = INITIAL_SIZE;
-    _nodes = new List<Node>(_size);
+    _nodes = new List<Node>.filled(_size, null);
     _count = 0;
   }
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/link.dart b/pkg/_fe_analyzer_shared/lib/src/util/link.dart
index 8cb8dd0..2474f06 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/link.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/link.dart
@@ -24,9 +24,9 @@
   List<T> toList({bool growable: true}) {
     List<T> result;
     if (!growable) {
-      result = new List<T>(slowLength());
+      result = new List<T>.filled(slowLength(), null);
     } else {
-      result = new List<T>();
+      result = <T>[];
       result.length = slowLength();
     }
     int i = 0;
@@ -46,9 +46,9 @@
   List<E> mapToList<E>(E fn(T item), {bool growable: true}) {
     List<E> result;
     if (!growable) {
-      result = new List<E>(slowLength());
+      result = new List<E>.filled(slowLength(), null);
     } else {
-      result = new List<E>();
+      result = <E>[];
       result.length = slowLength();
     }
     int i = 0;
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart b/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart
index e9d97ec..7fced1a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart
@@ -168,8 +168,8 @@
   }
 
   List<T> toList() {
-    if (length == 0) return new List<T>(0);
-    List<T> list = new List<T>(length);
+    if (length == 0) return new List<T>.filled(0, null);
+    List<T> list = new List<T>.filled(length, null);
     int index = 0;
     Link<T> link = head;
     while (link.isNotEmpty) {
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 23f68a1..951d2a4 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,10 +1,10 @@
 name: _fe_analyzer_shared
-version: 12.0.0
+version: 14.0.0
 description: Logic that is shared between the front_end and analyzer packages.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
 
 environment:
-  sdk: '>=2.2.2 <3.0.0'
+  sdk: '>=2.9.0 <3.0.0'
 dependencies:
   meta: ^1.0.2
 dev_dependencies:
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart
index 10196f4..cae1c1c 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart
@@ -137,13 +137,17 @@
     assignedVariables.declare(v1);
     assignedVariables.beginNode();
     assignedVariables.beginNode();
+    assignedVariables.beginNode();
     assignedVariables.write(v1);
     assignedVariables.endNode(_Node(),
         isClosureOrLateVariableInitializer: true);
-    var node = _Node();
-    assignedVariables.endNode(node);
+    var innerNode = _Node();
+    assignedVariables.endNode(innerNode);
+    var outerNode = _Node();
+    assignedVariables.endNode(outerNode);
     assignedVariables.finish();
-    expect(assignedVariables.capturedInNode(node), {v1});
+    expect(assignedVariables.capturedInNode(innerNode), {v1});
+    expect(assignedVariables.capturedInNode(outerNode), {v1});
   });
 
   group('Variables do not percolate beyond the scope they were declared in',
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
new file mode 100644
index 0000000..6b7be5d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
@@ -0,0 +1,1513 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This file implements the AST of a Dart-like language suitable for testing
+/// flow analysis.  Callers may use the top level methods in this file to create
+/// AST nodes and then feed them to [Harness.run] to run them through flow
+/// analysis testing.
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+const Expression nullLiteral = const _NullLiteral();
+
+Statement assert_(Expression condition, [Expression message]) =>
+    new _Assert(condition, message);
+
+Statement block(List<Statement> statements) => new _Block(statements);
+
+Expression booleanLiteral(bool value) => _BooleanLiteral(value);
+
+/// Wrapper allowing creation of a statement that can be used as the target of
+/// `break` or `continue` statements.  [callback] will be invoked to create the
+/// statement, and it will be passed a [BranchTargetPlaceholder] that can be
+/// passed to [break_] or [continue_].
+Statement branchTarget(Statement Function(BranchTargetPlaceholder) callback) {
+  var branchTargetPlaceholder = BranchTargetPlaceholder._();
+  var stmt = callback(branchTargetPlaceholder);
+  branchTargetPlaceholder._target = stmt;
+  return stmt;
+}
+
+Statement break_(BranchTargetPlaceholder branchTargetPlaceholder) =>
+    new _Break(branchTargetPlaceholder);
+
+SwitchCase case_(List<Statement> body, {bool hasLabel = false}) =>
+    SwitchCase._(hasLabel, body);
+
+CatchClause catch_(
+        {Var exception, Var stackTrace, @required List<Statement> body}) =>
+    CatchClause._(body, exception, stackTrace);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s assigned state to be [expectedAssignedState].
+Statement checkAssigned(Var variable, bool expectedAssignedState) =>
+    new _CheckAssigned(variable, expectedAssignedState);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable] to be un-promoted.
+Statement checkNotPromoted(Var variable) => new _CheckPromoted(variable, null);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s assigned state to be promoted to [expectedTypeStr].
+Statement checkPromoted(Var variable, String expectedTypeStr) =>
+    new _CheckPromoted(variable, expectedTypeStr);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers the current location's reachability state to be
+/// [expectedReachable].
+Statement checkReachable(bool expectedReachable) =>
+    new _CheckReachable(expectedReachable);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s unassigned state to be [expectedUnassignedState].
+Statement checkUnassigned(Var variable, bool expectedUnassignedState) =>
+    new _CheckUnassigned(variable, expectedUnassignedState);
+
+Statement continue_(BranchTargetPlaceholder branchTargetPlaceholder) =>
+    new _Continue(branchTargetPlaceholder);
+
+Statement declare(Var variable, {@required bool initialized}) =>
+    new _Declare(variable, initialized);
+
+Statement do_(List<Statement> body, Expression condition) =>
+    _Do(body, condition);
+
+/// Creates a pseudo-expression having type [typeStr] that otherwise has no
+/// effect on flow analysis.
+Expression expr(String typeStr) =>
+    new _PlaceholderExpression(new Type(typeStr));
+
+/// Creates a conventional `for` statement.  Optional boolean [forCollection]
+/// indicates that this `for` statement is actually a collection element, so
+/// `null` should be passed to [for_bodyBegin].
+Statement for_(Statement initializer, Expression condition, Expression updater,
+        List<Statement> body,
+        {bool forCollection = false}) =>
+    new _For(initializer, condition, updater, body, forCollection);
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is not a local variable.
+///
+/// This models code like:
+///     var x; // Top level variable
+///     f(Iterable iterable) {
+///       for (x in iterable) { ... }
+///     }
+Statement forEachWithNonVariable(Expression iterable, List<Statement> body) =>
+    new _ForEach(null, iterable, body, false);
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is a variable that is being declared by the "for each" statement.
+///
+/// This models code like:
+///     f(Iterable iterable) {
+///       for (var x in iterable) { ... }
+///     }
+Statement forEachWithVariableDecl(
+    Var variable, Expression iterable, List<Statement> body) {
+  assert(variable != null);
+  return new _ForEach(variable, iterable, body, true);
+}
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is a local variable that is declared elsewhere in the function.
+///
+/// This models code like:
+///     f(Iterable iterable) {
+///       var x;
+///       for (x in iterable) { ... }
+///     }
+Statement forEachWithVariableSet(
+    Var variable, Expression iterable, List<Statement> body) {
+  assert(variable != null);
+  return new _ForEach(variable, iterable, body, false);
+}
+
+Statement if_(Expression condition, List<Statement> ifTrue,
+        [List<Statement> ifFalse]) =>
+    new _If(condition, ifTrue, ifFalse);
+
+Statement labeled(Statement body) => new _LabeledStatement(body);
+
+Statement localFunction(List<Statement> body) => _LocalFunction(body);
+
+Statement return_() => new _Return();
+
+Statement switch_(Expression expression, List<SwitchCase> cases,
+        {@required bool isExhaustive}) =>
+    new _Switch(expression, cases, isExhaustive);
+
+Statement tryCatch(List<Statement> body, List<CatchClause> catches) =>
+    new _TryCatch(body, catches);
+
+Statement tryFinally(List<Statement> body, List<Statement> finally_) =>
+    new _TryFinally(body, finally_);
+
+Statement while_(Expression condition, List<Statement> body) =>
+    new _While(condition, body);
+
+/// Placeholder used by [branchTarget] to tie `break` and `continue` statements
+/// to their branch targets.
+class BranchTargetPlaceholder {
+  Statement _target;
+
+  /*late*/ BranchTargetPlaceholder._();
+}
+
+/// Representation of a single catch clause in a try/catch statement.  Use
+/// [catch_] to create instances of this class.
+class CatchClause implements _Visitable<void> {
+  final List<Statement> _body;
+  final Var _exception;
+  final Var _stackTrace;
+
+  CatchClause._(this._body, this._exception, this._stackTrace);
+
+  String toString() {
+    String initialPart;
+    if (_stackTrace != null) {
+      initialPart = 'catch (${_exception.name}, ${_stackTrace.name})';
+    } else if (_exception != null) {
+      initialPart = 'catch (${_exception.name})';
+    } else {
+      initialPart = 'on ...';
+    }
+    return '$initialPart ${block(_body)}';
+  }
+
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    _body._preVisit(assignedVariables);
+  }
+
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.tryCatchStatement_catchBegin(_exception, _stackTrace);
+    _body._visit(h, flow);
+    flow.tryCatchStatement_catchEnd();
+  }
+}
+
+/// Representation of an expression in the pseudo-Dart language used for flow
+/// analysis testing.  Methods in this class may be used to create more complex
+/// expressions based on this one.
+abstract class Expression implements _Visitable<Type> {
+  const Expression();
+
+  /// If `this` is an expression `x`, creates the expression `x!`.
+  Expression get nonNullAssert => new _NonNullAssert(this);
+
+  /// If `this` is an expression `x`, creates the expression `(x)`.
+  Expression get parenthesized => new _ParenthesizedExpression(this);
+
+  /// If `this` is an expression `x`, creates the statement `x;`.
+  Statement get stmt => new _ExpressionStatement(this);
+
+  /// If `this` is an expression `x`, creates the expression `x && other`.
+  Expression and(Expression other) => new _Logical(this, other, isAnd: true);
+
+  /// If `this` is an expression `x`, creates the expression `x as typeStr`.
+  Expression as_(String typeStr) => new _As(this, Type(typeStr));
+
+  /// If `this` is an expression `x`, creates the expression
+  /// `x ? ifTrue : ifFalse`.
+  Expression conditional(Expression ifTrue, Expression ifFalse) =>
+      new _Conditional(this, ifTrue, ifFalse);
+
+  /// If `this` is an expression `x`, creates the expression `x == other`.
+  Expression eq(Expression other) => new _Equal(this, other, false);
+
+  /// If `this` is an expression `x`, creates the expression `x ?? other`.
+  Expression ifNull(Expression other) => new _IfNull(this, other);
+
+  /// If `this` is an expression `x`, creates the expression `x is typeStr`.
+  ///
+  /// With [isInverted] set to `true`, creates the expression `x is! typeStr`.
+  Expression is_(String typeStr, {bool isInverted = false}) =>
+      new _Is(this, Type(typeStr), isInverted);
+
+  /// If `this` is an expression `x`, creates the expression `x is! typeStr`.
+  Expression isNot(String typeStr) => _Is(this, Type(typeStr), true);
+
+  /// If `this` is an expression `x`, creates the expression `x != other`.
+  Expression notEq(Expression other) => _Equal(this, other, true);
+
+  /// If `this` is an expression `x`, creates the expression `x?.other`.
+  ///
+  /// Note that in the real Dart language, the RHS of a null aware access isn't
+  /// strictly speaking an expression.  However for flow analysis it suffices to
+  /// model it as an expression.
+  Expression nullAwareAccess(Expression other, {bool isCascaded = false}) =>
+      _NullAwareAccess(this, other, isCascaded);
+
+  /// If `this` is an expression `x`, creates the expression `x || other`.
+  Expression or(Expression other) => new _Logical(this, other, isAnd: false);
+
+  /// If `this` is an expression `x`, creates a pseudo-expression that models
+  /// evaluation of `x` followed by execution of [stmt].  This can be used to
+  /// test that flow analysis is in the correct state after an expression is
+  /// visited.
+  Expression thenStmt(Statement stmt) =>
+      new _WrappedExpression(null, this, stmt);
+}
+
+/// Test harness for creating flow analysis tests.  This class implements all
+/// the [TypeOperations] needed by flow analysis, as well as other methods
+/// needed for testing.
+class Harness extends TypeOperations<Var, Type> {
+  static const Map<String, bool> _coreSubtypes = const {
+    'double <: Object': true,
+    'double <: num': true,
+    'double <: num?': true,
+    'double <: int': false,
+    'double <: int?': false,
+    'int <: double': false,
+    'int <: int?': true,
+    'int <: Iterable': false,
+    'int <: List': false,
+    'int <: Null': false,
+    'int <: num': true,
+    'int <: num?': true,
+    'int <: num*': true,
+    'int <: Never?': false,
+    'int <: Object': true,
+    'int <: Object?': true,
+    'int <: String': false,
+    'int? <: int': false,
+    'int? <: Null': false,
+    'int? <: num': false,
+    'int? <: num?': true,
+    'int? <: Object': false,
+    'int? <: Object?': true,
+    'Null <: int': false,
+    'Null <: Object': false,
+    'num <: int': false,
+    'num <: Iterable': false,
+    'num <: List': false,
+    'num <: num?': true,
+    'num <: num*': true,
+    'num <: Object': true,
+    'num <: Object?': true,
+    'num? <: int?': false,
+    'num? <: num': false,
+    'num? <: num*': true,
+    'num? <: Object': false,
+    'num? <: Object?': true,
+    'num* <: num': true,
+    'num* <: num?': true,
+    'num* <: Object': true,
+    'num* <: Object?': true,
+    'Iterable <: int': false,
+    'Iterable <: num': false,
+    'Iterable <: Object': true,
+    'Iterable <: Object?': true,
+    'List <: int': false,
+    'List <: Iterable': true,
+    'List <: Object': true,
+    'Never <: int': true,
+    'Never <: int?': true,
+    'Never <: Null': true,
+    'Never? <: int': false,
+    'Never? <: int?': true,
+    'Never? <: num?': true,
+    'Never? <: Object?': true,
+    'Null <: int?': true,
+    'Object <: int': false,
+    'Object <: int?': false,
+    'Object <: List': false,
+    'Object <: num': false,
+    'Object <: num?': false,
+    'Object <: Object?': true,
+    'Object? <: Object': false,
+    'Object? <: int': false,
+    'Object? <: int?': false,
+    'String <: int': false,
+    'String <: int?': false,
+    'String <: num?': false,
+    'String <: Object?': true,
+  };
+
+  static final Map<String, Type> _coreFactors = {
+    'Object? - int': Type('Object?'),
+    'Object? - int?': Type('Object'),
+    'Object? - num?': Type('Object'),
+    'Object? - Object?': Type('Never?'),
+    'Object? - String': Type('Object?'),
+    'Object - int': Type('Object'),
+    'int - Object': Type('Never'),
+    'int - String': Type('int'),
+    'int - int': Type('Never'),
+    'int - int?': Type('Never'),
+    'int? - int': Type('Never?'),
+    'int? - int?': Type('Never'),
+    'int? - String': Type('int?'),
+    'Null - int': Type('Null'),
+    'num - int': Type('num'),
+    'num? - num': Type('Never?'),
+    'num? - int': Type('num?'),
+    'num? - int?': Type('num'),
+    'num? - Object': Type('Never?'),
+    'num? - String': Type('num?'),
+    'Object - int?': Type('Object'),
+    'Object - num': Type('Object'),
+    'Object - num?': Type('Object'),
+    'Object - num*': Type('Object'),
+    'Object - Iterable': Type('Object'),
+    'Object? - Object': Type('Never?'),
+    'Object? - Iterable': Type('Object?'),
+    'Object? - num': Type('Object?'),
+    'Iterable - List': Type('Iterable'),
+    'num* - Object': Type('Never'),
+  };
+
+  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
+
+  final Map<String, Type> _factorResults = Map.of(_coreFactors);
+
+  Node _currentSwitch;
+
+  /// Updates the harness so that when a [factor] query is invoked on types
+  /// [from] and [what], [result] will be returned.
+  void addFactor(Type from, Type what, Type result) {
+    var query = '$from - $what';
+    _factorResults[query] = result;
+  }
+
+  /// Updates the harness so that when an [isSubtypeOf] query is invoked on
+  /// types [leftType] and [rightType], [isSubtype] will be returned.
+  void addSubtype(Type leftType, Type rightType, bool isSubtype) {
+    var query = '$leftType <: $rightType';
+    _subtypes[query] = isSubtype;
+  }
+
+  @override
+  TypeClassification classifyType(Type type) {
+    if (isSubtypeOf(type, Type('Object'))) {
+      return TypeClassification.nonNullable;
+    } else if (isSubtypeOf(type, Type('Null'))) {
+      return TypeClassification.nullOrEquivalent;
+    } else {
+      return TypeClassification.potentiallyNullable;
+    }
+  }
+
+  @override
+  Type factor(Type from, Type what) {
+    var query = '$from - $what';
+    return _factorResults[query] ?? fail('Unknown factor query: $query');
+  }
+
+  @override
+  bool isNever(Type type) {
+    return type.type == 'Never';
+  }
+
+  @override
+  bool isSameType(Type type1, Type type2) {
+    return type1.type == type2.type;
+  }
+
+  @override
+  bool isSubtypeOf(Type leftType, Type rightType) {
+    if (leftType.type == rightType.type) return true;
+    var query = '$leftType <: $rightType';
+    return _subtypes[query] ?? fail('Unknown subtype query: $query');
+  }
+
+  @override
+  Type promoteToNonNull(Type type) {
+    if (type.type.endsWith('?')) {
+      return Type(type.type.substring(0, type.type.length - 1));
+    } else if (type.type == 'Null') {
+      return Type('Never');
+    } else {
+      return type;
+    }
+  }
+
+  /// Runs the given [statements] through flow analysis, checking any assertions
+  /// they contain.
+  void run(List<Statement> statements) {
+    var assignedVariables = AssignedVariables<Node, Var>();
+    statements._preVisit(assignedVariables);
+    var flow = FlowAnalysis<Node, Statement, Expression, Var, Type>(
+        this, assignedVariables);
+    statements._visit(this, flow);
+    flow.finish();
+  }
+
+  @override
+  Type tryPromoteToType(Type to, Type from) {
+    if (isSubtypeOf(to, from)) {
+      return to;
+    } else {
+      return null;
+    }
+  }
+
+  @override
+  Type variableType(Var variable) {
+    return variable.type;
+  }
+
+  Type _getIteratedType(Type iterableType) {
+    var typeStr = iterableType.type;
+    if (typeStr.startsWith('List<') && typeStr.endsWith('>')) {
+      return Type(typeStr.substring(5, typeStr.length - 1));
+    } else {
+      throw UnimplementedError('TODO(paulberry): getIteratedType($typeStr)');
+    }
+  }
+
+  Type _lub(Type type1, Type type2) {
+    if (isSameType(type1, type2)) {
+      return type1;
+    } else if (isSameType(promoteToNonNull(type1), type2)) {
+      return type1;
+    } else if (isSameType(promoteToNonNull(type2), type1)) {
+      return type2;
+    } else if (type1.type == 'Null' &&
+        !isSameType(promoteToNonNull(type2), type2)) {
+      // type2 is already nullable
+      return type2;
+    } else if (type2.type == 'Null' &&
+        !isSameType(promoteToNonNull(type1), type1)) {
+      // type1 is already nullable
+      return type1;
+    } else {
+      throw UnimplementedError(
+          'TODO(paulberry): least upper bound of $type1 and $type2');
+    }
+  }
+}
+
+/// Representation of an expression or statement in the pseudo-Dart language
+/// used for flow analysis testing.
+class Node {
+  Node._();
+}
+
+/// Representation of a statement in the pseudo-Dart language used for flow
+/// analysis testing.
+abstract class Statement extends Node implements _Visitable<void> {
+  Statement._() : super._();
+
+  /// If `this` is a statement `x`, creates a pseudo-expression that models
+  /// execution of `x` followed by evaluation of [expr].  This can be used to
+  /// test that flow analysis is in the correct state before an expression is
+  /// visited.
+  Expression thenExpr(Expression expr) => _WrappedExpression(this, expr, null);
+}
+
+/// Representation of a single case clause in a switch statement.  Use [case_]
+/// to create instances of this class.
+class SwitchCase implements _Visitable<void> {
+  final bool _hasLabel;
+  final List<Statement> _body;
+
+  SwitchCase._(this._hasLabel, this._body);
+
+  String toString() =>
+      [if (_hasLabel) '<label>:', 'case <value>:', ..._body].join(' ');
+
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    _body._preVisit(assignedVariables);
+  }
+
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.switchStatement_beginCase(_hasLabel, h._currentSwitch);
+    _body._visit(h, flow);
+  }
+}
+
+/// Representation of a type in the pseudo-Dart language used for flow analysis
+/// testing.  This is essentially a thin wrapper around a string representation
+/// of the type.
+class Type {
+  final String type;
+
+  Type(this.type);
+
+  @override
+  bool operator ==(Object other) {
+    // The flow analysis engine should not compare types using operator==.  It
+    // should compare them using TypeOperations.
+    fail('Unexpected use of operator== on types');
+  }
+
+  @override
+  String toString() => type;
+}
+
+/// Representation of a local variable in the pseudo-Dart language used for flow
+/// analysis testing.
+class Var {
+  final String name;
+  final Type type;
+
+  Var(this.name, String typeStr) : type = Type(typeStr);
+
+  /// Creates an expression representing a read of this variable.
+  Expression get read => new _VariableRead(this);
+
+  @override
+  String toString() => '$type $name';
+
+  /// Creates an expression representing a write to this variable.
+  Expression write(Expression value) => new _Write(this, value);
+}
+
+class _As extends Expression {
+  final Expression target;
+  final Type type;
+
+  _As(this.target, this.type);
+
+  @override
+  String toString() => '$target as $type';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    target._visit(h, flow);
+    flow.asExpression_end(target, type);
+    return type;
+  }
+}
+
+class _Assert extends Statement {
+  final Expression condition;
+  final Expression message;
+
+  _Assert(this.condition, this.message) : super._();
+
+  @override
+  String toString() =>
+      'assert($condition${message == null ? '' : ', $message'});';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    message?._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.assert_begin();
+    flow.assert_afterCondition(condition.._visit(h, flow));
+    message?._visit(h, flow);
+    flow.assert_end();
+  }
+}
+
+class _Block extends Statement {
+  final List<Statement> statements;
+
+  _Block(this.statements) : super._();
+
+  @override
+  String toString() =>
+      statements.isEmpty ? '{}' : '{ ${statements.join(' ')} }';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    statements._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    statements._visit(h, flow);
+  }
+}
+
+class _BooleanLiteral extends Expression {
+  final bool value;
+
+  _BooleanLiteral(this.value);
+
+  @override
+  String toString() => '$value';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.booleanLiteral(this, value);
+    return Type('bool');
+  }
+}
+
+class _Break extends Statement {
+  final BranchTargetPlaceholder branchTargetPlaceholder;
+
+  _Break(this.branchTargetPlaceholder) : super._();
+
+  @override
+  String toString() => 'break;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    assert(branchTargetPlaceholder._target != null);
+    flow.handleBreak(branchTargetPlaceholder._target);
+  }
+}
+
+class _CheckAssigned extends Statement {
+  final Var variable;
+  final bool expectedAssignedState;
+
+  _CheckAssigned(this.variable, this.expectedAssignedState) : super._();
+
+  @override
+  String toString() {
+    var verb = expectedAssignedState ? 'is' : 'is not';
+    return 'check $variable $verb definitely assigned;';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expect(flow.isAssigned(variable), expectedAssignedState);
+  }
+}
+
+class _CheckPromoted extends Statement {
+  final Var variable;
+  final String expectedTypeStr;
+
+  _CheckPromoted(this.variable, this.expectedTypeStr) : super._();
+
+  @override
+  String toString() {
+    var predicate = expectedTypeStr == null
+        ? 'not promoted'
+        : 'promoted to $expectedTypeStr';
+    return 'check $variable $predicate;';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var promotedType = flow.promotedType(variable);
+    if (expectedTypeStr == null) {
+      expect(promotedType, isNull);
+    } else {
+      expect(promotedType.type, expectedTypeStr);
+    }
+  }
+}
+
+class _CheckReachable extends Statement {
+  final bool expectedReachable;
+
+  _CheckReachable(this.expectedReachable) : super._();
+
+  @override
+  String toString() => 'check reachable;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expect(flow.isReachable, expectedReachable);
+  }
+}
+
+class _CheckUnassigned extends Statement {
+  final Var variable;
+  final bool expectedUnassignedState;
+
+  _CheckUnassigned(this.variable, this.expectedUnassignedState) : super._();
+
+  @override
+  String toString() {
+    var verb = expectedUnassignedState ? 'is' : 'is not';
+    return 'check $variable $verb definitely unassigned;';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expect(flow.isUnassigned(variable), expectedUnassignedState);
+  }
+}
+
+class _Conditional extends Expression {
+  final Expression condition;
+  final Expression ifTrue;
+  final Expression ifFalse;
+
+  _Conditional(this.condition, this.ifTrue, this.ifFalse);
+
+  @override
+  String toString() => '$condition ? $ifTrue : $ifFalse';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    ifTrue._preVisit(assignedVariables);
+    ifFalse._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.conditional_conditionBegin();
+    flow.conditional_thenBegin(condition.._visit(h, flow));
+    var ifTrueType = ifTrue._visit(h, flow);
+    flow.conditional_elseBegin(ifTrue);
+    var ifFalseType = ifFalse._visit(h, flow);
+    flow.conditional_end(this, ifFalse);
+    return h._lub(ifTrueType, ifFalseType);
+  }
+}
+
+class _Continue extends Statement {
+  final BranchTargetPlaceholder branchTargetPlaceholder;
+
+  _Continue(this.branchTargetPlaceholder) : super._();
+
+  @override
+  String toString() => 'continue;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    assert(branchTargetPlaceholder._target != null);
+    flow.handleContinue(branchTargetPlaceholder._target);
+  }
+}
+
+class _Declare extends Statement {
+  final Var variable;
+  final bool initialized;
+
+  _Declare(this.variable, this.initialized) : super._();
+
+  @override
+  String toString() => '$variable${initialized ? ' = ...' : ''};';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.declare(variable, initialized);
+  }
+}
+
+class _Do extends Statement {
+  final List<Statement> body;
+  final Expression condition;
+
+  _Do(this.body, this.condition) : super._();
+
+  @override
+  String toString() => 'do ${block(body)} while ($condition);';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    condition._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.doStatement_bodyBegin(this);
+    body._visit(h, flow);
+    flow.doStatement_conditionBegin();
+    condition._visit(h, flow);
+    flow.doStatement_end(condition);
+  }
+}
+
+class _Equal extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+  final bool isInverted;
+
+  _Equal(this.lhs, this.rhs, this.isInverted);
+
+  @override
+  String toString() => '$lhs ${isInverted ? '!=' : '=='} $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var lhsType = lhs._visit(h, flow);
+    flow.equalityOp_rightBegin(lhs, lhsType);
+    var rhsType = rhs._visit(h, flow);
+    flow.equalityOp_end(this, rhs, rhsType, notEqual: isInverted);
+    return Type('bool');
+  }
+}
+
+class _ExpressionStatement extends Statement {
+  final Expression expr;
+
+  _ExpressionStatement(this.expr) : super._();
+
+  @override
+  String toString() => '$expr;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    expr._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expr._visit(h, flow);
+  }
+}
+
+class _For extends Statement {
+  final Statement initializer;
+  final Expression condition;
+  final Expression updater;
+  final List<Statement> body;
+  final bool forCollection;
+
+  _For(this.initializer, this.condition, this.updater, this.body,
+      this.forCollection)
+      : super._();
+
+  @override
+  String toString() {
+    var buffer = StringBuffer('for (');
+    if (initializer == null) {
+      buffer.write(';');
+    } else {
+      buffer.write(initializer);
+    }
+    if (condition == null) {
+      buffer.write(';');
+    } else {
+      buffer.write(' $condition;');
+    }
+    if (updater != null) {
+      buffer.write(' $updater');
+    }
+    buffer.write(') ${block(body)}');
+    return buffer.toString();
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    initializer?._preVisit(assignedVariables);
+    assignedVariables.beginNode();
+    condition?._preVisit(assignedVariables);
+    body._preVisit(assignedVariables);
+    updater?._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    initializer?._visit(h, flow);
+    flow.for_conditionBegin(this);
+    condition?._visit(h, flow);
+    flow.for_bodyBegin(forCollection ? null : this, condition);
+    body._visit(h, flow);
+    flow.for_updaterBegin();
+    updater?._visit(h, flow);
+    flow.for_end();
+  }
+}
+
+class _ForEach extends Statement {
+  final Var variable;
+  final Expression iterable;
+  final List<Statement> body;
+  final bool declaresVariable;
+
+  _ForEach(this.variable, this.iterable, this.body, this.declaresVariable)
+      : super._();
+
+  @override
+  String toString() {
+    String declarationPart;
+    if (variable == null) {
+      declarationPart = '<identifier>';
+    } else if (declaresVariable) {
+      declarationPart = variable.toString();
+    } else {
+      declarationPart = variable.name;
+    }
+    return 'for ($declarationPart in $iterable) ${block(body)}';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    iterable._preVisit(assignedVariables);
+    if (variable != null) {
+      if (declaresVariable) {
+        assignedVariables.declare(variable);
+      } else {
+        assignedVariables.write(variable);
+      }
+    }
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var iteratedType = h._getIteratedType(iterable._visit(h, flow));
+    flow.forEach_bodyBegin(this, variable, iteratedType);
+    body._visit(h, flow);
+    flow.forEach_end();
+  }
+}
+
+class _If extends Statement {
+  final Expression condition;
+  final List<Statement> ifTrue;
+  final List<Statement> ifFalse;
+
+  _If(this.condition, this.ifTrue, this.ifFalse) : super._();
+
+  @override
+  String toString() =>
+      'if ($condition) ${block(ifTrue)}' +
+      (ifFalse == null ? '' : 'else ${block(ifFalse)}');
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    ifTrue._preVisit(assignedVariables);
+    ifFalse?._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.ifStatement_conditionBegin();
+    flow.ifStatement_thenBegin(condition.._visit(h, flow));
+    ifTrue._visit(h, flow);
+    if (ifFalse == null) {
+      flow.ifStatement_end(false);
+    } else {
+      flow.ifStatement_elseBegin();
+      ifFalse._visit(h, flow);
+      flow.ifStatement_end(true);
+    }
+  }
+}
+
+class _IfNull extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+
+  _IfNull(this.lhs, this.rhs);
+
+  @override
+  String toString() => '$lhs ?? $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var lhsType = lhs._visit(h, flow);
+    flow.ifNullExpression_rightBegin(lhs, lhsType);
+    var rhsType = rhs._visit(h, flow);
+    flow.ifNullExpression_end();
+    return h._lub(h.promoteToNonNull(lhsType), rhsType);
+  }
+}
+
+class _Is extends Expression {
+  final Expression target;
+  final Type type;
+  final bool isInverted;
+
+  _Is(this.target, this.type, this.isInverted);
+
+  @override
+  String toString() => '$target is${isInverted ? '!' : ''} $type';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.isExpression_end(this, target.._visit(h, flow), isInverted, type);
+    return Type('bool');
+  }
+}
+
+class _LabeledStatement extends Statement {
+  final Statement body;
+
+  _LabeledStatement(this.body) : super._();
+
+  @override
+  String toString() => 'labeled: $body';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    body._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.labeledStatement_begin(this);
+    body._visit(h, flow);
+    flow.labeledStatement_end();
+  }
+}
+
+class _LocalFunction extends Statement {
+  final List<Statement> body;
+
+  _LocalFunction(this.body) : super._();
+
+  @override
+  String toString() => '() ${block(body)}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this, isClosureOrLateVariableInitializer: true);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.functionExpression_begin(this);
+    body._visit(h, flow);
+    flow.functionExpression_end();
+  }
+}
+
+class _Logical extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+  final bool isAnd;
+
+  _Logical(this.lhs, this.rhs, {@required this.isAnd});
+
+  @override
+  String toString() => '$lhs ${isAnd ? '&&' : '||'} $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.logicalBinaryOp_begin();
+    flow.logicalBinaryOp_rightBegin(lhs.._visit(h, flow), isAnd: isAnd);
+    flow.logicalBinaryOp_end(this, rhs.._visit(h, flow), isAnd: isAnd);
+    return Type('bool');
+  }
+}
+
+class _NonNullAssert extends Expression {
+  final Expression operand;
+
+  _NonNullAssert(this.operand);
+
+  @override
+  String toString() => '$operand!';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    operand._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = operand._visit(h, flow);
+    flow.nonNullAssert_end(operand);
+    return h.promoteToNonNull(type);
+  }
+}
+
+class _NullAwareAccess extends Expression {
+  final Expression lhs;
+  final Expression rhs;
+  final bool isCascaded;
+
+  _NullAwareAccess(this.lhs, this.rhs, this.isCascaded);
+
+  @override
+  String toString() => '$lhs?.${isCascaded ? '.' : ''}($rhs)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var lhsType = lhs._visit(h, flow);
+    flow.nullAwareAccess_rightBegin(isCascaded ? null : lhs, lhsType);
+    var rhsType = rhs._visit(h, flow);
+    flow.nullAwareAccess_end();
+    return h._lub(rhsType, Type('Null'));
+  }
+}
+
+class _NullLiteral extends Expression {
+  const _NullLiteral();
+
+  @override
+  String toString() => 'null';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.nullLiteral(this);
+    return Type('Null');
+  }
+}
+
+class _ParenthesizedExpression extends Expression {
+  final Expression expr;
+
+  _ParenthesizedExpression(this.expr);
+
+  @override
+  String toString() => '($expr)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    expr._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = expr._visit(h, flow);
+    flow.parenthesizedExpression(this, expr);
+    return type;
+  }
+}
+
+class _PlaceholderExpression extends Expression {
+  final Type type;
+
+  _PlaceholderExpression(this.type);
+
+  @override
+  String toString() => '(expr with type $type)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(Harness h,
+          FlowAnalysis<Node, Statement, Expression, Var, Type> flow) =>
+      type;
+}
+
+class _Return extends Statement {
+  _Return() : super._();
+
+  @override
+  String toString() => 'return;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.handleExit();
+  }
+}
+
+class _Switch extends Statement {
+  final Expression expression;
+  final List<SwitchCase> cases;
+  final bool isExhaustive;
+
+  _Switch(this.expression, this.cases, this.isExhaustive) : super._();
+
+  @override
+  String toString() {
+    var exhaustiveness = isExhaustive ? 'exhaustive' : 'non-exhaustive';
+    String body;
+    if (cases.isEmpty) {
+      body = '{}';
+    } else {
+      var contents = cases.join(' ');
+      body = '{ $contents }';
+    }
+    return 'switch<$exhaustiveness> ($expression) $body';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    expression._preVisit(assignedVariables);
+    assignedVariables.beginNode();
+    cases._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    expression._visit(h, flow);
+    flow.switchStatement_expressionEnd(this);
+    var oldSwitch = h._currentSwitch;
+    h._currentSwitch = this;
+    cases._visit(h, flow);
+    h._currentSwitch = oldSwitch;
+    flow.switchStatement_end(isExhaustive);
+  }
+}
+
+class _TryCatch extends Statement {
+  final List<Statement> body;
+  final List<CatchClause> catches;
+
+  _TryCatch(this.body, this.catches) : super._();
+
+  @override
+  String toString() => 'try ${block(body)} ${catches.join(' ')}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+    catches._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.tryCatchStatement_bodyBegin();
+    body._visit(h, flow);
+    flow.tryCatchStatement_bodyEnd(this);
+    catches._visit(h, flow);
+    flow.tryCatchStatement_end();
+  }
+}
+
+class _TryFinally extends Statement {
+  final List<Statement> body;
+  final List<Statement> finally_;
+  final Node _bodyNode = Node._();
+  final Node _finallyNode = Node._();
+
+  _TryFinally(this.body, this.finally_) : super._();
+
+  @override
+  String toString() => 'try ${block(body)} finally ${block(finally_)}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(_bodyNode);
+    assignedVariables.beginNode();
+    finally_._preVisit(assignedVariables);
+    assignedVariables.endNode(_finallyNode);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.tryFinallyStatement_bodyBegin();
+    body._visit(h, flow);
+    flow.tryFinallyStatement_finallyBegin(_bodyNode);
+    finally_._visit(h, flow);
+    flow.tryFinallyStatement_end(_finallyNode);
+  }
+}
+
+class _VariableRead extends Expression {
+  final Var variable;
+
+  _VariableRead(this.variable);
+
+  @override
+  String toString() => variable.name;
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    return flow.variableRead(this, variable) ?? variable.type;
+  }
+}
+
+abstract class _Visitable<T> {
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables);
+
+  T _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow);
+}
+
+class _While extends Statement {
+  final Expression condition;
+  final List<Statement> body;
+
+  _While(this.condition, this.body) : super._();
+
+  @override
+  String toString() => 'while ($condition) ${block(body)}';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.beginNode();
+    condition?._preVisit(assignedVariables);
+    body._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.whileStatement_conditionBegin(this);
+    condition?._visit(h, flow);
+    flow.whileStatement_bodyBegin(this, condition);
+    body._visit(h, flow);
+    flow.whileStatement_end();
+  }
+}
+
+class _WrappedExpression extends Expression {
+  final Statement before;
+  final Expression expr;
+  final Statement after;
+
+  _WrappedExpression(this.before, this.expr, this.after);
+
+  @override
+  String toString() {
+    var s = StringBuffer('(');
+    if (before != null) {
+      s.write('($before) ');
+    }
+    s.write(expr);
+    if (after != null) {
+      s.write(' ($after)');
+    }
+    s.write(')');
+    return s.toString();
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    before?._preVisit(assignedVariables);
+    expr._preVisit(assignedVariables);
+    after?._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    before?._visit(h, flow);
+    var type = expr._visit(h, flow);
+    after?._visit(h, flow);
+    flow.forwardExpression(this, expr);
+    return type;
+  }
+}
+
+class _Write extends Expression {
+  final Var variable;
+  final Expression rhs;
+
+  _Write(this.variable, this.rhs);
+
+  @override
+  String toString() => '${variable.name} = $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    assignedVariables.write(variable);
+    rhs._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = rhs._visit(h, flow);
+    flow.write(variable, type);
+    return type;
+  }
+}
+
+extension on List<_Visitable<void>> {
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    for (var element in this) {
+      element._preVisit(assignedVariables);
+    }
+  }
+
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    for (var element in this) {
+      element._visit(h, flow);
+    }
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 02d3307..7d3a04f 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -3,152 +3,139 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
+import 'flow_analysis_mini_ast.dart';
+
 main() {
   group('API', () {
     test('asExpression_end promotes variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var expr = _Expression();
-        flow.variableRead(expr, x);
-        flow.asExpression_end(expr, _Type('int'));
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('asExpression_end handles other expressions', () {
-      var h = _Harness();
-      h.run((flow) {
-        var expr = _Expression();
-        flow.asExpression_end(expr, _Type('int'));
-      });
+      var h = Harness();
+      h.run([
+        expr('Object').as_('int').stmt,
+      ]);
     });
 
     test('assert_afterCondition promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        flow.assert_begin();
-        var expr = h.eqNull(x, _Type('int?'))();
-        flow.assert_afterCondition(expr);
-        expect(flow.promotedType(x).type, 'int');
-        flow.assert_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        assert_(x.read.eq(nullLiteral),
+            checkPromoted(x, 'int').thenExpr(expr('String'))),
+      ]);
     });
 
     test('assert_end joins previous and ifTrue states', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('x', 'int?');
-      var z = h.addVar('x', 'int?');
-      h.assignedVariables((vars) {
-        vars.write(x);
-        vars.write(z);
-      });
-      h.run((flow) {
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.assert_begin();
-        flow.write(x, _Type('int?'));
-        flow.write(z, _Type('int?'));
-        var expr =
-            h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?')))();
-        flow.assert_afterCondition(expr);
-        flow.assert_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('x', 'int?');
+      var z = Var('x', 'int?');
+      h.run([
+        x.read.as_('int').stmt,
+        z.read.as_('int').stmt,
+        assert_(block([
+          x.write(expr('int?')).stmt,
+          z.write(expr('int?')).stmt,
+        ]).thenExpr(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)))),
         // x should be promoted because it was promoted before the assert, and
         // it is re-promoted within the assert (if it passes)
-        expect(flow.promotedType(x).type, 'int');
+        checkPromoted(x, 'int'),
         // y should not be promoted because it was not promoted before the
         // assert.
-        expect(flow.promotedType(y), null);
+        checkNotPromoted(y),
         // z should not be promoted because it is demoted in the assert
         // condition.
-        expect(flow.promotedType(z), null);
-      });
+        checkNotPromoted(z),
+      ]);
     });
 
     test('conditional_thenBegin promotes true branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.conditional_conditionBegin();
-        flow.conditional_thenBegin(h.notNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-        flow.conditional_elseBegin(_Expression());
-        expect(flow.promotedType(x), isNull);
-        flow.conditional_end(_Expression(), _Expression());
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .notEq(nullLiteral)
+            .conditional(checkPromoted(x, 'int').thenExpr(expr('int')),
+                checkNotPromoted(x).thenExpr(expr('int')))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('conditional_elseBegin promotes false branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.conditional_conditionBegin();
-        flow.conditional_thenBegin(h.eqNull(x, _Type('int?'))());
-        expect(flow.promotedType(x), isNull);
-        flow.conditional_elseBegin(_Expression());
-        expect(flow.promotedType(x).type, 'int');
-        flow.conditional_end(_Expression(), _Expression());
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .eq(nullLiteral)
+            .conditional(checkNotPromoted(x).thenExpr(expr('Null')),
+                checkPromoted(x, 'int').thenExpr(expr('Null')))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('conditional_end keeps promotions common to true and false branches',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.conditional_conditionBegin();
-        flow.conditional_thenBegin(_Expression());
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        flow.conditional_elseBegin(_Expression());
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.conditional_end(_Expression(), _Expression());
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        expr('bool')
+            .conditional(
+                block([
+                  x.read.as_('int').stmt,
+                  y.read.as_('int').stmt,
+                ]).thenExpr(expr('Null')),
+                block([
+                  x.read.as_('int').stmt,
+                  z.read.as_('int').stmt,
+                ]).thenExpr(expr('Null')))
+            .stmt,
+        checkPromoted(x, 'int'),
+        checkNotPromoted(y),
+        checkNotPromoted(z),
+      ]);
     });
 
     test('conditional joins true states', () {
       // if (... ? (x != null && y != null) : (x != null && z != null)) {
       //   promotes x, but not y or z
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.if_(
-            h.conditional(
-                h.expr,
-                h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?'))),
-                h.and(
-                    h.notNull(x, _Type('int?')), h.notNull(z, _Type('int?')))),
-            () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y), isNull);
-          expect(flow.promotedType(z), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        if_(
+            expr('bool').conditional(
+                x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)),
+                x.read.notEq(nullLiteral).and(z.read.notEq(nullLiteral))),
+            [
+              checkPromoted(x, 'int'),
+              checkNotPromoted(y),
+              checkNotPromoted(z),
+            ]),
+      ]);
     });
 
     test('conditional joins false states', () {
@@ -156,1087 +143,845 @@
       // } else {
       //   promotes x, but not y or z
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.ifElse(
-            h.conditional(
-                h.expr,
-                h.or(h.eqNull(x, _Type('int?')), h.eqNull(y, _Type('int?'))),
-                h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))),
-            () {}, () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y), isNull);
-          expect(flow.promotedType(z), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        if_(
+            expr('bool').conditional(
+                x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)),
+                x.read.eq(nullLiteral).or(z.read.eq(nullLiteral))),
+            [],
+            [
+              checkPromoted(x, 'int'),
+              checkNotPromoted(y),
+              checkNotPromoted(z),
+            ]),
+      ]);
     });
 
     test('equalityOp(x != null) promotes true branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int?'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(nullLiteral), [
+          checkReachable(true),
+          checkPromoted(x, 'int'),
+        ], [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(x != null) when x is non-nullable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(nullLiteral), [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ], [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ])
+      ]);
     });
 
     test('equalityOp(<expr> == <expr>) has no special effect', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        flow.equalityOp_rightBegin(_Expression(), _Type('int?'));
-        var expr = _Expression();
-        flow.equalityOp_end(expr, _Expression(), _Type('int?'),
-            notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int?').eq(expr('int?')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(<expr> != <expr>) has no special effect', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        flow.equalityOp_rightBegin(_Expression(), _Type('int?'));
-        var expr = _Expression();
-        flow.equalityOp_end(expr, _Expression(), _Type('int?'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int?').notEq(expr('int?')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(x != <null expr>) does not promote', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int?'));
-        var nullExpr = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(expr('Null')), [
+          checkNotPromoted(x),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(x == null) promotes false branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int?'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.eq(nullLiteral), [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ], [
+          checkReachable(true),
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('equalityOp(x == null) when x is non-nullable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.equalityOp_rightBegin(varExpr, _Type('int'));
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.eq(nullLiteral), [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ], [
+          checkReachable(true),
+          checkNotPromoted(x),
+        ])
+      ]);
     });
 
     test('equalityOp(null != x) promotes true branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(nullLiteral.notEq(x.read), [
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(<null expr> != x) does not promote', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var nullExpr = _Expression();
-        flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('Null').notEq(x.read), [
+          checkNotPromoted(x),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('equalityOp(null == x) promotes false branch', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var nullExpr = _Expression();
-        flow.nullLiteral(nullExpr);
-        flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        var expr = _Expression();
-        flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: false);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.promotedType(x), isNull);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(nullLiteral.eq(x.read), [
+          checkNotPromoted(x),
+        ], [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('equalityOp(null == null) equivalent to true', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, false);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').eq(expr('Null')), [
+          checkReachable(true),
+        ], [
+          checkReachable(false),
+        ]),
+      ]);
     });
 
     test('equalityOp(null != null) equivalent to false', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, false);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').notEq(expr('Null')), [
+          checkReachable(false),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(null == non-null) is not equivalent to false', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('int'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').eq(expr('int')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(null != non-null) is not equivalent to true', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('Null'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('int'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').notEq(expr('int')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(non-null == null) is not equivalent to false', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('int'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int').eq(expr('Null')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('equalityOp(non-null != null) is not equivalent to true', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var null1 = _Expression();
-        flow.equalityOp_rightBegin(null1, _Type('int'));
-        var null2 = _Expression();
-        var expr = _Expression();
-        flow.equalityOp_end(expr, null2, _Type('Null'), notEqual: true);
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('int').notEq(expr('Null')), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('conditionEqNull() does not promote write-captured vars', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.if_(h.notNull(x, _Type('int?')), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        h.if_(h.notNull(x, _Type('int?')), () {
-          expect(flow.promotedType(x), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.notEq(nullLiteral), [
+          checkPromoted(x, 'int'),
+        ]),
+        localFunction([
+          x.write(expr('int?')).stmt,
+        ]),
+        if_(x.read.notEq(nullLiteral), [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('doStatement_bodyBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var doStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(doStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.doStatement_bodyBegin(doStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.doStatement_conditionBegin();
-        flow.doStatement_end(_Expression());
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        branchTarget((t) => do_([
+              checkNotPromoted(x),
+              x.write(expr('Null')).stmt,
+            ], expr('bool'))),
+      ]);
     });
 
     test('doStatement_bodyBegin() handles write captures in the loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var doStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(
-          doStatement, () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.doStatement_bodyBegin(doStatement);
-        h.promote(x, 'int');
-        // The promotion should have no effect, because the second time through
-        // the loop, x has been write-captured.
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.doStatement_conditionBegin();
-        flow.doStatement_end(_Expression());
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        do_([
+          x.read.as_('int').stmt,
+          // The promotion should have no effect, because the second time
+          // through the loop, x has been write-captured.
+          checkNotPromoted(x),
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+        ], expr('bool')),
+      ]);
     });
 
     test('doStatement_conditionBegin() joins continue state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.doStatement_bodyBegin(stmt);
-        h.if_(h.notNull(x, _Type('int?')), () {
-          flow.handleContinue(stmt);
-        });
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        expect(flow.promotedType(x), isNull);
-        flow.doStatement_conditionBegin();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.doStatement_end(_Expression());
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        branchTarget((t) => do_(
+                [
+                  if_(x.read.notEq(nullLiteral), [
+                    continue_(t),
+                  ]),
+                  return_(),
+                  checkReachable(false),
+                  checkNotPromoted(x),
+                ],
+                block([
+                  checkReachable(true),
+                  checkPromoted(x, 'int'),
+                ]).thenExpr(expr('bool')))),
+      ]);
     });
 
     test('doStatement_end() promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.doStatement_bodyBegin(stmt);
-        flow.doStatement_conditionBegin();
-        expect(flow.promotedType(x), isNull);
-        flow.doStatement_end(h.eqNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        branchTarget((t) =>
+            do_([], checkNotPromoted(x).thenExpr(x.read.eq(nullLiteral)))),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('finish checks proper nesting', () {
-      var h = _Harness();
-      var expr = _Expression();
-      var flow = h.createFlow();
+      var h = Harness();
+      var e = expr('Null');
+      var flow = FlowAnalysis<Node, Statement, Expression, Var, Type>(
+          h, AssignedVariables<Node, Var>());
       flow.ifStatement_conditionBegin();
-      flow.ifStatement_thenBegin(expr);
+      flow.ifStatement_thenBegin(e);
       expect(() => flow.finish(), _asserts);
     });
 
     test('for_conditionBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.for_conditionBegin(forStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.for_bodyBegin(_Statement(), _Expression());
-        flow.write(x, _Type('int?'));
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        for_(null, checkNotPromoted(x).thenExpr(expr('bool')), null, [
+          x.write(expr('int?')).stmt,
+        ]),
+      ]);
     });
 
     test('for_conditionBegin() handles write captures in the loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(forStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.for_conditionBegin(forStatement);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.for_bodyBegin(_Statement(), _Expression());
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        for_(
+            null,
+            block([
+              x.read.as_('int').stmt,
+              checkNotPromoted(x),
+              localFunction([
+                x.write(expr('int?')).stmt,
+              ]),
+            ]).thenExpr(expr('bool')),
+            null,
+            []),
+      ]);
     });
 
     test('for_conditionBegin() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.for_conditionBegin(forStatement);
-        flow.declare(x, true);
-        flow.for_bodyBegin(_Statement(), _Expression());
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        for_(null, declare(x, initialized: true).thenExpr(expr('bool')), null, [
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('for_bodyBegin() handles empty condition', () {
-      var h = _Harness();
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt, null);
-        flow.for_updaterBegin();
-        expect(flow.isReachable, isTrue);
-        flow.for_end();
-        expect(flow.isReachable, isFalse);
-      });
+      var h = Harness();
+      h.run([
+        for_(null, null, checkReachable(true).thenExpr(expr('Null')), []),
+        checkReachable(false),
+      ]);
     });
 
     test('for_bodyBegin() promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt, h.notNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('for_bodyBegin() can be used with a null statement', () {
       // This is needed for collection elements that are for-loops.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var node = _Node();
-      h.assignedVariables((vars) => vars.nest(node, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.for_conditionBegin(node);
-        flow.for_bodyBegin(null, h.notNull(x, _Type('int?'))());
-        flow.for_updaterBegin();
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [],
+            forCollection: true),
+      ]);
     });
 
     test('for_updaterBegin() joins current and continue states', () {
       // To test that the states are properly joined, we have three variables:
       // x, y, and z.  We promote x and y in the continue path, and x and z in
       // the current path.  Inside the updater, only x should be promoted.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt, h.expr());
-        h.if_(h.expr, () {
-          h.promote(x, 'int');
-          h.promote(y, 'int');
-          flow.handleContinue(stmt);
-        });
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.for_updaterBegin();
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-        flow.for_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        branchTarget((t) => for_(
+                null,
+                expr('bool'),
+                block([
+                  checkPromoted(x, 'int'),
+                  checkNotPromoted(y),
+                  checkNotPromoted(z),
+                ]).thenExpr(expr('Null')),
+                [
+                  if_(expr('bool'), [
+                    x.read.as_('int').stmt,
+                    y.read.as_('int').stmt,
+                    continue_(t),
+                  ]),
+                  x.read.as_('int').stmt,
+                  z.read.as_('int').stmt,
+                ])),
+      ]);
     });
 
     test('for_end() joins break and condition-false states', () {
       // To test that the states are properly joined, we have three variables:
       // x, y, and z.  We promote x and y in the break path, and x and z in the
       // condition-false path.  After the loop, only x should be promoted.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.for_conditionBegin(stmt);
-        flow.for_bodyBegin(stmt,
-            h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))());
-        h.if_(h.expr, () {
-          h.promote(x, 'int');
-          h.promote(y, 'int');
-          flow.handleBreak(stmt);
-        });
-        flow.for_updaterBegin();
-        flow.for_end();
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        branchTarget((t) => for_(
+                null, x.read.eq(nullLiteral).or(z.read.eq(nullLiteral)), null, [
+              if_(expr('bool'), [
+                x.read.as_('int').stmt,
+                y.read.as_('int').stmt,
+                break_(t),
+              ]),
+            ])),
+        checkPromoted(x, 'int'),
+        checkNotPromoted(y),
+        checkNotPromoted(z),
+      ]);
     });
 
     test('forEach_bodyBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.forEach_bodyBegin(forStatement, null, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.write(x, _Type('int?'));
-        flow.forEach_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        forEachWithNonVariable(expr('List<int?>'), [
+          checkNotPromoted(x),
+          x.write(expr('int?')).stmt,
+        ]),
+      ]);
     });
 
     test('forEach_bodyBegin() handles write captures in the loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(forStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.forEach_bodyBegin(forStatement, null, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.forEach_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        forEachWithNonVariable(expr('List<int?>'), [
+          x.read.as_('int').stmt,
+          checkNotPromoted(x),
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+        ]),
+      ]);
     });
 
     test('forEach_bodyBegin() writes to loop variable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: false);
-        expect(flow.isAssigned(x), false);
-        flow.forEach_bodyBegin(forStatement, x, _Type('int?'));
-        expect(flow.isAssigned(x), true);
-        flow.forEach_end();
-        expect(flow.isAssigned(x), false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: false),
+        checkAssigned(x, false),
+        forEachWithVariableSet(x, expr('List<int?>'), [
+          checkAssigned(x, true),
+        ]),
+        checkAssigned(x, false),
+      ]);
     });
 
     test('forEach_bodyBegin() pushes conservative join state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      var forStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(forStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: false);
-        expect(flow.isUnassigned(x), true);
-        flow.forEach_bodyBegin(forStatement, null, _Type('int'));
-        // Since a write to x occurs somewhere in the loop, x should no longer
-        // be considered unassigned.
-        expect(flow.isUnassigned(x), false);
-        flow.handleBreak(forStatement);
-        flow.write(x, _Type('int'));
-        flow.forEach_end();
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: false),
+        checkUnassigned(x, true),
+        branchTarget((t) => forEachWithNonVariable(expr('List<int>'), [
+              // Since a write to x occurs somewhere in the loop, x should no
+              // longer be considered unassigned.
+              checkUnassigned(x, false),
+              break_(t), x.write(expr('int')).stmt,
+            ])),
         // Even though the write to x is unreachable (since it occurs after a
         // break), x should still be considered "possibly assigned" because of
         // the conservative join done at the top of the loop.
-        expect(flow.isUnassigned(x), false);
-      });
+        checkUnassigned(x, false),
+      ]);
     });
 
     test('forEach_end() restores state before loop', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.forEach_bodyBegin(stmt, null, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.forEach_end();
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        forEachWithNonVariable(expr('List<int?>'), [
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ]),
+        checkNotPromoted(x),
+      ]);
     });
 
     test('functionExpression_begin() cancels promotions of self-captured vars',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(functionNode);
-        // x is unpromoted within the local function
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.write(x, _Type('int?'));
-        h.promote(x, 'int');
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        x.read.as_('int').stmt,
+        y.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted within the local function
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          x.write(expr('int?')).stmt, x.read.as_('int').stmt,
+        ]),
         // x is unpromoted after the local function too
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('functionExpression_begin() cancels promotions of other-captured vars',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var functionNode1 = _Node();
-      var functionNode2 = _Node();
-      h.assignedVariables((vars) {
-        vars.function(functionNode1, () {});
-        vars.function(functionNode2, () => vars.write(x));
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(functionNode1);
-        // x is unpromoted within the local function, because the write
-        // might have been captured by the time the local function executes.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        // And any effort to promote x fails, because there is no way of knowing
-        // when the captured write might occur.
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        x.read.as_('int').stmt, y.read.as_('int').stmt,
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted within the local function, because the write
+          // might have been captured by the time the local function executes.
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          // And any effort to promote x fails, because there is no way of
+          // knowing when the captured write might occur.
+          x.read.as_('int').stmt,
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+        ]),
         // x is still promoted after the local function, though, because the
         // write hasn't been captured yet.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(functionNode2);
-        // x is unpromoted inside this local function too.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.write(x, _Type('int?'));
-        flow.functionExpression_end();
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted inside this local function too.
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          x.write(expr('int?')).stmt,
+        ]),
         // And since the second local function captured x, it remains
         // unpromoted.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('functionExpression_begin() cancels promotions of written vars', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var node = _Node();
-      h.assignedVariables((vars) {
-        vars.function(node, () {});
-        vars.write(x);
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_begin(node);
-        // x is unpromoted within the local function, because the write
-        // might have happened by the time the local function executes.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        // But it can be re-promoted because the write isn't captured.
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        x.read.as_('int').stmt, y.read.as_('int').stmt,
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        localFunction([
+          // x is unpromoted within the local function, because the write
+          // might have happened by the time the local function executes.
+          checkNotPromoted(x), checkPromoted(y, 'int'),
+          // But it can be re-promoted because the write isn't captured.
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        ]),
         // x is still promoted after the local function, though, because the
         // write hasn't occurred yet.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.write(x, _Type('int?'));
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+        x.write(expr('int?')).stmt,
         // x is unpromoted now.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('functionExpression_begin() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        flow.functionExpression_begin(functionNode);
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        localFunction([]),
         // x is declared after the local function, so the local function
         // cannot possibly write to x.
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-      });
+        declare(x, initialized: true), x.read.as_('int').stmt,
+        checkPromoted(x, 'int'), x.write(expr('Null')).stmt,
+      ]);
     });
 
     test('functionExpression_begin() handles not-yet-seen write-captured vars',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var functionNode1 = _Node();
-      var functionNode2 = _Node();
-      h.assignedVariables((vars) {
-        vars.function(functionNode1, () {});
-        vars.function(functionNode2, () => vars.write(x));
-      });
-      h.run((flow) {
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.functionExpression_begin(functionNode1);
-        h.promote(x, 'int');
-        // Promotion should not occur, because x might be write-captured by the
-        // time this code is reached.
-        expect(flow.promotedType(x), isNull);
-        flow.functionExpression_end();
-        flow.functionExpression_begin(functionNode2);
-        h.declare(x, initialized: true);
-        flow.functionExpression_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        localFunction([
+          x.read.as_('int').stmt,
+          // Promotion should not occur, because x might be write-captured by
+          // the time this code is reached.
+          checkNotPromoted(x),
+        ]),
+        localFunction([
+          declare(x, initialized: true),
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test(
         'functionExpression_end does not propagate "definitely unassigned" '
         'data', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      var functionNode = _Node();
-      h.assignedVariables((vars) {
-        vars.function(functionNode, () {});
-        vars.write(x);
-      });
-      h.run((flow) {
-        flow.declare(x, false);
-        expect(flow.isUnassigned(x), true);
-        flow.functionExpression_begin(functionNode);
-        // The function expression could be called at any time, so x might be
-        // assigned now.
-        expect(flow.isUnassigned(x), false);
-        flow.functionExpression_end();
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: false),
+        checkUnassigned(x, true),
+        localFunction([
+          // The function expression could be called at any time, so x might
+          // be assigned now.
+          checkUnassigned(x, false),
+        ]),
         // But now that we are back outside the function expression, we once
         // again know that x is unassigned.
-        expect(flow.isUnassigned(x), true);
-        flow.write(x, _Type('int'));
-        expect(flow.isUnassigned(x), false);
-      });
+        checkUnassigned(x, true),
+        x.write(expr('int')).stmt,
+        checkUnassigned(x, false),
+      ]);
     });
 
     test('handleBreak handles deep nesting', () {
-      var h = _Harness();
-      var whileStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(whileStatement, () {});
-      });
-      h.run((flow) {
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.whileStatement_bodyBegin(whileStatement, h.booleanLiteral(true)());
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleBreak(whileStatement);
-          });
-        });
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        flow.whileStatement_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => while_(booleanLiteral(true), [
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  break_(t),
+                ]),
+              ]),
+              return_(),
+              checkReachable(false),
+            ])),
+        checkReachable(true),
+      ]);
     });
 
     test('handleBreak handles mixed nesting', () {
-      var h = _Harness();
-      var whileStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(whileStatement, () {});
-      });
-      h.run((flow) {
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.whileStatement_bodyBegin(whileStatement, h.booleanLiteral(true)());
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleBreak(whileStatement);
-          });
-          flow.handleBreak(whileStatement);
-        });
-        flow.handleBreak(whileStatement);
-        expect(flow.isReachable, false);
-        flow.whileStatement_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => while_(booleanLiteral(true), [
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  break_(t),
+                ]),
+                break_(t),
+              ]),
+              break_(t),
+              checkReachable(false),
+            ])),
+        checkReachable(true),
+      ]);
     });
 
     test('handleContinue handles deep nesting', () {
-      var h = _Harness();
-      var doStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(doStatement, () {});
-      });
-      h.run((flow) {
-        flow.doStatement_bodyBegin(doStatement);
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleContinue(doStatement);
-          });
-        });
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        flow.doStatement_conditionBegin();
-        expect(flow.isReachable, true);
-        flow.doStatement_end(h.booleanLiteral(true)());
-        expect(flow.isReachable, false);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => do_([
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  continue_(t),
+                ]),
+              ]),
+              return_(),
+              checkReachable(false),
+            ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+        checkReachable(false),
+      ]);
     });
 
     test('handleContinue handles mixed nesting', () {
-      var h = _Harness();
-      var doStatement = _Statement();
-      h.assignedVariables((vars) {
-        vars.nest(doStatement, () {});
-      });
-      h.run((flow) {
-        flow.doStatement_bodyBegin(doStatement);
-        h.if_(h.expr, () {
-          h.if_(h.expr, () {
-            flow.handleContinue(doStatement);
-          });
-          flow.handleContinue(doStatement);
-        });
-        flow.handleContinue(doStatement);
-        expect(flow.isReachable, false);
-        flow.doStatement_conditionBegin();
-        expect(flow.isReachable, true);
-        flow.doStatement_end(h.booleanLiteral(true)());
-        expect(flow.isReachable, false);
-      });
+      var h = Harness();
+      h.run([
+        branchTarget((t) => do_([
+              if_(expr('bool'), [
+                if_(expr('bool'), [
+                  continue_(t),
+                ]),
+                continue_(t),
+              ]),
+              continue_(t),
+              checkReachable(false),
+            ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+        checkReachable(false),
+      ]);
     });
 
     test('ifNullExpression allows ensure guarding', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.assignedVariables((vars) => vars.write(x));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifNullExpression_rightBegin(h.variableRead(x)(), _Type('int?'));
-        expect(flow.isReachable, true);
-        flow.write(x, _Type('int'));
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .ifNull(block([
+              checkReachable(true),
+              x.write(expr('int')).stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('int?')))
+            .thenStmt(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression allows promotion of tested var', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifNullExpression_rightBegin(h.variableRead(x)(), _Type('int?'));
-        expect(flow.isReachable, true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .ifNull(block([
+              checkReachable(true),
+              x.read.as_('int').stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('int?')))
+            .thenStmt(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression discards promotions unrelated to tested expr', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifNullExpression_rightBegin(h.expr(), _Type('int?'));
-        expect(flow.isReachable, true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), null);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        expr('int?')
+            .ifNull(block([
+              checkReachable(true),
+              x.read.as_('int').stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('int?')))
+            .thenStmt(block([
+              checkReachable(true),
+              checkNotPromoted(x),
+            ]))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression does not detect when RHS is unreachable', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifNullExpression_rightBegin(h.expr(), _Type('int'));
-        expect(flow.isReachable, true);
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        expr('int')
+            .ifNull(checkReachable(true).thenExpr(expr('int')))
+            .thenStmt(checkReachable(true))
+            .stmt,
+      ]);
     });
 
     test('ifNullExpression determines reachability correctly for `Null` type',
         () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifNullExpression_rightBegin(h.expr(), _Type('Null'));
-        expect(flow.isReachable, true);
-        flow.ifNullExpression_end();
-        expect(flow.isReachable, true);
-      });
+      var h = Harness();
+      h.run([
+        expr('Null')
+            .ifNull(checkReachable(true).thenExpr(expr('Null')))
+            .thenStmt(checkReachable(true))
+            .stmt,
+      ]);
     });
 
     test('ifStatement with early exit promotes in unreachable code', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.handleExit();
-        expect(flow.isReachable, false);
-        flow.ifStatement_conditionBegin();
-        flow.ifStatement_thenBegin(h.eqNull(x, _Type('int?'))());
-        flow.handleExit();
-        flow.ifStatement_end(false);
-        expect(flow.isReachable, false);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        return_(),
+        checkReachable(false),
+        if_(x.read.eq(nullLiteral), [
+          return_(),
+        ]),
+        checkReachable(false),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('ifStatement_end(false) keeps else branch if then branch exits', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        flow.ifStatement_thenBegin(h.eqNull(x, _Type('int?'))());
-        flow.handleExit();
-        flow.ifStatement_end(false);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.eq(nullLiteral), [
+          return_(),
+        ]),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     void _checkIs(String declaredType, String tryPromoteType,
         String expectedPromotedTypeThen, String expectedPromotedTypeElse,
         {bool inverted = false}) {
-      var h = _Harness();
-      var x = h.addVar('x', declaredType);
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        var read = _Expression();
-        flow.variableRead(read, x);
-        var expr = _Expression();
-        flow.isExpression_end(expr, read, inverted, _Type(tryPromoteType));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        if (expectedPromotedTypeThen == null) {
-          expect(flow.promotedType(x), isNull);
-        } else {
-          expect(flow.promotedType(x).type, expectedPromotedTypeThen);
-        }
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        if (expectedPromotedTypeElse == null) {
-          expect(flow.promotedType(x), isNull);
-        } else {
-          expect(flow.promotedType(x).type, expectedPromotedTypeElse);
-        }
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', declaredType);
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.is_(tryPromoteType, isInverted: inverted), [
+          checkReachable(true),
+          checkPromoted(x, expectedPromotedTypeThen),
+        ], [
+          checkReachable(true),
+          checkPromoted(x, expectedPromotedTypeElse),
+        ])
+      ]);
     }
 
     test('isExpression_end promotes to a subtype', () {
@@ -1265,755 +1010,681 @@
     });
 
     test('isExpression_end does nothing if applied to a non-variable', () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var subExpr = _Expression();
-        var expr = _Expression();
-        flow.isExpression_end(expr, subExpr, false, _Type('int'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').is_('int'), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('isExpression_end does nothing if applied to a non-variable, inverted',
         () {
-      var h = _Harness();
-      h.run((flow) {
-        flow.ifStatement_conditionBegin();
-        var subExpr = _Expression();
-        var expr = _Expression();
-        flow.isExpression_end(expr, subExpr, true, _Type('int'));
-        flow.ifStatement_thenBegin(expr);
-        expect(flow.isReachable, true);
-        flow.ifStatement_elseBegin();
-        expect(flow.isReachable, true);
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      h.run([
+        if_(expr('Null').isNot('int'), [
+          checkReachable(true),
+        ], [
+          checkReachable(true),
+        ]),
+      ]);
     });
 
     test('isExpression_end() does not promote write-captured vars', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x), isNull);
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.is_('int'), [
+          checkPromoted(x, 'int'),
+        ]),
+        localFunction([
+          x.write(expr('int?')).stmt,
+        ]),
+        if_(x.read.is_('int'), [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('isExpression_end() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.assignedVariables(
-          (vars) => vars.function(_Node(), () => vars.write(x)));
-      h.run((flow) {
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-        h.declare(x, initialized: true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        if_(x.read.is_('int'), [
+          checkPromoted(x, 'int'),
+        ]),
+        declare(x, initialized: true),
+        localFunction([
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('labeledBlock without break', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var block = _Statement();
-      h.run((flow) {
-        h.declare(x, initialized: true);
-
-        h.ifIsNotType(x, 'int', () {
-          h.labeledBlock(block, () {
-            flow.handleExit();
-          });
-        });
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.isNot('int'), [
+          labeled(return_()),
+        ]),
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('labeledBlock with break joins', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var block = _Statement();
-      h.run((flow) {
-        h.declare(x, initialized: true);
-
-        h.ifIsNotType(x, 'int', () {
-          h.labeledBlock(block, () {
-            h.if_(h.expr, () {
-              flow.handleBreak(block);
-            });
-            flow.handleExit();
-          });
-        });
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(x.read.isNot('int'), [
+          branchTarget((t) => labeled(block([
+                if_(expr('bool'), [
+                  break_(t),
+                ]),
+                return_(),
+              ]))),
+        ]),
+        checkNotPromoted(x),
+      ]);
     });
 
     test('logicalBinaryOp_rightBegin(isAnd: true) promotes in RHS', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(h.notNull(x, _Type('int?'))(),
-            isAnd: true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .notEq(nullLiteral)
+            .and(checkPromoted(x, 'int').thenExpr(expr('bool')))
+            .stmt,
+      ]);
     });
 
     test('logicalBinaryOp_rightEnd(isAnd: true) keeps promotions from RHS', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: true);
-        var wholeExpr = _Expression();
-        flow.logicalBinaryOp_end(wholeExpr, h.notNull(x, _Type('int?'))(),
-            isAnd: true);
-        flow.ifStatement_thenBegin(wholeExpr);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('bool').and(x.read.notEq(nullLiteral)), [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('logicalBinaryOp_rightEnd(isAnd: false) keeps promotions from RHS',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.ifStatement_conditionBegin();
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: false);
-        var wholeExpr = _Expression();
-        flow.logicalBinaryOp_end(wholeExpr, h.eqNull(x, _Type('int?'))(),
-            isAnd: false);
-        flow.ifStatement_thenBegin(wholeExpr);
-        flow.ifStatement_elseBegin();
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('bool').or(x.read.eq(nullLiteral)), [], [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('logicalBinaryOp_rightBegin(isAnd: false) promotes in RHS', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.logicalBinaryOp_begin();
-        flow.logicalBinaryOp_rightBegin(h.eqNull(x, _Type('int?'))(),
-            isAnd: false);
-        expect(flow.promotedType(x).type, 'int');
-        flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .eq(nullLiteral)
+            .or(checkPromoted(x, 'int').thenExpr(expr('bool')))
+            .stmt,
+      ]);
     });
 
     test('logicalBinaryOp(isAnd: true) joins promotions', () {
       // if (x != null && y != null) {
       //   promotes x and y
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.if_(h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?'))),
-            () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y).type, 'int');
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        if_(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)), [
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ]),
+      ]);
     });
 
     test('logicalBinaryOp(isAnd: false) joins promotions', () {
       // if (x == null || y == null) {} else {
       //   promotes x and y
       // }
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.ifElse(
-            h.or(h.eqNull(x, _Type('int?')), h.eqNull(y, _Type('int?'))), () {},
-            () {
-          expect(flow.promotedType(x).type, 'int');
-          expect(flow.promotedType(y).type, 'int');
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        if_(x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)), [], [
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ]),
+      ]);
     });
 
     test('nonNullAssert_end(x) promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.nonNullAssert_end(varExpr);
-        expect(flow.promotedType(x).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.nonNullAssert.stmt,
+        checkPromoted(x, 'int'),
+      ]);
     });
 
     test('nullAwareAccess temporarily promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.nullAwareAccess_rightBegin(varExpr, _Type('int?'));
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.nullAwareAccess_end();
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .nullAwareAccess(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('Null')))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('nullAwareAccess does not promote the target of a cascade', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        var varExpr = _Expression();
-        flow.variableRead(varExpr, x);
-        flow.nullAwareAccess_rightBegin(null, _Type('int?'));
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x), isNull);
-        flow.nullAwareAccess_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read
+            .nullAwareAccess(
+                block([
+                  checkReachable(true),
+                  checkNotPromoted(x),
+                ]).thenExpr(expr('Null')),
+                isCascaded: true)
+            .stmt,
+      ]);
     });
 
     test('nullAwareAccess preserves demotions', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.assignedVariables((vars) => vars.write(x));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        var lhs = _Expression();
-        flow.nullAwareAccess_rightBegin(lhs, _Type('int'));
-        expect(flow.isReachable, true);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.nullAwareAccess_end();
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        expr('int')
+            .nullAwareAccess(block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]).thenExpr(x.write(expr('int?'))).thenStmt(checkNotPromoted(x)))
+            .stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('nullAwareAccess_end ignores shorting if target is non-nullable', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.nullAwareAccess_rightBegin(_Expression(), _Type('int'));
-        expect(flow.isReachable, true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.nullAwareAccess_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        expr('int')
+            .nullAwareAccess(block([
+              checkReachable(true),
+              x.read.as_('int').stmt,
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('Null')))
+            .stmt,
         // Since the null-shorting path was reachable, promotion of `x` should
         // be cancelled.
-        expect(flow.promotedType(x), isNull);
-      });
+        checkNotPromoted(x),
+      ]);
     });
 
     test('parenthesizedExpression preserves promotion behaviors', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      h.run((flow) {
-        h.if_(
-            h.parenthesized(h.notEqual(
-                h.parenthesized(h.variableRead(x)),
-                _Type('int?'),
-                h.parenthesized(h.nullLiteral),
-                _Type('Null'))), () {
-          expect(flow.promotedType(x).type, 'int');
-        });
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        if_(
+            x.read.parenthesized.notEq(nullLiteral.parenthesized).parenthesized,
+            [
+              checkPromoted(x, 'int'),
+            ]),
+      ]);
     });
 
     test('promote promotes to a subtype and sets type of interest', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'num?');
-      h.assignedVariables((vars) {
-        vars.write(x);
-      });
-      h.run((flow) {
-        flow.declare(x, true);
-        expect(flow.promotedType(x), isNull);
-        flow.promote(x, _Type('num'));
-        expect(flow.promotedType(x).type, 'num');
+      var h = Harness();
+      var x = Var('x', 'num?');
+      h.run([
+        declare(x, initialized: true),
+        checkNotPromoted(x),
+        x.read.as_('num').stmt,
+        checkPromoted(x, 'num'),
         // Check that it's a type of interest by promoting and de-promoting.
-        h.if_(h.isType(h.variableRead(x), 'int'), () {
-          expect(flow.promotedType(x).type, 'int');
-          flow.write(x, _Type('num'));
-          expect(flow.promotedType(x).type, 'num');
-        });
-      });
+        if_(x.read.is_('int'), [
+          checkPromoted(x, 'int'),
+          x.write(expr('num')).stmt,
+          checkPromoted(x, 'num'),
+        ]),
+      ]);
     });
 
     test('promote does not promote to a non-subtype', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'num?');
-      h.run((flow) {
-        flow.declare(x, true);
-        expect(flow.promotedType(x), isNull);
-        flow.promote(x, _Type('String'));
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'num?');
+      h.run([
+        declare(x, initialized: true),
+        checkNotPromoted(x),
+        x.read.as_('String').stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('promote does not promote if variable is write-captured', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'num?');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        flow.declare(x, true);
-        expect(flow.promotedType(x), isNull);
-        flow.functionExpression_begin(functionNode);
-        flow.write(x, _Type('num'));
-        flow.functionExpression_end();
-        flow.promote(x, _Type('num'));
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'num?');
+      h.run([
+        declare(x, initialized: true),
+        checkNotPromoted(x),
+        localFunction([
+          x.write(expr('num')).stmt,
+        ]),
+        x.read.as_('num').stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('promotedType handles not-yet-seen variables', () {
       // Note: this is needed for error recovery in the analyzer.
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      h.run((flow) {
-        expect(flow.promotedType(x), isNull);
-        h.declare(x, initialized: true);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        checkNotPromoted(x),
+        declare(x, initialized: true),
+      ]);
     });
 
     test('switchStatement_beginCase(false) restores previous promotions', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkPromoted(x, 'int'),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ]),
+              case_([
+                checkPromoted(x, 'int'),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ]),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(false) does not un-promote', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkPromoted(x, 'int'),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ])
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(false) handles write captures in cases',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(switchStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(false, switchStatement);
-        expect(flow.promotedType(x).type, 'int');
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkPromoted(x, 'int'),
+                localFunction([
+                  x.write(expr('int?')).stmt,
+                ]),
+                checkNotPromoted(x),
+              ]),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(true) un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(true, switchStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.write(x, _Type('int?'));
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                checkNotPromoted(x),
+                x.write(expr('int?')).stmt,
+                checkNotPromoted(x),
+              ], hasLabel: true),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_beginCase(true) handles write captures in cases', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var switchStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(switchStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        flow.switchStatement_expressionEnd(_Statement());
-        flow.switchStatement_beginCase(true, switchStatement);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        expect(flow.promotedType(x), isNull);
-        flow.switchStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        switch_(
+            expr('Null'),
+            [
+              case_([
+                x.read.as_('int').stmt,
+                checkNotPromoted(x),
+                localFunction([
+                  x.write(expr('int?')).stmt,
+                ]),
+                checkNotPromoted(x),
+              ], hasLabel: true),
+            ],
+            isExhaustive: false),
+      ]);
     });
 
     test('switchStatement_end(false) joins break and default', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(switchStatement, () => vars.write(y)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.promote(y, 'int');
-        h.promote(z, 'int');
-        var stmt = _Statement();
-        flow.switchStatement_expressionEnd(stmt);
-        flow.switchStatement_beginCase(false, switchStatement);
-        h.promote(x, 'int');
-        flow.write(y, _Type('int?'));
-        flow.handleBreak(stmt);
-        flow.switchStatement_end(false);
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z).type, 'int');
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        y.read.as_('int').stmt,
+        z.read.as_('int').stmt,
+        branchTarget((t) => switch_(
+            expr('Null'),
+            [
+              case_([
+                x.read.as_('int').stmt,
+                y.write(expr('int?')).stmt,
+                break_(t),
+              ]),
+            ],
+            isExhaustive: false)),
+        checkNotPromoted(x),
+        checkNotPromoted(y),
+        checkPromoted(z, 'int'),
+      ]);
     });
 
     test('switchStatement_end(true) joins breaks', () {
-      var h = _Harness();
-      var w = h.addVar('w', 'int?');
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var switchStatement = _Statement();
-      h.assignedVariables((vars) => vars.nest(switchStatement, () {
-            vars.write(x);
-            vars.write(y);
-          }));
-      h.run((flow) {
-        h.declare(w, initialized: true);
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        h.promote(z, 'int');
-        var stmt = _Statement();
-        flow.switchStatement_expressionEnd(stmt);
-        flow.switchStatement_beginCase(false, switchStatement);
-        h.promote(w, 'int');
-        h.promote(y, 'int');
-        flow.write(x, _Type('int?'));
-        flow.handleBreak(stmt);
-        flow.switchStatement_beginCase(false, switchStatement);
-        h.promote(w, 'int');
-        h.promote(x, 'int');
-        flow.write(y, _Type('int?'));
-        flow.handleBreak(stmt);
-        flow.switchStatement_end(true);
-        expect(flow.promotedType(w).type, 'int');
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z).type, 'int');
-      });
+      var h = Harness();
+      var w = Var('w', 'int?');
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(w, initialized: true),
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        x.read.as_('int').stmt,
+        y.read.as_('int').stmt,
+        z.read.as_('int').stmt,
+        branchTarget((t) => switch_(
+            expr('Null'),
+            [
+              case_([
+                w.read.as_('int').stmt,
+                y.read.as_('int').stmt,
+                x.write(expr('int?')).stmt,
+                break_(t),
+              ]),
+              case_([
+                w.read.as_('int').stmt,
+                x.read.as_('int').stmt,
+                y.write(expr('int?')).stmt,
+                break_(t),
+              ]),
+            ],
+            isExhaustive: true)),
+        checkPromoted(w, 'int'),
+        checkNotPromoted(x),
+        checkNotPromoted(y),
+        checkPromoted(z, 'int'),
+      ]);
     });
 
     test('switchStatement_end(true) allows fall-through of last case', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.switchStatement_expressionEnd(stmt);
-        flow.switchStatement_beginCase(false, stmt);
-        h.promote(x, 'int');
-        flow.handleBreak(stmt);
-        flow.switchStatement_beginCase(false, stmt);
-        flow.switchStatement_end(true);
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        branchTarget((t) => switch_(
+            expr('Null'),
+            [
+              case_([
+                x.read.as_('int').stmt,
+                break_(t),
+              ]),
+              case_([]),
+            ],
+            isExhaustive: true)),
+        checkNotPromoted(x),
+      ]);
     });
 
     test('tryCatchStatement_bodyEnd() restores pre-try state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.tryCatchStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        tryCatch([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ], [
+          catch_(body: [
+            checkNotPromoted(x),
+            checkPromoted(y, 'int'),
+          ])
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_bodyEnd() un-promotes variables assigned in body',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Statement();
-      h.assignedVariables((vars) => vars.nest(body, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_bodyBegin();
-        flow.write(x, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_bodyEnd(body);
-        flow.tryCatchStatement_catchBegin(null, null);
-        expect(flow.promotedType(x), isNull);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        tryCatch([
+          x.write(expr('int?')).stmt,
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          catch_(body: [
+            checkNotPromoted(x),
+          ]),
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_bodyEnd() preserves write captures in body', () {
       // Note: it's not necessary for the write capture to survive to the end of
       // the try body, because an exception could occur at any time.  We check
       // this by putting an exit in the try body.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(
-          body, () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_bodyBegin();
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.handleExit();
-        flow.tryCatchStatement_bodyEnd(body);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        tryCatch([
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+          return_(),
+        ], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            checkNotPromoted(x),
+          ])
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_catchBegin() restores previous post-body state',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.tryCatchStatement_bodyBegin();
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_catchBegin(null, null);
-        expect(flow.promotedType(x), isNull);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        tryCatch([], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            checkPromoted(x, 'int'),
+          ]),
+          catch_(body: [
+            checkNotPromoted(x),
+          ]),
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_catchBegin() initializes vars', () {
-      var h = _Harness();
-      var e = h.addVar('e', 'int');
-      var st = h.addVar('st', 'StackTrace');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        flow.tryCatchStatement_bodyBegin();
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(e, st);
-        expect(flow.isAssigned(e), true);
-        expect(flow.isAssigned(st), true);
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
-      });
+      var h = Harness();
+      var e = Var('e', 'int');
+      var st = Var('st', 'StackTrace');
+      h.run([
+        tryCatch([], [
+          catch_(exception: e, stackTrace: st, body: [
+            checkAssigned(e, true),
+            checkAssigned(st, true),
+          ]),
+        ]),
+      ]);
     });
 
     test('tryCatchStatement_catchEnd() joins catch state with after-try state',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.tryCatchStatement_bodyBegin();
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        declare(z, initialized: true),
+        tryCatch([
+          x.read.as_('int').stmt,
+          y.read.as_('int').stmt,
+        ], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            z.read.as_('int').stmt,
+          ]),
+        ]),
         // 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);
-      });
+        checkPromoted(x, 'int'), checkNotPromoted(y), checkNotPromoted(z),
+      ]);
     });
 
     test('tryCatchStatement_catchEnd() joins catch states', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.tryCatchStatement_bodyBegin();
-        flow.handleExit();
-        flow.tryCatchStatement_bodyEnd(stmt);
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        h.promote(y, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_catchBegin(null, null);
-        h.promote(x, 'int');
-        h.promote(z, 'int');
-        flow.tryCatchStatement_catchEnd();
-        flow.tryCatchStatement_end();
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        declare(z, initialized: true),
+        tryCatch([
+          return_(),
+        ], [
+          catch_(body: [
+            x.read.as_('int').stmt,
+            y.read.as_('int').stmt,
+          ]),
+          catch_(body: [
+            x.read.as_('int').stmt,
+            z.read.as_('int').stmt,
+          ]),
+        ]),
         // Only x should be promoted, because it's the only variable promoted
         // in both catch handlers.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+        checkPromoted(x, 'int'), checkNotPromoted(y), checkNotPromoted(z),
+      ]);
     });
 
     test('tryFinallyStatement_finallyBegin() restores pre-try state', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var body = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) {
-        vars.nest(body, () {});
-        vars.nest(finallyBlock, () {});
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.tryFinallyStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_end(finallyBlock);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        tryFinally([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+          checkPromoted(y, 'int'),
+        ], [
+          checkNotPromoted(x),
+          checkPromoted(y, 'int'),
+        ]),
+      ]);
     });
 
     test(
         'tryFinallyStatement_finallyBegin() un-promotes variables assigned in '
         'body', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) {
-        vars.nest(body, () => vars.write(x));
-        vars.nest(finallyBlock, () {});
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_bodyBegin();
-        flow.write(x, _Type('int?'));
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        flow.tryFinallyStatement_end(finallyBlock);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        tryFinally([
+          x.write(expr('int?')).stmt,
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('tryFinallyStatement_finallyBegin() preserves write captures in body',
@@ -2021,262 +1692,206 @@
       // Note: it's not necessary for the write capture to survive to the end of
       // the try body, because an exception could occur at any time.  We check
       // this by putting an exit in the try body.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var body = _Statement();
-      var functionNode = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) => vars.nest(body, () {
-            vars.function(functionNode, () => vars.write(x));
-            vars.nest(finallyBlock, () {});
-          }));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.tryFinallyStatement_bodyBegin();
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.handleExit();
-        flow.tryFinallyStatement_finallyBegin(body);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        flow.tryFinallyStatement_end(finallyBlock);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        tryFinally([
+          localFunction([
+            x.write(expr('int?')).stmt,
+          ]),
+          return_(),
+        ], [
+          x.read.as_('int').stmt,
+          checkNotPromoted(x),
+        ]),
+      ]);
     });
 
     test('tryFinallyStatement_end() restores promotions from try body', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var body = _Statement();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) => vars.nest(body, () {
-            vars.nest(body, () {});
-            vars.nest(finallyBlock, () {});
-          }));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        flow.tryFinallyStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        h.promote(y, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_end(finallyBlock);
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        tryFinally([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+          y.read.as_('int').stmt,
+          checkPromoted(y, 'int'),
+        ]),
         // Both x and y should now be promoted.
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+      ]);
     });
 
     test(
         'tryFinallyStatement_end() does not restore try body promotions for '
         'variables assigned in finally', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var body = _Node();
-      var finallyBlock = _Node();
-      h.assignedVariables((vars) {
-        vars.nest(body, () {});
-        vars.nest(finallyBlock, () {
-          vars.write(x);
-          vars.write(y);
-        });
-      });
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        flow.tryFinallyStatement_bodyBegin();
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.tryFinallyStatement_finallyBegin(body);
-        expect(flow.promotedType(x), isNull);
-        flow.write(x, _Type('int?'));
-        flow.write(y, _Type('int?'));
-        h.promote(y, 'int');
-        expect(flow.promotedType(y).type, 'int');
-        flow.tryFinallyStatement_end(finallyBlock);
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(x, initialized: true), declare(y, initialized: true),
+        tryFinally([
+          x.read.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ], [
+          checkNotPromoted(x),
+          x.write(expr('int?')).stmt,
+          y.write(expr('int?')).stmt,
+          y.read.as_('int').stmt,
+          checkPromoted(y, 'int'),
+        ]),
         // x should not be re-promoted, because it might have been assigned a
         // non-promoted value in the "finally" block.  But y's promotion still
         // stands, because y was promoted in the finally block.
-        expect(flow.promotedType(x), isNull);
-        expect(flow.promotedType(y).type, 'int');
-      });
+        checkNotPromoted(x), checkPromoted(y, 'int'),
+      ]);
     });
 
     test('whileStatement_conditionBegin() un-promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var whileStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(whileStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.whileStatement_conditionBegin(whileStatement);
-        expect(flow.promotedType(x), isNull);
-        flow.whileStatement_bodyBegin(_Statement(), _Expression());
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        while_(checkNotPromoted(x).thenExpr(expr('bool')), [
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('whileStatement_conditionBegin() handles write captures in the loop',
         () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var whileStatement = _Statement();
-      var functionNode = _Node();
-      h.assignedVariables((vars) => vars.nest(whileStatement,
-          () => vars.function(functionNode, () => vars.write(x))));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        flow.whileStatement_conditionBegin(whileStatement);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-        h.function(functionNode, () {
-          flow.write(x, _Type('int?'));
-        });
-        flow.whileStatement_bodyBegin(_Statement(), _Expression());
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        while_(
+            block([
+              x.read.as_('int').stmt,
+              checkNotPromoted(x),
+              localFunction([
+                x.write(expr('int?')).stmt,
+              ]),
+            ]).thenExpr(expr('bool')),
+            []),
+      ]);
     });
 
     test('whileStatement_conditionBegin() handles not-yet-seen variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var whileStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(whileStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(y, initialized: true);
-        h.promote(y, 'int');
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.declare(x, true);
-        flow.whileStatement_bodyBegin(_Statement(), _Expression());
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      h.run([
+        declare(y, initialized: true),
+        y.read.as_('int').stmt,
+        while_(declare(x, initialized: true).thenExpr(expr('bool')), [
+          x.write(expr('Null')).stmt,
+        ]),
+      ]);
     });
 
     test('whileStatement_bodyBegin() promotes', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        flow.whileStatement_conditionBegin(stmt);
-        flow.whileStatement_bodyBegin(stmt, h.notNull(x, _Type('int?'))());
-        expect(flow.promotedType(x).type, 'int');
-        flow.whileStatement_end();
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        while_(x.read.notEq(nullLiteral), [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('whileStatement_end() joins break and condition-false states', () {
       // To test that the states are properly joined, we have three variables:
       // x, y, and z.  We promote x and y in the break path, and x and z in the
       // condition-false path.  After the loop, only x should be promoted.
-      var h = _Harness();
-      var x = h.addVar('x', 'int?');
-      var y = h.addVar('y', 'int?');
-      var z = h.addVar('z', 'int?');
-      var stmt = _Statement();
-      h.assignedVariables((vars) => vars.nest(stmt, () {}));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.declare(y, initialized: true);
-        h.declare(z, initialized: true);
-        flow.whileStatement_conditionBegin(stmt);
-        flow.whileStatement_bodyBegin(stmt,
-            h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))());
-        h.if_(h.expr, () {
-          h.promote(x, 'int');
-          h.promote(y, 'int');
-          flow.handleBreak(stmt);
-        });
-        flow.whileStatement_end();
-        expect(flow.promotedType(x).type, 'int');
-        expect(flow.promotedType(y), isNull);
-        expect(flow.promotedType(z), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
+      h.run([
+        declare(x, initialized: true),
+        declare(y, initialized: true),
+        declare(z, initialized: true),
+        branchTarget(
+            (t) => while_(x.read.eq(nullLiteral).or(z.read.eq(nullLiteral)), [
+                  if_(expr('bool'), [
+                    x.read.as_('int').stmt,
+                    y.read.as_('int').stmt,
+                    break_(t),
+                  ]),
+                ])),
+        checkPromoted(x, 'int'),
+        checkNotPromoted(y),
+        checkNotPromoted(z),
+      ]);
     });
 
     test('Infinite loop does not implicitly assign variables', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'int');
-      var whileStatement = _Statement();
-      h.assignedVariables(
-          (vars) => vars.nest(whileStatement, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: false);
-        var trueCondition = _Expression();
-        flow.whileStatement_conditionBegin(whileStatement);
-        flow.booleanLiteral(trueCondition, true);
-        flow.whileStatement_bodyBegin(whileStatement, trueCondition);
-        flow.whileStatement_end();
-        expect(flow.isAssigned(x), false);
-      });
+      var h = Harness();
+      var x = Var('x', 'int');
+      h.run([
+        declare(x, initialized: false),
+        while_(booleanLiteral(true), [
+          x.write(expr('Null')).stmt,
+        ]),
+        checkAssigned(x, false),
+      ]);
     });
 
     test('If(false) does not discard promotions', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'Object');
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.promote(x, 'int');
-        expect(flow.promotedType(x).type, 'int');
-        // if (false) {
-        flow.ifStatement_conditionBegin();
-        var falseExpression = _Expression();
-        flow.booleanLiteral(falseExpression, false);
-        flow.ifStatement_thenBegin(falseExpression);
-        expect(flow.promotedType(x).type, 'int');
-        flow.ifStatement_end(false);
-      });
+      var h = Harness();
+      var x = Var('x', 'Object');
+      h.run([
+        declare(x, initialized: true),
+        x.read.as_('int').stmt,
+        checkPromoted(x, 'int'),
+        if_(booleanLiteral(false), [
+          checkPromoted(x, 'int'),
+        ]),
+      ]);
     });
 
     test('Promotions do not occur when a variable is write-captured', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'Object');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.function(functionNode, () {});
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-      });
+      var h = Harness();
+      var x = Var('x', 'Object');
+      h.run([
+        declare(x, initialized: true),
+        localFunction([
+          x.write(expr('Object')).stmt,
+        ]),
+        x.read.as_('int').stmt,
+        checkNotPromoted(x),
+      ]);
     });
 
     test('Promotion cancellation of write-captured vars survives join', () {
-      var h = _Harness();
-      var x = h.addVar('x', 'Object');
-      var functionNode = _Node();
-      h.assignedVariables(
-          (vars) => vars.function(functionNode, () => vars.write(x)));
-      h.run((flow) {
-        h.declare(x, initialized: true);
-        h.ifElse(h.expr, () {
-          h.function(functionNode, () {});
-        }, () {
+      var h = Harness();
+      var x = Var('x', 'Object');
+      h.run([
+        declare(x, initialized: true),
+        if_(expr('bool'), [
+          localFunction([
+            x.write(expr('Object')).stmt,
+          ]),
+        ], [
           // Promotion should work here because the write capture is in the
           // other branch.
-          h.promote(x, 'int');
-          expect(flow.promotedType(x).type, 'int');
-        });
+          x.read.as_('int').stmt, checkPromoted(x, 'int'),
+        ]),
         // But the promotion should be cancelled now, after the join.
-        expect(flow.promotedType(x), isNull);
+        checkNotPromoted(x),
         // And further attempts to promote should fail due to the write capture.
-        h.promote(x, 'int');
-        expect(flow.promotedType(x), isNull);
-      });
+        x.read.as_('int').stmt, checkNotPromoted(x),
+      ]);
     });
   });
 
@@ -2362,20 +1977,20 @@
   });
 
   group('State', () {
-    var intVar = _Var('x', _Type('int'));
-    var intQVar = _Var('x', _Type('int?'));
-    var objectQVar = _Var('x', _Type('Object?'));
-    var nullVar = _Var('x', _Type('Null'));
+    var intVar = Var('x', 'int');
+    var intQVar = Var('x', 'int?');
+    var objectQVar = Var('x', 'Object?');
+    var nullVar = Var('x', 'Null');
     group('setUnreachable', () {
       var unreachable =
-          FlowModel<_Var, _Type>(Reachability.initial.setUnreachable());
-      var reachable = FlowModel<_Var, _Type>(Reachability.initial);
+          FlowModel<Var, Type>(Reachability.initial.setUnreachable());
+      var reachable = FlowModel<Var, Type>(Reachability.initial);
       test('unchanged', () {
         expect(unreachable.setUnreachable(), same(unreachable));
       });
 
       test('changed', () {
-        void _check(FlowModel<_Var, _Type> initial) {
+        void _check(FlowModel<Var, Type> initial) {
           var s = initial.setUnreachable();
           expect(s, isNot(same(initial)));
           expect(s.reachable.overallReachable, false);
@@ -2387,33 +2002,33 @@
     });
 
     test('split', () {
-      var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+      var s1 = FlowModel<Var, Type>(Reachability.initial);
       var s2 = s1.split();
       expect(s2.reachable.parent, same(s1.reachable));
     });
 
     test('unsplit', () {
-      var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+      var s1 = FlowModel<Var, Type>(Reachability.initial.split());
       var s2 = s1.unsplit();
       expect(s2.reachable, same(Reachability.initial));
     });
 
     group('unsplitTo', () {
       test('no change', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var result = s1.unsplitTo(s1.reachable.parent);
         expect(result, same(s1));
       });
 
       test('unsplit once, reachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split();
         var result = s2.unsplitTo(s1.reachable.parent);
         expect(result.reachable, same(s1.reachable));
       });
 
       test('unsplit once, unreachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split().setUnreachable();
         var result = s2.unsplitTo(s1.reachable.parent);
         expect(result.reachable.locallyReachable, false);
@@ -2421,7 +2036,7 @@
       });
 
       test('unsplit twice, reachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split();
         var s3 = s2.split();
         var result = s3.unsplitTo(s1.reachable.parent);
@@ -2429,7 +2044,7 @@
       });
 
       test('unsplit twice, top unreachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split();
         var s3 = s2.split().setUnreachable();
         var result = s3.unsplitTo(s1.reachable.parent);
@@ -2438,7 +2053,7 @@
       });
 
       test('unsplit twice, previous unreachable', () {
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+        var s1 = FlowModel<Var, Type>(Reachability.initial.split());
         var s2 = s1.split().setUnreachable();
         var s3 = s2.split();
         var result = s3.unsplitTo(s1.reachable.parent);
@@ -2449,30 +2064,30 @@
 
     group('tryPromoteForTypeCheck', () {
       test('unpromoted -> unchanged (same)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('int')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('int')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (supertype)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('Object')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('Object')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (unrelated)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('String')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('String')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> subtype', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
-        var s2 = s1.tryPromoteForTypeCheck(h, intQVar, _Type('int')).ifTrue;
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
+        var s2 = s1.tryPromoteForTypeCheck(h, intQVar, Type('int')).ifTrue;
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           intQVar: _matchVariableModel(chain: ['int'], ofInterest: ['int'])
@@ -2480,40 +2095,40 @@
       });
 
       test('promoted -> unchanged (same)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
-        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, Type('int')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (supertype)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 =
-            s1.tryPromoteForTypeCheck(h, objectQVar, _Type('Object')).ifTrue;
+            s1.tryPromoteForTypeCheck(h, objectQVar, Type('Object')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (unrelated)', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 =
-            s1.tryPromoteForTypeCheck(h, objectQVar, _Type('String')).ifTrue;
+            s1.tryPromoteForTypeCheck(h, objectQVar, Type('String')).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> subtype', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
             .ifTrue;
-        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
+        var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, Type('int')).ifTrue;
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2523,29 +2138,29 @@
     });
 
     group('write', () {
-      var objectQVar = _Var('x', _Type('Object?'));
+      var objectQVar = Var('x', 'Object?');
 
       test('without declaration', () {
         // This should not happen in valid code, but test that we don't crash.
-        var h = _Harness();
-        var s = FlowModel<_Var, _Type>(Reachability.initial)
-            .write(objectQVar, _Type('Object?'), h);
+        var h = Harness();
+        var s = FlowModel<Var, Type>(Reachability.initial)
+            .write(objectQVar, Type('Object?'), h);
         expect(s.variableInfo[objectQVar], isNull);
       });
 
       test('unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true);
-        var s2 = s1.write(objectQVar, _Type('Object?'), h);
+        var s2 = s1.write(objectQVar, Type('Object?'), h);
         expect(s2, same(s1));
       });
 
       test('marks as assigned', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, false);
-        var s2 = s1.write(objectQVar, _Type('int?'), h);
+        var s2 = s1.write(objectQVar, Type('int?'), h);
         expect(s2.reachable.overallReachable, true);
         expect(
             s2.infoFor(objectQVar),
@@ -2557,13 +2172,13 @@
       });
 
       test('un-promotes fully', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         expect(s1.variableInfo, contains(objectQVar));
-        var s2 = s1.write(objectQVar, _Type('int?'), h);
+        var s2 = s1.write(objectQVar, Type('int?'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2575,12 +2190,12 @@
       });
 
       test('un-promotes partially, when no exact match', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2589,7 +2204,7 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('num'), h);
+        var s2 = s1.write(objectQVar, Type('num'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2601,14 +2216,14 @@
       });
 
       test('un-promotes partially, when exact match', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2617,7 +2232,7 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('num'), h);
+        var s2 = s1.write(objectQVar, Type('num'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2629,12 +2244,12 @@
       });
 
       test('leaves promoted, when exact match', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2643,18 +2258,18 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('num'), h);
+        var s2 = s1.write(objectQVar, Type('num'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, same(s1.variableInfo));
       });
 
       test('leaves promoted, when writing a subtype', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
             .ifTrue;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2663,34 +2278,32 @@
               assigned: true,
               unassigned: false)
         });
-        var s2 = s1.write(objectQVar, _Type('int'), h);
+        var s2 = s1.write(objectQVar, Type('int'), h);
         expect(s2.reachable.overallReachable, true);
         expect(s2.variableInfo, same(s1.variableInfo));
       });
 
       group('Promotes to NonNull of a type of interest', () {
         test('when declared type', () {
-          var h = _Harness();
-          var x = _Var('x', _Type('int?'));
+          var h = Harness();
+          var x = Var('x', 'int?');
 
-          var s1 =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+          var s1 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           expect(s1.variableInfo, {
             x: _matchVariableModel(chain: null),
           });
 
-          var s2 = s1.write(x, _Type('int'), h);
+          var s2 = s1.write(x, Type('int'), h);
           expect(s2.variableInfo, {
             x: _matchVariableModel(chain: ['int']),
           });
         });
 
         test('when declared type, if write-captured', () {
-          var h = _Harness();
-          var x = h.addVar('x', 'int?');
+          var h = Harness();
+          var x = Var('x', 'int?');
 
-          var s1 =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+          var s1 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           expect(s1.variableInfo, {
             x: _matchVariableModel(chain: null),
           });
@@ -2701,17 +2314,17 @@
           });
 
           // 'x' is write-captured, so not promoted
-          var s3 = s2.write(x, _Type('int'), h);
+          var s3 = s2.write(x, Type('int'), h);
           expect(s3.variableInfo, {
             x: _matchVariableModel(chain: null, writeCaptured: true),
           });
         });
 
         test('when promoted', () {
-          var h = _Harness();
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var h = Harness();
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(objectQVar, true)
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
               .ifTrue;
           expect(s1.variableInfo, {
             objectQVar: _matchVariableModel(
@@ -2719,7 +2332,7 @@
               ofInterest: ['int?'],
             ),
           });
-          var s2 = s1.write(objectQVar, _Type('int'), h);
+          var s2 = s1.write(objectQVar, Type('int'), h);
           expect(s2.variableInfo, {
             objectQVar: _matchVariableModel(
               chain: ['int?', 'int'],
@@ -2729,10 +2342,10 @@
         });
 
         test('when not promoted', () {
-          var h = _Harness();
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var h = Harness();
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(objectQVar, true)
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
               .ifFalse;
           expect(s1.variableInfo, {
             objectQVar: _matchVariableModel(
@@ -2740,7 +2353,7 @@
               ofInterest: ['int?'],
             ),
           });
-          var s2 = s1.write(objectQVar, _Type('int'), h);
+          var s2 = s1.write(objectQVar, Type('int'), h);
           expect(s2.variableInfo, {
             objectQVar: _matchVariableModel(
               chain: ['Object', 'int'],
@@ -2751,10 +2364,10 @@
       });
 
       test('Promotes to type of interest when not previously promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifFalse;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2762,7 +2375,7 @@
             ofInterest: ['num?'],
           ),
         });
-        var s2 = s1.write(objectQVar, _Type('num?'), h);
+        var s2 = s1.write(objectQVar, Type('num?'), h);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
             chain: ['num?'],
@@ -2772,12 +2385,12 @@
       });
 
       test('Promotes to type of interest when previously promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
             .ifFalse;
         expect(s1.variableInfo, {
           objectQVar: _matchVariableModel(
@@ -2785,7 +2398,7 @@
             ofInterest: ['num?', 'int?'],
           ),
         });
-        var s2 = s1.write(objectQVar, _Type('int?'), h);
+        var s2 = s1.write(objectQVar, Type('int?'), h);
         expect(s2.variableInfo, {
           objectQVar: _matchVariableModel(
             chain: ['num?', 'int?'],
@@ -2796,56 +2409,56 @@
 
       group('Multiple candidate types of interest', () {
         group('; choose most specific', () {
-          _Harness h;
+          Harness h;
 
           setUp(() {
-            h = _Harness();
+            h = Harness();
 
             // class A {}
             // class B extends A {}
             // class C extends B {}
-            h.addSubtype(_Type('Object'), _Type('A'), false);
-            h.addSubtype(_Type('Object'), _Type('A?'), false);
-            h.addSubtype(_Type('Object'), _Type('B?'), false);
-            h.addSubtype(_Type('A'), _Type('Object'), true);
-            h.addSubtype(_Type('A'), _Type('Object?'), true);
-            h.addSubtype(_Type('A'), _Type('A?'), true);
-            h.addSubtype(_Type('A'), _Type('B'), false);
-            h.addSubtype(_Type('A'), _Type('B?'), false);
-            h.addSubtype(_Type('A?'), _Type('Object'), false);
-            h.addSubtype(_Type('A?'), _Type('Object?'), true);
-            h.addSubtype(_Type('A?'), _Type('A'), false);
-            h.addSubtype(_Type('A?'), _Type('B?'), false);
-            h.addSubtype(_Type('B'), _Type('Object'), true);
-            h.addSubtype(_Type('B'), _Type('A'), true);
-            h.addSubtype(_Type('B'), _Type('A?'), true);
-            h.addSubtype(_Type('B'), _Type('B?'), true);
-            h.addSubtype(_Type('B?'), _Type('Object'), false);
-            h.addSubtype(_Type('B?'), _Type('Object?'), true);
-            h.addSubtype(_Type('B?'), _Type('A'), false);
-            h.addSubtype(_Type('B?'), _Type('A?'), true);
-            h.addSubtype(_Type('B?'), _Type('B'), false);
-            h.addSubtype(_Type('C'), _Type('Object'), true);
-            h.addSubtype(_Type('C'), _Type('A'), true);
-            h.addSubtype(_Type('C'), _Type('A?'), true);
-            h.addSubtype(_Type('C'), _Type('B'), true);
-            h.addSubtype(_Type('C'), _Type('B?'), true);
+            h.addSubtype(Type('Object'), Type('A'), false);
+            h.addSubtype(Type('Object'), Type('A?'), false);
+            h.addSubtype(Type('Object'), Type('B?'), false);
+            h.addSubtype(Type('A'), Type('Object'), true);
+            h.addSubtype(Type('A'), Type('Object?'), true);
+            h.addSubtype(Type('A'), Type('A?'), true);
+            h.addSubtype(Type('A'), Type('B'), false);
+            h.addSubtype(Type('A'), Type('B?'), false);
+            h.addSubtype(Type('A?'), Type('Object'), false);
+            h.addSubtype(Type('A?'), Type('Object?'), true);
+            h.addSubtype(Type('A?'), Type('A'), false);
+            h.addSubtype(Type('A?'), Type('B?'), false);
+            h.addSubtype(Type('B'), Type('Object'), true);
+            h.addSubtype(Type('B'), Type('A'), true);
+            h.addSubtype(Type('B'), Type('A?'), true);
+            h.addSubtype(Type('B'), Type('B?'), true);
+            h.addSubtype(Type('B?'), Type('Object'), false);
+            h.addSubtype(Type('B?'), Type('Object?'), true);
+            h.addSubtype(Type('B?'), Type('A'), false);
+            h.addSubtype(Type('B?'), Type('A?'), true);
+            h.addSubtype(Type('B?'), Type('B'), false);
+            h.addSubtype(Type('C'), Type('Object'), true);
+            h.addSubtype(Type('C'), Type('A'), true);
+            h.addSubtype(Type('C'), Type('A?'), true);
+            h.addSubtype(Type('C'), Type('B'), true);
+            h.addSubtype(Type('C'), Type('B?'), true);
 
-            h.addFactor(_Type('Object'), _Type('A?'), _Type('Object'));
-            h.addFactor(_Type('Object'), _Type('B?'), _Type('Object'));
-            h.addFactor(_Type('Object?'), _Type('A'), _Type('Object?'));
-            h.addFactor(_Type('Object?'), _Type('A?'), _Type('Object'));
-            h.addFactor(_Type('Object?'), _Type('B?'), _Type('Object'));
+            h.addFactor(Type('Object'), Type('A?'), Type('Object'));
+            h.addFactor(Type('Object'), Type('B?'), Type('Object'));
+            h.addFactor(Type('Object?'), Type('A'), Type('Object?'));
+            h.addFactor(Type('Object?'), Type('A?'), Type('Object'));
+            h.addFactor(Type('Object?'), Type('B?'), Type('Object'));
           });
 
           test('; first', () {
-            var x = _Var('x', _Type('Object?'));
+            var x = Var('x', 'Object?');
 
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(x, true)
-                .tryPromoteForTypeCheck(h, x, _Type('B?'))
+                .tryPromoteForTypeCheck(h, x, Type('B?'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .tryPromoteForTypeCheck(h, x, Type('A?'))
                 .ifFalse;
             expect(s1.variableInfo, {
               x: _matchVariableModel(
@@ -2854,7 +2467,7 @@
               ),
             });
 
-            var s2 = s1.write(x, _Type('C'), h);
+            var s2 = s1.write(x, Type('C'), h);
             expect(s2.variableInfo, {
               x: _matchVariableModel(
                 chain: ['Object', 'B'],
@@ -2864,13 +2477,13 @@
           });
 
           test('; second', () {
-            var x = _Var('x', _Type('Object?'));
+            var x = Var('x', 'Object?');
 
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(x, true)
-                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .tryPromoteForTypeCheck(h, x, Type('A?'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, x, _Type('B?'))
+                .tryPromoteForTypeCheck(h, x, Type('B?'))
                 .ifFalse;
             expect(s1.variableInfo, {
               x: _matchVariableModel(
@@ -2879,7 +2492,7 @@
               ),
             });
 
-            var s2 = s1.write(x, _Type('C'), h);
+            var s2 = s1.write(x, Type('C'), h);
             expect(s2.variableInfo, {
               x: _matchVariableModel(
                 chain: ['Object', 'B'],
@@ -2889,13 +2502,13 @@
           });
 
           test('; nullable and non-nullable', () {
-            var x = _Var('x', _Type('Object?'));
+            var x = Var('x', 'Object?');
 
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(x, true)
-                .tryPromoteForTypeCheck(h, x, _Type('A'))
+                .tryPromoteForTypeCheck(h, x, Type('A'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, x, _Type('A?'))
+                .tryPromoteForTypeCheck(h, x, Type('A?'))
                 .ifFalse;
             expect(s1.variableInfo, {
               x: _matchVariableModel(
@@ -2904,7 +2517,7 @@
               ),
             });
 
-            var s2 = s1.write(x, _Type('B'), h);
+            var s2 = s1.write(x, Type('B'), h);
             expect(s2.variableInfo, {
               x: _matchVariableModel(
                 chain: ['Object', 'A'],
@@ -2916,12 +2529,12 @@
 
         group('; ambiguous', () {
           test('; no promotion', () {
-            var h = _Harness();
-            var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+            var h = Harness();
+            var s1 = FlowModel<Var, Type>(Reachability.initial)
                 .declare(objectQVar, true)
-                .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+                .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
                 .ifFalse
-                .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+                .tryPromoteForTypeCheck(h, objectQVar, Type('num*'))
                 .ifFalse;
             expect(s1.variableInfo, {
               objectQVar: _matchVariableModel(
@@ -2929,7 +2542,7 @@
                 ofInterest: ['num?', 'num*'],
               ),
             });
-            var s2 = s1.write(objectQVar, _Type('int'), h);
+            var s2 = s1.write(objectQVar, Type('int'), h);
             // It's ambiguous whether to promote to num? or num*, so we don't
             // promote.
             expect(s2, same(s1));
@@ -2937,12 +2550,12 @@
         });
 
         test('exact match', () {
-          var h = _Harness();
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+          var h = Harness();
+          var s1 = FlowModel<Var, Type>(Reachability.initial)
               .declare(objectQVar, true)
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
               .ifFalse
-              .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+              .tryPromoteForTypeCheck(h, objectQVar, Type('num*'))
               .ifFalse;
           expect(s1.variableInfo, {
             objectQVar: _matchVariableModel(
@@ -2950,7 +2563,7 @@
               ofInterest: ['num?', 'num*'],
             ),
           });
-          var s2 = s1.write(objectQVar, _Type('num?'), h);
+          var s2 = s1.write(objectQVar, Type('num?'), h);
           // It's ambiguous whether to promote to num? or num*, but since the
           // written type is exactly num?, we use that.
           expect(s2.variableInfo, {
@@ -2965,15 +2578,15 @@
 
     group('demotion, to NonNull', () {
       test('when promoted via test', () {
-        var x = _Var('x', _Type('Object?'));
+        var x = Var('x', 'Object?');
 
-        var h = _Harness();
+        var h = Harness();
 
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(x, true)
-            .tryPromoteForTypeCheck(h, x, _Type('num?'))
+            .tryPromoteForTypeCheck(h, x, Type('num?'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, x, _Type('int?'))
+            .tryPromoteForTypeCheck(h, x, Type('int?'))
             .ifTrue;
         expect(s1.variableInfo, {
           x: _matchVariableModel(
@@ -2982,7 +2595,7 @@
           ),
         });
 
-        var s2 = s1.write(x, _Type('double'), h);
+        var s2 = s1.write(x, Type('double'), h);
         expect(s2.variableInfo, {
           x: _matchVariableModel(
             chain: ['num?', 'num'],
@@ -2993,10 +2606,10 @@
     });
 
     group('declare', () {
-      var objectQVar = _Var('x', _Type('Object?'));
+      var objectQVar = Var('x', 'Object?');
 
       test('initialized', () {
-        var s = FlowModel<_Var, _Type>(Reachability.initial)
+        var s = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, true);
         expect(s.variableInfo, {
           objectQVar: _matchVariableModel(assigned: true, unassigned: false),
@@ -3004,7 +2617,7 @@
       });
 
       test('not initialized', () {
-        var s = FlowModel<_Var, _Type>(Reachability.initial)
+        var s = FlowModel<Var, Type>(Reachability.initial)
             .declare(objectQVar, false);
         expect(s.variableInfo, {
           objectQVar: _matchVariableModel(assigned: false, unassigned: true),
@@ -3014,15 +2627,15 @@
 
     group('markNonNullable', () {
       test('unpromoted -> unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
         var s2 = s1.tryMarkNonNullable(h, intVar).ifTrue;
         expect(s2, same(s1));
       });
 
       test('unpromoted -> promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
         var s2 = s1.tryMarkNonNullable(h, intQVar).ifTrue;
         expect(s2.reachable.overallReachable, true);
         expect(s2.infoFor(intQVar),
@@ -3030,18 +2643,18 @@
       });
 
       test('promoted -> unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
         expect(s2, same(s1));
       });
 
       test('promoted -> re-promoted', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
             .ifTrue;
         var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
         expect(s2.reachable.overallReachable, true);
@@ -3052,8 +2665,8 @@
       });
 
       test('promote to Never', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial);
         var s2 = s1.tryMarkNonNullable(h, nullVar).ifTrue;
         expect(s2.reachable.overallReachable, false);
         expect(s2.infoFor(nullVar),
@@ -3061,85 +2674,23 @@
       });
     });
 
-    group('joinUnassigned', () {
-      group('other', () {
-        test('unchanged', () {
-          var h = _Harness();
-
-          var a = _Var('a', _Type('int'));
-          var b = _Var('b', _Type('int'));
-
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-              .declare(a, false)
-              .declare(b, false)
-              .write(a, _Type('int'), h);
-          expect(s1.variableInfo, {
-            a: _matchVariableModel(assigned: true, unassigned: false),
-            b: _matchVariableModel(assigned: false, unassigned: true),
-          });
-
-          var s2 = s1.write(a, _Type('int'), h);
-          expect(s2.variableInfo, {
-            a: _matchVariableModel(assigned: true, unassigned: false),
-            b: _matchVariableModel(assigned: false, unassigned: true),
-          });
-
-          var s3 = s1.joinUnassigned(s2);
-          expect(s3, same(s1));
-        });
-
-        test('changed', () {
-          var h = _Harness();
-
-          var a = _Var('a', _Type('int'));
-          var b = _Var('b', _Type('int'));
-          var c = _Var('c', _Type('int'));
-
-          var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-              .declare(a, false)
-              .declare(b, false)
-              .declare(c, false)
-              .write(a, _Type('int'), h);
-          expect(s1.variableInfo, {
-            a: _matchVariableModel(assigned: true, unassigned: false),
-            b: _matchVariableModel(assigned: false, unassigned: true),
-            c: _matchVariableModel(assigned: false, unassigned: true),
-          });
-
-          var s2 = s1.write(b, _Type('int'), h);
-          expect(s2.variableInfo, {
-            a: _matchVariableModel(assigned: true, unassigned: false),
-            b: _matchVariableModel(assigned: true, unassigned: false),
-            c: _matchVariableModel(assigned: false, unassigned: true),
-          });
-
-          var s3 = s1.joinUnassigned(s2);
-          expect(s3.variableInfo, {
-            a: _matchVariableModel(assigned: true, unassigned: false),
-            b: _matchVariableModel(assigned: false, unassigned: false),
-            c: _matchVariableModel(assigned: false, unassigned: true),
-          });
-        });
-      });
-    });
-
     group('conservativeJoin', () {
       test('unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
             .declare(intQVar, true)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue;
         var s2 = s1.conservativeJoin([intQVar], []);
         expect(s2, same(s1));
       });
 
       test('written', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, intQVar, Type('int'))
             .ifTrue;
         var s2 = s1.conservativeJoin([intQVar], []);
         expect(s2.reachable.overallReachable, true);
@@ -3150,11 +2701,11 @@
       });
 
       test('write captured', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(Reachability.initial)
-            .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+        var h = Harness();
+        var s1 = FlowModel<Var, Type>(Reachability.initial)
+            .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
             .ifTrue
-            .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
+            .tryPromoteForTypeCheck(h, intQVar, Type('int'))
             .ifTrue;
         var s2 = s1.conservativeJoin([], [intQVar]);
         expect(s2.reachable.overallReachable, true);
@@ -3168,8 +2719,8 @@
 
     group('restrict', () {
       test('reachability', () {
-        var h = _Harness();
-        var reachable = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var reachable = FlowModel<Var, Type>(Reachability.initial);
         var unreachable = reachable.setUnreachable();
         expect(reachable.restrict(h, reachable, Set()), same(reachable));
         expect(reachable.restrict(h, unreachable, Set()), same(unreachable));
@@ -3178,18 +2729,18 @@
       });
 
       test('assignments', () {
-        var h = _Harness();
-        var a = _Var('a', _Type('int'));
-        var b = _Var('b', _Type('int'));
-        var c = _Var('c', _Type('int'));
-        var d = _Var('d', _Type('int'));
-        var s0 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var a = Var('a', 'int');
+        var b = Var('b', 'int');
+        var c = Var('c', 'int');
+        var d = Var('d', 'int');
+        var s0 = FlowModel<Var, Type>(Reachability.initial)
             .declare(a, false)
             .declare(b, false)
             .declare(c, false)
             .declare(d, false);
-        var s1 = s0.write(a, _Type('int'), h).write(b, _Type('int'), h);
-        var s2 = s1.write(a, _Type('int'), h).write(c, _Type('int'), h);
+        var s1 = s0.write(a, Type('int'), h).write(b, Type('int'), h);
+        var s2 = s1.write(a, Type('int'), h).write(c, Type('int'), h);
         var result = s2.restrict(h, s1, Set());
         expect(result.infoFor(a).assigned, true);
         expect(result.infoFor(b).assigned, true);
@@ -3198,12 +2749,12 @@
       });
 
       test('write captured', () {
-        var h = _Harness();
-        var a = _Var('a', _Type('int'));
-        var b = _Var('b', _Type('int'));
-        var c = _Var('c', _Type('int'));
-        var d = _Var('d', _Type('int'));
-        var s0 = FlowModel<_Var, _Type>(Reachability.initial)
+        var h = Harness();
+        var a = Var('a', 'int');
+        var b = Var('b', 'int');
+        var c = Var('c', 'int');
+        var d = Var('d', 'int');
+        var s0 = FlowModel<Var, Type>(Reachability.initial)
             .declare(a, false)
             .declare(b, false)
             .declare(c, false)
@@ -3233,16 +2784,15 @@
       test('promotion', () {
         void _check(String thisType, String otherType, bool unsafe,
             List<String> expectedChain) {
-          var h = _Harness();
-          var x = _Var('x', _Type('Object?'));
-          var s0 =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+          var h = Harness();
+          var x = Var('x', 'Object?');
+          var s0 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           var s1 = thisType == null
               ? s0
-              : s0.tryPromoteForTypeCheck(h, x, _Type(thisType)).ifTrue;
+              : s0.tryPromoteForTypeCheck(h, x, Type(thisType)).ifTrue;
           var s2 = otherType == null
               ? s0
-              : s0.tryPromoteForTypeCheck(h, x, _Type(otherType)).ifTrue;
+              : s0.tryPromoteForTypeCheck(h, x, Type(otherType)).ifTrue;
           var result = s1.restrict(h, s2, unsafe ? [x].toSet() : Set());
           if (expectedChain == null) {
             expect(result.variableInfo, contains(x));
@@ -3270,8 +2820,8 @@
       test('promotion chains', () {
         // Verify that the given promotion chain matches the expected list of
         // strings.
-        void _checkChain(List<_Type> chain, List<String> expected) {
-          var strings = (chain ?? <_Type>[]).map((t) => t.type).toList();
+        void _checkChain(List<Type> chain, List<String> expected) {
+          var strings = (chain ?? <Type>[]).map((t) => t.type).toList();
           expect(strings, expected);
         }
 
@@ -3286,25 +2836,25 @@
         //   block, the expected promotion chain is [expectedResult].
         void _check(List<String> before, List<String> inTry,
             List<String> inFinally, List<String> expectedResult) {
-          var h = _Harness();
-          var x = _Var('x', _Type('Object?'));
+          var h = Harness();
+          var x = Var('x', 'Object?');
           var initialModel =
-              FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+              FlowModel<Var, Type>(Reachability.initial).declare(x, true);
           for (var t in before) {
             initialModel =
-                initialModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+                initialModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
           }
           _checkChain(initialModel.infoFor(x).promotedTypes, before);
           var tryModel = initialModel;
           for (var t in inTry) {
-            tryModel = tryModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+            tryModel = tryModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
           }
           var expectedTryChain = before.toList()..addAll(inTry);
           _checkChain(tryModel.infoFor(x).promotedTypes, expectedTryChain);
           var finallyModel = initialModel;
           for (var t in inFinally) {
             finallyModel =
-                finallyModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+                finallyModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
           }
           var expectedFinallyChain = before.toList()..addAll(inFinally);
           _checkChain(
@@ -3340,9 +2890,9 @@
       });
 
       test('variable present in one state but not the other', () {
-        var h = _Harness();
-        var x = _Var('x', _Type('Object?'));
-        var s0 = FlowModel<_Var, _Type>(Reachability.initial);
+        var h = Harness();
+        var x = Var('x', 'Object?');
+        var s0 = FlowModel<Var, Type>(Reachability.initial);
         var s1 = s0.declare(x, true);
         expect(s0.restrict(h, s1, {}), same(s0));
         expect(s0.restrict(h, s1, {x}), same(s0));
@@ -3353,25 +2903,25 @@
   });
 
   group('joinPromotionChains', () {
-    var doubleType = _Type('double');
-    var intType = _Type('int');
-    var numType = _Type('num');
-    var objectType = _Type('Object');
+    var doubleType = Type('double');
+    var intType = Type('int');
+    var numType = Type('num');
+    var objectType = Type('Object');
 
     test('should handle nulls', () {
-      var h = _Harness();
+      var h = Harness();
       expect(VariableModel.joinPromotedTypes(null, null, h), null);
       expect(VariableModel.joinPromotedTypes(null, [intType], h), null);
       expect(VariableModel.joinPromotedTypes([intType], null, h), null);
     });
 
     test('should return null if there are no common types', () {
-      var h = _Harness();
+      var h = Harness();
       expect(VariableModel.joinPromotedTypes([intType], [doubleType], h), null);
     });
 
     test('should return common prefix if there are common types', () {
-      var h = _Harness();
+      var h = Harness();
       expect(
           VariableModel.joinPromotedTypes(
               [objectType, intType], [objectType, doubleType], h),
@@ -3383,7 +2933,7 @@
     });
 
     test('should return an input if it is a prefix of the other', () {
-      var h = _Harness();
+      var h = Harness();
       var prefix = [objectType, numType];
       var largerChain = [objectType, numType, intType];
       expect(VariableModel.joinPromotedTypes(prefix, largerChain, h),
@@ -3394,15 +2944,15 @@
     });
 
     test('should intersect', () {
-      var h = _Harness();
+      var h = Harness();
 
       // F <: E <: D <: C <: B <: A
-      var A = _Type('A');
-      var B = _Type('B');
-      var C = _Type('C');
-      var D = _Type('D');
-      var E = _Type('E');
-      var F = _Type('F');
+      var A = Type('A');
+      var B = Type('B');
+      var C = Type('C');
+      var D = Type('D');
+      var E = Type('E');
+      var F = Type('F');
       h.addSubtype(A, B, false);
       h.addSubtype(B, A, true);
       h.addSubtype(B, C, false);
@@ -3420,7 +2970,7 @@
       h.addSubtype(F, D, true);
       h.addSubtype(F, E, true);
 
-      void check(List<_Type> chain1, List<_Type> chain2, Matcher matcher) {
+      void check(List<Type> chain1, List<Type> chain2, Matcher matcher) {
         expect(
           VariableModel.joinPromotedTypes(chain1, chain2, h),
           matcher,
@@ -3471,11 +3021,11 @@
   });
 
   group('joinTypesOfInterest', () {
-    List<_Type> _makeTypes(List<String> typeNames) =>
-        typeNames.map((t) => _Type(t)).toList();
+    List<Type> _makeTypes(List<String> typeNames) =>
+        typeNames.map((t) => Type(t)).toList();
 
     test('simple prefix', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['double', 'int']);
       var s2 = _makeTypes(['double', 'int', 'bool']);
       var expected = _matchOfInterestSet(['double', 'int', 'bool']);
@@ -3484,7 +3034,7 @@
     });
 
     test('common prefix', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['double', 'int', 'String']);
       var s2 = _makeTypes(['double', 'int', 'bool']);
       var expected = _matchOfInterestSet(['double', 'int', 'String', 'bool']);
@@ -3493,7 +3043,7 @@
     });
 
     test('order mismatch', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['double', 'int']);
       var s2 = _makeTypes(['int', 'double']);
       var expected = _matchOfInterestSet(['double', 'int']);
@@ -3502,7 +3052,7 @@
     });
 
     test('small common prefix', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = _makeTypes(['int', 'double', 'String', 'bool']);
       var s2 = _makeTypes(['int', 'List', 'bool', 'Future']);
       var expected = _matchOfInterestSet(
@@ -3513,18 +3063,18 @@
   });
 
   group('join', () {
-    var x = _Var('x', _Type('Object?'));
-    var y = _Var('y', _Type('Object?'));
-    var z = _Var('z', _Type('Object?'));
-    var w = _Var('w', _Type('Object?'));
-    var intType = _Type('int');
-    var intQType = _Type('int?');
-    var stringType = _Type('String');
-    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+    var x = Var('x', 'Object?');
+    var y = Var('y', 'Object?');
+    var z = Var('z', 'Object?');
+    var w = Var('w', 'Object?');
+    var intType = Type('int');
+    var intQType = Type('int?');
+    var stringType = Type('String');
+    const emptyMap = const <Var, VariableModel<Var, Type>>{};
 
-    VariableModel<_Var, _Type> model(List<_Type> promotionChain,
-            {List<_Type> typesOfInterest, bool assigned = false}) =>
-        VariableModel<_Var, _Type>(
+    VariableModel<Var, Type> model(List<Type> promotionChain,
+            {List<Type> typesOfInterest, bool assigned = false}) =>
+        VariableModel<Var, Type>(
           promotionChain,
           typesOfInterest ?? promotionChain ?? [],
           assigned,
@@ -3534,7 +3084,7 @@
 
     group('without input reuse', () {
       test('promoted with unpromoted', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType]),
           y: model(null)
@@ -3551,7 +3101,7 @@
     });
     group('should re-use an input if possible', () {
       test('identical inputs', () {
-        var h = _Harness();
+        var h = Harness();
         var p = {
           x: model([intType]),
           y: model([stringType])
@@ -3560,18 +3110,18 @@
       });
 
       test('one input empty', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType]),
           y: model([stringType])
         };
-        var p2 = <_Var, VariableModel<_Var, _Type>>{};
+        var p2 = <Var, VariableModel<Var, Type>>{};
         expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(emptyMap));
         expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(emptyMap));
       });
 
       test('promoted with unpromoted', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType])
         };
@@ -3584,7 +3134,7 @@
       });
 
       test('related type chains', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intQType, intType])
         };
@@ -3599,7 +3149,7 @@
       });
 
       test('unrelated type chains', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intType])
         };
@@ -3614,7 +3164,7 @@
       });
 
       test('sub-map', () {
-        var h = _Harness();
+        var h = Harness();
         var xModel = model([intType]);
         var p1 = {
           x: xModel,
@@ -3626,7 +3176,7 @@
       });
 
       test('sub-map with matched subtype', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intQType, intType]),
           y: model([stringType])
@@ -3642,7 +3192,7 @@
       });
 
       test('sub-map with mismatched subtype', () {
-        var h = _Harness();
+        var h = Harness();
         var p1 = {
           x: model([intQType]),
           y: model([stringType])
@@ -3658,7 +3208,7 @@
       });
 
       test('assigned', () {
-        var h = _Harness();
+        var h = Harness();
         var unassigned = model(null, assigned: false);
         var assigned = model(null, assigned: true);
         var p1 = {x: assigned, y: assigned, z: unassigned, w: unassigned};
@@ -3675,7 +3225,7 @@
       });
 
       test('write captured', () {
-        var h = _Harness();
+        var h = Harness();
         var intQModel = model([intQType]);
         var writeCapturedModel = intQModel.writeCapture();
         var p1 = {
@@ -3702,14 +3252,14 @@
   });
 
   group('merge', () {
-    var x = _Var('x', _Type('Object?'));
-    var intType = _Type('int');
-    var stringType = _Type('String');
-    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+    var x = Var('x', 'Object?');
+    var intType = Type('int');
+    var stringType = Type('String');
+    const emptyMap = const <Var, VariableModel<Var, Type>>{};
 
-    VariableModel<_Var, _Type> varModel(List<_Type> promotionChain,
+    VariableModel<Var, Type> varModel(List<Type> promotionChain,
             {bool assigned = false}) =>
-        VariableModel<_Var, _Type>(
+        VariableModel<Var, Type>(
           promotionChain,
           promotionChain ?? [],
           assigned,
@@ -3718,14 +3268,14 @@
         );
 
     test('first is null', () {
-      var h = _Harness();
+      var h = Harness();
       var s1 = FlowModel.withInfo(Reachability.initial.split(), {});
       var result = FlowModel.merge(h, null, s1, emptyMap);
       expect(result.reachable, same(Reachability.initial));
     });
 
     test('second is null', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit, {});
@@ -3734,7 +3284,7 @@
     });
 
     test('both are reachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit, {
@@ -3749,7 +3299,7 @@
     });
 
     test('first is unreachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit.setUnreachable(), {
@@ -3764,7 +3314,7 @@
     });
 
     test('second is unreachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit, {
@@ -3779,7 +3329,7 @@
     });
 
     test('both are unreachable', () {
-      var h = _Harness();
+      var h = Harness();
       var splitPoint = Reachability.initial.split();
       var afterSplit = splitPoint.split();
       var s1 = FlowModel.withInfo(afterSplit.setUnreachable(), {
@@ -3796,16 +3346,16 @@
   });
 
   group('inheritTested', () {
-    var x = _Var('x', _Type('Object?'));
-    var intType = _Type('int');
-    var stringType = _Type('String');
-    const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+    var x = Var('x', 'Object?');
+    var intType = Type('int');
+    var stringType = Type('String');
+    const emptyMap = const <Var, VariableModel<Var, Type>>{};
 
-    VariableModel<_Var, _Type> model(List<_Type> typesOfInterest) =>
-        VariableModel<_Var, _Type>(null, typesOfInterest, true, false, false);
+    VariableModel<Var, Type> model(List<Type> typesOfInterest) =>
+        VariableModel<Var, Type>(null, typesOfInterest, true, false, false);
 
     test('inherits types of interest from other', () {
-      var h = _Harness();
+      var h = Harness();
       var m1 = FlowModel.withInfo(Reachability.initial, {
         x: model([intType])
       });
@@ -3817,7 +3367,7 @@
     });
 
     test('handles variable missing from other', () {
-      var h = _Harness();
+      var h = Harness();
       var m1 = FlowModel.withInfo(Reachability.initial, {
         x: model([intType])
       });
@@ -3826,7 +3376,7 @@
     });
 
     test('returns identical model when no changes', () {
-      var h = _Harness();
+      var h = Harness();
       var m1 = FlowModel.withInfo(Reachability.initial, {
         x: model([intType])
       });
@@ -3858,7 +3408,7 @@
 
 Matcher _matchOfInterestSet(List<String> expectedTypes) {
   return predicate(
-      (List<_Type> x) => unorderedEquals(expectedTypes)
+      (List<Type> x) => unorderedEquals(expectedTypes)
           .matches(x.map((t) => t.type).toList(), {}),
       'interest set $expectedTypes');
 }
@@ -3866,7 +3416,7 @@
 Matcher _matchPromotionChain(List<String> expectedTypes) {
   if (expectedTypes == null) return isNull;
   return predicate(
-      (List<_Type> x) =>
+      (List<Type> x) =>
           equals(expectedTypes).matches(x.map((t) => t.type).toList(), {}),
       'promotion chain $expectedTypes');
 }
@@ -3885,7 +3435,7 @@
   Matcher assignedMatcher = wrapMatcher(assigned);
   Matcher unassignedMatcher = wrapMatcher(unassigned);
   Matcher writeCapturedMatcher = wrapMatcher(writeCaptured);
-  return predicate((VariableModel<_Var, _Type> model) {
+  return predicate((VariableModel<Var, Type> model) {
     if (!chainMatcher.matches(model.promotedTypes, {})) return false;
     if (!ofInterestMatcher.matches(model.tested, {})) return false;
     if (!assignedMatcher.matches(model.assigned, {})) return false;
@@ -3899,459 +3449,3 @@
       'unassigned: ${_describeMatcher(unassignedMatcher)}, '
       'writeCaptured: ${_describeMatcher(writeCapturedMatcher)})');
 }
-
-/// Representation of an expression to be visited by the test harness.  Calling
-/// the function causes the expression to be "visited" (in other words, the
-/// appropriate methods in [FlowAnalysis] are called in the appropriate order),
-/// and the [_Expression] object representing the whole expression is returned.
-///
-/// This is used by methods in [_Harness] as a lightweight way of building up
-/// complex sequences of calls to [FlowAnalysis] that represent large
-/// expressions.
-typedef _Expression LazyExpression();
-
-class _AssignedVariablesHarness {
-  final AssignedVariables<_Node, _Var> _assignedVariables;
-
-  _AssignedVariablesHarness(this._assignedVariables);
-
-  void function(_Node node, void Function() callback) {
-    _assignedVariables.beginNode();
-    callback();
-    _assignedVariables.endNode(node, isClosureOrLateVariableInitializer: true);
-  }
-
-  void nest(_Node node, void Function() callback) {
-    _assignedVariables.beginNode();
-    callback();
-    _assignedVariables.endNode(node);
-  }
-
-  void write(_Var v) {
-    _assignedVariables.write(v);
-  }
-}
-
-class _Expression {
-  static int _idCounter = 0;
-
-  final int _id = _idCounter++;
-
-  @override
-  String toString() => 'E$_id';
-}
-
-class _Harness extends TypeOperations<_Var, _Type> {
-  static const Map<String, bool> _coreSubtypes = const {
-    'double <: Object': true,
-    'double <: num': true,
-    'double <: num?': true,
-    'double <: int': false,
-    'double <: int?': false,
-    'int <: double': false,
-    'int <: int?': true,
-    'int <: Iterable': false,
-    'int <: List': false,
-    'int <: Null': false,
-    'int <: num': true,
-    'int <: num?': true,
-    'int <: num*': true,
-    'int <: Never?': false,
-    'int <: Object': true,
-    'int <: Object?': true,
-    'int <: String': false,
-    'int? <: int': false,
-    'int? <: Null': false,
-    'int? <: num': false,
-    'int? <: num?': true,
-    'int? <: Object': false,
-    'int? <: Object?': true,
-    'Null <: int': false,
-    'Null <: Object': false,
-    'num <: int': false,
-    'num <: Iterable': false,
-    'num <: List': false,
-    'num <: num?': true,
-    'num <: num*': true,
-    'num <: Object': true,
-    'num <: Object?': true,
-    'num? <: int?': false,
-    'num? <: num': false,
-    'num? <: num*': true,
-    'num? <: Object': false,
-    'num? <: Object?': true,
-    'num* <: num': true,
-    'num* <: num?': true,
-    'num* <: Object': true,
-    'num* <: Object?': true,
-    'Iterable <: int': false,
-    'Iterable <: num': false,
-    'Iterable <: Object': true,
-    'Iterable <: Object?': true,
-    'List <: int': false,
-    'List <: Iterable': true,
-    'List <: Object': true,
-    'Never <: int': true,
-    'Never <: int?': true,
-    'Never <: Null': true,
-    'Never? <: int': false,
-    'Never? <: int?': true,
-    'Never? <: num?': true,
-    'Never? <: Object?': true,
-    'Null <: int?': true,
-    'Object <: int': false,
-    'Object <: int?': false,
-    'Object <: List': false,
-    'Object <: num': false,
-    'Object <: num?': false,
-    'Object <: Object?': true,
-    'Object? <: Object': false,
-    'Object? <: int': false,
-    'Object? <: int?': false,
-    'String <: int': false,
-    'String <: int?': false,
-    'String <: num?': false,
-    'String <: Object?': true,
-  };
-
-  static final Map<String, _Type> _coreFactors = {
-    'Object? - int': _Type('Object?'),
-    'Object? - int?': _Type('Object'),
-    'Object? - num?': _Type('Object'),
-    'Object? - Object?': _Type('Never?'),
-    'Object? - String': _Type('Object?'),
-    'Object - int': _Type('Object'),
-    'int - Object': _Type('Never'),
-    'int - String': _Type('int'),
-    'int - int': _Type('Never'),
-    'int - int?': _Type('Never'),
-    'int? - int': _Type('Never?'),
-    'int? - int?': _Type('Never'),
-    'int? - String': _Type('int?'),
-    'Null - int': _Type('Null'),
-    'num - int': _Type('num'),
-    'num? - num': _Type('Never?'),
-    'num? - int': _Type('num?'),
-    'num? - int?': _Type('num'),
-    'num? - Object': _Type('Never?'),
-    'num? - String': _Type('num?'),
-    'Object - int?': _Type('Object'),
-    'Object - num': _Type('Object'),
-    'Object - num?': _Type('Object'),
-    'Object - num*': _Type('Object'),
-    'Object - Iterable': _Type('Object'),
-    'Object? - Object': _Type('Never?'),
-    'Object? - Iterable': _Type('Object?'),
-    'Object? - num': _Type('Object?'),
-    'Iterable - List': _Type('Iterable'),
-    'num* - Object': _Type('Never'),
-  };
-
-  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
-
-  final Map<String, _Type> _factorResults = Map.of(_coreFactors);
-
-  FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> _flow;
-
-  final _assignedVariables = AssignedVariables<_Node, _Var>();
-
-  /// Returns a [LazyExpression] representing an expression with now special
-  /// flow analysis semantics.
-  LazyExpression get expr => () => _Expression();
-
-  LazyExpression get nullLiteral => () {
-        var expr = _Expression();
-        _flow.nullLiteral(expr);
-        return expr;
-      };
-
-  void addFactor(_Type from, _Type what, _Type result) {
-    var query = '$from - $what';
-    _factorResults[query] = result;
-  }
-
-  void addSubtype(_Type leftType, _Type rightType, bool isSubtype) {
-    var query = '$leftType <: $rightType';
-    _subtypes[query] = isSubtype;
-  }
-
-  _Var addVar(String name, String type) {
-    assert(_flow == null);
-    return _Var(name, _Type(type));
-  }
-
-  /// Given two [LazyExpression]s, produces a new [LazyExpression] representing
-  /// the result of combining them with `&&`.
-  LazyExpression and(LazyExpression lhs, LazyExpression rhs) {
-    return () {
-      var expr = _Expression();
-      _flow.logicalBinaryOp_begin();
-      _flow.logicalBinaryOp_rightBegin(lhs(), isAnd: true);
-      _flow.logicalBinaryOp_end(expr, rhs(), isAnd: true);
-      return expr;
-    };
-  }
-
-  void assignedVariables(void Function(_AssignedVariablesHarness) callback) {
-    callback(_AssignedVariablesHarness(_assignedVariables));
-  }
-
-  LazyExpression booleanLiteral(bool value) => () {
-        var expr = _Expression();
-        _flow.booleanLiteral(expr, value);
-        return expr;
-      };
-
-  @override
-  TypeClassification classifyType(_Type type) {
-    if (isSubtypeOf(type, _Type('Object'))) {
-      return TypeClassification.nonNullable;
-    } else if (isSubtypeOf(type, _Type('Null'))) {
-      return TypeClassification.nullOrEquivalent;
-    } else {
-      return TypeClassification.potentiallyNullable;
-    }
-  }
-
-  /// Given three [LazyExpression]s, produces a new [LazyExpression]
-  /// representing the result of combining them with `?` and `:`.
-  LazyExpression conditional(
-      LazyExpression cond, LazyExpression ifTrue, LazyExpression ifFalse) {
-    return () {
-      var expr = _Expression();
-      _flow.conditional_conditionBegin();
-      _flow.conditional_thenBegin(cond());
-      _flow.conditional_elseBegin(ifTrue());
-      _flow.conditional_end(expr, ifFalse());
-      return expr;
-    };
-  }
-
-  FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> createFlow() =>
-      FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type>(
-          this, _assignedVariables);
-
-  void declare(_Var v, {@required bool initialized}) {
-    _flow.declare(v, initialized);
-  }
-
-  /// Creates a [LazyExpression] representing an `== null` check performed on
-  /// [variable].
-  LazyExpression eqNull(_Var variable, _Type type) {
-    return () {
-      var varExpr = _Expression();
-      _flow.variableRead(varExpr, variable);
-      _flow.equalityOp_rightBegin(varExpr, type);
-      var nullExpr = _Expression();
-      _flow.nullLiteral(nullExpr);
-      var expr = _Expression();
-      _flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
-      return expr;
-    };
-  }
-
-  @override
-  _Type factor(_Type from, _Type what) {
-    var query = '$from - $what';
-    return _factorResults[query] ?? fail('Unknown factor query: $query');
-  }
-
-  /// Invokes flow analysis of a nested function.
-  void function(_Node node, void body()) {
-    _flow.functionExpression_begin(node);
-    body();
-    _flow.functionExpression_end();
-  }
-
-  /// Invokes flow analysis of an `if` statement with no `else` part.
-  void if_(LazyExpression cond, void ifTrue()) {
-    _flow.ifStatement_conditionBegin();
-    _flow.ifStatement_thenBegin(cond());
-    ifTrue();
-    _flow.ifStatement_end(false);
-  }
-
-  /// Invokes flow analysis of an `if` statement with an `else` part.
-  void ifElse(LazyExpression cond, void ifTrue(), void ifFalse()) {
-    _flow.ifStatement_conditionBegin();
-    _flow.ifStatement_thenBegin(cond());
-    ifTrue();
-    _flow.ifStatement_elseBegin();
-    ifFalse();
-    _flow.ifStatement_end(true);
-  }
-
-  /// Equivalent for `if (variable is! type) { ifTrue; }`
-  void ifIsNotType(_Var variable, String type, void ifTrue()) {
-    if_(isNotType(variableRead(variable), type), ifTrue);
-  }
-
-  @override
-  bool isNever(_Type type) {
-    return type.type == 'Never';
-  }
-
-  /// Creates a [LazyExpression] representing an `is!` check, checking whether
-  /// [subExpression] has the given [type].
-  LazyExpression isNotType(LazyExpression subExpression, String type) {
-    return () {
-      var expr = _Expression();
-      _flow.isExpression_end(expr, subExpression(), true, _Type(type));
-      return expr;
-    };
-  }
-
-  @override
-  bool isSameType(_Type type1, _Type type2) {
-    return type1.type == type2.type;
-  }
-
-  @override
-  bool isSubtypeOf(_Type leftType, _Type rightType) {
-    if (leftType.type == rightType.type) return true;
-    var query = '$leftType <: $rightType';
-    return _subtypes[query] ?? fail('Unknown subtype query: $query');
-  }
-
-  /// Creates a [LazyExpression] representing an `is` check, checking whether
-  /// [subExpression] has the given [type].
-  LazyExpression isType(LazyExpression subExpression, String type) {
-    return () {
-      var expr = _Expression();
-      _flow.isExpression_end(expr, subExpression(), false, _Type(type));
-      return expr;
-    };
-  }
-
-  /// Invokes flow analysis of a labeled block.
-  void labeledBlock(_Statement node, void body()) {
-    _flow.labeledStatement_begin(node);
-    body();
-    _flow.labeledStatement_end();
-  }
-
-  /// Creates a [LazyExpression] representing an equality check between two
-  /// other expressions.
-  LazyExpression notEqual(
-      LazyExpression lhs, _Type lhsType, LazyExpression rhs, _Type rhsType) {
-    return () {
-      var expr = _Expression();
-      _flow.equalityOp_rightBegin(lhs(), lhsType);
-      _flow.equalityOp_end(expr, rhs(), rhsType, notEqual: true);
-      return expr;
-    };
-  }
-
-  /// Creates a [LazyExpression] representing a `!= null` check performed on
-  /// [variable].
-  LazyExpression notNull(_Var variable, _Type type) {
-    return () {
-      var varExpr = _Expression();
-      _flow.variableRead(varExpr, variable);
-      _flow.equalityOp_rightBegin(varExpr, type);
-      var nullExpr = _Expression();
-      _flow.nullLiteral(nullExpr);
-      var expr = _Expression();
-      _flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
-      return expr;
-    };
-  }
-
-  /// Given two [LazyExpression]s, produces a new [LazyExpression] representing
-  /// the result of combining them with `||`.
-  LazyExpression or(LazyExpression lhs, LazyExpression rhs) {
-    return () {
-      var expr = _Expression();
-      _flow.logicalBinaryOp_begin();
-      _flow.logicalBinaryOp_rightBegin(lhs(), isAnd: false);
-      _flow.logicalBinaryOp_end(expr, rhs(), isAnd: false);
-      return expr;
-    };
-  }
-
-  /// Creates a [LazyExpression] representing a parenthesized subexpression.
-  LazyExpression parenthesized(LazyExpression inner) {
-    return () {
-      var expr = _Expression();
-      _flow.parenthesizedExpression(expr, inner());
-      return expr;
-    };
-  }
-
-  /// Causes [variable] to be promoted to [type].
-  void promote(_Var variable, String type) {
-    ifIsNotType(variable, type, _flow.handleExit);
-  }
-
-  @override
-  _Type promoteToNonNull(_Type type) {
-    if (type.type.endsWith('?')) {
-      return _Type(type.type.substring(0, type.type.length - 1));
-    } else if (type.type == 'Null') {
-      return _Type('Never');
-    } else {
-      return type;
-    }
-  }
-
-  void run(
-      void callback(
-          FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> flow)) {
-    assert(_flow == null);
-    _flow = createFlow();
-    callback(_flow);
-    _flow.finish();
-  }
-
-  @override
-  _Type tryPromoteToType(_Type to, _Type from) {
-    if (isSubtypeOf(to, from)) {
-      return to;
-    } else {
-      return null;
-    }
-  }
-
-  LazyExpression variableRead(_Var variable) {
-    return () {
-      var expr = _Expression();
-      _flow.variableRead(expr, variable);
-      return expr;
-    };
-  }
-
-  @override
-  _Type variableType(_Var variable) {
-    return variable.type;
-  }
-}
-
-class _Node {}
-
-class _Statement extends _Node {}
-
-class _Type {
-  final String type;
-
-  _Type(this.type);
-
-  @override
-  bool operator ==(Object other) {
-    // The flow analysis engine should not compare types using operator==.  It
-    // should compare them using TypeOperations.
-    fail('Unexpected use of operator== on types');
-  }
-
-  @override
-  String toString() => type;
-}
-
-class _Var {
-  final String name;
-  final _Type type;
-
-  _Var(this.name, this.type);
-
-  @override
-  String toString() => '$type $name';
-}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical.dart
new file mode 100644
index 0000000..f74d1ec
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Null nullExpr = null;
+
+void var_identical_null(int? x) {
+  if (identical(x, null)) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
+
+void var_notIdentical_null(int? x) {
+  if (!identical(x, null)) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+void null_identical_var(int? x) {
+  if (identical(null, x)) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
+
+void null_notIdentical_var(int? x) {
+  if (!identical(null, x)) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+void var_identical_nullExpr(int? x) {
+  if (identical(x, nullExpr)) {
+    x;
+  } else {
+    x;
+  }
+}
+
+void var_notIdentical_nullExpr(int? x) {
+  if (!identical(x, nullExpr)) {
+    x;
+  } else {
+    x;
+  }
+}
+
+void nullExpr_identical_var(int? x) {
+  if (identical(nullExpr, x)) {
+    x;
+  } else {
+    x;
+  }
+}
+
+void nullExpr_notIdentical_var(int? x) {
+  if (!identical(nullExpr, x)) {
+    x;
+  } else {
+    x;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_prefixed.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_prefixed.dart
new file mode 100644
index 0000000..febe994
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_prefixed.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:core';
+import 'dart:core' as core;
+
+void test(int? x) {
+  if (core.identical(x, null)) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_spoof.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_spoof.dart
new file mode 100644
index 0000000..1fdc9fe
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_spoof.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool identical(Object? x, Object? y) => false;
+
+void test(int? x) {
+  if (identical(x, null)) {
+    x;
+  } else {
+    x;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/issue44276.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/issue44276.dart
new file mode 100644
index 0000000..a1f87af
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/issue44276.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Base {
+  int? value1;
+  int? value2;
+}
+
+int? fun() {
+  Base? a;
+  // if `a` is `null`, then `a?.value1` evaluates to `null`, so the RHS of the
+  // `??` will be evaluated.  Therefore, we can't promote `a` to non-nullable in
+  // `a?.value2`.
+  final b = a?.value1 ?? a?.value2;
+  return b;
+}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_in/core.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_in/core.dart
index 65dfce3..da9e41a 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_in/core.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_in/core.dart
@@ -9,6 +9,8 @@
 
 export 'dart:async' show Future;
 
+bool identical(a, b) => false;
+
 /*class: Object:Object*/
 class Object {
   const Object();
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_out/core.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_out/core.dart
index 2712fa3..0df65e1 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_out/core.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/object_opt_out/core.dart
@@ -13,6 +13,8 @@
 
 export 'dart:async' show Future;
 
+bool identical(a, b) => false;
+
 /*class: Object:Object*/
 class Object {
   const Object();
diff --git a/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart b/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart
index e5c6d2b..2c7025c 100644
--- a/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart
+++ b/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart
@@ -10,7 +10,7 @@
 
 main(List<String> args) async {
   Stopwatch stopwatch = new Stopwatch()..start();
-  List<Future> futures = new List<Future>();
+  List<Future> futures = <Future>[];
   futures.add(run("pkg/front_end/test/spelling_test_src_suite.dart",
       ["--", "spelling_test_src/_fe_analyzer_shared/..."]));
   futures.add(run(
diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart
index 260937a..8bb8c6d 100644
--- a/pkg/_js_interop_checks/lib/js_interop_checks.dart
+++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart
@@ -170,12 +170,17 @@
 
   /// Returns whether [member] is considered to be a JS interop member.
   bool _isJSInteropMember(Member member) {
-    if (!member.isExternal) return false;
-    if (_classHasJSAnnotation) return true;
-    if (!_classHasJSAnnotation && member.enclosingClass != null) return false;
-    // In the case where the member does not belong to any class, a JS
-    // annotation is not needed on the library to be considered JS interop as
-    // long as the member has an annotation.
-    return hasJSInteropAnnotation(member) || _libraryHasJSAnnotation;
+    if (member.isExternal) {
+      if (_classHasJSAnnotation) return true;
+      if (member.enclosingClass == null) {
+        // In the case where the member does not belong to any class, a JS
+        // annotation is not needed on the library to be considered JS interop
+        // as long as the member has an annotation.
+        return hasJSInteropAnnotation(member) || _libraryHasJSAnnotation;
+      }
+    }
+
+    // Otherwise, not JS interop.
+    return false;
   }
 }
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 37b095d9..0bce9d2 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.30.0
+  1.32.1
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -235,6 +235,11 @@
   the server so clients should ensure unknown values are handled gracefully, either
   ignoring the item or treating it with some default/fallback handling.
 </p>
+<h3>Changelog</h3>
+<h4>1.32.1</h4>
+<ul>
+  <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt></li>
+</ul>
 <h3>Domains</h3>
 <p>
   For convenience, the API is divided into domains. Each domain is specified
@@ -3046,6 +3051,8 @@
   
   
   
+  
+  
 <dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
     <p>
       A directive to begin overlaying the contents of a file. The supplied
@@ -3323,6 +3330,37 @@
         </p>
       </dd><dt class="field"><b>items: List&lt;<a href="#type_AvailableSuggestion">AvailableSuggestion</a>&gt;</b></dt><dd>
         
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_BulkFix">BulkFix: object</a></dt><dd>
+    <p>
+      A description of bulk fixes to a library.
+    </p>
+    
+  <dl><dt class="field"><b>path: <a href="#type_FilePath">FilePath</a></b></dt><dd>
+        
+        <p>
+          The path of the library.
+        </p>
+      </dd><dt class="field"><b>fixes: List&lt;<a href="#type_BulkFixDetail">BulkFixDetail</a>&gt;</b></dt><dd>
+        
+        <p>
+          A list of bulk fix details.
+        </p>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_BulkFixDetail">BulkFixDetail: object</a></dt><dd>
+    <p>
+      A description of a fix applied to a library.
+    </p>
+    
+  <dl><dt class="field"><b>code: String</b></dt><dd>
+        
+        <p>
+          The code of the diagnostic associated with the fix.
+        </p>
+      </dd><dt class="field"><b>occurrences: int</b></dt><dd>
+        
+        <p>
+          The number times the associated diagnostic was fixed in the associated
+          source edit.
+        </p>
       </dd></dl></dd><dt class="typeDefinition"><a name="type_ChangeContentOverlay">ChangeContentOverlay: object</a></dt><dd>
     <p>
       A directive to modify an existing file content overlay. One or more ranges
@@ -3590,7 +3628,10 @@
         <p>
           An overriding implementation of a class member is being suggested.
         </p>
-      </dd><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
+      </dd><dt class="value">PARAMETER</dt><dt class="value">PACKAGE_NAME</dt><dd>
+        
+        <p>The name of a pub package is being suggested.</p>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
     <p>
       Information about an analysis context.
     </p>
@@ -4239,152 +4280,47 @@
     
   <dl><dt class="value">ANNOTATION</dt><dt class="value">BUILT_IN</dt><dt class="value">CLASS</dt><dt class="value">COMMENT_BLOCK</dt><dt class="value">COMMENT_DOCUMENTATION</dt><dt class="value">COMMENT_END_OF_LINE</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">DIRECTIVE</dt><dt class="value">DYNAMIC_TYPE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FIELD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INVALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">METHOD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">PARAMETER</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">SETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_FIELD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">VALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
     <p>
       The hover information associated with a specific location.
     </p>
@@ -6062,7 +5998,7 @@
   TODO: TBD
 </p>
 <h2 class="domain"><a name="index">Index</a></h2>
-<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
 
 
 </body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
index 5c97433..16daa2d 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -192,66 +192,30 @@
       CompletionItemResolutionInfo.canParse,
       CompletionItemResolutionInfo.fromJson);
 
-  CompletionItemResolutionInfo(
-      {@required this.file,
-      @required this.offset,
-      @required this.libId,
-      @required this.displayUri,
-      @required this.rOffset,
-      @required this.rLength}) {
+  CompletionItemResolutionInfo({@required this.file, @required this.offset}) {
     if (file == null) {
       throw 'file is required but was not provided';
     }
     if (offset == null) {
       throw 'offset is required but was not provided';
     }
-    if (libId == null) {
-      throw 'libId is required but was not provided';
-    }
-    if (displayUri == null) {
-      throw 'displayUri is required but was not provided';
-    }
-    if (rOffset == null) {
-      throw 'rOffset is required but was not provided';
-    }
-    if (rLength == null) {
-      throw 'rLength is required but was not provided';
-    }
   }
   static CompletionItemResolutionInfo fromJson(Map<String, dynamic> json) {
+    if (DartCompletionItemResolutionInfo.canParse(json, nullLspJsonReporter)) {
+      return DartCompletionItemResolutionInfo.fromJson(json);
+    }
     final file = json['file'];
     final offset = json['offset'];
-    final libId = json['libId'];
-    final displayUri = json['displayUri'];
-    final rOffset = json['rOffset'];
-    final rLength = json['rLength'];
-    return CompletionItemResolutionInfo(
-        file: file,
-        offset: offset,
-        libId: libId,
-        displayUri: displayUri,
-        rOffset: rOffset,
-        rLength: rLength);
+    return CompletionItemResolutionInfo(file: file, offset: offset);
   }
 
-  final String displayUri;
   final String file;
-  final num libId;
   final num offset;
-  final num rLength;
-  final num rOffset;
 
   Map<String, dynamic> toJson() {
     var __result = <String, dynamic>{};
     __result['file'] = file ?? (throw 'file is required but was not set');
     __result['offset'] = offset ?? (throw 'offset is required but was not set');
-    __result['libId'] = libId ?? (throw 'libId is required but was not set');
-    __result['displayUri'] =
-        displayUri ?? (throw 'displayUri is required but was not set');
-    __result['rOffset'] =
-        rOffset ?? (throw 'rOffset is required but was not set');
-    __result['rLength'] =
-        rLength ?? (throw 'rLength is required but was not set');
     return __result;
   }
 
@@ -291,6 +255,105 @@
       } finally {
         reporter.pop();
       }
+      return true;
+    } else {
+      reporter.reportError('must be of type CompletionItemResolutionInfo');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is CompletionItemResolutionInfo &&
+        other.runtimeType == CompletionItemResolutionInfo) {
+      return file == other.file && offset == other.offset && true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
+class DartCompletionItemResolutionInfo
+    implements CompletionItemResolutionInfo, ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+      DartCompletionItemResolutionInfo.canParse,
+      DartCompletionItemResolutionInfo.fromJson);
+
+  DartCompletionItemResolutionInfo(
+      {@required this.libId,
+      @required this.displayUri,
+      @required this.rOffset,
+      @required this.rLength,
+      @required this.file,
+      @required this.offset}) {
+    if (libId == null) {
+      throw 'libId is required but was not provided';
+    }
+    if (displayUri == null) {
+      throw 'displayUri is required but was not provided';
+    }
+    if (rOffset == null) {
+      throw 'rOffset is required but was not provided';
+    }
+    if (rLength == null) {
+      throw 'rLength is required but was not provided';
+    }
+    if (file == null) {
+      throw 'file is required but was not provided';
+    }
+    if (offset == null) {
+      throw 'offset is required but was not provided';
+    }
+  }
+  static DartCompletionItemResolutionInfo fromJson(Map<String, dynamic> json) {
+    final libId = json['libId'];
+    final displayUri = json['displayUri'];
+    final rOffset = json['rOffset'];
+    final rLength = json['rLength'];
+    final file = json['file'];
+    final offset = json['offset'];
+    return DartCompletionItemResolutionInfo(
+        libId: libId,
+        displayUri: displayUri,
+        rOffset: rOffset,
+        rLength: rLength,
+        file: file,
+        offset: offset);
+  }
+
+  final String displayUri;
+  final String file;
+  final num libId;
+  final num offset;
+  final num rLength;
+  final num rOffset;
+
+  Map<String, dynamic> toJson() {
+    var __result = <String, dynamic>{};
+    __result['libId'] = libId ?? (throw 'libId is required but was not set');
+    __result['displayUri'] =
+        displayUri ?? (throw 'displayUri is required but was not set');
+    __result['rOffset'] =
+        rOffset ?? (throw 'rOffset is required but was not set');
+    __result['rLength'] =
+        rLength ?? (throw 'rLength is required but was not set');
+    __result['file'] = file ?? (throw 'file is required but was not set');
+    __result['offset'] = offset ?? (throw 'offset is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj, LspJsonReporter reporter) {
+    if (obj is Map<String, dynamic>) {
       reporter.push('libId');
       try {
         if (!obj.containsKey('libId')) {
@@ -359,23 +422,57 @@
       } finally {
         reporter.pop();
       }
+      reporter.push('file');
+      try {
+        if (!obj.containsKey('file')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        if (obj['file'] == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (!(obj['file'] is String)) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('offset');
+      try {
+        if (!obj.containsKey('offset')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        if (obj['offset'] == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (!(obj['offset'] is num)) {
+          reporter.reportError('must be of type num');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
       return true;
     } else {
-      reporter.reportError('must be of type CompletionItemResolutionInfo');
+      reporter.reportError('must be of type DartCompletionItemResolutionInfo');
       return false;
     }
   }
 
   @override
   bool operator ==(Object other) {
-    if (other is CompletionItemResolutionInfo &&
-        other.runtimeType == CompletionItemResolutionInfo) {
-      return file == other.file &&
-          offset == other.offset &&
-          libId == other.libId &&
+    if (other is DartCompletionItemResolutionInfo &&
+        other.runtimeType == DartCompletionItemResolutionInfo) {
+      return libId == other.libId &&
           displayUri == other.displayUri &&
           rOffset == other.rOffset &&
           rLength == other.rLength &&
+          file == other.file &&
+          offset == other.offset &&
           true;
     }
     return false;
@@ -384,12 +481,12 @@
   @override
   int get hashCode {
     var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, file.hashCode);
-    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, libId.hashCode);
     hash = JenkinsSmiHash.combine(hash, displayUri.hashCode);
     hash = JenkinsSmiHash.combine(hash, rOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, rLength.hashCode);
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 6578de6..7b20e05 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -420,7 +420,7 @@
     return ClientCapabilitiesWindow(workDoneProgress: workDoneProgress);
   }
 
-  /// Whether client supports handling progress notifications. If set servers
+  /// Whether client supports handling progress notifications. If set, servers
   /// are allowed to report in `workDoneProgress` property in the request
   /// specific server capabilities.
   ///
@@ -712,8 +712,8 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// A code action represents a change that can be performed in code, e.g. to fix
-/// a problem or to refactor code.
+/// A code action represents a change that can be performed in code. For
+/// example, to fix a problem or to refactor code.
 ///
 /// A CodeAction must set either `edit` and/or a `command`. If both are
 /// supplied, the `edit` is applied first, then the `command` is executed.
@@ -1222,7 +1222,7 @@
   /// Requested kind of actions to return.
   ///
   /// Actions not of this kind are filtered out by the client before being
-  /// shown. So servers can omit computing them.
+  /// shown, so servers can omit computing them.
   final List<CodeActionKind> only;
 
   Map<String, dynamic> toJson() {
@@ -1357,7 +1357,7 @@
   /// Source code actions apply to the entire file.
   static const Source = CodeActionKind('source');
 
-  /// Base kind for an organize imports source action: `source.organizeImports`.
+  /// Base kind for an organize imports source action `source.organizeImports`.
   static const SourceOrganizeImports = CodeActionKind('source.organizeImports');
 
   Object toJson() => _value;
@@ -1516,8 +1516,8 @@
   /// Context carrying additional information.
   final CodeActionContext context;
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The range for which the command was invoked.
@@ -1687,7 +1687,7 @@
   final List<CodeActionKind> codeActionKinds;
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -1777,11 +1777,11 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// A code lens represents a command that should be shown along with source
+/// A CodeLense represents a command that should be shown along with source
 /// text, like the number of references, a way to run tests, etc.
 ///
-/// A code lens is _unresolved_ when no command is associated to it. For
-/// performance reasons the creation of a code lens and resolving should be done
+/// A CodeLens is _unresolved_ when no command is associated to it. For
+/// performance reasons, the creation of a CodeLens and resolving should be done
 /// in two stages.
 class CodeLens implements ToJsonable {
   static const jsonHandler =
@@ -1800,15 +1800,14 @@
     return CodeLens(range: range, command: command, data: data);
   }
 
-  /// The command this code lens represents.
+  /// The command this CodeLens represents.
   final Command command;
 
-  /// A data entry field that is preserved on a code lens item between a code
-  /// lens and a code lens resolve request.
+  /// A data entry field that is preserved on a CodeLens item between a CodeLens
+  /// and a CodeLens resolve request.
   final dynamic data;
 
-  /// The range in which this code lens is valid. Should only span a single
-  /// line.
+  /// The range in which the CodeLens is valid. Should only span a single line.
   final Range range;
 
   Map<String, dynamic> toJson() {
@@ -1903,7 +1902,7 @@
     return CodeLensClientCapabilities(dynamicRegistration: dynamicRegistration);
   }
 
-  /// Whether code lens supports dynamic registration.
+  /// Whether CodeLens supports dynamic registration.
   final bool dynamicRegistration;
 
   Map<String, dynamic> toJson() {
@@ -2071,11 +2070,11 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
-  /// The document to request code lens for.
+  /// The document to request CodeLens for.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
@@ -2188,7 +2187,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// Code lens has a resolve provider as well.
@@ -2558,12 +2557,12 @@
   final List<TextEdit> additionalTextEdits;
 
   /// The label of this color presentation. It will be shown on the color picker
-  /// header. By default this is also the text that is inserted when selecting
+  /// header. By default, this is also the text that is inserted when selecting
   /// this color presentation.
   final String label;
 
   /// An edit ([TextEdit]) which is applied to a document when selecting this
-  /// presentation for the color.  When `falsy` the
+  /// presentation for the color. When `falsy`, the
   /// [label](#ColorPresentation.label) is used.
   final TextEdit textEdit;
 
@@ -2704,8 +2703,8 @@
   /// The color information to request presentations for.
   final Color color;
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The range where the color would be inserted. Serves as a context.
@@ -3149,8 +3148,8 @@
   ///
   /// A snippet can define tab stops and placeholders with `$1`, `$2` and
   /// `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the
-  /// snippet. Placeholders with equal identifiers are linked, that is typing in
-  /// one will update others too.
+  /// snippet. Placeholders with equal identifiers are linked, so that typing in
+  /// one will update others as well.
   final bool snippetSupport;
 
   /// Client supports the tag property on a completion item. Clients supporting
@@ -3464,7 +3463,7 @@
         triggerKind: triggerKind, triggerCharacter: triggerCharacter);
   }
 
-  /// The trigger character (a single character) that has trigger code complete.
+  /// The trigger character (single character) that has trigger code complete.
   /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
   final String triggerCharacter;
 
@@ -3636,10 +3635,10 @@
   /// described with the additionalTextEdits-property.
   final Command command;
 
-  /// An optional set of characters that when pressed while this completion is
-  /// active will accept it first and then type that character. *Note* that all
-  /// commit characters should have `length=1` and that superfluous characters
-  /// will be ignored.
+  /// An optional set of characters that when pressed, while this completion is
+  /// active, will accept it first and then type that character.
+  /// *Note* that all commit characters should have `length=1` and that
+  /// superfluous characters will be ignored.
   final List<String> commitCharacters;
 
   /// A data entry field that is preserved on a completion item between a
@@ -3648,7 +3647,6 @@
 
   /// Indicates if this item is deprecated.
   ///  @deprecated Use `tags` instead if supported.
-  @core.deprecated
   final bool deprecated;
 
   /// A human-readable string with additional information about this item, like
@@ -3666,15 +3664,15 @@
   /// completion. When `falsy` the label is used.
   ///
   /// The `insertText` is subject to interpretation by the client side. Some
-  /// tools might not take the string literally. For example VS Code when code
+  /// tools might not take the string literally. For example, VS Code when code
   /// complete is requested in this example `con<cursor position>` and a
-  /// completion item with an `insertText` of `console` is provided it will only
-  /// insert `sole`. Therefore it is recommended to use `textEdit` instead since
-  /// it avoids additional client side interpretation.
+  /// completion item with an `insertText` of `console` is provided, it will
+  /// only insert `sole`. Therefore, it is recommended to use `textEdit` instead
+  /// since it avoids additional client side interpretation.
   final String insertText;
 
   /// The format of the insert text. The format applies to both the `insertText`
-  /// property and the `newText` property of a provided `textEdit`. If omitted
+  /// property and the `newText` property of a provided `textEdit`. If omitted,
   /// defaults to `InsertTextFormat.PlainText`.
   final InsertTextFormat insertTextFormat;
 
@@ -3702,8 +3700,8 @@
   ///  @since 3.15.0
   final List<CompletionItemTag> tags;
 
-  /// An edit which is applied to a document when selecting this completion.
-  /// When an edit is provided the value of `insertText` is ignored.
+  /// An edit that is applied to a document when selecting this completion. When
+  /// an edit is provided, the value of `insertText` is ignored.
   ///
   /// *Note:* The range of the edit must be a single line range and it must
   /// contain the position at which completion has been requested.
@@ -4204,11 +4202,11 @@
 
   /// The list of all possible characters that commit a completion. This field
   /// can be used if clients don't support individual commit characters per
-  /// completion item. See
-  /// `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`.
+  /// completion item. See `ClientCapabilities.`
+  /// `textDocument.completion.completionItem.commitCharactersSupport`.
   ///
   /// If a server provides both `allCommitCharacters` and commit characters on
-  /// an individual completion item the ones on the completion item win.
+  /// an individual completion item, the ones on the completion item win.
   ///  @since 3.2.0
   final List<String> allCommitCharacters;
 
@@ -4217,14 +4215,14 @@
   final bool resolveProvider;
 
   /// Most tools trigger completion request automatically without explicitly
-  /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they
-  /// do so when the user starts to type an identifier. For example if the user
-  /// types `c` in a JavaScript file code complete will automatically pop up
-  /// present `console` besides others as a completion item. Characters that
-  /// make up identifiers don't need to be listed here.
+  /// requesting it using a keyboard shortcut (for example Ctrl+Space).
+  /// Typically they do so when the user starts to type an identifier. For
+  /// example, if the user types `c` in a JavaScript file, code complete will
+  /// automatically display `console` along with others as a completion item.
+  /// Characters that make up identifiers don't need to be listed here.
   ///
-  /// If code complete should automatically be trigger on characters not being
-  /// valid inside an identifier (for example `.` in JavaScript) list them in
+  /// If code complete should automatically be triggered on characters not being
+  /// valid inside an identifier (for example `.` in JavaScript), list them in
   /// `triggerCharacters`.
   final List<String> triggerCharacters;
   final bool workDoneProgress;
@@ -4384,8 +4382,8 @@
   /// === true`
   final CompletionContext context;
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -4555,16 +4553,16 @@
 
   /// The list of all possible characters that commit a completion. This field
   /// can be used if clients don't support individual commit characters per
-  /// completion item. See
-  /// `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`.
+  /// completion item. See `ClientCapabilities.`
+  /// `textDocument.completion.completionItem.commitCharactersSupport`.
   ///
   /// If a server provides both `allCommitCharacters` and commit characters on
-  /// an individual completion item the ones on the completion item win.
+  /// an individual completion item, the ones on the completion item win.
   ///  @since 3.2.0
   final List<String> allCommitCharacters;
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The server provides support to resolve additional information for a
@@ -4572,14 +4570,14 @@
   final bool resolveProvider;
 
   /// Most tools trigger completion request automatically without explicitly
-  /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they
-  /// do so when the user starts to type an identifier. For example if the user
-  /// types `c` in a JavaScript file code complete will automatically pop up
-  /// present `console` besides others as a completion item. Characters that
-  /// make up identifiers don't need to be listed here.
+  /// requesting it using a keyboard shortcut (for example Ctrl+Space).
+  /// Typically they do so when the user starts to type an identifier. For
+  /// example, if the user types `c` in a JavaScript file, code complete will
+  /// automatically display `console` along with others as a completion item.
+  /// Characters that make up identifiers don't need to be listed here.
   ///
-  /// If code complete should automatically be trigger on characters not being
-  /// valid inside an identifier (for example `.` in JavaScript) list them in
+  /// If code complete should automatically be triggered on characters not being
+  /// valid inside an identifier (for example `.` in JavaScript), list them in
   /// `triggerCharacters`.
   final List<String> triggerCharacters;
   final bool workDoneProgress;
@@ -4724,7 +4722,7 @@
   static const Invoked = CompletionTriggerKind._(1);
 
   /// Completion was triggered by a trigger character specified by the
-  /// `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+  /// `triggerCharacters` properties of `CompletionRegistrationOptions`.
   static const TriggerCharacter = CompletionTriggerKind._(2);
 
   /// Completion was re-triggered as the current completion list is incomplete.
@@ -5103,8 +5101,8 @@
   }
 
   /// Whether declaration supports dynamic registration. If this is set to
-  /// `true` the client supports the new `DeclarationRegistrationOptions` return
-  /// value for the corresponding server capability as well.
+  /// `true`, the client supports the new `DeclarationRegistrationOptions`
+  /// return value for the corresponding server capability as well.
   final bool dynamicRegistration;
 
   /// The client supports additional metadata in the form of declaration links.
@@ -5282,8 +5280,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -5427,7 +5425,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The id used to register the request. The id can be used to deregister the
@@ -5708,8 +5706,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -5845,7 +5843,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -6346,7 +6344,7 @@
 
 /// Represents a related message and source code location for a diagnostic. This
 /// should be used to point to code locations that cause or are related to a
-/// diagnostics, e.g when duplicating a symbol in a scope.
+/// diagnostics, for example, when duplicating a symbol in a scope.
 class DiagnosticRelatedInformation implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
       DiagnosticRelatedInformation.canParse,
@@ -6679,19 +6677,18 @@
   }
 
   /// The actual content changes. The content changes describe single state
-  /// changes to the document. So if there are two content changes c1 (at array
-  /// index 0) and c2 (at array index 1) for a document in state S then c1 moves
-  /// the document from S to S' and c2 from S' to S''. So c1 is computed on the
-  /// state S and c2 is computed on the state S'.
+  /// changes to the document. If there are two content changes c1 (at array
+  /// index 0) and c2 (at array index 1) for a document in state S, then c1
+  /// moves the document from S to S' and c2 from S' to S''. So c1 is computed
+  /// on the state S and c2 is computed on the state S'.
   ///
-  /// To mirror the content of a document using change events use the following
+  /// To mirror the content of a document using change events, use the following
   /// approach:
   /// - start with the same initial content
-  /// - apply the 'textDocument/didChange' notifications in the order you
-  /// recevie them.
-  /// - apply the `TextDocumentContentChangeEvent`s in a single notification in
-  /// the order
-  ///   you receive them.
+  /// - apply the 'textDocument/didChange' notifications
+  ///     in the order you receive them.
+  /// - apply the `TextDocumentContentChangeEvent`s
+  ///     in a single notification in the order you receive them.
   final List<
       Either2<TextDocumentContentChangeEvent1,
           TextDocumentContentChangeEvent2>> contentChanges;
@@ -7484,8 +7481,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The text document.
@@ -7606,7 +7603,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The id used to register the request. The id can be used to deregister the
@@ -7717,13 +7714,13 @@
   /// - `*` to match one or more characters in a path segment
   /// - `?` to match on one character in a path segment
   /// - `**` to match any number of path segments, including none
-  /// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript
-  /// and JavaScript files)
-  /// - `[]` to declare a range of characters to match in a path segment (e.g.,
-  /// `example.[0-9]` to match on `example.0`, `example.1`, …)
+  /// - `{}` to group conditions
+  ///   (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+  /// - `[]` to declare a range of characters to match in a path segment
+  ///   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
   /// - `[!...]` to negate a range of characters to match in a path segment
-  /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not
-  /// `example.0`)
+  ///   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
+  ///    but not `example.0`)
   final String pattern;
 
   /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
@@ -8088,7 +8085,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -8460,8 +8457,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -8603,7 +8600,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -8708,7 +8705,7 @@
 
   /// The tooltip text when you hover over this link.
   ///
-  /// If a tooltip is provided, is will be displayed in a string that includes
+  /// If a tooltip is provided, it will be displayed in a string that includes
   /// instructions on how to trigger the link, such as `{0} (ctrl + click)`. The
   /// specific instructions vary depending on OS, user settings, and
   /// localization.
@@ -9013,8 +9010,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The document to provide document links for.
@@ -9134,7 +9131,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// Document links have a resolve provider as well.
@@ -9596,7 +9593,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// A character on which formatting should be triggered, like `}`.
@@ -10017,7 +10014,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -10093,7 +10090,7 @@
 /// Represents programming constructs like variables, classes, interfaces etc.
 /// that appear in a document. Document symbols can be hierarchical and they
 /// have two ranges: one that encloses its definition and one that points to its
-/// most interesting range, e.g. the range of an identifier.
+/// most interesting range, for example, the range of an identifier.
 class DocumentSymbol implements ToJsonable {
   static const jsonHandler =
       LspJsonHandler(DocumentSymbol.canParse, DocumentSymbol.fromJson);
@@ -10162,12 +10159,13 @@
 
   /// The range enclosing this symbol not including leading/trailing whitespace
   /// but everything else like comments. This information is typically used to
-  /// determine if the clients cursor is inside the symbol to reveal in the
+  /// determine if the client's cursor is inside the symbol to reveal in the
   /// symbol in the UI.
   final Range range;
 
   /// The range that should be selected and revealed when this symbol is being
-  /// picked, e.g the name of a function. Must be contained by the `range`.
+  /// picked, for example, the name of a function. Must be contained by the
+  /// `range`.
   final Range selectionRange;
 
   Map<String, dynamic> toJson() {
@@ -10621,8 +10619,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The text document.
@@ -10739,7 +10737,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -11247,9 +11245,9 @@
   /// succeed or no changes at all are applied to the workspace.
   static const Transactional = FailureHandlingKind._('transactional');
 
-  /// If the workspace edit contains only textual file changes they are executed
-  /// transactional. If resource changes (create, rename or delete file) are
-  /// part of the change the failure handling strategy is abort.
+  /// If the workspace edit contains only textual file changes, they are
+  /// executed transactionally. If resource changes (create, rename or delete
+  /// file) are part of the change, the failure handling strategy is abort.
   static const TextOnlyTransactional =
       FailureHandlingKind._('textOnlyTransactional');
 
@@ -11416,12 +11414,12 @@
   /// - `?` to match on one character in a path segment
   /// - `**` to match any number of path segments, including none
   /// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript
-  /// and JavaScript files)
-  /// - `[]` to declare a range of characters to match in a path segment (e.g.,
-  /// `example.[0-9]` to match on `example.0`, `example.1`, …)
+  ///   and JavaScript files)
+  /// - `[]` to declare a range of characters to match in a path segment
+  ///   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
   /// - `[!...]` to negate a range of characters to match in a path segment
-  /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not
-  /// `example.0`)
+  ///   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
+  ///    but not `example.0`)
   final String globPattern;
 
   /// The kind of events of interest. If omitted it defaults to WatchKind.Create
@@ -11681,15 +11679,15 @@
         lineFoldingOnly: lineFoldingOnly);
   }
 
-  /// Whether implementation supports dynamic registration for folding range
-  /// providers. If this is set to `true` the client supports the new
+  /// Whether the implementation supports dynamic registration for folding range
+  /// providers. If this is set to `true`, the client supports the new
   /// `FoldingRangeRegistrationOptions` return value for the corresponding
   /// server capability as well.
   final bool dynamicRegistration;
 
   /// If set, the client signals that it only supports folding complete lines.
-  /// If set, client will ignore specified `startCharacter` and `endCharacter`
-  /// properties in a FoldingRange.
+  /// If set, the client will ignore specified `startCharacter` and
+  /// `endCharacter` properties in a FoldingRange.
   final bool lineFoldingOnly;
 
   /// The maximum number of folding ranges that the client prefers to receive
@@ -11904,8 +11902,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The text document.
@@ -12026,7 +12024,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The id used to register the request. The id can be used to deregister the
@@ -12680,7 +12678,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -12767,7 +12765,7 @@
   }
 
   /// Whether implementation supports dynamic registration. If this is set to
-  /// `true` the client supports the new `ImplementationRegistrationOptions`
+  /// `true`, the client supports the new `ImplementationRegistrationOptions`
   /// return value for the corresponding server capability as well.
   final bool dynamicRegistration;
 
@@ -12947,8 +12945,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -13093,7 +13091,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The id used to register the request. The id can be used to deregister the
@@ -13249,15 +13247,14 @@
   /// User provided initialization options.
   final dynamic initializationOptions;
 
-  /// The process Id of the parent process that started the server. Is null if
+  /// The process ID of the parent process that started the server. Is null if
   /// the process has not been started by another process. If the parent process
-  /// is not alive then the server should exit (see exit notification) its
+  /// is not alive, then the server should exit (see exit notification) its
   /// process.
   final num processId;
 
   /// The rootPath of the workspace. Is null if no folder is open.
   ///  @deprecated in favour of rootUri.
-  @core.deprecated
   final String rootPath;
 
   /// The rootUri of the workspace. Is null if no folder is open. If both
@@ -13939,15 +13936,15 @@
   /// range at the mouse position.
   final Range originSelectionRange;
 
-  /// The full target range of this link. If the target for example is a symbol
-  /// then target range is the range enclosing this symbol not including
+  /// The full target range of this link. For example, if the target is a
+  /// symbol, then target range is the range enclosing this symbol not including
   /// leading/trailing whitespace but everything else like comments. This
   /// information is typically used to highlight the range in the editor.
   final Range targetRange;
 
   /// The range that should be selected and revealed when this link is being
-  /// followed, e.g the name of a function. Must be contained by the the
-  /// `targetRange`. See also `DocumentSymbol#range`
+  /// followed, for example, the name of a function. Must be contained by the
+  /// the `targetRange`. See also `DocumentSymbol#range`
   final Range targetSelectionRange;
 
   /// The target resource identifier of this link.
@@ -14160,16 +14157,15 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// A `MarkupContent` literal represents a string value which content is
+/// A `MarkupContent` literal represents a string value, which content is
 /// interpreted base on its kind flag. Currently the protocol supports
 /// `plaintext` and `markdown` as markup kinds.
 ///
-/// If the kind is `markdown` then the value can contain fenced code blocks like
-/// in GitHub issues. See
-/// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+/// If the kind is `markdown`, then the value can contain fenced code blocks
+/// like in GitHub issues.
 ///
-/// Here is an example how such a string can be constructed using JavaScript /
-/// TypeScript: ```typescript let markdown: MarkdownContent = {
+/// An example how such a string is constructed using JavaScript / TypeScript:
+/// ```typescript let markdown: MarkdownContent = {
 ///
 /// kind: MarkupKind.Markdown,
 /// 	value: [
@@ -14180,8 +14176,8 @@
 /// 		'```'
 /// 	].join('\n') }; ```
 ///
-/// *Please Note* that clients might sanitize the return markdown. A client
-/// could decide to remove HTML from the markdown to avoid script execution.
+/// *Please Note* that clients might sanitize the returned Markdown. A client
+/// could decide to remove HTML from the Markdown to avoid script execution.
 class MarkupContent implements ToJsonable {
   static const jsonHandler =
       LspJsonHandler(MarkupContent.canParse, MarkupContent.fromJson);
@@ -14990,8 +14986,8 @@
     return PartialResultParams(partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   Map<String, dynamic> toJson() {
@@ -15566,9 +15562,8 @@
   /// The URI for which diagnostic information is reported.
   final String uri;
 
-  /// Optional the version number of the document the diagnostics are published
-  /// for.
-  ///  @since 3.15.0
+  /// The version number of the document the diagnostics are published for.
+  /// Optional. @since 3.15.0
   final num version;
 
   Map<String, dynamic> toJson() {
@@ -16102,8 +16097,8 @@
 
   final ReferenceContext context;
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -16260,7 +16255,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
   final bool workDoneProgress;
 
@@ -17105,7 +17100,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// Renames should be checked and tested before being executed.
@@ -17796,7 +17791,7 @@
   }
 
   /// Whether implementation supports dynamic registration for selection range
-  /// providers. If this is set to `true` the client supports the new
+  /// providers. If set to `true`, the client supports the new
   /// `SelectionRangeRegistrationOptions` return value for the corresponding
   /// server capability as well.
   final bool dynamicRegistration;
@@ -17956,8 +17951,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The positions inside the text document.
@@ -18105,7 +18100,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The id used to register the request. The id can be used to deregister the
@@ -18473,7 +18468,19 @@
                 : (json['selectionRangeProvider'] == null
                     ? null
                     : (throw '''${json['selectionRangeProvider']} was not one of (bool, SelectionRangeOptions, SelectionRangeRegistrationOptions)'''))));
-    final workspaceSymbolProvider = json['workspaceSymbolProvider'];
+    final workspaceSymbolProvider = json['workspaceSymbolProvider'] is bool
+        ? Either2<bool, WorkspaceSymbolOptions>.t1(
+            json['workspaceSymbolProvider'])
+        : (WorkspaceSymbolOptions.canParse(
+                json['workspaceSymbolProvider'], nullLspJsonReporter)
+            ? Either2<bool, WorkspaceSymbolOptions>.t2(
+                json['workspaceSymbolProvider'] != null
+                    ? WorkspaceSymbolOptions.fromJson(
+                        json['workspaceSymbolProvider'])
+                    : null)
+            : (json['workspaceSymbolProvider'] == null
+                ? null
+                : (throw '''${json['workspaceSymbolProvider']} was not one of (bool, WorkspaceSymbolOptions)''')));
     final workspace = json['workspace'] != null
         ? ServerCapabilitiesWorkspace.fromJson(json['workspace'])
         : null;
@@ -18511,7 +18518,7 @@
   /// property `textDocument.codeAction.codeActionLiteralSupport`.
   final Either2<bool, CodeActionOptions> codeActionProvider;
 
-  /// The server provides code lens.
+  /// The server provides CodeLens.
   final CodeLensOptions codeLensProvider;
 
   /// The server provides color provider support.
@@ -18585,8 +18592,8 @@
   final SignatureHelpOptions signatureHelpProvider;
 
   /// Defines how text documents are synced. Is either a detailed structure
-  /// defining each notification or for backwards compatibility the
-  /// TextDocumentSyncKind number. If omitted it defaults to
+  /// defining each notification or for backwards compatibility, the
+  /// TextDocumentSyncKind number. If omitted, it defaults to
   /// `TextDocumentSyncKind.None`.
   final Either2<TextDocumentSyncOptions, num> textDocumentSync;
 
@@ -18599,7 +18606,7 @@
   final ServerCapabilitiesWorkspace workspace;
 
   /// The server provides workspace symbol support.
-  final bool workspaceSymbolProvider;
+  final Either2<bool, WorkspaceSymbolOptions> workspaceSymbolProvider;
 
   Map<String, dynamic> toJson() {
     var __result = <String, dynamic>{};
@@ -18969,8 +18976,11 @@
       reporter.push('workspaceSymbolProvider');
       try {
         if (obj['workspaceSymbolProvider'] != null &&
-            !(obj['workspaceSymbolProvider'] is bool)) {
-          reporter.reportError('must be of type bool');
+            !((obj['workspaceSymbolProvider'] is bool ||
+                WorkspaceSymbolOptions.canParse(
+                    obj['workspaceSymbolProvider'], reporter)))) {
+          reporter.reportError(
+              'must be of type Either2<bool, WorkspaceSymbolOptions>');
           return false;
         }
       } finally {
@@ -19411,7 +19421,7 @@
   /// better express this.
   final num activeSignature;
 
-  /// One or more signatures. If no signaures are availabe the signature help
+  /// One or more signatures. If no signatures are available the signature help
   /// request should return `null`.
   final List<SignatureInformation> signatures;
 
@@ -19838,7 +19848,7 @@
   /// Character that caused signature help to be triggered.
   ///
   /// This is undefined when `triggerKind !==
-  /// SignatureHelpTriggerKind.TriggerCharacter`
+  /// SignatureHelpTriggerKind.TriggerCharacter`.
   final String triggerCharacter;
 
   /// Action that caused signature help to be triggered.
@@ -20113,7 +20123,7 @@
 
   /// The signature help context. This is only available if the client specifies
   /// to send this using the client capability
-  /// `textDocument.signatureHelp.contextSupport === true`
+  /// `textDocument.signatureHelp.contextSupport === true`.
   ///  @since 3.15.0
   final SignatureHelpContext context;
 
@@ -20268,7 +20278,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// List of characters that re-trigger signature help.
@@ -20891,7 +20901,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// How documents are synced to the server. See TextDocumentSyncKind.Full and
@@ -21594,7 +21604,6 @@
 
   /// The optional length of the range that got replaced.
   ///  @deprecated use range instead.
-  @core.deprecated
   final num rangeLength;
 
   /// The new text for the provided range.
@@ -22322,7 +22331,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   Map<String, dynamic> toJson() {
@@ -22389,8 +22398,8 @@
     return obj is num;
   }
 
-  /// Manually triggered, e.g. by the user pressing save, by starting debugging,
-  /// or by an API call.
+  /// Manually triggered, for example, by the user pressing save, by starting
+  /// debugging, or by an API call.
   static const Manual = TextDocumentSaveReason(1);
 
   /// Automatic after a delay.
@@ -22431,7 +22440,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The client is supposed to include the content on save.
@@ -22702,25 +22711,25 @@
   }
 
   /// Change notifications are sent to the server. See
-  /// TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
-  /// TextDocumentSyncKind.Incremental. If omitted it defaults to
+  /// TextDocumentSyncKind.None, TextDocumentSyncKind.Full, and
+  /// TextDocumentSyncKind.Incremental. If omitted, it defaults to
   /// TextDocumentSyncKind.None.
   final TextDocumentSyncKind change;
 
-  /// Open and close notifications are sent to the server. If omitted open close
-  /// notification should not be sent.
+  /// Open and close notifications are sent to the server. If omitted, open
+  /// close notification should not be sent.
   final bool openClose;
 
-  /// If present save notifications are sent to the server. If omitted the
+  /// If present save notifications are sent to the server. If omitted, the
   /// notification should not be sent.
   final Either2<bool, SaveOptions> save;
 
-  /// If present will save notifications are sent to the server. If omitted the
+  /// If present will save notifications are sent to the server. If omitted, the
   /// notification should not be sent.
   final bool willSave;
 
   /// If present will save wait until requests are sent to the server. If
-  /// omitted the request should not be sent.
+  /// omitted, the request should not be sent.
   final bool willSaveWaitUntil;
 
   Map<String, dynamic> toJson() {
@@ -22942,7 +22951,7 @@
   }
 
   /// Whether implementation supports dynamic registration. If this is set to
-  /// `true` the client supports the new `TypeDefinitionRegistrationOptions`
+  /// `true`, the client supports the new ` TypeDefinitionRegistrationOptions`
   /// return value for the corresponding server capability as well.
   final bool dynamicRegistration;
 
@@ -23122,8 +23131,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// The position inside the text document.
@@ -23268,7 +23277,7 @@
   }
 
   /// A document selector to identify the scope of the registration. If set to
-  /// null the document selector provided on the client side will be used.
+  /// null, the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
 
   /// The id used to register the request. The id can be used to deregister the
@@ -23555,9 +23564,10 @@
 
   /// The version number of this document. If a versioned text document
   /// identifier is sent from the server to the client and the file is not open
-  /// in the editor (the server has not received an open notification before)
+  /// in the editor (the server has not received an open notification before),
   /// the server can send `null` to indicate that the version is known and the
-  /// content on disk is the master (as speced with document content ownership).
+  /// content on disk is the master (as specified with document content
+  /// ownership).
   ///
   /// The version number of a document will increase after each change,
   /// including undo/redo. The number doesn't need to be consecutive.
@@ -23795,8 +23805,8 @@
   }
 
   /// Controls if a cancel button should show to allow the user to cancel the
-  /// long running operation. Clients that don't support cancellation are
-  /// allowed to ignore the setting.
+  /// long running operation. Clients that don't support cancellation can ignore
+  /// the setting.
   final bool cancellable;
   final String kind;
 
@@ -24450,10 +24460,11 @@
         percentage: percentage);
   }
 
-  /// Controls enablement state of a cancel button. This property is only valid
-  /// if a cancel button got requested in the `WorkDoneProgressStart` payload.
+  /// Controls enablement state of a cancel button. T This property is only
+  /// valid if a cancel button is requested in the `WorkDoneProgressStart`
+  /// payload.
   ///
-  /// Clients that don't support cancellation or don't support control the
+  /// Clients that don't support cancellation or don't support controlling the
   /// button's enablement state are allowed to ignore the setting.
   final bool cancellable;
   final String kind;
@@ -24606,18 +24617,18 @@
   /// Holds changes to existing resources.
   final Map<String, List<TextEdit>> changes;
 
-  /// Depending on the client capability
-  /// `workspace.workspaceEdit.resourceOperations` document changes are either
-  /// an array of `TextDocumentEdit`s to express changes to n different text
-  /// documents where each text document edit addresses a specific version of a
-  /// text document. Or it can contain above `TextDocumentEdit`s mixed with
-  /// create, rename and delete file / folder operations.
+  /// The client capability `workspace.workspaceEdit.resourceOperations`
+  /// determines whether document changes are either an array of
+  /// `TextDocumentEdit`s to express changes to different text documents, where
+  /// each text document edit addresses a specific version of a text document,
+  /// or it can contains the above `TextDocumentEdit`s mixed with create,
+  /// rename, and delete file / folder operations.
   ///
   /// Whether a client supports versioned document edits is expressed via
   /// `workspace.workspaceEdit.documentChanges` client capability.
   ///
-  /// If a client neither supports `documentChanges` nor
-  /// `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
+  /// If a client doesn't support `documentChanges` or
+  /// `workspace.workspaceEdit.resourceOperations`, then only plain `TextEdit`s
   /// using the `changes` property are supported.
   final Either2<List<TextDocumentEdit>,
           List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>
@@ -25384,8 +25395,8 @@
         partialResultToken: partialResultToken);
   }
 
-  /// An optional token that a server can use to report partial results (e.g.
-  /// streaming) to the client.
+  /// An optional token that a server can use to report partial results (for
+  /// example, streaming) to the client.
   final Either2<num, String> partialResultToken;
 
   /// A query string to filter symbols by. Clients may send an empty string here
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
index 54b682a..3154306 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
@@ -3,12 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 
 /// An object used to provide context information for Dart assist contributors.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class DartAssistContext {
+  /// Return the instrumentation service used to report errors that prevent a
+  /// fix from being composed.
+  InstrumentationService get instrumentationService;
+
   /// The resolution result in which assist operates.
   ResolvedUnitResult get resolveResult;
 
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index ede6d26..4792bed 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -5,12 +5,17 @@
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 
 /// An object used to provide context information for [DartFixContributor]s.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class DartFixContext implements FixContext {
+  /// Return the instrumentation service used to report errors that prevent a
+  /// fix from being composed.
+  InstrumentationService get instrumentationService;
+
   /// The resolution result in which fix operates.
   ResolvedUnitResult get resolveResult;
 
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 25f5a64..7636ffc 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.30.0';
+const String PROTOCOL_VERSION = '1.32.1';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -222,6 +222,7 @@
 const String EDIT_REQUEST_ORGANIZE_DIRECTIVES_FILE = 'file';
 const String EDIT_REQUEST_SORT_MEMBERS = 'edit.sortMembers';
 const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file';
+const String EDIT_RESPONSE_BULK_FIXES_DETAILS = 'details';
 const String EDIT_RESPONSE_BULK_FIXES_EDITS = 'edits';
 const String EDIT_RESPONSE_DARTFIX_DETAILS = 'details';
 const String EDIT_RESPONSE_DARTFIX_EDITS = 'edits';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 06c3551..3cf16bf 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -4955,6 +4955,188 @@
   }
 }
 
+/// BulkFix
+///
+/// {
+///   "path": FilePath
+///   "fixes": List<BulkFixDetail>
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class BulkFix implements HasToJson {
+  String _path;
+
+  List<BulkFixDetail> _fixes;
+
+  /// The path of the library.
+  String get path => _path;
+
+  /// The path of the library.
+  set path(String value) {
+    assert(value != null);
+    _path = value;
+  }
+
+  /// A list of bulk fix details.
+  List<BulkFixDetail> get fixes => _fixes;
+
+  /// A list of bulk fix details.
+  set fixes(List<BulkFixDetail> value) {
+    assert(value != null);
+    _fixes = value;
+  }
+
+  BulkFix(String path, List<BulkFixDetail> fixes) {
+    this.path = path;
+    this.fixes = fixes;
+  }
+
+  factory BulkFix.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    json ??= {};
+    if (json is Map) {
+      String path;
+      if (json.containsKey('path')) {
+        path = jsonDecoder.decodeString(jsonPath + '.path', json['path']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'path');
+      }
+      List<BulkFixDetail> fixes;
+      if (json.containsKey('fixes')) {
+        fixes = jsonDecoder.decodeList(
+            jsonPath + '.fixes',
+            json['fixes'],
+            (String jsonPath, Object json) =>
+                BulkFixDetail.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'fixes');
+      }
+      return BulkFix(path, fixes);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'BulkFix', json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var result = <String, dynamic>{};
+    result['path'] = path;
+    result['fixes'] =
+        fixes.map((BulkFixDetail value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is BulkFix) {
+      return path == other.path &&
+          listEqual(
+              fixes, other.fixes, (BulkFixDetail a, BulkFixDetail b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, path.hashCode);
+    hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/// BulkFixDetail
+///
+/// {
+///   "code": String
+///   "occurrences": int
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class BulkFixDetail implements HasToJson {
+  String _code;
+
+  int _occurrences;
+
+  /// The code of the diagnostic associated with the fix.
+  String get code => _code;
+
+  /// The code of the diagnostic associated with the fix.
+  set code(String value) {
+    assert(value != null);
+    _code = value;
+  }
+
+  /// The number times the associated diagnostic was fixed in the associated
+  /// source edit.
+  int get occurrences => _occurrences;
+
+  /// The number times the associated diagnostic was fixed in the associated
+  /// source edit.
+  set occurrences(int value) {
+    assert(value != null);
+    _occurrences = value;
+  }
+
+  BulkFixDetail(String code, int occurrences) {
+    this.code = code;
+    this.occurrences = occurrences;
+  }
+
+  factory BulkFixDetail.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    json ??= {};
+    if (json is Map) {
+      String code;
+      if (json.containsKey('code')) {
+        code = jsonDecoder.decodeString(jsonPath + '.code', json['code']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'code');
+      }
+      int occurrences;
+      if (json.containsKey('occurrences')) {
+        occurrences = jsonDecoder.decodeInt(
+            jsonPath + '.occurrences', json['occurrences']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'occurrences');
+      }
+      return BulkFixDetail(code, occurrences);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'BulkFixDetail', json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var result = <String, dynamic>{};
+    result['code'] = code;
+    result['occurrences'] = occurrences;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is BulkFixDetail) {
+      return code == other.code && occurrences == other.occurrences;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, code.hashCode);
+    hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
 /// ClosingLabel
 ///
 /// {
@@ -7210,12 +7392,15 @@
 ///
 /// {
 ///   "edits": List<SourceFileEdit>
+///   "details": List<BulkFix>
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditBulkFixesResult implements ResponseResult {
   List<SourceFileEdit> _edits;
 
+  List<BulkFix> _details;
+
   /// A list of source edits to apply the recommended changes.
   List<SourceFileEdit> get edits => _edits;
 
@@ -7225,8 +7410,18 @@
     _edits = value;
   }
 
-  EditBulkFixesResult(List<SourceFileEdit> edits) {
+  /// Details that summarize the fixes associated with the recommended changes.
+  List<BulkFix> get details => _details;
+
+  /// Details that summarize the fixes associated with the recommended changes.
+  set details(List<BulkFix> value) {
+    assert(value != null);
+    _details = value;
+  }
+
+  EditBulkFixesResult(List<SourceFileEdit> edits, List<BulkFix> details) {
     this.edits = edits;
+    this.details = details;
   }
 
   factory EditBulkFixesResult.fromJson(
@@ -7243,7 +7438,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
       }
-      return EditBulkFixesResult(edits);
+      List<BulkFix> details;
+      if (json.containsKey('details')) {
+        details = jsonDecoder.decodeList(
+            jsonPath + '.details',
+            json['details'],
+            (String jsonPath, Object json) =>
+                BulkFix.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'details');
+      }
+      return EditBulkFixesResult(edits, details);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'edit.bulkFixes result', json);
     }
@@ -7261,6 +7466,7 @@
     var result = <String, dynamic>{};
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
+    result['details'] = details.map((BulkFix value) => value.toJson()).toList();
     return result;
   }
 
@@ -7275,8 +7481,9 @@
   @override
   bool operator ==(other) {
     if (other is EditBulkFixesResult) {
-      return listEqual(
-          edits, other.edits, (SourceFileEdit a, SourceFileEdit b) => a == b);
+      return listEqual(edits, other.edits,
+              (SourceFileEdit a, SourceFileEdit b) => a == b) &&
+          listEqual(details, other.details, (BulkFix a, BulkFix b) => a == b);
     }
     return false;
   }
@@ -7285,6 +7492,7 @@
   int get hashCode {
     var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
+    hash = JenkinsSmiHash.combine(hash, details.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index ce3c063..4599f0a 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -16,7 +16,6 @@
 import 'package:analysis_server/src/analysis_server_abstract.dart';
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/computer/computer_highlights.dart';
-import 'package:analysis_server/src/computer/computer_highlights2.dart';
 import 'package:analysis_server/src/computer/new_notifications.dart';
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
@@ -601,9 +600,6 @@
 
 /// Various IDE options.
 class AnalysisServerOptions {
-  bool useAnalysisHighlight2 = false;
-
-  String fileReadMode = 'as-is';
   String newAnalysisDriverLog;
 
   String clientId;
@@ -629,15 +625,6 @@
   /// Whether to use the Language Server Protocol.
   bool useLanguageServerProtocol = false;
 
-  /// Base path to locate trained completion language model files.
-  ///
-  /// ML completion is enabled if this is non-null.
-  String completionModelFolder;
-
-  /// Return `true` if the new relevance computations should be used when
-  /// computing code completion suggestions.
-  bool useNewRelevance = true;
-
   /// The set of enabled features.
   FeatureSet featureSet = FeatureSet();
 }
@@ -829,11 +816,7 @@
   }
 
   List<HighlightRegion> _computeHighlightRegions(CompilationUnit unit) {
-    if (analysisServer.options.useAnalysisHighlight2) {
-      return DartUnitHighlightsComputer2(unit).compute();
-    } else {
-      return DartUnitHighlightsComputer(unit).compute();
-    }
+    return DartUnitHighlightsComputer(unit).compute();
   }
 
   server.AnalysisNavigationParams _computeNavigationParams(
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
index 7864fa2..9c33f83 100644
--- a/pkg/analysis_server/lib/src/cider/completion.dart
+++ b/pkg/analysis_server/lib/src/cider/completion.dart
@@ -77,7 +77,6 @@
       var completionRequest = CompletionRequestImpl(
         resolvedUnit,
         offset,
-        false,
         CompletionPerformance(),
       );
       var dartdocDirectiveInfo = DartdocDirectiveInfo();
diff --git a/pkg/analysis_server/lib/src/cider/fixes.dart b/pkg/analysis_server/lib/src/cider/fixes.dart
index 099287a..60f649e 100644
--- a/pkg/analysis_server/lib/src/cider/fixes.dart
+++ b/pkg/analysis_server/lib/src/cider/fixes.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:meta/meta.dart';
@@ -43,6 +44,7 @@
         if (errorLine == requestLine) {
           var workspace = DartChangeWorkspace([resolvedUnit.session]);
           var context = DartFixContextImpl(
+            InstrumentationService.NULL_SERVICE,
             workspace,
             resolvedUnit,
             error,
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 3c280ff..df56229 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -64,15 +64,15 @@
     if (_addIdentifierRegion_constructor(node)) {
       return;
     }
-    if (_addIdentifierRegion_dynamicType(node)) {
-      return;
-    }
     if (_addIdentifierRegion_getterSetterDeclaration(node)) {
       return;
     }
     if (_addIdentifierRegion_field(node)) {
       return;
     }
+    if (_addIdentifierRegion_dynamicLocal(node)) {
+      return;
+    }
     if (_addIdentifierRegion_function(node)) {
       return;
     }
@@ -97,6 +97,9 @@
     if (_addIdentifierRegion_typeParameter(node)) {
       return;
     }
+    if (_addIdentifierRegion_unresolvedInstanceMemberReference(node)) {
+      return;
+    }
     _addRegion_node(node, HighlightRegionType.IDENTIFIER_DEFAULT);
   }
 
@@ -141,14 +144,25 @@
     return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR);
   }
 
-  bool _addIdentifierRegion_dynamicType(SimpleIdentifier node) {
+  bool _addIdentifierRegion_dynamicLocal(SimpleIdentifier node) {
     var element = node.writeOrReadElement;
-    if (element is VariableElement) {
-      var staticType = element.type;
-      if (staticType == null || !staticType.isDynamic) {
-        return false;
+    if (element is LocalVariableElement) {
+      var elementType = element.type;
+      if (elementType?.isDynamic == true) {
+        var type = node.inDeclarationContext()
+            ? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION
+            : HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE;
+        return _addRegion_node(node, type);
       }
-      return _addRegion_node(node, HighlightRegionType.DYNAMIC_TYPE);
+    }
+    if (element is ParameterElement) {
+      var elementType = element.type;
+      if (elementType?.isDynamic == true) {
+        var type = node.inDeclarationContext()
+            ? HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION
+            : HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE;
+        return _addRegion_node(node, type);
+      }
     }
     return false;
   }
@@ -156,10 +170,9 @@
   bool _addIdentifierRegion_field(SimpleIdentifier node) {
     var element = node.writeOrReadElement;
     if (element is FieldFormalParameterElement) {
-      element = (element as FieldFormalParameterElement).field;
-    }
-    if (element is PropertyAccessorElement) {
-      element = (element as PropertyAccessorElement).variable;
+      if (node.parent is FieldFormalParameter) {
+        element = (element as FieldFormalParameterElement).field;
+      }
     }
     // prepare type
     HighlightRegionType type;
@@ -168,12 +181,33 @@
       if (enclosingElement is ClassElement && enclosingElement.isEnum) {
         type = HighlightRegionType.ENUM_CONSTANT;
       } else if (element.isStatic) {
-        type = HighlightRegionType.FIELD_STATIC;
+        type = HighlightRegionType.STATIC_FIELD_DECLARATION;
       } else {
-        type = HighlightRegionType.FIELD;
+        type = node.inDeclarationContext()
+            ? HighlightRegionType.INSTANCE_FIELD_DECLARATION
+            : HighlightRegionType.INSTANCE_FIELD_REFERENCE;
       }
     } else if (element is TopLevelVariableElement) {
-      type = HighlightRegionType.TOP_LEVEL_VARIABLE;
+      type = HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION;
+    }
+    if (element is PropertyAccessorElement) {
+      var accessor = element;
+      var enclosingElement = element.enclosingElement;
+      if (accessor.variable is TopLevelVariableElement) {
+        type = accessor.isGetter
+            ? HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE
+            : HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE;
+      } else if (enclosingElement is ClassElement && enclosingElement.isEnum) {
+        type = HighlightRegionType.ENUM_CONSTANT;
+      } else if (accessor.isStatic) {
+        type = accessor.isGetter
+            ? HighlightRegionType.STATIC_GETTER_REFERENCE
+            : HighlightRegionType.STATIC_SETTER_REFERENCE;
+      } else {
+        type = accessor.isGetter
+            ? HighlightRegionType.INSTANCE_GETTER_REFERENCE
+            : HighlightRegionType.INSTANCE_SETTER_REFERENCE;
+      }
     }
     // add region
     if (type != null) {
@@ -188,10 +222,15 @@
       return false;
     }
     HighlightRegionType type;
+    var isTopLevel = element.enclosingElement is CompilationUnitElement;
     if (node.inDeclarationContext()) {
-      type = HighlightRegionType.FUNCTION_DECLARATION;
+      type = isTopLevel
+          ? HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION
+          : HighlightRegionType.LOCAL_FUNCTION_DECLARATION;
     } else {
-      type = HighlightRegionType.FUNCTION;
+      type = isTopLevel
+          ? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE
+          : HighlightRegionType.LOCAL_FUNCTION_REFERENCE;
     }
     return _addRegion_node(node, type);
   }
@@ -217,11 +256,26 @@
     }
     // getter or setter
     var propertyAccessorElement = element as PropertyAccessorElement;
+    var isTopLevel = element.enclosingElement is CompilationUnitElement;
+    HighlightRegionType type;
     if (propertyAccessorElement.isGetter) {
-      return _addRegion_node(node, HighlightRegionType.GETTER_DECLARATION);
+      if (isTopLevel) {
+        type = HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION;
+      } else if (propertyAccessorElement.isStatic) {
+        type = HighlightRegionType.STATIC_GETTER_DECLARATION;
+      } else {
+        type = HighlightRegionType.INSTANCE_GETTER_DECLARATION;
+      }
     } else {
-      return _addRegion_node(node, HighlightRegionType.SETTER_DECLARATION);
+      if (isTopLevel) {
+        type = HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION;
+      } else if (propertyAccessorElement.isStatic) {
+        type = HighlightRegionType.STATIC_SETTER_DECLARATION;
+      } else {
+        type = HighlightRegionType.INSTANCE_SETTER_DECLARATION;
+      }
     }
+    return _addRegion_node(node, type);
   }
 
   bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) {
@@ -254,12 +308,9 @@
       return false;
     }
     // OK
-    HighlightRegionType type;
-    if (node.inDeclarationContext()) {
-      type = HighlightRegionType.LOCAL_VARIABLE_DECLARATION;
-    } else {
-      type = HighlightRegionType.LOCAL_VARIABLE;
-    }
+    var type = node.inDeclarationContext()
+        ? HighlightRegionType.LOCAL_VARIABLE_DECLARATION
+        : HighlightRegionType.LOCAL_VARIABLE_REFERENCE;
     return _addRegion_node(node, type);
   }
 
@@ -274,15 +325,15 @@
     HighlightRegionType type;
     if (node.inDeclarationContext()) {
       if (isStatic) {
-        type = HighlightRegionType.METHOD_DECLARATION_STATIC;
+        type = HighlightRegionType.STATIC_METHOD_DECLARATION;
       } else {
-        type = HighlightRegionType.METHOD_DECLARATION;
+        type = HighlightRegionType.INSTANCE_METHOD_DECLARATION;
       }
     } else {
       if (isStatic) {
-        type = HighlightRegionType.METHOD_STATIC;
+        type = HighlightRegionType.STATIC_METHOD_REFERENCE;
       } else {
-        type = HighlightRegionType.METHOD;
+        type = HighlightRegionType.INSTANCE_METHOD_REFERENCE;
       }
     }
     return _addRegion_node(node, type);
@@ -293,7 +344,10 @@
     if (element is! ParameterElement) {
       return false;
     }
-    return _addRegion_node(node, HighlightRegionType.PARAMETER);
+    var type = node.inDeclarationContext()
+        ? HighlightRegionType.PARAMETER_DECLARATION
+        : HighlightRegionType.PARAMETER_REFERENCE;
+    return _addRegion_node(node, type);
   }
 
   bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) {
@@ -304,6 +358,38 @@
     return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER);
   }
 
+  bool _addIdentifierRegion_unresolvedInstanceMemberReference(
+      SimpleIdentifier node) {
+    // unresolved
+    var element = node.writeOrReadElement;
+    if (element != null) {
+      return false;
+    }
+    // invoke / get / set
+    var decorate = false;
+    var parent = node.parent;
+    if (parent is MethodInvocation) {
+      var target = parent.realTarget;
+      if (parent.methodName == node &&
+          target != null &&
+          _isDynamicExpression(target)) {
+        decorate = true;
+      }
+    } else if (node.inGetterContext() || node.inSetterContext()) {
+      if (parent is PrefixedIdentifier) {
+        decorate = parent.identifier == node;
+      } else if (parent is PropertyAccess) {
+        decorate = parent.propertyName == node;
+      }
+    }
+    if (decorate) {
+      _addRegion_node(
+          node, HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE);
+      return true;
+    }
+    return false;
+  }
+
   void _addRegion(int offset, int length, HighlightRegionType type) {
     _regions.add(HighlightRegion(type, offset, length));
   }
@@ -336,6 +422,11 @@
     var end = b.end;
     _addRegion(offset, end - offset, type);
   }
+
+  static bool _isDynamicExpression(Expression e) {
+    var type = e.staticType;
+    return type != null && type.isDynamic;
+  }
 }
 
 /// An AST visitor for [DartUnitHighlightsComputer].
@@ -622,6 +713,12 @@
   }
 
   @override
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    computer._addRegion_node(node, HighlightRegionType.LIBRARY_NAME);
+    null;
+  }
+
+  @override
   void visitListLiteral(ListLiteral node) {
     computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
     computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
@@ -660,6 +757,12 @@
   }
 
   @override
+  void visitNullLiteral(NullLiteral node) {
+    computer._addRegion_token(node.literal, HighlightRegionType.KEYWORD);
+    super.visitNullLiteral(node);
+  }
+
+  @override
   void visitOnClause(OnClause node) {
     computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
     super.visitOnClause(node);
@@ -762,6 +865,12 @@
   }
 
   @override
+  void visitThrowExpression(ThrowExpression node) {
+    computer._addRegion_token(node.throwKeyword, HighlightRegionType.KEYWORD);
+    super.visitThrowExpression(node);
+  }
+
+  @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
deleted file mode 100644
index 70489fe..0000000
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ /dev/null
@@ -1,937 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/extensions.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
-
-/// A computer for [HighlightRegion]s in a Dart [CompilationUnit].
-class DartUnitHighlightsComputer2 {
-  final CompilationUnit _unit;
-
-  final List<HighlightRegion> _regions = <HighlightRegion>[];
-
-  DartUnitHighlightsComputer2(this._unit);
-
-  /// Returns the computed highlight regions, not `null`.
-  List<HighlightRegion> compute() {
-    _unit.accept(_DartUnitHighlightsComputerVisitor2(this));
-    _addCommentRanges();
-    return _regions;
-  }
-
-  void _addCommentRanges() {
-    var token = _unit.beginToken;
-    while (token != null) {
-      Token commentToken = token.precedingComments;
-      while (commentToken != null) {
-        HighlightRegionType highlightType;
-        if (commentToken.type == TokenType.MULTI_LINE_COMMENT) {
-          if (commentToken.lexeme.startsWith('/**')) {
-            highlightType = HighlightRegionType.COMMENT_DOCUMENTATION;
-          } else {
-            highlightType = HighlightRegionType.COMMENT_BLOCK;
-          }
-        }
-        if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
-          highlightType = HighlightRegionType.COMMENT_END_OF_LINE;
-        }
-        if (highlightType != null) {
-          _addRegion_token(commentToken, highlightType);
-        }
-        commentToken = commentToken.next;
-      }
-      if (token.type == TokenType.EOF) {
-        // Only exit the loop *after* processing the EOF token as it may
-        // have preceeding comments.
-        break;
-      }
-      token = token.next;
-    }
-  }
-
-  void _addIdentifierRegion(SimpleIdentifier node) {
-    if (_addIdentifierRegion_keyword(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_class(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_constructor(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_getterSetterDeclaration(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_field(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_dynamicLocal(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_function(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_functionTypeAlias(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_importPrefix(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_label(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_localVariable(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_method(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_parameter(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_typeParameter(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_unresolvedInstanceMemberReference(node)) {
-      return;
-    }
-    _addRegion_node(node, HighlightRegionType.IDENTIFIER_DEFAULT);
-  }
-
-  void _addIdentifierRegion_annotation(Annotation node) {
-    var arguments = node.arguments;
-    if (arguments == null) {
-      _addRegion_node(node, HighlightRegionType.ANNOTATION);
-    } else {
-      _addRegion_nodeStart_tokenEnd(
-          node, arguments.beginToken, HighlightRegionType.ANNOTATION);
-      _addRegion_token(arguments.endToken, HighlightRegionType.ANNOTATION);
-    }
-  }
-
-  bool _addIdentifierRegion_class(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! ClassElement) {
-      return false;
-    }
-    ClassElement classElement = element;
-    // prepare type
-    HighlightRegionType type;
-    if (node.parent is TypeName &&
-        node.parent.parent is ConstructorName &&
-        node.parent.parent.parent is InstanceCreationExpression) {
-      // new Class()
-      type = HighlightRegionType.CONSTRUCTOR;
-    } else if (classElement.isEnum) {
-      type = HighlightRegionType.ENUM;
-    } else {
-      type = HighlightRegionType.CLASS;
-    }
-    // add region
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_constructor(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! ConstructorElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR);
-  }
-
-  bool _addIdentifierRegion_dynamicLocal(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is LocalVariableElement) {
-      var elementType = element.type;
-      if (elementType?.isDynamic == true) {
-        var type = node.inDeclarationContext()
-            ? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION
-            : HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE;
-        return _addRegion_node(node, type);
-      }
-    }
-    if (element is ParameterElement) {
-      var elementType = element.type;
-      if (elementType?.isDynamic == true) {
-        var type = node.inDeclarationContext()
-            ? HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION
-            : HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE;
-        return _addRegion_node(node, type);
-      }
-    }
-    return false;
-  }
-
-  bool _addIdentifierRegion_field(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is FieldFormalParameterElement) {
-      if (node.parent is FieldFormalParameter) {
-        element = (element as FieldFormalParameterElement).field;
-      }
-    }
-    // prepare type
-    HighlightRegionType type;
-    if (element is FieldElement) {
-      var enclosingElement = element.enclosingElement;
-      if (enclosingElement is ClassElement && enclosingElement.isEnum) {
-        type = HighlightRegionType.ENUM_CONSTANT;
-      } else if (element.isStatic) {
-        type = HighlightRegionType.STATIC_FIELD_DECLARATION;
-      } else {
-        type = node.inDeclarationContext()
-            ? HighlightRegionType.INSTANCE_FIELD_DECLARATION
-            : HighlightRegionType.INSTANCE_FIELD_REFERENCE;
-      }
-    } else if (element is TopLevelVariableElement) {
-      type = HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION;
-    }
-    if (element is PropertyAccessorElement) {
-      var accessor = element;
-      var enclosingElement = element.enclosingElement;
-      if (accessor.variable is TopLevelVariableElement) {
-        type = accessor.isGetter
-            ? HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE
-            : HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE;
-      } else if (enclosingElement is ClassElement && enclosingElement.isEnum) {
-        type = HighlightRegionType.ENUM_CONSTANT;
-      } else if (accessor.isStatic) {
-        type = accessor.isGetter
-            ? HighlightRegionType.STATIC_GETTER_REFERENCE
-            : HighlightRegionType.STATIC_SETTER_REFERENCE;
-      } else {
-        type = accessor.isGetter
-            ? HighlightRegionType.INSTANCE_GETTER_REFERENCE
-            : HighlightRegionType.INSTANCE_SETTER_REFERENCE;
-      }
-    }
-    // add region
-    if (type != null) {
-      return _addRegion_node(node, type);
-    }
-    return false;
-  }
-
-  bool _addIdentifierRegion_function(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! FunctionElement) {
-      return false;
-    }
-    HighlightRegionType type;
-    var isTopLevel = element.enclosingElement is CompilationUnitElement;
-    if (node.inDeclarationContext()) {
-      type = isTopLevel
-          ? HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION
-          : HighlightRegionType.LOCAL_FUNCTION_DECLARATION;
-    } else {
-      type = isTopLevel
-          ? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE
-          : HighlightRegionType.LOCAL_FUNCTION_REFERENCE;
-    }
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! FunctionTypeAliasElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS);
-  }
-
-  bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) {
-    // should be declaration
-    var parent = node.parent;
-    if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) {
-      return false;
-    }
-    // should be property accessor
-    var element = node.writeOrReadElement;
-    if (element is! PropertyAccessorElement) {
-      return false;
-    }
-    // getter or setter
-    var propertyAccessorElement = element as PropertyAccessorElement;
-    var isTopLevel = element.enclosingElement is CompilationUnitElement;
-    HighlightRegionType type;
-    if (propertyAccessorElement.isGetter) {
-      if (isTopLevel) {
-        type = HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION;
-      } else if (propertyAccessorElement.isStatic) {
-        type = HighlightRegionType.STATIC_GETTER_DECLARATION;
-      } else {
-        type = HighlightRegionType.INSTANCE_GETTER_DECLARATION;
-      }
-    } else {
-      if (isTopLevel) {
-        type = HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION;
-      } else if (propertyAccessorElement.isStatic) {
-        type = HighlightRegionType.STATIC_SETTER_DECLARATION;
-      } else {
-        type = HighlightRegionType.INSTANCE_SETTER_DECLARATION;
-      }
-    }
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! PrefixElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX);
-  }
-
-  bool _addIdentifierRegion_keyword(SimpleIdentifier node) {
-    var name = node.name;
-    if (name == 'void') {
-      return _addRegion_node(node, HighlightRegionType.KEYWORD);
-    }
-    return false;
-  }
-
-  bool _addIdentifierRegion_label(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! LabelElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.LABEL);
-  }
-
-  bool _addIdentifierRegion_localVariable(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! LocalVariableElement) {
-      return false;
-    }
-    // OK
-    var type = node.inDeclarationContext()
-        ? HighlightRegionType.LOCAL_VARIABLE_DECLARATION
-        : HighlightRegionType.LOCAL_VARIABLE_REFERENCE;
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_method(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! MethodElement) {
-      return false;
-    }
-    var methodElement = element as MethodElement;
-    var isStatic = methodElement.isStatic;
-    // OK
-    HighlightRegionType type;
-    if (node.inDeclarationContext()) {
-      if (isStatic) {
-        type = HighlightRegionType.STATIC_METHOD_DECLARATION;
-      } else {
-        type = HighlightRegionType.INSTANCE_METHOD_DECLARATION;
-      }
-    } else {
-      if (isStatic) {
-        type = HighlightRegionType.STATIC_METHOD_REFERENCE;
-      } else {
-        type = HighlightRegionType.INSTANCE_METHOD_REFERENCE;
-      }
-    }
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_parameter(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! ParameterElement) {
-      return false;
-    }
-    var type = node.inDeclarationContext()
-        ? HighlightRegionType.PARAMETER_DECLARATION
-        : HighlightRegionType.PARAMETER_REFERENCE;
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! TypeParameterElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER);
-  }
-
-  bool _addIdentifierRegion_unresolvedInstanceMemberReference(
-      SimpleIdentifier node) {
-    // unresolved
-    var element = node.writeOrReadElement;
-    if (element != null) {
-      return false;
-    }
-    // invoke / get / set
-    var decorate = false;
-    var parent = node.parent;
-    if (parent is MethodInvocation) {
-      var target = parent.realTarget;
-      if (parent.methodName == node &&
-          target != null &&
-          _isDynamicExpression(target)) {
-        decorate = true;
-      }
-    } else if (node.inGetterContext() || node.inSetterContext()) {
-      if (parent is PrefixedIdentifier) {
-        decorate = parent.identifier == node;
-      } else if (parent is PropertyAccess) {
-        decorate = parent.propertyName == node;
-      }
-    }
-    if (decorate) {
-      _addRegion_node(
-          node, HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE);
-      return true;
-    }
-    return false;
-  }
-
-  void _addRegion(int offset, int length, HighlightRegionType type) {
-    _regions.add(HighlightRegion(type, offset, length));
-  }
-
-  bool _addRegion_node(AstNode node, HighlightRegionType type) {
-    var offset = node.offset;
-    var length = node.length;
-    _addRegion(offset, length, type);
-    return true;
-  }
-
-  void _addRegion_nodeStart_tokenEnd(
-      AstNode a, Token b, HighlightRegionType type) {
-    var offset = a.offset;
-    var end = b.end;
-    _addRegion(offset, end - offset, type);
-  }
-
-  void _addRegion_token(Token token, HighlightRegionType type) {
-    if (token != null) {
-      var offset = token.offset;
-      var length = token.length;
-      _addRegion(offset, length, type);
-    }
-  }
-
-  void _addRegion_tokenStart_tokenEnd(
-      Token a, Token b, HighlightRegionType type) {
-    var offset = a.offset;
-    var end = b.end;
-    _addRegion(offset, end - offset, type);
-  }
-
-  static bool _isDynamicExpression(Expression e) {
-    var type = e.staticType;
-    return type != null && type.isDynamic;
-  }
-}
-
-/// An AST visitor for [DartUnitHighlightsComputer2].
-class _DartUnitHighlightsComputerVisitor2 extends RecursiveAstVisitor<void> {
-  final DartUnitHighlightsComputer2 computer;
-
-  _DartUnitHighlightsComputerVisitor2(this.computer);
-
-  @override
-  void visitAnnotation(Annotation node) {
-    computer._addIdentifierRegion_annotation(node);
-    super.visitAnnotation(node);
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN);
-    super.visitAsExpression(node);
-  }
-
-  @override
-  void visitAssertStatement(AssertStatement node) {
-    computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD);
-    super.visitAssertStatement(node);
-  }
-
-  @override
-  void visitAwaitExpression(AwaitExpression node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    super.visitAwaitExpression(node);
-  }
-
-  @override
-  void visitBlockFunctionBody(BlockFunctionBody node) {
-    _addRegions_functionBody(node);
-    super.visitBlockFunctionBody(node);
-  }
-
-  @override
-  void visitBooleanLiteral(BooleanLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.KEYWORD);
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN);
-    super.visitBooleanLiteral(node);
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD);
-    super.visitBreakStatement(node);
-  }
-
-  @override
-  void visitCatchClause(CatchClause node) {
-    computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
-    super.visitCatchClause(node);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(
-        node.abstractKeyword, HighlightRegionType.BUILT_IN);
-    super.visitClassDeclaration(node);
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    computer._addRegion_token(
-        node.abstractKeyword, HighlightRegionType.BUILT_IN);
-    super.visitClassTypeAlias(node);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.factoryKeyword, HighlightRegionType.BUILT_IN);
-    super.visitConstructorDeclaration(node);
-  }
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {
-    computer._addRegion_token(
-        node.continueKeyword, HighlightRegionType.KEYWORD);
-    super.visitContinueStatement(node);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitDefaultFormalParameter(node);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
-    super.visitDoStatement(node);
-  }
-
-  @override
-  void visitDoubleLiteral(DoubleLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE);
-    super.visitDoubleLiteral(node);
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);
-    super.visitEnumDeclaration(node);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitExportDirective(node);
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    _addRegions_functionBody(node);
-    super.visitExpressionFunctionBody(node);
-  }
-
-  @override
-  void visitExtendsClause(ExtendsClause node) {
-    computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
-    super.visitExtendsClause(node);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    computer._addRegion_token(
-        node.extensionKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
-    super.visitExtensionDeclaration(node);
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    computer._addRegion_token(
-        node.abstractKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
-    super.visitFieldDeclaration(node);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitFieldFormalParameter(node);
-  }
-
-  @override
-  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
-    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
-    super.visitForEachPartsWithDeclaration(node);
-  }
-
-  @override
-  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
-    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
-    super.visitForEachPartsWithIdentifier(node);
-  }
-
-  @override
-  void visitForElement(ForElement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitForElement(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitForStatement(node);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.propertyKeyword, HighlightRegionType.BUILT_IN);
-    super.visitFunctionDeclaration(node);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    computer._addRegion_token(
-        node.typedefKeyword, HighlightRegionType.BUILT_IN);
-    super.visitFunctionTypeAlias(node);
-  }
-
-  @override
-  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitFunctionTypedFormalParameter(node);
-  }
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    computer._addRegion_token(
-        node.functionKeyword, HighlightRegionType.KEYWORD);
-    super.visitGenericFunctionType(node);
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD);
-    super.visitGenericTypeAlias(node);
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitHideCombinator(node);
-  }
-
-  @override
-  void visitIfElement(IfElement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitIfElement(node);
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitIfStatement(node);
-  }
-
-  @override
-  void visitImplementsClause(ImplementsClause node) {
-    computer._addRegion_token(
-        node.implementsKeyword, HighlightRegionType.BUILT_IN);
-    super.visitImplementsClause(node);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.deferredKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.asKeyword, HighlightRegionType.BUILT_IN);
-    super.visitImportDirective(node);
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    if (node.keyword != null) {
-      computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    }
-    super.visitInstanceCreationExpression(node);
-  }
-
-  @override
-  void visitIntegerLiteral(IntegerLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER);
-    super.visitIntegerLiteral(node);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD);
-    super.visitIsExpression(node);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitLibraryDirective(node);
-  }
-
-  @override
-  void visitLibraryIdentifier(LibraryIdentifier node) {
-    computer._addRegion_node(node, HighlightRegionType.LIBRARY_NAME);
-    null;
-  }
-
-  @override
-  void visitListLiteral(ListLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
-    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
-    super.visitListLiteral(node);
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.modifierKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.operatorKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.propertyKeyword, HighlightRegionType.BUILT_IN);
-    super.visitMethodDeclaration(node);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
-    super.visitMixinDeclaration(node);
-  }
-
-  @override
-  void visitNativeClause(NativeClause node) {
-    computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
-    super.visitNativeClause(node);
-  }
-
-  @override
-  void visitNativeFunctionBody(NativeFunctionBody node) {
-    computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
-    super.visitNativeFunctionBody(node);
-  }
-
-  @override
-  void visitNullLiteral(NullLiteral node) {
-    computer._addRegion_token(node.literal, HighlightRegionType.KEYWORD);
-    super.visitNullLiteral(node);
-  }
-
-  @override
-  void visitOnClause(OnClause node) {
-    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
-    super.visitOnClause(node);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitPartDirective(node);
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_tokenStart_tokenEnd(
-        node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN);
-    super.visitPartOfDirective(node);
-  }
-
-  @override
-  void visitRethrowExpression(RethrowExpression node) {
-    computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD);
-    super.visitRethrowExpression(node);
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD);
-    super.visitReturnStatement(node);
-  }
-
-  @override
-  void visitSetOrMapLiteral(SetOrMapLiteral node) {
-    if (node.isMap) {
-      computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
-      // TODO(brianwilkerson) Add a highlight region for set literals. This
-      //  would be a breaking change, but would be consistent with list and map
-      //  literals.
-//    } else if (node.isSet) {
-//    computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
-    }
-    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
-    super.visitSetOrMapLiteral(node);
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitShowCombinator(node);
-  }
-
-  @override
-  void visitSimpleFormalParameter(SimpleFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitSimpleFormalParameter(node);
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    computer._addIdentifierRegion(node);
-    super.visitSimpleIdentifier(node);
-  }
-
-  @override
-  void visitSimpleStringLiteral(SimpleStringLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING);
-    super.visitSimpleStringLiteral(node);
-  }
-
-  @override
-  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD);
-    super.visitSuperConstructorInvocation(node);
-  }
-
-  @override
-  void visitSwitchCase(SwitchCase node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    super.visitSwitchCase(node);
-  }
-
-  @override
-  void visitSwitchDefault(SwitchDefault node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    super.visitSwitchDefault(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD);
-    super.visitSwitchStatement(node);
-  }
-
-  @override
-  void visitThisExpression(ThisExpression node) {
-    computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD);
-    super.visitThisExpression(node);
-  }
-
-  @override
-  void visitThrowExpression(ThrowExpression node) {
-    computer._addRegion_token(node.throwKeyword, HighlightRegionType.KEYWORD);
-    super.visitThrowExpression(node);
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    super.visitTopLevelVariableDeclaration(node);
-  }
-
-  @override
-  void visitTryStatement(TryStatement node) {
-    computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD);
-    super.visitTryStatement(node);
-  }
-
-  @override
-  void visitTypeName(TypeName node) {
-    var type = node.type;
-    if (type != null) {
-      if (type.isDynamic && node.name.name == 'dynamic') {
-        computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC);
-        return null;
-      }
-    }
-    super.visitTypeName(node);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    computer._addRegion_token(node.lateKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    super.visitVariableDeclarationList(node);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
-    super.visitWhileStatement(node);
-  }
-
-  @override
-  void visitWithClause(WithClause node) {
-    computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD);
-    super.visitWithClause(node);
-  }
-
-  @override
-  void visitYieldStatement(YieldStatement node) {
-    var keyword = node.yieldKeyword;
-    var star = node.star;
-    var offset = keyword.offset;
-    var end = star != null ? star.end : keyword.end;
-    computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
-    super.visitYieldStatement(node);
-  }
-
-  void _addRegions_functionBody(FunctionBody node) {
-    var keyword = node.keyword;
-    if (keyword != null) {
-      var star = node.star;
-      var offset = keyword.offset;
-      var end = star != null ? star.end : keyword.end;
-      computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
index 7f5a9a4..2229f6f 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -341,7 +341,7 @@
   /// [importedElements]. They will match if they import the same library using
   /// the same prefix.
   bool _matches(ImportDirective import, ImportedElements importedElements) {
-    var library = (import.element as ImportElement).importedLibrary;
+    var library = import.element.importedLibrary;
     return library != null &&
         library.source.fullName == importedElements.path &&
         (import.prefix?.name ?? '') == importedElements.prefix;
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 7ba35cd..0aafdda 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -17,6 +17,10 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/token_details/token_detail_builder.dart';
+import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/exception/exception.dart';
@@ -145,6 +149,25 @@
         request.replacementOffset, request.replacementLength, suggestions);
   }
 
+  /// Return the suggestions that should be presented in the YAML [file] at the
+  /// given [offset].
+  YamlCompletionResults computeYamlSuggestions(String file, int offset) {
+    var provider = server.resourceProvider;
+    if (AnalysisEngine.isAnalysisOptionsFileName(file)) {
+      var generator = AnalysisOptionsGenerator(provider);
+      return generator.getSuggestions(file, offset);
+    }
+    var fileName = provider.pathContext.basename(file);
+    if (fileName == AnalysisEngine.PUBSPEC_YAML_FILE) {
+      var generator = PubspecGenerator(provider);
+      return generator.getSuggestions(file, offset);
+    } else if (fileName == AnalysisEngine.FIX_DATA_FILE) {
+      var generator = FixDataGenerator(provider);
+      return generator.getSuggestions(file, offset);
+    }
+    return const YamlCompletionResults.empty();
+  }
+
   /// Process a `completion.getSuggestionDetails` request.
   void getSuggestionDetails(Request request) async {
     var params = CompletionGetSuggestionDetailsParams.fromRequest(request);
@@ -297,6 +320,25 @@
       if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
         return;
       }
+      if (file.endsWith('.yaml')) {
+        // Return the response without results.
+        var completionId = (_nextCompletionId++).toString();
+        server.sendResponse(CompletionGetSuggestionsResult(completionId)
+            .toResponse(request.id));
+        // Send a notification with results.
+        final suggestions = computeYamlSuggestions(file, offset);
+        sendCompletionNotification(
+          completionId,
+          suggestions.replacementOffset,
+          suggestions.replacementLength,
+          suggestions.suggestions,
+          null,
+          null,
+          null,
+          null,
+        );
+        return;
+      }
 
       var resolvedUnit = await server.getResolvedUnit(file);
       server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
@@ -312,8 +354,8 @@
 
         recordRequest(performance, file, resolvedUnit.content, offset);
       }
-      var completionRequest = CompletionRequestImpl(
-          resolvedUnit, offset, server.options.useNewRelevance, performance);
+      var completionRequest =
+          CompletionRequestImpl(resolvedUnit, offset, performance);
 
       var completionId = (_nextCompletionId++).toString();
 
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index 454be82..12a49cd 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -85,7 +85,6 @@
     var request = CompletionRequestImpl(
       targetResult,
       targetOffset,
-      false,
       CompletionPerformance(),
     );
 
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index e2fc729..30a2a3dd 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -106,7 +106,8 @@
       }
 
       var workspace = DartChangeWorkspace(server.currentSessions);
-      var processor = BulkFixProcessor(workspace);
+      var processor =
+          BulkFixProcessor(server.instrumentationService, workspace);
 
       String sdkPath;
       var sdk = server.findSdk();
@@ -120,7 +121,8 @@
       );
       var changeBuilder = await processor.fixErrors(collection.contexts);
 
-      var response = EditBulkFixesResult(changeBuilder.sourceChange.edits)
+      var response = EditBulkFixesResult(
+              changeBuilder.sourceChange.edits, processor.fixDetails)
           .toResponse(request.id);
       server.sendResponse(response);
     } catch (exception, stackTrace) {
@@ -212,7 +214,6 @@
       return;
     }
 
-    var changes = <SourceChange>[];
     //
     // Allow plugins to start computing assists.
     //
@@ -225,34 +226,12 @@
       pluginFutures = server.pluginManager
           .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
     }
+
     //
     // Compute fixes associated with server-generated errors.
     //
-    var result = await server.getResolvedUnit(file);
-    server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
-    if (result != null) {
-      var context = DartAssistContextImpl(
-        DartChangeWorkspace(server.currentSessions),
-        result,
-        offset,
-        length,
-      );
-      try {
-        List<Assist> assists;
-        try {
-          var processor = AssistProcessor(context);
-          assists = await processor.compute();
-        } on InconsistentAnalysisException {
-          assists = [];
-        }
+    var changes = await _computeServerAssists(request, file, offset, length);
 
-        assists.sort(Assist.SORT_BY_RELEVANCE);
-        for (var assist in assists) {
-          changes.add(assist.change);
-        }
-        server.requestStatistics?.addItemTimeNow(request, 'computedAssists');
-      } catch (_) {}
-    }
     //
     // Add the fixes produced by plugins to the server-generated fixes.
     //
@@ -268,6 +247,7 @@
     pluginChanges
         .sort((first, second) => first.priority.compareTo(second.priority));
     changes.addAll(pluginChanges.map(converter.convertPrioritizedSourceChange));
+
     //
     // Send the response.
     //
@@ -643,7 +623,8 @@
         var errorLine = lineInfo.getLocation(error.offset).lineNumber;
         if (errorLine == requestLine) {
           var workspace = DartChangeWorkspace(server.currentSessions);
-          var context = DartFixContextImpl(workspace, result, error, (name) {
+          var context = DartFixContextImpl(
+              server.instrumentationService, workspace, result, error, (name) {
             var tracker = server.declarationsTracker;
             var provider = TopLevelDeclarationsProvider(tracker);
             return provider.get(
@@ -761,6 +742,48 @@
     return errorFixesList;
   }
 
+  Future<List<SourceChange>> _computeServerAssists(
+      Request request, String file, int offset, int length) async {
+    var changes = <SourceChange>[];
+
+    var result = await server.getResolvedUnit(file);
+    server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
+
+    if (result != null) {
+      var context = DartAssistContextImpl(
+        server.instrumentationService,
+        DartChangeWorkspace(server.currentSessions),
+        result,
+        offset,
+        length,
+      );
+
+      try {
+        var processor = AssistProcessor(context);
+        var assists = await processor.compute();
+        assists.sort(Assist.SORT_BY_RELEVANCE);
+        for (var assist in assists) {
+          changes.add(assist.change);
+        }
+      } on InconsistentAnalysisException {
+        // ignore
+      } catch (exception, stackTrace) {
+        var parametersFile = '''
+offset: $offset
+length: $length
+      ''';
+        throw CaughtExceptionWithFiles(exception, stackTrace, {
+          file: result.content,
+          'parameters': parametersFile,
+        });
+      }
+
+      server.requestStatistics?.addItemTimeNow(request, 'computedAssists');
+    }
+
+    return changes;
+  }
+
   /// Compute and return the fixes associated with server-generated errors.
   Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
       Request request, String file, int offset) async {
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
index d15e724..b78a73b 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
@@ -11,6 +11,7 @@
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/error/codes.dart';
 
 /// A processor used by [EditDartFix] to manage [FixErrorTask]s.
@@ -45,6 +46,7 @@
   Future<void> fixError(ResolvedUnitResult result, AnalysisError error) async {
     final workspace = DartChangeWorkspace(listener.server.currentSessions);
     final dartContext = DartFixContextImpl(
+      InstrumentationService.NULL_SERVICE,
       workspace,
       result,
       error,
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
index 6ab084c..870c33f 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/lint/registry.dart';
 
@@ -34,6 +35,7 @@
           declaration.name.name == elem.name) {
         var processor = AssistProcessor(
           DartAssistContextImpl(
+              InstrumentationService.NULL_SERVICE,
               DartChangeWorkspace(listener.server.currentSessions),
               result,
               declaration.name.offset,
diff --git a/pkg/analysis_server/lib/src/lsp/client_configuration.dart b/pkg/analysis_server/lib/src/lsp/client_configuration.dart
index 55bfaf5..8af5a85 100644
--- a/pkg/analysis_server/lib/src/lsp/client_configuration.dart
+++ b/pkg/analysis_server/lib/src/lsp/client_configuration.dart
@@ -20,6 +20,7 @@
     }
   }
 
+  bool get completeFunctionCalls => _settings['completeFunctionCalls'] ?? false;
   bool get enableSdkFormatter => _settings['enableSdkFormatter'] ?? true;
   int get lineLength => _settings['lineLength'];
 
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 8ee02fc..c58b195 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -68,11 +68,13 @@
     organizeImports,
     sendWorkspaceEdit,
     performRefactor,
+    fixAllOfErrorCodeInFile,
   ];
   static const sortMembers = 'edit.sortMembers';
   static const organizeImports = 'edit.organizeImports';
   static const sendWorkspaceEdit = 'edit.sendWorkspaceEdit';
   static const performRefactor = 'refactor.perform';
+  static const fixAllOfErrorCodeInFile = 'edit.fixAll.errorCodeInFile';
 }
 
 abstract class CustomMethods {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all_of_error_code_in_file.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all_of_error_code_in_file.dart
new file mode 100644
index 0000000..d43b9d9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/fix_all_of_error_code_in_file.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/commands/simple_edit_handler.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/progress.dart';
+import 'package:analysis_server/src/services/correction/bulk_fix_processor.dart';
+import 'package:analysis_server/src/services/correction/change_workspace.dart';
+
+/// This command allows a client to request request applying all fixes for a
+/// type of error.
+class FixAllOfErrorCodeInFileCommandHandler extends SimpleEditCommandHandler {
+  FixAllOfErrorCodeInFileCommandHandler(LspAnalysisServer server)
+      : super(server);
+
+  @override
+  String get commandName => 'Fix All of Error Code in File';
+
+  @override
+  Future<ErrorOr<void>> handle(List<dynamic> arguments,
+      ProgressReporter reporter, CancellationToken cancellationToken) async {
+    if (arguments == null ||
+        arguments.length != 3 ||
+        arguments[0] is! String ||
+        arguments[1] is! String ||
+        (arguments[2] is! int && arguments[2] != null)) {
+      return ErrorOr.error(ResponseError(
+        code: ServerErrorCodes.InvalidCommandArguments,
+        message: '$commandName requires three arguments: '
+            '1) an ErrorCode, '
+            '2) a file path, '
+            '3) a document version',
+      ));
+    }
+
+    final errorCode = arguments[0] as String;
+    final path = arguments[1] as String;
+    final clientDocumentVersion = arguments[2] as int;
+
+    if (fileHasBeenModified(path, clientDocumentVersion)) {
+      return fileModifiedError;
+    }
+
+    final result = await requireResolvedUnit(path);
+
+    if (cancellationToken.isCancellationRequested) {
+      return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
+    }
+
+    return result.mapResult((result) async {
+      final workspace = DartChangeWorkspace(server.currentSessions);
+      final processor =
+          BulkFixProcessor(server.instrumentationService, workspace);
+
+      final changeBuilder = await processor.fixOfTypeInUnit(result, errorCode);
+
+      final edit =
+          createWorkspaceEdit(server, changeBuilder.sourceChange.edits);
+
+      return await sendWorkspaceEditToClient(edit);
+    });
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
index bd880eb..4a302a2 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
@@ -83,18 +83,14 @@
 
           // If the file changed while we were validating and preparing the change,
           // we should fail to avoid sending bad edits.
-          if (docVersion != null &&
-              docVersion !=
-                  server.getVersionedDocumentIdentifier(path).version) {
-            return error(ErrorCodes.ContentModified,
-                'Content was modified before refactor was applied');
+          if (fileHasBeenModified(path, docVersion)) {
+            return fileModifiedError;
           }
 
           final edit = createWorkspaceEdit(server, change.edits);
           return await sendWorkspaceEditToClient(edit);
         } on InconsistentAnalysisException {
-          return error(ErrorCodes.ContentModified,
-              'Content was modified before refactor was applied');
+          return fileModifiedError;
         } finally {
           _manager.end(cancellationToken);
           reporter.end();
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 0e5a949..355cbde 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -12,9 +12,10 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
-import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/protocol_server.dart' hide Position;
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analysis_server/src/services/correction/bulk_fix_processor.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
@@ -23,7 +24,9 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart'
     show InconsistentAnalysisException;
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:collection/collection.dart' show groupBy;
 
 class CodeActionHandler extends MessageHandler<CodeActionParams,
@@ -89,6 +92,21 @@
     });
   }
 
+  /// Creates a comparer for [CodeActions] that compares the column distance from [pos].
+  Function(CodeAction a, CodeAction b) _codeActionColumnDistanceComparer(
+      Position pos) {
+    Position posOf(CodeAction action) => action.diagnostics.isNotEmpty
+        ? action.diagnostics.first.range.start
+        : pos;
+
+    return (a, b) => _columnDistance(posOf(a), pos)
+        .compareTo(_columnDistance(posOf(b), pos));
+  }
+
+  /// Returns the distance (in columns, ignoring lines) between two positions.
+  int _columnDistance(Position a, Position b) =>
+      (a.character - b.character).abs();
+
   /// Wraps a command in a CodeAction if the client supports it so that a
   /// CodeActionKind can be supplied.
   Either2<Command, CodeAction> _commandOrCodeAction(
@@ -129,33 +147,80 @@
     );
   }
 
-  /// Dedupes actions that perform the same edit and merge their diagnostics
-  /// together. This avoids duplicates where there are multiple errors on
-  /// the same line that have the same fix (for example importing a
-  /// library that fixes multiple unresolved types).
-  List<CodeAction> _dedupeActions(Iterable<CodeAction> actions) {
-    final groups = groupBy(actions, (CodeAction action) => action.edit);
-    return groups.keys.map((edit) {
-      final first = groups[edit].first;
-      // Avoid constructing new CodeActions if there was only one in this group.
-      if (groups[edit].length == 1) {
-        return first;
+  /// Creates a CodeAction command to apply a particular fix for all instances of
+  /// a specific error in the file for [path].
+  CodeAction _createFixAllCommand(Fix fix, Diagnostic diagnostic, String path) {
+    final title = 'Apply all: ${fix.change.message}';
+    return CodeAction(
+      title: title,
+      kind: CodeActionKind.QuickFix,
+      diagnostics: [diagnostic],
+      command: Command(
+        command: Commands.fixAllOfErrorCodeInFile,
+        title: title,
+        arguments: [
+          diagnostic.code,
+          path,
+          server.getVersionedDocumentIdentifier(path).version
+        ],
+      ),
+    );
+  }
+
+  /// Dedupes/merges actions that have the same title, selecting the one nearest [pos].
+  ///
+  /// If actions perform the same edit/command, their diagnostics will be merged
+  /// together. Otherwise, the additional accounts are just dropped.
+  ///
+  /// The first diagnostic for an action is used to determine the position (using
+  /// its `start`). If there is no diagnostic, it will be treated as being at [pos].
+  ///
+  /// If multiple actions have the same position, one will arbitrarily be chosen.
+  List<CodeAction> _dedupeActions(Iterable<CodeAction> actions, Position pos) {
+    final groups = groupBy(actions, (CodeAction action) => action.title);
+    return groups.keys.map((title) {
+      final actions = groups[title];
+
+      // If there's only one in the group, just return it.
+      if (actions.length == 1) {
+        return actions.single;
       }
+
+      // Otherwise, find the action nearest to the caret.
+      actions.sort(_codeActionColumnDistanceComparer(pos));
+      final first = actions.first;
+
+      // Get any actions with the same fix (edit/command) for merging diagnostics.
+      final others = actions.skip(1).where(
+            (other) =>
+                // Compare either edits or commands based on which the selected action has.
+                first.edit != null
+                    ? first.edit == other.edit
+                    : first.command != null
+                        ? first.command == other.command
+                        : false,
+          );
+
       // Build a new CodeAction that merges the diagnostics from each same
       // code action onto a single one.
       return CodeAction(
-          title: first.title,
-          kind: first.kind,
-          // Merge diagnostics from all of the CodeActions.
-          diagnostics: groups[edit].expand((r) => r.diagnostics).toList(),
-          edit: first.edit,
-          command: first.command);
+        title: first.title,
+        kind: first.kind,
+        // Merge diagnostics from all of the matching CodeActions.
+        diagnostics: [
+          ...?first.diagnostics,
+          for (final other in others) ...?other.diagnostics,
+        ],
+        edit: first.edit,
+        command: first.command,
+      );
     }).toList();
   }
 
   Future<List<Either2<Command, CodeAction>>> _getAssistActions(
     HashSet<CodeActionKind> clientSupportedCodeActionKinds,
     bool clientSupportsLiteralCodeActions,
+    Range range,
     int offset,
     int length,
     ResolvedUnitResult unit,
@@ -168,6 +233,7 @@
 
     try {
       var context = DartAssistContextImpl(
+        server.instrumentationService,
         DartChangeWorkspace(server.currentSessions),
         unit,
         offset,
@@ -177,7 +243,8 @@
       final assists = await processor.compute();
       assists.sort(Assist.SORT_BY_RELEVANCE);
 
-      final assistActions = _dedupeActions(assists.map(_createAssistAction));
+      final assistActions =
+          _dedupeActions(assists.map(_createAssistAction), range.start);
 
       return assistActions
           .map((action) => Either2<Command, CodeAction>.t2(action))
@@ -204,7 +271,7 @@
     final results = await Future.wait([
       _getSourceActions(
           kinds, supportsLiterals, supportsWorkspaceApplyEdit, path),
-      _getAssistActions(kinds, supportsLiterals, offset, length, unit),
+      _getAssistActions(kinds, supportsLiterals, range, offset, length, unit),
       _getRefactorActions(kinds, supportsLiterals, path, offset, length, unit),
       _getFixActions(
           kinds, supportsLiterals, supportedDiagnosticTags, range, unit),
@@ -229,39 +296,82 @@
 
     final lineInfo = unit.lineInfo;
     final codeActions = <CodeAction>[];
+    final fixAllCodeActions = <CodeAction>[];
     final fixContributor = DartFixContributor();
 
     try {
+      final errorCodeCounts = <ErrorCode, int>{};
+      // Count the errors by code so we know whether to include a fix-all.
+      for (final error in unit.errors) {
+        errorCodeCounts[error.errorCode] =
+            (errorCodeCounts[error.errorCode] ?? 0) + 1;
+      }
+
+      // Because an error code may appear multiple times, cache the possible fixes
+      // as we discover them to avoid re-computing them for a given diagnostic.
+      final possibleFixesForErrorCode = <ErrorCode, Set<FixKind>>{};
+      final workspace = DartChangeWorkspace(server.currentSessions);
+      final processor =
+          BulkFixProcessor(server.instrumentationService, workspace);
+
       for (final error in unit.errors) {
         // Server lineNumber is one-based so subtract one.
         var errorLine = lineInfo.getLocation(error.offset).lineNumber - 1;
-        if (errorLine >= range.start.line && errorLine <= range.end.line) {
-          var workspace = DartChangeWorkspace(server.currentSessions);
-          var context = DartFixContextImpl(workspace, unit, error, (name) {
-            var tracker = server.declarationsTracker;
-            return TopLevelDeclarationsProvider(tracker).get(
-              unit.session.analysisContext,
-              unit.path,
-              name,
-            );
-          });
-          final fixes = await fixContributor.computeFixes(context);
-          if (fixes.isNotEmpty) {
-            fixes.sort(Fix.SORT_BY_RELEVANCE);
+        if (errorLine < range.start.line || errorLine > range.end.line) {
+          continue;
+        }
+        var workspace = DartChangeWorkspace(server.currentSessions);
+        var context = DartFixContextImpl(
+            server.instrumentationService, workspace, unit, error, (name) {
+          var tracker = server.declarationsTracker;
+          return TopLevelDeclarationsProvider(tracker).get(
+            unit.session.analysisContext,
+            unit.path,
+            name,
+          );
+        });
+        final fixes = await fixContributor.computeFixes(context);
+        if (fixes.isNotEmpty) {
+          fixes.sort(Fix.SORT_BY_RELEVANCE);
 
-            final diagnostic = toDiagnostic(
-              unit,
-              error,
-              supportedTags: supportedDiagnosticTags,
-            );
-            codeActions.addAll(
-              fixes.map((fix) => _createFixAction(fix, diagnostic)),
-            );
+          final diagnostic = toDiagnostic(
+            unit,
+            error,
+            supportedTags: supportedDiagnosticTags,
+          );
+          codeActions.addAll(
+            fixes.map((fix) => _createFixAction(fix, diagnostic)),
+          );
+
+          // Only consider an apply-all if there's more than one of these errors.
+          if (errorCodeCounts[error.errorCode] > 1) {
+            // Find out which fixes the bulk processor can handle.
+            possibleFixesForErrorCode[error.errorCode] ??=
+                processor.producableFixesForError(unit, error).toSet();
+
+            // Get the intersection of single-fix kinds we created and those
+            // the bulk processor can handle.
+            final possibleFixes = possibleFixesForErrorCode[error.errorCode]
+                .intersection(fixes.map((f) => f.kind).toSet())
+                  // Exclude data-driven fixes as they're more likely to apply
+                  // different fixes for the same error/fix kind that users
+                  // might not expect.
+                  ..remove(DartFixKind.DATA_DRIVEN);
+
+            // Until we can apply a specific fix, only include apply-all when
+            // there's exactly one.
+            if (possibleFixes.length == 1) {
+              fixAllCodeActions.addAll(fixes.map(
+                  (fix) => _createFixAllCommand(fix, diagnostic, unit.path)));
+            }
           }
         }
       }
 
-      final dedupedActions = _dedupeActions(codeActions);
+      // Append all fix-alls to the very end.
+      codeActions.addAll(fixAllCodeActions);
+
+      final dedupedActions = _dedupeActions(codeActions, range.start);
 
       return dedupedActions
           .map((action) => Either2<Command, CodeAction>.t2(action))
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 430489a..ba9c66d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -16,8 +16,13 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
+import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
@@ -89,18 +94,47 @@
         await lineInfo.mapResult((lineInfo) => toOffset(lineInfo, pos));
 
     return offset.mapResult((offset) async {
-      // For server results we need a valid unit, but if we don't have one
-      // we shouldn't consider this an error when merging with plugin results.
-      final serverResultsFuture = unit.isError
-          ? Future.value(success(const <CompletionItem>[]))
-          : _getServerItems(
-              completionCapabilities,
-              clientSupportedCompletionKinds,
-              includeSuggestionSets,
-              unit.result,
-              offset,
-              token,
-            );
+      Future<ErrorOr<List<CompletionItem>>> serverResultsFuture;
+      final pathContext = server.resourceProvider.pathContext;
+      final filename = pathContext.basename(path.result);
+      final fileExtension = pathContext.extension(path.result);
+
+      if (fileExtension == '.dart' && !unit.isError) {
+        serverResultsFuture = _getServerDartItems(
+          completionCapabilities,
+          clientSupportedCompletionKinds,
+          includeSuggestionSets,
+          unit.result,
+          offset,
+          token,
+        );
+      } else if (fileExtension == '.yaml') {
+        YamlCompletionGenerator generator;
+        switch (filename) {
+          case AnalysisEngine.PUBSPEC_YAML_FILE:
+            generator = PubspecGenerator(server.resourceProvider);
+            break;
+          case AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE:
+            generator = AnalysisOptionsGenerator(server.resourceProvider);
+            break;
+          case AnalysisEngine.FIX_DATA_FILE:
+            generator = FixDataGenerator(server.resourceProvider);
+            break;
+        }
+        if (generator != null) {
+          serverResultsFuture = _getServerYamlItems(
+            generator,
+            completionCapabilities,
+            clientSupportedCompletionKinds,
+            path.result,
+            lineInfo.result,
+            offset,
+            token,
+          );
+        }
+      }
+
+      serverResultsFuture ??= Future.value(success(const <CompletionItem>[]));
 
       final pluginResultsFuture = _getPluginResults(completionCapabilities,
           clientSupportedCompletionKinds, lineInfo.result, path.result, offset);
@@ -175,7 +209,7 @@
     ).toList());
   }
 
-  Future<ErrorOr<List<CompletionItem>>> _getServerItems(
+  Future<ErrorOr<List<CompletionItem>>> _getServerDartItems(
     CompletionClientCapabilities completionCapabilities,
     HashSet<CompletionItemKind> clientSupportedCompletionKinds,
     bool includeSuggestionSets,
@@ -189,8 +223,8 @@
     server.performanceStats.completion.add(performance);
 
     return await performance.runRequestOperation((perf) async {
-      final completionRequest = CompletionRequestImpl(
-          unit, offset, server.options.useNewRelevance, performance);
+      final completionRequest =
+          CompletionRequestImpl(unit, offset, performance);
       final directiveInfo =
           server.getDartdocDirectiveInfoFor(completionRequest.result);
       final dartCompletionRequest = await DartCompletionRequestImpl.from(
@@ -239,6 +273,8 @@
                 // https://github.com/microsoft/vscode-languageserver-node/issues/673
                 includeCommitCharacters:
                     server.clientConfiguration.previewCommitCharacters,
+                completeFunctionCalls:
+                    server.clientConfiguration.completeFunctionCalls,
               ),
             )
             .toList();
@@ -331,6 +367,8 @@
                     // https://github.com/microsoft/vscode-languageserver-node/issues/673
                     includeCommitCharacters:
                         server.clientConfiguration.previewCommitCharacters,
+                    completeFunctionCalls:
+                        server.clientConfiguration.completeFunctionCalls,
                   ));
           results.addAll(setResults);
         });
@@ -353,6 +391,33 @@
     });
   }
 
+  Future<ErrorOr<List<CompletionItem>>> _getServerYamlItems(
+    YamlCompletionGenerator generator,
+    CompletionClientCapabilities completionCapabilities,
+    HashSet<CompletionItemKind> clientSupportedCompletionKinds,
+    String path,
+    LineInfo lineInfo,
+    int offset,
+    CancellationToken token,
+  ) async {
+    final suggestions = generator.getSuggestions(path, offset);
+    final completionItems = suggestions.suggestions
+        .map(
+          (item) => toCompletionItem(
+            completionCapabilities,
+            clientSupportedCompletionKinds,
+            lineInfo,
+            item,
+            suggestions.replacementOffset,
+            suggestions.replacementLength,
+            includeCommitCharacters: false,
+            completeFunctionCalls: false,
+          ),
+        )
+        .toList();
+    return success(completionItems);
+  }
+
   Iterable<CompletionItem> _pluginResultsToItems(
     CompletionClientCapabilities completionCapabilities,
     HashSet<CompletionItemKind> clientSupportedCompletionKinds,
@@ -372,6 +437,7 @@
           // not assume that the Dart ones would be correct for all of their
           // completions.
           includeCommitCharacters: false,
+          completeFunctionCalls: false,
         ),
       );
     });
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
index d7f1610..3157a79 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
@@ -15,10 +16,11 @@
 
 class CompletionResolveHandler
     extends MessageHandler<CompletionItem, CompletionItem> {
+  /// The last completion item we asked to be resolved.
   ///
-  /// The latest completion item we were asked to resolve. We use it to abort
-  /// previous requests.
-  ///
+  /// Used to abort previous requests in async handlers if another resolve request
+  /// arrives while the previous is being processed (for clients that don't send
+  /// cancel events).
   CompletionItem _latestCompletionItem;
 
   CompletionResolveHandler(LspAnalysisServer server) : super(server);
@@ -31,13 +33,23 @@
 
   @override
   Future<ErrorOr<CompletionItem>> handle(
-      CompletionItem item, CancellationToken token) async {
-    // If this isn't an item with resolution data, return the same item back.
-    if (item.data == null) {
+    CompletionItem item,
+    CancellationToken token,
+  ) async {
+    final resolutionInfo = item.data;
+
+    if (resolutionInfo is DartCompletionItemResolutionInfo) {
+      return resolveDartCompletion(item, resolutionInfo, token);
+    } else {
       return success(item);
     }
+  }
 
-    final data = item.data;
+  Future<ErrorOr<CompletionItem>> resolveDartCompletion(
+    CompletionItem item,
+    DartCompletionItemResolutionInfo data,
+    CancellationToken token,
+  ) async {
     final lineInfo = server.getLineInfo(data.file);
     if (lineInfo == null) {
       return error(
@@ -60,8 +72,11 @@
       );
     }
 
+    // If filterText is different to the label, it's because label has parens/args
+    // appended and we should take the basic label. We cannot use insertText as
+    // it may include snippets, whereas filterText is always just the pure string.
+    var requestedName = item.filterText ?? item.label;
     // The label might be `MyEnum.myValue`, but we import only `MyEnum`.
-    var requestedName = item.insertText ?? item.label;
     if (requestedName.contains('.')) {
       requestedName = requestedName.substring(
         0,
@@ -154,9 +169,6 @@
                   .trim()
               : item.detail,
           documentation: documentation,
-          // The deprecated field is deprecated, but we should still supply it
-          // for clients that have not adopted CompletionItemTags.
-          // ignore: deprecated_member_use_from_same_package
           deprecated: item.deprecated,
           preselect: item.preselect,
           sortText: item.sortText,
@@ -164,9 +176,7 @@
           insertText: newInsertText,
           insertTextFormat: item.insertTextFormat,
           textEdit: TextEdit(
-            // TODO(dantup): If `clientSupportsSnippets == true` then we should map
-            // `selection` in to a snippet (see how Dart Code does this).
-            range: toRange(lineInfo, item.data.rOffset, item.data.rLength),
+            range: toRange(lineInfo, data.rOffset, data.rLength),
             newText: newInsertText,
           ),
           additionalTextEdits: thisFilesChanges
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
index 967e8e8..60416b4 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/commands/fix_all_of_error_code_in_file.dart';
 import 'package:analysis_server/src/lsp/handlers/commands/organize_imports.dart';
 import 'package:analysis_server/src/lsp/handlers/commands/perform_refactor.dart';
 import 'package:analysis_server/src/lsp/handlers/commands/send_workspace_edit.dart';
@@ -24,6 +25,8 @@
           Commands.organizeImports: OrganizeImportsCommandHandler(server),
           Commands.performRefactor: PerformRefactorCommandHandler(server),
           Commands.sendWorkspaceEdit: SendWorkspaceEditCommandHandler(server),
+          Commands.fixAllOfErrorCodeInFile:
+              FixAllOfErrorCodeInFileCommandHandler(server),
         },
         super(server);
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
index ad0869e..d34bcea 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 
 class FormatOnTypeHandler
     extends MessageHandler<DocumentOnTypeFormattingParams, List<TextEdit>> {
@@ -26,9 +27,13 @@
       return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
     }
 
-    final unformattedSource = file.readAsStringSync();
-    return success(generateEditsForFormatting(
-        unformattedSource, server.clientConfiguration.lineLength));
+    final result = server.getParsedUnit(path);
+    if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+      return success();
+    }
+
+    return generateEditsForFormatting(
+        result, server.clientConfiguration.lineLength);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
new file mode 100644
index 0000000..3c6183d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+class FormatRangeHandler
+    extends MessageHandler<DocumentRangeFormattingParams, List<TextEdit>> {
+  FormatRangeHandler(LspAnalysisServer server) : super(server);
+  @override
+  Method get handlesMessage => Method.textDocument_rangeFormatting;
+
+  @override
+  LspJsonHandler<DocumentRangeFormattingParams> get jsonHandler =>
+      DocumentRangeFormattingParams.jsonHandler;
+
+  ErrorOr<List<TextEdit>> formatRange(String path, Range range) {
+    final file = server.resourceProvider.getFile(path);
+    if (!file.exists) {
+      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+    }
+
+    final result = server.getParsedUnit(path);
+    if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+      return success();
+    }
+
+    return generateEditsForFormatting(
+        result, server.clientConfiguration.lineLength,
+        range: range);
+  }
+
+  @override
+  Future<ErrorOr<List<TextEdit>>> handle(
+      DocumentRangeFormattingParams params, CancellationToken token) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(null);
+    }
+
+    if (!server.clientConfiguration.enableSdkFormatter) {
+      return error(ServerErrorCodes.FeatureDisabled,
+          'Formatter was disabled by client settings');
+    }
+
+    final path = pathOfDoc(params.textDocument);
+    return path.mapResult((path) => formatRange(path, params.range));
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
index 031d5a9..554ed01 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 
 class FormattingHandler
     extends MessageHandler<DocumentFormattingParams, List<TextEdit>> {
@@ -26,9 +27,13 @@
       return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
     }
 
-    final unformattedSource = file.readAsStringSync();
-    return success(generateEditsForFormatting(
-        unformattedSource, server.clientConfiguration.lineLength));
+    final result = server.getParsedUnit(path);
+    if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+      return success();
+    }
+
+    return generateEditsForFormatting(
+        result, server.clientConfiguration.lineLength);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index 4ee1e1a..242c72f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -41,11 +41,7 @@
       }
       if (params.rootUri != null) {
         openWorkspacePaths.add(Uri.parse(params.rootUri).toFilePath());
-        // ignore: deprecated_member_use_from_same_package
       } else if (params.rootPath != null) {
-        // This is deprecated according to LSP spec, but we still want to support
-        // it in case older clients send us it.
-        // ignore: deprecated_member_use_from_same_package
         openWorkspacePaths.add(params.rootPath);
       }
     }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 7375cc2..71205a0 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -95,8 +95,9 @@
     // send the edits.
     final docIdentifier = await path.mapResult((path) => success(
         params.textDocument is VersionedTextDocumentIdentifier
-            ? params.textDocument
+            ? params.textDocument as VersionedTextDocumentIdentifier
             : server.getVersionedDocumentIdentifier(path)));
+
     final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
@@ -178,10 +179,8 @@
 
       // Before we send anything back, ensure the original file didn't change
       // while we were computing changes.
-      if (server.getVersionedDocumentIdentifier(path.result) !=
-          docIdentifier.result) {
-        return error(ErrorCodes.ContentModified,
-            'Document was modified while rename was being computed', null);
+      if (fileHasBeenModified(path.result, docIdentifier.result.version)) {
+        return fileModifiedError;
       }
 
       final workspaceEdit = createWorkspaceEdit(server, change.edits);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index 949777a..be00dc9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -21,6 +21,7 @@
 import 'package:analysis_server/src/lsp/handlers/handler_exit.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_folding.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_format_range.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_formatting.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_hover.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_implementation.dart';
@@ -81,6 +82,7 @@
     registerHandler(ImplementationHandler(server));
     registerHandler(FormattingHandler(server));
     registerHandler(FormatOnTypeHandler(server));
+    registerHandler(FormatRangeHandler(server));
     registerHandler(DocumentHighlightsHandler(server));
     registerHandler(DocumentSymbolHandler(server));
     registerHandler(CodeActionHandler(server));
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 41f20f4..96db148 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -55,6 +55,15 @@
 mixin Handler<P, R> {
   LspAnalysisServer server;
 
+  final fileModifiedError = error<R>(ErrorCodes.ContentModified,
+      'Document was modified before operation completed', null);
+
+  bool fileHasBeenModified(String path, int clientVersion) {
+    final serverDocIdentifier = server.getVersionedDocumentIdentifier(path);
+    return clientVersion != null &&
+        clientVersion != serverDocIdentifier.version;
+  }
+
   ErrorOr<LineInfo> getLineInfo(String path) {
     final lineInfo = server.getLineInfo(path);
 
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index c8acbe8..3c67aab 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -31,6 +31,7 @@
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
 import 'package:analysis_server/src/server/diagnostic_server.dart';
+import 'package:analysis_server/src/server/error_notifier.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart'
     show CompletionPerformance;
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
@@ -43,6 +44,7 @@
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
@@ -153,9 +155,6 @@
     channel.listen(handleMessage, onDone: done, onError: socketError);
     _pluginChangeSubscription =
         pluginManager.pluginsChanged.listen((_) => _onPluginsChanged());
-
-    analyzingProgressReporter =
-        ProgressReporter.serverCreated(this, analyzingProgressToken);
   }
 
   /// The capabilities of the LSP client. Will be null prior to initialization.
@@ -355,14 +354,16 @@
   /// Logs an exception by sending it to the client (window/logMessage) and
   /// recording it in a buffer on the server for diagnostics.
   void logException(String message, exception, stackTrace) {
+    var fullMessage = message;
     if (exception is CaughtException) {
       stackTrace ??= exception.stackTrace;
-      message = '$message: ${exception.exception}';
+      fullMessage = '$fullMessage: ${exception.exception}';
     } else if (exception != null) {
-      message = '$message: $exception';
+      fullMessage = '$fullMessage: $exception';
     }
 
-    final fullError = stackTrace == null ? message : '$message\n$stackTrace';
+    final fullError =
+        stackTrace == null ? fullMessage : '$fullMessage\n$stackTrace';
 
     // Log the full message since showMessage above may be truncated or
     // formatted badly (eg. VS Code takes the newlines out).
@@ -375,6 +376,16 @@
       stackTrace is StackTrace ? stackTrace : null,
       false,
     ));
+
+    AnalysisEngine.instance.instrumentationService.logException(
+      FatalException(
+        message,
+        exception,
+        stackTrace,
+      ),
+      null,
+      crashReportingAttachmentsBuilder.forException(exception),
+    );
   }
 
   void onOverlayCreated(String path, String content) {
@@ -535,7 +546,7 @@
 
   /// Send status notification to the client. The state of analysis is given by
   /// the [status] information.
-  void sendStatusNotification(nd.AnalysisStatus status) {
+  Future<void> sendStatusNotification(nd.AnalysisStatus status) async {
     // Send old custom notifications to clients that do not support $/progress.
     // TODO(dantup): Remove this custom notification (and related classes) when
     // it's unlikely to be in use by any clients.
@@ -549,9 +560,16 @@
     }
 
     if (status.isAnalyzing) {
-      analyzingProgressReporter.begin('Analyzing…');
+      analyzingProgressReporter ??=
+          ProgressReporter.serverCreated(this, analyzingProgressToken)
+            ..begin('Analyzing…');
     } else {
-      analyzingProgressReporter.end();
+      if (analyzingProgressReporter != null) {
+        // Do not null this out until after end completes, otherwise we may try
+        // to create a new token before it's really completed.
+        await analyzingProgressReporter.end();
+        analyzingProgressReporter = null;
+      }
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
index ae00fb8..832f432 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
@@ -64,18 +64,8 @@
       return;
     }
 
-    PhysicalResourceProvider resourceProvider;
-    if (analysisServerOptions.fileReadMode == 'as-is') {
-      resourceProvider = PhysicalResourceProvider(null,
-          stateLocation: analysisServerOptions.cacheFolder);
-    } else if (analysisServerOptions.fileReadMode == 'normalize-eol-always') {
-      resourceProvider = PhysicalResourceProvider(
-          PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS,
-          stateLocation: analysisServerOptions.cacheFolder);
-    } else {
-      throw Exception(
-          'File read mode was set to the unknown mode: $analysisServerOptions.fileReadMode');
-    }
+    var resourceProvider = PhysicalResourceProvider(
+        stateLocation: analysisServerOptions.cacheFolder);
 
     analysisServer = LspAnalysisServer(
         serverChannel,
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 717b6cd..6f0cd7b 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -34,6 +34,7 @@
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/services/available_declarations.dart' as dec;
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
+import 'package:analyzer_plugin/utilities/pair.dart';
 import 'package:meta/meta.dart';
 
 const diagnosticTagsForErrorCode = <server.ErrorCode, List<lsp.DiagnosticTag>>{
@@ -62,32 +63,53 @@
           _asMarkup(preferredFormats, content));
 }
 
-/// Builds an LSP snippet string that uses a $1 tabstop to set the selected text
-/// after insertion.
-String buildSnippetStringWithSelection(
+/// Builds an LSP snippet string with supplied ranges as tabstops.
+String buildSnippetStringWithTabStops(
   String text,
-  int selectionOffset,
-  int selectionLength,
+  List<int> offsetLengthPairs,
 ) {
+  text ??= '';
+  offsetLengthPairs ??= const [];
+
   String escape(String input) => input.replaceAllMapped(
         RegExp(r'[$}\\]'), // Replace any of $ } \
         (c) => '\\${c[0]}', // Prefix with a backslash
       );
+
   // Snippets syntax is documented in the LSP spec:
-  // https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#snippet-syntax
+  // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
   //
   // $1, $2, etc. are used for tab stops and ${1:foo} inserts a placeholder of foo.
-  // Since we only need to support a single tab stop, our string is constructed of three parts:
-  // - Anything before the selection
-  // - The selection (which may or may not include text, depending on selectionLength)
-  // - Anything after the selection
-  final prefix = escape(text.substring(0, selectionOffset));
-  final selectionText = escape(
-      text.substring(selectionOffset, selectionOffset + selectionLength));
-  final selection = '\${1:$selectionText}';
-  final suffix = escape(text.substring(selectionOffset + selectionLength));
 
-  return '$prefix$selection$suffix';
+  final output = [];
+  var offset = 0;
+
+  // When there's only a single tabstop, it should be ${0} as this is treated
+  // specially as the final cursor position (if we use 1, the editor will insert
+  // a 0 at the end of the string which is not what we expect).
+  // When there are multiple, start with ${1} since these are placeholders the
+  // user can tab through and the editor-inserted ${0} at the end is expected.
+  var tabStopNumber = offsetLengthPairs.length <= 2 ? 0 : 1;
+
+  for (var i = 0; i < offsetLengthPairs.length; i += 2) {
+    final pairOffset = offsetLengthPairs[i];
+    final pairLength = offsetLengthPairs[i + 1];
+
+    // Add any text that came before this tabstop to the result.
+    output.add(escape(text.substring(offset, pairOffset)));
+
+    // Add this tabstop
+    final tabStopText =
+        escape(text.substring(pairOffset, pairOffset + pairLength));
+    output.add('\${${tabStopNumber++}:$tabStopText}');
+
+    offset = pairOffset + pairLength;
+  }
+
+  // Add any remaining text that was after the last tabstop.
+  output.add(escape(text.substring(offset)));
+
+  return output.join('');
 }
 
 /// Note: This code will fetch the version of each document being modified so
@@ -156,8 +178,9 @@
       case server.DeclarationKind.CONSTRUCTOR:
         return const [lsp.SymbolKind.Constructor];
       case server.DeclarationKind.ENUM:
-      case server.DeclarationKind.ENUM_CONSTANT:
         return const [lsp.SymbolKind.Enum];
+      case server.DeclarationKind.ENUM_CONSTANT:
+        return const [lsp.SymbolKind.EnumMember, lsp.SymbolKind.Enum];
       case server.DeclarationKind.FIELD:
         return const [lsp.SymbolKind.Field];
       case server.DeclarationKind.FUNCTION:
@@ -201,43 +224,67 @@
   int replacementOffset,
   int replacementLength, {
   @required bool includeCommitCharacters,
+  @required bool completeFunctionCalls,
 }) {
-  // Build display labels and text to insert. insertText and filterText may
-  // differ from label (for ex. if the label includes things like (…)). If
-  // either are missing then label will be used by the client.
-  String label;
-  String insertText;
-  String filterText;
+  final supportsSnippets =
+      completionCapabilities?.completionItem?.snippetSupport == true;
+
+  String completion;
   switch (declaration.kind) {
     case DeclarationKind.ENUM_CONSTANT:
-      label = '${declaration.parent.name}.${declaration.name}';
+      completion = '${declaration.parent.name}.${declaration.name}';
       break;
     case DeclarationKind.GETTER:
     case DeclarationKind.FIELD:
-      label = declaration.parent != null &&
+      completion = declaration.parent != null &&
               declaration.parent.name != null &&
               declaration.parent.name.isNotEmpty
           ? '${declaration.parent.name}.${declaration.name}'
           : declaration.name;
       break;
     case DeclarationKind.CONSTRUCTOR:
-      label = declaration.parent.name;
+      completion = declaration.parent.name;
       if (declaration.name.isNotEmpty) {
-        label += '.${declaration.name}';
+        completion += '.${declaration.name}';
       }
-      insertText = label;
-      filterText = label;
-      label += declaration.parameterNames?.isNotEmpty ?? false ? '(…)' : '()';
-      break;
-    case DeclarationKind.FUNCTION:
-      label = declaration.name;
-      insertText = label;
-      filterText = label;
-      label += declaration.parameterNames?.isNotEmpty ?? false ? '(…)' : '()';
       break;
     default:
-      label = declaration.name;
+      completion = declaration.name;
+      break;
   }
+  // By default, label is the same as the completion text, but may be added to
+  // later (parens/snippets).
+  var label = completion;
+
+  // isCallable is used to suffix the label with parens so it's clear the item
+  // is callable.
+  final declarationKind = declaration.kind;
+  final isCallable = declarationKind == DeclarationKind.CONSTRUCTOR ||
+      declarationKind == DeclarationKind.FUNCTION ||
+      declarationKind == DeclarationKind.METHOD;
+
+  if (isCallable) {
+    label += declaration.parameterNames?.isNotEmpty ?? false ? '(…)' : '()';
+  }
+
+  final insertTextInfo = _buildInsertText(
+    supportsSnippets: supportsSnippets,
+    includeCommitCharacters: includeCommitCharacters,
+    completeFunctionCalls: completeFunctionCalls,
+    isCallable: isCallable,
+    // For SuggestionSets, we don't have a CompletionKind to check if it's
+    // an invocation, but since they do not show in show/hide combinators
+    // we can assume if an item is callable it's probably being used in a context
+    // that can invoke it.
+    isInvocation: isCallable,
+    defaultArgumentListString: declaration.defaultArgumentListString,
+    defaultArgumentListTextRanges: declaration.defaultArgumentListTextRanges,
+    completion: completion,
+    selectionOffset: 0,
+    selectionLength: 0,
+  );
+  final insertText = insertTextInfo.first;
+  final insertTextFormat = insertTextInfo.last;
 
   final supportsDeprecatedFlag =
       completionCapabilities?.completionItem?.deprecatedSupport == true;
@@ -280,14 +327,17 @@
     //  10 -> 999990
     //   1 -> 999999
     sortText: (1000000 - itemRelevance).toString(),
-    filterText: filterText != label
-        ? filterText
+    filterText: completion != label
+        ? completion
         : null, // filterText uses label if not set
     insertText: insertText != label
         ? insertText
         : null, // insertText uses label if not set
+    insertTextFormat: insertTextFormat != lsp.InsertTextFormat.PlainText
+        ? insertTextFormat
+        : null, // Defaults to PlainText if not supplied
     // data, used for completionItem/resolve.
-    data: lsp.CompletionItemResolutionInfo(
+    data: lsp.DartCompletionItemResolutionInfo(
         file: file,
         offset: offset,
         libId: includedSuggestionSet.id,
@@ -380,8 +430,9 @@
       case server.ElementKind.CONSTRUCTOR_INVOCATION:
         return const [lsp.SymbolKind.Constructor];
       case server.ElementKind.ENUM:
-      case server.ElementKind.ENUM_CONSTANT:
         return const [lsp.SymbolKind.Enum];
+      case server.ElementKind.ENUM_CONSTANT:
+        return const [lsp.SymbolKind.EnumMember, lsp.SymbolKind.Enum];
       case server.ElementKind.EXTENSION:
         return const [lsp.SymbolKind.Namespace];
       case server.ElementKind.FIELD:
@@ -767,27 +818,37 @@
   int replacementOffset,
   int replacementLength, {
   @required bool includeCommitCharacters,
+  @required bool completeFunctionCalls,
+  Object resolutionData,
 }) {
   // Build display labels and text to insert. insertText and filterText may
   // differ from label (for ex. if the label includes things like (…)). If
   // either are missing then label will be used by the client.
   var label = suggestion.displayText ?? suggestion.completion;
-  var insertText = suggestion.completion;
-  var filterText = suggestion.completion;
 
   // Trim any trailing comma from the (displayed) label.
   if (label.endsWith(',')) {
     label = label.substring(0, label.length - 1);
   }
 
-  if (suggestion.displayText == null) {
-    switch (suggestion.element?.kind) {
-      case server.ElementKind.CONSTRUCTOR:
-      case server.ElementKind.FUNCTION:
-      case server.ElementKind.METHOD:
-        label += suggestion.parameterNames?.isNotEmpty ?? false ? '(…)' : '()';
-        break;
-    }
+  // isCallable is used to suffix the label with parens so it's clear the item
+  // is callable.
+  //
+  // isInvocation means the location at which it's used is an invocation (and
+  // therefore it is appropriate to include the parens/parameters in the
+  // inserted text).
+  //
+  // In the case of show combinators, the parens will still be shown to indicate
+  // functions but they should not be included in the completions.
+  final elementKind = suggestion.element?.kind;
+  final isCallable = elementKind == server.ElementKind.CONSTRUCTOR ||
+      elementKind == server.ElementKind.FUNCTION ||
+      elementKind == server.ElementKind.METHOD;
+  final isInvocation =
+      suggestion.kind == server.CompletionSuggestionKind.INVOCATION;
+
+  if (suggestion.displayText == null && isCallable) {
+    label += suggestion.parameterNames?.isNotEmpty ?? false ? '(…)' : '()';
   }
 
   final supportsDeprecatedFlag =
@@ -806,15 +867,20 @@
       : suggestionKindToCompletionItemKind(
           supportedCompletionItemKinds, suggestion.kind, label);
 
-  var insertTextFormat = lsp.InsertTextFormat.PlainText;
-  if (supportsSnippets && suggestion.selectionOffset != 0) {
-    insertTextFormat = lsp.InsertTextFormat.Snippet;
-    insertText = buildSnippetStringWithSelection(
-      suggestion.completion,
-      suggestion.selectionOffset,
-      suggestion.selectionLength,
-    );
-  }
+  final insertTextInfo = _buildInsertText(
+    supportsSnippets: supportsSnippets,
+    includeCommitCharacters: includeCommitCharacters,
+    completeFunctionCalls: completeFunctionCalls,
+    isCallable: isCallable,
+    isInvocation: isInvocation,
+    defaultArgumentListString: suggestion.defaultArgumentListString,
+    defaultArgumentListTextRanges: suggestion.defaultArgumentListTextRanges,
+    completion: suggestion.completion,
+    selectionOffset: suggestion.selectionOffset,
+    selectionLength: suggestion.selectionLength,
+  );
+  final insertText = insertTextInfo.first;
+  final insertTextFormat = insertTextInfo.last;
 
   // Because we potentially send thousands of these items, we should minimise
   // the generated JSON as much as possible - for example using nulls in place
@@ -830,6 +896,7 @@
         : null,
     commitCharacters:
         includeCommitCharacters ? dartCompletionCommitCharacters : null,
+    data: resolutionData,
     detail: getCompletionDetail(suggestion, completionKind,
         supportsDeprecatedFlag || supportsDeprecatedTag),
     documentation:
@@ -841,8 +908,8 @@
     //  10 -> 999990
     //   1 -> 999999
     sortText: (1000000 - suggestion.relevance).toString(),
-    filterText: filterText != label
-        ? filterText
+    filterText: suggestion.completion != label
+        ? suggestion.completion
         : null, // filterText uses label if not set
     insertText: insertText != label
         ? insertText
@@ -1026,7 +1093,8 @@
   lsp.Position pos, {
   failureIsCritial = false,
 }) {
-  if (pos.line > lineInfo.lineCount) {
+  // line is zero-based so cannot equal lineCount
+  if (pos.line >= lineInfo.lineCount) {
     return ErrorOr<int>.error(lsp.ResponseError(
         code: failureIsCritial
             ? lsp.ServerErrorCodes.ClientServerInconsistentState
@@ -1210,3 +1278,51 @@
 
   return lsp.MarkupContent(kind: format, value: content);
 }
+
+Pair<String, lsp.InsertTextFormat> _buildInsertText({
+  @required bool supportsSnippets,
+  @required bool includeCommitCharacters,
+  @required bool completeFunctionCalls,
+  @required bool isCallable,
+  @required bool isInvocation,
+  @required String defaultArgumentListString,
+  @required List<int> defaultArgumentListTextRanges,
+  @required String completion,
+  @required int selectionOffset,
+  @required int selectionLength,
+}) {
+  var insertText = completion;
+  var insertTextFormat = lsp.InsertTextFormat.PlainText;
+
+  // If the client supports snippets, we can support completeFunctionCalls or
+  // setting a selection.
+  if (supportsSnippets) {
+    // completeFunctionCalls should only work if commit characters are disabled
+    // otherwise the editor may insert parens that we're also inserting.
+    if (!includeCommitCharacters &&
+        completeFunctionCalls &&
+        isCallable &&
+        isInvocation) {
+      insertTextFormat = lsp.InsertTextFormat.Snippet;
+      final hasRequiredParameters =
+          (defaultArgumentListTextRanges?.length ?? 0) > 0;
+      final functionCallSuffix = hasRequiredParameters
+          ? buildSnippetStringWithTabStops(
+              defaultArgumentListString,
+              defaultArgumentListTextRanges,
+            )
+          : '\${0:}'; // No required params still gets a tabstop in the parens.
+      insertText += '($functionCallSuffix)';
+    } else if (selectionOffset != 0 &&
+        // We don't need a tabstop if the selection is the end of the string.
+        selectionOffset != completion.length) {
+      insertTextFormat = lsp.InsertTextFormat.Snippet;
+      insertText = buildSnippetStringWithTabStops(
+        completion,
+        [selectionOffset, selectionLength],
+      );
+    }
+  }
+
+  return Pair(insertText, insertTextFormat);
+}
diff --git a/pkg/analysis_server/lib/src/lsp/progress.dart b/pkg/analysis_server/lib/src/lsp/progress.dart
index 585c391..45c040a 100644
--- a/pkg/analysis_server/lib/src/lsp/progress.dart
+++ b/pkg/analysis_server/lib/src/lsp/progress.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:math';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
@@ -30,9 +31,9 @@
   ProgressReporter._();
 
   // TODO(dantup): Add support for cancellable progress notifications.
-  void begin(String title, {String message});
+  FutureOr<void> begin(String title, {String message});
 
-  void end([String message]);
+  FutureOr<void> end([String message]);
 }
 
 class _NoopProgressReporter extends ProgressReporter {
@@ -45,7 +46,7 @@
 
 class _ServerCreatedProgressReporter extends _TokenProgressReporter {
   static final _random = Random();
-  Future<ResponseMessage> _tokenCreateRequest;
+  Future<bool> _tokenBeginRequest;
 
   _ServerCreatedProgressReporter(
     LspAnalysisServer server,
@@ -56,28 +57,39 @@
         );
 
   @override
-  void begin(String title, {String message}) {
-    // Create the token lazily so we don't create it if it's not required.
-    _tokenCreateRequest ??= _server.sendRequest(
-        Method.window_workDoneProgress_create,
-        WorkDoneProgressCreateParams(token: _token));
+  Future<void> begin(String title, {String message}) async {
+    assert(_tokenBeginRequest == null,
+        'Begin should not be called more than once');
 
-    // Chain onto the end of tokenCreateRequest so we do not try to use
-    // the token without the client accepting it.
-    _tokenCreateRequest.then((response) {
-      if (response.error != null) return;
+    // Put the create/begin into a future so if end() is called before the
+    // begin is sent (which could happen because create is async), end will
+    // not be sent/return too early.
+    _tokenBeginRequest = _server
+        .sendRequest(Method.window_workDoneProgress_create,
+            WorkDoneProgressCreateParams(token: _token))
+        .then((response) {
+      // If the client did not create a token, do not send begin (and signal
+      // that we should also not send end).
+      if (response.error != null) return false;
       super.begin(title, message: message);
+      return true;
     });
+
+    await _tokenBeginRequest;
   }
 
   @override
-  void end([String message]) {
-    // Chain onto the end of tokenCreateRequest so we do not try to use
-    // the token without the client accepting it.
-    _tokenCreateRequest.then((response) {
-      if (response.error != null) return;
-      super.end(message);
-    });
+  Future<void> end([String message]) async {
+    // Only end the token after both create/begin have completed, and return
+    // a Future to indicate that has happened to callers know when it's safe
+    // to re-use the token identifier.
+    if (_tokenBeginRequest != null) {
+      final didBegin = await _tokenBeginRequest;
+      if (didBegin) {
+        super.end(message);
+      }
+      _tokenBeginRequest = null;
+    }
   }
 
   static String _randomTokenIdentifier() {
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
index 2a7a501e..b621c69 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -30,6 +30,7 @@
     Method.textDocument_documentHighlight,
     Method.textDocument_formatting,
     Method.textDocument_onTypeFormatting,
+    Method.textDocument_rangeFormatting,
     Method.textDocument_definition,
     Method.textDocument_codeAction,
     Method.textDocument_rename,
@@ -71,6 +72,9 @@
   bool get implementation =>
       _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
 
+  bool get rangeFormatting =>
+      _capabilities.textDocument?.rangeFormatting?.dynamicRegistration ?? false;
+
   bool get references =>
       _capabilities.textDocument?.references?.dynamicRegistration ?? false;
 
@@ -187,6 +191,9 @@
                   moreTriggerCharacter:
                       dartTypeFormattingCharacters.skip(1).toList())
               : null,
+      documentRangeFormattingProvider: dynamicRegistrations.typeFormatting
+          ? null
+          : Either2<bool, DocumentRangeFormattingOptions>.t1(enableFormatter),
       renameProvider: dynamicRegistrations.rename
           ? null
           : renameOptionsSupport
@@ -203,7 +210,7 @@
         commands: Commands.serverSupportedCommands,
         workDoneProgress: true,
       ),
-      workspaceSymbolProvider: true,
+      workspaceSymbolProvider: Either2<bool, WorkspaceSymbolOptions>.t1(true),
       workspace: ServerCapabilitiesWorkspace(
           workspaceFolders: WorkspaceFoldersServerCapabilities(
         supported: true,
@@ -235,15 +242,25 @@
         // folders as well.
         .map((glob) => DocumentFilter(scheme: 'file', pattern: '**/$glob'));
 
-    final allTypes = {dartFiles, ...pluginTypes}.toList();
+    final fullySupportedTypes = {dartFiles, ...pluginTypes}.toList();
 
     // Add pubspec + analysis options only for synchronisation. We do not support
     // things like hovers/formatting/etc. for these files so there's no point
     // in having the client send those requests (plus, for things like formatting
     // this could result in the editor reporting "multiple formatters installed"
     // and prevent a built-in YAML formatter from being selected).
-    final allSynchronisedTypes = {
-      ...allTypes,
+    final synchronisedTypes = {
+      ...fullySupportedTypes,
+      pubspecFile,
+      analysisOptionsFile,
+      fixDataFile,
+    }.toList();
+
+    // Completion is supported for some synchronised files that we don't _fully_
+    // support (eg. YAML). If these gain support for things like hover, we may
+    // wish to move them to fullySupprtedTypes but add an exclusion for formatting.
+    final completionSupportedTypes = {
+      ...fullySupportedTypes,
       pubspecFile,
       analysisOptionsFile,
       fixDataFile,
@@ -271,25 +288,25 @@
     register(
       dynamicRegistrations.textSync,
       Method.textDocument_didOpen,
-      TextDocumentRegistrationOptions(documentSelector: allSynchronisedTypes),
+      TextDocumentRegistrationOptions(documentSelector: synchronisedTypes),
     );
     register(
       dynamicRegistrations.textSync,
       Method.textDocument_didClose,
-      TextDocumentRegistrationOptions(documentSelector: allSynchronisedTypes),
+      TextDocumentRegistrationOptions(documentSelector: synchronisedTypes),
     );
     register(
       dynamicRegistrations.textSync,
       Method.textDocument_didChange,
       TextDocumentChangeRegistrationOptions(
           syncKind: TextDocumentSyncKind.Incremental,
-          documentSelector: allSynchronisedTypes),
+          documentSelector: synchronisedTypes),
     );
     register(
       dynamicRegistrations.completion,
       Method.textDocument_completion,
       CompletionRegistrationOptions(
-        documentSelector: allTypes,
+        documentSelector: completionSupportedTypes,
         triggerCharacters: dartCompletionTriggerCharacters,
         allCommitCharacters:
             previewCommitCharacters ? dartCompletionCommitCharacters : null,
@@ -299,13 +316,13 @@
     register(
       dynamicRegistrations.hover,
       Method.textDocument_hover,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       dynamicRegistrations.signatureHelp,
       Method.textDocument_signatureHelp,
       SignatureHelpRegistrationOptions(
-        documentSelector: allTypes,
+        documentSelector: fullySupportedTypes,
         triggerCharacters: dartSignatureHelpTriggerCharacters,
         retriggerCharacters: dartSignatureHelpRetriggerCharacters,
       ),
@@ -313,22 +330,22 @@
     register(
       dynamicRegistrations.references,
       Method.textDocument_references,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       dynamicRegistrations.documentHighlights,
       Method.textDocument_documentHighlight,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       dynamicRegistrations.documentSymbol,
       Method.textDocument_documentSymbol,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       enableFormatter && dynamicRegistrations.formatting,
       Method.textDocument_formatting,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       enableFormatter && dynamicRegistrations.typeFormatting,
@@ -340,20 +357,27 @@
       ),
     );
     register(
+      enableFormatter && dynamicRegistrations.rangeFormatting,
+      Method.textDocument_rangeFormatting,
+      DocumentRangeFormattingRegistrationOptions(
+        documentSelector: [dartFiles], // This one is currently Dart-specific
+      ),
+    );
+    register(
       dynamicRegistrations.definition,
       Method.textDocument_definition,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       dynamicRegistrations.implementation,
       Method.textDocument_implementation,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       dynamicRegistrations.codeActions,
       Method.textDocument_codeAction,
       CodeActionRegistrationOptions(
-        documentSelector: allTypes,
+        documentSelector: fullySupportedTypes,
         codeActionKinds: DartCodeActionKind.serverSupportedKinds,
       ),
     );
@@ -361,12 +385,12 @@
       dynamicRegistrations.rename,
       Method.textDocument_rename,
       RenameRegistrationOptions(
-          documentSelector: allTypes, prepareProvider: true),
+          documentSelector: fullySupportedTypes, prepareProvider: true),
     );
     register(
       dynamicRegistrations.folding,
       Method.textDocument_foldingRange,
-      TextDocumentRegistrationOptions(documentSelector: allTypes),
+      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
       dynamicRegistrations.didChangeConfiguration,
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index 2105c85..b98a101 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -7,7 +7,13 @@
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/protocol_server.dart' as server
     show SourceEdit;
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/utilities/pair.dart';
 import 'package:dart_style/dart_style.dart';
@@ -70,9 +76,13 @@
   return ErrorOr.success(Pair(newContent, serverEdits));
 }
 
-List<TextEdit> generateEditsForFormatting(
-    String unformattedSource, int lineLength) {
-  final lineInfo = LineInfo.fromContent(unformattedSource);
+ErrorOr<List<TextEdit>> generateEditsForFormatting(
+  ParsedUnitResult result,
+  int lineLength, {
+  Range range,
+}) {
+  final unformattedSource = result.content;
+
   final code =
       SourceCode(unformattedSource, uri: null, isCompilationUnit: true);
   SourceCode formattedResult;
@@ -87,16 +97,19 @@
     // use seeing edits on every save with invalid code (if LSP gains the
     // ability to pass a context to know if the format was manually invoked
     // we may wish to change this to return an error for that case).
-    return null;
+    return success();
   }
   final formattedSource = formattedResult.text;
 
   if (formattedSource == unformattedSource) {
-    return null;
+    return success();
   }
 
-  // We don't currently support returning "minimal" edits, we just replace
-  // entire document.
+  return _generateMinimalEdits(result, formattedSource, range: range);
+}
+
+List<TextEdit> _generateFullEdit(
+    LineInfo lineInfo, String unformattedSource, String formattedSource) {
   final end = lineInfo.getLocation(unformattedSource.length);
   return [
     TextEdit(
@@ -107,6 +120,185 @@
   ];
 }
 
+/// Generates edits that modify the minimum amount of code (only whitespace) to
+/// change [unformatted] to [formatted].
+///
+/// This allows editors to more easily track important locations (such as
+/// breakpoints) without needing to do their own diffing.
+///
+/// If [range] is supplied, only whitespace edits that fall entirely inside this
+/// range will be included in the results.
+ErrorOr<List<TextEdit>> _generateMinimalEdits(
+  ParsedUnitResult result,
+  String formatted, {
+  Range range,
+}) {
+  final unformatted = result.content;
+  final lineInfo = result.lineInfo;
+  final rangeStart = range != null ? toOffset(lineInfo, range.start) : null;
+  final rangeEnd = range != null ? toOffset(lineInfo, range.end) : null;
+
+  if (rangeStart?.isError ?? false) {
+    return failure(rangeStart);
+  }
+  if (rangeEnd?.isError ?? false) {
+    return failure(rangeEnd);
+  }
+
+  // It shouldn't be the case that we can't parse the code but if it happens
+  // fall back to a full replacement rather than fail.
+  final parsedFormatted = _parse(formatted, result.unit.featureSet);
+  final parsedUnformatted = _parse(unformatted, result.unit.featureSet);
+  if (parsedFormatted == null || parsedUnformatted == null) {
+    return success(_generateFullEdit(lineInfo, unformatted, formatted));
+  }
+
+  final unformattedTokens = _iterateAllTokens(parsedUnformatted).iterator;
+  final formattedTokens = _iterateAllTokens(parsedFormatted).iterator;
+
+  var unformattedOffset = 0;
+  var formattedOffset = 0;
+  final edits = <TextEdit>[];
+
+  /// Helper for comparing whitespace and appending an edit.
+  void addEditFor(
+    int unformattedStart,
+    int unformattedEnd,
+    int formattedStart,
+    int formattedEnd,
+  ) {
+    if (rangeStart != null && rangeEnd != null) {
+      // If we're formatting only a range, skip over any segments that don't fall
+      // entirely within that range.
+      if (unformattedStart < rangeStart.result ||
+          unformattedEnd > rangeEnd.result) {
+        return;
+      }
+    }
+
+    final unformattedWhitespace =
+        unformatted.substring(unformattedStart, unformattedEnd);
+    final formattedWhitespace =
+        formatted.substring(formattedStart, formattedEnd);
+
+    if (unformattedWhitespace == formattedWhitespace) {
+      return;
+    }
+
+    // Validate we didn't find more than whitespace. If this occurs, it's likely
+    // the token offsets used were incorrect. In this case it's better to not
+    // modify the code than potentially remove something important.
+    if (unformattedWhitespace.trim().isNotEmpty ||
+        formattedWhitespace.trim().isNotEmpty) {
+      return;
+    }
+
+    var startOffset = unformattedStart;
+    var endOffset = unformattedEnd;
+    var newText = formattedWhitespace;
+
+    // Simplify some common cases where the new whitespace is a subset of
+    // the old.
+    if (formattedWhitespace.isNotEmpty) {
+      if (unformattedWhitespace.startsWith(formattedWhitespace)) {
+        startOffset = unformattedStart + formattedWhitespace.length;
+        newText = '';
+      } else if (unformattedWhitespace.endsWith(formattedWhitespace)) {
+        endOffset = unformattedEnd - formattedWhitespace.length;
+        newText = '';
+      }
+    }
+
+    // Finally, append the edit for this whitespace.
+    // Note: As with all LSP edits, offsets are based on the original location
+    // as they are applied in one shot. They should not account for the previous
+    // edits in the same set.
+    edits.add(TextEdit(
+      range: Range(
+        start: toPosition(lineInfo.getLocation(startOffset)),
+        end: toPosition(lineInfo.getLocation(endOffset)),
+      ),
+      newText: newText,
+    ));
+  }
+
+  // Process the whitespace before each token.
+  bool unformattedHasMore, formattedHasMore;
+  while ((unformattedHasMore =
+          unformattedTokens.moveNext()) & // Don't short-circuit
+      (formattedHasMore = formattedTokens.moveNext())) {
+    final unformattedToken = unformattedTokens.current;
+    final formattedToken = formattedTokens.current;
+
+    if (unformattedToken.lexeme != formattedToken.lexeme) {
+      // If the token lexems do not match, there is a difference in the parsed
+      // token streams (this should not ordinarily happen) so fall back to a
+      // full edit.
+      return success(_generateFullEdit(lineInfo, unformatted, formatted));
+    }
+
+    addEditFor(
+      unformattedOffset,
+      unformattedToken.offset,
+      formattedOffset,
+      formattedToken.offset,
+    );
+
+    // When range formatting, if we've processed a token that ends after the
+    // range then there can't be any more relevant edits and we can return early.
+    if (rangeEnd != null && unformattedToken.end > rangeEnd.result) {
+      return success(edits);
+    }
+
+    unformattedOffset = unformattedToken.end;
+    formattedOffset = formattedToken.end;
+  }
+
+  // If we got here and either of the streams still have tokens, something
+  // did not match so fall back to a full edit.
+  if (unformattedHasMore || formattedHasMore) {
+    return success(_generateFullEdit(lineInfo, unformatted, formatted));
+  }
+
+  // Finally, handle any whitespace that was after the last token.
+  addEditFor(
+    unformattedOffset,
+    unformatted.length,
+    formattedOffset,
+    formatted.length,
+  );
+
+  return success(edits);
+}
+
+/// Iterates over a token stream returning all tokens including comments.
+Iterable<Token> _iterateAllTokens(Token token) sync* {
+  while (token.type != TokenType.EOF) {
+    var commentToken = token.precedingComments;
+    while (commentToken != null) {
+      yield commentToken;
+      commentToken = commentToken.next;
+    }
+    yield token;
+    token = token.next;
+  }
+}
+
+/// Parse and return the first of the given Dart source, `null` if code cannot
+/// be parsed.
+Token _parse(String s, FeatureSet featureSet) {
+  try {
+    var scanner = Scanner(null, CharSequenceReader(s), null)
+      ..configureFeatures(
+        featureSetForOverriding: featureSet,
+        featureSet: featureSet,
+      );
+    return scanner.tokenize();
+  } catch (e) {
+    return null;
+  }
+}
+
 /// Helper class that bundles up all information required when converting server
 /// SourceEdits into LSP-compatible WorkspaceEdits.
 class FileEditInformation {
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index c26fd4a..a53a0cf 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -6,7 +6,6 @@
 import 'package:analysis_server/src/computer/computer_closingLabels.dart';
 import 'package:analysis_server/src/computer/computer_folding.dart';
 import 'package:analysis_server/src/computer/computer_highlights.dart';
-import 'package:analysis_server/src/computer/computer_highlights2.dart';
 import 'package:analysis_server/src/computer/computer_outline.dart';
 import 'package:analysis_server/src/computer/computer_overrides.dart';
 import 'package:analysis_server/src/domains/analysis/implemented_dart.dart';
@@ -100,12 +99,7 @@
 void sendAnalysisNotificationHighlights(
     AnalysisServer server, String file, CompilationUnit dartUnit) {
   _sendNotification(server, () {
-    List<protocol.HighlightRegion> regions;
-    if (server.options.useAnalysisHighlight2) {
-      regions = DartUnitHighlightsComputer2(dartUnit).compute();
-    } else {
-      regions = DartUnitHighlightsComputer(dartUnit).compute();
-    }
+    var regions = DartUnitHighlightsComputer(dartUnit).compute();
     var params = protocol.AnalysisHighlightsParams(file, regions);
     server.sendNotification(params.toNotification());
   });
diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
index 06e7ddb..88b348e 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
@@ -46,10 +46,6 @@
   /// requested, or `null` if the content could not be accessed.
   String get sourceContents;
 
-  /// Return `true` if the new relevance computations should be used when
-  /// computing code completion suggestions.
-  bool get useNewRelevance;
-
   /// Throw [AbortCompletion] if the completion request has been aborted.
   void checkAborted();
 }
diff --git a/pkg/analysis_server/lib/src/server/crash_reporting.dart b/pkg/analysis_server/lib/src/server/crash_reporting.dart
index 59cecd9..c76bba4 100644
--- a/pkg/analysis_server/lib/src/server/crash_reporting.dart
+++ b/pkg/analysis_server/lib/src/server/crash_reporting.dart
@@ -8,16 +8,11 @@
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:telemetry/crash_reporting.dart';
 
-const _angularPluginName = 'Angular Analysis Plugin';
-
 class CrashReportingInstrumentation extends NoopInstrumentationService {
   // A prod reporter, for analysis server crashes.
   final CrashReportSender serverReporter;
 
-  // The angular plugin crash reporter.
-  final CrashReportSender angularReporter;
-
-  CrashReportingInstrumentation(this.serverReporter, this.angularReporter);
+  CrashReportingInstrumentation(this.serverReporter);
 
   @override
   void logException(dynamic exception,
@@ -48,14 +43,7 @@
     dynamic exception,
     StackTrace stackTrace,
   ) {
-    if (plugin.name == _angularPluginName) {
-      angularReporter.sendReport(exception, stackTrace).catchError((error) {
-        // We silently ignore errors sending crash reports (network issues, ...).
-      });
-    } else {
-      _sendServerReport(exception, stackTrace,
-          comment: 'plugin: ${plugin.name}');
-    }
+    _sendServerReport(exception, stackTrace, comment: 'plugin: ${plugin.name}');
   }
 
   void _sendServerReport(Object exception, Object stackTrace,
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 8e7af39..183c669 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:ffi' as ffi;
 import 'dart:io';
 import 'dart:isolate';
 import 'dart:math';
@@ -24,11 +23,9 @@
 import 'package:analysis_server/src/server/lsp_stdio_server.dart';
 import 'package:analysis_server/src/server/sdk_configuration.dart';
 import 'package:analysis_server/src/server/stdio_server.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analysis_server/src/utilities/request_statistics.dart';
 import 'package:analysis_server/starter.dart';
-import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/file_instrumentation.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -38,178 +35,15 @@
 import 'package:args/args.dart';
 import 'package:cli_util/cli_util.dart';
 import 'package:linter/src/rules.dart' as linter;
-import 'package:path/path.dart' as path;
 import 'package:telemetry/crash_reporting.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
 
-/// Commandline argument parser. (Copied from analyzer/lib/options.dart)
-/// TODO(pquitslund): replaces with a simple [ArgParser] instance
-/// when the args package supports ignoring unrecognized
-/// options/flags (https://github.com/dart-lang/args/issues/9).
-/// TODO(devoncarew): Consider removing the ability to support unrecognized
-/// flags for the analysis server.
-class CommandLineParser {
-  final List<String> _knownFlags;
-  final ArgParser _parser;
-
-  /// Creates a new command line parser
-  CommandLineParser()
-      : _knownFlags = <String>[],
-        _parser = ArgParser(allowTrailingOptions: true);
-
-  ArgParser get parser => _parser;
-
-  /// Defines a flag.
-  /// See [ArgParser.addFlag()].
-  void addFlag(String name,
-      {String abbr,
-      String help,
-      bool defaultsTo = false,
-      bool negatable = true,
-      void Function(bool value) callback,
-      bool hide = false}) {
-    _knownFlags.add(name);
-    _parser.addFlag(name,
-        abbr: abbr,
-        help: help,
-        defaultsTo: defaultsTo,
-        negatable: negatable,
-        callback: callback,
-        hide: hide);
-  }
-
-  /// Defines an option that takes multiple values.
-  /// See [ArgParser.addMultiOption].
-  void addMultiOption(String name,
-      {String abbr,
-      String help,
-      String valueHelp,
-      Iterable<String> allowed,
-      Map<String, String> allowedHelp,
-      Iterable<String> defaultsTo,
-      void Function(List<String> values) callback,
-      bool splitCommas = true,
-      bool hide = false}) {
-    _knownFlags.add(name);
-    _parser.addMultiOption(name,
-        abbr: abbr,
-        help: help,
-        valueHelp: valueHelp,
-        allowed: allowed,
-        allowedHelp: allowedHelp,
-        defaultsTo: defaultsTo,
-        callback: callback,
-        splitCommas: splitCommas,
-        hide: hide);
-  }
-
-  /// Defines a value-taking option.
-  /// See [ArgParser.addOption()].
-  void addOption(String name,
-      {String abbr,
-      String help,
-      String valueHelp,
-      List<String> allowed,
-      Map<String, String> allowedHelp,
-      String defaultsTo,
-      void Function(Object) callback}) {
-    _knownFlags.add(name);
-    _parser.addOption(name,
-        abbr: abbr,
-        help: help,
-        valueHelp: valueHelp,
-        allowed: allowed,
-        allowedHelp: allowedHelp,
-        defaultsTo: defaultsTo,
-        callback: callback);
-  }
-
-  /// Generates a string displaying usage information for the defined options.
-  /// See [ArgParser.usage].
-  String getUsage() => _parser.usage;
-
-  /// Parses [args], a list of command-line arguments, matches them against the
-  /// flags and options defined by this parser, and returns the result. The
-  /// values of any defined variables are captured in the given map.
-  /// See [ArgParser].
-  ArgResults parse(List<String> args, Map<String, String> definedVariables) =>
-      _parser.parse(
-          _filterUnknowns(parseDefinedVariables(args, definedVariables)));
-
-  List<String> parseDefinedVariables(
-      List<String> args, Map<String, String> definedVariables) {
-    var count = args.length;
-    var remainingArgs = <String>[];
-    for (var i = 0; i < count; i++) {
-      var arg = args[i];
-      if (arg == '--') {
-        while (i < count) {
-          remainingArgs.add(args[i++]);
-        }
-      } else if (arg.startsWith('-D')) {
-        definedVariables[arg.substring(2)] = args[++i];
-      } else {
-        remainingArgs.add(arg);
-      }
-    }
-    return remainingArgs;
-  }
-
-  List<String> _filterUnknowns(List<String> args) {
-    // TODO(devoncarew): Consider dropping support for the
-    // --ignore-unrecognized-flags option.
-
-    // Only filter args if the ignore flag is specified.
-    if (args.contains('--ignore-unrecognized-flags')) {
-      // Filter all unrecognized flags and options.
-      var filtered = <String>[];
-      for (var i = 0; i < args.length; ++i) {
-        var arg = args[i];
-        if (arg.startsWith('--') && arg.length > 2) {
-          var option = arg.substring(2);
-          // remove any leading 'no-'
-          if (option.startsWith('no-')) {
-            option = option.substring(3);
-          }
-          // strip the last '=value'
-          var equalsOffset = option.lastIndexOf('=');
-          if (equalsOffset != -1) {
-            option = option.substring(0, equalsOffset);
-          }
-          // check the option
-          if (!_knownFlags.contains(option)) {
-            //"eat" params by advancing to the next flag/option
-            i = _getNextFlagIndex(args, i);
-          } else {
-            filtered.add(arg);
-          }
-        } else {
-          filtered.add(arg);
-        }
-      }
-
-      return filtered;
-    } else {
-      return args;
-    }
-  }
-
-  int _getNextFlagIndex(List<String> args, int i) {
-    for (; i < args.length; ++i) {
-      if (args[i].startsWith('--')) {
-        return i;
-      }
-    }
-    return i;
-  }
-}
-
 /// The [Driver] class represents a single running instance of the analysis
 /// server application.  It is responsible for parsing command line options
 /// and starting the HTTP and/or stdio servers.
 class Driver implements ServerStarter {
   /// The name of the application that is used to start a server.
-  static const BINARY_NAME = 'server';
+  static const BINARY_NAME = 'analysis_server';
 
   /// The name of the option used to set the identifier for the client.
   static const String CLIENT_ID = 'client-id';
@@ -229,9 +63,6 @@
   static const String DISABLE_SERVER_FEATURE_SEARCH =
       'disable-server-feature-search';
 
-  /// The name of the option used to set the file read mode.
-  static const String FILE_READ_MODE = 'file-read-mode';
-
   /// The name of the option used to print usage information.
   static const String HELP_OPTION = 'help';
 
@@ -243,26 +74,26 @@
 
   /// The name of the option used to cause instrumentation to also be written to
   /// a local file.
-  static const String INSTRUMENTATION_LOG_FILE = 'instrumentation-log-file';
+  static const String PROTOCOL_TRAFFIC_LOG = 'protocol-traffic-log';
+  static const String PROTOCOL_TRAFFIC_LOG_ALIAS = 'instrumentation-log-file';
 
   /// The name of the option used to specify if [print] should print to the
   /// console instead of being intercepted.
   static const String INTERNAL_PRINT_TO_CONSOLE = 'internal-print-to-console';
 
   /// The name of the option used to describe the new analysis driver logger.
-  static const String NEW_ANALYSIS_DRIVER_LOG = 'new-analysis-driver-log';
-
-  /// The name of the flag used to enable version 2 of semantic highlight
-  /// notification.
-  static const String USE_ANALYSIS_HIGHLIGHT2 = 'useAnalysisHighlight2';
+  static const String ANALYSIS_DRIVER_LOG = 'analysis-driver-log';
+  static const String ANALYSIS_DRIVER_LOG_ALIAS = 'new-analysis-driver-log';
 
   /// The option for specifying the http diagnostic port.
   /// If specified, users can review server status and performance information
   /// by opening a web browser on http://localhost:<port>
-  static const String PORT_OPTION = 'port';
+  static const String DIAGNOSTIC_PORT = 'diagnostic-port';
+  static const String DIAGNOSTIC_PORT_ALIAS = 'port';
 
   /// The path to the SDK.
-  static const String SDK_OPTION = 'sdk';
+  static const String DART_SDK = 'dart-sdk';
+  static const String DART_SDK_ALIAS = 'sdk';
 
   /// The path to the data cache.
   static const String CACHE_FOLDER = 'cache';
@@ -270,20 +101,9 @@
   /// The name of the flag to use the Language Server Protocol (LSP).
   static const String USE_LSP = 'lsp';
 
-  /// Whether or not to enable ML ranking for code completion.
-  static const String ENABLE_COMPLETION_MODEL = 'enable-completion-model';
-
-  /// The path on disk to a directory containing language model files for smart
-  /// code completion.
-  static const String COMPLETION_MODEL_FOLDER = 'completion-model';
-
   /// A directory to analyze in order to train an analysis server snapshot.
   static const String TRAIN_USING = 'train-using';
 
-  /// A flag indicating that the new code completion relevance computation
-  /// should be used to compute relevance scores.
-  static const String USE_NEW_RELEVANCE = 'use-new-relevance';
-
   /// The builder for attachments that should be included into crash reports.
   CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder =
       CrashReportingAttachmentsBuilder.empty;
@@ -306,14 +126,11 @@
   @override
   void start(List<String> arguments, [SendPort sendPort]) {
     var parser = _createArgParser();
-    var results = parser.parse(arguments, <String, String>{});
+    var results = parser.parse(arguments);
 
     var analysisServerOptions = AnalysisServerOptions();
-    analysisServerOptions.useAnalysisHighlight2 =
-        results[USE_ANALYSIS_HIGHLIGHT2];
-    analysisServerOptions.fileReadMode = results[FILE_READ_MODE];
     analysisServerOptions.newAnalysisDriverLog =
-        results[NEW_ANALYSIS_DRIVER_LOG];
+        results[ANALYSIS_DRIVER_LOG] ?? results[ANALYSIS_DRIVER_LOG_ALIAS];
     analysisServerOptions.clientId = results[CLIENT_ID];
     analysisServerOptions.useLanguageServerProtocol = results[USE_LSP];
     // For clients that don't supply their own identifier, use a default based on
@@ -325,41 +142,11 @@
 
     analysisServerOptions.clientVersion = results[CLIENT_VERSION];
     analysisServerOptions.cacheFolder = results[CACHE_FOLDER];
-    analysisServerOptions.useNewRelevance = results[USE_NEW_RELEVANCE];
 
     // Read in any per-SDK overrides specified in <sdk>/config/settings.json.
     var sdkConfig = SdkConfiguration.readFromSdk();
     analysisServerOptions.configurationOverrides = sdkConfig;
 
-    // ML model configuration.
-    // TODO(brianwilkerson) Uncomment the line below and delete the second line
-    //  when there is a new completion model to query. Until then we ignore the
-    //  flag to enable the model so that we can't try to read from a file that
-    //  doesn't exist.
-//    final bool enableCompletionModel = results[ENABLE_COMPLETION_MODEL];
-    final enableCompletionModel = false;
-    analysisServerOptions.completionModelFolder =
-        results[COMPLETION_MODEL_FOLDER];
-    if (results.wasParsed(ENABLE_COMPLETION_MODEL) && !enableCompletionModel) {
-      // This is the case where the user has explicitly turned off model-based
-      // code completion.
-      analysisServerOptions.completionModelFolder = null;
-    }
-    // TODO(devoncarew): Simplify this logic and use the value from sdkConfig.
-    if (enableCompletionModel &&
-        analysisServerOptions.completionModelFolder == null) {
-      // The user has enabled ML code completion without explicitly setting a
-      // model for us to choose, so use the default one. We need to walk over
-      // from $SDK/bin/snapshots/analysis_server.dart.snapshot to
-      // $SDK/bin/model/lexeme.
-      analysisServerOptions.completionModelFolder = path.join(
-        File.fromUri(Platform.script).parent.path,
-        '..',
-        'model',
-        'lexeme',
-      );
-    }
-
     // Analytics
     bool disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG];
     if (results.wasParsed(TRAIN_USING)) {
@@ -399,9 +186,6 @@
     final crashProductId = sdkConfig.crashReportingId ?? 'Dart_analysis_server';
     final crashReportSender =
         CrashReportSender.prod(crashProductId, shouldSendCallback);
-    // TODO(mfairhurst): send these to prod or disable.
-    final crashReportSenderAngular = CrashReportSender.staging(
-        'Dart_angular_analysis_plugin', shouldSendCallback);
 
     if (telemetry.SHOW_ANALYTICS_UI) {
       if (results.wasParsed(ANALYTICS_FLAG)) {
@@ -423,7 +207,7 @@
     }
 
     if (results[HELP_OPTION]) {
-      _printUsage(parser.parser, analytics, fromHelp: true);
+      _printUsage(parser, analytics, fromHelp: true);
       return null;
     }
 
@@ -437,7 +221,8 @@
     //
     // Initialize the instrumentation service.
     //
-    String logFilePath = results[INSTRUMENTATION_LOG_FILE];
+    String logFilePath =
+        results[PROTOCOL_TRAFFIC_LOG] ?? results[PROTOCOL_TRAFFIC_LOG_ALIAS];
     var allInstrumentationServices = instrumentationService == null
         ? <InstrumentationService>[]
         : [instrumentationService];
@@ -448,8 +233,8 @@
     }
 
     var errorNotifier = ErrorNotifier();
-    allInstrumentationServices.add(CrashReportingInstrumentation(
-        crashReportSender, crashReportSenderAngular));
+    allInstrumentationServices
+        .add(CrashReportingInstrumentation(crashReportSender));
     instrumentationService =
         MulticastInstrumentationService(allInstrumentationServices);
 
@@ -465,13 +250,15 @@
     AnalysisEngine.instance.instrumentationService = instrumentationService;
 
     int diagnosticServerPort;
-    if (results[PORT_OPTION] != null) {
+    final String portValue =
+        results[DIAGNOSTIC_PORT] ?? results[DIAGNOSTIC_PORT_ALIAS];
+    if (portValue != null) {
       try {
-        diagnosticServerPort = int.parse(results[PORT_OPTION]);
+        diagnosticServerPort = int.parse(portValue);
       } on FormatException {
-        print('Invalid port number: ${results[PORT_OPTION]}');
+        print('Invalid port number: $portValue');
         print('');
-        _printUsage(parser.parser, analytics);
+        _printUsage(parser, analytics);
         exitCode = 1;
         return null;
       }
@@ -503,7 +290,7 @@
   void startAnalysisServer(
     ArgResults results,
     AnalysisServerOptions analysisServerOptions,
-    CommandLineParser parser,
+    ArgParser parser,
     DartSdkManager dartSdkManager,
     CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
     InstrumentationService instrumentationService,
@@ -614,7 +401,6 @@
           socketServer.analysisServer.shutdown();
           if (sendPort == null) exit(0);
         });
-        startCompletionRanking(socketServer, null, analysisServerOptions);
       },
           print: results[INTERNAL_PRINT_TO_CONSOLE]
               ? null
@@ -622,36 +408,6 @@
     }
   }
 
-  /// This will be invoked after createAnalysisServer has been called on the
-  /// socket server. At that point, we'll be able to send a server.error
-  /// notification in case model startup fails.
-  void startCompletionRanking(
-      SocketServer socketServer,
-      LspSocketServer lspSocketServer,
-      AnalysisServerOptions analysisServerOptions) {
-    // If ML completion is not enabled, or we're on a 32-bit machine, don't try
-    // and start the completion model.
-    if (analysisServerOptions.completionModelFolder == null ||
-        ffi.sizeOf<ffi.IntPtr>() == 4) {
-      return;
-    }
-
-    // Start completion model isolate if this is a 64 bit system and analysis
-    // server was configured to load a language model on disk.
-    CompletionRanking.instance =
-        CompletionRanking(analysisServerOptions.completionModelFolder);
-    CompletionRanking.instance.start().catchError((exception, stackTrace) {
-      // Disable smart ranking if model startup fails.
-      analysisServerOptions.completionModelFolder = null;
-      // TODO(brianwilkerson) Shutdown the isolates that have already been
-      //  started.
-      CompletionRanking.instance = null;
-      AnalysisEngine.instance.instrumentationService.logException(
-          CaughtException.withMessage(
-              'Failed to start ranking model isolate', exception, stackTrace));
-    });
-  }
-
   void startLspServer(
     ArgResults args,
     AnalysisServerOptions analysisServerOptions,
@@ -694,7 +450,6 @@
           exit(0);
         }
       });
-      startCompletionRanking(null, socketServer, analysisServerOptions);
     });
   }
 
@@ -724,17 +479,64 @@
   }
 
   /// Create and return the parser used to parse the command-line arguments.
-  CommandLineParser _createArgParser() {
-    var parser = CommandLineParser();
+  ArgParser _createArgParser() {
+    var parser = ArgParser();
     parser.addFlag(HELP_OPTION,
-        help: 'print this help message without starting a server',
-        abbr: 'h',
-        defaultsTo: false,
-        negatable: false);
+        abbr: 'h', negatable: false, help: 'Print this usage information.');
     parser.addOption(CLIENT_ID,
-        valueHelp: 'name', help: 'an identifier used to identify the client');
+        valueHelp: 'name',
+        help: 'An identifier for the analysis server client.');
     parser.addOption(CLIENT_VERSION,
-        valueHelp: 'version', help: 'the version of the client');
+        valueHelp: 'version',
+        help: 'The version of the analysis server client.');
+    parser.addOption(DART_SDK,
+        valueHelp: 'path', help: 'Override the Dart SDK to use for analysis.');
+    parser.addOption(DART_SDK_ALIAS, hide: true);
+    parser.addOption(CACHE_FOLDER,
+        valueHelp: 'path',
+        help: 'Override the location of the analysis server\'s cache.');
+    parser.addFlag(USE_LSP,
+        defaultsTo: false,
+        negatable: false,
+        help: 'Whether to use the Language Server Protocol (LSP).');
+
+    parser.addSeparator('Server diagnostics:');
+
+    parser.addOption(PROTOCOL_TRAFFIC_LOG,
+        valueHelp: 'file path',
+        help: 'Write server protocol traffic to the given file.');
+    parser.addOption(PROTOCOL_TRAFFIC_LOG_ALIAS, hide: true);
+
+    parser.addOption(ANALYSIS_DRIVER_LOG,
+        valueHelp: 'file path',
+        help: 'Write analysis driver diagnostic data to the given file.');
+    parser.addOption(ANALYSIS_DRIVER_LOG_ALIAS, hide: true);
+
+    parser.addOption(DIAGNOSTIC_PORT,
+        valueHelp: 'port',
+        help: 'Serve a web UI for status and performance data on the given '
+            'port.');
+    parser.addOption(DIAGNOSTIC_PORT_ALIAS, hide: true);
+
+    //
+    // Hidden; these have not yet been made public.
+    //
+    parser.addFlag(ANALYTICS_FLAG,
+        help: 'enable or disable sending analytics information to Google',
+        hide: !telemetry.SHOW_ANALYTICS_UI);
+    parser.addFlag(SUPPRESS_ANALYTICS_FLAG,
+        negatable: false,
+        help: 'suppress analytics for this session',
+        hide: !telemetry.SHOW_ANALYTICS_UI);
+
+    //
+    // Hidden; these are for internal development.
+    //
+    parser.addOption(TRAIN_USING,
+        valueHelp: 'path',
+        help: 'Pass in a directory to analyze for purposes of training an '
+            'analysis server snapshot.',
+        hide: true);
     parser.addFlag(DISABLE_SERVER_EXCEPTION_HANDLING,
         // TODO(jcollins-g): Pipeline option through and apply to all
         // exception-nullifying runZoned() calls.
@@ -746,80 +548,36 @@
         help: 'disable all completion features', defaultsTo: false, hide: true);
     parser.addFlag(DISABLE_SERVER_FEATURE_SEARCH,
         help: 'disable all search features', defaultsTo: false, hide: true);
-    parser.addOption(INSTRUMENTATION_LOG_FILE,
-        valueHelp: 'file path',
-        help: 'write instrumentation data to the given file');
     parser.addFlag(INTERNAL_PRINT_TO_CONSOLE,
         help: 'enable sending `print` output to the console',
         defaultsTo: false,
-        negatable: false);
-    parser.addOption(NEW_ANALYSIS_DRIVER_LOG,
-        valueHelp: 'path',
-        help: "set a destination for the new analysis driver's log");
-    parser.addFlag(ANALYTICS_FLAG,
-        help: 'enable or disable sending analytics information to Google',
-        hide: !telemetry.SHOW_ANALYTICS_UI);
-    parser.addFlag(SUPPRESS_ANALYTICS_FLAG,
         negatable: false,
-        help: 'suppress analytics for this session',
-        hide: !telemetry.SHOW_ANALYTICS_UI);
-    parser.addOption(PORT_OPTION,
-        valueHelp: 'port',
-        help: 'the http diagnostic port on which the server provides'
-            ' status and performance information');
-    parser.addOption(SDK_OPTION,
-        valueHelp: 'path', help: 'Path to the Dart sdk');
-    parser.addFlag(USE_ANALYSIS_HIGHLIGHT2,
-        help: 'enable version 2 of semantic highlight',
-        defaultsTo: false,
-        negatable: false);
-    parser.addOption(FILE_READ_MODE,
-        help: 'an option for reading files (some clients normalize eol '
-            'characters, which make the file offset and range information '
-            'incorrect)',
-        valueHelp: 'mode',
-        allowed: ['as-is', 'normalize-eol-always'],
-        allowedHelp: {
-          'as-is': 'file contents are read as-is',
-          'normalize-eol-always':
-              r"eol characters normalized to the single character new line ('\n')"
-        },
-        defaultsTo: 'as-is');
-    parser.addOption(CACHE_FOLDER,
-        valueHelp: 'path', help: 'Path to the location to write cache data');
-    parser.addFlag(USE_LSP,
-        defaultsTo: false,
-        negatable: false,
-        help: 'Whether to use the Language Server Protocol');
-    parser.addFlag(ENABLE_COMPLETION_MODEL,
-        help: 'Whether or not to turn on ML ranking for code completion');
-    parser.addOption(COMPLETION_MODEL_FOLDER,
-        valueHelp: 'path',
-        help: 'Path to the location of a code completion model');
-    parser.addOption(TRAIN_USING,
-        valueHelp: 'path',
-        help: 'Pass in a directory to analyze for purposes of training an '
-            'analysis server snapshot.');
+        hide: true);
 
     //
-    // Temporary flags.
-    //
-    parser.addFlag(USE_NEW_RELEVANCE,
-        defaultsTo: true,
-        help: 'Use the new relevance computation for code completion.');
-
-    //
-    // Deprecated options - no longer read from.
+    // Hidden; these are deprecated and no longer read from.
     //
 
+    // Removed 11/15/2020.
+    parser.addOption('completion-model', hide: true);
     // Removed 11/8/2020.
     parser.addFlag('dartpad', hide: true);
+    // Removed 11/15/2020.
+    parser.addFlag('enable-completion-model', hide: true);
     // Removed 10/30/2020.
     parser.addMultiOption('enable-experiment', hide: true);
     // Removed 9/23/2020.
     parser.addFlag('enable-instrumentation', hide: true);
+    // Removed 11/12/2020.
+    parser.addOption('file-read-mode', hide: true);
+    // Removed 11/12/2020.
+    parser.addFlag('ignore-unrecognized-flags', hide: true);
     // Removed 11/8/2020.
     parser.addFlag('preview-dart-2', hide: true);
+    // Removed 11/12/2020.
+    parser.addFlag('useAnalysisHighlight2', hide: true);
+    // Removed 11/13/2020.
+    parser.addFlag('use-new-relevance', hide: true);
     // Removed 9/23/2020.
     parser.addFlag('use-fasta-parser', hide: true);
 
@@ -842,16 +600,21 @@
   }
 
   String _getSdkPath(ArgResults args) {
-    if (args[SDK_OPTION] != null) {
-      return args[SDK_OPTION];
+    if (args[DART_SDK] != null) {
+      return args[DART_SDK];
+    } else if (args[DART_SDK_ALIAS] != null) {
+      return args[DART_SDK_ALIAS];
     } else {
       return getSdkPath();
     }
   }
 
   /// Print information about how to use the server.
-  void _printUsage(ArgParser parser, telemetry.Analytics analytics,
-      {bool fromHelp = false}) {
+  void _printUsage(
+    ArgParser parser,
+    telemetry.Analytics analytics, {
+    bool fromHelp = false,
+  }) {
     print('Usage: $BINARY_NAME [flags]');
     print('');
     print('Supported flags are:');
diff --git a/pkg/analysis_server/lib/src/server/sdk_configuration.dart b/pkg/analysis_server/lib/src/server/sdk_configuration.dart
index d952a21..08105f8 100644
--- a/pkg/analysis_server/lib/src/server/sdk_configuration.dart
+++ b/pkg/analysis_server/lib/src/server/sdk_configuration.dart
@@ -61,9 +61,6 @@
   /// Returns whether this SDK configuration has any configured values.
   bool get hasAnyOverrides => _values.isNotEmpty;
 
-  /// Return an override value for the analysis server's ML model file path.
-  String get mlModelPath => _values['server.ml.model.path'];
-
   @override
   String toString() => displayString;
 
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
index a84b968..4141b3b 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
@@ -16,9 +16,6 @@
   @override
   final int offset;
 
-  @override
-  bool useNewRelevance;
-
   /// The offset of the start of the text to be replaced.
   /// This will be different than the [offset] used to request the completion
   /// suggestions if there was a portion of an identifier before the original
@@ -39,8 +36,7 @@
 
   /// Initialize a newly created completion request based on the given
   /// arguments.
-  CompletionRequestImpl(
-      this.result, this.offset, this.useNewRelevance, this.performance)
+  CompletionRequestImpl(this.result, this.offset, this.performance)
       : replacementOffset = offset,
         replacementLength = 0;
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
deleted file mode 100644
index d553529..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.completion.dart.sorter.common;
-
-import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
-
-part 'common_usage_sorter.g.dart';
-
-/// A computer for adjusting the relevance of completions computed by others
-/// based upon common Dart usage patterns. This is a long-lived object
-/// that should not maintain state between calls to it's [sort] method.
-class CommonUsageSorter implements DartContributionSorter {
-  /// A map of <library>.<classname> to an ordered list of method names,
-  /// field names, getter names, and named constructors.
-  /// The names are ordered from most relevant to least relevant.
-  /// Names not listed are considered equally less relevant than those listed.
-  final Map<String, List<String>> selectorRelevance;
-
-  CommonUsageSorter([this.selectorRelevance = defaultSelectorRelevance]);
-
-  @override
-  Future sort(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions) {
-    _update(request, suggestions);
-    return Future.value();
-  }
-
-  CompletionTarget _getCompletionTarget(CompletionRequest request) =>
-      CompletionTarget.forOffset(request.result.unit, request.offset);
-
-  /// Adjusts the relevance based on the given completion context.
-  /// The compilation unit and completion node
-  /// in the given completion context may not be resolved.
-  void _update(
-      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
-    var target = _getCompletionTarget(request);
-    if (target != null) {
-      var visitor = _BestTypeVisitor(target.entity);
-      var typeElem = target.containingNode.accept(visitor);
-      if (typeElem != null) {
-        var libElem = typeElem.library;
-        if (libElem != null) {
-          _updateInvocationRelevance(typeElem.name, libElem, suggestions);
-        }
-      }
-    }
-  }
-
-  /// Adjusts the relevance of all method suggestions based upon the given
-  /// target type and library.
-  void _updateInvocationRelevance(String typeName, LibraryElement libElem,
-      Iterable<CompletionSuggestion> suggestions) {
-    var selectors = selectorRelevance['${libElem.name}.$typeName'];
-    if (selectors != null) {
-      for (var suggestion in suggestions) {
-        var element = suggestion.element;
-        if (element != null &&
-            (element.kind == protocol.ElementKind.CONSTRUCTOR ||
-                element.kind == protocol.ElementKind.FIELD ||
-                element.kind == protocol.ElementKind.GETTER ||
-                element.kind == protocol.ElementKind.METHOD ||
-                element.kind == protocol.ElementKind.SETTER) &&
-            suggestion.kind == CompletionSuggestionKind.INVOCATION &&
-            suggestion.declaringType == typeName) {
-          var index = selectors.indexOf(suggestion.completion);
-          if (index != -1) {
-            suggestion.relevance = DART_RELEVANCE_COMMON_USAGE - index;
-          }
-        }
-      }
-    }
-  }
-}
-
-/// An [AstVisitor] used to determine the best defining type of a node.
-class _BestTypeVisitor extends UnifyingAstVisitor<Element> {
-  /// The entity which the completed text will replace (or which will be
-  /// displaced once the completed text is inserted).  This may be an AstNode or
-  /// a Token, or it may be `null` if the cursor is after all tokens in the
-  /// file. See field of the same name in [CompletionTarget].
-  final Object entity;
-
-  _BestTypeVisitor(this.entity);
-
-  @override
-  Element visitConstructorName(ConstructorName node) {
-    return node.period != null && node.name == entity
-        ? node.type?.type?.element
-        : null;
-  }
-
-  @override
-  Element visitNamedExpression(NamedExpression node) {
-    var parent = node.parent;
-    if (parent is ArgumentListImpl) {
-      var params = parent.correspondingStaticParameters;
-      if (params != null) {
-        var index = parent.arguments.indexOf(node);
-        return params[index]?.type?.element;
-      }
-    }
-    return super.visitNamedExpression(node);
-  }
-
-  @override
-  Element visitNode(AstNode node) {
-    return null;
-  }
-
-  @override
-  Element visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (node.identifier == entity) {
-      var type = node.prefix.staticType;
-      if (type is InterfaceType) {
-        return type.element;
-      }
-      return node.prefix.staticElement;
-    }
-    return null;
-  }
-
-  @override
-  Element visitPropertyAccess(PropertyAccess node) =>
-      node.propertyName == entity ? node.realTarget?.staticType?.element : null;
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart
deleted file mode 100644
index fad6b92..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart
+++ /dev/null
@@ -1,3873 +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.
-
-part of services.completion.dart.sorter.common;
-
-// Auto-generated, please do not edit.
-
-/// A map of <library>.<classname> to an ordered list of method names,
-/// field names, getter names, and named constructors.
-/// The names are ordered from most relevant to least relevant.
-/// Names not listed are considered equally less relevant than those listed.
-const Map<String, List<String>> defaultSelectorRelevance = {
-  'dart.core.Comparable': [
-    'compareTo',
-    'compare',
-  ],
-  'dart.math.Random': [
-    'nextInt',
-    'nextDouble',
-    'nextBool',
-  ],
-  'dart.core.List': [
-    'add',
-    'map',
-    'length',
-    'removeLast',
-    'addAll',
-    'join',
-    'forEach',
-    'contains',
-    'removeAt',
-    'where',
-    'last',
-    'clear',
-    'setRange',
-    'sort',
-    'insert',
-    'remove',
-    'sublist',
-    'indexOf',
-    'isEmpty',
-    'any',
-    'insertAll',
-    'first',
-    'removeRange',
-    'replaceRange',
-    'take',
-    'getRange',
-    'skip',
-    'toList',
-    'retainWhere',
-    'fillRange',
-    'removeWhere',
-    'expand',
-    'fold',
-    'reversed',
-    'firstWhere',
-    'every',
-    'setAll',
-    'asMap',
-    'isNotEmpty',
-    'lastIndexOf',
-    'singleWhere',
-    'lastWhere',
-    'shuffle',
-    'takeWhile',
-    'iterator',
-    'toString',
-    'toSet',
-    'single',
-    'reduce',
-    'elementAt',
-    'skipWhile',
-    'insertRange',
-    'filter',
-    'push',
-    'mappedBy',
-    'addLast',
-    'some',
-    'slice',
-    'retainMatching',
-    'firstMatching',
-    'removeAll',
-    'retainAll',
-    'removeMatching',
-    'min',
-    'lastMatching',
-    'singleMatching',
-    'max',
-    'get',
-    'toArray',
-    'runtimeType',
-    'reverse',
-    'addd',
-    'asByteArray',
-  ],
-  'dart.core.Iterable': [
-    'toList',
-    'map',
-    'join',
-    'toSet',
-    'where',
-    'forEach',
-    'expand',
-    'fold',
-    'every',
-    'any',
-    'contains',
-    'firstWhere',
-    'length',
-    'elementAt',
-    'skipWhile',
-    'reduce',
-    'iterator',
-    'take',
-    'skip',
-    'toString',
-    'singleWhere',
-    'lastWhere',
-    'takeWhile',
-    'isEmpty',
-    'first',
-    'single',
-    'last',
-    'isNotEmpty',
-    'addAll',
-    'indexOf',
-    'add',
-    'sort',
-    'toArray',
-    'mappedBy',
-    'filter',
-  ],
-  'dart.core.Set': [
-    'add',
-    'contains',
-    'remove',
-    'addAll',
-    'clear',
-    'difference',
-    'map',
-    'containsAll',
-    'union',
-    'removeWhere',
-    'removeAll',
-    'intersection',
-    'retainAll',
-    'retainWhere',
-    'forEach',
-    'toSet',
-    'every',
-    'lookup',
-    'any',
-    'toString',
-    'toList',
-    'where',
-    'length',
-    'join',
-    'skip',
-    'firstWhere',
-    'isEmpty',
-    'first',
-    'iterator',
-    'singleWhere',
-    'expand',
-    'elementAt',
-    'fold',
-    'reduce',
-    'single',
-    'lastWhere',
-    'isNotEmpty',
-    'take',
-    'takeWhile',
-    'skipWhile',
-    'last',
-    'findBy',
-    'toArray',
-    'filter',
-  ],
-  'dart.collection.Queue': [
-    'add',
-    'removeFirst',
-    'clear',
-    'removeLast',
-    'remove',
-    'addAll',
-    'addLast',
-    'addFirst',
-    'removeWhere',
-    'retainWhere',
-    'length',
-    'toList',
-    'where',
-    'contains',
-    'forEach',
-    'map',
-    'isNotEmpty',
-    'first',
-    'isEmpty',
-    'fold',
-    'skip',
-    'any',
-    'elementAt',
-  ],
-  'dart.core.Map': [
-    'containsKey',
-    'forEach',
-    'remove',
-    'putIfAbsent',
-    'clear',
-    'addAll',
-    'length',
-    'keys',
-    'values',
-    'containsValue',
-    'toString',
-    'isNotEmpty',
-    'isEmpty',
-    'get',
-    'getKeys',
-    'put',
-    'getValues',
-    'clone',
-    'keySet',
-    'hashCode',
-    'runtimeType',
-  ],
-  'dart.core.Iterator': [
-    'moveNext',
-    'current',
-    'next',
-    'hasNext',
-  ],
-  'dart.pkg.collection.equality.Equality': [
-    'hash',
-    'equals',
-    'isValidKey',
-  ],
-  'dart.pkg.collection.equality.SetEquality': [
-    'equals',
-    'hash',
-  ],
-  'dart.pkg.collection.equality.MapEquality': [
-    'equals',
-    'hash',
-  ],
-  'dart.pkg.collection.equality.ListEquality': [
-    'equals',
-    'hash',
-  ],
-  'dart.pkg.collection.equality.IterableEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.pkg.collection.equality.UnorderedIterableEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.async.StreamSubscription': [
-    'cancel',
-    'pause',
-    'onDone',
-    'resume',
-    'onError',
-    'asFuture',
-    'onData',
-    'isPaused',
-  ],
-  'dart.async.StreamController': [
-    'add',
-    'close',
-    'addError',
-    'addStream',
-    'stream',
-    'hasListener',
-    'signalError',
-    'sink',
-    'done',
-  ],
-  'dart.async.Stream': [
-    'listen',
-    'transform',
-    'pipe',
-    'first',
-    'toList',
-    'forEach',
-    'firstWhere',
-    'where',
-    'join',
-    'fold',
-    'asyncMap',
-    'map',
-    'isEmpty',
-    'asBroadcastStream',
-    'handleError',
-    'capture',
-    'asyncExpand',
-    'take',
-    'single',
-    'expand',
-    'onFile',
-    'skip',
-    'any',
-    'timeout',
-    'add',
-    'last',
-    'runtimeType',
-    'isBroadcast',
-    'drain',
-    'elementAt',
-    'skipWhile',
-    'distinct',
-    'singleWhere',
-    'lastWhere',
-    'contains',
-    'every',
-    'takeWhile',
-    'emit',
-    'onDir',
-    'onError',
-    'onDone',
-    'onData',
-    'length',
-  ],
-  'dart.async.Future': [
-    'then',
-    'catchError',
-    'wait',
-    'whenComplete',
-    'forEach',
-    'asStream',
-    'timeout',
-    'map',
-    'packages',
-    'where',
-    'firstWhere',
-    'chain',
-    'transform',
-    'doWhile',
-    'onError',
-    'onResponse',
-    'onRequest',
-    'handleException',
-  ],
-  'dart.core.String': [
-    'substring',
-    'codeUnitAt',
-    'startsWith',
-    'replaceAll',
-    'split',
-    'contains',
-    'indexOf',
-    'toLowerCase',
-    'trim',
-    'length',
-    'endsWith',
-    'lastIndexOf',
-    'compareTo',
-    'isEmpty',
-    'toUpperCase',
-    'replaceFirst',
-    'toString',
-    'replaceAllMapped',
-    'allMatches',
-    'padLeft',
-    'codeUnits',
-    'hashCode',
-    'splitMapJoin',
-    'isNotEmpty',
-    'runes',
-    'charCodeAt',
-    'charCodes',
-    'trimRight',
-    'padRight',
-    'concat',
-    'equalsIgnoreCase',
-    'splitChars',
-    'trimLeft',
-    'matchAsPrefix',
-    'equals',
-    'map',
-    'toLoweCase',
-    'match',
-    'slice',
-    'getBytes',
-    'toCharArray',
-    'runtimeType',
-    'charAt',
-    'valueOf',
-  ],
-  'dart.core.StringBuffer': [
-    'write',
-    'toString',
-    'writeln',
-    'writeCharCode',
-    'clear',
-    'writeAll',
-    'add',
-    'addAll',
-    'addCharCode',
-    'isEmpty',
-  ],
-  'dart.core.RegExp': [
-    'firstMatch',
-    'hasMatch',
-    'allMatches',
-    'matchAsPrefix',
-    'pattern',
-    'stringMatch',
-    'toString',
-    'exec',
-  ],
-  'dart.core.double': [
-    'parse',
-    'toInt',
-    'compareTo',
-    'floor',
-    'toString',
-    'abs',
-    'round',
-    'toStringAsPrecision',
-    'toDouble',
-    'floorToDouble',
-    'ceil',
-    'truncate',
-    'toStringAsFixed',
-    'roundToDouble',
-    'clamp',
-    'isNaN',
-    'isFinite',
-    'toStringAsExponential',
-    'ceilToDouble',
-    'truncateToDouble',
-    'isNan',
-    'isNegative',
-    'isInfinite',
-    'hashCode',
-  ],
-  'dart.core.Type': [
-    'toString',
-    'hashCode',
-    'runtimeType',
-  ],
-  'dart.mirrors.InstanceMirror': [
-    'reflectee',
-    'getField',
-    'type',
-    'invoke',
-    'setField',
-    'delegate',
-    'function',
-    'then',
-    'apply',
-    'hasReflectee',
-  ],
-  'dart.collection.IterableBase': [
-    'iterableToFullString',
-  ],
-  'dart.pkg.collection.utils.Pair': [
-    'last',
-  ],
-  'dart.collection.Maps': [
-    'mapToString',
-    'length',
-    'putIfAbsent',
-    'clear',
-    'containsKey',
-    'getValues',
-    'forEach',
-    'containsValue',
-    'isNotEmpty',
-    'isEmpty',
-  ],
-  'dart.collection.SplayTreeSet': [
-    'add',
-    'addAll',
-    'where',
-  ],
-  'dart.core.StackTrace': [
-    'toString',
-    'frames',
-  ],
-  'dart.convert.JsonCodec': [
-    'encode',
-    'decode',
-    'fuse',
-  ],
-  'dart.mirrors.MirrorSystem': [
-    'getName',
-    'libraries',
-    'findLibrary',
-    'isolate',
-    'dynamicType',
-    'getSymbol',
-    'voidType',
-  ],
-  'dart.mirrors.ClassMirror': [
-    'newInstance',
-    'isSubtypeOf',
-    'reflectedType',
-    'qualifiedName',
-    'metadata',
-    'getField',
-    'owner',
-    'declarations',
-    'superclass',
-    'simpleName',
-    'isSubclassOf',
-    'invoke',
-    'instanceMembers',
-    'mixin',
-    'isAbstract',
-    'originalDeclaration',
-    'typeVariables',
-    'setField',
-    'isOriginalDeclaration',
-    'superinterfaces',
-    'isAssignableTo',
-    'owners',
-  ],
-  'dart.io.Process': [
-    'start',
-    'runSync',
-    'run',
-    'kill',
-    'exitCode',
-  ],
-  'dart.core.int': [
-    'parse',
-    'toDouble',
-    'toString',
-    'toInt',
-    'compareTo',
-    'toRadixString',
-    'abs',
-    'remainder',
-    'toUnsigned',
-    'toSigned',
-    'clamp',
-    'round',
-    'floor',
-    'substr',
-    'ceil',
-    'isEven',
-    'id',
-    'append',
-    'truncate',
-    'hashCode',
-    'toStringAsFixed',
-    'ceilToDouble',
-    'roundToDouble',
-    'floorToDouble',
-    'truncateToDouble',
-    'isNegative',
-    'length',
-    'isNaN',
-    'isInfinite',
-    'runtimeType',
-    'bitLength',
-  ],
-  'dart.core.Sink': [
-    'add',
-    'close',
-  ],
-  'dart.async.EventSink': [
-    'close',
-    'add',
-    'addError',
-  ],
-  'dart.async.Completer': [
-    'complete',
-    'completeError',
-    'future',
-    'isCompleted',
-    'completeException',
-    'then',
-  ],
-  'dart.io.FileStat': [
-    'mode',
-    'stat',
-    'type',
-    'statSync',
-    'changed',
-    'modified',
-    'size',
-  ],
-  'dart.io.Link': [
-    'existsSync',
-    'createSync',
-    'resolveSymbolicLinksSync',
-    'exists',
-    'delete',
-    'targetSync',
-    'deleteSync',
-    'target',
-    'create',
-    'updateSync',
-  ],
-  'dart.io.FileSystemEntityType': [
-    'toString',
-    'NOT_FOUND',
-    'DIRECTORY',
-    'FILE',
-  ],
-  'dart.io.Directory': [
-    'existsSync',
-    'list',
-    'listSync',
-    'watch',
-    'path',
-    'exists',
-    'createSync',
-    'create',
-    'deleteSync',
-    'delete',
-    'createTemp',
-    'createTempSync',
-    'renameSync',
-    'parent',
-    'absolute',
-    'stat',
-    'current',
-    'createRecursivelySync',
-    'resolveSymbolicLinksSync',
-    'rename',
-    'statSync',
-  ],
-  'dart.io.File': [
-    'existsSync',
-    'readAsStringSync',
-    'openRead',
-    'writeAsStringSync',
-    'readAsString',
-    'openWrite',
-    'lastModifiedSync',
-    'exists',
-    'resolveSymbolicLinksSync',
-    'writeAsString',
-    'path',
-    'resolveSymbolicLinks',
-    'statSync',
-    'deleteSync',
-    'createSync',
-    'delete',
-    'openSync',
-    'parent',
-    'readAsBytesSync',
-    'copy',
-    'open',
-    'absolute',
-    'fullPathSync',
-    'length',
-    'writeAsBytesSync',
-    'lastModified',
-    'writeAsBytes',
-    'readAsLinesSync',
-    'fullPath',
-    'readAsBytes',
-    'copySync',
-    'create',
-    'lengthSync',
-    'readAsLines',
-    'isFileSync',
-    'isFile',
-    'rename',
-    'openOutputStream',
-    'openInputStream',
-    'stat',
-    'renameSync',
-    'watch',
-    'directorySync',
-    'isAbsolute',
-    'directory',
-  ],
-  'dart.io.Stdout': [
-    'writeln',
-    'close',
-    'write',
-    'flush',
-    'addStream',
-    'writeString',
-    'add',
-    'writeCharCode',
-    'addString',
-  ],
-  'dart.io.IOSink': [
-    'write',
-    'close',
-    'writeln',
-    'flush',
-    'add',
-    'addStream',
-    'writeAll',
-    'writeCharCode',
-    'encoding',
-    'addError',
-    'done',
-  ],
-  'dart.mirrors.LibraryMirror': [
-    'uri',
-    'getField',
-    'declarations',
-    'invoke',
-    'topLevelMembers',
-    'setField',
-    'classes',
-    'first',
-  ],
-  'dart.core.Match': [
-    'group',
-    'end',
-    'start',
-    'groups',
-    'toString',
-  ],
-  'dart.isolate.SendPort': [
-    'send',
-    'call',
-    'hashCode',
-  ],
-  'dart.core.DateTime': [
-    'parse',
-    'toIso8601String',
-    'millisecondsSinceEpoch',
-    'difference',
-    'toUtc',
-    'add',
-    'day',
-    'year',
-    'month',
-    'isAfter',
-    'toString',
-    'compareTo',
-    'subtract',
-    'isBefore',
-    'millisecond',
-    'toLocal',
-    'timeZoneName',
-    'timeZoneOffset',
-    'isUtc',
-    'weekday',
-    'isAtSameMomentAs',
-    'second',
-    'hour',
-    'minute',
-    'hashCode',
-    'now',
-    'runtimeType',
-  ],
-  'dart.core.Duration': [
-    'inMilliseconds',
-    'toString',
-    'inSeconds',
-    'inMicroseconds',
-    'inHours',
-    'inMinutes',
-    'inDays',
-    'isNegative',
-    'compareTo',
-  ],
-  'dart.core.Uri': [
-    'parse',
-    'toString',
-    'toFilePath',
-    'path',
-    'resolve',
-    'decodeComponent',
-    'encodeFull',
-    'decodeQueryComponent',
-    'scheme',
-    'encodeComponent',
-    'resolveUri',
-    'encodeQueryComponent',
-    'query',
-    'decodeFull',
-    'pathSegments',
-    'queryParameters',
-    'origin',
-    'authority',
-    'splitQueryString',
-    'replace',
-    'host',
-    'isAbsolute',
-    'port',
-    'fragment',
-    'hasAuthority',
-    'userInfo',
-    'parseIPv4Address',
-    'parseIPv6Address',
-    'hasQuery',
-    'endsWith',
-    'startsWith',
-  ],
-  'dart.typed_data.Uint32List': [
-    'sublist',
-    'setAll',
-    'fillRange',
-    'setRange',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-  ],
-  'dart.typed_data.TypedData': [
-    'buffer',
-  ],
-  'dart.io.BytesBuilder': [
-    'takeBytes',
-    'addByte',
-    'add',
-    'clear',
-    'toBytes',
-  ],
-  'dart.isolate.ReceivePort': [
-    'close',
-    'transform',
-    'listen',
-    'receive',
-    'toSendPort',
-    'takeWhile',
-    'sendPort',
-    'asBroadcastStream',
-  ],
-  'dart.convert.Encoding': [
-    'decode',
-    'encode',
-    'getByName',
-    'decodeStream',
-    'name',
-  ],
-  'dart.convert.Utf8Codec': [
-    'encode',
-    'decode',
-    'decoder',
-    'decodeStream',
-  ],
-  'dart.core.Stopwatch': [
-    'start',
-    'stop',
-    'reset',
-    'elapsedMicroseconds',
-    'elapsedMilliseconds',
-    'elapsed',
-    'elapsedInMs',
-  ],
-  'dart.async.ZoneDelegate': [
-    'handleUncaughtError',
-    'registerUnaryCallback',
-    'registerCallback',
-    'registerBinaryCallback',
-    'runBinary',
-    'errorCallback',
-    'scheduleMicrotask',
-    'run',
-    'createTimer',
-  ],
-  'dart.async.Zone': [
-    'handleUncaughtError',
-    'run',
-    'fork',
-    'inSameErrorZone',
-    'runGuarded',
-    'bindUnaryCallback',
-    'bindBinaryCallback',
-    'runUnary',
-    'bindCallback',
-    'scheduleMicrotask',
-    'createTimer',
-  ],
-  'dart.dom.html.BodyElement': [
-    'innerHtml',
-    'children',
-    'nodes',
-    'append',
-    'style',
-    'onContextMenu',
-    'onMouseDown',
-    'onMouseWheel',
-    'scrollTop',
-    'onMouseUp',
-    'onClick',
-    'scrollLeft',
-    'clientHeight',
-    'clientWidth',
-    'onBlur',
-    'onFocus',
-    'onDoubleClick',
-    'scrollHeight',
-    'onMouseMove',
-    'elements',
-    'createFragment',
-    'classes',
-    'ownerDocument',
-    'query',
-    'onKeyDown',
-    'querySelector',
-    'offsetWidth',
-    'scrollWidth',
-    'offsetHeight',
-    'setInnerHtml',
-    'childNodes',
-    'requestFullscreen',
-    'offsetTop',
-  ],
-  'dart.dom.html.Location': [
-    'hash',
-    'search',
-    'reload',
-    'pathname',
-    'toString',
-    'href',
-    'host',
-    'assign',
-    'replace',
-    'protocol',
-    'hostname',
-    'port',
-    'origin',
-  ],
-  'dart.convert.HtmlEscape': [
-    'convert',
-  ],
-  'dart.dom.html.Window': [
-    'postMessage',
-    'btoa',
-    'lookupPort',
-    'document',
-    'requestAnimationFrame',
-    'alert',
-    'navigator',
-    'devicePixelRatio',
-    'pageYOffset',
-    'pageXOffset',
-    'onAnimationEnd',
-    'innerWidth',
-    'onResize',
-    'getSelection',
-    'cancelAnimationFrame',
-    'animationEndEvent',
-    'innerHeight',
-    'registerPort',
-    'dispatchEvent',
-    'onAnimationStart',
-    'onMouseUp',
-    'onMouseMove',
-    'open',
-    'screen',
-    'indexedDB',
-    'setTimeout',
-    'scrollX',
-    'scrollY',
-    'onScroll',
-    'openDatabase',
-    'confirm',
-    'getContainer',
-    'location',
-    'onKeyUp',
-    'atob',
-    'scrollTo',
-    'localStorage',
-    'scrollBy',
-    'setInterval',
-    'setImmediate',
-    'requestLayoutFrame',
-    'requestFileSystem',
-    'onHashChange',
-    'close',
-    'console',
-    'onError',
-    'onMessage',
-    'animationFrame',
-  ],
-  'dart.core.Function': [
-    'apply',
-    'toString',
-    'call',
-    'bind',
-  ],
-  'dart.async.Timer': [
-    'cancel',
-    'run',
-  ],
-  'dart.dom.html.HeadElement': [
-    'append',
-    'querySelector',
-    'query',
-    'children',
-    'style',
-    'elements',
-    'querySelectorAll',
-    'nodes',
-    'id',
-    'insertBefore',
-    'text',
-  ],
-  'dart.dom.html.ElementStream': [
-    'listen',
-    'where',
-    'first',
-    'matches',
-    'forEach',
-    'map',
-  ],
-  'dart.dom.html.Element': [
-    'query',
-    'onClick',
-    'innerHtml',
-    'style',
-    'querySelector',
-    'nodes',
-    'children',
-    'remove',
-    'append',
-    'querySelectorAll',
-    'classes',
-    'attributes',
-    'setInnerHtml',
-    'getComputedStyle',
-    'onChange',
-    'parent',
-    'matches',
-    'getBoundingClientRect',
-    'focus',
-    'dispatchEvent',
-    'addEventListener',
-    'insertAllBefore',
-    'clone',
-    'getAttribute',
-    'blur',
-    'createShadowRoot',
-    'contains',
-    'text',
-    'setAttribute',
-    'insertAdjacentElement',
-    'appendText',
-    'scrollIntoView',
-    'shadowRoot',
-    'getNamespacedAttributes',
-    'removeEventListener',
-    'insertBefore',
-    'appendHtml',
-    'click',
-    'offsetWidth',
-    'insertAdjacentHtml',
-    'insertAdjacentText',
-    'getClientRects',
-    'getElementsByClassName',
-    'replaceWith',
-    'scrollByLines',
-    'scrollByPages',
-    'hasChildNodes',
-    'requestFullscreen',
-    'requestPointerLock',
-    'queryAll',
-    'setAttributeNS',
-    'getAttributeNS',
-    'dataset',
-    'offsetHeight',
-    'on',
-    'createFragment',
-    'offsetTo',
-    'getDestinationInsertionPoints',
-    'matchesWithAncestors',
-    'attributeChanged',
-    'onMouseDown',
-    'nextElementSibling',
-    'getRegionFlowRanges',
-    'onContextMenu',
-    'animate',
-    'onTouchStart',
-    'scrollTop',
-    'offsetTop',
-    'onTouchMove',
-    'onTouchEnd',
-    'onMouseWheel',
-    'clientWidth',
-    'scrollLeft',
-    'clientHeight',
-    'isTagSupported',
-    'parentNode',
-    'onMouseUp',
-    'bind',
-    'onKeyDown',
-    'ownerDocument',
-    'unbind',
-    'unbindAll',
-    'init',
-    'createInstance',
-    'render',
-    'update',
-    'onKeyUp',
-    'onMouseMove',
-    'xtag',
-    'offsetLeft',
-    'tabIndex',
-    'client',
-    'requestFullScreen',
-    'getInputContext',
-    'borderEdge',
-    'clearModel',
-    'id',
-    'disabled',
-    'value',
-    'getContext',
-    'lastChild',
-    'firstChild',
-    'nextNode',
-    'innerHTML',
-    'onMouseEnter',
-    'onMouseLeave',
-    'contentEdge',
-    'elements',
-    'matchesSelector',
-    'webkitRequestPointerLock',
-    'tagName',
-    'childNodes',
-    'webkitRequestFullscreen',
-    'webkitRequestFullScreen',
-    'marginEdge',
-    'paddingEdge',
-    'outerHtml',
-    'onMouseOver',
-    'onMouseOut',
-    'onDragEnd',
-    'boolean',
-    'scrollHeight',
-    'hidden',
-    'onDragStart',
-    'onDoubleClick',
-    'nodeType',
-    'hashCode',
-    'onDrag',
-    'onInput',
-    'selectionStart',
-    'selectionEnd',
-    'onDrop',
-    'onDragLeave',
-    'hideOrShowNavigation',
-    'onDragOver',
-    'model',
-    'scrollEvent',
-    'onDragEnter',
-    'previousElementSibling',
-    'className',
-    'namespaceUri',
-    'onSubmit',
-    'selection',
-    'setItemSelected',
-    'runtimeType',
-    'apply',
-    'createBinding',
-    'values',
-    'onBlur',
-    'onTouchCancel',
-    'show',
-    'insertAdjacentHTML',
-    'nodeName',
-    'selected',
-    'contentEditable',
-    'localName',
-    'number',
-    'draggable',
-    'src',
-    'addText',
-    'addHTML',
-    'select',
-    'clear',
-    'str',
-    'clearSelection',
-  ],
-  'dart.dom.html.HtmlElement': [
-    'querySelector',
-    'query',
-    'append',
-    'classes',
-    'style',
-    'getComputedStyle',
-    'remove',
-    'getBoundingClientRect',
-    'querySelectorAll',
-    'clone',
-    'attributes',
-    'focus',
-    'tabIndex',
-    'onClick',
-    'parent',
-    'onMouseLeave',
-    'replaceWith',
-    'onContextMenu',
-    'onMouseEnter',
-    'onKeyDown',
-    'blur',
-    'setInnerText',
-    'scrollTop',
-    'appendHtml',
-    'dataset',
-    'lastChild',
-    'onSelectStart',
-    'onDrop',
-    'onDragOver',
-    'onDragLeave',
-    'onDragEnter',
-    'onDragEnd',
-    'onDragStart',
-    'onDrag',
-    'onDoubleClick',
-    'children',
-    'onScroll',
-    'getAttribute',
-    'nodes',
-    'outerHtml',
-    'click',
-    'createShadowRoot',
-  ],
-  'dart.dom.html.ElementList': [
-    'forEach',
-    'length',
-    'contains',
-    'last',
-    'style',
-    'addAll',
-    'first',
-    'where',
-    'onMouseLeave',
-    'onMouseEnter',
-    'toList',
-    'some',
-    'onClick',
-    'map',
-    'classes',
-    'indexOf',
-  ],
-  'dart.dom.html.HtmlDocument': [
-    'query',
-    'querySelectorAll',
-    'querySelector',
-    'queryAll',
-    'createElement',
-    'body',
-    'title',
-    'createElementUpgrader',
-    'documentElement',
-    'timeline',
-    'onKeyDown',
-    'getElementById',
-    'registerElement',
-    'onClick',
-    'addEventListener',
-    'onMouseUp',
-    'onMouseMove',
-    'activeElement',
-    'createElementNS',
-    'createDocumentFragment',
-    'createRange',
-    'adoptNode',
-    'getElementsByTagName',
-    'onKeyUp',
-    'elementFromPoint',
-    'contains',
-    'getElementsByName',
-    'head',
-    'exitFullscreen',
-    'onMouseWheel',
-    'register',
-  ],
-  'dart.collection.LinkedHashMap': [
-    'containsKey',
-    'forEach',
-    'remove',
-    'putIfAbsent',
-    'keys',
-    'length',
-    'clear',
-    'values',
-    'isNotEmpty',
-  ],
-  'dart.dom.html.Navigator': [
-    'userAgent',
-    'language',
-    'appVersion',
-    'appName',
-    'geolocation',
-    'vendor',
-    'appCodeName',
-    'dartEnabled',
-    'getUserMedia',
-    'onLine',
-    'platform',
-    'storageQuota',
-  ],
-  'dart.dom.html.CssStyleDeclaration': [
-    'display',
-    'width',
-    'height',
-    'top',
-    'setProperty',
-    'left',
-    'position',
-    'zIndex',
-    'cssText',
-    'right',
-    'maxHeight',
-    'visibility',
-    'bottom',
-    'background',
-    'removeProperty',
-    'cursor',
-    'overflow',
-    'getPropertyValue',
-    'opacity',
-    'backgroundColor',
-    'float',
-    'transform',
-    'padding',
-    'border',
-    'borderRadius',
-    'paddingBottom',
-    'transition',
-    'paddingTop',
-    'overflowY',
-    'color',
-    'outline',
-    'backgroundImage',
-    'transformStyle',
-    'pointerEvents',
-    'marginLeft',
-    'textAlign',
-    'backgroundPosition',
-    'boxSizing',
-    'paddingLeft',
-    'backgroundSize',
-    'margin',
-    'fontFamily',
-    'userSelect',
-    'fontSize',
-    'lineHeight',
-    'willChange',
-    'fontWeight',
-    'getProperty',
-    'marginRight',
-    'whiteSpace',
-    'overflowX',
-    'textDecoration',
-    'perspective',
-    'perspectiveOrigin',
-    'appearance',
-    'borderLeftWidth',
-    'paddingRight',
-    'borderColor',
-    'borderBottomWidth',
-    'borderTopWidth',
-    'webkitOverflowScrolling',
-    'borderRightWidth',
-    'marginBottom',
-    'transitionProperty',
-    'transitionTimingFunction',
-    'transitionDuration',
-    'animation',
-    'animationDelay',
-    'animationFillMode',
-    'animationDirection',
-    'animationIterationCount',
-    'animationTimingFunction',
-    'animationDuration',
-    'animationName',
-    'verticalAlign',
-    'marginTop',
-    'boxShadow',
-    'getPropertyPriority',
-    'textStrokeColor',
-    'borderBottom',
-    'font',
-    'supportsProperty',
-    'textShadow',
-    'maxWidth',
-    'minWidth',
-    'minHeight',
-    'outlineColor',
-    'filter',
-    'borderWidth',
-    'animationPlayState',
-    'fontStyle',
-    'borderRight',
-    'borderLeft',
-    'borderTop',
-  ],
-  'dart.io.ProcessResult': [
-    'stdout',
-    'exitCode',
-  ],
-  'dart.io.FileSystemEvent': [
-    'path',
-    'isDirectory',
-    'type',
-    'MODIFY',
-    'CREATE',
-    'DELETE',
-  ],
-  'dart.collection.HashSet': [
-    'add',
-    'contains',
-    'remove',
-    'clear',
-    'addAll',
-    'retainAll',
-    'length',
-    'isEmpty',
-    'toList',
-    'removeAll',
-    'any',
-    'forEach',
-    'map',
-  ],
-  'dart.collection.HashMap': [
-    'remove',
-    'containsKey',
-    'forEach',
-    'clear',
-    'keys',
-    'putIfAbsent',
-    'addAll',
-    'values',
-  ],
-  'dart.io.FileSystemEntity': [
-    'isDirectorySync',
-    'path',
-    'typeSync',
-    'existsSync',
-    'isDirectory',
-    'identicalSync',
-    'isFileSync',
-    'type',
-    'isFile',
-    'statSync',
-    'deleteSync',
-    'isLinkSync',
-    'parentOf',
-    'renameSync',
-    'isLink',
-    'readAsStringSync',
-    'identical',
-    'rename',
-    'toString',
-    'delete',
-    'exists',
-    'parent',
-    'stat',
-  ],
-  'dart.io.OSError': [
-    'errorCode',
-    'toString',
-  ],
-  'dart.async.StreamTransformer': [
-    'bind',
-  ],
-  'dart.core.Runes': [
-    'toList',
-    'any',
-    'elementAt',
-    'iterator',
-    'single',
-    'first',
-    'forEach',
-    'last',
-  ],
-  'dart.core.Object': [
-    'toString',
-    'toJson',
-    'hashCode',
-    'discardListChages',
-    'reverse',
-    'map',
-    'lightDom',
-    'getName',
-    'where',
-    'add',
-    'containsKey',
-    'format',
-    'setTable',
-    'getClass',
-    'getNamespace',
-    'getId',
-    'getCell',
-    'getSize',
-    'setNamespace',
-    'equals',
-    'setColumn',
-    'getColumnName',
-    'getForeignTableName',
-    'setDatabase',
-    'setAttribute',
-    'setId',
-    'getChild',
-    'body',
-    'setPrevious',
-    'getIndex',
-    'getParent',
-    'getChildAt',
-    'getChildCount',
-    'getValue',
-    'getRoot',
-    'POST',
-    'GET',
-    'getPackage',
-    'setSchema',
-    'clone',
-    'getType',
-    'then',
-    'isInheritance',
-    'isVisible',
-    'getDartName',
-    'getPlatform',
-    'setPosition',
-    'setPackage',
-    'requiresTransactionInPostgres',
-    'setAppData',
-    'getSchema',
-    'getBuildProperty',
-    'getPrevious',
-    'getTerminal',
-    'n',
-    'replaceWith',
-    'setChild',
-    'setPlatform',
-    'run',
-    'removeItem',
-    'getAllItems',
-    'bytes',
-    'compareTo',
-    'getAttribute',
-    'setPreviousIndex',
-    'isEmpty',
-    'getEdgeAt',
-    'isVertex',
-    'writeExternal',
-    'isEdge',
-    'getEdgeCount',
-    'isConnectable',
-    'setValue',
-    'isCollapsed',
-    'getStyles',
-    'setRoot',
-    'getStyle',
-    'getGeometry',
-    'noSuchMethod',
-    'contains',
-    'elementAt',
-    'e',
-  ],
-  'dart.core.StringSink': [
-    'write',
-    'writeln',
-    'writeCharCode',
-    'toString',
-    'writeAll',
-  ],
-  'dart.io.Stdin': [
-    'pipe',
-    'readLineSync',
-    'transform',
-    'listen',
-  ],
-  'dart.io.HttpServer': [
-    'bind',
-    'listen',
-    'close',
-    'connectionsInfo',
-    'bindSecure',
-    'address',
-    'port',
-    'idleTimeout',
-    'serverHeader',
-    'autoCompress',
-    'asBroadcastStream',
-    'transform',
-    'addRequestHandler',
-    'listenOn',
-    'on',
-  ],
-  'dart.io.HttpResponse': [
-    'close',
-    'write',
-    'statusCode',
-    'headers',
-    'add',
-    'done',
-    'redirect',
-    'addStream',
-    'detachSocket',
-    'reasonPhrase',
-    'writeln',
-    'addError',
-    'writeCharCode',
-    'writeAll',
-    'flush',
-    'toString',
-    'when',
-    'cookies',
-    'contentLength',
-    'addString',
-    'getLogs',
-    'listen',
-    'persistentConnection',
-    'deadline',
-  ],
-  'dart.io.HttpRequest': [
-    'listen',
-    'uri',
-    'session',
-    'drain',
-    'transform',
-    'response',
-    'toString',
-    'cookies',
-    'method',
-    'fold',
-    'connectionInfo',
-    'pipe',
-    'asBroadcastStream',
-    'toList',
-    'timeout',
-    'takeWhile',
-    'take',
-    'skipWhile',
-    'singleWhere',
-    'map',
-    'lastWhere',
-    'join',
-    'handleError',
-    'skip',
-    'firstWhere',
-    'expand',
-    'every',
-    'elementAt',
-    'distinct',
-    'asyncMap',
-    'asyncExpand',
-    'any',
-    'toSet',
-    'contains',
-    'where',
-    'reduce',
-    'forEach',
-    'headers',
-    'path',
-  ],
-  'dart.collection.SplayTreeMap': [
-    'forEach',
-    'containsKey',
-    'remove',
-    'keys',
-    'values',
-    'firstKeyAfter',
-    'lastKeyBefore',
-    'clear',
-    'length',
-  ],
-  'dart.io.HttpClient': [
-    'post',
-    'getUrl',
-    'openUrl',
-    'close',
-    'postUrl',
-    'get',
-    'open',
-    'addCredentials',
-    'patchUrl',
-    'shutdown',
-    'put',
-    'delete',
-    'addProxyCredentials',
-    'findProxyFromEnvironment',
-  ],
-  'dart.io.HttpClientRequest': [
-    'close',
-    'add',
-    'write',
-    'addStream',
-    'cookies',
-  ],
-  'dart.io.Platform': [
-    'isWindows',
-    'script',
-    'environment',
-    'operatingSystem',
-    'pathSeparator',
-  ],
-  'dart.collection.LinkedHashSet': [
-    'add',
-    'map',
-    'contains',
-    'toList',
-    'addAll',
-    'remove',
-  ],
-  'dart.io.RandomAccessFile': [
-    'lengthSync',
-    'readIntoSync',
-    'close',
-    'closeSync',
-    'writeStringSync',
-    'writeString',
-    'writeFromSync',
-    'length',
-    'readInto',
-    'read',
-    'readSync',
-    'writeFrom',
-    'readListSync',
-    'flushSync',
-    'positionSync',
-    'setPosition',
-    'writeListSync',
-    'setPositionSync',
-    'unlock',
-    'lock',
-    'unlockSync',
-    'readList',
-    'lockSync',
-    'readByteSync',
-    'position',
-    'writeList',
-    'writeByteSync',
-  ],
-  'dart.core.num': [
-    'round',
-    'toDouble',
-    'toInt',
-    'floor',
-    'abs',
-    'toString',
-    'parse',
-    'ceil',
-    'toStringAsFixed',
-    'isNaN',
-    'compareTo',
-    'roundToDouble',
-    'remainder',
-    'hashCode',
-    'clamp',
-    'isInfinite',
-    'isNegative',
-    'truncate',
-    'toStringAsPrecision',
-    'toStringAsExponential',
-    'isFinite',
-    'truncateToDouble',
-    'toRadixString',
-  ],
-  'dart.dom.html.HttpRequest': [
-    'send',
-    'open',
-    'getString',
-    'abort',
-    'setRequestHeader',
-    'request',
-    'getAllResponseHeaders',
-    'overrideMimeType',
-    'requestCrossOrigin',
-    'getResponseHeader',
-    'postFormData',
-    'onLoadEnd',
-    'onError',
-    'onLoad',
-    'DONE',
-    'withCredentials',
-    'onReadyStateChange',
-    'onLoadStart',
-  ],
-  'dart.dom.html.Event': [
-    'preventDefault',
-    'toString',
-    'stopImmediatePropagation',
-    'stopPropagation',
-    'target',
-    'currentTarget',
-  ],
-  'dart.dom.html.FileReader': [
-    'readAsArrayBuffer',
-    'readAsDataUrl',
-    'readAsText',
-    'onError',
-    'onLoadEnd',
-    'result',
-  ],
-  'dart.core.Pattern': [
-    'allMatches',
-    'matchAsPrefix',
-    'toString',
-    'firstMatch',
-    'pattern',
-    'codeUnitAt',
-  ],
-  'dart.io.ContentType': [
-    'parse',
-    'toString',
-    'charset',
-    'mimeType',
-    'value',
-    'parameters',
-    'subType',
-    'primaryType',
-  ],
-  'dart.io.HttpHeaders': [
-    'set',
-    'contentType',
-    'ifModifiedSince',
-    'value',
-    'add',
-    'host',
-    'forEach',
-    'date',
-    'removeAll',
-    'clear',
-    'remove',
-    'noFolding',
-    'contentLength',
-    'port',
-    'expires',
-    'chunkedTransferEncoding',
-    'persistentConnection',
-    'toString',
-    'CONTENT_TYPE',
-    'data',
-  ],
-  'dart.typed_data.Uint8List': [
-    'setRange',
-    'sublist',
-    'fillRange',
-    'setAll',
-    'length',
-    'buffer',
-    'toString',
-    'toList',
-    'lastIndexOf',
-    'indexOf',
-    'join',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-  ],
-  'dart.async.StreamSink': [
-    'close',
-    'addStream',
-    'add',
-    'addError',
-  ],
-  'dart.typed_data.ByteData': [
-    'getUint32',
-    'setUint32',
-    'getUint8',
-    'setUint64',
-    'getInt32',
-    'getUint16',
-    'getUint64',
-    'setUint16',
-    'getInt16',
-    'setInt64',
-    'setInt32',
-    'setInt16',
-    'setFloat64',
-    'getInt64',
-    'setInt8',
-    'getFloat64',
-    'getFloat32',
-    'setFloat32',
-    'getInt8',
-    'setUint8',
-  ],
-  'dart.io.HttpClientResponse': [
-    'listen',
-    'toList',
-    'transform',
-    'drain',
-    'fold',
-    'pipe',
-    'detachSocket',
-  ],
-  'dart.core.BidirectionalIterator': [
-    'moveNext',
-    'movePrevious',
-  ],
-  'dart.mirrors.ClosureMirror': [
-    'invoke',
-    'apply',
-    'function',
-  ],
-  'dart.typed_data.Int32x4': [
-    'x',
-    'signMask',
-    'select',
-  ],
-  'dart.js.JsObject': [
-    'callMethod',
-    'hasProperty',
-    'toString',
-    'deleteProperty',
-    'instanceof',
-  ],
-  'dart.dom.html.Node': [
-    'remove',
-    'ELEMENT_NODE',
-    'insertBefore',
-    'replaceWith',
-    'insertAllBefore',
-    'querySelector',
-    'localName',
-    'text',
-    'append',
-    'setMenubarOrientation',
-    'getElementsByTagName',
-    'getElementsByClassName',
-    'nodes',
-    'parentNode',
-    'getElementById',
-    'firstChild',
-    'parent',
-    'contains',
-    'tagName',
-    'value',
-    'toString',
-    'name',
-    'querySelectorAll',
-    'clone',
-    'attributes',
-    'nextNode',
-    'nodeType',
-    'click',
-    'bind',
-    'outerHtml',
-    'dispatchEvent',
-    'on',
-    'childNodes',
-  ],
-  'dart.core.RuneIterator': [
-    'moveNext',
-    'reset',
-  ],
-  'dart.mirrors.DeclarationMirror': [
-    'isPrivate',
-    'simpleName',
-    'metadata',
-    'isSubclassOf',
-    'qualifiedName',
-    'parameters',
-    'invoke',
-  ],
-  'dart.dom.html.History': [
-    'pushState',
-    'back',
-    'replaceState',
-    'length',
-  ],
-  'dart.dom.html.CssClassSet': [
-    'add',
-    'remove',
-    'toggle',
-    'clear',
-    'contains',
-    'addAll',
-    'removeAll',
-    'toString',
-    'firstWhere',
-    'first',
-    'toggleAll',
-    'length',
-    'containsAll',
-  ],
-  'dart.dom.html.Document': [
-    'querySelector',
-    'querySelectorAll',
-    'documentElement',
-    'createElement',
-    'title',
-    'body',
-    'removeEventListener',
-    'addEventListener',
-    'getElementsByTagName',
-    'createElementNS',
-    'query',
-    'window',
-    'queryAll',
-  ],
-  'dart.mirrors.IsolateMirror': [
-    'rootLibrary',
-  ],
-  'dart.mirrors.ObjectMirror': [
-    'invoke',
-    'getField',
-    'setField',
-  ],
-  'dart.dom.html.DivElement': [
-    'append',
-    'classes',
-    'style',
-    'setInnerHtml',
-    'remove',
-    'querySelector',
-    'id',
-    'getComputedStyle',
-    'appendText',
-    'text',
-    'querySelectorAll',
-    'onDragEnd',
-    'onDrag',
-    'onDragStart',
-    'draggable',
-    'innerHtml',
-    'insertAdjacentElement',
-    'appendHtml',
-    'className',
-    'children',
-    'focus',
-    'query',
-    'nodes',
-    'createShadowRoot',
-    'clone',
-    'attributes',
-    'queryAll',
-    'click',
-    'onMouseDown',
-    'onClick',
-    'hidden',
-    'addEventListener',
-    'onMouseMove',
-    'scrollIntoView',
-    'onKeyDown',
-    'title',
-    'getBoundingClientRect',
-    'onMouseUp',
-    'dispatchEvent',
-    'insertAdjacentText',
-    'contentEditable',
-    'scrollTop',
-    'scrollByLines',
-    'bind',
-    'insertBefore',
-    'xtag',
-    'insertAdjacentHtml',
-    'matches',
-    'setAttribute',
-    'on',
-    'onKeyUp',
-    'getElementsByClassName',
-  ],
-  'dart.dom.html.NodeValidatorBuilder': [
-    'allowNavigation',
-    'allowElement',
-    'allowHtml5',
-    'allowSvg',
-    'allowInlineStyles',
-    'allowTextElements',
-    'allowTemplating',
-    'allowCustomElement',
-    'allowTagExtension',
-    'allowImages',
-  ],
-  'dart.dom.html.Console': [
-    'timeEnd',
-    'time',
-    'timeStamp',
-    'warn',
-    'log',
-    'error',
-    'groupEnd',
-    'info',
-    'debug',
-    'groupCollapsed',
-    'group',
-    'dir',
-  ],
-  'dart.dom.html.ElementUpgrader': [
-    'upgrade',
-  ],
-  'dart.async.StreamIterator': [
-    'moveNext',
-    'cancel',
-  ],
-  'dart.io.SystemEncoding': [
-    'decode',
-  ],
-  'dart.collection.UnmodifiableListView': [
-    'where',
-    'contains',
-    'any',
-    'length',
-    'join',
-    'firstWhere',
-  ],
-  'dart.core.Error': [
-    'safeToString',
-    'toString',
-  ],
-  'dart.convert.Utf8Encoder': [
-    'bind',
-    'convert',
-    'startChunkedConversion',
-  ],
-  'dart.dom.html.DomImplementation': [
-    'createHtmlDocument',
-  ],
-  'dart.dom.html.DocumentFragment': [
-    'querySelectorAll',
-    'append',
-    'clone',
-    'nodes',
-    'children',
-    'setInnerHtml',
-    'querySelector',
-    'queryAll',
-    'query',
-    'remove',
-    'ownerDocument',
-  ],
-  'dart.dom.html.ShadowRoot': [
-    'querySelector',
-    'querySelectorAll',
-    'host',
-    'children',
-    'append',
-    'contains',
-    'query',
-    'activeElement',
-    'supported',
-    'nodes',
-    'firstChild',
-    'getElementsByTagName',
-    'text',
-    'innerHtml',
-    'olderShadowRoot',
-  ],
-  'dart.mirrors.TypeMirror': [
-    'qualifiedName',
-    'isSubtypeOf',
-    'reflectedType',
-    'newInstance',
-    'isAssignableTo',
-    'simpleName',
-    'typeArguments',
-    'originalDeclaration',
-    'toString',
-    'referent',
-    'hasReflectedType',
-    'isPrivate',
-    'typeVariables',
-    'owner',
-    'invoke',
-    'isOriginalDeclaration',
-  ],
-  'dart.io.ServerSocket': [
-    'bind',
-    'close',
-    'listen',
-  ],
-  'dart.dom.html.PerformanceNavigation': [
-    'type',
-    'redirectCount',
-  ],
-  'dart.dom.html.Performance': [
-    'now',
-    'timing',
-    'navigation',
-  ],
-  'dart.dom.html.PerformanceTiming': [
-    'navigationStart',
-  ],
-  'dart.typed_data.ByteBuffer': [
-    'asUint8List',
-    'asUint32List',
-    'asInt32List',
-    'asByteData',
-    'asFloat64x2List',
-    'asInt32x4List',
-    'asFloat32x4List',
-    'asFloat64List',
-    'asFloat32List',
-    'asUint64List',
-    'asInt64List',
-    'asUint16List',
-    'asInt16List',
-    'asUint8ClampedList',
-    'asInt8List',
-  ],
-  'dart.io.WebSocket': [
-    'add',
-    'listen',
-    'close',
-    'connect',
-    'where',
-    'map',
-    'send',
-  ],
-  'dart.convert.JsonEncoder': [
-    'convert',
-    'startChunkedConversion',
-  ],
-  'dart.convert.JsonDecoder': [
-    'convert',
-    'startChunkedConversion',
-  ],
-  'dart.core.bool': [
-    'toString',
-    'should',
-    'hashCode',
-    'isAssignableFrom',
-    'parse',
-    'containsKey',
-  ],
-  'dart.core.FormatException': [
-    'toString',
-  ],
-  'dart.dom.html.WindowBase': [
-    'postMessage',
-    'navigator',
-    'close',
-    'alert',
-  ],
-  'dart.dom.html.ButtonElement': [
-    'text',
-    'onClick',
-    'classes',
-    'attributes',
-    'style',
-    'append',
-    'type',
-    'setInnerHtml',
-    'children',
-    'onMouseOut',
-    'onMouseOver',
-    'click',
-    'disabled',
-    'dataset',
-    'appendText',
-  ],
-  'dart.core.Exception': [
-    'toString',
-    'printStackTrace',
-  ],
-  'dart.dom.html.DataTransfer': [
-    'setData',
-    'setDragImage',
-    'types',
-    'effectAllowed',
-    'dropEffect',
-    'getData',
-    'files',
-  ],
-  'dart.math.Point': [
-    'x',
-    'y',
-    'distanceTo',
-    'magnitude',
-  ],
-  'dart.dom.html.LIElement': [
-    'classes',
-    'append',
-    'style',
-    'text',
-    'querySelector',
-    'innerHtml',
-    'dispatchEvent',
-    'children',
-    'dataset',
-    'className',
-    'nodes',
-    'remove',
-    'value',
-  ],
-  'dart.dom.html.CanvasRenderingContext2D': [
-    'lineTo',
-    'beginPath',
-    'fillRect',
-    'moveTo',
-    'stroke',
-    'drawImage',
-    'closePath',
-    'restore',
-    'translate',
-    'save',
-    'scale',
-    'fill',
-    'getImageData',
-    'clearRect',
-    'setTransform',
-    'strokeRect',
-    'rotate',
-    'putImageData',
-    'fillStyle',
-    'arc',
-    'transform',
-    'fillText',
-    'strokeStyle',
-    'createImageData',
-    'createPatternFromImage',
-    'clip',
-    'lineWidth',
-    'drawImageToRect',
-    'strokeText',
-    'font',
-    'rect',
-    'drawImageScaledFromSource',
-    'setFillColorRgb',
-    'createLinearGradient',
-    'bezierCurveTo',
-    'drawImageScaled',
-    'measureText',
-    'setLineDash',
-    'shadowBlur',
-    'shadowOffsetX',
-    'shadowOffsetY',
-    'shadowColor',
-    'quadraticCurveTo',
-    'imageSmoothingEnabled',
-    'textAlign',
-    'createRadialGradient',
-    'textBaseline',
-    'globalAlpha',
-    'lineCap',
-  ],
-  'dart.io.HeaderValue': [
-    'parse',
-  ],
-  'dart.dom.html.ScriptElement': [
-    'src',
-    'type',
-    'async',
-    'remove',
-    'text',
-  ],
-  'dart.dom.html.MouseEvent': [
-    'preventDefault',
-    'stopPropagation',
-    'target',
-    'dataTransfer',
-    'page',
-    'client',
-    'ctrlKey',
-    'stopImmediatePropagation',
-    'metaKey',
-    'shiftKey',
-  ],
-  'dart.io.RawSocket': [
-    'write',
-    'listen',
-    'close',
-    'connect',
-    'read',
-    'available',
-    'shutdown',
-    'setOption',
-  ],
-  'dart.io.RawSecureSocket': [
-    'secure',
-    'connect',
-    'shutdown',
-    'listen',
-    'secureServer',
-    'write',
-    'read',
-  ],
-  'dart.dom.web_sql.SqlDatabase': [
-    'transaction',
-    'supported',
-  ],
-  'dart.dom.web_sql.SqlTransaction': [
-    'executeSql',
-  ],
-  'dart.dom.web_sql.SqlResultSetRowList': [
-    'length',
-    'elementAt',
-    'isNotEmpty',
-    'item',
-    'forEach',
-  ],
-  'dart.convert.AsciiCodec': [
-    'encode',
-    'decode',
-  ],
-  'dart.dom.html.EventStreamProvider': [
-    'forTarget',
-    'forElement',
-  ],
-  'dart.dom.html.MutationObserver': [
-    'observe',
-    'disconnect',
-    'takeRecords',
-  ],
-  'dart.dom.html.UListElement': [
-    'queryAll',
-    'append',
-    'style',
-    'id',
-    'children',
-    'remove',
-    'query',
-    'insertBefore',
-    'classes',
-  ],
-  'dart.dom.html.VideoElement': [
-    'canPlayType',
-    'load',
-    'pause',
-    'play',
-    'autoplay',
-    'remove',
-    'src',
-  ],
-  'dart.dom.html.MediaError': [
-    'code',
-  ],
-  'dart.dom.html.TimeRanges': [
-    'start',
-    'end',
-  ],
-  'dart.dom.html.SourceElement': [
-    'remove',
-  ],
-  'dart.dom.html.ObjectElement': [
-    'remove',
-    'getAttribute',
-  ],
-  'dart.dom.html.OptionElement': [
-    'value',
-    'text',
-    'selected',
-    'label',
-    'appendText',
-  ],
-  'dart.dom.html.SpanElement': [
-    'classes',
-    'text',
-    'style',
-    'append',
-    'appendText',
-    'onMouseOut',
-    'onMouseOver',
-    'onClick',
-    'attributes',
-    'remove',
-    'draggable',
-    'id',
-    'outerHtml',
-    'innerHtml',
-    'setAttribute',
-    'querySelector',
-    'scrollIntoView',
-  ],
-  'dart.dom.html.Geolocation': [
-    'getCurrentPosition',
-    'watchPosition',
-  ],
-  'dart.dom.html.Coordinates': [
-    'accuracy',
-    'longitude',
-    'latitude',
-    'speed',
-    'heading',
-    'altitudeAccuracy',
-    'altitude',
-  ],
-  'dart.dom.html.ImageElement': [
-    'remove',
-    'width',
-    'height',
-    'onLoad',
-    'src',
-    'style',
-    'crossOrigin',
-    'classes',
-    'className',
-    'id',
-    'onDragStart',
-  ],
-  'dart.mirrors.MethodMirror': [
-    'parameters',
-    'isGetter',
-    'isConstructor',
-    'returnType',
-    'owner',
-    'simpleName',
-    'location',
-    'source',
-    'isStatic',
-  ],
-  'dart.dom.html.Storage': [
-    'containsKey',
-    'clear',
-    'remove',
-    'length',
-    'keys',
-    'containsValue',
-  ],
-  'dart.convert.ChunkedConversionSink': [
-    'add',
-    'close',
-    'specialI',
-  ],
-  'dart.collection.ListQueue': [
-    'add',
-    'removeFirst',
-    'addAll',
-    'addLast',
-    'removeLast',
-    'forEach',
-    'toList',
-    'removeWhere',
-    'addFirst',
-  ],
-  'dart.dom.html.CanvasElement': [
-    'getContext',
-    'style',
-    'width',
-    'height',
-    'context2D',
-    'toDataUrl',
-    'getContext3d',
-    'onMouseUp',
-    'onMouseDown',
-    'getBoundingClientRect',
-    'onMouseMove',
-    'onClick',
-    'onMouseOut',
-    'className',
-    'onMouseOver',
-    'setAttribute',
-    'remove',
-    'context2d',
-    'focus',
-  ],
-  'dart.dom.html.KeyboardEvent': [
-    'preventDefault',
-    'which',
-    'stopPropagation',
-    'ctrlKey',
-    'keyCode',
-    'stopImmediatePropagation',
-    'metaKey',
-    'altKey',
-    'shiftKey',
-    'getModifierState',
-  ],
-  'dart.dom.html.WebSocket': [
-    'send',
-    'close',
-    'onMessage',
-    'onClose',
-    'onError',
-    'onOpen',
-    'readyState',
-    'url',
-    'sendTypedData',
-    'binaryType',
-  ],
-  'dart.io.WebSocketTransformer': [
-    'upgrade',
-    'isUpgradeRequest',
-  ],
-  'dart.core.Symbol': [
-    'toString',
-    'length',
-  ],
-  'dart.js.JsFunction': [
-    'apply',
-  ],
-  'dart.io.InternetAddress': [
-    'address',
-    'host',
-    'lookup',
-    'toString',
-    'isLoopback',
-  ],
-  'dart.convert.Latin1Codec': [
-    'decode',
-  ],
-  'dart.dom.html.ElementEvents': [
-    'click',
-    'load',
-    'change',
-    'keyPress',
-    'drop',
-    'dragOver',
-    'dragEnter',
-    'input',
-    'keyDown',
-    'dragLeave',
-    'dragEnd',
-    'dragStart',
-    'mouseOut',
-    'mouseMove',
-    'keyUp',
-    'loadedMetadata',
-  ],
-  'dart.dom.html.TableCellElement': [
-    'setInnerHtml',
-    'style',
-    'append',
-    'text',
-    'insertAdjacentElement',
-    'colSpan',
-    'setAttribute',
-    'innerHtml',
-    'cellIndex',
-  ],
-  'dart.dom.html.TableRowElement': [
-    'append',
-    'attributes',
-    'classes',
-    'onClick',
-    'children',
-    'onMouseOut',
-    'onMouseOver',
-    'remove',
-    'insertCell',
-    'cells',
-    'createFragment',
-    'addCell',
-    'query',
-    'outerHtml',
-  ],
-  'dart.convert.Converter': [
-    'convert',
-    'startChunkedConversion',
-  ],
-  'dart.dom.html.FormData': [
-    'append',
-    'appendBlob',
-  ],
-  'dart.io.ProcessException': [
-    'toString',
-  ],
-  'dart.dom.html.Text': [
-    'remove',
-    'text',
-    'toString',
-  ],
-  'dart.dom.html.AnchorElement': [
-    'href',
-    'text',
-    'onClick',
-    'id',
-    'classes',
-    'append',
-    'dispatchEvent',
-    'replaceWith',
-    'download',
-    'click',
-    'setAttribute',
-    'appendText',
-  ],
-  'dart.dom.svg.LineElement': [
-    'setAttribute',
-  ],
-  'dart.dom.svg.RectElement': [
-    'setAttribute',
-    'attributes',
-  ],
-  'dart.dom.svg.EllipseElement': [
-    'setAttribute',
-  ],
-  'dart.dom.svg.PolylineElement': [
-    'attributes',
-  ],
-  'dart.dom.svg.CircleElement': [
-    'setAttribute',
-  ],
-  'dart.dom.svg.PathElement': [
-    'setAttribute',
-    'createSvgPathSegLinetoAbs',
-    'createSvgPathSegMovetoAbs',
-  ],
-  'dart.dom.html.HeadingElement': [
-    'text',
-    'classes',
-    'appendText',
-    'append',
-    'id',
-  ],
-  'dart.dom.html.TableElement': [
-    'insertRow',
-    'createFragment',
-    'append',
-    'children',
-    'createTBody',
-    'deleteRow',
-    'addRow',
-    'query',
-    'querySelector',
-  ],
-  'dart.io.HttpConnectionInfo': [
-    'remoteAddress',
-    'remotePort',
-    'localPort',
-    'remoteHost',
-  ],
-  'dart.dom.html.FormElement': [
-    'append',
-    'submit',
-    'children',
-    'remove',
-  ],
-  'dart.io.Cookie': [
-    'value',
-    'toString',
-    'path',
-  ],
-  'dart.dom.html.InputElement': [
-    'focus',
-    'select',
-    'value',
-    'remove',
-    'type',
-    'checkValidity',
-    'dataset',
-    'onKeyDown',
-    'setSelectionRange',
-    'dispatchEvent',
-    'selectionStart',
-    'selectionEnd',
-    'setAttribute',
-    'bind',
-    'checked',
-    'attributes',
-    'blur',
-    'setRangeText',
-    'click',
-    'onChange',
-    'placeholder',
-    'id',
-    'onKeyUp',
-    'onBlur',
-    'onKeyPress',
-    'autocomplete',
-    'onPaste',
-    'defaultChecked',
-    'onFocus',
-    'disabled',
-  ],
-  'dart.io.Socket': [
-    'close',
-    'connect',
-    'transform',
-    'destroy',
-    'add',
-    'listen',
-    'write',
-    'addStream',
-    'pipe',
-    'address',
-    'read',
-    'writeList',
-    'setOption',
-    'flush',
-    'map',
-    'readList',
-    'available',
-  ],
-  'dart.mirrors.ParameterMirror': [
-    'type',
-    'isOptional',
-    'defaultValue',
-  ],
-  'dart.convert.Codec': [
-    'fuse',
-    'encode',
-    'decode',
-  ],
-  'dart.dom.indexed_db.Database': [
-    'transaction',
-    'createObjectStore',
-    'close',
-  ],
-  'dart.dom.indexed_db.Transaction': [
-    'objectStore',
-    'onAbort',
-    'onError',
-    'onComplete',
-  ],
-  'dart.dom.indexed_db.ObjectStore': [
-    'put',
-    'delete',
-    'createIndex',
-    'getObject',
-    'index',
-    'openCursor',
-    'clear',
-  ],
-  'dart.dom.svg.SvgSvgElement': [
-    'append',
-    'setAttribute',
-    'createFragment',
-    'createSvgPoint',
-    'getScreenCtm',
-    'onMouseUp',
-    'onMouseMove',
-  ],
-  'dart.dom.svg.Point': [
-    'matrixTransform',
-  ],
-  'dart.dom.svg.Matrix': [
-    'inverse',
-  ],
-  'dart.dom.html.WheelEvent': [
-    'preventDefault',
-    'stopPropagation',
-  ],
-  'dart.dom.svg.AnimatedRect': [
-    'baseVal',
-  ],
-  'dart.dom.html.SelectElement': [
-    'append',
-    'focus',
-    'remove',
-    'classes',
-    'tabIndex',
-    'options',
-    'selectedIndex',
-    'querySelectorAll',
-    'multiple',
-    'value',
-  ],
-  'dart.dom.html.LabelElement': [
-    'query',
-    'text',
-    'append',
-    'htmlFor',
-    'style',
-    'appendText',
-    'classes',
-  ],
-  'dart.io.HttpSession': [
-    'id',
-    'destroy',
-    'clear',
-    'containsKey',
-    'isNew',
-    'remove',
-    'onTimeout',
-  ],
-  'dart.dom.indexed_db.IdbFactory': [
-    'open',
-    'deleteDatabase',
-    'supported',
-    'supportsDatabaseNames',
-    'getDatabaseNames',
-  ],
-  'dart.dom.indexed_db.Request': [
-    'result',
-  ],
-  'dart.dom.indexed_db.Index': [
-    'openCursor',
-  ],
-  'dart.dom.indexed_db.KeyRange': [
-    'upperBound_',
-    'bound_',
-    'lowerBound_',
-    'only_',
-  ],
-  'dart.dom.indexed_db.CursorWithValue': [
-    'delete',
-  ],
-  'dart.core.NoSuchMethodError': [
-    'toString',
-  ],
-  'dart.isolate.Isolate': [
-    'spawn',
-    'spawnUri',
-    'resume',
-    'addOnExitListener',
-    'removeErrorListener',
-    'addErrorListener',
-    'kill',
-    'ping',
-    'pause',
-    'setErrorsFatal',
-  ],
-  'dart.dom.html.TemplateElement': [
-    'decorate',
-    'content',
-  ],
-  'dart.dom.html.TreeWalker': [
-    'nextNode',
-  ],
-  'dart.dom.html.StyleElement': [
-    'remove',
-    'appendText',
-    'text',
-    'sheet',
-    'attributes',
-    'type',
-    'appendHtml',
-    'dataset',
-    'append',
-    'innerHtml',
-  ],
-  'dart.dom.html.EventTarget': [
-    'error',
-    'result',
-    'matchesWithAncestors',
-    'nodeName',
-    'matches',
-    'classes',
-    'dispatchEvent',
-    'removeEventListener',
-    'addEventListener',
-    'status',
-    'parent',
-    'value',
-    'hashCode',
-  ],
-  'dart.collection_helpers.equality.Equality': [
-    'hash',
-    'equals',
-    'isValidKey',
-  ],
-  'dart.collection_helpers.equality.SetEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.collection_helpers.equality.MapEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.collection_helpers.equality.ListEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.collection_helpers.equality.IterableEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.collection_helpers.equality.UnorderedIterableEquality': [
-    'hash',
-    'equals',
-  ],
-  'dart.io.SecureSocket': [
-    'initialize',
-    'close',
-    'connect',
-    'listen',
-    'write',
-    'add',
-    'fold',
-    'writeln',
-    'secure',
-    'transform',
-  ],
-  'dart.io.HttpDate': [
-    'parse',
-    'format',
-  ],
-  'dart.math.Rectangle': [
-    'top',
-    'left',
-    'containsPoint',
-    'height',
-    'width',
-    'topLeft',
-    'intersection',
-    'topRight',
-    'intersects',
-    'containsRectangle',
-    'boundingBox',
-    'snap',
-  ],
-  'dart.dom.html.ContentElement': [
-    'getDistributedNodes',
-  ],
-  'dart.io.SocketException': [
-    'toString',
-  ],
-  'dart.dom.html.TextAreaElement': [
-    'style',
-    'focus',
-    'select',
-    'rows',
-    'attributes',
-    'setSelectionRange',
-    'value',
-    'appendText',
-    'remove',
-  ],
-  'dart.dom.html.LinkElement': [
-    'href',
-    'replaceWith',
-    'rel',
-  ],
-  'dart.dom.html.ParagraphElement': [
-    'text',
-    'appendHtml',
-    'classes',
-    'addHtml',
-    'hidden',
-  ],
-  'dart.typed_data.Int32List': [
-    'setRange',
-    'indexOf',
-    'sublist',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-    'setAll',
-  ],
-  'dart.dom.web_gl.RenderingContext': [
-    'ARRAY_BUFFER',
-    'texParameteri',
-    'bindBuffer',
-    'bindFramebuffer',
-    'TEXTURE_2D',
-    'enable',
-    'deleteShader',
-    'getUniformLocation',
-    'bindTexture',
-    'clear',
-    'createTexture',
-    'detachShader',
-    'attachShader',
-    'getAttribLocation',
-    'createBuffer',
-    'enableVertexAttribArray',
-    'vertexAttribPointer',
-    'FLOAT',
-    'STATIC_DRAW',
-    'createShader',
-    'shaderSource',
-    'compileShader',
-    'viewport',
-    'useProgram',
-    'clearColor',
-    'bufferDataTyped',
-    'getShaderParameter',
-    'uniformMatrix4fv',
-    'getShaderInfoLog',
-    'bindRenderbuffer',
-    'deleteTexture',
-    'deleteProgram',
-    'RGBA',
-    'linkProgram',
-    'createProgram',
-    'disableVertexAttribArray',
-    'disable',
-    'getProgramParameter',
-    'blendFunc',
-    'drawArrays',
-    'getProgramInfoLog',
-    'TRIANGLES',
-    'lineWidth',
-    'COMPILE_STATUS',
-    'texImage2DTyped',
-    'NEAREST',
-    'createFramebuffer',
-    'getExtension',
-    'framebufferTexture2D',
-    'framebufferRenderbuffer',
-    'renderbufferStorage',
-    'createRenderbuffer',
-    'ELEMENT_ARRAY_BUFFER',
-    'uniformMatrix3fv',
-    'uniform2f',
-    'UNSIGNED_BYTE',
-    'deleteFramebuffer',
-    'deleteRenderbuffer',
-    'TEXTURE_MIN_FILTER',
-    'TEXTURE_MAG_FILTER',
-    'CLAMP_TO_EDGE',
-    'DEPTH_TEST',
-    'DEPTH_BUFFER_BIT',
-    'texImage2DImage',
-    'COLOR_BUFFER_BIT',
-    'LINK_STATUS',
-    'FRAGMENT_SHADER',
-    'VERTEX_SHADER',
-    'bufferData',
-    'TEXTURE_WRAP_S',
-    'TEXTURE_WRAP_T',
-    'texImage2DCanvas',
-    'LINEAR',
-    'UNSIGNED_SHORT',
-    'texImage2D',
-    'drawElements',
-    'pixelStorei',
-    'colorMask',
-    'depthFunc',
-    'TRIANGLE_STRIP',
-    'activeTexture',
-    'TEXTURE0',
-    'depthMask',
-    'FRAMEBUFFER',
-    'UNPACK_FLIP_Y_WEBGL',
-    'generateMipmap',
-    'uniform1i',
-  ],
-  'dart.typed_data.Float32List': [
-    'sublist',
-    'indexOf',
-    'buffer',
-    'setRange',
-    'length',
-  ],
-  'dart.dom.html.DirectoryEntry': [
-    'getFile',
-    'createDirectory',
-    'createFile',
-    'createReader',
-    'getDirectory',
-    'removeRecursively',
-    'toUrl',
-    'fullPath',
-    'toString',
-  ],
-  'dart.dom.html.Entry': [
-    'moveTo',
-    'isFile',
-    'copyTo',
-    'isDirectory',
-    'fullPath',
-    'name',
-    'remove',
-    'getMetadata',
-    'createWriter',
-    'file',
-    'getParent',
-    'toUrl',
-  ],
-  'dart.dom.html.DirectoryReader': [
-    'readEntries',
-  ],
-  'dart.dom.html.KeyCode': [
-    'DOWN',
-    'RIGHT',
-    'LEFT',
-    'TAB',
-    'UP',
-    'ESC',
-    'ENTER',
-    'isCharacterKey',
-    'SPACE',
-    'NUM_SOUTH',
-    'NUM_NORTH',
-    'NUM_EAST',
-    'NUM_WEST',
-    'NUM_NORTH_EAST',
-    'NUM_SOUTH_EAST',
-    'R',
-  ],
-  'dart.pkg.collection.iterable_zip.IterableZip': [
-    'map',
-    'toList',
-  ],
-  'dart.convert.LineSplitter': [
-    'convert',
-  ],
-  'dart.dom.html.HttpRequestUpload': [
-    'onProgress',
-    'onError',
-    'onTimeout',
-  ],
-  'dart.dom.html.File': [
-    'name',
-    'slice',
-    'readAsBytesSync',
-    'existsSync',
-  ],
-  'dart.dom.html.Events': [
-    'error',
-    'message',
-    'load',
-    'hashChange',
-    'popState',
-    'resize',
-    'loadEnd',
-  ],
-  'dart.dom.html.Url': [
-    'createObjectUrl',
-    'revokeObjectUrl',
-    'createObjectUrlFromBlob',
-    'createObjectUrlFromStream',
-  ],
-  'dart.dom.html.RtcIceCandidate': [
-    'candidate',
-    'sdpMLineIndex',
-  ],
-  'dart.dom.html.RtcPeerConnection': [
-    'setLocalDescription',
-    'createDataChannel',
-    'createOffer',
-    'createAnswer',
-  ],
-  'dart.io.RawDatagramSocket': [
-    'bind',
-    'close',
-    'receive',
-    'send',
-    'listen',
-  ],
-  'dart.pkg.collection.equality.DeepCollectionEquality': [
-    'equals',
-    'hash',
-  ],
-  'dart.pkg.collection.priority_queue.PriorityQueue': [
-    'addAll',
-    'contains',
-    'removeFirst',
-    'add',
-    'removeAll',
-  ],
-  'dart.convert.StringConversionSink': [
-    'add',
-    'asUtf8Sink',
-    'close',
-    'asStringSink',
-    'addSlice',
-  ],
-  'dart.dom.html.ImageData': [
-    'data',
-  ],
-  'dart.dom.html.PreElement': [
-    'appendText',
-    'text',
-    'append',
-    'classes',
-  ],
-  'dart.dom.html.MediaStream': [
-    'stop',
-  ],
-  'dart.dom.html.DomParser': [
-    'parseFromString',
-  ],
-  'dart.dom.html.CustomEvent': [
-    'stopImmediatePropagation',
-    'preventDefault',
-    'stopPropagation',
-  ],
-  'dart.typed_data.Uint16List': [
-    'buffer',
-    'sublist',
-    'setRange',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-    'length',
-  ],
-  'dart.dom.html.CanvasGradient': [
-    'addColorStop',
-  ],
-  'dart.dom.html.Notification': [
-    'requestPermission',
-  ],
-  'dart.dom.svg.Length': [
-    'value',
-    'valueAsString',
-  ],
-  'dart.dom.svg.AnimatedLength': [
-    'baseVal',
-  ],
-  'dart.dom.svg.PointList': [
-    'getItem',
-  ],
-  'dart.mirrors.SourceLocation': [
-    'line',
-  ],
-  'dart.DartGrammarDefinition': [
-    'build',
-  ],
-  'dart.dom.html.TextMetrics': [
-    'width',
-  ],
-  'dart.dom.html.CssRect': [
-    'width',
-    'height',
-    'top',
-    'left',
-    'topLeft',
-  ],
-  'dart.dom.html.KeyboardEventStream': [
-    'onKeyDown',
-  ],
-  'dart.dom.html.CssRule': [
-    'selectorText',
-  ],
-  'dart.dom.html.CssStyleRule': [
-    'style',
-    'selectorText',
-  ],
-  'dart.dom.html.Selection': [
-    'removeAllRanges',
-    'collapse',
-    'getRangeAt',
-  ],
-  'dart.dom.html.CheckboxInputElement': [
-    'checked',
-    'attributes',
-    'classes',
-    'value',
-  ],
-  'dart.dom.html.TextInputElement': [
-    'classes',
-    'value',
-    'focus',
-    'select',
-    'className',
-    'onKeyDown',
-    'style',
-  ],
-  'dart.dom.html.DateInputElement': [
-    'classes',
-  ],
-  'dart.dom.html.RangeInputElement': [
-    'style',
-    'attributes',
-    'onChange',
-    'value',
-    'step',
-    'max',
-    'min',
-  ],
-  'dart.dom.html.AnimationTimeline': [
-    'play',
-  ],
-  'dart.dom.html.AnimationPlayer': [
-    'play',
-  ],
-  'dart.dom.html.GlobalEventHandlers': [
-    'clickEvent',
-  ],
-  'dart.dom.html.TouchEvent': [
-    'preventDefault',
-    'supported',
-    'stopPropagation',
-  ],
-  'dart.dom.html.AudioElement': [
-    'canPlayType',
-    'load',
-    'append',
-    'play',
-    'pause',
-    'remove',
-  ],
-  'dart.io.ProcessSignal': [
-    'watch',
-  ],
-  'dart.convert.Utf8Decoder': [
-    'convert',
-    'startChunkedConversion',
-  ],
-  'dart.dom.html.AnimationEvent': [
-    'preventDefault',
-    'stopImmediatePropagation',
-  ],
-  'dart.dom.html.FocusEvent': [
-    'stopImmediatePropagation',
-  ],
-  'dart.dom.html.Touch': [
-    'page',
-    'client',
-  ],
-  'dart.async.DeferredLibrary': [
-    'load',
-  ],
-  'dart.dom.html.TableSectionElement': [
-    'append',
-    'innerHtml',
-    'rows',
-    'createFragment',
-    'addRow',
-  ],
-  'dart.mirrors.Mirror': [
-    'methods',
-    'invoke',
-    'type',
-    'delegate',
-    'members',
-  ],
-  'dart.core.StateError': [
-    'toString',
-  ],
-  'dart.io.FileMode': [
-    'APPEND',
-    'READ',
-    'WRITE',
-  ],
-  'dart.dom.html.CssStyleDeclarationBase': [
-    'display',
-    'backgroundColor',
-    'opacity',
-    'borderLeftWidth',
-  ],
-  'dart.dom.html.IFrameElement': [
-    'style',
-    'src',
-  ],
-  'dart.io.FileSystemException': [
-    'toString',
-  ],
-  'dart.dom.html.Screen': [
-    'width',
-    'height',
-    'pixelDepth',
-  ],
-  'dart.core.ArgumentError': [
-    'toString',
-  ],
-  'dart.dom.html.Blob': [
-    'slice',
-  ],
-  'dart.dom.svg.PatternElement': [
-    'setAttribute',
-    'append',
-  ],
-  'dart.dom.svg.DefsElement': [
-    'append',
-  ],
-  'dart.dom.svg.PathSegList': [
-    'appendItem',
-    'clear',
-    'length',
-    'getItem',
-  ],
-  'dart.dom.html.FileList': [
-    'length',
-    'item',
-  ],
-  'dart.dom.html.FileError': [
-    'NOT_FOUND_ERR',
-    'code',
-  ],
-  'dart.mirrors.VariableMirror': [
-    'type',
-    'isFinal',
-    'isStatic',
-  ],
-  'dart.io.HttpStatus': [
-    'NOT_FOUND',
-  ],
-  'dart.typed_data.Float64List': [
-    'sublist',
-    'indexOf',
-    'setRange',
-  ],
-  'dart.typed_data.Float32x4': [
-    'shuffle',
-    'shuffleMix',
-    'scale',
-    'signMask',
-    'clamp',
-    'withX',
-    'withY',
-    'w',
-    'z',
-    'y',
-    'x',
-  ],
-  'dart.pkg.typed_data.typed_buffers.Int32x4Buffer': [
-    'add',
-  ],
-  'dart.dom.html.NumberInputElement': [
-    'step',
-    'max',
-    'min',
-    'valueAsNumber',
-  ],
-  'dart.dom.html.ValidityState': [
-    'valid',
-  ],
-  'dart.dom.html.CssStyleSheet': [
-    'ownerNode',
-    'insertRule',
-    'addRule',
-  ],
-  'dart.io.ZLibCodec': [
-    'decode',
-  ],
-  'dart.collection.HasNextIterator': [
-    'next',
-  ],
-  'dart.isolate.RawReceivePort': [
-    'close',
-  ],
-  'dart.mirrors.TypeVariableMirror': [
-    'simpleName',
-    'isSubtypeOf',
-    'isAssignableTo',
-    'owner',
-  ],
-  'dart.typed_data.implementation.NativeByteBuffer': [
-    'asFloat64List',
-    'asFloat32List',
-    'asInt32List',
-  ],
-  'dart.typed_data.implementation.NativeFloat32x4List': [
-    'length',
-  ],
-  'dart.typed_data.implementation.NativeFloat32List': [
-    'sublist',
-  ],
-  'dart.typed_data.implementation.NativeInt32x4List': [
-    'length',
-  ],
-  'dart.typed_data.implementation.NativeFloat64x2List': [
-    'length',
-  ],
-  'dart.typed_data.implementation.NativeFloat64List': [
-    'sublist',
-  ],
-  'dart.typed_data.implementation.NativeTypedArray': [
-    'length',
-  ],
-  'dart.typed_data.implementation.NativeTypedArrayOfDouble': [
-    'setRange',
-  ],
-  'dart.typed_data.implementation.NativeTypedArrayOfInt': [
-    'setRange',
-  ],
-  'dart.typed_data.implementation.NativeInt32x4': [
-    'w',
-    'z',
-    'y',
-    'x',
-  ],
-  'dart.dom.svg.SvgElement': [
-    'isTagSupported',
-    'clone',
-    'setAttribute',
-    'children',
-    'setInnerHtml',
-    'attributes',
-  ],
-  'dart.dom.svg.GElement': [
-    'append',
-    'querySelector',
-    'id',
-  ],
-  'dart.dom.html.ProgressEvent': [
-    'toString',
-  ],
-  'dart.core.RangeError': [
-    'toString',
-    'checkValidRange',
-    'checkNotNegative',
-    'checkValueInInterval',
-    'checkValidIndex',
-  ],
-  'dart.dom.html.TouchList': [
-    'length',
-    'first',
-    'isEmpty',
-    'isNotEmpty',
-  ],
-  'dart.dom.html.FieldSetElement': [
-    'append',
-    'querySelector',
-  ],
-  'dart.dom.html.ShadowElement': [
-    'getDistributedNodes',
-  ],
-  'dart.dom.html.KeyEvent': [
-    'keyCode',
-    'type',
-    'preventDefault',
-  ],
-  'dart.dom.html.NodeList': [
-    'length',
-    'add',
-  ],
-  'dart.dom.html.DomStringList': [
-    'length',
-  ],
-  'dart.dom.html.HtmlCollection': [
-    'length',
-    'forEach',
-    'contains',
-  ],
-  'dart.dom.html.Range': [
-    'createContextualFragment',
-    'selectNodeContents',
-    'insertNode',
-    'setEndAfter',
-  ],
-  'dart.dom.html.NodeTreeSanitizer': [
-    'sanitizeTree',
-  ],
-  'dart.dom.html.MimeTypeArray': [
-    'length',
-  ],
-  'dart.dom.html.PluginArray': [
-    'length',
-  ],
-  'dart.dom.html.SourceBufferList': [
-    'length',
-  ],
-  'dart.dom.html.SpeechGrammarList': [
-    'length',
-  ],
-  'dart.dom.html.TextTrackCueList': [
-    'length',
-  ],
-  'dart.dom.html.TextTrackList': [
-    'length',
-  ],
-  'dart.dom.html.Dimension': [
-    'value',
-    'toString',
-  ],
-  'dart.dom.html.UriPolicy': [
-    'allowsUri',
-  ],
-  'dart.dom.html.NodeValidator': [
-    'allowsAttribute',
-    'allowsElement',
-  ],
-  'dart.dom.html.Worker': [
-    'terminate',
-  ],
-  'dart.typed_data.Int16List': [
-    'sublist',
-    'buffer',
-    'contains',
-    'setRange',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-  ],
-  'dart.dom.indexed_db.Cursor': [
-    'next',
-  ],
-  'dart.dom.svg.LengthList': [
-    'length',
-    'getItem',
-  ],
-  'dart.dom.svg.NumberList': [
-    'length',
-    'getItem',
-  ],
-  'dart.dom.svg.StringList': [
-    'length',
-    'getItem',
-  ],
-  'dart.dom.svg.TransformList': [
-    'length',
-    'getItem',
-  ],
-  'dart.js.JsArray': [
-    'length',
-    'addAll',
-    'insert',
-    'removeRange',
-    'removeAt',
-    'add',
-    'setRange',
-    'removeLast',
-  ],
-  'dart.dom.html.ApplicationCache': [
-    'swapCache',
-  ],
-  'dart.dom.web_audio.AudioContext': [
-    'createBufferSource',
-    'createOscillator',
-    'destination',
-    'createPanner',
-    'createGain',
-  ],
-  'dart.dom.html.FileUploadInputElement': [
-    'click',
-  ],
-  'dart.dom.html.DomRectReadOnly': [
-    'top',
-    'left',
-    'height',
-    'width',
-  ],
-  'dart.typed_data.Int8List': [
-    'sublist',
-    'setRange',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-    'buffer',
-  ],
-  'dart.dom.web_audio.AudioBufferSourceNode': [
-    'connectNode',
-    'start',
-    'stop',
-  ],
-  'dart.dom.html.FileEntry': [
-    'file',
-    'getParent',
-    'toUrl',
-    'getMetadata',
-  ],
-  'dart.dom.html.CustomStream': [
-    'listen',
-  ],
-  'dart.dom.html.TrackElement': [
-    'defaultValue',
-  ],
-  'dart.dom.web_audio.OscillatorNode': [
-    'connectNode',
-  ],
-  'dart.dom.html.StorageQuota': [
-    'queryInfo',
-  ],
-  'dart.collection.DoubleLinkedQueue': [
-    'add',
-  ],
-  'dart.core.TypeError': [
-    'toString',
-  ],
-  'dart.core.AssertionError': [
-    'toString',
-  ],
-  'dart.profiler.Metrics': [
-    'register',
-  ],
-  'dart.collection.LinkedList': [
-    'remove',
-    'addFirst',
-    'clear',
-    'add',
-  ],
-  'dart.typed_data.Uint8ClampedList': [
-    'sublist',
-  ],
-  'dart.typed_data.Float64x2': [
-    'y',
-    'x',
-    'withX',
-  ],
-  'dart.convert.ByteConversionSink': [
-    'close',
-    'add',
-    'addSlice',
-  ],
-  'dart.convert.ClosableStringSink': [
-    'close',
-    'write',
-  ],
-  'dart.mirrors.TypedefMirror': [
-    'isSubtypeOf',
-    'isAssignableTo',
-    'referent',
-  ],
-  'dart.mirrors.FunctionTypeMirror': [
-    'isSubtypeOf',
-    'isAssignableTo',
-    'returnType',
-    'parameters',
-    'isOriginalDeclaration',
-  ],
-  'dart.mirrors.LibraryDependencyMirror': [
-    'metadata',
-  ],
-  'dart.test.stream_from_iterable.IterableTest': [
-    'run',
-  ],
-  'dart.io.SecureServerSocket': [
-    'bind',
-    'close',
-    'listen',
-  ],
-  'dart.io.RawServerSocket': [
-    'bind',
-    'listen',
-    'close',
-  ],
-  'dart.typed_data.Uint64List': [
-    'sublist',
-    'setRange',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-  ],
-  'dart.typed_data.Int64List': [
-    'sublist',
-    'setRange',
-    'removeRange',
-    'removeLast',
-    'clear',
-    'addAll',
-    'add',
-  ],
-  'dart.io.StdioType': [
-    'name',
-  ],
-  'dart.io.HttpConnectionsInfo': [
-    'total',
-    'idle',
-    'active',
-  ],
-  'dart.io.RawSecureServerSocket': [
-    'bind',
-    'close',
-    'listen',
-  ],
-  'dart.io.ServerSocketReference': [
-    'create',
-  ],
-  'dart.io.NetworkInterface': [
-    'list',
-  ],
-  'dart.io.ZLibDecoder': [
-    'convert',
-  ],
-  'dart.io.ZLibEncoder': [
-    'convert',
-  ],
-  'dart.pkg.async.results.ValueResult': [
-    'value',
-  ],
-  'dart.pkg.async.stream_zip.StreamZip': [
-    'toList',
-  ],
-  'dart.pkg.async.results.Result': [
-    'flatten',
-    'release',
-  ],
-  'dart.pkg.async.results.ErrorResult': [
-    'stackTrace',
-    'error',
-  ],
-  'dart.dom.html.OptGroupElement': [
-    'append',
-  ],
-  'dart.dom.html.UnknownElement': [
-    'query',
-  ],
-  'dart.dom.web_audio.AudioParam': [
-    'value',
-    'setValueAtTime',
-  ],
-  'dart.dom.html.RadioButtonInputElement': [
-    'checked',
-  ],
-  'dart.dom.web_audio.BiquadFilterNode': [
-    'connectNode',
-  ],
-  'dart.async.StreamConsumer': [
-    'addStream',
-    'close',
-  ],
-  'dart.dom.html.FileSystem': [
-    'root',
-  ],
-  'dart.dom.html.FileWriter': [
-    'write',
-    'abort',
-  ],
-  'dart.dom.html.OutputElement': [
-    'scrollIntoView',
-  ],
-  'dart.dom.html.Css': [
-    'supports',
-  ],
-  'dart.io.IOException': [
-    'toString',
-  ],
-  'dart.dom.html.ButtonInputElement': [
-    'value',
-    'onClick',
-  ],
-};
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index f6dc272..b27b353 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -10,9 +10,6 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
-import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
-import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
 import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
@@ -38,7 +35,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
@@ -54,10 +50,6 @@
 /// [DartCompletionManager] determines if a completion request is Dart specific
 /// and forwards those requests to all [DartCompletionContributor]s.
 class DartCompletionManager {
-  /// The [contributionSorter] is a long-lived object that isn't allowed
-  /// to maintain state between calls to [DartContributionSorter#sort(...)].
-  static DartContributionSorter contributionSorter = CommonUsageSorter();
-
   /// The object used to resolve macros in Dartdoc comments.
   final DartdocDirectiveInfo dartdocDirectiveInfo;
 
@@ -122,10 +114,6 @@
 
     request.checkAborted();
 
-    final ranking = CompletionRanking.instance;
-    var probabilityFuture =
-        ranking != null ? ranking.predict(dartRequest) : Future.value(null);
-
     var range = dartRequest.target.computeReplacementRange(dartRequest.offset);
     (request as CompletionRequestImpl)
       ..replacementOffset = range.offset
@@ -175,38 +163,7 @@
       throw AbortCompletion();
     }
 
-    // Adjust suggestion relevance before returning
-    var suggestions = builder.suggestions.toList();
-    const SORT_TAG = 'DartCompletionManager - sort';
-    await performance.runAsync(SORT_TAG, (_) async {
-      if (ranking != null) {
-        request.checkAborted();
-        try {
-          suggestions = await ranking.rerank(
-              probabilityFuture,
-              suggestions,
-              includedElementNames,
-              includedSuggestionRelevanceTags,
-              dartRequest,
-              request.result.unit.featureSet);
-        } catch (exception, stackTrace) {
-          // TODO(brianwilkerson) Shutdown the isolates that have already been
-          //  started.
-          // Disable smart ranking if prediction fails.
-          CompletionRanking.instance = null;
-          AnalysisEngine.instance.instrumentationService.logException(
-              CaughtException.withMessage(
-                  'Failed to rerank completion suggestions',
-                  exception,
-                  stackTrace));
-          await contributionSorter.sort(dartRequest, suggestions);
-        }
-      } else if (!request.useNewRelevance) {
-        await contributionSorter.sort(dartRequest, suggestions);
-      }
-    });
-    request.checkAborted();
-    return suggestions;
+    return builder.suggestions.toList();
   }
 
   void _addIncludedElementKinds(DartCompletionRequestImpl request) {
@@ -242,22 +199,19 @@
   }
 
   void _addIncludedSuggestionRelevanceTags(DartCompletionRequestImpl request) {
-    if (request.useNewRelevance) {
-      var location = request.opType.completionLocation;
-      if (location != null) {
-        var locationTable = elementKindRelevance[location];
-        if (locationTable != null) {
-          var inConstantContext = request.inConstantContext;
-          for (var entry in locationTable.entries) {
-            var kind = entry.key.toString();
-            var elementBoost = (entry.value.upper * 100).floor();
-            includedSuggestionRelevanceTags
-                .add(IncludedSuggestionRelevanceTag(kind, elementBoost));
-            if (inConstantContext) {
-              includedSuggestionRelevanceTags.add(
-                  IncludedSuggestionRelevanceTag(
-                      '$kind+const', elementBoost + 100));
-            }
+    var location = request.opType.completionLocation;
+    if (location != null) {
+      var locationTable = elementKindRelevance[location];
+      if (locationTable != null) {
+        var inConstantContext = request.inConstantContext;
+        for (var entry in locationTable.entries) {
+          var kind = entry.key.toString();
+          var elementBoost = (entry.value.upper * 100).floor();
+          includedSuggestionRelevanceTags
+              .add(IncludedSuggestionRelevanceTag(kind, elementBoost));
+          if (inConstantContext) {
+            includedSuggestionRelevanceTags.add(IncludedSuggestionRelevanceTag(
+                '$kind+const', elementBoost + 100));
           }
         }
       }
@@ -268,13 +222,10 @@
       var element = type.element;
       var tag = '${element.librarySource.uri}::${element.name}';
       if (element.isEnum) {
-        var relevance = request.useNewRelevance
-            ? RelevanceBoost.availableEnumConstant
-            : DART_RELEVANCE_BOOST_AVAILABLE_ENUM;
         includedSuggestionRelevanceTags.add(
           IncludedSuggestionRelevanceTag(
             tag,
-            relevance,
+            RelevanceBoost.availableEnumConstant,
           ),
         );
       } else {
@@ -284,13 +235,10 @@
         //  boost will almost always be ignored because the element boost will
         //  be bigger. Find a way to use this boost without negating the element
         //  boost, which is how we get constructors to come before classes.
-        var relevance = request.useNewRelevance
-            ? RelevanceBoost.availableDeclaration
-            : DART_RELEVANCE_BOOST_AVAILABLE_DECLARATION;
         includedSuggestionRelevanceTags.add(
           IncludedSuggestionRelevanceTag(
             tag,
-            relevance,
+            RelevanceBoost.availableDeclaration,
           ),
         );
       }
@@ -369,8 +317,7 @@
   }
 
   @override
-  FeatureSet get featureSet =>
-      result.session.analysisContext.analysisOptions.contextFeatures;
+  FeatureSet get featureSet => result.libraryElement.featureSet;
 
   @override
   bool get includeIdentifiers {
@@ -427,9 +374,6 @@
     return '';
   }
 
-  @override
-  bool get useNewRelevance => _originalRequest.useNewRelevance;
-
   /// Throw [AbortCompletion] if the completion request has been aborted.
   @override
   void checkAborted() {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
deleted file mode 100644
index 021aaf8..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-import 'dart:isolate';
-
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_ranking_internal.dart';
-import 'package:analysis_server/src/services/completion/dart/language_model.dart';
-import 'package:analyzer/dart/analysis/features.dart';
-
-/// Number of code completion isolates.
-// TODO(devoncarew): We need to explore the memory costs of running multiple ML
-// isolates.
-const int _ISOLATE_COUNT = 2;
-
-/// Number of lookback tokens.
-const int _LOOKBACK = 100;
-
-/// Minimum probability to prioritize model-only suggestion.
-const double _MODEL_RELEVANCE_CUTOFF = 0.5;
-
-/// Prediction service run by the model isolate.
-void entrypoint(SendPort sendPort) {
-  LanguageModel model;
-  final port = ReceivePort();
-  sendPort.send(port.sendPort);
-  port.listen((message) {
-    var response = <String, Map<String, double>>{};
-    switch (message['method']) {
-      case 'load':
-        model = LanguageModel.load(message['args'][0]);
-        break;
-      case 'predict':
-        response['data'] = model.predictWithScores(message['args']);
-        break;
-    }
-
-    message['port'].send(response);
-  });
-}
-
-class CompletionRanking {
-  /// Singleton instance.
-  static CompletionRanking instance;
-
-  /// Filesystem location of model files.
-  final String _directory;
-
-  /// Ports to communicate from main to model isolates.
-  List<SendPort> _writes;
-
-  /// Pointer for round robin load balancing over isolates.
-  int _index;
-
-  /// General performance metrics around ML completion.
-  final PerformanceMetrics performanceMetrics = PerformanceMetrics._();
-
-  CompletionRanking(this._directory);
-
-  /// Send an RPC to the isolate worker requesting that it load the model and
-  /// wait for it to respond.
-  Future<Map<String, Map<String, double>>> makeLoadRequest(
-      SendPort sendPort, List<String> args) async {
-    final receivePort = ReceivePort();
-    sendPort.send({
-      'method': 'load',
-      'args': args,
-      'port': receivePort.sendPort,
-    });
-    return await receivePort.first;
-  }
-
-  /// Send an RPC to the isolate worker requesting that it make a prediction and
-  /// wait for it to respond.
-  Future<Map<String, Map<String, double>>> makePredictRequest(
-      List<String> args) async {
-    final receivePort = ReceivePort();
-    _writes[_index].send({
-      'method': 'predict',
-      'args': args,
-      'port': receivePort.sendPort,
-    });
-    _index = (_index + 1) % _writes.length;
-    return await receivePort.first;
-  }
-
-  /// Return a next-token prediction starting at the completion request cursor
-  /// and walking back to find previous input tokens, or `null` if the
-  /// prediction isolates are not running.
-  Future<Map<String, double>> predict(DartCompletionRequest request) async {
-    if (_writes == null || _writes.isEmpty) {
-      // The field `_writes` is initialized in `start`, but the code that
-      // invokes `start` doesn't wait for it complete. That means that it's
-      // possible for this method to be invoked before `_writes` is initialized.
-      // In those cases we return `null`
-      return null;
-    }
-    final query = constructQuery(request, _LOOKBACK);
-    if (query == null) {
-      return Future.value();
-    }
-
-    performanceMetrics._incrementPredictionRequestCount();
-
-    var timer = Stopwatch()..start();
-    var response = await makePredictRequest(query);
-    timer.stop();
-
-    var result = response['data'];
-
-    performanceMetrics._addPredictionResult(PredictionResult(
-      result,
-      timer.elapsed,
-      request.source.fullName,
-      computeCompletionSnippet(request.sourceContents, request.offset),
-    ));
-
-    return result;
-  }
-
-  /// Transforms [CompletionSuggestion] relevances and
-  /// [IncludedSuggestionRelevanceTag] relevanceBoosts based on language model
-  /// predicted next-token probability distribution.
-  Future<List<CompletionSuggestion>> rerank(
-      Future<Map<String, double>> probabilityFuture,
-      List<CompletionSuggestion> suggestions,
-      Set<String> includedElementNames,
-      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
-      DartCompletionRequest request,
-      FeatureSet featureSet) async {
-    assert((includedElementNames != null &&
-            includedSuggestionRelevanceTags != null) ||
-        (includedElementNames == null &&
-            includedSuggestionRelevanceTags == null));
-    final probability = await probabilityFuture
-        .timeout(const Duration(seconds: 1), onTimeout: () => null);
-    if (probability == null || probability.isEmpty) {
-      // Failed to compute probability distribution, don't rerank.
-      return suggestions;
-    }
-
-    // Discard the type-based relevance boosts.
-    if (includedSuggestionRelevanceTags != null) {
-      includedSuggestionRelevanceTags.forEach((tag) {
-        tag.relevanceBoost = 0;
-      });
-    }
-
-    // Intersection between static analysis and model suggestions.
-    var middle = DART_RELEVANCE_HIGH + probability.length;
-    // Up to one suggestion from model with very high confidence.
-    var high = middle + probability.length;
-    // Lower relevance, model-only suggestions (perhaps literals).
-    var low = DART_RELEVANCE_LOW - 1;
-
-    List<MapEntry> entries = probability.entries.toList()
-      ..sort((a, b) => b.value.compareTo(a.value));
-
-    if (testInsideQuotes(request)) {
-      // If completion is requested inside of quotes, remove any suggestions
-      // which are not string literal.
-      entries = selectStringLiterals(entries);
-    } else if (request.opType.includeVarNameSuggestions &&
-        suggestions.every((CompletionSuggestion suggestion) =>
-            suggestion.kind == CompletionSuggestionKind.IDENTIFIER)) {
-      // If analysis server thinks this is a declaration context,
-      // remove all of the model-suggested literals.
-      // TODO(lambdabaa): Ask Brian for help leveraging
-      //     SimpleIdentifier#inDeclarationContext.
-      entries.retainWhere((MapEntry entry) => !isLiteral(entry.key));
-    }
-
-    var allowModelOnlySuggestions =
-        !testNamedArgument(suggestions) && !testFollowingDot(request);
-    for (var entry in entries) {
-      // There may be multiple like
-      // CompletionSuggestion and CompletionSuggestion().
-      final completionSuggestions = suggestions.where((suggestion) =>
-          areCompletionsEquivalent(suggestion.completion, entry.key));
-      List<IncludedSuggestionRelevanceTag> includedSuggestions;
-      final isIncludedElementName = includedElementNames != null &&
-          includedElementNames.contains(entry.key);
-      if (includedSuggestionRelevanceTags != null) {
-        includedSuggestions = includedSuggestionRelevanceTags
-            .where((tag) => areCompletionsEquivalent(
-                elementNameFromRelevanceTag(tag.tag), entry.key))
-            .toList();
-      } else {
-        includedSuggestions = [];
-      }
-      if (allowModelOnlySuggestions && entry.value > _MODEL_RELEVANCE_CUTOFF) {
-        final relevance = high--;
-        if (completionSuggestions.isNotEmpty ||
-            includedSuggestions.isNotEmpty) {
-          completionSuggestions.forEach((completionSuggestion) {
-            completionSuggestion.relevance = relevance;
-          });
-          includedSuggestions.forEach((includedSuggestion) {
-            includedSuggestion.relevanceBoost = relevance;
-          });
-        } else if (isIncludedElementName) {
-          if (includedSuggestionRelevanceTags != null) {
-            includedSuggestionRelevanceTags
-                .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
-          }
-        } else {
-          suggestions
-              .add(createCompletionSuggestion(entry.key, featureSet, high--));
-        }
-      } else if (completionSuggestions.isNotEmpty ||
-          includedSuggestions.isNotEmpty ||
-          isIncludedElementName) {
-        final relevance = middle--;
-        completionSuggestions.forEach((completionSuggestion) {
-          completionSuggestion.relevance = relevance;
-        });
-        if (includedSuggestions.isNotEmpty) {
-          includedSuggestions.forEach((includedSuggestion) {
-            includedSuggestion.relevanceBoost = relevance;
-          });
-        } else if (includedSuggestionRelevanceTags != null) {
-          includedSuggestionRelevanceTags
-              .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
-        }
-      } else if (allowModelOnlySuggestions) {
-        final relevance = low--;
-        suggestions
-            .add(createCompletionSuggestion(entry.key, featureSet, relevance));
-        if (includedSuggestionRelevanceTags != null) {
-          includedSuggestionRelevanceTags
-              .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
-        }
-      }
-    }
-    return suggestions;
-  }
-
-  /// Spin up the model isolates and load the tflite model.
-  Future<void> start() async {
-    _writes = [];
-    _index = 0;
-    final initializations = <Future<void>>[];
-
-    // Start the first isolate.
-    await _startIsolate();
-
-    // Start the 2nd and later isolates.
-    for (var i = 1; i < _ISOLATE_COUNT; i++) {
-      initializations.add(_startIsolate());
-    }
-
-    return Future.wait(initializations);
-  }
-
-  Future<void> _startIsolate() async {
-    var timer = Stopwatch()..start();
-    var port = ReceivePort();
-    await Isolate.spawn(entrypoint, port.sendPort);
-    SendPort sendPort = await port.first;
-    return makeLoadRequest(sendPort, [_directory]).whenComplete(() {
-      timer.stop();
-      performanceMetrics._isolateInitTimes.add(timer.elapsed);
-      _writes.add(sendPort);
-    });
-  }
-}
-
-class PerformanceMetrics {
-  static const int _maxResultBuffer = 50;
-
-  final Queue<PredictionResult> _predictionResults = Queue();
-  int _predictionRequestCount = 0;
-  final List<Duration> _isolateInitTimes = [];
-
-  PerformanceMetrics._();
-
-  List<Duration> get isolateInitTimes => _isolateInitTimes;
-
-  /// The total prediction requests to ML Complete.
-  int get predictionRequestCount => _predictionRequestCount;
-
-  /// An iterable of the last `n` prediction results;
-  Iterable<PredictionResult> get predictionResults => _predictionResults;
-
-  void _addPredictionResult(PredictionResult request) {
-    _predictionResults.addFirst(request);
-    if (_predictionResults.length > _maxResultBuffer) {
-      _predictionResults.removeLast();
-    }
-  }
-
-  void _incrementPredictionRequestCount() {
-    _predictionRequestCount++;
-  }
-}
-
-class PredictionResult {
-  final Map<String, double> results;
-  final Duration elapsedTime;
-  final String sourcePath;
-  final String snippet;
-
-  PredictionResult(
-      this.results, this.elapsedTime, this.sourcePath, this.snippet);
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
index 6779aa9..512f787 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -48,12 +48,9 @@
             var types = <InterfaceType>[];
             ClassElementImpl.collectAllSupertypes(types, extendedType, null);
             for (var type in types) {
-              double inheritanceDistance;
-              if (request.useNewRelevance) {
-                inheritanceDistance = memberBuilder.request.featureComputer
-                    .inheritanceDistanceFeature(
-                        extendedType.element, type.element);
-              }
+              var inheritanceDistance = memberBuilder.request.featureComputer
+                  .inheritanceDistanceFeature(
+                      extendedType.element, type.element);
               _addTypeMembers(type, inheritanceDistance);
             }
           }
@@ -102,13 +99,11 @@
           _resolveExtendedType(containingLibrary, extension, type);
       if (extendedType != null && typeSystem.isSubtypeOf(type, extendedType)) {
         double inheritanceDistance;
-        if (memberBuilder.request.useNewRelevance) {
-          if (type is InterfaceType && extendedType is InterfaceType) {
-            inheritanceDistance = memberBuilder.request.featureComputer
-                .inheritanceDistanceFeature(type.element, extendedType.element);
-          } else {
-            inheritanceDistance = -1;
-          }
+        if (type is InterfaceType && extendedType is InterfaceType) {
+          inheritanceDistance = memberBuilder.request.featureComputer
+              .inheritanceDistanceFeature(type.element, extendedType.element);
+        } else {
+          inheritanceDistance = -1;
         }
         // TODO(brianwilkerson) We might want to apply the substitution to the
         //  members of the extension for display purposes.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 3d8234d..4963edb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -47,16 +47,8 @@
 
   _KeywordVisitor(this.request, this.builder) : entity = request.target.entity;
 
-  int get defaultKeyword =>
-      request.useNewRelevance ? 800 : DART_RELEVANCE_KEYWORD;
-
   Token get droppedToken => request.target.droppedToken;
 
-  int get highKeyword => request.useNewRelevance ? 1000 : DART_RELEVANCE_HIGH;
-
-  int get lowKeyword =>
-      request.useNewRelevance ? 400 : DART_RELEVANCE_KEYWORD - 1;
-
   @override
   void visitArgumentList(ArgumentList node) {
     if (request is DartCompletionRequestImpl) {
@@ -97,9 +89,9 @@
   void visitAsExpression(AsExpression node) {
     if (identical(entity, node.asOperator) &&
         node.expression is ParenthesizedExpression) {
-      _addSuggestion(Keyword.ASYNC, relevance: highKeyword);
-      _addSuggestion2(ASYNC_STAR, relevance: highKeyword);
-      _addSuggestion2(SYNC_STAR, relevance: highKeyword);
+      _addSuggestion(Keyword.ASYNC);
+      _addSuggestion2(ASYNC_STAR);
+      _addSuggestion2(SYNC_STAR);
     }
   }
 
@@ -142,7 +134,7 @@
     }
     _addStatementKeywords(node);
     if (node.inCatchClause) {
-      _addSuggestion(Keyword.RETHROW, relevance: lowKeyword);
+      _addSuggestion(Keyword.RETHROW);
     }
   }
 
@@ -216,19 +208,19 @@
     if (previousMember == null || previousMember is Directive) {
       if (previousMember == null &&
           !node.directives.any((d) => d is LibraryDirective)) {
-        _addSuggestions([Keyword.LIBRARY], relevance: highKeyword);
+        _addSuggestions([Keyword.LIBRARY]);
       }
-      _addSuggestion2(IMPORT_STATEMENT, offset: 8, relevance: highKeyword);
-      _addSuggestion2(EXPORT_STATEMENT, offset: 8, relevance: highKeyword);
-      _addSuggestion2(PART_STATEMENT, offset: 6, relevance: highKeyword);
+      _addSuggestion2(IMPORT_STATEMENT, offset: 8);
+      _addSuggestion2(EXPORT_STATEMENT, offset: 8);
+      _addSuggestion2(PART_STATEMENT, offset: 6);
     }
     if (entity == null || entity is Declaration) {
       if (previousMember is FunctionDeclaration &&
           previousMember.functionExpression is FunctionExpression &&
           previousMember.functionExpression.body.isEmpty) {
-        _addSuggestion(Keyword.ASYNC, relevance: highKeyword);
-        _addSuggestion2(ASYNC_STAR, relevance: highKeyword);
-        _addSuggestion2(SYNC_STAR, relevance: highKeyword);
+        _addSuggestion(Keyword.ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
       }
       _addCompilationUnitKeywords();
     }
@@ -340,7 +332,7 @@
         _addSuggestions(
             [Keyword.CONST, Keyword.FALSE, Keyword.NULL, Keyword.TRUE]);
       } else {
-        _addSuggestion(Keyword.IN, relevance: highKeyword);
+        _addSuggestion(Keyword.IN);
       }
     }
   }
@@ -396,7 +388,7 @@
         node is ForPartsWithDeclarations &&
         node.variables != null) {
       if (_isPreviousTokenSynthetic(entity, TokenType.SEMICOLON)) {
-        _addSuggestion(Keyword.IN, relevance: highKeyword);
+        _addSuggestion(Keyword.IN);
       }
     }
   }
@@ -406,7 +398,7 @@
     // Actual: for (va^)
     // Parsed: for (va^; ;)
     if (node.forLoopParts == entity) {
-      _addSuggestion(Keyword.VAR, relevance: highKeyword);
+      _addSuggestion(Keyword.VAR);
     }
   }
 
@@ -425,10 +417,10 @@
     if (entity == node.body) {
       var body = node.body;
       if (!body.isAsynchronous) {
-        _addSuggestion(Keyword.ASYNC, relevance: highKeyword);
+        _addSuggestion(Keyword.ASYNC);
         if (body is! ExpressionFunctionBody) {
-          _addSuggestion2(ASYNC_STAR, relevance: highKeyword);
-          _addSuggestion2(SYNC_STAR, relevance: highKeyword);
+          _addSuggestion2(ASYNC_STAR);
+          _addSuggestion2(SYNC_STAR);
         }
       }
       if (body is EmptyFunctionBody &&
@@ -452,14 +444,14 @@
       // analyzer parser
       // Actual: if (x i^)
       // Parsed: if (x) i^
-      _addSuggestion(Keyword.IS, relevance: highKeyword);
+      _addSuggestion(Keyword.IS);
     } else if (entity == node.rightParenthesis) {
       if (node.condition.endToken.next == droppedToken) {
         // fasta parser
         // Actual: if (x i^)
         // Parsed: if (x)
         //    where "i" is in the token stream but not part of the AST
-        _addSuggestion(Keyword.IS, relevance: highKeyword);
+        _addSuggestion(Keyword.IS);
       }
     } else if (entity == node.thenStatement || entity == node.elseStatement) {
       _addStatementKeywords(node);
@@ -472,7 +464,7 @@
   void visitImportDirective(ImportDirective node) {
     if (entity == node.asKeyword) {
       if (node.deferredKeyword == null) {
-        _addSuggestion(Keyword.DEFERRED, relevance: highKeyword);
+        _addSuggestion(Keyword.DEFERRED);
       }
     }
     // Handle degenerate case where import statement does not have a semicolon
@@ -497,7 +489,7 @@
   @override
   void visitIsExpression(IsExpression node) {
     if (entity == node.isOperator) {
-      _addSuggestion(Keyword.IS, relevance: highKeyword);
+      _addSuggestion(Keyword.IS);
     } else {
       _addExpressionKeywords(node);
     }
@@ -523,10 +515,10 @@
         _addSuggestion2(ASYNC_STAR);
         _addSuggestion2(SYNC_STAR);
       } else {
-        _addSuggestion(Keyword.ASYNC, relevance: highKeyword);
+        _addSuggestion(Keyword.ASYNC);
         if (node.body is! ExpressionFunctionBody) {
-          _addSuggestion2(ASYNC_STAR, relevance: highKeyword);
-          _addSuggestion2(SYNC_STAR, relevance: highKeyword);
+          _addSuggestion2(ASYNC_STAR);
+          _addSuggestion2(SYNC_STAR);
         }
       }
     } else if (entity == node.returnType || entity == node.name) {
@@ -596,7 +588,7 @@
         if (next == entity || next == droppedToken) {
           // Fasta parses `if (x i^)` as `if (x ^) where the `i` is in the token
           // stream but not part of the ParenthesizedExpression.
-          _addSuggestion(Keyword.IS, relevance: highKeyword);
+          _addSuggestion(Keyword.IS);
           return;
         }
       }
@@ -655,8 +647,8 @@
       _addExpressionKeywords(node);
     } else if (entity == node.rightBracket) {
       if (node.members.isEmpty) {
-        _addSuggestion(Keyword.CASE, relevance: highKeyword);
-        _addSuggestion2(DEFAULT_COLON, relevance: highKeyword);
+        _addSuggestion(Keyword.CASE);
+        _addSuggestion2(DEFAULT_COLON);
       } else {
         _addSuggestion(Keyword.CASE);
         _addSuggestion2(DEFAULT_COLON);
@@ -665,8 +657,8 @@
     }
     if (node.members.contains(entity)) {
       if (entity == node.members.first) {
-        _addSuggestion(Keyword.CASE, relevance: highKeyword);
-        _addSuggestion2(DEFAULT_COLON, relevance: highKeyword);
+        _addSuggestion(Keyword.CASE);
+        _addSuggestion2(DEFAULT_COLON);
       } else {
         _addSuggestion(Keyword.CASE);
         _addSuggestion2(DEFAULT_COLON);
@@ -746,12 +738,12 @@
     // Very simplistic suggestion because analyzer will warn if
     // the extends / with / implements keywords are out of order
     if (node.extendsClause == null) {
-      _addSuggestion(Keyword.EXTENDS, relevance: highKeyword);
+      _addSuggestion(Keyword.EXTENDS);
     } else if (node.withClause == null) {
-      _addSuggestion(Keyword.WITH, relevance: highKeyword);
+      _addSuggestion(Keyword.WITH);
     }
     if (node.implementsClause == null) {
-      _addSuggestion(Keyword.IMPLEMENTS, relevance: highKeyword);
+      _addSuggestion(Keyword.IMPLEMENTS);
     }
   }
 
@@ -775,12 +767,12 @@
       Keyword.TYPEDEF,
       Keyword.VAR,
       Keyword.VOID
-    ], relevance: highKeyword);
+    ]);
     if (request.featureSet.isEnabled(Feature.extension_methods)) {
-      _addSuggestion(Keyword.EXTENSION, relevance: highKeyword);
+      _addSuggestion(Keyword.EXTENSION);
     }
     if (request.featureSet.isEnabled(Feature.non_nullable)) {
-      _addSuggestion(Keyword.LATE, relevance: highKeyword);
+      _addSuggestion(Keyword.LATE);
     }
   }
 
@@ -820,7 +812,7 @@
 
   void _addExtensionDeclarationKeywords(ExtensionDeclaration node) {
     if (node.onKeyword == null || node.onKeyword.isSynthetic) {
-      _addSuggestion(Keyword.ON, relevance: highKeyword);
+      _addSuggestion(Keyword.ON);
     }
   }
 
@@ -828,19 +820,19 @@
     var hasDeferredKeyword = node.deferredKeyword != null;
     var hasAsKeyword = node.asKeyword != null;
     if (!hasAsKeyword) {
-      _addSuggestion(Keyword.AS, relevance: highKeyword);
+      _addSuggestion(Keyword.AS);
     }
     if (!hasDeferredKeyword) {
       if (!hasAsKeyword) {
-        _addSuggestion2(DEFERRED_AS, relevance: highKeyword);
+        _addSuggestion2(DEFERRED_AS);
       } else if (entity == node.asKeyword) {
-        _addSuggestion(Keyword.DEFERRED, relevance: highKeyword);
+        _addSuggestion(Keyword.DEFERRED);
       }
     }
     if (!hasDeferredKeyword || hasAsKeyword) {
       if (node.combinators.isEmpty) {
-        _addSuggestion(Keyword.SHOW, relevance: highKeyword);
-        _addSuggestion(Keyword.HIDE, relevance: highKeyword);
+        _addSuggestion(Keyword.SHOW);
+        _addSuggestion(Keyword.HIDE);
       }
     }
   }
@@ -849,10 +841,10 @@
     // Very simplistic suggestion because analyzer will warn if
     // the on / implements clauses are out of order
     if (node.onClause == null) {
-      _addSuggestion(Keyword.ON, relevance: highKeyword);
+      _addSuggestion(Keyword.ON);
     }
     if (node.implementsClause == null) {
-      _addSuggestion(Keyword.IMPLEMENTS, relevance: highKeyword);
+      _addSuggestion(Keyword.IMPLEMENTS);
     }
   }
 
@@ -897,18 +889,17 @@
     }
   }
 
-  void _addSuggestion(Keyword keyword, {int relevance}) {
-    _addSuggestion2(keyword.lexeme, relevance: relevance);
+  void _addSuggestion(Keyword keyword) {
+    _addSuggestion2(keyword.lexeme);
   }
 
-  void _addSuggestion2(String keyword, {int offset, int relevance}) {
-    builder.suggestKeyword(keyword,
-        offset: offset, relevance: relevance ?? defaultKeyword);
+  void _addSuggestion2(String keyword, {int offset}) {
+    builder.suggestKeyword(keyword, offset: offset);
   }
 
-  void _addSuggestions(List<Keyword> keywords, {int relevance}) {
+  void _addSuggestions(List<Keyword> keywords) {
     keywords.forEach((Keyword keyword) {
-      _addSuggestion(keyword, relevance: relevance);
+      _addSuggestion(keyword);
     });
   }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
deleted file mode 100644
index 8a2e044..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:path/path.dart' as path;
-import 'package:tflite_native/tflite.dart' as tfl;
-
-/// Interface to TensorFlow-based Dart language model for next-token prediction.
-class LanguageModel {
-  static const _probabilityThreshold = 0.0001;
-  static final _numeric = RegExp(r'^\d+(\.\d+)?$');
-  static final _alphanumeric = RegExp(r"^['\w]+$");
-  static final _doubleQuote = '"'.codeUnitAt(0);
-
-  final tfl.Interpreter _interpreter;
-  final Map<String, int> _word2idx;
-  final Map<int, String> _idx2word;
-  final int _lookback;
-
-  /// Load model from directory.
-  factory LanguageModel.load(String directory) {
-    // Load model.
-    final interpreter =
-        tfl.Interpreter.fromFile(path.join(directory, 'model.tflite'));
-    interpreter.allocateTensors();
-
-    // Load word2idx mapping for input.
-    final word2idx = json
-        .decode(File(path.join(directory, 'word2idx.json')).readAsStringSync())
-        .cast<String, int>();
-
-    // Load idx2word mapping for output.
-    final idx2word = json
-        .decode(File(path.join(directory, 'idx2word.json')).readAsStringSync())
-        .map<int, String>((k, v) => MapEntry<int, String>(int.parse(k), v));
-
-    // Get lookback size from model input tensor shape.
-    final tensorShape = interpreter.getInputTensors().single.shape;
-    if (tensorShape.length != 2 || tensorShape.first != 1) {
-      throw ArgumentError(
-          'tensor shape $tensorShape does not match the expected [1, X]');
-    }
-    final lookback = tensorShape.last;
-
-    return LanguageModel._(interpreter, word2idx, idx2word, lookback);
-  }
-
-  LanguageModel._(
-      this._interpreter, this._word2idx, this._idx2word, this._lookback);
-
-  /// Number of previous tokens to look at during predictions.
-  int get lookback => _lookback;
-
-  /// Tear down the interpreter.
-  void close() {
-    _interpreter.delete();
-  }
-
-  bool isNumber(String token) {
-    return _numeric.hasMatch(token) || token.startsWith('0x');
-  }
-
-  /// Predicts the next token to follow a list of precedent tokens
-  ///
-  /// Returns a list of tokens, sorted by most probable first.
-  List<String> predict(List<String> tokens) =>
-      predictWithScores(tokens).keys.toList();
-
-  /// Predicts the next token with confidence scores.
-  ///
-  /// Returns an ordered map of tokens to scores, sorted by most probable first.
-  Map<String, double> predictWithScores(List<String> tokens) {
-    final tensorIn = _interpreter.getInputTensors().single;
-    tensorIn.data = _transformInput(tokens);
-    _interpreter.invoke();
-    final tensorOut = _interpreter.getOutputTensors().single;
-    return _transformOutput(tensorOut.data, tokens);
-  }
-
-  bool _isAlphanumeric(String token) {
-    // Note that _numeric covers integral and decimal values whereas
-    // _alphanumeric only matches integral values. Check both.
-    return _alphanumeric.hasMatch(token) || _numeric.hasMatch(token);
-  }
-
-  bool _isString(String token) {
-    return token.contains('"') || token.contains("'");
-  }
-
-  /// Transforms tokens to data bytes that can be used as interpreter input.
-  List<int> _transformInput(List<String> tokens) {
-    // Replace out of vocabulary tokens.
-    final sanitizedTokens = tokens.map((token) {
-      if (_word2idx.containsKey(token)) {
-        return token;
-      }
-      if (isNumber(token)) {
-        return '<num>';
-      }
-      if (_isString(token)) {
-        return '<str>';
-      }
-      return '<unk>';
-    });
-    // Get indexes (as floats).
-    final indexes = Float32List(lookback)
-      ..setAll(0, sanitizedTokens.map((token) => _word2idx[token].toDouble()));
-    // Get bytes
-    return Uint8List.view(indexes.buffer);
-  }
-
-  /// Transforms interpreter output data to map of tokens to scores.
-  Map<String, double> _transformOutput(
-      List<int> databytes, List<String> tokens) {
-    // Get bytes.
-    final bytes = Uint8List.fromList(databytes);
-
-    // Get scores (as floats)
-    final probabilities = Float32List.view(bytes.buffer);
-
-    final scores = <String, double>{};
-    final scoresAboveThreshold = <String, double>{};
-    probabilities.asMap().forEach((k, v) {
-      // x in 0, 1, ..., |V| - 1 correspond to specific members of the vocabulary.
-      // x in |V|, |V| + 1, ..., |V| + 49 are pointers to reference positions along the
-      // network input.
-      if (k >= _idx2word.length + tokens.length) {
-        return;
-      }
-      // Find the name corresponding to this position along the network output.
-      final lexeme =
-          k < _idx2word.length ? _idx2word[k] : tokens[k - _idx2word.length];
-      // Normalize double to single quotes.
-      final sanitized = lexeme.codeUnitAt(0) != _doubleQuote
-          ? lexeme
-          : lexeme.replaceAll('"', '\'');
-      final score = (scores[sanitized] ?? 0.0) + v;
-      scores[sanitized] = score;
-      if (score < _probabilityThreshold ||
-          k >= _idx2word.length && !_isAlphanumeric(sanitized)) {
-        // Discard names below a fixed likelihood, and
-        // don't assign probability to punctuation by reference.
-        return;
-      }
-      scoresAboveThreshold[sanitized] = score;
-    });
-
-    return Map.fromEntries(scoresAboveThreshold.entries.toList()
-      ..sort((a, b) => b.value.compareTo(a.value)));
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 33d22cf..4b1b121 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -110,9 +110,8 @@
   @override
   void visitPropertyAccessorElement(PropertyAccessorElement element) {
     if (opType.includeReturnValueSuggestions) {
-      if (element.enclosingElement is ClassElement) {
-        // TODO(brianwilkerson) Verify that we cannot reach this point and
-        //  remove the dead code.
+      var parent = element.enclosingElement;
+      if (parent is ClassElement || parent is ExtensionElement) {
         builder.suggestAccessor(element, inheritanceDistance: -1.0);
       } else {
         builder.suggestTopLevelPropertyAccessor(element, prefix: prefix);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index f638e9a..4c87bce 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -6,11 +6,9 @@
     show CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/utilities/strings.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart'
@@ -144,11 +142,8 @@
         ? CompletionSuggestionKind.IDENTIFIER
         : CompletionSuggestionKind.INVOCATION;
     for (var type in classElement.allSupertypes) {
-      double inheritanceDistance;
-      if (request.useNewRelevance) {
-        inheritanceDistance = request.featureComputer
-            .inheritanceDistanceFeature(classElement, type.element);
-      }
+      var inheritanceDistance = request.featureComputer
+          .inheritanceDistanceFeature(classElement, type.element);
       _addSuggestionsForType(type, request, inheritanceDistance,
           isFunctionalArgument: isFunctionalArgument);
     }
@@ -188,10 +183,6 @@
   /// The op type associated with the request.
   final OpType opType;
 
-  /// A flag indicating whether the suggestions should use the new relevance
-  /// scores.
-  final bool useNewRelevance;
-
   /// A flag indicating whether the target of the request is a function-valued
   /// argument in an argument list.
   final bool targetIsFunctionalArgument;
@@ -203,46 +194,14 @@
   /// clause.
   bool inExtendsClause = false;
 
-  /// Only used when [useNewRelevance] is `false`.
-  int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
-
   _VisibilityTracker visibilityTracker;
 
   _LocalVisitor(this.request, this.builder, this.visibilityTracker,
       {@required this.suggestLocalFields})
       : assert(visibilityTracker != null),
         opType = request.opType,
-        useNewRelevance = request.useNewRelevance,
         targetIsFunctionalArgument = request.target.isFunctionalArgument(),
-        super(request.offset) {
-    // Suggestions for inherited members are provided by
-    // InheritedReferenceContributor.
-    if (!useNewRelevance) {
-      // If the user typed an identifier starting with '_' then do not suppress
-      // the relevance of private members.
-      var data = request.result != null
-          ? request.result.content
-          : request.sourceContents;
-      var offset = request.offset;
-      if (data != null && 0 < offset && offset <= data.length) {
-        bool isIdentifierChar(int index) {
-          var code = data.codeUnitAt(index);
-          return isLetterOrDigit(code) || code == CHAR_UNDERSCORE;
-        }
-
-        if (isIdentifierChar(offset - 1)) {
-          while (offset > 0 && isIdentifierChar(offset - 1)) {
-            --offset;
-          }
-          if (data.codeUnitAt(offset) == CHAR_UNDERSCORE) {
-            privateMemberRelevance = null;
-          }
-        }
-      }
-    }
-  }
-
-  TypeProvider get typeProvider => request.libraryElement.typeProvider;
+        super(request.offset);
 
   CompletionSuggestionKind get _defaultKind => targetIsFunctionalArgument
       ? CompletionSuggestionKind.IDENTIFIER
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index ae57075..127d348 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -217,47 +217,33 @@
       }
     } else {
       var type = _getPropertyAccessorType(accessor);
-      int relevance;
-      if (request.useNewRelevance) {
-        var featureComputer = request.featureComputer;
-        var contextType =
-            featureComputer.contextTypeFeature(request.contextType, type);
-        var elementKind = _computeElementKind(accessor);
-        var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
-        var isConstant = request.inConstantContext
-            ? featureComputer.isConstantFeature(accessor)
-            : -1.0;
-        var startsWithDollar =
-            featureComputer.startsWithDollarFeature(accessor.name);
-        var superMatches = featureComputer.superMatchesFeature(
-            _containingMemberName, accessor.name);
-        relevance = _computeMemberRelevance(
-            contextType: contextType,
-            elementKind: elementKind,
-            hasDeprecated: hasDeprecated,
-            inheritanceDistance: inheritanceDistance,
-            isConstant: isConstant,
-            startsWithDollar: startsWithDollar,
-            superMatches: superMatches);
-        listener?.computedFeatures(
-            contextType: contextType,
-            elementKind: elementKind,
-            hasDeprecated: hasDeprecated,
-            inheritanceDistance: inheritanceDistance,
-            startsWithDollar: startsWithDollar,
-            superMatches: superMatches);
-      } else {
-        relevance = accessor.hasOrInheritsDeprecated
-            ? DART_RELEVANCE_LOW
-            : _computeOldMemberRelevance(accessor);
-        if (request.opType.includeReturnValueSuggestions) {
-          relevance =
-              request.opType.returnValueSuggestionsFilter(type, relevance);
-        }
-        if (relevance == null) {
-          return;
-        }
-      }
+      var featureComputer = request.featureComputer;
+      var contextType =
+          featureComputer.contextTypeFeature(request.contextType, type);
+      var elementKind = _computeElementKind(accessor);
+      var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+      var isConstant = request.inConstantContext
+          ? featureComputer.isConstantFeature(accessor)
+          : -1.0;
+      var startsWithDollar =
+          featureComputer.startsWithDollarFeature(accessor.name);
+      var superMatches = featureComputer.superMatchesFeature(
+          _containingMemberName, accessor.name);
+      var relevance = _computeMemberRelevance(
+          contextType: contextType,
+          elementKind: elementKind,
+          hasDeprecated: hasDeprecated,
+          inheritanceDistance: inheritanceDistance,
+          isConstant: isConstant,
+          startsWithDollar: startsWithDollar,
+          superMatches: superMatches);
+      listener?.computedFeatures(
+          contextType: contextType,
+          elementKind: elementKind,
+          hasDeprecated: hasDeprecated,
+          inheritanceDistance: inheritanceDistance,
+          startsWithDollar: startsWithDollar,
+          superMatches: superMatches);
       _add(_createSuggestion(accessor, relevance: relevance));
     }
   }
@@ -265,28 +251,17 @@
   /// Add a suggestion for a catch [parameter].
   void suggestCatchParameter(LocalVariableElement parameter) {
     var variableType = parameter.type;
-    int relevance;
-    if (request.useNewRelevance) {
-      var contextType = request.featureComputer
-          .contextTypeFeature(request.contextType, variableType);
-      var elementKind = _computeElementKind(parameter);
-      var isConstant = request.inConstantContext
-          ? request.featureComputer.isConstantFeature(parameter)
-          : -1.0;
-      relevance = toRelevance(
-          weightedAverage(
-              [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
-          800);
-      listener?.computedFeatures(contextType: contextType);
-    } else {
-      relevance = _computeOldMemberRelevance(parameter);
-      relevance =
-          request.opType.returnValueSuggestionsFilter(variableType, relevance);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var contextType = request.featureComputer
+        .contextTypeFeature(request.contextType, variableType);
+    var elementKind = _computeElementKind(parameter);
+    var isConstant = request.inConstantContext
+        ? request.featureComputer.isConstantFeature(parameter)
+        : -1.0;
+    var relevance = toRelevance(
+        weightedAverage(
+            [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
+        800);
+    listener?.computedFeatures(contextType: contextType);
     _add(_createSuggestion(parameter,
         elementKind: protocol.ElementKind.PARAMETER, relevance: relevance));
   }
@@ -297,20 +272,8 @@
   void suggestClass(ClassElement classElement,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       String prefix}) {
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance = _computeTopLevelRelevance(classElement,
-          elementType: _instantiateClassElement(classElement));
-    } else if (classElement.hasOrInheritsDeprecated) {
-      relevance = DART_RELEVANCE_LOW;
-    } else {
-      relevance = request.opType.typeNameSuggestionsFilter(
-          _instantiateClassElement(classElement), DART_RELEVANCE_DEFAULT);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var relevance = _computeTopLevelRelevance(classElement,
+        elementType: _instantiateClassElement(classElement));
     _add(_createSuggestion(classElement,
         kind: kind, prefix: prefix, relevance: relevance));
   }
@@ -345,7 +308,7 @@
     }) {
       return CompletionSuggestion(
         CompletionSuggestionKind.INVOCATION,
-        request.useNewRelevance ? Relevance.closure : DART_RELEVANCE_HIGH,
+        Relevance.closure,
         completion,
         selectionOffset,
         0,
@@ -398,22 +361,9 @@
       return null;
     }
 
-    int relevance;
     var returnType = _instantiateClassElement(enclosingClass);
-    if (request.useNewRelevance) {
-      relevance =
-          _computeTopLevelRelevance(constructor, elementType: returnType);
-    } else {
-      relevance = constructor.hasOrInheritsDeprecated
-          ? DART_RELEVANCE_LOW
-          : DART_RELEVANCE_DEFAULT;
-      relevance =
-          request.opType.returnValueSuggestionsFilter(returnType, relevance);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var relevance =
+        _computeTopLevelRelevance(constructor, elementType: returnType);
     _add(_createSuggestion(constructor,
         completion: completion,
         kind: kind,
@@ -451,21 +401,8 @@
     var enumElement = constant.enclosingElement;
     var enumName = enumElement.name;
     var completion = '$enumName.$constantName';
-
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance =
-          _computeTopLevelRelevance(constant, elementType: constant.type);
-    } else if (constant.hasOrInheritsDeprecated) {
-      relevance = DART_RELEVANCE_LOW;
-    } else {
-      relevance = request.opType.returnValueSuggestionsFilter(
-          _instantiateClassElement(enumElement), DART_RELEVANCE_DEFAULT);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var relevance =
+        _computeTopLevelRelevance(constant, elementType: constant.type);
     _add(_createSuggestion(constant,
         completion: completion, prefix: prefix, relevance: relevance));
   }
@@ -476,16 +413,8 @@
   void suggestExtension(ExtensionElement extension,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       String prefix}) {
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance = _computeTopLevelRelevance(extension,
-          elementType: extension.extendedType);
-    } else {
-      relevance = extension.hasOrInheritsDeprecated
-          ? DART_RELEVANCE_LOW
-          : DART_RELEVANCE_DEFAULT;
-    }
-
+    var relevance = _computeTopLevelRelevance(extension,
+        elementType: extension.extendedType);
     _add(_createSuggestion(extension,
         kind: kind, prefix: prefix, relevance: relevance));
   }
@@ -497,45 +426,32 @@
   /// `-1.0` if the field is a static field).
   void suggestField(FieldElement field,
       {@required double inheritanceDistance}) {
-    int relevance;
-    if (request.useNewRelevance) {
-      var featureComputer = request.featureComputer;
-      var contextType =
-          featureComputer.contextTypeFeature(request.contextType, field.type);
-      var elementKind = _computeElementKind(field);
-      var hasDeprecated = featureComputer.hasDeprecatedFeature(field);
-      var isConstant = request.inConstantContext
-          ? featureComputer.isConstantFeature(field)
-          : -1.0;
-      var startsWithDollar =
-          featureComputer.startsWithDollarFeature(field.name);
-      var superMatches = featureComputer.superMatchesFeature(
-          _containingMemberName, field.name);
-      relevance = _computeMemberRelevance(
-          contextType: contextType,
-          elementKind: elementKind,
-          hasDeprecated: hasDeprecated,
-          inheritanceDistance: inheritanceDistance,
-          isConstant: isConstant,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
-      listener?.computedFeatures(
-          contextType: contextType,
-          elementKind: elementKind,
-          hasDeprecated: hasDeprecated,
-          inheritanceDistance: inheritanceDistance,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
-    } else {
-      relevance = _computeOldMemberRelevance(field);
-      if (request.opType.includeReturnValueSuggestions) {
-        relevance =
-            request.opType.returnValueSuggestionsFilter(field.type, relevance);
-      }
-      if (relevance == null) {
-        return;
-      }
-    }
+    var featureComputer = request.featureComputer;
+    var contextType =
+        featureComputer.contextTypeFeature(request.contextType, field.type);
+    var elementKind = _computeElementKind(field);
+    var hasDeprecated = featureComputer.hasDeprecatedFeature(field);
+    var isConstant = request.inConstantContext
+        ? featureComputer.isConstantFeature(field)
+        : -1.0;
+    var startsWithDollar = featureComputer.startsWithDollarFeature(field.name);
+    var superMatches =
+        featureComputer.superMatchesFeature(_containingMemberName, field.name);
+    var relevance = _computeMemberRelevance(
+        contextType: contextType,
+        elementKind: elementKind,
+        hasDeprecated: hasDeprecated,
+        inheritanceDistance: inheritanceDistance,
+        isConstant: isConstant,
+        startsWithDollar: startsWithDollar,
+        superMatches: superMatches);
+    listener?.computedFeatures(
+        contextType: contextType,
+        elementKind: elementKind,
+        hasDeprecated: hasDeprecated,
+        inheritanceDistance: inheritanceDistance,
+        startsWithDollar: startsWithDollar,
+        superMatches: superMatches);
     _add(_createSuggestion(field, relevance: relevance));
   }
 
@@ -543,11 +459,7 @@
   void suggestFieldFormalParameter(FieldElement field) {
     // TODO(brianwilkerson) Add a parameter (`bool includePrefix`) indicating
     //  whether to include the `this.` prefix in the completion.
-    var relevance = request.useNewRelevance
-        ? Relevance.fieldFormalParameter
-        : DART_RELEVANCE_LOCAL_FIELD;
-
-    _add(_createSuggestion(field, relevance: relevance));
+    _add(_createSuggestion(field, relevance: Relevance.fieldFormalParameter));
   }
 
   /// Add a suggestion for the `call` method defined on functions.
@@ -561,7 +473,7 @@
         returnType: 'void');
     _add(CompletionSuggestion(
       CompletionSuggestionKind.INVOCATION,
-      request.useNewRelevance ? Relevance.callFunction : DART_RELEVANCE_HIGH,
+      Relevance.callFunction,
       callString,
       callString.length,
       0,
@@ -583,32 +495,21 @@
   void suggestFunctionTypeAlias(FunctionTypeAliasElement functionTypeAlias,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       String prefix}) {
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance = _computeTopLevelRelevance(functionTypeAlias,
-          defaultRelevance: 750,
-          elementType: _instantiateFunctionTypeAlias(functionTypeAlias));
-    } else if (functionTypeAlias.hasOrInheritsDeprecated) {
-      relevance = DART_RELEVANCE_LOW;
-    } else {
-      relevance = functionTypeAlias.library == request.libraryElement
-          ? DART_RELEVANCE_LOCAL_FUNCTION
-          : DART_RELEVANCE_DEFAULT;
-    }
+    var relevance = _computeTopLevelRelevance(functionTypeAlias,
+        defaultRelevance: 750,
+        elementType: _instantiateFunctionTypeAlias(functionTypeAlias));
     _add(_createSuggestion(functionTypeAlias,
         kind: kind, prefix: prefix, relevance: relevance));
   }
 
   /// Add a suggestion for a [keyword]. The [offset] is the offset from the
   /// beginning of the keyword where the cursor will be left.
-  void suggestKeyword(String keyword, {int offset, @required int relevance}) {
-    if (request.useNewRelevance) {
-      // TODO(brianwilkerson) The default value should probably be a constant.
-      relevance = toRelevance(
-          request.featureComputer
-              .keywordFeature(keyword, request.opType.completionLocation),
-          800);
-    }
+  void suggestKeyword(String keyword, {int offset}) {
+    // TODO(brianwilkerson) The default value should probably be a constant.
+    var relevance = toRelevance(
+        request.featureComputer
+            .keywordFeature(keyword, request.opType.completionLocation),
+        800);
     _add(CompletionSuggestion(CompletionSuggestionKind.KEYWORD, relevance,
         keyword, offset ?? keyword.length, 0, false, false));
   }
@@ -619,14 +520,8 @@
     // TODO(brianwilkerson) Figure out why we're excluding labels consisting of
     //  a single underscore.
     if (completion != null && completion.isNotEmpty && completion != '_') {
-      var suggestion = CompletionSuggestion(
-          CompletionSuggestionKind.IDENTIFIER,
-          request.useNewRelevance ? Relevance.label : DART_RELEVANCE_DEFAULT,
-          completion,
-          completion.length,
-          0,
-          false,
-          false);
+      var suggestion = CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER,
+          Relevance.label, completion, completion.length, 0, false, false);
       suggestion.element = createLocalElement(
           request.source, protocol.ElementKind.LABEL, label.label,
           returnType: NO_RETURN_TYPE);
@@ -637,49 +532,29 @@
   /// Add a suggestion for the `loadLibrary` [function] associated with a
   /// prefix.
   void suggestLoadLibraryFunction(FunctionElement function) {
-    int relevance;
-    if (request.useNewRelevance) {
-      // TODO(brianwilkerson) This might want to use the context type rather
-      //  than a fixed value.
-      relevance = Relevance.loadLibrary;
-    } else {
-      relevance = function.hasOrInheritsDeprecated
-          ? DART_RELEVANCE_LOW
-          : DART_RELEVANCE_DEFAULT;
-    }
-
+    // TODO(brianwilkerson) This might want to use the context type rather than
+    //  a fixed value.
+    var relevance = Relevance.loadLibrary;
     _add(_createSuggestion(function, relevance: relevance));
   }
 
   /// Add a suggestion for a local [variable].
   void suggestLocalVariable(LocalVariableElement variable) {
     var variableType = variable.type;
-    int relevance;
-    if (request.useNewRelevance) {
-      var contextType = request.featureComputer
-          .contextTypeFeature(request.contextType, variableType);
-      var elementKind = _computeElementKind(variable);
-      var isConstant = request.inConstantContext
-          ? request.featureComputer.isConstantFeature(variable)
-          : -1.0;
-      var localVariableDistance = request.featureComputer
-          .localVariableDistanceFeature(
-              request.target.containingNode, variable);
-      relevance = toRelevance(
-          weightedAverage(
-              [contextType, elementKind, isConstant, localVariableDistance],
-              [1.0, 1.0, 1.0, 1.0]),
-          800);
-      listener?.computedFeatures(contextType: contextType);
-    } else {
-      relevance = _computeOldMemberRelevance(variable);
-      relevance =
-          request.opType.returnValueSuggestionsFilter(variableType, relevance);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var contextType = request.featureComputer
+        .contextTypeFeature(request.contextType, variableType);
+    var elementKind = _computeElementKind(variable);
+    var isConstant = request.inConstantContext
+        ? request.featureComputer.isConstantFeature(variable)
+        : -1.0;
+    var localVariableDistance = request.featureComputer
+        .localVariableDistanceFeature(request.target.containingNode, variable);
+    var relevance = toRelevance(
+        weightedAverage(
+            [contextType, elementKind, isConstant, localVariableDistance],
+            [1.0, 1.0, 1.0, 1.0]),
+        800);
+    listener?.computedFeatures(contextType: contextType);
     _add(_createSuggestion(variable, relevance: relevance));
   }
 
@@ -693,45 +568,32 @@
     // TODO(brianwilkerson) Refactor callers so that we're passing in the type
     //  of the target (assuming we don't already have that type available via
     //  the [request]) and compute the [inheritanceDistance] in this method.
-    int relevance;
-    if (request.useNewRelevance) {
-      var featureComputer = request.featureComputer;
-      var contextType = featureComputer.contextTypeFeature(
-          request.contextType, method.returnType);
-      var elementKind = _computeElementKind(method);
-      var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
-      var isConstant = request.inConstantContext
-          ? featureComputer.isConstantFeature(method)
-          : -1.0;
-      var startsWithDollar =
-          featureComputer.startsWithDollarFeature(method.name);
-      var superMatches = featureComputer.superMatchesFeature(
-          _containingMemberName, method.name);
-      relevance = _computeMemberRelevance(
-          contextType: contextType,
-          elementKind: elementKind,
-          hasDeprecated: hasDeprecated,
-          inheritanceDistance: inheritanceDistance,
-          isConstant: isConstant,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
-      listener?.computedFeatures(
-          contextType: contextType,
-          elementKind: elementKind,
-          hasDeprecated: hasDeprecated,
-          inheritanceDistance: inheritanceDistance,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
-    } else {
-      relevance = _computeOldMemberRelevance(method);
-      if (request.opType.includeReturnValueSuggestions) {
-        relevance = request.opType
-            .returnValueSuggestionsFilter(method.returnType, relevance);
-      }
-      if (relevance == null) {
-        return;
-      }
-    }
+    var featureComputer = request.featureComputer;
+    var contextType = featureComputer.contextTypeFeature(
+        request.contextType, method.returnType);
+    var elementKind = _computeElementKind(method);
+    var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
+    var isConstant = request.inConstantContext
+        ? featureComputer.isConstantFeature(method)
+        : -1.0;
+    var startsWithDollar = featureComputer.startsWithDollarFeature(method.name);
+    var superMatches =
+        featureComputer.superMatchesFeature(_containingMemberName, method.name);
+    var relevance = _computeMemberRelevance(
+        contextType: contextType,
+        elementKind: elementKind,
+        hasDeprecated: hasDeprecated,
+        inheritanceDistance: inheritanceDistance,
+        isConstant: isConstant,
+        startsWithDollar: startsWithDollar,
+        superMatches: superMatches);
+    listener?.computedFeatures(
+        contextType: contextType,
+        elementKind: elementKind,
+        hasDeprecated: hasDeprecated,
+        inheritanceDistance: inheritanceDistance,
+        startsWithDollar: startsWithDollar,
+        superMatches: superMatches);
 
     var suggestion =
         _createSuggestion(method, kind: kind, relevance: relevance);
@@ -769,14 +631,8 @@
   void suggestName(String name) {
     // TODO(brianwilkerson) Explore whether there are any features of the name
     //  that can be used to provide better relevance scores.
-    _add(CompletionSuggestion(
-        CompletionSuggestionKind.IDENTIFIER,
-        request.useNewRelevance ? 500 : DART_RELEVANCE_DEFAULT,
-        name,
-        name.length,
-        0,
-        false,
-        false));
+    _add(CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER, 500, name,
+        name.length, 0, false, false));
   }
 
   /// Add a suggestion to add a named argument corresponding to the [parameter].
@@ -821,13 +677,9 @@
 
     int relevance;
     if (parameter.isRequiredNamed || parameter.hasRequired) {
-      relevance = request.useNewRelevance
-          ? Relevance.requiredNamedArgument
-          : DART_RELEVANCE_NAMED_PARAMETER_REQUIRED;
+      relevance = Relevance.requiredNamedArgument;
     } else {
-      relevance = request.useNewRelevance
-          ? Relevance.namedArgument
-          : DART_RELEVANCE_NAMED_PARAMETER;
+      relevance = Relevance.namedArgument;
     }
 
     var suggestion = CompletionSuggestion(
@@ -894,7 +746,7 @@
         displayTextBuffer.isNotEmpty ? displayTextBuffer.toString() : null;
     var suggestion = CompletionSuggestion(
         CompletionSuggestionKind.OVERRIDE,
-        request.useNewRelevance ? Relevance.override : DART_RELEVANCE_HIGH,
+        Relevance.override,
         completion,
         selectionRange.offset - offsetDelta,
         selectionRange.length,
@@ -908,47 +760,30 @@
   /// Add a suggestion for a [parameter].
   void suggestParameter(ParameterElement parameter) {
     var variableType = parameter.type;
-    int relevance;
-    if (request.useNewRelevance) {
-      // TODO(brianwilkerson) Use the distance to the declaring function as
-      //  another feature.
-      var contextType = request.featureComputer
-          .contextTypeFeature(request.contextType, variableType);
-      var elementKind = _computeElementKind(parameter);
-      var isConstant = request.inConstantContext
-          ? request.featureComputer.isConstantFeature(parameter)
-          : -1.0;
-      relevance = toRelevance(
-          weightedAverage(
-              [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
-          800);
-      listener?.computedFeatures(contextType: contextType);
-    } else {
-      relevance = _computeOldMemberRelevance(parameter);
-      relevance =
-          request.opType.returnValueSuggestionsFilter(variableType, relevance);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    // TODO(brianwilkerson) Use the distance to the declaring function as
+    //  another feature.
+    var contextType = request.featureComputer
+        .contextTypeFeature(request.contextType, variableType);
+    var elementKind = _computeElementKind(parameter);
+    var isConstant = request.inConstantContext
+        ? request.featureComputer.isConstantFeature(parameter)
+        : -1.0;
+    var relevance = toRelevance(
+        weightedAverage(
+            [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
+        800);
+    listener?.computedFeatures(contextType: contextType);
     _add(_createSuggestion(parameter, relevance: relevance));
   }
 
   /// Add a suggestion for a [prefix] associated with a [library].
   void suggestPrefix(LibraryElement library, String prefix) {
-    int relevance;
-    if (request.useNewRelevance) {
-      var elementKind = _computeElementKind(library);
-      // TODO(brianwilkerson) If we are in a constant context it would be nice
-      //  to promote prefixes for libraries that define constants, but that
-      //  might be more work than it's worth.
-      relevance = toRelevance(elementKind, Relevance.prefix);
-      listener?.computedFeatures(elementKind: elementKind);
-    } else {
-      relevance =
-          library.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
-    }
+    var elementKind = _computeElementKind(library);
+    // TODO(brianwilkerson) If we are in a constant context it would be nice
+    //  to promote prefixes for libraries that define constants, but that
+    //  might be more work than it's worth.
+    var relevance = toRelevance(elementKind, Relevance.prefix);
+    listener?.computedFeatures(elementKind: elementKind);
     _add(_createSuggestion(library,
         completion: prefix,
         kind: CompletionSuggestionKind.IDENTIFIER,
@@ -961,23 +796,8 @@
   void suggestTopLevelFunction(FunctionElement function,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       String prefix}) {
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance =
-          _computeTopLevelRelevance(function, elementType: function.returnType);
-    } else if (function.hasOrInheritsDeprecated) {
-      relevance = DART_RELEVANCE_LOW;
-    } else {
-      relevance = function.library == request.libraryElement
-          ? DART_RELEVANCE_LOCAL_FUNCTION
-          : DART_RELEVANCE_DEFAULT;
-      relevance =
-          request.opType.returnValueSuggestionsFilter(function.type, relevance);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var relevance =
+        _computeTopLevelRelevance(function, elementType: function.returnType);
     _add(_createSuggestion(function,
         kind: kind, prefix: prefix, relevance: relevance));
   }
@@ -989,7 +809,10 @@
   void suggestTopLevelPropertyAccessor(PropertyAccessorElement accessor,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       String prefix}) {
-    assert(accessor.enclosingElement is CompilationUnitElement);
+    assert(
+        accessor.enclosingElement is CompilationUnitElement,
+        'Enclosing element of ${accessor.runtimeType} is '
+        '${accessor.enclosingElement.runtimeType}.');
     if (accessor.isSynthetic) {
       // Avoid visiting a field twice. All fields induce a getter, but only
       // non-final fields induce a setter, so we don't add a suggestion for a
@@ -1002,43 +825,29 @@
       }
     } else {
       var type = _getPropertyAccessorType(accessor);
-      int relevance;
-      if (request.useNewRelevance) {
-        var featureComputer = request.featureComputer;
-        var contextType =
-            featureComputer.contextTypeFeature(request.contextType, type);
-        var elementKind = _computeElementKind(accessor);
-        var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
-        var isConstant = request.inConstantContext
-            ? featureComputer.isConstantFeature(accessor)
-            : -1.0;
-        var startsWithDollar =
-            featureComputer.startsWithDollarFeature(accessor.name);
-        relevance = _computeMemberRelevance(
-            contextType: contextType,
-            elementKind: elementKind,
-            hasDeprecated: hasDeprecated,
-            inheritanceDistance: -1.0,
-            isConstant: isConstant,
-            startsWithDollar: startsWithDollar,
-            superMatches: -1.0);
-        listener?.computedFeatures(
-            contextType: contextType,
-            elementKind: elementKind,
-            hasDeprecated: hasDeprecated,
-            startsWithDollar: startsWithDollar);
-      } else {
-        relevance = accessor.hasOrInheritsDeprecated
-            ? DART_RELEVANCE_LOW
-            : _computeOldMemberRelevance(accessor);
-        if (request.opType.includeReturnValueSuggestions) {
-          relevance =
-              request.opType.returnValueSuggestionsFilter(type, relevance);
-        }
-        if (relevance == null) {
-          return;
-        }
-      }
+      var featureComputer = request.featureComputer;
+      var contextType =
+          featureComputer.contextTypeFeature(request.contextType, type);
+      var elementKind = _computeElementKind(accessor);
+      var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+      var isConstant = request.inConstantContext
+          ? featureComputer.isConstantFeature(accessor)
+          : -1.0;
+      var startsWithDollar =
+          featureComputer.startsWithDollarFeature(accessor.name);
+      var relevance = _computeMemberRelevance(
+          contextType: contextType,
+          elementKind: elementKind,
+          hasDeprecated: hasDeprecated,
+          inheritanceDistance: -1.0,
+          isConstant: isConstant,
+          startsWithDollar: startsWithDollar,
+          superMatches: -1.0);
+      listener?.computedFeatures(
+          contextType: contextType,
+          elementKind: elementKind,
+          hasDeprecated: hasDeprecated,
+          startsWithDollar: startsWithDollar);
       _add(_createSuggestion(accessor, prefix: prefix, relevance: relevance));
     }
   }
@@ -1050,55 +859,30 @@
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       String prefix}) {
     assert(variable.enclosingElement is CompilationUnitElement);
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance =
-          _computeTopLevelRelevance(variable, elementType: variable.type);
-    } else {
-      var type = variable.type;
-      relevance = variable.hasOrInheritsDeprecated
-          ? DART_RELEVANCE_LOW
-          : _computeOldMemberRelevance(variable);
-      relevance = request.opType.returnValueSuggestionsFilter(type, relevance);
-      if (relevance == null) {
-        return;
-      }
-    }
-
+    var relevance =
+        _computeTopLevelRelevance(variable, elementType: variable.type);
     _add(_createSuggestion(variable,
         kind: kind, prefix: prefix, relevance: relevance));
   }
 
   /// Add a suggestion for a type [parameter].
   void suggestTypeParameter(TypeParameterElement parameter) {
-    int relevance;
-    if (request.useNewRelevance) {
-      var elementKind = _computeElementKind(parameter);
-      var isConstant = request.inConstantContext
-          ? request.featureComputer.isConstantFeature(parameter)
-          : -1.0;
-      relevance = toRelevance(
-          weightedAverage([elementKind, isConstant], [1.0, 1.0]),
-          Relevance.typeParameter);
-      listener?.computedFeatures(elementKind: elementKind);
-    } else {
-      relevance = _computeOldMemberRelevance(parameter);
-    }
-
+    var elementKind = _computeElementKind(parameter);
+    var isConstant = request.inConstantContext
+        ? request.featureComputer.isConstantFeature(parameter)
+        : -1.0;
+    var relevance = toRelevance(
+        weightedAverage([elementKind, isConstant], [1.0, 1.0]),
+        Relevance.typeParameter);
+    listener?.computedFeatures(elementKind: elementKind);
     _add(_createSuggestion(parameter,
         kind: CompletionSuggestionKind.IDENTIFIER, relevance: relevance));
   }
 
   /// Add a suggestion to use the [uri] in an import, export, or part directive.
   void suggestUri(String uri) {
-    int relevance;
-    if (request.useNewRelevance) {
-      relevance =
-          uri == 'dart:core' ? Relevance.importDartCore : Relevance.import;
-    } else {
-      relevance =
-          uri == 'dart:core' ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
-    }
+    var relevance =
+        uri == 'dart:core' ? Relevance.importDartCore : Relevance.import;
     _add(CompletionSuggestion(CompletionSuggestionKind.IMPORT, relevance, uri,
         uri.length, 0, false, false));
   }
@@ -1175,46 +959,6 @@
     return toRelevance(score, Relevance.member);
   }
 
-  /// Compute the old relevance score for a member.
-  int _computeOldMemberRelevance(Element member) {
-    if (member.hasOrInheritsDeprecated) {
-      return DART_RELEVANCE_LOW;
-    } else if (member.name == _containingMemberName) {
-      // Boost the relevance of a super expression calling a method of the
-      // same name as the containing method.
-      return DART_RELEVANCE_HIGH;
-    }
-    var identifier = member.displayName;
-    if (identifier != null && identifier.startsWith(r'$')) {
-      // Decrease relevance of suggestions starting with $
-      // https://github.com/dart-lang/sdk/issues/27303
-      return DART_RELEVANCE_LOW;
-    }
-    if (member is LocalVariableElement) {
-      return DART_RELEVANCE_LOCAL_VARIABLE;
-    }
-    if (!member.name.startsWith('_') &&
-        member.library == request.libraryElement) {
-      // Locally declared elements sometimes have a special relevance.
-      if (member is PropertyAccessorElement) {
-        return DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (member is FieldElement) {
-        return DART_RELEVANCE_LOCAL_FIELD;
-      } else if (member is FunctionElement) {
-        return DART_RELEVANCE_LOCAL_FUNCTION;
-      } else if (member is MethodElement) {
-        return DART_RELEVANCE_LOCAL_METHOD;
-      } else if (member is ParameterElement) {
-        return DART_RELEVANCE_PARAMETER;
-      } else if (member is TopLevelVariableElement) {
-        return DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
-      } else if (member is TypeParameterElement) {
-        return DART_RELEVANCE_TYPE_PARAMETER;
-      }
-    }
-    return DART_RELEVANCE_DEFAULT;
-  }
-
   /// Return the relevance score for a top-level [element].
   int _computeTopLevelRelevance(Element element,
       {int defaultRelevance = 800, @required DartType elementType}) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 3120c99..e3eee98 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -236,11 +236,8 @@
       types.addAll(superclassConstraints);
     }
     for (var targetType in types) {
-      double inheritanceDistance;
-      if (request.useNewRelevance) {
-        inheritanceDistance = request.featureComputer
-            .inheritanceDistanceFeature(type.element, targetType.element);
-      }
+      var inheritanceDistance = request.featureComputer
+          .inheritanceDistanceFeature(type.element, targetType.element);
       for (var method in targetType.methods) {
         // Exclude static methods when completion on an instance.
         if (!method.isStatic) {
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index 808cb44..2984122 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -203,7 +203,24 @@
 
   void _addReplaceEdit(SourceRange range, String text) {
     var edit = SourceEdit(range.offset, range.length, text);
-    doSourceChange_addElementEdit(change, unitElement, edit);
+    // TODO(brianwilkerson) The commented out function call has been inlined in
+    //  order to work around a situation in which _complete_doStatement creates
+    //  a conflicting edit that happens to work because of the order in which
+    //  the edits are applied. The implementation needs to be cleaned up in
+    //  order to prevent the conflicting edit from being generated.
+    // doSourceChange_addElementEdit(change, unitElement, edit);
+    var fileEdit = change.getFileEdit(unitElement.source.fullName);
+    if (fileEdit == null) {
+      fileEdit = SourceFileEdit(file, 0);
+      change.addFileEdit(fileEdit);
+    }
+    var edits = fileEdit.edits;
+    var length = edits.length;
+    var index = 0;
+    while (index < length && edits[index].offset > edit.offset) {
+      index++;
+    }
+    edits.insert(index, edit);
   }
 
   void _appendEmptyBraces(SourceBuilder sb, [bool needsExitMark = false]) {
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart
new file mode 100644
index 0000000..cd4d7bd
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/analysis_options_generator.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/services/completion/yaml/producer.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/task/options.dart';
+
+/// A completion generator that can produce completion suggestions for analysis
+/// options files.
+class AnalysisOptionsGenerator extends YamlCompletionGenerator {
+  /// The producer representing the known valid structure of an analysis options
+  /// file.
+  // TODO(brianwilkerson) We need to support multiple valid formats.
+  //  For example, the lint rules can either be a list or a map, but we only
+  //  suggest list items.
+  static const MapProducer analysisOptionsProducer = MapProducer({
+    AnalyzerOptions.analyzer: MapProducer({
+      AnalyzerOptions.enableExperiment: EmptyProducer(),
+      AnalyzerOptions.errors: EmptyProducer(),
+      AnalyzerOptions.exclude: EmptyProducer(),
+      AnalyzerOptions.language: MapProducer({
+        AnalyzerOptions.strictInference: EmptyProducer(),
+        AnalyzerOptions.strictRawTypes: EmptyProducer(),
+      }),
+      AnalyzerOptions.optionalChecks: MapProducer({
+        AnalyzerOptions.chromeOsManifestChecks: EmptyProducer(),
+      }),
+      AnalyzerOptions.plugins: EmptyProducer(),
+      AnalyzerOptions.strong_mode: MapProducer({
+        AnalyzerOptions.declarationCasts: EmptyProducer(),
+        AnalyzerOptions.implicitCasts: EmptyProducer(),
+        AnalyzerOptions.implicitDynamic: EmptyProducer(),
+      }),
+    }),
+    // TODO(brianwilkerson) Create a producer to produce `package:` URIs.
+    AnalyzerOptions.include: EmptyProducer(),
+    // TODO(brianwilkerson) Create constants for 'linter' and 'rules'.
+    'linter': MapProducer({
+      'rules': ListProducer(LintRuleProducer()),
+    }),
+  });
+
+  /// Initialize a newly created suggestion generator for analysis options
+  /// files.
+  AnalysisOptionsGenerator(ResourceProvider resourceProvider)
+      : super(resourceProvider);
+
+  @override
+  Producer get topLevelProducer => analysisOptionsProducer;
+}
+
+class LintRuleProducer extends Producer {
+  /// Initialize a location whose valid values are the names of the registered
+  /// lint rules.
+  const LintRuleProducer();
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    for (var rule in Registry.ruleRegistry.rules) {
+      yield identifier(rule.name);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart
new file mode 100644
index 0000000..81bc727
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/completion/yaml/producer.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/file_system/file_system.dart';
+
+/// A completion generator that can produce completion suggestions for fix data
+/// files.
+class FixDataGenerator extends YamlCompletionGenerator {
+  /// The producer representing the known valid structure of a fix data file.
+  static const MapProducer fixDataProducer = MapProducer({
+    'version': EmptyProducer(),
+    'transforms': ListProducer(MapProducer({
+      'title': EmptyProducer(),
+      'date': EmptyProducer(),
+      'bulkApply': BooleanProducer(),
+      'element': MapProducer({
+        // TODO(brianwilkerson) Support suggesting uris.
+        'uris': EmptyProducer(),
+        'class': EmptyProducer(),
+        'constant': EmptyProducer(),
+        'constructor': EmptyProducer(),
+        'enum': EmptyProducer(),
+        'extension': EmptyProducer(),
+        'field': EmptyProducer(),
+        'function': EmptyProducer(),
+        'getter': EmptyProducer(),
+        'method': EmptyProducer(),
+        'mixin': EmptyProducer(),
+        'setter': EmptyProducer(),
+        'typedef': EmptyProducer(),
+        'variable': EmptyProducer(),
+        'inClass': EmptyProducer(),
+        'inEnum': EmptyProducer(),
+        'inExtension': EmptyProducer(),
+        'inMixin': EmptyProducer(),
+      }),
+      'changes': _changesProducer,
+      'oneOf': ListProducer(MapProducer({
+        'if': EmptyProducer(),
+        'changes': _changesProducer,
+      })),
+      'variables': EmptyProducer(),
+    })),
+  });
+
+  /// The producer representing the known valid structure of a list of changes.
+  static const ListProducer _changesProducer = ListProducer(MapProducer({
+    // TODO(brianwilkerson) Create a way to tailor the list of additional
+    //  keys based on the kind when a kind has already been provided.
+    'kind': EnumProducer([
+      'addParameter',
+      'addTypeParameter',
+      'removeParameter',
+      'rename',
+      'renameParameter',
+    ]),
+    'index': EmptyProducer(),
+    'name': EmptyProducer(),
+    'style': EmptyProducer(),
+    'argumentValue': MapProducer({
+      'expression': EmptyProducer(),
+      'requiredIf': EmptyProducer(),
+      // TODO(brianwilkerson) Figure out how to support 'variables'.
+      'variables': EmptyProducer(),
+    }),
+    'extends': EmptyProducer(),
+    'oldName': EmptyProducer(),
+    'newName': EmptyProducer(),
+  }));
+
+  /// Initialize a newly created suggestion generator for fix data files.
+  FixDataGenerator(ResourceProvider resourceProvider) : super(resourceProvider);
+
+  @override
+  Producer get topLevelProducer => fixDataProducer;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
new file mode 100644
index 0000000..cc96113
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
@@ -0,0 +1,203 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' as path;
+
+/// An object that represents the location of a Boolean value.
+class BooleanProducer extends Producer {
+  /// Initialize a location whose valid values are Booleans.
+  const BooleanProducer();
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    yield identifier('true');
+    yield identifier('false');
+  }
+}
+
+/// An object that represents the location of an arbitrary value. They serve as
+/// placeholders when there are no reasonable suggestions for a given location.
+class EmptyProducer extends Producer {
+  /// Initialize a location whose valid values are arbitrary.
+  const EmptyProducer();
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    // Returns nothing.
+  }
+}
+
+/// An object that represents the location of a value from a finite set of
+/// choices.
+class EnumProducer extends Producer {
+  /// The list of valid values at this location.
+  final List<String> values;
+
+  /// Initialize a location whose valid values are in the list of [values].
+  const EnumProducer(this.values);
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    for (var value in values) {
+      yield identifier(value);
+    }
+  }
+}
+
+/// An object that represents the location of a possibly relative file path.
+class FilePathProducer extends Producer {
+  /// Initialize a producer whose valid values are file paths.
+  const FilePathProducer();
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    // This currently assumes that all paths will be posix paths, but we might
+    // want to support platform-specific paths at some point, in which case we
+    // should add a flag to the constructor and use that to choose between the
+    // hard-coded `path.posix` and `provider.pathContext`;
+    var provider = request.resourceProvider;
+    var context = path.posix;
+    var separator = context.separator;
+    var precedingText = request.precedingText;
+
+    String parentDirectory;
+    if (precedingText.isEmpty || precedingText.endsWith(separator)) {
+      parentDirectory = precedingText;
+    } else {
+      parentDirectory = context.dirname(precedingText);
+    }
+    if (parentDirectory == '.') {
+      parentDirectory = '';
+    } else if (parentDirectory.endsWith(separator)) {
+      parentDirectory = parentDirectory.substring(
+          0, parentDirectory.length - separator.length);
+    }
+    if (context.isRelative(parentDirectory)) {
+      parentDirectory =
+          context.join(context.dirname(request.filePath), parentDirectory);
+    }
+    parentDirectory = context.normalize(parentDirectory);
+    var dir = provider.getResource(parentDirectory);
+    if (dir is Folder) {
+      try {
+        for (var child in dir.getChildren()) {
+          var name = child.shortName;
+          if (child is Folder) {
+            if (!name.startsWith('.')) {
+              yield identifier(name);
+            }
+          } else if (child is File) {
+            yield identifier(name);
+          }
+        }
+      } on FileSystemException {
+        // Guard against I/O exceptions.
+      }
+    }
+  }
+}
+
+/// An object that represents the location of the keys/values in a map.
+abstract class KeyValueProducer extends Producer {
+  /// Initialize a producer representing a key/value pair in a map.
+  const KeyValueProducer();
+
+  /// Returns a producer for values of the given [key].
+  Producer producerForKey(String key);
+}
+
+/// An object that represents the location of an element in a list.
+class ListProducer extends Producer {
+  /// The producer used to produce suggestions for an element of the list.
+  final Producer element;
+
+  /// Initialize a location whose valid values are determined by the [element]
+  /// producer.
+  const ListProducer(this.element);
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    for (var suggestion in element.suggestions(request)) {
+      // TODO(brianwilkerson) Consider prepending the suggestion with a hyphen
+      //  when the current node isn't already preceded by a hyphen. The
+      //  cleanest way to do this is probably to access the [element] producer
+      //  in the place where we're choosing a producer in that situation.
+      // suggestion.completion = '- ${suggestion.completion}';
+      yield suggestion;
+    }
+  }
+}
+
+/// An object that represents the location of the keys in a map.
+class MapProducer extends KeyValueProducer {
+  /// A table from the value of a key to the producer used to make suggestions
+  /// for the value following the key.
+  final Map<String, Producer> _children;
+
+  /// Initialize a location whose valid values are the keys of a map as encoded
+  /// by the map of [children].
+  const MapProducer(this._children);
+
+  @override
+  Producer producerForKey(String key) => _children[key];
+
+  @override
+  Iterable<CompletionSuggestion> suggestions(
+      YamlCompletionRequest request) sync* {
+    for (var entry in _children.entries) {
+      if (entry.value is ListProducer) {
+        yield identifier('${entry.key}:');
+      } else {
+        yield identifier('${entry.key}: ');
+      }
+    }
+  }
+}
+
+/// An object that represents a specific location in the structure of the valid
+/// YAML representation and can produce completion suggestions appropriate for
+/// that location.
+abstract class Producer {
+  /// Initialize a newly created instance of this class.
+  const Producer();
+
+  /// A utility method used to create a suggestion for the [identifier].
+  CompletionSuggestion identifier(String identifier) => CompletionSuggestion(
+      CompletionSuggestionKind.IDENTIFIER,
+      1000,
+      identifier,
+      identifier.length,
+      0,
+      false,
+      false);
+
+  /// Return the completion suggestions appropriate to this location.
+  Iterable<CompletionSuggestion> suggestions(YamlCompletionRequest request);
+}
+
+/// The information provided to a [Producer] when requesting completions.
+class YamlCompletionRequest {
+  /// The resource provider used to access the file system.
+  final ResourceProvider resourceProvider;
+
+  /// The absolute path of the file in which completions are being requested.
+  final String filePath;
+
+  /// The text to the left of the cursor.
+  final String precedingText;
+
+  /// Initialize a newly created completion request.
+  YamlCompletionRequest(
+      {@required this.filePath,
+      @required this.precedingText,
+      @required this.resourceProvider});
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
new file mode 100644
index 0000000..2b3794f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/completion/yaml/producer.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/file_system/file_system.dart';
+
+/// A completion generator that can produce completion suggestions for pubspec
+/// files.
+class PubspecGenerator extends YamlCompletionGenerator {
+  /// The producer representing the known valid structure of a pubspec file.
+  static const MapProducer pubspecProducer = MapProducer({
+    'name': EmptyProducer(),
+    'version': EmptyProducer(),
+    'description': EmptyProducer(),
+    'homepage': EmptyProducer(),
+    'repository': EmptyProducer(),
+    'issue_tracker': EmptyProducer(),
+    'documentation': EmptyProducer(),
+    'executables': EmptyProducer(),
+    'publish_to': EmptyProducer(),
+    'environment': MapProducer({
+      'flutter': EmptyProducer(),
+      'sdk': EmptyProducer(),
+    }),
+    'dependencies': EmptyProducer(),
+    'dev_dependencies': EmptyProducer(),
+    // TODO(brianwilkerson) Suggest names already listed under 'dependencies'
+    //  and 'dev_dependencies'.
+    'dependency_overrides': EmptyProducer(),
+    'flutter': MapProducer({
+      'assets': ListProducer(FilePathProducer()),
+      'fonts': ListProducer(MapProducer({
+        'family': EmptyProducer(),
+        'fonts': ListProducer(MapProducer({
+          'asset': EmptyProducer(),
+          'style': EnumProducer(['italic', 'normal']),
+          'weight': EnumProducer(
+              ['100', '200', '300', '400', '500', '600', '700', '800', '900']),
+        })),
+      })),
+      'generate': BooleanProducer(),
+      'module': MapProducer({
+        'androidX': BooleanProducer(),
+        'androidPackage': EmptyProducer(),
+        'iosBundleIdentifier': EmptyProducer(),
+      }),
+      'plugin': MapProducer({
+        'platforms': MapProducer({
+          'android': MapProducer({
+            'package': EmptyProducer(),
+            'pluginClass': EmptyProducer(),
+          }),
+          'ios': MapProducer({
+            'pluginClass': EmptyProducer(),
+          }),
+          'linux': MapProducer({
+            'dartPluginClass': EmptyProducer(),
+            'pluginClass': EmptyProducer(),
+          }),
+          'macos': MapProducer({
+            'dartPluginClass': EmptyProducer(),
+            'pluginClass': EmptyProducer(),
+          }),
+          'web': MapProducer({
+            'fileName': EmptyProducer(),
+            'pluginClass': EmptyProducer(),
+          }),
+          'windows': MapProducer({
+            'dartPluginClass': EmptyProducer(),
+            'pluginClass': EmptyProducer(),
+          }),
+        }),
+      }),
+      'uses-material-design': BooleanProducer(),
+    }),
+  });
+
+  /// Initialize a newly created suggestion generator for pubspec files.
+  PubspecGenerator(ResourceProvider resourceProvider) : super(resourceProvider);
+
+  @override
+  Producer get topLevelProducer => pubspecProducer;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
new file mode 100644
index 0000000..2746a76
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
@@ -0,0 +1,189 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/services/completion/yaml/producer.dart';
+import 'package:analysis_server/src/utilities/extensions/yaml.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:yaml/yaml.dart';
+
+/// A completion generator that can produce completion suggestions for files
+/// containing a YAML structure.
+abstract class YamlCompletionGenerator {
+  /// The resource provider used to access the content of the file in which
+  /// completion was requested.
+  final ResourceProvider resourceProvider;
+
+  /// Initialize a newly created generator to use the [resourceProvider] to
+  /// access the content of the file in which completion was requested.
+  YamlCompletionGenerator(this.resourceProvider);
+
+  /// Return the producer used to produce suggestions at the top-level of the
+  /// file.
+  Producer get topLevelProducer;
+
+  /// Return the completion suggestions appropriate for the given [offset] in
+  /// the file at the given [filePath].
+  YamlCompletionResults getSuggestions(String filePath, int offset) {
+    var file = resourceProvider.getFile(filePath);
+    String content;
+    try {
+      content = file.readAsStringSync();
+    } on FileSystemException {
+      // If the file doesn't exist or can't be read, then there are no
+      // suggestions.
+      return const YamlCompletionResults.empty();
+    }
+    var root = _parseYaml(content);
+    if (root == null) {
+      // If the contents can't be parsed, then there are no suggestions.
+      return const YamlCompletionResults.empty();
+    }
+    var nodePath = _pathToOffset(root, offset);
+    var completionNode = nodePath.last;
+    var precedingText = '';
+    if (completionNode is YamlScalar) {
+      var value = completionNode.value;
+      if (value is String && completionNode.style == ScalarStyle.PLAIN) {
+        precedingText =
+            value.substring(0, offset - completionNode.span.start.offset);
+      } else if (value != null) {
+        // There are no completions at the given location.
+        return const YamlCompletionResults.empty();
+      }
+    }
+    var request = YamlCompletionRequest(
+        filePath: filePath,
+        precedingText: precedingText,
+        resourceProvider: resourceProvider);
+    return getSuggestionsForPath(request, nodePath, offset);
+  }
+
+  /// Given the [request] to pass to producers, a [nodePath] to the node in
+  /// which completions are being requested and the offset of the cursor, return
+  /// the completions appropriate at that location.
+  YamlCompletionResults getSuggestionsForPath(
+      YamlCompletionRequest request, List<YamlNode> nodePath, int offset) {
+    var producer = _producerForPath(nodePath);
+    if (producer == null) {
+      return const YamlCompletionResults.empty();
+    }
+    var invalidSuggestions = _siblingsOnPath(nodePath);
+    var suggestions = <CompletionSuggestion>[];
+    for (var suggestion in producer.suggestions(request)) {
+      if (!invalidSuggestions.contains(suggestion.completion)) {
+        suggestions.add(suggestion);
+      }
+    }
+    final node = nodePath.isNotEmpty ? nodePath.last : null;
+    final replaceNode = node is YamlScalar && node.containsOffset(offset);
+    final replacementOffset = replaceNode ? node.span.start.offset : offset;
+    final replacementLength = replaceNode ? node.span.length : 0;
+    return YamlCompletionResults(
+        suggestions, replacementOffset, replacementLength);
+  }
+
+  /// Return the result of parsing the file [content] into a YAML node.
+  YamlNode _parseYaml(String content) {
+    try {
+      return loadYamlNode(content);
+    } on YamlException {
+      // If the file can't be parsed, then fall through to return `null`.
+    }
+    return null;
+  }
+
+  /// Return a list containing the node containing the [offset] and all of the
+  /// nodes between that and the [root] node. The root node is first in the list
+  /// and the node containing the offset is the last element in the list.
+  List<YamlNode> _pathToOffset(YamlNode root, int offset) {
+    var path = <YamlNode>[];
+    var node = root;
+    while (node != null) {
+      path.add(node);
+      node = node.childContainingOffset(offset);
+    }
+    return path;
+  }
+
+  /// Return the producer that should be used to produce completion suggestions
+  /// for the last node in the node [path].
+  Producer _producerForPath(List<YamlNode> path) {
+    var producer = topLevelProducer;
+    for (var i = 0; i < path.length - 1; i++) {
+      var node = path[i];
+      if (node is YamlMap && producer is KeyValueProducer) {
+        var key = node.keyAtValue(path[i + 1]);
+        if (key is YamlScalar) {
+          producer = (producer as KeyValueProducer).producerForKey(key.value);
+        } else {
+          return null;
+        }
+      } else if (node is YamlList && producer is ListProducer) {
+        producer = (producer as ListProducer).element;
+      } else {
+        return producer;
+      }
+    }
+    return producer;
+  }
+
+  /// Return a list of the suggestions that should not be suggested because they
+  /// are already in the structure.
+  List<String> _siblingsOnPath(List<YamlNode> path) {
+    List<String> siblingsInList(YamlList list, YamlNode currentElement) {
+      var siblings = <String>[];
+      for (var element in list.nodes) {
+        if (element != currentElement &&
+            element is YamlScalar &&
+            element.value is String) {
+          siblings.add(element.value);
+        }
+      }
+      return siblings;
+    }
+
+    List<String> siblingsInMap(YamlMap map, YamlNode currentKey) {
+      var siblings = <String>[];
+      for (var key in map.nodes.keys) {
+        if (key != currentKey && key is YamlScalar && key.value is String) {
+          siblings.add('${key.value}: ');
+        }
+      }
+      return siblings;
+    }
+
+    var length = path.length;
+    if (length < 2) {
+      return const <String>[];
+    }
+    var node = path[length - 1];
+    if (node is YamlList) {
+      return siblingsInList(node, null);
+    } else if (node is YamlMap) {
+      return siblingsInMap(node, null);
+    }
+    var parent = path[length - 2];
+    if (parent is YamlList) {
+      return siblingsInList(parent, node);
+    } else if (parent is YamlMap) {
+      return siblingsInMap(parent, node);
+    }
+    return const <String>[];
+  }
+}
+
+class YamlCompletionResults {
+  final List<CompletionSuggestion> suggestions;
+  final int replacementOffset;
+  final int replacementLength;
+
+  const YamlCompletionResults(
+      this.suggestions, this.replacementOffset, this.replacementLength);
+
+  const YamlCompletionResults.empty()
+      : suggestions = const [],
+        replacementOffset = 0,
+        replacementLength = 0;
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 50910b8..04dc79d 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -4,12 +4,16 @@
 
 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 
 /// The implementation of [DartAssistContext].
 class DartAssistContextImpl implements DartAssistContext {
   @override
+  final InstrumentationService instrumentationService;
+
+  @override
   final ChangeWorkspace workspace;
 
   @override
@@ -21,8 +25,8 @@
   @override
   final int selectionLength;
 
-  DartAssistContextImpl(this.workspace, this.resolveResult,
-      this.selectionOffset, this.selectionLength);
+  DartAssistContextImpl(this.instrumentationService, this.workspace,
+      this.resolveResult, this.selectionOffset, this.selectionLength);
 }
 
 /// An enumeration of possible assist kinds.
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 6f994e4..d304168 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -73,6 +73,7 @@
 import 'package:analyzer_plugin/utilities/assist/assist.dart'
     hide AssistContributor;
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
 
 /// The computer for Dart assists.
 class AssistProcessor extends BaseProcessor {
@@ -151,16 +152,16 @@
     SurroundWith.newInstance,
   ];
 
-  final DartAssistContext context;
+  final DartAssistContext assistContext;
 
   final List<Assist> assists = <Assist>[];
 
-  AssistProcessor(this.context)
+  AssistProcessor(this.assistContext)
       : super(
-          selectionOffset: context.selectionOffset,
-          selectionLength: context.selectionLength,
-          resolvedResult: context.resolveResult,
-          workspace: context.workspace,
+          selectionOffset: assistContext.selectionOffset,
+          selectionLength: assistContext.selectionLength,
+          resolvedResult: assistContext.resolveResult,
+          workspace: assistContext.workspace,
         );
 
   Future<List<Assist>> compute() async {
@@ -241,36 +242,42 @@
     if (!setupSuccess) {
       return;
     }
+
+    Future<void> compute(CorrectionProducer producer) async {
+      producer.configure(context);
+      var builder = ChangeBuilder(
+          workspace: context.workspace, eol: context.utils.endOfLine);
+      try {
+        await producer.compute(builder);
+        _addAssistFromBuilder(builder, producer.assistKind,
+            args: producer.assistArguments);
+      } on ConflictingEditException catch (exception, stackTrace) {
+        // Handle the exception by (a) not adding an assist based on the
+        // producer and (b) logging the exception.
+        assistContext.instrumentationService
+            .logException(exception, stackTrace);
+      }
+    }
+
     for (var generator in generators) {
       var ruleNames = lintRuleMap[generator] ?? {};
       if (!_containsErrorCode(ruleNames)) {
         var producer = generator();
-        producer.configure(context);
-
-        var builder = ChangeBuilder(
-            workspace: context.workspace, eol: context.utils.endOfLine);
-        await producer.compute(builder);
-        _addAssistFromBuilder(builder, producer.assistKind,
-            args: producer.assistArguments);
+        await compute(producer);
       }
     }
     for (var multiGenerator in multiGenerators) {
       var multiProducer = multiGenerator();
       multiProducer.configure(context);
       for (var producer in multiProducer.producers) {
-        var builder = ChangeBuilder(
-            workspace: context.workspace, eol: context.utils.endOfLine);
-        producer.configure(context);
-        await producer.compute(builder);
-        _addAssistFromBuilder(builder, producer.assistKind,
-            args: producer.assistArguments);
+        await compute(producer);
       }
     }
   }
 
   bool _containsErrorCode(Set<String> errorCodes) {
     final fileOffset = node.offset;
-    for (var error in context.resolveResult.errors) {
+    for (var error in assistContext.resolveResult.errors) {
       final errorSource = error.source;
       if (file == errorSource.fullName) {
         if (fileOffset >= error.offset &&
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index dfece89..0dae89c 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -5,6 +5,7 @@
 import 'dart:core';
 
 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/dart/add_await.dart';
@@ -66,11 +67,15 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
 /// A fix producer that produces changes to fix multiple diagnostics.
 class BulkFixProcessor {
@@ -338,6 +343,9 @@
         RemoveNonNullAssertion.newInstance,
   };
 
+  /// The service used to report errors when building fixes.
+  final InstrumentationService instrumentationService;
+
   /// Information about the workspace containing the libraries in which changes
   /// will be produced.
   final DartChangeWorkspace workspace;
@@ -346,10 +354,24 @@
   /// diagnostics.
   ChangeBuilder builder;
 
+  /// A map associating libraries to fixes with change counts.
+  final ChangeMap changeMap = ChangeMap();
+
   /// Initialize a newly created processor to create fixes for diagnostics in
   /// libraries in the [workspace].
-  BulkFixProcessor(this.workspace) {
-    builder = ChangeBuilder(workspace: workspace);
+  BulkFixProcessor(this.instrumentationService, this.workspace)
+      : builder = ChangeBuilder(workspace: workspace);
+
+  List<BulkFix> get fixDetails {
+    var details = <BulkFix>[];
+    for (var change in changeMap.libraryMap.entries) {
+      var fixes = <BulkFixDetail>[];
+      for (var codeEntry in change.value.entries) {
+        fixes.add(BulkFixDetail(codeEntry.key, codeEntry.value));
+      }
+      details.add(BulkFix(change.key, fixes));
+    }
+    return details;
   }
 
   /// Return a change builder that has been used to create fixes for the
@@ -372,12 +394,99 @@
     return builder;
   }
 
+  /// Return a change builder that has been used to create all fixes for a
+  /// specific diagnostic code in the given [unit].
+  Future<ChangeBuilder> fixOfTypeInUnit(
+    ResolvedUnitResult unit,
+    String errorCode,
+  ) async {
+    final errorCodeLowercase = errorCode.toLowerCase();
+    final errors = unit.errors.where(
+      (error) => error.errorCode.name.toLowerCase() == errorCodeLowercase,
+    );
+
+    final analysisOptions = unit.session.analysisContext.analysisOptions;
+    final fixContext = DartFixContextImpl(
+      instrumentationService,
+      workspace,
+      unit,
+      null,
+      (name) => [],
+    );
+
+    for (var error in errors) {
+      final processor = ErrorProcessor.getProcessor(analysisOptions, error);
+      // Only fix errors not filtered out in analysis options.
+      if (processor == null || processor.severity != null) {
+        await _fixSingleError(fixContext, unit, error);
+      }
+    }
+
+    return builder;
+  }
+
+  /// Returns the potential [FixKind]s that may be available for a given diagnostic.
+  ///
+  /// The presence of a kind does not guarantee a fix will be produced, nor does
+  /// the absence of a kind mean that it definitely will not (some producers
+  /// do not provide FixKinds up-front). These results are intended as a hint
+  /// for populating something like a quick-fix menu with possible apply-all fixes.
+  Iterable<FixKind> producableFixesForError(
+    ResolvedUnitResult result,
+    AnalysisError diagnostic,
+  ) sync* {
+    final errorCode = diagnostic.errorCode;
+    if (errorCode is LintCode) {
+      final generators = lintProducerMap[errorCode.name];
+      if (generators != null) {
+        yield* generators.map((g) => g().fixKind).where((k) => k != null);
+      }
+      return;
+    }
+
+    final generator = nonLintProducerMap[errorCode];
+    if (generator != null) {
+      final kind = generator().fixKind;
+      if (kind != null) yield kind;
+    }
+
+    final multiGenerators = nonLintMultiProducerMap[errorCode];
+    if (multiGenerators != null) {
+      final fixContext = DartFixContextImpl(
+        instrumentationService,
+        workspace,
+        result,
+        null,
+        (name) => [],
+      );
+
+      var context = CorrectionProducerContext(
+        applyingBulkFixes: true,
+        dartFixContext: fixContext,
+        diagnostic: diagnostic,
+        resolvedResult: result,
+        selectionOffset: diagnostic.offset,
+        selectionLength: diagnostic.length,
+        workspace: workspace,
+      );
+
+      for (final multiGenerator in multiGenerators) {
+        final multiProducer = multiGenerator();
+        multiProducer.configure(context);
+        yield* multiProducer.producers
+            .map((p) => p.fixKind)
+            .where((k) => k != null);
+      }
+    }
+  }
+
   /// Use the change [builder] to create fixes for the diagnostics in the
   /// library associated with the analysis [result].
   Future<void> _fixErrorsInLibrary(ResolvedLibraryResult result) async {
     var analysisOptions = result.session.analysisContext.analysisOptions;
     for (var unitResult in result.units) {
       final fixContext = DartFixContextImpl(
+        instrumentationService,
         workspace,
         unitResult,
         null,
@@ -415,22 +524,48 @@
 
     Future<void> compute(CorrectionProducer producer) async {
       producer.configure(context);
-      await producer.compute(builder);
+      try {
+        var localBuilder = builder.copy();
+        await producer.compute(localBuilder);
+        builder = localBuilder;
+      } on ConflictingEditException {
+        // If a conflicting edit was added in [compute], then the [localBuilder]
+        // is discarded and we revert to the previous state of the builder.
+      }
+    }
+
+    int computeChangeHash() {
+      var hash = 0;
+      var edits = builder.sourceChange.edits;
+      for (var i = 0; i < edits.length; ++i) {
+        hash = JenkinsSmiHash.combine(hash, edits[i].hashCode);
+      }
+      return JenkinsSmiHash.finish(hash);
+    }
+
+    Future<void> generate(CorrectionProducer producer, String code) async {
+      var oldHash = computeChangeHash();
+      await compute(producer);
+      var newHash = computeChangeHash();
+      if (newHash != oldHash) {
+        changeMap.add(result.path, code);
+      }
     }
 
     var errorCode = diagnostic.errorCode;
     try {
+      var codeName = errorCode.name;
       if (errorCode is LintCode) {
-        var generators = lintProducerMap[errorCode.name];
+        var generators = lintProducerMap[codeName];
         if (generators != null) {
           for (var generator in generators) {
-            await compute(generator());
+            await generate(generator(), codeName);
           }
         }
       } else {
         var generator = nonLintProducerMap[errorCode];
         if (generator != null) {
-          await compute(generator());
+          await generate(generator(), codeName);
         }
         var multiGenerators = nonLintMultiProducerMap[errorCode];
         if (multiGenerators != null) {
@@ -438,7 +573,7 @@
             var multiProducer = multiGenerator();
             multiProducer.configure(context);
             for (var producer in multiProducer.producers) {
-              await compute(producer);
+              await generate(producer, codeName);
             }
           }
         }
@@ -451,3 +586,15 @@
     }
   }
 }
+
+/// Maps changes to library paths.
+class ChangeMap {
+  /// Map of paths to maps of codes to counts.
+  final Map<String, Map<String, int>> libraryMap = {};
+
+  /// Add an entry for the given [code] in the given [libraryPath].
+  void add(String libraryPath, String code) {
+    var changes = libraryMap.putIfAbsent(libraryPath, () => {});
+    changes.update(code, (value) => value + 1, ifAbsent: () => 1);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
index ef18db3..2e73adb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
@@ -5,24 +5,92 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
 class AddAsync extends CorrectionProducer {
+  /// A flag indicating whether this producer is producing a fix in the case
+  /// where a function is missing a return at the end.
+  final bool isForMissingReturn;
+
+  /// Initialize a newly created producer.
+  AddAsync(this.isForMissingReturn);
+
   @override
   FixKind get fixKind => DartFixKind.ADD_ASYNC;
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var body = node.thisOrAncestorOfType<FunctionBody>();
-    if (body != null && body.keyword == null) {
-      var typeProvider = this.typeProvider;
-      await builder.addDartFileEdit(file, (builder) {
-        builder.convertFunctionFromSyncToAsync(body, typeProvider);
-      });
+    if (isForMissingReturn) {
+      var parent = node.parent;
+      DartType returnType;
+      FunctionBody body;
+      if (parent is FunctionDeclaration) {
+        returnType = parent.declaredElement.returnType;
+        body = parent.functionExpression.body;
+      } else if (parent is MethodDeclaration) {
+        returnType = parent.declaredElement.returnType;
+        body = parent.body;
+      }
+      if (body == null) {
+        return;
+      }
+      if (_isFutureVoid(returnType) && _hasNoReturns(body)) {
+        await builder.addDartFileEdit(file, (builder) {
+          builder.addSimpleInsertion(body.offset, 'async ');
+        });
+      }
+    } else {
+      var body = node.thisOrAncestorOfType<FunctionBody>();
+      if (body != null && body.keyword == null) {
+        var typeProvider = this.typeProvider;
+        await builder.addDartFileEdit(file, (builder) {
+          builder.convertFunctionFromSyncToAsync(body, typeProvider);
+        });
+      }
     }
   }
 
+  /// Return `true` if there are no return statements in the given function
+  /// [body].
+  bool _hasNoReturns(FunctionBody body) {
+    var finder = _ReturnFinder();
+    body.accept(finder);
+    return !finder.foundReturn;
+  }
+
+  /// Return `true` if the [type] is `Future<void>`.
+  bool _isFutureVoid(DartType type) {
+    if (type is InterfaceType && type.isDartAsyncFuture) {
+      return type.typeArguments[0].isVoid;
+    }
+    return false;
+  }
+
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
-  static AddAsync newInstance() => AddAsync();
+  static AddAsync missingReturn() => AddAsync(true);
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddAsync newInstance() => AddAsync(false);
+}
+
+/// An AST visitor used to find return statements in function bodies.
+class _ReturnFinder extends RecursiveAstVisitor<void> {
+  /// A flag indicating whether a return statement was visited.
+  bool foundReturn = false;
+
+  /// Initialize a newly created visitor.
+  _ReturnFinder();
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // Return statements within closures aren't counted.
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    foundReturn = true;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
index bc71685..8e20c54 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
@@ -4,6 +4,8 @@
 
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
@@ -14,7 +16,25 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
-      builder.addSimpleInsertion(node.parent.offset, 'required ');
+      var insertOffset = node.parent.offset;
+
+      var parent = node.parent;
+      if (parent is FormalParameter) {
+        var metadata = parent.metadata;
+        // Check for redundant `@required` annotations.
+        if (metadata.isNotEmpty) {
+          for (var annotation in metadata) {
+            if (annotation.elementAnnotation.isRequired) {
+              var length = annotation.endToken.next.offset -
+                  annotation.beginToken.offset;
+              builder.addDeletion(SourceRange(annotation.offset, length));
+              break;
+            }
+          }
+          insertOffset = metadata.endToken.next.offset;
+        }
+      }
+      builder.addSimpleInsertion(insertOffset, 'required ');
     });
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
index 403a6c4..feb830d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
@@ -86,7 +86,7 @@
       } else {
         return;
       }
-      if (operator.type != TokenType.PERIOD) {
+      if (operator == null || operator.type != TokenType.PERIOD) {
         return;
       }
       if (!(target is SimpleIdentifier &&
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
index f374346..f6a8db3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
@@ -178,6 +178,11 @@
           parent2.type?.type?.element == typeProvider.setElement) {
         return true;
       }
+    } else if (parent.parent is InvocationExpression) {
+      var parameterElement = creation.staticParameterElement;
+      if (parameterElement?.type?.element == typeProvider.setElement) {
+        return true;
+      }
     }
     return _hasUnambiguousElement(creation);
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
index d9d82b5..7ecd51e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
@@ -178,7 +179,11 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var changes = _transform.changes;
+    var changes = _transform.changesSelector
+        .getChanges(TemplateContext.forInvocation(node, utils));
+    if (changes == null) {
+      return;
+    }
     var data = <Object>[];
     for (var change in changes) {
       var result = change.validate(this);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
index 6f1065a..23d6686 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
@@ -51,11 +51,17 @@
     if (nameNode != node) {
       return;
     }
+
+    // Should be in a class or mixin.
+    if (fieldDeclaration.parent is! ClassOrMixinDeclaration) {
+      return;
+    }
+    var classDeclaration = fieldDeclaration.parent as ClassOrMixinDeclaration;
+
     await builder.addDartFileEdit(file, (builder) {
       // rename field
       builder.addSimpleReplacement(range.node(nameNode), '_$name');
       // update references in constructors
-      ClassOrMixinDeclaration classDeclaration = fieldDeclaration.parent;
       for (var member in classDeclaration.members) {
         if (member is ConstructorDeclaration) {
           for (var parameter in member.parameters.parameters) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_add_show.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_add_show.dart
index 306312f..2b53b99 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_add_show.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_add_show.dart
@@ -30,7 +30,7 @@
       return;
     }
     // prepare whole import namespace
-    ImportElement importElement = importDirective.element;
+    var importElement = importDirective.element;
     if (importElement == null) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
index cd226a8..8ac0b18 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -42,6 +42,9 @@
       String typeArgumentsText;
       int typeArgumentsOffset;
       if (type is NamedType && type.typeArguments != null) {
+        if (initializer is CascadeExpression) {
+          initializer = (initializer as CascadeExpression).target;
+        }
         if (initializer is TypedLiteral) {
           if (initializer.typeArguments == null) {
             typeArgumentsText = utils.getNodeText(type.typeArguments);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index fe6cbc4..8bd57b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
@@ -115,6 +116,9 @@
 /// The implementation of [DartFixContext].
 class DartFixContextImpl implements DartFixContext {
   @override
+  final InstrumentationService instrumentationService;
+
+  @override
   final ChangeWorkspace workspace;
 
   @override
@@ -126,8 +130,8 @@
   final List<TopLevelDeclaration> Function(String name)
       getTopLevelDeclarationsFunction;
 
-  DartFixContextImpl(this.workspace, this.resolveResult, this.error,
-      this.getTopLevelDeclarationsFunction);
+  DartFixContextImpl(this.instrumentationService, this.workspace,
+      this.resolveResult, this.error, this.getTopLevelDeclarationsFunction);
 
   @override
   List<TopLevelDeclaration> getTopLevelDeclarations(String name) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
index 6fbcad4..1dc11da 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
@@ -50,7 +50,7 @@
   @override
   _Data validate(DataDrivenFix fix) {
     var node = fix.node;
-    var context = TemplateContext(getInvocation(node), fix.utils);
+    var context = TemplateContext.forInvocation(node, fix.utils);
     if (node is NamedType) {
       // wrong_number_of_type_arguments
       // wrong_number_of_type_arguments_constructor
@@ -101,7 +101,7 @@
 
   void _applyToTypeArguments(
       DartFileEditBuilder builder, DataDrivenFix fix, _TypeArgumentData data) {
-    var context = TemplateContext(getInvocation(fix.node), fix.utils);
+    var context = TemplateContext.forInvocation(fix.node, fix.utils);
     var typeArguments = data.typeArguments;
     if (typeArguments == null) {
       // Adding the first type argument.
@@ -130,7 +130,7 @@
 
   void _applyToTypeParameters(
       DartFileEditBuilder builder, DataDrivenFix fix, _TypeParameterData data) {
-    var context = TemplateContext(getInvocation(fix.node), fix.utils);
+    var context = TemplateContext.forInvocation(fix.node, fix.utils);
 
     void writeParameter(DartEditBuilder builder) {
       builder.write(name);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart
index 39b5db6..f73f6ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
-import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 
 /// The behavior common to all of the changes used to construct a transform.
@@ -13,36 +12,6 @@
   /// [validate] method.
   void apply(DartFileEditBuilder builder, DataDrivenFix fix, D data);
 
-  /// Return the invocation containing the given [node]. The invocation will be
-  /// either an instance creation expression, function invocation, method
-  /// invocation, or an extension override.
-  AstNode getInvocation(AstNode node) {
-    if (node is ArgumentList) {
-      return node.parent;
-    } else if (node is InstanceCreationExpression ||
-        node is InvocationExpression) {
-      return node;
-    } else if (node is SimpleIdentifier) {
-      var parent = node.parent;
-      if (parent is ConstructorName) {
-        var grandparent = parent.parent;
-        if (grandparent is InstanceCreationExpression) {
-          return grandparent;
-        }
-      } else if (parent is MethodInvocation && parent.methodName == node) {
-        return parent;
-      }
-    } else if (node is TypeArgumentList) {
-      var parent = node.parent;
-      if (parent is InvocationExpression) {
-        return parent;
-      } else if (parent is ExtensionOverride) {
-        return parent;
-      }
-    }
-    return null;
-  }
-
   /// Validate that this change can be applied. Return the data to be passed to
   /// [apply] if the change can be applied, or `null` if it can't be applied.
   D validate(DataDrivenFix fix);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/changes_selector.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/changes_selector.dart
new file mode 100644
index 0000000..85f7b7e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/changes_selector.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
+
+/// An object that can select a single list of changes from among one or more
+/// possible lists.
+abstract class ChangesSelector {
+  /// Return the list of changes that should be applied based on the [context].
+  List<Change> getChanges(TemplateContext context);
+}
+
+/// A changes selector that uses boolean-valued conditions to select the list.
+class ConditionalChangesSelector implements ChangesSelector {
+  /// A table mapping the expressions to be evaluated to the changes that those
+  /// conditions select.
+  final Map<Expression, List<Change>> changeMap;
+
+  /// Initialize a newly created conditional changes selector with the changes
+  /// in the [changeMap].
+  ConditionalChangesSelector(this.changeMap);
+
+  @override
+  List<Change> getChanges(TemplateContext context) {
+    for (var entry in changeMap.entries) {
+      if (entry.key.evaluateIn(context)) {
+        return entry.value;
+      }
+    }
+    return null;
+  }
+}
+
+/// A changes selector that has a single, unconditional list of changes.
+class UnconditionalChangesSelector implements ChangesSelector {
+  /// The list of changes to be returned.
+  final List<Change> changes;
+
+  /// Initialize a newly created changes selector to return the given list of
+  /// [changes].
+  UnconditionalChangesSelector(this.changes);
+
+  @override
+  List<Change> getChanges(TemplateContext context) {
+    return changes;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart
index 649597a..0050c6d8 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/variable_scope.dart';
 import 'package:analyzer/error/listener.dart';
 
 /// A parser for the textual representation of a code fragment.
@@ -12,36 +14,63 @@
   /// The error reporter to which diagnostics will be reported.
   final ErrorReporter errorReporter;
 
+  /// The scope in which variables can be looked up.
+  VariableScope variableScope;
+
   /// The amount to be added to translate from offsets within the content to
   /// offsets within the file.
   int delta;
 
   /// The tokens being parsed.
-  List<_Token> tokens;
+  /* late */ List<_Token> tokens;
 
-  /// The accessors that have been parsed.
-  List<Accessor> accessors = [];
+  /// The index in the [tokens] of the next token to be consumed.
+  int currentIndex = 0;
 
   /// Initialize a newly created parser to report errors to the [errorReporter].
-  CodeFragmentParser(this.errorReporter);
+  CodeFragmentParser(this.errorReporter, {VariableScope scope})
+      : variableScope = scope ?? VariableScope(null, {});
+
+  /// Return the current token, or `null` if the end of the tokens has been
+  /// reached.
+  _Token get currentToken =>
+      currentIndex < tokens.length ? tokens[currentIndex] : null;
+
+  /// Advance to the next token.
+  void advance() {
+    if (currentIndex < tokens.length) {
+      currentIndex++;
+    }
+  }
 
   /// Parse the [content] into a list of accessors. Add the [delta] to translate
   /// from offsets within the content to offsets within the file.
   ///
   /// <content> ::=
   ///   <accessor> ('.' <accessor>)*
-  List<Accessor> parse(String content, int delta) {
+  List<Accessor> parseAccessors(String content, int delta) {
     this.delta = delta;
     tokens = _CodeFragmentScanner(content, delta, errorReporter).scan();
     if (tokens == null) {
       // The error has already been reported.
       return null;
     }
-    var index = _parseAccessor(0);
-    while (index < tokens.length) {
-      var token = tokens[index];
+    currentIndex = 0;
+    var accessors = <Accessor>[];
+    var accessor = _parseAccessor();
+    if (accessor == null) {
+      return accessors;
+    }
+    accessors.add(accessor);
+    while (currentIndex < tokens.length) {
+      var token = currentToken;
       if (token.kind == _TokenKind.period) {
-        index = _parseAccessor(index + 1);
+        advance();
+        accessor = _parseAccessor();
+        if (accessor == null) {
+          return accessors;
+        }
+        accessors.add(accessor);
       } else {
         errorReporter.reportErrorForOffset(TransformSetErrorCode.wrongToken,
             token.offset + delta, token.length, ['.', token.kind.displayName]);
@@ -51,10 +80,32 @@
     return accessors;
   }
 
-  /// Return the token at the given [index] if it exists and if it has one of
-  /// the [validKinds]. Report an error and return `null` if those conditions
-  /// aren't met.
-  _Token _expect(int index, List<_TokenKind> validKinds) {
+  /// Parse the [content] into a condition. Add the [delta] to translate
+  /// from offsets within the content to offsets within the file.
+  ///
+  /// <content> ::=
+  ///   <logicalExpression>
+  Expression parseCondition(String content, int delta) {
+    this.delta = delta;
+    tokens = _CodeFragmentScanner(content, delta, errorReporter).scan();
+    if (tokens == null) {
+      // The error has already been reported.
+      return null;
+    }
+    currentIndex = 0;
+    var expression = _parseLogicalAndExpression();
+    if (currentIndex < tokens.length) {
+      var token = tokens[currentIndex];
+      errorReporter.reportErrorForOffset(TransformSetErrorCode.unexpectedToken,
+          token.offset + delta, token.length, [token.kind.displayName]);
+      return null;
+    }
+    return expression;
+  }
+
+  /// Return the current token if it exists and has one of the [validKinds].
+  /// Report an error and return `null` if those conditions aren't met.
+  _Token _expect(List<_TokenKind> validKinds) {
     String validKindsDisplayString() {
       var buffer = StringBuffer();
       for (var i = 0; i < validKinds.length; i++) {
@@ -70,7 +121,8 @@
       return buffer.toString();
     }
 
-    if (index >= tokens.length) {
+    var token = currentToken;
+    if (token == null) {
       var offset = 0;
       var length = 0;
       if (tokens.isNotEmpty) {
@@ -82,7 +134,6 @@
           offset + delta, length, [validKindsDisplayString()]);
       return null;
     }
-    var token = tokens[index];
     if (!validKinds.contains(token.kind)) {
       errorReporter.reportErrorForOffset(
           TransformSetErrorCode.wrongToken,
@@ -98,23 +149,25 @@
   ///
   /// <accessor> ::=
   ///   <identifier> '[' (<integer> | <identifier>) ']'
-  int _parseAccessor(int index) {
-    var token = _expect(index, const [_TokenKind.identifier]);
+  Accessor _parseAccessor() {
+    var token = _expect(const [_TokenKind.identifier]);
     if (token == null) {
       // The error has already been reported.
-      return tokens.length;
+      return null;
     }
     var identifier = token.lexeme;
     if (identifier == 'arguments') {
-      token = _expect(index + 1, const [_TokenKind.openSquareBracket]);
+      advance();
+      token = _expect(const [_TokenKind.openSquareBracket]);
       if (token == null) {
         // The error has already been reported.
-        return tokens.length;
+        return null;
       }
-      token = _expect(index + 2, [_TokenKind.identifier, _TokenKind.integer]);
+      advance();
+      token = _expect(const [_TokenKind.identifier, _TokenKind.integer]);
       if (token == null) {
         // The error has already been reported.
-        return tokens.length;
+        return null;
       }
       ParameterReference reference;
       if (token.kind == _TokenKind.identifier) {
@@ -123,57 +176,164 @@
         var argumentIndex = int.parse(token.lexeme);
         reference = PositionalParameterReference(argumentIndex);
       }
-      token = _expect(index + 3, [_TokenKind.closeSquareBracket]);
+      advance();
+      token = _expect(const [_TokenKind.closeSquareBracket]);
       if (token == null) {
         // The error has already been reported.
-        return tokens.length;
+        return null;
       }
-      accessors.add(ArgumentAccessor(reference));
-      return index + 4;
+      advance();
+      return ArgumentAccessor(reference);
     } else if (identifier == 'typeArguments') {
-      token = _expect(index + 1, const [_TokenKind.openSquareBracket]);
+      advance();
+      token = _expect(const [_TokenKind.openSquareBracket]);
       if (token == null) {
         // The error has already been reported.
-        return tokens.length;
+        return null;
       }
-      token = _expect(index + 2, [_TokenKind.integer]);
+      advance();
+      token = _expect(const [_TokenKind.integer]);
       if (token == null) {
         // The error has already been reported.
-        return tokens.length;
+        return null;
       }
+      advance();
       var argumentIndex = int.parse(token.lexeme);
-      token = _expect(index + 3, [_TokenKind.closeSquareBracket]);
+      token = _expect(const [_TokenKind.closeSquareBracket]);
       if (token == null) {
         // The error has already been reported.
-        return tokens.length;
+        return null;
       }
-      accessors.add(TypeArgumentAccessor(argumentIndex));
-      return index + 4;
+      advance();
+      return TypeArgumentAccessor(argumentIndex);
     } else {
       errorReporter.reportErrorForOffset(TransformSetErrorCode.unknownAccessor,
           token.offset + delta, token.length, [identifier]);
-      return tokens.length;
+      return null;
     }
   }
+
+  /// Parse a logical expression.
+  ///
+  /// <equalityExpression> ::=
+  ///   <primaryExpression> (<comparisonOperator> <primaryExpression>)?
+  /// <comparisonOperator> ::=
+  ///   '==' | '!='
+  Expression _parseEqualityExpression() {
+    var expression = _parsePrimaryExpression();
+    if (expression == null) {
+      return null;
+    }
+    if (currentIndex >= tokens.length) {
+      return expression;
+    }
+    var kind = currentToken.kind;
+    if (kind == _TokenKind.equal || kind == _TokenKind.notEqual) {
+      advance();
+      var operator =
+          kind == _TokenKind.equal ? Operator.equal : Operator.notEqual;
+      var rightOperand = _parsePrimaryExpression();
+      if (rightOperand == null) {
+        return null;
+      }
+      expression = BinaryExpression(expression, operator, rightOperand);
+    }
+    return expression;
+  }
+
+  /// Parse a logical expression.
+  ///
+  /// <logicalExpression> ::=
+  ///   <equalityExpression> ('&&' <equalityExpression>)*
+  Expression _parseLogicalAndExpression() {
+    var expression = _parseEqualityExpression();
+    if (expression == null) {
+      return null;
+    }
+    if (currentIndex >= tokens.length) {
+      return expression;
+    }
+    var kind = currentToken.kind;
+    while (kind == _TokenKind.and) {
+      advance();
+      var rightOperand = _parseEqualityExpression();
+      if (rightOperand == null) {
+        return null;
+      }
+      expression = BinaryExpression(expression, Operator.and, rightOperand);
+      if (currentIndex >= tokens.length) {
+        return expression;
+      }
+      kind = currentToken.kind;
+    }
+    return expression;
+  }
+
+  /// Parse a logical expression.
+  ///
+  /// <primaryExpression> ::=
+  ///   <identifier> | <string>
+  Expression _parsePrimaryExpression() {
+    var token = currentToken;
+    var kind = token?.kind;
+    if (kind == _TokenKind.identifier) {
+      advance();
+      var variableName = token.lexeme;
+      var generator = variableScope.lookup(variableName);
+      if (generator == null) {
+        errorReporter.reportErrorForOffset(
+            TransformSetErrorCode.undefinedVariable,
+            token.offset + delta,
+            token.length,
+            [variableName]);
+        return null;
+      }
+      return VariableReference(generator);
+    } else if (kind == _TokenKind.string) {
+      advance();
+      var lexeme = token.lexeme;
+      var value = lexeme.substring(1, lexeme.length - 1);
+      return LiteralString(value);
+    }
+    int offset;
+    int length;
+    if (token == null) {
+      if (tokens.isNotEmpty) {
+        token = tokens[tokens.length - 1];
+        offset = token.offset + delta;
+        length = token.length;
+      } else {
+        offset = delta;
+        length = 0;
+      }
+    } else {
+      offset = token.offset + delta;
+      length = token.length;
+    }
+    errorReporter.reportErrorForOffset(
+        TransformSetErrorCode.expectedPrimary, offset, length);
+    return null;
+  }
 }
 
 /// A scanner for the textual representation of a code fragment.
 class _CodeFragmentScanner {
   static final int $0 = '0'.codeUnitAt(0);
-
   static final int $9 = '9'.codeUnitAt(0);
-
   static final int $a = 'a'.codeUnitAt(0);
-
   static final int $z = 'z'.codeUnitAt(0);
-
   static final int $A = 'A'.codeUnitAt(0);
   static final int $Z = 'Z'.codeUnitAt(0);
+
+  static final int ampersand = '&'.codeUnitAt(0);
+  static final int bang = '!'.codeUnitAt(0);
   static final int closeSquareBracket = ']'.codeUnitAt(0);
   static final int carriageReturn = '\r'.codeUnitAt(0);
+  static final int equal = '='.codeUnitAt(0);
   static final int newline = '\n'.codeUnitAt(0);
   static final int openSquareBracket = '['.codeUnitAt(0);
   static final int period = '.'.codeUnitAt(0);
+  static final int singleQuote = "'".codeUnitAt(0);
   static final int space = ' '.codeUnitAt(0);
 
   /// The string being scanned.
@@ -195,8 +355,15 @@
   /// Return the tokens in the content, or `null` if there is an error in the
   /// content that prevents it from being scanned.
   List<_Token> scan() {
-    if (content.isEmpty) {}
     var length = content.length;
+
+    int peekAt(int offset) {
+      if (offset > length) {
+        return -1;
+      }
+      return content.codeUnitAt(offset);
+    }
+
     var offset = _skipWhitespace(0);
     var tokens = <_Token>[];
     while (offset < length) {
@@ -210,6 +377,33 @@
       } else if (char == period) {
         tokens.add(_Token(offset, _TokenKind.period, '.'));
         offset++;
+      } else if (char == ampersand) {
+        if (peekAt(offset + 1) != ampersand) {
+          return _reportInvalidCharacter(offset);
+        }
+        tokens.add(_Token(offset, _TokenKind.and, '&&'));
+        offset += 2;
+      } else if (char == bang) {
+        if (peekAt(offset + 1) != equal) {
+          return _reportInvalidCharacter(offset);
+        }
+        tokens.add(_Token(offset, _TokenKind.notEqual, '!='));
+        offset += 2;
+      } else if (char == equal) {
+        if (peekAt(offset + 1) != equal) {
+          return _reportInvalidCharacter(offset);
+        }
+        tokens.add(_Token(offset, _TokenKind.equal, '=='));
+        offset += 2;
+      } else if (char == singleQuote) {
+        var start = offset;
+        offset++;
+        while (offset < length && content.codeUnitAt(offset) != singleQuote) {
+          offset++;
+        }
+        offset++;
+        tokens.add(
+            _Token(start, _TokenKind.string, content.substring(start, offset)));
       } else if (_isLetter(char)) {
         var start = offset;
         offset++;
@@ -227,12 +421,7 @@
         tokens.add(_Token(
             start, _TokenKind.integer, content.substring(start, offset)));
       } else {
-        errorReporter.reportErrorForOffset(
-            TransformSetErrorCode.invalidCharacter,
-            offset + delta,
-            1,
-            [content.substring(offset, offset + 1)]);
-        return null;
+        return _reportInvalidCharacter(offset);
       }
       offset = _skipWhitespace(offset);
     }
@@ -250,6 +439,13 @@
   bool _isWhitespace(int char) =>
       char == space || char == newline || char == carriageReturn;
 
+  /// Report the presence of an invalid character at the given [offset].
+  Null _reportInvalidCharacter(int offset) {
+    errorReporter.reportErrorForOffset(TransformSetErrorCode.invalidCharacter,
+        offset + delta, 1, [content.substring(offset, offset + 1)]);
+    return null;
+  }
+
   /// Return the index of the first character at or after the given [offset]
   /// that isn't a whitespace character.
   int _skipWhitespace(int offset) {
@@ -284,26 +480,38 @@
 
 /// An indication of the kind of a token.
 enum _TokenKind {
+  and,
   closeSquareBracket,
+  equal,
   identifier,
   integer,
+  notEqual,
   openSquareBracket,
   period,
+  string,
 }
 
 extension on _TokenKind {
   String get displayName {
     switch (this) {
+      case _TokenKind.and:
+        return "'&&'";
       case _TokenKind.closeSquareBracket:
         return "']'";
+      case _TokenKind.equal:
+        return "'=='";
       case _TokenKind.identifier:
         return 'an identifier';
       case _TokenKind.integer:
         return 'an integer';
+      case _TokenKind.notEqual:
+        return "'!='";
       case _TokenKind.openSquareBracket:
         return "'['";
       case _TokenKind.period:
         return "'.'";
+      case _TokenKind.string:
+        return 'a string';
     }
     return '';
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart
index b5936f4..054de2a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart'
+    as data_driven;
 import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -15,9 +17,13 @@
   /// The components of the template.
   final List<TemplateComponent> components;
 
+  /// The expression used to determine whether the template is required to be
+  /// used, or `null` if the template is not required to be used.
+  final data_driven.Expression requiredIfCondition;
+
   /// Initialize a newly generated code template with the given [kind] and
   /// [components].
-  CodeTemplate(this.kind, this.components)
+  CodeTemplate(this.kind, this.components, this.requiredIfCondition)
       : assert(kind != null),
         assert(components != null);
 
@@ -41,8 +47,9 @@
 
 /// The kinds of code that can be generated by a template.
 enum CodeTemplateKind {
+  // We currently only support expressions, but we will likely need to support
+  // statements at some point.
   expression,
-  statements,
 }
 
 /// An object used to compute some portion of a template.
@@ -65,8 +72,45 @@
   /// The utilities used to help extract the code associated with various nodes.
   final CorrectionUtils utils;
 
-  /// Initialize a newly created variable support.
+  /// Initialize a newly created template context with the [node] and [utils].
   TemplateContext(this.node, this.utils);
+
+  /// Initialize a newly created template context that uses the invocation
+  /// containing the [node] and the [utils].
+  factory TemplateContext.forInvocation(AstNode node, CorrectionUtils utils) =>
+      TemplateContext(_getInvocation(node), utils);
+
+  /// Return the invocation containing the given [node]. The invocation will be
+  /// either an instance creation expression, function invocation, method
+  /// invocation, or an extension override.
+  static AstNode _getInvocation(AstNode node) {
+    if (node is ArgumentList) {
+      return node.parent;
+    } else if (node is InstanceCreationExpression ||
+        node is InvocationExpression) {
+      return node;
+    } else if (node is SimpleIdentifier) {
+      var parent = node.parent;
+      if (parent is ConstructorName) {
+        var grandparent = parent.parent;
+        if (grandparent is InstanceCreationExpression) {
+          return grandparent;
+        }
+      } else if (parent is Label && parent.parent is NamedExpression) {
+        return parent.parent.parent.parent;
+      } else if (parent is MethodInvocation && parent.methodName == node) {
+        return parent;
+      }
+    } else if (node is TypeArgumentList) {
+      var parent = node.parent;
+      if (parent is InvocationExpression) {
+        return parent;
+      } else if (parent is ExtensionOverride) {
+        return parent;
+      }
+    }
+    return null;
+  }
 }
 
 /// Literal text within a template.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.dart
new file mode 100644
index 0000000..96651b9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
+
+/// A binary expression.
+class BinaryExpression extends Expression {
+  /// The left operand.
+  final Expression leftOperand;
+
+  /// The operator.
+  final Operator operator;
+
+  /// The right operand.
+  final Expression rightOperand;
+
+  /// Initialize a newly created binary expression consisting of the
+  /// [leftOperand], [operator], and [rightOperand].
+  BinaryExpression(this.leftOperand, this.operator, this.rightOperand);
+
+  @override
+  Object evaluateIn(TemplateContext context) {
+    switch (operator) {
+      case Operator.and:
+        var left = leftOperand.evaluateIn(context);
+        var right = rightOperand.evaluateIn(context);
+        if (left is bool && right is bool) {
+          return left && right;
+        }
+        return null;
+      case Operator.equal:
+        var left = leftOperand.evaluateIn(context);
+        var right = rightOperand.evaluateIn(context);
+        return left == right;
+      case Operator.notEqual:
+        var left = leftOperand.evaluateIn(context);
+        var right = rightOperand.evaluateIn(context);
+        return left != right;
+    }
+    return null;
+  }
+}
+
+/// An expression.
+abstract class Expression {
+  /// Return the result of evaluating this expression.
+  Object evaluateIn(TemplateContext context);
+}
+
+/// A literal string.
+class LiteralString extends Expression {
+  /// The value of the literal string.
+  final String value;
+
+  /// Initialize a newly created literal string to have the given [value].
+  LiteralString(this.value);
+
+  @override
+  String evaluateIn(TemplateContext context) {
+    return value;
+  }
+}
+
+/// An operator used in a binary expression.
+enum Operator {
+  and,
+  equal,
+  notEqual,
+}
+
+/// A reference to a variable.
+class VariableReference extends Expression {
+  /// The generator used to generate the value of the variable.
+  final ValueGenerator generator;
+
+  /// Initialize a newly created variable reference to reference the variable
+  /// whose value is computed by the [generator].
+  VariableReference(this.generator);
+
+  @override
+  String evaluateIn(TemplateContext context) {
+    return generator.evaluateIn(context);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 78ae593..b73a574 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -59,6 +59,7 @@
     var argumentList = data.argumentList;
     var arguments = argumentList.arguments;
     var argumentCount = arguments.length;
+    var templateContext = TemplateContext(argumentList.parent, fix.utils);
     var newNamed = <AddParameter>[];
     var indexToNewArgumentMap = <int, AddParameter>{};
     var argumentsToInsert = <int>[];
@@ -72,6 +73,13 @@
           argumentsToInsert.add(index);
         } else if (modification.isRequired) {
           newNamed.add(modification);
+        } else {
+          var requiredIfCondition =
+              modification.argumentValue?.requiredIfCondition;
+          if (requiredIfCondition != null &&
+              requiredIfCondition.evaluateIn(templateContext)) {
+            newNamed.add(modification);
+          }
         }
       } else if (modification is RemoveParameter) {
         var argument = modification.parameter.argumentFrom(argumentList);
@@ -95,8 +103,7 @@
         builder.write(parameter.name);
         builder.write(': ');
       }
-      parameter.argumentValue
-          .writeOn(builder, TemplateContext(argumentList.parent, fix.utils));
+      parameter.argumentValue.writeOn(builder, templateContext);
     }
 
     var insertionRanges = argumentsToInsert.contiguousSubRanges.toList();
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
index 13b32f3..58eb217 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
@@ -66,6 +66,16 @@
   SimpleIdentifier validate(DataDrivenFix fix) {
     var node = fix.node;
     if (node is SimpleIdentifier) {
+      var parent = node.parent;
+      if (parent is Label && parent.parent is NamedExpression) {
+        var invocation = parent.parent.parent.parent;
+        if (invocation is InstanceCreationExpression) {
+          invocation.constructorName.name;
+        } else if (invocation is MethodInvocation) {
+          return invocation.methodName;
+        }
+        return null;
+      }
       return node;
     } else if (node is ConstructorName) {
       return node.name;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart
index 2cda293..20d7ff4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
 import 'package:meta/meta.dart';
@@ -23,7 +23,7 @@
   final ElementDescriptor element;
 
   /// A list containing the changes to be applied to affect the transform.
-  final List<Change> changes;
+  final ChangesSelector changesSelector;
 
   /// Initialize a newly created transform to describe a transformation of the
   /// [element].
@@ -32,7 +32,7 @@
       this.date,
       @required this.bulkApply,
       @required this.element,
-      @required this.changes});
+      @required this.changesSelector});
 
   /// Return `true` if this transform can be applied to fix an issue related to
   /// an element that matches the given [matcher]. The flag [applyingBulkFixes]
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index 7ea8635..508635c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -18,6 +18,12 @@
       "The key '{0}' can't be used when '{1}' is also used.");
 
   /**
+   * No parameters.
+   */
+  static const TransformSetErrorCode expectedPrimary = TransformSetErrorCode(
+      'expected_primary', "Expected either an identifier or a string literal.");
+
+  /**
    * Parameters:
    * 0: the character that is invalid
    */
@@ -32,6 +38,13 @@
       'invalid_key', "Keys must be of type 'String' but found the type '{0}'.");
 
   /**
+   * No parameters.
+   */
+  static const TransformSetErrorCode invalidRequiredIf = TransformSetErrorCode(
+      'invalid_required_if',
+      "The key 'requiredIf' can only be used with optional named parameters.");
+
+  /**
    * Parameters:
    * 0: the key with which the value is associated
    * 1: the expected type of the value
@@ -97,7 +110,14 @@
    * 0: the missing key
    */
   static const TransformSetErrorCode undefinedVariable = TransformSetErrorCode(
-      'undefined_variable', "The variable '{0}' is not defined.");
+      'undefined_variable', "The variable '{0}' isn't defined.");
+
+  /**
+   * Parameters:
+   * 0: the token that was unexpectedly found
+   */
+  static const TransformSetErrorCode unexpectedToken =
+      TransformSetErrorCode('unexpected_token', "Didn't expect to find {0}.");
 
   /**
    * Parameters:
@@ -122,7 +142,7 @@
   /**
    * Parameters:
    * 0: a description of the expected kind of token
-   * 1: a description of the actial kind of token
+   * 1: a description of the actual kind of token
    */
   static const TransformSetErrorCode wrongToken = TransformSetErrorCode(
       'wrong_token', "Expected to find {0}, but found {1}.");
@@ -135,10 +155,18 @@
       TransformSetErrorCode('yaml_syntax_error', "Parse error: {0}");
 
   /// Initialize a newly created error code.
-  const TransformSetErrorCode(String name, String message,
-      {String correction, bool hasPublishedDocs = false})
-      : super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+  const TransformSetErrorCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'TransformSetErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index ef73836..351608c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -4,10 +4,12 @@
 
 import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_fragment_parser.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -16,6 +18,7 @@
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/variable_scope.dart';
 import 'package:analysis_server/src/utilities/extensions/yaml.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:meta/meta.dart';
@@ -52,6 +55,7 @@
   static const String _fieldKey = 'field';
   static const String _functionKey = 'function';
   static const String _getterKey = 'getter';
+  static const String _ifKey = 'if';
   static const String _inClassKey = 'inClass';
   static const String _inEnumKey = 'inEnum';
   static const String _inExtensionKey = 'inExtension';
@@ -63,8 +67,9 @@
   static const String _nameKey = 'name';
   static const String _newNameKey = 'newName';
   static const String _oldNameKey = 'oldName';
+  static const String _oneOfKey = 'oneOf';
+  static const String _requiredIfKey = 'requiredIf';
   static const String _setterKey = 'setter';
-  static const String _statementsKey = 'statements';
   static const String _styleKey = 'style';
   static const String _titleKey = 'title';
   static const String _transformsKey = 'transforms';
@@ -117,8 +122,13 @@
   /// The error reporter to which diagnostics will be reported.
   final ErrorReporter errorReporter;
 
+  /// The name of the package from which the data file being translated was
+  /// found.
   final String packageName;
 
+  /// The variable scope defined for the current transform.
+  VariableScope transformVariableScope = VariableScope.empty;
+
   /// The parameter modifications associated with the current transform, or
   /// `null` if the current transform does not yet have any such modifications.
   List<ParameterModification> _parameterModifications;
@@ -141,8 +151,8 @@
 
   /// Convert the given [template] into a list of components. Variable
   /// references in the template are looked up in the map of [generators].
-  List<TemplateComponent> _extractTemplateComponents(String template,
-      Map<String, ValueGenerator> generators, int templateOffset) {
+  List<TemplateComponent> _extractTemplateComponents(
+      String template, VariableScope variableScope, int templateOffset) {
     var components = <TemplateComponent>[];
     var textStart = 0;
     var variableStart = template.indexOf(_openComponent);
@@ -163,7 +173,7 @@
         return components;
       } else {
         var name = template.substring(variableStart + 2, endIndex).trim();
-        var generator = generators[name];
+        var generator = variableScope.lookup(name);
         if (generator == null) {
           errorReporter.reportErrorForOffset(
               TransformSetErrorCode.undefinedVariable,
@@ -182,6 +192,8 @@
       // TODO(brianwilkerson) Check for an end brace without a start brace.
       components.add(TemplateText(template.substring(textStart)));
     }
+    // TODO(brianwilkerson) If there are no other errors, then report
+    //  unreferenced variables.
     return components;
   }
 
@@ -333,8 +345,10 @@
     }
     var isRequired = style.startsWith('required_');
     var isPositional = style.endsWith('_positional');
-    var argumentValue = _translateCodeTemplate(node.valueAt(_argumentValueKey),
-        ErrorContext(key: _argumentValueKey, parentNode: node));
+    var argumentValueNode = node.valueAt(_argumentValueKey);
+    var argumentValue = _translateCodeTemplate(argumentValueNode,
+        ErrorContext(key: _argumentValueKey, parentNode: node),
+        canBeConditionallyRequired: true);
     // TODO(brianwilkerson) We really ought to require an argument value for
     //  optional positional parameters too for the case where the added
     //  parameter is being added before the end of the list and call sites might
@@ -345,6 +359,18 @@
       // TODO(brianwilkerson) Report that required parameters must have an
       //  argument value.
       return;
+    } else if (argumentValue != null &&
+        argumentValue.requiredIfCondition != null) {
+      if (style != 'optional_named') {
+        var valueNode = argumentValueNode as YamlMap;
+        _reportError(TransformSetErrorCode.invalidRequiredIf,
+            valueNode.keyAtValue(valueNode.valueAt(_requiredIfKey)));
+        return;
+      } else if (argumentValue == null) {
+        // TODO(brianwilkerson) Report that conditionally required parameters must
+        //  have an argument value.
+        return;
+      }
     }
     _parameterModifications ??= [];
     _parameterModifications.add(
@@ -382,8 +408,9 @@
   }
 
   /// Translate the [node] into a bool. Return the resulting bool, or `null`
-  /// if the [node] does not represent a valid bool. If the [node] is not
-  /// valid, use the [context] to report the error.
+  /// if the [node] doesn't represent a valid bool. If the [node] isn't valid,
+  /// use the [context] to report the error. If the [node] doesn't exist and
+  /// [required] is `true`, then report an error.
   bool _translateBool(YamlNode node, ErrorContext context,
       {bool required = true}) {
     if (node is YamlScalar) {
@@ -451,7 +478,7 @@
       return null;
     }
     var accessors = CodeFragmentParser(errorReporter)
-        .parse(value, _offsetOfString(valueNode));
+        .parseAccessors(value, _offsetOfString(valueNode));
     if (accessors == null) {
       // The error has already been reported.
       return null;
@@ -460,41 +487,49 @@
   }
 
   /// Translate the [node] into a code template. Return the resulting template,
-  /// or `null` if the [node] does not represent a valid code template. If the
-  /// [node] is not valid, use the [context] to report the error.
+  /// or `null` if the [node] doesn't represent a valid code template. If the
+  /// [node] isn't valid, use the [context] to report the error. If the [node]
+  /// doesn't exist and [required] is `true`, then report an error.
   CodeTemplate _translateCodeTemplate(YamlNode node, ErrorContext context,
-      {bool required = true}) {
+      {bool canBeConditionallyRequired = false, bool required = true}) {
     if (node is YamlMap) {
-      CodeTemplateKind kind;
-      int templateOffset;
-      String template;
-      var expressionNode = node.valueAt(_expressionKey);
-      if (expressionNode != null) {
-        _reportUnsupportedKeys(node, const {_expressionKey, _variablesKey});
-        kind = CodeTemplateKind.expression;
-        templateOffset = _offsetOfString(expressionNode);
-        template = _translateString(expressionNode,
-            ErrorContext(key: _expressionKey, parentNode: node));
+      if (canBeConditionallyRequired) {
+        _reportUnsupportedKeys(
+            node, const {_expressionKey, _requiredIfKey, _variablesKey});
       } else {
-        var statementsNode = node.valueAt(_statementsKey);
-        if (statementsNode != null) {
-          _reportUnsupportedKeys(node, const {_statementsKey, _variablesKey});
-          kind = CodeTemplateKind.statements;
-          templateOffset = _offsetOfString(statementsNode);
-          template = _translateString(statementsNode,
-              ErrorContext(key: _statementsKey, parentNode: node));
-        } else {
-          _reportError(TransformSetErrorCode.missingOneOfMultipleKeys, node,
-              ["'$_expressionKey' or '$_statementsKey'"]);
-          return null;
+        _reportUnsupportedKeys(node, const {_expressionKey, _variablesKey});
+      }
+      var expressionNode = node.valueAt(_expressionKey);
+      var template = _translateString(
+          expressionNode, ErrorContext(key: _expressionKey, parentNode: node));
+      var variableScope = _translateTemplateVariables(
+          node.valueAt(_variablesKey),
+          ErrorContext(key: _variablesKey, parentNode: node));
+      Expression requiredIfCondition;
+      if (canBeConditionallyRequired) {
+        var requiredIfNode = node.valueAt(_requiredIfKey);
+        var requiredIfText = _translateString(
+            requiredIfNode, ErrorContext(key: _requiredIfKey, parentNode: node),
+            required: false);
+        if (requiredIfText != null) {
+          requiredIfCondition = CodeFragmentParser(errorReporter,
+                  scope: variableScope)
+              .parseCondition(requiredIfText, _offsetOfString(requiredIfNode));
+          if (requiredIfCondition == null) {
+            // The error has already been reported.
+            return null;
+          }
         }
       }
-      // TODO(brianwilkerson) We should report unreferenced variables.
-      var generators = _translateTemplateVariables(node.valueAt(_variablesKey),
-          ErrorContext(key: _variablesKey, parentNode: node));
+      if (template == null) {
+        // The error has already been reported.
+        return null;
+      }
+      var templateOffset = _offsetOfString(expressionNode);
       var components =
-          _extractTemplateComponents(template, generators, templateOffset);
-      return CodeTemplate(kind, components);
+          _extractTemplateComponents(template, variableScope, templateOffset);
+      return CodeTemplate(
+          CodeTemplateKind.expression, components, requiredIfCondition);
     } else if (node == null) {
       if (required) {
         _reportMissingKey(context);
@@ -505,6 +540,47 @@
     }
   }
 
+  void _translateConditionalChange(YamlNode node, ErrorContext context,
+      Map<Expression, List<Change>> changeMap) {
+    if (node is YamlMap) {
+      _reportUnsupportedKeys(node, const {_ifKey, _changesKey});
+      var expressionNode = node.valueAt(_ifKey);
+      var expressionText = _translateString(
+          expressionNode, ErrorContext(key: _ifKey, parentNode: node));
+      var changes = _translateList(node.valueAt(_changesKey),
+          ErrorContext(key: _changesKey, parentNode: node), _translateChange);
+      if (_parameterModifications != null) {
+        if (changes != null) {
+          changes.add(ModifyParameters(modifications: _parameterModifications));
+        }
+        _parameterModifications = null;
+      }
+      if (expressionText != null && changes != null) {
+        var expression = CodeFragmentParser(errorReporter,
+                scope: transformVariableScope)
+            .parseCondition(expressionText, _offsetOfString(expressionNode));
+        if (expression != null) {
+          changeMap[expression] = changes;
+        }
+      }
+    } else {
+      return _reportInvalidValue(node, context, 'Map');
+    }
+  }
+
+  ChangesSelector _translateConditionalChanges(
+      YamlNode node, ErrorContext context) {
+    if (node is YamlList) {
+      var changeMap = <Expression, List<Change>>{};
+      for (var element in node.nodes) {
+        _translateConditionalChange(element, context, changeMap);
+      }
+      return ConditionalChangesSelector(changeMap);
+    } else {
+      return _reportInvalidValue(node, context, 'List');
+    }
+  }
+
   /// Translate the [node] into a date. Return the resulting date, or `null`
   /// if the [node] does not represent a valid date. If the [node] is not
   /// valid, use the [context] to report the error.
@@ -746,8 +822,9 @@
   }
 
   /// Translate the [node] into a string. Return the resulting string, or `null`
-  /// if the [node] does not represent a valid string. If the [node] is not
-  /// valid, use the [context] to report the error.
+  /// if the [node] doesn't represent a valid string. If the [node] isn't valid,
+  /// use the [context] to report the error. If the [node] doesn't exist and
+  /// [required] is `true`, then report an error.
   String _translateString(YamlNode node, ErrorContext context,
       {bool required = true}) {
     if (node is YamlScalar) {
@@ -766,11 +843,10 @@
     }
   }
 
-  /// Translate the [node] into a list of template components. Return the
-  /// resulting list, or `null` if the [node] does not represent a valid
-  /// variables map. If the [node] is not valid, use the [context] to report the
-  /// error.
-  Map<String, ValueGenerator> _translateTemplateVariables(
+  /// Translate the [node] into a variable scope. Return the resulting scope, or
+  /// the enclosing scope if the [node] does not represent a valid variables
+  /// map. If the [node] is not valid, use the [context] to report the error.
+  VariableScope _translateTemplateVariables(
       YamlNode node, ErrorContext context) {
     if (node is YamlMap) {
       var generators = <String, ValueGenerator>{};
@@ -784,11 +860,12 @@
           }
         }
       }
-      return generators;
+      return VariableScope(transformVariableScope, generators);
     } else if (node == null) {
-      return const {};
+      return transformVariableScope;
     } else {
-      return _reportInvalidValue(node, context, 'Map');
+      _reportInvalidValue(node, context, 'Map');
+      return transformVariableScope;
     }
   }
 
@@ -798,8 +875,15 @@
   Transform _translateTransform(YamlNode node, ErrorContext context) {
     assert(node != null);
     if (node is YamlMap) {
-      _reportUnsupportedKeys(node,
-          const {_bulkApplyKey, _changesKey, _dateKey, _elementKey, _titleKey});
+      _reportUnsupportedKeys(node, const {
+        _bulkApplyKey,
+        _changesKey,
+        _dateKey,
+        _elementKey,
+        _oneOfKey,
+        _titleKey,
+        _variablesKey
+      });
       var title = _translateString(node.valueAt(_titleKey),
           ErrorContext(key: _titleKey, parentNode: node));
       var date = _translateDate(node.valueAt(_dateKey),
@@ -810,22 +894,47 @@
           true;
       var element = _translateElement(node.valueAt(_elementKey),
           ErrorContext(key: _elementKey, parentNode: node));
-      var changes = _translateList(node.valueAt(_changesKey),
-          ErrorContext(key: _changesKey, parentNode: node), _translateChange);
-      if (title == null || date == null || element == null || changes == null) {
+      transformVariableScope = _translateTemplateVariables(
+          node.valueAt(_variablesKey),
+          ErrorContext(key: _variablesKey, parentNode: node));
+      ChangesSelector selector;
+      var key = _singleKey(
+          node, const [_changesKey, _oneOfKey], context.parentNode,
+          required: true);
+      if (key == _oneOfKey) {
+        selector = _translateConditionalChanges(node.valueAt(_oneOfKey),
+            ErrorContext(key: _oneOfKey, parentNode: node));
+      } else if (key == _changesKey) {
+        var changes = _translateList(node.valueAt(_changesKey),
+            ErrorContext(key: _changesKey, parentNode: node), _translateChange);
+        if (changes == null) {
+          // The error has already been reported.
+          _parameterModifications = null;
+          return null;
+        }
+        if (_parameterModifications != null) {
+          changes.add(ModifyParameters(modifications: _parameterModifications));
+          _parameterModifications = null;
+        }
+        selector = UnconditionalChangesSelector(changes);
+      } else {
         // The error has already been reported.
         return null;
       }
-      if (_parameterModifications != null) {
-        changes.add(ModifyParameters(modifications: _parameterModifications));
-        _parameterModifications = null;
+      transformVariableScope = VariableScope.empty;
+      if (title == null ||
+          date == null ||
+          element == null ||
+          selector == null) {
+        // The error has already been reported.
+        return null;
       }
       return Transform(
           title: title,
           date: date,
           bulkApply: bulkApply,
           element: element,
-          changes: changes);
+          changesSelector: selector);
     } else {
       return _reportInvalidValue(node, context, 'Map');
     }
@@ -873,8 +982,9 @@
   }
 
   /// Translate the [node] into a URI. Return the resulting URI, or `null` if
-  /// the [node] does not represent a valid URI. If the [node] is not valid, use
-  /// the [context] to report the error.
+  /// the [node] doesn't represent a valid URI. If the [node] isn't valid, use
+  /// the [context] to report the error. If the [node] doesn't exist and
+  /// [required] is `true`, then report an error.
   Uri _translateUri(YamlNode node, ErrorContext context,
       {bool required = true}) {
     if (node is YamlScalar) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart
index 659bb47..b59bac9 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart
@@ -19,6 +19,23 @@
   CodeFragment(this.accessors);
 
   @override
+  String evaluateIn(TemplateContext context) {
+    Object target = context.node;
+    for (var accessor in accessors) {
+      target = accessor.getValue(target).result;
+    }
+    if (target is AstNode) {
+      return context.utils.getRangeText(range.node(target));
+    } else if (target is DartType) {
+      // TODO(brianwilkerson) If we end up needing it, figure out how to convert
+      //  a type into valid code.
+      throw UnsupportedError('Unexpected result of ${target.runtimeType}');
+    } else {
+      throw UnsupportedError('Unexpected result of ${target.runtimeType}');
+    }
+  }
+
+  @override
   bool validate(TemplateContext context) {
     Object target = context.node;
     for (var accessor in accessors) {
@@ -59,6 +76,11 @@
   ImportedName(this.uris, this.name);
 
   @override
+  String evaluateIn(TemplateContext context) {
+    return name;
+  }
+
+  @override
   bool validate(TemplateContext context) {
     // TODO(brianwilkerson) Validate that the import can be added.
     return true;
@@ -72,6 +94,10 @@
 
 /// An object used to generate the value of a template variable.
 abstract class ValueGenerator {
+  /// Return the value generated by this generator, using the [context] to
+  /// access needed information that isn't already known to this generator.
+  String evaluateIn(TemplateContext context);
+
   /// Use the [context] to validate that this generator will be able to generate
   /// a value.
   bool validate(TemplateContext context);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/variable_scope.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/variable_scope.dart
new file mode 100644
index 0000000..0ae0c27
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/variable_scope.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
+
+/// A scope in which the generators associated with variables can be looked up.
+class VariableScope {
+  /// An empty variable scope.
+  static final empty = VariableScope(null, {});
+
+  /// The outer scope in which this scope is nested.
+  final VariableScope outerScope;
+
+  /// A table mapping variable names to generators.
+  final Map<String, ValueGenerator> _generators;
+
+  /// Initialize a newly created variable scope defining the variables in the
+  /// [_generators] map. Any variables not defined locally will be looked up in
+  /// the [outerScope].
+  VariableScope(this.outerScope, this._generators);
+
+  /// Return the generator used to generate the value of the variable with the
+  /// given [variableName], or `null` if the variable is not defined.
+  ValueGenerator lookup(String variableName) {
+    return _generators[variableName] ?? outerScope?.lookup(variableName);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 30ab805..5995aaf 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -160,6 +160,7 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     hide AnalysisError, Element, ElementKind;
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart' hide FixContributor;
 
 /// A function that can be executed to create a multi-correction producer.
@@ -209,13 +210,14 @@
     // one.
     // For each fix, put the fix into the HashMap.
     for (var i = 0; i < allAnalysisErrors.length; i++) {
-      final FixContext fixContextI = DartFixContextImpl(
+      final FixContext fixContext = DartFixContextImpl(
+        context.instrumentationService,
         context.workspace,
         context.resolveResult,
         allAnalysisErrors[i],
         (name) => [],
       );
-      var processorI = FixProcessor(fixContextI);
+      var processorI = FixProcessor(fixContext);
       var fixesListI = await processorI.compute();
       for (var f in fixesListI) {
         if (!map.containsKey(f.kind)) {
@@ -227,11 +229,11 @@
     }
 
     // For each FixKind in the HashMap, union each list together, then return
-    // the set of unioned Fixes.
+    // the set of unioned fixes.
     var result = <Fix>[];
-    map.forEach((FixKind kind, List<Fix> fixesListJ) {
-      if (fixesListJ.first.kind.canBeAppliedTogether()) {
-        var unionFix = _unionFixList(fixesListJ);
+    map.forEach((FixKind kind, List<Fix> fixesList) {
+      if (fixesList.first.kind.canBeAppliedTogether()) {
+        var unionFix = _unionFixList(fixesList);
         if (unionFix != null) {
           result.add(unionFix);
         }
@@ -644,6 +646,9 @@
     CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT: [
       AddAsync.newInstance,
     ],
+    CompileTimeErrorCode.BODY_MIGHT_COMPLETE_NORMALLY: [
+      AddAsync.missingReturn,
+    ],
     CompileTimeErrorCode.CAST_TO_NON_TYPE: [
       ChangeTo.classOrMixin,
       CreateClass.newInstance,
@@ -957,6 +962,9 @@
     HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS: [
       AddMissingRequiredArgument.newInstance,
     ],
+    HintCode.MISSING_RETURN: [
+      AddAsync.missingReturn,
+    ],
     HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE: [
       RemoveQuestionMark.newInstance,
     ],
@@ -1134,9 +1142,15 @@
       producer.configure(context);
       var builder = ChangeBuilder(
           workspace: context.workspace, eol: context.utils.endOfLine);
-      await producer.compute(builder);
-      _addFixFromBuilder(builder, producer.fixKind,
-          args: producer.fixArguments);
+      try {
+        await producer.compute(builder);
+        _addFixFromBuilder(builder, producer.fixKind,
+            args: producer.fixArguments);
+      } on ConflictingEditException catch (exception, stackTrace) {
+        // Handle the exception by (a) not adding a fix based on the producer
+        // and (b) logging the exception.
+        fixContext.instrumentationService.logException(exception, stackTrace);
+      }
     }
 
     var errorCode = error.errorCode;
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index c21363f..96e8e89 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -32,7 +32,7 @@
     }
     return tokens;
   } catch (e) {
-    return List<Token>(0);
+    return List<Token>.filled(0, null);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 59dca74..46b3f03 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -422,7 +422,7 @@
     }
   }
   // fill array of parents
-  var parents = List<AstNode>(numParents);
+  var parents = List<AstNode>.filled(numParents, null);
   var current = node.parent;
   var index = numParents;
   while (current != null) {
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 25ad0f77..b86d18d 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -17,7 +17,9 @@
 
 abstract class AbstractSocketServer {
   AbstractAnalysisServer get analysisServer;
+
   AnalysisServerOptions get analysisServerOptions;
+
   DiagnosticServer get diagnosticServer;
 }
 
@@ -66,18 +68,8 @@
       return;
     }
 
-    PhysicalResourceProvider resourceProvider;
-    if (analysisServerOptions.fileReadMode == 'as-is') {
-      resourceProvider = PhysicalResourceProvider(null,
-          stateLocation: analysisServerOptions.cacheFolder);
-    } else if (analysisServerOptions.fileReadMode == 'normalize-eol-always') {
-      resourceProvider = PhysicalResourceProvider(
-          PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS,
-          stateLocation: analysisServerOptions.cacheFolder);
-    } else {
-      throw Exception(
-          'File read mode was set to the unknown mode: $analysisServerOptions.fileReadMode');
-    }
+    var resourceProvider = PhysicalResourceProvider(
+        stateLocation: analysisServerOptions.cacheFolder);
 
     analysisServer = AnalysisServer(
       serverChannel,
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index bd39067..8f04747 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -16,7 +16,6 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/server/http_server.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analysis_server/src/status/ast_writer.dart';
 import 'package:analysis_server/src/status/element_writer.dart';
@@ -759,7 +758,6 @@
     // Add server-specific pages. Ordering doesn't matter as the items are
     // sorted later.
     var server = socketServer.analysisServer;
-    pages.add(MLCompletionPage(this, server));
     pages.add(PluginsPage(this, server));
 
     if (server is AnalysisServer) {
@@ -1074,100 +1072,6 @@
   }
 }
 
-class MLCompletionPage extends DiagnosticPageWithNav {
-  @override
-  final AbstractAnalysisServer server;
-
-  MLCompletionPage(DiagnosticsSite site, this.server)
-      : super(site, 'ml-completion', 'ML Completion',
-            description: 'Statistics for ML code completion.');
-
-  path.Context get pathContext => server.resourceProvider.pathContext;
-
-  @override
-  Future<void> generateContent(Map<String, String> params) async {
-    var hasMLComplete = CompletionRanking.instance != null;
-    if (!hasMLComplete) {
-      blankslate('''ML code completion is not enabled (see <a
-href="https://github.com/dart-lang/sdk/wiki/Previewing-Dart-code-completions-powered-by-machine-learning"
->previewing Dart ML completion</a> for how to enable it).''');
-      return;
-    }
-
-    buf.writeln('ML completion enabled.<br>');
-
-    var isolateTimes = CompletionRanking
-        .instance.performanceMetrics.isolateInitTimes
-        .map((Duration time) {
-      return '${time.inMilliseconds}ms';
-    }).join(', ');
-    p('ML isolate init times: $isolateTimes');
-
-    var predictions = CompletionRanking
-        .instance.performanceMetrics.predictionResults
-        .toList();
-
-    if (predictions.isEmpty) {
-      blankslate('No completions recorded.');
-      return;
-    }
-
-    p('${CompletionRanking.instance.performanceMetrics.predictionRequestCount} '
-        'requests');
-
-    // draw a chart
-    buf.writeln(
-        '<div id="chart-div" style="width: 700px; height: 300px;"></div>');
-    var rowData = StringBuffer();
-    for (var prediction in predictions.reversed) {
-      // [' ', 101.5]
-      if (rowData.isNotEmpty) {
-        rowData.write(',');
-      }
-      rowData.write("[' ', ${prediction.elapsedTime.inMilliseconds}]");
-    }
-    buf.writeln('''
-      <script type="text/javascript">
-      google.charts.load('current', {'packages':['bar']});
-      google.charts.setOnLoadCallback(drawChart);
-      function drawChart() {
-        var data = google.visualization.arrayToDataTable([
-          ['Completions', 'Time'],
-          $rowData
-        ]);
-        var options = { bars: 'vertical', vAxis: {format: 'decimal'}, height: 300 };
-        var chart = new google.charts.Bar(document.getElementById('chart-div'));
-        chart.draw(data, google.charts.Bar.convertOptions(options));
-      }
-      </script>
-''');
-
-    String summarize(PredictionResult prediction) {
-      var entries = prediction.results.entries.toList();
-      entries.sort((a, b) => b.value.compareTo(a.value));
-      var summary = entries
-          .take(3)
-          .map((entry) => '"${entry.key}":${entry.value.toStringAsFixed(3)}')
-          .join('<br>');
-      return summary;
-    }
-
-    // emit the data as a table
-    buf.writeln('<table>');
-    buf.writeln(
-        '<tr><th>Time</th><th>Results</th><th>Snippet</th><th>Top suggestions</th></tr>');
-    for (var prediction in predictions) {
-      buf.writeln('<tr>'
-          '<td class="pre right">${printMilliseconds(prediction.elapsedTime.inMilliseconds)}</td>'
-          '<td class="right">${prediction.results.length}</td>'
-          '<td><code>${escape(prediction.snippet)}</code></td>'
-          '<td class="right">${summarize(prediction)}</td>'
-          '</tr>');
-    }
-    buf.writeln('</table>');
-  }
-}
-
 class NotFoundPage extends DiagnosticPage {
   @override
   final String path;
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart b/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
index 0107f62..6ce971a 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
@@ -5,6 +5,17 @@
 import 'package:yaml/yaml.dart';
 
 extension YamlMapExtensions on YamlMap {
+  /// Return the node representing the key that corresponds to the value
+  /// represented by the [value] node.
+  YamlNode keyAtValue(YamlNode value) {
+    for (var entry in nodes.entries) {
+      if (entry.value == value) {
+        return entry.key;
+      }
+    }
+    return null;
+  }
+
   /// Return the value associated with the key whose value matches the given
   /// [key], or `null` if there is no matching key.
   YamlNode valueAt(String key) {
@@ -16,3 +27,49 @@
     return null;
   }
 }
+
+extension YamlNodeExtensions on YamlNode {
+  /// Return the child of this node that contains the given [offset], or `null`
+  /// if none of the children contains the offset.
+  YamlNode childContainingOffset(int offset) {
+    var node = this;
+    if (node is YamlList) {
+      for (var element in node.nodes) {
+        if (element.containsOffset(offset)) {
+          return element;
+        }
+      }
+      for (var element in node.nodes) {
+        if (element is YamlScalar && element.value == null) {
+          // TODO(brianwilkerson) Testing for a null value probably gets
+          //  confused when there are multiple null values.
+          return element;
+        }
+      }
+    } else if (node is YamlMap) {
+      for (var entry in node.nodes.entries) {
+        if ((entry.key as YamlNode).containsOffset(offset)) {
+          return entry.key;
+        }
+        var value = entry.value;
+        if (value.containsOffset(offset) ||
+            (value is YamlScalar && value.value == null)) {
+          // TODO(brianwilkerson) Testing for a null value probably gets
+          //  confused when there are multiple null values or when there is a
+          //  null value before the node that actually contains the offset.
+          return entry.value;
+        }
+      }
+    }
+    return null;
+  }
+
+  /// Return `true` if this node contains the given [offset].
+  bool containsOffset(int offset) {
+    // TODO(brianwilkerson) Nodes at the end of the file contain any trailing
+    //  whitespace. This needs to be accounted for, here or elsewhere.
+    var nodeOffset = span.start.offset;
+    var nodeEnd = nodeOffset + span.length;
+    return nodeOffset <= offset && offset <= nodeEnd;
+  }
+}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index da3e6a6..ef86eeb 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -8,8 +8,10 @@
 dependencies:
   _fe_analyzer_shared:
     path: ../_fe_analyzer_shared
-  analyzer: any
-  analyzer_plugin: any
+  analyzer:
+    path: ../analyzer
+  analyzer_plugin:
+    path: ../analyzer_plugin
   args: any
   cli_util: any
   collection: any
@@ -19,18 +21,19 @@
   html: any
   intl: any
   linter: any
-  meta: any
+  meta:
+    path: ../meta
   stream_channel: any
   telemetry:
     path: ../telemetry
   test: any
   path: any
-  tflite_native: any
   watcher: any
   yaml: any
 
 dev_dependencies:
-  analysis_tool: any
+  analyzer_utilities:
+    path: ../analyzer_utilities
   http: any
   logging: any
   matcher: any
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 7d5e49a..9c2c7e9 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -270,23 +269,7 @@
 
 mixin WithNullSafetyMixin on AbstractContextTest {
   @override
-  String get testPackageLanguageVersion =>
-      Feature.non_nullable.isEnabledByDefault ? '2.12' : '2.11';
-
-  bool get withPackageMeta => false;
-
-  /// TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-  /// Remove when Null Safety is enabled by default.
-  @nonVirtual
-  @override
-  void setUp() {
-    super.setUp();
-    writeTestPackageConfig(
-      languageVersion: testPackageLanguageVersion,
-      meta: withPackageMeta,
-    );
-    createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
-  }
+  String get testPackageLanguageVersion => '2.12';
 }
 
 /// Wraps the given [_ElementVisitorFunction] into an instance of
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 411e163..8d9c2bb 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -1142,7 +1142,6 @@
   @override
   void setUp() {
     super.setUp();
-    server.options.useAnalysisHighlight2 = true;
     createProject();
   }
 
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
deleted file mode 100644
index 9432795..0000000
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ /dev/null
@@ -1,1194 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../analysis_abstract.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisNotificationHighlightsTest);
-    defineReflectiveTests(HighlightsWithControlFlowCollectionsTest);
-    defineReflectiveTests(HighlightsWithNullSafetyTest);
-    defineReflectiveTests(HighlightTypeTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
-  Future<void> test_ANNOTATION_hasArguments() async {
-    addTestFile('''
-class AAA {
-  const AAA(a, b, c);
-}
-@AAA(1, 2, 3) main() {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
-    assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
-  }
-
-  Future<void> test_ANNOTATION_noArguments() async {
-    addTestFile('''
-const AAA = 42;
-@AAA main() {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
-  }
-
-  Future<void> test_BUILT_IN_abstract() async {
-    addTestFile('''
-abstract class A {};
-abstract class B = Object with A;
-main() {
-  var abstract = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
-  }
-
-  Future<void> test_BUILT_IN_as() async {
-    addTestFile('''
-import 'dart:math' as math;
-main() {
-  p as int;
-  var as = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
-  }
-
-  Future<void> test_BUILT_IN_async() async {
-    addTestFile('''
-fa() async {}
-fb() async* {}
-main() {
-  bool async = false;
-}
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
-  }
-
-  Future<void> test_BUILT_IN_await() async {
-    addTestFile('''
-main() async {
-  await 42;
-  await for (var item in []) {
-    print(item);
-  }
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
-  }
-
-  Future<void> test_BUILT_IN_deferred() async {
-    addTestFile('''
-import 'dart:math' deferred as math;
-main() {
-  var deferred = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
-  }
-
-  Future<void> test_BUILT_IN_export() async {
-    addTestFile('''
-export "dart:math";
-main() {
-  var export = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
-  }
-
-  Future<void> test_BUILT_IN_external() async {
-    addTestFile('''
-class A {
-  external A();
-  external aaa();
-}
-external main() {
-  var external = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
-  }
-
-  Future<void> test_BUILT_IN_factory() async {
-    addTestFile('''
-class A {
-  A.named();
-  factory A() => A();
-}
-main() {
-  var factory = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
-  }
-
-  Future<void> test_BUILT_IN_get() async {
-    addTestFile('''
-get aaa => 1;
-class A {
-  get bbb => 2;
-}
-main() {
-  var get = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
-  }
-
-  Future<void> test_BUILT_IN_hide() async {
-    addTestFile('''
-import 'foo.dart' hide Foo;
-main() {
-  var hide = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
-  }
-
-  Future<void> test_BUILT_IN_implements() async {
-    addTestFile('''
-class A {}
-class B implements A {}
-main() {
-  var implements = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
-  }
-
-  Future<void> test_BUILT_IN_import() async {
-    addTestFile('''
-import "foo.dart";
-main() {
-  var import = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
-  }
-
-  Future<void> test_BUILT_IN_library() async {
-    addTestFile('''
-library lib;
-main() {
-  var library = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
-  }
-
-  Future<void> test_BUILT_IN_native() async {
-    addTestFile('''
-class A native "A_native" {}
-class B {
-  bbb() native "bbb_native";
-}
-main() {
-  var native = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
-  }
-
-  Future<void> test_BUILT_IN_on_inMixin() async {
-    addTestFile('''
-mixin M on N {}
-class N {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'on N');
-  }
-
-  Future<void> test_BUILT_IN_on_inTry() async {
-    addTestFile('''
-main() {
-  try {
-  } on int catch (e) {
-  }
-  var on = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
-  }
-
-  Future<void> test_BUILT_IN_operator() async {
-    addTestFile('''
-class A {
-  operator +(x) => null;
-}
-main() {
-  var operator = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
-  }
-
-  Future<void> test_BUILT_IN_part() async {
-    addTestFile('''
-part "my_part.dart";
-main() {
-  var part = 42;
-}''');
-    newFile('/project/bin/my_part.dart', content: 'part of lib;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
-  }
-
-  Future<void> test_BUILT_IN_partOf() async {
-    addTestFile('''
-part of lib;
-main() {
-  var part = 1;
-  var of = 2;
-}''');
-    _addLibraryForTestPart();
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
-  }
-
-  Future<void> test_BUILT_IN_set() async {
-    addTestFile('''
-set aaa(x) {}
-class A
-  set bbb(x) {}
-}
-main() {
-  var set = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
-  }
-
-  Future<void> test_BUILT_IN_show() async {
-    addTestFile('''
-import 'foo.dart' show Foo;
-main() {
-  var show = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
-  }
-
-  Future<void> test_BUILT_IN_static() async {
-    addTestFile('''
-class A {
-  static aaa;
-  static bbb() {}
-}
-main() {
-  var static = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
-  }
-
-  Future<void> test_BUILT_IN_sync() async {
-    addTestFile('''
-fa() sync {}
-fb() sync* {}
-main() {
-  bool sync = false;
-}
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
-  }
-
-  Future<void> test_BUILT_IN_typedef() async {
-    addTestFile('''
-typedef A();
-main() {
-  var typedef = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
-  }
-
-  Future<void> test_BUILT_IN_yield() async {
-    addTestFile('''
-main() async* {
-  yield 42;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
-  }
-
-  Future<void> test_BUILT_IN_yieldStar() async {
-    addTestFile('''
-main() async* {
-  yield* [];
-}
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
-  }
-
-  Future<void> test_CLASS() async {
-    addTestFile('''
-class AAA {}
-AAA aaa;
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
-    assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
-  }
-
-  Future<void> test_CLASS_notDynamic() async {
-    addTestFile('''
-dynamic f() {}
-''');
-    await prepareHighlights();
-    assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
-  }
-
-  Future<void> test_CLASS_notVoid() async {
-    addTestFile('''
-void f() {}
-''');
-    await prepareHighlights();
-    assertNoRegion(HighlightRegionType.CLASS, 'void f()');
-  }
-
-  Future<void> test_COMMENT() async {
-    addTestFile('''
-/**
- * documentation comment
- */
-void main() {
-  // end-of-line comment
-  my_function(1);
-}
-
-void my_function(String a) {
- /* block comment */
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
-    assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
-    assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
-  }
-
-  Future<void> test_CONSTRUCTOR_explicitNew() async {
-    addTestFile('''
-class AAA<T> {
-  AAA() {}
-  AAA.name(p) {}
-}
-main() {
-  new AAA<int>();
-  new AAA<int>.name(42);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>.name(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>.name(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
-  }
-
-  Future<void> test_CONSTRUCTOR_implicitNew() async {
-    addTestFile('''
-class AAA<T> {
-  AAA() {}
-  AAA.name(p) {}
-}
-main() {
-  AAA<int>();
-  AAA<int>.name(42);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>.name(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>.name(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
-  }
-
-  Future<void> test_DIRECTIVE() async {
-    addTestFile('''
-library lib;
-import 'dart:math';
-export 'dart:math';
-part 'part.dart';
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'library lib;');
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';");
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';");
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
-  }
-
-  Future<void> test_DIRECTIVE_partOf() async {
-    addTestFile('''
-part of lib;
-''');
-    _addLibraryForTestPart();
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'part of lib;');
-  }
-
-  Future<void> test_DYNAMIC_TYPE() async {
-    addTestFile('''
-f() {}
-main(p) {
-  print(p);
-  var v1 = f();
-  int v2;
-  var v3 = v2;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'p)');
-    assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'v1 =');
-    assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v2;');
-    assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v3 =');
-  }
-
-  Future<void> test_ENUM() async {
-    addTestFile('''
-enum MyEnum {A, B, C}
-MyEnum value;
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
-    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
-  }
-
-  Future<void> test_ENUM_CONSTANT() async {
-    addTestFile('''
-enum MyEnum {AAA, BBB}
-main() {
-  print(MyEnum.AAA);
-  print(MyEnum.BBB);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
-  }
-
-  Future<void> test_FIELD() async {
-    addTestFile('''
-class A {
-  int aaa = 1;
-  int bbb = 2;
-  A([this.bbb = 3]);
-}
-main(A a) {
-  a.aaa = 4;
-  a.bbb = 5;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FIELD, 'aaa = 1');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 3');
-    assertHasRegion(HighlightRegionType.FIELD, 'aaa = 4');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 5');
-  }
-
-  Future<void> test_FIELD_STATIC() async {
-    addTestFile('''
-class A {
-  static aaa = 1;
-  static get bbb => null;
-  static set ccc(x) {}
-}
-main() {
-  A.aaa = 2;
-  A.bbb;
-  A.ccc = 3;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 1');
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 2');
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'bbb;');
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'ccc = 3');
-  }
-
-  Future<void> test_FUNCTION() async {
-    addTestFile('''
-fff(p) {}
-main() {
-  fff(42);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FUNCTION_DECLARATION, 'fff(p) {}');
-    assertHasRegion(HighlightRegionType.FUNCTION, 'fff(42)');
-  }
-
-  Future<void> test_FUNCTION_TYPE_ALIAS() async {
-    addTestFile('''
-typedef FFF(p);
-main(FFF fff) {
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
-    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
-  }
-
-  Future<void> test_GETTER_DECLARATION() async {
-    addTestFile('''
-get aaa => null;
-class A {
-  get bbb => null;
-}
-main(A a) {
-  aaa;
-  a.bbb;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'aaa => null');
-    assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'bbb => null');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa;');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb;');
-  }
-
-  Future<void> test_IDENTIFIER_DEFAULT() async {
-    addTestFile('''
-main() {
-  aaa = 42;
-  bbb(84);
-  CCC ccc;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
-    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
-    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
-  }
-
-  Future<void> test_IMPORT_PREFIX() async {
-    addTestFile('''
-import 'dart:math' as ma;
-main() {
-  ma.max(1, 2);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
-    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
-  }
-
-  Future<void> test_KEYWORD() async {
-    addTestFile('''
-main() {
-  assert(true);
-  for (;;) break;
-  switch (0) {
-    case 0: break;
-    default: break;
-  }
-  try {} catch (e) {}
-  const v1 = 0;
-  for (;;) continue;
-  do {} while (true);
-  if (true) {} else {}
-  var v2 = false;
-  final v3 = 1;
-  try {} finally {}
-  for (var v4 in []) {}
-  v3 is int;
-  new A();
-  try {} catch (e) {rethrow;}
-  var v5 = true;
-  while (true) {}
-}
-class A {}
-class B extends A {
-  B() : super();
-  m() {
-    return this;
-  }
-}
-class C = Object with A;
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
-  }
-
-  Future<void> test_KEYWORD_ifElse_statement() async {
-    addTestFile('''
-f(a, b) {
-  if (a < b) {} else {}
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_KEYWORD_mixin() async {
-    addTestFile('''
-mixin M {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'mixin');
-  }
-
-  Future<void> test_KEYWORD_void() async {
-    addTestFile('''
-void main() {
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
-  }
-
-  Future<void> test_LABEL() async {
-    addTestFile('''
-main() {
-myLabel:
-  while (true) {
-    break myLabel;
-  }
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
-    assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
-  }
-
-  Future<void> test_LITERAL_BOOLEAN() async {
-    addTestFile('var V = true;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
-  }
-
-  Future<void> test_LITERAL_DOUBLE() async {
-    addTestFile('var V = 4.2;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
-  }
-
-  Future<void> test_LITERAL_INTEGER() async {
-    addTestFile('var V = 42;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
-  }
-
-  Future<void> test_LITERAL_LIST() async {
-    addTestFile('var V = <int>[1, 2, 3];');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
-  }
-
-  Future<void> test_LITERAL_MAP() async {
-    addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
-        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
-  }
-
-  Future<void> test_LITERAL_STRING() async {
-    addTestFile('var V = "abc";');
-    await prepareHighlights();
-    assertHasRegion(
-        HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
-  }
-
-  Future<void> test_LOCAL_VARIABLE() async {
-    addTestFile('''
-main() {
-  int vvv = 0;
-  vvv;
-  vvv = 1;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
-    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv;');
-    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv = 1;');
-  }
-
-  Future<void> test_METHOD() async {
-    addTestFile('''
-class A {
-  aaa() {}
-  static bbb() {}
-}
-main(A a) {
-  a.aaa();
-  a.aaa;
-  A.bbb();
-  A.bbb;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.METHOD_DECLARATION, 'aaa() {}');
-    assertHasRegion(HighlightRegionType.METHOD_DECLARATION_STATIC, 'bbb() {}');
-    assertHasRegion(HighlightRegionType.METHOD, 'aaa();');
-    assertHasRegion(HighlightRegionType.METHOD, 'aaa;');
-    assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb();');
-    assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb;');
-  }
-
-  Future<void> test_METHOD_bestType() async {
-    addTestFile('''
-main(p) {
-  if (p is List) {
-    p.add(null);
-  }
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.METHOD, 'add(null)');
-  }
-
-  Future<void> test_PARAMETER() async {
-    addTestFile('''
-main(int p) {
-  p;
-  p = 42;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.PARAMETER, 'p) {');
-    assertHasRegion(HighlightRegionType.PARAMETER, 'p;');
-    assertHasRegion(HighlightRegionType.PARAMETER, 'p = 42');
-  }
-
-  Future<void> test_SETTER_DECLARATION() async {
-    addTestFile('''
-set aaa(x) {}
-class A {
-  set bbb(x) {}
-}
-main(A a) {
-  aaa = 1;
-  a.bbb = 2;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'aaa(x)');
-    assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'bbb(x)');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa = 1');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
-  }
-
-  Future<void> test_TOP_LEVEL_VARIABLE() async {
-    addTestFile('''
-const VVV = 0;
-@VVV // annotation
-main() {
-  print(VVV);
-  VVV = 1;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 0');
-    assertHasRegion(
-        HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV // annotation');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV);');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 1');
-  }
-
-  Future<void> test_TYPE_NAME_DYNAMIC() async {
-    addTestFile('''
-dynamic main() {
-  dynamic = 42;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
-    assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
-    assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
-  }
-
-  Future<void> test_TYPE_PARAMETER() async {
-    addTestFile('''
-class A<T> {
-  T fff;
-  T mmm(T p) => null;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
-  }
-}
-
-class HighlightsTestSupport extends AbstractAnalysisTest {
-  List<HighlightRegion> regions;
-
-  final Completer<void> _resultsAvailable = Completer();
-
-  void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
-    for (var region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        return;
-      }
-    }
-    fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
-        '${regions.join('\n')}');
-  }
-
-  void assertHasRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    var offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertHasStringRegion(HighlightRegionType type, String str) {
-    var offset = findOffset(str);
-    var length = str.length;
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
-    for (var region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        fail(
-            'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
-            '${regions.join('\n')}');
-      }
-    }
-  }
-
-  void assertNoRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    var offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertNoRawRegion(type, offset, length);
-  }
-
-  int findRegionLength(String search, int length) {
-    if (length == -1) {
-      length = 0;
-      while (length < search.length) {
-        var c = search.codeUnitAt(length);
-        if (length == 0 && c == '@'.codeUnitAt(0)) {
-          length++;
-          continue;
-        }
-        if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
-            c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
-            c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
-          break;
-        }
-        length++;
-      }
-    }
-    return length;
-  }
-
-  Future prepareHighlights() {
-    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
-    return _resultsAvailable.future;
-  }
-
-  @override
-  void processNotification(Notification notification) {
-    if (notification.event == SERVER_NOTIFICATION_ERROR) {
-      print('SERVER_NOTIFICATION_ERROR: ${notification.toJson()}');
-      _resultsAvailable.complete();
-      fail('SERVER_NOTIFICATION_ERROR');
-    }
-    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
-      var params = AnalysisHighlightsParams.fromNotification(notification);
-      if (params.file == testFile) {
-        regions = params.regions;
-        _resultsAvailable.complete();
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
-  }
-
-  void _addLibraryForTestPart() {
-    newFile(join(testFolder, 'my_lib.dart'), content: '''
-library lib;
-part 'test.dart';
-    ''');
-  }
-}
-
-@reflectiveTest
-class HighlightsWithControlFlowCollectionsTest extends HighlightsTestSupport {
-  @failingTest
-  Future<void> test_KEYWORD_awaitForIn_list() async {
-    addTestFile('''
-f(a) async {
-  return [await for(var b in a) b];
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
-  }
-
-  @failingTest
-  Future<void> test_KEYWORD_awaitForIn_map() async {
-    addTestFile('''
-f(a) async {
-  return {await for(var b in a) b : 0};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
-  }
-
-  @failingTest
-  Future<void> test_KEYWORD_awaitForIn_set() async {
-    addTestFile('''
-f(a) async {
-  return {await for(var b in a) b};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
-  }
-
-  Future<void> test_KEYWORD_const_list() async {
-    addTestFile('''
-var v = const [];
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
-  }
-
-  Future<void> test_KEYWORD_const_map() async {
-    addTestFile('''
-var v = const {0 : 1};
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
-  }
-
-  Future<void> test_KEYWORD_const_set() async {
-    addTestFile('''
-var v = const {0};
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
-  }
-
-  Future<void> test_KEYWORD_if_list() async {
-    addTestFile('''
-f(a, b) {
-  return [if (a < b) 'a'];
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-  }
-
-  Future<void> test_KEYWORD_if_map() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a' : 1};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-  }
-
-  Future<void> test_KEYWORD_if_set() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a'};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-  }
-
-  Future<void> test_KEYWORD_ifElse_list() async {
-    addTestFile('''
-f(a, b) {
-  return [if (a < b) 'a' else 'b'];
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_KEYWORD_ifElse_map() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a' : 1 else 'b' : 2};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_KEYWORD_ifElse_set() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a' else 'b'};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_LITERAL_LIST_withControlFlow() async {
-    addTestFile('var V = <int>[1, 2, 3];');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
-  }
-
-  Future<void> test_LITERAL_MAP_withControlFlow() async {
-    addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
-        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
-  }
-}
-
-@reflectiveTest
-class HighlightsWithNullSafetyTest extends HighlightsTestSupport {
-  @override
-  void createProject({Map<String, String> packageRoots}) {
-    addAnalysisOptionsFile('''
-analyzer:
-  enable-experiment:
-    - non-nullable
-''');
-    super.createProject(packageRoots: packageRoots);
-  }
-
-  Future<void> test_KEYWORD_late() async {
-    addTestFile('''
-class C {
-  late int x;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'late');
-  }
-
-  Future<void> test_KEYWORD_required() async {
-    addTestFile('''
-void f({required int x}) {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'required');
-  }
-}
-
-@reflectiveTest
-class HighlightTypeTest {
-  void test_constructor() {
-    expect(HighlightRegionType.CLASS,
-        HighlightRegionType(HighlightRegionType.CLASS.name));
-  }
-
-  void test_toString() {
-    expect(HighlightRegionType.CLASS.toString(), 'HighlightRegionType.CLASS');
-  }
-
-  void test_valueOf_unknown() {
-    expect(() {
-      HighlightRegionType('no-such-type');
-    }, throwsException);
-  }
-}
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 702a96c..1187065 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -15,7 +15,6 @@
 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;
@@ -37,7 +36,6 @@
     notification_folding.main();
     notification_errors.main();
     notification_highlights2.main();
-    notification_highlights.main();
     notification_implemented.main();
     notification_navigation.main();
     notification_occurrences.main();
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index d8894c8..f000bb7 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 8a90649..dd5d637 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -16,6 +16,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
 import 'mocks.dart';
@@ -189,6 +190,7 @@
     handleSuccessfulRequest(request);
   }
 
+  @mustCallSuper
   void setUp() {
     serverChannel = MockServerChannel();
     projectPath = convertPath('/project');
@@ -205,6 +207,7 @@
     });
   }
 
+  @mustCallSuper
   void tearDown() {
     server.done();
     handler = null;
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index ec1e2e4..bb5fa96 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -155,13 +155,9 @@
 class String{}class List{}class DateTime{}typedef T Y<T extends !1>(List input);''',
         <String>['1+DateTime', '1+String']);
 
-    // https://github.com/dart-lang/sdk/issues/33992
-    buildTests(
-        'testCommentSnippets029',
-        '''
+    buildTests('testCommentSnippets029', '''
 interface A<X> default B<X extends !1List!2> {}''',
-        <String>['1+DateTime', '2+List'],
-        failingTests: '12');
+        <String>['1+DateTime', '2+List']);
 
     buildTests('testCommentSnippets030', '''
 class Bar<T extends Foo> {const Bar(!1T!2 k);T!3 m(T!4 a, T!5 b){}final T!6 f = null;}''',
@@ -185,7 +181,7 @@
 
     // Type propagation
     buildTests('testCommentSnippets035', '''
-class List{clear(){}length(){}}t3() {var x=new List(), y=x.!1length();x.!2clear();}''',
+class List{clear(){}length(){}}t3() {var x=[], y=x.!1length();x.!2clear();}''',
         <String>['1+length', '2+clear']);
 
     buildTests('testCommentSnippets036', '''
@@ -1833,7 +1829,7 @@
   var x = [Q.!2]
 }
 void c() {
-  var x = new List([Q.!3])
+  var x = new List.filled([Q.!3], null)
 }
 void d() {
   new Q.!4
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index a6b4251..8b50d8f 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -55,14 +55,14 @@
 class AbstractContextManagerTest extends ContextManagerTest {
   void test_contextsInAnalysisRoot_nestedContext() {
     var subProjPath = join(projPath, 'subproj');
-    var subProjFolder = resourceProvider.newFolder(subProjPath);
-    resourceProvider.newFile(join(subProjPath, 'pubspec.yaml'), 'contents');
+    var subProjFolder = newFolder(subProjPath);
+    newFile(join(subProjPath, 'pubspec.yaml'), content: 'contents');
     var subProjFilePath = join(subProjPath, 'file.dart');
-    resourceProvider.newFile(subProjFilePath, 'contents');
+    newFile(subProjFilePath, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
     // Make sure that there really are contexts for both the main project and
     // the subproject.
-    var projectFolder = resourceProvider.getFolder(projPath);
+    var projectFolder = getFolder(projPath);
     var projContextInfo = manager.getContextInfoFor(projectFolder);
     expect(projContextInfo, isNotNull);
     expect(projContextInfo.folder, projectFolder);
@@ -106,7 +106,7 @@
   "dart:typed_data": "../embedder/src/part"
   ''');
 
-    var projectFolder = resourceProvider.newFolder(projPath);
+    var projectFolder = newFolder(projPath);
 
     // NOTE that this is Not in our package path yet.
 
@@ -159,8 +159,7 @@
     manager.setRoots(<String>[projPath], <String>[]);
     await pumpEventQueue();
     // Confirm that one context was created.
-    var count = manager
-        .numberOfContextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+    var count = manager.numberOfContextsInAnalysisRoot(newFolder(projPath));
     expect(count, equals(1));
     var source = sourceFactory.forUri('dart:foobar');
     expect(source, isNotNull);
@@ -178,8 +177,8 @@
     var project = convertPath('/project');
     var excludedFolder = convertPath('$project/excluded');
     // set roots
-    resourceProvider.newFolder(project);
-    resourceProvider.newFolder(excludedFolder);
+    newFolder(project);
+    newFolder(excludedFolder);
     manager.setRoots(<String>[project], <String>[excludedFolder]);
     // verify
     expect(manager.isInAnalysisRoot(convertPath('$excludedFolder/test.dart')),
@@ -188,10 +187,10 @@
 
   void test_isInAnalysisRoot_inNestedContext() {
     var subProjPath = join(projPath, 'subproj');
-    var subProjFolder = resourceProvider.newFolder(subProjPath);
-    resourceProvider.newFile(join(subProjPath, 'pubspec.yaml'), 'contents');
+    var subProjFolder = newFolder(subProjPath);
+    newFile(join(subProjPath, 'pubspec.yaml'), content: 'contents');
     var subProjFilePath = join(subProjPath, 'file.dart');
-    resourceProvider.newFile(subProjFilePath, 'contents');
+    newFile(subProjFilePath, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
     // Make sure that there really is a context for the subproject.
     var subProjContextInfo = manager.getContextInfoFor(subProjFolder);
@@ -214,14 +213,14 @@
   Future<void> test_packagesFolder_areAnalyzed() {
     // create a context with a pubspec.yaml file
     var pubspecPath = join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
+    newFile(pubspecPath, content: 'pubspec');
     // create a file in the "packages" folder
     var filePath1 = join(projPath, 'packages', 'file1.dart');
-    var file1 = resourceProvider.newFile(filePath1, 'contents');
+    var file1 = newFile(filePath1, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
     expect(callbacks.currentFilePaths, unorderedEquals([file1.path]));
     var filePath2 = join(projPath, 'packages', 'file2.dart');
-    var file2 = resourceProvider.newFile(filePath2, 'contents');
+    var file2 = newFile(filePath2, content: 'contents');
     return pumpEventQueue().then((_) {
       expect(callbacks.currentFilePaths,
           unorderedEquals([file1.path, file2.path]));
@@ -230,7 +229,7 @@
 
   Future<void> test_path_filter() async {
     // Setup context.
-    var root = resourceProvider.newFolder(projPath);
+    var root = newFolder(projPath);
     manager.setRoots(<String>[projPath], <String>[]);
     expect(callbacks.currentFilePaths, isEmpty);
     // Set ignore patterns for context.
@@ -257,7 +256,7 @@
   Future<void> test_refresh_folder_with_packagespec() {
     // create a context with a .packages file
     var packagespecFile = join(projPath, '.packages');
-    resourceProvider.newFile(packagespecFile, '');
+    newFile(packagespecFile, content: '');
     manager.setRoots(<String>[projPath], <String>[]);
     return pumpEventQueue().then((_) {
       expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
@@ -280,8 +279,8 @@
     var subdir2Path = join(projPath, 'subdir2');
     var packagespec1Path = join(subdir1Path, '.packages');
     var packagespec2Path = join(subdir2Path, '.packages');
-    resourceProvider.newFile(packagespec1Path, '');
-    resourceProvider.newFile(packagespec2Path, '');
+    newFile(packagespec1Path, content: '');
+    newFile(packagespec2Path, content: '');
     manager.setRoots(<String>[projPath], <String>[]);
     return pumpEventQueue().then((_) {
       expect(callbacks.currentContextRoots,
@@ -301,7 +300,7 @@
   Future<void> test_refresh_folder_with_pubspec() {
     // create a context with a pubspec.yaml file
     var pubspecPath = join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
+    newFile(pubspecPath, content: 'pubspec');
     manager.setRoots(<String>[projPath], <String>[]);
     return pumpEventQueue().then((_) {
       expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
@@ -321,8 +320,8 @@
     var subdir2Path = join(projPath, 'subdir2');
     var pubspec1Path = join(subdir1Path, 'pubspec.yaml');
     var pubspec2Path = join(subdir2Path, 'pubspec.yaml');
-    resourceProvider.newFile(pubspec1Path, 'pubspec');
-    resourceProvider.newFile(pubspec2Path, 'pubspec');
+    newFile(pubspec1Path, content: 'pubspec');
+    newFile(pubspec2Path, content: 'pubspec');
     manager.setRoots(<String>[projPath], <String>[]);
     return pumpEventQueue().then((_) {
       expect(callbacks.currentContextRoots,
@@ -342,12 +341,12 @@
   Future<void> test_refresh_oneContext() {
     // create two contexts with pubspec.yaml files
     var pubspecPath = join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec1');
+    newFile(pubspecPath, content: 'pubspec1');
 
     var proj2Path = convertPath('/my/proj2');
-    resourceProvider.newFolder(proj2Path);
+    newFolder(proj2Path);
     var pubspec2Path = join(proj2Path, 'pubspec.yaml');
-    resourceProvider.newFile(pubspec2Path, 'pubspec2');
+    newFile(pubspec2Path, content: 'pubspec2');
 
     var roots = <String>[projPath, proj2Path];
     manager.setRoots(roots, <String>[]);
@@ -355,7 +354,7 @@
       expect(callbacks.currentContextRoots, unorderedEquals(roots));
       var then = callbacks.now;
       callbacks.now++;
-      manager.refresh([resourceProvider.getResource(proj2Path)]);
+      manager.refresh([getFolder(proj2Path)]);
       return pumpEventQueue().then((_) {
         expect(callbacks.currentContextRoots, unorderedEquals(roots));
         expect(callbacks.currentContextTimestamps[projPath], then);
@@ -365,15 +364,14 @@
   }
 
   void test_setRoots_addFolderWithDartFile() {
-    var filePath = resourceProvider.pathContext.join(projPath, 'foo.dart');
-    resourceProvider.newFile(filePath, 'contents');
+    var filePath = join(projPath, 'foo.dart');
+    newFile(filePath, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
     // verify
     var filePaths = callbacks.currentFilePaths;
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
-    var drivers =
-        manager.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath));
+    var drivers = manager.getDriversInAnalysisRoot(newFolder(projPath));
     expect(drivers, hasLength(1));
     expect(drivers[0], isNotNull);
     var result = sourceFactory.forUri('dart:async');
@@ -382,7 +380,7 @@
 
   void test_setRoots_addFolderWithDartFileInSubfolder() {
     var filePath = join(projPath, 'foo', 'bar.dart');
-    resourceProvider.newFile(filePath, 'contents');
+    newFile(filePath, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
     // verify
     var filePaths = callbacks.currentFilePaths;
@@ -415,14 +413,12 @@
     expect(callbacks.currentContextRoots, contains(projPath));
     var projSources = callbacks.currentFileSources(projPath);
     expect(projSources, hasLength(1));
-    expect(projSources.first.uri.toString(),
-        (Uri.file(join(libPath, 'main.dart')).toString()));
+    expect(projSources.first.uri, toUri('$libPath/main.dart'));
 
     expect(callbacks.currentContextRoots, contains(examplePath));
     var exampleSources = callbacks.currentFileSources(examplePath);
     expect(exampleSources, hasLength(1));
-    expect(exampleSources.first.uri.toString(),
-        (Uri.file(join(examplePath, 'example.dart')).toString()));
+    expect(exampleSources.first.uri, toUri('$examplePath/example.dart'));
   }
 
   void test_setRoots_addFolderWithNestedPubspec() {
@@ -449,8 +445,7 @@
     expect(callbacks.currentContextRoots, contains(examplePath));
     var exampleSources = callbacks.currentFileSources(examplePath);
     expect(exampleSources, hasLength(1));
-    expect(exampleSources.first.uri.toString(),
-        (Uri.file('$examplePath/example.dart').toString()));
+    expect(exampleSources.first.uri, toUri('$examplePath/example.dart'));
   }
 
   void test_setRoots_addFolderWithoutPubspec() {
@@ -463,8 +458,7 @@
   void test_setRoots_addFolderWithPackagespec() {
     var packagespecPath = join(projPath, '.packages');
     var testLib = convertPath('/home/somebody/.pub/cache/unittest-0.9.9/lib');
-    var testLibUri = resourceProvider.pathContext.toUri(testLib);
-    resourceProvider.newFile(packagespecPath, 'unittest:$testLibUri');
+    newFile(packagespecPath, content: 'unittest:${toUriStr(testLib)}');
     var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
     var mainFile = newFile('$libPath/main.dart');
     var source = mainFile.createSource();
@@ -484,7 +478,7 @@
 
   void test_setRoots_addFolderWithPubspec() {
     var pubspecPath = join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
+    newFile(pubspecPath, content: 'pubspec');
     manager.setRoots(<String>[projPath], <String>[]);
     // verify
     expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
@@ -494,8 +488,8 @@
   void test_setRoots_addFolderWithPubspec_andPackagespec() {
     var pubspecPath = join(projPath, 'pubspec.yaml');
     var packagespecPath = join(projPath, '.packages');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
-    resourceProvider.newFile(packagespecPath, '');
+    newFile(pubspecPath, content: 'pubspec');
+    newFile(packagespecPath, content: '');
     manager.setRoots(<String>[projPath], <String>[]);
     // verify
     callbacks.assertContextPaths([projPath]);
@@ -521,10 +515,10 @@
     expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
     expect(sources, hasLength(4));
     var uris = sources.map((Source source) => source.uri.toString()).toList();
-    expect(uris, contains((Uri.file(appPath)).toString()));
+    expect(uris, contains(toUriStr(appPath)));
     expect(uris, contains('package:proj/main.dart'));
     expect(uris, contains('package:proj/src/internal.dart'));
-    expect(uris, contains((Uri.file(testFilePath)).toString()));
+    expect(uris, contains(toUriStr(testFilePath)));
   }
 
   void test_setRoots_addFolderWithPubspecAndPackagespecFolders() {
@@ -571,9 +565,9 @@
     newFile('$projectB/${ContextManagerImpl.PUBSPEC_NAME}');
     newFile('$projectB/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
         content: 'bar:lib/');
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subProjectA_file, 'library a;');
-    resourceProvider.newFile(subProjectB_file, 'library b;');
+    newFile(rootFile, content: 'library root;');
+    newFile(subProjectA_file, content: 'library a;');
+    newFile(subProjectB_file, content: 'library b;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, projectA, projectB]);
@@ -586,12 +580,12 @@
     expect(
         _packageMap(projectA),
         equals({
-          'foo': [resourceProvider.getFolder(projectALib)]
+          'foo': [getFolder(projectALib)]
         }));
     expect(
         _packageMap(projectB),
         equals({
-          'bar': [resourceProvider.getFolder(projectBLib)]
+          'bar': [getFolder(projectBLib)]
         }));
   }
 
@@ -601,8 +595,8 @@
     var file1 = convertPath('$project/file1.dart');
     var file2 = convertPath('$project/file2.dart');
     // create files
-    resourceProvider.newFile(file1, '// 1');
-    resourceProvider.newFile(file2, '// 2');
+    newFile(file1, content: '// 1');
+    newFile(file2, content: '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[file1]);
     callbacks.assertContextPaths([project]);
@@ -617,8 +611,8 @@
     var fileA = convertPath('$folderA/a.dart');
     var fileB = convertPath('$folderB/b.dart');
     // create files
-    resourceProvider.newFile(fileA, 'library a;');
-    resourceProvider.newFile(fileB, 'library b;');
+    newFile(fileA, content: 'library a;');
+    newFile(fileB, content: 'library b;');
     // set roots
     manager.setRoots(<String>[project], <String>[folderB]);
     callbacks.assertContextPaths([project]);
@@ -631,8 +625,8 @@
     var file1 = convertPath('$project/file1.dart');
     var file2 = convertPath('$project/file2.dart');
     // create files
-    resourceProvider.newFile(file1, '// 1');
-    resourceProvider.newFile(file2, '// 2');
+    newFile(file1, content: '// 1');
+    newFile(file2, content: '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
@@ -651,8 +645,8 @@
     var fileA = convertPath('$folderA/a.dart');
     var fileB = convertPath('$folderB/b.dart');
     // create files
-    resourceProvider.newFile(fileA, 'library a;');
-    resourceProvider.newFile(fileB, 'library b;');
+    newFile(fileA, content: 'library a;');
+    newFile(fileB, content: 'library b;');
     // initially both "aaa/a" and "bbb/b" are included
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
@@ -669,8 +663,8 @@
     var file1 = convertPath('$project/file1.dart');
     var file2 = convertPath('$project/file2.dart');
     // create files
-    resourceProvider.newFile(file1, '// 1');
-    resourceProvider.newFile(file2, '// 2');
+    newFile(file1, content: '// 1');
+    newFile(file2, content: '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[file2]);
     callbacks.assertContextPaths([project]);
@@ -687,8 +681,8 @@
     var file1 = convertPath('$project/bin/file1.dart');
     var file2 = convertPath('$project/bin/file2.dart');
     // create files
-    resourceProvider.newFile(file1, '// 1');
-    resourceProvider.newFile(file2, '// 2');
+    newFile(file1, content: '// 1');
+    newFile(file2, content: '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[file2]);
     callbacks.assertContextPaths([project]);
@@ -707,8 +701,8 @@
     var fileA = convertPath('$folderA/a.dart');
     var fileB = convertPath('$folderB/b.dart');
     // create files
-    resourceProvider.newFile(fileA, 'library a;');
-    resourceProvider.newFile(fileB, 'library b;');
+    newFile(fileA, content: 'library a;');
+    newFile(fileB, content: 'library b;');
     // exclude "bbb/"
     manager.setRoots(<String>[project], <String>[folderB]);
     callbacks.assertContextPaths([project]);
@@ -724,9 +718,9 @@
     var fileA = convertPath('$project/foo.dart');
     var fileB = convertPath('$project/lib/doc/bar.dart');
     var fileC = convertPath('$project/doc/bar.dart');
-    resourceProvider.newFile(fileA, '');
-    resourceProvider.newFile(fileB, '');
-    resourceProvider.newFile(fileC, '');
+    newFile(fileA, content: '');
+    newFile(fileB, content: '');
+    newFile(fileC, content: '');
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA, fileB]);
@@ -738,8 +732,8 @@
     var example = convertPath('$project/example');
     var examplePubspec = convertPath('$example/pubspec.yaml');
     // create files
-    resourceProvider.newFile(projectPubspec, 'name: project');
-    resourceProvider.newFile(examplePubspec, 'name: example');
+    newFile(projectPubspec, content: 'name: project');
+    newFile(examplePubspec, content: 'name: example');
     manager.setRoots(<String>[example, project], <String>[]);
     // verify
     {
@@ -764,8 +758,8 @@
     var projectPubspec = convertPath('$project/pubspec.yaml');
     var example = convertPath('$project/example');
     // create files
-    resourceProvider.newFile(projectPubspec, 'name: project');
-    resourceProvider.newFolder(example);
+    newFile(projectPubspec, content: 'name: project');
+    newFolder(example);
     manager.setRoots(<String>[project, example], <String>[]);
     // verify
     {
@@ -786,8 +780,8 @@
     var example = convertPath('$project/example');
     var examplePubspec = convertPath('$example/pubspec.yaml');
     // create files
-    resourceProvider.newFile(projectPubspec, 'name: project');
-    resourceProvider.newFile(examplePubspec, 'name: example');
+    newFile(projectPubspec, content: 'name: project');
+    newFile(examplePubspec, content: 'name: example');
     manager.setRoots(<String>[project, example], <String>[]);
     // verify
     {
@@ -811,7 +805,7 @@
     var packagePath = convertPath('/package/foo');
     newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
         content: 'foo:${toUriStr('/package/foo')}');
-    var packageFolder = resourceProvider.newFolder(packagePath);
+    var packageFolder = newFolder(packagePath);
     manager.setRoots(<String>[projPath], <String>[]);
     expect(
         _currentPackageMap,
@@ -826,7 +820,7 @@
     var excludedFolder = convertPath('$project/excluded');
     var excludedPubspec = convertPath('$excludedFolder/pubspec.yaml');
     // create files
-    resourceProvider.newFile(excludedPubspec, 'name: ignore-me');
+    newFile(excludedPubspec, content: 'name: ignore-me');
     // set "/project", and exclude "/project/excluded"
     manager.setRoots(<String>[project], <String>[excludedFolder]);
     callbacks.assertContextPaths([project]);
@@ -834,7 +828,7 @@
 
   void test_setRoots_noContext_inDotFolder() {
     var pubspecPath = join(projPath, '.pub', 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'name: test');
+    newFile(pubspecPath, content: 'name: test');
     manager.setRoots(<String>[projPath], <String>[]);
     // verify
     expect(callbacks.currentContextRoots, hasLength(1));
@@ -846,11 +840,10 @@
     var filePath = join(projPath, 'lib', 'foo.dart');
     newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
         content: 'foo:lib/');
-    resourceProvider.newFile(filePath, 'contents');
+    newFile(filePath, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
 
-    var drivers =
-        manager.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath));
+    var drivers = manager.getDriversInAnalysisRoot(newFolder(projPath));
     expect(drivers, hasLength(1));
     expect(drivers[0], isNotNull);
     var result = sourceFactory.forUri('package:foo/foo.dart');
@@ -859,7 +852,7 @@
 
   void test_setRoots_packagesFolder_hasContext() {
     var pubspecPath = join(projPath, 'packages', 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'name: test');
+    newFile(pubspecPath, content: 'name: test');
     manager.setRoots(<String>[projPath], <String>[]);
     // verify
     expect(callbacks.currentContextRoots, hasLength(2));
@@ -873,8 +866,8 @@
     var project = convertPath('/project');
     var fileA = convertPath('$project/foo.dart');
     var fileB = convertPath('$project/.pub/bar.dart');
-    resourceProvider.newFile(fileA, '');
-    resourceProvider.newFile(fileB, '');
+    newFile(fileA, content: '');
+    newFile(fileB, content: '');
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
@@ -893,7 +886,7 @@
   void test_setRoots_removeFolderWithPackagespec() {
     // create a pubspec
     var pubspecPath = join(projPath, '.packages');
-    resourceProvider.newFile(pubspecPath, '');
+    newFile(pubspecPath, content: '');
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[]);
     expect(manager.changeSubscriptions, hasLength(1));
@@ -918,12 +911,12 @@
     var subProjectA_file = convertPath('$subProjectA/bin/sub_a.dart');
     var subProjectB_file = convertPath('$subProjectB/bin/sub_b.dart');
     // create files
-    resourceProvider.newFile(projectA_file, '// a');
-    resourceProvider.newFile(projectB_file, '// b');
-    resourceProvider.newFile(subProjectA_pubspec, '');
-    resourceProvider.newFile(subProjectB_pubspec, '');
-    resourceProvider.newFile(subProjectA_file, '// sub-a');
-    resourceProvider.newFile(subProjectB_file, '// sub-b');
+    newFile(projectA_file, content: '// a');
+    newFile(projectB_file, content: '// b');
+    newFile(subProjectA_pubspec, content: '');
+    newFile(subProjectB_pubspec, content: '');
+    newFile(subProjectA_file, content: '// sub-a');
+    newFile(subProjectB_file, content: '// sub-b');
     // set roots
     manager.setRoots(<String>[projectA, projectB], <String>[]);
     callbacks
@@ -942,7 +935,7 @@
   void test_setRoots_removeFolderWithPubspec() {
     // create a pubspec
     var pubspecPath = join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
+    newFile(pubspecPath, content: 'pubspec');
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[]);
     expect(callbacks.currentContextRoots, hasLength(1));
@@ -965,12 +958,12 @@
     var subProjectA_file = convertPath('$subProjectA/bin/sub_a.dart');
     var subProjectB_file = convertPath('$subProjectB/bin/sub_b.dart');
     // create files
-    resourceProvider.newFile(projectA_file, '// a');
-    resourceProvider.newFile(projectB_file, '// b');
-    resourceProvider.newFile(subProjectA_pubspec, 'pubspec');
-    resourceProvider.newFile(subProjectB_pubspec, 'pubspec');
-    resourceProvider.newFile(subProjectA_file, '// sub-a');
-    resourceProvider.newFile(subProjectB_file, '// sub-b');
+    newFile(projectA_file, content: '// a');
+    newFile(projectB_file, content: '// b');
+    newFile(subProjectA_pubspec, content: 'pubspec');
+    newFile(subProjectB_pubspec, content: 'pubspec');
+    newFile(subProjectA_file, content: '// sub-a');
+    newFile(subProjectB_file, content: '// sub-b');
     // set roots
     manager.setRoots(<String>[projectA, projectB], <String>[]);
     callbacks
@@ -992,7 +985,7 @@
     // context to be ignored.
     var project = convertPath('/.pub/project');
     var fileA = convertPath('$project/foo.dart');
-    resourceProvider.newFile(fileA, '');
+    newFile(fileA, content: '');
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
@@ -1017,7 +1010,7 @@
     expect(callbacks.currentFilePaths, hasLength(0));
     // add file
     var filePath = join(projPath, 'foo.dart');
-    resourceProvider.newFile(filePath, 'contents');
+    newFile(filePath, content: 'contents');
     // the file was added
     return pumpEventQueue().then((_) {
       var filePaths = callbacks.currentFilePaths;
@@ -1034,13 +1027,13 @@
     var fileA = convertPath('$folderA/a.dart');
     var fileB = convertPath('$folderB/b.dart');
     // create files
-    resourceProvider.newFile(fileA, 'library a;');
+    newFile(fileA, content: 'library a;');
     // set roots
     manager.setRoots(<String>[project], <String>[folderB]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
     // add a file, ignored as excluded
-    resourceProvider.newFile(fileB, 'library b;');
+    newFile(fileB, content: 'library b;');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([project]);
       callbacks.assertContextFiles(project, [fileA]);
@@ -1053,13 +1046,13 @@
     var fileA = convertPath('$project/a.dart');
     var fileB = convertPath('$project/lib/doc/b.dart');
     // create files
-    resourceProvider.newFile(fileA, '');
+    newFile(fileA, content: '');
     // set roots
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
     // add a "lib/doc" file, it is not ignored
-    resourceProvider.newFile(fileB, '');
+    newFile(fileB, content: '');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([project]);
       callbacks.assertContextFiles(project, [fileA, fileB]);
@@ -1072,13 +1065,13 @@
     var fileA = convertPath('$project/a.dart');
     var fileB = convertPath('$project/doc/b.dart');
     // create files
-    resourceProvider.newFile(fileA, '');
+    newFile(fileA, content: '');
     // set roots
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
     // add a "doc" file, it is ignored
-    resourceProvider.newFile(fileB, '');
+    newFile(fileB, content: '');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([project]);
       callbacks.assertContextFiles(project, [fileA]);
@@ -1091,11 +1084,11 @@
     var project = convertPath('/project');
     var fileA = convertPath('$project/foo.dart');
     var fileB = convertPath('$project/.pub/bar.dart');
-    resourceProvider.newFile(fileA, '');
+    newFile(fileA, content: '');
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
-    resourceProvider.newFile(fileB, '');
+    newFile(fileB, content: '');
     await pumpEventQueue();
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
@@ -1107,11 +1100,11 @@
     var project = convertPath('/.pub/project');
     var fileA = convertPath('$project/foo.dart');
     var fileB = convertPath('$project/bar/baz.dart');
-    resourceProvider.newFile(fileA, '');
+    newFile(fileA, content: '');
     manager.setRoots(<String>[project], <String>[]);
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA]);
-    resourceProvider.newFile(fileB, '');
+    newFile(fileB, content: '');
     await pumpEventQueue();
     callbacks.assertContextPaths([project]);
     callbacks.assertContextFiles(project, [fileA, fileB]);
@@ -1123,7 +1116,7 @@
     expect(callbacks.currentFilePaths, hasLength(0));
     // add file in subfolder
     var filePath = join(projPath, 'foo', 'bar.dart');
-    resourceProvider.newFile(filePath, 'contents');
+    newFile(filePath, content: 'contents');
     // the file was added
     return pumpEventQueue().then((_) {
       var filePaths = callbacks.currentFilePaths;
@@ -1138,14 +1131,14 @@
     var rootFile = convertPath('$root/root.dart');
     var rootPackagespec = convertPath('$root/.packages');
     // create files
-    resourceProvider.newFile(rootFile, 'library root;');
+    newFile(rootFile, content: 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root]);
     // verify files
     callbacks.assertContextFiles(root, [rootFile]);
     // add packagespec - still just one root
-    resourceProvider.newFile(rootPackagespec, '');
+    newFile(rootPackagespec, content: '');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1162,15 +1155,15 @@
     var subPubspec = convertPath('$subProject/.packages');
     var subFile = convertPath('$subProject/bin/a.dart');
     // create files
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subFile, 'library a;');
+    newFile(rootFile, content: 'library root;');
+    newFile(subFile, content: 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root]);
     // verify files
     callbacks.assertContextFiles(root, [rootFile, subFile]);
     // add .packages
-    resourceProvider.newFile(subPubspec, '');
+    newFile(subPubspec, content: '');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root, subProject]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1187,16 +1180,16 @@
     var subFile = convertPath('$subProject/bin/sub.dart');
     var subSubPubspec = convertPath('$subProject/subsub/.packages');
     // create files
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subPubspec, '');
-    resourceProvider.newFile(subFile, 'library sub;');
+    newFile(rootFile, content: 'library root;');
+    newFile(subPubspec, content: '');
+    newFile(subFile, content: 'library sub;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, subProject]);
     callbacks.assertContextFiles(root, [rootFile]);
     callbacks.assertContextFiles(subProject, [subFile]);
     // add pubspec - ignore, because is already in a packagespec-based context
-    resourceProvider.newFile(subSubPubspec, '');
+    newFile(subSubPubspec, content: '');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root, subProject]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1213,9 +1206,9 @@
     var subPubspec = convertPath('$subProject/pubspec.yaml');
     var subFile = convertPath('$subProject/bin/a.dart');
     // create files
-    resourceProvider.newFile(subPubspec, 'pubspec');
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subFile, 'library a;');
+    newFile(subPubspec, content: 'pubspec');
+    newFile(rootFile, content: 'library root;');
+    newFile(subFile, content: 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, subProject]);
@@ -1224,7 +1217,7 @@
     callbacks.assertContextFiles(subProject, [subFile]);
 
     // add .packages
-    resourceProvider.newFile(subPackagespec, '');
+    newFile(subPackagespec, content: '');
     return pumpEventQueue().then((_) {
       // Should NOT create another context.
       callbacks.assertContextPaths([root, subProject]);
@@ -1239,14 +1232,14 @@
     var rootFile = convertPath('$root/root.dart');
     var rootPubspec = convertPath('$root/pubspec.yaml');
     // create files
-    resourceProvider.newFile(rootFile, 'library root;');
+    newFile(rootFile, content: 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root]);
     // verify files
     callbacks.assertContextFiles(root, [rootFile]);
     // add pubspec - still just one root
-    resourceProvider.newFile(rootPubspec, 'pubspec');
+    newFile(rootPubspec, content: 'pubspec');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1261,15 +1254,15 @@
     var subPubspec = convertPath('$subProject/pubspec.yaml');
     var subFile = convertPath('$subProject/bin/a.dart');
     // create files
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subFile, 'library a;');
+    newFile(rootFile, content: 'library root;');
+    newFile(subFile, content: 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root]);
     // verify files
     callbacks.assertContextFiles(root, [rootFile, subFile]);
     // add pubspec
-    resourceProvider.newFile(subPubspec, 'pubspec');
+    newFile(subPubspec, content: 'pubspec');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root, subProject]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1286,16 +1279,16 @@
     var subFile = convertPath('$subProject/bin/sub.dart');
     var subSubPubspec = convertPath('$subProject/subsub/pubspec.yaml');
     // create files
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subPubspec, 'pubspec');
-    resourceProvider.newFile(subFile, 'library sub;');
+    newFile(rootFile, content: 'library root;');
+    newFile(subPubspec, content: 'pubspec');
+    newFile(subFile, content: 'library sub;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, subProject]);
     callbacks.assertContextFiles(root, [rootFile]);
     callbacks.assertContextFiles(subProject, [subFile]);
     // add pubspec - ignore, because is already in a pubspec-based context
-    resourceProvider.newFile(subSubPubspec, 'pubspec');
+    newFile(subSubPubspec, content: 'pubspec');
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root, subProject]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1306,7 +1299,7 @@
   Future<void> test_watch_deleteFile() {
     var filePath = join(projPath, 'foo.dart');
     // add root with a file
-    var file = resourceProvider.newFile(filePath, 'contents');
+    var file = newFile(filePath, content: 'contents');
     var projFolder = file.parent;
     manager.setRoots(<String>[projPath], <String>[]);
     // the file was added
@@ -1316,7 +1309,7 @@
     expect(file.exists, isTrue);
     expect(projFolder.exists, isTrue);
     // delete the file
-    resourceProvider.deleteFile(filePath);
+    deleteFile(filePath);
     return pumpEventQueue().then((_) {
       expect(file.exists, isFalse);
       expect(projFolder.exists, isTrue);
@@ -1327,7 +1320,7 @@
   Future<void> test_watch_deleteFolder() {
     var filePath = join(projPath, 'foo.dart');
     // add root with a file
-    var file = resourceProvider.newFile(filePath, 'contents');
+    var file = newFile(filePath, content: 'contents');
     var projFolder = file.parent;
     manager.setRoots(<String>[projPath], <String>[]);
     // the file was added
@@ -1337,7 +1330,7 @@
     expect(file.exists, isTrue);
     expect(projFolder.exists, isTrue);
     // delete the folder
-    resourceProvider.deleteFolder(projPath);
+    deleteFolder(projPath);
     return pumpEventQueue().then((_) {
       expect(file.exists, isFalse);
       expect(projFolder.exists, isFalse);
@@ -1351,14 +1344,14 @@
     var rootPubspec = convertPath('$root/.packages');
     var rootFile = convertPath('$root/root.dart');
     // create files
-    resourceProvider.newFile(rootPubspec, '');
-    resourceProvider.newFile(rootFile, 'library root;');
+    newFile(rootPubspec, content: '');
+    newFile(rootFile, content: 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root]);
     callbacks.assertContextFiles(root, [rootFile]);
     // delete the pubspec
-    resourceProvider.deleteFile(rootPubspec);
+    deleteFile(rootPubspec);
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1373,9 +1366,9 @@
     var subPubspec = convertPath('$subProject/.packages');
     var subFile = convertPath('$subProject/bin/a.dart');
     // create files
-    resourceProvider.newFile(subPubspec, '');
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subFile, 'library a;');
+    newFile(subPubspec, content: '');
+    newFile(rootFile, content: 'library root;');
+    newFile(subFile, content: 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, subProject]);
@@ -1383,7 +1376,7 @@
     callbacks.assertContextFiles(root, [rootFile]);
     callbacks.assertContextFiles(subProject, [subFile]);
     // delete the pubspec
-    resourceProvider.deleteFile(subPubspec);
+    deleteFile(subPubspec);
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root]);
       callbacks.assertContextFiles(root, [rootFile, subFile]);
@@ -1409,10 +1402,10 @@
     var subPubspec = convertPath('$subProject/pubspec.yaml');
     var subFile = convertPath('$subProject/bin/a.dart');
     // create files
-    resourceProvider.newFile(subPackagespec, '');
-    resourceProvider.newFile(subPubspec, 'pubspec');
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subFile, 'library a;');
+    newFile(subPackagespec, content: '');
+    newFile(subPubspec, content: 'pubspec');
+    newFile(rootFile, content: 'library root;');
+    newFile(subFile, content: 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, subProject]);
@@ -1420,7 +1413,7 @@
     callbacks.assertContextFiles(root, [rootFile]);
     callbacks.assertContextFiles(subProject, [subFile]);
     // delete the packagespec
-    resourceProvider.deleteFile(subPackagespec);
+    deleteFile(subPackagespec);
     return pumpEventQueue().then((_) {
       // Should NOT merge
       callbacks.assertContextPaths([root, subProject]);
@@ -1434,14 +1427,14 @@
     var rootPubspec = convertPath('$root/pubspec.yaml');
     var rootFile = convertPath('$root/root.dart');
     // create files
-    resourceProvider.newFile(rootPubspec, 'pubspec');
-    resourceProvider.newFile(rootFile, 'library root;');
+    newFile(rootPubspec, content: 'pubspec');
+    newFile(rootFile, content: 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root]);
     callbacks.assertContextFiles(root, [rootFile]);
     // delete the pubspec
-    resourceProvider.deleteFile(rootPubspec);
+    deleteFile(rootPubspec);
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root]);
       callbacks.assertContextFiles(root, [rootFile]);
@@ -1456,9 +1449,9 @@
     var subPubspec = convertPath('$subProject/pubspec.yaml');
     var subFile = convertPath('$subProject/bin/a.dart');
     // create files
-    resourceProvider.newFile(subPubspec, 'pubspec');
-    resourceProvider.newFile(rootFile, 'library root;');
-    resourceProvider.newFile(subFile, 'library a;');
+    newFile(subPubspec, content: 'pubspec');
+    newFile(rootFile, content: 'library root;');
+    newFile(subFile, content: 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[]);
     callbacks.assertContextPaths([root, subProject]);
@@ -1466,7 +1459,7 @@
     callbacks.assertContextFiles(root, [rootFile]);
     callbacks.assertContextFiles(subProject, [subFile]);
     // delete the pubspec
-    resourceProvider.deleteFile(subPubspec);
+    deleteFile(subPubspec);
     return pumpEventQueue().then((_) {
       callbacks.assertContextPaths([root]);
       callbacks.assertContextFiles(root, [rootFile, subFile]);
@@ -1476,7 +1469,7 @@
   Future<void> test_watch_modifyFile() {
     var filePath = join(projPath, 'foo.dart');
     // add root with a file
-    resourceProvider.newFile(filePath, 'contents');
+    newFile(filePath, content: 'contents');
     manager.setRoots(<String>[projPath], <String>[]);
     // the file was added
     var filePaths = callbacks.currentFilePaths;
@@ -1485,7 +1478,7 @@
     // TODO(brianwilkerson) Test when the file was modified
     // update the file
     callbacks.now++;
-    resourceProvider.modifyFile(filePath, 'new contents');
+    modifyFile(filePath, 'new contents');
     return pumpEventQueue().then((_) {
       // TODO(brianwilkerson) Test when the file was modified
     });
@@ -1495,8 +1488,8 @@
     var packageConfigPath = '$projPath/.dart_tool/package_config.json';
     var filePath = convertPath('$projPath/bin/main.dart');
 
-    resourceProvider.newFile(packageConfigPath, '');
-    resourceProvider.newFile(filePath, 'library main;');
+    newFile(packageConfigPath, content: '');
+    newFile(filePath, content: 'library main;');
 
     manager.setRoots(<String>[projPath], <String>[]);
 
@@ -1507,7 +1500,7 @@
 
     // update .dart_tool/package_config.json
     callbacks.now++;
-    resourceProvider.modifyFile(
+    modifyFile(
       packageConfigPath,
       (PackageConfigFileBuilder()..add(name: 'my', rootPath: '../'))
           .toContent(toUriStr: toUriStr),
@@ -1523,8 +1516,8 @@
     var packagesPath = convertPath('$projPath/.packages');
     var filePath = convertPath('$projPath/bin/main.dart');
 
-    resourceProvider.newFile(packagesPath, '');
-    resourceProvider.newFile(filePath, 'library main;');
+    newFile(packagesPath, content: '');
+    newFile(filePath, content: 'library main;');
 
     manager.setRoots(<String>[projPath], <String>[]);
 
@@ -1535,7 +1528,7 @@
 
     // update .packages
     callbacks.now++;
-    resourceProvider.modifyFile(packagesPath, 'main:./lib/');
+    modifyFile(packagesPath, 'main:./lib/');
     return pumpEventQueue().then((_) {
       // verify new package info
       expect(_currentPackageMap.keys, unorderedEquals(['main']));
@@ -1615,7 +1608,7 @@
   void setUp() {
     processRequiredPlugins();
     projPath = convertPath('/my/proj');
-    resourceProvider.newFolder(projPath);
+    newFolder(projPath);
     // Create an SDK in the mock file system.
     MockSdk(resourceProvider: resourceProvider);
     var sdkManager = DartSdkManager(convertPath(sdkRoot));
@@ -1633,7 +1626,7 @@
   }
 
   Map<String, List<Folder>> _packageMap(String contextPath) {
-    var folder = resourceProvider.getFolder(contextPath);
+    var folder = getFolder(contextPath);
     var info = manager.getContextInfoFor(folder);
     return info.analysisDriver.sourceFactory?.packageMap;
   }
@@ -1821,7 +1814,7 @@
 
     // Remove the root, with the analysis options file.
     // No exceptions.
-    resourceProvider.deleteFolder(projPath);
+    deleteFolder(projPath);
     await pumpEventQueue();
   }
 
@@ -1867,8 +1860,7 @@
     await pumpEventQueue();
 
     // Confirm that one context was created.
-    var count = manager
-        .numberOfContextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+    var count = manager.numberOfContextsInAnalysisRoot(newFolder(projPath));
     expect(count, equals(1));
 
     // Verify options.
@@ -1973,7 +1965,7 @@
   Future<void> test_non_analyzable_files_not_considered() async {
     // Set up project and get a reference to the driver.
     manager.setRoots(<String>[projPath], <String>[]);
-    var projectFolder = resourceProvider.newFolder(projPath);
+    var projectFolder = newFolder(projPath);
     var drivers = manager.getDriversInAnalysisRoot(projectFolder);
     expect(drivers, hasLength(1));
 
@@ -1999,14 +1991,14 @@
     // After a few other changes, the test now times out on my machine, so I'm
     // disabling it in order to prevent it from being flaky.
     _fail('Test times out');
-    var file = resourceProvider.newFile('$projPath/bin/test.dart', r'''
+    var file = newFile('$projPath/bin/test.dart', content: r'''
 main() {
   var paths = <int>[];
   var names = <String>[];
   paths.addAll(names.map((s) => s.length));
 }
 ''');
-    resourceProvider.newFile('$projPath/$optionsFileName', r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   strong-mode: false
 ''');
@@ -2025,7 +2017,7 @@
     expect(result.errors, isEmpty);
 
     // Update the options file - turn on 'strong-mode'.
-    resourceProvider.updateFile('$projPath/$optionsFileName', r'''
+    modifyFile('$projPath/$optionsFileName', r'''
 analyzer:
   strong-mode: true
 ''');
@@ -2067,7 +2059,7 @@
     manager.setRoots(<String>[projPath], <String>[]);
 
     // Verify that analysis options was parsed and the ignore patterns applied.
-    var projectFolder = resourceProvider.newFolder(projPath);
+    var projectFolder = newFolder(projPath);
     var drivers = manager.getDriversInAnalysisRoot(projectFolder);
     expect(drivers, hasLength(1));
     var driver = drivers[0];
@@ -2100,7 +2092,7 @@
     manager.setRoots(<String>[projPath], <String>[]);
     // Verify that the context in other_lib wasn't created and that the
     // context in lib was created.
-    var projectFolder = resourceProvider.newFolder(projPath);
+    var projectFolder = newFolder(projPath);
     var drivers = manager.getDriversInAnalysisRoot(projectFolder);
     expect(drivers, hasLength(2));
     expect(drivers[0].name, equals(convertPath('/my/proj')));
@@ -2132,7 +2124,7 @@
 
     // Verify that the context in other_lib wasn't created and that the
     // context in lib was created.
-    var projectFolder = resourceProvider.newFolder(projPath);
+    var projectFolder = newFolder(projPath);
     var drivers = manager.getDriversInAnalysisRoot(projectFolder);
     expect(drivers, hasLength(2));
     expect(drivers[0].name, equals(convertPath('/my/proj')));
@@ -2161,7 +2153,7 @@
     // Setup context / driver.
     manager.setRoots(<String>[projPath], <String>[]);
 
-    var projectFolder = resourceProvider.newFolder(projPath);
+    var projectFolder = newFolder(projPath);
     var drivers = manager.getDriversInAnalysisRoot(projectFolder);
     expect(drivers, hasLength(2));
     expect(drivers[0].name, equals(convertPath('/my/proj')));
@@ -2174,8 +2166,8 @@
     var example = convertPath('$project/example');
     var examplePubspec = convertPath('$example/pubspec.yaml');
     // create files
-    resourceProvider.newFile(projectPubspec, 'name: project');
-    resourceProvider.newFile(examplePubspec, 'name: example');
+    newFile(projectPubspec, content: 'name: project');
+    newFile(examplePubspec, content: 'name: example');
     newFile('$project/$optionsFileName', content: r'''
 analyzer:
   exclude:
@@ -2207,8 +2199,8 @@
     var aPubspec = convertPath('$a/pubspec.yaml');
     var cPubspec = convertPath('$c/pubspec.yaml');
     // create files
-    resourceProvider.newFile(aPubspec, 'name: aaa');
-    resourceProvider.newFile(cPubspec, 'name: ccc');
+    newFile(aPubspec, content: 'name: aaa');
+    newFile(cPubspec, content: 'name: ccc');
     newFile('$a/$optionsFileName', content: r'''
 analyzer:
   exclude:
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index c00d24e..e72baca 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -6,11 +6,9 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -43,10 +41,8 @@
     addTestFile('main() { new A(^);}'
         'class A { A({one, two}) {} }');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ');
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
     expect(suggestions, hasLength(2));
   }
 
@@ -54,30 +50,24 @@
     addTestFile('main() { new A(^);}'
         'class A { factory A({one, two}) => throw 0; }');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ');
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
     expect(suggestions, hasLength(2));
   }
 
   Future<void> test_ArgumentList_imported_function_named_param() async {
     addTestFile('main() { int.parse("16", ^);}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ');
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ');
     expect(suggestions, hasLength(2));
   }
 
   Future<void> test_ArgumentList_imported_function_named_param1() async {
     addTestFile('main() { foo(o^);} foo({one, two}) {}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ');
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
     expect(suggestions, hasLength(2));
   }
 
@@ -85,54 +75,42 @@
     addTestFile('mainx() {A a = new A(); a.foo(one: 7, ^);}'
         'class A { foo({one, two}) {} }');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
     expect(suggestions, hasLength(1));
   }
 
   Future<void> test_ArgumentList_imported_function_named_param_label1() async {
     addTestFile('main() { int.parse("16", r^: 16);}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix');
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError');
     expect(suggestions, hasLength(2));
   }
 
   Future<void> test_ArgumentList_imported_function_named_param_label3() async {
     addTestFile('main() { int.parse("16", ^: 16);}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ',
-        relevance: DART_RELEVANCE_NAMED_PARAMETER);
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ');
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ');
     expect(suggestions, hasLength(2));
   }
 
   Future<void> test_catch() async {
     addTestFile('main() {try {} ^}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally',
-        relevance: DART_RELEVANCE_KEYWORD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on');
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch');
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally');
     expect(suggestions, hasLength(3));
   }
 
   Future<void> test_catch2() async {
     addTestFile('main() {try {} on Foo {} ^}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for',
-        relevance: DART_RELEVANCE_KEYWORD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on');
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch');
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally');
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for');
     suggestions.firstWhere(
         (CompletionSuggestion suggestion) =>
             suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
@@ -146,8 +124,7 @@
     assertNoResult('on');
     assertNoResult('catch');
     assertNoResult('finally');
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for',
-        relevance: DART_RELEVANCE_KEYWORD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for');
     suggestions.firstWhere(
         (CompletionSuggestion suggestion) =>
             suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
@@ -161,8 +138,7 @@
     assertNoResult('on');
     assertNoResult('catch');
     assertNoResult('finally');
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for',
-        relevance: DART_RELEVANCE_KEYWORD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for');
     suggestions.firstWhere(
         (CompletionSuggestion suggestion) =>
             suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
@@ -173,65 +149,51 @@
   Future<void> test_catch5() async {
     addTestFile('main() {try {} ^ finally {}}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch',
-        relevance: DART_RELEVANCE_KEYWORD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on');
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch');
     expect(suggestions, hasLength(2));
   }
 
   Future<void> test_constructor() async {
     addTestFile('class A {bool foo; A() : ^;}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
   }
 
   Future<void> test_constructor2() async {
     addTestFile('class A {bool foo; A() : s^;}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
   }
 
   Future<void> test_constructor3() async {
     addTestFile('class A {bool foo; A() : a=7,^;}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
   }
 
   Future<void> test_constructor4() async {
     addTestFile('class A {bool foo; A() : a=7,s^;}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
   }
 
   Future<void> test_constructor5() async {
     addTestFile('class A {bool foo; A() : a=7,s^}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
   }
 
   Future<void> test_constructor6() async {
     addTestFile('class A {bool foo; A() : a=7,^ void bar() {}}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
-        relevance: DART_RELEVANCE_KEYWORD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
   }
 
   Future<void> test_html() {
@@ -315,8 +277,7 @@
 
     // Assert valid results for the second request
     expect(allSuggestions[result2.id], same(suggestions));
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'class',
-        relevance: DART_RELEVANCE_HIGH);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'class');
   }
 
   @failingTest
@@ -370,9 +331,9 @@
     expect(replacementOffset, completionOffset - 3);
     expect(replacementLength, 3);
     assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
-        selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
+        selectionOffset: 8);
     assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';',
-        selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
+        selectionOffset: 8);
     assertNoResult('extends');
     assertNoResult('library');
   }
@@ -407,14 +368,13 @@
     }
     expect(replacementOffset, completionOffset - 1);
     expect(replacementLength, 1);
-    assertHasResult(CompletionSuggestionKind.KEYWORD, 'library',
-        relevance: DART_RELEVANCE_HIGH);
+    assertHasResult(CompletionSuggestionKind.KEYWORD, 'library');
     assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';',
-        selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
+        selectionOffset: 8);
     assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
-        selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
+        selectionOffset: 8);
     assertHasResult(CompletionSuggestionKind.KEYWORD, 'part \'\';',
-        selectionOffset: 6, relevance: DART_RELEVANCE_HIGH);
+        selectionOffset: 6);
     assertNoResult('extends');
   }
 
@@ -509,10 +469,8 @@
   main(aaa, bbb) {}
   ''');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
-        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
-    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo',
-        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main');
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
     assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min');
   }
 
@@ -522,8 +480,7 @@
   main(aaa, bbb) {}
   ''');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
-        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main');
   }
 
   Future<void> test_inherited() {
@@ -538,8 +495,7 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
     });
   }
 
@@ -568,45 +524,16 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
     });
   }
 
-  Future<void> test_invocation_sdk_relevancy_off() {
-    var originalSorter = DartCompletionManager.contributionSorter;
-    var mockSorter = MockRelevancySorter();
-    DartCompletionManager.contributionSorter = mockSorter;
-    addTestFile('main() {Map m; m.^}');
-    return getSuggestions().then((_) {
-      // Assert that the CommonUsageComputer has been replaced
-      expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
-          isFalse);
-      DartCompletionManager.contributionSorter = originalSorter;
-      mockSorter.enabled = false;
-    });
-  }
-
-  Future<void> test_invocation_sdk_relevancy_on() {
-    if (!server.options.useNewRelevance) {
-      addTestFile('main() {Map m; m.^}');
-      return getSuggestions().then((_) {
-        // Assert that the CommonUsageComputer is working
-        expect(
-            suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
-            isTrue);
-      });
-    }
-    return Future.value(null);
-  }
-
   Future<void> test_invocation_withTrailingStmt() {
     addTestFile('class A {b() {}} main() {A a; a.^ int x = 7;}');
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
     });
   }
 
@@ -615,8 +542,7 @@
 class A { var isVisible;}
 main(A p) { var v1 = p.is^; }''');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'isVisible',
-        relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'isVisible');
   }
 
   Future<void> test_keyword() {
@@ -625,9 +551,8 @@
       expect(replacementOffset, equals(completionOffset - 2));
       expect(replacementLength, equals(2));
       assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
-          selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
-      assertHasResult(CompletionSuggestionKind.KEYWORD, 'class',
-          relevance: DART_RELEVANCE_HIGH);
+          selectionOffset: 8);
+      assertHasResult(CompletionSuggestionKind.KEYWORD, 'class');
     });
   }
 
@@ -679,8 +604,7 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
     });
   }
 
@@ -701,8 +625,7 @@
     expect(replacementLength, equals(0));
 
     // The class is suggested.
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
-        relevance: DART_RELEVANCE_LOCAL_VARIABLE);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
 
     // Class and all its constructors are shadowed by the local variable.
     assertNoResult('A', elementKind: ElementKind.CLASS);
@@ -717,12 +640,9 @@
       expect(replacementLength, equals(0));
       assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
           elementKind: ElementKind.CLASS);
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'a',
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
-          relevance: DART_RELEVANCE_LOCAL_VARIABLE);
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'x',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'a');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'x');
       assertHasResult(CompletionSuggestionKind.INVOCATION, 'DateTime',
           elementKind: ElementKind.CLASS);
     });
@@ -746,8 +666,7 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
-          relevance: DART_RELEVANCE_LOCAL_METHOD);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
     });
   }
 
@@ -838,8 +757,7 @@
     await getSuggestions();
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
-        relevance: DART_RELEVANCE_INHERITED_METHOD);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
     assertNoResult('c');
   }
 
@@ -854,8 +772,7 @@
       expect(replacementLength, equals(4));
       // Suggestions based upon imported elements are partially filtered
       //assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'test',
-          relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'test');
       assertNoResult('HtmlElement');
     });
   }
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
index 7d42cf0..17cbdd8 100644
--- a/pkg/analysis_server/test/domain_completion_util.dart
+++ b/pkg/analysis_server/test/domain_completion_util.dart
@@ -8,7 +8,6 @@
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/domain_completion.dart';
-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 
@@ -41,8 +40,7 @@
   }
 
   void assertHasResult(CompletionSuggestionKind kind, String completion,
-      {int relevance = DART_RELEVANCE_DEFAULT,
-      bool isDeprecated = false,
+      {bool isDeprecated = false,
       bool isPotential = false,
       int selectionOffset,
       ElementKind elementKind}) {
@@ -70,9 +68,6 @@
       fail('expected $expectationText, but found\n $completions');
     }
     expect(cs.kind, equals(kind));
-    if (!server.options.useNewRelevance) {
-      expect(cs.relevance, equals(relevance));
-    }
     expect(cs.selectionOffset, selectionOffset ?? completion.length);
     expect(cs.selectionLength, equals(0));
     expect(cs.isDeprecated, equals(isDeprecated));
diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart
index 438a81e..3ab55f3 100644
--- a/pkg/analysis_server/test/edit/assists_test.dart
+++ b/pkg/analysis_server/test/edit/assists_test.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/edit/bulk_fixes_test.dart b/pkg/analysis_server/test/edit/bulk_fixes_test.dart
index 7f22771..f22d513 100644
--- a/pkg/analysis_server/test/edit/bulk_fixes_test.dart
+++ b/pkg/analysis_server/test/edit/bulk_fixes_test.dart
@@ -2,11 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:linter/src/rules.dart';
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,6 +24,21 @@
 
 @reflectiveTest
 class BulkFixesTest extends AbstractAnalysisTest {
+  void assertContains(List<BulkFix> details,
+      {@required String path, @required String code, @required int count}) {
+    for (var detail in details) {
+      if (detail.path == path) {
+        for (var fix in detail.fixes) {
+          if (fix.code == code) {
+            expect(fix.occurrences, count);
+            return;
+          }
+        }
+      }
+    }
+    fail('No match found for: $path:$code->$count in $details');
+  }
+
   Future<void> assertEditEquals(String expectedSource) async {
     await waitForTasksFinished();
     var edits = await _getBulkEdits();
@@ -131,6 +150,40 @@
 ''');
   }
 
+  Future<void> test_details() async {
+    addAnalysisOptionsFile('''
+linter:
+  rules:
+    - annotate_overrides
+    - unnecessary_new
+''');
+
+    var fileA = convertPath('$projectPath/a.dart');
+    newFile(fileA, content: '''
+class A {
+  A f() => new A();
+}
+class B extends A {
+  A f() => new B();
+}
+''');
+
+    addTestFile('''
+import 'a.dart';
+
+A f() => new A();
+''');
+
+    var details = await _getBulkFixDetails();
+    expect(details, hasLength(2));
+    assertContains(details,
+        path: fileA, code: LintNames.unnecessary_new, count: 2);
+    assertContains(details,
+        path: fileA, code: LintNames.annotate_overrides, count: 1);
+    assertContains(details,
+        path: testFile, code: LintNames.unnecessary_new, count: 1);
+  }
+
   Future<void> test_unnecessaryNew() async {
     addAnalysisOptionsFile('''
 linter:
@@ -150,6 +203,12 @@
 
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44080')
   Future<void> test_unnecessaryNew_collectionLiteral_overlap() async {
+    // The test case currently drops the 'new' but does not convert the code to
+    // use a set literal. The code is no longer mangled, but we need to run the
+    // BulkFixProcessor iteratively to solve the second case.
+    if (Platform.isWindows) {
+      fail('Should not be passing on Windows, but it does');
+    }
     addAnalysisOptionsFile('''
 linter:
   rules:
@@ -203,9 +262,18 @@
   }
 
   Future<List<SourceFileEdit>> _getBulkEdits() async {
+    var result = await _getBulkFixes();
+    return result.edits;
+  }
+
+  Future<List<BulkFix>> _getBulkFixDetails() async {
+    var result = await _getBulkFixes();
+    return result.details;
+  }
+
+  Future<EditBulkFixesResult> _getBulkFixes() async {
     var request = EditBulkFixesParams([projectPath]).toRequest('0');
     var response = await waitResponse(request);
-    var result = EditBulkFixesResult.fromResponse(response);
-    return result.edits;
+    return EditBulkFixesResult.fromResponse(response);
   }
 }
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 19588f5..660af49 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart b/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
deleted file mode 100644
index 9dfcaf7..0000000
--- a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../support/integration_tests.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisHighlightsTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  Map<HighlightRegionType, Set<String>> highlights;
-
-  void check(HighlightRegionType type, List<String> expected) {
-    expect(highlights[type], equals(expected.toSet()));
-    highlights.remove(type);
-  }
-
-  Future<void> computeHighlights(String pathname, String text) async {
-    writeFile(pathname, text);
-    standardAnalysisSetup();
-    sendAnalysisSetSubscriptions({
-      AnalysisService.HIGHLIGHTS: [pathname]
-    });
-    // Map from highlight type to highlighted text
-    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
-      expect(params.file, equals(pathname));
-      highlights = <HighlightRegionType, Set<String>>{};
-      for (var region in params.regions) {
-        var startIndex = region.offset;
-        var endIndex = startIndex + region.length;
-        var highlightedText = text.substring(startIndex, endIndex);
-        var type = region.type;
-        if (!highlights.containsKey(type)) {
-          highlights[type] = <String>{};
-        }
-        highlights[type].add(highlightedText);
-      }
-    });
-    await analysisFinished;
-  }
-
-  @override
-  Future startServer({
-    int diagnosticPort,
-    int servicesPort,
-  }) {
-    return server.start(
-        diagnosticPort: diagnosticPort,
-        servicesPort: servicesPort,
-        useAnalysisHighlight2: true);
-  }
-
-  Future<void> test_highlights() async {
-    var pathname = sourcePath('test.dart');
-    var text = r'''
-import 'dart:async' as async;
-
-/**
- * Doc comment
- */
-class Class<TypeParameter> {
-  Class() {
-    field = {1.0: [].toList()};
-  }
-
-  Class.constructor() {
-    dynamic local = true;
-    field = {2: local};
-  }
-
-  Map field = {3: 4};
-  static int staticField = 0;
-
-  method() {
-    // End of line comment
-    /* Block comment */
-  }
-
-  static staticMethod() {
-  }
-
-  get getter {
-  }
-
-  set setter(int parameter) {
-    print(parameter);
-  }
-}
-
-class Class2<TypeParameter> extends Class<TypeParameter> {
-  @override
-  method() {
-  }
-}
-
-typedef functionType();
-
-function(dynamicType) {
-  print('string');
-  unresolvedIdentifier = 42;
-  return async.Future.wait([]);
-}
-
-int topLevelVariable = 0;
-''';
-    await computeHighlights(pathname, text);
-    // There should be 1 error due to the fact that unresolvedIdentifier is
-    // unresolved.
-    expect(currentAnalysisErrors[pathname], hasLength(1));
-
-    check(HighlightRegionType.ANNOTATION, ['@override']);
-    check(HighlightRegionType.BUILT_IN,
-        ['as', 'get', 'import', 'set', 'static', 'typedef']);
-    check(
-        HighlightRegionType.CLASS, ['Class', 'Class2', 'Future', 'Map', 'int']);
-    check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
-    check(HighlightRegionType.COMMENT_DOCUMENTATION,
-        ['/**\n * Doc comment\n */']);
-    check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
-    check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
-    check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
-    check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
-    check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
-    check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
-    check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
-    check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
-    check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
-    check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
-    check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
-    check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
-    check(HighlightRegionType.IMPORT_PREFIX, ['async']);
-    check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
-    check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
-    check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
-    check(HighlightRegionType.LITERAL_INTEGER, ['2', '3', '4', '0', '42']);
-    check(HighlightRegionType.LITERAL_LIST, ['[]']);
-    check(HighlightRegionType.LITERAL_MAP,
-        ['{1.0: [].toList()}', '{2: local}', '{3: 4}']);
-    check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
-    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
-    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
-    check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
-    check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
-    check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
-    check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
-    check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
-    check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
-    check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
-    check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
-    check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
-        ['topLevelVariable']);
-    check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
-    check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
-    expect(highlights, isEmpty);
-  }
-
-  Future<void> test_highlights_mixin() async {
-    var pathname = sourcePath('test.dart');
-    var text = r'''
-mixin M on A implements B {}
-class A {}
-class B {}
-''';
-    await computeHighlights(pathname, text);
-    expect(currentAnalysisErrors[pathname], hasLength(0));
-
-    check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
-    check(HighlightRegionType.KEYWORD, ['class']);
-  }
-}
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
index 63f668b..9dfcaf7 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
@@ -48,6 +48,17 @@
     await analysisFinished;
   }
 
+  @override
+  Future startServer({
+    int diagnosticPort,
+    int servicesPort,
+  }) {
+    return server.start(
+        diagnosticPort: diagnosticPort,
+        servicesPort: servicesPort,
+        useAnalysisHighlight2: true);
+  }
+
   Future<void> test_highlights() async {
     var pathname = sourcePath('test.dart');
     var text = r'''
@@ -81,6 +92,7 @@
   }
 
   set setter(int parameter) {
+    print(parameter);
   }
 }
 
@@ -116,13 +128,14 @@
     check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
     check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
     check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
-    check(HighlightRegionType.DYNAMIC_TYPE, ['dynamicType', 'local']);
-    check(HighlightRegionType.FIELD, ['field']);
-    check(HighlightRegionType.FIELD_STATIC, ['staticField']);
-    check(HighlightRegionType.FUNCTION, ['print']);
-    check(HighlightRegionType.FUNCTION_DECLARATION, ['function']);
+    check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
+    check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
+    check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
+    check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
+    check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
+    check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
     check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
-    check(HighlightRegionType.GETTER_DECLARATION, ['getter']);
+    check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
     check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
     check(HighlightRegionType.IMPORT_PREFIX, ['async']);
     check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
@@ -133,16 +146,18 @@
     check(HighlightRegionType.LITERAL_MAP,
         ['{1.0: [].toList()}', '{2: local}', '{3: 4}']);
     check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
-    //check(HighlightRegionType.LOCAL_VARIABLE, ['local']);
-    //check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']);
-    check(HighlightRegionType.METHOD, ['toList']);
-    check(HighlightRegionType.METHOD_DECLARATION, ['method']);
-    check(HighlightRegionType.METHOD_DECLARATION_STATIC, ['staticMethod']);
-    check(HighlightRegionType.METHOD_STATIC, ['wait']);
-    check(HighlightRegionType.PARAMETER, ['parameter']);
-    check(HighlightRegionType.SETTER_DECLARATION, ['setter']);
-    check(HighlightRegionType.TOP_LEVEL_VARIABLE,
-        ['override', 'topLevelVariable']);
+    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
+    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
+    check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
+    check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
+    check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
+    check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
+    check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
+    check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
+    check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
+    check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
+    check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
+        ['topLevelVariable']);
     check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
     check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
     expect(highlights, isEmpty);
@@ -157,6 +172,7 @@
 ''';
     await computeHighlights(pathname, text);
     expect(currentAnalysisErrors[pathname], hasLength(0));
+
     check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
     check(HighlightRegionType.KEYWORD, ['class']);
   }
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index 2a760bf..2e463f0 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -13,7 +13,6 @@
 import 'get_library_dependencies_test.dart' as get_library_dependencies_test;
 import 'get_navigation_test.dart' as get_navigation_test;
 import 'get_reachable_sources_test.dart' as get_reachable_sources_test;
-import 'highlights2_test.dart' as highlights2_test;
 import 'highlights_test.dart' as highlights_test;
 import 'hint_sdk_version_async_exported_from_core_test.dart'
     as hint_sdk_version_async_exported_from_core_test;
@@ -44,7 +43,6 @@
     get_imported_elements_test.main();
     get_navigation_test.main();
     get_reachable_sources_test.main();
-    highlights2_test.main();
     highlights_test.main();
     hint_sdk_version_async_exported_from_core_test.main();
     lint_test.main();
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index c6f966e..27c7687 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1587,6 +1587,11 @@
   /// edits: List<SourceFileEdit>
   ///
   ///   A list of source edits to apply the recommended changes.
+  ///
+  /// details: List<BulkFix>
+  ///
+  ///   Details that summarize the fixes associated with the recommended
+  ///   changes.
   Future<EditBulkFixesResult> sendEditBulkFixes(List<String> included) async {
     var params = EditBulkFixesParams(included).toJson();
     var result = await server.send('edit.bulkFixes', params);
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 534a918..464139d 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -192,6 +192,24 @@
     'AvailableSuggestionSet',
     {'id': isInt, 'uri': isString, 'items': isListOf(isAvailableSuggestion)}));
 
+/// BulkFix
+///
+/// {
+///   "path": FilePath
+///   "fixes": List<BulkFixDetail>
+/// }
+final Matcher isBulkFix = LazyMatcher(() => MatchesJsonObject(
+    'BulkFix', {'path': isFilePath, 'fixes': isListOf(isBulkFixDetail)}));
+
+/// BulkFixDetail
+///
+/// {
+///   "code": String
+///   "occurrences": int
+/// }
+final Matcher isBulkFixDetail = LazyMatcher(() => MatchesJsonObject(
+    'BulkFixDetail', {'code': isString, 'occurrences': isInt}));
+
 /// ChangeContentOverlay
 ///
 /// {
@@ -288,6 +306,7 @@
 ///   OPTIONAL_ARGUMENT
 ///   OVERRIDE
 ///   PARAMETER
+///   PACKAGE_NAME
 /// }
 final Matcher isCompletionSuggestionKind =
     MatchesEnum('CompletionSuggestionKind', [
@@ -299,7 +318,8 @@
   'NAMED_ARGUMENT',
   'OPTIONAL_ARGUMENT',
   'OVERRIDE',
-  'PARAMETER'
+  'PARAMETER',
+  'PACKAGE_NAME'
 ]);
 
 /// ContextData
@@ -2229,9 +2249,11 @@
 ///
 /// {
 ///   "edits": List<SourceFileEdit>
+///   "details": List<BulkFix>
 /// }
 final Matcher isEditBulkFixesResult = LazyMatcher(() => MatchesJsonObject(
-    'edit.bulkFixes result', {'edits': isListOf(isSourceFileEdit)}));
+    'edit.bulkFixes result',
+    {'edits': isListOf(isSourceFileEdit), 'details': isListOf(isBulkFix)}));
 
 /// edit.dartfix params
 ///
diff --git a/pkg/analysis_server/test/lsp/code_actions_abstract.dart b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
index df1425e..3f59ec8 100644
--- a/pkg/analysis_server/test/lsp/code_actions_abstract.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
 
 import 'server_abstract.dart';
@@ -45,7 +46,7 @@
       [String wantedTitle]) {
     for (var codeAction in actions) {
       final id = codeAction.map(
-          (cmd) => cmd.command, (action) => action.command.command);
+          (cmd) => cmd.command, (action) => action.command?.command);
       final title =
           codeAction.map((cmd) => cmd.title, (action) => action.title);
       if (id == commandID && (wantedTitle == null || wantedTitle == title)) {
@@ -74,6 +75,15 @@
     }).toList();
   }
 
+  Future<Either2<Command, CodeAction>> getFixAllAction(
+      String title, Uri uri, String content) async {
+    final codeActions =
+        await getCodeActions(uri.toString(), range: rangeFromMarkers(content));
+    final fixAction =
+        findCommand(codeActions, Commands.fixAllOfErrorCodeInFile, title);
+    return fixAction;
+  }
+
   /// Verifies that executing the given code actions command on the server
   /// results in an edit being sent in the client that updates the file to match
   /// the expected content.
diff --git a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
index c424137..bf327be 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -12,6 +12,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(FixesCodeActionsTest);
+    defineReflectiveTests(FixesCodeActionsWithNullSafetyTest);
   });
 }
 
@@ -95,7 +96,7 @@
     expect(contents[mainFilePath], equals(expectedContent));
   }
 
-  Future<void> test_noDuplicates() async {
+  Future<void> test_noDuplicates_sameFix() async {
     const content = '''
     var a = [Test, Test, Te[[]]st];
     ''';
@@ -209,3 +210,153 @@
     expect(codeActions, isEmpty);
   }
 }
+
+@reflectiveTest
+class FixesCodeActionsWithNullSafetyTest extends AbstractCodeActionsTest {
+  @override
+  String get testPackageLanguageVersion => latestLanguageVersion;
+
+  Future<void> test_fixAll_notForAmbigiousProducers() async {
+    // The ReplaceWithIsEmpty producer does not provide a FixKind up-front, as
+    // it may produce `REPLACE_WITH_IS_EMPTY` or `REPLACE_WITH_IS_NOT_EMPTY`
+    // depending on the code.
+    // This test ensures this does not crash, and does not produce an apply-all.
+    registerLintRules();
+    newFile(analysisOptionsPath, content: '''
+linter:
+  rules:
+    - prefer_is_empty
+    ''');
+
+    const content = '''
+var a = [];
+var b = a.[[length]] == 0;
+var c = a.length == 0;
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final allFixes = await getCodeActions(mainFileUri.toString(),
+        range: rangeFromMarkers(content));
+
+    // Expect only the single-fix, there should be no apply-all.
+    expect(allFixes, hasLength(1));
+    final fixTitle = allFixes.first.map((f) => f.title, (f) => f.title);
+    expect(fixTitle, equals("Replace with \'isEmpty\'"));
+  }
+
+  Future<void> test_fixAll_notWhenNoBatchFix() async {
+    // Some fixes (for example 'create function foo') are not available in the
+    // batch processor, so should not generate Apply-all fixes even if there
+    // are multiple.
+    const content = '''
+var a = [[foo]]();
+var b = bar();
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final allFixes = await getCodeActions(mainFileUri.toString(),
+        range: rangeFromMarkers(content));
+
+    // Expect only the single-fix, there should be no apply-all.
+    expect(allFixes, hasLength(1));
+    final fixTitle = allFixes.first.map((f) => f.title, (f) => f.title);
+    expect(fixTitle, equals("Create function 'foo'"));
+  }
+
+  Future<void> test_fixAll_notWhenSingle() async {
+    const content = '''
+void f(String a) {
+  [[print(a!)]];
+}
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final fixAction = await getFixAllAction(
+        "Apply all: Remove the '!'", mainFileUri, content);
+
+    // Should not appear if there was only a single error.
+    expect(fixAction, isNull);
+  }
+
+  Future<void> test_fixAll_whenMultiple() async {
+    const content = '''
+void f(String a) {
+  [[print(a!!)]];
+  print(a!!);
+}
+    ''';
+
+    const expectedContent = '''
+void f(String a) {
+  print(a);
+  print(a);
+}
+    ''';
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final fixAction = await getFixAllAction(
+        "Apply all: Remove the '!'", mainFileUri, content);
+
+    expect(fixAction, isNotNull);
+
+    await verifyCodeActionEdits(
+        fixAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_noDuplicates_differentFix() async {
+    // For convenience, quick-fixes are usually returned for the entire line,
+    // though this can lead to duplicate entries (by title) when multiple
+    // diagnostics have their own fixes of the same type.
+    //
+    // Expect only the only one nearest to the start of the range to be returned.
+    const content = '''
+    main() {
+      var a = [];
+      print(a!!);^
+    }
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final caretPos = positionFromMarker(content);
+
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        range: Range(start: caretPos, end: caretPos));
+    final removeNnaAction = findEditActions(codeActions,
+        CodeActionKind('quickfix.remove.nonNullAssertion'), "Remove the '!'");
+
+    // Expect only one of the fixes.
+    expect(removeNnaAction, hasLength(1));
+
+    // Ensure the action is for the diagnostic on the second bang which was
+    // closest to the range requested.
+    final secondBangPos =
+        positionFromOffset(withoutMarkers(content).indexOf('!);'), content);
+    expect(removeNnaAction.first.diagnostics, hasLength(1));
+    final diagStart = removeNnaAction.first.diagnostics.first.range.start;
+    expect(diagStart, equals(secondBangPos));
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index f797e2b..0db9f8d 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -205,7 +205,7 @@
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle);
     await verifyCodeActionEdits(
         codeAction, withoutMarkers(content), expectedContent,
-        workDoneToken: testWorkDoneToken);
+        workDoneToken: clientProvidedTestWorkDoneToken);
   }
 
   Future<void> test_progress_notSupported() async {
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
new file mode 100644
index 0000000..f71db6c
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -0,0 +1,1435 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../tool/lsp_spec/matchers.dart';
+import 'server_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(CompletionTest);
+    defineReflectiveTests(CompletionTestWithNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class CompletionTest extends AbstractLspAnalysisServerTest {
+  void expectAutoImportCompletion(List<CompletionItem> items, String file) {
+    expect(
+      items.singleWhere(
+        (c) => c.detail?.contains("Auto import from '$file'") ?? false,
+        orElse: () => null,
+      ),
+      isNotNull,
+    );
+  }
+
+  Future<void> test_commitCharacter_completionItem() async {
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withAllSupportedDynamicRegistrations(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities:
+            withConfigurationSupport(emptyWorkspaceClientCapabilities),
+      ),
+      {'previewCommitCharacters': true},
+    );
+
+    final content = '''
+main() {
+  pri^
+}
+    ''';
+
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final print = res.singleWhere((c) => c.label == 'print(…)');
+    expect(print.commitCharacters, equals(dartCompletionCommitCharacters));
+  }
+
+  Future<void> test_commitCharacter_config() async {
+    final registrations = <Registration>[];
+    // Provide empty config and collect dynamic registrations during
+    // initialization.
+    await provideConfig(
+      () => monitorDynamicRegistrations(
+        registrations,
+        () => initialize(
+            textDocumentCapabilities: withAllSupportedDynamicRegistrations(
+                emptyTextDocumentClientCapabilities),
+            workspaceCapabilities:
+                withDidChangeConfigurationDynamicRegistration(
+                    withConfigurationSupport(
+                        emptyWorkspaceClientCapabilities))),
+      ),
+      {},
+    );
+
+    Registration registration(Method method) =>
+        registrationFor(registrations, method);
+
+    // By default, there should be no commit characters.
+    var reg = registration(Method.textDocument_completion);
+    var options = CompletionRegistrationOptions.fromJson(reg.registerOptions);
+    expect(options.allCommitCharacters, isNull);
+
+    // When we change config, we should get a re-registration (unregister then
+    // register) for completion which now includes the commit characters.
+    await monitorDynamicReregistration(
+        registrations, () => updateConfig({'previewCommitCharacters': true}));
+    reg = registration(Method.textDocument_completion);
+    options = CompletionRegistrationOptions.fromJson(reg.registerOptions);
+    expect(options.allCommitCharacters, equals(dartCompletionCommitCharacters));
+  }
+
+  Future<void> test_completeFunctionCalls() async {
+    final content = '''
+    void myFunction(String a, int b, {String c}) {}
+
+    main() {
+      [[myFu^]]
+    }
+    ''';
+
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities:
+            withConfigurationSupport(emptyWorkspaceClientCapabilities),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
+    // Ensure the snippet comes through in the expected format with the expected
+    // placeholders.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b})'));
+    expect(item.textEdit.newText, equals(item.insertText));
+    expect(
+      item.textEdit.range,
+      equals(rangeFromMarkers(content)),
+    );
+  }
+
+  Future<void> test_completeFunctionCalls_noRequiredParameters() async {
+    final content = '''
+    void myFunction({int a}) {}
+
+    main() {
+      [[myFu^]]
+    }
+    ''';
+
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities:
+            withConfigurationSupport(emptyWorkspaceClientCapabilities),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
+    // With no required params, there should still be parens and a tabstop inside.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'myFunction(${0:})'));
+    expect(item.textEdit.newText, equals(item.insertText));
+    expect(
+      item.textEdit.range,
+      equals(rangeFromMarkers(content)),
+    );
+  }
+
+  Future<void> test_completeFunctionCalls_show() async {
+    final content = '''
+    import 'dart:math' show mi^
+    ''';
+
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities:
+            withConfigurationSupport(emptyWorkspaceClientCapabilities),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'min(…)');
+    // The insert text should be a simple string with no parens/args and
+    // no need for snippets.
+    expect(item.insertTextFormat, isNull);
+    expect(item.insertText, equals(r'min'));
+    expect(item.textEdit.newText, equals(item.insertText));
+  }
+
+  Future<void> test_completeFunctionCalls_suggestionSets() async {
+    final content = '''
+    main() {
+      [[pri]]^
+    }
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities: withConfigurationSupport(
+            withApplyEditSupport(emptyWorkspaceClientCapabilities)),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'print(…)');
+    // Ensure the snippet comes through in the expected format with the expected
+    // placeholders.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'print(${0:object})'));
+    expect(item.textEdit, isNull);
+
+    // Ensure the item can be resolved and gets a proper TextEdit.
+    final resolved = await resolveCompletion(item);
+    expect(resolved.textEdit, isNotNull);
+    expect(resolved.textEdit.newText, equals(item.insertText));
+    expect(
+      resolved.textEdit.range,
+      equals(rangeFromMarkers(content)),
+    );
+  }
+
+  Future<void> test_completionKinds_default() async {
+    newFile(join(projectFolderPath, 'file.dart'));
+    newFolder(join(projectFolderPath, 'folder'));
+
+    final content = "import '^';";
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final file = res.singleWhere((c) => c.label == 'file.dart');
+    final folder = res.singleWhere((c) => c.label == 'folder/');
+    final builtin = res.singleWhere((c) => c.label == 'dart:core');
+    // Default capabilities include File + Module but not Folder.
+    expect(file.kind, equals(CompletionItemKind.File));
+    // We fall back to Module if Folder isn't supported.
+    expect(folder.kind, equals(CompletionItemKind.Module));
+    expect(builtin.kind, equals(CompletionItemKind.Module));
+  }
+
+  Future<void> test_completionKinds_imports() async {
+    final content = "import '^';";
+
+    // Tell the server we support some specific CompletionItemKinds.
+    await initialize(
+      textDocumentCapabilities: withCompletionItemKinds(
+        emptyTextDocumentClientCapabilities,
+        [
+          CompletionItemKind.File,
+          CompletionItemKind.Folder,
+          CompletionItemKind.Module,
+        ],
+      ),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final file = res.singleWhere((c) => c.label == 'file.dart');
+    final folder = res.singleWhere((c) => c.label == 'folder/');
+    final builtin = res.singleWhere((c) => c.label == 'dart:core');
+    expect(file.kind, equals(CompletionItemKind.File));
+    expect(folder.kind, equals(CompletionItemKind.Folder));
+    expect(builtin.kind, equals(CompletionItemKind.Module));
+  }
+
+  Future<void> test_completionKinds_supportedSubset() async {
+    final content = '''
+    class MyClass {
+      String abcdefghij;
+    }
+
+    main() {
+      MyClass a;
+      a.abc^
+    }
+    ''';
+
+    // Tell the server we only support the Field CompletionItemKind.
+    await initialize(
+      textDocumentCapabilities: withCompletionItemKinds(
+          emptyTextDocumentClientCapabilities, [CompletionItemKind.Field]),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final kinds = res.map((item) => item.kind).toList();
+
+    // Ensure we only get nulls or Fields (the sample code contains Classes).
+    expect(
+      kinds,
+      everyElement(anyOf(isNull, equals(CompletionItemKind.Field))),
+    );
+  }
+
+  Future<void> test_completionTriggerKinds_invalidParams() async {
+    await initialize();
+
+    final invalidTriggerKind = CompletionTriggerKind.fromJson(-1);
+    final request = getCompletion(
+      mainFileUri,
+      Position(line: 0, character: 0),
+      context: CompletionContext(
+          triggerKind: invalidTriggerKind, triggerCharacter: 'A'),
+    );
+
+    await expectLater(
+        request, throwsA(isResponseError(ErrorCodes.InvalidParams)));
+  }
+
+  Future<void> test_fromPlugin_dartFile() async {
+    final content = '''
+    void main() {
+      var x = '';
+      print(^);
+    }
+    ''';
+
+    final pluginResult = plugin.CompletionGetSuggestionsResult(
+      content.indexOf('^'),
+      0,
+      [
+        plugin.CompletionSuggestion(
+          plugin.CompletionSuggestionKind.INVOCATION,
+          100,
+          'x.toUpperCase()',
+          -1,
+          -1,
+          false,
+          false,
+        ),
+      ],
+    );
+    configureTestPlugin(respondWith: pluginResult);
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final fromServer = res.singleWhere((c) => c.label == 'x');
+    final fromPlugin = res.singleWhere((c) => c.label == 'x.toUpperCase()');
+
+    expect(fromServer.kind, equals(CompletionItemKind.Variable));
+    expect(fromPlugin.kind, equals(CompletionItemKind.Method));
+  }
+
+  Future<void> test_fromPlugin_nonDartFile() async {
+    final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.foo');
+    final pluginAnalyzedFileUri = Uri.file(pluginAnalyzedFilePath);
+    final content = '''
+    CREATE TABLE foo (
+      id INTEGER NOT NULL PRIMARY KEY
+    );
+
+    query: SELECT ^ FROM foo;
+    ''';
+
+    final pluginResult = plugin.CompletionGetSuggestionsResult(
+      content.indexOf('^'),
+      0,
+      [
+        plugin.CompletionSuggestion(
+          plugin.CompletionSuggestionKind.IDENTIFIER,
+          100,
+          'id',
+          -1,
+          -1,
+          false,
+          false,
+        ),
+      ],
+    );
+    configureTestPlugin(respondWith: pluginResult);
+
+    await initialize();
+    await openFile(pluginAnalyzedFileUri, withoutMarkers(content));
+    final res =
+        await getCompletion(pluginAnalyzedFileUri, positionFromMarker(content));
+
+    expect(res, hasLength(1));
+    final suggestion = res.single;
+
+    expect(suggestion.kind, CompletionItemKind.Variable);
+    expect(suggestion.label, equals('id'));
+  }
+
+  Future<void> test_fromPlugin_tooSlow() async {
+    final content = '''
+    void main() {
+      var x = '';
+      print(^);
+    }
+    ''';
+
+    final pluginResult = plugin.CompletionGetSuggestionsResult(
+      content.indexOf('^'),
+      0,
+      [
+        plugin.CompletionSuggestion(
+          plugin.CompletionSuggestionKind.INVOCATION,
+          100,
+          'x.toUpperCase()',
+          -1,
+          -1,
+          false,
+          false,
+        ),
+      ],
+    );
+    configureTestPlugin(
+      respondWith: pluginResult,
+      // Don't respond within an acceptable time
+      respondAfter: Duration(seconds: 1),
+    );
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final fromServer = res.singleWhere((c) => c.label == 'x');
+    final fromPlugin = res.singleWhere((c) => c.label == 'x.toUpperCase()',
+        orElse: () => null);
+
+    // Server results should still be included.
+    expect(fromServer.kind, equals(CompletionItemKind.Variable));
+    // Plugin results are not because they didn't arrive in time.
+    expect(fromPlugin, isNull);
+  }
+
+  Future<void> test_gettersAndSetters() async {
+    final content = '''
+    class MyClass {
+      String get justGetter => '';
+      String set justSetter(String value) {}
+      String get getterAndSetter => '';
+      String set getterAndSetter(String value) {}
+    }
+
+    main() {
+      MyClass a;
+      a.^
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final getter = res.singleWhere((c) => c.label == 'justGetter');
+    final setter = res.singleWhere((c) => c.label == 'justSetter');
+    final both = res.singleWhere((c) => c.label == 'getterAndSetter');
+    expect(getter.detail, equals('String'));
+    expect(setter.detail, equals('String'));
+    expect(both.detail, equals('String'));
+    [getter, setter, both].forEach((item) {
+      expect(item.kind, equals(CompletionItemKind.Property));
+    });
+  }
+
+  Future<void> test_insideString() async {
+    final content = '''
+    var a = "This is ^a test"
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res, isEmpty);
+  }
+
+  Future<void> test_isDeprecated_notSupported() async {
+    final content = '''
+    class MyClass {
+      @deprecated
+      String abcdefghij;
+    }
+
+    main() {
+      MyClass a;
+      a.abc^
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'abcdefghij');
+    expect(item.deprecated, isNull);
+    // If the does not say it supports the deprecated flag, we should show
+    // '(deprecated)' in the details.
+    expect(item.detail.toLowerCase(), contains('deprecated'));
+  }
+
+  Future<void> test_isDeprecated_supportedFlag() async {
+    final content = '''
+    class MyClass {
+      @deprecated
+      String abcdefghij;
+    }
+
+    main() {
+      MyClass a;
+      a.abc^
+    }
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withCompletionItemDeprecatedFlagSupport(
+            emptyTextDocumentClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'abcdefghij');
+    expect(item.deprecated, isTrue);
+    // If the client says it supports the deprecated flag, we should not show
+    // deprecated in the details.
+    expect(item.detail, isNot(contains('deprecated')));
+  }
+
+  Future<void> test_isDeprecated_supportedTag() async {
+    final content = '''
+    class MyClass {
+      @deprecated
+      String abcdefghij;
+    }
+
+    main() {
+      MyClass a;
+      a.abc^
+    }
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withCompletionItemTagSupport(
+            emptyTextDocumentClientCapabilities,
+            [CompletionItemTag.Deprecated]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'abcdefghij');
+    expect(item.tags, contains(CompletionItemTag.Deprecated));
+    // If the client says it supports the deprecated tag, we should not show
+    // deprecated in the details.
+    expect(item.detail, isNot(contains('deprecated')));
+  }
+
+  Future<void> test_namedArg_offsetBeforeCompletionTarget() async {
+    // This test checks for a previous bug where the completion target was a
+    // symbol far after the cursor offset (`aaaa` here) and caused the whole
+    // identifier to be used as the `targetPrefix` which would filter out
+    // other symbol.
+    // https://github.com/Dart-Code/Dart-Code/issues/2672#issuecomment-666085575
+    final content = '''
+    void main() {
+      myFunction(
+        ^
+        aaaa: '',
+      );
+    }
+
+    void myFunction({String aaaa, String aaab, String aaac}) {}
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'aaab: '), isTrue);
+  }
+
+  Future<void> test_namedArg_plainText() async {
+    final content = '''
+    class A { const A({int one}); }
+    @A(^)
+    main() { }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'one: '), isTrue);
+    final item = res.singleWhere((c) => c.label == 'one: ');
+    expect(item.insertTextFormat,
+        anyOf(equals(InsertTextFormat.PlainText), isNull));
+    expect(item.insertText, anyOf(equals('test'), isNull));
+    final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
+    expect(updated, contains('one: '));
+  }
+
+  Future<void> test_namedArg_snippetStringSelection_endOfString() async {
+    final content = '''
+    class A { const A({int one}); }
+    @A(^)
+    main() { }
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'one: '), isTrue);
+    final item = res.singleWhere((c) => c.label == 'one: ');
+    // As the selection is the end of the string, there's no need for a snippet
+    // here. Since the insert text is also the same as the label, it does not
+    // need to be provided.
+    expect(item.insertTextFormat, isNull);
+    expect(item.insertText, isNull);
+    expect(item.textEdit.newText, equals('one: '));
+    expect(
+      item.textEdit.range,
+      equals(Range(
+          start: positionFromMarker(content),
+          end: positionFromMarker(content))),
+    );
+  }
+
+  Future<void>
+      test_namedArgTrailing_snippetStringSelection_insideString() async {
+    final content = '''
+    main({int one, int two}) {
+      main(
+        ^
+        two: 2,
+      );
+    }
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'one: '), isTrue);
+    final item = res.singleWhere((c) => c.label == 'one: ');
+    // Ensure the snippet comes through in the expected format with the expected
+    // placeholder.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'one: ${0:},'));
+    expect(item.textEdit.newText, equals(r'one: ${0:},'));
+    expect(
+      item.textEdit.range,
+      equals(Range(
+          start: positionFromMarker(content),
+          end: positionFromMarker(content))),
+    );
+  }
+
+  Future<void> test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final res = await getCompletion(pubspecFileUri, startOfDocPos);
+    expect(res, isEmpty);
+  }
+
+  Future<void> test_parensNotInFilterTextInsertText() async {
+    final content = '''
+    class MyClass {}
+
+    main() {
+      MyClass a = new MyCla^
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'MyClass()'), isTrue);
+    final item = res.singleWhere((c) => c.label == 'MyClass()');
+    expect(item.filterText, equals('MyClass'));
+    expect(item.insertText, equals('MyClass'));
+  }
+
+  Future<void> test_plainText() async {
+    final content = '''
+    class MyClass {
+      String abcdefghij;
+    }
+
+    main() {
+      MyClass a;
+      a.abc^
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
+    final item = res.singleWhere((c) => c.label == 'abcdefghij');
+    expect(item.insertTextFormat,
+        anyOf(equals(InsertTextFormat.PlainText), isNull));
+    expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
+    final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
+    expect(updated, contains('a.abcdefghij'));
+  }
+
+  Future<void> test_prefixFilter_endOfSymbol() async {
+    final content = '''
+    class UniqueNamedClassForLspOne {}
+    class UniqueNamedClassForLspTwo {}
+    class UniqueNamedClassForLspThree {}
+
+    main() {
+      // Should match only Two and Three
+      UniqueNamedClassForLspT^
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
+  }
+
+  Future<void> test_prefixFilter_midSymbol() async {
+    final content = '''
+    class UniqueNamedClassForLspOne {}
+    class UniqueNamedClassForLspTwo {}
+    class UniqueNamedClassForLspThree {}
+
+    main() {
+      // Should match only Two and Three
+      UniqueNamedClassForLspT^hree
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
+  }
+
+  Future<void> test_prefixFilter_startOfSymbol() async {
+    final content = '''
+    class UniqueNamedClassForLspOne {}
+    class UniqueNamedClassForLspTwo {}
+    class UniqueNamedClassForLspThree {}
+
+    main() {
+      // Should match all three
+      ^UniqueNamedClassForLspT
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isTrue);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
+  }
+
+  Future<void> test_suggestionSets() async {
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: '''
+      /// This class is in another file.
+      class InOtherFile {}
+      ''',
+    );
+
+    final content = '''
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Find the completion for the class in the other file.
+    final completion = res.singleWhere((c) => c.label == 'InOtherFile');
+    expect(completion, isNotNull);
+
+    // Expect no docs or text edit, since these are added during resolve.
+    expect(completion.documentation, isNull);
+    expect(completion.textEdit, isNull);
+
+    // Resolve the completion item (via server) to get its edits. This is the
+    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
+    // populate additional info (in our case, the additional edits for inserting
+    // the import).
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+
+    // Ensure the detail field was update to show this will auto-import.
+    expect(
+        resolved.detail, startsWith("Auto import from '../other_file.dart'"));
+
+    // Ensure the doc comment was added.
+    expect(
+      resolved.documentation.valueEquals('This class is in another file.'),
+      isTrue,
+    );
+
+    // Ensure the edit was added on.
+    expect(resolved.textEdit, isNotNull);
+
+    // There should be no command for this item because it doesn't need imports
+    // in other files. Same-file completions are in additionalEdits.
+    expect(resolved.command, isNull);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+
+    // Ensure both edits were made - the completion, and the inserted import.
+    expect(newContent, equals('''
+import '../other_file.dart';
+
+main() {
+  InOtherFile
+}
+    '''));
+  }
+
+  Future<void> test_suggestionSets_doesNotFilterSymbolsWithSameName() async {
+    // Classes here are not re-exports, so should not be filtered out.
+    newFile(
+      join(projectFolderPath, 'source_file1.dart'),
+      content: 'class MyDuplicatedClass {}',
+    );
+    newFile(
+      join(projectFolderPath, 'source_file2.dart'),
+      content: 'class MyDuplicatedClass {}',
+    );
+    newFile(
+      join(projectFolderPath, 'source_file3.dart'),
+      content: 'class MyDuplicatedClass {}',
+    );
+
+    final content = '''
+main() {
+  MyDuplicated^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completions =
+        res.where((c) => c.label == 'MyDuplicatedClass').toList();
+    expect(completions, hasLength(3));
+
+    // Resolve the completions so we can get the auto-import text.
+    final resolvedCompletions =
+        await Future.wait(completions.map(resolveCompletion));
+
+    expectAutoImportCompletion(resolvedCompletions, '../source_file1.dart');
+    expectAutoImportCompletion(resolvedCompletions, '../source_file2.dart');
+    expectAutoImportCompletion(resolvedCompletions, '../source_file3.dart');
+  }
+
+  Future<void> test_suggestionSets_enumValues() async {
+    newFile(
+      join(projectFolderPath, 'source_file.dart'),
+      content: '''
+      enum MyExportedEnum { One, Two }
+      ''',
+    );
+
+    final content = '''
+main() {
+  var a = MyExported^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final enumCompletions =
+        res.where((c) => c.label.startsWith('MyExportedEnum')).toList();
+    expect(
+        enumCompletions.map((c) => c.label),
+        unorderedEquals(
+            ['MyExportedEnum', 'MyExportedEnum.One', 'MyExportedEnum.Two']));
+
+    final completion =
+        enumCompletions.singleWhere((c) => c.label == 'MyExportedEnum.One');
+
+    // Resolve the completion item (via server) to get its edits. This is the
+    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
+    // populate additional info (in our case, the additional edits for inserting
+    // the import).
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+
+    // Ensure the detail field was update to show this will auto-import.
+    expect(
+        resolved.detail, startsWith("Auto import from '../source_file.dart'"));
+
+    // Ensure the edit was added on.
+    expect(resolved.textEdit, isNotNull);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+
+    // Ensure both edits were made - the completion, and the inserted import.
+    expect(newContent, equals('''
+import '../source_file.dart';
+
+main() {
+  var a = MyExportedEnum.One
+}
+    '''));
+  }
+
+  Future<void> test_suggestionSets_enumValuesAlreadyImported() async {
+    newFile(
+      join(projectFolderPath, 'lib', 'source_file.dart'),
+      content: '''
+      enum MyExportedEnum { One, Two }
+      ''',
+    );
+    newFile(
+      join(projectFolderPath, 'lib', 'reexport1.dart'),
+      content: '''
+      export 'source_file.dart';
+      ''',
+    );
+    newFile(
+      join(projectFolderPath, 'lib', 'reexport2.dart'),
+      content: '''
+      export 'source_file.dart';
+      ''',
+    );
+
+    final content = '''
+import 'reexport1.dart';
+
+main() {
+  var a = MyExported^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completions =
+        res.where((c) => c.label == 'MyExportedEnum.One').toList();
+    expect(completions, hasLength(1));
+    final resolved = await resolveCompletion(completions.first);
+    // It should not include auto-import text since it's already imported.
+    expect(resolved.detail, isNull);
+  }
+
+  Future<void> test_suggestionSets_filtersOutAlreadyImportedSymbols() async {
+    newFile(
+      join(projectFolderPath, 'lib', 'source_file.dart'),
+      content: '''
+      class MyExportedClass {}
+      ''',
+    );
+    newFile(
+      join(projectFolderPath, 'lib', 'reexport1.dart'),
+      content: '''
+      export 'source_file.dart';
+      ''',
+    );
+    newFile(
+      join(projectFolderPath, 'lib', 'reexport2.dart'),
+      content: '''
+      export 'source_file.dart';
+      ''',
+    );
+
+    final content = '''
+import 'reexport1.dart';
+
+main() {
+  MyExported^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completions = res.where((c) => c.label == 'MyExportedClass').toList();
+    expect(completions, hasLength(1));
+    final resolved = await resolveCompletion(completions.first);
+    // It should not include auto-import text since it's already imported.
+    expect(resolved.detail, isNull);
+  }
+
+  Future<void>
+      test_suggestionSets_includesReexportedSymbolsForEachFile() async {
+    newFile(
+      join(projectFolderPath, 'source_file.dart'),
+      content: '''
+      class MyExportedClass {}
+      ''',
+    );
+    newFile(
+      join(projectFolderPath, 'reexport1.dart'),
+      content: '''
+      export 'source_file.dart';
+      ''',
+    );
+    newFile(
+      join(projectFolderPath, 'reexport2.dart'),
+      content: '''
+      export 'source_file.dart';
+      ''',
+    );
+
+    final content = '''
+main() {
+  MyExported^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completions = res.where((c) => c.label == 'MyExportedClass').toList();
+    expect(completions, hasLength(3));
+
+    // Resolve the completions so we can get the auto-import text.
+    final resolvedCompletions =
+        await Future.wait(completions.map(resolveCompletion));
+
+    expectAutoImportCompletion(resolvedCompletions, '../source_file.dart');
+    expectAutoImportCompletion(resolvedCompletions, '../reexport1.dart');
+    expectAutoImportCompletion(resolvedCompletions, '../reexport2.dart');
+  }
+
+  Future<void> test_suggestionSets_insertsIntoPartFiles() async {
+    // File we'll be adding an import for.
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    // File that will have the import added.
+    final parentContent = '''part 'main.dart';''';
+    final parentFilePath = newFile(
+      join(projectFolderPath, 'lib', 'parent.dart'),
+      content: parentContent,
+    ).path;
+
+    // File that we're invoking completion in.
+    final content = '''
+part of 'parent.dart';
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completion = res.singleWhere((c) => c.label == 'InOtherFile');
+    expect(completion, isNotNull);
+
+    // Resolve the completion item to get its edits.
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+    // Ensure it has a command, since it will need to make edits in other files
+    // and that's done by telling the server to send a workspace/applyEdit. LSP
+    // doesn't currently support these other-file edits in the completion.
+    // See https://github.com/microsoft/language-server-protocol/issues/749
+    expect(resolved.command, isNotNull);
+
+    // Apply all current-document edits.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+    expect(newContent, equals('''
+part of 'parent.dart';
+main() {
+  InOtherFile
+}
+    '''));
+
+    // Execute the associated command (which will handle edits in other files).
+    ApplyWorkspaceEditParams editParams;
+    final commandResponse = await handleExpectedRequest<Object,
+        ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse>(
+      Method.workspace_applyEdit,
+      ApplyWorkspaceEditParams.fromJson,
+      () => executeCommand(resolved.command),
+      handler: (edit) {
+        // When the server sends the edit back, just keep a copy and say we
+        // applied successfully (it'll be verified below).
+        editParams = edit;
+        return ApplyWorkspaceEditResponse(applied: true);
+      },
+    );
+    // Successful edits return an empty success() response.
+    expect(commandResponse, isNull);
+
+    // Ensure the edit came back.
+    expect(editParams, isNotNull);
+    expect(editParams.edit.changes, isNotNull);
+
+    // Ensure applying the changes will give us the expected content.
+    final contents = {
+      parentFilePath: withoutMarkers(parentContent),
+    };
+    applyChanges(contents, editParams.edit.changes);
+
+    // Check the parent file was modified to include the import by the edits
+    // that came from the server.
+    expect(contents[parentFilePath], equals('''
+import '../other_file.dart';
+
+part 'main.dart';'''));
+  }
+
+  Future<void> test_suggestionSets_members() async {
+    newFile(
+      join(projectFolderPath, 'source_file.dart'),
+      content: '''
+      class MyExportedClass {
+        DateTime myInstanceDateTime;
+        static DateTime myStaticDateTimeField;
+        static DateTime get myStaticDateTimeGetter => null;
+      }
+      ''',
+    );
+
+    final content = '''
+main() {
+  var a = MyExported^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completions =
+        res.where((c) => c.label.startsWith('MyExportedClass')).toList();
+    expect(
+        completions.map((c) => c.label),
+        unorderedEquals([
+          'MyExportedClass',
+          'MyExportedClass()',
+          // The instance field should not show up.
+          'MyExportedClass.myStaticDateTimeField',
+          'MyExportedClass.myStaticDateTimeGetter'
+        ]));
+
+    final completion = completions
+        .singleWhere((c) => c.label == 'MyExportedClass.myStaticDateTimeField');
+
+    // Resolve the completion item (via server) to get its edits. This is the
+    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
+    // populate additional info (in our case, the additional edits for inserting
+    // the import).
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+
+    // Ensure the detail field was update to show this will auto-import.
+    expect(
+        resolved.detail, startsWith("Auto import from '../source_file.dart'"));
+
+    // Ensure the edit was added on.
+    expect(resolved.textEdit, isNotNull);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+
+    // Ensure both edits were made - the completion, and the inserted import.
+    expect(newContent, equals('''
+import '../source_file.dart';
+
+main() {
+  var a = MyExportedClass.myStaticDateTimeField
+}
+    '''));
+  }
+
+  /// This test reproduces a bug where the pathKey hash used in
+  /// available_declarations.dart would not change with the contents of the file
+  /// (as it always used 0 as the modification stamp) which would prevent
+  /// completion including items from files that were open (had overlays).
+  /// https://github.com/Dart-Code/Dart-Code/issues/2286#issuecomment-658597532
+  Future<void> test_suggestionSets_modifiedFiles() async {
+    final otherFilePath = join(projectFolderPath, 'lib', 'other_file.dart');
+    final otherFileUri = Uri.file(otherFilePath);
+
+    final mainFileContent = 'MyOtherClass^';
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(mainFileContent));
+    await initialAnalysis;
+
+    // Start with a blank file.
+    newFile(otherFilePath, content: '');
+    await openFile(otherFileUri, '');
+    await pumpEventQueue(times: 5000);
+
+    // Reopen the file with a class definition.
+    await closeFile(otherFileUri);
+    await openFile(otherFileUri, 'class MyOtherClass {}');
+    await pumpEventQueue(times: 5000);
+
+    // Ensure the class appears in completion.
+    final completions =
+        await getCompletion(mainFileUri, positionFromMarker(mainFileContent));
+    final matching =
+        completions.where((c) => c.label == 'MyOtherClass').toList();
+    expect(matching, hasLength(1));
+  }
+
+  Future<void> test_suggestionSets_namedConstructors() async {
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: '''
+      /// This class is in another file.
+      class InOtherFile {
+        InOtherFile.fromJson() {}
+      }
+      ''',
+    );
+
+    final content = '''
+main() {
+  var a = InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Find the completion for the class in the other file.
+    final completion =
+        res.singleWhere((c) => c.label == 'InOtherFile.fromJson()');
+    expect(completion, isNotNull);
+
+    // Expect no docs or text edit, since these are added during resolve.
+    expect(completion.documentation, isNull);
+    expect(completion.textEdit, isNull);
+
+    // Resolve the completion item (via server) to get its edits. This is the
+    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
+    // populate additional info (in our case, the additional edits for inserting
+    // the import).
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+
+    // Ensure both edits were made - the completion, and the inserted import.
+    expect(newContent, equals('''
+import '../other_file.dart';
+
+main() {
+  var a = InOtherFile.fromJson
+}
+    '''));
+  }
+
+  Future<void> test_suggestionSets_unavailableIfDisabled() async {
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    final content = '''
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    // Support applyEdit, but explicitly disable the suggestions.
+    await initialize(
+      initializationOptions: {'suggestFromUnimportedLibraries': false},
+      workspaceCapabilities:
+          withApplyEditSupport(emptyWorkspaceClientCapabilities),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Ensure the item doesn't appear in the results (because we might not
+    // be able to execute the import edits if they're in another file).
+    final completion = res.singleWhere(
+      (c) => c.label == 'InOtherFile',
+      orElse: () => null,
+    );
+    expect(completion, isNull);
+  }
+
+  Future<void> test_suggestionSets_unavailableWithoutApplyEdit() async {
+    // If client doesn't advertise support for workspace/applyEdit, we won't
+    // include suggestion sets.
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    final content = '''
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Ensure the item doesn't appear in the results (because we might not
+    // be able to execute the import edits if they're in another file).
+    final completion = res.singleWhere(
+      (c) => c.label == 'InOtherFile',
+      orElse: () => null,
+    );
+    expect(completion, isNull);
+  }
+
+  Future<void> test_unopenFile() async {
+    final content = '''
+    class MyClass {
+      String abcdefghij;
+    }
+
+    main() {
+      MyClass a;
+      a.abc^
+    }
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
+    final item = res.singleWhere((c) => c.label == 'abcdefghij');
+    expect(item.insertTextFormat,
+        anyOf(equals(InsertTextFormat.PlainText), isNull));
+    expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
+    final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
+    expect(updated, contains('a.abcdefghij'));
+  }
+}
+
+@reflectiveTest
+class CompletionTestWithNullSafetyTest extends AbstractLspAnalysisServerTest {
+  @override
+  String get testPackageLanguageVersion => latestLanguageVersion;
+
+  @failingTest
+  Future<void> test_completeFunctionCalls_requiredNamed() async {
+    // TODO(dantup): Find out how we can tell this parameter is required
+    // (in the completion mapping).
+    final content = '''
+    void myFunction(String a, int b, {required String c, String d = ''}) {}
+
+    main() {
+      [[myFu^]]
+    }
+    ''';
+
+    await provideConfig(
+      () => initialize(
+        textDocumentCapabilities: withCompletionItemSnippetSupport(
+            emptyTextDocumentClientCapabilities),
+        workspaceCapabilities:
+            withConfigurationSupport(emptyWorkspaceClientCapabilities),
+      ),
+      {'completeFunctionCalls': true},
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final item = res.singleWhere((c) => c.label == 'myFunction(…)');
+    // Ensure the snippet comes through in the expected format with the expected
+    // placeholders.
+    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+    expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b}, ${2:c})'));
+    expect(item.textEdit.newText, equals(item.insertText));
+    expect(
+      item.textEdit.range,
+      equals(rangeFromMarkers(content)),
+    );
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
deleted file mode 100644
index cdecc6f..0000000
--- a/pkg/analysis_server/test/lsp/completion_test.dart
+++ /dev/null
@@ -1,1239 +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:analysis_server/lsp_protocol/protocol_generated.dart';
-import 'package:analysis_server/src/lsp/constants.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../tool/lsp_spec/matchers.dart';
-import 'server_abstract.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(CompletionTest);
-  });
-}
-
-@reflectiveTest
-class CompletionTest extends AbstractLspAnalysisServerTest {
-  void expectAutoImportCompletion(List<CompletionItem> items, String file) {
-    expect(
-      items.singleWhere(
-        (c) => c.detail?.contains("Auto import from '$file'") ?? false,
-        orElse: () => null,
-      ),
-      isNotNull,
-    );
-  }
-
-  Future<void> test_commitCharacter_completionItem() async {
-    await provideConfig(
-      () => initialize(
-        textDocumentCapabilities: withAllSupportedDynamicRegistrations(
-            emptyTextDocumentClientCapabilities),
-        workspaceCapabilities:
-            withConfigurationSupport(emptyWorkspaceClientCapabilities),
-      ),
-      {'previewCommitCharacters': true},
-    );
-
-    final content = '''
-main() {
-  pri^
-}
-    ''';
-
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final print = res.singleWhere((c) => c.label == 'print(…)');
-    expect(print.commitCharacters, equals(dartCompletionCommitCharacters));
-  }
-
-  Future<void> test_commitCharacter_config() async {
-    final registrations = <Registration>[];
-    // Provide empty config and collect dynamic registrations during
-    // initialization.
-    await provideConfig(
-      () => monitorDynamicRegistrations(
-        registrations,
-        () => initialize(
-            textDocumentCapabilities: withAllSupportedDynamicRegistrations(
-                emptyTextDocumentClientCapabilities),
-            workspaceCapabilities:
-                withDidChangeConfigurationDynamicRegistration(
-                    withConfigurationSupport(
-                        emptyWorkspaceClientCapabilities))),
-      ),
-      {},
-    );
-
-    Registration registration(Method method) =>
-        registrationFor(registrations, method);
-
-    // By default, there should be no commit characters.
-    var reg = registration(Method.textDocument_completion);
-    var options = CompletionRegistrationOptions.fromJson(reg.registerOptions);
-    expect(options.allCommitCharacters, isNull);
-
-    // When we change config, we should get a re-registration (unregister then
-    // register) for completion which now includes the commit characters.
-    await monitorDynamicReregistration(
-        registrations, () => updateConfig({'previewCommitCharacters': true}));
-    reg = registration(Method.textDocument_completion);
-    options = CompletionRegistrationOptions.fromJson(reg.registerOptions);
-    expect(options.allCommitCharacters, equals(dartCompletionCommitCharacters));
-  }
-
-  Future<void> test_completionKinds_default() async {
-    newFile(join(projectFolderPath, 'file.dart'));
-    newFolder(join(projectFolderPath, 'folder'));
-
-    final content = "import '^';";
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final file = res.singleWhere((c) => c.label == 'file.dart');
-    final folder = res.singleWhere((c) => c.label == 'folder/');
-    final builtin = res.singleWhere((c) => c.label == 'dart:core');
-    // Default capabilities include File + Module but not Folder.
-    expect(file.kind, equals(CompletionItemKind.File));
-    // We fall back to Module if Folder isn't supported.
-    expect(folder.kind, equals(CompletionItemKind.Module));
-    expect(builtin.kind, equals(CompletionItemKind.Module));
-  }
-
-  Future<void> test_completionKinds_imports() async {
-    final content = "import '^';";
-
-    // Tell the server we support some specific CompletionItemKinds.
-    await initialize(
-      textDocumentCapabilities: withCompletionItemKinds(
-        emptyTextDocumentClientCapabilities,
-        [
-          CompletionItemKind.File,
-          CompletionItemKind.Folder,
-          CompletionItemKind.Module,
-        ],
-      ),
-    );
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final file = res.singleWhere((c) => c.label == 'file.dart');
-    final folder = res.singleWhere((c) => c.label == 'folder/');
-    final builtin = res.singleWhere((c) => c.label == 'dart:core');
-    expect(file.kind, equals(CompletionItemKind.File));
-    expect(folder.kind, equals(CompletionItemKind.Folder));
-    expect(builtin.kind, equals(CompletionItemKind.Module));
-  }
-
-  Future<void> test_completionKinds_supportedSubset() async {
-    final content = '''
-    class MyClass {
-      String abcdefghij;
-    }
-
-    main() {
-      MyClass a;
-      a.abc^
-    }
-    ''';
-
-    // Tell the server we only support the Field CompletionItemKind.
-    await initialize(
-      textDocumentCapabilities: withCompletionItemKinds(
-          emptyTextDocumentClientCapabilities, [CompletionItemKind.Field]),
-    );
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final kinds = res.map((item) => item.kind).toList();
-
-    // Ensure we only get nulls or Fields (the sample code contains Classes).
-    expect(
-      kinds,
-      everyElement(anyOf(isNull, equals(CompletionItemKind.Field))),
-    );
-  }
-
-  Future<void> test_completionTriggerKinds_invalidParams() async {
-    await initialize();
-
-    final invalidTriggerKind = CompletionTriggerKind.fromJson(-1);
-    final request = getCompletion(
-      mainFileUri,
-      Position(line: 0, character: 0),
-      context: CompletionContext(
-          triggerKind: invalidTriggerKind, triggerCharacter: 'A'),
-    );
-
-    await expectLater(
-        request, throwsA(isResponseError(ErrorCodes.InvalidParams)));
-  }
-
-  Future<void> test_fromPlugin_dartFile() async {
-    final content = '''
-    void main() {
-      var x = '';
-      print(^);
-    }
-    ''';
-
-    final pluginResult = plugin.CompletionGetSuggestionsResult(
-      content.indexOf('^'),
-      0,
-      [
-        plugin.CompletionSuggestion(
-          plugin.CompletionSuggestionKind.INVOCATION,
-          100,
-          'x.toUpperCase()',
-          -1,
-          -1,
-          false,
-          false,
-        ),
-      ],
-    );
-    configureTestPlugin(respondWith: pluginResult);
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final fromServer = res.singleWhere((c) => c.label == 'x');
-    final fromPlugin = res.singleWhere((c) => c.label == 'x.toUpperCase()');
-
-    expect(fromServer.kind, equals(CompletionItemKind.Variable));
-    expect(fromPlugin.kind, equals(CompletionItemKind.Method));
-  }
-
-  Future<void> test_fromPlugin_nonDartFile() async {
-    final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.foo');
-    final pluginAnalyzedFileUri = Uri.file(pluginAnalyzedFilePath);
-    final content = '''
-    CREATE TABLE foo (
-      id INTEGER NOT NULL PRIMARY KEY
-    );
-
-    query: SELECT ^ FROM foo;
-    ''';
-
-    final pluginResult = plugin.CompletionGetSuggestionsResult(
-      content.indexOf('^'),
-      0,
-      [
-        plugin.CompletionSuggestion(
-          plugin.CompletionSuggestionKind.IDENTIFIER,
-          100,
-          'id',
-          -1,
-          -1,
-          false,
-          false,
-        ),
-      ],
-    );
-    configureTestPlugin(respondWith: pluginResult);
-
-    await initialize();
-    await openFile(pluginAnalyzedFileUri, withoutMarkers(content));
-    final res =
-        await getCompletion(pluginAnalyzedFileUri, positionFromMarker(content));
-
-    expect(res, hasLength(1));
-    final suggestion = res.single;
-
-    expect(suggestion.kind, CompletionItemKind.Variable);
-    expect(suggestion.label, equals('id'));
-  }
-
-  Future<void> test_fromPlugin_tooSlow() async {
-    final content = '''
-    void main() {
-      var x = '';
-      print(^);
-    }
-    ''';
-
-    final pluginResult = plugin.CompletionGetSuggestionsResult(
-      content.indexOf('^'),
-      0,
-      [
-        plugin.CompletionSuggestion(
-          plugin.CompletionSuggestionKind.INVOCATION,
-          100,
-          'x.toUpperCase()',
-          -1,
-          -1,
-          false,
-          false,
-        ),
-      ],
-    );
-    configureTestPlugin(
-      respondWith: pluginResult,
-      // Don't respond within an acceptable time
-      respondAfter: Duration(seconds: 1),
-    );
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final fromServer = res.singleWhere((c) => c.label == 'x');
-    final fromPlugin = res.singleWhere((c) => c.label == 'x.toUpperCase()',
-        orElse: () => null);
-
-    // Server results should still be included.
-    expect(fromServer.kind, equals(CompletionItemKind.Variable));
-    // Plugin results are not because they didn't arrive in time.
-    expect(fromPlugin, isNull);
-  }
-
-  Future<void> test_gettersAndSetters() async {
-    final content = '''
-    class MyClass {
-      String get justGetter => '';
-      String set justSetter(String value) {}
-      String get getterAndSetter => '';
-      String set getterAndSetter(String value) {}
-    }
-
-    main() {
-      MyClass a;
-      a.^
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final getter = res.singleWhere((c) => c.label == 'justGetter');
-    final setter = res.singleWhere((c) => c.label == 'justSetter');
-    final both = res.singleWhere((c) => c.label == 'getterAndSetter');
-    expect(getter.detail, equals('String'));
-    expect(setter.detail, equals('String'));
-    expect(both.detail, equals('String'));
-    [getter, setter, both].forEach((item) {
-      expect(item.kind, equals(CompletionItemKind.Property));
-    });
-  }
-
-  Future<void> test_insideString() async {
-    final content = '''
-    var a = "This is ^a test"
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res, isEmpty);
-  }
-
-  Future<void> test_isDeprecated_notSupported() async {
-    final content = '''
-    class MyClass {
-      @deprecated
-      String abcdefghij;
-    }
-
-    main() {
-      MyClass a;
-      a.abc^
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final item = res.singleWhere((c) => c.label == 'abcdefghij');
-    // ignore: deprecated_member_use_from_same_package
-    expect(item.deprecated, isNull);
-    // If the does not say it supports the deprecated flag, we should show
-    // '(deprecated)' in the details.
-    expect(item.detail.toLowerCase(), contains('deprecated'));
-  }
-
-  Future<void> test_isDeprecated_supportedFlag() async {
-    final content = '''
-    class MyClass {
-      @deprecated
-      String abcdefghij;
-    }
-
-    main() {
-      MyClass a;
-      a.abc^
-    }
-    ''';
-
-    await initialize(
-        textDocumentCapabilities: withCompletionItemDeprecatedFlagSupport(
-            emptyTextDocumentClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final item = res.singleWhere((c) => c.label == 'abcdefghij');
-    // ignore: deprecated_member_use_from_same_package
-    expect(item.deprecated, isTrue);
-    // If the client says it supports the deprecated flag, we should not show
-    // deprecated in the details.
-    expect(item.detail, isNot(contains('deprecated')));
-  }
-
-  Future<void> test_isDeprecated_supportedTag() async {
-    final content = '''
-    class MyClass {
-      @deprecated
-      String abcdefghij;
-    }
-
-    main() {
-      MyClass a;
-      a.abc^
-    }
-    ''';
-
-    await initialize(
-        textDocumentCapabilities: withCompletionItemTagSupport(
-            emptyTextDocumentClientCapabilities,
-            [CompletionItemTag.Deprecated]));
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    final item = res.singleWhere((c) => c.label == 'abcdefghij');
-    expect(item.tags, contains(CompletionItemTag.Deprecated));
-    // If the client says it supports the deprecated tag, we should not show
-    // deprecated in the details.
-    expect(item.detail, isNot(contains('deprecated')));
-  }
-
-  Future<void> test_namedArg_offsetBeforeCompletionTarget() async {
-    // This test checks for a previous bug where the completion target was a
-    // symbol far after the cursor offset (`aaaa` here) and caused the whole
-    // identifier to be used as the `targetPrefix` which would filter out
-    // other symbol.
-    // https://github.com/Dart-Code/Dart-Code/issues/2672#issuecomment-666085575
-    final content = '''
-    void main() {
-      myFunction(
-        ^
-        aaaa: '',
-      );
-    }
-
-    void myFunction({String aaaa, String aaab, String aaac}) {}
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'aaab: '), isTrue);
-  }
-
-  Future<void> test_namedArg_plainText() async {
-    final content = '''
-    class A { const A({int one}); }
-    @A(^)
-    main() { }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'one: '), isTrue);
-    final item = res.singleWhere((c) => c.label == 'one: ');
-    expect(item.insertTextFormat,
-        anyOf(equals(InsertTextFormat.PlainText), isNull));
-    expect(item.insertText, anyOf(equals('test'), isNull));
-    final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
-    expect(updated, contains('one: '));
-  }
-
-  Future<void> test_namedArg_snippetStringSelection() async {
-    final content = '''
-    class A { const A({int one}); }
-    @A(^)
-    main() { }
-    ''';
-
-    await initialize(
-        textDocumentCapabilities: withCompletionItemSnippetSupport(
-            emptyTextDocumentClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'one: '), isTrue);
-    final item = res.singleWhere((c) => c.label == 'one: ');
-    // Ensure the snippet comes through in the expected format with the expected
-    // placeholder.
-    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
-    expect(item.insertText, equals(r'one: ${1:}'));
-    expect(item.textEdit.newText, equals(r'one: ${1:}'));
-    expect(
-      item.textEdit.range,
-      equals(Range(
-          start: positionFromMarker(content),
-          end: positionFromMarker(content))),
-    );
-  }
-
-  Future<void> test_nonDartFile() async {
-    newFile(pubspecFilePath, content: simplePubspecContent);
-    await initialize();
-
-    final res = await getCompletion(pubspecFileUri, startOfDocPos);
-    expect(res, isEmpty);
-  }
-
-  Future<void> test_parensNotInFilterTextInsertText() async {
-    final content = '''
-    class MyClass {}
-
-    main() {
-      MyClass a = new MyCla^
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'MyClass()'), isTrue);
-    final item = res.singleWhere((c) => c.label == 'MyClass()');
-    expect(item.filterText, equals('MyClass'));
-    expect(item.insertText, equals('MyClass'));
-  }
-
-  Future<void> test_plainText() async {
-    final content = '''
-    class MyClass {
-      String abcdefghij;
-    }
-
-    main() {
-      MyClass a;
-      a.abc^
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
-    final item = res.singleWhere((c) => c.label == 'abcdefghij');
-    expect(item.insertTextFormat,
-        anyOf(equals(InsertTextFormat.PlainText), isNull));
-    expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
-    final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
-    expect(updated, contains('a.abcdefghij'));
-  }
-
-  Future<void> test_prefixFilter_endOfSymbol() async {
-    final content = '''
-    class UniqueNamedClassForLspOne {}
-    class UniqueNamedClassForLspTwo {}
-    class UniqueNamedClassForLspThree {}
-
-    main() {
-      // Should match only Two and Three
-      UniqueNamedClassForLspT^
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
-  }
-
-  Future<void> test_prefixFilter_midSymbol() async {
-    final content = '''
-    class UniqueNamedClassForLspOne {}
-    class UniqueNamedClassForLspTwo {}
-    class UniqueNamedClassForLspThree {}
-
-    main() {
-      // Should match only Two and Three
-      UniqueNamedClassForLspT^hree
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
-  }
-
-  Future<void> test_prefixFilter_startOfSymbol() async {
-    final content = '''
-    class UniqueNamedClassForLspOne {}
-    class UniqueNamedClassForLspTwo {}
-    class UniqueNamedClassForLspThree {}
-
-    main() {
-      // Should match all three
-      ^UniqueNamedClassForLspT
-    }
-    ''';
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isTrue);
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
-    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
-  }
-
-  Future<void> test_suggestionSets() async {
-    newFile(
-      join(projectFolderPath, 'other_file.dart'),
-      content: '''
-      /// This class is in another file.
-      class InOtherFile {}
-      ''',
-    );
-
-    final content = '''
-main() {
-  InOtherF^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    // Find the completion for the class in the other file.
-    final completion = res.singleWhere((c) => c.label == 'InOtherFile');
-    expect(completion, isNotNull);
-
-    // Expect no docs or text edit, since these are added during resolve.
-    expect(completion.documentation, isNull);
-    expect(completion.textEdit, isNull);
-
-    // Resolve the completion item (via server) to get its edits. This is the
-    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
-    // populate additional info (in our case, the additional edits for inserting
-    // the import).
-    final resolved = await resolveCompletion(completion);
-    expect(resolved, isNotNull);
-
-    // Ensure the detail field was update to show this will auto-import.
-    expect(
-        resolved.detail, startsWith("Auto import from '../other_file.dart'"));
-
-    // Ensure the doc comment was added.
-    expect(
-      resolved.documentation.valueEquals('This class is in another file.'),
-      isTrue,
-    );
-
-    // Ensure the edit was added on.
-    expect(resolved.textEdit, isNotNull);
-
-    // There should be no command for this item because it doesn't need imports
-    // in other files. Same-file completions are in additionalEdits.
-    expect(resolved.command, isNull);
-
-    // Apply both the main completion edit and the additionalTextEdits atomically.
-    final newContent = applyTextEdits(
-      withoutMarkers(content),
-      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
-    );
-
-    // Ensure both edits were made - the completion, and the inserted import.
-    expect(newContent, equals('''
-import '../other_file.dart';
-
-main() {
-  InOtherFile
-}
-    '''));
-  }
-
-  Future<void> test_suggestionSets_doesNotFilterSymbolsWithSameName() async {
-    // Classes here are not re-exports, so should not be filtered out.
-    newFile(
-      join(projectFolderPath, 'source_file1.dart'),
-      content: 'class MyDuplicatedClass {}',
-    );
-    newFile(
-      join(projectFolderPath, 'source_file2.dart'),
-      content: 'class MyDuplicatedClass {}',
-    );
-    newFile(
-      join(projectFolderPath, 'source_file3.dart'),
-      content: 'class MyDuplicatedClass {}',
-    );
-
-    final content = '''
-main() {
-  MyDuplicated^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completions =
-        res.where((c) => c.label == 'MyDuplicatedClass').toList();
-    expect(completions, hasLength(3));
-
-    // Resolve the completions so we can get the auto-import text.
-    final resolvedCompletions =
-        await Future.wait(completions.map(resolveCompletion));
-
-    expectAutoImportCompletion(resolvedCompletions, '../source_file1.dart');
-    expectAutoImportCompletion(resolvedCompletions, '../source_file2.dart');
-    expectAutoImportCompletion(resolvedCompletions, '../source_file3.dart');
-  }
-
-  Future<void> test_suggestionSets_enumValues() async {
-    newFile(
-      join(projectFolderPath, 'source_file.dart'),
-      content: '''
-      enum MyExportedEnum { One, Two }
-      ''',
-    );
-
-    final content = '''
-main() {
-  var a = MyExported^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final enumCompletions =
-        res.where((c) => c.label.startsWith('MyExportedEnum')).toList();
-    expect(
-        enumCompletions.map((c) => c.label),
-        unorderedEquals(
-            ['MyExportedEnum', 'MyExportedEnum.One', 'MyExportedEnum.Two']));
-
-    final completion =
-        enumCompletions.singleWhere((c) => c.label == 'MyExportedEnum.One');
-
-    // Resolve the completion item (via server) to get its edits. This is the
-    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
-    // populate additional info (in our case, the additional edits for inserting
-    // the import).
-    final resolved = await resolveCompletion(completion);
-    expect(resolved, isNotNull);
-
-    // Ensure the detail field was update to show this will auto-import.
-    expect(
-        resolved.detail, startsWith("Auto import from '../source_file.dart'"));
-
-    // Ensure the edit was added on.
-    expect(resolved.textEdit, isNotNull);
-
-    // Apply both the main completion edit and the additionalTextEdits atomically.
-    final newContent = applyTextEdits(
-      withoutMarkers(content),
-      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
-    );
-
-    // Ensure both edits were made - the completion, and the inserted import.
-    expect(newContent, equals('''
-import '../source_file.dart';
-
-main() {
-  var a = MyExportedEnum.One
-}
-    '''));
-  }
-
-  Future<void> test_suggestionSets_enumValuesAlreadyImported() async {
-    newFile(
-      join(projectFolderPath, 'lib', 'source_file.dart'),
-      content: '''
-      enum MyExportedEnum { One, Two }
-      ''',
-    );
-    newFile(
-      join(projectFolderPath, 'lib', 'reexport1.dart'),
-      content: '''
-      export 'source_file.dart';
-      ''',
-    );
-    newFile(
-      join(projectFolderPath, 'lib', 'reexport2.dart'),
-      content: '''
-      export 'source_file.dart';
-      ''',
-    );
-
-    final content = '''
-import 'reexport1.dart';
-
-main() {
-  var a = MyExported^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completions =
-        res.where((c) => c.label == 'MyExportedEnum.One').toList();
-    expect(completions, hasLength(1));
-    final resolved = await resolveCompletion(completions.first);
-    // It should not include auto-import text since it's already imported.
-    expect(resolved.detail, isNull);
-  }
-
-  Future<void> test_suggestionSets_filtersOutAlreadyImportedSymbols() async {
-    newFile(
-      join(projectFolderPath, 'lib', 'source_file.dart'),
-      content: '''
-      class MyExportedClass {}
-      ''',
-    );
-    newFile(
-      join(projectFolderPath, 'lib', 'reexport1.dart'),
-      content: '''
-      export 'source_file.dart';
-      ''',
-    );
-    newFile(
-      join(projectFolderPath, 'lib', 'reexport2.dart'),
-      content: '''
-      export 'source_file.dart';
-      ''',
-    );
-
-    final content = '''
-import 'reexport1.dart';
-
-main() {
-  MyExported^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completions = res.where((c) => c.label == 'MyExportedClass').toList();
-    expect(completions, hasLength(1));
-    final resolved = await resolveCompletion(completions.first);
-    // It should not include auto-import text since it's already imported.
-    expect(resolved.detail, isNull);
-  }
-
-  Future<void>
-      test_suggestionSets_includesReexportedSymbolsForEachFile() async {
-    newFile(
-      join(projectFolderPath, 'source_file.dart'),
-      content: '''
-      class MyExportedClass {}
-      ''',
-    );
-    newFile(
-      join(projectFolderPath, 'reexport1.dart'),
-      content: '''
-      export 'source_file.dart';
-      ''',
-    );
-    newFile(
-      join(projectFolderPath, 'reexport2.dart'),
-      content: '''
-      export 'source_file.dart';
-      ''',
-    );
-
-    final content = '''
-main() {
-  MyExported^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completions = res.where((c) => c.label == 'MyExportedClass').toList();
-    expect(completions, hasLength(3));
-
-    // Resolve the completions so we can get the auto-import text.
-    final resolvedCompletions =
-        await Future.wait(completions.map(resolveCompletion));
-
-    expectAutoImportCompletion(resolvedCompletions, '../source_file.dart');
-    expectAutoImportCompletion(resolvedCompletions, '../reexport1.dart');
-    expectAutoImportCompletion(resolvedCompletions, '../reexport2.dart');
-  }
-
-  Future<void> test_suggestionSets_insertsIntoPartFiles() async {
-    // File we'll be adding an import for.
-    newFile(
-      join(projectFolderPath, 'other_file.dart'),
-      content: 'class InOtherFile {}',
-    );
-
-    // File that will have the import added.
-    final parentContent = '''part 'main.dart';''';
-    final parentFilePath = newFile(
-      join(projectFolderPath, 'lib', 'parent.dart'),
-      content: parentContent,
-    ).path;
-
-    // File that we're invoking completion in.
-    final content = '''
-part of 'parent.dart';
-main() {
-  InOtherF^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completion = res.singleWhere((c) => c.label == 'InOtherFile');
-    expect(completion, isNotNull);
-
-    // Resolve the completion item to get its edits.
-    final resolved = await resolveCompletion(completion);
-    expect(resolved, isNotNull);
-    // Ensure it has a command, since it will need to make edits in other files
-    // and that's done by telling the server to send a workspace/applyEdit. LSP
-    // doesn't currently support these other-file edits in the completion.
-    // See https://github.com/microsoft/language-server-protocol/issues/749
-    expect(resolved.command, isNotNull);
-
-    // Apply all current-document edits.
-    final newContent = applyTextEdits(
-      withoutMarkers(content),
-      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
-    );
-    expect(newContent, equals('''
-part of 'parent.dart';
-main() {
-  InOtherFile
-}
-    '''));
-
-    // Execute the associated command (which will handle edits in other files).
-    ApplyWorkspaceEditParams editParams;
-    final commandResponse = await handleExpectedRequest<Object,
-        ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse>(
-      Method.workspace_applyEdit,
-      ApplyWorkspaceEditParams.fromJson,
-      () => executeCommand(resolved.command),
-      handler: (edit) {
-        // When the server sends the edit back, just keep a copy and say we
-        // applied successfully (it'll be verified below).
-        editParams = edit;
-        return ApplyWorkspaceEditResponse(applied: true);
-      },
-    );
-    // Successful edits return an empty success() response.
-    expect(commandResponse, isNull);
-
-    // Ensure the edit came back.
-    expect(editParams, isNotNull);
-    expect(editParams.edit.changes, isNotNull);
-
-    // Ensure applying the changes will give us the expected content.
-    final contents = {
-      parentFilePath: withoutMarkers(parentContent),
-    };
-    applyChanges(contents, editParams.edit.changes);
-
-    // Check the parent file was modified to include the import by the edits
-    // that came from the server.
-    expect(contents[parentFilePath], equals('''
-import '../other_file.dart';
-
-part 'main.dart';'''));
-  }
-
-  Future<void> test_suggestionSets_members() async {
-    newFile(
-      join(projectFolderPath, 'source_file.dart'),
-      content: '''
-      class MyExportedClass {
-        DateTime myInstanceDateTime;
-        static DateTime myStaticDateTimeField;
-        static DateTime get myStaticDateTimeGetter => null;
-      }
-      ''',
-    );
-
-    final content = '''
-main() {
-  var a = MyExported^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    final completions =
-        res.where((c) => c.label.startsWith('MyExportedClass')).toList();
-    expect(
-        completions.map((c) => c.label),
-        unorderedEquals([
-          'MyExportedClass',
-          'MyExportedClass()',
-          // The instance field should not show up.
-          'MyExportedClass.myStaticDateTimeField',
-          'MyExportedClass.myStaticDateTimeGetter'
-        ]));
-
-    final completion = completions
-        .singleWhere((c) => c.label == 'MyExportedClass.myStaticDateTimeField');
-
-    // Resolve the completion item (via server) to get its edits. This is the
-    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
-    // populate additional info (in our case, the additional edits for inserting
-    // the import).
-    final resolved = await resolveCompletion(completion);
-    expect(resolved, isNotNull);
-
-    // Ensure the detail field was update to show this will auto-import.
-    expect(
-        resolved.detail, startsWith("Auto import from '../source_file.dart'"));
-
-    // Ensure the edit was added on.
-    expect(resolved.textEdit, isNotNull);
-
-    // Apply both the main completion edit and the additionalTextEdits atomically.
-    final newContent = applyTextEdits(
-      withoutMarkers(content),
-      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
-    );
-
-    // Ensure both edits were made - the completion, and the inserted import.
-    expect(newContent, equals('''
-import '../source_file.dart';
-
-main() {
-  var a = MyExportedClass.myStaticDateTimeField
-}
-    '''));
-  }
-
-  /// This test reproduces a bug where the pathKey hash used in
-  /// available_declarations.dart would not change with the contents of the file
-  /// (as it always used 0 as the modification stamp) which would prevent
-  /// completion including items from files that were open (had overlays).
-  /// https://github.com/Dart-Code/Dart-Code/issues/2286#issuecomment-658597532
-  Future<void> test_suggestionSets_modifiedFiles() async {
-    final otherFilePath = join(projectFolderPath, 'lib', 'other_file.dart');
-    final otherFileUri = Uri.file(otherFilePath);
-
-    final mainFileContent = 'MyOtherClass^';
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(mainFileContent));
-    await initialAnalysis;
-
-    // Start with a blank file.
-    newFile(otherFilePath, content: '');
-    await openFile(otherFileUri, '');
-    await pumpEventQueue(times: 5000);
-
-    // Reopen the file with a class definition.
-    await closeFile(otherFileUri);
-    await openFile(otherFileUri, 'class MyOtherClass {}');
-    await pumpEventQueue(times: 5000);
-
-    // Ensure the class appears in completion.
-    final completions =
-        await getCompletion(mainFileUri, positionFromMarker(mainFileContent));
-    final matching =
-        completions.where((c) => c.label == 'MyOtherClass').toList();
-    expect(matching, hasLength(1));
-  }
-
-  Future<void> test_suggestionSets_namedConstructors() async {
-    newFile(
-      join(projectFolderPath, 'other_file.dart'),
-      content: '''
-      /// This class is in another file.
-      class InOtherFile {
-        InOtherFile.fromJson() {}
-      }
-      ''',
-    );
-
-    final content = '''
-main() {
-  var a = InOtherF^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize(
-        workspaceCapabilities:
-            withApplyEditSupport(emptyWorkspaceClientCapabilities));
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    // Find the completion for the class in the other file.
-    final completion =
-        res.singleWhere((c) => c.label == 'InOtherFile.fromJson()');
-    expect(completion, isNotNull);
-
-    // Expect no docs or text edit, since these are added during resolve.
-    expect(completion.documentation, isNull);
-    expect(completion.textEdit, isNull);
-
-    // Resolve the completion item (via server) to get its edits. This is the
-    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
-    // populate additional info (in our case, the additional edits for inserting
-    // the import).
-    final resolved = await resolveCompletion(completion);
-    expect(resolved, isNotNull);
-
-    // Apply both the main completion edit and the additionalTextEdits atomically.
-    final newContent = applyTextEdits(
-      withoutMarkers(content),
-      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
-    );
-
-    // Ensure both edits were made - the completion, and the inserted import.
-    expect(newContent, equals('''
-import '../other_file.dart';
-
-main() {
-  var a = InOtherFile.fromJson
-}
-    '''));
-  }
-
-  Future<void> test_suggestionSets_unavailableIfDisabled() async {
-    newFile(
-      join(projectFolderPath, 'other_file.dart'),
-      content: 'class InOtherFile {}',
-    );
-
-    final content = '''
-main() {
-  InOtherF^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    // Support applyEdit, but explicitly disable the suggestions.
-    await initialize(
-      initializationOptions: {'suggestFromUnimportedLibraries': false},
-      workspaceCapabilities:
-          withApplyEditSupport(emptyWorkspaceClientCapabilities),
-    );
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    // Ensure the item doesn't appear in the results (because we might not
-    // be able to execute the import edits if they're in another file).
-    final completion = res.singleWhere(
-      (c) => c.label == 'InOtherFile',
-      orElse: () => null,
-    );
-    expect(completion, isNull);
-  }
-
-  Future<void> test_suggestionSets_unavailableWithoutApplyEdit() async {
-    // If client doesn't advertise support for workspace/applyEdit, we won't
-    // include suggestion sets.
-    newFile(
-      join(projectFolderPath, 'other_file.dart'),
-      content: 'class InOtherFile {}',
-    );
-
-    final content = '''
-main() {
-  InOtherF^
-}
-    ''';
-
-    final initialAnalysis = waitForAnalysisComplete();
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-    await initialAnalysis;
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-
-    // Ensure the item doesn't appear in the results (because we might not
-    // be able to execute the import edits if they're in another file).
-    final completion = res.singleWhere(
-      (c) => c.label == 'InOtherFile',
-      orElse: () => null,
-    );
-    expect(completion, isNull);
-  }
-
-  Future<void> test_unopenFile() async {
-    final content = '''
-    class MyClass {
-      String abcdefghij;
-    }
-
-    main() {
-      MyClass a;
-      a.abc^
-    }
-    ''';
-
-    newFile(mainFilePath, content: withoutMarkers(content));
-    await initialize();
-    final res = await getCompletion(mainFileUri, positionFromMarker(content));
-    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
-    final item = res.singleWhere((c) => c.label == 'abcdefghij');
-    expect(item.insertTextFormat,
-        anyOf(equals(InsertTextFormat.PlainText), isNull));
-    expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
-    final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
-    expect(updated, contains('a.abcdefghij'));
-  }
-}
diff --git a/pkg/analysis_server/test/lsp/completion_yaml_test.dart b/pkg/analysis_server/test/lsp/completion_yaml_test.dart
new file mode 100644
index 0000000..0802d65
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/completion_yaml_test.dart
@@ -0,0 +1,302 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:linter/src/rules.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PubspecCompletionTest);
+    defineReflectiveTests(AnalysisOptionsCompletionTest);
+    defineReflectiveTests(FixDataCompletionTest);
+  });
+}
+
+@reflectiveTest
+class AnalysisOptionsCompletionTest extends AbstractLspAnalysisServerTest
+    with CompletionTestMixin {
+  @override
+  void setUp() {
+    registerLintRules();
+    super.setUp();
+  }
+
+  Future<void> test_nested() async {
+    final content = '''
+linter:
+  rules:
+    - ^''';
+
+    final expected = '''
+linter:
+  rules:
+    - annotate_overrides''';
+
+    await verifyCompletions(
+      analysisOptionsUri,
+      content,
+      expectCompletions: [
+        'always_declare_return_types',
+        'annotate_overrides',
+      ],
+      verifyEditsFor: 'annotate_overrides',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_nested_prefix() async {
+    final content = '''
+linter:
+  rules:
+    - ann^''';
+
+    final expected = '''
+linter:
+  rules:
+    - annotate_overrides''';
+
+    await verifyCompletions(
+      analysisOptionsUri,
+      content,
+      expectCompletions: ['annotate_overrides'],
+      verifyEditsFor: 'annotate_overrides',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_topLevel() async {
+    final content = '''
+^''';
+    final expected = '''
+linter: ''';
+
+    await verifyCompletions(
+      analysisOptionsUri,
+      content,
+      expectCompletions: ['linter: '],
+      verifyEditsFor: 'linter: ',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_topLevel_prefix() async {
+    final content = '''
+li^''';
+    final expected = '''
+linter: ''';
+
+    await verifyCompletions(
+      analysisOptionsUri,
+      content,
+      expectCompletions: ['linter: '],
+      verifyEditsFor: 'linter: ',
+      expectedContent: expected,
+    );
+  }
+}
+
+mixin CompletionTestMixin on AbstractLspAnalysisServerTest {
+  Future<void> verifyCompletions(
+    Uri fileUri,
+    String content, {
+    List<String> expectCompletions,
+    String verifyEditsFor,
+    String expectedContent,
+  }) async {
+    await initialize();
+    await openFile(fileUri, withoutMarkers(content));
+    final res = await getCompletion(fileUri, positionFromMarker(content));
+
+    for (final expectedCompletion in expectCompletions) {
+      expect(
+        res.any((c) => c.label == expectedCompletion),
+        isTrue,
+        reason:
+            '"$expectedCompletion" was not in ${res.map((c) => '"${c.label}"')}',
+      );
+    }
+
+    // Check the edits apply correctly.
+    if (verifyEditsFor != null) {
+      final item = res.singleWhere((c) => c.label == verifyEditsFor);
+      expect(item.insertTextFormat, isNull);
+      expect(item.insertText, isNull);
+      final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
+      expect(updated, equals(expectedContent));
+    }
+  }
+}
+
+@reflectiveTest
+class FixDataCompletionTest extends AbstractLspAnalysisServerTest
+    with CompletionTestMixin {
+  Uri fixDataUri;
+
+  @override
+  void setUp() {
+    super.setUp();
+    fixDataUri = Uri.file(join(projectFolderPath, 'lib', 'fix_data.yaml'));
+  }
+
+  Future<void> test_nested() async {
+    final content = '''
+version: 1.0.0
+transforms:
+  - changes:
+    - ^''';
+    final expected = '''
+version: 1.0.0
+transforms:
+  - changes:
+    - kind: ''';
+
+    await verifyCompletions(
+      fixDataUri,
+      content,
+      expectCompletions: ['kind: '],
+      verifyEditsFor: 'kind: ',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_nested_prefix() async {
+    final content = '''
+version: 1.0.0
+transforms:
+  - changes:
+    - ki^''';
+    final expected = '''
+version: 1.0.0
+transforms:
+  - changes:
+    - kind: ''';
+
+    await verifyCompletions(
+      fixDataUri,
+      content,
+      expectCompletions: ['kind: '],
+      verifyEditsFor: 'kind: ',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_topLevel() async {
+    final content = '''
+version: 1.0.0
+^''';
+    final expected = '''
+version: 1.0.0
+transforms:''';
+
+    await verifyCompletions(
+      fixDataUri,
+      content,
+      expectCompletions: ['transforms:'],
+      verifyEditsFor: 'transforms:',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_topLevel_prefix() async {
+    final content = '''
+tra^''';
+    final expected = '''
+transforms:''';
+
+    await verifyCompletions(
+      fixDataUri,
+      content,
+      expectCompletions: ['transforms:'],
+      verifyEditsFor: 'transforms:',
+      expectedContent: expected,
+    );
+  }
+}
+
+@reflectiveTest
+class PubspecCompletionTest extends AbstractLspAnalysisServerTest
+    with CompletionTestMixin {
+  Future<void> test_nested() async {
+    final content = '''
+name: foo
+version: 1.0.0
+
+environment:
+  ^''';
+
+    final expected = '''
+name: foo
+version: 1.0.0
+
+environment:
+  sdk: ''';
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: ['flutter: ', 'sdk: '],
+      verifyEditsFor: 'sdk: ',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_nested_prefix() async {
+    final content = '''
+name: foo
+version: 1.0.0
+
+environment:
+  sd^''';
+
+    final expected = '''
+name: foo
+version: 1.0.0
+
+environment:
+  sdk: ''';
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: ['flutter: ', 'sdk: '],
+      verifyEditsFor: 'sdk: ',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_topLevel() async {
+    final content = '''
+version: 1.0.0
+^''';
+    final expected = '''
+version: 1.0.0
+name: ''';
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: ['name: ', 'description: '],
+      verifyEditsFor: 'name: ',
+      expectedContent: expected,
+    );
+  }
+
+  Future<void> test_topLevel_prefix() async {
+    final content = '''
+na^''';
+    final expected = '''
+name: ''';
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: ['name: ', 'description: '],
+      verifyEditsFor: 'name: ',
+      expectedContent: expected,
+    );
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/document_highlights_test.dart b/pkg/analysis_server/test/lsp/document_highlights_test.dart
index aba5b75..68b147d 100644
--- a/pkg/analysis_server/test/lsp/document_highlights_test.dart
+++ b/pkg/analysis_server/test/lsp/document_highlights_test.dart
@@ -2,9 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../tool/lsp_spec/matchers.dart';
 import 'server_abstract.dart';
 
 void main() {
@@ -21,6 +24,22 @@
     }
     ''');
 
+  Future<void> test_invalidLineByOne() async {
+    // Test that requesting a line that's too high by one returns a valid
+    // error response instead of throwing.
+    const content = '// single line';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    // Lines are zero-based so 1 is invalid.
+    final pos = Position(line: 1, character: 0);
+    final request = getDocumentHighlights(mainFileUri, pos);
+
+    await expectLater(
+        request, throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)));
+  }
+
   Future<void> test_localVariable() => _testMarkedContent('''
     main() {
       var [[f^oo]] = 1;
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
index f66964d..fa1e3e0 100644
--- a/pkg/analysis_server/test/lsp/document_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/document_symbols_test.dart
@@ -18,6 +18,67 @@
 
 @reflectiveTest
 class DocumentSymbolsTest extends AbstractLspAnalysisServerTest {
+  Future<void> test_enumMember_notSupported() async {
+    const content = '''
+    enum Theme {
+      light,
+    }
+    ''';
+    newFile(mainFilePath, content: content);
+    await initialize();
+
+    final result = await getDocumentSymbols(mainFileUri.toString());
+    final symbols = result.map(
+      (docsymbols) => throw 'Expected SymbolInformations, got DocumentSymbols',
+      (symbolInfos) => symbolInfos,
+    );
+    expect(symbols, hasLength(2));
+
+    final themeEnum = symbols[0];
+    expect(themeEnum.name, equals('Theme'));
+    expect(themeEnum.kind, equals(SymbolKind.Enum));
+    expect(themeEnum.containerName, isNull);
+
+    final enumValue = symbols[1];
+    expect(enumValue.name, equals('light'));
+    // EnumMember is not in the original LSP list, so unless the client explicitly
+    // advertises support, we will fall back to Enum.
+    expect(enumValue.kind, equals(SymbolKind.Enum));
+    expect(enumValue.containerName, 'Theme');
+  }
+
+  Future<void> test_enumMember_supported() async {
+    const content = '''
+    enum Theme {
+      light,
+    }
+    ''';
+    newFile(mainFilePath, content: content);
+    await initialize(
+      textDocumentCapabilities: withDocumentSymbolKinds(
+        emptyTextDocumentClientCapabilities,
+        [SymbolKind.Enum, SymbolKind.EnumMember],
+      ),
+    );
+
+    final result = await getDocumentSymbols(mainFileUri.toString());
+    final symbols = result.map(
+      (docsymbols) => throw 'Expected SymbolInformations, got DocumentSymbols',
+      (symbolInfos) => symbolInfos,
+    );
+    expect(symbols, hasLength(2));
+
+    final themeEnum = symbols[0];
+    expect(themeEnum.name, equals('Theme'));
+    expect(themeEnum.kind, equals(SymbolKind.Enum));
+    expect(themeEnum.containerName, isNull);
+
+    final enumValue = symbols[1];
+    expect(enumValue.name, equals('light'));
+    expect(enumValue.kind, equals(SymbolKind.EnumMember));
+    expect(enumValue.containerName, 'Theme');
+  }
+
   Future<void> test_flat() async {
     const content = '''
     String topLevel = '';
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 5a51229..e629a4d 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -18,11 +18,22 @@
 
 @reflectiveTest
 class FormatTest extends AbstractLspAnalysisServerTest {
-  Future<void> expectFormattedContents(
+  Future<List<TextEdit>> expectFormattedContents(
       Uri uri, String original, String expected) async {
     final formatEdits = await formatDocument(uri.toString());
     final formattedContents = applyTextEdits(original, formatEdits);
     expect(formattedContents, equals(expected));
+    return formatEdits;
+  }
+
+  Future<List<TextEdit>> expectRangeFormattedContents(
+      Uri uri, String original, String expected) async {
+    final formatEdits =
+        await formatRange(uri.toString(), rangeFromMarkers(original));
+    final formattedContents =
+        applyTextEdits(withoutMarkers(original), formatEdits);
+    expect(formattedContents, equals(expected));
+    return formatEdits;
   }
 
   Future<void> test_alreadyFormatted() async {
@@ -37,6 +48,32 @@
     expect(formatEdits, isNull);
   }
 
+  Future<void> test_complex() async {
+    const contents = '''
+ErrorOr<Pair<A, List<B>>> c(
+  String d,
+  List<
+          Either2<E,
+              F>>
+      g, {
+  h = false,
+}) {
+}
+
+
+    ''';
+    final expected = '''
+ErrorOr<Pair<A, List<B>>> c(
+  String d,
+  List<Either2<E, F>> g, {
+  h = false,
+}) {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    await expectFormattedContents(mainFileUri, contents, expected);
+  }
+
   /// Ensures we use the same registration ID when unregistering even if the
   /// server has regenerated registrations multiple times.
   Future<void> test_dynamicRegistration_correctIdAfterMultipleChanges() async {
@@ -63,6 +100,7 @@
     // By default, the formatters should have been registered.
     expect(registration(Method.textDocument_formatting), isNotNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNotNull);
 
     // Sending config updates causes the server to rebuild its list of registrations
     // which exposes a previous bug where we'd retain newly-built registrations
@@ -78,6 +116,7 @@
     );
     expect(registration(Method.textDocument_formatting), isNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNull);
   }
 
   Future<void> test_dynamicRegistration_forConfiguration() async {
@@ -104,6 +143,7 @@
     // By default, the formatters should have been registered.
     expect(registration(Method.textDocument_formatting), isNotNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNotNull);
 
     // They should be unregistered if we change the config to disabled.
     await monitorDynamicUnregistrations(
@@ -112,6 +152,7 @@
     );
     expect(registration(Method.textDocument_formatting), isNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNull);
 
     // They should be reregistered if we change the config to enabled.
     await monitorDynamicRegistrations(
@@ -120,6 +161,7 @@
     );
     expect(registration(Method.textDocument_formatting), isNotNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNotNull);
   }
 
   Future<void> test_formatOnType_simple() async {
@@ -140,10 +182,96 @@
     final formatEdits = await formatOnType(
         mainFileUri.toString(), positionFromMarker(contents), '}');
     expect(formatEdits, isNotNull);
-    final formattedContents = applyTextEdits(contents, formatEdits);
+    final formattedContents =
+        applyTextEdits(withoutMarkers(contents), formatEdits);
     expect(formattedContents, equals(expected));
   }
 
+  Future<void> test_formatRange_editsOverlapRange() async {
+    // Only ranges that are fully contained by the range should be applied,
+    // not those that intersect the start/end.
+    const contents = '''
+main()
+{
+    [[    print('test');
+        print('test');
+    ]]    print('test');
+}
+''';
+    final expected = '''
+main()
+{
+        print('test');
+  print('test');
+        print('test');
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    await expectRangeFormattedContents(mainFileUri, contents, expected);
+  }
+
+  Future<void> test_formatRange_invalidRange() async {
+    const contents = '''
+main()
+{
+        print('test');
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final formatRangeRequest = formatRange(
+      mainFileUri.toString(),
+      Range(
+          start: Position(line: 0, character: 0),
+          end: Position(line: 10000, character: 0)),
+    );
+    await expectLater(formatRangeRequest,
+        throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)));
+  }
+
+  Future<void> test_formatRange_simple() async {
+    const contents = '''
+main  ()
+{
+
+    print('test');
+}
+
+[[main2  ()
+{
+
+    print('test');
+}]]
+
+main3  ()
+{
+
+    print('test');
+}
+''';
+    final expected = '''
+main  ()
+{
+
+    print('test');
+}
+
+main2() {
+  print('test');
+}
+
+main3  ()
+{
+
+    print('test');
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    await expectRangeFormattedContents(mainFileUri, contents, expected);
+  }
+
   Future<void> test_invalidSyntax() async {
     const contents = '''main(((( {
   print('test');
@@ -182,6 +310,186 @@
     await expectFormattedContents(mainFileUri, contents, expectedLongLines);
   }
 
+  Future<void> test_minimalEdits_addWhitespace() async {
+    // Check we only get one edit to add the required whitespace and not
+    // an entire document replacement.
+    const contents = '''
+main(){}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(formatEdits[0].newText, ' ');
+    expect(formatEdits[0].range.start, equals(Position(line: 0, character: 6)));
+  }
+
+  Future<void> test_minimalEdits_removeFileLeadingWhitespace() async {
+    // Check whitespace before the first token is handled.
+    const contents = '''
+
+
+
+main() {}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(formatEdits[0].newText, '');
+    expect(formatEdits[0].range.start, equals(Position(line: 0, character: 0)));
+    expect(formatEdits[0].range.end, equals(Position(line: 3, character: 0)));
+  }
+
+  Future<void> test_minimalEdits_removeFileTrailingWhitespace() async {
+    // Check whitespace after the last token is handled.
+    const contents = '''
+main() {}
+
+
+
+
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(formatEdits[0].newText, '');
+    expect(formatEdits[0].range.start, equals(Position(line: 1, character: 0)));
+    expect(formatEdits[0].range.end, equals(Position(line: 5, character: 0)));
+  }
+
+  Future<void> test_minimalEdits_removePartialWhitespaceAfter() async {
+    // Check we get an edit only to remove the unnecessary trailing whitespace
+    // and not to replace the whole whitespace with a single space.
+    const contents = '''
+main()       {}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(
+        formatEdits[0],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 0, character: 7),
+              end: Position(line: 0, character: 13)),
+          newText: '',
+        )));
+  }
+
+  Future<void> test_minimalEdits_removePartialWhitespaceBefore() async {
+    // Check we get an edit only to remove the unnecessary leading whitespace
+    // and not to replace the whole whitespace with a single space.
+    const contents = '''
+main()
+
+
+ {}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(
+        formatEdits[0],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 0, character: 6),
+              end: Position(line: 3, character: 0)),
+          newText: '',
+        )));
+  }
+
+  Future<void> test_minimalEdits_removeWhitespace() async {
+    // Check we only get two edits to remove the unwanted whitespace and not
+    // an entire document replacement.
+    const contents = '''
+main( ) { }
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(2));
+    expect(formatEdits[0].newText, isEmpty);
+    expect(formatEdits[0].range.start, equals(Position(line: 0, character: 5)));
+    expect(formatEdits[1].newText, isEmpty);
+    expect(formatEdits[1].range.start, equals(Position(line: 0, character: 9)));
+  }
+
+  Future<void> test_minimalEdits_withComments() async {
+    // Check we can get edits that span a comment (which does not appear in the
+    // main token list).
+    const contents = '''
+main() {
+        var a = 1;
+        // Comment
+        print(a);
+}
+''';
+    const expected = '''
+main() {
+  var a = 1;
+  // Comment
+  print(a);
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(3));
+    expect(
+        formatEdits[0],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 1, character: 2),
+              end: Position(line: 1, character: 8)),
+          newText: '',
+        )));
+    expect(
+        formatEdits[1],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 2, character: 2),
+              end: Position(line: 2, character: 8)),
+          newText: '',
+        )));
+    expect(
+        formatEdits[2],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 3, character: 2),
+              end: Position(line: 3, character: 8)),
+          newText: '',
+        )));
+  }
+
   Future<void> test_nonDartFile() async {
     await initialize();
     await openFile(pubspecFileUri, simplePubspecContent);
@@ -253,4 +561,21 @@
     await initialize();
     await expectFormattedContents(mainFileUri, contents, expected);
   }
+
+  Future<void> test_validSyntax_withErrors() async {
+    // We should still be able to format syntactically valid code even if it has analysis
+    // errors.
+    const contents = '''main() {
+       print(a);
+}
+''';
+    const expected = '''main() {
+  print(a);
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+
+    await expectFormattedContents(mainFileUri, contents, expected);
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 4caaecc..50bcc58 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -115,6 +115,7 @@
     expect(initResult.capabilities.documentHighlightProvider, isNotNull);
     expect(initResult.capabilities.documentFormattingProvider, isNotNull);
     expect(initResult.capabilities.documentOnTypeFormattingProvider, isNotNull);
+    expect(initResult.capabilities.documentRangeFormattingProvider, isNotNull);
     expect(initResult.capabilities.definitionProvider, isNotNull);
     expect(initResult.capabilities.codeActionProvider, isNotNull);
     expect(initResult.capabilities.renameProvider, isNotNull);
@@ -164,6 +165,7 @@
     expect(initResult.capabilities.documentHighlightProvider, isNull);
     expect(initResult.capabilities.documentFormattingProvider, isNull);
     expect(initResult.capabilities.documentOnTypeFormattingProvider, isNull);
+    expect(initResult.capabilities.documentRangeFormattingProvider, isNull);
     expect(initResult.capabilities.definitionProvider, isNull);
     expect(initResult.capabilities.codeActionProvider, isNull);
     expect(initResult.capabilities.renameProvider, isNull);
diff --git a/pkg/analysis_server/test/lsp/mapping_test.dart b/pkg/analysis_server/test/lsp/mapping_test.dart
index 2ae7ac1..9d88d76 100644
--- a/pkg/analysis_server/test/lsp/mapping_test.dart
+++ b/pkg/analysis_server/test/lsp/mapping_test.dart
@@ -74,18 +74,35 @@
     expect(result, isNull);
   }
 
-  Future<void> test_selectionsInSnippets_empty() async {
-    var result = lsp.buildSnippetStringWithSelection('teststring', 4, 0);
-    expect(result, equals(r'test${1:}string'));
+  Future<void> test_tabStopsInSnippets_contains() async {
+    var result = lsp.buildSnippetStringWithTabStops('a, b, c', [3, 1]);
+    expect(result, equals(r'a, ${0:b}, c'));
   }
 
-  Future<void> test_selectionsInSnippets_escaping() async {
-    var result = lsp.buildSnippetStringWithSelection(r'te$tstri}ng', 4, 3);
-    expect(result, equals(r'te\$t${1:str}i\}ng'));
+  Future<void> test_tabStopsInSnippets_empty() async {
+    var result = lsp.buildSnippetStringWithTabStops('a, b', []);
+    expect(result, equals(r'a, b'));
   }
 
-  Future<void> test_selectionsInSnippets_selection() async {
-    var result = lsp.buildSnippetStringWithSelection('teststring', 4, 3);
-    expect(result, equals(r'test${1:str}ing'));
+  Future<void> test_tabStopsInSnippets_endsWith() async {
+    var result = lsp.buildSnippetStringWithTabStops('a, b', [3, 1]);
+    expect(result, equals(r'a, ${0:b}'));
+  }
+
+  Future<void> test_tabStopsInSnippets_escape() async {
+    var result = lsp.buildSnippetStringWithTabStops(
+        r'te$tstri}ng, te$tstri}ng, te$tstri}ng', [13, 11]);
+    expect(result, equals(r'te\$tstri\}ng, ${0:te\$tstri\}ng}, te\$tstri\}ng'));
+  }
+
+  Future<void> test_tabStopsInSnippets_multiple() async {
+    var result =
+        lsp.buildSnippetStringWithTabStops('a, b, c', [0, 1, 3, 1, 6, 1]);
+    expect(result, equals(r'${1:a}, ${2:b}, ${3:c}'));
+  }
+
+  Future<void> test_tabStopsInSnippets_startsWith() async {
+    var result = lsp.buildSnippetStringWithTabStops('a, b', [0, 1]);
+    expect(result, equals(r'${0:a}, b'));
   }
 }
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index a21044d..f99877e 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -23,7 +23,6 @@
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
@@ -52,8 +51,6 @@
   TestPluginManager pluginManager;
   LspAnalysisServer server;
 
-  final testWorkDoneToken = Either2<num, String>.t2('test');
-
   AnalysisServerOptions get serverOptions => AnalysisServerOptions();
 
   @override
@@ -217,6 +214,7 @@
       'documentSymbol': {'dynamicRegistration': true},
       'formatting': {'dynamicRegistration': true},
       'onTypeFormatting': {'dynamicRegistration': true},
+      'rangeFormatting': {'dynamicRegistration': true},
       'declaration': {'dynamicRegistration': true},
       'definition': {'dynamicRegistration': true},
       'implementation': {'dynamicRegistration': true},
@@ -330,6 +328,18 @@
     return extendTextDocumentCapabilities(source, {
       'formatting': {'dynamicRegistration': true},
       'onTypeFormatting': {'dynamicRegistration': true},
+      'rangeFormatting': {'dynamicRegistration': true},
+    });
+  }
+
+  TextDocumentClientCapabilities withDocumentSymbolKinds(
+    TextDocumentClientCapabilities source,
+    List<SymbolKind> kinds,
+  ) {
+    return extendTextDocumentCapabilities(source, {
+      'documentSymbol': {
+        'symbolKind': {'valueSet': kinds.map((k) => k.toJson()).toList()}
+      }
     });
   }
 
@@ -462,6 +472,11 @@
   static final allMarkersPattern =
       RegExp(allMarkers.map(RegExp.escape).join('|'));
 
+  /// A progress token used in tests where the client-provides the token, which
+  /// should not be validated as being created by the server first.
+  final clientProvidedTestWorkDoneToken =
+      Either2<num, String>.t2('client-test');
+
   int _id = 0;
   String projectFolderPath, mainFilePath, pubspecFilePath, analysisOptionsPath;
   Uri projectFolderUri, mainFileUri, pubspecFileUri, analysisOptionsUri;
@@ -577,18 +592,18 @@
     /// logic.
     void validateChangesCanBeApplied() {
       /// Check if a position is before (but not equal) to another position.
-      bool isBefore(Position p, Position other) =>
+      bool isBeforeOrEqual(Position p, Position other) =>
           p.line < other.line ||
-          (p.line == other.line && p.character < other.character);
+          (p.line == other.line && p.character <= other.character);
 
       /// Check if a position is after (but not equal) to another position.
-      bool isAfter(Position p, Position other) =>
+      bool isAfterOrEqual(Position p, Position other) =>
           p.line > other.line ||
-          (p.line == other.line && p.character > other.character);
-      // Check if two ranges intersect or touch.
+          (p.line == other.line && p.character >= other.character);
+      // Check if two ranges intersect.
       bool rangesIntersect(Range r1, Range r2) {
-        var endsBefore = isBefore(r1.end, r2.start);
-        var startsAfter = isAfter(r1.start, r2.end);
+        var endsBefore = isBeforeOrEqual(r1.end, r2.start);
+        var startsAfter = isAfterOrEqual(r1.start, r2.end);
         return !(endsBefore || startsAfter);
       }
 
@@ -604,12 +619,13 @@
     }
 
     validateChangesCanBeApplied();
-    changes.sort(
-      (c1, c2) =>
-          positionCompare(c1.range.start, c2.range.start) *
-          -1, // Multiply by -1 to get descending sort.
-    );
-    for (final change in changes) {
+    final sortedChanges = changes.toList() // Don't mutate the original list.
+      ..sort(
+        // Multiply by -1 to get descending sort.
+        (c1, c2) => positionCompare(c1.range.start, c2.range.start) * -1,
+      );
+
+    for (final change in sortedChanges) {
       newContent = applyTextEdit(newContent, change);
     }
 
@@ -795,6 +811,21 @@
         request, _fromJsonList(TextEdit.fromJson));
   }
 
+  Future<List<TextEdit>> formatRange(String fileUri, Range range) {
+    final request = makeRequest(
+      Method.textDocument_rangeFormatting,
+      DocumentRangeFormattingParams(
+        options: FormattingOptions(
+            tabSize: 2,
+            insertSpaces: true), // These currently don't do anything
+        textDocument: TextDocumentIdentifier(uri: fileUri),
+        range: range,
+      ),
+    );
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(TextEdit.fromJson));
+  }
+
   Future<List<Either2<Command, CodeAction>>> getCodeActions(
     String fileUri, {
     Range range,
@@ -1077,6 +1108,12 @@
       }
     });
 
+    notificationsFromServer.listen((notification) async {
+      if (notification.method == Method.progress) {
+        await _handleProgress(notification);
+      }
+    });
+
     // Assume if none of the project options were set, that we want to default to
     // opening the test project folder.
     if (rootPath == null &&
@@ -1197,7 +1234,7 @@
     if (p1.line > p2.line) return 1;
 
     if (p1.character < p2.character) return -1;
-    if (p1.character > p2.character) return -1;
+    if (p1.character > p2.character) return 1;
 
     return 0;
   }
@@ -1408,10 +1445,6 @@
           }
 
           final params = ProgressParams.fromJson(message.params);
-          if (!validProgressTokens.contains(params.token)) {
-            throw Exception('Server sent a progress notification for a token '
-                'that has not been created: ${params.token}');
-          }
 
           // Skip unrelated progress notifications.
           if (params.token != analyzingProgressToken) {
@@ -1511,6 +1544,19 @@
           T Function(Map<String, dynamic>) fromJson) =>
       (input) => input.cast<Map<String, dynamic>>().map(fromJson).toList();
 
+  Future<void> _handleProgress(NotificationMessage request) async {
+    final params = ProgressParams.fromJson(request.params);
+    if (params.token != clientProvidedTestWorkDoneToken &&
+        !validProgressTokens.contains(params.token)) {
+      throw Exception('Server sent a progress notification for a token '
+          'that has not been created: ${params.token}');
+    }
+
+    if (WorkDoneProgressEnd.canParse(params.value, nullLspJsonReporter)) {
+      validProgressTokens.remove(params.token);
+    }
+  }
+
   Future<void> _handleWorkDoneProgressCreate(RequestMessage request) async {
     if (_clientCapabilities.window?.workDoneProgress != true) {
       throw Exception('Server sent ${Method.window_workDoneProgress_create} '
@@ -1518,7 +1564,7 @@
     }
     final params = WorkDoneProgressCreateParams.fromJson(request.params);
     if (validProgressTokens.contains(params.token)) {
-      throw Exception('Server tried to create the same progress token twice');
+      throw Exception('Server tried to create already-active progress token');
     }
     validProgressTokens.add(params.token);
   }
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index 628b142..ea56793 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -13,7 +13,8 @@
 import 'code_actions_fixes_test.dart' as code_actions_fixes;
 import 'code_actions_refactor_test.dart' as code_actions_refactor;
 import 'code_actions_source_test.dart' as code_actions_source;
-import 'completion_test.dart' as completion;
+import 'completion_dart_test.dart' as completion_dart;
+import 'completion_yaml_test.dart' as completion_yaml;
 import 'configuration_test.dart' as configuration;
 import 'definition_test.dart' as definition;
 import 'diagnostic_test.dart' as diagnostic;
@@ -48,7 +49,8 @@
     code_actions_fixes.main();
     code_actions_source.main();
     code_actions_refactor.main();
-    completion.main();
+    completion_dart.main();
+    completion_yaml.main();
     configuration.main();
     definition.main();
     diagnostic.main();
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 2fdf1c5..d693387 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -4,14 +4,8 @@
 
 import 'package:analysis_server/plugin/protocol/protocol_dart.dart';
 import 'package:analyzer/dart/ast/ast.dart' as engine;
-import 'package:analyzer/dart/ast/visitor.dart' as engine;
 import 'package:analyzer/dart/element/element.dart' as engine;
-import 'package:analyzer/dart/element/type.dart' as engine;
-import 'package:analyzer/error/error.dart' as engine;
-import 'package:analyzer/src/dart/ast/utilities.dart' as engine;
 import 'package:analyzer/src/dart/element/element.dart' as engine;
-import 'package:analyzer/src/error/codes.dart' as engine;
-import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:analyzer/src/generated/testing/element_search.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 0ce5609..0d5d964 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -9,9 +9,7 @@
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/ast/ast.dart' as engine;
 import 'package:analyzer/dart/element/element.dart' as engine;
-import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart' as engine;
 import 'package:analyzer/src/dart/analysis/results.dart' as engine;
@@ -231,6 +229,7 @@
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
       engine.ElementKind.NEVER: ElementKind.UNKNOWN,
+      engine.ElementKind.TYPE_ALIAS: ElementKind.UNKNOWN,
       engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
     });
   }
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 342dc7c..947a966 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -644,6 +644,48 @@
 LIBRARY my_lib''');
   }
 
+  Future<void> test_path_inExtension_named() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+extension E on A {
+  void bar() {
+    foo();
+  }
+}
+''');
+    await findElementReferences('foo() {}', false);
+    assertHasResult(SearchResultKind.INVOCATION, 'foo();');
+    expect(getPathString(result.path), '''
+METHOD bar
+EXTENSION E
+COMPILATION_UNIT test.dart
+LIBRARY''');
+  }
+
+  Future<void> test_path_inExtension_unnamed() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+extension on A {
+  void bar() {
+    foo();
+  }
+}
+''');
+    await findElementReferences('foo() {}', false);
+    assertHasResult(SearchResultKind.INVOCATION, 'foo();');
+    expect(getPathString(result.path), '''
+METHOD bar
+EXTENSION
+COMPILATION_UNIT test.dart
+LIBRARY''');
+  }
+
   @failingTest
   Future<void> test_path_inFunction() async {
     // The path does not contain the first expected element.
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
deleted file mode 100644
index c8d2ae5..0000000
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ /dev/null
@@ -1,168 +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:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../../domain_completion_util.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(CommonUsageSorterTest);
-  });
-}
-
-@reflectiveTest
-class CommonUsageSorterTest extends AbstractCompletionDomainTest {
-  Future getSuggestionsWith(Map<String, List<String>> selectorRelevance) async {
-    var originalSorter = DartCompletionManager.contributionSorter;
-    DartCompletionManager.contributionSorter =
-        CommonUsageSorter(selectorRelevance);
-    try {
-      return await getSuggestions();
-    } finally {
-      DartCompletionManager.contributionSorter = originalSorter;
-    }
-  }
-
-  Future<void> test_ConstructorName() async {
-    // SimpleIdentifier  ConstructorName  InstanceCreationExpression
-    addTestFile('import "dart:async"; class A {x() {new Future.^}}');
-    await getSuggestionsWith({
-      'dart.async.Future': ['value', 'wait']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'delayed');
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'value',
-        relevance: DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  Future<void> test_namedArgument_enum() async {
-    addTestFile('''
-enum E {e1, e2}
-f({E e}) {}
-main() {
-  f(e: ^);
-}
-''');
-    await getSuggestionsWith(<String, List<String>>{});
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'E');
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'E.e1',
-        relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_BOOST_TYPE);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'E.e2',
-        relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_BOOST_TYPE);
-  }
-
-  Future<void> test_PrefixedIdentifier_field() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestFile('class A {static int s1; static int s2; x() {A.^}}');
-    await getSuggestionsWith({
-      '.A': ['s2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1',
-        relevance: DART_RELEVANCE_INHERITED_FIELD);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
-        relevance: DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  Future<void> test_PrefixedIdentifier_field_inPart() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    newFile('/project/bin/myLib.dart',
-        content:
-            'library L; part "${toUriStr(testFile)}"; class A {static int s2;}');
-    addTestFile('part of L; foo() {A.^}');
-    await getSuggestionsWith({
-      'L.A': ['s2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
-        relevance: DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  Future<void> test_PrefixedIdentifier_getter() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}');
-    await getSuggestionsWith({
-      '.A': ['g2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1',
-        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g2',
-        relevance: DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  Future<void> test_PrefixedIdentifier_setter() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestFile('class A {set s1(v) {}; set s2(v) {}; x() {new A().^}}');
-    await getSuggestionsWith({
-      '.A': ['s2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1',
-        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
-        relevance: DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  Future<void> test_PrefixedIdentifier_static_method() async {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestFile('import "dart:async"; class A {x() {Future.^}}');
-    await getSuggestionsWith({
-      'dart.async.Future': ['value', 'wait']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'wait',
-        relevance: DART_RELEVANCE_COMMON_USAGE - 1);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  Future<void> test_PropertyAccess() async {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestFile('import "dart:math"; class A {x() {new Random().^}}');
-    await getSuggestionsWith({
-      'dart.math.Random': ['nextInt', 'nextDouble']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextBool');
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextDouble',
-        relevance: DART_RELEVANCE_COMMON_USAGE - 1);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextInt',
-        relevance: DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Random');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 8e22c6a..63573c1 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -96,10 +96,6 @@
   /// where there is no `new` or `const` keyword.
   bool get suggestConstructorsWithoutNew => true;
 
-  /// Return `true` if the new relevance computations should be used when
-  /// computing code completion suggestions.
-  bool get useNewRelevance => false;
-
   bool get usingFastaParser => analyzer.Parser.useFasta;
 
   void addTestSource(String content) {
@@ -552,7 +548,7 @@
   Future computeSuggestions({int times = 200}) async {
     result = await session.getResolvedUnit(testFile);
     var baseRequest = CompletionRequestImpl(
-        result, completionOffset, useNewRelevance, CompletionPerformance());
+        result, completionOffset, CompletionPerformance());
 
     return await baseRequest.performance.runRequestOperation(
       (performance) async {
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index 5a3825d..cd8e243 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -51,7 +51,6 @@
     var baseRequest = CompletionRequestImpl(
         await session.getResolvedUnit(testFile),
         completionOffset,
-        false,
         CompletionPerformance());
     await baseRequest.performance.runRequestOperation((performance) async {
       var requestCompleter = Completer<DartCompletionRequest>();
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_ranking_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_ranking_test.dart
deleted file mode 100644
index 841ad47..0000000
--- a/pkg/analysis_server/test/services/completion/dart/completion_ranking_test.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-void main() {
-  CompletionRanking ranking;
-
-  setUp(() async {
-    ranking = CompletionRanking(directory);
-    await ranking.start();
-  });
-
-  test('make request to isolate', () async {
-    final tokens =
-        tokenize('if (list == null) { return; } for (final i = 0; i < list.');
-    final response = await ranking.makePredictRequest(tokens);
-    expect(response['data']['length'], greaterThan(0.9));
-  }, skip: 'https://github.com/dart-lang/sdk/issues/42988');
-}
-
-final directory = path.join(File.fromUri(Platform.script).parent.path, '..',
-    '..', '..', '..', 'language_model', 'lexeme');
-
-/// Tokenizes the input string.
-///
-/// The input is split by word boundaries and trimmed of whitespace.
-List<String> tokenize(String input) =>
-    input.split(RegExp(r'\b|\s')).map((t) => t.trim()).toList()
-      ..removeWhere((t) => t.isEmpty);
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 610dded..ff603a4 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -315,7 +315,12 @@
     assertNotSuggested('==');
   }
 
+  @failingTest
   Future<void> test_AsExpression_type_subtype_extends_filter() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  AsExpression  IfStatement
     addSource('/home/test/lib/b.dart', '''
           foo() { }
@@ -337,7 +342,12 @@
     assertNotSuggested('main');
   }
 
+  @failingTest
   Future<void> test_AsExpression_type_subtype_implements_filter() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  AsExpression  IfStatement
     addSource('/home/test/lib/b.dart', '''
           foo() { }
@@ -2875,7 +2885,6 @@
     }
     assertSuggestTopLevelVar('T1', null);
     assertSuggestFunction('F1', null);
-    assertNotSuggested('D1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
     assertNotSuggested('D2');
@@ -3027,7 +3036,12 @@
     assertSuggestClass('Object');
   }
 
+  @failingTest
   Future<void> test_IsExpression_type_subtype_extends_filter() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addSource('/home/test/lib/b.dart', '''
         foo() { }
@@ -3049,7 +3063,12 @@
     assertNotSuggested('main');
   }
 
+  @failingTest
   Future<void> test_IsExpression_type_subtype_implements_filter() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addSource('/home/test/lib/b.dart', '''
         foo() { }
@@ -3402,7 +3421,7 @@
     assertNotSuggested('_g');
     assertSuggestClass('bool');
     if (suggestConstructorsWithoutNew) {
-      assertSuggestConstructor('List');
+      assertSuggestConstructor('List.filled');
     }
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/language_model_test.dart b/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
deleted file mode 100644
index 7a2434e..0000000
--- a/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:ffi';
-import 'dart:io';
-
-import 'package:analysis_server/src/services/completion/dart/language_model.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-void main() {
-  if (sizeOf<IntPtr>() == 4) {
-    // We don't yet support running tflite on 32-bit systems.
-    return;
-  }
-
-  group('LanguageModel', () {
-    LanguageModel model;
-
-    setUp(() {
-      model = LanguageModel.load(directory);
-    });
-
-    tearDown(() {
-      model.close();
-    });
-
-    test('calculates lookback', () {
-      expect(model.lookback, expectedLookback);
-    });
-
-    test('predict with defaults', () {
-      final tokens =
-          tokenize('if (list == null) { return; } for (final i = 0; i < list.');
-      final suggestions = model.predict(tokens);
-      expect(suggestions.first, 'length');
-    });
-
-    test('predict with confidence scores', () {
-      final tokens =
-          tokenize('if (list == null) { return; } for (final i = 0; i < list.');
-      final suggestions = model.predictWithScores(tokens);
-      final best = suggestions.entries.first;
-      expect(best.key, 'length');
-      expect(best.value, greaterThan(0.9));
-    });
-
-    test('predict when no previous tokens', () {
-      final tokens = <String>[];
-      final suggestions = model.predict(tokens);
-      expect(suggestions.first, isNotEmpty);
-    });
-
-    test('load fail', () {
-      try {
-        LanguageModel.load('doesnotexist');
-        fail('Failure to load language model should throw an exception');
-      } catch (e) {
-        expect(e.toString(),
-            equals('Invalid argument(s): Unable to create model.'));
-      }
-    });
-
-    test('isNumber', () {
-      expect(model.isNumber('0xCAb005E'), true);
-      expect(model.isNumber('foo'), false);
-      expect(model.isNumber('3.1415'), true);
-      expect(model.isNumber('1337'), true);
-      expect(model.isNumber('"four score and seven years ago"'), false);
-      expect(model.isNumber('0.0'), true);
-    });
-  }, skip: 'https://github.com/dart-lang/sdk/issues/42988');
-}
-
-const expectedLookback = 100;
-
-final directory = path.join(File.fromUri(Platform.script).parent.path, '..',
-    '..', '..', '..', 'language_model', 'lexeme');
-
-/// Tokenizes the input string.
-///
-/// The input is split by word boundaries and trimmed of whitespace.
-List<String> tokenize(String input) =>
-    input.split(RegExp(r'\b|\s')).map((t) => t.trim()).toList()
-      ..removeWhere((t) => t.isEmpty);
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index e0268de..0c7657a 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -546,7 +546,12 @@
     assertNotSuggested('==');
   }
 
+  @failingTest
   Future<void> test_AsExpression_type_filter_extends() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  AsExpression
     addTestSource('''
 class A {} class B extends A {} class C extends A {} class D {}
@@ -562,7 +567,12 @@
     assertNotSuggested('Object');
   }
 
+  @failingTest
   Future<void> test_AsExpression_type_filter_implements() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  AsExpression
     addTestSource('''
 class A {} class B implements A {} class C implements A {} class D {}
@@ -2967,6 +2977,55 @@
     assertNotSuggested('Object');
   }
 
+  Future<void> test_forElement_body() async {
+    addTestSource('var x = [for (int i; i < 10; ++i) ^];');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('i', 'int');
+    assertNotSuggested('Object');
+  }
+
+  Future<void> test_forElement_condition() async {
+    addTestSource('var x = [for (int index = 0; i^)];');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
+  Future<void> test_forElement_initializer() async {
+    addTestSource('var x = [for (^)];');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  Future<void> test_forElement_updaters() async {
+    addTestSource('var x = [for (int index = 0; index < 10; i^)];');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
+  Future<void> test_forElement_updaters_prefix_expression() async {
+    addTestSource('''
+var x = [for (int index = 0; index < 10; ++i^)];
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
   Future<void> test_FormalParameterList() async {
     // FormalParameterList MethodDeclaration
     addTestSource('''
@@ -3147,6 +3206,17 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
+  Future<void> test_functionDeclaration_parameter() async {
+    addTestSource('''
+void f<T>(^) {}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('T');
+  }
+
   Future<void> test_FunctionDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
@@ -3252,6 +3322,18 @@
     assertSuggest('bar', elemKind: ElementKind.LOCAL_VARIABLE);
   }
 
+  Future<void> test_functionDeclaration_typeParameterBounds() async {
+    addTestSource('''
+void f<T extends C<^>>() {}
+class C<E> {}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('T');
+  }
+
   Future<void> test_FunctionExpression_body_function() async {
     // Block  BlockFunctionBody  FunctionExpression
     addTestSource('''
@@ -3275,6 +3357,36 @@
     assertNotSuggested('Object');
   }
 
+  @failingTest
+  Future<void> test_functionExpression_expressionBody() async {
+    // This test fails because the OpType at the completion location doesn't
+    // allow for functions that return `void`. But because the expected return
+    // type is `dynamic` we probably want to allow it.
+    addTestSource('''
+void f() {
+  g(() => ^);
+}
+void g(dynamic Function() h) {}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('f', 'void');
+    assertSuggestFunction('g', 'void');
+  }
+
+  Future<void> test_functionExpression_parameterList() async {
+    addTestSource('''
+var c = <T>(^) {};
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('T');
+  }
+
   Future<void> test_functionTypeAlias_genericTypeAlias() async {
     addTestSource(r'''
 typedef F = void Function();
@@ -3308,6 +3420,17 @@
     assertSuggestFunctionTypeAlias('F', 'void');
   }
 
+  Future<void> test_genericFunctionType_parameterList() async {
+    addTestSource('''
+void f(int Function<T>(^) g) {}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('T');
+  }
+
   Future<void> test_IfStatement() async {
     // SimpleIdentifier  IfStatement
     addTestSource('''
@@ -3882,7 +4005,12 @@
     assertNotSuggested('Object');
   }
 
+  @failingTest
   Future<void> test_IsExpression_type_filter_extends() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('''
 class A {} class B extends A {} class C extends A {} class D {}
@@ -3898,7 +4026,12 @@
     assertNotSuggested('Object');
   }
 
+  @failingTest
   Future<void> test_IsExpression_type_filter_implements() async {
+    // This test fails because we are not filtering out the class `A` when
+    // suggesting types. We ought to do so because there's no reason to cast a
+    // value to the type it already has.
+
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('''
 class A {} class B implements A {} class C implements A {} class D {}
@@ -4578,6 +4711,22 @@
     assertNotSuggested('bool');
   }
 
+  Future<void> test_methodDeclaration_parameter() async {
+    addTestSource('''
+class C<E> {}
+extension E<S> on C<S> {
+  void m<T>(^) {}
+}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('S');
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('E');
+  }
+
   Future<void> test_MethodDeclaration_parameters_named() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('''
@@ -4784,6 +4933,22 @@
     assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
   }
 
+  Future<void> test_methodDeclaration_typeParameterBounds() async {
+    addTestSource('''
+class C<E> {}
+extension E<S> on C<S> {
+  void m<T extends C<^>>() {}
+}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('S');
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('E');
+  }
+
   Future<void> test_MethodInvocation_no_semicolon() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
@@ -5041,6 +5206,20 @@
     assertSuggestMethod('m', 'B', null);
   }
 
+  @failingTest
+  Future<void> test_parameterList_genericFunctionType() async {
+    // This test fails because we don't suggest `void` as the type of a
+    // parameter, but we should for the case of `void Function()`.
+    addTestSource('''
+void f(^) {}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggest('void');
+  }
+
   Future<void> test_parameterName_excludeTypes() async {
     addTestSource('m(int ^) {}');
     await computeSuggestions();
@@ -5574,6 +5753,19 @@
     assertNotSuggested('y2');
   }
 
+  Future<void> test_stringInterpolation() async {
+    addTestSource(r'''
+class C<T> {
+  String m() => 'abc $^ xyz';
+}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestTypeParameter('T');
+  }
+
   Future<void> test_SwitchStatement_c() async {
     // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {String g(int x) {switch(x) {c^}}}');
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
index 643fec4..81532df 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 
@@ -10,10 +9,6 @@
 
 class CompletionRelevanceTest extends AbstractCompletionDriverTest {
   @override
-  AnalysisServerOptions get serverOptions =>
-      AnalysisServerOptions()..useNewRelevance = true;
-
-  @override
   bool get supportsAvailableSuggestions => true;
 
   /// Assert that all of the given completions were produced and that the
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
index 9b59000..62388ae 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/analysis_server.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion_relevance.dart';
@@ -16,10 +15,6 @@
 @reflectiveTest
 class InstanceMemberRelevanceTest extends CompletionRelevanceTest {
   @override
-  AnalysisServerOptions get serverOptions =>
-      AnalysisServerOptions()..useNewRelevance = true;
-
-  @override
   bool get supportsAvailableSuggestions => true;
 
   Future<void> test_contextType() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 9b71160..bf9d30b 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -6,19 +6,14 @@
 
 import 'arglist_contributor_test.dart' as arglist_test;
 import 'combinator_contributor_test.dart' as combinator_test;
-import 'common_usage_sorter_test.dart' as common_usage_test;
 import 'completion_manager_test.dart' as completion_manager;
 import 'completion_ranking_internal_test.dart'
     as completion_ranking_internal_test;
-// ignore: unused_import
-import 'completion_ranking_test.dart' as completion_ranking_test;
 import 'extension_member_contributor_test.dart' as extension_member_contributor;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
 import 'imported_reference_contributor_test.dart' as imported_ref_test;
 import 'keyword_contributor_test.dart' as keyword_test;
 import 'label_contributor_test.dart' as label_contributor_test;
-// ignore: unused_import
-import 'language_model_test.dart' as language_model_test;
 import 'library_member_contributor_test.dart' as library_member_test;
 import 'library_prefix_contributor_test.dart' as library_prefix_test;
 import 'local_library_contributor_test.dart' as local_lib_test;
@@ -35,20 +30,13 @@
   defineReflectiveSuite(() {
     arglist_test.main();
     combinator_test.main();
-    common_usage_test.main();
     completion_manager.main();
-    // TODO(lambdabaa): Run this test once we figure out how to suppress
-    //   output from the tflite shared library
-    // completion_ranking_test.main();
     completion_ranking_internal_test.main();
     extension_member_contributor.main();
     field_formal_contributor_test.main();
     imported_ref_test.main();
     keyword_test.main();
     label_contributor_test.main();
-    // TODO(brianwilkerson) Run this test when it's been updated to not rely on
-    //   the location of the 'script' being run.
-    // language_model_test.main();
     library_member_test.main();
     library_prefix_test.main();
     local_lib_test.main();
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index f1fd8f5..aea6d40 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -13,7 +13,6 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(TypeMemberContributorTest);
-    defineReflectiveTests(TypeMemberContributorWithNewRelevanceTest);
   });
 }
 
@@ -4265,10 +4264,3 @@
     assertNotSuggested('e');
   }
 }
-
-@reflectiveTest
-class TypeMemberContributorWithNewRelevanceTest
-    extends TypeMemberContributorTest {
-  @override
-  bool get useNewRelevance => true;
-}
diff --git a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
index 47f0b08..504dc74 100644
--- a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
@@ -61,8 +61,7 @@
   }
 
   Future<void> _computeCompletion(int offset) async {
-    var result = await session.getResolvedUnit(testFile);
-    var context = StatementCompletionContext(result, offset);
+    var context = StatementCompletionContext(testAnalysisResult, offset);
     var processor = StatementCompletionProcessor(context);
     var completion = await processor.compute();
     change = completion.change;
diff --git a/pkg/analysis_server/test/services/correction/change_test.dart b/pkg/analysis_server/test/services/correction/change_test.dart
index ea70891..90b2dd9 100644
--- a/pkg/analysis_server/test/services/correction/change_test.dart
+++ b/pkg/analysis_server/test/services/correction/change_test.dart
@@ -25,7 +25,7 @@
   void test_addEdit() {
     var change = SourceChange('msg');
     var edit1 = SourceEdit(1, 2, 'a');
-    var edit2 = SourceEdit(1, 2, 'b');
+    var edit2 = SourceEdit(4, 2, 'b');
     expect(change.edits, hasLength(0));
     change.addEdit('/a.dart', 0, edit1);
     expect(change.edits, hasLength(1));
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 9db1931..ff277f5 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -1575,17 +1575,17 @@
   Future<void> test_singleExpression_returnTypeGeneric() async {
     await indexTestUnit('''
 main() {
-  var v = new List<String>();
+  var v = <String>[];
 }
 ''');
-    _createRefactoringForString('new List<String>()');
+    _createRefactoringForString('<String>[]');
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
   var v = res();
 }
 
-List<String> res() => new List<String>();
+List<String> res() => <String>[];
 ''');
   }
 
diff --git a/pkg/analysis_server/test/src/cider/completion_test.dart b/pkg/analysis_server/test/src/cider/completion_test.dart
index f37076b..86bd6a5 100644
--- a/pkg/analysis_server/test/src/cider/completion_test.dart
+++ b/pkg/analysis_server/test/src/cider/completion_test.dart
@@ -325,8 +325,8 @@
 ''');
 
     _assertOrder([
-      _assertHasLocalVariable(text: 'a'),
       _assertHasLocalVariable(text: 'b'),
+      _assertHasLocalVariable(text: 'a'),
     ]);
   }
 
@@ -410,6 +410,33 @@
     _assertHasTypeParameter(text: 'U');
   }
 
+  Future<void> test_limitedResolution_class_method_body2() async {
+    _configureToCheckNotResolved(
+      identifiers: {'print'},
+    );
+
+    await _compute(r'''
+class A {
+  void foo() {}
+}
+
+abstract class B {
+  A get a;
+
+  void notResolved() {
+    print(0);
+  }
+
+  void completionTarget() {
+    a.^;
+  }
+}
+''');
+
+    _assertHasGetter(text: 'hashCode');
+    _assertHasMethod(text: 'foo');
+  }
+
   Future<void> test_limitedResolution_class_method_parameterType() async {
     _configureToCheckNotResolved(
       identifiers: {'print'},
@@ -476,6 +503,33 @@
     _assertHasClass(text: 'A');
   }
 
+  Future<void> test_limitedResolution_mixin_method_body() async {
+    _configureToCheckNotResolved(
+      identifiers: {'print'},
+    );
+
+    await _compute(r'''
+class A {
+  void foo() {}
+}
+
+mixin M {
+  A get a;
+
+  void notResolved() {
+    print(0);
+  }
+
+  void completionTarget() {
+    a.^;
+  }
+}
+''');
+
+    _assertHasGetter(text: 'hashCode');
+    _assertHasMethod(text: 'foo');
+  }
+
   Future<void> test_limitedResolution_unit_function_body() async {
     _configureToCheckNotResolved(
       identifiers: {'print'},
diff --git a/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
deleted file mode 100644
index 33aa117..0000000
--- a/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/computer/computer_highlights2.dart';
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../abstract_context.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(Highlights2ComputerTest);
-  });
-}
-
-@reflectiveTest
-class Highlights2ComputerTest extends AbstractContextTest {
-  String sourcePath;
-  String content;
-  List<HighlightRegion> highlights;
-
-  @override
-  void setUp() {
-    super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
-  }
-
-  Future<void> test_comment() async {
-    await _computeHighlights('''
-// A trailing comment
-''');
-    _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
-  }
-
-  Future<void> test_comment_trailing() async {
-    await _computeHighlights('''
-class A {}
-// A trailing comment
-''');
-    _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
-  }
-
-  Future<void> test_extension() async {
-    await _computeHighlights('''
-extension E on String {}
-''');
-    _check(HighlightRegionType.KEYWORD, 'extension');
-    _check(HighlightRegionType.BUILT_IN, 'on');
-  }
-
-  Future<void> test_methodInvocation_ofExtensionOverride_unresolved() async {
-    await _computeHighlights('''
-extension E on int {}
-
-main() {
-  E(0).foo();
-}
-''', hasErrors: true);
-    _check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo');
-  }
-
-  Future<void> test_nullLiteral() async {
-    await _computeHighlights('var x = null;');
-    _check(HighlightRegionType.KEYWORD, 'null');
-  }
-
-  Future<void> test_throwExpression() async {
-    await _computeHighlights('''
-void main() {
-  throw 'foo';
-}
-  ''');
-    _check(HighlightRegionType.KEYWORD, 'throw');
-  }
-
-  void _check(HighlightRegionType expectedType, String expectedText) {
-    for (var region in highlights) {
-      if (region.type == expectedType) {
-        var startIndex = region.offset;
-        var endIndex = startIndex + region.length;
-        var highlightedText = content.substring(startIndex, endIndex);
-        if (highlightedText == expectedText) {
-          return;
-        }
-      }
-    }
-    fail('Expected region of type $expectedType with text "$expectedText"');
-  }
-
-  Future<void> _computeHighlights(
-    String content, {
-    bool hasErrors = false,
-  }) async {
-    this.content = content;
-    newFile(sourcePath, content: content);
-    var result = await session.getResolvedUnit(sourcePath);
-
-    if (hasErrors) {
-      expect(result.errors, isNotEmpty);
-    } else {
-      expect(result.errors, isEmpty);
-    }
-
-    var computer = DartUnitHighlightsComputer2(result.unit);
-    highlights = computer.compute();
-  }
-}
diff --git a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
index b9d1af4..d251985 100644
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
@@ -11,12 +11,12 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(HighlightsComputerTest);
+    defineReflectiveTests(Highlights2ComputerTest);
   });
 }
 
 @reflectiveTest
-class HighlightsComputerTest extends AbstractContextTest {
+class Highlights2ComputerTest extends AbstractContextTest {
   String sourcePath;
   String content;
   List<HighlightRegion> highlights;
@@ -61,6 +61,20 @@
     _check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo');
   }
 
+  Future<void> test_nullLiteral() async {
+    await _computeHighlights('var x = null;');
+    _check(HighlightRegionType.KEYWORD, 'null');
+  }
+
+  Future<void> test_throwExpression() async {
+    await _computeHighlights('''
+void main() {
+  throw 'foo';
+}
+  ''');
+    _check(HighlightRegionType.KEYWORD, 'throw');
+  }
+
   void _check(HighlightRegionType expectedType, String expectedText) {
     for (var region in highlights) {
       if (region.type == expectedType) {
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index 8d7653e..1a04173 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.dart
@@ -6,7 +6,6 @@
 
 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;
 import 'imported_elements_computer_test.dart' as imported_elements_computer;
@@ -16,7 +15,6 @@
   defineReflectiveSuite(() {
     closing_labels_computer.main();
     folding_computer.main();
-    highlights2_computer.main();
     highlights_computer.main();
     import_elements_computer.main();
     imported_elements_computer.main();
diff --git a/pkg/analysis_server/test/src/domain_abstract_test.dart b/pkg/analysis_server/test/src/domain_abstract_test.dart
index eb1fdb9..46c9aa6 100644
--- a/pkg/analysis_server/test/src/domain_abstract_test.dart
+++ b/pkg/analysis_server/test/src/domain_abstract_test.dart
@@ -6,7 +6,6 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
index 8053be5..4a2d307 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
@@ -205,7 +205,6 @@
   }
 
   Future<void> test_relevanceTags_constructorBeforeClass() async {
-    server.options.useNewRelevance = true;
     addTestFile(r'''
 void foo(List<int> a) {}
 
@@ -253,8 +252,7 @@
       testCode.indexOf(' // ref'),
     );
 
-    if (server.options.useNewRelevance) {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
 [
   {
     "tag": "ElementKind.PREFIX",
@@ -302,16 +300,6 @@
   }
 ]
 ''');
-    } else {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
-[
-  {
-    "tag": "package:test/a.dart::MyEnum",
-    "relevanceBoost": 1100
-  }
-]
-''');
-    }
   }
 
   Future<void> test_relevanceTags_location_argumentList_named() async {
@@ -328,8 +316,7 @@
       testCode.indexOf('); // ref'),
     );
 
-    if (server.options.useNewRelevance) {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
 [
   {
     "tag": "ElementKind.PREFIX",
@@ -377,16 +364,6 @@
   }
 ]
 ''');
-    } else {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
-[
-  {
-    "tag": "dart:core::String",
-    "relevanceBoost": 10
-  }
-]
-''');
-    }
   }
 
   Future<void> test_relevanceTags_location_argumentList_positional() async {
@@ -403,8 +380,7 @@
       testCode.indexOf('); // ref'),
     );
 
-    if (server.options.useNewRelevance) {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
 [
   {
     "tag": "ElementKind.MIXIN",
@@ -460,16 +436,6 @@
   }
 ]
 ''');
-    } else {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
-[
-  {
-    "tag": "dart:core::double",
-    "relevanceBoost": 10
-  }
-]
-''');
-    }
   }
 
   Future<void> test_relevanceTags_location_assignment() async {
@@ -485,8 +451,7 @@
       testCode.indexOf(' // ref'),
     );
 
-    if (server.options.useNewRelevance) {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
 [
   {
     "tag": "ElementKind.PREFIX",
@@ -534,16 +499,6 @@
   }
 ]
 ''');
-    } else {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
-[
-  {
-    "tag": "dart:core::int",
-    "relevanceBoost": 10
-  }
-]
-''');
-    }
   }
 
   Future<void> test_relevanceTags_location_initializer() async {
@@ -556,8 +511,7 @@
       testCode.indexOf(' // ref'),
     );
 
-    if (server.options.useNewRelevance) {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
 [
   {
     "tag": "ElementKind.MIXIN",
@@ -613,16 +567,6 @@
   }
 ]
 ''');
-    } else {
-      assertJsonText(results.includedSuggestionRelevanceTags, r'''
-[
-  {
-    "tag": "dart:core::int",
-    "relevanceBoost": 10
-  }
-]
-''');
-    }
   }
 
   Future<void> test_relevanceTags_location_listLiteral() async {
diff --git a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart b/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
index 88fd799..3157c0c 100644
--- a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
@@ -7,9 +7,7 @@
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/plugin/request_converter_test.dart b/pkg/analysis_server/test/src/plugin/request_converter_test.dart
index 78d9858..7ba3049 100644
--- a/pkg/analysis_server/test/src/plugin/request_converter_test.dart
+++ b/pkg/analysis_server/test/src/plugin/request_converter_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/protocol/protocol_generated.dart' as server;
 import 'package:analysis_server/src/plugin/request_converter.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart' as server;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/plugin/result_converter_test.dart b/pkg/analysis_server/test/src/plugin/result_converter_test.dart
index d45118b..220ca9a 100644
--- a/pkg/analysis_server/test/src/plugin/result_converter_test.dart
+++ b/pkg/analysis_server/test/src/plugin/result_converter_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/protocol/protocol_generated.dart' as server;
 import 'package:analysis_server/src/plugin/result_converter.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart' as server;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/server/sdk_configuration_test.dart b/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
index a961393..b007d66 100644
--- a/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
+++ b/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
@@ -43,7 +43,6 @@
       expect(config.analyticsForceEnabled, isNull);
       expect(config.crashReportingId, isNull);
       expect(config.crashReportingForceEnabled, isNull);
-      expect(config.mlModelPath, isNull);
     });
 
     test('is configured', () {
@@ -55,9 +54,7 @@
   "server.analytics.forceEnabled": true,
 
   "server.crash.reporting.id": "Test_crash_id",
-  "server.crash.reporting.forceEnabled": true,
-
-  "server.ml.model.path": "/foo/bar/baz.ml"
+  "server.crash.reporting.forceEnabled": true
 }
 ''');
 
@@ -68,7 +65,6 @@
       expect(config.analyticsForceEnabled, isTrue);
       expect(config.crashReportingId, 'Test_crash_id');
       expect(config.crashReportingForceEnabled, isTrue);
-      expect(config.mlModelPath, '/foo/bar/baz.ml');
     });
   });
 }
diff --git a/pkg/analysis_server/test/src/services/completion/test_all.dart b/pkg/analysis_server/test/src/services/completion/test_all.dart
index 6055c7b..19d31b3 100644
--- a/pkg/analysis_server/test/src/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/src/services/completion/test_all.dart
@@ -6,10 +6,12 @@
 
 import 'dart/test_all.dart' as dart;
 import 'filtering/test_all.dart' as filtering;
+import 'yaml/test_all.dart' as yaml;
 
 void main() {
   defineReflectiveSuite(() {
     dart.main();
     filtering.main();
+    yaml.main();
   }, name: 'completion');
 }
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart b/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart
new file mode 100644
index 0000000..c86dc28
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/yaml/analysis_options_generator_test.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:linter/src/rules.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'yaml_generator_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AnalysisOptionsGeneratorTest);
+  });
+}
+
+@reflectiveTest
+class AnalysisOptionsGeneratorTest extends YamlGeneratorTest {
+  @override
+  String get fileName => 'analysis_options.yaml';
+
+  @override
+  AnalysisOptionsGenerator get generator =>
+      AnalysisOptionsGenerator(resourceProvider);
+
+  void test_analyzer() {
+    getCompletions('''
+analyzer:
+  ^
+''');
+    assertSuggestion('${AnalyzerOptions.enableExperiment}: ');
+  }
+
+  void test_empty() {
+    getCompletions('^');
+    assertSuggestion('${AnalyzerOptions.analyzer}: ');
+    assertSuggestion('${AnalyzerOptions.include}: ');
+    // TODO(brianwilkerson) Replace this with a constant.
+    assertSuggestion('linter: ');
+  }
+
+  void test_linter() {
+    getCompletions('''
+linter:
+  ^
+''');
+    assertSuggestion('rules:');
+  }
+
+  void test_linter_rules() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    ^
+''');
+    assertSuggestion('annotate_overrides');
+  }
+
+  void test_linter_rules_listItem_first() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    - ^
+    - annotate_overrides
+''');
+    assertSuggestion('avoid_as');
+    assertNoSuggestion('annotate_overrides');
+  }
+
+  void test_linter_rules_listItem_last() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    - annotate_overrides
+    - ^
+''');
+    assertSuggestion('avoid_as');
+    assertNoSuggestion('annotate_overrides');
+  }
+
+  void test_linter_rules_listItem_middle() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    - annotate_overrides
+    - ^
+    - avoid_empty_else
+''');
+    assertSuggestion('avoid_as');
+    assertNoSuggestion('annotate_overrides');
+    assertNoSuggestion('avoid_empty_else');
+  }
+
+  void test_linter_rules_listItem_nonDuplicate() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    - annotate_overrides
+    - ^
+''');
+    assertNoSuggestion('annotate_overrides');
+  }
+
+  void test_linter_rules_listItem_only() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    - ^
+''');
+    assertSuggestion('annotate_overrides');
+  }
+
+  void test_linter_rules_listItem_partial() {
+    registerLintRules();
+    getCompletions('''
+linter:
+  rules:
+    - ann^
+''');
+    assertSuggestion('annotate_overrides');
+  }
+
+  @failingTest
+  void test_topLevel_afterOtherKeys() {
+    // This test fails because the cursor is considered to be inside the exclude
+    // list, and we don't suggest values there.
+    getCompletions('''
+analyzer:
+  exclude:
+    - '*.g.dart'
+^
+''');
+    assertSuggestion('${AnalyzerOptions.include}: ');
+  }
+
+  @failingTest
+  void test_topLevel_afterOtherKeys_partial() {
+    // This test fails because the YAML parser can't recover from this kind of
+    // invalid input.
+    getCompletions('''
+analyzer:
+  exclude:
+    - '*.g.dart'
+li^
+''');
+    assertSuggestion('linter');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/fix_data_generator_test.dart b/pkg/analysis_server/test/src/services/completion/yaml/fix_data_generator_test.dart
new file mode 100644
index 0000000..4634360
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/yaml/fix_data_generator_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'yaml_generator_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FixDataGeneratorTest);
+  });
+}
+
+@reflectiveTest
+class FixDataGeneratorTest extends YamlGeneratorTest {
+  @override
+  String get fileName => 'fix_data.yaml';
+
+  @override
+  FixDataGenerator get generator => FixDataGenerator(resourceProvider);
+
+  void test_empty() {
+    getCompletions('^');
+    assertSuggestion('version: ');
+    assertSuggestion('transforms:');
+  }
+
+  void test_transforms_changes_listItem_last() {
+    getCompletions('''
+transforms:
+  - changes:
+    - kind: rename
+      ^
+''');
+    assertSuggestion('newName: ');
+    assertNoSuggestion('kind: ');
+  }
+
+  void test_transforms_changes_listItem_only() {
+    getCompletions('''
+transforms:
+  - changes:
+    - ^
+''');
+    assertSuggestion('kind: ');
+  }
+
+  void test_transforms_element() {
+    getCompletions('''
+transforms:
+  - element:
+      ^
+''');
+    assertSuggestion('uris: ');
+  }
+
+  void test_transforms_listItem_last() {
+    getCompletions('''
+transforms:
+  - title: ''
+    ^
+''');
+    assertSuggestion('date: ');
+    assertNoSuggestion('title: ');
+  }
+
+  void test_transforms_listItem_only() {
+    getCompletions('''
+transforms:
+  - ^
+''');
+    assertSuggestion('title: ');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart b/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
new file mode 100644
index 0000000..b00f1d4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
@@ -0,0 +1,257 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'yaml_generator_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PubspecGeneratorTest);
+  });
+}
+
+@reflectiveTest
+class PubspecGeneratorTest extends YamlGeneratorTest {
+  @override
+  String get fileName => 'pubspec.yaml';
+
+  @override
+  PubspecGenerator get generator => PubspecGenerator(resourceProvider);
+
+  void test_empty() {
+    getCompletions('^');
+    assertSuggestion('flutter: ');
+    assertSuggestion('name: ');
+  }
+
+  void test_environment() {
+    getCompletions('''
+environment:
+  ^
+''');
+    assertSuggestion('flutter: ');
+    assertSuggestion('sdk: ');
+  }
+
+  void test_flutter() {
+    getCompletions('''
+flutter:
+  ^
+''');
+    assertSuggestion('assets:');
+    assertSuggestion('plugin: ');
+  }
+
+  void test_flutter_assets_invalidPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets?im^
+''');
+    assertNoSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_nonExistentPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - asets/im^
+''');
+    assertNoSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_noPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - ^
+''');
+    assertSuggestion('assets');
+  }
+
+  void test_flutter_assets_partialPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets/im^
+''');
+    assertSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_path_withFollowing() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets/^img
+''');
+    assertSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_path_withoutFollowing() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets/^
+''');
+    assertSuggestion('img1.jpg');
+  }
+
+  void test_flutter_fonts() {
+    getCompletions('''
+flutter:
+  fonts:
+    ^
+''');
+    assertSuggestion('family: ');
+    assertSuggestion('fonts:');
+  }
+
+  void test_flutter_fonts_fonts() {
+    getCompletions('''
+flutter:
+  fonts:
+    - fonts:
+        ^
+''');
+    assertSuggestion('asset: ');
+  }
+
+  void test_flutter_fonts_fonts_style() {
+    getCompletions('''
+flutter:
+  fonts:
+    - fonts:
+       - style: ^
+''');
+    assertSuggestion('italic');
+  }
+
+  void test_flutter_fonts_weight() {
+    getCompletions('''
+flutter:
+  fonts:
+    - fonts:
+        - weight: ^
+''');
+    assertSuggestion('100');
+    assertSuggestion('900');
+  }
+
+  void test_flutter_module() {
+    getCompletions('''
+flutter:
+  module:
+    ^
+''');
+    assertSuggestion('androidX: ');
+    assertSuggestion('iosBundleIdentifier: ');
+  }
+
+  void test_flutter_plugin() {
+    getCompletions('''
+flutter:
+  plugin:
+    ^
+''');
+    assertSuggestion('platforms: ');
+  }
+
+  void test_flutter_plugin_platforms() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      ^
+''');
+    assertSuggestion('android: ');
+    assertSuggestion('web: ');
+  }
+
+  void test_flutter_plugin_platforms_android() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      android:
+        ^
+''');
+    assertSuggestion('package: ');
+    assertSuggestion('pluginClass: ');
+  }
+
+  void test_flutter_plugin_platforms_ios() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      ios:
+        ^
+''');
+    assertSuggestion('pluginClass: ');
+  }
+
+  void test_flutter_plugin_platforms_linux() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      linux:
+        ^
+''');
+    assertSuggestion('dartPluginClass: ');
+    assertSuggestion('pluginClass: ');
+  }
+
+  void test_flutter_plugin_platforms_macos() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      macos:
+        ^
+''');
+    assertSuggestion('dartPluginClass: ');
+    assertSuggestion('pluginClass: ');
+  }
+
+  void test_flutter_plugin_platforms_web() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      web:
+        ^
+''');
+    assertSuggestion('fileName: ');
+    assertSuggestion('pluginClass: ');
+  }
+
+  void test_flutter_plugin_platforms_windows() {
+    getCompletions('''
+flutter:
+  plugin:
+    platforms:
+      windows:
+        ^
+''');
+    assertSuggestion('dartPluginClass: ');
+    assertSuggestion('pluginClass: ');
+  }
+
+  void test_flutter_usesMaterialDesign() {
+    getCompletions('''
+flutter:
+  uses-material-design: ^
+''');
+    assertSuggestion('true');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/test_all.dart b/pkg/analysis_server/test/src/services/completion/yaml/test_all.dart
new file mode 100644
index 0000000..0d82611
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/yaml/test_all.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'analysis_options_generator_test.dart' as analysis_options_generator;
+import 'fix_data_generator_test.dart' as fix_data_generator;
+import 'pubspec_generator_test.dart' as pubspec_generator;
+
+void main() {
+  defineReflectiveSuite(() {
+    analysis_options_generator.main();
+    fix_data_generator.main();
+    pubspec_generator.main();
+  }, name: 'yaml');
+}
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/yaml_generator_test_support.dart b/pkg/analysis_server/test/src/services/completion/yaml/yaml_generator_test_support.dart
new file mode 100644
index 0000000..3baebe1
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/yaml/yaml_generator_test_support.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test/test.dart';
+
+abstract class YamlGeneratorTest with ResourceProviderMixin {
+  /// The completion results produced by [getCompletions].
+  /* late */ List<CompletionSuggestion> results;
+
+  /// Return the name of the file being tested.
+  String get fileName;
+
+  /// Return the generator to be used for this test.
+  YamlCompletionGenerator get generator;
+
+  /// Assert that there is no suggestion with the given [completion].
+  void assertNoSuggestion(String completion) {
+    for (var suggestion in results) {
+      if (suggestion.completion == completion) {
+        var buffer = StringBuffer();
+        buffer.writeln("Unexpected suggestion of '$completion' in:");
+        for (var suggestion in results) {
+          buffer.writeln("  '${suggestion.completion}'");
+        }
+        fail(buffer.toString());
+      }
+    }
+  }
+
+  /// Assert that there is a suggestion with the given [completion].
+  void assertSuggestion(String completion) {
+    for (var suggestion in results) {
+      if (suggestion.completion == completion) {
+        return;
+      }
+    }
+    var buffer = StringBuffer();
+    buffer.writeln("Missing suggestion of '$completion', found:");
+    for (var suggestion in results) {
+      buffer.writeln("  '${suggestion.completion}'");
+    }
+    fail(buffer.toString());
+  }
+
+  /// Compute the completions in the given [content]. The location of the
+  /// completion request is encoded in the content as a caret (`^`).
+  void getCompletions(String content) {
+    // Extract the completion location from the [content].
+    var completionOffset = content.indexOf('^');
+    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
+    var nextOffset = content.indexOf('^', completionOffset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    content = content.substring(0, completionOffset) +
+        content.substring(completionOffset + 1);
+    // Add the file to the file system.
+    var file = newFile('/home/test/$fileName', content: content);
+    // Generate completions.
+    results = generator.getSuggestions(file.path, completionOffset).suggestions;
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
index b6ac127..2235fe2 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/test_utilities/platform.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     hide AnalysisError;
@@ -192,6 +193,7 @@
 
   Future<List<Assist>> _computeAssists() async {
     var context = DartAssistContextImpl(
+      InstrumentationService.NULL_SERVICE,
       workspace,
       testAnalysisResult,
       _offset,
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
index d12dd4c..7d6b659 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
@@ -11,12 +11,12 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ConvertToNormalParameterTest);
+    defineReflectiveTests(ConvertToNullAwareTest);
   });
 }
 
 @reflectiveTest
-class ConvertToNormalParameterTest extends AssistProcessorTest {
+class ConvertToNullAwareTest extends AssistProcessorTest {
   @override
   AssistKind get kind => DartAssistKind.CONVERT_TO_NULL_AWARE;
 
@@ -138,6 +138,18 @@
 ''');
   }
 
+  Future<void> test_notEqual_noTarget() async {
+    // https://github.com/dart-lang/sdk/issues/44173
+    verifyNoTestUnitErrors = false;
+    await resolveTestCode('''
+foo() {
+  var range = 1;
+  var rangeStart = range != null ? toOffset() : null;
+}
+''');
+    await assertNoAssistAt(' null;');
+  }
+
   Future<void> test_notEqual_notNullPreserving() async {
     await resolveTestCode('''
 abstract class A {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
index 3ab99bf..5817ae2 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
@@ -58,6 +58,16 @@
 ''');
   }
 
+  Future<void> test_extension_hasType() async {
+    verifyNoTestUnitErrors = false;
+    await resolveTestCode('''
+extension E on int {
+  int test = 42;
+}
+''');
+    await assertNoAssistAt('test = 42');
+  }
+
   Future<void> test_final() async {
     await resolveTestCode('''
 class A {
@@ -94,6 +104,25 @@
 ''');
   }
 
+  Future<void> test_mixin_hasType() async {
+    await resolveTestCode('''
+mixin M {
+  int test = 42;
+}
+''');
+    await assertHasAssistAt('test = 42', '''
+mixin M {
+  int _test = 42;
+
+  int get test => _test;
+
+  set test(int test) {
+    _test = test;
+  }
+}
+''');
+  }
+
   Future<void> test_multipleFields() async {
     await resolveTestCode('''
 class A {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
index 8047f30..bb382ff 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
@@ -4,16 +4,17 @@
 
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
-import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../abstract_context.dart';
 import 'fix_processor.dart';
 
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AddAsyncTest);
+    defineReflectiveTests(AddAsyncWithNullSafetyTest);
     defineReflectiveTests(AvoidReturningNullForFutureTest);
   });
 }
@@ -69,7 +70,7 @@
   await foo;
   return 1;
 }
-''', errorFilter: (AnalysisError error) {
+''', errorFilter: (error) {
       return error.errorCode == CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT;
     });
   }
@@ -84,7 +85,7 @@
 void takeFutureCallback(Future callback()) {}
 
 void doStuff() => takeFutureCallback(() async => await 1);
-''', errorFilter: (AnalysisError error) {
+''', errorFilter: (error) {
       return error.errorCode == CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT;
     });
   }
@@ -100,6 +101,42 @@
 ''');
   }
 
+  Future<void> test_missingReturn_hasReturn() async {
+    await resolveTestCode('''
+Future<int> f(bool b) {
+  if (b) {
+    return 0;
+  }
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION;
+    });
+  }
+
+  Future<void> test_missingReturn_notVoid() async {
+    await resolveTestCode('''
+Future<int> f() {
+  print('');
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_missingReturn_void() async {
+    await resolveTestCode('''
+Future<void> f() {
+  print('');
+}
+''');
+    await assertHasFix('''
+Future<void> f() async {
+  print('');
+}
+''');
+  }
+
   Future<void> test_nullFunctionBody() async {
     await resolveTestCode('''
 var F = await;
@@ -121,7 +158,7 @@
   await foo();
   return 42;
 }
-''', errorFilter: (AnalysisError error) {
+''', errorFilter: (error) {
       return error.errorCode == CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT;
     });
   }
@@ -179,6 +216,133 @@
 }
 
 @reflectiveTest
+class AddAsyncWithNullSafetyTest extends FixProcessorTest
+    with WithNullSafetyMixin {
+  @override
+  FixKind get kind => DartFixKind.ADD_ASYNC;
+
+  Future<void> test_missingReturn_method_hasReturn() async {
+    await resolveTestCode('''
+class C {
+  Future<int> m(bool b) {
+    if (b) {
+      return 0;
+    }
+  }
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_METHOD;
+    });
+  }
+
+  Future<void> test_missingReturn_method_notVoid() async {
+    await resolveTestCode('''
+class C {
+  Future<int> m() {
+    print('');
+  }
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_missingReturn_method_notVoid_inherited() async {
+    await resolveTestCode('''
+abstract class A {
+  Future<int> foo();
+}
+
+class B implements A {
+  foo() {
+  print('');
+  }
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_missingReturn_method_void() async {
+    await resolveTestCode('''
+class C {
+  Future<void> m() {
+    print('');
+  }
+}
+''');
+    await assertHasFix('''
+class C {
+  Future<void> m() async {
+    print('');
+  }
+}
+''');
+  }
+
+  Future<void> test_missingReturn_method_void_inherited() async {
+    await resolveTestCode('''
+abstract class A {
+  Future<void> foo();
+}
+
+class B implements A {
+  foo() {
+  print('');
+  }
+}
+''');
+    await assertHasFix('''
+abstract class A {
+  Future<void> foo();
+}
+
+class B implements A {
+  foo() async {
+  print('');
+  }
+}
+''');
+  }
+
+  Future<void> test_missingReturn_topLevel_hasReturn() async {
+    await resolveTestCode('''
+Future<int> f(bool b) {
+  if (b) {
+    return 0;
+  }
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION;
+    });
+  }
+
+  Future<void> test_missingReturn_topLevel_notVoid() async {
+    await resolveTestCode('''
+Future<int> f() {
+  print('');
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_missingReturn_topLevel_void() async {
+    await resolveTestCode('''
+Future<void> f() {
+  print('');
+}
+''');
+    await assertHasFix('''
+Future<void> f() async {
+  print('');
+}
+''');
+  }
+}
+
+@reflectiveTest
 class AvoidReturningNullForFutureTest extends FixProcessorLintTest {
   @override
   FixKind get kind => DartFixKind.ADD_ASYNC;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
index 16ec311..593c68c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
@@ -462,7 +462,10 @@
   FixKind get kind => DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT;
 
   @override
-  bool get withPackageMeta => true;
+  void setUp() {
+    super.setUp();
+    writeTestPackageConfig(meta: true);
+  }
 
   Future<void> test_constructor_single_closure_nnbd() async {
     addSource('/home/test/lib/a.dart', r'''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
index 1f22076..d5b03dc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
@@ -45,7 +45,7 @@
   @override
   FixKind get kind => DartFixKind.ADD_REQUIRED2;
 
-  Future<void> test_withAssert() async {
+  Future<void> test_nonNullable() async {
     await resolveTestCode('''
 void function({String param}) {}
 ''');
@@ -53,4 +53,124 @@
 void function({required String param}) {}
 ''');
   }
+
+  Future<void> test_withRequiredAnnotation() async {
+    writeTestPackageConfig(meta: true);
+
+    await resolveTestCode('''
+import 'package:meta/meta.dart';
+
+void function({@required String param}) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+void function({required String param}) {}
+''');
+  }
+
+  Future<void> test_withRequiredAnnotation_constructor() async {
+    writeTestPackageConfig(meta: true);
+
+    await resolveTestCode('''
+import 'package:meta/meta.dart';
+
+class A {
+  String foo;
+  A({@required this.foo});
+}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+class A {
+  String foo;
+  A({required this.foo});
+}
+''');
+  }
+
+  Future<void> test_withRequiredAnnotation_functionParam() async {
+    writeTestPackageConfig(meta: true);
+
+    await resolveTestCode('''
+import 'package:meta/meta.dart';
+
+void f({@required int g(String)}) { }
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+void f({required int g(String)}) { }
+''');
+  }
+
+  Future<void> test_withRequiredAnnotationInList_first() async {
+    writeTestPackageConfig(meta: true);
+
+    await resolveTestCode('''
+import 'package:meta/meta.dart';
+
+class Foo {
+  const Foo();
+}
+
+const foo = Foo();
+
+void function({@required @foo String param}) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+class Foo {
+  const Foo();
+}
+
+const foo = Foo();
+
+void function({@foo required String param}) {}
+''');
+  }
+
+  Future<void> test_withRequiredAnnotationInList_last() async {
+    writeTestPackageConfig(meta: true);
+
+    await resolveTestCode('''
+import 'package:meta/meta.dart';
+
+class Foo {
+  const Foo();
+}
+
+const foo = Foo();
+
+void function({@foo @required String param}) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+class Foo {
+  const Foo();
+}
+
+const foo = Foo();
+
+void function({@foo required String param}) {}
+''');
+  }
+
+  Future<void> test_withRequiredAnnotationWithReason() async {
+    writeTestPackageConfig(meta: true);
+
+    await resolveTestCode('''
+import 'package:meta/meta.dart';
+
+void function({@Required('reason') String param}) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+void function({required String param}) {}
+''');
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart
index de7282e..1f45cc4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/services/correction/bulk_fix_processor.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -35,7 +36,7 @@
   }
 
   Future<void> assertHasFix(String expected) async {
-    change = await _computeFixes();
+    change = await _computeSourceChange();
 
     // apply to "file"
     var fileEdits = change.edits;
@@ -47,11 +48,22 @@
   }
 
   Future<void> assertNoFix() async {
-    change = await _computeFixes();
+    change = await _computeSourceChange();
     var fileEdits = change.edits;
     expect(fileEdits, isEmpty);
   }
 
+  /// Computes fixes for the specified [testUnit].
+  Future<BulkFixProcessor> computeFixes() async {
+    var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
+    var analysisContext = contextFor(testFile);
+    tracker.addContext(analysisContext);
+    var processor =
+        BulkFixProcessor(InstrumentationService.NULL_SERVICE, workspace);
+    await processor.fixErrors([analysisContext]);
+    return processor;
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -59,14 +71,10 @@
     _createAnalysisOptionsFile();
   }
 
-  /// Computes fixes for the given [error] in [testUnit].
-  Future<SourceChange> _computeFixes() async {
-    var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
-    var analysisContext = contextFor(testFile);
-    tracker.addContext(analysisContext);
-    var changeBuilder =
-        await BulkFixProcessor(workspace).fixErrors([analysisContext]);
-    return changeBuilder.sourceChange;
+  /// Returns the source change for computed fixes in the specified [testUnit].
+  Future<SourceChange> _computeSourceChange() async {
+    var processor = await computeFixes();
+    return processor.builder.sourceChange;
   }
 
   /// Create the analysis options file needed in order to correctly analyze the
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor_test.dart
new file mode 100644
index 0000000..8ac6ee0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ChangeMapTest);
+  });
+}
+
+@reflectiveTest
+class ChangeMapTest extends BulkFixProcessorTest {
+  Future<void> test_changeMap() async {
+    createAnalysisOptionsFile(experiments: experiments, lints: [
+      LintNames.annotate_overrides,
+      LintNames.unnecessary_new,
+    ]);
+
+    await resolveTestCode('''
+class A { }
+
+var a = new A();
+var aa = new A();
+''');
+
+    var processor = await computeFixes();
+    var changeMap = processor.changeMap;
+    var errors = changeMap.libraryMap[testFile];
+    expect(errors, hasLength(1));
+    expect(errors[LintNames.unnecessary_new], 2);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
index 8404c8b..88e911a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
@@ -2,8 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/services/correction/bulk_fix_processor.dart';
+import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
+import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'bulk_fix_processor.dart';
@@ -30,6 +33,7 @@
     defineReflectiveTests(WrongNumberOfTypeArgumentsExtensionTest);
     defineReflectiveTests(WrongNumberOfTypeArgumentsMethodTest);
     defineReflectiveTests(WrongNumberOfTypeArgumentsTest);
+    defineReflectiveTests(NoProducerOverlapsTest);
   });
 }
 
@@ -493,6 +497,39 @@
 }
 
 @reflectiveTest
+class NoProducerOverlapsTest {
+  void test_noProducerOverlaps() {
+    // Ensure that no error code is used by both data-driven fixes and
+    // non-data-driven fixes, as this could result in an LSP "Apply-all" code
+    // action accidentally executing data-driven fixes.
+
+    final dataDrivenCodes = <String>{};
+    final nonDataDrivenCodes = <String>{
+      ...BulkFixProcessor.lintProducerMap.keys,
+      ...BulkFixProcessor.nonLintProducerMap.keys.map((c) => c.uniqueName),
+    };
+
+    for (final code in BulkFixProcessor.nonLintMultiProducerMap.keys) {
+      for (final producerFunc
+          in BulkFixProcessor.nonLintMultiProducerMap[code]) {
+        final producer = producerFunc();
+        if (producer is DataDriven) {
+          dataDrivenCodes.add(code.uniqueName);
+        } else {
+          nonDataDrivenCodes.add(code.uniqueName);
+        }
+      }
+    }
+
+    final intersection = dataDrivenCodes.intersection(nonDataDrivenCodes);
+    if (intersection.isNotEmpty) {
+      fail(
+          'Error codes $intersection have both data-driven and non-data-driven fixes');
+    }
+  }
+}
+
+@reflectiveTest
 class NotEnoughPositionalArgumentsTest extends _DataDrivenTest {
   Future<void> test_addParameter() async {
     setPackageContent('''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 3b98bfd..14012da 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -9,6 +9,7 @@
 import 'add_diagnostic_property_reference_test.dart'
     as add_diagnostic_property_reference;
 import 'add_override_test.dart' as add_override;
+import 'bulk_fix_processor_test.dart' as bulk_fix_processor;
 import 'convert_documentation_into_line_test.dart'
     as convert_documentation_into_line;
 import 'convert_map_from_iterable_to_for_literal_test.dart'
@@ -70,6 +71,7 @@
     add_const.main();
     add_diagnostic_property_reference.main();
     add_override.main();
+    bulk_fix_processor.main();
     convert_documentation_into_line.main();
     convert_map_from_iterable_to_for_literal.main();
     convert_to_contains.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart
index f12ee52..28674cb 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart
@@ -83,10 +83,7 @@
 ''');
   }
 
-  @failingTest
   Future<void> test_from_inferred() async {
-    // _setWouldBeInferred does not check for inference based on the parameter
-    // type.
     await resolveTestCode('''
 void f(Set<int> s) {}
 var s = f(Set.from([]));
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
index 6b81786..5ed784f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
@@ -484,12 +485,12 @@
               kind: ElementKindUtilities.fromName(_kind),
               components: components ?? ['C', 'm']),
           bulkApply: false,
-          changes: [
+          changesSelector: UnconditionalChangesSelector([
             AddTypeParameter(
                 index: index,
                 name: 'T',
                 extendedType:
                     extendedType == null ? null : codeTemplate(extendedType),
                 argumentValue: codeTemplate('String')),
-          ]);
+          ]));
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart
index 75e883e..2212ec0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart
@@ -5,6 +5,9 @@
 import 'package:_fe_analyzer_shared/src/base/errors.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_fragment_parser.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/variable_scope.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:matcher/matcher.dart';
 import 'package:test/test.dart';
@@ -15,7 +18,8 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(CodeFragmentParserTest);
+    defineReflectiveTests(AccessorsTest);
+    defineReflectiveTests(ConditionTest);
   });
 }
 
@@ -23,20 +27,36 @@
   List<Accessor> assertErrors(
       String content, List<ExpectedError> expectedErrors) {
     var errorListener = GatheringErrorListener();
-    var errorReporter = ErrorReporter(errorListener, MockSource());
-    var accessors = CodeFragmentParser(errorReporter).parse(content, 0);
+    var accessors = _parser(errorListener).parseAccessors(content, 0);
     errorListener.assertErrors(expectedErrors);
     return accessors;
   }
 
+  Expression assertErrorsInCondition(String content, List<String> variables,
+      List<ExpectedError> expectedErrors) {
+    var errorListener = GatheringErrorListener();
+    var expression =
+        _parser(errorListener, variables: variables).parseCondition(content, 0);
+    errorListener.assertErrors(expectedErrors);
+    return expression;
+  }
+
   List<Accessor> assertNoErrors(String content) {
     var errorListener = GatheringErrorListener();
-    var errorReporter = ErrorReporter(errorListener, MockSource());
-    var accessors = CodeFragmentParser(errorReporter).parse(content, 0);
+    var accessors = _parser(errorListener).parseAccessors(content, 0);
     errorListener.assertNoErrors();
     return accessors;
   }
 
+  Expression assertNoErrorsInCondition(String content,
+      {List<String> variables}) {
+    var errorListener = GatheringErrorListener();
+    var expression =
+        _parser(errorListener, variables: variables).parseCondition(content, 0);
+    errorListener.assertNoErrors();
+    return expression;
+  }
+
   ExpectedError error(ErrorCode code, int offset, int length,
           {String message,
           Pattern messageContains,
@@ -46,10 +66,23 @@
           message: message,
           messageContains: messageContains,
           expectedContextMessages: contextMessages);
+
+  CodeFragmentParser _parser(GatheringErrorListener listener,
+      {List<String> variables}) {
+    var errorReporter = ErrorReporter(listener, MockSource());
+    var map = <String, ValueGenerator>{};
+    if (variables != null) {
+      for (var variableName in variables) {
+        map[variableName] = CodeFragment([]);
+      }
+    }
+    var scope = VariableScope(null, map);
+    return CodeFragmentParser(errorReporter, scope: scope);
+  }
 }
 
 @reflectiveTest
-class CodeFragmentParserTest extends AbstractCodeFragmentParserTest {
+class AccessorsTest extends AbstractCodeFragmentParserTest {
   void test_arguments_arguments_arguments() {
     var accessors = assertNoErrors('arguments[0].arguments[1].arguments[2]');
     expect(accessors, hasLength(3));
@@ -83,3 +116,30 @@
     expect(accessors[0], isA<TypeArgumentAccessor>());
   }
 }
+
+@reflectiveTest
+class ConditionTest extends AbstractCodeFragmentParserTest {
+  void test_and() {
+    var expression = assertNoErrorsInCondition("'a' != 'b' && 'c' != 'd'")
+        as BinaryExpression;
+    expect(expression.leftOperand, isA<BinaryExpression>());
+    expect(expression.operator, Operator.and);
+    expect(expression.rightOperand, isA<BinaryExpression>());
+  }
+
+  void test_equal() {
+    var expression = assertNoErrorsInCondition('a == b', variables: ['a', 'b'])
+        as BinaryExpression;
+    expect(expression.leftOperand, isA<VariableReference>());
+    expect(expression.operator, Operator.equal);
+    expect(expression.rightOperand, isA<VariableReference>());
+  }
+
+  void test_notEqual() {
+    var expression = assertNoErrorsInCondition("a != 'b'", variables: ['a'])
+        as BinaryExpression;
+    expect(expression.leftOperand, isA<VariableReference>());
+    expect(expression.operator, Operator.notEqual);
+    expect(expression.rightOperand, isA<LiteralString>());
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_template_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_template_test.dart
index ebcdb94..f6ccc74 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_template_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_template_test.dart
@@ -77,7 +77,7 @@
     var body = function.functionExpression.body as BlockFunctionBody;
     var statement = body.block.statements[0] as ExpressionStatement;
     var node = statement.expression;
-    var template = CodeTemplate(CodeTemplateKind.expression, components);
+    var template = CodeTemplate(CodeTemplateKind.expression, components, null);
     var builder = ChangeBuilder(session: session);
     var context = TemplateContext(node, CorrectionUtils(testAnalysisResult));
     await builder.addDartFileEdit(testFile, (builder) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test_support.dart
index 39a4c16..4a70221 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test_support.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test_support.dart
@@ -33,7 +33,8 @@
 
   /// Return a code template that will produce the given [text].
   CodeTemplate codeTemplate(String text) {
-    return CodeTemplate(CodeTemplateKind.expression, [TemplateText(text)]);
+    return CodeTemplate(
+        CodeTemplateKind.expression, [TemplateText(text)], null);
   }
 
   /// A method that can be used as an error filter to ignore any unused_import
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/expected_primary_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/expected_primary_test.dart
new file mode 100644
index 0000000..38c7e43
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/expected_primary_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExpectedPrimaryTest);
+  });
+}
+
+@reflectiveTest
+class ExpectedPrimaryTest extends AbstractTransformSetParserTest {
+  void test_integer() {
+    assertErrors('''
+version: 1
+transforms:
+  - title: 'Remove nullOk'
+    date: 2020-11-04
+    element:
+      uris: [ 'test.dart' ]
+      method: 'm'
+      inClass: 'C'
+    oneOf:
+      - if: "'x' =="
+        changes: []
+''', [
+      error(TransformSetErrorCode.expectedPrimary, 177, 2),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_required_if_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_required_if_test.dart
new file mode 100644
index 0000000..5037a80
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_required_if_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidRequiredIfTest);
+  });
+}
+
+@reflectiveTest
+class InvalidRequiredIfTest extends AbstractTransformSetParserTest {
+  void test_requiredNamed() {
+    assertErrors('''
+version: 1
+transforms:
+- title: ''
+  date: 2020-09-14
+  element:
+    uris: ['test.dart']
+    method: 'm'
+    inClass: 'C'
+  changes:
+    - kind: addParameter
+      style: required_named
+      index: 0
+      name: 'p'
+      argumentValue:
+        expression: ''
+        requiredIf: "p != ''"
+        variables:
+          p:
+            kind: 'fragment'
+            value: 'arguments[1]'
+''', [
+      error(TransformSetErrorCode.invalidRequiredIf, 269, 10),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
index 1237ba0..c4a2e75 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
@@ -199,20 +199,6 @@
     ]);
   }
 
-  void test_transform_changes() {
-    assertErrors('''
-version: 1
-transforms:
-- title: ''
-  date: 2020-09-14
-  element:
-    uris: ['test.dart']
-    function: 'f'
-''', [
-      error(TransformSetErrorCode.missingKey, 25, 82),
-    ]);
-  }
-
   void test_transform_date() {
     assertErrors('''
 version: 1
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart
index 255767b..002f2f5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart
@@ -15,26 +15,6 @@
 
 @reflectiveTest
 class MissingOneOfMultipleKeysTest extends AbstractTransformSetParserTest {
-  void test_codeTemplate() {
-    assertErrors('''
-version: 1
-transforms:
-- title: ''
-  date: 2020-09-14
-  element:
-    uris: ['test.dart']
-    function: 'f'
-  changes:
-    - kind: addTypeParameter
-      index: 0
-      name: 'T'
-      argumentValue:
-        variables: []
-''', [
-      error(TransformSetErrorCode.missingOneOfMultipleKeys, 207, 14),
-    ]);
-  }
-
   void test_element() {
     assertErrors('''
 version: 1
@@ -79,4 +59,18 @@
       error(TransformSetErrorCode.missingOneOfMultipleKeys, 124, 22),
     ]);
   }
+
+  void test_transform() {
+    assertErrors('''
+version: 1
+transforms:
+- title: ''
+  date: 2020-09-14
+  element:
+    uris: ['test.dart']
+    function: 'f'
+''', [
+      error(TransformSetErrorCode.missingOneOfMultipleKeys, 0, 107),
+    ]);
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_token_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_token_test.dart
index ec8ac42..c1ee9bd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_token_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_token_test.dart
@@ -21,6 +21,12 @@
     ]);
   }
 
+  void test_empty() {
+    assertErrors('', [
+      error(TransformSetErrorCode.missingToken, 0, 0),
+    ]);
+  }
+
   void test_identifier_afterPeriod() {
     assertErrors('arguments[2].', [
       error(TransformSetErrorCode.missingToken, 12, 1),
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
index 651508b..bb2464ae 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
@@ -5,9 +5,11 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'conflicting_key_test.dart' as conflicting_key;
+import 'expected_primary_test.dart' as expected_primary;
 import 'invalid_character_test.dart' as invalid_character;
 import 'invalid_key_test.dart' as invalid_key;
 import 'invalid_parameter_style_test.dart' as invalid_parameter_style;
+import 'invalid_required_if_test.dart' as invalid_required_if;
 import 'invalid_value_one_of_test.dart' as invalid_value_one_of;
 import 'invalid_value_test.dart' as invalid_value;
 import 'missing_key_test.dart' as missing_key;
@@ -16,6 +18,7 @@
 import 'missing_token_test.dart' as missing_token;
 import 'missing_uri_test.dart' as missing_uri;
 import 'undefined_variable_test.dart' as undefined_variable;
+import 'unexpected_token_test.dart' as unexpected_token;
 import 'unknown_accessor_test.dart' as unknown_accessor;
 import 'unsupported_key_test.dart' as unsupported_key;
 import 'unsupported_version_test.dart' as unsupported_version;
@@ -25,9 +28,11 @@
 void main() {
   defineReflectiveSuite(() {
     conflicting_key.main();
+    expected_primary.main();
     invalid_character.main();
     invalid_key.main();
     invalid_parameter_style.main();
+    invalid_required_if.main();
     invalid_value_one_of.main();
     invalid_value.main();
     missing_key.main();
@@ -36,6 +41,7 @@
     missing_token.main();
     missing_uri.main();
     undefined_variable.main();
+    unexpected_token.main();
     unknown_accessor.main();
     unsupported_key.main();
     unsupported_version.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unexpected_token_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unexpected_token_test.dart
new file mode 100644
index 0000000..9f6213c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unexpected_token_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnexpectedTokenTest);
+  });
+}
+
+@reflectiveTest
+class UnexpectedTokenTest extends AbstractTransformSetParserTest {
+  void test_integer() {
+    assertErrors('''
+version: 1
+transforms:
+  - title: 'Remove nullOk'
+    date: 2020-11-04
+    element:
+      uris: [ 'test.dart' ]
+      method: 'm'
+      inClass: 'C'
+    oneOf:
+      - if: "'x' == 'y' 'z'"
+        changes: []
+''', [
+      error(TransformSetErrorCode.unexpectedToken, 184, 3),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/wrong_token_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/wrong_token_test.dart
index a047759..ed35ea9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/wrong_token_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/wrong_token_test.dart
@@ -9,12 +9,12 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(MissingTokenTest);
+    defineReflectiveTests(WrongTokenTest);
   });
 }
 
 @reflectiveTest
-class MissingTokenTest extends AbstractCodeFragmentParserTest {
+class WrongTokenTest extends AbstractCodeFragmentParserTest {
   void test_closeBracket() {
     assertErrors('arguments[2 3', [
       error(TransformSetErrorCode.wrongToken, 12, 1),
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
index 2e53eb1..7932354 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
@@ -600,6 +600,408 @@
   }
 
   Future<void>
+      test_material_InputDecoration_defaultConstructor_matchFirstCase_deprecated() async {
+    setPackageContent('''
+class InputDecoration {
+  InputDecoration({
+    @deprecated bool hasFloatingPlaceholder: true,
+    FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+  });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Rename to floatingLabelBehavior'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'InputDecoration'
+    oneOf:
+      - if: "hasFloatingPlaceholder == 'true'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.auto'
+              requiredIf: "hasFloatingPlaceholder == 'true'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder == 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder == 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+    variables:
+      hasFloatingPlaceholder:
+        kind: 'fragment'
+        value: 'arguments[hasFloatingPlaceholder]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: true);
+''');
+    await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.auto);
+''');
+  }
+
+  Future<void>
+      test_material_InputDecoration_defaultConstructor_matchSecondCase_deprecated() async {
+    setPackageContent('''
+class InputDecoration {
+  InputDecoration({
+    @deprecated bool hasFloatingPlaceholder: true,
+    FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+  });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Rename to floatingLabelBehavior'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'InputDecoration'
+    oneOf:
+      - if: "hasFloatingPlaceholder == 'true'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.auto'
+              requiredIf: "hasFloatingPlaceholder == 'true'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder == 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder == 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+    variables:
+      hasFloatingPlaceholder:
+        kind: 'fragment'
+        value: 'arguments[hasFloatingPlaceholder]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: false);
+''');
+    await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.never);
+''');
+  }
+
+  Future<void>
+      test_material_InputDecoration_defaultConstructor_matchThirdCase_deprecated() async {
+    setPackageContent('''
+class InputDecoration {
+  InputDecoration({
+    @deprecated bool hasFloatingPlaceholder: true,
+    FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+  });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Rename to floatingLabelBehavior'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'InputDecoration'
+    oneOf:
+      - if: "hasFloatingPlaceholder == 'true'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.auto'
+              requiredIf: "hasFloatingPlaceholder == 'true'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder == 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder == 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+      - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+        changes:
+          - kind: 'addParameter'
+            index: 14
+            name: 'floatingLabelBehavior'
+            style: optional_named
+            argumentValue:
+              expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+              requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+              variables:
+                FloatingLabelBehavior:
+                  kind: 'import'
+                  uris: ['$importUri']
+                  name: 'FloatingLabelBehavior'
+          - kind: 'removeParameter'
+            name: 'hasFloatingPlaceholder'
+    variables:
+      hasFloatingPlaceholder:
+        kind: 'fragment'
+        value: 'arguments[hasFloatingPlaceholder]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: b);
+''');
+    await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: b ? FloatingLabelBehavior.auto : FloatingLabelBehavior.never);
+''');
+  }
+
+  Future<void> test_material_Scaffold_of_matchFirstCase() async {
+    setPackageContent('''
+class Scaffold {
+  static ScaffoldState of(BuildContext context) => ScaffoldState();
+  static ScaffoldState maybeOf(BuildContext context) => ScaffoldState();
+}
+class ScaffoldState {}
+class BuildContext {}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Remove nullOk'
+    date: 2020-11-04
+    element:
+      uris: ['$importUri']
+      method: 'of'
+      inClass: 'Scaffold'
+    oneOf:
+      - if: "nullOk == 'true'"
+        changes:
+          - kind: 'rename'
+            newName: 'maybeOf'
+          - kind: 'removeParameter'
+            name: 'nullOk'
+      - if: "nullOk == 'false'"
+        changes:
+          - kind: 'removeParameter'
+            name: 'nullOk'
+    variables:
+      nullOk:
+        kind: 'fragment'
+        value: 'arguments[nullOk]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+  Scaffold.of(context, nullOk: true);
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+  Scaffold.maybeOf(context);
+}
+''');
+  }
+
+  Future<void> test_material_Scaffold_of_matchNoCases() async {
+    setPackageContent('''
+class Scaffold {
+  static ScaffoldState of(BuildContext context) => ScaffoldState();
+  static ScaffoldState maybeOf(BuildContext context) => ScaffoldState();
+}
+class ScaffoldState {}
+class BuildContext {}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Remove nullOk'
+    date: 2020-11-04
+    element:
+      uris: ['$importUri']
+      method: 'of'
+      inClass: 'Scaffold'
+    oneOf:
+      - if: "nullOk == 'true'"
+        changes:
+          - kind: 'rename'
+            newName: 'maybeOf'
+          - kind: 'removeParameter'
+            name: 'nullOk'
+      - if: "nullOk == 'false'"
+        changes:
+          - kind: 'removeParameter'
+            name: 'nullOk'
+    variables:
+      nullOk:
+        kind: 'fragment'
+        value: 'arguments[nullOk]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+  Scaffold.of(context, nullOk: b);
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_material_Scaffold_of_matchSecondCase() async {
+    setPackageContent('''
+class Scaffold {
+  static ScaffoldState of(BuildContext context) => ScaffoldState();
+  static ScaffoldState maybeOf(BuildContext context) => ScaffoldState();
+}
+class ScaffoldState {}
+class BuildContext {}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Remove nullOk'
+    date: 2020-11-04
+    element:
+      uris: ['$importUri']
+      method: 'of'
+      inClass: 'Scaffold'
+    oneOf:
+      - if: "nullOk == 'true'"
+        changes:
+          - kind: 'rename'
+            newName: 'maybeOf'
+          - kind: 'removeParameter'
+            name: 'nullOk'
+      - if: "nullOk == 'false'"
+        changes:
+          - kind: 'removeParameter'
+            name: 'nullOk'
+    variables:
+      nullOk:
+        kind: 'fragment'
+        value: 'arguments[nullOk]'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+  Scaffold.of(context, nullOk: false);
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+  Scaffold.of(context);
+}
+''');
+  }
+
+  Future<void>
       test_material_Scaffold_resizeToAvoidBottomPadding_deprecated() async {
     setPackageContent('''
 class Scaffold {
@@ -673,10 +1075,7 @@
 ''');
   }
 
-  @failingTest
   Future<void> test_material_showDialog_deprecated() async {
-    // This test is failing because there is no way to specify that if a `child`
-    // was previously provided that a `builder` should be provided.
     setPackageContent('''
 void showDialog({
   @deprecated Widget child,
@@ -700,10 +1099,11 @@
         style: optional_named
         argumentValue:
           expression: '(context) => {% widget %}'
+          requiredIf: "widget != ''"
           variables:
             widget:
-              kind: argument
-              name: 'child'
+              kind: fragment
+              value: 'arguments[child]'
       - kind: 'removeParameter'
         name: 'child'
 ''');
@@ -723,10 +1123,7 @@
 ''');
   }
 
-  @failingTest
   Future<void> test_material_showDialog_removed() async {
-    // This test is failing because there is no way to specify that if a `child`
-    // was previously provided that a `builder` should be provided.
     setPackageContent('''
 void showDialog({
   @deprecated Widget child,
@@ -750,10 +1147,11 @@
         style: optional_named
         argumentValue:
           expression: '(context) => {% widget %}'
+          requiredIf: "widget != ''"
           variables:
             widget:
-              kind: argument
-              name: 'child'
+              kind: fragment
+              value: 'arguments[child]'
       - kind: 'removeParameter'
         name: 'child'
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
index 028cda4..30f1bce 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
@@ -946,8 +947,8 @@
               kind: ElementKindUtilities.fromName(_kind),
               components: originalComponents),
           bulkApply: false,
-          changes: [
+          changesSelector: UnconditionalChangesSelector([
             ModifyParameters(modifications: modifications),
             if (newName != null) Rename(newName: newName),
-          ]);
+          ]));
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart
index eca3df1..f892cd6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename_parameter.dart';
@@ -335,7 +336,7 @@
               kind: ElementKindUtilities.fromName(_kind),
               components: components),
           bulkApply: false,
-          changes: [
+          changesSelector: UnconditionalChangesSelector([
             RenameParameter(newName: newName, oldName: oldName),
-          ]);
+          ]));
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart
index 2578b5b..2edc72d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -1231,13 +1232,13 @@
   String get _kind;
 
   Transform _rename(List<String> components, String newName) => Transform(
-          title: 'title',
-          element: ElementDescriptor(
-              libraryUris: [Uri.parse(importUri)],
-              kind: ElementKindUtilities.fromName(_kind),
-              components: components),
-          bulkApply: false,
-          changes: [
-            Rename(newName: newName),
-          ]);
+      title: 'title',
+      element: ElementDescriptor(
+          libraryUris: [Uri.parse(importUri)],
+          kind: ElementKindUtilities.fromName(_kind),
+          components: components),
+      bulkApply: false,
+      changesSelector: UnconditionalChangesSelector([
+        Rename(newName: newName),
+      ]));
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
index ac2dccb..c36ea63 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
@@ -4,8 +4,11 @@
 
 import 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -29,7 +32,7 @@
   List<Uri> get uris => [Uri.parse('package:myPackage/test.dart')];
 
   void test_addParameter_optionalNamed() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -53,8 +56,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as AddParameter;
@@ -70,7 +74,7 @@
   }
 
   void test_addParameter_optionalPositional() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -83,13 +87,16 @@
       index: 0
       name: 'p'
       style: optional_positional
+      argumentValue:
+        expression: ''
 ''');
     var transforms = _transforms('f');
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as AddParameter;
@@ -100,7 +107,7 @@
   }
 
   void test_addParameter_requiredNamed() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -124,8 +131,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as AddParameter;
@@ -141,7 +149,7 @@
   }
 
   void test_addParameter_requiredPositional() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -165,8 +173,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as AddParameter;
@@ -182,7 +191,7 @@
   }
 
   void test_addParameter_requiredPositional_complexTemplate() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -209,8 +218,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as AddParameter;
@@ -231,7 +241,7 @@
   }
 
   void test_addTypeParameter_fromImportedName() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - date: 2020-09-03
@@ -256,8 +266,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as AddTypeParameter;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as AddTypeParameter;
     expect(change.index, 0);
     expect(change.name, 'T');
     var components = change.argumentValue.components;
@@ -268,7 +279,7 @@
   }
 
   void test_addTypeParameter_fromNamedArgument() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -292,8 +303,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as AddTypeParameter;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as AddTypeParameter;
     expect(change.index, 0);
     expect(change.name, 'T');
     expect(change.extendedType, null);
@@ -306,7 +318,7 @@
   }
 
   void test_addTypeParameter_fromPositionalArgument() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Add'
@@ -332,8 +344,53 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Add');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as AddTypeParameter;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as AddTypeParameter;
+    expect(change.index, 0);
+    expect(change.name, 'T');
+
+    var extendsComponents = change.extendedType.components;
+    expect(extendsComponents, hasLength(1));
+    expect((extendsComponents[0] as TemplateText).text, 'Object');
+
+    var argumentComponents = change.argumentValue.components;
+    expect(argumentComponents, hasLength(1));
+    var value = _accessor(argumentComponents[0]) as ArgumentAccessor;
+    var parameter = value.parameter as PositionalParameterReference;
+    expect(parameter.index, 2);
+  }
+
+  void test_addTypeParameter_fromPositionalArgument_variableInOuterScope() {
+    assertNoErrors('''
+version: 1
+transforms:
+- title: 'Add'
+  date: 2020-09-03
+  element:
+    uris:
+      - 'test.dart'
+    class: 'A'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 0
+      name: 'T'
+      extends:
+        expression: 'Object'
+      argumentValue:
+        expression: '{% t %}'
+  variables:
+    t:
+      kind: 'fragment'
+      value: 'arguments[2]'
+''');
+    var transforms = _transforms('A');
+    expect(transforms, hasLength(1));
+    var transform = transforms[0];
+    expect(transform.title, 'Add');
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as AddTypeParameter;
     expect(change.index, 0);
     expect(change.name, 'T');
 
@@ -349,7 +406,7 @@
   }
 
   void test_bulkApply() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename g'
@@ -365,7 +422,7 @@
     var transform = transforms[0];
     expect(transform.title, 'Rename g');
     expect(transform.bulkApply, false);
-    expect(transform.changes, isEmpty);
+    expect(_changes(transform), isEmpty);
   }
 
   void test_correctOffsetForPlainStrings() {
@@ -396,7 +453,7 @@
   }
 
   void test_date() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename g'
@@ -410,11 +467,11 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Rename g');
-    expect(transform.changes, isEmpty);
+    expect(_changes(transform), isEmpty);
   }
 
   void test_element_getter_inMixin() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename g'
@@ -429,11 +486,11 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Rename g');
-    expect(transform.changes, isEmpty);
+    expect(_changes(transform), isEmpty);
   }
 
   void test_element_getter_topLevel() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename g'
@@ -447,11 +504,11 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Rename g');
-    expect(transform.changes, isEmpty);
+    expect(_changes(transform), isEmpty);
   }
 
   void test_element_method_inClass() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename m'
@@ -466,11 +523,11 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Rename m');
-    expect(transform.changes, isEmpty);
+    expect(_changes(transform), isEmpty);
   }
 
   void test_element_variable() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename v'
@@ -484,32 +541,30 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Rename v');
-    expect(transform.changes, isEmpty);
+    expect(_changes(transform), isEmpty);
   }
 
   void test_incomplete() {
-    parse('''
+    assertErrors('''
 version: 1
 transforms:
-''');
-    expect(result, null);
-    errorListener.assertErrors([
+''', [
       error(TransformSetErrorCode.invalidValue, 21, 0),
     ]);
+    expect(result, null);
   }
 
   void test_invalidYaml() {
-    parse('''
+    assertErrors('''
 [
-''');
-    expect(result, null);
-    errorListener.assertErrors([
+''', [
       error(TransformSetErrorCode.yamlSyntaxError, 2, 0),
     ]);
+    expect(result, null);
   }
 
   void test_removeParameter_named() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Remove'
@@ -525,8 +580,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Remove');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as RemoveParameter;
@@ -535,7 +591,7 @@
   }
 
   void test_removeParameter_positional() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Remove'
@@ -551,8 +607,9 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Remove');
-    expect(transform.changes, hasLength(1));
-    var change = transform.changes[0] as ModifyParameters;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
     var modifications = change.modifications;
     expect(modifications, hasLength(1));
     var modification = modifications[0] as RemoveParameter;
@@ -561,7 +618,7 @@
   }
 
   void test_rename() {
-    parse('''
+    assertNoErrors('''
 version: 1
 transforms:
 - title: 'Rename A'
@@ -578,15 +635,99 @@
     expect(transforms, hasLength(1));
     var transform = transforms[0];
     expect(transform.title, 'Rename A');
-    expect(transform.changes, hasLength(1));
-    var rename = transform.changes[0] as Rename;
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var rename = changes[0] as Rename;
     expect(rename.newName, 'B');
   }
 
+  void test_rename_oneOf() {
+    assertNoErrors('''
+version: 1
+transforms:
+- title: 'Rename A'
+  date: 2020-08-21
+  element:
+    uris:
+      - 'test.dart'
+    class: 'A'
+  oneOf:
+    - if: "'a' == 'b'"
+      changes:
+        - kind: 'rename'
+          newName: 'B'
+''');
+    var transforms = _transforms('A');
+    expect(transforms, hasLength(1));
+    var transform = transforms[0];
+    expect(transform.title, 'Rename A');
+    var selector = transform.changesSelector as ConditionalChangesSelector;
+    var changeMap = selector.changeMap;
+    expect(changeMap, hasLength(1));
+    var condition = changeMap.keys.first as BinaryExpression;
+    expect((condition.leftOperand as LiteralString).value, 'a');
+    expect(condition.operator, Operator.equal);
+    expect((condition.rightOperand as LiteralString).value, 'b');
+    var changes = changeMap[condition];
+    expect(changes, hasLength(1));
+    var rename = changes[0] as Rename;
+    expect(rename.newName, 'B');
+  }
+
+  void test_requiredIf() {
+    assertNoErrors('''
+version: 1
+transforms:
+- title: 'Add'
+  date: 2020-09-09
+  element:
+    uris: ['test.dart']
+    function: 'f'
+  changes:
+    - kind: 'addParameter'
+      index: 0
+      name: 'p'
+      style: optional_named
+      argumentValue:
+        expression: '{% p %}'
+        requiredIf: "p != ''"
+        variables:
+          p:
+            kind: 'fragment'
+            value: 'arguments[1]'
+''');
+    var transforms = _transforms('f');
+    expect(transforms, hasLength(1));
+    var transform = transforms[0];
+    expect(transform.title, 'Add');
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ModifyParameters;
+    var modifications = change.modifications;
+    expect(modifications, hasLength(1));
+    var modification = modifications[0] as AddParameter;
+    expect(modification.index, 0);
+    expect(modification.name, 'p');
+    expect(modification.isRequired, false);
+    expect(modification.isPositional, false);
+    var argumentValue = modification.argumentValue;
+    expect(argumentValue.requiredIfCondition, isNotNull);
+    var components = argumentValue.components;
+    expect(components, hasLength(1));
+    var value = _accessor(components[0]) as ArgumentAccessor;
+    var parameter = value.parameter as PositionalParameterReference;
+    expect(parameter.index, 1);
+  }
+
   /// Return the first accessor from the given [component].
   Accessor _accessor(TemplateComponent component) =>
       ((component as TemplateVariable).generator as CodeFragment).accessors[0];
 
+  /// Assuming that the [transform] has a single list of changes associated with
+  /// it, return the list of changes.
+  List<Change> _changes(Transform transform) =>
+      (transform.changesSelector as UnconditionalChangesSelector).changes;
+
   ElementMatcher _matcher(String name) =>
       ElementMatcher(importedUris: uris, name: name);
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart
index 789ef46..af3b094 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart
@@ -18,12 +18,16 @@
   /// The result of parsing the test file's content.
   TransformSet result;
 
-  Future<void> assertErrors(
-      String code, List<ExpectedError> expectedErrors) async {
+  void assertErrors(String code, List<ExpectedError> expectedErrors) {
     parse(code);
     errorListener.assertErrors(expectedErrors);
   }
 
+  void assertNoErrors(String content) {
+    parse(content);
+    errorListener.assertNoErrors();
+  }
+
   ExpectedError error(ErrorCode code, int offset, int length,
           {String text,
           Pattern messageContains,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index b474c5a..0900c1b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -7,10 +7,9 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/error/lint_codes.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/test_utilities/platform.dart';
@@ -39,8 +38,11 @@
   }
 
   @override
-  void _createAnalysisOptionsFile() {
-    createAnalysisOptionsFile(experiments: experiments, lints: [lintCode]);
+  void setUp() {
+    super.setUp();
+    createAnalysisOptionsFile(
+      lints: [lintCode],
+    );
   }
 }
 
@@ -57,10 +59,6 @@
   /// neither [assertHasFix] nor [assertHasFixAllFix] has been invoked.
   String resultCode;
 
-  /// Return a list of the experiments that are to be enabled for tests in this
-  /// class, or `null` if there are no experiments that should be enabled.
-  List<String> get experiments => null;
-
   /// Return the kind of fixes being tested by this test class.
   FixKind get kind;
 
@@ -165,7 +163,6 @@
     super.setUp();
     verifyNoTestUnitErrors = false;
     useLineEndingsForPlatform = true;
-    _createAnalysisOptionsFile();
   }
 
   /// Computes fixes and verifies that there is a fix for the given [error] of the appropriate kind.
@@ -277,6 +274,7 @@
     tracker.addContext(analysisContext);
 
     var context = DartFixContextImpl(
+      InstrumentationService.NULL_SERVICE,
       workspace,
       testAnalysisResult,
       error,
@@ -289,12 +287,6 @@
     return await DartFixContributor().computeFixes(context);
   }
 
-  /// Create the analysis options file needed in order to correctly analyze the
-  /// test file.
-  void _createAnalysisOptionsFile() {
-    createAnalysisOptionsFile(experiments: experiments);
-  }
-
   /// Find the error that is to be fixed by computing the errors in the file,
   /// using the [errorFilter] to filter out errors that should be ignored, and
   /// expecting that there is a single remaining error. The error filter should
@@ -347,16 +339,14 @@
   String get lintCode;
 
   @override
-  String get testPackageLanguageVersion =>
-      Feature.non_nullable.isEnabledByDefault ? '2.12' : '2.11';
+  String get testPackageLanguageVersion => '2.12';
 
-  /// TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-  /// Remove when Null Safety is enabled by default.
   @nonVirtual
   @override
   void setUp() {
     super.setUp();
     createAnalysisOptionsFile(
-        experiments: [EnableString.non_nullable], lints: [lintCode]);
+      lints: [lintCode],
+    );
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
index 62618ac..3fd394e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../abstract_context.dart';
 import 'fix_processor.dart';
 
 void main() {
@@ -140,10 +140,8 @@
 }
 
 @reflectiveTest
-class RemoveDeadCodeWithNullSafetyTest extends FixProcessorTest {
-  @override
-  List<String> get experiments => [EnableString.non_nullable];
-
+class RemoveDeadCodeWithNullSafetyTest extends FixProcessorTest
+    with WithNullSafetyMixin {
   @override
   FixKind get kind => DartFixKind.REMOVE_DEAD_CODE;
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
index d069876..422034e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
@@ -74,6 +74,21 @@
 ''');
   }
 
+  Future<void> test_generic_instanceCreation_cascade() async {
+    await resolveTestCode('''
+Set f() {
+  Set<String> s = Set<String>()..addAll([]);
+  return s;
+}
+''');
+    await assertHasFix('''
+Set f() {
+  var s = Set<String>()..addAll([]);
+  return s;
+}
+''');
+  }
+
   Future<void> test_generic_instanceCreation_withArguments() async {
     await resolveTestCode('''
 C<int> f() {
@@ -193,6 +208,21 @@
     await assertNoFix();
   }
 
+  Future<void> test_generic_setLiteral_cascade() async {
+    await resolveTestCode('''
+Set f() {
+  Set<String> s = {}..addAll([]);
+  return s;
+}
+''');
+    await assertHasFix('''
+Set f() {
+  var s = <String>{}..addAll([]);
+  return s;
+}
+''');
+  }
+
   Future<void> test_generic_setLiteral_const() async {
     await resolveTestCode('''
 String f() {
diff --git a/pkg/analysis_server/test/src/utilities/mock_packages.dart b/pkg/analysis_server/test/src/utilities/mock_packages.dart
index 2bfb8d4..c60002d 100644
--- a/pkg/analysis_server/test/src/utilities/mock_packages.dart
+++ b/pkg/analysis_server/test/src/utilities/mock_packages.dart
@@ -5,8 +5,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-
-import '../../utils/package_root.dart' as package_root;
+import 'package:analyzer_utilities/package_root.dart' as package_root;
 
 /// Helper for copying files from "tests/mock_packages" to memory file system.
 class MockPackages {
diff --git a/pkg/analysis_server/test/stress/completion/completion_runner.dart b/pkg/analysis_server/test/stress/completion/completion_runner.dart
index 3f69cff..7a1d675 100644
--- a/pkg/analysis_server/test/stress/completion/completion_runner.dart
+++ b/pkg/analysis_server/test/stress/completion/completion_runner.dart
@@ -97,8 +97,7 @@
           }
 
           timer.start();
-          var request =
-              CompletionRequestImpl(result, offset, false, statistics);
+          var request = CompletionRequestImpl(result, offset, statistics);
           var suggestions = await request.performance.runRequestOperation(
             (performance) async {
               return await contributor.computeSuggestions(
diff --git a/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart b/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart
index 0c4b3e1..5da637c 100644
--- a/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart
+++ b/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:test/test.dart';
 
-import '../../../tool/completion_metrics/metrics_util.dart';
+import '../../../tool/code_completion/metrics_util.dart';
 
 void main() {
   group('ArithmeticMeanComputer', () {
diff --git a/pkg/analysis_server/test/verify_sorted_test.dart b/pkg/analysis_server/test/verify_sorted_test.dart
index 858f7c4..60fda8d 100644
--- a/pkg/analysis_server/test/verify_sorted_test.dart
+++ b/pkg/analysis_server/test/verify_sorted_test.dart
@@ -10,11 +10,10 @@
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer_utilities/package_root.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
-import 'utils/package_root.dart';
-
 void main() {
   group('analysis_server', () {
     buildTestsForAnalysisServer();
diff --git a/pkg/analysis_server/test/verify_tests_test.dart b/pkg/analysis_server/test/verify_tests_test.dart
index 573eb05..4b07a76 100644
--- a/pkg/analysis_server/test/verify_tests_test.dart
+++ b/pkg/analysis_server/test/verify_tests_test.dart
@@ -2,87 +2,42 @@
 // for details. All 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/analysis_context_collection.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/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-import 'utils/package_root.dart' as package_root;
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:analyzer_utilities/verify_tests.dart';
 
 void main() {
   var provider = PhysicalResourceProvider.INSTANCE;
   var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
-  var analysisServerPath =
-      provider.pathContext.join(packageRoot, 'analysis_server');
-  var testDirPath = provider.pathContext.join(analysisServerPath, 'test');
-  var mocksDirPath = provider.pathContext.join(testDirPath, 'mock_packages');
-
-  var collection = AnalysisContextCollection(
-    resourceProvider: provider,
-    includedPaths: <String>[testDirPath],
-    excludedPaths: <String>[mocksDirPath],
-  );
-  var contexts = collection.contexts;
-  if (contexts.length != 1) {
-    fail('The test directory contains multiple analysis contexts.');
-  }
-
-  buildTestsIn(
-      contexts[0].currentSession, testDirPath, provider.getFolder(testDirPath));
+  var pathToAnalyze = provider.pathContext.join(packageRoot, 'analysis_server');
+  var testDirPath = provider.pathContext.join(pathToAnalyze, 'test');
+  _VerifyTests(testDirPath, excludedPaths: [
+    (provider.pathContext.join(testDirPath, 'mock_packages'))
+  ]).build();
 }
 
-void buildTestsIn(
-    AnalysisSession session, String testDirPath, Folder directory) {
-  var testFileNames = <String>[];
-  File testAllFile;
-  var children = directory.getChildren();
-  children.sort((first, second) => first.shortName.compareTo(second.shortName));
-  for (var child in children) {
-    if (child is Folder) {
-      if (child.shortName != 'integration' &&
-          child.getChildAssumingFile('test_all.dart').exists) {
-        testFileNames.add('${child.shortName}/test_all.dart');
-      }
-      buildTestsIn(session, testDirPath, child);
-    } else if (child is File) {
-      var name = child.shortName;
-      if (name == 'test_all.dart') {
-        testAllFile = child;
-      } else if (name.endsWith('_test.dart')) {
-        testFileNames.add(name);
-      }
+class _VerifyTests extends VerifyTests {
+  _VerifyTests(String testDirPath, {List<String> excludedPaths})
+      : super(testDirPath, excludedPaths: excludedPaths);
+
+  @override
+  bool isExpensive(Resource resource) => resource.shortName == 'integration';
+
+  @override
+  bool isOkAsAdditionalTestAllImport(Folder folder, String uri) {
+    if (folder.path == folder.provider.pathContext.join(testDirPath, 'lsp') &&
+        uri == '../src/lsp/lsp_packet_transformer_test.dart') {
+      // `lsp/test_all.dart` also runs this one test in `lsp/src` for
+      // convenience.
+      return true;
     }
+    if (folder.path == testDirPath &&
+        uri == '../tool/spec/check_all_test.dart') {
+      // The topmost `test_all.dart` also runs this one test in `tool` for
+      // convenience.
+      return true;
+    }
+    return super.isOkAsAdditionalTestAllImport(folder, uri);
   }
-  var relativePath = path.relative(directory.path, from: testDirPath);
-  test(relativePath, () {
-    if (testFileNames.isEmpty) {
-      return;
-    }
-    if (testAllFile == null) {
-      fail('Missing "test_all.dart" in $relativePath');
-    }
-    var result = session.getParsedUnit(testAllFile.path);
-    if (result.state != ResultState.VALID) {
-      fail('Could not parse ${testAllFile.path}');
-    }
-    var importedFiles = <String>[];
-    for (var directive in result.unit.directives) {
-      if (directive is ImportDirective) {
-        importedFiles.add(directive.uri.stringValue);
-      }
-    }
-    var missingFiles = <String>[];
-    for (var testFileName in testFileNames) {
-      if (!importedFiles.contains(testFileName)) {
-        missingFiles.add(testFileName);
-      }
-    }
-    if (missingFiles.isNotEmpty) {
-      fail('Tests missing from "test_all.dart": ${missingFiles.join(', ')}');
-    }
-  });
 }
diff --git a/pkg/analysis_server/tool/completion_metrics/code_metrics.dart b/pkg/analysis_server/tool/code_completion/code_metrics.dart
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/code_metrics.dart
rename to pkg/analysis_server/tool/code_completion/code_metrics.dart
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
new file mode 100644
index 0000000..1d1665c
--- /dev/null
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -0,0 +1,1386 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io' as io;
+import 'dart:math' as math;
+
+import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart'
+    show
+        ClassElement,
+        Element,
+        ExtensionElement,
+        ClassMemberElement,
+        ExecutableElement,
+        FieldElement,
+        VariableElement;
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/error/error.dart' as err;
+import 'package:analyzer/file_system/overlay_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' show ElementKind;
+import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
+import 'package:args/args.dart';
+import 'package:meta/meta.dart';
+
+import 'metrics_util.dart';
+import 'output_utilities.dart';
+import 'visitors.dart';
+
+Future<void> main(List<String> args) async {
+  var parser = createArgParser();
+  var result = parser.parse(args);
+
+  if (!validArguments(parser, result)) {
+    return io.exit(1);
+  }
+
+  var options = CompletionMetricsOptions(
+      availableSuggestions: result[AVAILABLE_SUGGESTIONS],
+      overlay: result[OVERLAY],
+      printMissedCompletionDetails: result[PRINT_MISSED_COMPLETION_DETAILS],
+      printMissedCompletionSummary: result[PRINT_MISSED_COMPLETION_SUMMARY],
+      printMissingInformation: result[PRINT_MISSING_INFORMATION],
+      printMrrByLocation: result[PRINT_MRR_BY_LOCATION],
+      printSlowestResults: result[PRINT_SLOWEST_RESULTS],
+      printWorstResults: result[PRINT_WORST_RESULTS]);
+  var root = result.rest[0];
+  print('Analyzing root: "$root"');
+  var stopwatch = Stopwatch()..start();
+  var code = await CompletionMetricsComputer(root, options).compute();
+  stopwatch.stop();
+
+  var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
+  print('');
+  print('Metrics computed in $duration');
+  return io.exit(code);
+}
+
+const String AVAILABLE_SUGGESTIONS = 'available-suggestions';
+
+/// An option to control whether and how overlays should be produced.
+const String OVERLAY = 'overlay';
+
+/// A mode indicating that no overlays should be produced.
+const String OVERLAY_NONE = 'none';
+
+/// A mode indicating that everything from the completion offset to the end of
+/// the file should be removed.
+const String OVERLAY_REMOVE_REST_OF_FILE = 'remove-rest-of-file';
+
+/// A mode indicating that the token whose offset is the same as the
+/// completion offset should be removed.
+const String OVERLAY_REMOVE_TOKEN = 'remove-token';
+
+/// A flag that causes detailed information to be printed every time a
+/// completion request fails to produce a suggestions matching the expected
+/// suggestion.
+const String PRINT_MISSED_COMPLETION_DETAILS =
+    'print-missed-completion-details';
+
+/// A flag that causes summary information to be printed about the times that a
+/// completion request failed to produce a suggestions matching the expected
+/// suggestion.
+const String PRINT_MISSED_COMPLETION_SUMMARY =
+    'print-missed-completion-summary';
+
+/// A flag that causes information to be printed about places where no
+/// completion location was computed and about information that's missing in the
+/// completion tables.
+const String PRINT_MISSING_INFORMATION = 'print-missing-information';
+
+/// A flag that causes information to be printed about the mrr score achieved at
+/// each completion location.
+const String PRINT_MRR_BY_LOCATION = 'print-mrr-by-location';
+
+/// A flag that causes information to be printed about the completion requests
+/// that were the slowest to return suggestions.
+const String PRINT_SLOWEST_RESULTS = 'print-slowest-results';
+
+/// A flag that causes information to be printed about the completion requests
+/// that had the worst mrr scores.
+const String PRINT_WORST_RESULTS = 'print-worst-results';
+
+/// A [Counter] to track the performance of each of the completion strategies
+/// that are being compared.
+Counter rankComparison = Counter('relevance rank comparison');
+
+/// Create a parser that can be used to parse the command-line arguments.
+ArgParser createArgParser() {
+  return ArgParser()
+    ..addFlag(AVAILABLE_SUGGESTIONS,
+        abbr: 'a',
+        help:
+            'Use the available suggestions feature in the Analysis Server when '
+            'computing the set of code completions. With this feature enabled, '
+            'completion will match the support in the Dart Plugin for '
+            'IntelliJ, without this enabled the completion support matches the '
+            'support in LSP.',
+        defaultsTo: false,
+        negatable: false)
+    ..addOption(
+      'help',
+      abbr: 'h',
+      help: 'Print this help message.',
+    )
+    ..addOption(OVERLAY,
+        allowed: [
+          OVERLAY_NONE,
+          OVERLAY_REMOVE_TOKEN,
+          OVERLAY_REMOVE_REST_OF_FILE
+        ],
+        defaultsTo: OVERLAY_NONE,
+        help:
+            'Before attempting a completion at the location of each token, the '
+            'token can be removed, or the rest of the file can be removed to '
+            'test code completion with diverse methods. The default mode is to '
+            'complete at the start of the token without modifying the file.')
+    ..addFlag(PRINT_MISSED_COMPLETION_DETAILS,
+        defaultsTo: false,
+        help:
+            'Print detailed information every time a completion request fails '
+            'to produce a suggestions matching the expected suggestion.',
+        negatable: false)
+    ..addFlag(PRINT_MISSED_COMPLETION_SUMMARY,
+        defaultsTo: false,
+        help: 'Print summary information about the times that a completion '
+            'request failed to produce a suggestions matching the expected '
+            'suggestion.',
+        negatable: false)
+    ..addFlag(PRINT_MISSING_INFORMATION,
+        defaultsTo: false,
+        help: 'Print information about places where no completion location was '
+            'computed and about information that is missing in the completion '
+            'tables.',
+        negatable: false)
+    ..addFlag(PRINT_MRR_BY_LOCATION,
+        defaultsTo: false,
+        help:
+            'Print information about the mrr score achieved at each completion '
+            'location. This can help focus efforts to improve the overall '
+            'score by pointing out the locations that are causing the biggest '
+            'impact.',
+        negatable: false)
+    ..addFlag(PRINT_SLOWEST_RESULTS,
+        defaultsTo: false,
+        help: 'Print information about the completion requests that were the '
+            'slowest to return suggestions.',
+        negatable: false)
+    ..addFlag(PRINT_WORST_RESULTS,
+        defaultsTo: false,
+        help:
+            'Print information about the completion requests that had the worst '
+            'mrr scores.',
+        negatable: false);
+}
+
+/// Print usage information for this tool.
+void printUsage(ArgParser parser, {String error}) {
+  if (error != null) {
+    print(error);
+    print('');
+  }
+  print('usage: dart completion_metrics.dart [options] packagePath');
+  print('');
+  print('Compute code completion health metrics.');
+  print('');
+  print(parser.usage);
+}
+
+/// Return `true` if the command-line arguments (represented by the [result] and
+/// parsed by the [parser]) are valid.
+bool validArguments(ArgParser parser, ArgResults result) {
+  if (result.wasParsed('help')) {
+    printUsage(parser);
+    return false;
+  } else if (result.rest.length != 1) {
+    printUsage(parser, error: 'No package path specified.');
+    return false;
+  }
+  var rootPath = result.rest[0];
+  if (!io.Directory(rootPath).existsSync()) {
+    printUsage(parser, error: 'The directory "$rootPath" does not exist.');
+    return false;
+  }
+  return true;
+}
+
+/// An indication of the group in which the completion falls for the purposes of
+/// subdividing the results.
+enum CompletionGroup {
+  instanceMember,
+  staticMember,
+  typeReference,
+  localReference,
+  paramReference,
+  topLevel
+}
+
+/// A wrapper for the collection of [Counter] and [MeanReciprocalRankComputer]
+/// objects for a run of [CompletionMetricsComputer].
+class CompletionMetrics {
+  /// The maximum number of slowest results to collect.
+  static const maxSlowestResults = 5;
+
+  /// The maximum number of worst results to collect.
+  static const maxWorstResults = 5;
+
+  /// The name associated with this set of metrics.
+  final String name;
+
+  /// The function to be executed when this metrics collector is enabled.
+  final void Function() enableFunction;
+
+  /// The function to be executed when this metrics collector is disabled.
+  final void Function() disableFunction;
+
+  Counter completionCounter = Counter('successful/ unsuccessful completions');
+
+  Counter completionMissedTokenCounter =
+      Counter('unsuccessful completion token counter');
+
+  Counter completionKindCounter =
+      Counter('unsuccessful completion kind counter');
+
+  Counter completionElementKindCounter =
+      Counter('unsuccessful completion element kind counter');
+
+  ArithmeticMeanComputer meanCompletionMS =
+      ArithmeticMeanComputer('ms per completion');
+
+  MeanReciprocalRankComputer mrrComputer =
+      MeanReciprocalRankComputer('successful/ unsuccessful completions');
+
+  MeanReciprocalRankComputer successfulMrrComputer =
+      MeanReciprocalRankComputer('successful completions');
+
+  MeanReciprocalRankComputer instanceMemberMrrComputer =
+      MeanReciprocalRankComputer('instance member completions');
+
+  MeanReciprocalRankComputer staticMemberMrrComputer =
+      MeanReciprocalRankComputer('static member completions');
+
+  MeanReciprocalRankComputer typeRefMrrComputer =
+      MeanReciprocalRankComputer('type reference completions');
+
+  MeanReciprocalRankComputer localRefMrrComputer =
+      MeanReciprocalRankComputer('local reference completions');
+
+  MeanReciprocalRankComputer paramRefMrrComputer =
+      MeanReciprocalRankComputer('param reference completions');
+
+  MeanReciprocalRankComputer topLevelMrrComputer =
+      MeanReciprocalRankComputer('non-type member completions');
+
+  Map<String, MeanReciprocalRankComputer> locationMrrComputers = {};
+
+  ArithmeticMeanComputer charsBeforeTop =
+      ArithmeticMeanComputer('chars_before_top');
+
+  ArithmeticMeanComputer charsBeforeTopFive =
+      ArithmeticMeanComputer('chars_before_top_five');
+
+  ArithmeticMeanComputer insertionLengthTheoretical =
+      ArithmeticMeanComputer('insertion_length_theoretical');
+
+  /// The places in which a completion location was requested when none was
+  /// available.
+  Set<String> missingCompletionLocations = {};
+
+  /// The completion locations for which no relevance table was available.
+  Set<String> missingCompletionLocationTables = {};
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks for completing to instance members.
+  List<CompletionResult> instanceMemberWorstResults = [];
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks for completing to static members.
+  List<CompletionResult> staticMemberWorstResults = [];
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks for completing to type references.
+  List<CompletionResult> typeRefWorstResults = [];
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks for completing to local references.
+  List<CompletionResult> localRefWorstResults = [];
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks for completing to parameter references.
+  List<CompletionResult> paramRefWorstResults = [];
+
+  /// A list of the top [maxWorstResults] completion results with the highest
+  /// (worst) ranks for completing to top-level declarations.
+  List<CompletionResult> topLevelWorstResults = [];
+
+  /// A list of the top [maxSlowestResults] completion results that took the
+  /// longest top compute for instance members.
+  List<CompletionResult> instanceMemberSlowestResults = [];
+
+  /// A list of the top [maxSlowestResults] completion results that took the
+  /// longest top compute for static members.
+  List<CompletionResult> staticMemberSlowestResults = [];
+
+  /// A list of the top [maxSlowestResults] completion results that took the
+  /// longest top compute for type references.
+  List<CompletionResult> typeRefSlowestResults = [];
+
+  /// A list of the top [maxSlowestResults] completion results that took the
+  /// longest top compute for local references.
+  List<CompletionResult> localRefSlowestResults = [];
+
+  /// A list of the top [maxSlowestResults] completion results that took the
+  /// longest top compute for parameter references.
+  List<CompletionResult> paramRefSlowestResults = [];
+
+  /// A list of the top [maxSlowestResults] completion results that took the
+  /// longest top compute for top-level declarations.
+  List<CompletionResult> topLevelSlowestResults = [];
+
+  CompletionMetrics(this.name, this.enableFunction, this.disableFunction);
+
+  /// Perform any operations required in order to revert computing the kind of
+  /// completions represented by this metrics collector.
+  void disable() {
+    if (disableFunction != null) {
+      disableFunction();
+    }
+  }
+
+  /// Perform any initialization required in order to compute the kind of
+  /// completions represented by this metrics collector.
+  void enable() {
+    if (enableFunction != null) {
+      enableFunction();
+    }
+  }
+
+  /// Record this completion result, this method handles the worst ranked items
+  /// as well as the longest sets of results to compute.
+  void recordCompletionResult(CompletionResult result) {
+    _recordTime(result);
+    _recordMrr(result);
+    _recordWorstResult(result);
+    _recordSlowestResult(result);
+    _recordMissingInformation(result);
+  }
+
+  /// If the completion location was requested but missing when computing the
+  /// [result], then record where that happened.
+  void _recordMissingInformation(CompletionResult result) {
+    var location = result.listener?.missingCompletionLocation;
+    if (location != null) {
+      missingCompletionLocations.add(location);
+    } else {
+      location = result.listener?.missingCompletionLocationTable;
+      if (location != null) {
+        missingCompletionLocationTables.add(location);
+      }
+    }
+  }
+
+  /// Record the MRR for the [result].
+  void _recordMrr(CompletionResult result) {
+    var rank = result.place.rank;
+    // Record globally.
+    successfulMrrComputer.addRank(rank);
+    // Record by group.
+    switch (result.group) {
+      case CompletionGroup.instanceMember:
+        instanceMemberMrrComputer.addRank(rank);
+        break;
+      case CompletionGroup.staticMember:
+        staticMemberMrrComputer.addRank(rank);
+        break;
+      case CompletionGroup.typeReference:
+        typeRefMrrComputer.addRank(rank);
+        break;
+      case CompletionGroup.localReference:
+        localRefMrrComputer.addRank(rank);
+        break;
+      case CompletionGroup.paramReference:
+        paramRefMrrComputer.addRank(rank);
+        break;
+      case CompletionGroup.topLevel:
+        topLevelMrrComputer.addRank(rank);
+        break;
+    }
+    // Record by completion location.
+    var location = result.completionLocation;
+    if (location != null) {
+      var computer = locationMrrComputers.putIfAbsent(
+          location, () => MeanReciprocalRankComputer(location));
+      computer.addRank(rank);
+    }
+  }
+
+  /// If the [result] is took longer than any previously recorded results,
+  /// record it.
+  void _recordSlowestResult(CompletionResult result) {
+    List<CompletionResult> getSlowestResults() {
+      switch (result.group) {
+        case CompletionGroup.instanceMember:
+          return instanceMemberSlowestResults;
+        case CompletionGroup.staticMember:
+          return staticMemberSlowestResults;
+        case CompletionGroup.typeReference:
+          return typeRefSlowestResults;
+        case CompletionGroup.localReference:
+          return localRefSlowestResults;
+        case CompletionGroup.paramReference:
+          return paramRefSlowestResults;
+        case CompletionGroup.topLevel:
+          return topLevelSlowestResults;
+      }
+      return const <CompletionResult>[];
+    }
+
+    var slowestResults = getSlowestResults();
+    if (slowestResults.length >= maxSlowestResults) {
+      if (result.elapsedMS <= slowestResults.last.elapsedMS) {
+        return;
+      }
+      slowestResults.removeLast();
+    }
+    slowestResults.add(result);
+    slowestResults.sort((first, second) => second.elapsedMS - first.elapsedMS);
+  }
+
+  /// Record this elapsed ms count for the average ms count.
+  void _recordTime(CompletionResult result) {
+    meanCompletionMS.addValue(result.elapsedMS);
+  }
+
+  /// If the [result] is worse than any previously recorded results, record it.
+  void _recordWorstResult(CompletionResult result) {
+    List<CompletionResult> getWorstResults() {
+      switch (result.group) {
+        case CompletionGroup.instanceMember:
+          return instanceMemberWorstResults;
+        case CompletionGroup.staticMember:
+          return staticMemberWorstResults;
+        case CompletionGroup.typeReference:
+          return typeRefWorstResults;
+        case CompletionGroup.localReference:
+          return localRefWorstResults;
+        case CompletionGroup.paramReference:
+          return paramRefWorstResults;
+        case CompletionGroup.topLevel:
+          return topLevelWorstResults;
+      }
+      return const <CompletionResult>[];
+    }
+
+    var worstResults = getWorstResults();
+    if (worstResults.length >= maxWorstResults) {
+      if (result.place.rank <= worstResults.last.place.rank) {
+        return;
+      }
+      worstResults.removeLast();
+    }
+    worstResults.add(result);
+    worstResults.sort((first, second) => second.place.rank - first.place.rank);
+  }
+}
+
+/// This is the main metrics computer class for code completions. After the
+/// object is constructed, [computeCompletionMetrics] is executed to do analysis
+/// and print a summary of the metrics gathered from the completion tests.
+class CompletionMetricsComputer {
+  final String rootPath;
+
+  final CompletionMetricsOptions options;
+
+  ResolvedUnitResult _resolvedUnitResult;
+
+  /// The int to be returned from the [compute] call.
+  int resultCode;
+
+  /// A list of the metrics to be computed.
+  final List<CompletionMetrics> targetMetrics = [];
+
+  final OverlayResourceProvider _provider =
+      OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
+
+  int overlayModificationStamp = 0;
+
+  CompletionMetricsComputer(this.rootPath, this.options);
+
+  Future<int> compute() async {
+    resultCode = 0;
+    // To compare two or more changes to completions, add a `CompletionMetrics`
+    // object with enable and disable functions to the list of `targetMetrics`.
+    targetMetrics.add(CompletionMetrics('shipping', null, null));
+    final collection = AnalysisContextCollection(
+      includedPaths: [rootPath],
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
+    );
+    for (var context in collection.contexts) {
+      await _computeInContext(context.contextRoot);
+    }
+    printComparison();
+    for (var metrics in targetMetrics) {
+      printMetrics(metrics);
+
+      print('');
+      print('====================');
+      rankComparison.printCounterValues();
+      print('====================');
+
+      if (options.printMissingInformation) {
+        printMissingInformation(metrics);
+      }
+      if (options.printSlowestResults) {
+        printSlowestResults(metrics);
+      }
+      if (options.printWorstResults) {
+        printWorstResults(metrics);
+      }
+    }
+    return resultCode;
+  }
+
+  int forEachExpectedCompletion(
+      CompletionRequestImpl request,
+      MetricsSuggestionListener listener,
+      ExpectedCompletion expectedCompletion,
+      String completionLocation,
+      List<protocol.CompletionSuggestion> suggestions,
+      CompletionMetrics metrics,
+      int elapsedMS,
+      bool doPrintMissedCompletions) {
+    assert(suggestions != null);
+
+    var place = placementInSuggestionList(suggestions, expectedCompletion);
+
+    metrics.mrrComputer.addRank(place.rank);
+
+    if (place.denominator != 0) {
+      metrics.completionCounter.count('successful');
+
+      metrics.recordCompletionResult(CompletionResult(place, request, listener,
+          suggestions, expectedCompletion, completionLocation, elapsedMS));
+
+      var charsBeforeTop =
+          _computeCharsBeforeTop(expectedCompletion, suggestions);
+      metrics.charsBeforeTop.addValue(charsBeforeTop);
+      metrics.charsBeforeTopFive.addValue(
+          _computeCharsBeforeTop(expectedCompletion, suggestions, minRank: 5));
+      metrics.insertionLengthTheoretical
+          .addValue(expectedCompletion.completion.length - charsBeforeTop);
+
+      return place.rank;
+    } else {
+      metrics.completionCounter.count('unsuccessful');
+
+      metrics.completionMissedTokenCounter.count(expectedCompletion.completion);
+      metrics.completionKindCounter.count(expectedCompletion.kind.toString());
+      metrics.completionElementKindCounter
+          .count(expectedCompletion.elementKind.toString());
+
+      if (doPrintMissedCompletions) {
+        protocol.CompletionSuggestion closeMatchSuggestion;
+        for (var suggestion in suggestions) {
+          if (suggestion.completion == expectedCompletion.completion) {
+            closeMatchSuggestion = suggestion;
+          }
+        }
+
+        print('missing completion (${metrics.name}):');
+        print('$expectedCompletion');
+        if (closeMatchSuggestion != null) {
+          print('    close matching completion that was in the list:');
+          print('    $closeMatchSuggestion');
+        }
+        print('');
+      }
+
+      return -1;
+    }
+  }
+
+  void printComparison() {
+    List<String> toRow(Iterable<MeanReciprocalRankComputer> computers) {
+      return [
+        computers.first.name,
+        for (var computer in computers) (1 / computer.mrr).toStringAsFixed(3),
+      ];
+    }
+
+    var buffer = StringBuffer();
+    var table = [
+      ['', for (var metrics in targetMetrics) metrics.name],
+      toRow(targetMetrics.map((metrics) => metrics.mrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.successfulMrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.instanceMemberMrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.staticMemberMrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.typeRefMrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.localRefMrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.paramRefMrrComputer)),
+      toRow(targetMetrics.map((metrics) => metrics.topLevelMrrComputer)),
+    ];
+    for (var i = 1; i < table[0].length; i++) {
+      rightJustifyColumn(i, table);
+    }
+    buffer.writeTable(table);
+
+    print('');
+    print('Comparison of inverse mean reciprocal ranks (lower is better)');
+    print('');
+    print(buffer.toString());
+  }
+
+  void printMetrics(CompletionMetrics metrics) {
+    print('====================');
+    print('Completion metrics for ${metrics.name}:');
+    print('');
+    if (options.printMissedCompletionSummary) {
+      metrics.completionMissedTokenCounter.printCounterValues();
+      print('');
+
+      metrics.completionKindCounter.printCounterValues();
+      print('');
+
+      metrics.completionElementKindCounter.printCounterValues();
+      print('');
+    }
+
+    List<String> toRow(MeanReciprocalRankComputer computer) {
+      return [
+        computer.name,
+        computer.mrr.toStringAsFixed(6),
+        (1 / computer.mrr).toStringAsFixed(3),
+        computer.mrr_5.toStringAsFixed(6),
+        (1 / computer.mrr_5).toStringAsFixed(3),
+        computer.count.toString(),
+      ];
+    }
+
+    var buffer = StringBuffer();
+    var table = [
+      ['', 'mrr', 'inverse mrr', 'mrr_5', 'inverse mrr_5', 'count'],
+      toRow(metrics.mrrComputer),
+      toRow(metrics.successfulMrrComputer),
+      toRow(metrics.instanceMemberMrrComputer),
+      toRow(metrics.staticMemberMrrComputer),
+      toRow(metrics.typeRefMrrComputer),
+      toRow(metrics.localRefMrrComputer),
+      toRow(metrics.paramRefMrrComputer),
+      toRow(metrics.topLevelMrrComputer),
+    ];
+    rightJustifyColumn(2, table);
+    rightJustifyColumn(4, table);
+    rightJustifyColumn(5, table);
+    buffer.writeTable(table);
+
+    print('Mean Reciprocal Rank');
+    print('');
+    print(buffer.toString());
+
+    if (options.printMrrByLocation) {
+      var lines = <LocationTableLine>[];
+      for (var entry in metrics.locationMrrComputers.entries) {
+        var count = entry.value.count;
+        var mrr = (1 / entry.value.mrr);
+        var mrr_5 = (1 / entry.value.mrr_5);
+        var product = count * mrr;
+        lines.add(LocationTableLine(
+            label: entry.key,
+            product: product,
+            count: count,
+            mrr: mrr,
+            mrr_5: mrr_5));
+      }
+      lines.sort((first, second) => second.product.compareTo(first.product));
+      var table = <List<String>>[];
+      table.add(['Location', 'Product', 'Count', 'Mrr', 'Mrr_5']);
+      for (var line in lines) {
+        var location = line.label;
+        var product = line.product.truncate().toString();
+        var count = line.count.toString();
+        var mrr = line.mrr.toStringAsFixed(3);
+        var mrr_5 = line.mrr_5.toStringAsFixed(3);
+        table.add([location, product, count, mrr, mrr_5]);
+      }
+      var buffer = StringBuffer();
+      buffer.writeTable(table);
+      print(buffer.toString());
+      print('');
+    }
+
+    metrics.charsBeforeTop.printMean();
+    metrics.charsBeforeTopFive.printMean();
+    metrics.insertionLengthTheoretical.printMean();
+    print('');
+
+    print('Summary for $rootPath:');
+    metrics.meanCompletionMS.printMean();
+    metrics.completionCounter.printCounterValues();
+    print('====================');
+  }
+
+  void printMissingInformation(CompletionMetrics metrics) {
+    var locations = metrics.missingCompletionLocations;
+    if (locations.isNotEmpty) {
+      print('');
+      print('====================');
+      print('Missing completion location in the following places:');
+      for (var location in locations.toList()..sort()) {
+        print('  $location');
+      }
+    }
+
+    var tables = metrics.missingCompletionLocationTables;
+    if (tables.isNotEmpty) {
+      print('');
+      print('====================');
+      print('Missing tables for the following completion locations:');
+      for (var table in tables.toList()..sort()) {
+        print('  $table');
+      }
+    }
+  }
+
+  void printSlowestResults(CompletionMetrics metrics) {
+    print('');
+    print('====================');
+    print('The slowest completion results to compute');
+    _printSlowestResults(
+        'Instance members', metrics.instanceMemberSlowestResults);
+    _printSlowestResults('Static members', metrics.staticMemberSlowestResults);
+    _printSlowestResults('Type references', metrics.typeRefSlowestResults);
+    _printSlowestResults('Local references', metrics.localRefSlowestResults);
+    _printSlowestResults(
+        'Parameter references', metrics.paramRefSlowestResults);
+    _printSlowestResults('Top level', metrics.topLevelSlowestResults);
+  }
+
+  void printWorstResults(CompletionMetrics metrics) {
+    print('');
+    print('====================');
+    print('The worst completion results');
+    _printWorstResults('Instance members', metrics.instanceMemberWorstResults);
+    _printWorstResults('Static members', metrics.staticMemberWorstResults);
+    _printWorstResults('Type references', metrics.topLevelWorstResults);
+    _printWorstResults('Local references', metrics.localRefWorstResults);
+    _printWorstResults('Parameter references', metrics.paramRefWorstResults);
+    _printWorstResults('Top level', metrics.topLevelWorstResults);
+  }
+
+  int _computeCharsBeforeTop(ExpectedCompletion target,
+      List<protocol.CompletionSuggestion> suggestions,
+      {int minRank = 1}) {
+    var rank = placementInSuggestionList(suggestions, target).rank;
+    if (rank <= minRank) {
+      return 0;
+    }
+    var expected = target.completion;
+    for (var i = 1; i < expected.length + 1; i++) {
+      var prefix = expected.substring(0, i);
+      var filteredSuggestions = _filterSuggestions(prefix, suggestions);
+      rank = placementInSuggestionList(filteredSuggestions, target).rank;
+      if (rank <= minRank) {
+        return i;
+      }
+    }
+    return expected.length;
+  }
+
+  Future<List<protocol.CompletionSuggestion>> _computeCompletionSuggestions(
+      MetricsSuggestionListener listener,
+      OperationPerformanceImpl performance,
+      CompletionRequestImpl request,
+      [DeclarationsTracker declarationsTracker,
+      protocol.CompletionAvailableSuggestionsParams
+          availableSuggestionsParams]) async {
+    List<protocol.CompletionSuggestion> suggestions;
+
+    if (declarationsTracker == null) {
+      // available suggestions == false
+      suggestions = await DartCompletionManager(
+        dartdocDirectiveInfo: DartdocDirectiveInfo(),
+        listener: listener,
+      ).computeSuggestions(performance, request);
+    } else {
+      // available suggestions == true
+      var includedElementKinds = <protocol.ElementKind>{};
+      var includedElementNames = <String>{};
+      var includedSuggestionRelevanceTagList =
+          <protocol.IncludedSuggestionRelevanceTag>[];
+      var includedSuggestionSetList = <protocol.IncludedSuggestionSet>[];
+      suggestions = await DartCompletionManager(
+        dartdocDirectiveInfo: DartdocDirectiveInfo(),
+        includedElementKinds: includedElementKinds,
+        includedElementNames: includedElementNames,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTagList,
+        listener: listener,
+      ).computeSuggestions(performance, request);
+
+      computeIncludedSetList(declarationsTracker, request.result,
+          includedSuggestionSetList, includedElementNames);
+
+      var includedSuggestionSetMap = {
+        for (var includedSuggestionSet in includedSuggestionSetList)
+          includedSuggestionSet.id: includedSuggestionSet,
+      };
+
+      var includedSuggestionRelevanceTagMap = {
+        for (var includedSuggestionRelevanceTag
+            in includedSuggestionRelevanceTagList)
+          includedSuggestionRelevanceTag.tag:
+              includedSuggestionRelevanceTag.relevanceBoost,
+      };
+
+      for (var availableSuggestionSet
+          in availableSuggestionsParams.changedLibraries) {
+        var id = availableSuggestionSet.id;
+        for (var availableSuggestion in availableSuggestionSet.items) {
+          // Exclude available suggestions where this element kind doesn't match
+          // an element kind in includedElementKinds.
+          var elementKind = availableSuggestion.element?.kind;
+          if (elementKind != null &&
+              includedElementKinds.contains(elementKind)) {
+            if (includedSuggestionSetMap.containsKey(id)) {
+              var relevance = includedSuggestionSetMap[id].relevance;
+
+              // Search for any matching relevance tags to apply any boosts
+              if (includedSuggestionRelevanceTagList.isNotEmpty &&
+                  availableSuggestion.relevanceTags != null &&
+                  availableSuggestion.relevanceTags.isNotEmpty) {
+                for (var tag in availableSuggestion.relevanceTags) {
+                  if (includedSuggestionRelevanceTagMap.containsKey(tag)) {
+                    // apply the boost
+                    relevance += includedSuggestionRelevanceTagMap[tag];
+                  }
+                }
+              }
+              suggestions
+                  .add(availableSuggestion.toCompletionSuggestion(relevance));
+            }
+          }
+        }
+      }
+    }
+
+    suggestions.sort(completionComparator);
+    return suggestions;
+  }
+
+  /// Compute the metrics for the files in the context [root], creating a
+  /// separate context collection to prevent accumulating memory. The metrics
+  /// should be captured in the [collector].
+  Future<void> _computeInContext(ContextRoot root) async {
+    // Create a new collection to avoid consuming large quantities of memory.
+    final collection = AnalysisContextCollection(
+      includedPaths: root.includedPaths.toList(),
+      excludedPaths: root.excludedPaths.toList(),
+      resourceProvider: _provider,
+    );
+
+    var context = collection.contexts[0];
+
+    // Set the DeclarationsTracker, only call doWork to build up the available
+    // suggestions if doComputeCompletionsFromAnalysisServer is true.
+    DeclarationsTracker declarationsTracker;
+    protocol.CompletionAvailableSuggestionsParams availableSuggestionsParams;
+    if (options.availableSuggestions) {
+      declarationsTracker = DeclarationsTracker(
+          MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
+      declarationsTracker.addContext(context);
+      while (declarationsTracker.hasWork) {
+        declarationsTracker.doWork();
+      }
+
+      // Have the AvailableDeclarationsSet computed to use later.
+      availableSuggestionsParams = createCompletionAvailableSuggestions(
+          declarationsTracker.allLibraries.toList(), []);
+
+      // assert that this object is not null, throw if it is.
+      if (availableSuggestionsParams == null) {
+        throw Exception('availableSuggestionsParam not computable.');
+      }
+    }
+
+    // Loop through each file, resolve the file and call
+    // forEachExpectedCompletion
+    for (var filePath in context.contextRoot.analyzedFiles()) {
+      if (AnalysisEngine.isDartFileName(filePath)) {
+        try {
+          _resolvedUnitResult =
+              await context.currentSession.getResolvedUnit(filePath);
+
+          var analysisError = getFirstErrorOrNull(_resolvedUnitResult);
+          if (analysisError != null) {
+            print('File $filePath skipped due to errors such as:');
+            print('  ${analysisError.toString()}');
+            print('');
+            resultCode = 1;
+            continue;
+          }
+
+          // Use the ExpectedCompletionsVisitor to compute the set of expected
+          // completions for this CompilationUnit.
+          final visitor = ExpectedCompletionsVisitor(filePath);
+          _resolvedUnitResult.unit.accept(visitor);
+
+          for (var expectedCompletion in visitor.expectedCompletions) {
+            var resolvedUnitResult = _resolvedUnitResult;
+
+            // If an overlay option is being used, compute the overlay file, and
+            // have the context reanalyze the file
+            if (options.overlay != OVERLAY_NONE) {
+              var overlayContents = _getOverlayContents(
+                  _resolvedUnitResult.content,
+                  expectedCompletion,
+                  options.overlay);
+
+              _provider.setOverlay(filePath,
+                  content: overlayContents,
+                  modificationStamp: overlayModificationStamp++);
+              (context as DriverBasedAnalysisContext)
+                  .driver
+                  .changeFile(filePath);
+              resolvedUnitResult =
+                  await context.currentSession.getResolvedUnit(filePath);
+            }
+
+            // As this point the completion suggestions are computed,
+            // and results are collected with varying settings for
+            // comparison:
+
+            Future<int> handleExpectedCompletion(
+                {MetricsSuggestionListener listener,
+                @required CompletionMetrics metrics,
+                @required bool printMissedCompletions}) async {
+              var stopwatch = Stopwatch()..start();
+              var request = CompletionRequestImpl(
+                resolvedUnitResult,
+                expectedCompletion.offset,
+                CompletionPerformance(),
+              );
+              var directiveInfo = DartdocDirectiveInfo();
+
+              OpType opType;
+              List<protocol.CompletionSuggestion> suggestions;
+              await request.performance.runRequestOperation(
+                (performance) async {
+                  var dartRequest = await DartCompletionRequestImpl.from(
+                      performance, request, directiveInfo);
+                  opType =
+                      OpType.forCompletion(dartRequest.target, request.offset);
+                  suggestions = await _computeCompletionSuggestions(
+                    listener,
+                    performance,
+                    request,
+                    declarationsTracker,
+                    availableSuggestionsParams,
+                  );
+                },
+              );
+              stopwatch.stop();
+
+              return forEachExpectedCompletion(
+                  request,
+                  listener,
+                  expectedCompletion,
+                  opType.completionLocation,
+                  suggestions,
+                  metrics,
+                  stopwatch.elapsedMilliseconds,
+                  printMissedCompletions);
+            }
+
+            var bestRank = -1;
+            var bestName = '';
+            for (var metrics in targetMetrics) {
+              // Compute the completions.
+              metrics.enable();
+              var listener = MetricsSuggestionListener();
+              var rank = await handleExpectedCompletion(
+                  listener: listener,
+                  metrics: metrics,
+                  printMissedCompletions: options.printMissedCompletionDetails);
+              if (bestRank < 0 || rank < bestRank) {
+                bestRank = rank;
+                bestName = metrics.name;
+              }
+              metrics.disable();
+            }
+            rankComparison.count(bestName);
+
+            // If an overlay option is being used, remove the overlay applied
+            // earlier
+            if (options.overlay != OVERLAY_NONE) {
+              _provider.removeOverlay(filePath);
+            }
+          }
+        } catch (exception, stackTrace) {
+          print('Exception caught analyzing: $filePath');
+          print(exception.toString());
+          print(stackTrace);
+          resultCode = 1;
+        }
+      }
+    }
+  }
+
+  List<protocol.CompletionSuggestion> _filterSuggestions(
+      String prefix, List<protocol.CompletionSuggestion> suggestions) {
+    // TODO(brianwilkerson) Replace this with a more realistic filtering algorithm.
+    return suggestions
+        .where((suggestion) => suggestion.completion.startsWith(prefix))
+        .toList();
+  }
+
+  String _getOverlayContents(String contents,
+      ExpectedCompletion expectedCompletion, String overlayMode) {
+    assert(contents.isNotEmpty);
+    var offset = expectedCompletion.offset;
+    var length = expectedCompletion.syntacticEntity.length;
+    assert(offset >= 0);
+    assert(length > 0);
+    if (overlayMode == OVERLAY_REMOVE_TOKEN) {
+      return contents.substring(0, offset) +
+          contents.substring(offset + length);
+    } else if (overlayMode == OVERLAY_REMOVE_REST_OF_FILE) {
+      return contents.substring(0, offset);
+    } else {
+      throw Exception('\'_getOverlayContents\' called with option other than'
+          '$OVERLAY_REMOVE_TOKEN and $OVERLAY_REMOVE_REST_OF_FILE: $overlayMode');
+    }
+  }
+
+  void _printSlowestResults(
+      String title, List<CompletionResult> slowestResults) {
+    print('');
+    print(title);
+    for (var result in slowestResults) {
+      var elapsedMS = result.elapsedMS;
+      var expected = result.expectedCompletion;
+      print('');
+      print('  Elapsed ms: $elapsedMS');
+      print('  Completion: ${expected.completion}');
+      print('  Completion kind: ${expected.kind}');
+      print('  Element kind: ${expected.elementKind}');
+      print('  Location: ${expected.location}');
+    }
+  }
+
+  void _printWorstResults(String title, List<CompletionResult> worstResults) {
+    print('');
+    print(title);
+    for (var result in worstResults) {
+      var rank = result.place.rank;
+      var expected = result.expectedCompletion;
+      var suggestions = result.suggestions;
+      var suggestion = suggestions[rank - 1];
+
+      var features = result.listener?.featureMap[suggestion];
+      var topSuggestions =
+          suggestions.sublist(0, math.min(10, suggestions.length));
+      var topSuggestionCount = topSuggestions.length;
+
+      var preceding = <int, int>{};
+      for (var i = 0; i < rank - 1; i++) {
+        var relevance = suggestions[i].relevance;
+        preceding[relevance] = (preceding[relevance] ?? 0) + 1;
+      }
+      var precedingRelevances = preceding.keys.toList();
+      precedingRelevances.sort();
+
+      print('');
+      print('  Rank: $rank');
+      print('  Location: ${expected.location}');
+      print('  Suggestion: ${suggestion.description}');
+      print('  Features: $features');
+      print('  Top $topSuggestionCount suggestions:');
+      for (var i = 0; i < topSuggestionCount; i++) {
+        var topSuggestion = topSuggestions[i];
+        print('  $i Suggestion: ${topSuggestion.description}');
+        if (result.listener != null) {
+          var feature = result.listener.featureMap[topSuggestion];
+          if (feature == null || feature.isEmpty) {
+            print('    Features: <none>');
+          } else {
+            print('    Features: $feature');
+          }
+        }
+      }
+      print('  Preceding relevance scores and counts:');
+      for (var relevance in precedingRelevances.reversed) {
+        print('    $relevance: ${preceding[relevance]}');
+      }
+    }
+  }
+
+  /// Given some [ResolvedUnitResult] return the first error of high severity
+  /// if such an error exists, `null` otherwise.
+  static err.AnalysisError getFirstErrorOrNull(
+      ResolvedUnitResult resolvedUnitResult) {
+    for (var error in resolvedUnitResult.errors) {
+      if (error.severity == Severity.error) {
+        return error;
+      }
+    }
+    return null;
+  }
+
+  static Place placementInSuggestionList(
+      List<protocol.CompletionSuggestion> suggestions,
+      ExpectedCompletion expectedCompletion) {
+    var placeCounter = 1;
+    for (var completionSuggestion in suggestions) {
+      if (expectedCompletion.matches(completionSuggestion)) {
+        return Place(placeCounter, suggestions.length);
+      }
+      placeCounter++;
+    }
+    return Place.none();
+  }
+}
+
+/// The options specified on the command-line.
+class CompletionMetricsOptions {
+  /// A flag indicating whether available suggestions should be enabled for this
+  /// run.
+  final bool availableSuggestions;
+
+  /// The overlay mode that should be used.
+  final String overlay;
+
+  /// A flag indicating whether information should be printed every time a
+  /// completion request fails to produce a suggestions matching the expected
+  /// suggestion.
+  final bool printMissedCompletionDetails;
+
+  /// A flag indicating whether information should be printed every time a
+  /// completion request fails to produce a suggestions matching the expected
+  /// suggestion.
+  final bool printMissedCompletionSummary;
+
+  /// A flag indicating whether information should be printed about places where
+  /// no completion location was computed and about information that's missing
+  /// in the completion tables.
+  final bool printMissingInformation;
+
+  /// A flag indicating whether information should be printed about the mrr
+  /// score achieved at each completion location.
+  final bool printMrrByLocation;
+
+  /// A flag indicating whether information should be printed about the
+  /// completion requests that were the slowest to return suggestions.
+  final bool printSlowestResults;
+
+  /// A flag indicating whether information should be printed about the
+  /// completion requests that had the worst mrr scores.
+  final bool printWorstResults;
+
+  CompletionMetricsOptions(
+      {@required this.availableSuggestions,
+      @required this.overlay,
+      @required this.printMissedCompletionDetails,
+      @required this.printMissedCompletionSummary,
+      @required this.printMissingInformation,
+      @required this.printMrrByLocation,
+      @required this.printSlowestResults,
+      @required this.printWorstResults})
+      : assert(overlay == OVERLAY_NONE ||
+            overlay == OVERLAY_REMOVE_TOKEN ||
+            overlay == OVERLAY_REMOVE_REST_OF_FILE);
+}
+
+/// The result of a single completion.
+class CompletionResult {
+  final Place place;
+
+  final CompletionRequestImpl request;
+
+  final MetricsSuggestionListener listener;
+
+  final List<protocol.CompletionSuggestion> suggestions;
+
+  final ExpectedCompletion expectedCompletion;
+
+  final String completionLocation;
+
+  final int elapsedMS;
+
+  CompletionResult(this.place, this.request, this.listener, this.suggestions,
+      this.expectedCompletion, this.completionLocation, this.elapsedMS);
+
+  /// Return the completion group for the location at which completion was
+  /// requested.
+  CompletionGroup get group {
+    var element = _getElement(expectedCompletion.syntacticEntity);
+    if (element != null) {
+      var parent = element.enclosingElement;
+      if (parent is ClassElement || parent is ExtensionElement) {
+        if (_isStatic(element)) {
+          return CompletionGroup.staticMember;
+        } else {
+          return CompletionGroup.instanceMember;
+        }
+      } else if (expectedCompletion.elementKind == ElementKind.CLASS ||
+          expectedCompletion.elementKind == ElementKind.MIXIN ||
+          expectedCompletion.elementKind == ElementKind.ENUM ||
+          expectedCompletion.elementKind == ElementKind.TYPE_PARAMETER) {
+        return CompletionGroup.typeReference;
+      } else if (expectedCompletion.elementKind == ElementKind.LOCAL_VARIABLE) {
+        return CompletionGroup.localReference;
+      } else if (expectedCompletion.elementKind == ElementKind.PARAMETER) {
+        return CompletionGroup.paramReference;
+      }
+    }
+    return CompletionGroup.topLevel;
+  }
+
+  /// Return the element associated with the syntactic [entity], or `null` if
+  /// there is no such element.
+  Element _getElement(SyntacticEntity entity) {
+    if (entity is SimpleIdentifier) {
+      return entity.staticElement;
+    }
+    return null;
+  }
+
+  /// Return `true` if the [element] is static (either top-level or a static
+  /// member of a class or extension).
+  bool _isStatic(Element element) {
+    if (element is ClassMemberElement) {
+      return element.isStatic;
+    } else if (element is ExecutableElement) {
+      return element.isStatic;
+    } else if (element is FieldElement) {
+      return element.isStatic;
+    } else if (element is VariableElement) {
+      return element.isStatic;
+    }
+    return true;
+  }
+}
+
+/// The data to be printed on a single line in the table of mrr values per
+/// completion location.
+class LocationTableLine {
+  final String label;
+  final double product;
+  final int count;
+  final double mrr;
+  final double mrr_5;
+
+  LocationTableLine(
+      {@required this.label,
+      @required this.product,
+      @required this.count,
+      @required this.mrr,
+      @required this.mrr_5});
+}
+
+class MetricsSuggestionListener implements SuggestionListener {
+  Map<protocol.CompletionSuggestion, String> featureMap = {};
+
+  String cachedFeatures = '';
+
+  String missingCompletionLocation;
+  String missingCompletionLocationTable;
+
+  @override
+  void builtSuggestion(protocol.CompletionSuggestion suggestion) {
+    featureMap[suggestion] = cachedFeatures;
+    cachedFeatures = '';
+  }
+
+  @override
+  void computedFeatures(
+      {double contextType,
+      double elementKind,
+      double hasDeprecated,
+      double inheritanceDistance,
+      double startsWithDollar,
+      double superMatches}) {
+    var buffer = StringBuffer();
+
+    bool write(String label, double value, bool needsComma) {
+      if (value != null) {
+        if (needsComma) {
+          buffer.write(', ');
+        }
+        buffer.write('$label: $value');
+        return true;
+      }
+      return needsComma;
+    }
+
+    var needsComma = false;
+    needsComma = write('contextType', contextType, needsComma);
+    needsComma = write('elementKind', elementKind, needsComma);
+    needsComma = write('hasDeprecated', hasDeprecated, needsComma);
+    needsComma = write('inheritanceDistance', inheritanceDistance, needsComma);
+    needsComma = write('startsWithDollar', startsWithDollar, needsComma);
+    needsComma = write('superMatches', superMatches, needsComma);
+    cachedFeatures = buffer.toString();
+  }
+
+  @override
+  void missingCompletionLocationAt(AstNode parent, SyntacticEntity child) {
+    if (missingCompletionLocation == null) {
+      String className(SyntacticEntity entity) {
+        var className = entity.runtimeType.toString();
+        if (className.endsWith('Impl')) {
+          className = className.substring(0, className.length - 4);
+        }
+        return className;
+      }
+
+      var parentClass = className(parent);
+      var childClass = className(child);
+      missingCompletionLocation = '$parentClass/$childClass';
+    }
+  }
+
+  @override
+  void missingElementKindTableFor(String completionLocation) {
+    missingCompletionLocationTable = completionLocation;
+  }
+}
+
+extension on protocol.CompletionSuggestion {
+  /// A shorter description of the suggestion than [toString] provides.
+  String get description =>
+      json.encode(toJson()..remove('docSummary')..remove('docComplete'));
+}
+
+extension AvailableSuggestionsExtension on protocol.AvailableSuggestion {
+  // TODO(jwren) I am not sure if we want CompletionSuggestionKind.INVOCATION in
+  // call cases here, to iterate I need to figure out why this algorithm is
+  // taking so much time.
+  protocol.CompletionSuggestion toCompletionSuggestion(int relevance) =>
+      protocol.CompletionSuggestion(
+          protocol.CompletionSuggestionKind.INVOCATION,
+          relevance,
+          label,
+          label.length,
+          0,
+          element.isDeprecated,
+          false);
+}
diff --git a/pkg/analysis_server/tool/completion_metrics/corpus.dart b/pkg/analysis_server/tool/code_completion/corpus.dart
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/corpus.dart
rename to pkg/analysis_server/tool/code_completion/corpus.dart
diff --git a/pkg/analysis_server/tool/completion_metrics/data/itsallwidgets_repos.txt b/pkg/analysis_server/tool/code_completion/data/itsallwidgets_repos.txt
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/data/itsallwidgets_repos.txt
rename to pkg/analysis_server/tool/code_completion/data/itsallwidgets_repos.txt
diff --git a/pkg/analysis_server/tool/completion_metrics/flutter_metrics.dart b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/flutter_metrics.dart
rename to pkg/analysis_server/tool/code_completion/flutter_metrics.dart
diff --git a/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
rename to pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
diff --git a/pkg/analysis_server/tool/code_completion/metrics_util.dart b/pkg/analysis_server/tool/code_completion/metrics_util.dart
new file mode 100644
index 0000000..6078af8d
--- /dev/null
+++ b/pkg/analysis_server/tool/code_completion/metrics_util.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/status/pages.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+/// https://en.wikipedia.org/wiki/Average#Arithmetic_mean
+class ArithmeticMeanComputer {
+  final String name;
+  num sum = 0;
+  int count = 0;
+
+  ArithmeticMeanComputer(this.name);
+
+  num get mean => sum / count;
+
+  void addValue(num val) {
+    sum += val;
+    count++;
+  }
+
+  void clear() {
+    sum = 0;
+    count = 0;
+  }
+
+  void printMean() {
+    print('Mean \'$name\' ${mean.toStringAsFixed(6)} (total = $count)');
+  }
+}
+
+/// A simple counter class.  A [String] name is passed to name the counter. Each
+/// time something is counted, a non-null, non-empty [String] key is passed to
+/// [count] to increment the amount from zero. [printCounterValues] is provided
+/// to have a [String] summary of the generated counts, example:
+///
+/// ```
+/// Counts for 'counter example':
+/// [bucket-1] 60 (60.0%)
+/// [bucket-2] 25 (25.0%)
+/// [bucket-3] 5 (5.0%)
+/// [bucket-4] 10 (10.0%)
+/// ```
+class Counter {
+  final String name;
+  final Map<String, int> _buckets = {};
+  int _totalCount = 0;
+
+  Counter(this.name);
+
+  /// Return a copy of all the current count data, this getter copies and
+  /// returns the data to ensure that the data is only modified with the public
+  /// accessors in this class.
+  Map<String, int> get map => Map.from(_buckets);
+
+  int get totalCount => _totalCount;
+
+  void clear() {
+    _buckets.clear();
+    _totalCount = 0;
+  }
+
+  void count(String id, [int countNumber = 1]) {
+    assert(id != null && id.isNotEmpty && 1 <= countNumber);
+    if (_buckets.containsKey(id)) {
+      _buckets[id] += countNumber;
+    } else {
+      _buckets.putIfAbsent(id, () => countNumber);
+    }
+    _totalCount += countNumber;
+  }
+
+  int getCountOf(String id) => _buckets[id] ?? 0;
+
+  void printCounterValues() {
+    print('Counts for \'$name\' (total = $_totalCount):');
+    if (_totalCount > 0) {
+      var entries = _buckets.entries.toList();
+      entries.sort((first, second) => second.value - first.value);
+      for (var entry in entries) {
+        var id = entry.key;
+        var count = entry.value;
+        print('[$id] $count (${printPercentage(count / _totalCount, 2)})');
+      }
+    } else {
+      print('<no counts>');
+    }
+  }
+}
+
+/// A computer for the mean reciprocal rank. The MRR as well as the MRR only
+/// if the item was in the top 5 in the list see [MAX_RANK], is computed.
+/// https://en.wikipedia.org/wiki/Mean_reciprocal_rank.
+class MeanReciprocalRankComputer {
+  static final int MAX_RANK = 5;
+  final String name;
+  double _sum = 0;
+  double _sum_5 = 0;
+  int _count = 0;
+
+  MeanReciprocalRankComputer(
+    this.name,
+  );
+
+  int get count => _count;
+
+  double get mrr {
+    if (count == 0) {
+      return 0;
+    }
+    return _sum / count;
+  }
+
+  double get mrr_5 {
+    if (count == 0) {
+      return 0;
+    }
+    return _sum_5 / count;
+  }
+
+  void addRank(int rank) {
+    if (rank != 0) {
+      _sum += 1 / rank;
+      if (rank <= MAX_RANK) {
+        _sum_5 += 1 / rank;
+      }
+    }
+    _count++;
+  }
+
+  void clear() {
+    _sum = 0;
+    _sum_5 = 0;
+    _count = 0;
+  }
+
+  void printMean() {
+    print('Mean Reciprocal Rank \'$name\' (total = $count)');
+    print('mrr   = ${mrr.toStringAsFixed(6)} '
+        '(inverse = ${(1 / mrr).toStringAsFixed(3)})');
+
+    print('mrr_5 = ${mrr_5.toStringAsFixed(6)} '
+        '(inverse = ${(1 / mrr_5).toStringAsFixed(3)})');
+  }
+}
+
+/// An immutable class to represent the placement in some list, for example '2nd
+/// place out of 5'.
+class Place {
+  /// A 1-indexed place in a list
+  final int _numerator;
+
+  /// The total number of possible places.
+  final int _denominator;
+
+  const Place(this._numerator, this._denominator)
+      : assert(_numerator > 0),
+        assert(_denominator >= _numerator);
+
+  const Place.none()
+      : _numerator = 0,
+        _denominator = 0;
+
+  int get denominator => _denominator;
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash2(_numerator, _denominator);
+
+  int get numerator => _numerator;
+
+  int get rank => _numerator;
+
+  @override
+  bool operator ==(dynamic other) =>
+      other is Place &&
+      _numerator == other._numerator &&
+      _denominator == other._denominator;
+}
diff --git a/pkg/analysis_server/tool/code_completion/output_utilities.dart b/pkg/analysis_server/tool/code_completion/output_utilities.dart
new file mode 100644
index 0000000..71660df
--- /dev/null
+++ b/pkg/analysis_server/tool/code_completion/output_utilities.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:math' as math;
+
+/// Given a [table] represented as a list of rows, right justify all of the
+/// cells in the given [column], except for the first row under the assumption
+/// that the first row contains headers.
+void rightJustifyColumn(int column, List<List<String>> table) {
+  var width = 0;
+  for (var i = 0; i < table.length; i++) {
+    var row = table[i];
+    width = math.max(width, row[column].length);
+  }
+  for (var i = 1; i < table.length; i++) {
+    var row = table[i];
+    var cellValue = row[column];
+    var length = cellValue.length;
+    if (length < width) {
+      var padding = ' ' * (width - length);
+      row[column] = '$padding$cellValue';
+    }
+  }
+}
+
+extension OutputUtilities on StringSink {
+  /// Write the given [table].
+  ///
+  /// The table is represented as a list or rows, where each row is a list of
+  /// the contents of the cells in that row.
+  ///
+  /// Throws an [ArgumentError] if the table is empty or if the rows do not
+  /// contain the same number of cells.
+  void writeTable(List<List<String>> table) {
+    var columnWidths = _computeColumnWidths(table);
+    for (var row in table) {
+      var lastNonEmpty = row.length - 1;
+      while (lastNonEmpty > 0) {
+        if (row[lastNonEmpty].isNotEmpty) {
+          break;
+        }
+        lastNonEmpty--;
+      }
+      for (var i = 0; i <= lastNonEmpty; i++) {
+        var cellContent = row[i];
+        var columnWidth = columnWidths[i];
+        var padding = columnWidth - cellContent.length;
+        write(cellContent);
+        if (i < lastNonEmpty) {
+          write(' ' * (padding + 2));
+        }
+      }
+      writeln();
+    }
+  }
+
+  /// Return the minimum widths for each of the columns in the given [table].
+  ///
+  /// The table is represented as a list or rows, where each row is a list of
+  /// the contents of the cells in that row.
+  ///
+  /// Throws an [ArgumentError] if the table is empty or if the rows do not
+  /// contain the same number of cells.
+  List<int> _computeColumnWidths(List<List<String>> table) {
+    if (table.isEmpty) {
+      throw ArgumentError('table cannot be empty');
+    }
+    var columnCount = table[0].length;
+    if (columnCount == 0) {
+      throw ArgumentError('rows cannot be empty');
+    }
+    var columnWidths = List<int>.filled(columnCount, 0);
+    for (var row in table) {
+      var rowLength = row.length;
+      if (rowLength > 0) {
+        if (rowLength != columnCount) {
+          throw ArgumentError(
+              'non-empty rows must contain the same number of columns');
+        }
+        for (var i = 0; i < rowLength; i++) {
+          var cellWidth = row[i].length;
+          columnWidths[i] = math.max(columnWidths[i], cellWidth);
+        }
+      }
+    }
+    return columnWidths;
+  }
+}
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
rename to pkg/analysis_server/tool/code_completion/relevance_metrics.dart
diff --git a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
new file mode 100644
index 0000000..21230de
--- /dev/null
+++ b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
@@ -0,0 +1,1610 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
+import 'package:analysis_server/src/protocol_server.dart' show ElementKind;
+import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
+import 'package:analysis_server/src/utilities/flutter.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
+import 'package:analyzer/dart/analysis/results.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/dart/element/element.dart'
+    show ClassElement, Element, LibraryElement;
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:analyzer_utilities/tools.dart';
+import 'package:args/args.dart';
+import 'package:meta/meta.dart';
+
+/// Compute metrics to determine whether they should be used to compute a
+/// relevance score for completion suggestions.
+Future<void> main(List<String> args) async {
+  var parser = createArgParser();
+  var result = parser.parse(args);
+
+  if (validArguments(parser, result)) {
+    var rootPath = result.rest[0];
+    print('Analyzing root: "$rootPath"');
+
+    var provider = PhysicalResourceProvider.INSTANCE;
+    var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
+    var generatedFilePath = provider.pathContext.join(
+        packageRoot,
+        'analysis_server',
+        'lib',
+        'src',
+        'services',
+        'completion',
+        'dart',
+        'relevance_tables.g.dart');
+    var generatedFile = provider.getFile(generatedFilePath);
+
+    var computer = RelevanceMetricsComputer();
+    var stopwatch = Stopwatch();
+    stopwatch.start();
+    await computer.compute(rootPath, verbose: result['verbose']);
+    var buffer = StringBuffer();
+    var writer = RelevanceTableWriter(buffer);
+    writer.write(computer.data);
+    generatedFile.writeAsStringSync(buffer.toString());
+    DartFormat.formatFile(io.File(generatedFile.path));
+    stopwatch.stop();
+
+    var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
+    print('Tables generated in $duration');
+  }
+}
+
+/// Create a parser that can be used to parse the command-line arguments.
+ArgParser createArgParser() {
+  var parser = ArgParser();
+  parser.addFlag(
+    'help',
+    abbr: 'h',
+    help: 'Print this help message.',
+  );
+  parser.addFlag(
+    'verbose',
+    abbr: 'v',
+    help: 'Print additional information about the analysis',
+    negatable: false,
+  );
+  return parser;
+}
+
+/// Print usage information for this tool.
+void printUsage(ArgParser parser, {String error}) {
+  if (error != null) {
+    print(error);
+    print('');
+  }
+  print('usage: dart relevance_table_generator.dart [options] packagePath');
+  print('');
+  print('Generate the tables used to compute the values of certain features.');
+  print('');
+  print(parser.usage);
+}
+
+/// Return `true` if the command-line arguments (represented by the [result] and
+/// parsed by the [parser]) are valid.
+bool validArguments(ArgParser parser, ArgResults result) {
+  if (result.wasParsed('help')) {
+    printUsage(parser);
+    return false;
+  } else if (result.rest.length != 1) {
+    printUsage(parser, error: 'No package path specified.');
+    return false;
+  }
+  var rootPath = result.rest[0];
+  if (!PhysicalResourceProvider.INSTANCE.pathContext.isAbsolute(rootPath)) {
+    printUsage(parser, error: 'The package path must be an absolute path.');
+    return false;
+  }
+  if (!io.Directory(rootPath).existsSync()) {
+    printUsage(parser, error: 'The directory "$rootPath" does not exist.');
+    return false;
+  }
+  return true;
+}
+
+/// An object that records the data used to compute the tables.
+class RelevanceData {
+  /// A table mapping element kinds and keywords to counts by context.
+  Map<String, Map<_Kind, int>> byKind = {};
+
+  /// Initialize a newly created set of relevance data to be empty.
+  RelevanceData();
+
+  /// Add the data from the given relevance [data] to this set of data.
+  void addDataFrom(RelevanceData data) {
+    _addToMap(byKind, data.byKind);
+  }
+
+  /// Record that an element of the given [kind] was found in the given
+  /// [context].
+  void recordElementKind(String context, ElementKind kind) {
+    var contextMap = byKind.putIfAbsent(context, () => {});
+    var key = _ElementKind(kind);
+    contextMap[key] = (contextMap[key] ?? 0) + 1;
+  }
+
+  /// Record that the given [keyword] was found in the given [context].
+  void recordKeyword(String context, Keyword keyword) {
+    var contextMap = byKind.putIfAbsent(context, () => {});
+    var key = _Keyword(keyword);
+    contextMap[key] = (contextMap[key] ?? 0) + 1;
+  }
+
+  /// Add the data in the [source] map to the [target] map.
+  void _addToMap<K>(Map<K, Map<K, int>> target, Map<K, Map<K, int>> source) {
+    for (var outerEntry in source.entries) {
+      var innerTarget = target.putIfAbsent(outerEntry.key, () => {});
+      for (var innerEntry in outerEntry.value.entries) {
+        var innerKey = innerEntry.key;
+        innerTarget[innerKey] = (innerTarget[innerKey] ?? 0) + innerEntry.value;
+      }
+    }
+  }
+}
+
+/// An object that visits a compilation unit in order to record the data used to
+/// compute the metrics.
+class RelevanceDataCollector extends RecursiveAstVisitor<void> {
+  static const List<Keyword> declarationKeywords = [
+    Keyword.MIXIN,
+    Keyword.TYPEDEF
+  ];
+
+  static const List<Keyword> directiveKeywords = [
+    Keyword.EXPORT,
+    Keyword.IMPORT,
+    Keyword.LIBRARY,
+    Keyword.PART
+  ];
+
+  static const List<Keyword> exportKeywords = [
+    Keyword.AS,
+    Keyword.HIDE,
+    Keyword.SHOW
+  ];
+
+  static const List<Keyword> expressionKeywords = [
+    Keyword.AWAIT,
+    Keyword.SUPER
+  ];
+
+  static const List<Keyword> functionBodyKeywords = [
+    Keyword.ASYNC,
+    Keyword.SYNC
+  ];
+
+  static const List<Keyword> importKeywords = [
+    Keyword.AS,
+    Keyword.HIDE,
+    Keyword.SHOW
+  ];
+
+  static const List<Keyword> memberKeywords = [
+    Keyword.FACTORY,
+    Keyword.GET,
+    Keyword.OPERATOR,
+    Keyword.SET,
+    Keyword.STATIC
+  ];
+
+  static const List<Keyword> noKeywords = [];
+
+  static const List<Keyword> statementKeywords = [Keyword.AWAIT, Keyword.YIELD];
+
+  /// The relevance data being collected.
+  final RelevanceData data;
+
+  /// The compilation unit in which data is currently being collected.
+  CompilationUnit unit;
+
+  InheritanceManager3 inheritanceManager = InheritanceManager3();
+
+  /// The library containing the compilation unit being visited.
+  LibraryElement enclosingLibrary;
+
+  /// The type provider associated with the current compilation unit.
+  TypeProvider typeProvider;
+
+  /// The type system associated with the current compilation unit.
+  TypeSystem typeSystem;
+
+  /// The object used to compute the values of features.
+  FeatureComputer featureComputer;
+
+  /// Initialize a newly created collector to add data points to the given
+  /// [data].
+  RelevanceDataCollector(this.data);
+
+  /// Initialize this collector prior to visiting the unit in the [result].
+  void initializeFrom(ResolvedUnitResult result) {
+    unit = result.unit;
+  }
+
+  @override
+  void visitAdjacentStrings(AdjacentStrings node) {
+    // There are no completions.
+    super.visitAdjacentStrings(node);
+  }
+
+  @override
+  void visitAnnotation(Annotation node) {
+    _recordDataForNode('Annotation_name', node.name);
+    super.visitAnnotation(node);
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    var context = _argumentListContext(node);
+    for (var argument in node.arguments) {
+      var realArgument = argument;
+      var argumentKind = 'unnamed';
+      if (argument is NamedExpression) {
+        realArgument = argument.expression;
+        argumentKind = 'named';
+      }
+      _recordDataForNode('ArgumentList_${context}_$argumentKind', realArgument,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitArgumentList(node);
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    _recordDataForNode('AsExpression_type', node.type);
+    super.visitAsExpression(node);
+  }
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {
+    _recordDataForNode('AssertInitializer_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('AssertInitializer_message', node.message,
+        allowedKeywords: expressionKeywords);
+    super.visitAssertInitializer(node);
+  }
+
+  @override
+  void visitAssertStatement(AssertStatement node) {
+    _recordDataForNode('AssertStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('AssertStatement_message', node.message,
+        allowedKeywords: expressionKeywords);
+    super.visitAssertStatement(node);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    _recordDataForNode('AssignmentExpression_rightHandSide', node.rightHandSide,
+        allowedKeywords: expressionKeywords);
+    super.visitAssignmentExpression(node);
+  }
+
+  @override
+  void visitAwaitExpression(AwaitExpression node) {
+    _recordDataForNode('AwaitExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitAwaitExpression(node);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    _recordDataForNode(
+        'BinaryExpression_${node.operator}_rightOperand', node.rightOperand,
+        allowedKeywords: expressionKeywords);
+    super.visitBinaryExpression(node);
+  }
+
+  @override
+  void visitBlock(Block node) {
+    for (var statement in node.statements) {
+      // Function declaration statements that have no return type begin with an
+      // identifier but don't have an element kind associated with the
+      // identifier.
+      _recordDataForNode('Block_statement', statement,
+          allowedKeywords: statementKeywords);
+    }
+    super.visitBlock(node);
+  }
+
+  @override
+  void visitBlockFunctionBody(BlockFunctionBody node) {
+    _recordKeyword('BlockFunctionBody_start', node,
+        allowedKeywords: functionBodyKeywords);
+    super.visitBlockFunctionBody(node);
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    _recordKeyword('BooleanLiteral_start', node);
+    super.visitBooleanLiteral(node);
+  }
+
+  @override
+  void visitBreakStatement(BreakStatement node) {
+    // The token following the `break` (if there is one) is always a label.
+    super.visitBreakStatement(node);
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    for (var cascade in node.cascadeSections) {
+      _recordDataForNode('CascadeExpression_cascadeSection', cascade);
+    }
+    super.visitCascadeExpression(node);
+  }
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    _recordDataForNode('CatchClause_exceptionType', node.exceptionType);
+    super.visitCatchClause(node);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    var context = 'name';
+    if (node.extendsClause != null) {
+      _recordKeyword('ClassDeclaration_$context', node.extendsClause,
+          allowedKeywords: [Keyword.EXTENDS]);
+      context = 'extends';
+    }
+    if (node.withClause != null) {
+      _recordKeyword('ClassDeclaration_$context', node.withClause);
+      context = 'with';
+    }
+    _recordKeyword('ClassDeclaration_$context', node.implementsClause,
+        allowedKeywords: [Keyword.IMPLEMENTS]);
+
+    for (var member in node.members) {
+      _recordDataForNode('ClassDeclaration_member', member,
+          allowedKeywords: memberKeywords);
+    }
+    super.visitClassDeclaration(node);
+  }
+
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    _recordDataForNode('ClassTypeAlias_superclass', node.superclass);
+    var context = 'superclass';
+    if (node.withClause != null) {
+      _recordKeyword('ClassTypeAlias_$context', node.withClause);
+      context = 'with';
+    }
+    _recordKeyword('ClassTypeAlias_$context', node.implementsClause);
+    super.visitClassTypeAlias(node);
+  }
+
+  @override
+  void visitComment(Comment node) {
+    // There are no completions.
+    super.visitComment(node);
+  }
+
+  @override
+  void visitCommentReference(CommentReference node) {
+    _recordDataForNode('CommentReference_identifier', node.identifier);
+    super.visitCommentReference(node);
+  }
+
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    enclosingLibrary = node.declaredElement.library;
+    typeProvider = enclosingLibrary.typeProvider;
+    typeSystem = enclosingLibrary.typeSystem;
+    inheritanceManager = InheritanceManager3();
+    featureComputer = FeatureComputer(typeSystem, typeProvider);
+
+    for (var directive in node.directives) {
+      _recordKeyword('CompilationUnit_directive', directive,
+          allowedKeywords: directiveKeywords);
+    }
+    for (var declaration in node.declarations) {
+      _recordDataForNode('CompilationUnit_declaration', declaration,
+          allowedKeywords: declarationKeywords);
+    }
+    super.visitCompilationUnit(node);
+
+    featureComputer = null;
+    inheritanceManager = null;
+    typeSystem = null;
+    typeProvider = null;
+    enclosingLibrary = null;
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    _recordDataForNode(
+        'ConditionalExpression_thenExpression', node.thenExpression,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode(
+        'ConditionalExpression_elseExpression', node.elseExpression,
+        allowedKeywords: expressionKeywords);
+    super.visitConditionalExpression(node);
+  }
+
+  @override
+  void visitConfiguration(Configuration node) {
+    // There are no completions.
+    super.visitConfiguration(node);
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    _recordDataForNode('ConstructorDeclaration_returnType', node.returnType);
+    for (var initializer in node.initializers) {
+      _recordDataForNode('ConstructorDeclaration_initializer', initializer);
+    }
+    super.visitConstructorDeclaration(node);
+  }
+
+  @override
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    _recordDataForNode(
+        'ConstructorFieldInitializer_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitConstructorFieldInitializer(node);
+  }
+
+  @override
+  void visitConstructorName(ConstructorName node) {
+    // The token following the `.` is always the name of a constructor.
+    super.visitConstructorName(node);
+  }
+
+  @override
+  void visitContinueStatement(ContinueStatement node) {
+    // The token following the `continue` (if there is one) is always a label.
+    super.visitContinueStatement(node);
+  }
+
+  @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    // There are no completions.
+    super.visitDeclaredIdentifier(node);
+  }
+
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _recordDataForNode('DefaultFormalParameter_defaultValue', node.defaultValue,
+        allowedKeywords: expressionKeywords);
+    super.visitDefaultFormalParameter(node);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    _recordDataForNode('DoStatement_body', node.body,
+        allowedKeywords: statementKeywords);
+    _recordDataForNode('DoStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    super.visitDoStatement(node);
+  }
+
+  @override
+  void visitDottedName(DottedName node) {
+    // The components are always identifiers.
+    super.visitDottedName(node);
+  }
+
+  @override
+  void visitDoubleLiteral(DoubleLiteral node) {
+    // There are no completions.
+    super.visitDoubleLiteral(node);
+  }
+
+  @override
+  void visitEmptyFunctionBody(EmptyFunctionBody node) {
+    // There are no completions.
+    super.visitEmptyFunctionBody(node);
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {
+    // There are no completions.
+    super.visitEmptyStatement(node);
+  }
+
+  @override
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    // There are no completions.
+    super.visitEnumConstantDeclaration(node);
+  }
+
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {
+    // There are no completions.
+    super.visitEnumDeclaration(node);
+  }
+
+  @override
+  void visitExportDirective(ExportDirective node) {
+    var context = 'uri';
+    if (node.configurations.isNotEmpty) {
+      _recordKeyword('ImportDirective_$context', node.configurations[0],
+          allowedKeywords: exportKeywords);
+      context = 'configurations';
+    }
+    if (node.combinators.isNotEmpty) {
+      _recordKeyword('ImportDirective_$context', node.combinators[0],
+          allowedKeywords: exportKeywords);
+    }
+    for (var combinator in node.combinators) {
+      _recordKeyword('ImportDirective_combinator', combinator,
+          allowedKeywords: exportKeywords);
+    }
+    super.visitExportDirective(node);
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _recordKeyword('ExpressionFunctionBody_start', node,
+        allowedKeywords: functionBodyKeywords);
+    _recordDataForNode('ExpressionFunctionBody_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitExpressionFunctionBody(node);
+  }
+
+  @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    _recordDataForNode('ExpressionStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitExpressionStatement(node);
+  }
+
+  @override
+  void visitExtendsClause(ExtendsClause node) {
+    _recordDataForNode('ExtendsClause_superclass', node.superclass);
+    super.visitExtendsClause(node);
+  }
+
+  @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    _recordDataForNode('ExtensionDeclaration_extendedType', node.extendedType);
+    for (var member in node.members) {
+      _recordDataForNode('ExtensionDeclaration_member', member,
+          allowedKeywords: memberKeywords);
+    }
+    super.visitExtensionDeclaration(node);
+  }
+
+  @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    // There are no completions.
+    super.visitExtensionOverride(node);
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    _recordDataForNode('FieldDeclaration_fields', node.fields);
+    super.visitFieldDeclaration(node);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    // The completions after `this.` are always existing fields.
+    super.visitFieldFormalParameter(node);
+  }
+
+  @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _recordDataForNode(
+        'ForEachPartsWithDeclaration_loopVariable', node.loopVariable);
+    _recordDataForNode('ForEachPartsWithDeclaration_iterable', node.iterable,
+        allowedKeywords: expressionKeywords);
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    _recordDataForNode(
+        'ForEachPartsWithIdentifier_identifier', node.identifier);
+    _recordDataForNode('ForEachPartsWithIdentifier_iterable', node.iterable,
+        allowedKeywords: expressionKeywords);
+    super.visitForEachPartsWithIdentifier(node);
+  }
+
+  @override
+  void visitForElement(ForElement node) {
+    _recordDataForNode('ForElement_forLoopParts', node.forLoopParts);
+    _recordDataForNode('ForElement_body', node.body);
+    super.visitForElement(node);
+  }
+
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    for (var parameter in node.parameters) {
+      _recordDataForNode('FormalParameterList_parameter', parameter,
+          allowedKeywords: [Keyword.COVARIANT]);
+    }
+    super.visitFormalParameterList(node);
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _recordDataForNode('ForParts_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    for (var updater in node.updaters) {
+      _recordDataForNode('ForParts_updater', updater,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitForPartsWithDeclarations(node);
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    _recordDataForNode('ForParts_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    for (var updater in node.updaters) {
+      _recordDataForNode('ForParts_updater', updater,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitForPartsWithExpression(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    _recordDataForNode('ForStatement_forLoopParts', node.forLoopParts);
+    _recordDataForNode('ForStatement_body', node.body,
+        allowedKeywords: statementKeywords);
+    super.visitForStatement(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    _recordDataForNode('FunctionDeclaration_returnType', node.returnType);
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    // There are no completions.
+    super.visitFunctionDeclarationStatement(node);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // There are no completions.
+    super.visitFunctionExpression(node);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    // There are no completions.
+    super.visitFunctionExpressionInvocation(node);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    // There are no completions.
+    super.visitFunctionTypeAlias(node);
+  }
+
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    // There are no completions.
+    super.visitFunctionTypedFormalParameter(node);
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    // There are no completions.
+    super.visitGenericFunctionType(node);
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    _recordDataForNode('GenericTypeAlias_functionType', node.functionType,
+        allowedKeywords: [Keyword.FUNCTION]);
+    super.visitGenericTypeAlias(node);
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    for (var hiddenName in node.hiddenNames) {
+      _recordDataForNode('HideCombinator_hiddenName', hiddenName);
+    }
+    super.visitHideCombinator(node);
+  }
+
+  @override
+  void visitIfElement(IfElement node) {
+    _recordDataForNode('IfElement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('IfElement_thenElement', node.thenElement);
+    _recordDataForNode('IfElement_elseElement', node.elseElement);
+    super.visitIfElement(node);
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    _recordDataForNode('IfStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('IfStatement_thenStatement', node.thenStatement,
+        allowedKeywords: statementKeywords);
+    _recordDataForNode('IfStatement_elseStatement', node.elseStatement,
+        allowedKeywords: statementKeywords);
+    super.visitIfStatement(node);
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    // At the start of each type name.
+    for (var typeName in node.interfaces) {
+      _recordDataForNode('ImplementsClause_interface', typeName);
+    }
+    super.visitImplementsClause(node);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    var context = 'uri';
+    if (node.deferredKeyword != null) {
+      data.recordKeyword('ImportDirective_$context', node.deferredKeyword.type);
+      context = 'deferred';
+    }
+    if (node.asKeyword != null) {
+      data.recordKeyword('ImportDirective_$context', node.asKeyword.type);
+      context = 'prefix';
+    }
+    if (node.configurations.isNotEmpty) {
+      _recordKeyword('ImportDirective_$context', node.configurations[0],
+          allowedKeywords: importKeywords);
+      context = 'configurations';
+    }
+    if (node.combinators.isNotEmpty) {
+      _recordKeyword('ImportDirective_$context', node.combinators[0],
+          allowedKeywords: importKeywords);
+    }
+    for (var combinator in node.combinators) {
+      _recordKeyword('ImportDirective_combinator', combinator,
+          allowedKeywords: importKeywords);
+    }
+    super.visitImportDirective(node);
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    _recordDataForNode('IndexExpression_index', node.index,
+        allowedKeywords: expressionKeywords);
+    super.visitIndexExpression(node);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _recordDataForNode(
+        'InstanceCreationExpression_constructorName', node.constructorName);
+    super.visitInstanceCreationExpression(node);
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    // There are no completions.
+    super.visitIntegerLiteral(node);
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    // TODO(brianwilkerson) Consider splitting this based on whether the
+    //  expression is a simple identifier ('$') or a full expression ('${').
+    _recordDataForNode('InterpolationExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitInterpolationExpression(node);
+  }
+
+  @override
+  void visitInterpolationString(InterpolationString node) {
+    // There are no completions.
+    super.visitInterpolationString(node);
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    _recordDataForNode('IsExpression_type', node.type);
+    super.visitIsExpression(node);
+  }
+
+  @override
+  void visitLabel(Label node) {
+    // There are no completions.
+    super.visitLabel(node);
+  }
+
+  @override
+  void visitLabeledStatement(LabeledStatement node) {
+    _recordDataForNode('LabeledStatement_statement', node.statement,
+        allowedKeywords: statementKeywords);
+    super.visitLabeledStatement(node);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    // There are no completions.
+    super.visitLibraryDirective(node);
+  }
+
+  @override
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    // There are no completions.
+    super.visitLibraryIdentifier(node);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    for (var element in node.elements) {
+      _recordDataForNode('ListLiteral_element', element,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitListLiteral(node);
+  }
+
+  @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    _recordDataForNode('MapLiteralEntry_value', node.value,
+        allowedKeywords: expressionKeywords);
+    super.visitMapLiteralEntry(node);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    _recordDataForNode('MethodDeclaration_returnType', node.returnType);
+    super.visitMethodDeclaration(node);
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    // There are no completions.
+    super.visitMethodInvocation(node);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    var context = 'name';
+    if (node.onClause != null) {
+      _recordKeyword('MixinDeclaration_$context', node.onClause,
+          allowedKeywords: [Keyword.ON]);
+      context = 'on';
+    }
+    _recordKeyword('MixinDeclaration_$context', node.implementsClause,
+        allowedKeywords: [Keyword.IMPLEMENTS]);
+
+    for (var member in node.members) {
+      _recordDataForNode('MixinDeclaration_member', member,
+          allowedKeywords: memberKeywords);
+    }
+    super.visitMixinDeclaration(node);
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression node) {
+    // Named expressions only occur in argument lists and are handled there.
+    super.visitNamedExpression(node);
+  }
+
+  @override
+  void visitNativeClause(NativeClause node) {
+    // There are no completions.
+    super.visitNativeClause(node);
+  }
+
+  @override
+  void visitNativeFunctionBody(NativeFunctionBody node) {
+    // There are no completions.
+    super.visitNativeFunctionBody(node);
+  }
+
+  @override
+  void visitNullLiteral(NullLiteral node) {
+    // There are no completions.
+    super.visitNullLiteral(node);
+  }
+
+  @override
+  void visitOnClause(OnClause node) {
+    for (var constraint in node.superclassConstraints) {
+      _recordDataForNode('OnClause_superclassConstraint', constraint);
+    }
+    super.visitOnClause(node);
+  }
+
+  @override
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    _recordDataForNode('ParenthesizedExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitParenthesizedExpression(node);
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    // There are no completions.
+    super.visitPartDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    // There are no completions.
+    super.visitPartOfDirective(node);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    // There are no completions.
+    super.visitPostfixExpression(node);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    // There are no completions.
+    super.visitPrefixedIdentifier(node);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    _recordDataForNode(
+        'PrefixExpression_${node.operator}_operand', node.operand,
+        allowedKeywords: expressionKeywords);
+    super.visitPrefixExpression(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    _recordDataForNode('PropertyAccess_propertyName', node.propertyName);
+    super.visitPropertyAccess(node);
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    // There are no completions.
+    super.visitRedirectingConstructorInvocation(node);
+  }
+
+  @override
+  void visitRethrowExpression(RethrowExpression node) {
+    // There are no completions.
+    super.visitRethrowExpression(node);
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    _recordDataForNode('ReturnStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitReturnStatement(node);
+  }
+
+  @override
+  void visitScriptTag(ScriptTag node) {
+    // There are no completions.
+    super.visitScriptTag(node);
+  }
+
+  @override
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    for (var element in node.elements) {
+      _recordDataForNode('SetOrMapLiteral_element', element,
+          allowedKeywords: expressionKeywords);
+    }
+    super.visitSetOrMapLiteral(node);
+  }
+
+  @override
+  void visitShowCombinator(ShowCombinator node) {
+    for (var name in node.shownNames) {
+      _recordDataForNode('ShowCombinator_shownName', name);
+    }
+    super.visitShowCombinator(node);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    // There are no completions.
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    // There are no completions.
+    super.visitSimpleStringLiteral(node);
+  }
+
+  @override
+  void visitSpreadElement(SpreadElement node) {
+    _recordDataForNode('SpreadElement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitSpreadElement(node);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    // There are no completions.
+    super.visitStringInterpolation(node);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    // There are no completions.
+    super.visitSuperConstructorInvocation(node);
+  }
+
+  @override
+  void visitSuperExpression(SuperExpression node) {
+    // There are no completions.
+    super.visitSuperExpression(node);
+  }
+
+  @override
+  void visitSwitchCase(SwitchCase node) {
+    _recordDataForNode('SwitchCase_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    for (var statement in node.statements) {
+      _recordDataForNode('SwitchMember_statement', statement,
+          allowedKeywords: statementKeywords);
+    }
+    super.visitSwitchCase(node);
+  }
+
+  @override
+  void visitSwitchDefault(SwitchDefault node) {
+    for (var statement in node.statements) {
+      _recordDataForNode('SwitchMember_statement', statement,
+          allowedKeywords: statementKeywords);
+    }
+    super.visitSwitchDefault(node);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    _recordDataForNode('SwitchStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitSwitchStatement(node);
+  }
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    // There are no completions.
+    super.visitSymbolLiteral(node);
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    // There are no completions.
+    super.visitThisExpression(node);
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    _recordDataForNode('ThrowExpression_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitThrowExpression(node);
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    // There are no completions.
+    super.visitTopLevelVariableDeclaration(node);
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    var context = 'try';
+    for (var clause in node.catchClauses) {
+      _recordKeyword('TryStatement_$context', clause,
+          allowedKeywords: [Keyword.ON]);
+      context = 'catch';
+    }
+    if (node.finallyKeyword != null) {
+      data.recordKeyword('TryStatement_$context', node.finallyKeyword.type);
+    }
+    super.visitTryStatement(node);
+  }
+
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    for (var typeArgument in node.arguments) {
+      _recordDataForNode('TypeArgumentList_argument', typeArgument);
+    }
+    super.visitTypeArgumentList(node);
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    // There are no completions.
+    super.visitTypeName(node);
+  }
+
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    if (node.bound != null) {
+      _recordDataForNode('TypeParameter_bound', node.bound);
+    }
+    super.visitTypeParameter(node);
+  }
+
+  @override
+  void visitTypeParameterList(TypeParameterList node) {
+    // There are no completions.
+    super.visitTypeParameterList(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    var keywords = node.parent.parent is FieldDeclaration
+        ? [Keyword.COVARIANT, ...expressionKeywords]
+        : expressionKeywords;
+    _recordDataForNode('VariableDeclaration_initializer', node.initializer,
+        allowedKeywords: keywords);
+    super.visitVariableDeclaration(node);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    _recordDataForNode('VariableDeclarationList_type', node.type);
+    super.visitVariableDeclarationList(node);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    // There are no completions.
+    super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    _recordDataForNode('WhileStatement_condition', node.condition,
+        allowedKeywords: expressionKeywords);
+    _recordDataForNode('WhileStatement_body', node.body,
+        allowedKeywords: statementKeywords);
+    super.visitWhileStatement(node);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    for (var typeName in node.mixinTypes) {
+      _recordDataForNode('WithClause_mixinType', typeName);
+    }
+    super.visitWithClause(node);
+  }
+
+  @override
+  void visitYieldStatement(YieldStatement node) {
+    _recordDataForNode('YieldStatement_expression', node.expression,
+        allowedKeywords: expressionKeywords);
+    super.visitYieldStatement(node);
+  }
+
+  /// Return the context in which the [node] occurs. The [node] is expected to
+  /// be the parent of the argument expression.
+  String _argumentListContext(AstNode node) {
+    if (node is ArgumentList) {
+      var parent = node.parent;
+      if (parent is Annotation) {
+        return 'annotation';
+      } else if (parent is ExtensionOverride) {
+        return 'extensionOverride';
+      } else if (parent is FunctionExpressionInvocation) {
+        return 'function';
+      } else if (parent is InstanceCreationExpression) {
+        if (Flutter.instance.isWidgetType(parent.staticType)) {
+          return 'widgetConstructor';
+        }
+        return 'constructor';
+      } else if (parent is MethodInvocation) {
+        return 'method';
+      } else if (parent is RedirectingConstructorInvocation) {
+        return 'constructorRedirect';
+      } else if (parent is SuperConstructorInvocation) {
+        return 'constructorRedirect';
+      }
+    } else if (node is AssignmentExpression ||
+        node is BinaryExpression ||
+        node is PrefixExpression ||
+        node is PostfixExpression) {
+      return 'operator';
+    } else if (node is IndexExpression) {
+      return 'index';
+    }
+    throw ArgumentError(
+        'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
+  }
+
+  /// Return the first child of the [node] that is neither a comment nor an
+  /// annotation.
+  SyntacticEntity _firstChild(AstNode node) {
+    var children = node.childEntities.toList();
+    for (var i = 0; i < children.length; i++) {
+      var child = children[i];
+      if (child is! Comment && child is! Annotation) {
+        return child;
+      }
+    }
+    return null;
+  }
+
+  /// Return the element associated with the left-most identifier that is a
+  /// child of the [node].
+  Element _leftMostElement(AstNode node) =>
+      _leftMostIdentifier(node)?.staticElement;
+
+  /// Return the left-most child of the [node] if it is a simple identifier, or
+  /// `null` if the left-most child is not a simple identifier. Comments and
+  /// annotations are ignored for this purpose.
+  SimpleIdentifier _leftMostIdentifier(AstNode node) {
+    var currentNode = node;
+    while (currentNode != null && currentNode is! SimpleIdentifier) {
+      var firstChild = _firstChild(currentNode);
+      if (firstChild is AstNode) {
+        currentNode = firstChild;
+      } else {
+        currentNode = null;
+      }
+    }
+    if (currentNode is SimpleIdentifier && currentNode.inDeclarationContext()) {
+      return null;
+    }
+    return currentNode;
+  }
+
+  /// Return the element kind of the element associated with the left-most
+  /// identifier that is a child of the [node].
+  ElementKind _leftMostKind(AstNode node) {
+    if (node is InstanceCreationExpression) {
+      return featureComputer
+          .computeElementKind(node.constructorName.staticElement);
+    }
+    var element = _leftMostElement(node);
+    if (element == null) {
+      return null;
+    }
+    if (element is ClassElement) {
+      var parent = node.parent;
+      if (parent is Annotation && parent.arguments != null) {
+        element = parent.element;
+      }
+    }
+    return featureComputer.computeElementKind(element);
+  }
+
+  /// Return the left-most token that is a child of the [node].
+  Token _leftMostToken(AstNode node) {
+    SyntacticEntity entity = node;
+    while (entity is AstNode) {
+      entity = _firstChild(entity as AstNode);
+    }
+    if (entity is Token) {
+      return entity;
+    }
+    return null;
+  }
+
+  /// Record information about the given [node] occurring in the given
+  /// [context].
+  void _recordDataForNode(String context, AstNode node,
+      {List<Keyword> allowedKeywords = noKeywords}) {
+    _recordElementKind(context, node);
+    _recordKeyword(context, node, allowedKeywords: allowedKeywords);
+  }
+
+  /// Record the element kind of the element associated with the left-most
+  /// identifier that is a child of the [node] in the given [context].
+  void _recordElementKind(String context, AstNode node) {
+    if (node != null) {
+      var kind = _leftMostKind(node);
+      if (kind != null) {
+        data.recordElementKind(context, kind);
+        if (node is Expression) {
+          data.recordElementKind('Expression', kind);
+        } else if (node is Statement) {
+          data.recordElementKind('Statement', kind);
+        }
+      }
+    }
+  }
+
+  /// If the left-most token of the [node] is a keyword, then record that it
+  /// occurred in the given [context].
+  void _recordKeyword(String context, AstNode node,
+      {List<Keyword> allowedKeywords = noKeywords}) {
+    if (node != null) {
+      var token = _leftMostToken(node);
+      if (token.isKeyword) {
+        var keyword = token.type;
+        if (keyword == Keyword.NEW) {
+          // We don't suggest `new`, so we don't care about the frequency with
+          // which it is used.
+          return;
+        } else if (token.keyword.isBuiltInOrPseudo &&
+            !allowedKeywords.contains(token.keyword)) {
+          // These keywords can be used as identifiers, so determine whether
+          // it is being used as a keyword or an identifier.
+          return;
+        }
+        data.recordKeyword(context, keyword);
+      }
+    }
+  }
+}
+
+/// An object used to compute metrics for a single file or directory.
+class RelevanceMetricsComputer {
+  /// The metrics data that was computed.
+  final RelevanceData data = RelevanceData();
+
+  /// Initialize a newly created metrics computer that can compute the metrics
+  /// in one or more files and directories.
+  RelevanceMetricsComputer();
+
+  /// Compute the metrics for the file(s) in the [rootPath].
+  /// If [corpus] is true, treat rootPath as a container of packages, creating
+  /// a new context collection for each subdirectory.
+  Future<void> compute(String rootPath, {@required bool verbose}) async {
+    final collection = AnalysisContextCollection(
+      includedPaths: [rootPath],
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
+    );
+    final collector = RelevanceDataCollector(data);
+    for (var context in collection.contexts) {
+      await _computeInContext(context.contextRoot, collector, verbose: verbose);
+    }
+  }
+
+  /// Compute the metrics for the files in the context [root], creating a
+  /// separate context collection to prevent accumulating memory. The metrics
+  /// should be captured in the [collector]. Include additional details in the
+  /// output if [verbose] is `true`.
+  Future<void> _computeInContext(
+      ContextRoot root, RelevanceDataCollector collector,
+      {@required bool verbose}) async {
+    // Create a new collection to avoid consuming large quantities of memory.
+    final collection = AnalysisContextCollection(
+      includedPaths: root.includedPaths.toList(),
+      excludedPaths: root.excludedPaths.toList(),
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
+    );
+    var context = collection.contexts[0];
+    for (var filePath in context.contextRoot.analyzedFiles()) {
+      if (AnalysisEngine.isDartFileName(filePath)) {
+        try {
+          var resolvedUnitResult =
+              await context.currentSession.getResolvedUnit(filePath);
+          //
+          // Check for errors that cause the file to be skipped.
+          //
+          if (resolvedUnitResult == null) {
+            print('File $filePath skipped because resolved unit was null.');
+            if (verbose) {
+              print('');
+            }
+            continue;
+          } else if (resolvedUnitResult.state != ResultState.VALID) {
+            print('File $filePath skipped because it could not be analyzed.');
+            if (verbose) {
+              print('');
+            }
+            continue;
+          } else if (hasError(resolvedUnitResult)) {
+            if (verbose) {
+              print('File $filePath skipped due to errors:');
+              for (var error in resolvedUnitResult.errors
+                  .where((e) => e.severity == Severity.error)) {
+                print('  ${error.toString()}');
+              }
+              print('');
+            } else {
+              print('File $filePath skipped due to analysis errors.');
+            }
+            continue;
+          }
+
+          collector.initializeFrom(resolvedUnitResult);
+          resolvedUnitResult.unit.accept(collector);
+        } catch (exception, stacktrace) {
+          print('Exception caught analyzing: "$filePath"');
+          print(exception);
+          print(stacktrace);
+        }
+      }
+    }
+  }
+
+  /// Return `true` if the [result] contains an error.
+  static bool hasError(ResolvedUnitResult result) {
+    for (var error in result.errors) {
+      if (error.severity == Severity.error) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/// A class used to write relevance data as a set of tables in a generated Dart
+/// file.
+class RelevanceTableWriter {
+  final StringSink sink;
+
+  RelevanceTableWriter(this.sink);
+
+  void write(RelevanceData data) {
+    writeFileHeader();
+    writeElementKindTable(data);
+    writeKeywordTable(data);
+  }
+
+  void writeElementKindTable(RelevanceData data) {
+    sink.writeln();
+    sink.write('''
+/// A table keyed by completion location and element kind whose values are the
+/// ranges of the relevance of those element kinds in those locations.
+const elementKindRelevance = {
+''');
+
+    var byKind = data.byKind;
+    var completionLocations = byKind.keys.toList()..sort();
+    for (var completionLocation in completionLocations) {
+      var counts = byKind[completionLocation];
+      if (_hasElementKind(counts)) {
+        var totalCount = _totalCount(counts);
+        // TODO(brianwilkerson) If two element kinds have the same count they
+        //  ought to have the same probability. This doesn't correctly do that.
+        var entries = counts.entries.toList()
+          ..sort((first, second) => first.value.compareTo(second.value));
+
+        sink.write("  '");
+        sink.write(completionLocation);
+        sink.writeln("': {");
+        var cumulativeCount = 0;
+        var lowerBound = 0.0;
+        for (var entry in entries) {
+          var kind = entry.key;
+          cumulativeCount += entry.value;
+          var upperBound = cumulativeCount / totalCount;
+          if (kind is _ElementKind) {
+            sink.write('    ElementKind.');
+            sink.write(kind.elementKind.name);
+            sink.write(': ProbabilityRange(lower: ');
+            sink.write(lowerBound.toStringAsFixed(3));
+            sink.write(', upper: ');
+            sink.write(upperBound.toStringAsFixed(3));
+            sink.writeln('),');
+          }
+          lowerBound = upperBound;
+        }
+        sink.writeln('  },');
+      }
+    }
+    sink.writeln('};');
+  }
+
+  void writeFileHeader() {
+    sink.write('''
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart",
+// passing it the location of a corpus of code that is large enough for the
+// computed values to be statistically meaningful.
+
+import 'package:analysis_server/src/services/completion/dart/probability_range.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+''');
+  }
+
+  void writeKeywordTable(RelevanceData data) {
+    sink.writeln();
+    sink.write('''
+/// A table keyed by completion location and keyword whose values are the
+/// ranges of the relevance of those keywords in those locations.
+const keywordRelevance = {
+''');
+
+    var byKind = data.byKind;
+    var completionLocations = byKind.keys.toList()..sort();
+    for (var completionLocation in completionLocations) {
+      var counts = byKind[completionLocation];
+      if (_hasKeyword(counts)) {
+        var totalCount = _totalCount(counts);
+        // TODO(brianwilkerson) If two keywords have the same count they ought to
+        //  have the same probability. This doesn't correctly do that.
+        var entries = counts.entries.toList()
+          ..sort((first, second) => first.value.compareTo(second.value));
+
+        sink.write("  '");
+        sink.write(completionLocation);
+        sink.writeln("': {");
+        var cumulativeCount = 0;
+        var lowerBound = 0.0;
+        for (var entry in entries) {
+          var kind = entry.key;
+          cumulativeCount += entry.value;
+          var upperBound = cumulativeCount / totalCount;
+          if (kind is _Keyword) {
+            sink.write("    '");
+            sink.write(kind.keyword.lexeme);
+            sink.write("': ProbabilityRange(lower: ");
+            sink.write(lowerBound.toStringAsFixed(3));
+            sink.write(', upper: ');
+            sink.write(upperBound.toStringAsFixed(3));
+            sink.writeln('),');
+          }
+          lowerBound = upperBound;
+        }
+        sink.writeln('  },');
+      }
+    }
+    sink.writeln('};');
+  }
+
+  /// Return `true` if the table of [counts] contains at least one key that is
+  /// an element kind.
+  bool _hasElementKind(Map<_Kind, int> counts) {
+    for (var kind in counts.keys) {
+      if (kind is _ElementKind) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Return `true` if the table of [counts] contains at least one key that is a
+  /// keyword.
+  bool _hasKeyword(Map<_Kind, int> counts) {
+    for (var kind in counts.keys) {
+      if (kind is _Keyword) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Return the total of the counts in the given table of [counts].
+  int _totalCount(Map<_Kind, int> counts) {
+    return counts.values
+        .fold(0, (previousValue, value) => previousValue + value);
+  }
+}
+
+/// A wrapper for an element kind to allow keywords and element kinds to be used
+/// as keys in a single table.
+class _ElementKind extends _Kind {
+  static final Map<ElementKind, _ElementKind> instances = {};
+
+  final ElementKind elementKind;
+
+  factory _ElementKind(ElementKind elementKind) =>
+      instances.putIfAbsent(elementKind, () => _ElementKind._(elementKind));
+
+  _ElementKind._(this.elementKind);
+}
+
+/// A wrapper for a keyword to allow keywords and element kinds to be used as
+/// keys in a single table.
+class _Keyword extends _Kind {
+  static final Map<Keyword, _Keyword> instances = {};
+
+  final Keyword keyword;
+
+  factory _Keyword(Keyword keyword) =>
+      instances.putIfAbsent(keyword, () => _Keyword._(keyword));
+
+  _Keyword._(this.keyword);
+}
+
+/// A superclass for [_ElementKind] and [_Keyword] to allow keywords and element
+/// kinds to be used as keys in a single table.
+class _Kind {}
diff --git a/pkg/analysis_server/tool/completion_metrics/visitors.dart b/pkg/analysis_server/tool/code_completion/visitors.dart
similarity index 100%
rename from pkg/analysis_server/tool/completion_metrics/visitors.dart
rename to pkg/analysis_server/tool/code_completion/visitors.dart
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
deleted file mode 100644
index 13f27be..0000000
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ /dev/null
@@ -1,1258 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io' as io;
-import 'dart:math' as math;
-
-import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
-import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
-import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analysis_server/src/services/completion/completion_core.dart';
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/dart/utilities.dart';
-import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/dart/analysis/context_root.dart';
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart'
-    show
-        ClassElement,
-        Element,
-        ExtensionElement,
-        ClassMemberElement,
-        ExecutableElement,
-        FieldElement,
-        VariableElement;
-import 'package:analyzer/diagnostic/diagnostic.dart';
-import 'package:analyzer/error/error.dart' as err;
-import 'package:analyzer/file_system/overlay_file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/services/available_declarations.dart';
-import 'package:analyzer/src/util/performance/operation_performance.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' show ElementKind;
-import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
-import 'package:args/args.dart';
-import 'package:meta/meta.dart';
-
-import 'metrics_util.dart';
-import 'output_utilities.dart';
-import 'visitors.dart';
-
-Future<void> main(List<String> args) async {
-  var parser = createArgParser();
-  var result = parser.parse(args);
-
-  if (!validArguments(parser, result)) {
-    return io.exit(1);
-  }
-
-  var root = result.rest[0];
-  print('Analyzing root: "$root"');
-  var stopwatch = Stopwatch()..start();
-  var code = await CompletionMetricsComputer(root,
-          availableSuggestions: result[AVAILABLE_SUGGESTIONS],
-          overlay: result[OVERLAY],
-          skipOldRelevance: result[SKIP_OLD_RELEVANCE],
-          verbose: result[VERBOSE])
-      .compute();
-  stopwatch.stop();
-
-  var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
-  print('');
-  print('Metrics computed in $duration');
-  return io.exit(code);
-}
-
-const String AVAILABLE_SUGGESTIONS = 'available-suggestions';
-
-/// An option to control whether and how overlays should be produced.
-const String OVERLAY = 'overlay';
-
-/// A mode indicating that no overlays should be produced.
-const String OVERLAY_NONE = 'none';
-
-/// A mode indicating that everything from the completion offset to the end of
-/// the file should be removed.
-const String OVERLAY_REMOVE_REST_OF_FILE = 'remove-rest-of-file';
-
-/// A mode indicating that the token whose offset is the same as the
-/// completion offset should be removed.
-const String OVERLAY_REMOVE_TOKEN = 'remove-token';
-
-/// A flag that causes metrics using the old relevance scores to not be
-/// produced.
-const String SKIP_OLD_RELEVANCE = 'skip-old-relevance';
-
-/// A flag that causes additional output to be produced.
-const String VERBOSE = 'verbose';
-
-/// A [Counter] to track the performance of the new relevance to the old
-/// relevance.
-Counter oldVsNewComparison =
-    Counter('use old vs new relevance rank comparison');
-
-/// Create a parser that can be used to parse the command-line arguments.
-ArgParser createArgParser() {
-  return ArgParser()
-    ..addOption(
-      'help',
-      abbr: 'h',
-      help: 'Print this help message.',
-    )
-    ..addFlag(
-      VERBOSE,
-      abbr: 'v',
-      help: 'Print additional information about the analysis',
-      negatable: false,
-    )
-    ..addFlag(AVAILABLE_SUGGESTIONS,
-        abbr: 'a',
-        help: 'Use the available suggestions feature in the Analysis Server '
-            'when computing the set of code completions. With this feature '
-            'enabled, completion will match the support in the Dart Plugin for '
-            'IntelliJ, without this enabled the completion support matches '
-            'the support in LSP.',
-        defaultsTo: false,
-        negatable: false)
-    ..addOption(OVERLAY,
-        allowed: [
-          OVERLAY_NONE,
-          OVERLAY_REMOVE_TOKEN,
-          OVERLAY_REMOVE_REST_OF_FILE
-        ],
-        defaultsTo: OVERLAY_NONE,
-        help:
-            'Before attempting a completion at the location of each token, the '
-            'token can be removed, or the rest of the file can be removed to test '
-            'code completion with diverse methods. The default mode is to '
-            'complete at the start of the token without modifying the file.')
-    ..addFlag(SKIP_OLD_RELEVANCE,
-        help: 'Used to skip the computation of suggestions using the old '
-            'relevance scores.',
-        defaultsTo: false,
-        negatable: false);
-}
-
-/// Print usage information for this tool.
-void printUsage(ArgParser parser, {String error}) {
-  if (error != null) {
-    print(error);
-    print('');
-  }
-  print('usage: dart completion_metrics.dart [options] packagePath');
-  print('');
-  print('Compute code completion health metrics.');
-  print('');
-  print(parser.usage);
-}
-
-/// Return `true` if the command-line arguments (represented by the [result] and
-/// parsed by the [parser]) are valid.
-bool validArguments(ArgParser parser, ArgResults result) {
-  if (result.wasParsed('help')) {
-    printUsage(parser);
-    return false;
-  } else if (result.rest.length != 1) {
-    printUsage(parser, error: 'No package path specified.');
-    return false;
-  }
-  var rootPath = result.rest[0];
-  if (!io.Directory(rootPath).existsSync()) {
-    printUsage(parser, error: 'The directory "$rootPath" does not exist.');
-    return false;
-  }
-  return true;
-}
-
-/// An indication of the group in which the completion falls for the purposes of
-/// subdividing the results.
-enum CompletionGroup {
-  instanceMember,
-  staticMember,
-  typeReference,
-  localReference,
-  paramReference,
-  topLevel
-}
-
-/// A wrapper for the collection of [Counter] and [MeanReciprocalRankComputer]
-/// objects for a run of [CompletionMetricsComputer].
-class CompletionMetrics {
-  /// The maximum number of slowest results to collect.
-  static const maxSlowestResults = 5;
-
-  /// The maximum number of worst results to collect.
-  static const maxWorstResults = 5;
-
-  /// The name associated with this set of metrics.
-  final String name;
-
-  Counter completionCounter = Counter('successful/ unsuccessful completions');
-
-  Counter completionMissedTokenCounter =
-      Counter('unsuccessful completion token counter');
-
-  Counter completionKindCounter =
-      Counter('unsuccessful completion kind counter');
-
-  Counter completionElementKindCounter =
-      Counter('unsuccessful completion element kind counter');
-
-  ArithmeticMeanComputer meanCompletionMS =
-      ArithmeticMeanComputer('ms per completion');
-
-  MeanReciprocalRankComputer mrrComputer =
-      MeanReciprocalRankComputer('successful/ unsuccessful completions');
-
-  MeanReciprocalRankComputer successfulMrrComputer =
-      MeanReciprocalRankComputer('successful completions');
-
-  MeanReciprocalRankComputer instanceMemberMrrComputer =
-      MeanReciprocalRankComputer('instance member completions');
-
-  MeanReciprocalRankComputer staticMemberMrrComputer =
-      MeanReciprocalRankComputer('static member completions');
-
-  MeanReciprocalRankComputer typeRefMrrComputer =
-      MeanReciprocalRankComputer('type reference completions');
-
-  MeanReciprocalRankComputer localRefMrrComputer =
-      MeanReciprocalRankComputer('local reference completions');
-
-  MeanReciprocalRankComputer paramRefMrrComputer =
-      MeanReciprocalRankComputer('param reference completions');
-
-  MeanReciprocalRankComputer topLevelMrrComputer =
-      MeanReciprocalRankComputer('non-type member completions');
-
-  Map<String, MeanReciprocalRankComputer> locationMrrComputers = {};
-
-  ArithmeticMeanComputer charsBeforeTop =
-      ArithmeticMeanComputer('chars_before_top');
-
-  ArithmeticMeanComputer charsBeforeTopFive =
-      ArithmeticMeanComputer('chars_before_top_five');
-
-  ArithmeticMeanComputer insertionLengthTheoretical =
-      ArithmeticMeanComputer('insertion_length_theoretical');
-
-  /// The places in which a completion location was requested when none was
-  /// available.
-  Set<String> missingCompletionLocations = {};
-
-  /// The completion locations for which no relevance table was available.
-  Set<String> missingCompletionLocationTables = {};
-
-  /// A list of the top [maxWorstResults] completion results with the highest
-  /// (worst) ranks for completing to instance members.
-  List<CompletionResult> instanceMemberWorstResults = [];
-
-  /// A list of the top [maxWorstResults] completion results with the highest
-  /// (worst) ranks for completing to static members.
-  List<CompletionResult> staticMemberWorstResults = [];
-
-  /// A list of the top [maxWorstResults] completion results with the highest
-  /// (worst) ranks for completing to type references.
-  List<CompletionResult> typeRefWorstResults = [];
-
-  /// A list of the top [maxWorstResults] completion results with the highest
-  /// (worst) ranks for completing to local references.
-  List<CompletionResult> localRefWorstResults = [];
-
-  /// A list of the top [maxWorstResults] completion results with the highest
-  /// (worst) ranks for completing to parameter references.
-  List<CompletionResult> paramRefWorstResults = [];
-
-  /// A list of the top [maxWorstResults] completion results with the highest
-  /// (worst) ranks for completing to top-level declarations.
-  List<CompletionResult> topLevelWorstResults = [];
-
-  /// A list of the top [maxSlowestResults] completion results that took the
-  /// longest top compute for instance members.
-  List<CompletionResult> instanceMemberSlowestResults = [];
-
-  /// A list of the top [maxSlowestResults] completion results that took the
-  /// longest top compute for static members.
-  List<CompletionResult> staticMemberSlowestResults = [];
-
-  /// A list of the top [maxSlowestResults] completion results that took the
-  /// longest top compute for type references.
-  List<CompletionResult> typeRefSlowestResults = [];
-
-  /// A list of the top [maxSlowestResults] completion results that took the
-  /// longest top compute for local references.
-  List<CompletionResult> localRefSlowestResults = [];
-
-  /// A list of the top [maxSlowestResults] completion results that took the
-  /// longest top compute for parameter references.
-  List<CompletionResult> paramRefSlowestResults = [];
-
-  /// A list of the top [maxSlowestResults] completion results that took the
-  /// longest top compute for top-level declarations.
-  List<CompletionResult> topLevelSlowestResults = [];
-
-  CompletionMetrics(this.name);
-
-  /// Record this completion result, this method handles the worst ranked items
-  /// as well as the longest sets of results to compute.
-  void recordCompletionResult(CompletionResult result) {
-    _recordTime(result);
-    _recordMrr(result);
-    _recordWorstResult(result);
-    _recordSlowestResult(result);
-    _recordMissingInformation(result);
-  }
-
-  /// If the completion location was requested but missing when computing the
-  /// [result], then record where that happened.
-  void _recordMissingInformation(CompletionResult result) {
-    var location = result.listener?.missingCompletionLocation;
-    if (location != null) {
-      missingCompletionLocations.add(location);
-    } else {
-      location = result.listener?.missingCompletionLocationTable;
-      if (location != null) {
-        missingCompletionLocationTables.add(location);
-      }
-    }
-  }
-
-  /// Record the MRR for the [result].
-  void _recordMrr(CompletionResult result) {
-    var rank = result.place.rank;
-    // Record globally.
-    successfulMrrComputer.addRank(rank);
-    // Record by group.
-    switch (result.group) {
-      case CompletionGroup.instanceMember:
-        instanceMemberMrrComputer.addRank(rank);
-        break;
-      case CompletionGroup.staticMember:
-        staticMemberMrrComputer.addRank(rank);
-        break;
-      case CompletionGroup.typeReference:
-        typeRefMrrComputer.addRank(rank);
-        break;
-      case CompletionGroup.localReference:
-        localRefMrrComputer.addRank(rank);
-        break;
-      case CompletionGroup.paramReference:
-        paramRefMrrComputer.addRank(rank);
-        break;
-      case CompletionGroup.topLevel:
-        topLevelMrrComputer.addRank(rank);
-        break;
-    }
-    // Record by completion location.
-    var location = result.completionLocation;
-    if (location != null) {
-      var computer = locationMrrComputers.putIfAbsent(
-          location, () => MeanReciprocalRankComputer(location));
-      computer.addRank(rank);
-    }
-  }
-
-  /// If the [result] is took longer than any previously recorded results,
-  /// record it.
-  void _recordSlowestResult(CompletionResult result) {
-    List<CompletionResult> getSlowestResults() {
-      switch (result.group) {
-        case CompletionGroup.instanceMember:
-          return instanceMemberSlowestResults;
-        case CompletionGroup.staticMember:
-          return staticMemberSlowestResults;
-        case CompletionGroup.typeReference:
-          return typeRefSlowestResults;
-        case CompletionGroup.localReference:
-          return localRefSlowestResults;
-        case CompletionGroup.paramReference:
-          return paramRefSlowestResults;
-        case CompletionGroup.topLevel:
-          return topLevelSlowestResults;
-      }
-      return const <CompletionResult>[];
-    }
-
-    var slowestResults = getSlowestResults();
-    if (slowestResults.length >= maxSlowestResults) {
-      if (result.elapsedMS <= slowestResults.last.elapsedMS) {
-        return;
-      }
-      slowestResults.removeLast();
-    }
-    slowestResults.add(result);
-    slowestResults.sort((first, second) => second.elapsedMS - first.elapsedMS);
-  }
-
-  /// Record this elapsed ms count for the average ms count.
-  void _recordTime(CompletionResult result) {
-    meanCompletionMS.addValue(result.elapsedMS);
-  }
-
-  /// If the [result] is worse than any previously recorded results, record it.
-  void _recordWorstResult(CompletionResult result) {
-    List<CompletionResult> getWorstResults() {
-      switch (result.group) {
-        case CompletionGroup.instanceMember:
-          return instanceMemberWorstResults;
-        case CompletionGroup.staticMember:
-          return staticMemberWorstResults;
-        case CompletionGroup.typeReference:
-          return typeRefWorstResults;
-        case CompletionGroup.localReference:
-          return localRefWorstResults;
-        case CompletionGroup.paramReference:
-          return paramRefWorstResults;
-        case CompletionGroup.topLevel:
-          return topLevelWorstResults;
-      }
-      return const <CompletionResult>[];
-    }
-
-    var worstResults = getWorstResults();
-    if (worstResults.length >= maxWorstResults) {
-      if (result.place.rank <= worstResults.last.place.rank) {
-        return;
-      }
-      worstResults.removeLast();
-    }
-    worstResults.add(result);
-    worstResults.sort((first, second) => second.place.rank - first.place.rank);
-  }
-}
-
-/// This is the main metrics computer class for code completions. After the
-/// object is constructed, [computeCompletionMetrics] is executed to do analysis
-/// and print a summary of the metrics gathered from the completion tests.
-class CompletionMetricsComputer {
-  final String rootPath;
-
-  final bool availableSuggestions;
-
-  final String overlay;
-
-  final bool skipOldRelevance;
-
-  final bool verbose;
-
-  ResolvedUnitResult _resolvedUnitResult;
-
-  /// The int to be returned from the [compute] call.
-  int resultCode;
-
-  CompletionMetrics metricsOldMode;
-
-  CompletionMetrics metricsNewMode;
-
-  final OverlayResourceProvider _provider =
-      OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
-
-  int overlayModificationStamp = 0;
-
-  CompletionMetricsComputer(this.rootPath,
-      {@required this.availableSuggestions,
-      @required this.overlay,
-      @required this.skipOldRelevance,
-      @required this.verbose})
-      : assert(overlay == OVERLAY_NONE ||
-            overlay == OVERLAY_REMOVE_TOKEN ||
-            overlay == OVERLAY_REMOVE_REST_OF_FILE);
-
-  Future<int> compute() async {
-    resultCode = 0;
-    metricsOldMode = CompletionMetrics('useNewRelevance = false');
-    metricsNewMode = CompletionMetrics('useNewRelevance = true');
-    final collection = AnalysisContextCollection(
-      includedPaths: [rootPath],
-      resourceProvider: PhysicalResourceProvider.INSTANCE,
-    );
-    for (var context in collection.contexts) {
-      await _computeInContext(context.contextRoot);
-    }
-    if (!skipOldRelevance) {
-      printMetrics(metricsOldMode);
-    }
-    printMetrics(metricsNewMode);
-
-    print('');
-    print('====================');
-    oldVsNewComparison.printCounterValues();
-    print('====================');
-
-    if (verbose) {
-      printWorstResults(metricsNewMode);
-      printSlowestResults(metricsNewMode);
-      printMissingInformation(metricsNewMode);
-    }
-    return resultCode;
-  }
-
-  int forEachExpectedCompletion(
-      CompletionRequestImpl request,
-      MetricsSuggestionListener listener,
-      ExpectedCompletion expectedCompletion,
-      String completionLocation,
-      List<protocol.CompletionSuggestion> suggestions,
-      CompletionMetrics metrics,
-      int elapsedMS,
-      bool doPrintMissedCompletions) {
-    assert(suggestions != null);
-
-    var place = placementInSuggestionList(suggestions, expectedCompletion);
-
-    metrics.mrrComputer.addRank(place.rank);
-
-    if (place.denominator != 0) {
-      metrics.completionCounter.count('successful');
-
-      metrics.recordCompletionResult(CompletionResult(place, request, listener,
-          suggestions, expectedCompletion, completionLocation, elapsedMS));
-
-      var charsBeforeTop =
-          _computeCharsBeforeTop(expectedCompletion, suggestions);
-      metrics.charsBeforeTop.addValue(charsBeforeTop);
-      metrics.charsBeforeTopFive.addValue(
-          _computeCharsBeforeTop(expectedCompletion, suggestions, minRank: 5));
-      metrics.insertionLengthTheoretical
-          .addValue(expectedCompletion.completion.length - charsBeforeTop);
-
-      return place.rank;
-    } else {
-      metrics.completionCounter.count('unsuccessful');
-
-      metrics.completionMissedTokenCounter.count(expectedCompletion.completion);
-      metrics.completionKindCounter.count(expectedCompletion.kind.toString());
-      metrics.completionElementKindCounter
-          .count(expectedCompletion.elementKind.toString());
-
-      if (doPrintMissedCompletions) {
-        protocol.CompletionSuggestion closeMatchSuggestion;
-        for (var suggestion in suggestions) {
-          if (suggestion.completion == expectedCompletion.completion) {
-            closeMatchSuggestion = suggestion;
-          }
-        }
-
-        print('missing completion (`useNewRelevance = true`):');
-        print('$expectedCompletion');
-        if (closeMatchSuggestion != null) {
-          print('    close matching completion that was in the list:');
-          print('    $closeMatchSuggestion');
-        }
-        print('');
-      }
-
-      return -1;
-    }
-  }
-
-  void printMetrics(CompletionMetrics metrics) {
-    print('');
-    print('');
-    print('====================');
-    print('Completion metrics for ${metrics.name}:');
-    if (verbose) {
-      metrics.completionMissedTokenCounter.printCounterValues();
-      print('');
-
-      metrics.completionKindCounter.printCounterValues();
-      print('');
-
-      metrics.completionElementKindCounter.printCounterValues();
-      print('');
-    }
-
-    metrics.mrrComputer.printMean();
-    print('');
-
-    metrics.successfulMrrComputer.printMean();
-    print('');
-
-    metrics.instanceMemberMrrComputer.printMean();
-    print('');
-
-    metrics.staticMemberMrrComputer.printMean();
-    print('');
-
-    metrics.typeRefMrrComputer.printMean();
-    print('');
-
-    metrics.localRefMrrComputer.printMean();
-    print('');
-
-    metrics.paramRefMrrComputer.printMean();
-    print('');
-
-    metrics.topLevelMrrComputer.printMean();
-    print('');
-
-    if (verbose) {
-      var lines = <LocationTableLine>[];
-      for (var entry in metrics.locationMrrComputers.entries) {
-        var count = entry.value.count;
-        var mrr = (1 / entry.value.mrr);
-        var mrr_5 = (1 / entry.value.mrr_5);
-        var product = count * mrr;
-        lines.add(LocationTableLine(
-            label: entry.key,
-            product: product,
-            count: count,
-            mrr: mrr,
-            mrr_5: mrr_5));
-      }
-      lines.sort((first, second) => second.product.compareTo(first.product));
-      var table = <List<String>>[];
-      table.add(['Location', 'Product', 'Count', 'Mrr', 'Mrr_5']);
-      for (var line in lines) {
-        var location = line.label;
-        var product = line.product.truncate().toString();
-        var count = line.count.toString();
-        var mrr = line.mrr.toStringAsFixed(3);
-        var mrr_5 = line.mrr_5.toStringAsFixed(3);
-        table.add([location, product, count, mrr, mrr_5]);
-      }
-      var buffer = StringBuffer();
-      buffer.writeTable(table);
-      print(buffer.toString());
-      print('');
-    }
-
-    metrics.charsBeforeTop.printMean();
-    metrics.charsBeforeTopFive.printMean();
-    metrics.insertionLengthTheoretical.printMean();
-    print('');
-
-    print('Summary for $rootPath:');
-    metrics.meanCompletionMS.printMean();
-    metrics.completionCounter.printCounterValues();
-    print('====================');
-  }
-
-  void printMissingInformation(CompletionMetrics metrics) {
-    var locations = metrics.missingCompletionLocations;
-    if (locations.isNotEmpty) {
-      print('');
-      print('====================');
-      print('Missing completion location in the following places:');
-      for (var location in locations.toList()..sort()) {
-        print('  $location');
-      }
-    }
-
-    var tables = metrics.missingCompletionLocationTables;
-    if (tables.isNotEmpty) {
-      print('');
-      print('====================');
-      print('Missing tables for the following completion locations:');
-      for (var table in tables.toList()..sort()) {
-        print('  $table');
-      }
-    }
-  }
-
-  void printSlowestResults(CompletionMetrics metrics) {
-    print('');
-    print('====================');
-    print('The slowest completion results to compute');
-    _printSlowestResults(
-        'Instance members', metrics.instanceMemberSlowestResults);
-    _printSlowestResults('Static members', metrics.staticMemberSlowestResults);
-    _printSlowestResults('Type references', metrics.typeRefSlowestResults);
-    _printSlowestResults('Local references', metrics.localRefSlowestResults);
-    _printSlowestResults(
-        'Parameter references', metrics.paramRefSlowestResults);
-    _printSlowestResults('Top level', metrics.topLevelSlowestResults);
-  }
-
-  void printWorstResults(CompletionMetrics metrics) {
-    print('');
-    print('====================');
-    print('The worst completion results');
-    _printWorstResults('Instance members', metrics.instanceMemberWorstResults);
-    _printWorstResults('Static members', metrics.staticMemberWorstResults);
-    _printWorstResults('Type references', metrics.topLevelWorstResults);
-    _printWorstResults('Local references', metrics.localRefWorstResults);
-    _printWorstResults('Parameter references', metrics.paramRefWorstResults);
-    _printWorstResults('Top level', metrics.topLevelWorstResults);
-  }
-
-  int _computeCharsBeforeTop(ExpectedCompletion target,
-      List<protocol.CompletionSuggestion> suggestions,
-      {int minRank = 1}) {
-    var rank = placementInSuggestionList(suggestions, target).rank;
-    if (rank <= minRank) {
-      return 0;
-    }
-    var expected = target.completion;
-    for (var i = 1; i < expected.length + 1; i++) {
-      var prefix = expected.substring(0, i);
-      var filteredSuggestions = _filterSuggestions(prefix, suggestions);
-      rank = placementInSuggestionList(filteredSuggestions, target).rank;
-      if (rank <= minRank) {
-        return i;
-      }
-    }
-    return expected.length;
-  }
-
-  Future<List<protocol.CompletionSuggestion>> _computeCompletionSuggestions(
-      MetricsSuggestionListener listener,
-      OperationPerformanceImpl performance,
-      CompletionRequestImpl request,
-      [DeclarationsTracker declarationsTracker,
-      protocol.CompletionAvailableSuggestionsParams
-          availableSuggestionsParams]) async {
-    List<protocol.CompletionSuggestion> suggestions;
-
-    if (declarationsTracker == null) {
-      // available suggestions == false
-      suggestions = await DartCompletionManager(
-        dartdocDirectiveInfo: DartdocDirectiveInfo(),
-        listener: listener,
-      ).computeSuggestions(performance, request);
-    } else {
-      // available suggestions == true
-      var includedElementKinds = <protocol.ElementKind>{};
-      var includedElementNames = <String>{};
-      var includedSuggestionRelevanceTagList =
-          <protocol.IncludedSuggestionRelevanceTag>[];
-      var includedSuggestionSetList = <protocol.IncludedSuggestionSet>[];
-      suggestions = await DartCompletionManager(
-        dartdocDirectiveInfo: DartdocDirectiveInfo(),
-        includedElementKinds: includedElementKinds,
-        includedElementNames: includedElementNames,
-        includedSuggestionRelevanceTags: includedSuggestionRelevanceTagList,
-        listener: listener,
-      ).computeSuggestions(performance, request);
-
-      computeIncludedSetList(declarationsTracker, request.result,
-          includedSuggestionSetList, includedElementNames);
-
-      var includedSuggestionSetMap = {
-        for (var includedSuggestionSet in includedSuggestionSetList)
-          includedSuggestionSet.id: includedSuggestionSet,
-      };
-
-      var includedSuggestionRelevanceTagMap = {
-        for (var includedSuggestionRelevanceTag
-            in includedSuggestionRelevanceTagList)
-          includedSuggestionRelevanceTag.tag:
-              includedSuggestionRelevanceTag.relevanceBoost,
-      };
-
-      for (var availableSuggestionSet
-          in availableSuggestionsParams.changedLibraries) {
-        var id = availableSuggestionSet.id;
-        for (var availableSuggestion in availableSuggestionSet.items) {
-          // Exclude available suggestions where this element kind doesn't match
-          // an element kind in includedElementKinds.
-          var elementKind = availableSuggestion.element?.kind;
-          if (elementKind != null &&
-              includedElementKinds.contains(elementKind)) {
-            if (includedSuggestionSetMap.containsKey(id)) {
-              var relevance = includedSuggestionSetMap[id].relevance;
-
-              // Search for any matching relevance tags to apply any boosts
-              if (includedSuggestionRelevanceTagList.isNotEmpty &&
-                  availableSuggestion.relevanceTags != null &&
-                  availableSuggestion.relevanceTags.isNotEmpty) {
-                for (var tag in availableSuggestion.relevanceTags) {
-                  if (includedSuggestionRelevanceTagMap.containsKey(tag)) {
-                    // apply the boost
-                    relevance += includedSuggestionRelevanceTagMap[tag];
-                  }
-                }
-              }
-              suggestions
-                  .add(availableSuggestion.toCompletionSuggestion(relevance));
-            }
-          }
-        }
-      }
-    }
-
-    suggestions.sort(completionComparator);
-    return suggestions;
-  }
-
-  /// Compute the metrics for the files in the context [root], creating a
-  /// separate context collection to prevent accumulating memory. The metrics
-  /// should be captured in the [collector].
-  Future<void> _computeInContext(ContextRoot root) async {
-    // Create a new collection to avoid consuming large quantities of memory.
-    final collection = AnalysisContextCollection(
-      includedPaths: root.includedPaths.toList(),
-      excludedPaths: root.excludedPaths.toList(),
-      resourceProvider: _provider,
-    );
-
-    var context = collection.contexts[0];
-
-    // Set the DeclarationsTracker, only call doWork to build up the available
-    // suggestions if doComputeCompletionsFromAnalysisServer is true.
-    DeclarationsTracker declarationsTracker;
-    protocol.CompletionAvailableSuggestionsParams availableSuggestionsParams;
-    if (availableSuggestions) {
-      declarationsTracker = DeclarationsTracker(
-          MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
-      declarationsTracker.addContext(context);
-      while (declarationsTracker.hasWork) {
-        declarationsTracker.doWork();
-      }
-
-      // Have the AvailableDeclarationsSet computed to use later.
-      availableSuggestionsParams = createCompletionAvailableSuggestions(
-          declarationsTracker.allLibraries.toList(), []);
-
-      // assert that this object is not null, throw if it is.
-      if (availableSuggestionsParams == null) {
-        throw Exception('availableSuggestionsParam not computable.');
-      }
-    }
-
-    // Loop through each file, resolve the file and call
-    // forEachExpectedCompletion
-    for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
-        try {
-          _resolvedUnitResult =
-              await context.currentSession.getResolvedUnit(filePath);
-
-          var analysisError = getFirstErrorOrNull(_resolvedUnitResult);
-          if (analysisError != null) {
-            print('File $filePath skipped due to errors such as:');
-            print('  ${analysisError.toString()}');
-            print('');
-            resultCode = 1;
-            continue;
-          }
-
-          // Use the ExpectedCompletionsVisitor to compute the set of expected
-          // completions for this CompilationUnit.
-          final visitor = ExpectedCompletionsVisitor(filePath);
-          _resolvedUnitResult.unit.accept(visitor);
-
-          for (var expectedCompletion in visitor.expectedCompletions) {
-            var resolvedUnitResult = _resolvedUnitResult;
-
-            // If an overlay option is being used, compute the overlay file, and
-            // have the context reanalyze the file
-            if (overlay != OVERLAY_NONE) {
-              var overlayContents = _getOverlayContents(
-                  _resolvedUnitResult.content, expectedCompletion, overlay);
-
-              _provider.setOverlay(filePath,
-                  content: overlayContents,
-                  modificationStamp: overlayModificationStamp++);
-              (context as DriverBasedAnalysisContext)
-                  .driver
-                  .changeFile(filePath);
-              resolvedUnitResult =
-                  await context.currentSession.getResolvedUnit(filePath);
-            }
-
-            // As this point the completion suggestions are computed,
-            // and results are collected with varying settings for
-            // comparison:
-
-            Future<int> handleExpectedCompletion(
-                {MetricsSuggestionListener listener,
-                @required CompletionMetrics metrics,
-                @required bool printMissedCompletions,
-                @required bool useNewRelevance}) async {
-              var stopwatch = Stopwatch()..start();
-              var request = CompletionRequestImpl(
-                resolvedUnitResult,
-                expectedCompletion.offset,
-                useNewRelevance,
-                CompletionPerformance(),
-              );
-              var directiveInfo = DartdocDirectiveInfo();
-
-              OpType opType;
-              List<protocol.CompletionSuggestion> suggestions;
-              await request.performance.runRequestOperation(
-                (performance) async {
-                  var dartRequest = await DartCompletionRequestImpl.from(
-                      performance, request, directiveInfo);
-                  opType =
-                      OpType.forCompletion(dartRequest.target, request.offset);
-                  suggestions = await _computeCompletionSuggestions(
-                    listener,
-                    performance,
-                    request,
-                    declarationsTracker,
-                    availableSuggestionsParams,
-                  );
-                },
-              );
-              stopwatch.stop();
-
-              return forEachExpectedCompletion(
-                  request,
-                  listener,
-                  expectedCompletion,
-                  opType.completionLocation,
-                  suggestions,
-                  metrics,
-                  stopwatch.elapsedMilliseconds,
-                  printMissedCompletions);
-            }
-
-            // First we compute the completions useNewRelevance set to
-            // false:
-            int oldRank;
-            if (!skipOldRelevance) {
-              oldRank = await handleExpectedCompletion(
-                  metrics: metricsOldMode,
-                  printMissedCompletions: false,
-                  useNewRelevance: false);
-            }
-
-            // And again here with useNewRelevance set to true:
-            var listener = MetricsSuggestionListener();
-            var newRank = await handleExpectedCompletion(
-                listener: listener,
-                metrics: metricsNewMode,
-                printMissedCompletions: verbose,
-                useNewRelevance: true);
-
-            if (!skipOldRelevance && newRank != -1 && oldRank != -1) {
-              if (newRank <= oldRank) {
-                oldVsNewComparison.count('new relevance');
-              } else {
-                oldVsNewComparison.count('old relevance');
-              }
-            }
-
-            if (!skipOldRelevance && verbose) {
-              if (newRank > 0 && oldRank < 0) {
-                print('    ===========');
-                print(
-                    '    The `useNewRelevance = true` generated a completion that `useNewRelevance = false` did not:');
-                print('    $expectedCompletion');
-                print('    ===========');
-                print('');
-              } else if (newRank < 0 && oldRank > 0) {
-                print('    ===========');
-                print(
-                    '    The `useNewRelevance = false` generated a completion that `useNewRelevance = true` did not:');
-                print('    $expectedCompletion');
-                print('    ===========');
-                print('');
-              }
-            }
-
-            // If an overlay option is being used, remove the overlay applied
-            // earlier
-            if (overlay != OVERLAY_NONE) {
-              _provider.removeOverlay(filePath);
-            }
-          }
-        } catch (e) {
-          print('Exception caught analyzing: $filePath');
-          print(e.toString());
-          resultCode = 1;
-        }
-      }
-    }
-  }
-
-  List<protocol.CompletionSuggestion> _filterSuggestions(
-      String prefix, List<protocol.CompletionSuggestion> suggestions) {
-    // TODO(brianwilkerson) Replace this with a more realistic filtering algorithm.
-    return suggestions
-        .where((suggestion) => suggestion.completion.startsWith(prefix))
-        .toList();
-  }
-
-  String _getOverlayContents(String contents,
-      ExpectedCompletion expectedCompletion, String overlayMode) {
-    assert(contents.isNotEmpty);
-    var offset = expectedCompletion.offset;
-    var length = expectedCompletion.syntacticEntity.length;
-    assert(offset >= 0);
-    assert(length > 0);
-    if (overlayMode == OVERLAY_REMOVE_TOKEN) {
-      return contents.substring(0, offset) +
-          contents.substring(offset + length);
-    } else if (overlayMode == OVERLAY_REMOVE_REST_OF_FILE) {
-      return contents.substring(0, offset);
-    } else {
-      throw Exception('\'_getOverlayContents\' called with option other than'
-          '$OVERLAY_REMOVE_TOKEN and $OVERLAY_REMOVE_REST_OF_FILE: $overlayMode');
-    }
-  }
-
-  void _printSlowestResults(
-      String title, List<CompletionResult> slowestResults) {
-    print('');
-    print(title);
-    for (var result in slowestResults) {
-      var elapsedMS = result.elapsedMS;
-      var expected = result.expectedCompletion;
-      print('');
-      print('  Elapsed ms: $elapsedMS');
-      print('  Completion: ${expected.completion}');
-      print('  Completion kind: ${expected.kind}');
-      print('  Element kind: ${expected.elementKind}');
-      print('  Location: ${expected.location}');
-    }
-  }
-
-  void _printWorstResults(String title, List<CompletionResult> worstResults) {
-    print('');
-    print(title);
-    for (var result in worstResults) {
-      var rank = result.place.rank;
-      var expected = result.expectedCompletion;
-      var suggestions = result.suggestions;
-      var suggestion = suggestions[rank - 1];
-
-      var features = result.listener?.featureMap[suggestion];
-      var topSuggestions =
-          suggestions.sublist(0, math.min(10, suggestions.length));
-      var topSuggestionCount = topSuggestions.length;
-
-      var preceding = <int, int>{};
-      for (var i = 0; i < rank - 1; i++) {
-        var relevance = suggestions[i].relevance;
-        preceding[relevance] = (preceding[relevance] ?? 0) + 1;
-      }
-      var precedingRelevances = preceding.keys.toList();
-      precedingRelevances.sort();
-
-      print('');
-      print('  Rank: $rank');
-      print('  Location: ${expected.location}');
-      print('  Suggestion: ${suggestion.description}');
-      print('  Features: $features');
-      print('  Top $topSuggestionCount suggestions:');
-      for (var i = 0; i < topSuggestionCount; i++) {
-        var topSuggestion = topSuggestions[i];
-        print('  $i Suggestion: ${topSuggestion.description}');
-        if (result.listener != null) {
-          var feature = result.listener.featureMap[topSuggestion];
-          if (feature == null || feature.isEmpty) {
-            print('    Features: <none>');
-          } else {
-            print('    Features: $feature');
-          }
-        }
-      }
-      print('  Preceding relevance scores and counts:');
-      for (var relevance in precedingRelevances.reversed) {
-        print('    $relevance: ${preceding[relevance]}');
-      }
-    }
-  }
-
-  /// Given some [ResolvedUnitResult] return the first error of high severity
-  /// if such an error exists, `null` otherwise.
-  static err.AnalysisError getFirstErrorOrNull(
-      ResolvedUnitResult resolvedUnitResult) {
-    for (var error in resolvedUnitResult.errors) {
-      if (error.severity == Severity.error) {
-        return error;
-      }
-    }
-    return null;
-  }
-
-  static Place placementInSuggestionList(
-      List<protocol.CompletionSuggestion> suggestions,
-      ExpectedCompletion expectedCompletion) {
-    var placeCounter = 1;
-    for (var completionSuggestion in suggestions) {
-      if (expectedCompletion.matches(completionSuggestion)) {
-        return Place(placeCounter, suggestions.length);
-      }
-      placeCounter++;
-    }
-    return Place.none();
-  }
-}
-
-/// The result of a single completion.
-class CompletionResult {
-  final Place place;
-
-  final CompletionRequestImpl request;
-
-  final MetricsSuggestionListener listener;
-
-  final List<protocol.CompletionSuggestion> suggestions;
-
-  final ExpectedCompletion expectedCompletion;
-
-  final String completionLocation;
-
-  final int elapsedMS;
-
-  CompletionResult(this.place, this.request, this.listener, this.suggestions,
-      this.expectedCompletion, this.completionLocation, this.elapsedMS);
-
-  /// Return the completion group for the location at which completion was
-  /// requested.
-  CompletionGroup get group {
-    var element = _getElement(expectedCompletion.syntacticEntity);
-    if (element != null) {
-      var parent = element.enclosingElement;
-      if (parent is ClassElement || parent is ExtensionElement) {
-        if (_isStatic(element)) {
-          return CompletionGroup.staticMember;
-        } else {
-          return CompletionGroup.instanceMember;
-        }
-      } else if (expectedCompletion.elementKind == ElementKind.CLASS ||
-          expectedCompletion.elementKind == ElementKind.MIXIN ||
-          expectedCompletion.elementKind == ElementKind.ENUM ||
-          expectedCompletion.elementKind == ElementKind.TYPE_PARAMETER) {
-        return CompletionGroup.typeReference;
-      } else if (expectedCompletion.elementKind == ElementKind.LOCAL_VARIABLE) {
-        return CompletionGroup.localReference;
-      } else if (expectedCompletion.elementKind == ElementKind.PARAMETER) {
-        return CompletionGroup.paramReference;
-      }
-    }
-    return CompletionGroup.topLevel;
-  }
-
-  /// Return the element associated with the syntactic [entity], or `null` if
-  /// there is no such element.
-  Element _getElement(SyntacticEntity entity) {
-    if (entity is SimpleIdentifier) {
-      return entity.staticElement;
-    }
-    return null;
-  }
-
-  /// Return `true` if the [element] is static (either top-level or a static
-  /// member of a class or extension).
-  bool _isStatic(Element element) {
-    if (element is ClassMemberElement) {
-      return element.isStatic;
-    } else if (element is ExecutableElement) {
-      return element.isStatic;
-    } else if (element is FieldElement) {
-      return element.isStatic;
-    } else if (element is VariableElement) {
-      return element.isStatic;
-    }
-    return true;
-  }
-}
-
-/// The data to be printed on a single line in the table of mrr values per
-/// completion location.
-class LocationTableLine {
-  final String label;
-  final double product;
-  final int count;
-  final double mrr;
-  final double mrr_5;
-
-  LocationTableLine(
-      {@required this.label,
-      @required this.product,
-      @required this.count,
-      @required this.mrr,
-      @required this.mrr_5});
-}
-
-class MetricsSuggestionListener implements SuggestionListener {
-  Map<protocol.CompletionSuggestion, String> featureMap = {};
-
-  String cachedFeatures = '';
-
-  String missingCompletionLocation;
-  String missingCompletionLocationTable;
-
-  @override
-  void builtSuggestion(protocol.CompletionSuggestion suggestion) {
-    featureMap[suggestion] = cachedFeatures;
-    cachedFeatures = '';
-  }
-
-  @override
-  void computedFeatures(
-      {double contextType,
-      double elementKind,
-      double hasDeprecated,
-      double inheritanceDistance,
-      double startsWithDollar,
-      double superMatches}) {
-    var buffer = StringBuffer();
-
-    bool write(String label, double value, bool needsComma) {
-      if (value != null) {
-        if (needsComma) {
-          buffer.write(', ');
-        }
-        buffer.write('$label: $value');
-        return true;
-      }
-      return needsComma;
-    }
-
-    var needsComma = false;
-    needsComma = write('contextType', contextType, needsComma);
-    needsComma = write('elementKind', elementKind, needsComma);
-    needsComma = write('hasDeprecated', hasDeprecated, needsComma);
-    needsComma = write('inheritanceDistance', inheritanceDistance, needsComma);
-    needsComma = write('startsWithDollar', startsWithDollar, needsComma);
-    needsComma = write('superMatches', superMatches, needsComma);
-    cachedFeatures = buffer.toString();
-  }
-
-  @override
-  void missingCompletionLocationAt(AstNode parent, SyntacticEntity child) {
-    if (missingCompletionLocation == null) {
-      String className(SyntacticEntity entity) {
-        var className = entity.runtimeType.toString();
-        if (className.endsWith('Impl')) {
-          className = className.substring(0, className.length - 4);
-        }
-        return className;
-      }
-
-      var parentClass = className(parent);
-      var childClass = className(child);
-      missingCompletionLocation = '$parentClass/$childClass';
-    }
-  }
-
-  @override
-  void missingElementKindTableFor(String completionLocation) {
-    missingCompletionLocationTable = completionLocation;
-  }
-}
-
-extension on protocol.CompletionSuggestion {
-  /// A shorter description of the suggestion than [toString] provides.
-  String get description =>
-      json.encode(toJson()..remove('docSummary')..remove('docComplete'));
-}
-
-extension AvailableSuggestionsExtension on protocol.AvailableSuggestion {
-  // TODO(jwren) I am not sure if we want CompletionSuggestionKind.INVOCATION in
-  // call cases here, to iterate I need to figure out why this algorithm is
-  // taking so much time.
-  protocol.CompletionSuggestion toCompletionSuggestion(int relevance) =>
-      protocol.CompletionSuggestion(
-          protocol.CompletionSuggestionKind.INVOCATION,
-          relevance,
-          label,
-          label.length,
-          0,
-          element.isDeprecated,
-          false);
-}
diff --git a/pkg/analysis_server/tool/completion_metrics/metrics_util.dart b/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
deleted file mode 100644
index cadc262..0000000
--- a/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/status/pages.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-
-/// https://en.wikipedia.org/wiki/Average#Arithmetic_mean
-class ArithmeticMeanComputer {
-  final String name;
-  num sum = 0;
-  int count = 0;
-
-  ArithmeticMeanComputer(this.name);
-
-  num get mean => sum / count;
-
-  void addValue(num val) {
-    sum += val;
-    count++;
-  }
-
-  void clear() {
-    sum = 0;
-    count = 0;
-  }
-
-  void printMean() {
-    print('Mean \'$name\' ${mean.toStringAsFixed(6)} (total = $count)');
-  }
-}
-
-/// A simple counter class.  A [String] name is passed to name the counter. Each
-/// time something is counted, a non-null, non-empty [String] key is passed to
-/// [count] to increment the amount from zero. [printCounterValues] is provided
-/// to have a [String] summary of the generated counts, example:
-///
-/// ```
-/// Counts for 'counter example':
-/// [bucket-1] 60 (60.0%)
-/// [bucket-2] 25 (25.0%)
-/// [bucket-3] 5 (5.0%)
-/// [bucket-4] 10 (10.0%)
-/// ```
-class Counter {
-  final String name;
-  final Map<String, int> _buckets = {};
-  int _totalCount = 0;
-
-  Counter(this.name);
-
-  /// Return a copy of all the current count data, this getter copies and
-  /// returns the data to ensure that the data is only modified with the public
-  /// accessors in this class.
-  Map<String, int> get map => Map.from(_buckets);
-
-  int get totalCount => _totalCount;
-
-  void clear() {
-    _buckets.clear();
-    _totalCount = 0;
-  }
-
-  void count(String id, [int countNumber = 1]) {
-    assert(id != null && id.isNotEmpty && 1 <= countNumber);
-    if (_buckets.containsKey(id)) {
-      _buckets[id] += countNumber;
-    } else {
-      _buckets.putIfAbsent(id, () => countNumber);
-    }
-    _totalCount += countNumber;
-  }
-
-  int getCountOf(String id) => _buckets[id] ?? 0;
-
-  void printCounterValues() {
-    print('Counts for \'$name\' (total = $_totalCount):');
-    if (_totalCount > 0) {
-      _buckets.forEach((id, count) =>
-          print('[$id] $count (${printPercentage(count / _totalCount, 2)})'));
-    } else {
-      print('<no counts>');
-    }
-  }
-}
-
-/// A computer for the mean reciprocal rank. The MRR as well as the MRR only
-/// if the item was in the top 5 in the list see [MAX_RANK], is computed.
-/// https://en.wikipedia.org/wiki/Mean_reciprocal_rank.
-class MeanReciprocalRankComputer {
-  static final int MAX_RANK = 5;
-  final String name;
-  double _sum = 0;
-  double _sum_5 = 0;
-  int _count = 0;
-
-  MeanReciprocalRankComputer(
-    this.name,
-  );
-
-  int get count => _count;
-
-  double get mrr {
-    if (count == 0) {
-      return 0;
-    }
-    return _sum / count;
-  }
-
-  double get mrr_5 {
-    if (count == 0) {
-      return 0;
-    }
-    return _sum_5 / count;
-  }
-
-  void addRank(int rank) {
-    if (rank != 0) {
-      _sum += 1 / rank;
-      if (rank <= MAX_RANK) {
-        _sum_5 += 1 / rank;
-      }
-    }
-    _count++;
-  }
-
-  void clear() {
-    _sum = 0;
-    _sum_5 = 0;
-    _count = 0;
-  }
-
-  void printMean() {
-    print('Mean Reciprocal Rank \'$name\' (total = $count)');
-    print('mrr   = ${mrr.toStringAsFixed(6)} '
-        '(inverse = ${(1 / mrr).toStringAsFixed(3)})');
-
-    print('mrr_5 = ${mrr_5.toStringAsFixed(6)} '
-        '(inverse = ${(1 / mrr_5).toStringAsFixed(3)})');
-  }
-}
-
-/// An immutable class to represent the placement in some list, for example '2nd
-/// place out of 5'.
-class Place {
-  /// A 1-indexed place in a list
-  final int _numerator;
-
-  /// The total number of possible places.
-  final int _denominator;
-
-  const Place(this._numerator, this._denominator)
-      : assert(_numerator > 0),
-        assert(_denominator >= _numerator);
-
-  const Place.none()
-      : _numerator = 0,
-        _denominator = 0;
-
-  int get denominator => _denominator;
-
-  @override
-  int get hashCode => JenkinsSmiHash.hash2(_numerator, _denominator);
-
-  int get numerator => _numerator;
-
-  int get rank => _numerator;
-
-  @override
-  bool operator ==(dynamic other) =>
-      other is Place &&
-      _numerator == other._numerator &&
-      _denominator == other._denominator;
-}
diff --git a/pkg/analysis_server/tool/completion_metrics/output_utilities.dart b/pkg/analysis_server/tool/completion_metrics/output_utilities.dart
deleted file mode 100644
index 00ed748..0000000
--- a/pkg/analysis_server/tool/completion_metrics/output_utilities.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:math' as math;
-
-extension OutputUtilities on StringSink {
-  /// Write the given [table].
-  ///
-  /// The table is represented as a list or rows, where each row is a list of
-  /// the contents of the cells in that row.
-  ///
-  /// Throws an [ArgumentError] if the table is empty or if the rows do not
-  /// contain the same number of cells.
-  void writeTable(List<List<String>> table) {
-    var columnWidths = _computeColumnWidths(table);
-    for (var row in table) {
-      var lastNonEmpty = row.length - 1;
-      while (lastNonEmpty > 0) {
-        if (row[lastNonEmpty].isNotEmpty) {
-          break;
-        }
-        lastNonEmpty--;
-      }
-      for (var i = 0; i <= lastNonEmpty; i++) {
-        var cellContent = row[i];
-        var columnWidth = columnWidths[i];
-        var padding = columnWidth - cellContent.length;
-        write(cellContent);
-        if (i < lastNonEmpty) {
-          write(' ' * (padding + 2));
-        }
-      }
-      writeln();
-    }
-  }
-
-  /// Return the minimum widths for each of the columns in the given [table].
-  ///
-  /// The table is represented as a list or rows, where each row is a list of
-  /// the contents of the cells in that row.
-  ///
-  /// Throws an [ArgumentError] if the table is empty or if the rows do not
-  /// contain the same number of cells.
-  List<int> _computeColumnWidths(List<List<String>> table) {
-    if (table.isEmpty) {
-      throw ArgumentError('table cannot be empty');
-    }
-    var columnCount = table[0].length;
-    if (columnCount == 0) {
-      throw ArgumentError('rows cannot be empty');
-    }
-    var columnWidths = List<int>.filled(columnCount, 0);
-    for (var row in table) {
-      var rowLength = row.length;
-      if (rowLength > 0) {
-        if (rowLength != columnCount) {
-          throw ArgumentError(
-              'non-empty rows must contain the same number of columns');
-        }
-        for (var i = 0; i < rowLength; i++) {
-          var cellWidth = row[i].length;
-          columnWidths[i] = math.max(columnWidths[i], cellWidth);
-        }
-      }
-    }
-    return columnWidths;
-  }
-}
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
deleted file mode 100644
index b746fb6..0000000
--- a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
+++ /dev/null
@@ -1,1611 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io' as io;
-
-import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
-import 'package:analysis_server/src/protocol_server.dart' show ElementKind;
-import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
-import 'package:analysis_server/src/utilities/flutter.dart';
-import 'package:analysis_tool/tools.dart';
-import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/dart/analysis/context_root.dart';
-import 'package:analyzer/dart/analysis/results.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/dart/element/element.dart'
-    show ClassElement, Element, LibraryElement;
-import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/dart/element/type_system.dart';
-import 'package:analyzer/diagnostic/diagnostic.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:args/args.dart';
-import 'package:meta/meta.dart';
-
-import '../../test/utils/package_root.dart' as package_root;
-
-/// Compute metrics to determine whether they should be used to compute a
-/// relevance score for completion suggestions.
-Future<void> main(List<String> args) async {
-  var parser = createArgParser();
-  var result = parser.parse(args);
-
-  if (validArguments(parser, result)) {
-    var rootPath = result.rest[0];
-    print('Analyzing root: "$rootPath"');
-
-    var provider = PhysicalResourceProvider.INSTANCE;
-    var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
-    var generatedFilePath = provider.pathContext.join(
-        packageRoot,
-        'analysis_server',
-        'lib',
-        'src',
-        'services',
-        'completion',
-        'dart',
-        'relevance_tables.g.dart');
-    var generatedFile = provider.getFile(generatedFilePath);
-
-    var computer = RelevanceMetricsComputer();
-    var stopwatch = Stopwatch();
-    stopwatch.start();
-    await computer.compute(rootPath, verbose: result['verbose']);
-    var buffer = StringBuffer();
-    var writer = RelevanceTableWriter(buffer);
-    writer.write(computer.data);
-    generatedFile.writeAsStringSync(buffer.toString());
-    DartFormat.formatFile(io.File(generatedFile.path));
-    stopwatch.stop();
-
-    var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
-    print('Tables generated in $duration');
-  }
-}
-
-/// Create a parser that can be used to parse the command-line arguments.
-ArgParser createArgParser() {
-  var parser = ArgParser();
-  parser.addFlag(
-    'help',
-    abbr: 'h',
-    help: 'Print this help message.',
-  );
-  parser.addFlag(
-    'verbose',
-    abbr: 'v',
-    help: 'Print additional information about the analysis',
-    negatable: false,
-  );
-  return parser;
-}
-
-/// Print usage information for this tool.
-void printUsage(ArgParser parser, {String error}) {
-  if (error != null) {
-    print(error);
-    print('');
-  }
-  print('usage: dart relevance_table_generator.dart [options] packagePath');
-  print('');
-  print('Generate the tables used to compute the values of certain features.');
-  print('');
-  print(parser.usage);
-}
-
-/// Return `true` if the command-line arguments (represented by the [result] and
-/// parsed by the [parser]) are valid.
-bool validArguments(ArgParser parser, ArgResults result) {
-  if (result.wasParsed('help')) {
-    printUsage(parser);
-    return false;
-  } else if (result.rest.length != 1) {
-    printUsage(parser, error: 'No package path specified.');
-    return false;
-  }
-  var rootPath = result.rest[0];
-  if (!PhysicalResourceProvider.INSTANCE.pathContext.isAbsolute(rootPath)) {
-    printUsage(parser, error: 'The package path must be an absolute path.');
-    return false;
-  }
-  if (!io.Directory(rootPath).existsSync()) {
-    printUsage(parser, error: 'The directory "$rootPath" does not exist.');
-    return false;
-  }
-  return true;
-}
-
-/// An object that records the data used to compute the tables.
-class RelevanceData {
-  /// A table mapping element kinds and keywords to counts by context.
-  Map<String, Map<_Kind, int>> byKind = {};
-
-  /// Initialize a newly created set of relevance data to be empty.
-  RelevanceData();
-
-  /// Add the data from the given relevance [data] to this set of data.
-  void addDataFrom(RelevanceData data) {
-    _addToMap(byKind, data.byKind);
-  }
-
-  /// Record that an element of the given [kind] was found in the given
-  /// [context].
-  void recordElementKind(String context, ElementKind kind) {
-    var contextMap = byKind.putIfAbsent(context, () => {});
-    var key = _ElementKind(kind);
-    contextMap[key] = (contextMap[key] ?? 0) + 1;
-  }
-
-  /// Record that the given [keyword] was found in the given [context].
-  void recordKeyword(String context, Keyword keyword) {
-    var contextMap = byKind.putIfAbsent(context, () => {});
-    var key = _Keyword(keyword);
-    contextMap[key] = (contextMap[key] ?? 0) + 1;
-  }
-
-  /// Add the data in the [source] map to the [target] map.
-  void _addToMap<K>(Map<K, Map<K, int>> target, Map<K, Map<K, int>> source) {
-    for (var outerEntry in source.entries) {
-      var innerTarget = target.putIfAbsent(outerEntry.key, () => {});
-      for (var innerEntry in outerEntry.value.entries) {
-        var innerKey = innerEntry.key;
-        innerTarget[innerKey] = (innerTarget[innerKey] ?? 0) + innerEntry.value;
-      }
-    }
-  }
-}
-
-/// An object that visits a compilation unit in order to record the data used to
-/// compute the metrics.
-class RelevanceDataCollector extends RecursiveAstVisitor<void> {
-  static const List<Keyword> declarationKeywords = [
-    Keyword.MIXIN,
-    Keyword.TYPEDEF
-  ];
-
-  static const List<Keyword> directiveKeywords = [
-    Keyword.EXPORT,
-    Keyword.IMPORT,
-    Keyword.LIBRARY,
-    Keyword.PART
-  ];
-
-  static const List<Keyword> exportKeywords = [
-    Keyword.AS,
-    Keyword.HIDE,
-    Keyword.SHOW
-  ];
-
-  static const List<Keyword> expressionKeywords = [
-    Keyword.AWAIT,
-    Keyword.SUPER
-  ];
-
-  static const List<Keyword> functionBodyKeywords = [
-    Keyword.ASYNC,
-    Keyword.SYNC
-  ];
-
-  static const List<Keyword> importKeywords = [
-    Keyword.AS,
-    Keyword.HIDE,
-    Keyword.SHOW
-  ];
-
-  static const List<Keyword> memberKeywords = [
-    Keyword.FACTORY,
-    Keyword.GET,
-    Keyword.OPERATOR,
-    Keyword.SET,
-    Keyword.STATIC
-  ];
-
-  static const List<Keyword> noKeywords = [];
-
-  static const List<Keyword> statementKeywords = [Keyword.AWAIT, Keyword.YIELD];
-
-  /// The relevance data being collected.
-  final RelevanceData data;
-
-  /// The compilation unit in which data is currently being collected.
-  CompilationUnit unit;
-
-  InheritanceManager3 inheritanceManager = InheritanceManager3();
-
-  /// The library containing the compilation unit being visited.
-  LibraryElement enclosingLibrary;
-
-  /// The type provider associated with the current compilation unit.
-  TypeProvider typeProvider;
-
-  /// The type system associated with the current compilation unit.
-  TypeSystem typeSystem;
-
-  /// The object used to compute the values of features.
-  FeatureComputer featureComputer;
-
-  /// Initialize a newly created collector to add data points to the given
-  /// [data].
-  RelevanceDataCollector(this.data);
-
-  /// Initialize this collector prior to visiting the unit in the [result].
-  void initializeFrom(ResolvedUnitResult result) {
-    unit = result.unit;
-  }
-
-  @override
-  void visitAdjacentStrings(AdjacentStrings node) {
-    // There are no completions.
-    super.visitAdjacentStrings(node);
-  }
-
-  @override
-  void visitAnnotation(Annotation node) {
-    _recordDataForNode('Annotation_name', node.name);
-    super.visitAnnotation(node);
-  }
-
-  @override
-  void visitArgumentList(ArgumentList node) {
-    var context = _argumentListContext(node);
-    for (var argument in node.arguments) {
-      var realArgument = argument;
-      var argumentKind = 'unnamed';
-      if (argument is NamedExpression) {
-        realArgument = argument.expression;
-        argumentKind = 'named';
-      }
-      _recordDataForNode('ArgumentList_${context}_$argumentKind', realArgument,
-          allowedKeywords: expressionKeywords);
-    }
-    super.visitArgumentList(node);
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    _recordDataForNode('AsExpression_type', node.type);
-    super.visitAsExpression(node);
-  }
-
-  @override
-  void visitAssertInitializer(AssertInitializer node) {
-    _recordDataForNode('AssertInitializer_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    _recordDataForNode('AssertInitializer_message', node.message,
-        allowedKeywords: expressionKeywords);
-    super.visitAssertInitializer(node);
-  }
-
-  @override
-  void visitAssertStatement(AssertStatement node) {
-    _recordDataForNode('AssertStatement_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    _recordDataForNode('AssertStatement_message', node.message,
-        allowedKeywords: expressionKeywords);
-    super.visitAssertStatement(node);
-  }
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    _recordDataForNode('AssignmentExpression_rightHandSide', node.rightHandSide,
-        allowedKeywords: expressionKeywords);
-    super.visitAssignmentExpression(node);
-  }
-
-  @override
-  void visitAwaitExpression(AwaitExpression node) {
-    _recordDataForNode('AwaitExpression_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitAwaitExpression(node);
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    _recordDataForNode(
-        'BinaryExpression_${node.operator}_rightOperand', node.rightOperand,
-        allowedKeywords: expressionKeywords);
-    super.visitBinaryExpression(node);
-  }
-
-  @override
-  void visitBlock(Block node) {
-    for (var statement in node.statements) {
-      // Function declaration statements that have no return type begin with an
-      // identifier but don't have an element kind associated with the
-      // identifier.
-      _recordDataForNode('Block_statement', statement,
-          allowedKeywords: statementKeywords);
-    }
-    super.visitBlock(node);
-  }
-
-  @override
-  void visitBlockFunctionBody(BlockFunctionBody node) {
-    _recordKeyword('BlockFunctionBody_start', node,
-        allowedKeywords: functionBodyKeywords);
-    super.visitBlockFunctionBody(node);
-  }
-
-  @override
-  void visitBooleanLiteral(BooleanLiteral node) {
-    _recordKeyword('BooleanLiteral_start', node);
-    super.visitBooleanLiteral(node);
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    // The token following the `break` (if there is one) is always a label.
-    super.visitBreakStatement(node);
-  }
-
-  @override
-  void visitCascadeExpression(CascadeExpression node) {
-    for (var cascade in node.cascadeSections) {
-      _recordDataForNode('CascadeExpression_cascadeSection', cascade);
-    }
-    super.visitCascadeExpression(node);
-  }
-
-  @override
-  void visitCatchClause(CatchClause node) {
-    _recordDataForNode('CatchClause_exceptionType', node.exceptionType);
-    super.visitCatchClause(node);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    var context = 'name';
-    if (node.extendsClause != null) {
-      _recordKeyword('ClassDeclaration_$context', node.extendsClause,
-          allowedKeywords: [Keyword.EXTENDS]);
-      context = 'extends';
-    }
-    if (node.withClause != null) {
-      _recordKeyword('ClassDeclaration_$context', node.withClause);
-      context = 'with';
-    }
-    _recordKeyword('ClassDeclaration_$context', node.implementsClause,
-        allowedKeywords: [Keyword.IMPLEMENTS]);
-
-    for (var member in node.members) {
-      _recordDataForNode('ClassDeclaration_member', member,
-          allowedKeywords: memberKeywords);
-    }
-    super.visitClassDeclaration(node);
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    _recordDataForNode('ClassTypeAlias_superclass', node.superclass);
-    var context = 'superclass';
-    if (node.withClause != null) {
-      _recordKeyword('ClassTypeAlias_$context', node.withClause);
-      context = 'with';
-    }
-    _recordKeyword('ClassTypeAlias_$context', node.implementsClause);
-    super.visitClassTypeAlias(node);
-  }
-
-  @override
-  void visitComment(Comment node) {
-    // There are no completions.
-    super.visitComment(node);
-  }
-
-  @override
-  void visitCommentReference(CommentReference node) {
-    _recordDataForNode('CommentReference_identifier', node.identifier);
-    super.visitCommentReference(node);
-  }
-
-  @override
-  void visitCompilationUnit(CompilationUnit node) {
-    enclosingLibrary = node.declaredElement.library;
-    typeProvider = enclosingLibrary.typeProvider;
-    typeSystem = enclosingLibrary.typeSystem;
-    inheritanceManager = InheritanceManager3();
-    featureComputer = FeatureComputer(typeSystem, typeProvider);
-
-    for (var directive in node.directives) {
-      _recordKeyword('CompilationUnit_directive', directive,
-          allowedKeywords: directiveKeywords);
-    }
-    for (var declaration in node.declarations) {
-      _recordDataForNode('CompilationUnit_declaration', declaration,
-          allowedKeywords: declarationKeywords);
-    }
-    super.visitCompilationUnit(node);
-
-    featureComputer = null;
-    inheritanceManager = null;
-    typeSystem = null;
-    typeProvider = null;
-    enclosingLibrary = null;
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    _recordDataForNode(
-        'ConditionalExpression_thenExpression', node.thenExpression,
-        allowedKeywords: expressionKeywords);
-    _recordDataForNode(
-        'ConditionalExpression_elseExpression', node.elseExpression,
-        allowedKeywords: expressionKeywords);
-    super.visitConditionalExpression(node);
-  }
-
-  @override
-  void visitConfiguration(Configuration node) {
-    // There are no completions.
-    super.visitConfiguration(node);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    _recordDataForNode('ConstructorDeclaration_returnType', node.returnType);
-    for (var initializer in node.initializers) {
-      _recordDataForNode('ConstructorDeclaration_initializer', initializer);
-    }
-    super.visitConstructorDeclaration(node);
-  }
-
-  @override
-  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    _recordDataForNode(
-        'ConstructorFieldInitializer_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitConstructorFieldInitializer(node);
-  }
-
-  @override
-  void visitConstructorName(ConstructorName node) {
-    // The token following the `.` is always the name of a constructor.
-    super.visitConstructorName(node);
-  }
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {
-    // The token following the `continue` (if there is one) is always a label.
-    super.visitContinueStatement(node);
-  }
-
-  @override
-  void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    // There are no completions.
-    super.visitDeclaredIdentifier(node);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    _recordDataForNode('DefaultFormalParameter_defaultValue', node.defaultValue,
-        allowedKeywords: expressionKeywords);
-    super.visitDefaultFormalParameter(node);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    _recordDataForNode('DoStatement_body', node.body,
-        allowedKeywords: statementKeywords);
-    _recordDataForNode('DoStatement_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    super.visitDoStatement(node);
-  }
-
-  @override
-  void visitDottedName(DottedName node) {
-    // The components are always identifiers.
-    super.visitDottedName(node);
-  }
-
-  @override
-  void visitDoubleLiteral(DoubleLiteral node) {
-    // There are no completions.
-    super.visitDoubleLiteral(node);
-  }
-
-  @override
-  void visitEmptyFunctionBody(EmptyFunctionBody node) {
-    // There are no completions.
-    super.visitEmptyFunctionBody(node);
-  }
-
-  @override
-  void visitEmptyStatement(EmptyStatement node) {
-    // There are no completions.
-    super.visitEmptyStatement(node);
-  }
-
-  @override
-  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    // There are no completions.
-    super.visitEnumConstantDeclaration(node);
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    // There are no completions.
-    super.visitEnumDeclaration(node);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    var context = 'uri';
-    if (node.configurations.isNotEmpty) {
-      _recordKeyword('ImportDirective_$context', node.configurations[0],
-          allowedKeywords: exportKeywords);
-      context = 'configurations';
-    }
-    if (node.combinators.isNotEmpty) {
-      _recordKeyword('ImportDirective_$context', node.combinators[0],
-          allowedKeywords: exportKeywords);
-    }
-    for (var combinator in node.combinators) {
-      _recordKeyword('ImportDirective_combinator', combinator,
-          allowedKeywords: exportKeywords);
-    }
-    super.visitExportDirective(node);
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    _recordKeyword('ExpressionFunctionBody_start', node,
-        allowedKeywords: functionBodyKeywords);
-    _recordDataForNode('ExpressionFunctionBody_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitExpressionFunctionBody(node);
-  }
-
-  @override
-  void visitExpressionStatement(ExpressionStatement node) {
-    _recordDataForNode('ExpressionStatement_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitExpressionStatement(node);
-  }
-
-  @override
-  void visitExtendsClause(ExtendsClause node) {
-    _recordDataForNode('ExtendsClause_superclass', node.superclass);
-    super.visitExtendsClause(node);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    _recordDataForNode('ExtensionDeclaration_extendedType', node.extendedType);
-    for (var member in node.members) {
-      _recordDataForNode('ExtensionDeclaration_member', member,
-          allowedKeywords: memberKeywords);
-    }
-    super.visitExtensionDeclaration(node);
-  }
-
-  @override
-  void visitExtensionOverride(ExtensionOverride node) {
-    // There are no completions.
-    super.visitExtensionOverride(node);
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    _recordDataForNode('FieldDeclaration_fields', node.fields);
-    super.visitFieldDeclaration(node);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    // The completions after `this.` are always existing fields.
-    super.visitFieldFormalParameter(node);
-  }
-
-  @override
-  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
-    _recordDataForNode(
-        'ForEachPartsWithDeclaration_loopVariable', node.loopVariable);
-    _recordDataForNode('ForEachPartsWithDeclaration_iterable', node.iterable,
-        allowedKeywords: expressionKeywords);
-    super.visitForEachPartsWithDeclaration(node);
-  }
-
-  @override
-  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
-    _recordDataForNode(
-        'ForEachPartsWithIdentifier_identifier', node.identifier);
-    _recordDataForNode('ForEachPartsWithIdentifier_iterable', node.iterable,
-        allowedKeywords: expressionKeywords);
-    super.visitForEachPartsWithIdentifier(node);
-  }
-
-  @override
-  void visitForElement(ForElement node) {
-    _recordDataForNode('ForElement_forLoopParts', node.forLoopParts);
-    _recordDataForNode('ForElement_body', node.body);
-    super.visitForElement(node);
-  }
-
-  @override
-  void visitFormalParameterList(FormalParameterList node) {
-    for (var parameter in node.parameters) {
-      _recordDataForNode('FormalParameterList_parameter', parameter,
-          allowedKeywords: [Keyword.COVARIANT]);
-    }
-    super.visitFormalParameterList(node);
-  }
-
-  @override
-  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
-    _recordDataForNode('ForParts_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    for (var updater in node.updaters) {
-      _recordDataForNode('ForParts_updater', updater,
-          allowedKeywords: expressionKeywords);
-    }
-    super.visitForPartsWithDeclarations(node);
-  }
-
-  @override
-  void visitForPartsWithExpression(ForPartsWithExpression node) {
-    _recordDataForNode('ForParts_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    for (var updater in node.updaters) {
-      _recordDataForNode('ForParts_updater', updater,
-          allowedKeywords: expressionKeywords);
-    }
-    super.visitForPartsWithExpression(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    _recordDataForNode('ForStatement_forLoopParts', node.forLoopParts);
-    _recordDataForNode('ForStatement_body', node.body,
-        allowedKeywords: statementKeywords);
-    super.visitForStatement(node);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    _recordDataForNode('FunctionDeclaration_returnType', node.returnType);
-    super.visitFunctionDeclaration(node);
-  }
-
-  @override
-  void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    // There are no completions.
-    super.visitFunctionDeclarationStatement(node);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    // There are no completions.
-    super.visitFunctionExpression(node);
-  }
-
-  @override
-  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    // There are no completions.
-    super.visitFunctionExpressionInvocation(node);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    // There are no completions.
-    super.visitFunctionTypeAlias(node);
-  }
-
-  @override
-  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    // There are no completions.
-    super.visitFunctionTypedFormalParameter(node);
-  }
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    // There are no completions.
-    super.visitGenericFunctionType(node);
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    _recordDataForNode('GenericTypeAlias_functionType', node.functionType,
-        allowedKeywords: [Keyword.FUNCTION]);
-    super.visitGenericTypeAlias(node);
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    for (var hiddenName in node.hiddenNames) {
-      _recordDataForNode('HideCombinator_hiddenName', hiddenName);
-    }
-    super.visitHideCombinator(node);
-  }
-
-  @override
-  void visitIfElement(IfElement node) {
-    _recordDataForNode('IfElement_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    _recordDataForNode('IfElement_thenElement', node.thenElement);
-    _recordDataForNode('IfElement_elseElement', node.elseElement);
-    super.visitIfElement(node);
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    _recordDataForNode('IfStatement_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    _recordDataForNode('IfStatement_thenStatement', node.thenStatement,
-        allowedKeywords: statementKeywords);
-    _recordDataForNode('IfStatement_elseStatement', node.elseStatement,
-        allowedKeywords: statementKeywords);
-    super.visitIfStatement(node);
-  }
-
-  @override
-  void visitImplementsClause(ImplementsClause node) {
-    // At the start of each type name.
-    for (var typeName in node.interfaces) {
-      _recordDataForNode('ImplementsClause_interface', typeName);
-    }
-    super.visitImplementsClause(node);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    var context = 'uri';
-    if (node.deferredKeyword != null) {
-      data.recordKeyword('ImportDirective_$context', node.deferredKeyword.type);
-      context = 'deferred';
-    }
-    if (node.asKeyword != null) {
-      data.recordKeyword('ImportDirective_$context', node.asKeyword.type);
-      context = 'prefix';
-    }
-    if (node.configurations.isNotEmpty) {
-      _recordKeyword('ImportDirective_$context', node.configurations[0],
-          allowedKeywords: importKeywords);
-      context = 'configurations';
-    }
-    if (node.combinators.isNotEmpty) {
-      _recordKeyword('ImportDirective_$context', node.combinators[0],
-          allowedKeywords: importKeywords);
-    }
-    for (var combinator in node.combinators) {
-      _recordKeyword('ImportDirective_combinator', combinator,
-          allowedKeywords: importKeywords);
-    }
-    super.visitImportDirective(node);
-  }
-
-  @override
-  void visitIndexExpression(IndexExpression node) {
-    _recordDataForNode('IndexExpression_index', node.index,
-        allowedKeywords: expressionKeywords);
-    super.visitIndexExpression(node);
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    _recordDataForNode(
-        'InstanceCreationExpression_constructorName', node.constructorName);
-    super.visitInstanceCreationExpression(node);
-  }
-
-  @override
-  void visitIntegerLiteral(IntegerLiteral node) {
-    // There are no completions.
-    super.visitIntegerLiteral(node);
-  }
-
-  @override
-  void visitInterpolationExpression(InterpolationExpression node) {
-    // TODO(brianwilkerson) Consider splitting this based on whether the
-    //  expression is a simple identifier ('$') or a full expression ('${').
-    _recordDataForNode('InterpolationExpression_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitInterpolationExpression(node);
-  }
-
-  @override
-  void visitInterpolationString(InterpolationString node) {
-    // There are no completions.
-    super.visitInterpolationString(node);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    _recordDataForNode('IsExpression_type', node.type);
-    super.visitIsExpression(node);
-  }
-
-  @override
-  void visitLabel(Label node) {
-    // There are no completions.
-    super.visitLabel(node);
-  }
-
-  @override
-  void visitLabeledStatement(LabeledStatement node) {
-    _recordDataForNode('LabeledStatement_statement', node.statement,
-        allowedKeywords: statementKeywords);
-    super.visitLabeledStatement(node);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    // There are no completions.
-    super.visitLibraryDirective(node);
-  }
-
-  @override
-  void visitLibraryIdentifier(LibraryIdentifier node) {
-    // There are no completions.
-    super.visitLibraryIdentifier(node);
-  }
-
-  @override
-  void visitListLiteral(ListLiteral node) {
-    for (var element in node.elements) {
-      _recordDataForNode('ListLiteral_element', element,
-          allowedKeywords: expressionKeywords);
-    }
-    super.visitListLiteral(node);
-  }
-
-  @override
-  void visitMapLiteralEntry(MapLiteralEntry node) {
-    _recordDataForNode('MapLiteralEntry_value', node.value,
-        allowedKeywords: expressionKeywords);
-    super.visitMapLiteralEntry(node);
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    _recordDataForNode('MethodDeclaration_returnType', node.returnType);
-    super.visitMethodDeclaration(node);
-  }
-
-  @override
-  void visitMethodInvocation(MethodInvocation node) {
-    // There are no completions.
-    super.visitMethodInvocation(node);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    var context = 'name';
-    if (node.onClause != null) {
-      _recordKeyword('MixinDeclaration_$context', node.onClause,
-          allowedKeywords: [Keyword.ON]);
-      context = 'on';
-    }
-    _recordKeyword('MixinDeclaration_$context', node.implementsClause,
-        allowedKeywords: [Keyword.IMPLEMENTS]);
-
-    for (var member in node.members) {
-      _recordDataForNode('MixinDeclaration_member', member,
-          allowedKeywords: memberKeywords);
-    }
-    super.visitMixinDeclaration(node);
-  }
-
-  @override
-  void visitNamedExpression(NamedExpression node) {
-    // Named expressions only occur in argument lists and are handled there.
-    super.visitNamedExpression(node);
-  }
-
-  @override
-  void visitNativeClause(NativeClause node) {
-    // There are no completions.
-    super.visitNativeClause(node);
-  }
-
-  @override
-  void visitNativeFunctionBody(NativeFunctionBody node) {
-    // There are no completions.
-    super.visitNativeFunctionBody(node);
-  }
-
-  @override
-  void visitNullLiteral(NullLiteral node) {
-    // There are no completions.
-    super.visitNullLiteral(node);
-  }
-
-  @override
-  void visitOnClause(OnClause node) {
-    for (var constraint in node.superclassConstraints) {
-      _recordDataForNode('OnClause_superclassConstraint', constraint);
-    }
-    super.visitOnClause(node);
-  }
-
-  @override
-  void visitParenthesizedExpression(ParenthesizedExpression node) {
-    _recordDataForNode('ParenthesizedExpression_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitParenthesizedExpression(node);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    // There are no completions.
-    super.visitPartDirective(node);
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    // There are no completions.
-    super.visitPartOfDirective(node);
-  }
-
-  @override
-  void visitPostfixExpression(PostfixExpression node) {
-    // There are no completions.
-    super.visitPostfixExpression(node);
-  }
-
-  @override
-  void visitPrefixedIdentifier(PrefixedIdentifier node) {
-    // There are no completions.
-    super.visitPrefixedIdentifier(node);
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    _recordDataForNode(
-        'PrefixExpression_${node.operator}_operand', node.operand,
-        allowedKeywords: expressionKeywords);
-    super.visitPrefixExpression(node);
-  }
-
-  @override
-  void visitPropertyAccess(PropertyAccess node) {
-    _recordDataForNode('PropertyAccess_propertyName', node.propertyName);
-    super.visitPropertyAccess(node);
-  }
-
-  @override
-  void visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    // There are no completions.
-    super.visitRedirectingConstructorInvocation(node);
-  }
-
-  @override
-  void visitRethrowExpression(RethrowExpression node) {
-    // There are no completions.
-    super.visitRethrowExpression(node);
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    _recordDataForNode('ReturnStatement_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitReturnStatement(node);
-  }
-
-  @override
-  void visitScriptTag(ScriptTag node) {
-    // There are no completions.
-    super.visitScriptTag(node);
-  }
-
-  @override
-  void visitSetOrMapLiteral(SetOrMapLiteral node) {
-    for (var element in node.elements) {
-      _recordDataForNode('SetOrMapLiteral_element', element,
-          allowedKeywords: expressionKeywords);
-    }
-    super.visitSetOrMapLiteral(node);
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    for (var name in node.shownNames) {
-      _recordDataForNode('ShowCombinator_shownName', name);
-    }
-    super.visitShowCombinator(node);
-  }
-
-  @override
-  void visitSimpleFormalParameter(SimpleFormalParameter node) {
-    // There are no completions.
-    super.visitSimpleFormalParameter(node);
-  }
-
-  @override
-  void visitSimpleStringLiteral(SimpleStringLiteral node) {
-    // There are no completions.
-    super.visitSimpleStringLiteral(node);
-  }
-
-  @override
-  void visitSpreadElement(SpreadElement node) {
-    _recordDataForNode('SpreadElement_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitSpreadElement(node);
-  }
-
-  @override
-  void visitStringInterpolation(StringInterpolation node) {
-    // There are no completions.
-    super.visitStringInterpolation(node);
-  }
-
-  @override
-  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    // There are no completions.
-    super.visitSuperConstructorInvocation(node);
-  }
-
-  @override
-  void visitSuperExpression(SuperExpression node) {
-    // There are no completions.
-    super.visitSuperExpression(node);
-  }
-
-  @override
-  void visitSwitchCase(SwitchCase node) {
-    _recordDataForNode('SwitchCase_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    for (var statement in node.statements) {
-      _recordDataForNode('SwitchMember_statement', statement,
-          allowedKeywords: statementKeywords);
-    }
-    super.visitSwitchCase(node);
-  }
-
-  @override
-  void visitSwitchDefault(SwitchDefault node) {
-    for (var statement in node.statements) {
-      _recordDataForNode('SwitchMember_statement', statement,
-          allowedKeywords: statementKeywords);
-    }
-    super.visitSwitchDefault(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    _recordDataForNode('SwitchStatement_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitSwitchStatement(node);
-  }
-
-  @override
-  void visitSymbolLiteral(SymbolLiteral node) {
-    // There are no completions.
-    super.visitSymbolLiteral(node);
-  }
-
-  @override
-  void visitThisExpression(ThisExpression node) {
-    // There are no completions.
-    super.visitThisExpression(node);
-  }
-
-  @override
-  void visitThrowExpression(ThrowExpression node) {
-    _recordDataForNode('ThrowExpression_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitThrowExpression(node);
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    // There are no completions.
-    super.visitTopLevelVariableDeclaration(node);
-  }
-
-  @override
-  void visitTryStatement(TryStatement node) {
-    var context = 'try';
-    for (var clause in node.catchClauses) {
-      _recordKeyword('TryStatement_$context', clause,
-          allowedKeywords: [Keyword.ON]);
-      context = 'catch';
-    }
-    if (node.finallyKeyword != null) {
-      data.recordKeyword('TryStatement_$context', node.finallyKeyword.type);
-    }
-    super.visitTryStatement(node);
-  }
-
-  @override
-  void visitTypeArgumentList(TypeArgumentList node) {
-    for (var typeArgument in node.arguments) {
-      _recordDataForNode('TypeArgumentList_argument', typeArgument);
-    }
-    super.visitTypeArgumentList(node);
-  }
-
-  @override
-  void visitTypeName(TypeName node) {
-    // There are no completions.
-    super.visitTypeName(node);
-  }
-
-  @override
-  void visitTypeParameter(TypeParameter node) {
-    if (node.bound != null) {
-      _recordDataForNode('TypeParameter_bound', node.bound);
-    }
-    super.visitTypeParameter(node);
-  }
-
-  @override
-  void visitTypeParameterList(TypeParameterList node) {
-    // There are no completions.
-    super.visitTypeParameterList(node);
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    var keywords = node.parent.parent is FieldDeclaration
-        ? [Keyword.COVARIANT, ...expressionKeywords]
-        : expressionKeywords;
-    _recordDataForNode('VariableDeclaration_initializer', node.initializer,
-        allowedKeywords: keywords);
-    super.visitVariableDeclaration(node);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    _recordDataForNode('VariableDeclarationList_type', node.type);
-    super.visitVariableDeclarationList(node);
-  }
-
-  @override
-  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    // There are no completions.
-    super.visitVariableDeclarationStatement(node);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    _recordDataForNode('WhileStatement_condition', node.condition,
-        allowedKeywords: expressionKeywords);
-    _recordDataForNode('WhileStatement_body', node.body,
-        allowedKeywords: statementKeywords);
-    super.visitWhileStatement(node);
-  }
-
-  @override
-  void visitWithClause(WithClause node) {
-    for (var typeName in node.mixinTypes) {
-      _recordDataForNode('WithClause_mixinType', typeName);
-    }
-    super.visitWithClause(node);
-  }
-
-  @override
-  void visitYieldStatement(YieldStatement node) {
-    _recordDataForNode('YieldStatement_expression', node.expression,
-        allowedKeywords: expressionKeywords);
-    super.visitYieldStatement(node);
-  }
-
-  /// Return the context in which the [node] occurs. The [node] is expected to
-  /// be the parent of the argument expression.
-  String _argumentListContext(AstNode node) {
-    if (node is ArgumentList) {
-      var parent = node.parent;
-      if (parent is Annotation) {
-        return 'annotation';
-      } else if (parent is ExtensionOverride) {
-        return 'extensionOverride';
-      } else if (parent is FunctionExpressionInvocation) {
-        return 'function';
-      } else if (parent is InstanceCreationExpression) {
-        if (Flutter.instance.isWidgetType(parent.staticType)) {
-          return 'widgetConstructor';
-        }
-        return 'constructor';
-      } else if (parent is MethodInvocation) {
-        return 'method';
-      } else if (parent is RedirectingConstructorInvocation) {
-        return 'constructorRedirect';
-      } else if (parent is SuperConstructorInvocation) {
-        return 'constructorRedirect';
-      }
-    } else if (node is AssignmentExpression ||
-        node is BinaryExpression ||
-        node is PrefixExpression ||
-        node is PostfixExpression) {
-      return 'operator';
-    } else if (node is IndexExpression) {
-      return 'index';
-    }
-    throw ArgumentError(
-        'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
-  }
-
-  /// Return the first child of the [node] that is neither a comment nor an
-  /// annotation.
-  SyntacticEntity _firstChild(AstNode node) {
-    var children = node.childEntities.toList();
-    for (var i = 0; i < children.length; i++) {
-      var child = children[i];
-      if (child is! Comment && child is! Annotation) {
-        return child;
-      }
-    }
-    return null;
-  }
-
-  /// Return the element associated with the left-most identifier that is a
-  /// child of the [node].
-  Element _leftMostElement(AstNode node) =>
-      _leftMostIdentifier(node)?.staticElement;
-
-  /// Return the left-most child of the [node] if it is a simple identifier, or
-  /// `null` if the left-most child is not a simple identifier. Comments and
-  /// annotations are ignored for this purpose.
-  SimpleIdentifier _leftMostIdentifier(AstNode node) {
-    var currentNode = node;
-    while (currentNode != null && currentNode is! SimpleIdentifier) {
-      var firstChild = _firstChild(currentNode);
-      if (firstChild is AstNode) {
-        currentNode = firstChild;
-      } else {
-        currentNode = null;
-      }
-    }
-    if (currentNode is SimpleIdentifier && currentNode.inDeclarationContext()) {
-      return null;
-    }
-    return currentNode;
-  }
-
-  /// Return the element kind of the element associated with the left-most
-  /// identifier that is a child of the [node].
-  ElementKind _leftMostKind(AstNode node) {
-    if (node is InstanceCreationExpression) {
-      return featureComputer
-          .computeElementKind(node.constructorName.staticElement);
-    }
-    var element = _leftMostElement(node);
-    if (element == null) {
-      return null;
-    }
-    if (element is ClassElement) {
-      var parent = node.parent;
-      if (parent is Annotation && parent.arguments != null) {
-        element = parent.element;
-      }
-    }
-    return featureComputer.computeElementKind(element);
-  }
-
-  /// Return the left-most token that is a child of the [node].
-  Token _leftMostToken(AstNode node) {
-    SyntacticEntity entity = node;
-    while (entity is AstNode) {
-      entity = _firstChild(entity as AstNode);
-    }
-    if (entity is Token) {
-      return entity;
-    }
-    return null;
-  }
-
-  /// Record information about the given [node] occurring in the given
-  /// [context].
-  void _recordDataForNode(String context, AstNode node,
-      {List<Keyword> allowedKeywords = noKeywords}) {
-    _recordElementKind(context, node);
-    _recordKeyword(context, node, allowedKeywords: allowedKeywords);
-  }
-
-  /// Record the element kind of the element associated with the left-most
-  /// identifier that is a child of the [node] in the given [context].
-  void _recordElementKind(String context, AstNode node) {
-    if (node != null) {
-      var kind = _leftMostKind(node);
-      if (kind != null) {
-        data.recordElementKind(context, kind);
-        if (node is Expression) {
-          data.recordElementKind('Expression', kind);
-        } else if (node is Statement) {
-          data.recordElementKind('Statement', kind);
-        }
-      }
-    }
-  }
-
-  /// If the left-most token of the [node] is a keyword, then record that it
-  /// occurred in the given [context].
-  void _recordKeyword(String context, AstNode node,
-      {List<Keyword> allowedKeywords = noKeywords}) {
-    if (node != null) {
-      var token = _leftMostToken(node);
-      if (token.isKeyword) {
-        var keyword = token.type;
-        if (keyword == Keyword.NEW) {
-          // We don't suggest `new`, so we don't care about the frequency with
-          // which it is used.
-          return;
-        } else if (token.keyword.isBuiltInOrPseudo &&
-            !allowedKeywords.contains(token.keyword)) {
-          // These keywords can be used as identifiers, so determine whether
-          // it is being used as a keyword or an identifier.
-          return;
-        }
-        data.recordKeyword(context, keyword);
-      }
-    }
-  }
-}
-
-/// An object used to compute metrics for a single file or directory.
-class RelevanceMetricsComputer {
-  /// The metrics data that was computed.
-  final RelevanceData data = RelevanceData();
-
-  /// Initialize a newly created metrics computer that can compute the metrics
-  /// in one or more files and directories.
-  RelevanceMetricsComputer();
-
-  /// Compute the metrics for the file(s) in the [rootPath].
-  /// If [corpus] is true, treat rootPath as a container of packages, creating
-  /// a new context collection for each subdirectory.
-  Future<void> compute(String rootPath, {@required bool verbose}) async {
-    final collection = AnalysisContextCollection(
-      includedPaths: [rootPath],
-      resourceProvider: PhysicalResourceProvider.INSTANCE,
-    );
-    final collector = RelevanceDataCollector(data);
-    for (var context in collection.contexts) {
-      await _computeInContext(context.contextRoot, collector, verbose: verbose);
-    }
-  }
-
-  /// Compute the metrics for the files in the context [root], creating a
-  /// separate context collection to prevent accumulating memory. The metrics
-  /// should be captured in the [collector]. Include additional details in the
-  /// output if [verbose] is `true`.
-  Future<void> _computeInContext(
-      ContextRoot root, RelevanceDataCollector collector,
-      {@required bool verbose}) async {
-    // Create a new collection to avoid consuming large quantities of memory.
-    final collection = AnalysisContextCollection(
-      includedPaths: root.includedPaths.toList(),
-      excludedPaths: root.excludedPaths.toList(),
-      resourceProvider: PhysicalResourceProvider.INSTANCE,
-    );
-    var context = collection.contexts[0];
-    for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
-        try {
-          var resolvedUnitResult =
-              await context.currentSession.getResolvedUnit(filePath);
-          //
-          // Check for errors that cause the file to be skipped.
-          //
-          if (resolvedUnitResult == null) {
-            print('File $filePath skipped because resolved unit was null.');
-            if (verbose) {
-              print('');
-            }
-            continue;
-          } else if (resolvedUnitResult.state != ResultState.VALID) {
-            print('File $filePath skipped because it could not be analyzed.');
-            if (verbose) {
-              print('');
-            }
-            continue;
-          } else if (hasError(resolvedUnitResult)) {
-            if (verbose) {
-              print('File $filePath skipped due to errors:');
-              for (var error in resolvedUnitResult.errors
-                  .where((e) => e.severity == Severity.error)) {
-                print('  ${error.toString()}');
-              }
-              print('');
-            } else {
-              print('File $filePath skipped due to analysis errors.');
-            }
-            continue;
-          }
-
-          collector.initializeFrom(resolvedUnitResult);
-          resolvedUnitResult.unit.accept(collector);
-        } catch (exception, stacktrace) {
-          print('Exception caught analyzing: "$filePath"');
-          print(exception);
-          print(stacktrace);
-        }
-      }
-    }
-  }
-
-  /// Return `true` if the [result] contains an error.
-  static bool hasError(ResolvedUnitResult result) {
-    for (var error in result.errors) {
-      if (error.severity == Severity.error) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-/// A class used to write relevance data as a set of tables in a generated Dart
-/// file.
-class RelevanceTableWriter {
-  final StringSink sink;
-
-  RelevanceTableWriter(this.sink);
-
-  void write(RelevanceData data) {
-    writeFileHeader();
-    writeElementKindTable(data);
-    writeKeywordTable(data);
-  }
-
-  void writeElementKindTable(RelevanceData data) {
-    sink.writeln();
-    sink.write('''
-/// A table keyed by completion location and element kind whose values are the
-/// ranges of the relevance of those element kinds in those locations.
-const elementKindRelevance = {
-''');
-
-    var byKind = data.byKind;
-    var completionLocations = byKind.keys.toList()..sort();
-    for (var completionLocation in completionLocations) {
-      var counts = byKind[completionLocation];
-      if (_hasElementKind(counts)) {
-        var totalCount = _totalCount(counts);
-        // TODO(brianwilkerson) If two element kinds have the same count they
-        //  ought to have the same probability. This doesn't correctly do that.
-        var entries = counts.entries.toList()
-          ..sort((first, second) => first.value.compareTo(second.value));
-
-        sink.write("  '");
-        sink.write(completionLocation);
-        sink.writeln("': {");
-        var cumulativeCount = 0;
-        var lowerBound = 0.0;
-        for (var entry in entries) {
-          var kind = entry.key;
-          cumulativeCount += entry.value;
-          var upperBound = cumulativeCount / totalCount;
-          if (kind is _ElementKind) {
-            sink.write('    ElementKind.');
-            sink.write(kind.elementKind.name);
-            sink.write(': ProbabilityRange(lower: ');
-            sink.write(lowerBound.toStringAsFixed(3));
-            sink.write(', upper: ');
-            sink.write(upperBound.toStringAsFixed(3));
-            sink.writeln('),');
-          }
-          lowerBound = upperBound;
-        }
-        sink.writeln('  },');
-      }
-    }
-    sink.writeln('};');
-  }
-
-  void writeFileHeader() {
-    sink.write('''
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the script
-// "pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart",
-// passing it the location of a corpus of code that is large enough for the
-// computed values to be statistically meaningful.
-
-import 'package:analysis_server/src/services/completion/dart/probability_range.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-''');
-  }
-
-  void writeKeywordTable(RelevanceData data) {
-    sink.writeln();
-    sink.write('''
-/// A table keyed by completion location and keyword whose values are the
-/// ranges of the relevance of those keywords in those locations.
-const keywordRelevance = {
-''');
-
-    var byKind = data.byKind;
-    var completionLocations = byKind.keys.toList()..sort();
-    for (var completionLocation in completionLocations) {
-      var counts = byKind[completionLocation];
-      if (_hasKeyword(counts)) {
-        var totalCount = _totalCount(counts);
-        // TODO(brianwilkerson) If two keywords have the same count they ought to
-        //  have the same probability. This doesn't correctly do that.
-        var entries = counts.entries.toList()
-          ..sort((first, second) => first.value.compareTo(second.value));
-
-        sink.write("  '");
-        sink.write(completionLocation);
-        sink.writeln("': {");
-        var cumulativeCount = 0;
-        var lowerBound = 0.0;
-        for (var entry in entries) {
-          var kind = entry.key;
-          cumulativeCount += entry.value;
-          var upperBound = cumulativeCount / totalCount;
-          if (kind is _Keyword) {
-            sink.write("    '");
-            sink.write(kind.keyword.lexeme);
-            sink.write("': ProbabilityRange(lower: ");
-            sink.write(lowerBound.toStringAsFixed(3));
-            sink.write(', upper: ');
-            sink.write(upperBound.toStringAsFixed(3));
-            sink.writeln('),');
-          }
-          lowerBound = upperBound;
-        }
-        sink.writeln('  },');
-      }
-    }
-    sink.writeln('};');
-  }
-
-  /// Return `true` if the table of [counts] contains at least one key that is
-  /// an element kind.
-  bool _hasElementKind(Map<_Kind, int> counts) {
-    for (var kind in counts.keys) {
-      if (kind is _ElementKind) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// Return `true` if the table of [counts] contains at least one key that is a
-  /// keyword.
-  bool _hasKeyword(Map<_Kind, int> counts) {
-    for (var kind in counts.keys) {
-      if (kind is _Keyword) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// Return the total of the counts in the given table of [counts].
-  int _totalCount(Map<_Kind, int> counts) {
-    return counts.values
-        .fold(0, (previousValue, value) => previousValue + value);
-  }
-}
-
-/// A wrapper for an element kind to allow keywords and element kinds to be used
-/// as keys in a single table.
-class _ElementKind extends _Kind {
-  static final Map<ElementKind, _ElementKind> instances = {};
-
-  final ElementKind elementKind;
-
-  factory _ElementKind(ElementKind elementKind) =>
-      instances.putIfAbsent(elementKind, () => _ElementKind._(elementKind));
-
-  _ElementKind._(this.elementKind);
-}
-
-/// A wrapper for a keyword to allow keywords and element kinds to be used as
-/// keys in a single table.
-class _Keyword extends _Kind {
-  static final Map<Keyword, _Keyword> instances = {};
-
-  final Keyword keyword;
-
-  factory _Keyword(Keyword keyword) =>
-      instances.putIfAbsent(keyword, () => _Keyword._(keyword));
-
-  _Keyword._(this.keyword);
-}
-
-/// A superclass for [_ElementKind] and [_Keyword] to allow keywords and element
-/// kinds to be used as keys in a single table.
-class _Kind {}
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index 051abb3..961b2c5 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -29,8 +29,10 @@
 
 Client workspace settings are requested with `workspace/configuration` during initialization and re-requested whenever the client notifies the server with `workspace/didChangeConfiguration`. This allows the settings to take effect without restarting the server.
 
+- `dart.analysisExcludedFolders`: An array of paths (absolute or relative to each workspace folder) that should be excluded from analysis.
 - `dart.enableSdkFormatter`: When set to `false`, prevents registration (or unregisters) the SDK formatter. When set to `true` or not supplied, will register/reregister the SDK formatter.
 - `dart.lineLength`: The number of characters the formatter should wrap code at. If unspecified, code will be wrapped at `80` characters.
+- `dart.completeFunctionCalls`: Completes functions/methods with their required parameters.
 
 ## Method Status
 
@@ -93,7 +95,7 @@
 | textDocument/documentColor | | | | | |
 | textDocument/colorPresentation | | | | | |
 | textDocument/formatting | ✅ | ✅ | | ✅ | ✅ |
-| textDocument/rangeFormatting | | | | | | requires support from dart_style?
+| textDocument/rangeFormatting | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/onTypeFormatting | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/rename | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/prepareRename | ✅ | ✅ | | ✅ | ✅ |
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index a9f9ce5..3c8a5a2 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -327,9 +327,14 @@
     lines = _wrapLines(lines, (80 - 4 - buffer.totalIndent).clamp(0, 80));
     lines.forEach((l) => buffer.writeIndentedln('/// $l'.trim()));
   }
-  if (node.isDeprecated) {
-    buffer.writeIndentedln('@core.deprecated');
-  }
+  // Marking LSP-deprecated fields as deprecated in Dart results in a lot
+  // of warnings because we still often populate these fields for clients that
+  // may still be using them. This code is useful for enabling temporarily
+  // and reviewing which deprecated fields we should still support but isn't
+  // generally useful to keep enabled.
+  // if (node.isDeprecated) {
+  //   buffer.writeIndentedln('@core.deprecated');
+  // }
 }
 
 void _writeEnumClass(IndentableStringBuffer buffer, Namespace namespace) {
@@ -379,6 +384,10 @@
     ..outdent()
     ..writeIndentedln('}');
   namespace.members.whereType<Const>().forEach((cons) {
+    // We don't use any deprecated enum values, so ommit them entirely.
+    if (cons.isDeprecated) {
+      return;
+    }
     _writeDocCommentsAndAnnotations(buffer, cons);
     buffer.writeIndentedln(
         'static const ${_makeValidIdentifier(cons.name)} = ${namespace.name}$constructorName(${cons.valueAsLiteral});');
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 26b8916..a265eb5 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -73,7 +73,7 @@
 /// Pattern to extract inline types from the `result: {xx, yy }` notes in the spec.
 /// Doesn't parse past full stops as some of these have english sentences tagged on
 /// the end that we don't want to parse.
-final _resultsInlineTypesPattern = RegExp(r'''\* result:[^\.]*({.*})''');
+final _resultsInlineTypesPattern = RegExp(r'''\* result:[^\.{}]*({[^\.`]*})''');
 
 Future<void> downloadSpec() async {
   final specResp = await http.get(specUri);
@@ -182,8 +182,14 @@
 ''';
 
 List<AstNode> getCustomClasses() {
-  Interface interface(String name, List<Member> fields) {
-    return Interface(null, Token.identifier(name), [], [], fields);
+  Interface interface(String name, List<Member> fields, {String baseType}) {
+    return Interface(
+      null,
+      Token.identifier(name),
+      [],
+      [if (baseType != null) Type.identifier(baseType)],
+      fields,
+    );
   }
 
   Field field(String name,
@@ -250,11 +256,17 @@
       [
         field('file', type: 'string'),
         field('offset', type: 'number'),
+      ],
+    ),
+    interface(
+      'DartCompletionItemResolutionInfo',
+      [
         field('libId', type: 'number'),
         field('displayUri', type: 'string'),
         field('rOffset', type: 'number'),
-        field('rLength', type: 'number')
+        field('rLength', type: 'number'),
       ],
+      baseType: 'CompletionItemResolutionInfo',
     ),
   ];
   return customTypes;
@@ -286,9 +298,10 @@
 
 /// Returns whether a script block should be parsed or not.
 bool shouldIncludeScriptBlock(String input) {
-  // We can't parse literal arrays, but this script block is just an example
-  // and not actually referenced anywhere.
-  if (input.trim() == r"export const EOL: string[] = ['\n', '\r\n', '\r'];") {
+  // Skip over some typescript blocks that are known sample code and not part
+  // of the LSP spec.
+  if (input.trim() == r"export const EOL: string[] = ['\n', '\r\n', '\r'];" ||
+      input.startsWith('textDocument.codeAction.resolveSupport =')) {
     return false;
   }
 
diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
index 4c8b08d..14ab9bc 100644
--- a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
+++ b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
@@ -10,8 +10,8 @@
 ---
 
 Copyright (c) Microsoft Corporation.
-
-All rights reserved.
+ 
+All rights reserved. 
 
 Distributed under the following terms:
 
@@ -32,11 +32,11 @@
 
 This document describes the 3.15.x version of the language server protocol. An implementation for node of the 3.15.x version of the protocol can be found [here](https://github.com/Microsoft/vscode-languageserver-node).
 
-**Note:** edits to this specification can be made via a pull request against this markdown [document](https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-15.md).
+**Note:** edits to this specification can be made via a pull request against this Markdown [document](https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-15.md).
 
 ## <a href="#whatIsNew" name="whatIsNew" class="anchor"> What's new in 3.15 </a>
 
-All new 3.15 features are tagged with a corresponding since version 3.15 text or in JSDoc using `@since 3.15.0` annotation. Major new feature are:
+All new 3.15 features are tagged with a corresponding since version 3.15 text or in JSDoc using `@since 3.15.0` annotation. Major new features are:
 
 - [general progress support](#progress), [work done progress](#workDoneProgress) and [partial result progress](#partialResults)
 - support for [selection ranges](#textDocument_selectionRange)
@@ -299,12 +299,12 @@
 	line: number;
 
 	/**
-	 * Character offset on a line in a document (zero-based). Assuming that the line is
-	 * represented as a string, the `character` value represents the gap between the
-	 * `character` and `character + 1`.
+	 * Character offset on a line in a document (zero-based). Assuming that the
+	 * line is represented as a string, the `character` value represents the gap
+	 * between the `character` and `character + 1`.
 	 *
-	 * If the character value is greater than the line length it defaults back to the
-	 * line length.
+	 * If the character value is greater than the line length it defaults back
+	 * to the line length.
 	 */
 	character: number;
 }
@@ -353,8 +353,8 @@
 	/**
 	 * Span of the origin of this link.
 	 *
-	 * Used as the underlined span for mouse interaction. Defaults to the word range at
-	 * the mouse position.
+	 * Used as the underlined span for mouse interaction.
+	 * Defaults to the word range at the mouse position.
 	 */
 	originSelectionRange?: Range;
 
@@ -364,15 +364,19 @@
 	targetUri: DocumentUri;
 
 	/**
-	 * The full target range of this link. If the target for example is a symbol then target range is the
-	 * range enclosing this symbol not including leading/trailing whitespace but everything else
-	 * like comments. This information is typically used to highlight the range in the editor.
+	 * The full target range of this link.
+	 * For example, if the target is a symbol, then target range is the range
+	 * enclosing this symbol not including leading/trailing whitespace but
+	 * everything else like comments.
+	 * This information is typically used to highlight the range in the editor.
 	 */
 	targetRange: Range;
 
 	/**
-	 * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
-	 * Must be contained by the the `targetRange`. See also `DocumentSymbol#range`
+	 * The range that should be selected and revealed when this link is being
+	 * followed, for example, the name of a function.
+	 * Must be contained by the the `targetRange`.
+	 * See also `DocumentSymbol#range`
 	 */
 	targetSelectionRange: Range;
 }
@@ -459,8 +463,8 @@
     /**
      * Unused or unnecessary code.
      *
-     * Clients are allowed to render diagnostics with this tag faded out instead of having
-     * an error squiggle.
+     * Clients are allowed to render diagnostics with this tag faded out
+	 * instead of having an error squiggle.
      */
     export const Unnecessary: 1 = 1;
     /**
@@ -478,9 +482,9 @@
 
 ```typescript
 /**
- * Represents a related message and source code location for a diagnostic. This should be
- * used to point to code locations that cause or are related to a diagnostics, e.g when duplicating
- * a symbol in a scope.
+ * Represents a related message and source code location for a diagnostic.
+ * This should be used to point to code locations that cause or are related
+ * to a diagnostics, for example, when duplicating a symbol in a scope.
  */
 export interface DiagnosticRelatedInformation {
 	/**
@@ -681,18 +685,24 @@
 	changes?: { [uri: DocumentUri]: TextEdit[]; };
 
 	/**
-	 * Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes
-	 * are either an array of `TextDocumentEdit`s to express changes to n different text documents
-	 * where each text document edit addresses a specific version of a text document. Or it can contain
-	 * above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations.
+	 * The client capability `workspace.workspaceEdit.resourceOperations`
+	 * determines whether document changes are either an array of
+	 * `TextDocumentEdit`s to express changes to different text documents,
+	 * where each text document edit addresses a specific version
+	 * of a text document, or it can contains the above `TextDocumentEdit`s
+	 * mixed with create, rename, and delete file / folder operations.
 	 *
 	 * Whether a client supports versioned document edits is expressed via
 	 * `workspace.workspaceEdit.documentChanges` client capability.
 	 *
-	 * If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then
-	 * only plain `TextEdit`s using the `changes` property are supported.
+	 * If a client doesn't support `documentChanges` or
+	 * `workspace.workspaceEdit.resourceOperations`, then only plain
+	 * `TextEdit`s using the `changes` property are supported.
 	 */
-	documentChanges?: (TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]);
+	documentChanges?: (
+		TextDocumentEdit[] |
+		(TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]
+	);
 }
 ```
 
@@ -753,13 +763,15 @@
 	export const Delete: ResourceOperationKind = 'delete';
 }
 
-export type FailureHandlingKind = 'abort' | 'transactional' | 'undo' | 'textOnlyTransactional';
+export type FailureHandlingKind = 'abort' | 'transactional' | 'undo'
+	| 'textOnlyTransactional';
 
 export namespace FailureHandlingKind {
 
 	/**
-	 * Applying the workspace change is simply aborted if one of the changes provided
-	 * fails. All operations executed before the failing operation stay executed.
+	 * Applying the workspace change is simply aborted if one of the changes
+	 * provided fails.
+	 * All operations executed before the failing operation stay executed.
 	 */
 	export const Abort: FailureHandlingKind = 'abort';
 
@@ -771,11 +783,13 @@
 
 
 	/**
-	 * If the workspace edit contains only textual file changes they are executed transactional.
-	 * If resource changes (create, rename or delete file) are part of the change the failure
-	 * handling strategy is abort.
+	 * If the workspace edit contains only textual file changes, they are
+	 * executed transactionally.
+	 * If resource changes (create, rename or delete file) are part of the
+	 * change, the failure handling strategy is abort.
 	 */
-	export const TextOnlyTransactional: FailureHandlingKind = 'textOnlyTransactional';
+	export const TextOnlyTransactional: FailureHandlingKind
+		= 'textOnlyTransactional';
 
 	/**
 	 * The client tries to undo the operations already executed. But there is no
@@ -894,14 +908,15 @@
 ```typescript
 interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
 	/**
-	 * The version number of this document. If a versioned text document identifier
-	 * is sent from the server to the client and the file is not open in the editor
-	 * (the server has not received an open notification before) the server can send
-	 * `null` to indicate that the version is known and the content on disk is the
-	 * master (as speced with document content ownership).
+	 * The version number of this document.
+	 * If a versioned text document identifier is sent from the server to the
+	 * client and the file is not open in the editor (the server has not
+	 * received an open notification before), the server can send `null` to
+	 * indicate that the version is known and the content on disk is the
+	 * master (as specified with document content ownership).
 	 *
-	 * The version number of a document will increase after each change, including
-	 * undo/redo. The number doesn't need to be consecutive.
+	 * The version number of a document will increase after each change,
+	 * including undo/redo. The number doesn't need to be consecutive.
 	 */
 	version: number | null;
 }
@@ -954,9 +969,13 @@
 	 * - `*` to match one or more characters in a path segment
 	 * - `?` to match on one character in a path segment
 	 * - `**` to match any number of path segments, including none
-	 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
-	 * - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
-	 * - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+	 * - `{}` to group conditions
+	 *   (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+	 * - `[]` to declare a range of characters to match in a path segment
+	 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+	 * - `[!...]` to negate a range of characters to match in a path segment
+	 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
+	 *    but not `example.0`)
 	 */
 	pattern?: string;
 }
@@ -995,8 +1014,9 @@
  */
 export interface TextDocumentRegistrationOptions {
 	/**
-	 * A document selector to identify the scope of the registration. If set to null
-	 * the document selector provided on the client side will be used.
+	 * A document selector to identify the scope of the registration.
+	 * If set to null, the document selector provided on the client side
+	 * will be used.
 	 */
 	documentSelector: DocumentSelector | null;
 }
@@ -1004,7 +1024,7 @@
 
 #### <a href="#markupContent" name="markupContent" class="anchor"> MarkupContent </a>
 
- A `MarkupContent` literal represents a string value which content can be represented in different formats. Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in documentation properties of result literals like `CompletionItem` or `SignatureInformation`.
+ A `MarkupContent` literal represents a string value which content can be represented in different formats. Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in documentation properties of result literals like `CompletionItem` or `SignatureInformation`. If the format is `markdown` the content can contain fenced code blocks like in [GitHub issues](https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting)
 
 ```typescript
 /**
@@ -1028,13 +1048,14 @@
 export type MarkupKind = 'plaintext' | 'markdown';
 
 /**
- * A `MarkupContent` literal represents a string value which content is interpreted base on its
- * kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
+ * A `MarkupContent` literal represents a string value, which content is
+ * interpreted base on its kind flag.
+ * Currently the protocol supports `plaintext` and `markdown` as markup kinds.
  *
- * If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
- * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ * If the kind is `markdown`, then the value can contain fenced code blocks
+ * like in GitHub issues.
  *
- * Here is an example how such a string can be constructed using JavaScript / TypeScript:
+ * An example how such a string is constructed using JavaScript / TypeScript:
  * ```typescript
  * let markdown: MarkdownContent = {
  *  kind: MarkupKind.Markdown,
@@ -1048,8 +1069,9 @@
  * };
  * ```
  *
- * *Please Note* that clients might sanitize the return markdown. A client could decide to
- * remove HTML from the markdown to avoid script execution.
+ * *Please Note* that clients might sanitize the returned Markdown.
+ * A client could decide to remove HTML from the Markdown to avoid
+ * script execution.
  */
 export interface MarkupContent {
 	/**
@@ -1089,8 +1111,8 @@
 
 	/**
 	 * Controls if a cancel button should show to allow the user to cancel the
-	 * long running operation. Clients that don't support cancellation are allowed
-	 * to ignore the setting.
+	 * long running operation.
+	 * Clients that don't support cancellation can ignore the setting.
 	 */
 	cancellable?: boolean;
 
@@ -1125,11 +1147,12 @@
 	kind: 'report';
 
 	/**
-	 * Controls enablement state of a cancel button. This property is only valid if a cancel
-	 * button got requested in the `WorkDoneProgressStart` payload.
+	 * Controls enablement state of a cancel button. T
+	 * This property is only valid if a cancel button is requested in
+	 * the `WorkDoneProgressStart` payload.
 	 *
-	 * Clients that don't support cancellation or don't support control the button's
-	 * enablement state are allowed to ignore the setting.
+	 * Clients that don't support cancellation or don't support controlling
+	 * the button's enablement state are allowed to ignore the setting.
 	 */
 	cancellable?: boolean;
 
@@ -1175,8 +1198,10 @@
 
 Work Done progress can be initiated in two different ways:
 
-1. by the sender of a request (mostly clients) using the predefined `workDoneToken` property in the requests parameter literal.
-1. by a server using the request `window/workDoneProgress/create`.
+1. by the sender of a request (mostly clients) using the predefined `workDoneToken` property in the requests parameter literal. The document will refer to this kind of progress as client initiated progress.
+1. by a server using the request `window/workDoneProgress/create`. The document will refer to this kind of progress as server initiated progress.
+
+###### <a href="#clientInitiatedProgress" name="clientInitiatedProgress" class="anchor">Client Initiated Progress </a>
 
 Consider a client sending a `textDocument/reference` request to a server and the client accepts work done progress reporting on that request. To signal this to the server the client would add a `workDoneToken` property to the reference request parameters. Something like this:
 
@@ -1197,6 +1222,17 @@
 }
 ```
 
+The corresponding type definition for the parameter property looks like this:
+
+```typescript
+export interface WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	workDoneToken?: ProgressToken;
+}
+```
+
 A server uses the `workDoneToken` to report progress for the specific `textDocument/reference`. For the above request the `$/progress` notification params look like this:
 
 ```json
@@ -1212,13 +1248,9 @@
 }
 ```
 
-Server initiated work done progress works the same. The only difference is that the server requests a progress user interface using the `window/workDoneProgress/create` request providing a token that is afterwards used to report progress.
+There is no specific client capability signaling whether a client will send a progress token per request. The reason for this is that this is in many clients not a static aspect and might even change for every request instance for the same request type. So the capability is signal on every request instance by the presence of a `workDoneToken` property.
 
-##### <a href="#signalingWorkDoneProgressReporting" name="signalingWorkDoneProgressReporting" class="anchor"> Signaling Work Done Progress Reporting </a>
-
-To keep the protocol backwards compatible servers are only allowed to use work done progress reporting if the client signals corresponding support using the client capability `window.workDoneProgress`.
-
-To avoid that clients set up a progress monitor user interface before sending a request but the server doesn't actually report any progress a server needs to signal work done progress reporting in the corresponding server capability. For the above find references example a server would signal such a support by setting the `referencesProvider` property in the server capabilities as follows:
+To avoid that clients set up a progress monitor user interface before sending a request but the server doesn't actually report any progress a server needs to signal general work done progress reporting support in the corresponding server capability. For the above find references example a server would signal such a support by setting the `referencesProvider` property in the server capabilities as follows:
 
 ```json
 {
@@ -1228,28 +1260,31 @@
 }
 ```
 
-#### <a href="#workDoneProgressParams" name="workDoneProgressParams" class="anchor"> WorkDoneProgressParams </a>
-
-A parameter literal used to pass a work done progress token.
-
-```typescript
-export interface WorkDoneProgressParams {
-	/**
-	 * An optional token that a server can use to report work done progress.
-	 */
-	workDoneToken?: ProgressToken;
-}
-```
-
-#### <a href="#workDoneProgressOptions" name="workDoneProgressOptions" class="anchor"> WorkDoneProgressOptions </a>
-
-Options to signal work done progress support in server capabilities.
+The corresponding type definition for the server capability looks like this:
 
 ```typescript
 export interface WorkDoneProgressOptions {
 	workDoneProgress?: boolean;
 }
 ```
+###### <a href="#serverInitiatedProgress" name="serverInitiatedProgress" class="anchor">Server Initiated Progress </a>
+
+Servers can also initiate progress reporting using the `window/workDoneProgress/create` request. This is useful if the server needs to report progress outside of a request (for example the server needs to re-index a database). The returned token can then be used to report progress using the same notifications used as for client initiated progress.
+
+To keep the protocol backwards compatible servers are only allowed to use `window/workDoneProgress/create` request if the client signals corresponding support using the client capability `window.workDoneProgress` which is defined as follows:
+
+```typescript
+	/**
+	 * Window specific client capabilities.
+	 */
+	window?: {
+		/**
+		 * Whether client supports server initiated progress using the
+		 * `window/workDoneProgress/create` request.
+		 */
+		workDoneProgress?: boolean;
+	}
+```
 
 #### <a href="#partialResults" name="partialResults" class="anchor"> Partial Result Progress </a>
 
@@ -1292,8 +1327,8 @@
 ```typescript
 export interface PartialResultParams {
 	/**
-	 * An optional token that a server can use to report partial results (e.g. streaming) to
-	 * the client.
+	 * An optional token that a server can use to report partial results
+	 * (for example, streaming) to the client.
 	 */
 	partialResultToken?: ProgressToken;
 }
@@ -1307,7 +1342,7 @@
 * an optional _Client capability_ section describing the client capability of the request. This includes the client capabilities property path and JSON structure.
 * an optional _Server Capability_ section describing the server capability of the request. This includes the server capabilities property path and JSON structure.
 * a _Request_ section describing the format of the request sent. The method is a string identifying the request the params are documented using a TypeScript interface. It is also documented whether the request supports work done progress and partial result progress.
-* a _Response_ section describing the format of the response. The result item describes the returned data in case of a success. The optional partial result item describes the returned data of a partial result notification. The error.data describes the returned data in case of an error. Please remember that in case of a failure the response already contains an error.code and an error.message field. These fields are only spec'd if the protocol forces the use of certain error codes or messages. In cases where the server can decide on these values freely they aren't listed here.
+* a _Response_ section describing the format of the response. The result item describes the returned data in case of a success. The optional partial result item describes the returned data of a partial result notification. The error.data describes the returned data in case of an error. Please remember that in case of a failure the response already contains an error.code and an error.message field. These fields are only specified if the protocol forces the use of certain error codes or messages. In cases where the server can decide on these values freely they aren't listed here.
 * a _Registration Options_ section describing the registration option if the request or notification supports dynamic capability registration.
 
 #### Request, Notification and Response ordering
@@ -1338,9 +1373,10 @@
 ```typescript
 interface InitializeParams extends WorkDoneProgressParams {
 	/**
-	 * The process Id of the parent process that started
-	 * the server. Is null if the process has not been started by another process.
-	 * If the parent process is not alive then the server should exit (see exit notification) its process.
+	 * The process ID of the parent process that started the server.
+	 * Is null if the process has not been started by another process.
+	 * If the parent process is not alive, then the server should exit
+	 * (see exit notification) its process.
 	 */
 	processId: number | null;
 
@@ -1515,7 +1551,8 @@
 	rename?: RenameClientCapabilities;
 
 	/**
-	 * Capabilities specific to the `textDocument/publishDiagnostics` notification.
+	 * Capabilities specific to the `textDocument/publishDiagnostics`
+	 * notification.
 	 */
 	publishDiagnostics?: PublishDiagnosticsClientCapabilities;
 
@@ -1558,12 +1595,14 @@
 		workspaceEdit?: WorkspaceEditClientCapabilities;
 
 		/**
-		* Capabilities specific to the `workspace/didChangeConfiguration` notification.
+		* Capabilities specific to the `workspace/didChangeConfiguration`
+		* notification.
 		*/
 		didChangeConfiguration?: DidChangeConfigurationClientCapabilities;
 
 		/**
-		* Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+		* Capabilities specific to the `workspace/didChangeWatchedFiles`
+		* notification.
 		*/
 		didChangeWatchedFiles?: DidChangeWatchedFilesClientCapabilities;
 
@@ -1602,8 +1641,9 @@
 	 */
 	window?: {
 		/**
-		 * Whether client supports handling progress notifications. If set servers are allowed to
-		 * report in `workDoneProgress` property in the request specific server capabilities.
+		 * Whether client supports handling progress notifications.
+		 * If set, servers are allowed to report in `workDoneProgress` property
+		 * in the request specific server capabilities.
 		 *
 		 * Since 3.15.0
 		 */
@@ -1653,9 +1693,10 @@
  */
 export namespace InitializeError {
 	/**
-	 * If the protocol version provided by the client can't be handled by the server.
-	 * @deprecated This initialize error got replaced by client capabilities. There is
-	 * no version handshake in version 3.0x
+	 * If the protocol version provided by the client can't be handled by
+	 * the server.
+	 * @deprecated This initialize error was replaced by client capabilities.
+	 * There is no version handshake in version 3.0x
 	 */
 	export const unknownProtocolVersion: number = 1;
 }
@@ -1680,8 +1721,10 @@
 ```typescript
 interface ServerCapabilities {
 	/**
-	 * Defines how text documents are synced. Is either a detailed structure defining each notification or
-	 * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
+	 * Defines how text documents are synced.
+	 * Is either a detailed structure defining each notification
+	 * or for backwards compatibility, the TextDocumentSyncKind number.
+	 * If omitted, it defaults to `TextDocumentSyncKind.None`.
 	 */
 	textDocumentSync?: TextDocumentSyncOptions | number;
 
@@ -1705,7 +1748,8 @@
 	 *
 	 * @since 3.14.0
 	 */
-	declarationProvider?: boolean | DeclarationOptions | DeclarationRegistrationOptions;
+	declarationProvider?: boolean | DeclarationOptions
+		| DeclarationRegistrationOptions;
 
 	/**
 	 * The server provides goto definition support.
@@ -1717,14 +1761,16 @@
 	 *
 	 * @since 3.6.0
 	 */
-	typeDefinitionProvider?: boolean | TypeDefinitionOptions | TypeDefinitionRegistrationOptions;
+	typeDefinitionProvider?: boolean | TypeDefinitionOptions
+		| TypeDefinitionRegistrationOptions;
 
 	/**
 	 * The server provides goto implementation support.
 	 *
 	 * @since 3.6.0
 	 */
-	implementationProvider?: boolean | ImplementationOptions | ImplementationRegistrationOptions;
+	implementationProvider?: boolean | ImplementationOptions
+		| ImplementationRegistrationOptions;
 
 	/**
 	 * The server provides find references support.
@@ -1742,14 +1788,15 @@
 	documentSymbolProvider?: boolean | DocumentSymbolOptions;
 
 	/**
-	 * The server provides code actions. The `CodeActionOptions` return type is only
-	 * valid if the client signals code action literal support via the property
+	 * The server provides code actions.
+	 * The `CodeActionOptions` return type is only valid if the client signals
+	 * code action literal support via the property
 	 * `textDocument.codeAction.codeActionLiteralSupport`.
 	 */
 	codeActionProvider?: boolean | CodeActionOptions;
 
 	/**
-	 * The server provides code lens.
+	 * The server provides CodeLens.
 	 */
 	codeLensProvider?: CodeLensOptions;
 
@@ -1763,7 +1810,8 @@
 	 *
 	 * @since 3.6.0
 	 */
-	colorProvider?: boolean | DocumentColorOptions | DocumentColorRegistrationOptions;
+	colorProvider?: boolean | DocumentColorOptions
+		| DocumentColorRegistrationOptions;
 
 	/**
 	 * The server provides document formatting.
@@ -1792,7 +1840,8 @@
 	 *
 	 * @since 3.10.0
 	 */
-	foldingRangeProvider?: boolean | FoldingRangeOptions | FoldingRangeRegistrationOptions;
+	foldingRangeProvider?: boolean | FoldingRangeOptions
+		| FoldingRangeRegistrationOptions;
 
 	/**
 	 * The server provides execute command support.
@@ -1804,12 +1853,13 @@
 	 *
 	 * @since 3.15.0
 	 */
-	selectionRangeProvider?: boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions;
+	selectionRangeProvider?: boolean | SelectionRangeOptions
+		| SelectionRangeRegistrationOptions;
 
 	/**
 	 * The server provides workspace symbol support.
 	 */
-	workspaceSymbolProvider?: boolean;
+	workspaceSymbolProvider?: boolean | WorkspaceSymbolOptions;
 
 	/**
 	 * Workspace specific server capabilities
@@ -2279,7 +2329,7 @@
 
 The `workspace/configuration` request is sent from the server to the client to fetch configuration settings from the client. The request can fetch several configuration settings in one roundtrip. The order of the returned configuration settings correspond to the order of the passed `ConfigurationItems` (e.g. the first item in the response is the result for the first configuration item in the params).
 
-A `ConfigurationItem` consists of the configuration section to ask for and an additional scope URI. The configuration section ask for is defined by the server and doesn't necessarily need to correspond to the configuration store used be the client. So a server might ask for a configuration `cpp.formatterOptions` but the client stores the configuration in a XML store layout differently. It is up to the client to do the necessary conversion. If a scope URI is provided the client should return the setting scoped to the provided resource. If the client for example uses [EditorConfig](http://editorconfig.org/) to manage its settings the configuration should be returned for the passed resource URI. If the client can't provide a configuration setting for a given scope then `null` need to be present in the returned array.
+A `ConfigurationItem` consists of the configuration section to ask for and an additional scope URI. The configuration section asked for is defined by the server and doesn't necessarily need to correspond to the configuration store used by the client. So a server might ask for a configuration `cpp.formatterOptions` but the client stores the configuration in an XML store layout differently. It is up to the client to do the necessary conversion. If a scope URI is provided the client should return the setting scoped to the provided resource. If the client for example uses [EditorConfig](http://editorconfig.org/) to manage its settings the configuration should be returned for the passed resource URI. If the client can't provide a configuration setting for a given scope then `null` needs to be present in the returned array.
 
 _Client Capability_:
 * property path (optional): `workspace.configuration`
@@ -2329,9 +2379,9 @@
 ```typescript
 export interface DidChangeWatchedFilesClientCapabilities {
 	/**
-	 * Did change watched files notification supports dynamic registration. Please note
-	 * that the current protocol doesn't support static configuration for file changes
-	 * from the server side.
+	 * Did change watched files notification supports dynamic registration.
+	 * Please note that the current protocol doesn't support static
+	 * configuration for file changes from the server side.
 	 */
 	dynamicRegistration?: boolean;
 }
@@ -2357,9 +2407,13 @@
 	 * - `*` to match one or more characters in a path segment
 	 * - `?` to match on one character in a path segment
 	 * - `**` to match any number of path segments, including none
-	 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
-	 * - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
-	 * - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+	 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript
+	 *   and JavaScript files)
+	 * - `[]` to declare a range of characters to match in a path segment
+	 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+	 * - `[!...]` to negate a range of characters to match in a path segment
+	 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
+	 *    but not `example.0`)
 	 */
 	globPattern: string;
 
@@ -2454,7 +2508,8 @@
 	dynamicRegistration?: boolean;
 
 	/**
-	 * Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
+	 * Specific capabilities for the `SymbolKind` in the
+	 * `workspace/symbol` request.
 	 */
 	symbolKind?: {
 		/**
@@ -2483,7 +2538,8 @@
 
 _Registration Options_: `WorkspaceSymbolRegistrationOptions` defined as follows:
 ```typescript
-export interface WorkspaceSymbolRegistrationOptions extends WorkspaceSymbolOptions {
+export interface WorkspaceSymbolRegistrationOptions
+	extends WorkspaceSymbolOptions {
 }
 ```
 
@@ -2495,7 +2551,8 @@
 /**
  * The parameters of a Workspace Symbol Request.
  */
-interface WorkspaceSymbolParams extends WorkDoneProgressParams, PartialResultParams {
+interface WorkspaceSymbolParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * A query string to filter symbols by. Clients may send an empty
 	 * string here to request all symbols.
@@ -2546,7 +2603,8 @@
 /**
  * Execute command registration options.
  */
-export interface ExecuteCommandRegistrationOptions extends ExecuteCommandOptions {
+export interface ExecuteCommandRegistrationOptions
+	extends ExecuteCommandOptions {
 }
 ```
 
@@ -2627,21 +2685,22 @@
 
 #### <a href="#textDocument_synchronization" name="textDocument_synchronization" class="anchor">Text Document Synchronization</a>
 
-Client support for `textDocument/open`, `textDocument/change` and `textDocument/close` notifications is mandatory in the protocol and clients can not opt out supporting them. This includes both full and incremental syncronization in the `textDocument/change` notification. In addition a server must either implement all three of them or none. Their capabilities are therefore controlled via a combined client and server capability.
+Client support for `textDocument/didOpen`, `textDocument/didChange` and `textDocument/didClose` notifications is mandatory in the protocol and clients can not opt out supporting them. This includes both full and incremental synchronization in the `textDocument/didChange` notification. In addition a server must either implement all three of them or none. Their capabilities are therefore controlled via a combined client and server capability.
 
-<a href="#textDocument_synchronization_cc" name="textDocument_synchronization_cc" class="anchor"></a>_Client Capability_:
+<a href="#textDocument_synchronization_cc" name="textDocument_synchronization_cc" class="anchor">_Client Capability_:</a>
 * property path (optional): `textDocument.synchronization.dynamicRegistration`
 * property type: `boolean`
 
 Controls whether text document synchronization supports dynamic registration.
 
-<a href="#textDocument_synchronization_sc" name="textDocument_synchronization_sc" class="anchor"></a>_Server Capability_:
+<a href="#textDocument_synchronization_sc" name="textDocument_synchronization_sc" class="anchor">_Server Capability_:</a>
 * property path (optional): `textDocumentSync`
 * property type: `TextDocumentSyncKind | TextDocumentSyncOptions`. The below definition of the `TextDocumentSyncOptions` only covers the properties specific to the open, change and close notifications. A complete definition covering all properties can be found [here](#textDocument_didClose):
 
 ```typescript
 /**
- * Defines how the host (editor) should sync document changes to the language server.
+ * Defines how the host (editor) should sync document changes
+ * to the language server.
  */
 export namespace TextDocumentSyncKind {
 	/**
@@ -2665,14 +2724,16 @@
 
 export interface TextDocumentSyncOptions {
 	/**
-	 * Open and close notifications are sent to the server. If omitted open close notification should not
-	 * be sent.
+	 * Open and close notifications are sent to the server.
+	 * If omitted open close notification should not be sent.
 	 */
 	openClose?: boolean;
 
 	/**
-	 * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
-	 * and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
+	 * Change notifications are sent to the server.
+	 * See TextDocumentSyncKind.None, TextDocumentSyncKind.Full,
+	 * and TextDocumentSyncKind.Incremental.
+	 * If omitted, it defaults to TextDocumentSyncKind.None.
 	 */
 	change?: TextDocumentSyncKind;
 }
@@ -2720,7 +2781,8 @@
 /**
  * Describe options to be used when registering for text document change events.
  */
-export interface TextDocumentChangeRegistrationOptions extends TextDocumentRegistrationOptions {
+export interface TextDocumentChangeRegistrationOptions
+	extends TextDocumentRegistrationOptions {
 	/**
 	 * How documents are synced to the server. See TextDocumentSyncKind.Full
 	 * and TextDocumentSyncKind.Incremental.
@@ -2743,24 +2805,28 @@
 	textDocument: VersionedTextDocumentIdentifier;
 
 	/**
-	 * The actual content changes. The content changes describe single state changes
-	 * to the document. So if there are two content changes c1 (at array index 0) and
-	 * c2 (at array index 1) for a document in state S then c1 moves the document from
-	 * S to S' and c2 from S' to S''. So c1 is computed on the state S and c2 is computed
-	 * on the state S'.
+	 * The actual content changes.
+	 * The content changes describe single state changes to the document.
+	 * If there are two content changes c1 (at array index 0) and
+	 * c2 (at array index 1) for a document in state S, then c1 moves the
+	 * document from S to S' and c2 from S' to S''.
+	 * So c1 is computed on the state S and c2 is computed on the state S'.
 	 *
-	 * To mirror the content of a document using change events use the following approach:
+	 * To mirror the content of a document using change events,
+	 * use the following approach:
 	 * - start with the same initial content
-	 * - apply the 'textDocument/didChange' notifications in the order you recevie them.
-	 * - apply the `TextDocumentContentChangeEvent`s in a single notification in the order
-	 *   you receive them.
+	 * - apply the 'textDocument/didChange' notifications
+	 *     in the order you receive them.
+	 * - apply the `TextDocumentContentChangeEvent`s
+	 *     in a single notification in the order you receive them.
 	 */
 	contentChanges: TextDocumentContentChangeEvent[];
 }
 
 /**
- * An event describing a change to a text document. If range and rangeLength are omitted
- * the new text is considered to be the full content of the document.
+ * An event describing a change to a text document.
+ * If range and rangeLength are omitted, the new text is considered to be
+ * the full content of the document.
  */
 export type TextDocumentContentChangeEvent = {
 	/**
@@ -2831,8 +2897,8 @@
 export namespace TextDocumentSaveReason {
 
 	/**
-	 * Manually triggered, e.g. by the user pressing save, by starting debugging,
-	 * or by an API call.
+	 * Manually triggered, for example, by the user pressing save,
+	 * by starting debugging, or by an API call.
 	 */
 	export const Manual = 1;
 
@@ -2901,7 +2967,8 @@
 
 _Registration Options_: `TextDocumentSaveRegistrationOptions` defined as follows:
 ```typescript
-export interface TextDocumentSaveRegistrationOptions extends TextDocumentRegistrationOptions {
+export interface TextDocumentSaveRegistrationOptions
+	extends TextDocumentRegistrationOptions {
 	/**
 	 * The client is supposed to include the content on save.
 	 */
@@ -2981,7 +3048,8 @@
 }
 
 /**
- * Defines how the host (editor) should sync document changes to the language server.
+ * Defines how the host (editor) should sync document changes
+ * to the language server.
  */
 export namespace TextDocumentSyncKind {
 	/**
@@ -3005,28 +3073,30 @@
 
 export interface TextDocumentSyncOptions {
 	/**
-	 * Open and close notifications are sent to the server. If omitted open close notification should not
-	 * be sent.
+	 * Open and close notifications are sent to the server.
+	 * If omitted, open close notification should not be sent.
 	 */
 	openClose?: boolean;
 	/**
-	 * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
-	 * and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
+	 * Change notifications are sent to the server.
+	 * See TextDocumentSyncKind.None, TextDocumentSyncKind.Full,
+	 * and TextDocumentSyncKind.Incremental.
+	 * If omitted, it defaults to TextDocumentSyncKind.None.
 	 */
 	change?: number;
 	/**
-	 * If present will save notifications are sent to the server. If omitted the notification should not be
-	 * sent.
+	 * If present will save notifications are sent to the server.
+	 * If omitted, the notification should not be sent.
 	 */
 	willSave?: boolean;
 	/**
-	 * If present will save wait until requests are sent to the server. If omitted the request should not be
-	 * sent.
+	 * If present will save wait until requests are sent to the server.
+	 * If omitted, the request should not be sent.
 	 */
 	willSaveWaitUntil?: boolean;
 	/**
-	 * If present save notifications are sent to the server. If omitted the notification should not be
-	 * sent.
+	 * If present save notifications are sent to the server.
+	 * If omitted, the notification should not be sent.
 	 */
 	save?: boolean | SaveOptions;
 }
@@ -3091,8 +3161,8 @@
 	uri: DocumentUri;
 
 	/**
-	 * Optional the version number of the document the diagnostics are published for.
-	 *
+	 * The version number of the document the diagnostics are published for.
+	 * Optional.
 	 * @since 3.15.0
 	 */
 	version?: number;
@@ -3106,7 +3176,7 @@
 
 #### <a href="#textDocument_completion" name="textDocument_completion" class="anchor">Completion Request (:leftwards_arrow_with_hook:)</a>
 
-The Completion request is sent from the client to the server to compute completion items at a given cursor position. Completion items are presented in the [IntelliSense](https://code.visualstudio.com/docs/editor/editingevolved#_intellisense) user interface. If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the 'textDocument/completion' request doesn't fill in the `documentation` property for returned completion items since it is expensive to compute. When the item is selected in the user interface then a 'completionItem/resolve' request is sent with the selected completion item as a parameter. The returned completion item should have the documentation property filled in. The request can only delay the computation of the `detail` and `documentation` properties. Other properties like `sortText`, `filterText`, `insertText`, `textEdit` and `additionalTextEdits` must be provided in the `textDocument/completion` response and must not be changed during resolve.
+The Completion request is sent from the client to the server to compute completion items at a given cursor position. Completion items are presented in the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense. If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the 'textDocument/completion' request doesn't fill in the `documentation` property for returned completion items since it is expensive to compute. When the item is selected in the user interface then a 'completionItem/resolve' request is sent with the selected completion item as a parameter. The returned completion item should have the documentation property filled in. The request can only delay the computation of the `detail` and `documentation` properties. Other properties like `sortText`, `filterText`, `insertText`, `textEdit` and `additionalTextEdits` must be provided in the `textDocument/completion` response and must not be changed during resolve.
 
 _Client Capability_:
 * property name (optional): `textDocument.completion`
@@ -3129,8 +3199,9 @@
 		 *
 		 * A snippet can define tab stops and placeholders with `$1`, `$2`
 		 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
-		 * the end of the snippet. Placeholders with equal identifiers are linked,
-		 * that is typing in one will update others too.
+		 * the end of the snippet.
+		 * Placeholders with equal identifiers are linked, so that typing in
+		 * one will update others as well.
 		 */
 		snippetSupport?: boolean;
 
@@ -3156,10 +3227,10 @@
 		preselectSupport?: boolean;
 
 		/**
-		 * Client supports the tag property on a completion item. Clients supporting
-		 * tags have to handle unknown tags gracefully. Clients especially need to
-		 * preserve unknown tags when sending a completion item back to the server in
-		 * a resolve call.
+		 * Client supports the tag property on a completion item.
+		 * Clients supporting tags have to handle unknown tags gracefully.
+		 * Clients especially need to preserve unknown tags when sending
+		 * a completion item back to the server in a resolve call.
 		 *
 		 * @since 3.15.0
 		 */
@@ -3203,24 +3274,28 @@
  */
 export interface CompletionOptions extends WorkDoneProgressOptions {
 	/**
-	 * Most tools trigger completion request automatically without explicitly requesting
-	 * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
-	 * starts to type an identifier. For example if the user types `c` in a JavaScript file
-	 * code complete will automatically pop up present `console` besides others as a
-	 * completion item. Characters that make up identifiers don't need to be listed here.
+	 * Most tools trigger completion request automatically without explicitly
+	 * requesting it using a keyboard shortcut (for example Ctrl+Space).
+	 * Typically they do so when the user starts to type an identifier.
+	 * For example, if the user types `c` in a JavaScript file, code complete
+	 * will automatically display `console` along with others as a
+	 * completion item.
+	 * Characters that make up identifiers don't need to be listed here.
 	 *
-	 * If code complete should automatically be trigger on characters not being valid inside
-	 * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+	 * If code complete should automatically be triggered on characters
+	 * not being valid inside an identifier (for example `.` in JavaScript),
+	 * list them in `triggerCharacters`.
 	 */
 	triggerCharacters?: string[];
 
 	/**
-	 * The list of all possible characters that commit a completion. This field can be used
-	 * if clients don't support individual commit characters per completion item. See
-	 * `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`.
+	 * The list of all possible characters that commit a completion.
+	 * This field can be used if clients don't support individual commit
+	 * characters per completion item. See `ClientCapabilities.`
+	 * `textDocument.completion.completionItem.commitCharactersSupport`.
 	 *
-	 * If a server provides both `allCommitCharacters` and commit characters on an individual
-	 * completion item the ones on the completion item win.
+	 * If a server provides both `allCommitCharacters` and commit characters
+	 * on an individual completion item, the ones on the completion item win.
 	 *
 	 * @since 3.2.0
 	 */
@@ -3236,7 +3311,8 @@
 
 _Registration Options_: `CompletionRegistrationOptions` options defined as follows:
 ```typescript
-export interface CompletionRegistrationOptions extends TextDocumentRegistrationOptions, CompletionOptions {
+export interface CompletionRegistrationOptions
+	extends TextDocumentRegistrationOptions, CompletionOptions {
 }
 ```
 
@@ -3245,10 +3321,13 @@
 * params: `CompletionParams` defined as follows:
 
 ```typescript
-export interface CompletionParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface CompletionParams
+	extends TextDocumentPositionParams, WorkDoneProgressParams,
+	PartialResultParams {
 	/**
-	 * The completion context. This is only available if the client specifies
-	 * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
+	 * The completion context.
+	 * This is only available if the client specifies to send this using
+	 * `ClientCapabilities.textDocument.completion.contextSupport === true`
 	 */
 	context?: CompletionContext;
 }
@@ -3265,7 +3344,7 @@
 
 	/**
 	 * Completion was triggered by a trigger character specified by
-	 * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+	 * the `triggerCharacters` properties of `CompletionRegistrationOptions`.
 	 */
 	export const TriggerCharacter: 2 = 2;
 
@@ -3278,7 +3357,8 @@
 
 
 /**
- * Contains additional information about the context in which a completion request is triggered.
+ * Contains additional information about the context in which a completion
+ * request is triggered.
  */
 export interface CompletionContext {
 	/**
@@ -3287,7 +3367,7 @@
 	triggerKind: CompletionTriggerKind;
 
 	/**
-	 * The trigger character (a single character) that has trigger code complete.
+	 * The trigger character (single character) that has trigger code complete.
 	 * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
 	 */
 	triggerCharacter?: string;
@@ -3299,8 +3379,8 @@
 
 ```typescript
 /**
- * Represents a collection of [completion items](#CompletionItem) to be presented
- * in the editor.
+ * Represents a collection of [completion items](#CompletionItem) to be
+ * presented in the editor.
  */
 export interface CompletionList {
 	/**
@@ -3339,8 +3419,8 @@
 export type InsertTextFormat = 1 | 2;
 
 /**
- * Completion item tags are extra annotations that tweak the rendering of a completion
- * item.
+ * Completion item tags are extra annotations that tweak the rendering of
+ * a completion item.
  *
  * @since 3.15.0
  */
@@ -3419,52 +3499,56 @@
 	 * this completion. When `falsy` the label is used.
 	 *
 	 * The `insertText` is subject to interpretation by the client side.
-	 * Some tools might not take the string literally. For example
-	 * VS Code when code complete is requested in this example `con<cursor position>`
-	 * and a completion item with an `insertText` of `console` is provided it
-	 * will only insert `sole`. Therefore it is recommended to use `textEdit` instead
-	 * since it avoids additional client side interpretation.
+	 * Some tools might not take the string literally.
+	 * For example, VS Code when code complete is requested in this example
+	 * `con<cursor position>` and a completion item with an `insertText` of
+	 * `console` is provided, it will only insert `sole`.
+	 * Therefore, it is recommended to use `textEdit` instead since it avoids
+	 * additional client side interpretation.
 	 */
 	insertText?: string;
 
 	/**
-	 * The format of the insert text. The format applies to both the `insertText` property
-	 * and the `newText` property of a provided `textEdit`. If omitted defaults to
-	 * `InsertTextFormat.PlainText`.
+	 * The format of the insert text.
+	 * The format applies to both the `insertText` property and the `newText`
+	 * property of a provided `textEdit`.
+	 * If omitted, defaults to `InsertTextFormat.PlainText`.
 	 */
 	insertTextFormat?: InsertTextFormat;
 
 	/**
-	 * An edit which is applied to a document when selecting this completion. When an edit is provided the value of
-	 * `insertText` is ignored.
+	 * An edit that is applied to a document when selecting this completion.
+	 * When an edit is provided, the value of `insertText` is ignored.
 	 *
-	 * *Note:* The range of the edit must be a single line range and it must contain the position at which completion
-	 * has been requested.
+	 * *Note:* The range of the edit must be a single line range and it must
+	 * contain the position at which completion has been requested.
 	 */
 	textEdit?: TextEdit;
 
 	/**
 	 * An optional array of additional text edits that are applied when
-	 * selecting this completion. Edits must not overlap (including the same insert position)
-	 * with the main edit nor with themselves.
+	 * selecting this completion.
+	 * Edits must not overlap (including the same insert position) with the
+	 * main edit nor with themselves.
 	 *
-	 * Additional text edits should be used to change text unrelated to the current cursor position
-	 * (for example adding an import statement at the top of the file if the completion item will
-	 * insert an unqualified type).
+	 * Additional text edits should be used to change text unrelated to the
+	 * current cursor position (for example adding an import statement at the
+	 * top of the file if the completion item will insert an unqualified type).
 	 */
 	additionalTextEdits?: TextEdit[];
 
 	/**
-	 * An optional set of characters that when pressed while this completion is active will accept it first and
-	 * then type that character. *Note* that all commit characters should have `length=1` and that superfluous
-	 * characters will be ignored.
+	 * An optional set of characters that when pressed, while this completion
+	 * is active, will accept it first and then type that character.
+	 * *Note* that all commit characters should have `length=1` and that
+	 * superfluous characters will be ignored.
 	 */
 	commitCharacters?: string[];
 
 	/**
-	 * An optional command that is executed *after* inserting this completion. *Note* that
-	 * additional modifications to the current document should be described with the
-	 * additionalTextEdits-property.
+	 * An optional command that is executed *after* inserting this completion.
+	 * *Note* that additional modifications to the current document should be
+	 * described with the additionalTextEdits-property.
 	 */
 	command?: Command;
 
@@ -3637,7 +3721,8 @@
 
 _Registration Options_: `HoverRegistrationOptions` defined as follows:
 ```typescript
-export interface HoverRegistrationOptions extends TextDocumentRegistrationOptions, HoverOptions {
+export interface HoverRegistrationOptions
+	extends TextDocumentRegistrationOptions, HoverOptions {
 }
 ```
 
@@ -3646,7 +3731,8 @@
 * params: `HoverParams` defined as follows:
 
 ```typescript
-export interface HoverParams extends TextDocumentPositionParams, WorkDoneProgressParams {
+export interface HoverParams
+	extends TextDocumentPositionParams, WorkDoneProgressParams {
 }
 ```
 
@@ -3675,17 +3761,17 @@
 
 ```typescript
 /**
- * MarkedString can be used to render human readable text. It is either a markdown string
- * or a code-block that provides a language and a code snippet. The language identifier
- * is semantically equal to the optional language identifier in fenced code blocks in GitHub
- * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ * MarkedString can be used to render human readable text.
+ * It is either a Markdown string or a code-block that provides a language
+ * and a code snippet. The language identifier is semantically equal to the
+ * optional language identifier in fenced code blocks in GitHub issues.
  *
- * The pair of a language and a value is an equivalent to markdown:
+ * The pair of a language and a value is an equivalent to Markdown:
  * ```${language}
  * ${value}
  * ```
  *
- * Note that markdown strings will be sanitized - that means html will be escaped.
+ * Note that Markdown strings will be sanitized, meaning HTML will be escaped.
 * @deprecated use MarkupContent instead.
 */
 type MarkedString = string | { language: string; value: string };
@@ -3760,8 +3846,9 @@
 	/**
 	 * List of characters that re-trigger signature help.
 	 *
-	 * These trigger characters are only active when signature help is already showing. All trigger characters
-	 * are also counted as re-trigger characters.
+	 * These trigger characters are only active when signature help is already
+	 * showing.
+	 * All trigger characters are also counted as re-trigger characters.
 	 *
 	 * @since 3.15.0
 	 */
@@ -3771,7 +3858,8 @@
 
 _Registration Options_: `SignatureHelpRegistrationOptions` defined as follows:
 ```typescript
-export interface SignatureHelpRegistrationOptions extends TextDocumentRegistrationOptions, SignatureHelpOptions {
+export interface SignatureHelpRegistrationOptions
+	extends TextDocumentRegistrationOptions, SignatureHelpOptions {
 }
 ```
 
@@ -3780,10 +3868,12 @@
 * params: `SignatureHelpParams` defined as follows:
 
 ```typescript
-export interface SignatureHelpParams extends TextDocumentPositionParams, WorkDoneProgressParams {
+export interface SignatureHelpParams extends TextDocumentPositionParams,
+	WorkDoneProgressParams {
 	/**
-	 * The signature help context. This is only available if the client specifies
-	 * to send this using the client capability  `textDocument.signatureHelp.contextSupport === true`
+	 * The signature help context.
+	 * This is only available if the client specifies to send this using the
+	 * client capability `textDocument.signatureHelp.contextSupport === true`.
 	 *
 	 * @since 3.15.0
 	 */
@@ -3805,14 +3895,16 @@
 	 */
 	export const TriggerCharacter: 2 = 2;
 	/**
-	 * Signature help was triggered by the cursor moving or by the document content changing.
+	 * Signature help was triggered by the cursor moving or
+	 * by the document content changing.
 	 */
 	export const ContentChange: 3 = 3;
 }
 export type SignatureHelpTriggerKind = 1 | 2 | 3;
 
 /**
- * Additional information about the context in which a signature help request was triggered.
+ * Additional information about the context in which a
+ * signature help request was triggered.
  *
  * @since 3.15.0
  */
@@ -3825,23 +3917,25 @@
 	/**
 	 * Character that caused signature help to be triggered.
 	 *
-	 * This is undefined when `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter`
+	 * This is undefined when
+	 * `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter`.
 	 */
 	triggerCharacter?: string;
 
 	/**
 	 * `true` if signature help was already showing when it was triggered.
 	 *
-	 * Retriggers occur when the signature help is already active and can be caused by actions such as
-	 * typing a trigger character, a cursor move, or document content changes.
+	 * Retriggers occur when the signature help is already active and can be
+	 * caused by actions such as typing a trigger character, a cursor move,
+	 * or document content changes.
 	 */
 	isRetrigger: boolean;
 
 	/**
 	 * The currently active `SignatureHelp`.
 	 *
-	 * The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field updated based on
-	 * the user navigating through available signatures.
+	 * The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field
+	 * updated based on the user navigating through available signatures.
 	 */
 	activeSignatureHelp?: SignatureHelp;
 }
@@ -3858,7 +3952,7 @@
  */
 export interface SignatureHelp {
 	/**
-	 * One or more signatures. If no signaures are availabe the signature help
+	 * One or more signatures. If no signatures are available the signature help
 	 * request should return `null`.
 	 */
 	signatures: SignatureInformation[];
@@ -3921,12 +4015,14 @@
 	/**
 	 * The label of this parameter information.
 	 *
-	 * Either a string or an inclusive start and exclusive end offsets within its containing
-	 * signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
-	 * string representation as `Position` and `Range` does.
+	 * Either a string or an inclusive start and exclusive end offsets within
+	 * its containing signature label. (see SignatureInformation.label).
+	 * The offsets are based on a UTF-16 string representation
+	 * as `Position` and `Range` does.
 	 *
-	 * *Note*: a label of type string should be a substring of its containing signature label.
-	 * Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
+	 * *Note*: a label of type string should be a substring of its containing
+	 * signature label. Its intended use case is to highlight the
+	 * parameter label part in the `SignatureInformation.label`.
 	 */
 	label: string | [number, number];
 
@@ -3955,9 +4051,10 @@
 ```typescript
 export interface DeclarationClientCapabilities {
 	/**
-	 * Whether declaration supports dynamic registration. If this is set to `true`
-	 * the client supports the new `DeclarationRegistrationOptions` return value
-	 * for the corresponding server capability as well.
+	 * Whether declaration supports dynamic registration.
+	 * If this is set to `true`, the client supports the new
+	 * `DeclarationRegistrationOptions` return value for the
+	 * corresponding server capability as well.
 	 */
 	dynamicRegistration?: boolean;
 
@@ -3979,7 +4076,8 @@
 
 _Registration Options_: `DeclarationRegistrationOptions` defined as follows:
 ```typescript
-export interface DeclarationRegistrationOptions extends DeclarationOptions, TextDocumentRegistrationOptions, StaticRegistrationOptions  {
+export interface DeclarationRegistrationOptions extends DeclarationOptions,
+	TextDocumentRegistrationOptions, StaticRegistrationOptions  {
 }
 ```
 
@@ -3988,7 +4086,8 @@
 * params: `DeclarationParams` defined as follows:
 
 ```typescript
-export interface DeclarationParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface DeclarationParams extends TextDocumentPositionParams,
+	WorkDoneProgressParams, PartialResultParams {
 }
 ```
 
@@ -4034,7 +4133,8 @@
 
 _Registration Options_: `DefinitionRegistrationOptions` defined as follows:
 ```typescript
-export interface DefinitionRegistrationOptions extends TextDocumentRegistrationOptions, DefinitionOptions {
+export interface DefinitionRegistrationOptions
+	extends TextDocumentRegistrationOptions, DefinitionOptions {
 }
 ```
 
@@ -4043,7 +4143,9 @@
 * params: `DefinitionParams` defined as follows:
 
 ```typescript
-export interface DefinitionParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface DefinitionParams
+	extends TextDocumentPositionParams, WorkDoneProgressParams,
+		PartialResultParams {
 }
 ```
 
@@ -4067,9 +4169,10 @@
 ```typescript
 export interface TypeDefinitionClientCapabilities {
 	/**
-	 * Whether implementation supports dynamic registration. If this is set to `true`
-	 * the client supports the new `TypeDefinitionRegistrationOptions` return value
-	 * for the corresponding server capability as well.
+	 * Whether implementation supports dynamic registration.
+	 * If this is set to `true`, the client supports the new `
+	 * TypeDefinitionRegistrationOptions` return value for the
+	 * corresponding server capability as well.
 	 */
 	dynamicRegistration?: boolean;
 
@@ -4093,7 +4196,9 @@
 
 _Registration Options_: `TypeDefinitionRegistrationOptions` defined as follows:
 ```typescript
-export interface TypeDefinitionRegistrationOptions extends TextDocumentRegistrationOptions, TypeDefinitionOptions, StaticRegistrationOptions {
+export interface TypeDefinitionRegistrationOptions
+	extends TextDocumentRegistrationOptions, TypeDefinitionOptions,
+		StaticRegistrationOptions {
 }
 ```
 
@@ -4102,7 +4207,9 @@
 * params: `TypeDefinitionParams` defined as follows:
 
 ```typescript
-export interface TypeDefinitionParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface TypeDefinitionParams
+	extends TextDocumentPositionParams, WorkDoneProgressParams,
+		PartialResultParams {
 }
 ```
 
@@ -4126,9 +4233,10 @@
 ```typescript
 export interface ImplementationClientCapabilities {
 	/**
-	 * Whether implementation supports dynamic registration. If this is set to `true`
-	 * the client supports the new `ImplementationRegistrationOptions` return value
-	 * for the corresponding server capability as well.
+	 * Whether implementation supports dynamic registration.
+	 * If this is set to `true`, the client supports the new
+	 * `ImplementationRegistrationOptions` return value for the
+	 * corresponding server capability as well.
 	 */
 	dynamicRegistration?: boolean;
 
@@ -4152,7 +4260,9 @@
 
 _Registration Options_: `ImplementationRegistrationOptions` defined as follows:
 ```typescript
-export interface ImplementationRegistrationOptions extends TextDocumentRegistrationOptions, ImplementationOptions, StaticRegistrationOptions {
+export interface ImplementationRegistrationOptions
+	extends TextDocumentRegistrationOptions, ImplementationOptions,
+		StaticRegistrationOptions {
 }
 ```
 
@@ -4161,7 +4271,8 @@
 * params: `ImplementationParams` defined as follows:
 
 ```typescript
-export interface ImplementationParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface ImplementationParams extends TextDocumentPositionParams,
+	WorkDoneProgressParams, PartialResultParams {
 }
 ```
 
@@ -4198,7 +4309,8 @@
 
 _Registration Options_: `ReferenceRegistrationOptions` defined as follows:
 ```typescript
-export interface ReferenceRegistrationOptions extends TextDocumentRegistrationOptions, ReferenceOptions {
+export interface ReferenceRegistrationOptions
+	extends TextDocumentRegistrationOptions, ReferenceOptions {
 }
 ```
 
@@ -4207,7 +4319,8 @@
 * params: `ReferenceParams` defined as follows:
 
 ```typescript
-export interface ReferenceParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface ReferenceParams extends TextDocumentPositionParams,
+	WorkDoneProgressParams, PartialResultParams {
 	context: ReferenceContext
 }
 
@@ -4254,7 +4367,8 @@
 
 _Registration Options_: `DocumentHighlightRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentHighlightRegistrationOptions extends TextDocumentRegistrationOptions, DocumentHighlightOptions {
+export interface DocumentHighlightRegistrationOptions
+	extends TextDocumentRegistrationOptions, DocumentHighlightOptions {
 }
 ```
 
@@ -4263,7 +4377,8 @@
 * params: `DocumentHighlightParams` defined as follows:
 
 ```typescript
-export interface DocumentHighlightParams extends TextDocumentPositionParams, WorkDoneProgressParams, PartialResultParams {
+export interface DocumentHighlightParams extends TextDocumentPositionParams,
+	WorkDoneProgressParams, PartialResultParams {
 }
 ```
 
@@ -4332,7 +4447,8 @@
 	dynamicRegistration?: boolean;
 
 	/**
-	 * Specific capabilities for the `SymbolKind` in the `textDocument/documentSymbol` request.
+	 * Specific capabilities for the `SymbolKind` in the
+	 * `textDocument/documentSymbol` request.
 	 */
 	symbolKind?: {
 		/**
@@ -4366,7 +4482,8 @@
 
 _Registration Options_: `DocumentSymbolRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentSymbolRegistrationOptions extends TextDocumentRegistrationOptions, DocumentSymbolOptions {
+export interface DocumentSymbolRegistrationOptions
+	extends TextDocumentRegistrationOptions, DocumentSymbolOptions {
 }
 ```
 
@@ -4375,7 +4492,8 @@
 * params: `DocumentSymbolParams` defined as follows:
 
 ```typescript
-export interface DocumentSymbolParams extends WorkDoneProgressParams, PartialResultParams {
+export interface DocumentSymbolParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The text document.
 	 */
@@ -4420,14 +4538,16 @@
 }
 
 /**
- * Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
- * hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
- * e.g. the range of an identifier.
+ * Represents programming constructs like variables, classes, interfaces etc.
+ * that appear in a document. Document symbols can be hierarchical and they
+ * have two ranges: one that encloses its definition and one that points to
+ * its most interesting range, for example, the range of an identifier.
  */
 export interface DocumentSymbol {
 
 	/**
-	 * The name of this symbol. Will be displayed in the user interface and therefore must not be
+	 * The name of this symbol.
+	 * Will be displayed in the user interface and therefore must not be
 	 * an empty string or a string only consisting of white spaces.
 	 */
 	name: string;
@@ -4448,14 +4568,16 @@
 	deprecated?: boolean;
 
 	/**
-	 * The range enclosing this symbol not including leading/trailing whitespace but everything else
-	 * like comments. This information is typically used to determine if the clients cursor is
-	 * inside the symbol to reveal in the symbol in the UI.
+	 * The range enclosing this symbol not including leading/trailing
+	 * whitespace but everything else like comments.
+	 * This information is typically used to determine if the client's cursor
+	 * is inside the symbol to reveal in the symbol in the UI.
 	 */
 	range: Range;
 
 	/**
-	 * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+	 * The range that should be selected and revealed when this symbol
+	 * is being picked, for example, the name of a function.
 	 * Must be contained by the `range`.
 	 */
 	selectionRange: Range;
@@ -4576,8 +4698,8 @@
 	/**
 	 * CodeActionKinds that this server may return.
 	 *
-	 * The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server
-	 * may list out every specific kind they provide.
+	 * The list of kinds may be generic, such as `CodeActionKind.Refactor`,
+	 * or the server may list out every specific kind they provide.
 	 */
 	codeActionKinds?: CodeActionKind[];
 }
@@ -4585,7 +4707,8 @@
 
 _Registration Options_: `CodeActionRegistrationOptions` defined as follows:
 ```typescript
-export interface CodeActionRegistrationOptions extends TextDocumentRegistrationOptions, CodeActionOptions {
+export interface CodeActionRegistrationOptions
+	extends TextDocumentRegistrationOptions, CodeActionOptions {
 }
 ```
 
@@ -4597,7 +4720,8 @@
 /**
  * Params for the CodeActionRequest
  */
-export interface CodeActionParams extends WorkDoneProgressParams, PartialResultParams {
+export interface CodeActionParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The document in which the command was invoked.
 	 */
@@ -4617,10 +4741,11 @@
 /**
  * The kind of a code action.
  *
- * Kinds are a hierarchical list of identifiers separated by `.`, e.g. `"refactor.extract.function"`.
+ * Kinds are a hierarchical list of identifiers separated by `.`,
+ * e.g. `"refactor.extract.function"`.
  *
- * The set of kinds is open and client needs to announce the kinds it supports to the server during
- * initialization.
+ * The set of kinds is open and the client needs to announce the kinds it
+ * supports to the server during initialization.
  */
 export type CodeActionKind = string;
 
@@ -4691,9 +4816,10 @@
 	export const Source: CodeActionKind = 'source';
 
 	/**
-	 * Base kind for an organize imports source action: `source.organizeImports`.
+	 * Base kind for an organize imports source action `source.organizeImports`.
 	 */
-	export const SourceOrganizeImports: CodeActionKind = 'source.organizeImports';
+	export const SourceOrganizeImports: CodeActionKind
+		= 'source.organizeImports';
 }
 
 /**
@@ -4702,19 +4828,20 @@
  */
 export interface CodeActionContext {
 	/**
-	 * An array of diagnostics known on the client side overlapping the range provided to the
-	 * `textDocument/codeAction` request. They are provided so that the server knows which
-	 * errors are currently presented to the user for the given range. There is no guarantee
-	 * that these accurately reflect the error state of the resource. The primary parameter
-	 * to compute code actions is the provided range.
+	 * An array of diagnostics known on the client side overlapping the range
+	 * provided to the `textDocument/codeAction` request.
+	 * They are provided so that the server knows which errors are currently
+	 * presented to the user for the given range. There is no guarantee that
+	 * these accurately reflect the error state of the resource.
+	 * The primary parameter to compute code actions is the provided range.
 	 */
 	diagnostics: Diagnostic[];
 
 	/**
 	 * Requested kind of actions to return.
 	 *
-	 * Actions not of this kind are filtered out by the client before being shown. So servers
-	 * can omit computing them.
+	 * Actions not of this kind are filtered out by the client before
+	 * being shown, so servers can omit computing them.
 	 */
 	only?: CodeActionKind[];
 }
@@ -4725,10 +4852,12 @@
 
 ```typescript
 /**
- * A code action represents a change that can be performed in code, e.g. to fix a problem or
- * to refactor code.
+ * A code action represents a change that can be performed in code.
+ * For example, to fix a problem or to refactor code.
  *
- * A CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed.
+ * A CodeAction must set either `edit` and/or a `command`.
+ * If both are supplied, the `edit` is applied first, then the `command`
+ * is executed.
  */
 export interface CodeAction {
 
@@ -4750,11 +4879,14 @@
 	diagnostics?: Diagnostic[];
 
 	/**
-	 * Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
-	 * by keybindings.
+	 * Marks this as a preferred action.
+	 * Preferred actions are used by the `auto fix` command and can be
+	 * targeted by keybindings.
 	 *
-	 * A quick fix should be marked preferred if it properly addresses the underlying error.
-	 * A refactoring should be marked preferred if it is the most reasonable choice of actions to take.
+	 * A quick fix should be marked preferred if it properly addresses the
+	 * underlying error.
+	 * A refactoring should be marked preferred if it is the most reasonable
+	 * choice of actions to take.
 	 *
 	 * @since 3.15.0
 	 */
@@ -4778,7 +4910,7 @@
 
 #### <a href="#textDocument_codeLens" name="textDocument_codeLens" class="anchor">Code Lens Request (:leftwards_arrow_with_hook:)</a>
 
-The code lens request is sent from the client to the server to compute code lenses for a given text document.
+The CodeLens request is sent from the client to the server to compute CodeLens for a given text document.
 
 _Client Capability_:
 * property name (optional): `textDocument.codeLens`
@@ -4787,7 +4919,7 @@
 ```typescript
 export interface CodeLensClientCapabilities {
 	/**
-	 * Whether code lens supports dynamic registration.
+	 * Whether CodeLens supports dynamic registration.
 	 */
 	dynamicRegistration?: boolean;
 }
@@ -4808,7 +4940,8 @@
 
 _Registration Options_: `CodeLensRegistrationOptions` defined as follows:
 ```typescript
-export interface CodeLensRegistrationOptions extends TextDocumentRegistrationOptions, CodeLensOptions {
+export interface CodeLensRegistrationOptions
+	extends TextDocumentRegistrationOptions, CodeLensOptions {
 }
 ```
 
@@ -4819,7 +4952,7 @@
 ```typescript
 interface CodeLensParams extends WorkDoneProgressParams, PartialResultParams {
 	/**
-	 * The document to request code lens for.
+	 * The document to request CodeLens for.
 	 */
 	textDocument: TextDocumentIdentifier;
 }
@@ -4830,36 +4963,37 @@
 
 ```typescript
 /**
- * A code lens represents a command that should be shown along with
+ * A CodeLense represents a command that should be shown along with
  * source text, like the number of references, a way to run tests, etc.
  *
- * A code lens is _unresolved_ when no command is associated to it. For performance
- * reasons the creation of a code lens and resolving should be done in two stages.
+ * A CodeLens is _unresolved_ when no command is associated to it.
+ * For performance reasons, the creation of a CodeLens and resolving should
+ * be done in two stages.
  */
 interface CodeLens {
 	/**
-	 * The range in which this code lens is valid. Should only span a single line.
+	 * The range in which the CodeLens is valid. Should only span a single line.
 	 */
 	range: Range;
 
 	/**
-	 * The command this code lens represents.
+	 * The command this CodeLens represents.
 	 */
 	command?: Command;
 
 	/**
-	 * A data entry field that is preserved on a code lens item between
-	 * a code lens and a code lens resolve request.
+	 * A data entry field that is preserved on a CodeLens item between
+	 * a CodeLens and a CodeLens resolve request.
 	 */
 	data?: any
 }
 ```
 * partial result: `CodeLens[]`
-* error: code and message set in case an exception happens during the code lens request.
+* error: code and message set in case an exception happens during the CodeLens request.
 
 #### <a href="#codeLens_resolve" name="codeLens_resolve" class="anchor">Code Lens Resolve Request (:leftwards_arrow_with_hook:)</a>
 
-The code lens resolve request is sent from the client to the server to resolve the command for a given code lens item.
+The CodeLens resolve request is sent from the client to the server to resolve the command for a given CodeLens item.
 
 _Request_:
 * method: 'codeLens/resolve'
@@ -4867,7 +5001,7 @@
 
 _Response_:
 * result: `CodeLens`
-* error: code and message set in case an exception happens during the code lens resolve request.
+* error: code and message set in case an exception happens during the CodeLens resolve request.
 
 #### <a href="#textDocument_documentLink" name="textDocument_documentLink" class="anchor">Document Link Request (:leftwards_arrow_with_hook:)</a>
 
@@ -4908,7 +5042,8 @@
 
 _Registration Options_: `DocumentLinkRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentLinkRegistrationOptions extends TextDocumentRegistrationOptions, DocumentLinkOptions {
+export interface DocumentLinkRegistrationOptions
+	extends TextDocumentRegistrationOptions, DocumentLinkOptions {
 }
 ```
 
@@ -4917,7 +5052,8 @@
 * params: `DocumentLinkParams` defined as follows:
 
 ```typescript
-interface DocumentLinkParams extends WorkDoneProgressParams, PartialResultParams {
+interface DocumentLinkParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The document to provide document links for.
 	 */
@@ -4930,8 +5066,8 @@
 
 ```typescript
 /**
- * A document link is a range in a text document that links to an internal or external resource, like another
- * text document or a web site.
+ * A document link is a range in a text document that links to an internal
+ * or external resource, like another text document or a web site.
  */
 interface DocumentLink {
 	/**
@@ -4947,9 +5083,11 @@
 	/**
 	 * The tooltip text when you hover over this link.
 	 *
-	 * If a tooltip is provided, is will be displayed in a string that includes instructions on how to
-	 * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
-	 * user settings, and localization.
+	 * If a tooltip is provided, it will be displayed in a string that
+	 * includes instructions on how to trigger the link,
+	 * such as `{0} (ctrl + click)`.
+	 * The specific instructions vary depending on OS, user settings,
+	 * and localization.
 	 *
 	 * @since 3.15.0
 	 */
@@ -5011,7 +5149,9 @@
 
 _Registration Options_: `DocumentColorRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentColorRegistrationOptions extends TextDocumentRegistrationOptions, StaticRegistrationOptions, DocumentColorOptions {
+export interface DocumentColorRegistrationOptions
+	extends TextDocumentRegistrationOptions, StaticRegistrationOptions,
+		DocumentColorOptions {
 }
 ```
 
@@ -5021,7 +5161,8 @@
 * params: `DocumentColorParams` defined as follows
 
 ```typescript
-interface DocumentColorParams extends WorkDoneProgressParams, PartialResultParams {
+interface DocumentColorParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The text document.
 	 */
@@ -5090,7 +5231,8 @@
 * params: `ColorPresentationParams` defined as follows
 
 ```typescript
-interface ColorPresentationParams extends WorkDoneProgressParams, PartialResultParams {
+interface ColorPresentationParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The text document.
 	 */
@@ -5115,19 +5257,22 @@
 interface ColorPresentation {
 	/**
 	 * The label of this color presentation. It will be shown on the color
-	 * picker header. By default this is also the text that is inserted when selecting
+	 * picker header.
+	 * By default, this is also the text that is inserted when selecting
 	 * this color presentation.
 	 */
 	label: string;
 	/**
 	 * An [edit](#TextEdit) which is applied to a document when selecting
-	 * this presentation for the color.  When `falsy` the [label](#ColorPresentation.label)
-	 * is used.
+	 * this presentation for the color.
+	 * When `falsy`, the [label](#ColorPresentation.label) is used.
 	 */
 	textEdit?: TextEdit;
 	/**
-	 * An optional array of additional [text edits](#TextEdit) that are applied when
-	 * selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.
+	 * An optional array of additional [text edits](#TextEdit) that are
+	 * applied when selecting this color presentation.
+	 * Edits must not overlap with the main [edit](#ColorPresentation.textEdit)
+	 * nor with themselves.
 	 */
 	additionalTextEdits?: TextEdit[];
 }
@@ -5164,7 +5309,8 @@
 
 _Registration Options_: `DocumentFormattingRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentFormattingRegistrationOptions extends TextDocumentRegistrationOptions, DocumentFormattingOptions {
+export interface DocumentFormattingRegistrationOptions
+	extends TextDocumentRegistrationOptions, DocumentFormattingOptions {
 }
 ```
 
@@ -5253,13 +5399,15 @@
 * property type: `boolean | DocumentRangeFormattingOptions` where `DocumentRangeFormattingOptions` is defined as follows:
 
 ```typescript
-export interface DocumentRangeFormattingOptions extends WorkDoneProgressOptions {
+export interface DocumentRangeFormattingOptions
+	extends WorkDoneProgressOptions {
 }
 ```
 
 _Registration Options_: `DocumentFormattingRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentRangeFormattingRegistrationOptions extends TextDocumentRegistrationOptions, DocumentRangeFormattingOptions {
+export interface DocumentRangeFormattingRegistrationOptions
+	extends TextDocumentRegistrationOptions, DocumentRangeFormattingOptions {
 }
 ```
 
@@ -5327,7 +5475,8 @@
 
 _Registration Options_: `DocumentOnTypeFormattingRegistrationOptions` defined as follows:
 ```typescript
-export interface DocumentOnTypeFormattingRegistrationOptions extends TextDocumentRegistrationOptions, DocumentOnTypeFormattingOptions {
+export interface DocumentOnTypeFormattingRegistrationOptions
+	extends TextDocumentRegistrationOptions, DocumentOnTypeFormattingOptions {
 }
 ```
 
@@ -5395,7 +5544,8 @@
 
 _Registration Options_: `RenameRegistrationOptions` defined as follows:
 ```typescript
-export interface RenameRegistrationOptions extends TextDocumentRegistrationOptions, RenameOptions {
+export interface RenameRegistrationOptions
+	extends TextDocumentRegistrationOptions, RenameOptions {
 }
 ```
 
@@ -5404,7 +5554,8 @@
 * params: `RenameParams` defined as follows
 
 ```typescript
-interface RenameParams extends TextDocumentPositionParams, WorkDoneProgressParams {
+interface RenameParams
+	extends TextDocumentPositionParams, WorkDoneProgressParams {
 	/**
 	 * The new name of the symbol. If the given name is not valid the
 	 * request must return a [ResponseError](#ResponseError) with an
@@ -5449,19 +5600,23 @@
 ```typescript
 export interface FoldingRangeClientCapabilities {
 	/**
-	 * Whether implementation supports dynamic registration for folding range providers. If this is set to `true`
-	 * the client supports the new `FoldingRangeRegistrationOptions` return value for the corresponding server
-	 * capability as well.
+	 * Whether the implementation supports dynamic registration for
+	 * folding range providers.
+	 * If this is set to `true`, the client supports the new
+	 * `FoldingRangeRegistrationOptions` return value for the corresponding
+	 * server capability as well.
 	 */
 	dynamicRegistration?: boolean;
 	/**
-	 * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
-	 * hint, servers are free to follow the limit.
+	 * The maximum number of folding ranges that the client prefers to
+	 * receive per document.
+	 * The value serves as a hint, servers are free to follow the limit.
 	 */
 	rangeLimit?: number;
 	/**
-	 * If set, the client signals that it only supports folding complete lines. If set, client will
-	 * ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
+	 * If set, the client signals that it only supports folding complete lines.
+	 * If set, the client will ignore specified `startCharacter` and
+	 * `endCharacter` properties in a FoldingRange.
 	 */
 	lineFoldingOnly?: boolean;
 }
@@ -5478,7 +5633,9 @@
 
 _Registration Options_: `FoldingRangeRegistrationOptions` defined as follows:
 ```typescript
-export interface FoldingRangeRegistrationOptions extends TextDocumentRegistrationOptions, FoldingRangeOptions, StaticRegistrationOptions {
+export interface FoldingRangeRegistrationOptions
+	extends TextDocumentRegistrationOptions, FoldingRangeOptions,
+		StaticRegistrationOptions {
 }
 ```
 
@@ -5488,7 +5645,8 @@
 * params: `FoldingRangeParams` defined as follows
 
 ```typescript
-export interface FoldingRangeParams extends WorkDoneProgressParams, PartialResultParams {
+export interface FoldingRangeParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The text document.
 	 */
@@ -5529,7 +5687,8 @@
 	startLine: number;
 
 	/**
-	 * The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
+	 * The zero-based character offset from where the folded range starts.
+	 * If not defined, defaults to the length of the start line.
 	 */
 	startCharacter?: number;
 
@@ -5539,14 +5698,17 @@
 	endLine: number;
 
 	/**
-	 * The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
+	 * The zero-based character offset before the folded range ends.
+	 * If not defined, defaults to the length of the end line.
 	 */
 	endCharacter?: number;
 
 	/**
-	 * Describes the kind of the folding range such as `comment` or `region`. The kind
-	 * is used to categorize folding ranges and used by commands like 'Fold all comments'. See
-	 * [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
+	 * Describes the kind of the folding range such as `comment` or `region`.
+	 * The kind is used to categorize folding ranges and used by commands
+	 * like 'Fold all comments'.
+	 * See [FoldingRangeKind](#FoldingRangeKind) for an enumeration of
+	 * standardized kinds.
 	 */
 	kind?: string;
 }
@@ -5572,9 +5734,11 @@
 ```typescript
 export interface SelectionRangeClientCapabilities {
 	/**
-	 * Whether implementation supports dynamic registration for selection range providers. If this is set to `true`
-	 * the client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server
-	 * capability as well.
+	 * Whether implementation supports dynamic registration for selection
+	 * range providers.
+	 * If set to `true`, the client supports the new
+	 * `SelectionRangeRegistrationOptions` return value for the corresponding
+	 * server capability as well.
 	 */
 	dynamicRegistration?: boolean;
 }
@@ -5591,7 +5755,9 @@
 
 _Registration Options_: `SelectionRangeRegistrationOptions` defined as follows:
 ```typescript
-export interface SelectionRangeRegistrationOptions extends SelectionRangeOptions, TextDocumentRegistrationOptions, StaticRegistrationOptions {
+export interface SelectionRangeRegistrationOptions
+	extends SelectionRangeOptions, TextDocumentRegistrationOptions,
+		StaticRegistrationOptions {
 }
 ```
 
@@ -5601,7 +5767,8 @@
 * params: `SelectionRangeParams` defined as follows
 
 ```typescript
-export interface SelectionRangeParams extends WorkDoneProgressParams, PartialResultParams {
+export interface SelectionRangeParams
+	extends WorkDoneProgressParams, PartialResultParams {
 	/**
 	 * The text document.
 	 */
@@ -5619,14 +5786,17 @@
 
 ```typescript
 export interface SelectionRange {
-    /**
-     * The [range](#Range) of this selection range.
-     */
-    range: Range;
-    /**
-     * The parent selection range containing this range. Therefore `parent.range` must contain `this.range`.
-     */
-    parent?: SelectionRange;
+	/**
+	 * The [range](#Range) of this selection range.
+	 */
+	range: Range;
+
+	/**
+	 * The parent selection range containing this range.
+	 * Therefore `parent.range` must
+	 * contain `this.range`.
+	 */
+	parent?: SelectionRange;
 }
 ```
 
diff --git a/pkg/analysis_server/tool/lsp_spec/markdown.dart b/pkg/analysis_server/tool/lsp_spec/markdown.dart
index 5b222d9..3104598 100644
--- a/pkg/analysis_server/tool/lsp_spec/markdown.dart
+++ b/pkg/analysis_server/tool/lsp_spec/markdown.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 final _methodNamesPattern = RegExp(
-    r'''_(?:Notification|Request):?_:?(?:\r?\n)+\* method: '(.*?)',?\r?\n''',
+    r'''_(?:Notification|Request):?_:?(?:\r?\n)+\* method: ['`](.*?)[`'],?\r?\n''',
     multiLine: true);
 final _typeScriptBlockPattern =
     RegExp(r'\B```typescript([\S\s]*?)\n```', multiLine: true);
diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart
index de4be12..3be8ed7 100644
--- a/pkg/analysis_server/tool/spec/check_all_test.dart
+++ b/pkg/analysis_server/tool/spec/check_all_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate_all.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index e72548d..9e19fb6 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code generation for the file "AnalysisServer.java".
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 import 'codegen_java.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
index 7fddd04..65515ef 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart';
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index a9da290..2acef57 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -4,7 +4,7 @@
 
 import 'dart:convert';
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:path/path.dart' as path;
 
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index 09a412b..208e0a0 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code generation for the file "integration_test_methods.dart".
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart' as path;
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index f898732..341e4e1 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Tools for Java code generation.
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 4ecbc1d..a59a788 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code generation for the file "AnalysisServer.java".
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index afe7545..2e53975 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code generation for the file "matchers.dart".
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 import 'from_html.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
index 12e2dc2..511f260 100644
--- a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 import 'codegen_dart.dart';
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index 5496a9c..237a6a7 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -5,7 +5,7 @@
 /// Code for reading an HTML API description.
 import 'dart:io';
 
-import 'package:analysis_tool/html.dart';
+import 'package:analyzer_utilities/html.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:html/parser.dart' as parser;
 import 'package:path/path.dart';
diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart
index ac9eb91..20840ce 100644
--- a/pkg/analysis_server/tool/spec/generate_all.dart
+++ b/pkg/analysis_server/tool/spec/generate_all.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 
 import 'codegen_analysis_server.dart' as codegen_analysis_server;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/BulkFix.java b/pkg/analysis_server/tool/spec/generated/java/types/BulkFix.java
new file mode 100644
index 0000000..5b62f16
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/BulkFix.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A description of bulk fixes to a library.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class BulkFix {
+
+  public static final BulkFix[] EMPTY_ARRAY = new BulkFix[0];
+
+  public static final List<BulkFix> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The path of the library.
+   */
+  private final String path;
+
+  /**
+   * A list of bulk fix details.
+   */
+  private final List<BulkFixDetail> fixes;
+
+  /**
+   * Constructor for {@link BulkFix}.
+   */
+  public BulkFix(String path, List<BulkFixDetail> fixes) {
+    this.path = path;
+    this.fixes = fixes;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof BulkFix) {
+      BulkFix other = (BulkFix) obj;
+      return
+        ObjectUtilities.equals(other.path, path) &&
+        ObjectUtilities.equals(other.fixes, fixes);
+    }
+    return false;
+  }
+
+  public static BulkFix fromJson(JsonObject jsonObject) {
+    String path = jsonObject.get("path").getAsString();
+    List<BulkFixDetail> fixes = BulkFixDetail.fromJsonArray(jsonObject.get("fixes").getAsJsonArray());
+    return new BulkFix(path, fixes);
+  }
+
+  public static List<BulkFix> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<BulkFix> list = new ArrayList<BulkFix>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * A list of bulk fix details.
+   */
+  public List<BulkFixDetail> getFixes() {
+    return fixes;
+  }
+
+  /**
+   * The path of the library.
+   */
+  public String getPath() {
+    return path;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(path);
+    builder.append(fixes);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("path", path);
+    JsonArray jsonArrayFixes = new JsonArray();
+    for (BulkFixDetail elt : fixes) {
+      jsonArrayFixes.add(elt.toJson());
+    }
+    jsonObject.add("fixes", jsonArrayFixes);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("path=");
+    builder.append(path + ", ");
+    builder.append("fixes=");
+    builder.append(StringUtils.join(fixes, ", "));
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/BulkFixDetail.java b/pkg/analysis_server/tool/spec/generated/java/types/BulkFixDetail.java
new file mode 100644
index 0000000..098306f7
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/BulkFixDetail.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A description of a fix applied to a library.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class BulkFixDetail {
+
+  public static final BulkFixDetail[] EMPTY_ARRAY = new BulkFixDetail[0];
+
+  public static final List<BulkFixDetail> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The code of the diagnostic associated with the fix.
+   */
+  private final String code;
+
+  /**
+   * The number times the associated diagnostic was fixed in the associated source edit.
+   */
+  private final int occurrences;
+
+  /**
+   * Constructor for {@link BulkFixDetail}.
+   */
+  public BulkFixDetail(String code, int occurrences) {
+    this.code = code;
+    this.occurrences = occurrences;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof BulkFixDetail) {
+      BulkFixDetail other = (BulkFixDetail) obj;
+      return
+        ObjectUtilities.equals(other.code, code) &&
+        other.occurrences == occurrences;
+    }
+    return false;
+  }
+
+  public static BulkFixDetail fromJson(JsonObject jsonObject) {
+    String code = jsonObject.get("code").getAsString();
+    int occurrences = jsonObject.get("occurrences").getAsInt();
+    return new BulkFixDetail(code, occurrences);
+  }
+
+  public static List<BulkFixDetail> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<BulkFixDetail> list = new ArrayList<BulkFixDetail>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The code of the diagnostic associated with the fix.
+   */
+  public String getCode() {
+    return code;
+  }
+
+  /**
+   * The number times the associated diagnostic was fixed in the associated source edit.
+   */
+  public int getOccurrences() {
+    return occurrences;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(code);
+    builder.append(occurrences);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("code", code);
+    jsonObject.addProperty("occurrences", occurrences);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("code=");
+    builder.append(code + ", ");
+    builder.append("occurrences=");
+    builder.append(occurrences);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
index e7595aa..8362cdd 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
@@ -58,4 +58,9 @@
 
   public static final String PARAMETER = "PARAMETER";
 
+  /**
+   * The name of a pub package is being suggested.
+   */
+  public static final String PACKAGE_NAME = "PACKAGE_NAME";
+
 }
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 21d7fbc..2b1e1d2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -32,28 +32,16 @@
   public static final String DIRECTIVE = "DIRECTIVE";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String DYNAMIC_TYPE = "DYNAMIC_TYPE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_LOCAL_VARIABLE_DECLARATION = "DYNAMIC_LOCAL_VARIABLE_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_LOCAL_VARIABLE_REFERENCE = "DYNAMIC_LOCAL_VARIABLE_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_PARAMETER_DECLARATION = "DYNAMIC_PARAMETER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_PARAMETER_REFERENCE = "DYNAMIC_PARAMETER_REFERENCE";
 
   public static final String ENUM = "ENUM";
@@ -61,29 +49,29 @@
   public static final String ENUM_CONSTANT = "ENUM_CONSTANT";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FIELD = "FIELD";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FIELD_STATIC = "FIELD_STATIC";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FUNCTION = "FUNCTION";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FUNCTION_DECLARATION = "FUNCTION_DECLARATION";
 
   public static final String FUNCTION_TYPE_ALIAS = "FUNCTION_TYPE_ALIAS";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String GETTER_DECLARATION = "GETTER_DECLARATION";
 
@@ -91,58 +79,28 @@
 
   public static final String IMPORT_PREFIX = "IMPORT_PREFIX";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_FIELD_DECLARATION = "INSTANCE_FIELD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_FIELD_REFERENCE = "INSTANCE_FIELD_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_GETTER_DECLARATION = "INSTANCE_GETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_GETTER_REFERENCE = "INSTANCE_GETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_METHOD_DECLARATION = "INSTANCE_METHOD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_METHOD_REFERENCE = "INSTANCE_METHOD_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_SETTER_DECLARATION = "INSTANCE_SETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_SETTER_REFERENCE = "INSTANCE_SETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INVALID_STRING_ESCAPE = "INVALID_STRING_ESCAPE";
 
   public static final String KEYWORD = "KEYWORD";
 
   public static final String LABEL = "LABEL";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LIBRARY_NAME = "LIBRARY_NAME";
 
   public static final String LITERAL_BOOLEAN = "LITERAL_BOOLEAN";
@@ -157,155 +115,92 @@
 
   public static final String LITERAL_STRING = "LITERAL_STRING";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LOCAL_FUNCTION_DECLARATION = "LOCAL_FUNCTION_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LOCAL_FUNCTION_REFERENCE = "LOCAL_FUNCTION_REFERENCE";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String LOCAL_VARIABLE = "LOCAL_VARIABLE";
 
   public static final String LOCAL_VARIABLE_DECLARATION = "LOCAL_VARIABLE_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LOCAL_VARIABLE_REFERENCE = "LOCAL_VARIABLE_REFERENCE";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD = "METHOD";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD_DECLARATION = "METHOD_DECLARATION";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD_DECLARATION_STATIC = "METHOD_DECLARATION_STATIC";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD_STATIC = "METHOD_STATIC";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String PARAMETER = "PARAMETER";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String SETTER_DECLARATION = "SETTER_DECLARATION";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String TOP_LEVEL_VARIABLE = "TOP_LEVEL_VARIABLE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String PARAMETER_DECLARATION = "PARAMETER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String PARAMETER_REFERENCE = "PARAMETER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_FIELD_DECLARATION = "STATIC_FIELD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_GETTER_DECLARATION = "STATIC_GETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_GETTER_REFERENCE = "STATIC_GETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_METHOD_DECLARATION = "STATIC_METHOD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_METHOD_REFERENCE = "STATIC_METHOD_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_SETTER_DECLARATION = "STATIC_SETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_SETTER_REFERENCE = "STATIC_SETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_FUNCTION_DECLARATION = "TOP_LEVEL_FUNCTION_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_FUNCTION_REFERENCE = "TOP_LEVEL_FUNCTION_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_GETTER_DECLARATION = "TOP_LEVEL_GETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_GETTER_REFERENCE = "TOP_LEVEL_GETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_SETTER_DECLARATION = "TOP_LEVEL_SETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_SETTER_REFERENCE = "TOP_LEVEL_SETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_VARIABLE_DECLARATION = "TOP_LEVEL_VARIABLE_DECLARATION";
 
   public static final String TYPE_NAME_DYNAMIC = "TYPE_NAME_DYNAMIC";
 
   public static final String TYPE_PARAMETER = "TYPE_PARAMETER";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String UNRESOLVED_INSTANCE_MEMBER_REFERENCE = "UNRESOLVED_INSTANCE_MEMBER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String VALID_STRING_ESCAPE = "VALID_STRING_ESCAPE";
 
 }
diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart
index 44d89c2..fb67058 100644
--- a/pkg/analysis_server/tool/spec/implied_types.dart
+++ b/pkg/analysis_server/tool/spec/implied_types.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code for enumerating the set of types implied by the API.
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index eb8cf23..57cd829 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.30.0</version>
+  <version>1.32.1</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -133,6 +133,11 @@
   the server so clients should ensure unknown values are handled gracefully, either
   ignoring the item or treating it with some default/fallback handling.
 </p>
+<h3>Changelog</h3>
+<h4>1.32.1</h4>
+<ul>
+  <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt></li>
+</ul>
 <h3>Domains</h3>
 <p>
   For convenience, the API is divided into domains. Each domain is specified
@@ -2196,6 +2201,15 @@
           A list of source edits to apply the recommended changes.
         </p>
       </field>
+      <field name="details">
+        <list>
+          <ref>BulkFix</ref>
+        </list>
+        <p>
+          Details that summarize the fixes associated with the recommended
+          changes.
+        </p>
+      </field>
     </result>
   </request>
   <request method="dartfix" experimental="true">
@@ -3537,6 +3551,47 @@
       </field>
     </object>
   </type>
+  <type name="BulkFix">
+    <p>
+      A description of bulk fixes to a library.
+    </p>
+    <object>
+      <field name="path">
+        <ref>FilePath</ref>
+        <p>
+          The path of the library.
+        </p>
+      </field>
+      <field name="fixes">
+        <list>
+          <ref>BulkFixDetail</ref>
+        </list>
+        <p>
+          A list of bulk fix details.
+        </p>
+      </field>
+    </object>
+  </type>
+  <type name="BulkFixDetail">
+    <p>
+      A description of a fix applied to a library.
+    </p>
+    <object>
+      <field name="code">
+        <ref>String</ref>
+        <p>
+          The code of the diagnostic associated with the fix.
+        </p>
+      </field>
+      <field name="occurrences">
+        <ref>int</ref>
+        <p>
+          The number times the associated diagnostic was fixed in the associated
+          source edit.
+        </p>
+      </field>
+    </object>
+  </type>
   <type name="ClosingLabel">
     <p>
       A label that is associated with a range of code that may be useful to
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 9ad321a..db50d44 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -7,8 +7,8 @@
 /// in generated code.
 import 'dart:convert';
 
-import 'package:analysis_tool/html.dart';
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/html.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
index 17afcd9..346847c 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
@@ -1,13 +1,10 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
 // This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
-//
-// TODO(brianwilkerson) This file is not being generated as advertised, but it
-//  should be generated. Fix the generator to generate this file.
 
 import 'dart:convert' hide JsonDecoder;
 
@@ -96,6 +93,8 @@
 ///   "message": String
 ///   "correction": optional String
 ///   "code": String
+///   "url": optional String
+///   "contextMessages": optional List<DiagnosticMessage>
 ///   "hasFix": optional bool
 /// }
 ///
@@ -113,6 +112,10 @@
 
   String _code;
 
+  String _url;
+
+  List<DiagnosticMessage> _contextMessages;
+
   bool _hasFix;
 
   /// The severity of the error.
@@ -174,37 +177,62 @@
     _code = value;
   }
 
-  /// A hint to indicate to interested clients that this error has an associated
-  /// fix (or fixes). The absence of this field implies there are not known to
-  /// be fixes. Note that since the operation to calculate whether fixes apply
-  /// needs to be performant it is possible that complicated tests will be
-  /// skipped and a false negative returned. For this reason, this attribute
-  /// should be treated as a "hint". Despite the possibility of false negatives,
-  /// no false positives should be returned. If a client sees this flag set they
-  /// can proceed with the confidence that there are in fact associated fixes.
+  /// The URL of a page containing documentation associated with this error.
+  String get url => _url;
+
+  /// The URL of a page containing documentation associated with this error.
+  set url(String value) {
+    _url = value;
+  }
+
+  /// Additional messages associated with this diagnostic that provide context
+  /// to help the user understand the diagnostic.
+  List<DiagnosticMessage> get contextMessages => _contextMessages;
+
+  /// Additional messages associated with this diagnostic that provide context
+  /// to help the user understand the diagnostic.
+  set contextMessages(List<DiagnosticMessage> value) {
+    _contextMessages = value;
+  }
+
+  /// A hint to indicate to interested clients that this error has an
+  /// associated fix (or fixes). The absence of this field implies there are
+  /// not known to be fixes. Note that since the operation to calculate whether
+  /// fixes apply needs to be performant it is possible that complicated tests
+  /// will be skipped and a false negative returned. For this reason, this
+  /// attribute should be treated as a "hint". Despite the possibility of false
+  /// negatives, no false positives should be returned. If a client sees this
+  /// flag set they can proceed with the confidence that there are in fact
+  /// associated fixes.
   bool get hasFix => _hasFix;
 
-  /// A hint to indicate to interested clients that this error has an associated
-  /// fix (or fixes). The absence of this field implies there are not known to
-  /// be fixes. Note that since the operation to calculate whether fixes apply
-  /// needs to be performant it is possible that complicated tests will be
-  /// skipped and a false negative returned. For this reason, this attribute
-  /// should be treated as a "hint". Despite the possibility of false negatives,
-  /// no false positives should be returned. If a client sees this flag set they
-  /// can proceed with the confidence that there are in fact associated fixes.
+  /// A hint to indicate to interested clients that this error has an
+  /// associated fix (or fixes). The absence of this field implies there are
+  /// not known to be fixes. Note that since the operation to calculate whether
+  /// fixes apply needs to be performant it is possible that complicated tests
+  /// will be skipped and a false negative returned. For this reason, this
+  /// attribute should be treated as a "hint". Despite the possibility of false
+  /// negatives, no false positives should be returned. If a client sees this
+  /// flag set they can proceed with the confidence that there are in fact
+  /// associated fixes.
   set hasFix(bool value) {
     _hasFix = value;
   }
 
   AnalysisError(AnalysisErrorSeverity severity, AnalysisErrorType type,
       Location location, String message, String code,
-      {String correction, bool hasFix}) {
+      {String correction,
+      String url,
+      List<DiagnosticMessage> contextMessages,
+      bool hasFix}) {
     this.severity = severity;
     this.type = type;
     this.location = location;
     this.message = message;
     this.correction = correction;
     this.code = code;
+    this.url = url;
+    this.contextMessages = contextMessages;
     this.hasFix = hasFix;
   }
 
@@ -251,12 +279,27 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'code');
       }
+      String url;
+      if (json.containsKey('url')) {
+        url = jsonDecoder.decodeString(jsonPath + '.url', json['url']);
+      }
+      List<DiagnosticMessage> contextMessages;
+      if (json.containsKey('contextMessages')) {
+        contextMessages = jsonDecoder.decodeList(
+            jsonPath + '.contextMessages',
+            json['contextMessages'],
+            (String jsonPath, Object json) =>
+                DiagnosticMessage.fromJson(jsonDecoder, jsonPath, json));
+      }
       bool hasFix;
       if (json.containsKey('hasFix')) {
         hasFix = jsonDecoder.decodeBool(jsonPath + '.hasFix', json['hasFix']);
       }
       return AnalysisError(severity, type, location, message, code,
-          correction: correction, hasFix: hasFix);
+          correction: correction,
+          url: url,
+          contextMessages: contextMessages,
+          hasFix: hasFix);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'AnalysisError', json);
     }
@@ -273,6 +316,14 @@
       result['correction'] = correction;
     }
     result['code'] = code;
+    if (url != null) {
+      result['url'] = url;
+    }
+    if (contextMessages != null) {
+      result['contextMessages'] = contextMessages
+          .map((DiagnosticMessage value) => value.toJson())
+          .toList();
+    }
     if (hasFix != null) {
       result['hasFix'] = hasFix;
     }
@@ -291,6 +342,9 @@
           message == other.message &&
           correction == other.correction &&
           code == other.code &&
+          url == other.url &&
+          listEqual(contextMessages, other.contextMessages,
+              (DiagnosticMessage a, DiagnosticMessage b) => a == b) &&
           hasFix == other.hasFix;
     }
     return false;
@@ -305,6 +359,8 @@
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, correction.hashCode);
     hash = JenkinsSmiHash.combine(hash, code.hashCode);
+    hash = JenkinsSmiHash.combine(hash, url.hashCode);
+    hash = JenkinsSmiHash.combine(hash, contextMessages.hashCode);
     hash = JenkinsSmiHash.combine(hash, hasFix.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -562,7 +618,6 @@
 ///   "hasNamedParameters": optional bool
 ///   "parameterName": optional String
 ///   "parameterType": optional String
-///   "importUri": optional String
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -609,8 +664,6 @@
 
   String _parameterType;
 
-  String _importUri;
-
   /// The kind of element being suggested.
   CompletionSuggestionKind get kind => _kind;
 
@@ -720,12 +773,12 @@
     _docComplete = value;
   }
 
-  /// The class that declares the element being suggested. This field is omitted
-  /// if the suggested element is not a member of a class.
+  /// The class that declares the element being suggested. This field is
+  /// omitted if the suggested element is not a member of a class.
   String get declaringType => _declaringType;
 
-  /// The class that declares the element being suggested. This field is omitted
-  /// if the suggested element is not a member of a class.
+  /// The class that declares the element being suggested. This field is
+  /// omitted if the suggested element is not a member of a class.
   set declaringType(String value) {
     _declaringType = value;
   }
@@ -766,14 +819,14 @@
     _element = value;
   }
 
-  /// The return type of the getter, function or method or the type of the field
-  /// being suggested. This field is omitted if the suggested element is not a
-  /// getter, function or method.
+  /// The return type of the getter, function or method or the type of the
+  /// field being suggested. This field is omitted if the suggested element is
+  /// not a getter, function or method.
   String get returnType => _returnType;
 
-  /// The return type of the getter, function or method or the type of the field
-  /// being suggested. This field is omitted if the suggested element is not a
-  /// getter, function or method.
+  /// The return type of the getter, function or method or the type of the
+  /// field being suggested. This field is omitted if the suggested element is
+  /// not a getter, function or method.
   set returnType(String value) {
     _returnType = value;
   }
@@ -842,16 +895,6 @@
     _parameterType = value;
   }
 
-  /// The import to be added if the suggestion is out of scope and needs an
-  /// import to be added to be in scope.
-  String get importUri => _importUri;
-
-  /// The import to be added if the suggestion is out of scope and needs an
-  /// import to be added to be in scope.
-  set importUri(String value) {
-    _importUri = value;
-  }
-
   CompletionSuggestion(
       CompletionSuggestionKind kind,
       int relevance,
@@ -873,8 +916,7 @@
       int requiredParameterCount,
       bool hasNamedParameters,
       String parameterName,
-      String parameterType,
-      String importUri}) {
+      String parameterType}) {
     this.kind = kind;
     this.relevance = relevance;
     this.completion = completion;
@@ -896,7 +938,6 @@
     this.hasNamedParameters = hasNamedParameters;
     this.parameterName = parameterName;
     this.parameterType = parameterType;
-    this.importUri = importUri;
   }
 
   factory CompletionSuggestion.fromJson(
@@ -1026,11 +1067,6 @@
         parameterType = jsonDecoder.decodeString(
             jsonPath + '.parameterType', json['parameterType']);
       }
-      String importUri;
-      if (json.containsKey('importUri')) {
-        importUri = jsonDecoder.decodeString(
-            jsonPath + '.importUri', json['importUri']);
-      }
       return CompletionSuggestion(kind, relevance, completion, selectionOffset,
           selectionLength, isDeprecated, isPotential,
           displayText: displayText,
@@ -1046,8 +1082,7 @@
           requiredParameterCount: requiredParameterCount,
           hasNamedParameters: hasNamedParameters,
           parameterName: parameterName,
-          parameterType: parameterType,
-          importUri: importUri);
+          parameterType: parameterType);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'CompletionSuggestion', json);
     }
@@ -1105,9 +1140,6 @@
     if (parameterType != null) {
       result['parameterType'] = parameterType;
     }
-    if (importUri != null) {
-      result['importUri'] = importUri;
-    }
     return result;
   }
 
@@ -1140,8 +1172,7 @@
           requiredParameterCount == other.requiredParameterCount &&
           hasNamedParameters == other.hasNamedParameters &&
           parameterName == other.parameterName &&
-          parameterType == other.parameterType &&
-          importUri == other.importUri;
+          parameterType == other.parameterType;
     }
     return false;
   }
@@ -1170,7 +1201,6 @@
     hash = JenkinsSmiHash.combine(hash, hasNamedParameters.hashCode);
     hash = JenkinsSmiHash.combine(hash, parameterName.hashCode);
     hash = JenkinsSmiHash.combine(hash, parameterType.hashCode);
-    hash = JenkinsSmiHash.combine(hash, importUri.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -1187,6 +1217,7 @@
 ///   OPTIONAL_ARGUMENT
 ///   OVERRIDE
 ///   PARAMETER
+///   PACKAGE_NAME
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -1209,13 +1240,14 @@
       CompletionSuggestionKind._('IDENTIFIER');
 
   /// The element is being invoked at the completion location. For example,
-  /// 'someMethod' in x.someMethod();. For suggestions of this kind, the element
-  /// attribute is defined and the completion field is the element's identifier.
+  /// 'someMethod' in x.someMethod();. For suggestions of this kind, the
+  /// element attribute is defined and the completion field is the element's
+  /// identifier.
   static const CompletionSuggestionKind INVOCATION =
       CompletionSuggestionKind._('INVOCATION');
 
-  /// A keyword is being suggested. For suggestions of this kind, the completion
-  /// is the keyword.
+  /// A keyword is being suggested. For suggestions of this kind, the
+  /// completion is the keyword.
   static const CompletionSuggestionKind KEYWORD =
       CompletionSuggestionKind._('KEYWORD');
 
@@ -1235,6 +1267,10 @@
   static const CompletionSuggestionKind PARAMETER =
       CompletionSuggestionKind._('PARAMETER');
 
+  /// The name of a pub package is being suggested.
+  static const CompletionSuggestionKind PACKAGE_NAME =
+      CompletionSuggestionKind._('PACKAGE_NAME');
+
   /// A list containing all of the enum values that are defined.
   static const List<CompletionSuggestionKind> VALUES =
       <CompletionSuggestionKind>[
@@ -1246,7 +1282,8 @@
     NAMED_ARGUMENT,
     OPTIONAL_ARGUMENT,
     OVERRIDE,
-    PARAMETER
+    PARAMETER,
+    PACKAGE_NAME
   ];
 
   @override
@@ -1274,6 +1311,8 @@
         return OVERRIDE;
       case 'PARAMETER':
         return PARAMETER;
+      case 'PACKAGE_NAME':
+        return PACKAGE_NAME;
     }
     throw Exception('Illegal enum value: $name');
   }
@@ -1296,6 +1335,96 @@
   String toJson() => name;
 }
 
+/// DiagnosticMessage
+///
+/// {
+///   "message": String
+///   "location": Location
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class DiagnosticMessage implements HasToJson {
+  String _message;
+
+  Location _location;
+
+  /// The message to be displayed to the user.
+  String get message => _message;
+
+  /// The message to be displayed to the user.
+  set message(String value) {
+    assert(value != null);
+    _message = value;
+  }
+
+  /// The location associated with or referenced by the message. Clients should
+  /// provide the ability to navigate to the location.
+  Location get location => _location;
+
+  /// The location associated with or referenced by the message. Clients should
+  /// provide the ability to navigate to the location.
+  set location(Location value) {
+    assert(value != null);
+    _location = value;
+  }
+
+  DiagnosticMessage(String message, Location location) {
+    this.message = message;
+    this.location = location;
+  }
+
+  factory DiagnosticMessage.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    json ??= {};
+    if (json is Map) {
+      String message;
+      if (json.containsKey('message')) {
+        message =
+            jsonDecoder.decodeString(jsonPath + '.message', json['message']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'message');
+      }
+      Location location;
+      if (json.containsKey('location')) {
+        location = Location.fromJson(
+            jsonDecoder, jsonPath + '.location', json['location']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'location');
+      }
+      return DiagnosticMessage(message, location);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'DiagnosticMessage', json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var result = <String, dynamic>{};
+    result['message'] = message;
+    result['location'] = location.toJson();
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is DiagnosticMessage) {
+      return message == other.message && location == other.location;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, message.hashCode);
+    hash = JenkinsSmiHash.combine(hash, location.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
 /// Element
 ///
 /// {
@@ -1415,14 +1544,14 @@
     _parameters = value;
   }
 
-  /// The return type of the element. If the element is not a method or function
-  /// this field will not be defined. If the element does not have a declared
-  /// return type, this field will contain an empty string.
+  /// The return type of the element. If the element is not a method or
+  /// function this field will not be defined. If the element does not have a
+  /// declared return type, this field will contain an empty string.
   String get returnType => _returnType;
 
-  /// The return type of the element. If the element is not a method or function
-  /// this field will not be defined. If the element does not have a declared
-  /// return type, this field will contain an empty string.
+  /// The return type of the element. If the element is not a method or
+  /// function this field will not be defined. If the element does not have a
+  /// declared return type, this field will contain an empty string.
   set returnType(String value) {
     _returnType = value;
   }
@@ -1573,6 +1702,7 @@
 ///   CONSTRUCTOR_INVOCATION
 ///   ENUM
 ///   ENUM_CONSTANT
+///   EXTENSION
 ///   FIELD
 ///   FILE
 ///   FUNCTION
@@ -1611,6 +1741,8 @@
 
   static const ElementKind ENUM_CONSTANT = ElementKind._('ENUM_CONSTANT');
 
+  static const ElementKind EXTENSION = ElementKind._('EXTENSION');
+
   static const ElementKind FIELD = ElementKind._('FIELD');
 
   static const ElementKind FILE = ElementKind._('FILE');
@@ -1661,6 +1793,7 @@
     CONSTRUCTOR_INVOCATION,
     ENUM,
     ENUM_CONSTANT,
+    EXTENSION,
     FIELD,
     FILE,
     FUNCTION,
@@ -1703,6 +1836,8 @@
         return ENUM;
       case 'ENUM_CONSTANT':
         return ENUM_CONSTANT;
+      case 'EXTENSION':
+        return EXTENSION;
       case 'FIELD':
         return FIELD;
       case 'FILE':
@@ -1767,6 +1902,7 @@
 ///
 /// enum {
 ///   ANNOTATIONS
+///   BLOCK
 ///   CLASS_BODY
 ///   DIRECTIVES
 ///   DOCUMENTATION_COMMENT
@@ -1780,6 +1916,8 @@
 class FoldingKind implements Enum {
   static const FoldingKind ANNOTATIONS = FoldingKind._('ANNOTATIONS');
 
+  static const FoldingKind BLOCK = FoldingKind._('BLOCK');
+
   static const FoldingKind CLASS_BODY = FoldingKind._('CLASS_BODY');
 
   static const FoldingKind DIRECTIVES = FoldingKind._('DIRECTIVES');
@@ -1798,6 +1936,7 @@
   /// A list containing all of the enum values that are defined.
   static const List<FoldingKind> VALUES = <FoldingKind>[
     ANNOTATIONS,
+    BLOCK,
     CLASS_BODY,
     DIRECTIVES,
     DOCUMENTATION_COMMENT,
@@ -1816,6 +1955,8 @@
     switch (name) {
       case 'ANNOTATIONS':
         return ANNOTATIONS;
+      case 'BLOCK':
+        return BLOCK;
       case 'CLASS_BODY':
         return CLASS_BODY;
       case 'DIRECTIVES':
@@ -2174,23 +2315,19 @@
   static const HighlightRegionType DIRECTIVE =
       HighlightRegionType._('DIRECTIVE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType DYNAMIC_TYPE =
       HighlightRegionType._('DYNAMIC_TYPE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_DECLARATION =
       HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_REFERENCE =
       HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_PARAMETER_DECLARATION =
       HighlightRegionType._('DYNAMIC_PARAMETER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_PARAMETER_REFERENCE =
       HighlightRegionType._('DYNAMIC_PARAMETER_REFERENCE');
 
@@ -2199,24 +2336,24 @@
   static const HighlightRegionType ENUM_CONSTANT =
       HighlightRegionType._('ENUM_CONSTANT');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FIELD = HighlightRegionType._('FIELD');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FIELD_STATIC =
       HighlightRegionType._('FIELD_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FUNCTION = HighlightRegionType._('FUNCTION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FUNCTION_DECLARATION =
       HighlightRegionType._('FUNCTION_DECLARATION');
 
   static const HighlightRegionType FUNCTION_TYPE_ALIAS =
       HighlightRegionType._('FUNCTION_TYPE_ALIAS');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType GETTER_DECLARATION =
       HighlightRegionType._('GETTER_DECLARATION');
 
@@ -2226,39 +2363,30 @@
   static const HighlightRegionType IMPORT_PREFIX =
       HighlightRegionType._('IMPORT_PREFIX');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_FIELD_DECLARATION =
       HighlightRegionType._('INSTANCE_FIELD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_FIELD_REFERENCE =
       HighlightRegionType._('INSTANCE_FIELD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_GETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_GETTER_REFERENCE =
       HighlightRegionType._('INSTANCE_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_METHOD_DECLARATION =
       HighlightRegionType._('INSTANCE_METHOD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_METHOD_REFERENCE =
       HighlightRegionType._('INSTANCE_METHOD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_SETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_SETTER_REFERENCE =
       HighlightRegionType._('INSTANCE_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INVALID_STRING_ESCAPE =
       HighlightRegionType._('INVALID_STRING_ESCAPE');
 
@@ -2266,7 +2394,6 @@
 
   static const HighlightRegionType LABEL = HighlightRegionType._('LABEL');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LIBRARY_NAME =
       HighlightRegionType._('LIBRARY_NAME');
 
@@ -2288,113 +2415,94 @@
   static const HighlightRegionType LITERAL_STRING =
       HighlightRegionType._('LITERAL_STRING');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_FUNCTION_DECLARATION =
       HighlightRegionType._('LOCAL_FUNCTION_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_FUNCTION_REFERENCE =
       HighlightRegionType._('LOCAL_FUNCTION_REFERENCE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType LOCAL_VARIABLE =
       HighlightRegionType._('LOCAL_VARIABLE');
 
   static const HighlightRegionType LOCAL_VARIABLE_DECLARATION =
       HighlightRegionType._('LOCAL_VARIABLE_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_VARIABLE_REFERENCE =
       HighlightRegionType._('LOCAL_VARIABLE_REFERENCE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD = HighlightRegionType._('METHOD');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_DECLARATION =
       HighlightRegionType._('METHOD_DECLARATION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_DECLARATION_STATIC =
       HighlightRegionType._('METHOD_DECLARATION_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_STATIC =
       HighlightRegionType._('METHOD_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType PARAMETER =
       HighlightRegionType._('PARAMETER');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType SETTER_DECLARATION =
       HighlightRegionType._('SETTER_DECLARATION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType TOP_LEVEL_VARIABLE =
       HighlightRegionType._('TOP_LEVEL_VARIABLE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType PARAMETER_DECLARATION =
       HighlightRegionType._('PARAMETER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType PARAMETER_REFERENCE =
       HighlightRegionType._('PARAMETER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_FIELD_DECLARATION =
       HighlightRegionType._('STATIC_FIELD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_GETTER_DECLARATION =
       HighlightRegionType._('STATIC_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_GETTER_REFERENCE =
       HighlightRegionType._('STATIC_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_METHOD_DECLARATION =
       HighlightRegionType._('STATIC_METHOD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_METHOD_REFERENCE =
       HighlightRegionType._('STATIC_METHOD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_SETTER_DECLARATION =
       HighlightRegionType._('STATIC_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_SETTER_REFERENCE =
       HighlightRegionType._('STATIC_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_FUNCTION_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_FUNCTION_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_GETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_GETTER_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_SETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_SETTER_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_VARIABLE_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_VARIABLE_DECLARATION');
 
@@ -2404,11 +2512,9 @@
   static const HighlightRegionType TYPE_PARAMETER =
       HighlightRegionType._('TYPE_PARAMETER');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType UNRESOLVED_INSTANCE_MEMBER_REFERENCE =
       HighlightRegionType._('UNRESOLVED_INSTANCE_MEMBER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType VALID_STRING_ESCAPE =
       HighlightRegionType._('VALID_STRING_ESCAPE');
 
@@ -2849,13 +2955,13 @@
     _signature = value;
   }
 
-  /// The corpus of source code this KytheVName belongs to. Loosely, a corpus is
-  /// a collection of related files, such as the contents of a given source
+  /// The corpus of source code this KytheVName belongs to. Loosely, a corpus
+  /// is a collection of related files, such as the contents of a given source
   /// repository.
   String get corpus => _corpus;
 
-  /// The corpus of source code this KytheVName belongs to. Loosely, a corpus is
-  /// a collection of related files, such as the contents of a given source
+  /// The corpus of source code this KytheVName belongs to. Loosely, a corpus
+  /// is a collection of related files, such as the contents of a given source
   /// repository.
   set corpus(String value) {
     assert(value != null);
@@ -3468,14 +3574,14 @@
     _length = value;
   }
 
-  /// The indexes of the targets (in the enclosing navigation response) to which
-  /// the given region is bound. By opening the target, clients can implement
-  /// one form of navigation. This list cannot be empty.
+  /// The indexes of the targets (in the enclosing navigation response) to
+  /// which the given region is bound. By opening the target, clients can
+  /// implement one form of navigation. This list cannot be empty.
   List<int> get targets => _targets;
 
-  /// The indexes of the targets (in the enclosing navigation response) to which
-  /// the given region is bound. By opening the target, clients can implement
-  /// one form of navigation. This list cannot be empty.
+  /// The indexes of the targets (in the enclosing navigation response) to
+  /// which the given region is bound. By opening the target, clients can
+  /// implement one form of navigation. This list cannot be empty.
   set targets(List<int> value) {
     assert(value != null);
     _targets = value;
@@ -3557,6 +3663,8 @@
 ///   "length": int
 ///   "startLine": int
 ///   "startColumn": int
+///   "codeOffset": optional int
+///   "codeLength": optional int
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -3573,6 +3681,10 @@
 
   int _startColumn;
 
+  int _codeOffset;
+
+  int _codeLength;
+
   /// The kind of the element.
   ElementKind get kind => _kind;
 
@@ -3593,54 +3705,73 @@
     _fileIndex = value;
   }
 
-  /// The offset of the region to which the user can navigate.
+  /// The offset of the name of the target to which the user can navigate.
   int get offset => _offset;
 
-  /// The offset of the region to which the user can navigate.
+  /// The offset of the name of the target to which the user can navigate.
   set offset(int value) {
     assert(value != null);
     _offset = value;
   }
 
-  /// The length of the region to which the user can navigate.
+  /// The length of the name of the target to which the user can navigate.
   int get length => _length;
 
-  /// The length of the region to which the user can navigate.
+  /// The length of the name of the target to which the user can navigate.
   set length(int value) {
     assert(value != null);
     _length = value;
   }
 
   /// The one-based index of the line containing the first character of the
-  /// region.
+  /// name of the target.
   int get startLine => _startLine;
 
   /// The one-based index of the line containing the first character of the
-  /// region.
+  /// name of the target.
   set startLine(int value) {
     assert(value != null);
     _startLine = value;
   }
 
   /// The one-based index of the column containing the first character of the
-  /// region.
+  /// name of the target.
   int get startColumn => _startColumn;
 
   /// The one-based index of the column containing the first character of the
-  /// region.
+  /// name of the target.
   set startColumn(int value) {
     assert(value != null);
     _startColumn = value;
   }
 
+  /// The offset of the target code to which the user can navigate.
+  int get codeOffset => _codeOffset;
+
+  /// The offset of the target code to which the user can navigate.
+  set codeOffset(int value) {
+    _codeOffset = value;
+  }
+
+  /// The length of the target code to which the user can navigate.
+  int get codeLength => _codeLength;
+
+  /// The length of the target code to which the user can navigate.
+  set codeLength(int value) {
+    _codeLength = value;
+  }
+
   NavigationTarget(ElementKind kind, int fileIndex, int offset, int length,
-      int startLine, int startColumn) {
+      int startLine, int startColumn,
+      {int codeOffset, int codeLength}) {
     this.kind = kind;
     this.fileIndex = fileIndex;
     this.offset = offset;
     this.length = length;
     this.startLine = startLine;
     this.startColumn = startColumn;
+    this.codeOffset = codeOffset;
+    this.codeLength = codeLength;
   }
 
   factory NavigationTarget.fromJson(
@@ -3687,8 +3818,19 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'startColumn');
       }
+      int codeOffset;
+      if (json.containsKey('codeOffset')) {
+        codeOffset =
+            jsonDecoder.decodeInt(jsonPath + '.codeOffset', json['codeOffset']);
+      }
+      int codeLength;
+      if (json.containsKey('codeLength')) {
+        codeLength =
+            jsonDecoder.decodeInt(jsonPath + '.codeLength', json['codeLength']);
+      }
       return NavigationTarget(
-          kind, fileIndex, offset, length, startLine, startColumn);
+          kind, fileIndex, offset, length, startLine, startColumn,
+          codeOffset: codeOffset, codeLength: codeLength);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'NavigationTarget', json);
     }
@@ -3703,6 +3845,12 @@
     result['length'] = length;
     result['startLine'] = startLine;
     result['startColumn'] = startColumn;
+    if (codeOffset != null) {
+      result['codeOffset'] = codeOffset;
+    }
+    if (codeLength != null) {
+      result['codeLength'] = codeLength;
+    }
     return result;
   }
 
@@ -3717,7 +3865,9 @@
           offset == other.offset &&
           length == other.length &&
           startLine == other.startLine &&
-          startColumn == other.startColumn;
+          startColumn == other.startColumn &&
+          codeOffset == other.codeOffset &&
+          codeLength == other.codeLength;
     }
     return false;
   }
@@ -3731,6 +3881,8 @@
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, startLine.hashCode);
     hash = JenkinsSmiHash.combine(hash, startColumn.hashCode);
+    hash = JenkinsSmiHash.combine(hash, codeOffset.hashCode);
+    hash = JenkinsSmiHash.combine(hash, codeLength.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -3881,15 +4033,15 @@
   }
 
   /// The offset of the first character of the element. This is different than
-  /// the offset in the Element, which is the offset of the name of the element.
-  /// It can be used, for example, to map locations in the file back to an
-  /// outline.
+  /// the offset in the Element, which is the offset of the name of the
+  /// element. It can be used, for example, to map locations in the file back
+  /// to an outline.
   int get offset => _offset;
 
   /// The offset of the first character of the element. This is different than
-  /// the offset in the Element, which is the offset of the name of the element.
-  /// It can be used, for example, to map locations in the file back to an
-  /// outline.
+  /// the offset in the Element, which is the offset of the name of the
+  /// element. It can be used, for example, to map locations in the file back
+  /// to an outline.
   set offset(int value) {
     assert(value != null);
     _offset = value;
@@ -4179,27 +4331,34 @@
 /// ParameterKind
 ///
 /// enum {
-///   NAMED
-///   OPTIONAL
-///   REQUIRED
+///   OPTIONAL_NAMED
+///   OPTIONAL_POSITIONAL
+///   REQUIRED_NAMED
+///   REQUIRED_POSITIONAL
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ParameterKind implements Enum {
-  /// A named parameter.
-  static const ParameterKind NAMED = ParameterKind._('NAMED');
+  /// An optional named parameter.
+  static const ParameterKind OPTIONAL_NAMED = ParameterKind._('OPTIONAL_NAMED');
 
-  /// An optional parameter.
-  static const ParameterKind OPTIONAL = ParameterKind._('OPTIONAL');
+  /// An optional positional parameter.
+  static const ParameterKind OPTIONAL_POSITIONAL =
+      ParameterKind._('OPTIONAL_POSITIONAL');
 
-  /// A required parameter.
-  static const ParameterKind REQUIRED = ParameterKind._('REQUIRED');
+  /// A required named parameter.
+  static const ParameterKind REQUIRED_NAMED = ParameterKind._('REQUIRED_NAMED');
+
+  /// A required positional parameter.
+  static const ParameterKind REQUIRED_POSITIONAL =
+      ParameterKind._('REQUIRED_POSITIONAL');
 
   /// A list containing all of the enum values that are defined.
   static const List<ParameterKind> VALUES = <ParameterKind>[
-    NAMED,
-    OPTIONAL,
-    REQUIRED
+    OPTIONAL_NAMED,
+    OPTIONAL_POSITIONAL,
+    REQUIRED_NAMED,
+    REQUIRED_POSITIONAL
   ];
 
   @override
@@ -4209,12 +4368,14 @@
 
   factory ParameterKind(String name) {
     switch (name) {
-      case 'NAMED':
-        return NAMED;
-      case 'OPTIONAL':
-        return OPTIONAL;
-      case 'REQUIRED':
-        return REQUIRED;
+      case 'OPTIONAL_NAMED':
+        return OPTIONAL_NAMED;
+      case 'OPTIONAL_POSITIONAL':
+        return OPTIONAL_POSITIONAL;
+      case 'REQUIRED_NAMED':
+        return REQUIRED_NAMED;
+      case 'REQUIRED_POSITIONAL':
+        return REQUIRED_POSITIONAL;
     }
     throw Exception('Illegal enum value: $name');
   }
@@ -4682,13 +4843,13 @@
   }
 
   /// The location of the problem being represented. This field is omitted
-  /// unless there is a specific location associated with the problem (such as a
-  /// location where an element being renamed will be shadowed).
+  /// unless there is a specific location associated with the problem (such as
+  /// a location where an element being renamed will be shadowed).
   Location get location => _location;
 
   /// The location of the problem being represented. This field is omitted
-  /// unless there is a specific location associated with the problem (such as a
-  /// location where an element being renamed will be shadowed).
+  /// unless there is a specific location associated with the problem (such as
+  /// a location where an element being renamed will be shadowed).
   set location(Location value) {
     _location = value;
   }
@@ -4778,10 +4939,10 @@
   static const RefactoringProblemSeverity INFO =
       RefactoringProblemSeverity._('INFO');
 
-  /// A minor code problem. For example names of local variables should be camel
-  /// case and start with a lower case letter. Staring the name of a variable
-  /// with an upper case is OK from the language point of view, but it is nice
-  /// to warn the user.
+  /// A minor code problem. For example names of local variables should be
+  /// camel case and start with a lower case letter. Staring the name of a
+  /// variable with an upper case is OK from the language point of view, but it
+  /// is nice to warn the user.
   static const RefactoringProblemSeverity WARNING =
       RefactoringProblemSeverity._('WARNING');
 
@@ -5112,8 +5273,8 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SourceEdit implements HasToJson {
-  /// Get the result of applying a set of [edits] to the given [code]. Edits are
-  /// applied in the order they appear in [edits].
+  /// Get the result of applying a set of [edits] to the given [code]. Edits
+  /// are applied in the order they appear in [edits].
   static String applySequence(String code, Iterable<SourceEdit> edits) =>
       applySequenceOfEdits(code, edits);
 
@@ -5284,16 +5445,16 @@
 
   /// The modification stamp of the file at the moment when the change was
   /// created, in milliseconds since the "Unix epoch". Will be -1 if the file
-  /// did not exist and should be created. The client may use this field to make
-  /// sure that the file was not changed since then, so it is safe to apply the
-  /// change.
+  /// did not exist and should be created. The client may use this field to
+  /// make sure that the file was not changed since then, so it is safe to
+  /// apply the change.
   int get fileStamp => _fileStamp;
 
   /// The modification stamp of the file at the moment when the change was
   /// created, in milliseconds since the "Unix epoch". Will be -1 if the file
-  /// did not exist and should be created. The client may use this field to make
-  /// sure that the file was not changed since then, so it is safe to apply the
-  /// change.
+  /// did not exist and should be created. The client may use this field to
+  /// make sure that the file was not changed since then, so it is safe to
+  /// apply the change.
   set fileStamp(int value) {
     assert(value != null);
     _fileStamp = value;
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 25f5a64..7636ffc 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.30.0';
+const String PROTOCOL_VERSION = '1.32.1';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -222,6 +222,7 @@
 const String EDIT_REQUEST_ORGANIZE_DIRECTIVES_FILE = 'file';
 const String EDIT_REQUEST_SORT_MEMBERS = 'edit.sortMembers';
 const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file';
+const String EDIT_RESPONSE_BULK_FIXES_DETAILS = 'details';
 const String EDIT_RESPONSE_BULK_FIXES_EDITS = 'edits';
 const String EDIT_RESPONSE_DARTFIX_DETAILS = 'details';
 const String EDIT_RESPONSE_DARTFIX_EDITS = 'edits';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index b6d697f..b9466f0 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -4955,6 +4955,188 @@
   }
 }
 
+/// BulkFix
+///
+/// {
+///   "path": FilePath
+///   "fixes": List<BulkFixDetail>
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class BulkFix implements HasToJson {
+  String _path;
+
+  List<BulkFixDetail> _fixes;
+
+  /// The path of the library.
+  String get path => _path;
+
+  /// The path of the library.
+  set path(String value) {
+    assert(value != null);
+    _path = value;
+  }
+
+  /// A list of bulk fix details.
+  List<BulkFixDetail> get fixes => _fixes;
+
+  /// A list of bulk fix details.
+  set fixes(List<BulkFixDetail> value) {
+    assert(value != null);
+    _fixes = value;
+  }
+
+  BulkFix(String path, List<BulkFixDetail> fixes) {
+    this.path = path;
+    this.fixes = fixes;
+  }
+
+  factory BulkFix.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    json ??= {};
+    if (json is Map) {
+      String path;
+      if (json.containsKey('path')) {
+        path = jsonDecoder.decodeString(jsonPath + '.path', json['path']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'path');
+      }
+      List<BulkFixDetail> fixes;
+      if (json.containsKey('fixes')) {
+        fixes = jsonDecoder.decodeList(
+            jsonPath + '.fixes',
+            json['fixes'],
+            (String jsonPath, Object json) =>
+                BulkFixDetail.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'fixes');
+      }
+      return BulkFix(path, fixes);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'BulkFix', json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var result = <String, dynamic>{};
+    result['path'] = path;
+    result['fixes'] =
+        fixes.map((BulkFixDetail value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is BulkFix) {
+      return path == other.path &&
+          listEqual(
+              fixes, other.fixes, (BulkFixDetail a, BulkFixDetail b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, path.hashCode);
+    hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/// BulkFixDetail
+///
+/// {
+///   "code": String
+///   "occurrences": int
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class BulkFixDetail implements HasToJson {
+  String _code;
+
+  int _occurrences;
+
+  /// The code of the diagnostic associated with the fix.
+  String get code => _code;
+
+  /// The code of the diagnostic associated with the fix.
+  set code(String value) {
+    assert(value != null);
+    _code = value;
+  }
+
+  /// The number times the associated diagnostic was fixed in the associated
+  /// source edit.
+  int get occurrences => _occurrences;
+
+  /// The number times the associated diagnostic was fixed in the associated
+  /// source edit.
+  set occurrences(int value) {
+    assert(value != null);
+    _occurrences = value;
+  }
+
+  BulkFixDetail(String code, int occurrences) {
+    this.code = code;
+    this.occurrences = occurrences;
+  }
+
+  factory BulkFixDetail.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    json ??= {};
+    if (json is Map) {
+      String code;
+      if (json.containsKey('code')) {
+        code = jsonDecoder.decodeString(jsonPath + '.code', json['code']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'code');
+      }
+      int occurrences;
+      if (json.containsKey('occurrences')) {
+        occurrences = jsonDecoder.decodeInt(
+            jsonPath + '.occurrences', json['occurrences']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'occurrences');
+      }
+      return BulkFixDetail(code, occurrences);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'BulkFixDetail', json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var result = <String, dynamic>{};
+    result['code'] = code;
+    result['occurrences'] = occurrences;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is BulkFixDetail) {
+      return code == other.code && occurrences == other.occurrences;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, code.hashCode);
+    hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
 /// ClosingLabel
 ///
 /// {
@@ -7210,12 +7392,15 @@
 ///
 /// {
 ///   "edits": List<SourceFileEdit>
+///   "details": List<BulkFix>
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditBulkFixesResult implements ResponseResult {
   List<SourceFileEdit> _edits;
 
+  List<BulkFix> _details;
+
   /// A list of source edits to apply the recommended changes.
   List<SourceFileEdit> get edits => _edits;
 
@@ -7225,8 +7410,18 @@
     _edits = value;
   }
 
-  EditBulkFixesResult(List<SourceFileEdit> edits) {
+  /// Details that summarize the fixes associated with the recommended changes.
+  List<BulkFix> get details => _details;
+
+  /// Details that summarize the fixes associated with the recommended changes.
+  set details(List<BulkFix> value) {
+    assert(value != null);
+    _details = value;
+  }
+
+  EditBulkFixesResult(List<SourceFileEdit> edits, List<BulkFix> details) {
     this.edits = edits;
+    this.details = details;
   }
 
   factory EditBulkFixesResult.fromJson(
@@ -7243,7 +7438,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
       }
-      return EditBulkFixesResult(edits);
+      List<BulkFix> details;
+      if (json.containsKey('details')) {
+        details = jsonDecoder.decodeList(
+            jsonPath + '.details',
+            json['details'],
+            (String jsonPath, Object json) =>
+                BulkFix.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'details');
+      }
+      return EditBulkFixesResult(edits, details);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'edit.bulkFixes result', json);
     }
@@ -7261,6 +7466,7 @@
     var result = <String, dynamic>{};
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
+    result['details'] = details.map((BulkFix value) => value.toJson()).toList();
     return result;
   }
 
@@ -7275,8 +7481,9 @@
   @override
   bool operator ==(other) {
     if (other is EditBulkFixesResult) {
-      return listEqual(
-          edits, other.edits, (SourceFileEdit a, SourceFileEdit b) => a == b);
+      return listEqual(edits, other.edits,
+              (SourceFileEdit a, SourceFileEdit b) => a == b) &&
+          listEqual(details, other.details, (BulkFix a, BulkFix b) => a == b);
     }
     return false;
   }
@@ -7285,6 +7492,7 @@
   int get hashCode {
     var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
+    hash = JenkinsSmiHash.combine(hash, details.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml
index 9ee4b0e..0589bc3 100644
--- a/pkg/analysis_server_client/pubspec.yaml
+++ b/pkg/analysis_server_client/pubspec.yaml
@@ -15,4 +15,6 @@
     path: ../analyzer
   analysis_server:
     path: ../analysis_server
+  analyzer_utilities:
+    path: ../analyzer_utilities
   test: ^1.14.2
diff --git a/pkg/analysis_server_client/test/utils/package_root.dart b/pkg/analysis_server_client/test/utils/package_root.dart
deleted file mode 100644
index e8befb2..0000000
--- a/pkg/analysis_server_client/test/utils/package_root.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:path/path.dart' as pathos;
-
-/// Returns a path to the directory containing source code for packages such as
-/// kernel, front_end, and analyzer.
-String get packageRoot {
-  // If the package root directory is specified on the command line using
-  // -DpkgRoot=..., use it.
-  const pkgRootVar =
-      bool.hasEnvironment('pkgRoot') ? String.fromEnvironment('pkgRoot') : null;
-  if (pkgRootVar != null) {
-    var path = pathos.join(Directory.current.path, pkgRootVar);
-    if (!path.endsWith(pathos.separator)) path += pathos.separator;
-    return path;
-  }
-  // Otherwise try to guess based on the script path.
-  var scriptPath = pathos.fromUri(Platform.script);
-  var parts = pathos.split(scriptPath);
-  var pkgIndex = parts.indexOf('pkg');
-  if (pkgIndex != -1) {
-    return pathos.joinAll(parts.sublist(0, pkgIndex + 1)) + pathos.separator;
-  }
-  throw StateError('Unable to find sdk/pkg/ in $scriptPath');
-}
diff --git a/pkg/analysis_server_client/test/verify_sorted_test.dart b/pkg/analysis_server_client/test/verify_sorted_test.dart
index 88f936f..79d7299 100644
--- a/pkg/analysis_server_client/test/verify_sorted_test.dart
+++ b/pkg/analysis_server_client/test/verify_sorted_test.dart
@@ -10,10 +10,9 @@
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer_utilities/package_root.dart';
 import 'package:test/test.dart';
 
-import 'utils/package_root.dart';
-
 void main() {
   var provider = PhysicalResourceProvider.INSTANCE;
   var normalizedRoot = provider.pathContext.normalize(packageRoot);
diff --git a/pkg/analysis_tool/lib/text_formatter.dart b/pkg/analysis_tool/lib/text_formatter.dart
deleted file mode 100644
index 2305910..0000000
--- a/pkg/analysis_tool/lib/text_formatter.dart
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Code for converting HTML into text, for use during code generation of
- * analyzer and analysis server.
- */
-
-import 'package:analysis_tool/tools.dart';
-import 'package:html/dom.dart' as dom;
-
-final RegExp whitespace = new RegExp(r'\s');
-
-/**
- * Convert the HTML in [desc] into text, word wrapping at width [width].
- *
- * If [javadocStyle] is true, then the output is compatible with Javadoc,
- * which understands certain HTML constructs.
- */
-String nodesToText(List<dom.Node> desc, int width, bool javadocStyle,
-    {bool removeTrailingNewLine: false}) {
-  _TextFormatter formatter = new _TextFormatter(width, javadocStyle);
-  return formatter.collectCode(() {
-    formatter.addAll(desc);
-    formatter.lineBreak(false);
-  }, removeTrailingNewLine: removeTrailingNewLine);
-}
-
-/**
- * Engine that transforms HTML to text.  The input HTML is processed one
- * character at a time, gathering characters into words and words into lines.
- */
-class _TextFormatter extends CodeGenerator {
-  /**
-   * Word-wrapping width.
-   */
-  final int width;
-
-  /**
-   * The word currently being gathered.
-   */
-  String word = '';
-
-  /**
-   * The line currently being gathered.
-   */
-  String line = '';
-
-  /**
-   * True if a blank line should be inserted before the next word.
-   */
-  bool verticalSpaceNeeded = false;
-
-  /**
-   * True if no text has been output yet.  This suppresses blank lines.
-   */
-  bool atStart = true;
-
-  /**
-   * True if we are processing a <pre> element, thus whitespace should be
-   * preserved.
-   */
-  bool preserveSpaces = false;
-
-  /**
-   * True if the output should be Javadoc compatible.
-   */
-  final bool javadocStyle;
-
-  _TextFormatter(this.width, this.javadocStyle);
-
-  /**
-   * Process an HTML node.
-   */
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      for (String char in node.text.split('')) {
-        if (preserveSpaces) {
-          wordBreak();
-          write(escape(char));
-        } else if (whitespace.hasMatch(char)) {
-          wordBreak();
-        } else {
-          resolveVerticalSpace();
-          word += escape(char);
-        }
-      }
-    } else if (node is dom.Element) {
-      switch (node.localName) {
-        case 'br':
-          lineBreak(false);
-          break;
-        case 'dl':
-        case 'dt':
-        case 'h1':
-        case 'h2':
-        case 'h3':
-        case 'h4':
-        case 'p':
-          lineBreak(true);
-          addAll(node.nodes);
-          lineBreak(true);
-          break;
-        case 'div':
-          lineBreak(false);
-          if (node.classes.contains('hangingIndent')) {
-            resolveVerticalSpace();
-            indentSpecial('', '        ', () {
-              addAll(node.nodes);
-              lineBreak(false);
-            });
-          } else {
-            addAll(node.nodes);
-            lineBreak(false);
-          }
-          break;
-        case 'ul':
-          lineBreak(false);
-          addAll(node.nodes);
-          lineBreak(false);
-          break;
-        case 'li':
-          lineBreak(false);
-          resolveVerticalSpace();
-          indentSpecial('- ', '  ', () {
-            addAll(node.nodes);
-            lineBreak(false);
-          });
-          break;
-        case 'dd':
-          lineBreak(true);
-          indent(() {
-            addAll(node.nodes);
-            lineBreak(true);
-          });
-          break;
-        case 'pre':
-          lineBreak(false);
-          resolveVerticalSpace();
-          if (javadocStyle) {
-            writeln('<pre>');
-          }
-          bool oldPreserveSpaces = preserveSpaces;
-          try {
-            preserveSpaces = true;
-            addAll(node.nodes);
-          } finally {
-            preserveSpaces = oldPreserveSpaces;
-          }
-          writeln();
-          if (javadocStyle) {
-            writeln('</pre>');
-          }
-          lineBreak(false);
-          break;
-        case 'a':
-        case 'b':
-        case 'body':
-        case 'html':
-        case 'i':
-        case 'span':
-        case 'tt':
-          addAll(node.nodes);
-          break;
-        case 'head':
-          break;
-        default:
-          throw new Exception('Unexpected HTML element: ${node.localName}');
-      }
-    } else {
-      throw new Exception('Unexpected HTML: $node');
-    }
-  }
-
-  /**
-   * Process a list of HTML nodes.
-   */
-  void addAll(List<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      add(node);
-    }
-  }
-
-  /**
-   * Escape the given character for HTML.
-   */
-  String escape(String char) {
-    if (javadocStyle) {
-      switch (char) {
-        case '<':
-          return '&lt;';
-        case '>':
-          return '&gt;';
-        case '&':
-          return '&amp;';
-      }
-    }
-    return char;
-  }
-
-  /**
-   * Terminate the current word and/or line, if either is in progress.
-   */
-  void lineBreak(bool gap) {
-    wordBreak();
-    if (line.isNotEmpty) {
-      writeln(line);
-      line = '';
-    }
-    if (gap && !atStart) {
-      verticalSpaceNeeded = true;
-    }
-  }
-
-  /**
-   * Insert vertical space if necessary.
-   */
-  void resolveVerticalSpace() {
-    if (verticalSpaceNeeded) {
-      writeln();
-      verticalSpaceNeeded = false;
-    }
-  }
-
-  /**
-   * Terminate the current word, if a word is in progress.
-   */
-  void wordBreak() {
-    if (word.isNotEmpty) {
-      atStart = false;
-      if (line.isNotEmpty) {
-        if (indentWidth + line.length + 1 + word.length <= width) {
-          line += ' $word';
-        } else {
-          writeln(line);
-          line = word;
-        }
-      } else {
-        line = word;
-      }
-      word = '';
-    }
-  }
-}
diff --git a/pkg/analysis_tool/lib/tools.dart b/pkg/analysis_tool/lib/tools.dart
deleted file mode 100644
index 831014e..0000000
--- a/pkg/analysis_tool/lib/tools.dart
+++ /dev/null
@@ -1,648 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Tools for generating code in analyzer and analysis server.
- */
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_tool/html.dart';
-import 'package:analysis_tool/text_formatter.dart';
-import 'package:html/dom.dart' as dom;
-import 'package:path/path.dart';
-
-final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
-final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
-
-/**
- * Join the given strings using camelCase.  If [doCapitalize] is true, the first
- * part will be capitalized as well.
- */
-String camelJoin(List<String> parts, {bool doCapitalize: false}) {
-  List<String> upcasedParts = <String>[];
-  for (int i = 0; i < parts.length; i++) {
-    if (i == 0 && !doCapitalize) {
-      upcasedParts.add(parts[i]);
-    } else {
-      upcasedParts.add(capitalize(parts[i]));
-    }
-  }
-  return upcasedParts.join();
-}
-
-/**
- * Capitalize and return the passed String.
- */
-String capitalize(String string) {
-  return string[0].toUpperCase() + string.substring(1);
-}
-
-/**
- * Type of functions used to compute the contents of a set of generated files.
- * [pkgPath] is the path to the current package.
- */
-typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
-    String pkgPath);
-
-/**
- * Type of functions used to compute the contents of a generated file.
- * [pkgPath] is the path to the current package.
- */
-typedef Future<String> FileContentsComputer(String pkgPath);
-
-/**
- * Mixin class for generating code.
- */
-class CodeGenerator {
-  _CodeGeneratorState _state;
-
-  /**
-   * Settings that specialize code generation behavior for a given
-   * programming language.
-   */
-  CodeGeneratorSettings codeGeneratorSettings = new CodeGeneratorSettings();
-
-  /**
-   * Measure the width of the current indentation level.
-   */
-  int get indentWidth => _state.nextIndent.length;
-
-  /**
-   * Execute [callback], collecting any code that is output using [write]
-   * or [writeln], and return the result as a string.
-   */
-  String collectCode(void callback(), {bool removeTrailingNewLine: false}) {
-    _CodeGeneratorState oldState = _state;
-    try {
-      _state = new _CodeGeneratorState();
-      callback();
-      var text =
-          _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, '');
-      if (!removeTrailingNewLine) {
-        return text;
-      } else {
-        return text.replaceAll(trailingWhitespaceRegExp, '');
-      }
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Generate a doc comment based on the HTML in [docs].
-   *
-   * When generating java code, the output is compatible with Javadoc, which
-   * understands certain HTML constructs.
-   */
-  void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
-    if (containsOnlyWhitespace(docs)) return;
-    if (codeGeneratorSettings.docCommentStartMarker != null)
-      writeln(codeGeneratorSettings.docCommentStartMarker);
-    int width = codeGeneratorSettings.commentLineLength;
-    bool javadocStyle = codeGeneratorSettings.languageName == 'java';
-    indentBy(codeGeneratorSettings.docCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, javadocStyle,
-          removeTrailingNewLine: removeTrailingNewLine));
-    });
-    if (codeGeneratorSettings.docCommentEndMarker != null)
-      writeln(codeGeneratorSettings.docCommentEndMarker);
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs.
-   */
-  void indent(void callback()) {
-    indentSpecial(
-        codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback);
-  }
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   */
-  void indentBy(String additionalIndent, void callback()) =>
-      indentSpecial(additionalIndent, additionalIndent, callback);
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   * The first line of output is indented by [firstAdditionalIndent] instead of
-   * [additionalIndent].
-   */
-  void indentSpecial(
-      String firstAdditionalIndent, String additionalIndent, void callback()) {
-    String oldNextIndent = _state.nextIndent;
-    String oldIndent = _state.indent;
-    try {
-      _state.nextIndent += firstAdditionalIndent;
-      _state.indent += additionalIndent;
-      callback();
-    } finally {
-      _state.nextIndent = oldNextIndent;
-      _state.indent = oldIndent;
-    }
-  }
-
-  void lineComment(List<dom.Node> docs) {
-    if (containsOnlyWhitespace(docs)) {
-      return;
-    }
-    write(codeGeneratorSettings.lineCommentLineLeader);
-    int width = codeGeneratorSettings.commentLineLength;
-    indentBy(codeGeneratorSettings.lineCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, false));
-    });
-  }
-
-  void outputHeader({bool javaStyle: false, String year = null}) {
-    String header;
-    if (codeGeneratorSettings.languageName == 'java') {
-      header = '''
-/*
- * Copyright (c) ${year ?? '2019'}, the Dart project authors. Please see the AUTHORS file
- * for details. All rights reserved. Use of this source code is governed by a
- * BSD-style license that can be found in the LICENSE file.
- *
- * This file has been automatically generated. Please do not edit it manually.
- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
- */''';
-    } else if (codeGeneratorSettings.languageName == 'python') {
-      header = '''
-# Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-#
-# This file has been automatically generated. Please do not edit it manually.
-# To regenerate the file, use the script
-# "pkg/analysis_server/tool/spec/generate_files".
-''';
-    } else {
-      header = '''
-// Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the script
-// "pkg/analysis_server/tool/spec/generate_files".
-''';
-    }
-    writeln(header.trim());
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * Controls several settings of [CodeGenerator].
- *
- * The default settings are valid for generating Java and Dart code.
- */
-class CodeGeneratorSettings {
-  /**
-   * Name of the language being generated. Lowercase.
-   */
-  String languageName;
-
-  /**
-   * Marker used in line comments.
-   */
-  String lineCommentLineLeader;
-
-  /**
-   * Start marker for doc comments.
-   */
-  String docCommentStartMarker;
-
-  /**
-   * Line leader for body lines in doc comments.
-   */
-  String docCommentLineLeader;
-
-  /**
-   * End marker for doc comments.
-   */
-  String docCommentEndMarker;
-
-  /**
-   * Line length for doc comment lines.
-   */
-  int commentLineLength;
-
-  /**
-   * String used for indenting code.
-   */
-  String indent;
-
-  CodeGeneratorSettings(
-      {this.languageName: 'java',
-      this.lineCommentLineLeader: '// ',
-      this.docCommentStartMarker: '/**',
-      this.docCommentLineLeader: ' * ',
-      this.docCommentEndMarker: ' */',
-      this.commentLineLength: 99,
-      this.indent: '  '});
-}
-
-/**
- * A utility class for invoking dartfmt.
- */
-class DartFormat {
-  static String get _dartfmtPath {
-    String binName = Platform.isWindows ? 'dartfmt.bat' : 'dartfmt';
-    for (var loc in [binName, join('dart-sdk', 'bin', binName)]) {
-      var candidatePath = join(dirname(Platform.resolvedExecutable), loc);
-      if (new File(candidatePath).existsSync()) {
-        return candidatePath;
-      }
-    }
-    throw new StateError('Could not find dartfmt executable');
-  }
-
-  static void formatFile(File file) {
-    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
-    if (result.exitCode != 0) throw result.stderr;
-  }
-
-  static String formatText(String text) {
-    File file = new File(join(Directory.systemTemp.path, 'gen.dart'));
-    file.writeAsStringSync(text);
-    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
-    if (result.exitCode != 0) throw result.stderr;
-    return file.readAsStringSync();
-  }
-}
-
-/**
- * Abstract base class representing behaviors common to generated files and
- * generated directories.
- */
-abstract class GeneratedContent {
-  /**
-   * Check whether the [output] has the correct contents, and return true if it
-   * does.  [pkgPath] is the path to the current package.
-   */
-  Future<bool> check(String pkgPath);
-
-  /**
-   * Replace the [output] with the correct contents.  [pkgPath] is the path to
-   * the current package.
-   */
-  Future<void> generate(String pkgPath);
-
-  /**
-   * Get a [FileSystemEntity] representing the output file or directory.
-   * [pkgPath] is the path to the current package.
-   */
-  FileSystemEntity output(String pkgPath);
-
-  /**
-   * Check that all of the [targets] are up to date.  If they are not, print
-   * out a message instructing the user to regenerate them, and exit with a
-   * nonzero error code.
-   *
-   * [pkgPath] is the path to the current package.  [generatorPath] is the path
-   * to a .dart script the user may use to regenerate the targets.
-   *
-   * To avoid mistakes when run on Windows, [generatorPath] always uses
-   * POSIX directory separators.
-   */
-  static Future<void> checkAll(
-      String pkgPath, String generatorPath, Iterable<GeneratedContent> targets,
-      {List<String> args = const []}) async {
-    bool generateNeeded = false;
-    for (GeneratedContent target in targets) {
-      bool ok = await target.check(pkgPath);
-      if (!ok) {
-        print("${target.output(pkgPath).absolute}"
-            " doesn't have expected contents.");
-        generateNeeded = true;
-      }
-    }
-    if (generateNeeded) {
-      print('Please regenerate using:');
-      String executable = Platform.executable;
-      String packageRoot = '';
-      // ignore: deprecated_member_use
-      if (Platform.packageRoot != null) {
-        // ignore: deprecated_member_use
-        packageRoot = ' --package-root=${Platform.packageRoot}';
-      }
-      String generateScript = normalize(joinAll(posix.split(generatorPath)));
-      print('  $executable$packageRoot $generateScript ${args.join(" ")}');
-      exit(1);
-    } else {
-      print('All generated files up to date.');
-    }
-  }
-
-  /**
-   * Regenerate all of the [targets].  [pkgPath] is the path to the current
-   * package.
-   */
-  static Future<void> generateAll(
-      String pkgPath, Iterable<GeneratedContent> targets) async {
-    print("Generating...");
-    for (GeneratedContent target in targets) {
-      await target.generate(pkgPath);
-    }
-  }
-}
-
-/**
- * Class representing a single output directory (either generated code or
- * generated HTML). No other content should exist in the directory.
- */
-class GeneratedDirectory extends GeneratedContent {
-  /**
-   * The path to the directory that will have the generated content.
-   */
-  final String outputDirPath;
-
-  /**
-   * Callback function that computes the directory contents.
-   */
-  final DirectoryContentsComputer directoryContentsComputer;
-
-  GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
-
-  @override
-  Future<bool> check(String pkgPath) async {
-    Directory outputDirectory = output(pkgPath);
-    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
-    try {
-      for (String file in map.keys) {
-        FileContentsComputer fileContentsComputer = map[file];
-        String expectedContents = await fileContentsComputer(pkgPath);
-        File outputFile = new File(posix.join(outputDirectory.path, file));
-        String actualContents = outputFile.readAsStringSync();
-        // Normalize Windows line endings to Unix line endings so that the
-        // comparison doesn't fail on Windows.
-        actualContents = actualContents.replaceAll('\r\n', '\n');
-        if (expectedContents != actualContents) {
-          return false;
-        }
-      }
-      int nonHiddenFileCount = 0;
-      outputDirectory
-          .listSync(recursive: false, followLinks: false)
-          .forEach((FileSystemEntity fileSystemEntity) {
-        if (fileSystemEntity is File &&
-            !basename(fileSystemEntity.path).startsWith('.')) {
-          nonHiddenFileCount++;
-        }
-      });
-      if (nonHiddenFileCount != map.length) {
-        // The number of files generated doesn't match the number we expected to
-        // generate.
-        return false;
-      }
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-    return true;
-  }
-
-  @override
-  Future<void> generate(String pkgPath) async {
-    Directory outputDirectory = output(pkgPath);
-    try {
-      // delete the contents of the directory (and the directory itself)
-      outputDirectory.deleteSync(recursive: true);
-    } catch (e) {
-      // Error caught while trying to delete the directory, this can happen if
-      // it didn't yet exist.
-    }
-    // re-create the empty directory
-    outputDirectory.createSync(recursive: true);
-
-    // generate all of the files in the directory
-    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
-    for (String file in map.keys) {
-      FileContentsComputer fileContentsComputer = map[file];
-      File outputFile = new File(posix.join(outputDirectory.path, file));
-      print('  ${outputFile.path}');
-      String contents = await fileContentsComputer(pkgPath);
-      outputFile.writeAsStringSync(contents);
-    }
-  }
-
-  @override
-  Directory output(String pkgPath) =>
-      new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
-}
-
-/**
- * Class representing a single output file (either generated code or generated
- * HTML).
- */
-class GeneratedFile extends GeneratedContent {
-  /**
-   * The output file to which generated output should be written, relative to
-   * the "tool/spec" directory.  This filename uses the posix path separator
-   * ('/') regardless of the OS.
-   */
-  final String outputPath;
-
-  /**
-   * Callback function which computes the file.
-   */
-  final FileContentsComputer computeContents;
-
-  GeneratedFile(this.outputPath, this.computeContents);
-
-  bool get isDartFile => outputPath.endsWith('.dart');
-
-  @override
-  Future<bool> check(String pkgPath) async {
-    File outputFile = output(pkgPath);
-    String expectedContents = await computeContents(pkgPath);
-    if (isDartFile) {
-      expectedContents = DartFormat.formatText(expectedContents);
-    }
-    try {
-      String actualContents = outputFile.readAsStringSync();
-      // Normalize Windows line endings to Unix line endings so that the
-      // comparison doesn't fail on Windows.
-      actualContents = actualContents.replaceAll('\r\n', '\n');
-      return expectedContents == actualContents;
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-  }
-
-  @override
-  Future<void> generate(String pkgPath) async {
-    File outputFile = output(pkgPath);
-    print('  ${outputFile.path}');
-    String contents = await computeContents(pkgPath);
-    outputFile.writeAsStringSync(contents);
-    if (isDartFile) {
-      DartFormat.formatFile(outputFile);
-    }
-  }
-
-  @override
-  File output(String pkgPath) =>
-      new File(join(pkgPath, joinAll(posix.split(outputPath))));
-}
-
-/**
- * Mixin class for generating HTML representations of code that are suitable
- * for enclosing inside a <pre> element.
- */
-abstract class HtmlCodeGenerator {
-  _HtmlCodeGeneratorState _state;
-
-  /**
-   * Add the given [node] to the HTML output.
-   */
-  void add(dom.Node node) {
-    _state.add(node);
-  }
-
-  /**
-   * Add the given [nodes] to the HTML output.
-   */
-  void addAll(Iterable<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      _state.add(node);
-    }
-  }
-
-  /**
-   * Execute [callback], collecting any code that is output using [write],
-   * [writeln], [add], or [addAll], and return the result as a list of DOM
-   * nodes.
-   */
-  List<dom.Node> collectHtml(void callback()) {
-    _HtmlCodeGeneratorState oldState = _state;
-    try {
-      _state = new _HtmlCodeGeneratorState();
-      if (callback != null) {
-        callback();
-      }
-      return _state.buffer;
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Execute [callback], wrapping its output in an element with the given
-   * [name] and [attributes].
-   */
-  void element(String name, Map<dynamic, String> attributes,
-      [void callback()]) {
-    add(makeElement(name, attributes, collectHtml(callback)));
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs by two spaces.
-   */
-  void indent(void callback()) {
-    String oldIndent = _state.indent;
-    try {
-      _state.indent += '  ';
-      callback();
-    } finally {
-      _state.indent = oldIndent;
-    }
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * State used by [CodeGenerator].
- */
-class _CodeGeneratorState {
-  StringBuffer buffer = new StringBuffer();
-  String nextIndent = '';
-  String indent = '';
-  bool indentNeeded = true;
-
-  void write(String text) {
-    List<String> lines = text.split('\n');
-    for (int i = 0; i < lines.length; i++) {
-      if (i == lines.length - 1 && lines[i].isEmpty) {
-        break;
-      }
-      if (indentNeeded) {
-        buffer.write(nextIndent);
-        nextIndent = indent;
-      }
-      indentNeeded = false;
-      buffer.write(lines[i]);
-      if (i != lines.length - 1) {
-        buffer.writeln();
-        indentNeeded = true;
-      }
-    }
-  }
-}
-
-/**
- * State used by [HtmlCodeGenerator].
- */
-class _HtmlCodeGeneratorState {
-  List<dom.Node> buffer = <dom.Node>[];
-  String indent = '';
-  bool indentNeeded = true;
-
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      write(node.text);
-    } else {
-      buffer.add(node);
-    }
-  }
-
-  void write(String text) {
-    if (text.isEmpty) {
-      return;
-    }
-    if (indentNeeded) {
-      buffer.add(new dom.Text(indent));
-    }
-    List<String> lines = text.split('\n');
-    if (lines.last.isEmpty) {
-      lines.removeLast();
-      buffer.add(new dom.Text(lines.join('\n$indent') + '\n'));
-      indentNeeded = true;
-    } else {
-      buffer.add(new dom.Text(lines.join('\n$indent')));
-      indentNeeded = false;
-    }
-  }
-}
diff --git a/pkg/analysis_tool/pubspec.yaml b/pkg/analysis_tool/pubspec.yaml
deleted file mode 100644
index 32199b3..0000000
--- a/pkg/analysis_tool/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: analysis_tool
-# This package is not intended for consumption on pub.dev. DO NOT publish.
-publish_to: none
-
-environment:
-  sdk: '>=2.1.0 <3.0.0'
-
-dependencies:
-  html: any
-  path: any
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 3fdeadb..227a18e 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,4 +1,11 @@
-## 0.41.0 (Not yet released - breaking changes)
+## 0.41.1
+* Updated `PackageBuildWorkspace` that supports `package:build` to stop
+  at the first directory with `pubspec.yaml`, and don't try to go up
+  and find another one with both `pubspec.yaml` and `.dart_tool/build`.
+* Added a new constructor for non-API `ErrorCode` class. It will be used to
+  migrate existing `ErrorCode` subclasses, and then deprecated and removed.
+
+## 0.41.0
 * Replaced `Scope.lookup({id, setter})` with `lookup(id)`.
 * Deprecated `Scope.lookup2(id)`, use `lookup()` instead.
 * Removed deprecated `Member.baseElement`.
@@ -10,6 +17,10 @@
 * The value of`FunctionType.element` for types created from a `typedef`
   is now `FunctionTypeAliasElement`, not its function element.
 * Removed deprecated `GenericTypeAliasElement`.
+* Removed `PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS`.
+* Changed the default `PhysicalResourceProvider` constructor to no longer take a
+  required positional parameter (removed the existing `fileReadMode` positional
+  parameter).
 
 ## 0.40.6
 * The non_nullable feature is released in 2.12 language version.
diff --git a/pkg/analyzer/TRIAGE.md b/pkg/analyzer/TRIAGE.md
new file mode 100644
index 0000000..4435727
--- /dev/null
+++ b/pkg/analyzer/TRIAGE.md
@@ -0,0 +1,112 @@
+# Triage Priorities for Dart Analyzer
+
+This document describes the relative priorities for bugs filed under the
+`area-analyzer` tag in GitHub as in
+[this search](https://github.com/dart-lang/sdk/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-analyzer).
+While there are always exceptions to any rule, in general try to align our
+priorities with these definitions.
+
+To triage bugs, search for `area-analyzer`
+[bugs that are not currently triaged](https://github.com/dart-lang/sdk/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-analyzer+-label%3AP0+-label%3AP1+-label%3AP2+-label%3AP3+-label%3AP4)
+and for each bug, mark priority based on how closely it matches with the below
+constraints.
+
+## Analyzer triage priorities
+
+Descriptions here use [terms and definitions](#terms-and-definitions) from the
+end of this document.  If your bug doesn't precisely match one of these,
+consider how impactful it is compared to examples given here and pick a priority
+reflecting that.
+
+### P0
+
+* Incorrect analysis errors or warnings, widespread
+* Uncaught exceptions resulting in tool crashes, widespread and no workaround
+* Incorrect resolution of symbols or libraries, widespread and no workaround
+* Incorrect data from analyzer API, widespread and with no workaround
+* Automation resulting in corrupted code from clean inputs, widespread
+* Performance regression, large and widespread
+* Any problem urgently blocking critical milestones for key users or Dart rolls
+  into Flutter/Google3
+* Security or privacy problem, widespread
+
+### P1
+
+* Incorrect analysis errors or warnings, on edge cases but no workarounds
+* Incorrect analysis infos, widespread
+* Incorrect resolution of symbols or libraries, edge cases, or widespread but
+  with workaround
+* Incorrect data from analyzer API, widespread but with workaround
+* Uncaught exceptions resulting in tool crashes, widespread but with workaround
+* Automation resulting in corrupted code from clean inputs, edge cases or with
+  an easy workaround
+* Automation resulting in incorrect code, widespread
+* Performance regression, large or widespread (but not both), or impacting key
+  users
+* An enhancement required for critical milestones for key users, or that has
+  significant evidence gathered indicating a positive impact if implemented
+* Any problem that, while it doesn't currently block, will block rolls into
+  Flutter/Google3 if not resolved within ~2 weeks
+* Security or privacy problem, in edge cases or with very simple workarounds
+
+### P2
+
+* Incorrect analysis errors or warnings, on edge cases with simple workaround
+* Incorrect analysis infos, on edge cases
+* Incorrect resolution of symbols or libraries, edge cases only with workarounds
+* Incorrect data from analyzer API, edge cases without workaround
+* Automation resulting in incorrect code, edge cases
+* Uncaught exceptions resulting in tool crashes, edge cases
+* Performance regression, large,  impacting edge cases, without good workarounds
+* Security or privacy problem, theoretical & non-exploitable
+* An enhancement that the team agrees is a good idea but without strong evidence
+  indicating positive impact
+
+### P3
+
+* Uncaught exceptions caught by a fuzzer, but believed to be theoretical
+  situations only
+* Incorrect analysis errors or warnings, theoretical
+* Incorrect analysis infos, on edge cases with workaround
+* Incorrect resolution of symbols or libraries, theoretical
+* Incorrect data from analyzer API, edge case with workaround available
+* Performance regression impacting edge cases with workaround or without
+  workaround if small
+* Automation resulting in incorrect code, theoretical or edge cases with easy
+  workaround
+* An enhancement that someone on the team thinks might be good but it isn't
+  (yet?) generally agreed by those working in the area that it is good
+
+### P4
+
+* Incorrect analysis infos, theoretical
+* Incorrect data from analyzer API, theoretical
+* Theoretical performance problems
+* An enhancement that may have some evidence that it isn't a good idea to
+  implement but it isn't clear enough to close
+
+## Terms and definitions
+
+### Terms describing impact
+
+* "edge cases" - Impacting only small parts of the ecosystem.  For example,
+  one package, or one key user with a workaround.  Note this is an edge case
+  from the perspective of the ecosystem vs. language definition.  If it isn't
+  happening much in the wild or (if there isn't evidence either way) if it
+  isn't believed to be super likely in the wild, it is an edge case.
+* "theoretical" - Something that we think is unlikely to happen in the wild
+  and there's no evidence for it happening in the wild.
+* "widespread" - Impact endemic throughout the ecosystem, or at least far
+  enough that this is impacting multiple key users.
+
+### Other terms
+
+* "automation" - Anything that changes the user's code automatically.
+  Autocompletion, quick fixing, NNBD migration, etc.
+* "corrupted code" - Modification of source code in such a way that it is
+  more than just a bit wrong or having some symbols that don't exist, but is
+  not valid Dart and would be painful to manually correct.
+* "incorrect code" - Modification of code in a way that is known to be wrong,
+  but would be trivial to figure out how to fix for the human using the tool.
+* "key users" - Flutter, Pub, Fuchsia, Dart, Google3, 1P
+* "tool" - Analysis Server, dartanalyzer, migration tool, analyzer-as-library
diff --git a/pkg/analyzer/doc/design/summaries.md b/pkg/analyzer/doc/design/summaries.md
new file mode 100644
index 0000000..3b3d623
--- /dev/null
+++ b/pkg/analyzer/doc/design/summaries.md
@@ -0,0 +1,103 @@
+# Summaries in Dart analyzer
+
+The purpose of this document is to provide a high-level overview of the summaries linking, storage format, and reading
+in Dart analyzer.
+
+## Design Considerations
+
+There are a couple of considerations to keep in mind when discussing the design.
+
+**We want the linking to be done using AST.** Default values, constructor initializers, and field initializers should be
+stored in their resolved state, with elements and type, because we need them to perform constant evaluation.
+
+**We want separation between AST and resolution.** Files change rarely, usually the user changes just one file, and this
+affects resolution of this file and a multiple other files. But only the resolution, not AST. So, we want to keep pieces
+that are not affected by the change.
+
+**We want to read only as much as necessary to do resolution.** Libraries often have many classes, but when we resolve a
+file, we don’t need all these classes, only those that are actually referenced. So, we want the format to support
+loading individual classes, functions, etc.
+
+## High level view
+
+When the analyzer needs to resolve a file, it works in the following way:
+
+1. Find the library cycle that contains this file, and library cycles of its dependencies, down to SDK.
+
+2. Link these library cycles from SDK up to the target cycle.
+
+3. Add linked bundles to `LinkedElementFactory`.
+
+4. When we need a specific element, we call `LinkedElementFactory.elementOfReference`. It will request parent elements,
+   and eventually load the containing library, the containing class, method, etc.
+
+## Lazy loading
+
+We try to load only libraries that are necessary. When a `PackageBundleReader` is created, it decodes only the header of
+the bundle - with the list of library URIs contained in the bundle, and creates `LibraryReader`s.
+
+When `LinkedElementFactory.createLibraryElementForReading` is invoked, the corresponding `LibraryReader` is asked to
+load units, which are `UnitReader`s. Each `UnitReader` keeps track of the location of its AST and resolution portions
+in `astReader` and `resolutionReader`. When `UnitReader` is created, it reads the index of top-level declarations, and
+fills `Reference` subtree. For each `Reference` we set its `nodeAccessor`, a pointer to the `_UnitMemberReader`, which
+can be used to load the corresponding AST node. This is a way to present the index of the unit to `LinkedElementFactory`
+.
+
+To support lazy loading the package bundle has the index of libraries, the library has the index of units, the unit has
+the index of top-level declarations, the class / extension / mixin has the index of members.
+
+Any time when we need the element for a `Reference`, we call `elementOfReference` of `LinkedElementFactory`, which
+asks `Reference.nodeAccessor` for the AST node, and then creates the corresponding `Element` wrapper around it, and
+stores into `Reference.element`. For example for `ClassDeclaration` it will create `ClassElement`. No resolution is
+required yet.
+
+When `Reference.element` is already set, we just return it, we have already done loading AST node and creating the
+element for this `Reference`.
+
+When we link libraries, we don’t use `LinkedElementFactory` to read nodes and create elements, because we already have
+full ASTs, and we can create elements for all nodes in advance, and put them into corresponding `Reference` children.
+
+We say that we need the element for a `Reference` because resolution stores elements as such references - a pair of the
+name, and the parent reference. So, we may have an empty `Reference` first, without `element` and `nodeAccessor`, then
+when `elementOfReference` is invoked, it will fill both for a `Reference`. But its siblings will stay unfilled.
+
+When we ask an `Element` anything that requires resolution, we apply resolution to the whole AST node of the element.
+For example, when we ask `ClassElement` for `supertype`, we apply resolution to the `ClassDeclaration` header (but not
+to any member of the `ClassDeclaration`) - supertype, mixins, interfaces. We do this by calling `applyResolution`
+of `AstLinkedContext`. We get `AstLinkedContext` from the node, which implements `HasAstLinkedContext`.
+
+`AstBinaryWriter` writes two streams of information at once - the AST itself, and resolution. In the future we might
+split writing AST and resolution into separate writers.
+
+Resolution information is just a sequence of elements and types, which is stored when we visit the resolved AST
+in `AstBinaryWriter`. We use the helper `_ResolutionSink` to encode elements and types into bytes.
+
+Resolution is applied to unresolved AST using `ApplyResolutionVisitor`, which visits AST nodes in the same sequence
+as `AstBinaryWriter`, and takes either elements or types from the same (untyped, unmarked in any way) stream of
+resolution bytes. `LinkedResolutionReader` corresponds to `_ResolutionSink` - it decodes elements and types from bytes.
+
+Each raw element is represented by an integer, an index in the reference table. This table is collected during writing
+in `_BundleWriterReferences`, and stored by `BundleWriterResolution` during `BundleWriter.finish()`. During
+loading `BundleReader` creates `_ReferenceReader`, which lazily converts names and parent references into `Reference`
+instances in the given `LinkedElementFactory` (from which we just take `rootReference`, not actually any elements). Once
+we have `Reference` for the element that we need to decode, we actually ask `LinkedResolutionReader` for the element,
+see above.
+
+In addition to raw elements, there are “members” (which is not the best name) - which might be `Element`s which we want
+to convert to legacy because they are declared in a null safe library, but we want their legacy types; or actually
+members of a class with type parameters and with some `Substitution` applied to them; or both.
+
+Strings are encoded as integers, during writing using `StringIndexer`, and during loading using `_StringTable`. We
+use `SummaryDataReader` to load primitive types, and also strings.
+
+## Known limitations
+
+Currently `LibraryScope` and its basis `_LibraryImportScope` and `PrefixScope` - they all work by asking all elements
+from the imported libraries. Which means that we load all top-level nodes of these libraries (and all libraries that
+they export). Fortunately we don’t apply resolution to these elements until we try to access some property of these
+elements, e.g. the return type of a getter. But still, we probably don’t actually use all the imported elements, and we
+potentially could avoid loading all these AST nodes. A solution could be to work with `Reference`s instead.
+
+Similarly `InheritanceManager3` builds the whole interface of a class, and loads all members of the class and all
+members of all its superinterfaces. But again, we might only call a few methods, and might not need any superinterfaces.
+A solution might be to fill class interfaces on demand.
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index e086608..5390ffa 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -32,6 +32,10 @@
   /// Feature information for the triple-shift operator.
   static final triple_shift = ExperimentalFeatures.triple_shift;
 
+  /// Feature information for non-function type aliases.
+  static final nonfunction_type_aliases =
+      ExperimentalFeatures.nonfunction_type_aliases;
+
   /// Feature information for variance.
   static final variance = ExperimentalFeatures.variance;
 
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 7ee7034..809579d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -1978,7 +1978,10 @@
 ///        [Annotation] 'export' [StringLiteral] [Combinator]* ';'
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class ExportDirective implements NamespaceDirective {}
+abstract class ExportDirective implements NamespaceDirective {
+  @override
+  ExportElement get element;
+}
 
 /// A node that represents an expression.
 ///
@@ -2930,21 +2933,30 @@
 
   /// Set the equal sign separating the name being defined from the function
   /// type to the given [token].
+  @Deprecated('Clients should not build AST manually')
   set equals(Token token);
 
   /// Return the type of function being defined by the alias.
+  ///
+  /// When the non-function type aliases feature is enabled and the denoted
+  /// type is not a [GenericFunctionType], return `null`.
   GenericFunctionType get functionType;
 
   /// Set the type of function being defined by the alias to the given
   /// [functionType].
+  @Deprecated('Clients should not build AST manually')
   set functionType(GenericFunctionType functionType);
 
+  /// Return the type being defined by the alias.
+  TypeAnnotation get type;
+
   /// Return the type parameters for the function type, or `null` if the
   /// function type does not have any type parameters.
   TypeParameterList get typeParameters;
 
   /// Set the type parameters for the function type to the given list of
   /// [typeParameters].
+  @Deprecated('Clients should not build AST manually')
   set typeParameters(TypeParameterList typeParameters);
 }
 
@@ -3217,6 +3229,9 @@
   /// Set the token representing the 'deferred' keyword to the given [token].
   set deferredKeyword(Token token);
 
+  @override
+  ImportElement get element;
+
   /// Return the prefix to be used with the imported names, or `null` if the
   /// imported names are not prefixed.
   SimpleIdentifier get prefix;
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 65b253e..4dcba21 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -511,7 +511,7 @@
       SimpleIdentifier name,
       TypeParameterList typeParameters,
       Token equals,
-      GenericFunctionType functionType,
+      TypeAnnotation type,
       Token semicolon);
 
   /// Returns a newly created import show combinator.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index be7a1eb..44d3ec9 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -408,6 +408,10 @@
   /// compilation unit.
   List<TopLevelVariableElement> get topLevelVariables;
 
+  /// Return a list containing all of the type aliases contained in this
+  /// compilation unit.
+  List<TypeAliasElement> get typeAliases;
+
   /// Return a list containing all of the classes contained in this compilation
   /// unit.
   List<ClassElement> get types;
@@ -859,7 +863,10 @@
   static const ElementKind TYPE_PARAMETER =
       ElementKind('TYPE_PARAMETER', 24, "type parameter");
 
-  static const ElementKind UNIVERSE = ElementKind('UNIVERSE', 25, "<universe>");
+  static const ElementKind TYPE_ALIAS =
+      ElementKind('TYPE_ALIAS', 25, "type alias");
+
+  static const ElementKind UNIVERSE = ElementKind('UNIVERSE', 26, "<universe>");
 
   static const List<ElementKind> values = [
     CLASS,
@@ -1653,6 +1660,19 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class TypeAliasElement
     implements TypeParameterizedElement, TypeDefiningElement {
+  /// If the aliased type has structure, return the corresponding element.
+  /// For example it could be [GenericFunctionTypeElement].
+  ///
+  /// If there is no structure, return `null`.
+  Element get aliasedElement;
+
+  /// Return the aliased type.
+  ///
+  /// If non-function type aliases feature is enabled for the enclosing library,
+  /// this type might be just anything. If the feature is disabled, return
+  /// a [FunctionType].
+  DartType get aliasedType;
+
   @override
   CompilationUnitElement get enclosingElement;
 
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 298ece7..865e8d3 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -38,11 +38,13 @@
   /// Instantiate the given generic element using the type arguments that
   /// correspond to the bounds of its type parameters.
   ///
-  /// One and only one of [classElement] or [functionTypeAliasElement] must
+  /// One and only one of [classElement] or [typeAliasElement] must
   /// be provided.
   DartType instantiateToBounds2({
     ClassElement classElement,
-    FunctionTypeAliasElement functionTypeAliasElement,
+    @Deprecated("Use 'typeAliasElement' instead")
+        FunctionTypeAliasElement functionTypeAliasElement,
+    TypeAliasElement typeAliasElement,
     @required NullabilitySuffix nullabilitySuffix,
   });
 
diff --git a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
index f3c9a79..1caa015 100644
--- a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
+++ b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
@@ -17,10 +17,9 @@
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:meta/meta.dart';
 import 'package:pub_semver/pub_semver.dart';
@@ -85,7 +84,6 @@
 
   AllowedExperiments allowedExperiments;
   Version languageVersion;
-  final PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
 
   _Builder(
     this.context,
@@ -106,21 +104,24 @@
       Reference.root(),
     );
 
-    var linkResult = link(elementFactory, inputLibraries);
-    bundleAssembler.setBundle2(linkResult.bundle);
+    var linkResult = link(elementFactory, inputLibraries, false);
 
-    var buffer = PackageBundleBuilder(
-      bundle2: linkResult.bundle,
-      sdk: PackageBundleSdkBuilder(
+    var bundleBuilder = PackageBundleBuilder();
+    for (var library in inputLibraries) {
+      bundleBuilder.addLibrary(
+        library.uriStr,
+        library.units.map((e) => e.uriStr).toList(),
+      );
+    }
+    return bundleBuilder.finish(
+      astBytes: linkResult.astBytes,
+      resolutionBytes: linkResult.resolutionBytes,
+      sdk: PackageBundleSdk(
+        languageVersionMajor: languageVersion.major,
+        languageVersionMinor: languageVersion.minor,
         allowedExperimentsJson: allowedExperimentsJson,
-        languageVersion: LinkedLanguageVersionBuilder(
-          major: languageVersion.major,
-          minor: languageVersion.minor,
-        ),
       ),
-    ).toBuffer();
-
-    return buffer is Uint8List ? buffer : Uint8List.fromList(buffer);
+    );
   }
 
   void _addLibrary(Source source) {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 38b3ce4..2357561 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -148,6 +148,7 @@
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
   CompileTimeErrorCode.DUPLICATE_DEFINITION,
+  CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER,
   CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
   CompileTimeErrorCode.DUPLICATE_PART,
   CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 0f0ee0d..9561ff6 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -55,22 +55,13 @@
 
 /// A `dart:io` based implementation of [ResourceProvider].
 class PhysicalResourceProvider implements ResourceProvider {
-  static final String Function(String) NORMALIZE_EOL_ALWAYS =
-      (String string) => string.replaceAll(RegExp('\r\n?'), '\n');
-
-  static final PhysicalResourceProvider INSTANCE =
-      PhysicalResourceProvider(null);
+  static final PhysicalResourceProvider INSTANCE = PhysicalResourceProvider();
 
   /// The path to the base folder where state is stored.
   final String _stateLocation;
 
-  PhysicalResourceProvider(String Function(String) fileReadMode,
-      {String stateLocation})
-      : _stateLocation = stateLocation ?? _getStandardStateLocation() {
-    if (fileReadMode != null) {
-      FileBasedSource.fileReadMode = fileReadMode;
-    }
-  }
+  PhysicalResourceProvider({String stateLocation})
+      : _stateLocation = stateLocation ?? _getStandardStateLocation();
 
   @override
   Context get pathContext => context;
@@ -188,7 +179,7 @@
   String readAsStringSync() {
     _throwIfWindowsDeviceDriver();
     try {
-      return FileBasedSource.fileReadMode(_file.readAsStringSync());
+      return _file.readAsStringSync();
     } on io.FileSystemException catch (exception) {
       throw FileSystemException(exception.path, exception.message);
     }
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
index 43ae068..b67961f 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
@@ -31,7 +31,12 @@
   /// Initialize a newly created error code to have the given [name].
   const AnalysisOptionsErrorCode(String name, String message,
       {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'AnalysisOptionsErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -78,7 +83,12 @@
   /// Initialize a newly created hint code to have the given [name].
   const AnalysisOptionsHintCode(String name, String message,
       {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'AnalysisOptionsHintCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
@@ -200,7 +210,12 @@
   /// Initialize a newly created warning code to have the given [name].
   const AnalysisOptionsWarningCode(String name, String message,
       {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'AnalysisOptionsWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/clients/angular_analyzer_plugin/angular_analyzer_plugin.dart b/pkg/analyzer/lib/src/clients/angular_analyzer_plugin/angular_analyzer_plugin.dart
deleted file mode 100644
index abedb68..0000000
--- a/pkg/analyzer/lib/src/clients/angular_analyzer_plugin/angular_analyzer_plugin.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// This library provides additional APIs for the corresponding client.
-///
-/// By providing such higher level APIs we simplify the clients, and reduce
-/// dependencies on analyzer internal, so can make otherwise breaking
-/// changes easily.
-library angular_analyzer_plugin;
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/scope.dart';
-import 'package:analyzer/src/dart/resolver/resolution_visitor.dart';
-import 'package:analyzer/src/generated/error_verifier.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:meta/meta.dart';
-
-/// Resolve the given [node] in the specified context.
-///
-/// The [componentClass] is the component class.
-///
-/// The [templateSource] is the file with the template.
-///
-/// The template might declare [localVariables], which might be referenced
-/// in the node being resolved.
-///
-/// The [overrideAsExpression] is invoked during [AsExpression] to support
-/// custom resolution behavior.
-void resolveTemplateNode({
-  @required ClassElement componentClass,
-  @required Source templateSource,
-  @required Iterable<LocalVariableElement> localVariables,
-  @required AstNode node,
-  @required AnalysisErrorListener errorListener,
-  @required ErrorReporter errorReporter,
-  OverrideAsExpression overrideAsExpression,
-}) {
-  final unitElement = componentClass.enclosingElement;
-  final library = componentClass.library;
-
-  node.accept(
-    ResolutionVisitor(
-      unitElement: unitElement,
-      errorListener: errorListener,
-      featureSet: library.context.analysisOptions.contextFeatures,
-      nameScope: library.scope,
-    ),
-  );
-
-  final inheritanceManager = InheritanceManager3();
-  final resolver = _AngularTemplateResolver(inheritanceManager, library,
-      templateSource, library.typeProvider, errorListener,
-      overrideAsExpression: overrideAsExpression);
-  // fill the name scope
-  final classScope = ClassScope(resolver.nameScope, componentClass);
-  final localScope = LocalScope(classScope);
-  resolver
-    ..nameScope = localScope
-    ..enclosingClass = componentClass;
-  localVariables.forEach(localScope.add);
-  // do resolve
-  node.accept(resolver);
-  // verify
-  final verifier = ErrorVerifier(
-      errorReporter, library, library.typeProvider, inheritanceManager)
-    ..enclosingClass = componentClass;
-  node.accept(verifier);
-}
-
-typedef OverrideAsExpression = void Function({
-  @required AsExpression node,
-  @required void Function(AsExpression) invokeSuper,
-});
-
-class _AngularTemplateResolver extends ResolverVisitor {
-  final OverrideAsExpression overrideAsExpression;
-
-  _AngularTemplateResolver(
-    InheritanceManager3 inheritanceManager,
-    LibraryElement library,
-    Source source,
-    TypeProvider typeProvider,
-    AnalysisErrorListener errorListener, {
-    @required this.overrideAsExpression,
-  }) : super(inheritanceManager, library, source, typeProvider, errorListener);
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    if (overrideAsExpression != null) {
-      overrideAsExpression(
-        node: node,
-        invokeSuper: (node) {
-          super.visitAsExpression(node);
-        },
-      );
-    } else {
-      super.visitAsExpression(node);
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index 8f23b6e..1bf44e0 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -7,9 +7,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
 import 'package:args/args.dart';
-import 'package:cli_util/cli_util.dart';
 
 const String analysisOptionsFileOption = 'options';
 const String defineVariableOption = 'D';
@@ -116,16 +114,6 @@
   return builderOptions;
 }
 
-/// Use the given [resourceProvider] and command-line [args] to create a Dart
-/// SDK manager. The manager will use summary information if [useSummaries] is
-/// `true` and if the summary information exists.
-DartSdkManager createDartSdkManager(
-    ResourceProvider resourceProvider, ArgResults args) {
-  String sdkPath = args[sdkPathOption] ?? getSdkPath();
-
-  return DartSdkManager(sdkPath);
-}
-
 /// Add the standard flags and options to the given [parser]. The standard flags
 /// are those that are typically used to control the way in which the code is
 /// analyzed.
diff --git a/pkg/analyzer/lib/src/context/packages.dart b/pkg/analyzer/lib/src/context/packages.dart
index 5ef1a56..087680f 100644
--- a/pkg/analyzer/lib/src/context/packages.dart
+++ b/pkg/analyzer/lib/src/context/packages.dart
@@ -6,8 +6,8 @@
 import 'package:analyzer/src/context/package_config_json.dart';
 import 'package:analyzer/src/util/uri.dart';
 import 'package:meta/meta.dart';
-// ignore: deprecated_member_use
-import 'package:package_config/packages_file.dart' as dot_packages;
+import 'package:package_config/src/packages_file.dart'
+    as package_config_packages_file;
 import 'package:pub_semver/pub_semver.dart';
 
 /// Find [Packages] starting from the given [start] resource.
@@ -45,18 +45,24 @@
 Packages parseDotPackagesFile(ResourceProvider provider, File file) {
   var uri = file.toUri();
   var content = file.readAsBytesSync();
-  var uriMap = dot_packages.parse(content, uri);
+  // TODO(srawlins): Replacing these two imports with public imports currently
+  // requires a sweeping breaking change, from synchronous code to asynchronous,
+  // including in our public APIs. When synchronous public APIs become
+  // available, use those.
+  // See https://github.com/dart-lang/package_config/issues/95.
+  var packageConfig = package_config_packages_file.parse(
+      content, uri, (Object error) => throw error);
 
   var map = <String, Package>{};
-  for (var name in uriMap.keys) {
-    var libUri = uriMap[name];
+  for (var package in packageConfig.packages) {
+    var libUri = package.packageUriRoot;
     var libPath = fileUriToNormalizedPath(
       provider.pathContext,
       libUri,
     );
     var libFolder = provider.getFolder(libPath);
-    map[name] = Package(
-      name: name,
+    map[package.name] = Package(
+      name: package.name,
       rootFolder: libFolder,
       libFolder: libFolder,
       languageVersion: null,
diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
index 74a6b93..1314ccf 100644
--- a/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
@@ -121,8 +121,9 @@
       }
     }
 
-    var importPrefixes = List<String>(importPrefixCount);
-    var importPrefixedReferencedNames = List<List<String>>(importPrefixCount);
+    var importPrefixes = List<String>.filled(importPrefixCount, null);
+    var importPrefixedReferencedNames =
+        List<List<String>>.filled(importPrefixCount, null);
     var importIndex = 0;
     for (var i = 0; i < _importPrefixedReferences.length; i++) {
       var import = _importPrefixedReferences[i];
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 57c4895..995281e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -85,7 +85,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 113;
+  static const int DATA_VERSION = 116;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
index bf11fc9..560bd68 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:typed_data';
+
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/dart/analysis/experiments_impl.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
@@ -42,11 +44,11 @@
   static final Version testingSdkLanguageVersion = Version.parse('2.10.0');
 
   /// The latest known language version.
-  static final Version latestSdkLanguageVersion = Version.parse('2.10.0');
+  static final Version latestSdkLanguageVersion = Version.parse('2.12.0');
 
   static final FeatureSet latestWithNullSafety = ExperimentStatus.fromStrings2(
     sdkLanguageVersion: latestSdkLanguageVersion,
-    flags: [EnableString.non_nullable],
+    flags: [],
   );
 
   /// A map containing information about all known experimental flags.
@@ -92,14 +94,36 @@
     );
   }
 
-  factory ExperimentStatus.fromStorage(List<int> encoded) {
-    var allFlags = encoded.skip(2).map((e) => e != 0).toList();
-    var featureCount = allFlags.length ~/ 3;
+  factory ExperimentStatus.fromStorage(Uint8List encoded) {
+    var byteIndex = 0;
+
+    int getByte() {
+      return encoded[byteIndex++];
+    }
+
+    List<bool> getBoolList(int length) {
+      var result = List<bool>.filled(length, false);
+      var byteValue = 0;
+      var bitIndex = 0;
+      for (var i = 0; i < length; i++) {
+        if (bitIndex == 0) {
+          byteValue = getByte();
+        }
+        if ((byteValue & (1 << bitIndex)) != 0) {
+          result[i] = true;
+        }
+        bitIndex = (bitIndex + 1) % 8;
+      }
+      return result;
+    }
+
+    var sdkLanguageVersion = Version(getByte(), getByte(), 0);
+    var featureCount = getByte();
     return ExperimentStatus._(
-      Version(encoded[0], encoded[1], 0),
-      allFlags.sublist(0, featureCount),
-      allFlags.sublist(featureCount, featureCount * 2),
-      allFlags.sublist(featureCount * 2, featureCount * 3),
+      sdkLanguageVersion,
+      getBoolList(featureCount),
+      getBoolList(featureCount),
+      getBoolList(featureCount),
     );
   }
 
@@ -210,14 +234,43 @@
   }
 
   /// Encode into the format suitable for [ExperimentStatus.fromStorage].
-  List<int> toStorage() {
-    return [
-      _sdkLanguageVersion.major,
-      _sdkLanguageVersion.minor,
-      ..._explicitEnabledFlags.map((e) => e ? 1 : 0),
-      ..._explicitDisabledFlags.map((e) => e ? 1 : 0),
-      ..._flags.map((e) => e ? 1 : 0),
-    ];
+  Uint8List toStorage() {
+    var result = Uint8List(16);
+    var resultIndex = 0;
+
+    void addByte(int value) {
+      assert(value >= 0 && value < 256);
+      result[resultIndex++] = value;
+    }
+
+    addByte(_sdkLanguageVersion.major);
+    addByte(_sdkLanguageVersion.minor);
+
+    void addBoolList(List<bool> values) {
+      var byteValue = 0;
+      var bitIndex = 0;
+      for (var value in values) {
+        if (value) {
+          byteValue |= 1 << bitIndex;
+        }
+        bitIndex++;
+        if (bitIndex == 8) {
+          addByte(byteValue);
+          byteValue = 0;
+          bitIndex = 0;
+        }
+      }
+      if (bitIndex != 0) {
+        addByte(byteValue);
+      }
+    }
+
+    addByte(_flags.length);
+    addBoolList(_explicitEnabledFlags);
+    addBoolList(_explicitDisabledFlags);
+    addBoolList(_flags);
+
+    return result.sublist(0, resultIndex);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
index 32b5d0f..771dfe8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -53,6 +53,12 @@
   }
 
   /// Return the [FeatureSet] for the package that contains the file.
+  ///
+  /// Note, that [getLanguageVersion] returns the default language version
+  /// for libraries in the package, but this method does not restrict the
+  /// [FeatureSet] of this version. The reason is that we allow libraries to
+  /// "upgrade" to higher version than the default package language version,
+  /// and want this to preserve experimental features.
   FeatureSet getFeatureSet(String path, Uri uri) {
     if (uri.isScheme('dart')) {
       var pathSegments = uri.pathSegments;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 00d6c6f..a37f6a7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -35,7 +35,7 @@
 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/summary2/informative_data.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
@@ -43,6 +43,7 @@
 import 'package:pub_semver/pub_semver.dart';
 
 var counterFileStateRefresh = 0;
+var counterUnlinkedBytes = 0;
 var counterUnlinkedLinkedBytes = 0;
 int fileObjectId = 0;
 var timerFileStateRefresh = Stopwatch();
@@ -125,7 +126,9 @@
   Set<String> _definedClassMemberNames;
   Set<String> _definedTopLevelNames;
   Set<String> _referencedNames;
+  List<int> _unlinkedSignature;
   String _unlinkedKey;
+  String _astKey;
   AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
   List<int> _apiSignature;
 
@@ -282,7 +285,7 @@
   LibraryCycle get libraryCycle {
     if (isPart) {
       var library = this.library;
-      if (library != null) {
+      if (library != null && !identical(library, this)) {
         return library.libraryCycle;
       }
     }
@@ -356,6 +359,9 @@
   /// The [UnlinkedUnit2] of the file.
   UnlinkedUnit2 get unlinked2 => _unlinked2;
 
+  /// The MD5 signature based on the content, feature sets, language version.
+  List<int> get unlinkedSignature => _unlinkedSignature;
+
   /// Return the [uri] string.
   String get uriStr => uri.toString();
 
@@ -364,6 +370,16 @@
     return other is FileState && other.uri == uri;
   }
 
+  Uint8List getAstBytes({CompilationUnit unit}) {
+    var bytes = _fsState._byteStore.get(_astKey);
+    if (bytes == null) {
+      unit ??= parse();
+      bytes = writeUnitToBytes(unit: unit);
+      _fsState._byteStore.put(_astKey, bytes);
+    }
+    return bytes;
+  }
+
   void internal_setLibraryCycle(LibraryCycle cycle, String signature) {
     if (cycle == null) {
       _libraryCycle = null;
@@ -414,7 +430,6 @@
     }
 
     // Prepare the unlinked bundle key.
-    List<int> contentSignature;
     {
       var signature = ApiSignature();
       signature.addUint32List(_fsState._saltForUnlinked);
@@ -422,8 +437,11 @@
       signature.addLanguageVersion(packageLanguageVersion);
       signature.addString(_contentHash);
       signature.addBool(_exists);
-      contentSignature = signature.toByteList();
-      _unlinkedKey = '${hex.encode(contentSignature)}.unlinked2';
+      _unlinkedSignature = signature.toByteList();
+      var signatureHex = hex.encode(_unlinkedSignature);
+      _unlinkedKey = '$signatureHex.unlinked2';
+      // TODO(scheglov) Use the path as the key, and store the signature.
+      _astKey = '$signatureHex.ast';
     }
 
     // Prepare bytes of the unlinked bundle - existing or new.
@@ -445,6 +463,8 @@
             subtypedNames: subtypedNames,
           ).toBuffer();
           _fsState._byteStore.put(_unlinkedKey, bytes);
+          counterUnlinkedBytes += bytes.length;
+          counterUnlinkedLinkedBytes += bytes.length;
         });
       }
     }
@@ -671,7 +691,6 @@
         ),
       );
     }
-    var informativeData = createInformativeData(unit);
     return UnlinkedUnit2Builder(
       apiSignature: computeUnlinkedApiSignature(unit),
       exports: exports,
@@ -680,7 +699,6 @@
       hasLibraryDirective: hasLibraryDirective,
       hasPartOfDirective: hasPartOfDirective,
       lineStarts: unit.lineInfo.lineStarts,
-      informativeData: informativeData,
     );
   }
 
@@ -820,6 +838,7 @@
   FileSystemStateTestView get test => _testView;
 
   /// Return the [FileState] instance that correspond to an unresolved URI.
+  /// TODO(scheglov) Remove it.
   FileState get unresolvedFile {
     if (_unresolvedFile == null) {
       var featureSet = FeatureSet.latestLanguageVersion();
@@ -1083,21 +1102,26 @@
   _FileContent get(String path, bool allowCached) {
     var file = allowCached ? _pathToFile[path] : null;
     if (file == null) {
+      List<int> contentBytes;
       String content;
       bool exists;
       try {
         if (_contentOverlay != null) {
           content = _contentOverlay[path];
         }
-        content ??= _resourceProvider.getFile(path).readAsStringSync();
+        if (content != null) {
+          contentBytes = utf8.encode(content);
+        } else {
+          contentBytes = _resourceProvider.getFile(path).readAsBytesSync();
+          content = utf8.decode(contentBytes);
+        }
         exists = true;
       } catch (_) {
+        contentBytes = Uint8List(0);
         content = '';
         exists = false;
       }
 
-      List<int> contentBytes = utf8.encode(content);
-
       List<int> contentHashBytes = md5.convert(contentBytes).bytes;
       String contentHash = hex.encode(contentHashBytes);
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 1402523..4d2ff12 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:typed_data';
+
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/element/element.dart'
     show CompilationUnitElement, LibraryElement;
@@ -16,17 +18,16 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptions;
 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/summary2/bundle_reader.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';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:meta/meta.dart';
 
 var counterLinkedLibraries = 0;
 var counterLoadedLibraries = 0;
-var timerBundleToBytes = Stopwatch();
+var timerBundleToBytes = Stopwatch(); // TODO(scheglov) use
 var timerInputLibraries = Stopwatch();
 var timerLinking = Stopwatch();
 var timerLoad2 = Stopwatch();
@@ -100,8 +101,6 @@
   /// Load data required to access elements of the given [targetLibrary].
   void load2(FileState targetLibrary) {
     timerLoad2.start();
-    var inputBundles = <LinkedNodeBundle>[];
-
     var librariesTotal = 0;
     var librariesLoaded = 0;
     var librariesLinked = 0;
@@ -119,14 +118,27 @@
 
       librariesTotal += cycle.libraries.length;
 
+      if (cycle.isUnresolvedFile) {
+        return;
+      }
+
       cycle.directDependencies.forEach(
         (e) => loadBundle(e, '$debugPrefix  '),
       );
 
-      var key = cycle.transitiveSignature + '.linked_bundle';
-      var bytes = byteStore.get(key);
+      var uriToLibrary_uriToUnitAstBytes = <String, Map<String, Uint8List>>{};
+      for (var library in cycle.libraries) {
+        var uriToUnitAstBytes = <String, Uint8List>{};
+        uriToLibrary_uriToUnitAstBytes[library.uriStr] = uriToUnitAstBytes;
+        for (var file in library.libraryFiles) {
+          uriToUnitAstBytes[file.uriStr] = file.getAstBytes();
+        }
+      }
 
-      if (bytes == null) {
+      var resolutionKey = cycle.transitiveSignature + '.linked_bundle';
+      var resolutionBytes = byteStore.get(resolutionKey);
+
+      if (resolutionBytes == null) {
         librariesLinkedTimer.start();
 
         testView.linkedCycles.add(
@@ -212,49 +224,33 @@
         link2.LinkResult linkResult;
         try {
           timerLinking.start();
-          linkResult = link2.link(elementFactory, inputLibraries);
+          linkResult = link2.link(elementFactory, inputLibraries, true);
           librariesLinked += cycle.libraries.length;
-          counterLinkedLibraries += linkResult.bundle.libraries.length;
+          counterLinkedLibraries += inputLibraries.length;
           timerLinking.stop();
         } catch (exception, stackTrace) {
           _throwLibraryCycleLinkException(cycle, exception, stackTrace);
         }
 
-        timerBundleToBytes.start();
-        bytes = linkResult.bundle.toBuffer();
-        timerBundleToBytes.stop();
-
-        byteStore.put(key, bytes);
-        bytesPut += bytes.length;
-        counterUnlinkedLinkedBytes += bytes.length;
+        resolutionBytes = linkResult.resolutionBytes;
+        byteStore.put(resolutionKey, resolutionBytes);
+        bytesPut += resolutionBytes.length;
+        counterUnlinkedLinkedBytes += resolutionBytes.length;
 
         librariesLinkedTimer.stop();
       } else {
         // TODO(scheglov) Take / clear parsed units in files.
-        bytesGet += bytes.length;
+        bytesGet += resolutionBytes.length;
         librariesLoaded += cycle.libraries.length;
       }
 
-      var bundle = LinkedNodeBundle.fromBuffer(bytes);
-      inputBundles.add(bundle);
-      elementFactory.addBundle(
-        LinkedBundleContext(elementFactory, bundle),
+      elementFactory.addLibraries(
+        createLibraryReadersWithAstBytes(
+          elementFactory: elementFactory,
+          resolutionBytes: resolutionBytes,
+          uriToLibrary_uriToUnitAstBytes: uriToLibrary_uriToUnitAstBytes,
+        ),
       );
-      counterLoadedLibraries += bundle.libraries.length;
-
-      // Set informative data.
-      for (var libraryFile in cycle.libraries) {
-        for (var unitFile in libraryFile.libraryFiles) {
-          elementFactory.setInformativeData(
-            libraryFile.uriStr,
-            unitFile.uriStr,
-            unitFile.unlinked2.informativeData,
-          );
-        }
-      }
-
-      // We might have just linked dart:core, ensure the type provider.
-      _createElementFactoryTypeProvider();
     }
 
     logger.run('Prepare linked bundles', () {
@@ -296,7 +292,11 @@
     if (externalSummaries != null) {
       for (var bundle in externalSummaries.bundles) {
         elementFactory.addBundle(
-          LinkedBundleContext(elementFactory, bundle.bundle2),
+          BundleReader(
+            elementFactory: elementFactory,
+            astBytes: bundle.astBytes,
+            resolutionBytes: bundle.resolutionBytes,
+          ),
         );
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
index dfcfb0d..bb04579 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -51,6 +51,10 @@
 
   LibraryCycle.external() : transitiveSignature = '<external>';
 
+  bool get isUnresolvedFile {
+    return libraries.length == 1 && libraries[0].isUnresolved;
+  }
+
   /// Invalidate this cycle and any cycles that directly or indirectly use it.
   ///
   /// Practically invalidation means that we clear the library cycle in all the
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
index f916888..6968796 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -28,15 +28,11 @@
     signature.addInt(node.members.length);
     for (var member in node.members) {
       if (member is ConstructorDeclaration) {
-        var lastInitializer = member.constKeyword != null &&
-                member.initializers != null &&
-                member.initializers.isNotEmpty
-            ? member.initializers.last
-            : null;
-        addTokens(
-          member.beginToken,
-          (lastInitializer ?? member.parameters ?? member.name).endToken,
-        );
+        addTokens(member.beginToken, member.parameters.endToken);
+        if (member.constKeyword != null) {
+          addNodeList(member.initializers);
+        }
+        addNode(member.redirectedConstructor);
       } else if (member is FieldDeclaration) {
         var variableList = member.fields;
         addVariables(
@@ -65,7 +61,15 @@
   }
 
   void addNode(AstNode node) {
-    addTokens(node.beginToken, node.endToken);
+    if (node != null) {
+      addTokens(node.beginToken, node.endToken);
+    }
+  }
+
+  void addNodeList(List<AstNode> nodes) {
+    for (var node in nodes) {
+      addNode(node);
+    }
   }
 
   void addToken(Token token) {
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 428ee8a..59fd5c6 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -19,9 +19,9 @@
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
 
 /// Two or more string literals that are implicitly concatenated because of
 /// being adjacent (separated only by whitespace).
@@ -725,6 +725,18 @@
       identical(child, _leftHandSide);
 }
 
+abstract class AstLinkedContext {
+  List<ClassMember> get classMembers;
+  int get codeLength;
+  int get codeOffset;
+  bool get isClassWithConstConstructor;
+  List<Directive> get unitDirectives;
+  void applyResolution(LinkedUnitContext unitContext);
+  int getVariableDeclarationCodeLength(VariableDeclaration node);
+  int getVariableDeclarationCodeOffset(VariableDeclaration node);
+  void readDocumentationComment();
+}
+
 /// A node in the AST structure for a Dart program.
 abstract class AstNodeImpl implements AstNode {
   /// The parent of the node, or `null` if the node is the root of an AST
@@ -1012,13 +1024,15 @@
   Token get endToken => _block.endToken;
 
   @override
-  bool get isAsynchronous => keyword != null && keyword.lexeme == Parser.ASYNC;
+  bool get isAsynchronous =>
+      keyword != null && keyword.lexeme == Keyword.ASYNC.lexeme;
 
   @override
   bool get isGenerator => star != null;
 
   @override
-  bool get isSynchronous => keyword == null || keyword.lexeme != Parser.ASYNC;
+  bool get isSynchronous =>
+      keyword == null || keyword.lexeme != Keyword.ASYNC.lexeme;
 
   @override
   E accept<E>(AstVisitor<E> visitor) => visitor.visitBlockFunctionBody(this);
@@ -1417,6 +1431,7 @@
 ///        [ImplementsClause]?
 ///        '{' [ClassMember]* '}'
 class ClassDeclarationImpl extends ClassOrMixinDeclarationImpl
+    with HasAstLinkedContext
     implements ClassDeclaration {
   /// The 'abstract' keyword, or `null` if the keyword was absent.
   @override
@@ -1665,7 +1680,9 @@
 ///
 ///    mixinApplication ::=
 ///        [TypeName] [WithClause] [ImplementsClause]? ';'
-class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias {
+class ClassTypeAliasImpl extends TypeAliasImpl
+    with HasAstLinkedContext
+    implements ClassTypeAlias {
   /// The type parameters for the class, or `null` if the class does not have
   /// any type parameters.
   TypeParameterListImpl _typeParameters;
@@ -2018,6 +2035,11 @@
   @override
   final FeatureSet featureSet;
 
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   /// Initialize a newly created compilation unit to have the given directives
   /// and declarations. The [scriptTag] can be `null` if there is no script tag
   /// in the compilation unit. The list of [directives] can be `null` if there
@@ -2369,6 +2391,7 @@
 ///    initializerList ::=
 ///        ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
 class ConstructorDeclarationImpl extends ClassMemberImpl
+    with HasAstLinkedContext
     implements ConstructorDeclaration {
   /// The token for the 'external' keyword, or `null` if the constructor is not
   /// external.
@@ -3245,6 +3268,7 @@
 
 /// The declaration of an enum constant.
 class EnumConstantDeclarationImpl extends DeclarationImpl
+    with HasAstLinkedContext
     implements EnumConstantDeclaration {
   /// The name of the constant.
   SimpleIdentifierImpl _name;
@@ -3297,6 +3321,7 @@
 ///        metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier]
 ///        (',' [SimpleIdentifier])* (',')? '}'
 class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements EnumDeclaration {
   /// The 'enum' keyword.
   @override
@@ -3375,6 +3400,7 @@
 ///    exportDirective ::=
 ///        [Annotation] 'export' [StringLiteral] [Combinator]* ';'
 class ExportDirectiveImpl extends NamespaceDirectiveImpl
+    with HasAstLinkedContext
     implements ExportDirective {
   /// Initialize a newly created export directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
@@ -3707,6 +3733,7 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtensionDeclarationImpl extends CompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements ExtensionDeclaration {
   @override
   Token extensionKeyword;
@@ -3910,7 +3937,9 @@
 ///
 ///    fieldDeclaration ::=
 ///        'static'? [VariableDeclarationList] ';'
-class FieldDeclarationImpl extends ClassMemberImpl implements FieldDeclaration {
+class FieldDeclarationImpl extends ClassMemberImpl
+    with HasAstLinkedContext
+    implements FieldDeclaration {
   @override
   Token abstractKeyword;
 
@@ -4304,6 +4333,11 @@
 ///      | [DefaultFormalParameter]
 abstract class FormalParameterImpl extends AstNodeImpl
     implements FormalParameter {
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   @override
   ParameterElement get declaredElement {
     SimpleIdentifier identifier = this.identifier;
@@ -4441,7 +4475,7 @@
   @override
   List<ParameterElement> get parameterElements {
     int count = _parameters.length;
-    List<ParameterElement> types = List<ParameterElement>(count);
+    List<ParameterElement> types = List<ParameterElement>.filled(count, null);
     for (int i = 0; i < count; i++) {
       types[i] = _parameters[i].declaredElement;
     }
@@ -4739,6 +4773,7 @@
 ///    functionSignature ::=
 ///        [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
 class FunctionDeclarationImpl extends NamedCompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements FunctionDeclaration {
   /// The token representing the 'external' keyword, or `null` if this is not an
   /// external function.
@@ -4932,7 +4967,7 @@
 
   @override
   Iterable<SyntacticEntity> get childEntities =>
-      ChildEntities()..add(_parameters)..add(_body);
+      ChildEntities()..add(_typeParameters)..add(_parameters)..add(_body);
 
   @override
   Token get endToken {
@@ -5048,7 +5083,9 @@
 ///
 ///    functionPrefix ::=
 ///        [TypeName]? [SimpleIdentifier]
-class FunctionTypeAliasImpl extends TypeAliasImpl implements FunctionTypeAlias {
+class FunctionTypeAliasImpl extends TypeAliasImpl
+    with HasAstLinkedContext
+    implements FunctionTypeAlias {
   /// The name of the return type of the function type being defined, or `null`
   /// if no return type was given.
   TypeAnnotationImpl _returnType;
@@ -5362,7 +5399,12 @@
 ///    functionTypeAlias ::=
 ///        metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? =
 ///        [FunctionType] ';'
-class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias {
+class GenericTypeAliasImpl extends TypeAliasImpl
+    with HasAstLinkedContext
+    implements GenericTypeAlias {
+  /// The type being defined by the alias.
+  TypeAnnotationImpl _type;
+
   /// The type parameters for the function type, or `null` if the function
   /// type does not have any type parameters.
   TypeParameterListImpl _typeParameters;
@@ -5370,9 +5412,6 @@
   @override
   Token equals;
 
-  /// The type of function being defined by the alias.
-  GenericFunctionTypeImpl _functionType;
-
   /// Returns a newly created generic type alias. Either or both of the
   /// [comment] and [metadata] can be `null` if the variable list does not have
   /// the corresponding attribute. The [typeParameters] can be `null` if there
@@ -5384,11 +5423,11 @@
       SimpleIdentifierImpl name,
       TypeParameterListImpl typeParameters,
       this.equals,
-      GenericFunctionTypeImpl functionType,
+      TypeAnnotationImpl type,
       Token semicolon)
       : super(comment, metadata, typedefToken, name, semicolon) {
     _typeParameters = _becomeParentOf(typeParameters);
-    _functionType = _becomeParentOf(functionType);
+    _type = _becomeParentOf(type);
   }
 
   @override
@@ -5398,17 +5437,33 @@
     ..add(name)
     ..add(_typeParameters)
     ..add(equals)
-    ..add(_functionType);
+    ..add(_type);
 
   @override
   Element get declaredElement => name.staticElement;
 
+  /// The type of function being defined by the alias.
+  ///
+  /// If the non-function type aliases feature is enabled, a type alias may have
+  /// a [_type] which is not a [GenericFunctionTypeImpl].  In that case `null`
+  /// is returned.
   @override
-  GenericFunctionType get functionType => _functionType;
+  GenericFunctionType get functionType {
+    var type = _type;
+    return type is GenericFunctionTypeImpl ? type : null;
+  }
 
   @override
   set functionType(GenericFunctionType functionType) {
-    _functionType = _becomeParentOf(functionType as GenericFunctionTypeImpl);
+    _type = _becomeParentOf(functionType as TypeAnnotationImpl);
+  }
+
+  @override
+  TypeAnnotation get type => _type;
+
+  /// Set the type being defined by the alias to the given [TypeAnnotation].
+  set type(TypeAnnotation typeAnnotation) {
+    _type = _becomeParentOf(typeAnnotation as TypeAnnotationImpl);
   }
 
   @override
@@ -5429,10 +5484,14 @@
     super.visitChildren(visitor);
     name?.accept(visitor);
     _typeParameters?.accept(visitor);
-    _functionType?.accept(visitor);
+    _type?.accept(visitor);
   }
 }
 
+mixin HasAstLinkedContext {
+  AstLinkedContext linkedContext;
+}
+
 /// A combinator that restricts the names being imported to those that are not
 /// in a given list.
 ///
@@ -5702,6 +5761,7 @@
 ///      | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier
 //         [Combinator]* ';'
 class ImportDirectiveImpl extends NamespaceDirectiveImpl
+    with HasAstLinkedContext
     implements ImportDirective {
   /// The token representing the 'deferred' keyword, or `null` if the imported
   /// is not deferred.
@@ -6526,6 +6586,11 @@
   @override
   Token semicolon;
 
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   /// Initialize a newly created library directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
   /// corresponding attribute.
@@ -6798,6 +6863,7 @@
 ///        [SimpleIdentifier]
 ///      | 'operator' [SimpleIdentifier]
 class MethodDeclarationImpl extends ClassMemberImpl
+    with HasAstLinkedContext
     implements MethodDeclaration {
   /// The token for the 'external' keyword, or `null` if the constructor is not
   /// external.
@@ -7137,6 +7203,7 @@
 ///        metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
 ///        [RequiresClause]? [ImplementsClause]? '{' [ClassMember]* '}'
 class MixinDeclarationImpl extends ClassOrMixinDeclarationImpl
+    with HasAstLinkedContext
     implements MixinDeclaration {
   @override
   Token mixinKeyword;
@@ -9790,6 +9857,7 @@
 ///        ('final' | 'const') type? staticFinalDeclarationList ';'
 ///      | variableDeclaration ';'
 class TopLevelVariableDeclarationImpl extends CompilationUnitMemberImpl
+    with HasAstLinkedContext
     implements TopLevelVariableDeclaration {
   /// The top-level variables being declared.
   VariableDeclarationListImpl _variableList;
@@ -10171,6 +10239,11 @@
   /// explicit upper bound.
   TypeAnnotationImpl _bound;
 
+  /// Data that is read during loading this node from summary, but is not
+  /// fully applied yet. For example in many cases we don't need the
+  /// documentation comment, and it is expensive to decode strings.
+  Object summaryData;
+
   /// Initialize a newly created type parameter. Either or both of the [comment]
   /// and [metadata] can be `null` if the parameter does not have the
   /// corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
@@ -10395,6 +10468,12 @@
   /// `null` if the initial value was not specified.
   ExpressionImpl _initializer;
 
+  /// When this node is read as a part of summaries, we usually don't want
+  /// to read the [initializer], but we need to know if there is one in
+  /// the code. So, this flag might be set to `true` even though
+  /// [initializer] is `null`.
+  bool hasInitializer = false;
+
   /// Initialize a newly created variable declaration. The [equals] and
   /// [initializer] can be `null` if there is no initializer.
   VariableDeclarationImpl(
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 8e1fd6a..f1a91b6 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -575,10 +575,10 @@
           SimpleIdentifier name,
           TypeParameterList typeParameters,
           Token equals,
-          GenericFunctionType functionType,
+          TypeAnnotation type,
           Token semicolon) =>
       GenericTypeAliasImpl(comment, metadata, typedefKeyword, name,
-          typeParameters, equals, functionType, semicolon);
+          typeParameters, equals, type, semicolon);
 
   @override
   HideCombinator hideCombinator(
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index 5f5e191..38736b4 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -668,7 +668,7 @@
     safelyVisitNode(node.name);
     safelyVisitNode(node.typeParameters);
     sink.write(" = ");
-    safelyVisitNode(node.functionType);
+    safelyVisitNode(node.type);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 3648e1e..6e0c1a8 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -603,7 +603,7 @@
           cloneNode(node.name),
           cloneNode(node.typeParameters),
           cloneToken(node.equals),
-          cloneNode(node.functionType),
+          cloneNode(node.type),
           cloneToken(node.semicolon));
 
   @override
@@ -1745,7 +1745,7 @@
         isEqualNodes(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualTokens(node.equals, other.equals) &&
-        isEqualNodes(node.functionType, other.functionType);
+        isEqualNodes(node.type, other.type);
   }
 
   @override
@@ -3298,14 +3298,15 @@
 
   @override
   bool visitGenericTypeAlias(GenericTypeAlias node) {
+    var nodeImpl = node as GenericTypeAliasImpl;
     if (identical(node.name, _oldNode)) {
       node.name = _newNode as SimpleIdentifier;
       return true;
     } else if (identical(node.typeParameters, _oldNode)) {
-      node.typeParameters = _newNode as TypeParameterList;
+      nodeImpl.typeParameters = _newNode as TypeParameterList;
       return true;
-    } else if (identical(node.functionType, _oldNode)) {
-      node.functionType = _newNode as GenericFunctionType;
+    } else if (identical(node.type, _oldNode)) {
+      nodeImpl.type = _newNode as TypeAnnotation;
       return true;
     } else if (_replaceInList(node.metadata)) {
       return true;
@@ -4664,7 +4665,7 @@
         _isEqualNodes(node.name, toNode.name),
         _isEqualNodes(node.typeParameters, toNode.typeParameters),
         _isEqualTokens(node.equals, toNode.equals),
-        _isEqualNodes(node.functionType, toNode.functionType),
+        _isEqualNodes(node.type, toNode.type),
         _isEqualTokens(node.semicolon, toNode.semicolon))) {
       return true;
     }
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 33034f0..6c1f831 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -406,7 +406,7 @@
     }
 
     int argumentCount = arguments.length;
-    var argumentValues = List<DartObjectImpl>(argumentCount);
+    var argumentValues = List<DartObjectImpl>.filled(argumentCount, null);
     Map<String, NamedExpression> namedNodes;
     Map<String, DartObjectImpl> namedValues;
     for (int i = 0; i < argumentCount; i++) {
diff --git a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
index 6c7dd55..20affb1 100644
--- a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
@@ -126,14 +126,6 @@
     _writeNullability(type.nullabilitySuffix);
   }
 
-  void writeFunctionTypeAliasElement(FunctionTypeAliasElementImpl element) {
-    _write('typedef ');
-    _write(element.displayName);
-    _writeTypeParameters(element.typeParameters);
-    _write(' = ');
-    element.function?.appendTo(this);
-  }
-
   void writeGenericFunctionTypeElement(GenericFunctionTypeElementImpl element) {
     _writeType(element.returnType);
     _write(' Function');
@@ -170,6 +162,20 @@
     _write(element.displayName);
   }
 
+  void writeTypeAliasElement(TypeAliasElementImpl element) {
+    _write('typedef ');
+    _write(element.displayName);
+    _writeTypeParameters(element.typeParameters);
+    _write(' = ');
+
+    var aliasedElement = element.aliasedElement;
+    if (aliasedElement != null) {
+      aliasedElement.appendTo(this);
+    } else {
+      _writeType(element.aliasedType);
+    }
+  }
+
   void writeTypeParameter(TypeParameterElement element) {
     if (element is TypeParameterElementImpl) {
       var variance = element.variance;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 74cdd53..1f98644 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -41,9 +41,9 @@
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:analyzer/src/util/comment.dart';
 import 'package:meta/meta.dart';
 
@@ -138,28 +138,6 @@
   T accept<T>(ElementVisitor<T> visitor) => visitor.visitClassElement(this);
 
   @override
-  ElementImpl getChild(String identifier) {
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (PropertyAccessorElement accessor in accessors) {
-      PropertyAccessorElementImpl accessorImpl = accessor;
-      if (accessorImpl.identifier == identifier) {
-        return accessorImpl;
-      }
-    }
-    for (FieldElement field in fields) {
-      FieldElementImpl fieldImpl = field;
-      if (fieldImpl.identifier == identifier) {
-        return fieldImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
   FieldElement getField(String name) {
     for (FieldElement fieldElement in fields) {
       if (name == fieldElement.name) {
@@ -464,11 +442,14 @@
 
   /// A flag indicating whether the types associated with the instance members
   /// of this class have been inferred.
-  bool _hasBeenInferred = false;
+  bool hasBeenInferred = false;
 
   /// This callback is set during mixins inference to handle reentrant calls.
   List<InterfaceType> Function(ClassElementImpl) linkedMixinInferenceCallback;
 
+  /// TODO(scheglov) implement as modifier
+  bool _isSimplyBounded = true;
+
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
   ClassElementImpl(String name, int offset) : super(name, offset);
@@ -481,6 +462,7 @@
     } else if (linkedNode is ClassTypeAlias) {
       linkedNode.name.staticElement = this;
     }
+    hasBeenInferred = !linkedContext.isLinking;
   }
 
   @override
@@ -533,6 +515,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@constructor');
       _constructors = context.getConstructors(linkedNode).map((node) {
@@ -594,6 +577,7 @@
 
     if (linkedNode != null) {
       if (linkedNode is ClassOrMixinDeclaration) {
+        linkedContext.applyResolution(linkedNode);
         _createPropertiesAndAccessors();
         assert(_fields != null);
         return _fields;
@@ -605,20 +589,6 @@
     return _fields ?? const <FieldElement>[];
   }
 
-  bool get hasBeenInferred {
-    if (linkedNode != null) {
-      return linkedContext.hasOverrideInferenceDone(linkedNode);
-    }
-    return _hasBeenInferred;
-  }
-
-  set hasBeenInferred(bool hasBeenInferred) {
-    if (linkedNode != null) {
-      return linkedContext.setOverrideInferenceDone(linkedNode);
-    }
-    _hasBeenInferred = hasBeenInferred;
-  }
-
   @override
   bool get hasNonFinalField {
     List<ClassElement> classesToVisit = <ClassElement>[];
@@ -694,6 +664,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var implementsClause = context.getImplementsClause(linkedNode);
       if (implementsClause != null) {
@@ -738,12 +709,18 @@
     setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
   }
 
+  /// TODO(scheglov) implement as modifier
   @override
   bool get isSimplyBounded {
     if (linkedNode != null) {
-      return linkedContext.isSimplyBounded(linkedNode);
+      linkedContext.applyResolution(linkedNode);
     }
-    return super.isSimplyBounded;
+    return _isSimplyBounded;
+  }
+
+  /// TODO(scheglov) implement as modifier
+  set isSimplyBounded(bool isSimplyBounded) {
+    _isSimplyBounded = isSimplyBounded;
   }
 
   @override
@@ -769,6 +746,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@method');
       return _methods = context
@@ -805,6 +783,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var withClause = context.getWithClause(linkedNode);
       if (withClause != null) {
@@ -854,6 +833,7 @@
     }
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var type = linkedContext.getSuperclass(linkedNode)?.type;
       if (_isInterfaceTypeClass(type)) {
         return _supertype = type;
@@ -897,38 +877,6 @@
   }
 
   @override
-  ElementImpl getChild(String identifier) {
-    ElementImpl child = super.getChild(identifier);
-    if (child != null) {
-      return child;
-    }
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (ConstructorElement constructor in constructors) {
-      ConstructorElementImpl constructorImpl = constructor;
-      if (constructorImpl.identifier == identifier) {
-        return constructorImpl;
-      }
-    }
-    for (MethodElement method in methods) {
-      MethodElementImpl methodImpl = method;
-      if (methodImpl.identifier == identifier) {
-        return methodImpl;
-      }
-    }
-    for (TypeParameterElement typeParameter in typeParameters) {
-      TypeParameterElementImpl typeParameterImpl = typeParameter;
-      if (typeParameterImpl.identifier == identifier) {
-        return typeParameterImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
   ConstructorElement getNamedConstructor(String name) =>
       getNamedConstructorFromList(name, constructors);
 
@@ -1017,7 +965,7 @@
       int count = superParameters.length;
       if (count > 0) {
         List<ParameterElement> implicitParameters =
-            List<ParameterElement>(count);
+            List<ParameterElement>.filled(count, null);
         for (int i = 0; i < count; i++) {
           ParameterElement superParameter = superParameters[i];
           ParameterElementImpl implicitParameter;
@@ -1055,11 +1003,9 @@
     var fields = context.getFields(linkedNode);
     for (var field in fields) {
       var name = field.name.name;
-      var fieldElement = FieldElementImpl.forLinkedNodeFactory(
-        this,
-        reference.getChild('@field').getChild(name),
-        field,
-      );
+      var fieldElement = field.declaredElement as FieldElementImpl;
+      fieldElement ??= FieldElementImpl.forLinkedNodeFactory(
+          this, reference.getChild('@field').getChild(name), field);
       fieldList.add(fieldElement);
 
       accessorList.add(fieldElement.getter);
@@ -1079,11 +1025,10 @@
           ? reference.getChild('@getter')
           : reference.getChild('@setter');
 
-      var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-        this,
-        containerRef.getChild(name),
-        method,
-      );
+      var accessorElement =
+          method.declaredElement as PropertyAccessorElementImpl;
+      accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+          this, containerRef.getChild(name), method);
       accessorList.add(accessorElement);
 
       var fieldRef = reference.getChild('@field').getChild(name);
@@ -1219,7 +1164,11 @@
 
   /// A list containing all of the function type aliases contained in this
   /// compilation unit.
-  List<FunctionTypeAliasElement> _typeAliases;
+  List<FunctionTypeAliasElement> _functionTypeAliases;
+
+  /// A list containing all of the type aliases contained in this compilation
+  /// unit.
+  List<TypeAliasElement> _typeAliases;
 
   /// A list containing all of the classes contained in this compilation unit.
   List<ClassElement> _types;
@@ -1324,9 +1273,13 @@
       CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@extension');
       _extensions = <ExtensionElement>[];
+      var nextUnnamedExtensionId = 0;
       for (var node in linkedNode.declarations) {
         if (node is ExtensionDeclaration) {
-          var refName = linkedContext.getExtensionRefName(node);
+          var nameIdentifier = node.name;
+          var refName = nameIdentifier != null
+              ? nameIdentifier.name
+              : 'extension-${nextUnnamedExtensionId++}';
           var reference = containerRef.getChild(refName);
           var element = node.declaredElement;
           element ??= ExtensionElementImpl.forLinkedNode(this, reference, node);
@@ -1352,9 +1305,8 @@
     if (_functions != null) return _functions;
 
     if (linkedNode != null) {
-      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@function');
-      return _functions = linkedNode.declarations
+      return _functions = linkedContext.unit_withDeclarations.declarations
           .whereType<FunctionDeclaration>()
           .where((node) => !node.isGetter && !node.isSetter)
           .map((node) {
@@ -1379,31 +1331,8 @@
 
   @override
   List<FunctionTypeAliasElement> get functionTypeAliases {
-    if (_typeAliases != null) return _typeAliases;
-
-    if (linkedNode != null) {
-      CompilationUnit linkedNode = this.linkedNode;
-      var containerRef = reference.getChild('@typeAlias');
-      _typeAliases = <FunctionTypeAliasElement>[];
-      for (var node in linkedNode.declarations) {
-        String name;
-        if (node is FunctionTypeAlias) {
-          name = node.name.name;
-        } else if (node is GenericTypeAlias) {
-          name = node.name.name;
-        } else {
-          continue;
-        }
-
-        var reference = containerRef.getChild(name);
-        var element = node.declaredElement as FunctionTypeAliasElement;
-        element ??=
-            FunctionTypeAliasElementImpl.forLinkedNode(this, reference, node);
-        _typeAliases.add(element);
-      }
-    }
-
-    return _typeAliases ?? const <FunctionTypeAliasElement>[];
+    return _functionTypeAliases ??=
+        typeAliases.whereType<FunctionTypeAliasElement>().toList();
   }
 
   @override
@@ -1464,12 +1393,14 @@
 
   @override
   List<TopLevelVariableElement> get topLevelVariables {
+    if (_variables != null) return _variables;
+
     if (linkedNode != null) {
-      if (_variables != null) return _variables;
       _createPropertiesAndAccessors(this);
       assert(_variables != null);
       return _variables;
     }
+
     return _variables ?? const <TopLevelVariableElement>[];
   }
 
@@ -1482,6 +1413,34 @@
     _variables = variables;
   }
 
+  @override
+  List<TypeAliasElement> get typeAliases {
+    if (_typeAliases != null) return _typeAliases;
+
+    if (linkedNode != null) {
+      var containerRef = reference.getChild('@typeAlias');
+      _typeAliases = <TypeAliasElement>[];
+      for (var node in linkedContext.unit_withDeclarations.declarations) {
+        String name;
+        if (node is FunctionTypeAlias) {
+          name = node.name.name;
+        } else if (node is GenericTypeAlias) {
+          name = node.name.name;
+        } else {
+          continue;
+        }
+
+        var reference = containerRef.getChild(name);
+        var element = node.declaredElement as TypeAliasElement;
+        element ??=
+            TypeAliasElementImpl.forLinkedNodeFactory(this, reference, node);
+        _typeAliases.add(element);
+      }
+    }
+
+    return _typeAliases ?? const <TypeAliasElement>[];
+  }
+
   /// Set the function type aliases contained in this compilation unit to the
   /// given [typeAliases].
   set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
@@ -1499,10 +1458,9 @@
     if (_types != null) return _types;
 
     if (linkedNode != null) {
-      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@class');
       _types = <ClassElement>[];
-      for (var node in linkedNode.declarations) {
+      for (var node in linkedContext.unit_withDeclarations.declarations) {
         if (node is ClassDeclaration) {
           var name = node.name.name;
           var reference = containerRef.getChild(name);
@@ -1551,51 +1509,6 @@
   }
 
   @override
-  ElementImpl getChild(String identifier) {
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (PropertyAccessorElement accessor in accessors) {
-      PropertyAccessorElementImpl accessorImpl = accessor;
-      if (accessorImpl.identifier == identifier) {
-        return accessorImpl;
-      }
-    }
-    for (TopLevelVariableElement variable in topLevelVariables) {
-      TopLevelVariableElementImpl variableImpl = variable;
-      if (variableImpl.identifier == identifier) {
-        return variableImpl;
-      }
-    }
-    for (FunctionElement function in functions) {
-      FunctionElementImpl functionImpl = function;
-      if (functionImpl.identifier == identifier) {
-        return functionImpl;
-      }
-    }
-    for (FunctionTypeAliasElementImpl typeAlias in functionTypeAliases) {
-      if (typeAlias.identifier == identifier) {
-        return typeAlias;
-      }
-    }
-    for (ClassElement type in types) {
-      ClassElementImpl typeImpl = type;
-      if (typeImpl.name == identifier) {
-        return typeImpl;
-      }
-    }
-    for (ClassElement type in enums) {
-      EnumElementImpl typeImpl = type;
-      if (typeImpl.identifier == identifier) {
-        return typeImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
   ClassElement getEnum(String enumName) {
     for (ClassElement enumDeclaration in enums) {
       if (enumDeclaration.name == enumName) {
@@ -1647,18 +1560,20 @@
       var variableList = <TopLevelVariableElement>[];
       variableMap[unit] = variableList;
 
-      var unitNode = unit.linkedContext.unit_withDeclarations;
+      // TODO(scheglov) Bad, we want to read only functions / variables.
+      var unitNode = context.unit_withDeclarations;
       var unitDeclarations = unitNode.declarations;
 
       var variables = context.topLevelVariables(unitNode);
       for (var variable in variables) {
-        var name = variable.name.name;
-        var reference = unit.reference.getChild('@variable').getChild(name);
-        var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
-          unit,
-          reference,
-          variable,
-        );
+        var variableElement =
+            variable.declaredElement as TopLevelVariableElementImpl;
+        if (variableElement == null) {
+          var name = variable.name.name;
+          var reference = unit.reference.getChild('@variable').getChild(name);
+          variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
+              unit, reference, variable);
+        }
         variableList.add(variableElement);
 
         accessorList.add(variableElement.getter);
@@ -1678,14 +1593,13 @@
               ? unit.reference.getChild('@getter')
               : unit.reference.getChild('@setter');
 
-          var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-            unit,
-            containerRef.getChild(name),
-            node,
-          );
+          var accessorElement =
+              node.declaredElement as PropertyAccessorElementImpl;
+          accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+              unit, containerRef.getChild(name), node);
           accessorList.add(accessorElement);
 
-          var fieldRef = unit.reference.getChild('@field').getChild(name);
+          var fieldRef = unit.reference.getChild('@variable').getChild(name);
           TopLevelVariableElementImpl field = fieldRef.element;
           if (field == null) {
             field = TopLevelVariableElementImpl(name, -1);
@@ -1953,6 +1867,7 @@
     if (_constantInitializers != null) return _constantInitializers;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       return _constantInitializers = linkedContext.getConstructorInitializers(
         linkedNode,
       );
@@ -2069,6 +1984,7 @@
     if (_redirectedConstructor != null) return _redirectedConstructor;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       if (isFactory) {
         var node = context.getConstructorRedirected(linkedNode);
@@ -2203,8 +2119,8 @@
     if (_constantInitializer != null) return _constantInitializer;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      return _constantInitializer = context.readInitializer(linkedNode);
+      linkedContext.applyResolution(linkedNode);
+      return _constantInitializer = linkedContext.getInitializer(linkedNode);
     }
 
     return _constantInitializer;
@@ -2919,9 +2835,13 @@
   /// children of this element's parent.
   String get identifier => name;
 
+  bool get isNonFunctionTypeAliasesEnabled {
+    return library.featureSet.isEnabled(Feature.nonfunction_type_aliases);
+  }
+
   @override
   bool get isPrivate {
-    String name = displayName;
+    var name = this.name;
     if (name == null) {
       return true;
     }
@@ -2967,11 +2887,14 @@
 
   @override
   List<ElementAnnotation> get metadata {
+    if (_metadata != null) return _metadata;
+
     if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
+      linkedContext.applyResolution(linkedNode);
       var metadata = linkedContext.getMetadata(linkedNode);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
+
     return _metadata ?? const <ElementAnnotation>[];
   }
 
@@ -3052,10 +2975,6 @@
     }
   }
 
-  /// Return the child of this element that is uniquely identified by the given
-  /// [identifier], or `null` if there is no such child.
-  ElementImpl getChild(String identifier) => null;
-
   @override
   String getDisplayString({@required bool withNullability}) {
     var builder = ElementDisplayStringBuilder(
@@ -3145,7 +3064,7 @@
       return const <ElementAnnotation>[];
     }
 
-    var annotations = List<ElementAnnotation>(length);
+    var annotations = List<ElementAnnotation>.filled(length, null);
     for (int i = 0; i < length; i++) {
       var ast = nodeList[i];
       annotations[i] = ElementAnnotationImpl(unit)
@@ -3501,7 +3420,7 @@
 
     // Build fields for all enum constants.
     var containerRef = reference.getChild('@constant');
-    var constants = linkedContext.getEnumConstants(linkedNode);
+    var constants = (linkedNode as EnumDeclaration).constants;
     for (var i = 0; i < constants.length; ++i) {
       var constant = constants[i];
       var name = constant.name.name;
@@ -3686,6 +3605,7 @@
     if (_parameters != null) return _parameters;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@parameter');
       var formalParameters = context.getFormalParameters(linkedNode);
@@ -3705,9 +3625,6 @@
       ElementTypeProvider.current.getExecutableReturnType(this);
 
   set returnType(DartType returnType) {
-    if (linkedNode != null) {
-      linkedContext.setReturnType(linkedNode, returnType);
-    }
     _returnType = returnType;
     // We do this because of return type inference. At the moment when we
     // create a local function element we don't know yet its return type,
@@ -3724,8 +3641,8 @@
     if (_returnType != null) return _returnType;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      return _returnType = context.getReturnType(linkedNode);
+      linkedContext.applyResolution(linkedNode);
+      return _returnType;
     }
     return _returnType;
   }
@@ -3765,17 +3682,6 @@
   }
 
   @override
-  ElementImpl getChild(String identifier) {
-    for (ParameterElement parameter in parameters) {
-      ParameterElementImpl parameterImpl = parameter;
-      if (parameterImpl.identifier == identifier) {
-        return parameterImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     _safelyVisitPossibleChild(returnType, visitor);
@@ -3799,7 +3705,9 @@
 
   ExportElementImpl.forLinkedNode(
       LibraryElementImpl enclosing, ExportDirective linkedNode)
-      : super.forLinkedNode(enclosing, null, linkedNode);
+      : super.forLinkedNode(enclosing, null, linkedNode) {
+    linkedNode.element = this;
+  }
 
   @override
   List<NamespaceCombinator> get combinators {
@@ -3831,7 +3739,7 @@
     if (_exportedLibrary != null) return _exportedLibrary;
 
     if (linkedNode != null) {
-      return _exportedLibrary = linkedContext.directiveLibrary(linkedNode);
+      linkedContext.applyResolution(linkedNode);
     }
 
     return _exportedLibrary;
@@ -3947,7 +3855,7 @@
   }
 
   @override
-  String get displayName => name;
+  String get displayName => name ?? '';
 
   @override
   String get documentationComment {
@@ -3971,7 +3879,8 @@
     if (_extendedType != null) return _extendedType;
 
     if (linkedNode != null) {
-      return _extendedType = linkedContext.getExtendedType(linkedNode).type;
+      var linkedNode = this.linkedNode as ExtensionDeclaration;
+      return _extendedType = linkedNode.extendedType.type;
     }
 
     return _extendedType;
@@ -4135,11 +4044,9 @@
     var fields = context.getFields(linkedNode);
     for (var field in fields) {
       var name = field.name.name;
-      var fieldElement = FieldElementImpl.forLinkedNodeFactory(
-        this,
-        reference.getChild('@field').getChild(name),
-        field,
-      );
+      var fieldElement = field.declaredElement as FieldElementImpl;
+      fieldElement ??= FieldElementImpl.forLinkedNodeFactory(
+          this, reference.getChild('@field').getChild(name), field);
       fieldList.add(fieldElement);
 
       accessorList.add(fieldElement.getter);
@@ -4159,11 +4066,10 @@
           ? reference.getChild('@getter')
           : reference.getChild('@setter');
 
-      var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-        this,
-        containerRef.getChild(name),
-        method,
-      );
+      var accessorElement =
+          method.declaredElement as PropertyAccessorElementImpl;
+      accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+          this, containerRef.getChild(name), method);
       accessorList.add(accessorElement);
 
       var fieldRef = reference.getChild('@field').getChild(name);
@@ -4198,6 +4104,10 @@
 /// A concrete implementation of a [FieldElement].
 class FieldElementImpl extends PropertyInducingElementImpl
     implements FieldElement {
+  /// True if this field inherits from a covariant parameter. This happens
+  /// when it overrides a field in a supertype that is covariant.
+  bool inheritsCovariant = false;
+
   /// Initialize a newly created synthetic field element to have the given
   /// [name] at the given [offset].
   FieldElementImpl(String name, int offset) : super(name, offset);
@@ -4205,6 +4115,9 @@
   FieldElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
+    if (linkedNode is VariableDeclaration) {
+      linkedNode.name.staticElement = this;
+    }
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
 
@@ -4392,7 +4305,7 @@
   String get identifier {
     String identifier = super.identifier;
     Element enclosing = enclosingElement;
-    if (enclosing is ExecutableElement) {
+    if (enclosing is ExecutableElement || enclosing is VariableElement) {
       identifier += "@$nameOffset";
     }
     return identifier;
@@ -4421,209 +4334,33 @@
   T accept<T>(ElementVisitor<T> visitor) => visitor.visitFunctionElement(this);
 }
 
-/// An element that represents [FunctionTypeAlias] or [GenericTypeAlias].
-///
-/// Clients may not extend, implement or mix-in this class.
-class FunctionTypeAliasElementImpl extends ElementImpl
-    with TypeParameterizedElementMixin
+class FunctionTypeAliasElementImpl extends TypeAliasElementImpl
     implements FunctionTypeAliasElement {
-  /// The element representing the generic function type.
-  GenericFunctionTypeElementImpl _function;
-
-  /// Initialize a newly created type alias element to have the given [name].
-  FunctionTypeAliasElementImpl(String name, int offset) : super(name, offset);
-
   FunctionTypeAliasElementImpl.forLinkedNode(
-      CompilationUnitElementImpl enclosingUnit,
-      Reference reference,
-      AstNode linkedNode)
-      : super.forLinkedNode(enclosingUnit, reference, linkedNode) {
-    if (linkedNode is FunctionTypeAlias) {
-      linkedNode.name.staticElement = this;
-    } else {
-      (linkedNode as GenericTypeAlias).name.staticElement = this;
-    }
-  }
-
-  @override
-  int get codeLength {
-    if (linkedNode != null) {
-      return linkedContext.getCodeLength(linkedNode);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext.getCodeOffset(linkedNode);
-    }
-    return super.codeOffset;
-  }
-
-  @override
-  String get displayName => name;
-
-  @override
-  String get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      var comment = context.getDocumentationComment(linkedNode);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
-  CompilationUnitElement get enclosingElement =>
-      super.enclosingElement as CompilationUnitElement;
-
-  @override
-  CompilationUnitElementImpl get enclosingUnit =>
-      _enclosingElement as CompilationUnitElementImpl;
+    CompilationUnitElementImpl enclosingUnit,
+    Reference reference,
+    TypeAlias linkedNode,
+  ) : super.forLinkedNode(enclosingUnit, reference, linkedNode);
 
   @override
   GenericFunctionTypeElementImpl get function {
-    if (_function != null) return _function;
-
-    if (linkedNode != null) {
-      if (linkedNode is GenericTypeAlias) {
-        var context = enclosingUnit.linkedContext;
-        var function = context.getGeneticTypeAliasFunction(linkedNode);
-        if (function != null) {
-          var reference = context.getGenericFunctionTypeReference(function);
-          _function = reference.element;
-          encloseElement(_function);
-          return _function;
-        } else {
-          return _function = GenericFunctionTypeElementImpl.forOffset(-1)
-            ..typeParameters = const <TypeParameterElement>[]
-            ..parameters = const <ParameterElement>[]
-            ..returnType = DynamicTypeImpl.instance;
-        }
-      } else {
-        return _function = GenericFunctionTypeElementImpl.forLinkedNode(
-          this,
-          reference.getChild('@function'),
-          linkedNode,
-        );
-      }
-    }
-
-    return _function;
-  }
-
-  /// Set the function element representing the generic function type on the
-  /// right side of the equals to the given [function].
-  set function(GenericFunctionTypeElementImpl function) {
-    if (function != null) {
-      function.enclosingElement = this;
-    }
-    _function = function;
-  }
-
-  /// Return `true` if the element has direct or indirect reference to itself
-  /// from anywhere except a class element or type parameter bounds.
-  bool get hasSelfReference {
-    if (linkedNode != null) {
-      return linkedContext.getHasTypedefSelfReference(linkedNode);
-    }
-    return false;
+    return aliasedElement as GenericFunctionTypeElementImpl;
   }
 
   @override
-  bool get isSimplyBounded {
-    if (linkedNode != null) {
-      return linkedContext.isSimplyBounded(linkedNode);
-    }
-    return super.isSimplyBounded;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
-
-  @override
-  String get name {
-    if (linkedNode != null) {
-      return reference.name;
-    }
-    return super.name;
-  }
-
-  @override
-  int get nameOffset {
-    if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
-    }
-
-    return super.nameOffset;
-  }
-
-  /// Set the type parameters defined for this type to the given
-  /// [typeParameters].
-  set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement typeParameter in typeParameters) {
-      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    _typeParameterElements = typeParameters;
-  }
-
-  @override
-  T accept<T>(ElementVisitor<T> visitor) =>
-      visitor.visitFunctionTypeAliasElement(this);
-
-  @override
-  void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeFunctionTypeAliasElement(this);
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (TypeParameterElement typeParameter in typeParameters) {
-      TypeParameterElementImpl typeParameterImpl = typeParameter;
-      if (typeParameterImpl.identifier == identifier) {
-        return typeParameterImpl;
-      }
-    }
-    return null;
+  T accept<T>(ElementVisitor<T> visitor) {
+    return visitor.visitFunctionTypeAliasElement(this);
   }
 
   @override
   FunctionType instantiate({
-    @required List<DartType> typeArguments,
-    @required NullabilitySuffix nullabilitySuffix,
+    List<DartType> typeArguments,
+    NullabilitySuffix nullabilitySuffix,
   }) {
-    if (function == null) {
-      return null;
-    }
-
-    if (typeArguments.length != typeParameters.length) {
-      throw ArgumentError("typeArguments.length (${typeArguments.length}) != "
-          "typeParameters.length (${typeParameters.length})");
-    }
-
-    var substitution = Substitution.fromPairs(typeParameters, typeArguments);
-    var type = substitution.substituteType(function.type) as FunctionType;
-
-    var resultNullability = type.nullabilitySuffix == NullabilitySuffix.question
-        ? NullabilitySuffix.question
-        : nullabilitySuffix;
-
-    return FunctionTypeImpl(
-      typeFormals: type.typeFormals,
-      parameters: type.parameters,
-      returnType: type.returnType,
-      nullabilitySuffix: resultNullability,
-      element: this,
+    return super.instantiate(
       typeArguments: typeArguments,
-    );
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(typeParameters, visitor);
-    function?.accept(visitor);
+      nullabilitySuffix: nullabilitySuffix,
+    ) as FunctionType;
   }
 }
 
@@ -4658,7 +4395,11 @@
 
   GenericFunctionTypeElementImpl.forLinkedNode(
       ElementImpl enclosingElement, Reference reference, AstNode linkedNode)
-      : super.forLinkedNode(enclosingElement, reference, linkedNode);
+      : super.forLinkedNode(enclosingElement, reference, linkedNode) {
+    if (linkedNode is GenericFunctionTypeImpl) {
+      linkedNode.declaredElement = this;
+    }
+  }
 
   /// Initialize a newly created function element to have no name and the given
   /// [nameOffset]. This is used for function expressions, that have no name.
@@ -4695,7 +4436,7 @@
         return _parameters = ParameterElementImpl.forLinkedNodeList(
           this,
           context,
-          reference.getChild('@parameter'),
+          null,
           context.getFormalParameters(linkedNode),
         );
       }
@@ -4867,7 +4608,9 @@
 
   ImportElementImpl.forLinkedNode(
       LibraryElementImpl enclosing, ImportDirective linkedNode)
-      : super.forLinkedNode(enclosing, null, linkedNode);
+      : super.forLinkedNode(enclosing, null, linkedNode) {
+    linkedNode.element = this;
+  }
 
   @override
   List<NamespaceCombinator> get combinators {
@@ -4902,7 +4645,7 @@
     if (_importedLibrary != null) return _importedLibrary;
 
     if (linkedNode != null) {
-      return _importedLibrary = linkedContext.directiveLibrary(linkedNode);
+      linkedContext.applyResolution(linkedNode);
     }
 
     return _importedLibrary;
@@ -5179,7 +4922,7 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      var comment = linkedContext.getLibraryDocumentationComment(linkedNode);
+      var comment = linkedContext.getLibraryDocumentationComment();
       return getCommentNodeRawText(comment);
     }
     return super.documentationComment;
@@ -5222,7 +4965,7 @@
     if (_exportNamespace != null) return _exportNamespace;
 
     if (linkedNode != null) {
-      var elements = linkedContext.bundleContext.elementFactory;
+      var elements = linkedContext.elementFactory;
       return _exportNamespace = elements.buildExportNamespace(source.uri);
     }
 
@@ -5241,7 +4984,7 @@
       var unit = linkedContext.unit_withDirectives;
       return _exports = unit.directives
           .whereType<ExportDirective>()
-          .map((node) => ExportElementImpl.forLinkedNode(this, node))
+          .map((node) => node.element)
           .toList();
     }
 
@@ -5263,9 +5006,12 @@
       var unit = linkedContext.unit_withDirectives;
       for (var import in unit.directives) {
         if (import is ImportDirective) {
-          var uriStr = linkedContext.getSelectedUri(import);
-          if (DartUriResolver.isDartExtUri(uriStr)) {
-            return true;
+          var uriLiteral = import.uri;
+          if (uriLiteral is SimpleStringLiteral) {
+            var uriStr = uriLiteral.value;
+            if (DartUriResolver.isDartExtUri(uriStr)) {
+              return true;
+            }
           }
         }
       }
@@ -5316,13 +5062,13 @@
       var unit = linkedContext.unit_withDirectives;
       _imports = unit.directives
           .whereType<ImportDirective>()
-          .map((node) => ImportElementImpl.forLinkedNode(this, node))
+          .map((node) => node.element)
           .toList();
       var hasCore = _imports.any((import) {
         return import.importedLibrary?.isDartCore ?? false;
       });
       if (!hasCore) {
-        var elements = linkedContext.bundleContext.elementFactory;
+        var elements = linkedContext.elementFactory;
         _imports.add(
           ImportElementImpl(-1)
             ..importedLibrary = elements.libraryOfUri('dart:core')
@@ -5444,7 +5190,7 @@
     if (_metadata != null) return _metadata;
 
     if (linkedNode != null) {
-      var metadata = linkedContext.getLibraryMetadata(linkedNode);
+      var metadata = linkedContext.getLibraryMetadata();
       return _metadata = _buildAnnotations2(definingCompilationUnit, metadata);
     }
 
@@ -5533,33 +5279,6 @@
           ..returnType = typeProvider.futureDynamicType;
   }
 
-  @override
-  ElementImpl getChild(String identifier) {
-    CompilationUnitElementImpl unitImpl = _definingCompilationUnit;
-    if (unitImpl.identifier == identifier) {
-      return unitImpl;
-    }
-    for (CompilationUnitElement part in _parts) {
-      CompilationUnitElementImpl partImpl = part;
-      if (partImpl.identifier == identifier) {
-        return partImpl;
-      }
-    }
-    for (ImportElement importElement in imports) {
-      ImportElementImpl importElementImpl = importElement;
-      if (importElementImpl.identifier == identifier) {
-        return importElementImpl;
-      }
-    }
-    for (ExportElement exportElement in exports) {
-      ExportElementImpl exportElementImpl = exportElement;
-      if (exportElementImpl.identifier == identifier) {
-        return exportElementImpl;
-      }
-    }
-    return null;
-  }
-
   ClassElement getEnum(String name) {
     ClassElement element = _definingCompilationUnit.getEnum(name);
     if (element != null) {
@@ -5682,6 +5401,15 @@
 
 /// A concrete implementation of a [MethodElement].
 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+  /// Is `true` if this method is `operator==`, and there is no explicit
+  /// type specified for its formal parameter, in this method or in any
+  /// overridden methods other than the one declared in `Object`.
+  bool isOperatorEqualWithParameterTypeFromObject = false;
+
+  /// The error reported during type inference for this variable, or `null` if
+  /// this variable is not a subject of type inference, or there was no error.
+  TopLevelInferenceError typeInferenceError;
+
   /// Initialize a newly created method element to have the given [name] at the
   /// given [offset].
   MethodElementImpl(String name, int offset) : super(name, offset);
@@ -5722,23 +5450,6 @@
         first == 0x24);
   }
 
-  /// Return `true` if this method is `operator==`, and there is no explicit
-  /// type specified for its formal parameter, in this method or in any
-  /// overridden methods other than the one declared in `Object`.
-  bool get isOperatorEqualWithParameterTypeFromObject {
-    if (linkedNode != null) {
-      return linkedContext.hasOperatorEqualParameterTypeFromObject(linkedNode);
-    }
-    return false;
-  }
-
-  /// See [isOperatorEqualWithParameterTypeFromObject].
-  set isOperatorEqualWithParameterTypeFromObject(bool value) {
-    if (linkedNode != null) {
-      linkedContext.setOperatorEqualParameterTypeFromObject(linkedNode, value);
-    }
-  }
-
   @override
   bool get isStatic {
     if (linkedNode != null) {
@@ -5764,18 +5475,6 @@
     return super.name;
   }
 
-  /// Return the error reported during type inference for this method, or
-  /// `null` if this method is not a subject of type inference, or there was
-  /// no error.
-  TopLevelInferenceError get typeInferenceError {
-    if (linkedNode != null) {
-      return linkedContext.getTypeInferenceError(linkedNode);
-    }
-
-    // We don't support type inference errors without linking.
-    return null;
-  }
-
   @override
   T accept<T>(ElementVisitor<T> visitor) => visitor.visitMethodElement(this);
 }
@@ -5790,10 +5489,8 @@
   /// the mixin.
   List<InterfaceType> _superclassConstraints;
 
-  /// Names of methods, getters, setters, and operators that this mixin
-  /// declaration super-invokes.  For setters this includes the trailing "=".
-  /// The list will be empty if this class is not a mixin declaration.
-  List<String> _superInvokedNames;
+  @override
+  List<String> superInvokedNames;
 
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
@@ -5818,9 +5515,11 @@
   List<InterfaceType> get superclassConstraints {
     if (_superclassConstraints != null) return _superclassConstraints;
 
-    if (linkedNode != null) {
+    var linkedNode = this.linkedNode;
+    if (linkedNode is MixinDeclaration) {
+      linkedContext.applyResolution(linkedNode);
       List<InterfaceType> constraints;
-      var onClause = enclosingUnit.linkedContext.getOnClause(linkedNode);
+      var onClause = linkedNode.onClause;
       if (onClause != null) {
         constraints = onClause.superclassConstraints
             .map((node) => node.type)
@@ -5842,22 +5541,6 @@
   }
 
   @override
-  List<String> get superInvokedNames {
-    if (_superInvokedNames != null) return _superInvokedNames;
-
-    if (linkedNode != null) {
-      return _superInvokedNames =
-          linkedContext.getMixinSuperInvokedNames(linkedNode);
-    }
-
-    return _superInvokedNames ?? const <String>[];
-  }
-
-  set superInvokedNames(List<String> superInvokedNames) {
-    _superInvokedNames = superInvokedNames;
-  }
-
-  @override
   InterfaceType get supertype => null;
 
   @override
@@ -6288,9 +5971,6 @@
 
   @override
   set type(DartType type) {
-    if (linkedNode != null) {
-      return linkedContext.setVariableType(linkedNode, type);
-    }
     _type = type;
   }
 }
@@ -6315,7 +5995,10 @@
   /// The Dart code of the default value.
   String _defaultValueCode;
 
-  bool _inheritsCovariant = false;
+  /// True if this parameter inherits from a covariant parameter. This happens
+  /// when it overrides a method in a supertype that has a corresponding
+  /// covariant parameter.
+  bool inheritsCovariant = false;
 
   /// Initialize a newly created parameter element to have the given [name] and
   /// [nameOffset].
@@ -6324,6 +6007,7 @@
   ParameterElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, FormalParameter linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
+    assert(linkedNode.isNamed || reference == null);
     FormalParameterImpl.setDeclaredElement(linkedNode, this);
   }
 
@@ -6354,28 +6038,13 @@
   }
 
   @override
-  int get codeLength {
-    if (linkedNode != null) {
-      return linkedContext.getCodeLength(linkedNode);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext.getCodeOffset(linkedNode);
-    }
-    return super.codeOffset;
-  }
-
-  @override
   ParameterElement get declaration => this;
 
   @override
   String get defaultValueCode {
-    if (linkedNode != null) {
-      return linkedContext.getDefaultValueCode(linkedNode);
+    var linkedNode = this.linkedNode;
+    if (linkedNode is DefaultFormalParameter) {
+      return linkedNode.defaultValue?.toSource();
     }
 
     return _defaultValueCode;
@@ -6399,25 +6068,6 @@
     return super.hasImplicitType;
   }
 
-  /// True if this parameter inherits from a covariant parameter. This happens
-  /// when it overrides a method in a supertype that has a corresponding
-  /// covariant parameter.
-  bool get inheritsCovariant {
-    if (linkedNode != null) {
-      return linkedContext.getInheritsCovariant(linkedNode);
-    }
-    return _inheritsCovariant;
-  }
-
-  /// Record whether or not this parameter inherits from a covariant parameter.
-  set inheritsCovariant(bool value) {
-    if (linkedNode != null) {
-      linkedContext.setInheritsCovariant(linkedNode, value);
-      return;
-    }
-    _inheritsCovariant = value;
-  }
-
   @override
   bool get isCovariant {
     if (isExplicitlyCovariant || inheritsCovariant) {
@@ -6461,7 +6111,7 @@
   @override
   String get name {
     if (linkedNode != null) {
-      return reference.name;
+      return linkedContext.getFormalParameterName(linkedNode);
     }
     return super.name;
   }
@@ -6498,11 +6148,10 @@
       var context = enclosingUnit.linkedContext;
       var formalParameters = context.getFormalParameters(linkedNode);
       if (formalParameters != null) {
-        var containerRef = reference.getChild('@parameter');
         return _parameters = ParameterElementImpl.forLinkedNodeList(
           this,
           context,
-          containerRef,
+          null,
           formalParameters,
         );
       } else {
@@ -6523,19 +6172,6 @@
   }
 
   @override
-  DartType get type => ElementTypeProvider.current.getVariableType(this);
-
-  @override
-  DartType get typeInternal {
-    if (linkedNode != null) {
-      if (_type != null) return _type;
-      var context = enclosingUnit.linkedContext;
-      return _type = context.getType(linkedNode);
-    }
-    return super.typeInternal;
-  }
-
-  @override
   List<TypeParameterElement> get typeParameters {
     if (_typeParameters != null) return _typeParameters;
 
@@ -6544,13 +6180,10 @@
       if (typeParameters == null) {
         return _typeParameters = const [];
       }
-      var containerRef = reference.getChild('@typeParameter');
       return _typeParameters =
           typeParameters.typeParameters.map<TypeParameterElement>((node) {
-        var reference = containerRef.getChild(node.name.name);
         var element = node.declaredElement;
-        element ??=
-            TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        element ??= TypeParameterElementImpl.forLinkedNode(this, node);
         return element;
       }).toList();
     }
@@ -6581,6 +6214,9 @@
     safelyVisitChildren(parameters, visitor);
   }
 
+  /// TODO(scheglov) Do we need this method at all?
+  /// We should create all parameter elements during applying resolution.
+  /// Or when we build elements before linking.
   static List<ParameterElement> forLinkedNodeList(
       ElementImpl enclosing,
       LinkedUnitContext context,
@@ -6598,9 +6234,12 @@
 
       if (node is DefaultFormalParameter) {
         NormalFormalParameter parameterNode = node.parameter;
-        var name = parameterNode.identifier?.name ?? '';
-        var reference = containerRef.getChild(name);
-        reference.node = node;
+        Reference reference;
+        if (node.isNamed) {
+          var name = parameterNode.identifier?.name ?? '';
+          reference = containerRef?.getChild(name);
+          reference?.node = node;
+        }
         if (parameterNode is FieldFormalParameter) {
           return DefaultFieldFormalParameterElementImpl.forLinkedNode(
             enclosing,
@@ -6615,24 +6254,7 @@
           );
         }
       } else {
-        if (node.identifier == null) {
-          return ParameterElementImpl.forLinkedNodeFactory(
-            enclosing,
-            containerRef.getChild(''),
-            node,
-          );
-        } else {
-          var name = node.identifier.name;
-          var reference = containerRef.getChild(name);
-          if (reference.hasElementFor(node)) {
-            return reference.element as ParameterElement;
-          }
-          return ParameterElementImpl.forLinkedNodeFactory(
-            enclosing,
-            reference,
-            node,
-          );
-        }
+        return ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
       }
     }).toList();
   }
@@ -6655,10 +6277,7 @@
   bool get inheritsCovariant {
     PropertyInducingElement variable = setter.variable;
     if (variable is FieldElementImpl) {
-      if (variable.linkedNode != null) {
-        var context = variable.linkedContext;
-        return context.getInheritsCovariant(variable.linkedNode);
-      }
+      return variable.inheritsCovariant;
     }
     return false;
   }
@@ -6667,10 +6286,7 @@
   set inheritsCovariant(bool value) {
     PropertyInducingElement variable = setter.variable;
     if (variable is FieldElementImpl) {
-      if (variable.linkedNode != null) {
-        var context = variable.linkedContext;
-        return context.setInheritsCovariant(variable.linkedNode, value);
-      }
+      variable.inheritsCovariant = value;
     }
   }
 
@@ -6946,6 +6562,7 @@
       : super.forVariable(property, reference: reference) {
     property.getter = this;
     enclosingElement = property.enclosingElement;
+    reference?.element = this;
   }
 
   @override
@@ -7083,6 +6700,10 @@
   /// this property. After linking this field is always `null`.
   PropertyInducingElementTypeInference typeInference;
 
+  /// The error reported during type inference for this variable, or `null` if
+  /// this variable is not a subject of type inference, or there was no error.
+  TopLevelInferenceError typeInferenceError;
+
   /// Initialize a newly created synthetic element to have the given [name] and
   /// [offset].
   PropertyInducingElementImpl(String name, int offset) : super(name, offset);
@@ -7091,6 +6712,8 @@
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
+  bool get hasTypeInferred => _type != null;
+
   @override
   bool get isConstantEvaluated => true;
 
@@ -7105,23 +6728,12 @@
   @override
   DartType get type => ElementTypeProvider.current.getFieldType(this);
 
-  /// Return the error reported during type inference for this variable, or
-  /// `null` if this variable is not a subject of type inference, or there was
-  /// no error.
-  TopLevelInferenceError get typeInferenceError {
-    if (linkedNode != null) {
-      return linkedContext.getTypeInferenceError(linkedNode);
-    }
-
-    // We don't support type inference errors without linking.
-    return null;
-  }
-
   @override
   DartType get typeInternal {
+    if (_type != null) return _type;
+
     if (linkedNode != null) {
-      if (_type != null) return _type;
-      _type = linkedContext.getType(linkedNode);
+      linkedContext.applyResolution(linkedNode);
 
       // While performing inference during linking, the first step is to collect
       // dependencies. During this step we resolve the expression, but we might
@@ -7195,7 +6807,7 @@
   @override
   int get end {
     if (linkedNode != null) {
-      return linkedContext.getCombinatorEnd(linkedNode);
+      return linkedNode.end;
     }
     return _end;
   }
@@ -7256,6 +6868,9 @@
   TopLevelVariableElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
+    if (linkedNode is VariableDeclaration) {
+      linkedNode.name.staticElement = this;
+    }
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
 
@@ -7311,13 +6926,262 @@
       visitor.visitTopLevelVariableElement(this);
 }
 
+/// An element that represents [GenericTypeAlias].
+///
+/// Clients may not extend, implement or mix-in this class.
+class TypeAliasElementImpl extends ElementImpl
+    with TypeParameterizedElementMixin
+    implements TypeAliasElement {
+  /// TODO(scheglov) implement as modifier
+  @override
+  bool isSimplyBounded = true;
+
+  /// Is `true` if the element has direct or indirect reference to itself
+  /// from anywhere except a class element or type parameter bounds.
+  bool hasSelfReference = false;
+
+  bool _isRawElementReady = false;
+  ElementImpl _aliasedElement;
+  DartType _aliasedType;
+
+  TypeAliasElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  TypeAliasElementImpl.forLinkedNode(
+    CompilationUnitElementImpl enclosingUnit,
+    Reference reference,
+    TypeAlias linkedNode,
+  ) : super.forLinkedNode(enclosingUnit, reference, linkedNode) {
+    var nameNode = linkedNode is FunctionTypeAlias
+        ? linkedNode.name
+        : (linkedNode as GenericTypeAlias).name;
+    nameNode.staticElement = this;
+  }
+
+  factory TypeAliasElementImpl.forLinkedNodeFactory(
+    CompilationUnitElementImpl enclosingUnit,
+    Reference reference,
+    TypeAlias linkedNode,
+  ) {
+    if (linkedNode is FunctionTypeAlias) {
+      return FunctionTypeAliasElementImpl.forLinkedNode(
+          enclosingUnit, reference, linkedNode);
+    } else {
+      var aliasedType = (linkedNode as GenericTypeAlias).type;
+      if (aliasedType is GenericFunctionType ||
+          !enclosingUnit.isNonFunctionTypeAliasesEnabled) {
+        return FunctionTypeAliasElementImpl.forLinkedNode(
+            enclosingUnit, reference, linkedNode);
+      } else {
+        return TypeAliasElementImpl.forLinkedNode(
+            enclosingUnit, reference, linkedNode);
+      }
+    }
+  }
+
+  @override
+  ElementImpl get aliasedElement {
+    _ensureAliasedElement();
+    return _aliasedElement;
+  }
+
+  @override
+  DartType get aliasedType {
+    if (_aliasedType != null) return _aliasedType;
+
+    _ensureAliasedElement();
+
+    var linkedNode = this.linkedNode;
+    if (linkedNode is GenericTypeAlias) {
+      var typeNode = linkedNode.type;
+      if (isNonFunctionTypeAliasesEnabled) {
+        _aliasedType = typeNode.type;
+        assert(_aliasedType != null);
+      } else if (typeNode is GenericFunctionType) {
+        _aliasedType = typeNode.type;
+        assert(_aliasedType != null);
+      } else {
+        _aliasedType = _errorFunctionType(NullabilitySuffix.none);
+      }
+    } else if (linkedNode is FunctionTypeAlias) {
+      _aliasedType = (_aliasedElement as GenericFunctionTypeElementImpl).type;
+    }
+
+    return _aliasedType;
+  }
+
+  set aliasedType(DartType rawType) {
+    _aliasedType = rawType;
+  }
+
+  @override
+  int get codeLength {
+    if (linkedNode != null) {
+      return linkedContext.getCodeLength(linkedNode);
+    }
+    return super.codeLength;
+  }
+
+  @override
+  int get codeOffset {
+    if (linkedNode != null) {
+      return linkedContext.getCodeOffset(linkedNode);
+    }
+    return super.codeOffset;
+  }
+
+  @override
+  String get displayName => name;
+
+  @override
+  String get documentationComment {
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
+    }
+    return super.documentationComment;
+  }
+
+  @override
+  CompilationUnitElement get enclosingElement =>
+      super.enclosingElement as CompilationUnitElement;
+
+  @override
+  ElementKind get kind {
+    if (isNonFunctionTypeAliasesEnabled) {
+      return ElementKind.TYPE_ALIAS;
+    } else {
+      return ElementKind.FUNCTION_TYPE_ALIAS;
+    }
+  }
+
+  @override
+  String get name {
+    if (linkedNode != null) {
+      return reference.name;
+    }
+    return super.name;
+  }
+
+  @override
+  int get nameOffset {
+    if (linkedNode != null) {
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
+    }
+
+    return super.nameOffset;
+  }
+
+  /// Set the type parameters defined for this type to the given
+  /// [typeParameters].
+  set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
+      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    _typeParameterElements = typeParameters;
+  }
+
+  @override
+  T accept<T>(ElementVisitor<T> visitor) {
+    // TODO(scheglov) `visitTypeAliasElement`
+    throw UnimplementedError();
+  }
+
+  @override
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeTypeAliasElement(this);
+  }
+
+  @override
+  DartType instantiate({
+    List<DartType> typeArguments,
+    NullabilitySuffix nullabilitySuffix,
+  }) {
+    if (hasSelfReference) {
+      if (isNonFunctionTypeAliasesEnabled) {
+        return DynamicTypeImpl.instance;
+      } else {
+        return _errorFunctionType(nullabilitySuffix);
+      }
+    }
+
+    var substitution = Substitution.fromPairs(typeParameters, typeArguments);
+    var type = substitution.substituteType(aliasedType);
+
+    var resultNullability = type.nullabilitySuffix == NullabilitySuffix.question
+        ? NullabilitySuffix.question
+        : nullabilitySuffix;
+
+    if (type is FunctionType) {
+      return FunctionTypeImpl(
+        typeFormals: type.typeFormals,
+        parameters: type.parameters,
+        returnType: type.returnType,
+        nullabilitySuffix: resultNullability,
+        element: this,
+        typeArguments: typeArguments,
+      );
+    } else {
+      return (type as TypeImpl).withNullability(resultNullability);
+    }
+  }
+
+  void _ensureAliasedElement() {
+    if (_isRawElementReady) return;
+    _isRawElementReady = true;
+
+    var linkedNode = this.linkedNode;
+    if (linkedNode != null) {
+      if (linkedNode is GenericTypeAlias) {
+        var type = linkedNode.type;
+        if (type is GenericFunctionTypeImpl) {
+          _aliasedElement =
+              type.declaredElement as GenericFunctionTypeElementImpl;
+          // TODO(scheglov) Do we need this?
+          // We probably should set it when linking and when applying.
+          // TODO(scheglov) And remove the reference.
+          _aliasedElement ??= GenericFunctionTypeElementImpl.forLinkedNode(
+            this,
+            reference.getChild('@function'),
+            type,
+          );
+        } else if (isNonFunctionTypeAliasesEnabled) {
+          // No element for `typedef A<T> = List<T>;`
+        } else {
+          _aliasedElement = GenericFunctionTypeElementImpl.forOffset(-1)
+            ..typeParameters = const <TypeParameterElement>[]
+            ..parameters = const <ParameterElement>[]
+            ..returnType = DynamicTypeImpl.instance;
+        }
+      } else {
+        // TODO(scheglov) Same as above (both).
+        _aliasedElement = GenericFunctionTypeElementImpl.forLinkedNode(
+          this,
+          reference.getChild('@function'),
+          linkedNode,
+        );
+      }
+      linkedContext.applyResolution(linkedNode);
+    }
+  }
+
+  FunctionTypeImpl _errorFunctionType(NullabilitySuffix nullabilitySuffix) {
+    return FunctionTypeImpl(
+      typeFormals: const [],
+      parameters: const [],
+      returnType: DynamicTypeImpl.instance,
+      nullabilitySuffix: nullabilitySuffix,
+    );
+  }
+}
+
 /// A concrete implementation of a [TypeParameterElement].
 class TypeParameterElementImpl extends ElementImpl
     implements TypeParameterElement {
   /// The default value of the type parameter. It is used to provide the
   /// corresponding missing type argument in type annotations and as the
   /// fall-back type value in type inference.
-  DartType _defaultType;
+  DartType defaultType;
 
   /// The type representing the bound associated with this parameter, or `null`
   /// if this parameter does not have an explicit bound.
@@ -7332,8 +7196,8 @@
   TypeParameterElementImpl(String name, int offset) : super(name, offset);
 
   TypeParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, TypeParameter linkedNode)
-      : super.forLinkedNode(enclosing, reference, linkedNode) {
+      ElementImpl enclosing, TypeParameter linkedNode)
+      : super.forLinkedNode(enclosing, null, linkedNode) {
     linkedNode.name.staticElement = this;
   }
 
@@ -7353,9 +7217,9 @@
   DartType get boundInternal {
     if (_bound != null) return _bound;
 
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
-      return _bound = context.getTypeParameterBound(linkedNode)?.type;
+    var linkedNode = this.linkedNode;
+    if (linkedNode is TypeParameter) {
+      return _bound = linkedNode.bound?.type;
     }
 
     return _bound;
@@ -7380,29 +7244,10 @@
   @override
   TypeParameterElement get declaration => this;
 
-  /// The default value of the type parameter. It is used to provide the
-  /// corresponding missing type argument in type annotations and as the
-  /// fall-back type value in type inference.
-  DartType get defaultType {
-    if (_defaultType != null) return _defaultType;
-
-    if (linkedNode != null) {
-      return _defaultType = linkedContext.getDefaultType(linkedNode);
-    }
-    return null;
-  }
-
-  set defaultType(DartType defaultType) {
-    _defaultType = defaultType;
-  }
-
   @override
   String get displayName => name;
 
   bool get isLegacyCovariant {
-    if (linkedNode != null) {
-      return linkedContext.getTypeParameterVariance(linkedNode) == null;
-    }
     return _variance == null;
   }
 
@@ -7428,12 +7273,6 @@
   }
 
   Variance get variance {
-    if (_variance != null) return _variance;
-
-    if (linkedNode != null) {
-      _variance = linkedContext.getTypeParameterVariance(linkedNode);
-    }
-
     return _variance ?? Variance.covariant;
   }
 
@@ -7489,18 +7328,16 @@
     if (_typeParameterElements != null) return _typeParameterElements;
 
     if (linkedNode != null) {
+      linkedContext.applyResolution(linkedNode);
       var typeParameters = linkedContext.getTypeParameters2(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
-      var containerRef = reference.getChild('@typeParameter');
       return _typeParameterElements =
           typeParameters.typeParameters.map<TypeParameterElement>((node) {
-        var reference = containerRef.getChild(node.name.name);
-        if (reference.hasElementFor(node)) {
-          return reference.element as TypeParameterElement /*!*/;
-        }
-        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        var element = node.declaredElement;
+        element ??= TypeParameterElementImpl.forLinkedNode(this, node);
+        return element;
       }).toList();
     }
 
@@ -7655,9 +7492,6 @@
   DartType get type => ElementTypeProvider.current.getVariableType(this);
 
   set type(DartType type) {
-    if (linkedNode != null) {
-      return linkedContext.setVariableType(linkedNode, type);
-    }
     _type = type;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
index 2cb1bde..d355eab 100644
--- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:math' show max;
+
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -50,15 +52,7 @@
   /// Return the interfaces that are directly implemented by this class.
   List<InstantiatedClass> get interfaces {
     var interfaces = element.interfaces;
-
-    var result = List<InstantiatedClass>(interfaces.length);
-    for (var i = 0; i < interfaces.length; i++) {
-      var interface = interfaces[i];
-      var substituted = _substitution.substituteType(interface);
-      result[i] = InstantiatedClass.of(substituted);
-    }
-
-    return result;
+    return _toInstantiatedClasses(interfaces);
   }
 
   /// Return `true` if this type represents the type 'Function' defined in the
@@ -67,6 +61,12 @@
     return element.name == 'Function' && element.library.isDartCore;
   }
 
+  /// Return the mixin that are directly implemented by this class.
+  List<InstantiatedClass> get mixins {
+    var mixins = element.mixins;
+    return _toInstantiatedClasses(mixins);
+  }
+
   /// Return the superclass of this type, or `null` if this type represents
   /// the class 'Object'.
   InstantiatedClass get superclass {
@@ -84,15 +84,7 @@
   /// the type for the class `Object`.
   List<InstantiatedClass> get superclassConstraints {
     var constraints = element.superclassConstraints;
-
-    var result = List<InstantiatedClass>(constraints.length);
-    for (var i = 0; i < constraints.length; i++) {
-      var constraint = constraints[i];
-      var substituted = _substitution.substituteType(constraint);
-      result[i] = InstantiatedClass.of(substituted);
-    }
-
-    return result;
+    return _toInstantiatedClasses(constraints);
   }
 
   @visibleForTesting
@@ -139,6 +131,19 @@
       nullabilitySuffix: nullability,
     );
   }
+
+  List<InstantiatedClass> _toInstantiatedClasses(
+    List<InterfaceType> interfaces,
+  ) {
+    var result = List<InstantiatedClass>.filled(interfaces.length, null);
+    for (var i = 0; i < interfaces.length; i++) {
+      var interface = interfaces[i];
+      var substituted = _substitution.substituteType(interface);
+      result[i] = InstantiatedClass.of(substituted);
+    }
+
+    return result;
+  }
 }
 
 class InterfaceLeastUpperBoundHelper {
@@ -191,7 +196,7 @@
       assert(args1.length == args2.length);
       assert(args1.length == params.length);
 
-      var args = List<DartType>(args1.length);
+      var args = List<DartType>.filled(args1.length, null);
       for (int i = 0; i < args1.length; i++) {
         // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
         // variance is added to the interface.
@@ -277,11 +282,7 @@
   /// Object.
   @visibleForTesting
   static int computeLongestInheritancePathToObject(ClassElement element) {
-    return _computeLongestInheritancePathToObject(
-      element,
-      0,
-      <ClassElement>{},
-    );
+    return _computeLongestInheritancePathToObject(element, <ClassElement>{});
   }
 
   /// Add all of the superinterfaces of the given [type] to the given [set].
@@ -295,6 +296,14 @@
       }
     }
 
+    for (var mixin in type.mixins) {
+      if (!mixin.isDartCoreFunction) {
+        if (set.add(mixin)) {
+          _addSuperinterfaces(set, mixin);
+        }
+      }
+    }
+
     for (var constraint in type.superclassConstraints) {
       if (!constraint.isDartCoreFunction) {
         if (set.add(constraint)) {
@@ -333,47 +342,53 @@
   /// is used to prevent infinite recursion in the case of a cyclic type
   /// structure.
   static int _computeLongestInheritancePathToObject(
-      ClassElement element, int depth, Set<ClassElement> visitedElements) {
+      ClassElement element, Set<ClassElement> visitedElements) {
     // Object case
     if (element.isDartCoreObject || visitedElements.contains(element)) {
-      return depth;
+      return 0;
     }
-    int longestPath = 1;
+    int longestPath = 0;
     try {
       visitedElements.add(element);
-      int pathLength;
 
       // loop through each of the superinterfaces recursively calling this
       // method and keeping track of the longest path to return
       for (InterfaceType interface in element.superclassConstraints) {
-        pathLength = _computeLongestInheritancePathToObject(
-            interface.element, depth + 1, visitedElements);
-        if (pathLength > longestPath) {
-          longestPath = pathLength;
-        }
+        var pathLength = _computeLongestInheritancePathToObject(
+            interface.element, visitedElements);
+        longestPath = max(longestPath, 1 + pathLength);
       }
 
       // loop through each of the superinterfaces recursively calling this
       // method and keeping track of the longest path to return
       for (InterfaceType interface in element.interfaces) {
-        pathLength = _computeLongestInheritancePathToObject(
-            interface.element, depth + 1, visitedElements);
-        if (pathLength > longestPath) {
-          longestPath = pathLength;
-        }
+        var pathLength = _computeLongestInheritancePathToObject(
+            interface.element, visitedElements);
+        longestPath = max(longestPath, 1 + pathLength);
       }
 
-      // finally, perform this same check on the super type
-      // TODO(brianwilkerson) Does this also need to add in the number of mixin
-      // classes?
-      InterfaceType supertype = element.supertype;
-      if (supertype != null) {
-        pathLength = _computeLongestInheritancePathToObject(
-            supertype.element, depth + 1, visitedElements);
-        if (pathLength > longestPath) {
-          longestPath = pathLength;
-        }
+      var supertype = element.supertype;
+      if (supertype == null) {
+        return longestPath;
       }
+
+      var superLength = _computeLongestInheritancePathToObject(
+          supertype.element, visitedElements);
+
+      var mixins = element.mixins;
+      for (var i = 0; i < mixins.length; i++) {
+        // class _X&S&M extends S implements M {}
+        // So, we choose the maximum length from S and M.
+        var mixinLength = _computeLongestInheritancePathToObject(
+          mixins[i].element,
+          visitedElements,
+        );
+        superLength = max(superLength, mixinLength);
+        // For this synthetic class representing the mixin application.
+        superLength++;
+      }
+
+      longestPath = max(longestPath, 1 + superLength);
     } finally {
       visitedElements.remove(element);
     }
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 9816e56..f343aa1 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -1069,8 +1069,8 @@
 
     // Create type formals with specialized bounds.
     // For example `<U extends T>` where T comes from an outer scope.
-    var newElements = List<TypeParameterElement>(elements.length);
-    var newTypes = List<TypeParameterType>(elements.length);
+    var newElements = List<TypeParameterElement>.filled(elements.length, null);
+    var newTypes = List<TypeParameterType>.filled(elements.length, null);
     for (int i = 0; i < newElements.length; i++) {
       var element = elements[i];
       var newElement = TypeParameterElementImpl.synthetic(element.name);
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index c90174a..87503e9 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -162,7 +162,7 @@
       var typeParameter = node.typeFormals[i];
       var bound = typeParameter.bound;
       if (bound != null) {
-        var newBound = bound.accept(this);
+        var newBound = visitTypeParameterBound(bound);
         if (newBound != null) {
           newTypeParameters ??= node.typeFormals.toList(growable: false);
           newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -258,7 +258,7 @@
       var typeParameter = node.typeFormals[i];
       var bound = typeParameter.bound;
       if (bound != null) {
-        var newBound = bound.accept(this);
+        var newBound = visitTypeParameterBound(bound);
         if (newBound != null) {
           newTypeParameters ??= node.typeFormals.toList(growable: false);
           newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -394,6 +394,10 @@
     return argument.accept(this);
   }
 
+  DartType visitTypeParameterBound(DartType type) {
+    return type.accept(this);
+  }
+
   @override
   DartType visitTypeParameterType(TypeParameterType type) {
     var newNullability = visitNullability(type);
diff --git a/pkg/analyzer/lib/src/dart/element/scope.dart b/pkg/analyzer/lib/src/dart/element/scope.dart
index 2e1daa0..85085f8 100644
--- a/pkg/analyzer/lib/src/dart/element/scope.dart
+++ b/pkg/analyzer/lib/src/dart/element/scope.dart
@@ -174,7 +174,7 @@
     compilationUnit.enums.forEach(_addGetter);
     compilationUnit.extensions.forEach(_addExtension);
     compilationUnit.functions.forEach(_addGetter);
-    compilationUnit.functionTypeAliases.forEach(_addGetter);
+    compilationUnit.typeAliases.forEach(_addGetter);
     compilationUnit.mixins.forEach(_addGetter);
     compilationUnit.types.forEach(_addGetter);
   }
diff --git a/pkg/analyzer/lib/src/dart/element/top_merge.dart b/pkg/analyzer/lib/src/dart/element/top_merge.dart
index 78714ea..8fb1327 100644
--- a/pkg/analyzer/lib/src/dart/element/top_merge.dart
+++ b/pkg/analyzer/lib/src/dart/element/top_merge.dart
@@ -212,7 +212,7 @@
       throw _TopMergeStateError(T, S, 'Different number of formal parameters');
     }
 
-    var R_parameters = List<ParameterElement>(T_parameters.length);
+    var R_parameters = List<ParameterElement>.filled(T_parameters.length, null);
     for (var i = 0; i < T_parameters.length; i++) {
       var T_parameter = T_parameters[i];
       var S_parameter = S_parameters[i];
@@ -278,7 +278,7 @@
     if (T_arguments.isEmpty) {
       return T;
     } else {
-      var arguments = List<DartType>(T_arguments.length);
+      var arguments = List<DartType>.filled(T_arguments.length, null);
       for (var i = 0; i < T_arguments.length; i++) {
         arguments[i] = topMerge(T_arguments[i], S_arguments[i]);
       }
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 20211b6..50953f8 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -644,7 +644,7 @@
     if (_accessors == null) {
       List<PropertyAccessorElement> accessors = element.accessors;
       List<PropertyAccessorElement> members =
-          List<PropertyAccessorElement>(accessors.length);
+          List<PropertyAccessorElement>.filled(accessors.length, null);
       for (int i = 0; i < accessors.length; i++) {
         members[i] = PropertyAccessorMember.from(accessors[i], this);
       }
@@ -666,7 +666,7 @@
     if (_constructors == null) {
       List<ConstructorElement> constructors = element.constructors;
       List<ConstructorElement> members =
-          List<ConstructorElement>(constructors.length);
+          List<ConstructorElement>.filled(constructors.length, null);
       for (int i = 0; i < constructors.length; i++) {
         members[i] = ConstructorMember.from(constructors[i], this);
       }
@@ -767,7 +767,8 @@
   List<MethodElement> get methods {
     if (_methods == null) {
       List<MethodElement> methods = element.methods;
-      List<MethodElement> members = List<MethodElement>(methods.length);
+      List<MethodElement> members =
+          List<MethodElement>.filled(methods.length, null);
       for (int i = 0; i < methods.length; i++) {
         members[i] = MethodMember.from(methods[i], this);
       }
@@ -1322,7 +1323,7 @@
     if (typeParameters.isEmpty) return defined;
 
     var substitution = Substitution.fromInterfaceType(this);
-    var result = List<InterfaceType>(defined.length);
+    var result = List<InterfaceType>.filled(defined.length, null);
     for (int i = 0; i < defined.length; i++) {
       result[i] = substitution.substituteType(defined[i]);
     }
@@ -1425,7 +1426,7 @@
     if (argumentCount == 0) {
       return firstType;
     }
-    List<DartType> lubArguments = List<DartType>(argumentCount);
+    List<DartType> lubArguments = List<DartType>.filled(argumentCount, null);
     for (int i = 0; i < argumentCount; i++) {
       //
       // Ideally we would take the least upper bound of the two argument types,
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 2854f7e..a6ca14b 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -239,7 +239,8 @@
       return const <TypeParameterElement>[];
     }
 
-    var freshElements = List<TypeParameterElement>(elements.length);
+    var freshElements =
+        List<TypeParameterElement>.filled(elements.length, null);
     for (var i = 0; i < elements.length; i++) {
       // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
       // variance is added to the interface.
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index c38172a..3acda34 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -20,6 +20,7 @@
 import 'package:analyzer/src/dart/element/normalize.dart';
 import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
 import 'package:analyzer/src/dart/element/replace_top_bottom_visitor.dart';
+import 'package:analyzer/src/dart/element/replacement_visitor.dart';
 import 'package:analyzer/src/dart/element/runtime_type_equality.dart';
 import 'package:analyzer/src/dart/element/subtype.dart';
 import 'package:analyzer/src/dart/element/top_merge.dart';
@@ -501,9 +502,12 @@
   @override
   DartType instantiateToBounds2({
     ClassElement classElement,
-    FunctionTypeAliasElement functionTypeAliasElement,
+    @Deprecated("Use 'typeAliasElement' instead")
+        FunctionTypeAliasElement functionTypeAliasElement,
+    TypeAliasElement typeAliasElement,
     @required NullabilitySuffix nullabilitySuffix,
   }) {
+    typeAliasElement ??= functionTypeAliasElement;
     if (classElement != null) {
       var typeParameters = classElement.typeParameters;
       var typeArguments = _defaultTypeArguments(typeParameters);
@@ -513,10 +517,10 @@
       );
       type = toLegacyType(type);
       return type;
-    } else if (functionTypeAliasElement != null) {
-      var typeParameters = functionTypeAliasElement.typeParameters;
+    } else if (typeAliasElement != null) {
+      var typeParameters = typeAliasElement.typeParameters;
       var typeArguments = _defaultTypeArguments(typeParameters);
-      var type = functionTypeAliasElement.instantiate(
+      var type = typeAliasElement.instantiate(
         typeArguments: typeArguments,
         nullabilitySuffix: nullabilitySuffix,
       );
@@ -597,6 +601,8 @@
           if (type is FunctionType) {
             appendParameters(type.returnType);
             type.parameters.map((p) => p.type).forEach(appendParameters);
+            // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44218
+            type.typeArguments.forEach(appendParameters);
           } else if (type is InterfaceType) {
             type.typeArguments.forEach(appendParameters);
           }
@@ -1230,6 +1236,8 @@
       typeParameters,
       considerExtendsClause: false,
     );
+    inferredTypes =
+        inferredTypes.map(_removeBoundsOfGenericFunctionTypes).toList();
     var substitution = Substitution.fromPairs(typeParameters, inferredTypes);
 
     for (int i = 0; i < srcTypes.length; i++) {
@@ -1785,6 +1793,15 @@
     return currentType;
   }
 
+  DartType _removeBoundsOfGenericFunctionTypes(DartType type) {
+    return _RemoveBoundsOfGenericFunctionTypeVisitor.run(
+      bottomType: isNonNullableByDefault
+          ? NeverTypeImpl.instance
+          : typeProvider.nullType,
+      type: type,
+    );
+  }
+
   /// Starting from the given [type], search its class hierarchy for types of
   /// the form Future<R>, and return a list of the resulting R's.
   List<DartType> _searchTypeHierarchyForFutureTypeParameters(DartType type) {
@@ -1810,6 +1827,27 @@
   }
 }
 
+/// TODO(scheglov) Ask the language team how to deal with it.
+class _RemoveBoundsOfGenericFunctionTypeVisitor extends ReplacementVisitor {
+  final DartType _bottomType;
+
+  _RemoveBoundsOfGenericFunctionTypeVisitor._(this._bottomType);
+
+  @override
+  DartType visitTypeParameterBound(DartType type) {
+    return _bottomType;
+  }
+
+  static DartType run({
+    @required DartType bottomType,
+    @required DartType type,
+  }) {
+    var visitor = _RemoveBoundsOfGenericFunctionTypeVisitor._(bottomType);
+    var result = type.accept(visitor);
+    return result ?? type;
+  }
+}
+
 class _TypeVariableEliminator extends Substitution {
   final DartType _topType;
   final DartType _bottomType;
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index f2711d9..eda16d1 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -170,10 +170,11 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_EXTENDS = FfiCode(
-      name: 'SUBTYPE_OF_FFI_CLASS',
-      uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_EXTENDS',
-      message: "The class '{0}' can't extend '{1}'.",
-      correction: "Try extending 'Struct'.");
+    name: 'SUBTYPE_OF_FFI_CLASS',
+    message: "The class '{0}' can't extend '{1}'.",
+    correction: "Try extending 'Struct'.",
+    uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_EXTENDS',
+  );
 
   /**
    * Parameters:
@@ -181,10 +182,11 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS = FfiCode(
-      name: 'SUBTYPE_OF_FFI_CLASS',
-      uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
-      message: "The class '{0}' can't implement '{1}'.",
-      correction: "Try extending 'Struct'.");
+    name: 'SUBTYPE_OF_FFI_CLASS',
+    message: "The class '{0}' can't implement '{1}'.",
+    correction: "Try extending 'Struct'.",
+    uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
+  );
 
   /**
    * Parameters:
@@ -192,10 +194,11 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_WITH = FfiCode(
-      name: 'SUBTYPE_OF_FFI_CLASS',
-      uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_WITH',
-      message: "The class '{0}' can't mix in '{1}'.",
-      correction: "Try extending 'Struct'.");
+    name: 'SUBTYPE_OF_FFI_CLASS',
+    message: "The class '{0}' can't mix in '{1}'.",
+    correction: "Try extending 'Struct'.",
+    uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_WITH',
+  );
 
   /**
    * Parameters:
@@ -203,12 +206,12 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS = FfiCode(
-      name: 'SUBTYPE_OF_STRUCT_CLASS',
-      uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS',
-      message:
-          "The class '{0}' can't extend '{1}' because '{1}' is a subtype of "
-          "'Struct'.",
-      correction: "Try extending 'Struct' directly.");
+    name: 'SUBTYPE_OF_STRUCT_CLASS',
+    message: "The class '{0}' can't extend '{1}' because '{1}' is a subtype of "
+        "'Struct'.",
+    correction: "Try extending 'Struct' directly.",
+    uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS',
+  );
 
   /**
    * Parameters:
@@ -216,12 +219,13 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS = FfiCode(
-      name: 'SUBTYPE_OF_STRUCT_CLASS',
-      uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS',
-      message:
-          "The class '{0}' can't implement '{1}' because '{1}' is a subtype of "
-          "'Struct'.",
-      correction: "Try extending 'Struct' directly.");
+    name: 'SUBTYPE_OF_STRUCT_CLASS',
+    message:
+        "The class '{0}' can't implement '{1}' because '{1}' is a subtype of "
+        "'Struct'.",
+    correction: "Try extending 'Struct' directly.",
+    uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS',
+  );
 
   /**
    * Parameters:
@@ -229,15 +233,12 @@
    * 1: the name of the class being extended, implemented, or mixed in
    */
   static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_WITH = FfiCode(
-      name: 'SUBTYPE_OF_STRUCT_CLASS',
-      uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_WITH',
-      message:
-          "The class '{0}' can't mix in '{1}' because '{1}' is a subtype of "
-          "'Struct'.",
-      correction: "Try extending 'Struct' directly.");
-
-  @override
-  final String uniqueName;
+    name: 'SUBTYPE_OF_STRUCT_CLASS',
+    message: "The class '{0}' can't mix in '{1}' because '{1}' is a subtype of "
+        "'Struct'.",
+    correction: "Try extending 'Struct' directly.",
+    uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_WITH',
+  );
 
   /// Initialize a newly created error code to have the given [name]. If
   /// [uniqueName] is provided, then it will be used to construct the unique
@@ -249,16 +250,19 @@
   /// created from the given [correction] template.
   ///
   /// If [hasPublishedDocs] is `true` then a URL for the docs will be generated.
-  const FfiCode(
-      {@required String message,
-      @required String name,
-      String correction,
-      bool hasPublishedDocs,
-      String uniqueName})
-      : uniqueName =
-            uniqueName == null ? 'FfiCode.$name' : 'FfiCode.$uniqueName',
-        super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+  const FfiCode({
+    String correction,
+    bool hasPublishedDocs = false,
+    @required String message,
+    @required String name,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'FfiCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 2a7a07a..402b9c7 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -293,27 +293,28 @@
    * 1: message details
    */
   static const HintCode DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE =
-      HintCodeWithUniqueName(
-          'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
-          'HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE',
-          "'{0}' is deprecated and shouldn't be used. {1}.",
-          correction: "Try replacing the use of the deprecated member with the "
-              "replacement.",
-          hasPublishedDocs: true);
+      HintCode(
+    'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
+    "'{0}' is deprecated and shouldn't be used. {1}.",
+    correction: "Try replacing the use of the deprecated member with the "
+        "replacement.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE',
+  );
 
   /**
    * Parameters:
    * 0: the name of the member
    * 1: message details
    */
-  static const HintCode DEPRECATED_MEMBER_USE_WITH_MESSAGE =
-      HintCodeWithUniqueName(
-          'DEPRECATED_MEMBER_USE',
-          'HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE',
-          "'{0}' is deprecated and shouldn't be used. {1}.",
-          correction: "Try replacing the use of the deprecated member with the "
-              "replacement.",
-          hasPublishedDocs: true);
+  static const HintCode DEPRECATED_MEMBER_USE_WITH_MESSAGE = HintCode(
+    'DEPRECATED_MEMBER_USE',
+    "'{0}' is deprecated and shouldn't be used. {1}.",
+    correction: "Try replacing the use of the deprecated member with the "
+        "replacement.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE',
+  );
 
   /**
    * `Function` should not be mixed in anymore.
@@ -721,13 +722,13 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN',
-          "The Dart language version override number must begin with '@dart'",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override number must begin with '@dart'",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -739,32 +740,30 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
-          "The Dart language version override comment must be specified with "
-              "an '=' character",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
-
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER =
-      HintCodeWithUniqueName(
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS = HintCode(
     'INVALID_LANGUAGE_VERSION_OVERRIDE',
-    'INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER',
+    "The Dart language version override comment must be specified with "
+        "an '=' character",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
+  );
+
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
     "The language version override can't specify a version greater than the "
         "latest known language version: {0}.{1}",
     correction: "Try removing the language version override.",
+    uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER',
   );
 
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION =
-      HintCodeWithUniqueName(
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION = HintCode(
     'INVALID_LANGUAGE_VERSION_OVERRIDE',
-    'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
     "The language version override must be before any declaration or "
         "directive.",
     correction:
         "Try moving the language version override to the top of the file.",
+    uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
   );
 
   /// Invalid Dart language version comments don't follow the specification [1].
@@ -777,14 +776,14 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE',
-          "The Dart language version override comment must be specified with "
-              "the word 'dart' in all lower case",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override comment must be specified with "
+        "the word 'dart' in all lower case",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -796,14 +795,14 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER',
-          "The Dart language version override comment must be specified with a "
-              "version number, like '2.0', after the '=' character.",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override comment must be specified with a "
+        "version number, like '2.0', after the '=' character.",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -815,14 +814,14 @@
   /// valid language version override comment, it is reported.
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
-  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX',
-          "The Dart language version override number can't be prefixed with "
-              "a letter",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+  static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX = HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override number can't be prefixed with "
+        "a letter",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -835,13 +834,15 @@
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
   static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS',
-          "The Dart language version override comment can't be followed by "
-              "any non-whitespace characters",
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+      HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    "The Dart language version override comment can't be followed by "
+        "any non-whitespace characters",
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName:
+        'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS',
+  );
 
   /// Invalid Dart language version comments don't follow the specification [1].
   /// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -854,13 +855,14 @@
   ///
   /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
   static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES =
-      HintCodeWithUniqueName(
-          'INVALID_LANGUAGE_VERSION_OVERRIDE',
-          'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES',
-          'The Dart language version override comment must be specified with '
-              'exactly two slashes.',
-          correction: "Specify a Dart language version override with a comment "
-              "like '// @dart = 2.0'.");
+      HintCode(
+    'INVALID_LANGUAGE_VERSION_OVERRIDE',
+    'The Dart language version override comment must be specified with '
+        'exactly two slashes.',
+    correction: "Specify a Dart language version override with a comment "
+        "like '// @dart = 2.0'.",
+    uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES',
+  );
 
   /**
    * No parameters.
@@ -1150,6 +1152,7 @@
   // is required:
   //
   // ```dart
+  // %language=2.9
   // import 'package:meta/meta.dart';
   //
   // void f({@required int x}) {}
@@ -1164,6 +1167,7 @@
   // Provide the required value:
   //
   // ```dart
+  // %language=2.9
   // import 'package:meta/meta.dart';
   //
   // void f({@required int x}) {}
@@ -1184,12 +1188,12 @@
    * 0: the name of the parameter
    * 1: message details
    */
-  static const HintCode MISSING_REQUIRED_PARAM_WITH_DETAILS =
-      HintCodeWithUniqueName(
-          'MISSING_REQUIRED_PARAM',
-          'HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS',
-          "The parameter '{0}' is required. {1}.",
-          hasPublishedDocs: true);
+  static const HintCode MISSING_REQUIRED_PARAM_WITH_DETAILS = HintCode(
+    'MISSING_REQUIRED_PARAM',
+    "The parameter '{0}' is required. {1}.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS',
+  );
 
   /**
    * Parameters:
@@ -1207,6 +1211,7 @@
   // return:
   //
   // ```dart
+  // %language=2.9
   // int [!f!](int x) {
   //   if (x < 0) {
   //     return 0;
@@ -1320,7 +1325,8 @@
   // ```
   //
   // If the instances of the class should be mutable, then remove the
-  //annotation, or choose a different superclass if the annotation is inherited:
+  // annotation, or choose a different superclass if the annotation is
+  // inherited:
   //
   // ```dart
   // class C {
@@ -1449,13 +1455,14 @@
    * 0: the name of the class defining the annotated constructor
    */
   static const HintCode NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW =
-      HintCodeWithUniqueName(
-          'NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR',
-          'HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW',
-          "This instance creation must be 'const', because the {0} constructor "
-              "is marked as '@literal'.",
-          correction: "Try replacing the 'new' keyword with 'const'.",
-          hasPublishedDocs: true);
+      HintCode(
+    'NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR',
+    "This instance creation must be 'const', because the {0} constructor "
+        "is marked as '@literal'.",
+    correction: "Try replacing the 'new' keyword with 'const'.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW',
+  );
 
   /**
    * When the left operand of a binary expression uses '?.' operator, it can be
@@ -1511,7 +1518,6 @@
   // specified to allow `null` when `null` can't be thrown:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f() {
   //   try {
   //     // ...
@@ -1525,7 +1531,6 @@
   // Remove the question mark from the type:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f() {
   //   try {
   //     // ...
@@ -1558,28 +1563,28 @@
    *
    * No parameters.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD',
-          "The field doesn't override an inherited getter or setter.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The field doesn't override an inherited getter or setter.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD',
+  );
 
   /**
    * A getter with the override annotation does not override an existing getter.
    *
    * No parameters.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER',
-          "The getter doesn't override an inherited getter.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The getter doesn't override an inherited getter.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER',
+  );
 
   /**
    * A method with the override annotation does not override an existing method.
@@ -1620,28 +1625,28 @@
   // superclass, then consider removing the member from the subclass.
   //
   // If the member can't be removed, then remove the annotation.
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD',
-          "The method doesn't override an inherited method.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The method doesn't override an inherited method.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD',
+  );
 
   /**
    * A setter with the override annotation does not override an existing setter.
    *
    * No parameters.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER =
-      HintCodeWithUniqueName(
-          'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
-          'HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER',
-          "The setter doesn't override an inherited setter.",
-          correction: "Try updating this class to match the superclass, or "
-              "removing the override annotation.",
-          hasPublishedDocs: true);
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = HintCode(
+    'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+    "The setter doesn't override an inherited setter.",
+    correction: "Try updating this class to match the superclass, or "
+        "removing the override annotation.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER',
+  );
 
   /**
    * It is a bad practice for a package import to reference anything outside the
@@ -1879,6 +1884,7 @@
   // diagnostic:
   //
   // ```dart
+  // %language=2.9
   // class C {}
   // const C a = null;
   // const C b = null;
@@ -1900,6 +1906,7 @@
   // expression isn't in a [constant context][]:
   //
   // ```dart
+  // %language=2.9
   // class C {}
   // const C a = null;
   // const C b = null;
@@ -2113,6 +2120,7 @@
   // diagnostic:
   //
   // ```dart
+  // %language=2.9
   // [!Never!] n;
   // ```
   //
@@ -2501,7 +2509,6 @@
   // `null`, so the comparison always evaluates to `true`:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int x) {
   //   if (x [!!= null!]) {
   //     print(x);
@@ -2513,7 +2520,6 @@
   // `null`, so the comparison always evaluates to `false`:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int x) {
   //   if (x [!== null!]) {
   //     throw ArgumentError("x can't be null");
@@ -2527,7 +2533,6 @@
   // the operand:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int? x) {
   //   if (x != null) {
   //     print(x);
@@ -2538,52 +2543,53 @@
   // If the other operand really can't be `null`, then remove the condition:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int x) {
   //   print(x);
   // }
   // ```
-  static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE =
-      HintCodeWithUniqueName(
-          'UNNECESSARY_NULL_COMPARISON',
-          'UNNECESSARY_NULL_COMPARISON_FALSE',
-          "The operand can't be null, so the condition is always false.",
-          correction: "Try removing the condition, an enclosing condition, "
-              "or the whole conditional statement.",
-          hasPublishedDocs: true);
+  static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE = HintCode(
+    'UNNECESSARY_NULL_COMPARISON',
+    "The operand can't be null, so the condition is always false.",
+    correction: "Try removing the condition, an enclosing condition, "
+        "or the whole conditional statement.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNNECESSARY_NULL_COMPARISON_FALSE',
+  );
 
   /**
    * No parameters.
    */
-  static const HintCode UNNECESSARY_NULL_COMPARISON_TRUE =
-      HintCodeWithUniqueName(
-          'UNNECESSARY_NULL_COMPARISON',
-          'UNNECESSARY_NULL_COMPARISON_TRUE',
-          "The operand can't be null, so the condition is always true.",
-          correction: "Remove the condition.",
-          hasPublishedDocs: true);
+  static const HintCode UNNECESSARY_NULL_COMPARISON_TRUE = HintCode(
+    'UNNECESSARY_NULL_COMPARISON',
+    "The operand can't be null, so the condition is always true.",
+    correction: "Remove the condition.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNNECESSARY_NULL_COMPARISON_TRUE',
+  );
 
   /**
    * Unnecessary type checks, the result is always false.
    *
    * No parameters.
    */
-  static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCodeWithUniqueName(
-      'UNNECESSARY_TYPE_CHECK',
-      'UNNECESSARY_TYPE_CHECK_FALSE',
-      "Unnecessary type check, the result is always false.",
-      correction: "Try correcting the type check, or removing the type check.");
+  static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCode(
+    'UNNECESSARY_TYPE_CHECK',
+    "Unnecessary type check, the result is always false.",
+    correction: "Try correcting the type check, or removing the type check.",
+    uniqueName: 'UNNECESSARY_TYPE_CHECK_FALSE',
+  );
 
   /**
    * Unnecessary type checks, the result is always true.
    *
    * No parameters.
    */
-  static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = HintCodeWithUniqueName(
-      'UNNECESSARY_TYPE_CHECK',
-      'UNNECESSARY_TYPE_CHECK_TRUE',
-      "Unnecessary type check, the result is always true.",
-      correction: "Try correcting the type check, or removing the type check.");
+  static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = HintCode(
+    'UNNECESSARY_TYPE_CHECK',
+    "Unnecessary type check, the result is always true.",
+    correction: "Try correcting the type check, or removing the type check.",
+    uniqueName: 'UNNECESSARY_TYPE_CHECK_TRUE',
+  );
 
   /**
    * Parameters:
@@ -2703,6 +2709,7 @@
   // invocation of `_m`, the following code produces this diagnostic:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   void _m(int x, [int [!y!]]) {}
   //
@@ -2732,12 +2739,13 @@
    * Parameters:
    * 0: the name of the parameter that is declared but not used
    */
-  static const HintCode UNUSED_ELEMENT_PARAMETER = HintCodeWithUniqueName(
-      'UNUSED_ELEMENT',
-      'HintCode.UNUSED_ELEMENT_PARAMETER',
-      "A value for optional parameter '{0}' isn't ever given.",
-      correction: "Try removing the unused parameter.",
-      hasPublishedDocs: true);
+  static const HintCode UNUSED_ELEMENT_PARAMETER = HintCode(
+    'UNUSED_ELEMENT',
+    "A value for optional parameter '{0}' isn't ever given.",
+    correction: "Try removing the unused parameter.",
+    hasPublishedDocs: true,
+    uniqueName: 'HintCode.UNUSED_ELEMENT_PARAMETER',
+  );
 
   /**
    * Parameters:
@@ -2754,6 +2762,7 @@
   // anywhere in the library:
   //
   // ```dart
+  // %language=2.9
   // class Point {
   //   int [!_x!];
   // }
@@ -2923,10 +2932,19 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const HintCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+  const HintCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'HintCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.HINT.severity;
@@ -2934,15 +2952,3 @@
   @override
   ErrorType get type => ErrorType.HINT;
 }
-
-/// A [HintCode] class in which a [uniqueName] can be given which is not just
-/// derived from [name].
-class HintCodeWithUniqueName extends HintCode {
-  @override
-  final String uniqueName;
-
-  const HintCodeWithUniqueName(String name, this.uniqueName, String message,
-      {String correction, bool hasPublishedDocs})
-      : super(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
-}
diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
index 5b5e320..cc1f0c2 100644
--- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
@@ -10,8 +10,17 @@
 /// compiler, lint recommendations focus on matters of style and practices that
 /// might aggregated to define a project's style guide.
 class LintCode extends ErrorCode {
-  const LintCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+  const LintCode(
+    String name,
+    String message, {
+    String correction,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'LintCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
@@ -22,12 +31,6 @@
   @override
   ErrorType get type => ErrorType.LINT;
 
-  /// Overridden so that [LintCode] and its subclasses share the same uniqueName
-  /// pattern (we know how to identify a lint even if we don't know the specific
-  /// subclass the lint's code is defined in.
-  @override
-  String get uniqueName => "LintCode.$name";
-
   @override
   String get url => 'https://dart-lang.github.io/linter/lints/$name.html';
 
@@ -36,13 +39,11 @@
       other is LintCode && uniqueName == other.uniqueName;
 }
 
+@Deprecated('Use SecurityLintCode and its uniqueName')
 class LintCodeWithUniqueName extends LintCode {
-  @override
-  final String uniqueName;
-
-  const LintCodeWithUniqueName(String name, this.uniqueName, String message,
+  const LintCodeWithUniqueName(String name, String uniqueName, String message,
       {String correction})
-      : super(name, message, correction: correction);
+      : super(name, message, uniqueName: uniqueName, correction: correction);
 }
 
 /// Defines security-related best practice recommendations.
@@ -50,19 +51,19 @@
 /// The primary difference from [LintCode]s is that these codes cannot be
 /// suppressed with `// ignore:` or `// ignore_for_file:` comments.
 class SecurityLintCode extends LintCode {
-  const SecurityLintCode(String name, String message, {String correction})
-      : super(name, message, correction: correction);
+  const SecurityLintCode(String name, String message,
+      {String uniqueName, String correction})
+      : super(name, message,
+            uniqueName: uniqueName ?? 'LintCode.$name', correction: correction);
 
   @override
   bool get isIgnorable => false;
 }
 
+@Deprecated('Use SecurityLintCode and its uniqueName')
 class SecurityLintCodeWithUniqueName extends SecurityLintCode {
-  @override
-  final String uniqueName;
-
   const SecurityLintCodeWithUniqueName(
-      String name, this.uniqueName, String message,
+      String name, String uniqueName, String message,
       {String correction})
-      : super(name, message, correction: correction);
+      : super(name, message, uniqueName: uniqueName, correction: correction);
 }
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 46bede3..8472e01 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -309,6 +309,7 @@
   // field:
   //
   // ```dart
+  // %language=2.9
   // extension E on String {
   //   String [!s!];
   // }
@@ -923,11 +924,19 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ParserErrorCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false);
+  const ParserErrorCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'ParserErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/lib/src/dart/error/todo_codes.dart b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
index fe6ed97..15db063 100644
--- a/pkg/analyzer/lib/src/dart/error/todo_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
@@ -37,7 +37,12 @@
   /**
    * Initialize a newly created error code to have the given [name].
    */
-  const TodoCode(String name) : super.temporary(name, "{0}");
+  const TodoCode(String name)
+      : super(
+          message: "{0}",
+          name: name,
+          uniqueName: 'TodoCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
index 9fd158d..2d4c16b 100644
--- a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
@@ -35,10 +35,17 @@
   void release(Iterable<int> ids);
 }
 
+class CiderByteStoreTestView {
+  int length = 0;
+}
+
 class CiderCachedByteStore implements CiderByteStore {
   final Cache<String, CiderCacheEntry> _cache;
   int idCounter = 0;
 
+  /// This field gets value only during testing.
+  CiderByteStoreTestView testView;
+
   CiderCachedByteStore(int maxCacheSize)
       : _cache = Cache<String, CiderCacheEntry>(
             maxCacheSize, (v) => v.data.bytes.length);
@@ -59,6 +66,7 @@
     idCounter++;
     var entry = CiderCacheEntry(signature, CacheData(idCounter, bytes));
     _cache.put(key, entry);
+    testView?.length++;
     return entry.data;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index 00352e2..44ab5b5 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -714,21 +714,24 @@
         _inheritance, _libraryElement, source, _typeProvider, errorListener,
         featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper);
 
+    var donePartialResolution = false;
     if (completionOffset != null) {
       var node = NodeLocator(completionOffset).searchWithin(unit);
-      var enclosingExecutable = node?.thisOrAncestorMatching((e) {
-        return e.parent is ClassDeclaration || e.parent is CompilationUnit;
+      var nodeToResolve = node?.thisOrAncestorMatching((e) {
+        return e.parent is ClassDeclaration ||
+            e.parent is CompilationUnit ||
+            e.parent is MixinDeclaration;
       });
-
-      if (enclosingExecutable != null) {
-        var enclosingClass = enclosingExecutable.parent;
-        if (enclosingClass is ClassDeclaration) {
-          resolverVisitor.enclosingClass = enclosingClass.declaredElement;
+      if (nodeToResolve != null) {
+        var can = resolverVisitor.prepareForResolving(nodeToResolve);
+        if (can) {
+          nodeToResolve?.accept(resolverVisitor);
+          donePartialResolution = true;
         }
-
-        enclosingExecutable?.accept(resolverVisitor);
       }
-    } else {
+    }
+
+    if (!donePartialResolution) {
       unit.accept(resolverVisitor);
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 527a89b..26887ce 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:collection';
 import 'dart:convert';
 import 'dart:typed_data';
 
@@ -28,7 +29,6 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
-import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
@@ -136,6 +136,18 @@
   /// Return the [uri] string.
   String get uriStr => uri.toString();
 
+  /// Recursively traverse imports, exports, and parts to collect all
+  /// files that are accessed.
+  void collectAllReferencedFiles(Set<String> referencedFiles) {
+    var deps = {...importedFiles, ...exportedFiles, ...partedFiles};
+    for (var file in deps) {
+      if (!referencedFiles.contains(file.path)) {
+        referencedFiles.add(file.path);
+        file.collectAllReferencedFiles(referencedFiles);
+      }
+    }
+  }
+
   /// Return the content of the file, the empty string if cannot be read.
   String getContent() {
     try {
@@ -412,7 +424,6 @@
         ),
       );
     }
-    var informativeData = createInformativeData(unit);
     var unlinkedBuilder = UnlinkedUnit2Builder(
       apiSignature: computeUnlinkedApiSignature(unit),
       exports: exports,
@@ -422,7 +433,6 @@
       hasPartOfDirective: hasPartOfDirective,
       partOfUri: partOfUriStr,
       lineStarts: unit.lineInfo.lineStarts,
-      informativeData: informativeData,
     );
     return CiderUnlinkedUnitBuilder(
         contentDigest: digest, unlinkedUnit: unlinkedBuilder);
@@ -506,6 +516,13 @@
     }
   }
 
+  /// Clears all the cached files. Returns the list of ids of all the removed
+  /// files.
+  Set<int> collectSharedDataIdentifiers() {
+    var files = _pathToFile.values.map((file) => file.id).toSet();
+    return files;
+  }
+
   FeatureSet contextFeatureSet(
     String path,
     Uri uri,
@@ -601,10 +618,34 @@
     }
     return source.fullName;
   }
+
+  /// Computes the set of [FileState]'s used/not used to analyze the given
+  /// [files]. Removes the [FileState]'s of the files not used for analysis from
+  /// the cache. Returns the set of unused [FileState]'s.
+  List<FileState> removeUnusedFiles(List<String> files) {
+    var removedFiles = <FileState>[];
+    var unusedFiles = _pathToFile.keys.toSet();
+    var deps = HashSet<String>();
+    for (var path in files) {
+      unusedFiles.remove(path);
+      _pathToFile[path].collectAllReferencedFiles(deps);
+    }
+    for (var path in deps) {
+      unusedFiles.remove(path);
+    }
+    for (var path in unusedFiles) {
+      var file = _pathToFile.remove(path);
+      _uriToFile.remove(file.uri);
+      removedFiles.add(file);
+    }
+    testView.unusedFiles = unusedFiles;
+    return removedFiles;
+  }
 }
 
 class FileSystemStateTestView {
   final List<String> refreshedFiles = [];
+  Set<String> unusedFiles = {};
 }
 
 class FileSystemStateTimer {
@@ -664,8 +705,11 @@
   /// The hash of all the paths of the files in this cycle.
   String cyclePathsHash;
 
-  /// id of the cache entry.
-  int id;
+  /// id of the ast cache entry.
+  int astId;
+
+  /// id of the resolution cache entry.
+  int resolutionId;
 
   LibraryCycle();
 
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index b0e1808..29516e9 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -29,8 +29,8 @@
 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/summary2/bundle_reader.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';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/options.dart';
@@ -147,6 +147,13 @@
     }
   }
 
+  /// Collects all the cached artifacts and add all the cache id's for the
+  /// removed artifacts to [removedCacheIds].
+  void collectSharedDataIdentifiers() {
+    removedCacheIds.addAll(fsState.collectSharedDataIdentifiers());
+    removedCacheIds.addAll(libraryContext.collectSharedDataIdentifiers());
+  }
+
   @deprecated
   void dispose() {}
 
@@ -304,6 +311,17 @@
     removedCacheIds.clear();
   }
 
+  /// Remove cached [FileState]'s that were not used in the current analysis
+  /// session. The list of files analyzed is used to compute the set of unused
+  /// [FileState]'s. Adds the cache id's for the removed [FileState]'s to
+  /// [removedCacheIds].
+  void removeFilesNotNecessaryForAnalysisOf(List<String> files) {
+    var removedFiles = fsState.removeUnusedFiles(files);
+    for (var removedFile in removedFiles) {
+      removedCacheIds.add(removedFile.id);
+    }
+  }
+
   /// The [completionLine] and [completionColumn] are zero based.
   ResolvedUnitResult resolve({
     int completionLine,
@@ -620,13 +638,23 @@
     );
   }
 
+  /// Clears all the loaded libraries. Returns the cache ids for the removed
+  /// artifacts.
+  Set<int> collectSharedDataIdentifiers() {
+    var idSet = <int>{};
+    for (var cycle in loadedBundles) {
+      idSet.add(cycle.astId);
+      idSet.add(cycle.resolutionId);
+    }
+    loadedBundles.clear();
+    return idSet;
+  }
+
   /// Load data required to access elements of the given [targetLibrary].
   void load2({
     @required FileState targetLibrary,
     @required OperationPerformanceImpl performance,
   }) {
-    var inputBundles = <LinkedNodeBundle>[];
-
     var librariesLinked = 0;
     var librariesLinkedTimer = Stopwatch();
     var inputsTimer = Stopwatch();
@@ -639,11 +667,14 @@
 
       cycle.directDependencies.forEach(loadBundle);
 
-      var key = cycle.cyclePathsHash;
-      var data = byteStore.get(key, cycle.signature);
-      var bytes = data?.bytes;
+      var astKey = '${cycle.cyclePathsHash}.ast';
+      var resolutionKey = '${cycle.cyclePathsHash}.resolution';
+      var astData = byteStore.get(astKey, cycle.signature);
+      var resolutionData = byteStore.get(resolutionKey, cycle.signature);
+      var astBytes = astData?.bytes;
+      var resolutionBytes = resolutionData?.bytes;
 
-      if (bytes == null) {
+      if (astBytes == null || resolutionBytes == null) {
         librariesLinkedTimer.start();
 
         inputsTimer.start();
@@ -688,39 +719,38 @@
         }
         inputsTimer.stop();
 
-        var linkResult = link2.link(elementFactory, inputLibraries);
+        var linkResult = link2.link(elementFactory, inputLibraries, true);
         librariesLinked += cycle.libraries.length;
 
-        bytes = serializeBundle(cycle.signature, linkResult).toBuffer();
+        astBytes = linkResult.astBytes;
+        resolutionBytes = linkResult.resolutionBytes;
 
-        data = byteStore.putGet(key, cycle.signature, bytes);
-        bytes = data.bytes;
-        performance.getDataInt('bytesPut').add(bytes.length);
+        astData = byteStore.putGet(astKey, cycle.signature, astBytes);
+        astBytes = astData.bytes;
+        performance.getDataInt('bytesPut').add(astBytes.length);
+
+        resolutionData =
+            byteStore.putGet(resolutionKey, cycle.signature, resolutionBytes);
+        resolutionBytes = resolutionData.bytes;
+        performance.getDataInt('bytesPut').add(resolutionBytes.length);
 
         librariesLinkedTimer.stop();
       } else {
-        performance.getDataInt('bytesGet').add(bytes.length);
+        performance.getDataInt('bytesGet').add(astBytes.length);
+        performance.getDataInt('bytesGet').add(resolutionBytes.length);
         performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
       }
-      cycle.id = data.id;
+      cycle.astId = astData.id;
+      cycle.resolutionId = resolutionData.id;
 
-      var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
-      inputBundles.add(cBundle.bundle);
       elementFactory.addBundle(
-        LinkedBundleContext(elementFactory, cBundle.bundle),
+        BundleReader(
+          elementFactory: elementFactory,
+          astBytes: astBytes,
+          resolutionBytes: resolutionBytes,
+        ),
       );
 
-      // Set informative data.
-      for (var libraryFile in cycle.libraries) {
-        for (var unitFile in libraryFile.libraryFiles) {
-          elementFactory.setInformativeData(
-            libraryFile.uriStr,
-            unitFile.uriStr,
-            unitFile.unlinked2.informativeData,
-          );
-        }
-      }
-
       // We might have just linked dart:core, ensure the type provider.
       _createElementFactoryTypeProvider();
     }
@@ -746,7 +776,8 @@
     var removedSet = removed.toSet();
     loadedBundles.removeWhere((cycle) {
       if (cycle.libraries.any(removedSet.contains)) {
-        removedIds.add(cycle.id);
+        removedIds.add(cycle.astId);
+        removedIds.add(cycle.resolutionId);
         return true;
       }
       return false;
@@ -762,12 +793,4 @@
       elementFactory.createTypeProviders(dartCore, dartAsync);
     }
   }
-
-  static CiderLinkedLibraryCycleBuilder serializeBundle(
-      List<int> signature, link2.LinkResult linkResult) {
-    return CiderLinkedLibraryCycleBuilder(
-      signature: signature,
-      bundle: linkResult.bundle,
-    );
-  }
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 1b4b7a0..a07074f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -312,8 +312,19 @@
     return typeArgs;
   }
 
+  bool _isCallToIdentical(AstNode invocation) {
+    if (invocation is MethodInvocation) {
+      var invokedMethod = invocation.methodName.staticElement;
+      return invokedMethod != null &&
+          invokedMethod.name == 'identical' &&
+          invokedMethod.library.isDartCore;
+    }
+    return false;
+  }
+
   void _resolveArguments(ArgumentList argumentList) {
-    argumentList.accept(_resolver);
+    _resolver.visitArgumentList(argumentList,
+        isIdentical: _isCallToIdentical(argumentList.parent));
   }
 
   void _resolveInvocation({
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 858f235..8ad526f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -726,7 +726,7 @@
       _withNameScope(() {
         _buildTypeParameterElements(node.typeParameters);
         node.typeParameters?.accept(this);
-        node.functionType?.accept(this);
+        node.type?.accept(this);
       });
     });
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
index c32b116..d3b354b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
@@ -245,7 +245,7 @@
         node.staticType = _typeProvider.typeType;
       }
       return;
-    } else if (element is FunctionTypeAliasElement) {
+    } else if (element is TypeAliasElement) {
       if (node.inDeclarationContext() || node.parent is TypeName) {
         // no type
       } else {
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
index a880d32..c077118 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -133,7 +133,7 @@
       return const <DartType>[];
     }
 
-    var typeArguments = List<DartType>(parameterCount);
+    var typeArguments = List<DartType>.filled(parameterCount, null);
     for (var i = 0; i < parameterCount; i++) {
       typeArguments[i] = arguments[i].type;
     }
@@ -202,7 +202,7 @@
       } else if (element is DynamicElementImpl) {
         _buildTypeArguments(node, 0);
         return DynamicTypeImpl.instance;
-      } else if (element is FunctionTypeAliasElement) {
+      } else if (element is TypeAliasElement) {
         var typeArguments = _buildTypeArguments(
           node,
           element.typeParameters.length,
@@ -249,9 +249,9 @@
       return dynamicType;
     } else if (element is DynamicElementImpl) {
       return DynamicTypeImpl.instance;
-    } else if (element is FunctionTypeAliasElement) {
+    } else if (element is TypeAliasElement) {
       return typeSystem.instantiateToBounds2(
-        functionTypeAliasElement: element,
+        typeAliasElement: element,
         nullabilitySuffix: nullability,
       );
     } else if (element is NeverElementImpl) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index dcf0d9d..dc990de 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -233,7 +233,10 @@
 
     return ResolutionResult(
       getter: getter,
-      needsGetterError: _needsGetterError && !_reportedGetterError,
+      // Parser recovery resulting in an empty property name should not be
+      // reported as an undefined getter.
+      needsGetterError:
+          _needsGetterError && _name.isNotEmpty && !_reportedGetterError,
       setter: setter,
       needsSetterError: _needsSetterError && !_reportedSetterError,
     );
diff --git a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
index b36521c..e701244 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -768,8 +768,9 @@
       nullabilitySuffix: _noneOrStarSuffix,
     );
 
-    var parameters = List<ParameterElement>(2 * inferredTypes.length);
-    var argumentTypes = List<DartType>(2 * inferredTypes.length);
+    var parameters =
+        List<ParameterElement>.filled(2 * inferredTypes.length, null);
+    var argumentTypes = List<DartType>.filled(2 * inferredTypes.length, null);
     for (var i = 0; i < inferredTypes.length; i++) {
       parameters[2 * i + 0] = ParameterElementImpl.synthetic(
           'key', genericKeyType, ParameterKind.POSITIONAL);
@@ -802,8 +803,8 @@
       nullabilitySuffix: _noneOrStarSuffix,
     );
 
-    var parameters = List<ParameterElement>(inferredTypes.length);
-    var argumentTypes = List<DartType>(inferredTypes.length);
+    var parameters = List<ParameterElement>.filled(inferredTypes.length, null);
+    var argumentTypes = List<DartType>.filled(inferredTypes.length, null);
     for (var i = 0; i < inferredTypes.length; i++) {
       parameters[i] = ParameterElementImpl.synthetic(
           'element', genericElementType, ParameterKind.POSITIONAL);
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 5c3e5c9..0a0d0fa 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -142,7 +142,7 @@
   String _getPath(File file) {
     List<SdkLibrary> libraries = libraryMap.sdkLibraries;
     int length = libraries.length;
-    List<String> paths = List(length);
+    List<String> paths = List.filled(length, null);
     String filePath = getRelativePathFromFile(file);
     if (filePath == null) {
       return null;
diff --git a/pkg/analyzer/lib/src/error/analyzer_error_code.dart b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
index f8cb42d..a3543a2 100644
--- a/pkg/analyzer/lib/src/error/analyzer_error_code.dart
+++ b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
@@ -3,14 +3,24 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/error/error.dart';
+import 'package:meta/meta.dart';
 
 /// A superclass for error codes that can have a url associated with them.
 abstract class AnalyzerErrorCode extends ErrorCode {
   /// Initialize a newly created error code.
-  const AnalyzerErrorCode.temporary(String name, String message,
-      {String correction, bool hasPublishedDocs, bool isUnresolvedIdentifier})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false,
-            isUnresolvedIdentifier: isUnresolvedIdentifier ?? false);
+  const AnalyzerErrorCode({
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    @required String message,
+    @required String name,
+    @required String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName,
+        );
 }
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index acc8ac7..45b860a 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -928,7 +928,11 @@
       return;
     }
 
-    var importElement = node.element as ImportElement;
+    var importElement = node.element;
+    if (importElement == null) {
+      return;
+    }
+
     var importedLibrary = importElement.importedLibrary;
     if (importedLibrary == null || importedLibrary.isNonNullableByDefault) {
       return;
@@ -1360,17 +1364,17 @@
       _errorReporter.reportErrorForNode(
           HintCode.INVALID_REQUIRED_OPTIONAL_POSITIONAL_PARAM,
           param,
-          [param.identifier.name]);
+          [_formalParameterNameOrEmpty(param)]);
     }
     for (final param in nonNamedParamsWithRequired.where((p) => p.isRequired)) {
       _errorReporter.reportErrorForNode(
           HintCode.INVALID_REQUIRED_POSITIONAL_PARAM,
           param,
-          [param.identifier.name]);
+          [_formalParameterNameOrEmpty(param)]);
     }
     for (final param in namedParamsWithRequiredAndDefault) {
       _errorReporter.reportErrorForNode(HintCode.INVALID_REQUIRED_NAMED_PARAM,
-          param, [param.identifier.name]);
+          param, [_formalParameterNameOrEmpty(param)]);
     }
   }
 
@@ -1629,6 +1633,11 @@
     return true;
   }
 
+  static String _formalParameterNameOrEmpty(FormalParameter node) {
+    var identifier = node.identifier;
+    return identifier?.name ?? '';
+  }
+
   static bool _hasNonVirtualAnnotation(ExecutableElement element) {
     if (element == null) {
       return false;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index ed2da59..22fbfd8 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -36,7 +36,6 @@
   // `abstract` and has an initializer:
   //
   // ```dart
-  // %experiments=non-nullable
   // abstract class C {
   //   abstract int [!f!] = 0;
   // }
@@ -46,7 +45,6 @@
   // `abstract` and there's an initializer in the constructor:
   //
   // ```dart
-  // %experiments=non-nullable
   // abstract class C {
   //   abstract int f;
   //
@@ -59,7 +57,6 @@
   // If the field must be abstract, then remove the initializer:
   //
   // ```dart
-  // %experiments=non-nullable
   // abstract class C {
   //   abstract int f;
   // }
@@ -73,13 +70,13 @@
   // }
   // ```
   static const CompileTimeErrorCode ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER =
-      CompileTimeErrorCodeWithUniqueName(
-          'ABSTRACT_FIELD_INITIALIZER',
-          'ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER',
-          "Abstract fields can't have initializers.",
-          correction:
-              "Try removing the field initializer or the 'abstract' keyword "
-              "from the field declaration.");
+      CompileTimeErrorCode(
+    'ABSTRACT_FIELD_INITIALIZER',
+    "Abstract fields can't have initializers.",
+    correction: "Try removing the field initializer or the 'abstract' keyword "
+        "from the field declaration.",
+    uniqueName: 'ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER',
+  );
 
   /**
    * No parameters.
@@ -514,6 +511,7 @@
   // assigned to a `String`:
   //
   // ```dart
+  // %language=2.9
   // String f(String x) => x;
   // String g(num y) => f([!y!]);
   // ```
@@ -524,6 +522,7 @@
   // example above you might be able to change the type of the parameter `y`:
   //
   // ```dart
+  // %language=2.9
   // String f(String x) => x;
   // String g(String y) => f(y);
   // ```
@@ -533,6 +532,7 @@
   // types to the required type:
   //
   // ```dart
+  // %language=2.9
   // String f(String x) => x;
   // String g(num y) => f(y.toString());
   // ```
@@ -540,6 +540,7 @@
   // Another approach is to add explicit type tests and fallback code:
   //
   // ```dart
+  // %language=2.9
   // String f(String x) => x;
   // String g(num y) => f(y is String ? y : '');
   // ```
@@ -881,7 +882,6 @@
   // is used in the initializer for `v`, a local variable that is marked `late`:
   //
   // ```dart
-  // %experiments=non-nullable
   // Future<int> f() async {
   //   late var v = [!await!] 42;
   //   return v;
@@ -893,7 +893,6 @@
   // If the initializer can be rewritten to not use `await`, then rewrite it:
   //
   // ```dart
-  // %experiments=non-nullable
   // Future<int> f() async {
   //   late var v = 42;
   //   return v;
@@ -903,7 +902,6 @@
   // If the initializer can't be rewritten, then remove the `late` modifier:
   //
   // ```dart
-  // %experiments=non-nullable
   // Future<int> f() async {
   //   var v = await 42;
   //   return v;
@@ -946,7 +944,6 @@
   // is declared to not return `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int [!m!](int t) {
   //     print(t);
@@ -960,7 +957,6 @@
   // method is effectively declared to not return `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C<T> {
   //   T [!m!](T t) {
   //     print(t);
@@ -974,7 +970,6 @@
   // statement at the end of the method:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C<T> {
   //   T m(T t) {
   //     print(t);
@@ -987,7 +982,6 @@
   // end of the method:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C<T> {
   //   T m(T t) {
   //     print(t);
@@ -1000,7 +994,6 @@
   // return type so that it's valid to return `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C<T> {
   //   T? m(T t) {
   //     print(t);
@@ -1147,6 +1140,7 @@
   // with an assignment:
   //
   // ```dart
+  // %language=2.9
   // void f(int x) {
   //   switch (x) {
   //     [!case!] 0:
@@ -1162,6 +1156,7 @@
   // Add one of the required terminators:
   //
   // ```dart
+  // %language=2.9
   // void f(int x) {
   //   switch (x) {
   //     case 0:
@@ -1210,7 +1205,6 @@
   // isn't a subtype of `String` (the type of `s`):
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String s) {
   //   switch (s) {
   //     case [!1!]:
@@ -1225,7 +1219,6 @@
   // expression so that it has the required type:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String s) {
   //   switch (s) {
   //     case '1':
@@ -1238,7 +1231,6 @@
   // expression to have the required type:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int s) {
   //   switch (s) {
   //     case 1:
@@ -1452,12 +1444,13 @@
    * 0: the name of the type variable
    */
   static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
-          'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
-          "'{0}' can't be used to name both a type variable and the class in "
-              "which the type variable is defined.",
-          correction: "Try renaming either the type variable or the class.");
+      CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
+    "'{0}' can't be used to name both a type variable and the class in "
+        "which the type variable is defined.",
+    correction: "Try renaming either the type variable or the class.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
+  );
 
   /**
    * It is a compile time error if an extension declares a type parameter with
@@ -1467,13 +1460,13 @@
    * 0: the name of the type variable
    */
   static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_EXTENSION =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
-          'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION',
-          "'{0}' can't be used to name both a type variable and the extension "
-              "in which the type variable is defined.",
-          correction:
-              "Try renaming either the type variable or the extension.");
+      CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
+    "'{0}' can't be used to name both a type variable and the extension "
+        "in which the type variable is defined.",
+    correction: "Try renaming either the type variable or the extension.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION',
+  );
 
   /**
    * 7. Classes: It is a compile time error if a generic class declares a type
@@ -1484,25 +1477,26 @@
    * 0: the name of the type variable
    */
   static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
-          "'{0}' can't be used to name both a type variable and a member in "
-              "this class.",
-          correction: "Try renaming either the type variable or the member.");
+      CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
+    "'{0}' can't be used to name both a type variable and a member in "
+        "this class.",
+    correction: "Try renaming either the type variable or the member.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
+  );
 
   /**
    * It is a compile time error if a generic extension declares a member with
    * the same basename as the name of any of the extension's type parameters.
    */
   static const CompileTimeErrorCode
-      CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
-          'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
-          "'{0}' can't be used to name both a type variable and a member in "
-              "this extension.",
-          correction: "Try renaming either the type variable or the member.");
+      CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION = CompileTimeErrorCode(
+    'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
+    "'{0}' can't be used to name both a type variable and a member in "
+        "this extension.",
+    correction: "Try renaming either the type variable or the member.",
+    uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
+  );
 
   /**
    * 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -1648,14 +1642,15 @@
    * 0: the name of the instance field.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          "This constructor can't be declared 'const' because a mixin adds the "
-              "instance field: {0}.",
-          correction: "Try removing the 'const' keyword or removing the 'with' "
-              "clause from the class declaration, or removing the field from "
-              "the mixin class.");
+      CompileTimeErrorCode(
+    'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+    "This constructor can't be declared 'const' because a mixin adds the "
+        "instance field: {0}.",
+    correction: "Try removing the 'const' keyword or removing the 'with' "
+        "clause from the class declaration, or removing the field from "
+        "the mixin class.",
+    uniqueName: 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+  );
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1672,14 +1667,15 @@
    * 0: the names of the instance fields.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS =
-      CompileTimeErrorCodeWithUniqueName(
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
-          "This constructor can't be declared 'const' because the mixins add "
-              "the instance fields: {0}.",
-          correction: "Try removing the 'const' keyword or removing the 'with' "
-              "clause from the class declaration, or removing the fields from "
-              "the mixin classes.");
+      CompileTimeErrorCode(
+    'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+    "This constructor can't be declared 'const' because the mixins add "
+        "the instance fields: {0}.",
+    correction: "Try removing the 'const' keyword or removing the 'with' "
+        "clause from the class declaration, or removing the fields from "
+        "the mixin classes.",
+    uniqueName: 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
+  );
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1839,13 +1835,14 @@
    * 1: the name of the type of the field
    */
   static const CompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
-      CompileTimeErrorCodeWithUniqueName(
-          'FIELD_INITIALIZER_NOT_ASSIGNABLE',
-          'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
-          "The initializer type '{0}' can't be assigned to the field type "
-              "'{1}' in a const constructor.",
-          correction: "Try using a subtype, or removing the 'const' keyword",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FIELD_INITIALIZER_NOT_ASSIGNABLE',
+    "The initializer type '{0}' can't be assigned to the field type "
+        "'{1}' in a const constructor.",
+    correction: "Try using a subtype, or removing the 'const' keyword",
+    hasPublishedDocs: true,
+    uniqueName: 'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
+  );
 
   /**
    * No parameters.
@@ -2024,6 +2021,7 @@
   // `null`, which is neither a list nor a set:
   //
   // ```dart
+  // %language=2.9
   // const List<int> list1 = null;
   // const List<int> list2 = [...[!list1!]];
   // ```
@@ -2034,6 +2032,7 @@
   // or a constant set:
   //
   // ```dart
+  // %language=2.9
   // const List<int> list1 = [];
   // const List<int> list2 = [...list1];
   // ```
@@ -2056,6 +2055,7 @@
   // `null`, which isn't a map:
   //
   // ```dart
+  // %language=2.9
   // const Map<String, int> map1 = null;
   // const Map<String, int> map2 = {...[!map1!]};
   // ```
@@ -2065,6 +2065,7 @@
   // Change the expression to something that evaluates to a constant map:
   //
   // ```dart
+  // %language=2.9
   // const Map<String, int> map1 = {};
   // const Map<String, int> map2 = {...map1};
   // ```
@@ -2166,12 +2167,14 @@
    * Parameters:
    * 0: the name of the non-type element
    */
-  static const CompileTimeErrorCode CONST_WITH_NON_TYPE =
-      CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
-          'CONST_WITH_NON_TYPE', "The name '{0}' isn't a class.",
-          correction: "Try correcting the name to match an existing class.",
-          hasPublishedDocs: true,
-          isUnresolvedIdentifier: true);
+  static const CompileTimeErrorCode CONST_WITH_NON_TYPE = CompileTimeErrorCode(
+    'CREATION_WITH_NON_TYPE',
+    "The name '{0}' isn't a class.",
+    correction: "Try correcting the name to match an existing class.",
+    hasPublishedDocs: true,
+    isUnresolvedIdentifier: true,
+    uniqueName: 'CONST_WITH_NON_TYPE',
+  );
 
   /**
    * No parameters.
@@ -2268,7 +2271,6 @@
   // diagnostic because it uses the default `List` constructor:
   //
   // ```dart
-  // %experiments=non-nullable
   // var l = [!List<int>!]();
   // ```
   //
@@ -2278,7 +2280,6 @@
   // literal:
   //
   // ```dart
-  // %experiments=non-nullable
   // var l = <int>[];
   // ```
   //
@@ -2286,7 +2287,6 @@
   // initial value for the elements, then use `List.filled`:
   //
   // ```dart
-  // %experiments=non-nullable
   // var l = List.filled(3, 0);
   // ```
   //
@@ -2294,7 +2294,6 @@
   // computed, then use `List.generate`:
   //
   // ```dart
-  // %experiments=non-nullable
   // var l = List.generate(3, (i) => i);
   // ```
   static const CompileTimeErrorCode DEFAULT_LIST_CONSTRUCTOR =
@@ -2382,7 +2381,6 @@
   // value before being read:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(bool b) {
   //   late int x;
   //   print([!x!]);
@@ -2394,7 +2392,6 @@
   // Assign a value to the variable before reading from it:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(bool b) {
   //   late int x;
   //   x = b ? 1 : 0;
@@ -2485,24 +2482,26 @@
   // }
   // ```
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT =
-      CompileTimeErrorCodeWithUniqueName(
-          'DUPLICATE_CONSTRUCTOR',
-          'DUPLICATE_CONSTRUCTOR_DEFAULT',
-          "The default constructor is already defined.",
-          correction: "Try giving one of the constructors a name.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'DUPLICATE_CONSTRUCTOR',
+    "The default constructor is already defined.",
+    correction: "Try giving one of the constructors a name.",
+    hasPublishedDocs: true,
+    uniqueName: 'DUPLICATE_CONSTRUCTOR_DEFAULT',
+  );
 
   /**
    * Parameters:
    * 0: the name of the duplicate entity
    */
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME =
-      CompileTimeErrorCodeWithUniqueName(
-          'DUPLICATE_CONSTRUCTOR',
-          'DUPLICATE_CONSTRUCTOR_NAME',
-          "The constructor with name '{0}' is already defined.",
-          correction: "Try renaming one of the constructors.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'DUPLICATE_CONSTRUCTOR',
+    "The constructor with name '{0}' is already defined.",
+    correction: "Try renaming one of the constructors.",
+    hasPublishedDocs: true,
+    uniqueName: 'DUPLICATE_CONSTRUCTOR_NAME',
+  );
 
   /**
    * Parameters:
@@ -2536,6 +2535,14 @@
       correction: "Try renaming one of the declarations.",
       hasPublishedDocs: true);
 
+  static const CompileTimeErrorCode DUPLICATE_FIELD_FORMAL_PARAMETER =
+      CompileTimeErrorCode(
+          'DUPLICATE_FIELD_FORMAL_PARAMETER',
+          "The field '{0}' can't be referenced in multiple initializing "
+              "parameters in the same constructor.",
+          correction: "Try removing one of the parameters, or "
+              "using different fields.");
+
   /**
    * Parameters:
    * 0: the name of the parameter that was duplicated
@@ -2551,6 +2558,7 @@
   // with the name `a`:
   //
   // ```dart
+  // %language=2.9
   // void f(C c) {
   //   c.m(a: 0, [!a!]: 1);
   // }
@@ -2565,6 +2573,7 @@
   // If one of the arguments should have a different name, then change the name:
   //
   // ```dart
+  // %language=2.9
   // void f(C c) {
   //   c.m(a: 0, b: 1);
   // }
@@ -2577,6 +2586,7 @@
   // If one of the arguments is wrong, then remove it:
   //
   // ```dart
+  // %language=2.9
   // void f(C c) {
   //   c.m(a: 1);
   // }
@@ -2844,7 +2854,6 @@
   // from an opted-out library:
   //
   // ```dart
-  // %experiments=non-nullable
   // export [!'optedOut.dart'!];
   //
   // class C {}
@@ -2856,7 +2865,6 @@
   // need to opt out:
   //
   // ```dart
-  // %experiments=non-nullable
   // String? s;
   // ```
   //
@@ -3019,11 +3027,14 @@
   static const CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS =
       // TODO(scheglov) We might want to restore specific code with FrontEnd.
       //  https://github.com/dart-lang/sdk/issues/31821
-      CompileTimeErrorCodeWithUniqueName('SUBTYPE_OF_DISALLOWED_TYPE',
-          'EXTENDS_DISALLOWED_CLASS', "Classes can't extend '{0}'.",
-          correction: "Try specifying a different superclass, or "
-              "removing the extends clause.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "Classes can't extend '{0}'.",
+    correction: "Try specifying a different superclass, or "
+        "removing the extends clause.",
+    hasPublishedDocs: true,
+    uniqueName: 'EXTENDS_DISALLOWED_CLASS',
+  );
 
   /**
    * Parameters:
@@ -3472,6 +3483,7 @@
   // third argument:
   //
   // ```dart
+  // %language=2.9
   // void f(int a, int b, {int c}) {}
   // void g() {
   //   f[!(1, 2, 3)!];
@@ -3484,6 +3496,7 @@
   // the names before the arguments:
   //
   // ```dart
+  // %language=2.9
   // void f(int a, int b, {int c}) {}
   // void g() {
   //   f(1, 2, c: 3);
@@ -3494,6 +3507,7 @@
   // parameters:
   //
   // ```dart
+  // %language=2.9
   // void f(int a, int b, {int c}) {}
   // void g() {
   //   f(1, 2);
@@ -3857,12 +3871,13 @@
   // }
   // ```
   static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 =
-      CompileTimeErrorCodeWithUniqueName(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
-          "All final variables must be initialized, but '{0}' isn't.",
-          correction: "Try adding an initializer for the field.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+    "All final variables must be initialized, but '{0}' isn't.",
+    correction: "Try adding an initializer for the field.",
+    hasPublishedDocs: true,
+    uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
+  );
 
   /**
    * Parameters:
@@ -3870,13 +3885,14 @@
    * 1: the name of the uninitialized final variable
    */
   static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 =
-      CompileTimeErrorCodeWithUniqueName(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
-          "All final variables must be initialized, but '{0}' and '{1}' "
-              "aren't.",
-          correction: "Try adding initializers for the fields.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+    "All final variables must be initialized, but '{0}' and '{1}' "
+        "aren't.",
+    correction: "Try adding initializers for the fields.",
+    hasPublishedDocs: true,
+    uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
+  );
 
   /**
    * Parameters:
@@ -3885,13 +3901,14 @@
    * 2: the number of additional not initialized variables that aren't listed
    */
   static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
-      CompileTimeErrorCodeWithUniqueName(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
-          "All final variables must be initialized, but '{0}', '{1}', and {2} "
-              "others aren't.",
-          correction: "Try adding initializers for the fields.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+    "All final variables must be initialized, but '{0}', '{1}', and {2} "
+        "others aren't.",
+    correction: "Try adding initializers for the fields.",
+    hasPublishedDocs: true,
+    uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+  );
 
   /**
    * 17.6.2 For-in. It the iterable expression does not implement Iterable with
@@ -4016,7 +4033,6 @@
   // `num` isn't a subtype of `int`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   num get [!x!] => 0;
   //
@@ -4029,7 +4045,6 @@
   // If the type of the getter is correct, then change the type of the setter:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   num get x => 0;
   //
@@ -4040,7 +4055,6 @@
   // If the type of the setter is correct, then change the type of the getter:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int get x => 0;
   //
@@ -4210,13 +4224,14 @@
    * 0: The name of the disallowed type
    */
   static const CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'SUBTYPE_OF_DISALLOWED_TYPE',
-          'IMPLEMENTS_DISALLOWED_CLASS',
-          "Classes and mixins can't implement '{0}'.",
-          correction: "Try specifying a different interface, or "
-              "remove the class from the list.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "Classes and mixins can't implement '{0}'.",
+    correction: "Try specifying a different interface, or "
+        "remove the class from the list.",
+    hasPublishedDocs: true,
+    uniqueName: 'IMPLEMENTS_DISALLOWED_CLASS',
+  );
 
   /**
    * Parameters:
@@ -4463,6 +4478,7 @@
   // the signature of `m` that's inherited from `B`:
   //
   // ```dart
+  // %language=2.9
   // class A {
   //   void m({int a}) {}
   // }
@@ -4481,6 +4497,7 @@
   // signatures:
   //
   // ```dart
+  // %language=2.9
   // class A {
   //   void m({int a}) {}
   // }
@@ -4554,6 +4571,7 @@
   // initializing `x`, but `x` isn't a field in the class:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int y;
   //
@@ -4567,6 +4585,7 @@
   // name of the field:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int y;
   //
@@ -4577,6 +4596,7 @@
   // If the field must be declared, then add a declaration:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int x;
   //   int y;
@@ -4628,6 +4648,7 @@
   // defined:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int y;
   //
@@ -4641,6 +4662,7 @@
   // field:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int y;
   //
@@ -4652,6 +4674,7 @@
   // field:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int x;
   //   int y;
@@ -4664,6 +4687,7 @@
   // it to a normal parameter and use it:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int y;
   //
@@ -4674,6 +4698,7 @@
   // If the parameter isn't needed, then remove it:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int y;
   //
@@ -4811,6 +4836,7 @@
   // is being referenced in a static method:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int x;
   //
@@ -4826,6 +4852,7 @@
   // so remove the keyword:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int x;
   //
@@ -4839,6 +4866,7 @@
   // that an instance of the class can be passed in:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   int x;
   //
@@ -5039,10 +5067,13 @@
    * No parameters.
    */
   static const CompileTimeErrorCode INVALID_ANNOTATION_GETTER =
-      CompileTimeErrorCodeWithUniqueName('INVALID_ANNOTATION',
-          'INVALID_ANNOTATION_GETTER', "Getters can't be used as annotations.",
-          correction: "Try using a top-level variable or a field.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'INVALID_ANNOTATION',
+    "Getters can't be used as annotations.",
+    correction: "Try using a top-level variable or a field.",
+    hasPublishedDocs: true,
+    uniqueName: 'INVALID_ANNOTATION_GETTER',
+  );
 
   /**
    * Parameters:
@@ -5545,39 +5576,39 @@
   // List<T> newList<T>() => <T>[];
   // ```
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST =
-      CompileTimeErrorCodeWithUniqueName(
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
-          "Constant list literals can't include a type parameter as a type "
-              "argument, such as '{0}'.",
-          correction:
-              "Try replacing the type parameter with a different type.");
+      CompileTimeErrorCode(
+    'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+    "Constant list literals can't include a type parameter as a type "
+        "argument, such as '{0}'.",
+    correction: "Try replacing the type parameter with a different type.",
+    uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
+  );
 
   /**
    * Parameters:
    * 0: the name of the type parameter
    */
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP =
-      CompileTimeErrorCodeWithUniqueName(
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
-          'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
-          "Constant map literals can't include a type parameter as a type "
-              "argument, such as '{0}'.",
-          correction:
-              "Try replacing the type parameter with a different type.");
+      CompileTimeErrorCode(
+    'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+    "Constant map literals can't include a type parameter as a type "
+        "argument, such as '{0}'.",
+    correction: "Try replacing the type parameter with a different type.",
+    uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
+  );
 
   /**
    * Parameters:
    * 0: the name of the type parameter
    */
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_SET =
-      CompileTimeErrorCodeWithUniqueName(
-          'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
-          'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
-          "Constant set literals can't include a type parameter as a type "
-              "argument, such as '{0}'.",
-          correction:
-              "Try replacing the type parameter with a different type.");
+      CompileTimeErrorCode(
+    'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+    "Constant set literals can't include a type parameter as a type "
+        "argument, such as '{0}'.",
+    correction: "Try replacing the type parameter with a different type.",
+    uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
+  );
 
   /**
    * Parameters:
@@ -5628,7 +5659,6 @@
   // `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f(Null x) {
   //   return [!x!].length;
   // }
@@ -5640,7 +5670,6 @@
   // type of the expression:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f(String? x) {
   //   return x!.length;
   // }
@@ -5884,7 +5913,6 @@
   // `const` constructor and the `final` field `f` is marked as `late`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class A {
   //   [!late!] final int f;
   //
@@ -5909,7 +5937,6 @@
   // the constructors:
   //
   // ```dart
-  // %experiments=non-nullable
   // class A {
   //   late final int f;
   //
@@ -5941,7 +5968,6 @@
   // `v` is assigned a value in two places:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f() {
   //   late final int v;
   //   v = 0;
@@ -5956,7 +5982,6 @@
   // keyword:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f() {
   //   late int v;
   //   v = 0;
@@ -5969,7 +5994,6 @@
   // first of the assignments:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f() {
   //   late final int v;
   //   v = 0;
@@ -6075,7 +6099,6 @@
   // being used to declare a top-level variable:
   //
   // ```dart
-  // %experiments=non-nullable
   // var [!main!] = 3;
   // ```
   //
@@ -6084,7 +6107,6 @@
   // Use a different name for the declaration:
   //
   // ```dart
-  // %experiments=non-nullable
   // var mainIndex = 3;
   // ```
   static const CompileTimeErrorCode MAIN_IS_NOT_FUNCTION = CompileTimeErrorCode(
@@ -6269,14 +6291,12 @@
   // and no non-`null` default value is specified:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f([int [!x!]]) {}
   // ```
   //
   // As does this:
   //
   // ```dart
-  // %experiments=non-nullable
   // void g({int [!x!]}) {}
   // ```
   //
@@ -6286,7 +6306,6 @@
   // need to make the type nullable:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f([int? x]) {}
   // void g({int? x}) {}
   // ```
@@ -6294,7 +6313,6 @@
   // If the parameter can't be null, then either provide a default value:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f([int x = 1]) {}
   // void g({int x = 2}) {}
   // ```
@@ -6302,7 +6320,6 @@
   // or make the parameter a required parameter:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int x) {}
   // void g({required int x}) {}
   // ```
@@ -6310,9 +6327,10 @@
       CompileTimeErrorCode(
           'MISSING_DEFAULT_VALUE_FOR_PARAMETER',
           "The parameter '{0}' can't have a value of 'null' because of its "
-              "type, and no non-null default value is provided.",
+              "type, but the implicit default value is 'null'.",
           correction:
-              "Try adding either a default value or the 'required' modifier.",
+              "Try adding either an explicit non-'null' default value or the "
+              "'required' modifier.",
           hasPublishedDocs: true);
 
   /**
@@ -6330,7 +6348,6 @@
   // doesn't include a value for the required named parameter `end`:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int start, {required int end}) {}
   // void g() {
   //   [!f!](3);
@@ -6342,7 +6359,6 @@
   // Add a named argument corresponding to the missing required parameter:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(int start, {required int end}) {}
   // void g() {
   //   f(3, end: 5);
@@ -6487,11 +6503,14 @@
    * 0: The name of the disallowed type
    */
   static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS =
-      CompileTimeErrorCodeWithUniqueName('SUBTYPE_OF_DISALLOWED_TYPE',
-          'MIXIN_OF_DISALLOWED_CLASS', "Classes can't mixin '{0}'.",
-          correction: "Try specifying a different class or mixin, or "
-              "remove the class or mixin from the list.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "Classes can't mixin '{0}'.",
+    correction: "Try specifying a different class or mixin, or "
+        "remove the class or mixin from the list.",
+    hasPublishedDocs: true,
+    uniqueName: 'MIXIN_OF_DISALLOWED_CLASS',
+  );
 
   /**
    * No parameters.
@@ -6540,14 +6559,14 @@
    * 0: The name of the disallowed type
    */
   static const CompileTimeErrorCode
-      MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS =
-      CompileTimeErrorCodeWithUniqueName(
-          'SUBTYPE_OF_DISALLOWED_TYPE',
-          'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
-          "''{0}' can't be used as a superclass constraint.",
-          correction: "Try specifying a different super-class constraint, or "
-              "remove the 'on' clause.",
-          hasPublishedDocs: true);
+      MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS = CompileTimeErrorCode(
+    'SUBTYPE_OF_DISALLOWED_TYPE',
+    "''{0}' can't be used as a superclass constraint.",
+    correction: "Try specifying a different super-class constraint, or "
+        "remove the 'on' clause.",
+    hasPublishedDocs: true,
+    uniqueName: 'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
+  );
 
   /**
    * No parameters.
@@ -6664,12 +6683,14 @@
   //   f();
   // }
   // ```
-  static const CompileTimeErrorCode NEW_WITH_NON_TYPE =
-      CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
-          'NEW_WITH_NON_TYPE', "The name '{0}' isn't a class.",
-          correction: "Try correcting the name to match an existing class.",
-          hasPublishedDocs: true,
-          isUnresolvedIdentifier: true);
+  static const CompileTimeErrorCode NEW_WITH_NON_TYPE = CompileTimeErrorCode(
+    'CREATION_WITH_NON_TYPE',
+    "The name '{0}' isn't a class.",
+    correction: "Try correcting the name to match an existing class.",
+    hasPublishedDocs: true,
+    isUnresolvedIdentifier: true,
+    uniqueName: 'NEW_WITH_NON_TYPE',
+  );
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the
@@ -6855,12 +6876,13 @@
    *    constructor
    */
   static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT =
-      CompileTimeErrorCodeWithUniqueName(
-          'NO_DEFAULT_SUPER_CONSTRUCTOR',
-          'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
-          "The superclass '{0}' doesn't have a zero argument constructor.",
-          correction: "Try declaring a zero argument constructor in '{0}', or "
-              "explicitly invoking a different constructor in '{0}'.");
+      CompileTimeErrorCode(
+    'NO_DEFAULT_SUPER_CONSTRUCTOR',
+    "The superclass '{0}' doesn't have a zero argument constructor.",
+    correction: "Try declaring a zero argument constructor in '{0}', or "
+        "explicitly invoking a different constructor in '{0}'.",
+    uniqueName: 'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
+  );
 
   /**
    * User friendly specialized error for [NON_GENERATIVE_CONSTRUCTOR]. This
@@ -6884,13 +6906,14 @@
    * 1: the name of the subclass that does not contain any explicit constructors
    */
   static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT =
-      CompileTimeErrorCodeWithUniqueName(
-          'NO_DEFAULT_SUPER_CONSTRUCTOR',
-          'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
-          "The superclass '{0}' doesn't have a zero argument constructor.",
-          correction: "Try declaring a zero argument constructor in '{0}', or "
-              "declaring a constructor in {1} that explicitly invokes a "
-              "constructor in '{0}'.");
+      CompileTimeErrorCode(
+    'NO_DEFAULT_SUPER_CONSTRUCTOR',
+    "The superclass '{0}' doesn't have a zero argument constructor.",
+    correction: "Try declaring a zero argument constructor in '{0}', or "
+        "declaring a constructor in {1} that explicitly invokes a "
+        "constructor in '{0}'.",
+    uniqueName: 'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
+  );
 
   /**
    * Parameters:
@@ -6902,14 +6925,15 @@
    */
   static const CompileTimeErrorCode
       NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
-          "Missing concrete implementations of '{0}', '{1}', '{2}', '{3}', and "
-              "{4} more.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}', '{1}', '{2}', '{3}', and "
+        "{4} more.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
+  );
 
   /**
    * Parameters:
@@ -6919,14 +6943,14 @@
    * 3: the name of the fourth member
    */
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
-          "Missing concrete implementations of '{0}', '{1}', '{2}', and '{3}'.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}', '{1}', '{2}', and '{3}'.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
+  );
 
   /**
    * Parameters:
@@ -6992,14 +7016,14 @@
   // abstract class B extends A {}
   // ```
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
-          "Missing concrete implementation of '{0}'.",
-          correction: "Try implementing the missing method, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementation of '{0}'.",
+    correction: "Try implementing the missing method, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
+  );
 
   /**
    * Parameters:
@@ -7008,14 +7032,14 @@
    * 2: the name of the third member
    */
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
-          "Missing concrete implementations of '{0}', '{1}', and '{2}'.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}', '{1}', and '{2}'.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
+  );
 
   /**
    * Parameters:
@@ -7023,14 +7047,14 @@
    * 1: the name of the second member
    */
   static const CompileTimeErrorCode
-      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO =
-      CompileTimeErrorCodeWithUniqueName(
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
-          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
-          "Missing concrete implementations of '{0}' and '{1}'.",
-          correction: "Try implementing the missing methods, or make the class "
-              "abstract.",
-          hasPublishedDocs: true);
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = CompileTimeErrorCode(
+    'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+    "Missing concrete implementations of '{0}' and '{1}'.",
+    correction: "Try implementing the missing methods, or make the class "
+        "abstract.",
+    hasPublishedDocs: true,
+    uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
+  );
 
   /**
    * No parameters.
@@ -7299,6 +7323,7 @@
   // The following code produces this diagnostic:
   //
   // ```dart
+  // %language=2.9
   // var defaultValue = 3;
   //
   // void f([int value = [!defaultValue!]]) {}
@@ -7309,6 +7334,7 @@
   // If the default value can be converted to be a constant, then convert it:
   //
   // ```dart
+  // %language=2.9
   // const defaultValue = 3;
   //
   // void f([int value = defaultValue]) {}
@@ -7318,6 +7344,7 @@
   // value inside the function:
   //
   // ```dart
+  // %language=2.9
   // var defaultValue = 3;
   //
   // void f([int value]) {
@@ -7696,6 +7723,7 @@
   // a type:
   //
   // ```dart
+  // %language=2.9
   // void f() {
   //   try {
   //     // ...
@@ -7710,6 +7738,7 @@
   // Change the name to the type of object that should be caught:
   //
   // ```dart
+  // %language=2.9
   // void f() {
   //   try {
   //     // ...
@@ -7791,7 +7820,6 @@
   // of `null`, but is referenced before a value was assigned to it:
   //
   // ```dart
-  // %experiments=non-nullable
   // String f() {
   //   int x;
   //   return [!x!].toString();
@@ -7802,7 +7830,6 @@
   // might not be executed, so it might have a value of `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int g(bool b) {
   //   int x;
   //   if (b) {
@@ -7817,7 +7844,6 @@
   // without having a value assigned to it:
   //
   // ```dart
-  // %experiments=non-nullable
   // int h(bool b) {
   //   int x;
   //   if (b) {
@@ -7835,7 +7861,6 @@
   // If `null` is a valid value, then make the variable nullable:
   //
   // ```dart
-  // %experiments=non-nullable
   // String f() {
   //   int? x;
   //   return x!.toString();
@@ -7846,7 +7871,6 @@
   // add an initializer:
   //
   // ```dart
-  // %experiments=non-nullable
   // int g(bool b) {
   //   int x = 2;
   //   if (b) {
@@ -7860,7 +7884,6 @@
   // before the value is accessed:
   //
   // ```dart
-  // %experiments=non-nullable
   // int g(bool b) {
   //   int x;
   //   if (b) {
@@ -7879,7 +7902,6 @@
   // though the analyzer can't prove it based on definite assignment analysis.
   //
   // ```dart
-  // %experiments=non-nullable
   // int h(bool b) {
   //   late int x;
   //   if (b) {
@@ -7958,7 +7980,6 @@
   // initialized to `null` when it isn't allowed to be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int [!x!];
   // }
@@ -7970,7 +7991,6 @@
   // constructors:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int x;
   //
@@ -7986,7 +8006,6 @@
   // instances, then add an initializer expression:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int x = 0;
   // }
@@ -7997,7 +8016,6 @@
   // existing constructor:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int x;
   //
@@ -8011,7 +8029,6 @@
   // you're sure that the field will always be assigned before it's referenced.
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   late int x;
   // }
@@ -8031,14 +8048,15 @@
    */
   static const CompileTimeErrorCode
       NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR =
-      CompileTimeErrorCodeWithUniqueName(
-          'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
-          'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR',
-          "Non-nullable instance field '{0}' must be initialized.",
-          correction: "Try adding an initializer expression, "
-              "or add a field initializer in this constructor, "
-              "or mark it 'late'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
+    "Non-nullable instance field '{0}' must be initialized.",
+    correction: "Try adding an initializer expression, "
+        "or add a field initializer in this constructor, "
+        "or mark it 'late'.",
+    hasPublishedDocs: true,
+    uniqueName: 'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR',
+  );
 
   /**
    * Parameters:
@@ -8058,7 +8076,6 @@
   // initialized to `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   static int [!f!];
   // }
@@ -8068,7 +8085,6 @@
   // top-level variable `v` can't be initialized to `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int [!v!];
   // ```
   //
@@ -8078,7 +8094,6 @@
   // initializer that sets it to a non-null value:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   static int f = 0;
   // }
@@ -8088,7 +8103,6 @@
   // type to be nullable:
   //
   // ```dart
-  // %experiments=non-nullable
   // int? v;
   // ```
   //
@@ -8096,7 +8110,6 @@
   // always be initialized before it's referenced, then mark it as being `late`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   static late int f;
   // }
@@ -8209,7 +8222,6 @@
   // type, and nullable types can't be used in an `extends` clause:
   //
   // ```dart
-  // %experiments=non-nullable
   // class A {}
   // class B extends [!A?!] {}
   // ```
@@ -8219,7 +8231,6 @@
   // Remove the question mark from the type:
   //
   // ```dart
-  // %experiments=non-nullable
   // class A {}
   // class B extends A {}
   // ```
@@ -8251,7 +8262,6 @@
   // type, and nullable types can't be used in an `implements` clause:
   //
   // ```dart
-  // %experiments=non-nullable
   // class A {}
   // class B implements [!A?!] {}
   // ```
@@ -8261,7 +8271,6 @@
   // Remove the question mark from the type:
   //
   // ```dart
-  // %experiments=non-nullable
   // class A {}
   // class B implements A {}
   // ```
@@ -8294,7 +8303,6 @@
   // and nullable types can't be used in an `on` clause:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {}
   // mixin M on [!C?!] {}
   // ```
@@ -8304,7 +8312,6 @@
   // Remove the question mark from the type:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {}
   // mixin M on C {}
   // ```
@@ -8335,7 +8342,6 @@
   // type, and nullable types can't be used in a `with` clause:
   //
   // ```dart
-  // %experiments=non-nullable
   // mixin M {}
   // class C with [!M?!] {}
   // ```
@@ -8345,7 +8351,6 @@
   // Remove the question mark from the type:
   //
   // ```dart
-  // %experiments=non-nullable
   // mixin M {}
   // class C with M {}
   // ```
@@ -8624,7 +8629,7 @@
    */
   static const CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER =
       CompileTimeErrorCode('PRIVATE_OPTIONAL_PARAMETER',
-          "Named optional parameters can't start with an underscore.");
+          "Named parameters can't start with an underscore.");
 
   static const CompileTimeErrorCode PRIVATE_SETTER = CompileTimeErrorCode(
       'PRIVATE_SETTER',
@@ -9012,6 +9017,7 @@
   // is declared:
   //
   // ```dart
+  // %language=2.9
   // void f() {
   //   print([!i!]);
   //   int i = 5;
@@ -9024,6 +9030,7 @@
   // before the first reference:
   //
   // ```dart
+  // %language=2.9
   // void f() {
   //   int i = 5;
   //   print(i);
@@ -9035,6 +9042,7 @@
   // declaration so that it doesn't hide the outer variable.
   //
   // ```dart
+  // %language=2.9
   // void f(int i) {
   //   print(i);
   //   int x = 5;
@@ -9169,12 +9177,13 @@
    * 2: the name of the constructor
    */
   static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR =
-      CompileTimeErrorCodeWithUniqueName(
-          'RETURN_OF_INVALID_TYPE',
-          'RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR',
-          "A value of type '{0}' can't be returned from constructor '{2}' "
-              "because it has a return type of '{1}'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'RETURN_OF_INVALID_TYPE',
+    "A value of type '{0}' can't be returned from constructor '{2}' "
+        "because it has a return type of '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR',
+  );
 
   /**
    * Parameters:
@@ -9211,12 +9220,13 @@
   // int f() => 3;
   // ```
   static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_FUNCTION =
-      CompileTimeErrorCodeWithUniqueName(
-          'RETURN_OF_INVALID_TYPE',
-          'RETURN_OF_INVALID_TYPE_FROM_FUNCTION',
-          "A value of type '{0}' can't be returned from function '{2}' because "
-              "it has a return type of '{1}'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'RETURN_OF_INVALID_TYPE',
+    "A value of type '{0}' can't be returned from function '{2}' because "
+        "it has a return type of '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_FUNCTION',
+  );
 
   /**
    * Parameters:
@@ -9225,12 +9235,13 @@
    * 2: the name of the method
    */
   static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_METHOD =
-      CompileTimeErrorCodeWithUniqueName(
-          'RETURN_OF_INVALID_TYPE',
-          'RETURN_OF_INVALID_TYPE_FROM_METHOD',
-          "A value of type '{0}' can't be returned from method '{2}' because "
-              "it has a return type of '{1}'.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'RETURN_OF_INVALID_TYPE',
+    "A value of type '{0}' can't be returned from method '{2}' because "
+        "it has a return type of '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_METHOD',
+  );
 
   /**
    * No parameters.
@@ -9314,6 +9325,7 @@
   // field:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   static int a;
   //
@@ -9329,6 +9341,7 @@
   // to an existing static field:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   static int a;
   //
@@ -9342,6 +9355,7 @@
   // class to access the field:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   static int a;
   //
@@ -9463,6 +9477,7 @@
   // (`String`) isn't assignable to the type of `0` (`int`):
   //
   // ```dart
+  // %language=2.9
   // void f(String s) {
   //   switch ([!s!]) {
   //     case 0:
@@ -9477,6 +9492,7 @@
   // expression in the `switch` statement to have the correct type:
   //
   // ```dart
+  // %language=2.9
   // void f(String s) {
   //   switch (int.parse(s)) {
   //     case 0:
@@ -9489,6 +9505,7 @@
   // expressions to have the correct type:
   //
   // ```dart
+  // %language=2.9
   // void f(String s) {
   //   switch (s) {
   //     case '0':
@@ -9519,7 +9536,6 @@
   // The following code produces this diagnostic because `s` might be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String? s) {
   //   throw [!s!];
   // }
@@ -9530,7 +9546,6 @@
   // Add an explicit null check to the expression:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String? s) {
   //   throw s!;
   // }
@@ -9713,7 +9728,6 @@
   // the point where it's referenced:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String? s) {
   //   if ([!s!].length > 3) {
   //     // ...
@@ -9727,7 +9741,6 @@
   // are only accessed when the value isn't `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String? s) {
   //   if (s != null && s.length > 3) {
   //     // ...
@@ -9739,7 +9752,6 @@
   // change the type of the variable to be non-nullable:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String s) {
   //   if (s.length > 3) {
   //     // ...
@@ -9753,7 +9765,6 @@
   // that the value isn't null:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String? s) {
   //   if (s!.length > 3) {
   //     // ...
@@ -9939,13 +9950,13 @@
    * 0: the name of the superclass that does not define the invoked constructor
    */
   static const CompileTimeErrorCode
-      UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
-          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
-          "The class '{0}' doesn't have an unnamed constructor.",
-          correction: "Try defining an unnamed constructor in '{0}', or "
-              "invoking a different constructor.");
+      UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = CompileTimeErrorCode(
+    'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
+    "The class '{0}' doesn't have an unnamed constructor.",
+    correction: "Try defining an unnamed constructor in '{0}', or "
+        "invoking a different constructor.",
+    uniqueName: 'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
+  );
 
   /**
    * Parameters:
@@ -10519,6 +10530,7 @@
   // named parameter named `a`:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   m({int b}) {}
   // }
@@ -10534,6 +10546,7 @@
   // The example above can be fixed by changing `a` to `b`:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   m({int b}) {}
   // }
@@ -10547,6 +10560,7 @@
   // receiver to the subclass:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   m({int b}) {}
   // }
@@ -10563,6 +10577,7 @@
   // If the parameter should be added to the function, then add it:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   m({int a, int b}) {}
   // }
@@ -10708,14 +10723,14 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const CompileTimeErrorCode UNDEFINED_SUPER_GETTER =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_GETTER',
-          "The getter '{0}' isn't defined in a superclass of '{1}'.",
-          correction:
-              "Try correcting the name to the name of an existing getter, or "
-              "defining a getter or field named '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The getter '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try correcting the name to the name of an existing getter, or "
+        "defining a getter or field named '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_GETTER',
+  );
 
   /**
    * Parameters:
@@ -10763,14 +10778,14 @@
   // If the member isn’t defined, then either add the member to one of the
   // superclasses or remove the invocation.
   static const CompileTimeErrorCode UNDEFINED_SUPER_METHOD =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_METHOD',
-          "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.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "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.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_METHOD',
+  );
 
   /**
    * Parameters:
@@ -10778,12 +10793,13 @@
    * 1: the name of the enclosing type where the operator is being looked for
    */
   static const CompileTimeErrorCode UNDEFINED_SUPER_OPERATOR =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_OPERATOR',
-          "The operator '{0}' isn't defined in a superclass of '{1}'.",
-          correction: "Try defining the operator '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The operator '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try defining the operator '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_OPERATOR',
+  );
 
   /**
    * Parameters:
@@ -10791,14 +10807,14 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const CompileTimeErrorCode UNDEFINED_SUPER_SETTER =
-      CompileTimeErrorCodeWithUniqueName(
-          'UNDEFINED_SUPER_MEMBER',
-          'UNDEFINED_SUPER_SETTER',
-          "The setter '{0}' isn't defined in a superclass of '{1}'.",
-          correction:
-              "Try correcting the name to the name of an existing setter, or "
-              "defining a setter or field named '{0}' in a superclass.",
-          hasPublishedDocs: true);
+      CompileTimeErrorCode(
+    'UNDEFINED_SUPER_MEMBER',
+    "The setter '{0}' isn't defined in a superclass of '{1}'.",
+    correction: "Try correcting the name to the name of an existing setter, or "
+        "defining a setter or field named '{0}' in a superclass.",
+    hasPublishedDocs: true,
+    uniqueName: 'UNDEFINED_SUPER_SETTER',
+  );
 
   /**
    * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
@@ -11023,6 +11039,7 @@
   // `int`, which can't be assigned to `y` because an `int` isn't a `String`:
   //
   // ```dart
+  // %language=2.9
   // const Object x = 0;
   // const String y = [!x!];
   // ```
@@ -11033,6 +11050,7 @@
   // assigned to be of the correct type:
   //
   // ```dart
+  // %language=2.9
   // const Object x = 0;
   // const String y = '$x';
   // ```
@@ -11041,6 +11059,7 @@
   // correct type:
   //
   // ```dart
+  // %language=2.9
   // const Object x = 0;
   // const int y = x;
   // ```
@@ -11145,6 +11164,7 @@
   // two required parameters:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   set [!s!](int x, int y) {}
   // }
@@ -11154,6 +11174,7 @@
   // one optional parameter:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   set [!s!]([int x]) {}
   // }
@@ -11165,6 +11186,7 @@
   // parameter:
   //
   // ```dart
+  // %language=2.9
   // class C {
   //   set s(int x) {}
   // }
@@ -11409,14 +11431,21 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const CompileTimeErrorCode(String name, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
+  const CompileTimeErrorCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'CompileTimeErrorCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
@@ -11425,21 +11454,6 @@
   ErrorType get type => ErrorType.COMPILE_TIME_ERROR;
 }
 
-class CompileTimeErrorCodeWithUniqueName extends CompileTimeErrorCode {
-  @override
-  final String uniqueName;
-
-  const CompileTimeErrorCodeWithUniqueName(
-      String name, this.uniqueName, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
-}
-
 /**
  * This class has experimental Language-specific codes.
  *
@@ -11513,10 +11527,14 @@
    * created from the optional [correction] template.
    */
   const LanguageCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false);
+      {String correction, bool hasPublishedDocs = false})
+      : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'LanguageCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
@@ -11551,7 +11569,6 @@
   // The following code produces this diagnostic because `x` can't be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f(int x) {
   //   return x ?? [!0!];
   // }
@@ -11560,7 +11577,6 @@
   // The following code produces this diagnostic because `f` can't be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int f = -1;
   //
@@ -11576,7 +11592,6 @@
   // operator and the right operand:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f(int x) {
   //   return x;
   // }
@@ -11586,7 +11601,6 @@
   // needed, then remove the assignment:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int f = -1;
   //
@@ -11599,7 +11613,6 @@
   // then rewrite the code to use `=` and the different condition:
   //
   // ```dart
-  // %experiments=non-nullable
   // class C {
   //   int f = -1;
   //
@@ -11632,7 +11645,6 @@
   // The following code produces this diagnostic because `s` can't be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int? getLength(String s) {
   //   return s[!?.!]length;
   // }
@@ -11641,7 +11653,6 @@
   // The following code produces this diagnostic because `a` can't be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // var a = [];
   // var b = [[!...?!]a];
   // ```
@@ -11650,7 +11661,6 @@
   // return `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // void f(String? s) {
   //   s?.length[!?.!]isEven;
   // }
@@ -11671,7 +11681,6 @@
   // example, change `?.` to  `.`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int getLength(String s) {
   //   return s.length;
   // }
@@ -11693,14 +11702,14 @@
    * 1: The non-null-aware operator that can replace the invalid operator
    */
   static const StaticWarningCode
-      INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT =
-      StaticWarningCodeWithUniqueName(
-          'INVALID_NULL_AWARE_OPERATOR',
-          'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
-          "The receiver can't be null because of short-circuiting, so the "
-              "null-aware operator '{0}' can't be used.",
-          correction: "Try replacing the operator '{0}' with '{1}'.",
-          hasPublishedDocs: true);
+      INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT = StaticWarningCode(
+    'INVALID_NULL_AWARE_OPERATOR',
+    "The receiver can't be null because of short-circuiting, so the "
+        "null-aware operator '{0}' can't be used.",
+    correction: "Try replacing the operator '{0}' with '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
+  );
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -11814,7 +11823,6 @@
   // The following code produces this diagnostic because `x` can't be `null`:
   //
   // ```dart
-  // %experiments=non-nullable
   // int f(int x) {
   //   return x[!!!];
   // }
@@ -11825,7 +11833,6 @@
   // Remove the null check operator (`!`):
   //
   // ```dart
-  // %experiments=non-nullable
   // int f(int x) {
   //   return x;
   // }
@@ -11841,14 +11848,21 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const StaticWarningCode(String name, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
+  const StaticWarningCode(
+    String name,
+    String message, {
+    String correction,
+    bool hasPublishedDocs = false,
+    bool isUnresolvedIdentifier = false,
+    String uniqueName,
+  }) : super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          isUnresolvedIdentifier: isUnresolvedIdentifier,
+          message: message,
+          name: name,
+          uniqueName: uniqueName ?? 'StaticWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
@@ -11857,21 +11871,6 @@
   ErrorType get type => ErrorType.STATIC_WARNING;
 }
 
-class StaticWarningCodeWithUniqueName extends StaticWarningCode {
-  @override
-  final String uniqueName;
-
-  const StaticWarningCodeWithUniqueName(
-      String name, this.uniqueName, String message,
-      {String correction,
-      bool hasPublishedDocs,
-      bool isUnresolvedIdentifier = false})
-      : super(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs,
-            isUnresolvedIdentifier: isUnresolvedIdentifier);
-}
-
 /**
  * This class has Strong Mode specific error codes.
  *
@@ -11932,11 +11931,15 @@
    * created from the optional [correction] template.
    */
   const StrongModeCode(ErrorType type, String name, String message,
-      {String correction, bool hasPublishedDocs})
+      {String correction, bool hasPublishedDocs = false})
       : type = type,
-        super.temporary(name, message,
-            correction: correction,
-            hasPublishedDocs: hasPublishedDocs ?? false);
+        super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'StrongModeCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index e90e5de..0b5e1f1 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -367,7 +367,10 @@
     }
 
     ErrorCode getError(Element previous, Element current) {
-      if (previous is PrefixElement) {
+      if (previous is FieldFormalParameterElement &&
+          current is FieldFormalParameterElement) {
+        return CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER;
+      } else if (previous is PrefixElement) {
         return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
       }
       return CompileTimeErrorCode.DUPLICATE_DEFINITION;
@@ -383,7 +386,9 @@
       if (_isGetterSetterPair(element, previous)) {
         // OK
       } else if (element is FieldFormalParameterElement &&
-          previous is FieldFormalParameterElement) {
+          previous is FieldFormalParameterElement &&
+          element.field != null &&
+          element.field.isFinal) {
         // Reported as CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES.
       } else {
         _errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/error/ignore_validator.dart b/pkg/analyzer/lib/src/error/ignore_validator.dart
index 9f81675..a8dd8d8 100644
--- a/pkg/analyzer/lib/src/error/ignore_validator.dart
+++ b/pkg/analyzer/lib/src/error/ignore_validator.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/ignore_comments/ignore_info.dart';
+import 'package:meta/meta.dart';
 
 /// Used to validate the ignore comments in a single file.
 class IgnoreValidator {
@@ -29,7 +30,7 @@
   /// be ignored. Note that this list is incomplete. Plugins might well define
   /// diagnostics with a severity of `ERROR`, but we won't be able to flag their
   /// use because we have no visibility of them here.
-  final Set<String> unignorableNames = {};
+  Set<String> _unignorableNames;
 
   /// Initialize a newly created validator to report any issues with ignore
   /// comments in the file being analyzed. The diagnostics will be reported to
@@ -37,12 +38,7 @@
   IgnoreValidator(this._errorReporter, this._reportedErrors, this._ignoreInfo,
       this._lineInfo) {
     var filePath = _errorReporter.source.fullName;
-    for (var code in errorCodeValues) {
-      if (!isIgnorable(filePath, code)) {
-        unignorableNames.add(code.name.toLowerCase());
-        unignorableNames.add(code.uniqueName.toLowerCase());
-      }
-    }
+    _unignorableNames = _UnignorableNames.forFile(filePath);
   }
 
   /// Report any issues with ignore comments in the file being analyzed.
@@ -60,7 +56,7 @@
     var duplicated = <DiagnosticName>[];
     for (var ignoredName in ignoredForFile) {
       var name = ignoredName.name;
-      if (unignorableNames.contains(name)) {
+      if (_unignorableNames.contains(name)) {
         unignorable.add(ignoredName);
       } else if (!namesIgnoredForFile.add(name)) {
         duplicated.add(ignoredName);
@@ -73,7 +69,7 @@
       var duplicated = <DiagnosticName>[];
       for (var ignoredName in ignoredOnLine) {
         var name = ignoredName.name;
-        if (unignorableNames.contains(name)) {
+        if (_unignorableNames.contains(name)) {
           unignorable.add(ignoredName);
         } else if (namesIgnoredForFile.contains(name) ||
             !namedIgnoredOnLine.add(name)) {
@@ -137,6 +133,65 @@
   }
 
   static bool isIgnorable(String filePath, ErrorCode code) {
+    return _UnignorableNames.isIgnorable(
+      code,
+      isFlutter: filePath.contains('flutter'),
+      isDart2jsTest: filePath.contains('tests/compiler/dart2js') ||
+          filePath.contains('pkg/compiler/test'),
+    );
+  }
+}
+
+/// Helper for caching unignorable names.
+class _UnignorableNames {
+  static Set<String> _forFlutter;
+  static Set<String> _forDart2jsTest;
+  static Set<String> _forOther;
+
+  static Set<String> forFile(String filePath) {
+    var isFlutter = filePath.contains('flutter');
+    var isDart2jsTest = filePath.contains('tests/compiler/dart2js') ||
+        filePath.contains('pkg/compiler/test');
+
+    if (isFlutter) {
+      if (_forFlutter != null) {
+        return _forFlutter;
+      }
+    } else if (isDart2jsTest) {
+      if (_forDart2jsTest != null) {
+        return _forDart2jsTest;
+      }
+    } else {
+      if (_forOther != null) {
+        return _forOther;
+      }
+    }
+
+    var unignorableNames = <String>{};
+    for (var code in errorCodeValues) {
+      if (!isIgnorable(code,
+          isFlutter: isFlutter, isDart2jsTest: isDart2jsTest)) {
+        unignorableNames.add(code.name.toLowerCase());
+        unignorableNames.add(code.uniqueName.toLowerCase());
+      }
+    }
+
+    if (isFlutter) {
+      _forFlutter = unignorableNames;
+    } else if (isDart2jsTest) {
+      _forDart2jsTest = unignorableNames;
+    } else {
+      _forOther = unignorableNames;
+    }
+
+    return unignorableNames;
+  }
+
+  static bool isIgnorable(
+    ErrorCode code, {
+    @required bool isFlutter,
+    @required bool isDart2jsTest,
+  }) {
     if (code.isIgnorable) {
       return true;
     }
@@ -154,7 +209,7 @@
       // library, which uses a special version of the "dart:ui" library
       // which the Analyzer does not use during analysis. See
       // https://github.com/flutter/flutter/issues/52899.
-      if (filePath.contains('flutter')) {
+      if (isFlutter) {
         return true;
       }
     }
@@ -162,8 +217,7 @@
     if ((code == CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY ||
             code == CompileTimeErrorCode.UNDEFINED_ANNOTATION ||
             code == ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE) &&
-        (filePath.contains('tests/compiler/dart2js') ||
-            filePath.contains('pkg/compiler/test'))) {
+        isDart2jsTest) {
       // Special case the dart2js language tests. Some of these import
       // various internal libraries.
       return true;
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index 674e4f5..198ee09 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -217,11 +217,6 @@
   /// element, the import directive can be marked as used (removed from the
   /// unusedImports) by looking at the resolved `lib` in `lib.X`, instead of
   /// looking at which library the `lib.X` resolves.
-  ///
-  /// TODO (jwren) Since multiple [ImportDirective]s can share the same
-  /// [PrefixElement], it is possible to have an unreported unused import in
-  /// situations where two imports use the same prefix and at least one import
-  /// directive is used.
   final HashMap<PrefixElement, List<ImportDirective>> _prefixElementMap =
       HashMap<PrefixElement, List<ImportDirective>>();
 
@@ -410,22 +405,28 @@
 
   /// Remove elements from [_unusedImports] using the given [usedElements].
   void removeUsedElements(UsedImportedElements usedElements) {
-    // Stop if all the imports and shown names are known to be used.
-    if (_unusedImports.isEmpty && _unusedShownNamesMap.isEmpty) {
-      return;
-    }
+    bool everythingIsKnownToBeUsed() =>
+        _unusedImports.isEmpty && _unusedShownNamesMap.isEmpty;
+
     // Process import prefixes.
     usedElements.prefixMap
         .forEach((PrefixElement prefix, List<Element> elements) {
-      List<ImportDirective> importDirectives = _prefixElementMap[prefix];
-      if (importDirectives != null) {
-        int importLength = importDirectives.length;
-        for (int i = 0; i < importLength; i++) {
-          ImportDirective importDirective = importDirectives[i];
+      if (everythingIsKnownToBeUsed()) {
+        return;
+      }
+      // Find import directives using namespaces.
+      for (var importDirective in _prefixElementMap[prefix] ?? []) {
+        Namespace namespace = _computeNamespace(importDirective);
+        if (elements.isEmpty) {
+          // [prefix] and [elements] were added to [usedElements.prefixMap] but
+          // [elements] is empty, so the prefix was referenced incorrectly.
+          // Another diagnostic about the prefix reference is reported, and we
+          // shouldn't confuse by also reporting an unused prefix.
           _unusedImports.remove(importDirective);
-          int elementLength = elements.length;
-          for (int j = 0; j < elementLength; j++) {
-            Element element = elements[j];
+        }
+        for (var element in elements) {
+          if (namespace?.getPrefixed(prefix.name, element.name) != null) {
+            _unusedImports.remove(importDirective);
             _removeFromUnusedShownNamesMap(element, importDirective);
           }
         }
@@ -433,15 +434,13 @@
     });
     // Process top-level elements.
     for (Element element in usedElements.elements) {
-      // Stop if all the imports and shown names are known to be used.
-      if (_unusedImports.isEmpty && _unusedShownNamesMap.isEmpty) {
+      if (everythingIsKnownToBeUsed()) {
         return;
       }
       // Find import directives using namespaces.
-      String name = element.name;
       for (ImportDirective importDirective in _allImports) {
         Namespace namespace = _computeNamespace(importDirective);
-        if (namespace?.get(name) != null) {
+        if (namespace?.get(element.name) != null) {
           _unusedImports.remove(importDirective);
           _removeFromUnusedShownNamesMap(element, importDirective);
         }
@@ -449,17 +448,27 @@
     }
     // Process extension elements.
     for (ExtensionElement extensionElement in usedElements.usedExtensions) {
-      // Stop if all the imports and shown names are known to be used.
-      if (_unusedImports.isEmpty && _unusedShownNamesMap.isEmpty) {
+      if (everythingIsKnownToBeUsed()) {
         return;
       }
       // Find import directives using namespaces.
-      String name = extensionElement.name;
       for (ImportDirective importDirective in _allImports) {
         Namespace namespace = _computeNamespace(importDirective);
-        if (namespace?.get(name) == extensionElement) {
-          _unusedImports.remove(importDirective);
-          _removeFromUnusedShownNamesMap(extensionElement, importDirective);
+        var prefix = importDirective.prefix?.name;
+        var elementName = extensionElement.name;
+        if (prefix == null) {
+          if (namespace?.get(elementName) == extensionElement) {
+            _unusedImports.remove(importDirective);
+            _removeFromUnusedShownNamesMap(extensionElement, importDirective);
+          }
+        } else {
+          // An extension might be used solely because one or more instance
+          // members are referenced, which does not require explicit use of the
+          // prefix. We still indicate that the import directive is used.
+          if (namespace?.getPrefixed(prefix, elementName) == extensionElement) {
+            _unusedImports.remove(importDirective);
+            _removeFromUnusedShownNamesMap(extensionElement, importDirective);
+          }
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 159b36d..d3d43e6 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -17,7 +17,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/correct_override.dart';
 import 'package:analyzer/src/error/getter_setter_types_verifier.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:meta/meta.dart';
 
 class InheritanceOverrideVerifier {
diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
index c4368cf..03496ce 100644
--- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
+++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
@@ -97,6 +97,15 @@
   }
 
   @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    for (var argument in node.argumentList.arguments) {
+      var parameter = argument.staticParameterElement;
+      usedElements.elements.add(parameter);
+    }
+    super.visitInstanceCreationExpression(node);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement enclosingExecOld = _enclosingExec;
     try {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index ccfec81..16eb67e 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -128,6 +128,9 @@
   /// `true` if triple-shift behavior is enabled
   final bool enableTripleShift;
 
+  /// `true` if nonfunction-type-aliases behavior is enabled
+  final bool enableNonFunctionTypeAliases;
+
   /// `true` if variance behavior is enabled
   final bool enableVariance;
 
@@ -143,6 +146,8 @@
         enableControlFlowCollections =
             _featureSet.isEnabled(Feature.control_flow_collections),
         enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
+        enableNonFunctionTypeAliases =
+            _featureSet.isEnabled(Feature.nonfunction_type_aliases),
         enableVariance = _featureSet.isEnabled(Feature.variance),
         uri = uri ?? fileUri;
 
@@ -1532,20 +1537,11 @@
       SimpleIdentifier name = pop();
       List<Annotation> metadata = pop();
       Comment comment = _findComment(metadata, typedefKeyword);
-      if (type is! GenericFunctionType) {
-        // This error is also reported in the OutlineBuilder.
+      if (type is! GenericFunctionType && !enableNonFunctionTypeAliases) {
         handleRecoverableError(messageTypedefNotFunction, equals, equals);
-        type = null;
       }
-      declarations.add(ast.genericTypeAlias(
-          comment,
-          metadata,
-          typedefKeyword,
-          name,
-          templateParameters,
-          equals,
-          type as GenericFunctionType,
-          semicolon));
+      declarations.add(ast.genericTypeAlias(comment, metadata, typedefKeyword,
+          name, templateParameters, equals, type, semicolon));
     }
   }
 
@@ -2091,10 +2087,10 @@
           member.labels.insert(0, pop());
           --labelCount;
         }
-        members = List<SwitchMember>(expressionCount + 1);
+        members = List<SwitchMember>.filled(expressionCount + 1, null);
         members[expressionCount] = member;
       } else {
-        members = List<SwitchMember>(expressionCount);
+        members = List<SwitchMember>.filled(expressionCount, null);
       }
       for (int index = expressionCount - 1; index >= 0; --index) {
         SwitchMember member = pop();
@@ -3042,8 +3038,11 @@
 
       // Determine if this is a set or map based on type args and content
       final typeArgCount = typeArguments?.arguments?.length;
-      bool isSet =
-          typeArgCount == 1 ? true : typeArgCount != null ? false : null;
+      bool isSet = typeArgCount == 1
+          ? true
+          : typeArgCount != null
+              ? false
+              : null;
       isSet ??= hasSetEntry;
 
       // Build the set or map
@@ -3477,7 +3476,7 @@
   void handleTypeVariablesDefined(Token token, int count) {
     debugEvent("handleTypeVariablesDefined");
     assert(count > 0);
-    push(popTypedList(count, List<TypeParameter>(count)));
+    push(popTypedList(count, List<TypeParameter>.filled(count, null)));
   }
 
   @override
@@ -3564,7 +3563,7 @@
   List<CommentReference> parseCommentReferences(Token dartdoc) {
     // Parse dartdoc into potential comment reference source/offset pairs
     int count = parser.parseCommentReferences(dartdoc);
-    List sourcesAndOffsets = List(count * 2);
+    List sourcesAndOffsets = List.filled(count * 2, null);
     popList(count * 2, sourcesAndOffsets);
 
     // Parse each of the source/offset pairs into actual comment references
@@ -3582,7 +3581,7 @@
       }
     }
 
-    final references = List<CommentReference>(count);
+    final references = List<CommentReference>.filled(count, null);
     popTypedList(count, references);
     return references;
   }
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index fea0326..5737b9d 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -27,7 +27,7 @@
   int _mixinIndex = 0;
   List<ParameterElement> _parameters;
   int _parameterIndex = 0;
-  List<FunctionTypeAliasElement> _typedefs;
+  List<TypeAliasElement> _typedefs;
   int _typedefIndex = 0;
   List<TypeParameterElement> _typeParameters;
   int _typeParameterIndex = 0;
@@ -56,7 +56,7 @@
         _extensions = element.extensions,
         _functions = element.functions,
         _mixins = element.mixins,
-        _typedefs = element.functionTypeAliases,
+        _typedefs = element.typeAliases,
         _variables = element.topLevelVariables.where(_isNotSynthetic).toList();
 
   /// Creates an [ElementWalker] which walks the child elements of a compilation
@@ -85,7 +85,7 @@
 
   /// Creates an [ElementWalker] which walks the child elements of a typedef
   /// element defined using a generic function type.
-  ElementWalker.forGenericTypeAlias(FunctionTypeAliasElement element)
+  ElementWalker.forGenericTypeAlias(TypeAliasElement element)
       : element = element,
         _typeParameters = element.typeParameters;
 
@@ -144,7 +144,7 @@
 
   /// Returns the next non-synthetic child of [element] which is a typedef;
   /// throws an [IndexError] if there are no more.
-  FunctionTypeAliasElement getTypedef() => _typedefs[_typedefIndex++];
+  TypeAliasElement getTypedef() => _typedefs[_typedefIndex++];
 
   /// Returns the next non-synthetic child of [element] which is a type
   /// parameter; throws an [IndexError] if there are no more.
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 8a09582..5864421 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -443,7 +443,7 @@
 
   @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    ClassElementImpl enclosingClass = _resolver.enclosingClass;
+    var enclosingClass = _resolver.enclosingClass;
     if (enclosingClass == null) {
       // TODO(brianwilkerson) Report this error.
       return;
@@ -646,7 +646,7 @@
     element = _resolver.toLegacyElement(element);
 
     if (element is PropertyAccessorElement && identifier.inSetterContext()) {
-      PropertyAccessorElement setter = lookupResult.setter;
+      var setter = lookupResult.setter;
       if (setter == null) {
         //
         // Check to see whether there might be a locally defined getter and
@@ -734,7 +734,8 @@
   /// Resolve each of the annotations in the given list of [annotations].
   static void _resolveAnnotations(NodeList<Annotation> annotations) {
     for (Annotation annotation in annotations) {
-      ElementAnnotationImpl elementAnnotation = annotation.elementAnnotation;
+      var elementAnnotation =
+          annotation.elementAnnotation as ElementAnnotationImpl;
       elementAnnotation.element = annotation.element;
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index f1baaf4..63e7b03 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -101,6 +101,10 @@
   /// The file name used for analysis options files.
   static const String ANALYSIS_OPTIONS_YAML_FILE = 'analysis_options.yaml';
 
+  /// The file name used for the files containing the data for the data-driven
+  /// fixes.
+  static const String FIX_DATA_FILE = 'fix_data.yaml';
+
   /// The file name used for pubspec files.
   static const String PUBSPEC_YAML_FILE = 'pubspec.yaml';
 
@@ -386,7 +390,7 @@
   FeatureSet get contextFeatures => _contextFeatures;
 
   set contextFeatures(FeatureSet featureSet) {
-    _contextFeatures = featureSet;
+    _contextFeatures = featureSet as ExperimentStatus;
     nonPackageFeatureSet = featureSet;
   }
 
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 98b30f2..e54f009 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -22,6 +22,7 @@
 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/element/type_system.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
@@ -47,9 +48,9 @@
   final ExecutableElement element;
   final bool isAsynchronous;
   final bool isConstConstructor;
-  final bool isFactoryConstructor;
   final bool isGenerativeConstructor;
   final bool isGenerator;
+  final bool inFactoryConstructor;
   final bool inStaticMethod;
 
   /// The return statements that have a value.
@@ -65,11 +66,10 @@
   EnclosingExecutableContext(this.element)
       : isAsynchronous = element != null && element.isAsynchronous,
         isConstConstructor = element is ConstructorElement && element.isConst,
-        isFactoryConstructor =
-            element is ConstructorElement && element.isFactory,
         isGenerativeConstructor =
             element is ConstructorElement && !element.isFactory,
         isGenerator = element != null && element.isGenerator,
+        inFactoryConstructor = _inFactoryConstructor(element),
         inStaticMethod = _inStaticMethod(element);
 
   EnclosingExecutableContext.empty() : this(null);
@@ -83,7 +83,7 @@
           ? className
           : '$className.$constructorName';
     } else {
-      return element.displayName;
+      return element?.displayName;
     }
   }
 
@@ -106,6 +106,17 @@
 
   DartType get returnType => element.returnType;
 
+  static bool _inFactoryConstructor(ExecutableElement element) {
+    if (element is ConstructorElement) {
+      return element.isFactory;
+    }
+    var enclosing = element?.enclosingElement;
+    if (enclosing is ExecutableElement) {
+      return _inFactoryConstructor(enclosing);
+    }
+    return false;
+  }
+
   static bool _inStaticMethod(ExecutableElement element) {
     var enclosing = element?.enclosingElement;
     if (enclosing is ClassElement || enclosing is ExtensionElement) {
@@ -240,8 +251,8 @@
     _isInStaticVariableDeclaration = false;
     _isInConstructorInitializer = false;
     _intType = _typeProvider.intType;
-    _typeSystem = _currentLibrary.typeSystem;
-    _options = _currentLibrary.context.analysisOptions;
+    _typeSystem = _currentLibrary.typeSystem as TypeSystemImpl;
+    _options = _currentLibrary.context.analysisOptions as AnalysisOptionsImpl;
     _typeArgumentsVerifier =
         TypeArgumentsVerifier(_options, _currentLibrary, _errorReporter);
     _constructorFieldsVerifier = ConstructorFieldsVerifier(
@@ -249,7 +260,7 @@
       errorReporter: _errorReporter,
     );
     _returnTypeVerifier = ReturnTypeVerifier(
-      typeProvider: _typeProvider,
+      typeProvider: _typeProvider as TypeProviderImpl,
       typeSystem: _typeSystem,
       errorReporter: _errorReporter,
     );
@@ -268,7 +279,7 @@
     assert(_enclosingClass == null);
     assert(_enclosingEnum == null);
     assert(_enclosingExecutable.element == null);
-    _enclosingClass = classElement;
+    _enclosingClass = classElement as ClassElementImpl;
   }
 
   /// The language team is thinking about adding abstract fields, or external
@@ -329,14 +340,14 @@
       _checkForArgumentTypeNotAssignableForArgument(rhs);
     }
     if (operatorType == TokenType.QUESTION_QUESTION_EQ) {
-      _checkForDeadNullCoalesce(node.readType, node.rightHandSide);
+      _checkForDeadNullCoalesce(node.readType as TypeImpl, node.rightHandSide);
     }
     _checkForAssignmentToFinal(lhs);
     if (lhs is IndexExpression) {
       _checkIndexExpressionIndex(
         lhs.index,
-        readElement: node.readElement,
-        writeElement: node.writeElement,
+        readElement: node.readElement as ExecutableElement,
+        writeElement: node.writeElement as ExecutableElement,
       );
     }
     super.visitAssignmentExpression(node);
@@ -371,7 +382,8 @@
     }
 
     if (type == TokenType.QUESTION_QUESTION) {
-      _checkForDeadNullCoalesce(node.leftOperand.staticType, node.rightOperand);
+      _checkForDeadNullCoalesce(
+          node.leftOperand.staticType as TypeImpl, node.rightOperand);
     }
 
     _checkForUseOfVoidResult(node.leftOperand);
@@ -427,7 +439,7 @@
     ClassElementImpl outerClass = _enclosingClass;
     try {
       _isInNativeClass = node.nativeClause != null;
-      _enclosingClass = node.declaredElement;
+      _enclosingClass = node.declaredElement as ClassElementImpl;
 
       List<ClassMember> members = node.members;
       _duplicateDefinitionVerifier.checkClass(node);
@@ -465,7 +477,7 @@
         node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
     ClassElementImpl outerClassElement = _enclosingClass;
     try {
-      _enclosingClass = node.declaredElement;
+      _enclosingClass = node.declaredElement as ClassElementImpl;
       _checkClassInheritance(
           node, node.superclass, node.withClause, node.implementsClause);
       _checkForMainFunction(node.name);
@@ -567,7 +579,7 @@
 
   @override
   void visitExportDirective(ExportDirective node) {
-    ExportElement exportElement = node.element;
+    var exportElement = node.element;
     if (exportElement != null) {
       LibraryElement exportedLibrary = exportElement.exportedLibrary;
       _checkForAmbiguousExport(node, exportElement, exportedLibrary);
@@ -660,8 +672,9 @@
     }
     if (_checkForEachParts(node, loopVariable.identifier)) {
       if (loopVariable.isConst) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, loopVariable);
+        _errorReporter.reportErrorForToken(
+            CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE,
+            loopVariable.keyword);
       }
     }
     super.visitForEachPartsWithDeclaration(node);
@@ -711,7 +724,8 @@
         GetterSetterTypesVerifier(
           typeSystem: _typeSystem,
           errorReporter: _errorReporter,
-        ).checkGetter(node.name, node.declaredElement);
+        ).checkGetter(
+            node.name, node.declaredElement as PropertyAccessorElement);
       }
       if (node.isSetter) {
         FunctionExpression functionExpression = node.functionExpression;
@@ -772,7 +786,8 @@
     _checkForBuiltInIdentifierAsName(
         node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
     _checkForMainFunction(node.name);
-    _checkForTypeAliasCannotReferenceItself(node, node.declaredElement);
+    _checkForTypeAliasCannotReferenceItself(
+        node, node.declaredElement as TypeAliasElementImpl);
     super.visitFunctionTypeAlias(node);
   }
 
@@ -808,7 +823,8 @@
     _checkForBuiltInIdentifierAsName(
         node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
     _checkForMainFunction(node.name);
-    _checkForTypeAliasCannotReferenceItself(node, node.declaredElement);
+    _checkForTypeAliasCannotReferenceItself(
+        node, node.declaredElement as TypeAliasElementImpl);
     super.visitGenericTypeAlias(node);
   }
 
@@ -820,7 +836,7 @@
 
   @override
   void visitImportDirective(ImportDirective node) {
-    ImportElement importElement = node.element;
+    var importElement = node.element;
     if (node.prefix != null) {
       _checkForBuiltInIdentifierAsName(
           node.prefix, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_PREFIX_NAME);
@@ -910,7 +926,8 @@
         GetterSetterTypesVerifier(
           typeSystem: _typeSystem,
           errorReporter: _errorReporter,
-        ).checkGetter(node.name, node.declaredElement);
+        ).checkGetter(
+            node.name, node.declaredElement as PropertyAccessorElement);
       }
       if (node.isSetter) {
         _checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
@@ -952,7 +969,7 @@
     // TODO(scheglov) Verify for all mixin errors.
     ClassElementImpl outerClass = _enclosingClass;
     try {
-      _enclosingClass = node.declaredElement;
+      _enclosingClass = node.declaredElement as ClassElementImpl;
 
       List<ClassMember> members = node.members;
       _duplicateDefinitionVerifier.checkMixin(node);
@@ -1009,8 +1026,8 @@
     if (operand is IndexExpression) {
       _checkIndexExpressionIndex(
         operand.index,
-        readElement: node.readElement,
-        writeElement: node.writeElement,
+        readElement: node.readElement as ExecutableElement,
+        writeElement: node.writeElement as ExecutableElement,
       );
     }
     super.visitPostfixExpression(node);
@@ -1042,8 +1059,8 @@
     if (operand is IndexExpression) {
       _checkIndexExpressionIndex(
         operand.index,
-        readElement: node.readElement,
-        writeElement: node.writeElement,
+        readElement: node.readElement as ExecutableElement,
+        writeElement: node.writeElement as ExecutableElement,
       );
     }
     super.visitPrefixExpression(node);
@@ -1124,7 +1141,7 @@
   void visitSimpleIdentifier(SimpleIdentifier node) {
     _checkForAmbiguousImport(node);
     _checkForReferenceBeforeDeclaration(node);
-    _checkForImplicitThisReferenceInInitializer(node);
+    _checkForInvalidInstanceMemberAccess(node);
     _checkForTypeParameterReferencedByStatic(node);
     if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) {
       _checkForUnqualifiedReferenceToNonLocalStaticMember(node);
@@ -1512,7 +1529,7 @@
       String name = element.displayName;
       List<Element> conflictingMembers = element.conflictingElements;
       int count = conflictingMembers.length;
-      List<String> libraryNames = List<String>(count);
+      List<String> libraryNames = List<String>.filled(count, null);
       for (int i = 0; i < count; i++) {
         libraryNames[i] = _getLibraryName(conflictingMembers[i]);
       }
@@ -1570,7 +1587,8 @@
   }) {
     DartType staticParameterType = parameter?.type;
     if (promoteParameterToNullable && staticParameterType != null) {
-      staticParameterType = _typeSystem.makeNullable(staticParameterType);
+      staticParameterType =
+          _typeSystem.makeNullable(staticParameterType as TypeImpl);
     }
     _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
         staticParameterType, CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
@@ -2404,7 +2422,7 @@
       return;
     }
 
-    var element = node.element as ExportElement;
+    var element = node.element;
     // TODO(scheglov) Expose from ExportElement.
     var namespace =
         NamespaceBuilder().createExportNamespaceForDirective(element);
@@ -2767,76 +2785,6 @@
     }
   }
 
-  /// Verify that if the given [identifier] is part of a constructor
-  /// initializer, then it does not implicitly reference 'this' expression.
-  ///
-  /// See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and
-  /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC].
-  /// TODO(scheglov) rename thid method
-  void _checkForImplicitThisReferenceInInitializer(
-      SimpleIdentifier identifier) {
-    if (_isInComment) {
-      return;
-    }
-    if (!_isInConstructorInitializer &&
-        !_enclosingExecutable.inStaticMethod &&
-        !_enclosingExecutable.isFactoryConstructor &&
-        !_isInInstanceNotLateVariableDeclaration &&
-        !_isInStaticVariableDeclaration) {
-      return;
-    }
-    // prepare element
-    Element element = identifier.writeOrReadElement;
-    if (!(element is MethodElement || element is PropertyAccessorElement)) {
-      return;
-    }
-    // static element
-    ExecutableElement executableElement = element as ExecutableElement;
-    if (executableElement.isStatic) {
-      return;
-    }
-    // not a class member
-    Element enclosingElement = element.enclosingElement;
-    if (enclosingElement is! ClassElement &&
-        enclosingElement is! ExtensionElement) {
-      return;
-    }
-    // qualified method invocation
-    AstNode parent = identifier.parent;
-    if (parent is MethodInvocation) {
-      if (identical(parent.methodName, identifier) &&
-          parent.realTarget != null) {
-        return;
-      }
-    }
-    // qualified property access
-    if (parent is PropertyAccess) {
-      if (identical(parent.propertyName, identifier) &&
-          parent.realTarget != null) {
-        return;
-      }
-    }
-    if (parent is PrefixedIdentifier) {
-      if (identical(parent.identifier, identifier)) {
-        return;
-      }
-    }
-
-    if (_enclosingExecutable.inStaticMethod) {
-      // TODO
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
-    } else if (_enclosingExecutable.isFactoryConstructor) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
-    } else {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
-          identifier,
-          [identifier.name]);
-    }
-  }
-
   /// Check that if the visiting library is not system, then any given library
   /// should not be SDK internal library. The [importElement] is the
   /// [ImportElement] retrieved from the node, if the element in the node was
@@ -3005,6 +2953,74 @@
     }
   }
 
+  /// Verify that if the given [identifier] is part of a constructor
+  /// initializer, then it does not implicitly reference 'this' expression.
+  ///
+  /// See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER],
+  /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY], and
+  /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC].
+  void _checkForInvalidInstanceMemberAccess(SimpleIdentifier identifier) {
+    if (_isInComment) {
+      return;
+    }
+    if (!_isInConstructorInitializer &&
+        !_enclosingExecutable.inStaticMethod &&
+        !_enclosingExecutable.inFactoryConstructor &&
+        !_isInInstanceNotLateVariableDeclaration &&
+        !_isInStaticVariableDeclaration) {
+      return;
+    }
+    // prepare element
+    Element element = identifier.writeOrReadElement;
+    if (!(element is MethodElement || element is PropertyAccessorElement)) {
+      return;
+    }
+    // static element
+    ExecutableElement executableElement = element as ExecutableElement;
+    if (executableElement.isStatic) {
+      return;
+    }
+    // not a class member
+    Element enclosingElement = element.enclosingElement;
+    if (enclosingElement is! ClassElement &&
+        enclosingElement is! ExtensionElement) {
+      return;
+    }
+    // qualified method invocation
+    AstNode parent = identifier.parent;
+    if (parent is MethodInvocation) {
+      if (identical(parent.methodName, identifier) &&
+          parent.realTarget != null) {
+        return;
+      }
+    }
+    // qualified property access
+    if (parent is PropertyAccess) {
+      if (identical(parent.propertyName, identifier) &&
+          parent.realTarget != null) {
+        return;
+      }
+    }
+    if (parent is PrefixedIdentifier) {
+      if (identical(parent.identifier, identifier)) {
+        return;
+      }
+    }
+
+    if (_enclosingExecutable.inStaticMethod) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
+    } else if (_enclosingExecutable.inFactoryConstructor) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
+    } else {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+          identifier,
+          [identifier.name]);
+    }
+  }
+
   /// Check to see whether the given function [body] has a modifier associated
   /// with it, and report it as an error if it does.
   void _checkForInvalidModifierOnBody(
@@ -3203,7 +3219,7 @@
 
         for (var member in statement.members) {
           if (member is SwitchCase) {
-            var expression = member.expression;
+            var expression = member.expression.unParenthesized;
             if (expression is NullLiteral) {
               hasCaseNull = true;
             } else {
@@ -3295,7 +3311,7 @@
   /// the [mixinIndex] position in the mixins list are satisfied by the
   /// [_enclosingClass], or a previous mixin.
   bool _checkForMixinSuperclassConstraints(int mixinIndex, TypeName mixinName) {
-    InterfaceType mixinType = mixinName.type;
+    InterfaceType mixinType = mixinName.type as InterfaceType;
     for (var constraint in mixinType.superclassConstraints) {
       var superType = _enclosingClass.supertype as InterfaceTypeImpl;
       if (_currentLibrary.isNonNullableByDefault) {
@@ -3330,7 +3346,7 @@
   /// implementations of all the super-invoked members of the [mixinElement].
   bool _checkForMixinSuperInvokedMembers(int mixinIndex, TypeName mixinName,
       ClassElement mixinElement, InterfaceType mixinType) {
-    ClassElementImpl mixinElementImpl = mixinElement;
+    var mixinElementImpl = mixinElement as ClassElementImpl;
     if (mixinElementImpl.superInvokedNames.isEmpty) {
       return false;
     }
@@ -3843,8 +3859,6 @@
   }
 
   /// Check that the given named optional [parameter] does not begin with '_'.
-  ///
-  /// See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER].
   void _checkForPrivateOptionalParameter(FormalParameter parameter) {
     // should be named parameter
     if (!parameter.isNamed) {
@@ -3857,7 +3871,7 @@
     }
 
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
+        CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter.identifier);
   }
 
   /// Check whether the given constructor [declaration] is the redirecting
@@ -4227,9 +4241,9 @@
   /// See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF].
   void _checkForTypeAliasCannotReferenceItself(
     AstNode node,
-    FunctionTypeAliasElement element,
+    TypeAliasElementImpl element,
   ) {
-    if ((element as FunctionTypeAliasElementImpl).hasSelfReference) {
+    if (element.hasSelfReference) {
       _errorReporter.reportErrorForNode(
         CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
         node,
@@ -4903,7 +4917,7 @@
     if (withClause == null) {
       return;
     }
-    ClassElement classElement = node.declaredElement;
+    var classElement = node.declaredElement as ClassElement;
     var supertype = classElement.supertype;
 
     var interfacesMerger = InterfacesMerger(_typeSystem);
@@ -5035,6 +5049,12 @@
         }
         return true;
       } else if (parent is FunctionExpression) {
+        var parent2 = parent.parent;
+        if (parent2 is FunctionDeclaration && parent2.externalKeyword != null) {
+          return false;
+        } else if (parent.body is NativeFunctionBody) {
+          return false;
+        }
         return true;
       } else if (parent is MethodDeclaration) {
         if (parent.isAbstract) {
@@ -5308,7 +5328,7 @@
       if (fieldDeclaration is FieldDeclaration) {
         for (VariableDeclaration field in fieldDeclaration.fields.variables) {
           if (field.initializer == null) {
-            fields.add(field.declaredElement);
+            fields.add(field.declaredElement as FieldElement);
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index a3a03ad..c43c75f 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -72,7 +72,7 @@
     currentToken = fastaParser
         .parseMetadata(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as Annotation;
   }
 
   @override
@@ -82,7 +82,7 @@
     currentToken = fastaParser
         .parseArguments(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    MethodInvocation invocation = astBuilder.pop();
+    var invocation = astBuilder.pop() as MethodInvocation;
     return invocation.argumentList.arguments[0];
   }
 
@@ -92,7 +92,9 @@
         .parseArguments(fastaParser.syntheticPreviousToken(currentToken))
         .next;
     var result = astBuilder.pop();
-    return result is MethodInvocation ? result.argumentList : result;
+    return result is MethodInvocation
+        ? result.argumentList
+        : result as ArgumentList;
   }
 
   @override
@@ -124,7 +126,7 @@
       null /* leftBracket */,
       <ClassMember>[],
       null /* rightBracket */,
-    );
+    ) as ClassDeclarationImpl;
     // TODO(danrubel): disambiguate between class and mixin
     currentToken = fastaParser.parseClassMember(currentToken, className);
     //currentToken = fastaParser.parseMixinMember(currentToken);
@@ -138,7 +140,7 @@
     currentToken = fastaParser
         .parseCombinatorStar(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as List<Combinator>;
   }
 
   @override
@@ -150,7 +152,7 @@
   @override
   CompilationUnit parseCompilationUnit2() {
     currentToken = fastaParser.parseUnit(currentToken);
-    return astBuilder.pop();
+    return astBuilder.pop() as CompilationUnit;
   }
 
   @override
@@ -161,7 +163,7 @@
     currentToken = fastaParser
         .parseConditionalUri(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as Configuration;
   }
 
   @override
@@ -176,7 +178,7 @@
   @override
   CompilationUnit parseDirectives2() {
     currentToken = fastaParser.parseDirectives(currentToken);
-    return astBuilder.pop();
+    return astBuilder.pop() as CompilationUnit;
   }
 
   @override
@@ -184,7 +186,7 @@
     currentToken = fastaParser
         .parseDottedName(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as DottedName;
   }
 
   @override
@@ -201,7 +203,7 @@
     currentToken = fastaParser
         .parseExpression(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as Expression;
   }
 
   @override
@@ -216,7 +218,7 @@
                 ? fasta.MemberKind.GeneralizedFunctionType
                 : fasta.MemberKind.NonStaticMethod)
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as FormalParameterList;
   }
 
   @override
@@ -226,11 +228,12 @@
         fastaParser.syntheticPreviousToken(currentToken));
     currentToken =
         fastaParser.parseFunctionBody(currentToken, inExpression, mayBeEmpty);
-    return astBuilder.pop();
+    return astBuilder.pop() as FunctionBody;
   }
 
   @override
-  FunctionExpression parseFunctionExpression() => parseExpression2();
+  FunctionExpression parseFunctionExpression() =>
+      parseExpression2() as FunctionExpression;
 
   @override
   Expression parseLogicalAndExpression() => parseExpression2();
@@ -242,13 +245,14 @@
   Expression parseMultiplicativeExpression() => parseExpression2();
 
   @override
-  InstanceCreationExpression parseNewExpression() => parseExpression2();
+  InstanceCreationExpression parseNewExpression() =>
+      parseExpression2() as InstanceCreationExpression;
 
   @override
   Expression parsePostfixExpression() => parseExpression2();
 
   @override
-  Identifier parsePrefixedIdentifier() => parseExpression2();
+  Identifier parsePrefixedIdentifier() => parseExpression2() as Identifier;
 
   @override
   Expression parsePrimaryExpression() {
@@ -256,7 +260,7 @@
         .parsePrimary(fastaParser.syntheticPreviousToken(currentToken),
             fasta.IdentifierContext.expression)
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as Expression;
   }
 
   @override
@@ -271,7 +275,7 @@
   @override
   SimpleIdentifier parseSimpleIdentifier(
           {bool allowKeyword = false, bool isDeclaration = false}) =>
-      parseExpression2();
+      parseExpression2() as SimpleIdentifier;
 
   @override
   Statement parseStatement(Token token) {
@@ -284,14 +288,14 @@
     currentToken = fastaParser
         .parseStatement(fastaParser.syntheticPreviousToken(currentToken))
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as Statement;
   }
 
   @override
-  StringLiteral parseStringLiteral() => parseExpression2();
+  StringLiteral parseStringLiteral() => parseExpression2() as StringLiteral;
 
   @override
-  SymbolLiteral parseSymbolLiteral() => parseExpression2();
+  SymbolLiteral parseSymbolLiteral() => parseExpression2() as SymbolLiteral;
 
   @override
   Expression parseThrowExpression() => parseExpression2();
@@ -312,7 +316,7 @@
         .computeType(previous, true, !inExpression)
         .parseType(previous, fastaParser)
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as TypeAnnotation;
   }
 
   @override
@@ -322,7 +326,7 @@
         .computeTypeParamOrArg(previous)
         .parseArguments(previous, fastaParser)
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as TypeArgumentList;
   }
 
   @override
@@ -332,7 +336,7 @@
         .computeType(previous, true, !inExpression)
         .parseType(previous, fastaParser)
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as TypeName;
   }
 
   @override
@@ -352,7 +356,7 @@
         .computeTypeParamOrArg(token, true)
         .parseVariables(token, fastaParser)
         .next;
-    return astBuilder.pop();
+    return astBuilder.pop() as TypeParameterList;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 4cbf579..d6c7ecd 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -275,7 +275,7 @@
             inheritanceManager,
             definingLibrary,
             source,
-            definingLibrary.typeSystem,
+            definingLibrary.typeSystem as TypeSystemImpl,
             typeProvider,
             errorListener,
             featureSet ??
@@ -301,7 +301,8 @@
       MigrationResolutionHooks migrationResolutionHooks)
       : _featureSet = featureSet,
         migrationResolutionHooks = migrationResolutionHooks,
-        super(definingLibrary, source, typeProvider, errorListener,
+        super(definingLibrary, source, typeProvider as TypeProviderImpl,
+            errorListener,
             nameScope: nameScope) {
     _promoteManager = TypePromotionManager(typeSystem);
 
@@ -463,7 +464,8 @@
     }
 
     if (element is VariableElement) {
-      var assigned = _flowAnalysis.isDefinitelyAssigned(node, element);
+      var assigned = _flowAnalysis.isDefinitelyAssigned(
+          node, element as PromotableElement);
       var unassigned = _flowAnalysis.isDefinitelyUnassigned(node, element);
 
       if (element.isLate) {
@@ -546,7 +548,7 @@
         _flowAnalysis.flow.nullAwareAccess_end();
       } while (identical(_unfinishedNullShorts.last, node));
       if (node is! CascadeExpression && !discardType) {
-        node.staticType = typeSystem.makeNullable(node.staticType);
+        node.staticType = typeSystem.makeNullable(node.staticType as TypeImpl);
       }
     }
   }
@@ -581,11 +583,44 @@
     _enclosingFunction = enclosingExecutableElement;
   }
 
-  /// A client is about to resolve a member in the given class declaration.
-  void prepareToResolveMembersInClass(ClassDeclaration node) {
-    _enclosingClassDeclaration = node;
-    enclosingClass = node.declaredElement;
-    _thisType = enclosingClass?.thisType;
+  /// We are going to resolve [node], without visiting its parent.
+  /// Do necessary preparations - set enclosing elements, scopes, etc.
+  /// This [ResolverVisitor] instance is fresh, just created.
+  ///
+  /// Return `true` if we were able to do this, or `false` if it is not
+  /// possible to resolve only [node].
+  bool prepareForResolving(AstNode node) {
+    var parent = node.parent;
+
+    if (parent is CompilationUnit) {
+      return node is ClassDeclaration ||
+          node is ExtensionDeclaration ||
+          node is FunctionDeclaration;
+    }
+
+    void forClassElement(ClassElement parentElement) {
+      enclosingClass = parentElement;
+      nameScope = ClassScope(
+        TypeParameterScope(
+          nameScope,
+          parentElement.typeParameters,
+        ),
+        parentElement,
+      );
+      _thisType = parentElement.thisType;
+    }
+
+    if (parent is ClassDeclaration) {
+      forClassElement(parent.declaredElement);
+      return true;
+    }
+
+    if (parent is MixinDeclaration) {
+      forClassElement(parent.declaredElement);
+      return true;
+    }
+
+    return false;
   }
 
   /// Resolve LHS [node] of an assignment, an explicit [AssignmentExpression],
@@ -670,7 +705,7 @@
       if (element is PropertyAccessorElement && element.isGetter) {
         readType = element.returnType;
       } else if (element is VariableElement) {
-        readType = localVariableTypeProvider.getType(node);
+        readType = localVariableTypeProvider.getType(node as SimpleIdentifier);
       }
     }
 
@@ -737,7 +772,7 @@
 
   void startNullAwareIndexExpression(IndexExpression node) {
     if (_migratableAstInfoProvider.isIndexExpressionNullAware(node) &&
-        _isNonNullableByDefault) {
+        _flowAnalysis != null) {
       _flowAnalysis.flow.nullAwareAccess_rightBegin(
           node.target, node.realTarget.staticType ?? typeProvider.dynamicType);
       _unfinishedNullShorts.add(node.nullShortingTermination);
@@ -748,7 +783,7 @@
     PropertyAccess node,
   ) {
     if (_migratableAstInfoProvider.isPropertyAccessNullAware(node) &&
-        _isNonNullableByDefault) {
+        _flowAnalysis != null) {
       var target = node.target;
       if (target is SimpleIdentifier && target.staticElement is ClassElement) {
         // `?.` to access static methods is equivalent to `.`, so do nothing.
@@ -764,7 +799,7 @@
   /// Otherwise, return the original element.
   T toLegacyElement<T extends Element>(T element) {
     if (_isNonNullableByDefault) return element;
-    return Member.legacy(element);
+    return Member.legacy(element) as T;
   }
 
   /// If in a legacy library, return the legacy version of the [type].
@@ -786,8 +821,9 @@
   }
 
   @override
-  void visitArgumentList(ArgumentList node) {
+  void visitArgumentList(ArgumentList node, {bool isIdentical = false}) {
     DartType callerType = InferenceContext.getContext(node);
+    NodeList<Expression> arguments = node.arguments;
     if (callerType is FunctionType) {
       Map<String, DartType> namedParameterTypes =
           callerType.namedParameterTypes;
@@ -796,7 +832,6 @@
       int normalCount = normalParameterTypes.length;
       int optionalCount = optionalParameterTypes.length;
 
-      NodeList<Expression> arguments = node.arguments;
       Iterable<Expression> positional =
           arguments.takeWhile((l) => l is! NamedExpression);
       Iterable<Expression> required = positional.take(normalCount);
@@ -838,7 +873,23 @@
         }
       }
     }
-    super.visitArgumentList(node);
+    checkUnreachableNode(node);
+    int length = arguments.length;
+    for (var i = 0; i < length; i++) {
+      if (isIdentical && length > 1 && i == 1) {
+        var firstArg = arguments[0];
+        _flowAnalysis?.flow
+            ?.equalityOp_rightBegin(firstArg, firstArg.staticType);
+      }
+      arguments[i].accept(this);
+    }
+    if (isIdentical && length > 1) {
+      var secondArg = arguments[1];
+      _flowAnalysis?.flow
+          ?.equalityOp_end(node.parent, secondArg, secondArg.staticType);
+    }
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
   }
 
   @override
@@ -877,7 +928,7 @@
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
-    _assignmentExpressionResolver.resolve(node);
+    _assignmentExpressionResolver.resolve(node as AssignmentExpressionImpl);
   }
 
   @override
@@ -892,7 +943,7 @@
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
-    _binaryExpressionResolver.resolve(node);
+    _binaryExpressionResolver.resolve(node as BinaryExpressionImpl);
   }
 
   @override
@@ -930,7 +981,7 @@
     InferenceContext.setTypeFromNode(node.target, node);
     node.target.accept(this);
 
-    if (node.isNullAware && _isNonNullableByDefault) {
+    if (node.isNullAware && _flowAnalysis != null) {
       _flowAnalysis.flow.nullAwareAccess_rightBegin(
           node.target, node.target.staticType ?? typeProvider.dynamicType);
       _unfinishedNullShorts.add(node.nullShortingTermination);
@@ -980,16 +1031,16 @@
     // TODO(scheglov) Change corresponding visiting places to visit comments
     // with name scopes set for correct comments resolution.
     if (parent is GenericTypeAlias) {
-      var element = parent.declaredElement as FunctionTypeAliasElement;
+      var element = parent.declaredElement as TypeAliasElement;
       var outerScope = nameScope;
       try {
         nameScope = TypeParameterScope(nameScope, element.typeParameters);
 
-        var functionElement = element.function;
-        if (functionElement != null) {
+        var aliasedElement = element.aliasedElement;
+        if (aliasedElement is GenericFunctionTypeElement) {
           nameScope = FormalParameterScope(
-            TypeParameterScope(nameScope, functionElement.typeParameters),
-            functionElement.parameters,
+            TypeParameterScope(nameScope, aliasedElement.typeParameters),
+            aliasedElement.parameters,
           );
         }
 
@@ -1127,7 +1178,7 @@
       _promoteManager.exitFunctionBody();
     }
 
-    ConstructorElementImpl constructor = node.declaredElement;
+    var constructor = node.declaredElement as ConstructorElementImpl;
     constructor.constantInitializers =
         _createCloner().cloneNodeList(node.initializers);
 
@@ -1315,12 +1366,12 @@
 
   @override
   void visitForElementInScope(ForElement node) {
-    _forResolver.resolveElement(node);
+    _forResolver.resolveElement(node as ForElementImpl);
   }
 
   @override
   void visitForStatementInScope(ForStatement node) {
-    _forResolver.resolveStatement(node);
+    _forResolver.resolveStatement(node as ForStatementImpl);
     nullSafetyDeadCodeVerifier?.flowEnd(node.body);
   }
 
@@ -1415,7 +1466,8 @@
   @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     node.function?.accept(this);
-    _functionExpressionInvocationResolver.resolve(node);
+    _functionExpressionInvocationResolver
+        .resolve(node as FunctionExpressionInvocationImpl);
   }
 
   @override
@@ -1540,7 +1592,7 @@
     );
 
     var element = result.readElement;
-    node.staticElement = element;
+    node.staticElement = element as MethodElement;
 
     InferenceContext.setType(node.index, result.indexContextType);
     node.index?.accept(this);
@@ -1633,7 +1685,7 @@
     target?.accept(this);
 
     if (_migratableAstInfoProvider.isMethodInvocationNullAware(node) &&
-        _isNonNullableByDefault) {
+        _flowAnalysis != null) {
       if (target is SimpleIdentifier && target.staticElement is ClassElement) {
         // `?.` to access static methods is equivalent to `.`, so do nothing.
       } else {
@@ -1708,7 +1760,7 @@
 
   @override
   void visitPostfixExpression(PostfixExpression node) {
-    _postfixExpressionResolver.resolve(node);
+    _postfixExpressionResolver.resolve(node as PostfixExpressionImpl);
   }
 
   @override
@@ -1718,7 +1770,7 @@
 
   @override
   void visitPrefixExpression(PrefixExpression node) {
-    _prefixExpressionResolver.resolve(node);
+    _prefixExpressionResolver.resolve(node as PrefixExpressionImpl);
   }
 
   @override
@@ -1927,8 +1979,8 @@
         var catchClause = catchClauses[i];
         nullSafetyDeadCodeVerifier.verifyCatchClause(catchClause);
         flow.tryCatchStatement_catchBegin(
-          catchClause.exceptionParameter?.staticElement,
-          catchClause.stackTraceParameter?.staticElement,
+          catchClause.exceptionParameter?.staticElement as PromotableElement,
+          catchClause.stackTraceParameter?.staticElement as PromotableElement,
         );
         catchClause.accept(this);
         flow.tryCatchStatement_catchEnd();
@@ -1952,7 +2004,7 @@
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    _variableDeclarationResolver.resolve(node);
+    _variableDeclarationResolver.resolve(node as VariableDeclarationImpl);
 
     var declaredElement = node.declaredElement;
     if (node.parent.parent is ForParts) {
@@ -1966,10 +2018,12 @@
       var initializerStaticType = initializer.staticType;
       if (declaredType == null) {
         if (initializerStaticType is TypeParameterType) {
-          _flowAnalysis?.flow?.promote(declaredElement, initializerStaticType);
+          _flowAnalysis?.flow?.promote(
+              declaredElement as PromotableElement, initializerStaticType);
         }
       } else if (!parent.isFinal) {
-        _flowAnalysis?.flow?.write(declaredElement, initializerStaticType,
+        _flowAnalysis?.flow?.write(
+            declaredElement as PromotableElement, initializerStaticType,
             viaInitializer: true);
       }
     }
@@ -2102,7 +2156,7 @@
         // as computing constant values. It is stored in two places.
         var constructorElement = ConstructorMember.from(
           rawElement,
-          inferred.returnType,
+          inferred.returnType as InterfaceType,
         );
         constructorElement = toLegacyElement(constructorElement);
         constructor.staticElement = constructorElement;
@@ -2111,7 +2165,7 @@
 
     if (inferred == null) {
       var type = originalElement?.type;
-      type = toLegacyTypeIfOptOut(type);
+      type = toLegacyTypeIfOptOut(type) as FunctionType;
       InferenceContext.setType(node.argumentList, type);
     }
   }
@@ -2141,7 +2195,8 @@
       }
     }
 
-    _functionExpressionInvocationResolver.resolve(node);
+    _functionExpressionInvocationResolver
+        .resolve(node as FunctionExpressionInvocationImpl);
 
     nullShortingTermination(node);
   }
@@ -2186,7 +2241,7 @@
     NodeList<Expression> arguments = argumentList.arguments;
     int argumentCount = arguments.length;
     List<ParameterElement> resolvedParameters =
-        List<ParameterElement>(argumentCount);
+        List<ParameterElement>.filled(argumentCount, null);
     int positionalArgumentCount = 0;
     HashSet<String> usedNames;
     bool noBlankArguments = true;
@@ -2804,16 +2859,13 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     Scope outerScope = nameScope;
     try {
-      FunctionTypeAliasElement element = node.declaredElement;
+      var element = node.declaredElement as TypeAliasElement;
       nameScope = TypeParameterScope(nameScope, element.typeParameters);
       super.visitGenericTypeAlias(node);
 
-      GenericFunctionTypeElement functionElement = element.function;
-      if (functionElement != null) {
-        nameScope = FormalParameterScope(
-          nameScope,
-          functionElement.parameters,
-        );
+      var aliasedElement = element.aliasedElement;
+      if (aliasedElement is GenericFunctionTypeElement) {
+        nameScope = FormalParameterScope(nameScope, aliasedElement.parameters);
         visitGenericTypeAliasInFunctionScope(node);
       }
     } finally {
@@ -3053,7 +3105,8 @@
   VariableResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
       {Scope nameScope})
-      : super(definingLibrary, source, typeProvider, errorListener,
+      : super(definingLibrary, source, typeProvider as TypeProviderImpl,
+            errorListener,
             nameScope: nameScope);
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 2188bba..fb337a8 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -13,9 +13,6 @@
 /// Instances of the class `FileBasedSource` implement a source that represents
 /// a file.
 class FileBasedSource extends Source {
-  /// A function that changes the way that files are read off of disk.
-  static Function fileReadMode = (String s) => s;
-
   /// Map from encoded URI/filepath pair to a unique integer identifier.  This
   /// identifier is used for equality tests and hash codes.
   ///
@@ -65,7 +62,7 @@
   /// See [contents].
   TimestampedData<String> get contentsFromFile {
     return TimestampedData<String>(
-        file.lastModified(), fileReadMode(file.readAsStringSync()));
+        file.lastModified(), file.readAsStringSync());
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 6a45033..a51dcbc 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -411,7 +411,7 @@
         isConst: node.isConst);
 
     if (inferred != null && inferred != originalElement.type) {
-      inferred = _resolver.toLegacyTypeIfOptOut(inferred);
+      inferred = _resolver.toLegacyTypeIfOptOut(inferred) as FunctionType;
       // Fix up the parameter elements based on inferred method.
       arguments.correspondingStaticParameters =
           ResolverVisitor.resolveArgumentsToParameters(
@@ -421,7 +421,7 @@
       // computing constant values. It is stored in two places.
       var constructorElement = ConstructorMember.from(
         rawElement,
-        inferred.returnType,
+        inferred.returnType as InterfaceType,
       );
       constructorElement = _resolver.toLegacyElement(constructorElement);
       constructor.staticElement = constructorElement;
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 81d60f6..a76d625 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -451,7 +451,7 @@
       String name, List<String> constantNames) {
     int count = constantNames.length;
     List<EnumConstantDeclaration> constants =
-        List<EnumConstantDeclaration>(count);
+        List<EnumConstantDeclaration>.filled(count, null);
     for (int i = 0; i < count; i++) {
       constants[i] = astFactory.enumConstantDeclaration(
           null, null, identifier3(constantNames[i]));
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index c0c1b6e..88250f8 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -126,7 +126,8 @@
     constructor.isConst = isConst;
     if (argumentTypes != null) {
       int count = argumentTypes.length;
-      List<ParameterElement> parameters = List<ParameterElement>(count);
+      List<ParameterElement> parameters =
+          List<ParameterElement>.filled(count, null);
       for (int i = 0; i < count; i++) {
         ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
         parameter.type = argumentTypes[i];
@@ -162,10 +163,10 @@
     // Build the enum.
     //
     EnumElementImpl enumElement = EnumElementImpl(enumName, -1);
-    InterfaceTypeImpl enumType = enumElement.instantiate(
+    var enumType = enumElement.instantiate(
       typeArguments: const [],
       nullabilitySuffix: NullabilitySuffix.star,
-    );
+    ) as InterfaceTypeImpl;
     //
     // Populate the fields.
     //
@@ -261,15 +262,6 @@
     _objectElement = null;
   }
 
-  static FunctionTypeAliasElementImpl functionTypeAliasElement(String name,
-      {List<ParameterElement> parameters = const [], DartType returnType}) {
-    var element = FunctionTypeAliasElementImpl(name, -1);
-    element.function = GenericFunctionTypeElementImpl.forOffset(-1)
-      ..parameters = parameters
-      ..returnType = returnType ?? DynamicTypeImpl.instance;
-    return element;
-  }
-
   static PropertyAccessorElementImpl getterElement(
       String name, bool isStatic, DartType type) {
     FieldElementImpl field = FieldElementImpl(name, -1);
@@ -329,7 +321,8 @@
       method.parameters = const <ParameterElement>[];
     } else {
       int count = argumentTypes.length;
-      List<ParameterElement> parameters = List<ParameterElement>(count);
+      List<ParameterElement> parameters =
+          List<ParameterElement>.filled(count, null);
       for (int i = 0; i < count; i++) {
         ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
         parameter.type = argumentTypes[i];
@@ -462,11 +455,12 @@
     if (isConst) {
       ConstTopLevelVariableElementImpl constant =
           ConstTopLevelVariableElementImpl(name, -1);
+      var typeElement = type.element as ClassElement;
       InstanceCreationExpression initializer =
           AstTestFactory.instanceCreationExpression2(
-              Keyword.CONST, AstTestFactory.typeName(type.element));
+              Keyword.CONST, AstTestFactory.typeName(typeElement));
       if (type is InterfaceType) {
-        ConstructorElement element = type.element.unnamedConstructor;
+        ConstructorElement element = typeElement.unnamedConstructor;
         initializer.constructorName.staticElement = element;
       }
       constant.constantInitializer = initializer;
@@ -495,7 +489,7 @@
       return const <TypeParameterElement>[];
     }
     List<TypeParameterElementImpl> typeParameters =
-        List<TypeParameterElementImpl>(count);
+        List<TypeParameterElementImpl>.filled(count, null);
     for (int i = 0; i < count; i++) {
       typeParameters[i] = typeParameterWithType(names[i]);
     }
diff --git a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
index 1858a9b..3ac9ea4 100644
--- a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
+++ b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
@@ -132,7 +132,8 @@
   void _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
       AstNode target) {
     for (Element element in _promotedElements) {
-      if (_currentFunctionBody.isPotentiallyMutatedInScope(element)) {
+      if (_currentFunctionBody
+          .isPotentiallyMutatedInScope(element as VariableElement)) {
         if (_isVariableAccessedInClosure(element, target)) {
           _setType(element, null);
         }
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index cbbbaa9..025dc92 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -83,14 +83,14 @@
   }
 
   /// Combines together two hash codes.
-  static int hash2(Object a, Object b) => finish(combine(combine(0, a), b));
+  static int hash2(int a, int b) => finish(combine(combine(0, a), b));
 
   /// Combines together three hash codes.
-  static int hash3(Object a, Object b, Object c) =>
+  static int hash3(int a, int b, int c) =>
       finish(combine(combine(combine(0, a), b), c));
 
   /// Combines together four hash codes.
-  static int hash4(Object a, Object b, Object c, Object d) =>
+  static int hash4(int a, int b, int c, int d) =>
       finish(combine(combine(combine(combine(0, a), b), c), d));
 }
 
diff --git a/pkg/analyzer/lib/src/lint/config.dart b/pkg/analyzer/lib/src/lint/config.dart
index f18198a..4286bd5 100644
--- a/pkg/analyzer/lib/src/lint/config.dart
+++ b/pkg/analyzer/lib/src/lint/config.dart
@@ -20,7 +20,8 @@
 /// Process the given option [fileContents] and produce a corresponding
 /// [LintConfig].
 LintConfig processAnalysisOptionsFile(String fileContents, {String fileUrl}) {
-  var yaml = loadYamlNode(fileContents, sourceUrl: fileUrl);
+  var yaml = loadYamlNode(fileContents,
+      sourceUrl: fileUrl != null ? Uri.parse(fileUrl) : null);
   if (yaml is YamlMap) {
     return parseConfig(yaml);
   }
@@ -101,7 +102,8 @@
   }
 
   void _parse(String src, {String sourceUrl}) {
-    var yaml = loadYamlNode(src, sourceUrl: sourceUrl);
+    var yaml = loadYamlNode(src,
+        sourceUrl: sourceUrl != null ? Uri.parse(sourceUrl) : null);
     if (yaml is YamlMap) {
       _parseYaml(yaml);
     }
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
index f4d5b8f..1d2955b 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -81,7 +81,12 @@
   /// Initialize a newly created warning code to have the given [name],
   /// [message] and [correction].
   const ManifestWarningCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'ManifestWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
index fd22ea0..b47fb44 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -249,6 +249,12 @@
       if (pathEntry != null) {
         YamlNode pathKey() => getKey(dependency, PATH_FIELD);
         YamlNode pathValue() => getValue(dependency, PATH_FIELD);
+
+        if (pathEntry.contains(r'\')) {
+          _reportErrorForNode(reporter, pathValue(),
+              PubspecWarningCode.PATH_NOT_POSIX, [pathEntry]);
+          return;
+        }
         var context = provider.pathContext;
         var normalizedPath = context.joinAll(path.posix.split(pathEntry));
         var packageRoot = context.dirname(source.fullName);
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
index a93cca0..9fb2b1c 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -83,6 +83,14 @@
       correction:
           "Try creating the referenced path or using a path that exists.");
 
+  /// A code indicating that a path value is not is not posix-style.
+  ///
+  /// Parameters:
+  /// 0: the path as given in the file.
+  static const PubspecWarningCode PATH_NOT_POSIX = PubspecWarningCode(
+      'PATH_NOT_POSIX', "The path {0} is not posix.",
+      correction: "Try converting the value to a posix-style path.");
+
   /// A code indicating that a specified path dependency points to a directory
   /// that does not contain a pubspec.
   ///
@@ -109,7 +117,12 @@
   /// Initialize a newly created warning code to have the given [name],
   /// [message] and [correction].
   const PubspecWarningCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+      : super(
+          correction: correction,
+          message: message,
+          name: name,
+          uniqueName: 'PubspecWarningCode.$name',
+        );
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index b939bb9..764ea95 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -737,7 +737,7 @@
 
   @override
   E operator [](int i) {
-    _items ??= List<E>(length);
+    _items ??= List<E>.filled(length, null);
     E item = _items[i];
     if (item == null) {
       item = elementReader.read(bc, offset + 4 + elementReader.size * i);
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index cddf91d..aa37cf6 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -35,22 +35,6 @@
   }
 }
 
-class _EntityRefNullabilitySuffixReader
-    extends fb.Reader<idl.EntityRefNullabilitySuffix> {
-  const _EntityRefNullabilitySuffixReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.EntityRefNullabilitySuffix read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.EntityRefNullabilitySuffix.values.length
-        ? idl.EntityRefNullabilitySuffix.values[index]
-        : idl.EntityRefNullabilitySuffix.starOrIrrelevant;
-  }
-}
-
 class _IndexRelationKindReader extends fb.Reader<idl.IndexRelationKind> {
   const _IndexRelationKindReader() : super();
 
@@ -82,99 +66,6 @@
   }
 }
 
-class _LinkedNodeCommentTypeReader
-    extends fb.Reader<idl.LinkedNodeCommentType> {
-  const _LinkedNodeCommentTypeReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeCommentType read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeCommentType.values.length
-        ? idl.LinkedNodeCommentType.values[index]
-        : idl.LinkedNodeCommentType.block;
-  }
-}
-
-class _LinkedNodeFormalParameterKindReader
-    extends fb.Reader<idl.LinkedNodeFormalParameterKind> {
-  const _LinkedNodeFormalParameterKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeFormalParameterKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeFormalParameterKind.values.length
-        ? idl.LinkedNodeFormalParameterKind.values[index]
-        : idl.LinkedNodeFormalParameterKind.requiredPositional;
-  }
-}
-
-class _LinkedNodeKindReader extends fb.Reader<idl.LinkedNodeKind> {
-  const _LinkedNodeKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeKind.values.length
-        ? idl.LinkedNodeKind.values[index]
-        : idl.LinkedNodeKind.adjacentStrings;
-  }
-}
-
-class _LinkedNodeTypeKindReader extends fb.Reader<idl.LinkedNodeTypeKind> {
-  const _LinkedNodeTypeKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.LinkedNodeTypeKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.LinkedNodeTypeKind.values.length
-        ? idl.LinkedNodeTypeKind.values[index]
-        : idl.LinkedNodeTypeKind.dynamic_;
-  }
-}
-
-class _TopLevelInferenceErrorKindReader
-    extends fb.Reader<idl.TopLevelInferenceErrorKind> {
-  const _TopLevelInferenceErrorKindReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.TopLevelInferenceErrorKind read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.TopLevelInferenceErrorKind.values.length
-        ? idl.TopLevelInferenceErrorKind.values[index]
-        : idl.TopLevelInferenceErrorKind.assignment;
-  }
-}
-
-class _UnlinkedTokenTypeReader extends fb.Reader<idl.UnlinkedTokenType> {
-  const _UnlinkedTokenTypeReader() : super();
-
-  @override
-  int get size => 1;
-
-  @override
-  idl.UnlinkedTokenType read(fb.BufferContext bc, int offset) {
-    int index = const fb.Uint8Reader().read(bc, offset);
-    return index < idl.UnlinkedTokenType.values.length
-        ? idl.UnlinkedTokenType.values[index]
-        : idl.UnlinkedTokenType.NOTHING;
-  }
-}
-
 class AnalysisDriverExceptionContextBuilder extends Object
     with _AnalysisDriverExceptionContextMixin
     implements idl.AnalysisDriverExceptionContext {
@@ -3511,143 +3402,6 @@
   String toString() => convert.json.encode(toJson());
 }
 
-class CiderLinkedLibraryCycleBuilder extends Object
-    with _CiderLinkedLibraryCycleMixin
-    implements idl.CiderLinkedLibraryCycle {
-  LinkedNodeBundleBuilder _bundle;
-  List<int> _signature;
-
-  @override
-  LinkedNodeBundleBuilder get bundle => _bundle;
-
-  set bundle(LinkedNodeBundleBuilder value) {
-    this._bundle = value;
-  }
-
-  @override
-  List<int> get signature => _signature ??= <int>[];
-
-  /// The hash signature for this linked cycle. It depends of API signatures
-  /// of all files in the cycle, and on the signatures of the transitive
-  /// closure of the cycle dependencies.
-  set signature(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._signature = value;
-  }
-
-  CiderLinkedLibraryCycleBuilder(
-      {LinkedNodeBundleBuilder bundle, List<int> signature})
-      : _bundle = bundle,
-        _signature = signature;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _bundle?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._signature == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._signature.length);
-      for (var x in this._signature) {
-        signature.addInt(x);
-      }
-    }
-    signature.addBool(this._bundle != null);
-    this._bundle?.collectApiSignature(signature);
-  }
-
-  List<int> toBuffer() {
-    fb.Builder fbBuilder = fb.Builder();
-    return fbBuilder.finish(finish(fbBuilder), "CLNB");
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_bundle;
-    fb.Offset offset_signature;
-    if (_bundle != null) {
-      offset_bundle = _bundle.finish(fbBuilder);
-    }
-    if (!(_signature == null || _signature.isEmpty)) {
-      offset_signature = fbBuilder.writeListUint32(_signature);
-    }
-    fbBuilder.startTable();
-    if (offset_bundle != null) {
-      fbBuilder.addOffset(1, offset_bundle);
-    }
-    if (offset_signature != null) {
-      fbBuilder.addOffset(0, offset_signature);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-idl.CiderLinkedLibraryCycle readCiderLinkedLibraryCycle(List<int> buffer) {
-  fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
-  return const _CiderLinkedLibraryCycleReader().read(rootRef, 0);
-}
-
-class _CiderLinkedLibraryCycleReader
-    extends fb.TableReader<_CiderLinkedLibraryCycleImpl> {
-  const _CiderLinkedLibraryCycleReader();
-
-  @override
-  _CiderLinkedLibraryCycleImpl createObject(fb.BufferContext bc, int offset) =>
-      _CiderLinkedLibraryCycleImpl(bc, offset);
-}
-
-class _CiderLinkedLibraryCycleImpl extends Object
-    with _CiderLinkedLibraryCycleMixin
-    implements idl.CiderLinkedLibraryCycle {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _CiderLinkedLibraryCycleImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeBundle _bundle;
-  List<int> _signature;
-
-  @override
-  idl.LinkedNodeBundle get bundle {
-    _bundle ??=
-        const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _bundle;
-  }
-
-  @override
-  List<int> get signature {
-    _signature ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
-    return _signature;
-  }
-}
-
-abstract class _CiderLinkedLibraryCycleMixin
-    implements idl.CiderLinkedLibraryCycle {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (bundle != null) {
-      _result["bundle"] = bundle.toJson();
-    }
-    if (signature.isNotEmpty) {
-      _result["signature"] = signature;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "bundle": bundle,
-        "signature": signature,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class CiderUnitErrorsBuilder extends Object
     with _CiderUnitErrorsMixin
     implements idl.CiderUnitErrors {
@@ -4217,13505 +3971,28 @@
   String toString() => convert.json.encode(toJson());
 }
 
-class LinkedLanguageVersionBuilder extends Object
-    with _LinkedLanguageVersionMixin
-    implements idl.LinkedLanguageVersion {
-  int _major;
-  int _minor;
-
-  @override
-  int get major => _major ??= 0;
-
-  set major(int value) {
-    assert(value == null || value >= 0);
-    this._major = value;
-  }
-
-  @override
-  int get minor => _minor ??= 0;
-
-  set minor(int value) {
-    assert(value == null || value >= 0);
-    this._minor = value;
-  }
-
-  LinkedLanguageVersionBuilder({int major, int minor})
-      : _major = major,
-        _minor = minor;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {}
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addInt(this._major ?? 0);
-    signature.addInt(this._minor ?? 0);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fbBuilder.startTable();
-    if (_major != null && _major != 0) {
-      fbBuilder.addUint32(0, _major);
-    }
-    if (_minor != null && _minor != 0) {
-      fbBuilder.addUint32(1, _minor);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedLanguageVersionReader
-    extends fb.TableReader<_LinkedLanguageVersionImpl> {
-  const _LinkedLanguageVersionReader();
-
-  @override
-  _LinkedLanguageVersionImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedLanguageVersionImpl(bc, offset);
-}
-
-class _LinkedLanguageVersionImpl extends Object
-    with _LinkedLanguageVersionMixin
-    implements idl.LinkedLanguageVersion {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedLanguageVersionImpl(this._bc, this._bcOffset);
-
-  int _major;
-  int _minor;
-
-  @override
-  int get major {
-    _major ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
-    return _major;
-  }
-
-  @override
-  int get minor {
-    _minor ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
-    return _minor;
-  }
-}
-
-abstract class _LinkedLanguageVersionMixin
-    implements idl.LinkedLanguageVersion {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (major != 0) {
-      _result["major"] = major;
-    }
-    if (minor != 0) {
-      _result["minor"] = minor;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "major": major,
-        "minor": minor,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedLibraryLanguageVersionBuilder extends Object
-    with _LinkedLibraryLanguageVersionMixin
-    implements idl.LinkedLibraryLanguageVersion {
-  LinkedLanguageVersionBuilder _override2;
-  LinkedLanguageVersionBuilder _package;
-
-  @override
-  LinkedLanguageVersionBuilder get override2 => _override2;
-
-  set override2(LinkedLanguageVersionBuilder value) {
-    this._override2 = value;
-  }
-
-  @override
-  LinkedLanguageVersionBuilder get package => _package;
-
-  set package(LinkedLanguageVersionBuilder value) {
-    this._package = value;
-  }
-
-  LinkedLibraryLanguageVersionBuilder(
-      {LinkedLanguageVersionBuilder override2,
-      LinkedLanguageVersionBuilder package})
-      : _override2 = override2,
-        _package = package;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _override2?.flushInformative();
-    _package?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addBool(this._package != null);
-    this._package?.collectApiSignature(signature);
-    signature.addBool(this._override2 != null);
-    this._override2?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_override2;
-    fb.Offset offset_package;
-    if (_override2 != null) {
-      offset_override2 = _override2.finish(fbBuilder);
-    }
-    if (_package != null) {
-      offset_package = _package.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_override2 != null) {
-      fbBuilder.addOffset(1, offset_override2);
-    }
-    if (offset_package != null) {
-      fbBuilder.addOffset(0, offset_package);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedLibraryLanguageVersionReader
-    extends fb.TableReader<_LinkedLibraryLanguageVersionImpl> {
-  const _LinkedLibraryLanguageVersionReader();
-
-  @override
-  _LinkedLibraryLanguageVersionImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedLibraryLanguageVersionImpl(bc, offset);
-}
-
-class _LinkedLibraryLanguageVersionImpl extends Object
-    with _LinkedLibraryLanguageVersionMixin
-    implements idl.LinkedLibraryLanguageVersion {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedLibraryLanguageVersionImpl(this._bc, this._bcOffset);
-
-  idl.LinkedLanguageVersion _override2;
-  idl.LinkedLanguageVersion _package;
-
-  @override
-  idl.LinkedLanguageVersion get override2 {
-    _override2 ??=
-        const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _override2;
-  }
-
-  @override
-  idl.LinkedLanguageVersion get package {
-    _package ??=
-        const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 0, null);
-    return _package;
-  }
-}
-
-abstract class _LinkedLibraryLanguageVersionMixin
-    implements idl.LinkedLibraryLanguageVersion {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (override2 != null) {
-      _result["override2"] = override2.toJson();
-    }
-    if (package != null) {
-      _result["package"] = package.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "override2": override2,
-        "package": package,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeBuilder extends Object
-    with _LinkedNodeMixin
-    implements idl.LinkedNode {
-  LinkedNodeTypeBuilder _variantField_24;
-  List<LinkedNodeBuilder> _variantField_2;
-  List<LinkedNodeBuilder> _variantField_4;
-  LinkedNodeBuilder _variantField_6;
-  LinkedNodeBuilder _variantField_7;
-  int _variantField_17;
-  LinkedNodeBuilder _variantField_8;
-  LinkedNodeTypeSubstitutionBuilder _variantField_38;
-  int _variantField_15;
-  idl.UnlinkedTokenType _variantField_28;
-  bool _variantField_27;
-  LinkedNodeBuilder _variantField_9;
-  LinkedNodeBuilder _variantField_12;
-  List<LinkedNodeBuilder> _variantField_5;
-  LinkedNodeBuilder _variantField_13;
-  List<String> _variantField_33;
-  idl.LinkedNodeCommentType _variantField_29;
-  List<LinkedNodeBuilder> _variantField_3;
-  List<int> _variantField_41;
-  LinkedLibraryLanguageVersionBuilder _variantField_40;
-  LinkedNodeBuilder _variantField_10;
-  idl.LinkedNodeFormalParameterKind _variantField_26;
-  double _variantField_21;
-  LinkedNodeTypeBuilder _variantField_25;
-  String _variantField_20;
-  List<LinkedNodeTypeBuilder> _variantField_39;
-  int _flags;
-  String _variantField_1;
-  int _variantField_36;
-  int _variantField_16;
-  String _variantField_30;
-  LinkedNodeBuilder _variantField_14;
-  idl.LinkedNodeKind _kind;
-  bool _variantField_31;
-  List<String> _variantField_34;
-  String _name;
-  idl.UnlinkedTokenType _variantField_35;
-  TopLevelInferenceErrorBuilder _variantField_32;
-  LinkedNodeTypeBuilder _variantField_23;
-  LinkedNodeBuilder _variantField_11;
-  String _variantField_22;
-  int _variantField_19;
-
-  @override
-  LinkedNodeTypeBuilder get actualReturnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericFunctionType ||
-        kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get actualType {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get extensionOverride_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get invocationExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_24;
-  }
-
-  /// The explicit or inferred return type of a function typed node.
-  set actualReturnType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericFunctionType ||
-        kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_24 = value;
-  }
-
-  set actualType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_24 = value;
-  }
-
-  set binaryExpression_invokeType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_24 = value;
-  }
-
-  set extensionOverride_extendedType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_24 = value;
-  }
-
-  set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_24 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get adjacentStrings_strings {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get argumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get block_statements {
-    assert(kind == idl.LinkedNodeKind.block);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get cascadeExpression_sections {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get comment_references {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get compilationUnit_declarations {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get constructorDeclaration_initializers {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get dottedName_components {
-    assert(kind == idl.LinkedNodeKind.dottedName);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get enumDeclaration_constants {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get extensionOverride_arguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get formalParameterList_parameters {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get implementsClause_interfaces {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get instanceCreationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get labeledStatement_labels {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get libraryIdentifier_components {
-    assert(kind == idl.LinkedNodeKind.libraryIdentifier);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get namespaceDirective_combinators {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get onClause_superclassConstraints {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get stringInterpolation_elements {
-    assert(kind == idl.LinkedNodeKind.stringInterpolation);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get switchStatement_members {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get tryStatement_catchClauses {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typeArgumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typedLiteral_typeArguments {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typeName_typeArguments {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get typeParameterList_typeParameters {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get variableDeclarationList_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get withClause_mixinTypes {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings);
-    _variantField_2 = value;
-  }
-
-  set argumentList_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    _variantField_2 = value;
-  }
-
-  set block_statements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.block);
-    _variantField_2 = value;
-  }
-
-  set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_2 = value;
-  }
-
-  set comment_references(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_2 = value;
-  }
-
-  set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_2 = value;
-  }
-
-  set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_2 = value;
-  }
-
-  set dottedName_components(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.dottedName);
-    _variantField_2 = value;
-  }
-
-  set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_2 = value;
-  }
-
-  set extensionOverride_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_2 = value;
-  }
-
-  set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_2 = value;
-  }
-
-  set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    _variantField_2 = value;
-  }
-
-  set instanceCreationExpression_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_2 = value;
-  }
-
-  set labeledStatement_labels(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_2 = value;
-  }
-
-  set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.libraryIdentifier);
-    _variantField_2 = value;
-  }
-
-  set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_2 = value;
-  }
-
-  set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    _variantField_2 = value;
-  }
-
-  set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.stringInterpolation);
-    _variantField_2 = value;
-  }
-
-  set switchStatement_members(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_2 = value;
-  }
-
-  set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_2 = value;
-  }
-
-  set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    _variantField_2 = value;
-  }
-
-  set typedLiteral_typeArguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_2 = value;
-  }
-
-  set typeName_typeArguments(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_2 = value;
-  }
-
-  set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    _variantField_2 = value;
-  }
-
-  set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_2 = value;
-  }
-
-  set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    _variantField_2 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get annotatedNode_metadata {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.declaredIdentifier ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_4 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get normalFormalParameter_metadata {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_4 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get switchMember_statements {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    return _variantField_4 ??= <LinkedNodeBuilder>[];
-  }
-
-  set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.declaredIdentifier ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_4 = value;
-  }
-
-  set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_4 = value;
-  }
-
-  set switchMember_statements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_4 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get annotation_arguments {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get asExpression_expression {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get assertInitializer_condition {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get assertStatement_condition {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get assignmentExpression_leftHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get awaitExpression_expression {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get binaryExpression_leftOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get blockFunctionBody_block {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get breakStatement_label {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get cascadeExpression_target {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_body {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get classDeclaration_extendsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get commentReference_identifier {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get compilationUnit_scriptTag {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get conditionalExpression_condition {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get configuration_name {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorFieldInitializer_expression {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorName_name {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get continueStatement_label {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get declaredIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get defaultFormalParameter_defaultValue {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get doStatement_body {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get expressionFunctionBody_expression {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get expressionStatement_expression {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get extendsClause_superclass {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldDeclaration_fields {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get forEachParts_iterable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get forMixin_forLoopParts {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get forParts_condition {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionDeclaration_functionExpression {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionDeclarationStatement_functionDeclaration {
-    assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpression_body {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpressionInvocation_function {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypeAlias_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypedFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get genericFunctionType_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get genericTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get ifMixin_condition {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get indexExpression_index {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get interpolationExpression_expression {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get isExpression_expression {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get label_label {
-    assert(kind == idl.LinkedNodeKind.label);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get labeledStatement_statement {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get libraryDirective_name {
-    assert(kind == idl.LinkedNodeKind.libraryDirective);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get mapLiteralEntry_key {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get methodInvocation_methodName {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get mixinDeclaration_onClause {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get namedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get nativeClause_name {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get nativeFunctionBody_stringLiteral {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get parenthesizedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get partOfDirective_libraryName {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get postfixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get prefixedIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get prefixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get propertyAccess_propertyName {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get redirectingConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get returnStatement_expression {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get simpleFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get spreadElement_expression {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get superConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get switchCase_expression {
-    assert(kind == idl.LinkedNodeKind.switchCase);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get throwExpression_expression {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get topLevelVariableDeclaration_variableList {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get tryStatement_body {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get typeName_name {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get typeParameter_bound {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclaration_initializer {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclarationList_type {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclarationStatement_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get whileStatement_body {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_6;
-  }
-
-  @override
-  LinkedNodeBuilder get yieldStatement_expression {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    return _variantField_6;
-  }
-
-  set annotation_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_6 = value;
-  }
-
-  set asExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_6 = value;
-  }
-
-  set assertInitializer_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_6 = value;
-  }
-
-  set assertStatement_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_6 = value;
-  }
-
-  set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_6 = value;
-  }
-
-  set awaitExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    _variantField_6 = value;
-  }
-
-  set binaryExpression_leftOperand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_6 = value;
-  }
-
-  set blockFunctionBody_block(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    _variantField_6 = value;
-  }
-
-  set breakStatement_label(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    _variantField_6 = value;
-  }
-
-  set cascadeExpression_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_6 = value;
-  }
-
-  set catchClause_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_6 = value;
-  }
-
-  set classDeclaration_extendsClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_6 = value;
-  }
-
-  set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_6 = value;
-  }
-
-  set commentReference_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    _variantField_6 = value;
-  }
-
-  set compilationUnit_scriptTag(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_6 = value;
-  }
-
-  set conditionalExpression_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_6 = value;
-  }
-
-  set configuration_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_6 = value;
-  }
-
-  set constructorDeclaration_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_6 = value;
-  }
-
-  set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_6 = value;
-  }
-
-  set constructorName_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_6 = value;
-  }
-
-  set continueStatement_label(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    _variantField_6 = value;
-  }
-
-  set declaredIdentifier_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_6 = value;
-  }
-
-  set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set doStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_6 = value;
-  }
-
-  set expressionFunctionBody_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_6 = value;
-  }
-
-  set expressionStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    _variantField_6 = value;
-  }
-
-  set extendsClause_superclass(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    _variantField_6 = value;
-  }
-
-  set extensionDeclaration_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_6 = value;
-  }
-
-  set fieldDeclaration_fields(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_6 = value;
-  }
-
-  set fieldFormalParameter_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set forEachParts_iterable(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_6 = value;
-  }
-
-  set forMixin_forLoopParts(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_6 = value;
-  }
-
-  set forParts_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_6 = value;
-  }
-
-  set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_6 = value;
-  }
-
-  set functionDeclarationStatement_functionDeclaration(
-      LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
-    _variantField_6 = value;
-  }
-
-  set functionExpression_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_6 = value;
-  }
-
-  set functionExpressionInvocation_function(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
-    _variantField_6 = value;
-  }
-
-  set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_6 = value;
-  }
-
-  set functionTypedFormalParameter_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_6 = value;
-  }
-
-  set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_6 = value;
-  }
-
-  set ifMixin_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_6 = value;
-  }
-
-  set indexExpression_index(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_6 = value;
-  }
-
-  set interpolationExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    _variantField_6 = value;
-  }
-
-  set isExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_6 = value;
-  }
-
-  set label_label(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.label);
-    _variantField_6 = value;
-  }
-
-  set labeledStatement_statement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_6 = value;
-  }
-
-  set libraryDirective_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.libraryDirective);
-    _variantField_6 = value;
-  }
-
-  set mapLiteralEntry_key(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_6 = value;
-  }
-
-  set methodDeclaration_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_6 = value;
-  }
-
-  set methodInvocation_methodName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_6 = value;
-  }
-
-  set mixinDeclaration_onClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_6 = value;
-  }
-
-  set namedExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_6 = value;
-  }
-
-  set nativeClause_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    _variantField_6 = value;
-  }
-
-  set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    _variantField_6 = value;
-  }
-
-  set parenthesizedExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    _variantField_6 = value;
-  }
-
-  set partOfDirective_libraryName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_6 = value;
-  }
-
-  set postfixExpression_operand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_6 = value;
-  }
-
-  set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_6 = value;
-  }
-
-  set prefixExpression_operand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_6 = value;
-  }
-
-  set propertyAccess_propertyName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_6 = value;
-  }
-
-  set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_6 = value;
-  }
-
-  set returnStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    _variantField_6 = value;
-  }
-
-  set simpleFormalParameter_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_6 = value;
-  }
-
-  set spreadElement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_6 = value;
-  }
-
-  set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_6 = value;
-  }
-
-  set switchCase_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.switchCase);
-    _variantField_6 = value;
-  }
-
-  set throwExpression_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_6 = value;
-  }
-
-  set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_6 = value;
-  }
-
-  set tryStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_6 = value;
-  }
-
-  set typeName_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_6 = value;
-  }
-
-  set typeParameter_bound(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_6 = value;
-  }
-
-  set variableDeclaration_initializer(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_6 = value;
-  }
-
-  set variableDeclarationList_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_6 = value;
-  }
-
-  set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    _variantField_6 = value;
-  }
-
-  set whileStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_6 = value;
-  }
-
-  set yieldStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_6 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get annotation_constructorName {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get asExpression_type {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get assertInitializer_message {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get assertStatement_message {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get assignmentExpression_rightHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get binaryExpression_rightOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_exceptionParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get classDeclaration_withClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_superclass {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get conditionalExpression_elseExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get configuration_value {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorFieldInitializer_fieldName {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorName_type {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get declaredIdentifier_type {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get defaultFormalParameter_parameter {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get doStatement_condition {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionDeclaration_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionOverride_extensionName {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forEachPartsWithDeclaration_loopVariable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forEachPartsWithIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forElement_body {
-    assert(kind == idl.LinkedNodeKind.forElement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forPartsWithDeclarations_variables {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forPartsWithExpression_initialization {
-    assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get forStatement_body {
-    assert(kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpression_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypeAlias_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypedFormalParameter_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get genericFunctionType_returnType {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get genericTypeAlias_functionType {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get ifStatement_elseStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get indexExpression_target {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get instanceCreationExpression_constructorName {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get isExpression_type {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get mapLiteralEntry_value {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_formalParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get methodInvocation_target {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get namedExpression_name {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get partOfDirective_uri {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get prefixedIdentifier_prefix {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get propertyAccess_target {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get redirectingConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get superConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get switchStatement_expression {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get tryStatement_finallyBlock {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get whileStatement_condition {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_7;
-  }
-
-  set annotation_constructorName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_7 = value;
-  }
-
-  set asExpression_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_7 = value;
-  }
-
-  set assertInitializer_message(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_7 = value;
-  }
-
-  set assertStatement_message(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_7 = value;
-  }
-
-  set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_7 = value;
-  }
-
-  set binaryExpression_rightOperand(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_7 = value;
-  }
-
-  set catchClause_exceptionParameter(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_7 = value;
-  }
-
-  set classDeclaration_withClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_7 = value;
-  }
-
-  set classTypeAlias_superclass(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_7 = value;
-  }
-
-  set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_7 = value;
-  }
-
-  set configuration_value(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_7 = value;
-  }
-
-  set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_7 = value;
-  }
-
-  set constructorName_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_7 = value;
-  }
-
-  set declaredIdentifier_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_7 = value;
-  }
-
-  set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_7 = value;
-  }
-
-  set doStatement_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_7 = value;
-  }
-
-  set extensionDeclaration_extendedType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_7 = value;
-  }
-
-  set extensionOverride_extensionName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_7 = value;
-  }
-
-  set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_7 = value;
-  }
-
-  set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
-    _variantField_7 = value;
-  }
-
-  set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_7 = value;
-  }
-
-  set forElement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forElement);
-    _variantField_7 = value;
-  }
-
-  set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
-    _variantField_7 = value;
-  }
-
-  set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_7 = value;
-  }
-
-  set forStatement_body(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.forStatement);
-    _variantField_7 = value;
-  }
-
-  set functionDeclaration_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_7 = value;
-  }
-
-  set functionExpression_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_7 = value;
-  }
-
-  set functionTypeAlias_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_7 = value;
-  }
-
-  set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_7 = value;
-  }
-
-  set genericFunctionType_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_7 = value;
-  }
-
-  set genericTypeAlias_functionType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_7 = value;
-  }
-
-  set ifStatement_elseStatement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_7 = value;
-  }
-
-  set indexExpression_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_7 = value;
-  }
-
-  set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_7 = value;
-  }
-
-  set isExpression_type(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_7 = value;
-  }
-
-  set mapLiteralEntry_value(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_7 = value;
-  }
-
-  set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_7 = value;
-  }
-
-  set methodInvocation_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_7 = value;
-  }
-
-  set namedExpression_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_7 = value;
-  }
-
-  set partOfDirective_uri(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_7 = value;
-  }
-
-  set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_7 = value;
-  }
-
-  set propertyAccess_target(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_7 = value;
-  }
-
-  set redirectingConstructorInvocation_constructorName(
-      LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_7 = value;
-  }
-
-  set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_7 = value;
-  }
-
-  set switchStatement_expression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_7 = value;
-  }
-
-  set tryStatement_finallyBlock(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_7 = value;
-  }
-
-  set whileStatement_condition(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_7 = value;
-  }
-
-  @override
-  int get annotation_element {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get genericFunctionType_id {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_17 ??= 0;
-  }
-
-  set annotation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set genericFunctionType_id(int value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get annotation_name {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_exceptionType {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get classDeclaration_nativeClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_withClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get conditionalExpression_thenExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get configuration_uri {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_parameters {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get extensionOverride_typeArguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get fieldFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get functionExpression_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get functionTypedFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get genericFunctionType_formalParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get ifElement_thenElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get ifStatement_thenStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get instanceCreationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_8;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_8;
-  }
-
-  set annotation_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_8 = value;
-  }
-
-  set catchClause_exceptionType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_8 = value;
-  }
-
-  set classDeclaration_nativeClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_8 = value;
-  }
-
-  set classTypeAlias_withClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_8 = value;
-  }
-
-  set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_8 = value;
-  }
-
-  set configuration_uri(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_8 = value;
-  }
-
-  set constructorDeclaration_parameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_8 = value;
-  }
-
-  set extensionOverride_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_8 = value;
-  }
-
-  set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_8 = value;
-  }
-
-  set functionExpression_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_8 = value;
-  }
-
-  set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_8 = value;
-  }
-
-  set functionTypedFormalParameter_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_8 = value;
-  }
-
-  set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_8 = value;
-  }
-
-  set ifElement_thenElement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_8 = value;
-  }
-
-  set ifStatement_thenStatement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_8 = value;
-  }
-
-  set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_8 = value;
-  }
-
-  set methodDeclaration_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_8 = value;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get annotation_substitution {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get assignmentExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get binaryExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get constructorName_substitution {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get indexExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get postfixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get prefixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder
-      get redirectingConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder get simpleIdentifier_substitution {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_38;
-  }
-
-  @override
-  LinkedNodeTypeSubstitutionBuilder
-      get superConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_38;
-  }
-
-  set annotation_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_38 = value;
-  }
-
-  set assignmentExpression_substitution(
-      LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_38 = value;
-  }
-
-  set binaryExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_38 = value;
-  }
-
-  set constructorName_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_38 = value;
-  }
-
-  set indexExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_38 = value;
-  }
-
-  set postfixExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_38 = value;
-  }
-
-  set prefixExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_38 = value;
-  }
-
-  set redirectingConstructorInvocation_substitution(
-      LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_38 = value;
-  }
-
-  set simpleIdentifier_substitution(LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_38 = value;
-  }
-
-  set superConstructorInvocation_substitution(
-      LinkedNodeTypeSubstitutionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_38 = value;
-  }
-
-  @override
-  int get assignmentExpression_element {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get binaryExpression_element {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get constructorName_element {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get emptyFunctionBody_fake {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get emptyStatement_fake {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get indexExpression_element {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get nullLiteral_fake {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get postfixExpression_element {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get prefixExpression_element {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get simpleIdentifier_element {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get superConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get typeParameter_variance {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_15 ??= 0;
-  }
-
-  set assignmentExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set binaryExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set constructorName_element(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set emptyFunctionBody_fake(int value) {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set emptyStatement_fake(int value) {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set indexExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set nullLiteral_fake(int value) {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set postfixExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set prefixExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set redirectingConstructorInvocation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set simpleIdentifier_element(int value) {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set superConstructorInvocation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set typeParameter_variance(int value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  @override
-  idl.UnlinkedTokenType get assignmentExpression_operator {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get binaryExpression_operator {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get postfixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get prefixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  @override
-  idl.UnlinkedTokenType get propertyAccess_operator {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  set assignmentExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_28 = value;
-  }
-
-  set binaryExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_28 = value;
-  }
-
-  set postfixExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_28 = value;
-  }
-
-  set prefixExpression_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_28 = value;
-  }
-
-  set propertyAccess_operator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_28 = value;
-  }
-
-  @override
-  bool get booleanLiteral_value {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get classDeclaration_isDartObject {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get inheritsCovariant {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get typeAlias_hasSelfReference {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_27 ??= false;
-  }
-
-  set booleanLiteral_value(bool value) {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    _variantField_27 = value;
-  }
-
-  set classDeclaration_isDartObject(bool value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_27 = value;
-  }
-
-  set inheritsCovariant(bool value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_27 = value;
-  }
-
-  set typeAlias_hasSelfReference(bool value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_27 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get catchClause_stackTraceParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get classTypeAlias_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_redirectedConstructor {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get ifElement_elseElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    return _variantField_9;
-  }
-
-  @override
-  LinkedNodeBuilder get methodDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_9;
-  }
-
-  set catchClause_stackTraceParameter(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_9 = value;
-  }
-
-  set classTypeAlias_implementsClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_9 = value;
-  }
-
-  set constructorDeclaration_redirectedConstructor(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_9 = value;
-  }
-
-  set ifElement_elseElement(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_9 = value;
-  }
-
-  set methodDeclaration_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_9 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get classOrMixinDeclaration_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_12;
-  }
-
-  @override
-  LinkedNodeBuilder get invocationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_12;
-  }
-
-  set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_12 = value;
-  }
-
-  set invocationExpression_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_12 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get classOrMixinDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_5 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get extensionDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_5 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get forParts_updaters {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_5 ??= <LinkedNodeBuilder>[];
-  }
-
-  set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_5 = value;
-  }
-
-  set extensionDeclaration_members(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_5 = value;
-  }
-
-  set forParts_updaters(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_5 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get classOrMixinDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_13;
-  }
-
-  set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_13 = value;
-  }
-
-  @override
-  List<String> get comment_tokens {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_33 ??= <String>[];
-  }
-
-  set comment_tokens(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_33 = value;
-  }
-
-  @override
-  idl.LinkedNodeCommentType get comment_type {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_29 ??= idl.LinkedNodeCommentType.block;
-  }
-
-  set comment_type(idl.LinkedNodeCommentType value) {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_29 = value;
-  }
-
-  @override
-  List<LinkedNodeBuilder> get compilationUnit_directives {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get listLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get namespaceDirective_configurations {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get setOrMapLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get switchMember_labels {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    return _variantField_3 ??= <LinkedNodeBuilder>[];
-  }
-
-  set compilationUnit_directives(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_3 = value;
-  }
-
-  set listLiteral_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_3 = value;
-  }
-
-  set namespaceDirective_configurations(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_3 = value;
-  }
-
-  set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_3 = value;
-  }
-
-  set switchMember_labels(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_3 = value;
-  }
-
-  @override
-  List<int> get compilationUnit_featureSet {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_41 ??= <int>[];
-  }
-
-  set compilationUnit_featureSet(List<int> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    assert(value == null || value.every((e) => e >= 0));
-    _variantField_41 = value;
-  }
-
-  @override
-  LinkedLibraryLanguageVersionBuilder get compilationUnit_languageVersion {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_40;
-  }
-
-  /// The language version information.
-  set compilationUnit_languageVersion(
-      LinkedLibraryLanguageVersionBuilder value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_40 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get constructorDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_10;
-  }
-
-  set constructorDeclaration_returnType(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_10 = value;
-  }
-
-  @override
-  idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_26 ??=
-        idl.LinkedNodeFormalParameterKind.requiredPositional;
-  }
-
-  set defaultFormalParameter_kind(idl.LinkedNodeFormalParameterKind value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_26 = value;
-  }
-
-  @override
-  double get doubleLiteral_value {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    return _variantField_21 ??= 0.0;
-  }
-
-  set doubleLiteral_value(double value) {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    _variantField_21 = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get expression_type {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
-        kind == idl.LinkedNodeKind.asExpression ||
-        kind == idl.LinkedNodeKind.awaitExpression ||
-        kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.cascadeExpression ||
-        kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.indexExpression ||
-        kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.nullLiteral ||
-        kind == idl.LinkedNodeKind.parenthesizedExpression ||
-        kind == idl.LinkedNodeKind.prefixExpression ||
-        kind == idl.LinkedNodeKind.prefixedIdentifier ||
-        kind == idl.LinkedNodeKind.propertyAccess ||
-        kind == idl.LinkedNodeKind.postfixExpression ||
-        kind == idl.LinkedNodeKind.rethrowExpression ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral ||
-        kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.superExpression ||
-        kind == idl.LinkedNodeKind.symbolLiteral ||
-        kind == idl.LinkedNodeKind.thisExpression ||
-        kind == idl.LinkedNodeKind.throwExpression);
-    return _variantField_25;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get genericFunctionType_type {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_25;
-  }
-
-  set expression_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
-        kind == idl.LinkedNodeKind.asExpression ||
-        kind == idl.LinkedNodeKind.awaitExpression ||
-        kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.cascadeExpression ||
-        kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.indexExpression ||
-        kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.nullLiteral ||
-        kind == idl.LinkedNodeKind.parenthesizedExpression ||
-        kind == idl.LinkedNodeKind.prefixExpression ||
-        kind == idl.LinkedNodeKind.prefixedIdentifier ||
-        kind == idl.LinkedNodeKind.propertyAccess ||
-        kind == idl.LinkedNodeKind.postfixExpression ||
-        kind == idl.LinkedNodeKind.rethrowExpression ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral ||
-        kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.superExpression ||
-        kind == idl.LinkedNodeKind.symbolLiteral ||
-        kind == idl.LinkedNodeKind.thisExpression ||
-        kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_25 = value;
-  }
-
-  set genericFunctionType_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_25 = value;
-  }
-
-  @override
-  String get extensionDeclaration_refName {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    return _variantField_20 ??= '';
-  }
-
-  @override
-  String get namespaceDirective_selectedUri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_20 ??= '';
-  }
-
-  @override
-  String get simpleStringLiteral_value {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    return _variantField_20 ??= '';
-  }
-
-  set extensionDeclaration_refName(String value) {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_20 = value;
-  }
-
-  set namespaceDirective_selectedUri(String value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_20 = value;
-  }
-
-  set simpleStringLiteral_value(String value) {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    _variantField_20 = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get extensionOverride_typeArgumentTypes {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    return _variantField_39 ??= <LinkedNodeTypeBuilder>[];
-  }
-
-  set extensionOverride_typeArgumentTypes(List<LinkedNodeTypeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_39 = value;
-  }
-
-  @override
-  int get flags => _flags ??= 0;
-
-  set flags(int value) {
-    assert(value == null || value >= 0);
-    this._flags = value;
-  }
-
-  @override
-  String get importDirective_prefix {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_1 ??= '';
-  }
-
-  set importDirective_prefix(String value) {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_1 = value;
-  }
-
-  @override
-  int get informativeId {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_36 ??= 0;
-  }
-
-  set informativeId(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    assert(value == null || value >= 0);
-    _variantField_36 = value;
-  }
-
-  @override
-  int get integerLiteral_value {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    return _variantField_16 ??= 0;
-  }
-
-  set integerLiteral_value(int value) {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  @override
-  String get interpolationString_value {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    return _variantField_30 ??= '';
-  }
-
-  set interpolationString_value(String value) {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    _variantField_30 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get invocationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_14;
-  }
-
-  @override
-  LinkedNodeBuilder get uriBasedDirective_uri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_14;
-  }
-
-  set invocationExpression_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_14 = value;
-  }
-
-  set uriBasedDirective_uri(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_14 = value;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
-
-  set kind(idl.LinkedNodeKind value) {
-    this._kind = value;
-  }
-
-  @override
-  bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_31 ??= false;
-  }
-
-  @override
-  bool get simplyBoundable_isSimplyBounded {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_31 ??= false;
-  }
-
-  set methodDeclaration_hasOperatorEqualWithParameterTypeFromObject(
-      bool value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_31 = value;
-  }
-
-  set simplyBoundable_isSimplyBounded(bool value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_31 = value;
-  }
-
-  @override
-  List<String> get mixinDeclaration_superInvokedNames {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_34 ??= <String>[];
-  }
-
-  @override
-  List<String> get names {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.symbolLiteral);
-    return _variantField_34 ??= <String>[];
-  }
-
-  set mixinDeclaration_superInvokedNames(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_34 = value;
-  }
-
-  set names(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.symbolLiteral);
-    _variantField_34 = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  @override
-  idl.UnlinkedTokenType get spreadElement_spreadOperator {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    return _variantField_35 ??= idl.UnlinkedTokenType.NOTHING;
-  }
-
-  set spreadElement_spreadOperator(idl.UnlinkedTokenType value) {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_35 = value;
-  }
-
-  @override
-  TopLevelInferenceErrorBuilder get topLevelTypeInferenceError {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_32;
-  }
-
-  set topLevelTypeInferenceError(TopLevelInferenceErrorBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_32 = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get typeName_type {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_23;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get typeParameter_defaultType {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_23;
-  }
-
-  set typeName_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_23 = value;
-  }
-
-  set typeParameter_defaultType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_23 = value;
-  }
-
-  @override
-  LinkedNodeBuilder get unused11 {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_11;
-  }
-
-  set unused11(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_11 = value;
-  }
-
-  @override
-  String get uriBasedDirective_uriContent {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_22 ??= '';
-  }
-
-  set uriBasedDirective_uriContent(String value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_22 = value;
-  }
-
-  @override
-  int get uriBasedDirective_uriElement {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_19 ??= 0;
-  }
-
-  set uriBasedDirective_uriElement(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  LinkedNodeBuilder.adjacentStrings({
-    List<LinkedNodeBuilder> adjacentStrings_strings,
-  })  : _kind = idl.LinkedNodeKind.adjacentStrings,
-        _variantField_2 = adjacentStrings_strings;
-
-  LinkedNodeBuilder.annotation({
-    LinkedNodeBuilder annotation_arguments,
-    LinkedNodeBuilder annotation_constructorName,
-    int annotation_element,
-    LinkedNodeBuilder annotation_name,
-    LinkedNodeTypeSubstitutionBuilder annotation_substitution,
-  })  : _kind = idl.LinkedNodeKind.annotation,
-        _variantField_6 = annotation_arguments,
-        _variantField_7 = annotation_constructorName,
-        _variantField_17 = annotation_element,
-        _variantField_8 = annotation_name,
-        _variantField_38 = annotation_substitution;
-
-  LinkedNodeBuilder.argumentList({
-    List<LinkedNodeBuilder> argumentList_arguments,
-  })  : _kind = idl.LinkedNodeKind.argumentList,
-        _variantField_2 = argumentList_arguments;
-
-  LinkedNodeBuilder.asExpression({
-    LinkedNodeBuilder asExpression_expression,
-    LinkedNodeBuilder asExpression_type,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.asExpression,
-        _variantField_6 = asExpression_expression,
-        _variantField_7 = asExpression_type,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.assertInitializer({
-    LinkedNodeBuilder assertInitializer_condition,
-    LinkedNodeBuilder assertInitializer_message,
-  })  : _kind = idl.LinkedNodeKind.assertInitializer,
-        _variantField_6 = assertInitializer_condition,
-        _variantField_7 = assertInitializer_message;
-
-  LinkedNodeBuilder.assertStatement({
-    LinkedNodeBuilder assertStatement_condition,
-    LinkedNodeBuilder assertStatement_message,
-  })  : _kind = idl.LinkedNodeKind.assertStatement,
-        _variantField_6 = assertStatement_condition,
-        _variantField_7 = assertStatement_message;
-
-  LinkedNodeBuilder.assignmentExpression({
-    LinkedNodeBuilder assignmentExpression_leftHandSide,
-    LinkedNodeBuilder assignmentExpression_rightHandSide,
-    LinkedNodeTypeSubstitutionBuilder assignmentExpression_substitution,
-    int assignmentExpression_element,
-    idl.UnlinkedTokenType assignmentExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.assignmentExpression,
-        _variantField_6 = assignmentExpression_leftHandSide,
-        _variantField_7 = assignmentExpression_rightHandSide,
-        _variantField_38 = assignmentExpression_substitution,
-        _variantField_15 = assignmentExpression_element,
-        _variantField_28 = assignmentExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.awaitExpression({
-    LinkedNodeBuilder awaitExpression_expression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.awaitExpression,
-        _variantField_6 = awaitExpression_expression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.binaryExpression({
-    LinkedNodeTypeBuilder binaryExpression_invokeType,
-    LinkedNodeBuilder binaryExpression_leftOperand,
-    LinkedNodeBuilder binaryExpression_rightOperand,
-    LinkedNodeTypeSubstitutionBuilder binaryExpression_substitution,
-    int binaryExpression_element,
-    idl.UnlinkedTokenType binaryExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.binaryExpression,
-        _variantField_24 = binaryExpression_invokeType,
-        _variantField_6 = binaryExpression_leftOperand,
-        _variantField_7 = binaryExpression_rightOperand,
-        _variantField_38 = binaryExpression_substitution,
-        _variantField_15 = binaryExpression_element,
-        _variantField_28 = binaryExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.block({
-    List<LinkedNodeBuilder> block_statements,
-  })  : _kind = idl.LinkedNodeKind.block,
-        _variantField_2 = block_statements;
-
-  LinkedNodeBuilder.blockFunctionBody({
-    LinkedNodeBuilder blockFunctionBody_block,
-  })  : _kind = idl.LinkedNodeKind.blockFunctionBody,
-        _variantField_6 = blockFunctionBody_block;
-
-  LinkedNodeBuilder.booleanLiteral({
-    bool booleanLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.booleanLiteral,
-        _variantField_27 = booleanLiteral_value;
-
-  LinkedNodeBuilder.breakStatement({
-    LinkedNodeBuilder breakStatement_label,
-  })  : _kind = idl.LinkedNodeKind.breakStatement,
-        _variantField_6 = breakStatement_label;
-
-  LinkedNodeBuilder.cascadeExpression({
-    List<LinkedNodeBuilder> cascadeExpression_sections,
-    LinkedNodeBuilder cascadeExpression_target,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.cascadeExpression,
-        _variantField_2 = cascadeExpression_sections,
-        _variantField_6 = cascadeExpression_target,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.catchClause({
-    LinkedNodeBuilder catchClause_body,
-    LinkedNodeBuilder catchClause_exceptionParameter,
-    LinkedNodeBuilder catchClause_exceptionType,
-    LinkedNodeBuilder catchClause_stackTraceParameter,
-  })  : _kind = idl.LinkedNodeKind.catchClause,
-        _variantField_6 = catchClause_body,
-        _variantField_7 = catchClause_exceptionParameter,
-        _variantField_8 = catchClause_exceptionType,
-        _variantField_9 = catchClause_stackTraceParameter;
-
-  LinkedNodeBuilder.classDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder classDeclaration_extendsClause,
-    LinkedNodeBuilder classDeclaration_withClause,
-    LinkedNodeBuilder classDeclaration_nativeClause,
-    bool classDeclaration_isDartObject,
-    LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
-    List<LinkedNodeBuilder> classOrMixinDeclaration_members,
-    LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-    LinkedNodeBuilder unused11,
-  })  : _kind = idl.LinkedNodeKind.classDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = classDeclaration_extendsClause,
-        _variantField_7 = classDeclaration_withClause,
-        _variantField_8 = classDeclaration_nativeClause,
-        _variantField_27 = classDeclaration_isDartObject,
-        _variantField_12 = classOrMixinDeclaration_implementsClause,
-        _variantField_5 = classOrMixinDeclaration_members,
-        _variantField_13 = classOrMixinDeclaration_typeParameters,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded,
-        _variantField_11 = unused11;
-
-  LinkedNodeBuilder.classTypeAlias({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder classTypeAlias_typeParameters,
-    LinkedNodeBuilder classTypeAlias_superclass,
-    LinkedNodeBuilder classTypeAlias_withClause,
-    LinkedNodeBuilder classTypeAlias_implementsClause,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-  })  : _kind = idl.LinkedNodeKind.classTypeAlias,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = classTypeAlias_typeParameters,
-        _variantField_7 = classTypeAlias_superclass,
-        _variantField_8 = classTypeAlias_withClause,
-        _variantField_9 = classTypeAlias_implementsClause,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded;
-
-  LinkedNodeBuilder.comment({
-    List<LinkedNodeBuilder> comment_references,
-    List<String> comment_tokens,
-    idl.LinkedNodeCommentType comment_type,
-  })  : _kind = idl.LinkedNodeKind.comment,
-        _variantField_2 = comment_references,
-        _variantField_33 = comment_tokens,
-        _variantField_29 = comment_type;
-
-  LinkedNodeBuilder.commentReference({
-    LinkedNodeBuilder commentReference_identifier,
-  })  : _kind = idl.LinkedNodeKind.commentReference,
-        _variantField_6 = commentReference_identifier;
-
-  LinkedNodeBuilder.compilationUnit({
-    List<LinkedNodeBuilder> compilationUnit_declarations,
-    LinkedNodeBuilder compilationUnit_scriptTag,
-    List<LinkedNodeBuilder> compilationUnit_directives,
-    List<int> compilationUnit_featureSet,
-    LinkedLibraryLanguageVersionBuilder compilationUnit_languageVersion,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.compilationUnit,
-        _variantField_2 = compilationUnit_declarations,
-        _variantField_6 = compilationUnit_scriptTag,
-        _variantField_3 = compilationUnit_directives,
-        _variantField_41 = compilationUnit_featureSet,
-        _variantField_40 = compilationUnit_languageVersion,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.conditionalExpression({
-    LinkedNodeBuilder conditionalExpression_condition,
-    LinkedNodeBuilder conditionalExpression_elseExpression,
-    LinkedNodeBuilder conditionalExpression_thenExpression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.conditionalExpression,
-        _variantField_6 = conditionalExpression_condition,
-        _variantField_7 = conditionalExpression_elseExpression,
-        _variantField_8 = conditionalExpression_thenExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.configuration({
-    LinkedNodeBuilder configuration_name,
-    LinkedNodeBuilder configuration_value,
-    LinkedNodeBuilder configuration_uri,
-  })  : _kind = idl.LinkedNodeKind.configuration,
-        _variantField_6 = configuration_name,
-        _variantField_7 = configuration_value,
-        _variantField_8 = configuration_uri;
-
-  LinkedNodeBuilder.constructorDeclaration({
-    List<LinkedNodeBuilder> constructorDeclaration_initializers,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder constructorDeclaration_body,
-    LinkedNodeBuilder constructorDeclaration_parameters,
-    LinkedNodeBuilder constructorDeclaration_redirectedConstructor,
-    LinkedNodeBuilder constructorDeclaration_returnType,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.constructorDeclaration,
-        _variantField_2 = constructorDeclaration_initializers,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = constructorDeclaration_body,
-        _variantField_8 = constructorDeclaration_parameters,
-        _variantField_9 = constructorDeclaration_redirectedConstructor,
-        _variantField_10 = constructorDeclaration_returnType,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.constructorFieldInitializer({
-    LinkedNodeBuilder constructorFieldInitializer_expression,
-    LinkedNodeBuilder constructorFieldInitializer_fieldName,
-  })  : _kind = idl.LinkedNodeKind.constructorFieldInitializer,
-        _variantField_6 = constructorFieldInitializer_expression,
-        _variantField_7 = constructorFieldInitializer_fieldName;
-
-  LinkedNodeBuilder.constructorName({
-    LinkedNodeBuilder constructorName_name,
-    LinkedNodeBuilder constructorName_type,
-    LinkedNodeTypeSubstitutionBuilder constructorName_substitution,
-    int constructorName_element,
-  })  : _kind = idl.LinkedNodeKind.constructorName,
-        _variantField_6 = constructorName_name,
-        _variantField_7 = constructorName_type,
-        _variantField_38 = constructorName_substitution,
-        _variantField_15 = constructorName_element;
-
-  LinkedNodeBuilder.continueStatement({
-    LinkedNodeBuilder continueStatement_label,
-  })  : _kind = idl.LinkedNodeKind.continueStatement,
-        _variantField_6 = continueStatement_label;
-
-  LinkedNodeBuilder.declaredIdentifier({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder declaredIdentifier_identifier,
-    LinkedNodeBuilder declaredIdentifier_type,
-  })  : _kind = idl.LinkedNodeKind.declaredIdentifier,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = declaredIdentifier_identifier,
-        _variantField_7 = declaredIdentifier_type;
-
-  LinkedNodeBuilder.defaultFormalParameter({
-    LinkedNodeBuilder defaultFormalParameter_defaultValue,
-    LinkedNodeBuilder defaultFormalParameter_parameter,
-    idl.LinkedNodeFormalParameterKind defaultFormalParameter_kind,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
-        _variantField_6 = defaultFormalParameter_defaultValue,
-        _variantField_7 = defaultFormalParameter_parameter,
-        _variantField_26 = defaultFormalParameter_kind,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.doStatement({
-    LinkedNodeBuilder doStatement_body,
-    LinkedNodeBuilder doStatement_condition,
-  })  : _kind = idl.LinkedNodeKind.doStatement,
-        _variantField_6 = doStatement_body,
-        _variantField_7 = doStatement_condition;
-
-  LinkedNodeBuilder.dottedName({
-    List<LinkedNodeBuilder> dottedName_components,
-  })  : _kind = idl.LinkedNodeKind.dottedName,
-        _variantField_2 = dottedName_components;
-
-  LinkedNodeBuilder.doubleLiteral({
-    double doubleLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.doubleLiteral,
-        _variantField_21 = doubleLiteral_value;
-
-  LinkedNodeBuilder.emptyFunctionBody({
-    int emptyFunctionBody_fake,
-  })  : _kind = idl.LinkedNodeKind.emptyFunctionBody,
-        _variantField_15 = emptyFunctionBody_fake;
-
-  LinkedNodeBuilder.emptyStatement({
-    int emptyStatement_fake,
-  })  : _kind = idl.LinkedNodeKind.emptyStatement,
-        _variantField_15 = emptyStatement_fake;
-
-  LinkedNodeBuilder.enumConstantDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.enumDeclaration({
-    List<LinkedNodeBuilder> enumDeclaration_constants,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.enumDeclaration,
-        _variantField_2 = enumDeclaration_constants,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.exportDirective({
-    List<LinkedNodeBuilder> namespaceDirective_combinators,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    List<LinkedNodeBuilder> namespaceDirective_configurations,
-    String namespaceDirective_selectedUri,
-    int informativeId,
-    LinkedNodeBuilder uriBasedDirective_uri,
-    String uriBasedDirective_uriContent,
-    int uriBasedDirective_uriElement,
-  })  : _kind = idl.LinkedNodeKind.exportDirective,
-        _variantField_2 = namespaceDirective_combinators,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_3 = namespaceDirective_configurations,
-        _variantField_20 = namespaceDirective_selectedUri,
-        _variantField_36 = informativeId,
-        _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent,
-        _variantField_19 = uriBasedDirective_uriElement;
-
-  LinkedNodeBuilder.expressionFunctionBody({
-    LinkedNodeBuilder expressionFunctionBody_expression,
-  })  : _kind = idl.LinkedNodeKind.expressionFunctionBody,
-        _variantField_6 = expressionFunctionBody_expression;
-
-  LinkedNodeBuilder.expressionStatement({
-    LinkedNodeBuilder expressionStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.expressionStatement,
-        _variantField_6 = expressionStatement_expression;
-
-  LinkedNodeBuilder.extendsClause({
-    LinkedNodeBuilder extendsClause_superclass,
-  })  : _kind = idl.LinkedNodeKind.extendsClause,
-        _variantField_6 = extendsClause_superclass;
-
-  LinkedNodeBuilder.extensionDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder extensionDeclaration_typeParameters,
-    LinkedNodeBuilder extensionDeclaration_extendedType,
-    List<LinkedNodeBuilder> extensionDeclaration_members,
-    String extensionDeclaration_refName,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.extensionDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = extensionDeclaration_typeParameters,
-        _variantField_7 = extensionDeclaration_extendedType,
-        _variantField_5 = extensionDeclaration_members,
-        _variantField_20 = extensionDeclaration_refName,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.extensionOverride({
-    LinkedNodeTypeBuilder extensionOverride_extendedType,
-    List<LinkedNodeBuilder> extensionOverride_arguments,
-    LinkedNodeBuilder extensionOverride_extensionName,
-    LinkedNodeBuilder extensionOverride_typeArguments,
-    List<LinkedNodeTypeBuilder> extensionOverride_typeArgumentTypes,
-  })  : _kind = idl.LinkedNodeKind.extensionOverride,
-        _variantField_24 = extensionOverride_extendedType,
-        _variantField_2 = extensionOverride_arguments,
-        _variantField_7 = extensionOverride_extensionName,
-        _variantField_8 = extensionOverride_typeArguments,
-        _variantField_39 = extensionOverride_typeArgumentTypes;
-
-  LinkedNodeBuilder.fieldDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder fieldDeclaration_fields,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.fieldDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = fieldDeclaration_fields,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.fieldFormalParameter({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder fieldFormalParameter_type,
-    LinkedNodeBuilder fieldFormalParameter_typeParameters,
-    LinkedNodeBuilder fieldFormalParameter_formalParameters,
-    bool inheritsCovariant,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.fieldFormalParameter,
-        _variantField_24 = actualType,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = fieldFormalParameter_type,
-        _variantField_7 = fieldFormalParameter_typeParameters,
-        _variantField_8 = fieldFormalParameter_formalParameters,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.forEachPartsWithDeclaration({
-    LinkedNodeBuilder forEachParts_iterable,
-    LinkedNodeBuilder forEachPartsWithDeclaration_loopVariable,
-  })  : _kind = idl.LinkedNodeKind.forEachPartsWithDeclaration,
-        _variantField_6 = forEachParts_iterable,
-        _variantField_7 = forEachPartsWithDeclaration_loopVariable;
-
-  LinkedNodeBuilder.forEachPartsWithIdentifier({
-    LinkedNodeBuilder forEachParts_iterable,
-    LinkedNodeBuilder forEachPartsWithIdentifier_identifier,
-  })  : _kind = idl.LinkedNodeKind.forEachPartsWithIdentifier,
-        _variantField_6 = forEachParts_iterable,
-        _variantField_7 = forEachPartsWithIdentifier_identifier;
-
-  LinkedNodeBuilder.forElement({
-    LinkedNodeBuilder forMixin_forLoopParts,
-    LinkedNodeBuilder forElement_body,
-  })  : _kind = idl.LinkedNodeKind.forElement,
-        _variantField_6 = forMixin_forLoopParts,
-        _variantField_7 = forElement_body;
-
-  LinkedNodeBuilder.forPartsWithDeclarations({
-    LinkedNodeBuilder forParts_condition,
-    LinkedNodeBuilder forPartsWithDeclarations_variables,
-    List<LinkedNodeBuilder> forParts_updaters,
-  })  : _kind = idl.LinkedNodeKind.forPartsWithDeclarations,
-        _variantField_6 = forParts_condition,
-        _variantField_7 = forPartsWithDeclarations_variables,
-        _variantField_5 = forParts_updaters;
-
-  LinkedNodeBuilder.forPartsWithExpression({
-    LinkedNodeBuilder forParts_condition,
-    LinkedNodeBuilder forPartsWithExpression_initialization,
-    List<LinkedNodeBuilder> forParts_updaters,
-  })  : _kind = idl.LinkedNodeKind.forPartsWithExpression,
-        _variantField_6 = forParts_condition,
-        _variantField_7 = forPartsWithExpression_initialization,
-        _variantField_5 = forParts_updaters;
-
-  LinkedNodeBuilder.forStatement({
-    LinkedNodeBuilder forMixin_forLoopParts,
-    LinkedNodeBuilder forStatement_body,
-  })  : _kind = idl.LinkedNodeKind.forStatement,
-        _variantField_6 = forMixin_forLoopParts,
-        _variantField_7 = forStatement_body;
-
-  LinkedNodeBuilder.formalParameterList({
-    List<LinkedNodeBuilder> formalParameterList_parameters,
-  })  : _kind = idl.LinkedNodeKind.formalParameterList,
-        _variantField_2 = formalParameterList_parameters;
-
-  LinkedNodeBuilder.functionDeclaration({
-    LinkedNodeTypeBuilder actualReturnType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder functionDeclaration_functionExpression,
-    LinkedNodeBuilder functionDeclaration_returnType,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.functionDeclaration,
-        _variantField_24 = actualReturnType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = functionDeclaration_functionExpression,
-        _variantField_7 = functionDeclaration_returnType,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.functionDeclarationStatement({
-    LinkedNodeBuilder functionDeclarationStatement_functionDeclaration,
-  })  : _kind = idl.LinkedNodeKind.functionDeclarationStatement,
-        _variantField_6 = functionDeclarationStatement_functionDeclaration;
-
-  LinkedNodeBuilder.functionExpression({
-    LinkedNodeTypeBuilder actualReturnType,
-    LinkedNodeBuilder functionExpression_body,
-    LinkedNodeBuilder functionExpression_formalParameters,
-    LinkedNodeBuilder functionExpression_typeParameters,
-  })  : _kind = idl.LinkedNodeKind.functionExpression,
-        _variantField_24 = actualReturnType,
-        _variantField_6 = functionExpression_body,
-        _variantField_7 = functionExpression_formalParameters,
-        _variantField_8 = functionExpression_typeParameters;
-
-  LinkedNodeBuilder.functionExpressionInvocation({
-    LinkedNodeTypeBuilder invocationExpression_invokeType,
-    LinkedNodeBuilder functionExpressionInvocation_function,
-    LinkedNodeBuilder invocationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder invocationExpression_arguments,
-  })  : _kind = idl.LinkedNodeKind.functionExpressionInvocation,
-        _variantField_24 = invocationExpression_invokeType,
-        _variantField_6 = functionExpressionInvocation_function,
-        _variantField_12 = invocationExpression_typeArguments,
-        _variantField_25 = expression_type,
-        _variantField_14 = invocationExpression_arguments;
-
-  LinkedNodeBuilder.functionTypeAlias({
-    LinkedNodeTypeBuilder actualReturnType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder functionTypeAlias_formalParameters,
-    LinkedNodeBuilder functionTypeAlias_returnType,
-    LinkedNodeBuilder functionTypeAlias_typeParameters,
-    bool typeAlias_hasSelfReference,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-  })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
-        _variantField_24 = actualReturnType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = functionTypeAlias_formalParameters,
-        _variantField_7 = functionTypeAlias_returnType,
-        _variantField_8 = functionTypeAlias_typeParameters,
-        _variantField_27 = typeAlias_hasSelfReference,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded;
-
-  LinkedNodeBuilder.functionTypedFormalParameter({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder functionTypedFormalParameter_formalParameters,
-    LinkedNodeBuilder functionTypedFormalParameter_returnType,
-    LinkedNodeBuilder functionTypedFormalParameter_typeParameters,
-    bool inheritsCovariant,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
-        _variantField_24 = actualType,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = functionTypedFormalParameter_formalParameters,
-        _variantField_7 = functionTypedFormalParameter_returnType,
-        _variantField_8 = functionTypedFormalParameter_typeParameters,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.genericFunctionType({
-    LinkedNodeTypeBuilder actualReturnType,
-    LinkedNodeBuilder genericFunctionType_typeParameters,
-    LinkedNodeBuilder genericFunctionType_returnType,
-    int genericFunctionType_id,
-    LinkedNodeBuilder genericFunctionType_formalParameters,
-    LinkedNodeTypeBuilder genericFunctionType_type,
-  })  : _kind = idl.LinkedNodeKind.genericFunctionType,
-        _variantField_24 = actualReturnType,
-        _variantField_6 = genericFunctionType_typeParameters,
-        _variantField_7 = genericFunctionType_returnType,
-        _variantField_17 = genericFunctionType_id,
-        _variantField_8 = genericFunctionType_formalParameters,
-        _variantField_25 = genericFunctionType_type;
-
-  LinkedNodeBuilder.genericTypeAlias({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder genericTypeAlias_typeParameters,
-    LinkedNodeBuilder genericTypeAlias_functionType,
-    bool typeAlias_hasSelfReference,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-  })  : _kind = idl.LinkedNodeKind.genericTypeAlias,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = genericTypeAlias_typeParameters,
-        _variantField_7 = genericTypeAlias_functionType,
-        _variantField_27 = typeAlias_hasSelfReference,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded;
-
-  LinkedNodeBuilder.hideCombinator({
-    int informativeId,
-    List<String> names,
-  })  : _kind = idl.LinkedNodeKind.hideCombinator,
-        _variantField_36 = informativeId,
-        _variantField_34 = names;
-
-  LinkedNodeBuilder.ifElement({
-    LinkedNodeBuilder ifMixin_condition,
-    LinkedNodeBuilder ifElement_thenElement,
-    LinkedNodeBuilder ifElement_elseElement,
-  })  : _kind = idl.LinkedNodeKind.ifElement,
-        _variantField_6 = ifMixin_condition,
-        _variantField_8 = ifElement_thenElement,
-        _variantField_9 = ifElement_elseElement;
-
-  LinkedNodeBuilder.ifStatement({
-    LinkedNodeBuilder ifMixin_condition,
-    LinkedNodeBuilder ifStatement_elseStatement,
-    LinkedNodeBuilder ifStatement_thenStatement,
-  })  : _kind = idl.LinkedNodeKind.ifStatement,
-        _variantField_6 = ifMixin_condition,
-        _variantField_7 = ifStatement_elseStatement,
-        _variantField_8 = ifStatement_thenStatement;
-
-  LinkedNodeBuilder.implementsClause({
-    List<LinkedNodeBuilder> implementsClause_interfaces,
-  })  : _kind = idl.LinkedNodeKind.implementsClause,
-        _variantField_2 = implementsClause_interfaces;
-
-  LinkedNodeBuilder.importDirective({
-    List<LinkedNodeBuilder> namespaceDirective_combinators,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    List<LinkedNodeBuilder> namespaceDirective_configurations,
-    String namespaceDirective_selectedUri,
-    String importDirective_prefix,
-    int informativeId,
-    LinkedNodeBuilder uriBasedDirective_uri,
-    String uriBasedDirective_uriContent,
-    int uriBasedDirective_uriElement,
-  })  : _kind = idl.LinkedNodeKind.importDirective,
-        _variantField_2 = namespaceDirective_combinators,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_3 = namespaceDirective_configurations,
-        _variantField_20 = namespaceDirective_selectedUri,
-        _variantField_1 = importDirective_prefix,
-        _variantField_36 = informativeId,
-        _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent,
-        _variantField_19 = uriBasedDirective_uriElement;
-
-  LinkedNodeBuilder.indexExpression({
-    LinkedNodeBuilder indexExpression_index,
-    LinkedNodeBuilder indexExpression_target,
-    LinkedNodeTypeSubstitutionBuilder indexExpression_substitution,
-    int indexExpression_element,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.indexExpression,
-        _variantField_6 = indexExpression_index,
-        _variantField_7 = indexExpression_target,
-        _variantField_38 = indexExpression_substitution,
-        _variantField_15 = indexExpression_element,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.instanceCreationExpression({
-    List<LinkedNodeBuilder> instanceCreationExpression_arguments,
-    LinkedNodeBuilder instanceCreationExpression_constructorName,
-    LinkedNodeBuilder instanceCreationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.instanceCreationExpression,
-        _variantField_2 = instanceCreationExpression_arguments,
-        _variantField_7 = instanceCreationExpression_constructorName,
-        _variantField_8 = instanceCreationExpression_typeArguments,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.integerLiteral({
-    LinkedNodeTypeBuilder expression_type,
-    int integerLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.integerLiteral,
-        _variantField_25 = expression_type,
-        _variantField_16 = integerLiteral_value;
-
-  LinkedNodeBuilder.interpolationExpression({
-    LinkedNodeBuilder interpolationExpression_expression,
-  })  : _kind = idl.LinkedNodeKind.interpolationExpression,
-        _variantField_6 = interpolationExpression_expression;
-
-  LinkedNodeBuilder.interpolationString({
-    String interpolationString_value,
-  })  : _kind = idl.LinkedNodeKind.interpolationString,
-        _variantField_30 = interpolationString_value;
-
-  LinkedNodeBuilder.isExpression({
-    LinkedNodeBuilder isExpression_expression,
-    LinkedNodeBuilder isExpression_type,
-  })  : _kind = idl.LinkedNodeKind.isExpression,
-        _variantField_6 = isExpression_expression,
-        _variantField_7 = isExpression_type;
-
-  LinkedNodeBuilder.label({
-    LinkedNodeBuilder label_label,
-  })  : _kind = idl.LinkedNodeKind.label,
-        _variantField_6 = label_label;
-
-  LinkedNodeBuilder.labeledStatement({
-    List<LinkedNodeBuilder> labeledStatement_labels,
-    LinkedNodeBuilder labeledStatement_statement,
-  })  : _kind = idl.LinkedNodeKind.labeledStatement,
-        _variantField_2 = labeledStatement_labels,
-        _variantField_6 = labeledStatement_statement;
-
-  LinkedNodeBuilder.libraryDirective({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder libraryDirective_name,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.libraryDirective,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = libraryDirective_name,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.libraryIdentifier({
-    List<LinkedNodeBuilder> libraryIdentifier_components,
-  })  : _kind = idl.LinkedNodeKind.libraryIdentifier,
-        _variantField_2 = libraryIdentifier_components;
-
-  LinkedNodeBuilder.listLiteral({
-    List<LinkedNodeBuilder> typedLiteral_typeArguments,
-    List<LinkedNodeBuilder> listLiteral_elements,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.listLiteral,
-        _variantField_2 = typedLiteral_typeArguments,
-        _variantField_3 = listLiteral_elements,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.mapLiteralEntry({
-    LinkedNodeBuilder mapLiteralEntry_key,
-    LinkedNodeBuilder mapLiteralEntry_value,
-  })  : _kind = idl.LinkedNodeKind.mapLiteralEntry,
-        _variantField_6 = mapLiteralEntry_key,
-        _variantField_7 = mapLiteralEntry_value;
-
-  LinkedNodeBuilder.methodDeclaration({
-    LinkedNodeTypeBuilder actualReturnType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder methodDeclaration_body,
-    LinkedNodeBuilder methodDeclaration_formalParameters,
-    LinkedNodeBuilder methodDeclaration_returnType,
-    LinkedNodeBuilder methodDeclaration_typeParameters,
-    int informativeId,
-    bool methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
-    TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
-  })  : _kind = idl.LinkedNodeKind.methodDeclaration,
-        _variantField_24 = actualReturnType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = methodDeclaration_body,
-        _variantField_7 = methodDeclaration_formalParameters,
-        _variantField_8 = methodDeclaration_returnType,
-        _variantField_9 = methodDeclaration_typeParameters,
-        _variantField_36 = informativeId,
-        _variantField_31 =
-            methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
-        _variantField_32 = topLevelTypeInferenceError;
-
-  LinkedNodeBuilder.methodInvocation({
-    LinkedNodeTypeBuilder invocationExpression_invokeType,
-    LinkedNodeBuilder methodInvocation_methodName,
-    LinkedNodeBuilder methodInvocation_target,
-    LinkedNodeBuilder invocationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder invocationExpression_arguments,
-  })  : _kind = idl.LinkedNodeKind.methodInvocation,
-        _variantField_24 = invocationExpression_invokeType,
-        _variantField_6 = methodInvocation_methodName,
-        _variantField_7 = methodInvocation_target,
-        _variantField_12 = invocationExpression_typeArguments,
-        _variantField_25 = expression_type,
-        _variantField_14 = invocationExpression_arguments;
-
-  LinkedNodeBuilder.mixinDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder mixinDeclaration_onClause,
-    LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
-    List<LinkedNodeBuilder> classOrMixinDeclaration_members,
-    LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
-    int informativeId,
-    bool simplyBoundable_isSimplyBounded,
-    List<String> mixinDeclaration_superInvokedNames,
-  })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = mixinDeclaration_onClause,
-        _variantField_12 = classOrMixinDeclaration_implementsClause,
-        _variantField_5 = classOrMixinDeclaration_members,
-        _variantField_13 = classOrMixinDeclaration_typeParameters,
-        _variantField_36 = informativeId,
-        _variantField_31 = simplyBoundable_isSimplyBounded,
-        _variantField_34 = mixinDeclaration_superInvokedNames;
-
-  LinkedNodeBuilder.namedExpression({
-    LinkedNodeBuilder namedExpression_expression,
-    LinkedNodeBuilder namedExpression_name,
-  })  : _kind = idl.LinkedNodeKind.namedExpression,
-        _variantField_6 = namedExpression_expression,
-        _variantField_7 = namedExpression_name;
-
-  LinkedNodeBuilder.nativeClause({
-    LinkedNodeBuilder nativeClause_name,
-  })  : _kind = idl.LinkedNodeKind.nativeClause,
-        _variantField_6 = nativeClause_name;
-
-  LinkedNodeBuilder.nativeFunctionBody({
-    LinkedNodeBuilder nativeFunctionBody_stringLiteral,
-  })  : _kind = idl.LinkedNodeKind.nativeFunctionBody,
-        _variantField_6 = nativeFunctionBody_stringLiteral;
-
-  LinkedNodeBuilder.nullLiteral({
-    int nullLiteral_fake,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.nullLiteral,
-        _variantField_15 = nullLiteral_fake,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.onClause({
-    List<LinkedNodeBuilder> onClause_superclassConstraints,
-  })  : _kind = idl.LinkedNodeKind.onClause,
-        _variantField_2 = onClause_superclassConstraints;
-
-  LinkedNodeBuilder.parenthesizedExpression({
-    LinkedNodeBuilder parenthesizedExpression_expression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.parenthesizedExpression,
-        _variantField_6 = parenthesizedExpression_expression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.partDirective({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    int informativeId,
-    LinkedNodeBuilder uriBasedDirective_uri,
-    String uriBasedDirective_uriContent,
-    int uriBasedDirective_uriElement,
-  })  : _kind = idl.LinkedNodeKind.partDirective,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_36 = informativeId,
-        _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent,
-        _variantField_19 = uriBasedDirective_uriElement;
-
-  LinkedNodeBuilder.partOfDirective({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder partOfDirective_libraryName,
-    LinkedNodeBuilder partOfDirective_uri,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.partOfDirective,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = partOfDirective_libraryName,
-        _variantField_7 = partOfDirective_uri,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.postfixExpression({
-    LinkedNodeBuilder postfixExpression_operand,
-    LinkedNodeTypeSubstitutionBuilder postfixExpression_substitution,
-    int postfixExpression_element,
-    idl.UnlinkedTokenType postfixExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.postfixExpression,
-        _variantField_6 = postfixExpression_operand,
-        _variantField_38 = postfixExpression_substitution,
-        _variantField_15 = postfixExpression_element,
-        _variantField_28 = postfixExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.prefixExpression({
-    LinkedNodeBuilder prefixExpression_operand,
-    LinkedNodeTypeSubstitutionBuilder prefixExpression_substitution,
-    int prefixExpression_element,
-    idl.UnlinkedTokenType prefixExpression_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.prefixExpression,
-        _variantField_6 = prefixExpression_operand,
-        _variantField_38 = prefixExpression_substitution,
-        _variantField_15 = prefixExpression_element,
-        _variantField_28 = prefixExpression_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.prefixedIdentifier({
-    LinkedNodeBuilder prefixedIdentifier_identifier,
-    LinkedNodeBuilder prefixedIdentifier_prefix,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.prefixedIdentifier,
-        _variantField_6 = prefixedIdentifier_identifier,
-        _variantField_7 = prefixedIdentifier_prefix,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.propertyAccess({
-    LinkedNodeBuilder propertyAccess_propertyName,
-    LinkedNodeBuilder propertyAccess_target,
-    idl.UnlinkedTokenType propertyAccess_operator,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.propertyAccess,
-        _variantField_6 = propertyAccess_propertyName,
-        _variantField_7 = propertyAccess_target,
-        _variantField_28 = propertyAccess_operator,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.redirectingConstructorInvocation({
-    LinkedNodeBuilder redirectingConstructorInvocation_arguments,
-    LinkedNodeBuilder redirectingConstructorInvocation_constructorName,
-    LinkedNodeTypeSubstitutionBuilder
-        redirectingConstructorInvocation_substitution,
-    int redirectingConstructorInvocation_element,
-  })  : _kind = idl.LinkedNodeKind.redirectingConstructorInvocation,
-        _variantField_6 = redirectingConstructorInvocation_arguments,
-        _variantField_7 = redirectingConstructorInvocation_constructorName,
-        _variantField_38 = redirectingConstructorInvocation_substitution,
-        _variantField_15 = redirectingConstructorInvocation_element;
-
-  LinkedNodeBuilder.rethrowExpression({
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.rethrowExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.returnStatement({
-    LinkedNodeBuilder returnStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.returnStatement,
-        _variantField_6 = returnStatement_expression;
-
-  LinkedNodeBuilder.setOrMapLiteral({
-    List<LinkedNodeBuilder> typedLiteral_typeArguments,
-    List<LinkedNodeBuilder> setOrMapLiteral_elements,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.setOrMapLiteral,
-        _variantField_2 = typedLiteral_typeArguments,
-        _variantField_3 = setOrMapLiteral_elements,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.showCombinator({
-    int informativeId,
-    List<String> names,
-  })  : _kind = idl.LinkedNodeKind.showCombinator,
-        _variantField_36 = informativeId,
-        _variantField_34 = names;
-
-  LinkedNodeBuilder.simpleFormalParameter({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder simpleFormalParameter_type,
-    bool inheritsCovariant,
-    int informativeId,
-    TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
-  })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
-        _variantField_24 = actualType,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = simpleFormalParameter_type,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId,
-        _variantField_32 = topLevelTypeInferenceError;
-
-  LinkedNodeBuilder.simpleIdentifier({
-    LinkedNodeTypeSubstitutionBuilder simpleIdentifier_substitution,
-    int simpleIdentifier_element,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.simpleIdentifier,
-        _variantField_38 = simpleIdentifier_substitution,
-        _variantField_15 = simpleIdentifier_element,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.simpleStringLiteral({
-    String simpleStringLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.simpleStringLiteral,
-        _variantField_20 = simpleStringLiteral_value;
-
-  LinkedNodeBuilder.spreadElement({
-    LinkedNodeBuilder spreadElement_expression,
-    idl.UnlinkedTokenType spreadElement_spreadOperator,
-  })  : _kind = idl.LinkedNodeKind.spreadElement,
-        _variantField_6 = spreadElement_expression,
-        _variantField_35 = spreadElement_spreadOperator;
-
-  LinkedNodeBuilder.stringInterpolation({
-    List<LinkedNodeBuilder> stringInterpolation_elements,
-  })  : _kind = idl.LinkedNodeKind.stringInterpolation,
-        _variantField_2 = stringInterpolation_elements;
-
-  LinkedNodeBuilder.superConstructorInvocation({
-    LinkedNodeBuilder superConstructorInvocation_arguments,
-    LinkedNodeBuilder superConstructorInvocation_constructorName,
-    LinkedNodeTypeSubstitutionBuilder superConstructorInvocation_substitution,
-    int superConstructorInvocation_element,
-  })  : _kind = idl.LinkedNodeKind.superConstructorInvocation,
-        _variantField_6 = superConstructorInvocation_arguments,
-        _variantField_7 = superConstructorInvocation_constructorName,
-        _variantField_38 = superConstructorInvocation_substitution,
-        _variantField_15 = superConstructorInvocation_element;
-
-  LinkedNodeBuilder.superExpression({
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.superExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.switchCase({
-    List<LinkedNodeBuilder> switchMember_statements,
-    LinkedNodeBuilder switchCase_expression,
-    List<LinkedNodeBuilder> switchMember_labels,
-  })  : _kind = idl.LinkedNodeKind.switchCase,
-        _variantField_4 = switchMember_statements,
-        _variantField_6 = switchCase_expression,
-        _variantField_3 = switchMember_labels;
-
-  LinkedNodeBuilder.switchDefault({
-    List<LinkedNodeBuilder> switchMember_statements,
-    List<LinkedNodeBuilder> switchMember_labels,
-  })  : _kind = idl.LinkedNodeKind.switchDefault,
-        _variantField_4 = switchMember_statements,
-        _variantField_3 = switchMember_labels;
-
-  LinkedNodeBuilder.switchStatement({
-    List<LinkedNodeBuilder> switchStatement_members,
-    LinkedNodeBuilder switchStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.switchStatement,
-        _variantField_2 = switchStatement_members,
-        _variantField_7 = switchStatement_expression;
-
-  LinkedNodeBuilder.symbolLiteral({
-    LinkedNodeTypeBuilder expression_type,
-    List<String> names,
-  })  : _kind = idl.LinkedNodeKind.symbolLiteral,
-        _variantField_25 = expression_type,
-        _variantField_34 = names;
-
-  LinkedNodeBuilder.thisExpression({
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.thisExpression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.throwExpression({
-    LinkedNodeBuilder throwExpression_expression,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.throwExpression,
-        _variantField_6 = throwExpression_expression,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.topLevelVariableDeclaration({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder topLevelVariableDeclaration_variableList,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = topLevelVariableDeclaration_variableList,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.tryStatement({
-    List<LinkedNodeBuilder> tryStatement_catchClauses,
-    LinkedNodeBuilder tryStatement_body,
-    LinkedNodeBuilder tryStatement_finallyBlock,
-  })  : _kind = idl.LinkedNodeKind.tryStatement,
-        _variantField_2 = tryStatement_catchClauses,
-        _variantField_6 = tryStatement_body,
-        _variantField_7 = tryStatement_finallyBlock;
-
-  LinkedNodeBuilder.typeArgumentList({
-    List<LinkedNodeBuilder> typeArgumentList_arguments,
-  })  : _kind = idl.LinkedNodeKind.typeArgumentList,
-        _variantField_2 = typeArgumentList_arguments;
-
-  LinkedNodeBuilder.typeName({
-    List<LinkedNodeBuilder> typeName_typeArguments,
-    LinkedNodeBuilder typeName_name,
-    LinkedNodeTypeBuilder typeName_type,
-  })  : _kind = idl.LinkedNodeKind.typeName,
-        _variantField_2 = typeName_typeArguments,
-        _variantField_6 = typeName_name,
-        _variantField_23 = typeName_type;
-
-  LinkedNodeBuilder.typeParameter({
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder typeParameter_bound,
-    int typeParameter_variance,
-    int informativeId,
-    LinkedNodeTypeBuilder typeParameter_defaultType,
-  })  : _kind = idl.LinkedNodeKind.typeParameter,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = typeParameter_bound,
-        _variantField_15 = typeParameter_variance,
-        _variantField_36 = informativeId,
-        _variantField_23 = typeParameter_defaultType;
-
-  LinkedNodeBuilder.typeParameterList({
-    List<LinkedNodeBuilder> typeParameterList_typeParameters,
-  })  : _kind = idl.LinkedNodeKind.typeParameterList,
-        _variantField_2 = typeParameterList_typeParameters;
-
-  LinkedNodeBuilder.variableDeclaration({
-    LinkedNodeTypeBuilder actualType,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder variableDeclaration_initializer,
-    bool inheritsCovariant,
-    int informativeId,
-    TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
-  })  : _kind = idl.LinkedNodeKind.variableDeclaration,
-        _variantField_24 = actualType,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = variableDeclaration_initializer,
-        _variantField_27 = inheritsCovariant,
-        _variantField_36 = informativeId,
-        _variantField_32 = topLevelTypeInferenceError;
-
-  LinkedNodeBuilder.variableDeclarationList({
-    List<LinkedNodeBuilder> variableDeclarationList_variables,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder variableDeclarationList_type,
-    int informativeId,
-  })  : _kind = idl.LinkedNodeKind.variableDeclarationList,
-        _variantField_2 = variableDeclarationList_variables,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = variableDeclarationList_type,
-        _variantField_36 = informativeId;
-
-  LinkedNodeBuilder.variableDeclarationStatement({
-    LinkedNodeBuilder variableDeclarationStatement_variables,
-  })  : _kind = idl.LinkedNodeKind.variableDeclarationStatement,
-        _variantField_6 = variableDeclarationStatement_variables;
-
-  LinkedNodeBuilder.whileStatement({
-    LinkedNodeBuilder whileStatement_body,
-    LinkedNodeBuilder whileStatement_condition,
-  })  : _kind = idl.LinkedNodeKind.whileStatement,
-        _variantField_6 = whileStatement_body,
-        _variantField_7 = whileStatement_condition;
-
-  LinkedNodeBuilder.withClause({
-    List<LinkedNodeBuilder> withClause_mixinTypes,
-  })  : _kind = idl.LinkedNodeKind.withClause,
-        _variantField_2 = withClause_mixinTypes;
-
-  LinkedNodeBuilder.yieldStatement({
-    LinkedNodeBuilder yieldStatement_expression,
-  })  : _kind = idl.LinkedNodeKind.yieldStatement,
-        _variantField_6 = yieldStatement_expression;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      adjacentStrings_strings?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.annotation) {
-      annotation_arguments?.flushInformative();
-      annotation_constructorName?.flushInformative();
-      annotation_name?.flushInformative();
-      annotation_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.argumentList) {
-      argumentList_arguments?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.asExpression) {
-      asExpression_expression?.flushInformative();
-      asExpression_type?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.assertInitializer) {
-      assertInitializer_condition?.flushInformative();
-      assertInitializer_message?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.assertStatement) {
-      assertStatement_condition?.flushInformative();
-      assertStatement_message?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      assignmentExpression_leftHandSide?.flushInformative();
-      assignmentExpression_rightHandSide?.flushInformative();
-      assignmentExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.awaitExpression) {
-      awaitExpression_expression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.binaryExpression) {
-      binaryExpression_invokeType?.flushInformative();
-      binaryExpression_leftOperand?.flushInformative();
-      binaryExpression_rightOperand?.flushInformative();
-      binaryExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.block) {
-      block_statements?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      blockFunctionBody_block?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.booleanLiteral) {
-    } else if (kind == idl.LinkedNodeKind.breakStatement) {
-      breakStatement_label?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      cascadeExpression_sections?.forEach((b) => b.flushInformative());
-      cascadeExpression_target?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.catchClause) {
-      catchClause_body?.flushInformative();
-      catchClause_exceptionParameter?.flushInformative();
-      catchClause_exceptionType?.flushInformative();
-      catchClause_stackTraceParameter?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.classDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      classDeclaration_extendsClause?.flushInformative();
-      classDeclaration_withClause?.flushInformative();
-      classDeclaration_nativeClause?.flushInformative();
-      classOrMixinDeclaration_implementsClause?.flushInformative();
-      classOrMixinDeclaration_members?.forEach((b) => b.flushInformative());
-      classOrMixinDeclaration_typeParameters?.flushInformative();
-      informativeId = null;
-      unused11?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      classTypeAlias_typeParameters?.flushInformative();
-      classTypeAlias_superclass?.flushInformative();
-      classTypeAlias_withClause?.flushInformative();
-      classTypeAlias_implementsClause?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.comment) {
-      comment_references?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.commentReference) {
-      commentReference_identifier?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-      compilationUnit_declarations?.forEach((b) => b.flushInformative());
-      compilationUnit_scriptTag?.flushInformative();
-      compilationUnit_directives?.forEach((b) => b.flushInformative());
-      compilationUnit_languageVersion?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      conditionalExpression_condition?.flushInformative();
-      conditionalExpression_elseExpression?.flushInformative();
-      conditionalExpression_thenExpression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.configuration) {
-      configuration_name?.flushInformative();
-      configuration_value?.flushInformative();
-      configuration_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      constructorDeclaration_initializers?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      constructorDeclaration_body?.flushInformative();
-      constructorDeclaration_parameters?.flushInformative();
-      constructorDeclaration_redirectedConstructor?.flushInformative();
-      constructorDeclaration_returnType?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      constructorFieldInitializer_expression?.flushInformative();
-      constructorFieldInitializer_fieldName?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.constructorName) {
-      constructorName_name?.flushInformative();
-      constructorName_type?.flushInformative();
-      constructorName_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.continueStatement) {
-      continueStatement_label?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      declaredIdentifier_identifier?.flushInformative();
-      declaredIdentifier_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      defaultFormalParameter_defaultValue?.flushInformative();
-      defaultFormalParameter_parameter?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.doStatement) {
-      doStatement_body?.flushInformative();
-      doStatement_condition?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.dottedName) {
-      dottedName_components?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.doubleLiteral) {
-    } else if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-    } else if (kind == idl.LinkedNodeKind.emptyStatement) {
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      enumDeclaration_constants?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-      namespaceDirective_combinators?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      namespaceDirective_configurations?.forEach((b) => b.flushInformative());
-      informativeId = null;
-      uriBasedDirective_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      expressionFunctionBody_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.expressionStatement) {
-      expressionStatement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.extendsClause) {
-      extendsClause_superclass?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      extensionDeclaration_typeParameters?.flushInformative();
-      extensionDeclaration_extendedType?.flushInformative();
-      extensionDeclaration_members?.forEach((b) => b.flushInformative());
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.extensionOverride) {
-      extensionOverride_extendedType?.flushInformative();
-      extensionOverride_arguments?.forEach((b) => b.flushInformative());
-      extensionOverride_extensionName?.flushInformative();
-      extensionOverride_typeArguments?.flushInformative();
-      extensionOverride_typeArgumentTypes?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      fieldDeclaration_fields?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      actualType?.flushInformative();
-      normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
-      fieldFormalParameter_type?.flushInformative();
-      fieldFormalParameter_typeParameters?.flushInformative();
-      fieldFormalParameter_formalParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      forEachParts_iterable?.flushInformative();
-      forEachPartsWithDeclaration_loopVariable?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      forEachParts_iterable?.flushInformative();
-      forEachPartsWithIdentifier_identifier?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.forElement) {
-      forMixin_forLoopParts?.flushInformative();
-      forElement_body?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      forParts_condition?.flushInformative();
-      forPartsWithDeclarations_variables?.flushInformative();
-      forParts_updaters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      forParts_condition?.flushInformative();
-      forPartsWithExpression_initialization?.flushInformative();
-      forParts_updaters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.forStatement) {
-      forMixin_forLoopParts?.flushInformative();
-      forStatement_body?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.formalParameterList) {
-      formalParameterList_parameters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      actualReturnType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      functionDeclaration_functionExpression?.flushInformative();
-      functionDeclaration_returnType?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      functionDeclarationStatement_functionDeclaration?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.functionExpression) {
-      actualReturnType?.flushInformative();
-      functionExpression_body?.flushInformative();
-      functionExpression_formalParameters?.flushInformative();
-      functionExpression_typeParameters?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      invocationExpression_invokeType?.flushInformative();
-      functionExpressionInvocation_function?.flushInformative();
-      invocationExpression_typeArguments?.flushInformative();
-      expression_type?.flushInformative();
-      invocationExpression_arguments?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      actualReturnType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      functionTypeAlias_formalParameters?.flushInformative();
-      functionTypeAlias_returnType?.flushInformative();
-      functionTypeAlias_typeParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      actualType?.flushInformative();
-      normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
-      functionTypedFormalParameter_formalParameters?.flushInformative();
-      functionTypedFormalParameter_returnType?.flushInformative();
-      functionTypedFormalParameter_typeParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      actualReturnType?.flushInformative();
-      genericFunctionType_typeParameters?.flushInformative();
-      genericFunctionType_returnType?.flushInformative();
-      genericFunctionType_formalParameters?.flushInformative();
-      genericFunctionType_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      genericTypeAlias_typeParameters?.flushInformative();
-      genericTypeAlias_functionType?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.ifElement) {
-      ifMixin_condition?.flushInformative();
-      ifElement_thenElement?.flushInformative();
-      ifElement_elseElement?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.ifStatement) {
-      ifMixin_condition?.flushInformative();
-      ifStatement_elseStatement?.flushInformative();
-      ifStatement_thenStatement?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.implementsClause) {
-      implementsClause_interfaces?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-      namespaceDirective_combinators?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      namespaceDirective_configurations?.forEach((b) => b.flushInformative());
-      informativeId = null;
-      uriBasedDirective_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.indexExpression) {
-      indexExpression_index?.flushInformative();
-      indexExpression_target?.flushInformative();
-      indexExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      instanceCreationExpression_arguments
-          ?.forEach((b) => b.flushInformative());
-      instanceCreationExpression_constructorName?.flushInformative();
-      instanceCreationExpression_typeArguments?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.integerLiteral) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      interpolationExpression_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.interpolationString) {
-    } else if (kind == idl.LinkedNodeKind.isExpression) {
-      isExpression_expression?.flushInformative();
-      isExpression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.label) {
-      label_label?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.labeledStatement) {
-      labeledStatement_labels?.forEach((b) => b.flushInformative());
-      labeledStatement_statement?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      libraryDirective_name?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      libraryIdentifier_components?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.listLiteral) {
-      typedLiteral_typeArguments?.forEach((b) => b.flushInformative());
-      listLiteral_elements?.forEach((b) => b.flushInformative());
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      mapLiteralEntry_key?.flushInformative();
-      mapLiteralEntry_value?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      actualReturnType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      methodDeclaration_body?.flushInformative();
-      methodDeclaration_formalParameters?.flushInformative();
-      methodDeclaration_returnType?.flushInformative();
-      methodDeclaration_typeParameters?.flushInformative();
-      informativeId = null;
-      topLevelTypeInferenceError?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.methodInvocation) {
-      invocationExpression_invokeType?.flushInformative();
-      methodInvocation_methodName?.flushInformative();
-      methodInvocation_target?.flushInformative();
-      invocationExpression_typeArguments?.flushInformative();
-      expression_type?.flushInformative();
-      invocationExpression_arguments?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      mixinDeclaration_onClause?.flushInformative();
-      classOrMixinDeclaration_implementsClause?.flushInformative();
-      classOrMixinDeclaration_members?.forEach((b) => b.flushInformative());
-      classOrMixinDeclaration_typeParameters?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.namedExpression) {
-      namedExpression_expression?.flushInformative();
-      namedExpression_name?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.nativeClause) {
-      nativeClause_name?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      nativeFunctionBody_stringLiteral?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.nullLiteral) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.onClause) {
-      onClause_superclassConstraints?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      parenthesizedExpression_expression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      informativeId = null;
-      uriBasedDirective_uri?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      partOfDirective_libraryName?.flushInformative();
-      partOfDirective_uri?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.postfixExpression) {
-      postfixExpression_operand?.flushInformative();
-      postfixExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.prefixExpression) {
-      prefixExpression_operand?.flushInformative();
-      prefixExpression_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      prefixedIdentifier_identifier?.flushInformative();
-      prefixedIdentifier_prefix?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.propertyAccess) {
-      propertyAccess_propertyName?.flushInformative();
-      propertyAccess_target?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      redirectingConstructorInvocation_arguments?.flushInformative();
-      redirectingConstructorInvocation_constructorName?.flushInformative();
-      redirectingConstructorInvocation_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.returnStatement) {
-      returnStatement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      typedLiteral_typeArguments?.forEach((b) => b.flushInformative());
-      setOrMapLiteral_elements?.forEach((b) => b.flushInformative());
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      actualType?.flushInformative();
-      normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
-      simpleFormalParameter_type?.flushInformative();
-      informativeId = null;
-      topLevelTypeInferenceError?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      simpleIdentifier_substitution?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-    } else if (kind == idl.LinkedNodeKind.spreadElement) {
-      spreadElement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      stringInterpolation_elements?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      superConstructorInvocation_arguments?.flushInformative();
-      superConstructorInvocation_constructorName?.flushInformative();
-      superConstructorInvocation_substitution?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.superExpression) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.switchCase) {
-      switchMember_statements?.forEach((b) => b.flushInformative());
-      switchCase_expression?.flushInformative();
-      switchMember_labels?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.switchDefault) {
-      switchMember_statements?.forEach((b) => b.flushInformative());
-      switchMember_labels?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.switchStatement) {
-      switchStatement_members?.forEach((b) => b.flushInformative());
-      switchStatement_expression?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.thisExpression) {
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.throwExpression) {
-      throwExpression_expression?.flushInformative();
-      expression_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      topLevelVariableDeclaration_variableList?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.tryStatement) {
-      tryStatement_catchClauses?.forEach((b) => b.flushInformative());
-      tryStatement_body?.flushInformative();
-      tryStatement_finallyBlock?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      typeArgumentList_arguments?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.typeName) {
-      typeName_typeArguments?.forEach((b) => b.flushInformative());
-      typeName_name?.flushInformative();
-      typeName_type?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      typeParameter_bound?.flushInformative();
-      informativeId = null;
-      typeParameter_defaultType?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.typeParameterList) {
-      typeParameterList_typeParameters?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      actualType?.flushInformative();
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      variableDeclaration_initializer?.flushInformative();
-      informativeId = null;
-      topLevelTypeInferenceError?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      variableDeclarationList_variables?.forEach((b) => b.flushInformative());
-      annotatedNode_metadata?.forEach((b) => b.flushInformative());
-      variableDeclarationList_type?.flushInformative();
-      informativeId = null;
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      variableDeclarationStatement_variables?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.whileStatement) {
-      whileStatement_body?.flushInformative();
-      whileStatement_condition?.flushInformative();
-    } else if (kind == idl.LinkedNodeKind.withClause) {
-      withClause_mixinTypes?.forEach((b) => b.flushInformative());
-    } else if (kind == idl.LinkedNodeKind.yieldStatement) {
-      yieldStatement_expression?.flushInformative();
-    }
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.adjacentStrings_strings == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.adjacentStrings_strings.length);
-        for (var x in this.adjacentStrings_strings) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.annotation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.annotation_arguments != null);
-      this.annotation_arguments?.collectApiSignature(signature);
-      signature.addBool(this.annotation_constructorName != null);
-      this.annotation_constructorName?.collectApiSignature(signature);
-      signature.addBool(this.annotation_name != null);
-      this.annotation_name?.collectApiSignature(signature);
-      signature.addInt(this.annotation_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.annotation_substitution != null);
-      this.annotation_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.argumentList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.argumentList_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.argumentList_arguments.length);
-        for (var x in this.argumentList_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.asExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.asExpression_expression != null);
-      this.asExpression_expression?.collectApiSignature(signature);
-      signature.addBool(this.asExpression_type != null);
-      this.asExpression_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.assertInitializer) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.assertInitializer_condition != null);
-      this.assertInitializer_condition?.collectApiSignature(signature);
-      signature.addBool(this.assertInitializer_message != null);
-      this.assertInitializer_message?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.assertStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.assertStatement_condition != null);
-      this.assertStatement_condition?.collectApiSignature(signature);
-      signature.addBool(this.assertStatement_message != null);
-      this.assertStatement_message?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.assignmentExpression_leftHandSide != null);
-      this.assignmentExpression_leftHandSide?.collectApiSignature(signature);
-      signature.addBool(this.assignmentExpression_rightHandSide != null);
-      this.assignmentExpression_rightHandSide?.collectApiSignature(signature);
-      signature.addInt(this.assignmentExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.assignmentExpression_operator == null
-          ? 0
-          : this.assignmentExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.assignmentExpression_substitution != null);
-      this.assignmentExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.awaitExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.awaitExpression_expression != null);
-      this.awaitExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.binaryExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.binaryExpression_leftOperand != null);
-      this.binaryExpression_leftOperand?.collectApiSignature(signature);
-      signature.addBool(this.binaryExpression_rightOperand != null);
-      this.binaryExpression_rightOperand?.collectApiSignature(signature);
-      signature.addInt(this.binaryExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.binaryExpression_invokeType != null);
-      this.binaryExpression_invokeType?.collectApiSignature(signature);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.binaryExpression_operator == null
-          ? 0
-          : this.binaryExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.binaryExpression_substitution != null);
-      this.binaryExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.block) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.block_statements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.block_statements.length);
-        for (var x in this.block_statements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.blockFunctionBody_block != null);
-      this.blockFunctionBody_block?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.booleanLiteral_value == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.breakStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.breakStatement_label != null);
-      this.breakStatement_label?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.cascadeExpression_sections == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.cascadeExpression_sections.length);
-        for (var x in this.cascadeExpression_sections) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.cascadeExpression_target != null);
-      this.cascadeExpression_target?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.catchClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.catchClause_body != null);
-      this.catchClause_body?.collectApiSignature(signature);
-      signature.addBool(this.catchClause_exceptionParameter != null);
-      this.catchClause_exceptionParameter?.collectApiSignature(signature);
-      signature.addBool(this.catchClause_exceptionType != null);
-      this.catchClause_exceptionType?.collectApiSignature(signature);
-      signature.addBool(this.catchClause_stackTraceParameter != null);
-      this.catchClause_stackTraceParameter?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.classDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.classOrMixinDeclaration_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.classOrMixinDeclaration_members.length);
-        for (var x in this.classOrMixinDeclaration_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.classDeclaration_extendsClause != null);
-      this.classDeclaration_extendsClause?.collectApiSignature(signature);
-      signature.addBool(this.classDeclaration_withClause != null);
-      this.classDeclaration_withClause?.collectApiSignature(signature);
-      signature.addBool(this.classDeclaration_nativeClause != null);
-      this.classDeclaration_nativeClause?.collectApiSignature(signature);
-      signature.addBool(this.unused11 != null);
-      this.unused11?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_implementsClause != null);
-      this
-          .classOrMixinDeclaration_implementsClause
-          ?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_typeParameters != null);
-      this
-          .classOrMixinDeclaration_typeParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.classDeclaration_isDartObject == true);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.classTypeAlias_typeParameters != null);
-      this.classTypeAlias_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.classTypeAlias_superclass != null);
-      this.classTypeAlias_superclass?.collectApiSignature(signature);
-      signature.addBool(this.classTypeAlias_withClause != null);
-      this.classTypeAlias_withClause?.collectApiSignature(signature);
-      signature.addBool(this.classTypeAlias_implementsClause != null);
-      this.classTypeAlias_implementsClause?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.comment) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.comment_references == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.comment_references.length);
-        for (var x in this.comment_references) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.comment_type == null ? 0 : this.comment_type.index);
-      if (this.comment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.comment_tokens.length);
-        for (var x in this.comment_tokens) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.commentReference) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.commentReference_identifier != null);
-      this.commentReference_identifier?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.compilationUnit_declarations == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_declarations.length);
-        for (var x in this.compilationUnit_declarations) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.compilationUnit_directives == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_directives.length);
-        for (var x in this.compilationUnit_directives) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.compilationUnit_scriptTag != null);
-      this.compilationUnit_scriptTag?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.compilationUnit_languageVersion != null);
-      this.compilationUnit_languageVersion?.collectApiSignature(signature);
-      if (this.compilationUnit_featureSet == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_featureSet.length);
-        for (var x in this.compilationUnit_featureSet) {
-          signature.addInt(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.conditionalExpression_condition != null);
-      this.conditionalExpression_condition?.collectApiSignature(signature);
-      signature.addBool(this.conditionalExpression_elseExpression != null);
-      this.conditionalExpression_elseExpression?.collectApiSignature(signature);
-      signature.addBool(this.conditionalExpression_thenExpression != null);
-      this.conditionalExpression_thenExpression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.configuration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.configuration_name != null);
-      this.configuration_name?.collectApiSignature(signature);
-      signature.addBool(this.configuration_value != null);
-      this.configuration_value?.collectApiSignature(signature);
-      signature.addBool(this.configuration_uri != null);
-      this.configuration_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.constructorDeclaration_initializers == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.constructorDeclaration_initializers.length);
-        for (var x in this.constructorDeclaration_initializers) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.constructorDeclaration_body != null);
-      this.constructorDeclaration_body?.collectApiSignature(signature);
-      signature.addBool(this.constructorDeclaration_parameters != null);
-      this.constructorDeclaration_parameters?.collectApiSignature(signature);
-      signature
-          .addBool(this.constructorDeclaration_redirectedConstructor != null);
-      this
-          .constructorDeclaration_redirectedConstructor
-          ?.collectApiSignature(signature);
-      signature.addBool(this.constructorDeclaration_returnType != null);
-      this.constructorDeclaration_returnType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.constructorFieldInitializer_expression != null);
-      this
-          .constructorFieldInitializer_expression
-          ?.collectApiSignature(signature);
-      signature.addBool(this.constructorFieldInitializer_fieldName != null);
-      this
-          .constructorFieldInitializer_fieldName
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.constructorName) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.constructorName_name != null);
-      this.constructorName_name?.collectApiSignature(signature);
-      signature.addBool(this.constructorName_type != null);
-      this.constructorName_type?.collectApiSignature(signature);
-      signature.addInt(this.constructorName_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.constructorName_substitution != null);
-      this.constructorName_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.continueStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.continueStatement_label != null);
-      this.continueStatement_label?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.declaredIdentifier_identifier != null);
-      this.declaredIdentifier_identifier?.collectApiSignature(signature);
-      signature.addBool(this.declaredIdentifier_type != null);
-      this.declaredIdentifier_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.defaultFormalParameter_defaultValue != null);
-      this.defaultFormalParameter_defaultValue?.collectApiSignature(signature);
-      signature.addBool(this.defaultFormalParameter_parameter != null);
-      this.defaultFormalParameter_parameter?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.defaultFormalParameter_kind == null
-          ? 0
-          : this.defaultFormalParameter_kind.index);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.doStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.doStatement_body != null);
-      this.doStatement_body?.collectApiSignature(signature);
-      signature.addBool(this.doStatement_condition != null);
-      this.doStatement_condition?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.dottedName) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.dottedName_components == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.dottedName_components.length);
-        for (var x in this.dottedName_components) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addDouble(this.doubleLiteral_value ?? 0.0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.emptyFunctionBody_fake ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.emptyStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.emptyStatement_fake ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.enumDeclaration_constants == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.enumDeclaration_constants.length);
-        for (var x in this.enumDeclaration_constants) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.namespaceDirective_combinators == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_combinators.length);
-        for (var x in this.namespaceDirective_combinators) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.namespaceDirective_configurations == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_configurations.length);
-        for (var x in this.namespaceDirective_configurations) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.uriBasedDirective_uri != null);
-      this.uriBasedDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.uriBasedDirective_uriElement ?? 0);
-      signature.addString(this.namespaceDirective_selectedUri ?? '');
-      signature.addString(this.uriBasedDirective_uriContent ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.expressionFunctionBody_expression != null);
-      this.expressionFunctionBody_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.expressionStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.expressionStatement_expression != null);
-      this.expressionStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.extendsClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.extendsClause_superclass != null);
-      this.extendsClause_superclass?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.extensionDeclaration_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.extensionDeclaration_members.length);
-        for (var x in this.extensionDeclaration_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.extensionDeclaration_typeParameters != null);
-      this.extensionDeclaration_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.extensionDeclaration_extendedType != null);
-      this.extensionDeclaration_extendedType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.extensionDeclaration_refName ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.extensionOverride) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.extensionOverride_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.extensionOverride_arguments.length);
-        for (var x in this.extensionOverride_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.extensionOverride_extensionName != null);
-      this.extensionOverride_extensionName?.collectApiSignature(signature);
-      signature.addBool(this.extensionOverride_typeArguments != null);
-      this.extensionOverride_typeArguments?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.extensionOverride_extendedType != null);
-      this.extensionOverride_extendedType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-      if (this.extensionOverride_typeArgumentTypes == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.extensionOverride_typeArgumentTypes.length);
-        for (var x in this.extensionOverride_typeArgumentTypes) {
-          x?.collectApiSignature(signature);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.fieldDeclaration_fields != null);
-      this.fieldDeclaration_fields?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.normalFormalParameter_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.normalFormalParameter_metadata.length);
-        for (var x in this.normalFormalParameter_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.fieldFormalParameter_type != null);
-      this.fieldFormalParameter_type?.collectApiSignature(signature);
-      signature.addBool(this.fieldFormalParameter_typeParameters != null);
-      this.fieldFormalParameter_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.fieldFormalParameter_formalParameters != null);
-      this
-          .fieldFormalParameter_formalParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forEachParts_iterable != null);
-      this.forEachParts_iterable?.collectApiSignature(signature);
-      signature.addBool(this.forEachPartsWithDeclaration_loopVariable != null);
-      this
-          .forEachPartsWithDeclaration_loopVariable
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forEachParts_iterable != null);
-      this.forEachParts_iterable?.collectApiSignature(signature);
-      signature.addBool(this.forEachPartsWithIdentifier_identifier != null);
-      this
-          .forEachPartsWithIdentifier_identifier
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forElement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forMixin_forLoopParts != null);
-      this.forMixin_forLoopParts?.collectApiSignature(signature);
-      signature.addBool(this.forElement_body != null);
-      this.forElement_body?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.forParts_updaters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.forParts_updaters.length);
-        for (var x in this.forParts_updaters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.forParts_condition != null);
-      this.forParts_condition?.collectApiSignature(signature);
-      signature.addBool(this.forPartsWithDeclarations_variables != null);
-      this.forPartsWithDeclarations_variables?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.forParts_updaters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.forParts_updaters.length);
-        for (var x in this.forParts_updaters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.forParts_condition != null);
-      this.forParts_condition?.collectApiSignature(signature);
-      signature.addBool(this.forPartsWithExpression_initialization != null);
-      this
-          .forPartsWithExpression_initialization
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.forStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.forMixin_forLoopParts != null);
-      this.forMixin_forLoopParts?.collectApiSignature(signature);
-      signature.addBool(this.forStatement_body != null);
-      this.forStatement_body?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.formalParameterList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.formalParameterList_parameters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.formalParameterList_parameters.length);
-        for (var x in this.formalParameterList_parameters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.functionDeclaration_functionExpression != null);
-      this
-          .functionDeclaration_functionExpression
-          ?.collectApiSignature(signature);
-      signature.addBool(this.functionDeclaration_returnType != null);
-      this.functionDeclaration_returnType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(
-          this.functionDeclarationStatement_functionDeclaration != null);
-      this
-          .functionDeclarationStatement_functionDeclaration
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.functionExpression_body != null);
-      this.functionExpression_body?.collectApiSignature(signature);
-      signature.addBool(this.functionExpression_formalParameters != null);
-      this.functionExpression_formalParameters?.collectApiSignature(signature);
-      signature.addBool(this.functionExpression_typeParameters != null);
-      this.functionExpression_typeParameters?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.functionExpressionInvocation_function != null);
-      this
-          .functionExpressionInvocation_function
-          ?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_typeArguments != null);
-      this.invocationExpression_typeArguments?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_arguments != null);
-      this.invocationExpression_arguments?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.invocationExpression_invokeType != null);
-      this.invocationExpression_invokeType?.collectApiSignature(signature);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.functionTypeAlias_formalParameters != null);
-      this.functionTypeAlias_formalParameters?.collectApiSignature(signature);
-      signature.addBool(this.functionTypeAlias_returnType != null);
-      this.functionTypeAlias_returnType?.collectApiSignature(signature);
-      signature.addBool(this.functionTypeAlias_typeParameters != null);
-      this.functionTypeAlias_typeParameters?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addBool(this.typeAlias_hasSelfReference == true);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.normalFormalParameter_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.normalFormalParameter_metadata.length);
-        for (var x in this.normalFormalParameter_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature
-          .addBool(this.functionTypedFormalParameter_formalParameters != null);
-      this
-          .functionTypedFormalParameter_formalParameters
-          ?.collectApiSignature(signature);
-      signature.addBool(this.functionTypedFormalParameter_returnType != null);
-      this
-          .functionTypedFormalParameter_returnType
-          ?.collectApiSignature(signature);
-      signature
-          .addBool(this.functionTypedFormalParameter_typeParameters != null);
-      this
-          .functionTypedFormalParameter_typeParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.genericFunctionType_typeParameters != null);
-      this.genericFunctionType_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.genericFunctionType_returnType != null);
-      this.genericFunctionType_returnType?.collectApiSignature(signature);
-      signature.addBool(this.genericFunctionType_formalParameters != null);
-      this.genericFunctionType_formalParameters?.collectApiSignature(signature);
-      signature.addInt(this.genericFunctionType_id ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addBool(this.genericFunctionType_type != null);
-      this.genericFunctionType_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.genericTypeAlias_typeParameters != null);
-      this.genericTypeAlias_typeParameters?.collectApiSignature(signature);
-      signature.addBool(this.genericTypeAlias_functionType != null);
-      this.genericTypeAlias_functionType?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.typeAlias_hasSelfReference == true);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      if (this.names == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.names.length);
-        for (var x in this.names) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.ifElement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.ifMixin_condition != null);
-      this.ifMixin_condition?.collectApiSignature(signature);
-      signature.addBool(this.ifElement_thenElement != null);
-      this.ifElement_thenElement?.collectApiSignature(signature);
-      signature.addBool(this.ifElement_elseElement != null);
-      this.ifElement_elseElement?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.ifStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.ifMixin_condition != null);
-      this.ifMixin_condition?.collectApiSignature(signature);
-      signature.addBool(this.ifStatement_elseStatement != null);
-      this.ifStatement_elseStatement?.collectApiSignature(signature);
-      signature.addBool(this.ifStatement_thenStatement != null);
-      this.ifStatement_thenStatement?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.implementsClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.implementsClause_interfaces == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.implementsClause_interfaces.length);
-        for (var x in this.implementsClause_interfaces) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addString(this.importDirective_prefix ?? '');
-      if (this.namespaceDirective_combinators == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_combinators.length);
-        for (var x in this.namespaceDirective_combinators) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.namespaceDirective_configurations == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.namespaceDirective_configurations.length);
-        for (var x in this.namespaceDirective_configurations) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.uriBasedDirective_uri != null);
-      this.uriBasedDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.uriBasedDirective_uriElement ?? 0);
-      signature.addString(this.namespaceDirective_selectedUri ?? '');
-      signature.addString(this.uriBasedDirective_uriContent ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.indexExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.indexExpression_index != null);
-      this.indexExpression_index?.collectApiSignature(signature);
-      signature.addBool(this.indexExpression_target != null);
-      this.indexExpression_target?.collectApiSignature(signature);
-      signature.addInt(this.indexExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.indexExpression_substitution != null);
-      this.indexExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.instanceCreationExpression_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.instanceCreationExpression_arguments.length);
-        for (var x in this.instanceCreationExpression_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature
-          .addBool(this.instanceCreationExpression_constructorName != null);
-      this
-          .instanceCreationExpression_constructorName
-          ?.collectApiSignature(signature);
-      signature.addBool(this.instanceCreationExpression_typeArguments != null);
-      this
-          .instanceCreationExpression_typeArguments
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.integerLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.integerLiteral_value ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.interpolationExpression_expression != null);
-      this.interpolationExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.interpolationString) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.interpolationString_value ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.isExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.isExpression_expression != null);
-      this.isExpression_expression?.collectApiSignature(signature);
-      signature.addBool(this.isExpression_type != null);
-      this.isExpression_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.label) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.label_label != null);
-      this.label_label?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.labeledStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.labeledStatement_labels == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.labeledStatement_labels.length);
-        for (var x in this.labeledStatement_labels) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.labeledStatement_statement != null);
-      this.labeledStatement_statement?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.libraryDirective_name != null);
-      this.libraryDirective_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.libraryIdentifier_components == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.libraryIdentifier_components.length);
-        for (var x in this.libraryIdentifier_components) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.listLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typedLiteral_typeArguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typedLiteral_typeArguments.length);
-        for (var x in this.typedLiteral_typeArguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.listLiteral_elements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.listLiteral_elements.length);
-        for (var x in this.listLiteral_elements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.mapLiteralEntry_key != null);
-      this.mapLiteralEntry_key?.collectApiSignature(signature);
-      signature.addBool(this.mapLiteralEntry_value != null);
-      this.mapLiteralEntry_value?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.methodDeclaration_body != null);
-      this.methodDeclaration_body?.collectApiSignature(signature);
-      signature.addBool(this.methodDeclaration_formalParameters != null);
-      this.methodDeclaration_formalParameters?.collectApiSignature(signature);
-      signature.addBool(this.methodDeclaration_returnType != null);
-      this.methodDeclaration_returnType?.collectApiSignature(signature);
-      signature.addBool(this.methodDeclaration_typeParameters != null);
-      this.methodDeclaration_typeParameters?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualReturnType != null);
-      this.actualReturnType?.collectApiSignature(signature);
-      signature.addBool(
-          this.methodDeclaration_hasOperatorEqualWithParameterTypeFromObject ==
-              true);
-      signature.addBool(this.topLevelTypeInferenceError != null);
-      this.topLevelTypeInferenceError?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.methodInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.methodInvocation_methodName != null);
-      this.methodInvocation_methodName?.collectApiSignature(signature);
-      signature.addBool(this.methodInvocation_target != null);
-      this.methodInvocation_target?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_typeArguments != null);
-      this.invocationExpression_typeArguments?.collectApiSignature(signature);
-      signature.addBool(this.invocationExpression_arguments != null);
-      this.invocationExpression_arguments?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.invocationExpression_invokeType != null);
-      this.invocationExpression_invokeType?.collectApiSignature(signature);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.classOrMixinDeclaration_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.classOrMixinDeclaration_members.length);
-        for (var x in this.classOrMixinDeclaration_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.mixinDeclaration_onClause != null);
-      this.mixinDeclaration_onClause?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_implementsClause != null);
-      this
-          .classOrMixinDeclaration_implementsClause
-          ?.collectApiSignature(signature);
-      signature.addBool(this.classOrMixinDeclaration_typeParameters != null);
-      this
-          .classOrMixinDeclaration_typeParameters
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.simplyBoundable_isSimplyBounded == true);
-      if (this.mixinDeclaration_superInvokedNames == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.mixinDeclaration_superInvokedNames.length);
-        for (var x in this.mixinDeclaration_superInvokedNames) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.namedExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.namedExpression_expression != null);
-      this.namedExpression_expression?.collectApiSignature(signature);
-      signature.addBool(this.namedExpression_name != null);
-      this.namedExpression_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.nativeClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.nativeClause_name != null);
-      this.nativeClause_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.nativeFunctionBody_stringLiteral != null);
-      this.nativeFunctionBody_stringLiteral?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.nullLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nullLiteral_fake ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.onClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.onClause_superclassConstraints == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.onClause_superclassConstraints.length);
-        for (var x in this.onClause_superclassConstraints) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.parenthesizedExpression_expression != null);
-      this.parenthesizedExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.uriBasedDirective_uri != null);
-      this.uriBasedDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.uriBasedDirective_uriElement ?? 0);
-      signature.addString(this.uriBasedDirective_uriContent ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.partOfDirective_libraryName != null);
-      this.partOfDirective_libraryName?.collectApiSignature(signature);
-      signature.addBool(this.partOfDirective_uri != null);
-      this.partOfDirective_uri?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.postfixExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.postfixExpression_operand != null);
-      this.postfixExpression_operand?.collectApiSignature(signature);
-      signature.addInt(this.postfixExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.postfixExpression_operator == null
-          ? 0
-          : this.postfixExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.postfixExpression_substitution != null);
-      this.postfixExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.prefixExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.prefixExpression_operand != null);
-      this.prefixExpression_operand?.collectApiSignature(signature);
-      signature.addInt(this.prefixExpression_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.prefixExpression_operator == null
-          ? 0
-          : this.prefixExpression_operator.index);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.prefixExpression_substitution != null);
-      this.prefixExpression_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.prefixedIdentifier_identifier != null);
-      this.prefixedIdentifier_identifier?.collectApiSignature(signature);
-      signature.addBool(this.prefixedIdentifier_prefix != null);
-      this.prefixedIdentifier_prefix?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.propertyAccess) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.propertyAccess_propertyName != null);
-      this.propertyAccess_propertyName?.collectApiSignature(signature);
-      signature.addBool(this.propertyAccess_target != null);
-      this.propertyAccess_target?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addInt(this.propertyAccess_operator == null
-          ? 0
-          : this.propertyAccess_operator.index);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature
-          .addBool(this.redirectingConstructorInvocation_arguments != null);
-      this
-          .redirectingConstructorInvocation_arguments
-          ?.collectApiSignature(signature);
-      signature.addBool(
-          this.redirectingConstructorInvocation_constructorName != null);
-      this
-          .redirectingConstructorInvocation_constructorName
-          ?.collectApiSignature(signature);
-      signature.addInt(this.redirectingConstructorInvocation_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature
-          .addBool(this.redirectingConstructorInvocation_substitution != null);
-      this
-          .redirectingConstructorInvocation_substitution
-          ?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.returnStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.returnStatement_expression != null);
-      this.returnStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typedLiteral_typeArguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typedLiteral_typeArguments.length);
-        for (var x in this.typedLiteral_typeArguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.setOrMapLiteral_elements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.setOrMapLiteral_elements.length);
-        for (var x in this.setOrMapLiteral_elements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      if (this.names == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.names.length);
-        for (var x in this.names) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.normalFormalParameter_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.normalFormalParameter_metadata.length);
-        for (var x in this.normalFormalParameter_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.simpleFormalParameter_type != null);
-      this.simpleFormalParameter_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addBool(this.topLevelTypeInferenceError != null);
-      this.topLevelTypeInferenceError?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.simpleIdentifier_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.simpleIdentifier_substitution != null);
-      this.simpleIdentifier_substitution?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.simpleStringLiteral_value ?? '');
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.spreadElement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.spreadElement_expression != null);
-      this.spreadElement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addInt(this.spreadElement_spreadOperator == null
-          ? 0
-          : this.spreadElement_spreadOperator.index);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.stringInterpolation_elements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.stringInterpolation_elements.length);
-        for (var x in this.stringInterpolation_elements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.superConstructorInvocation_arguments != null);
-      this.superConstructorInvocation_arguments?.collectApiSignature(signature);
-      signature
-          .addBool(this.superConstructorInvocation_constructorName != null);
-      this
-          .superConstructorInvocation_constructorName
-          ?.collectApiSignature(signature);
-      signature.addInt(this.superConstructorInvocation_element ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-      signature.addBool(this.superConstructorInvocation_substitution != null);
-      this
-          .superConstructorInvocation_substitution
-          ?.collectApiSignature(signature);
-    } else if (kind == idl.LinkedNodeKind.superExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.switchCase) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.switchMember_labels == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_labels.length);
-        for (var x in this.switchMember_labels) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.switchMember_statements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_statements.length);
-        for (var x in this.switchMember_statements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.switchCase_expression != null);
-      this.switchCase_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.switchDefault) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.switchMember_labels == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_labels.length);
-        for (var x in this.switchMember_labels) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.switchMember_statements == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchMember_statements.length);
-        for (var x in this.switchMember_statements) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.switchStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.switchStatement_members == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.switchStatement_members.length);
-        for (var x in this.switchStatement_members) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.switchStatement_expression != null);
-      this.switchStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      if (this.names == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.names.length);
-        for (var x in this.names) {
-          signature.addString(x);
-        }
-      }
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.thisExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.throwExpression) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.throwExpression_expression != null);
-      this.throwExpression_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.expression_type != null);
-      this.expression_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.topLevelVariableDeclaration_variableList != null);
-      this
-          .topLevelVariableDeclaration_variableList
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.tryStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.tryStatement_catchClauses == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.tryStatement_catchClauses.length);
-        for (var x in this.tryStatement_catchClauses) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.tryStatement_body != null);
-      this.tryStatement_body?.collectApiSignature(signature);
-      signature.addBool(this.tryStatement_finallyBlock != null);
-      this.tryStatement_finallyBlock?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typeArgumentList_arguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typeArgumentList_arguments.length);
-        for (var x in this.typeArgumentList_arguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeName) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typeName_typeArguments == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typeName_typeArguments.length);
-        for (var x in this.typeName_typeArguments) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.typeName_name != null);
-      this.typeName_name?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.typeName_type != null);
-      this.typeName_type?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.typeParameter_bound != null);
-      this.typeParameter_bound?.collectApiSignature(signature);
-      signature.addInt(this.typeParameter_variance ?? 0);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.typeParameter_defaultType != null);
-      this.typeParameter_defaultType?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.typeParameterList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.typeParameterList_typeParameters == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.typeParameterList_typeParameters.length);
-        for (var x in this.typeParameterList_typeParameters) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.variableDeclaration_initializer != null);
-      this.variableDeclaration_initializer?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addBool(this.actualType != null);
-      this.actualType?.collectApiSignature(signature);
-      signature.addBool(this.inheritsCovariant == true);
-      signature.addBool(this.topLevelTypeInferenceError != null);
-      this.topLevelTypeInferenceError?.collectApiSignature(signature);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.variableDeclarationList_variables == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.variableDeclarationList_variables.length);
-        for (var x in this.variableDeclarationList_variables) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      if (this.annotatedNode_metadata == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.annotatedNode_metadata.length);
-        for (var x in this.annotatedNode_metadata) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addBool(this.variableDeclarationList_type != null);
-      this.variableDeclarationList_type?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.variableDeclarationStatement_variables != null);
-      this
-          .variableDeclarationStatement_variables
-          ?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.whileStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.whileStatement_body != null);
-      this.whileStatement_body?.collectApiSignature(signature);
-      signature.addBool(this.whileStatement_condition != null);
-      this.whileStatement_condition?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.withClause) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.withClause_mixinTypes == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.withClause_mixinTypes.length);
-        for (var x in this.withClause_mixinTypes) {
-          x?.collectApiSignature(signature);
-        }
-      }
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    } else if (kind == idl.LinkedNodeKind.yieldStatement) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addBool(this.yieldStatement_expression != null);
-      this.yieldStatement_expression?.collectApiSignature(signature);
-      signature.addInt(this.flags ?? 0);
-      signature.addString(this.name ?? '');
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_variantField_24;
-    fb.Offset offset_variantField_2;
-    fb.Offset offset_variantField_4;
-    fb.Offset offset_variantField_6;
-    fb.Offset offset_variantField_7;
-    fb.Offset offset_variantField_8;
-    fb.Offset offset_variantField_38;
-    fb.Offset offset_variantField_9;
-    fb.Offset offset_variantField_12;
-    fb.Offset offset_variantField_5;
-    fb.Offset offset_variantField_13;
-    fb.Offset offset_variantField_33;
-    fb.Offset offset_variantField_3;
-    fb.Offset offset_variantField_41;
-    fb.Offset offset_variantField_40;
-    fb.Offset offset_variantField_10;
-    fb.Offset offset_variantField_25;
-    fb.Offset offset_variantField_20;
-    fb.Offset offset_variantField_39;
-    fb.Offset offset_variantField_1;
-    fb.Offset offset_variantField_30;
-    fb.Offset offset_variantField_14;
-    fb.Offset offset_variantField_34;
-    fb.Offset offset_name;
-    fb.Offset offset_variantField_32;
-    fb.Offset offset_variantField_23;
-    fb.Offset offset_variantField_11;
-    fb.Offset offset_variantField_22;
-    if (_variantField_24 != null) {
-      offset_variantField_24 = _variantField_24.finish(fbBuilder);
-    }
-    if (!(_variantField_2 == null || _variantField_2.isEmpty)) {
-      offset_variantField_2 = fbBuilder
-          .writeList(_variantField_2.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
-      offset_variantField_4 = fbBuilder
-          .writeList(_variantField_4.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_variantField_6 != null) {
-      offset_variantField_6 = _variantField_6.finish(fbBuilder);
-    }
-    if (_variantField_7 != null) {
-      offset_variantField_7 = _variantField_7.finish(fbBuilder);
-    }
-    if (_variantField_8 != null) {
-      offset_variantField_8 = _variantField_8.finish(fbBuilder);
-    }
-    if (_variantField_38 != null) {
-      offset_variantField_38 = _variantField_38.finish(fbBuilder);
-    }
-    if (_variantField_9 != null) {
-      offset_variantField_9 = _variantField_9.finish(fbBuilder);
-    }
-    if (_variantField_12 != null) {
-      offset_variantField_12 = _variantField_12.finish(fbBuilder);
-    }
-    if (!(_variantField_5 == null || _variantField_5.isEmpty)) {
-      offset_variantField_5 = fbBuilder
-          .writeList(_variantField_5.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_variantField_13 != null) {
-      offset_variantField_13 = _variantField_13.finish(fbBuilder);
-    }
-    if (!(_variantField_33 == null || _variantField_33.isEmpty)) {
-      offset_variantField_33 = fbBuilder.writeList(
-          _variantField_33.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    if (!(_variantField_3 == null || _variantField_3.isEmpty)) {
-      offset_variantField_3 = fbBuilder
-          .writeList(_variantField_3.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_variantField_41 == null || _variantField_41.isEmpty)) {
-      offset_variantField_41 = fbBuilder.writeListUint32(_variantField_41);
-    }
-    if (_variantField_40 != null) {
-      offset_variantField_40 = _variantField_40.finish(fbBuilder);
-    }
-    if (_variantField_10 != null) {
-      offset_variantField_10 = _variantField_10.finish(fbBuilder);
-    }
-    if (_variantField_25 != null) {
-      offset_variantField_25 = _variantField_25.finish(fbBuilder);
-    }
-    if (_variantField_20 != null) {
-      offset_variantField_20 = fbBuilder.writeString(_variantField_20);
-    }
-    if (!(_variantField_39 == null || _variantField_39.isEmpty)) {
-      offset_variantField_39 = fbBuilder
-          .writeList(_variantField_39.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_variantField_1 != null) {
-      offset_variantField_1 = fbBuilder.writeString(_variantField_1);
-    }
-    if (_variantField_30 != null) {
-      offset_variantField_30 = fbBuilder.writeString(_variantField_30);
-    }
-    if (_variantField_14 != null) {
-      offset_variantField_14 = _variantField_14.finish(fbBuilder);
-    }
-    if (!(_variantField_34 == null || _variantField_34.isEmpty)) {
-      offset_variantField_34 = fbBuilder.writeList(
-          _variantField_34.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    if (_variantField_32 != null) {
-      offset_variantField_32 = _variantField_32.finish(fbBuilder);
-    }
-    if (_variantField_23 != null) {
-      offset_variantField_23 = _variantField_23.finish(fbBuilder);
-    }
-    if (_variantField_11 != null) {
-      offset_variantField_11 = _variantField_11.finish(fbBuilder);
-    }
-    if (_variantField_22 != null) {
-      offset_variantField_22 = fbBuilder.writeString(_variantField_22);
-    }
-    fbBuilder.startTable();
-    if (offset_variantField_24 != null) {
-      fbBuilder.addOffset(24, offset_variantField_24);
-    }
-    if (offset_variantField_2 != null) {
-      fbBuilder.addOffset(2, offset_variantField_2);
-    }
-    if (offset_variantField_4 != null) {
-      fbBuilder.addOffset(4, offset_variantField_4);
-    }
-    if (offset_variantField_6 != null) {
-      fbBuilder.addOffset(6, offset_variantField_6);
-    }
-    if (offset_variantField_7 != null) {
-      fbBuilder.addOffset(7, offset_variantField_7);
-    }
-    if (_variantField_17 != null && _variantField_17 != 0) {
-      fbBuilder.addUint32(17, _variantField_17);
-    }
-    if (offset_variantField_8 != null) {
-      fbBuilder.addOffset(8, offset_variantField_8);
-    }
-    if (offset_variantField_38 != null) {
-      fbBuilder.addOffset(38, offset_variantField_38);
-    }
-    if (_variantField_15 != null && _variantField_15 != 0) {
-      fbBuilder.addUint32(15, _variantField_15);
-    }
-    if (_variantField_28 != null &&
-        _variantField_28 != idl.UnlinkedTokenType.NOTHING) {
-      fbBuilder.addUint8(28, _variantField_28.index);
-    }
-    if (_variantField_27 == true) {
-      fbBuilder.addBool(27, true);
-    }
-    if (offset_variantField_9 != null) {
-      fbBuilder.addOffset(9, offset_variantField_9);
-    }
-    if (offset_variantField_12 != null) {
-      fbBuilder.addOffset(12, offset_variantField_12);
-    }
-    if (offset_variantField_5 != null) {
-      fbBuilder.addOffset(5, offset_variantField_5);
-    }
-    if (offset_variantField_13 != null) {
-      fbBuilder.addOffset(13, offset_variantField_13);
-    }
-    if (offset_variantField_33 != null) {
-      fbBuilder.addOffset(33, offset_variantField_33);
-    }
-    if (_variantField_29 != null &&
-        _variantField_29 != idl.LinkedNodeCommentType.block) {
-      fbBuilder.addUint8(29, _variantField_29.index);
-    }
-    if (offset_variantField_3 != null) {
-      fbBuilder.addOffset(3, offset_variantField_3);
-    }
-    if (offset_variantField_41 != null) {
-      fbBuilder.addOffset(41, offset_variantField_41);
-    }
-    if (offset_variantField_40 != null) {
-      fbBuilder.addOffset(40, offset_variantField_40);
-    }
-    if (offset_variantField_10 != null) {
-      fbBuilder.addOffset(10, offset_variantField_10);
-    }
-    if (_variantField_26 != null &&
-        _variantField_26 !=
-            idl.LinkedNodeFormalParameterKind.requiredPositional) {
-      fbBuilder.addUint8(26, _variantField_26.index);
-    }
-    if (_variantField_21 != null && _variantField_21 != 0.0) {
-      fbBuilder.addFloat64(21, _variantField_21);
-    }
-    if (offset_variantField_25 != null) {
-      fbBuilder.addOffset(25, offset_variantField_25);
-    }
-    if (offset_variantField_20 != null) {
-      fbBuilder.addOffset(20, offset_variantField_20);
-    }
-    if (offset_variantField_39 != null) {
-      fbBuilder.addOffset(39, offset_variantField_39);
-    }
-    if (_flags != null && _flags != 0) {
-      fbBuilder.addUint32(18, _flags);
-    }
-    if (offset_variantField_1 != null) {
-      fbBuilder.addOffset(1, offset_variantField_1);
-    }
-    if (_variantField_36 != null && _variantField_36 != 0) {
-      fbBuilder.addUint32(36, _variantField_36);
-    }
-    if (_variantField_16 != null && _variantField_16 != 0) {
-      fbBuilder.addUint32(16, _variantField_16);
-    }
-    if (offset_variantField_30 != null) {
-      fbBuilder.addOffset(30, offset_variantField_30);
-    }
-    if (offset_variantField_14 != null) {
-      fbBuilder.addOffset(14, offset_variantField_14);
-    }
-    if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    if (_variantField_31 == true) {
-      fbBuilder.addBool(31, true);
-    }
-    if (offset_variantField_34 != null) {
-      fbBuilder.addOffset(34, offset_variantField_34);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(37, offset_name);
-    }
-    if (_variantField_35 != null &&
-        _variantField_35 != idl.UnlinkedTokenType.NOTHING) {
-      fbBuilder.addUint8(35, _variantField_35.index);
-    }
-    if (offset_variantField_32 != null) {
-      fbBuilder.addOffset(32, offset_variantField_32);
-    }
-    if (offset_variantField_23 != null) {
-      fbBuilder.addOffset(23, offset_variantField_23);
-    }
-    if (offset_variantField_11 != null) {
-      fbBuilder.addOffset(11, offset_variantField_11);
-    }
-    if (offset_variantField_22 != null) {
-      fbBuilder.addOffset(22, offset_variantField_22);
-    }
-    if (_variantField_19 != null && _variantField_19 != 0) {
-      fbBuilder.addUint32(19, _variantField_19);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeReader extends fb.TableReader<_LinkedNodeImpl> {
-  const _LinkedNodeReader();
-
-  @override
-  _LinkedNodeImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeImpl(bc, offset);
-}
-
-class _LinkedNodeImpl extends Object
-    with _LinkedNodeMixin
-    implements idl.LinkedNode {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeType _variantField_24;
-  List<idl.LinkedNode> _variantField_2;
-  List<idl.LinkedNode> _variantField_4;
-  idl.LinkedNode _variantField_6;
-  idl.LinkedNode _variantField_7;
-  int _variantField_17;
-  idl.LinkedNode _variantField_8;
-  idl.LinkedNodeTypeSubstitution _variantField_38;
-  int _variantField_15;
-  idl.UnlinkedTokenType _variantField_28;
-  bool _variantField_27;
-  idl.LinkedNode _variantField_9;
-  idl.LinkedNode _variantField_12;
-  List<idl.LinkedNode> _variantField_5;
-  idl.LinkedNode _variantField_13;
-  List<String> _variantField_33;
-  idl.LinkedNodeCommentType _variantField_29;
-  List<idl.LinkedNode> _variantField_3;
-  List<int> _variantField_41;
-  idl.LinkedLibraryLanguageVersion _variantField_40;
-  idl.LinkedNode _variantField_10;
-  idl.LinkedNodeFormalParameterKind _variantField_26;
-  double _variantField_21;
-  idl.LinkedNodeType _variantField_25;
-  String _variantField_20;
-  List<idl.LinkedNodeType> _variantField_39;
-  int _flags;
-  String _variantField_1;
-  int _variantField_36;
-  int _variantField_16;
-  String _variantField_30;
-  idl.LinkedNode _variantField_14;
-  idl.LinkedNodeKind _kind;
-  bool _variantField_31;
-  List<String> _variantField_34;
-  String _name;
-  idl.UnlinkedTokenType _variantField_35;
-  idl.TopLevelInferenceError _variantField_32;
-  idl.LinkedNodeType _variantField_23;
-  idl.LinkedNode _variantField_11;
-  String _variantField_22;
-  int _variantField_19;
-
-  @override
-  idl.LinkedNodeType get actualReturnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericFunctionType ||
-        kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get actualType {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get extensionOverride_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get invocationExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  List<idl.LinkedNode> get adjacentStrings_strings {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get argumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get block_statements {
-    assert(kind == idl.LinkedNodeKind.block);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get cascadeExpression_sections {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get comment_references {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get compilationUnit_declarations {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get constructorDeclaration_initializers {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get dottedName_components {
-    assert(kind == idl.LinkedNodeKind.dottedName);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get enumDeclaration_constants {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get extensionOverride_arguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get formalParameterList_parameters {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get implementsClause_interfaces {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get instanceCreationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get labeledStatement_labels {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get libraryIdentifier_components {
-    assert(kind == idl.LinkedNodeKind.libraryIdentifier);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get namespaceDirective_combinators {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get onClause_superclassConstraints {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get stringInterpolation_elements {
-    assert(kind == idl.LinkedNodeKind.stringInterpolation);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get switchStatement_members {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get tryStatement_catchClauses {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typeArgumentList_arguments {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typedLiteral_typeArguments {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typeName_typeArguments {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get typeParameterList_typeParameters {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get variableDeclarationList_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get withClause_mixinTypes {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get annotatedNode_metadata {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.declaredIdentifier ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
-    return _variantField_4;
-  }
-
-  @override
-  List<idl.LinkedNode> get normalFormalParameter_metadata {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
-    return _variantField_4;
-  }
-
-  @override
-  List<idl.LinkedNode> get switchMember_statements {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
-    return _variantField_4;
-  }
-
-  @override
-  idl.LinkedNode get annotation_arguments {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get asExpression_expression {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get assertInitializer_condition {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get assertStatement_condition {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get assignmentExpression_leftHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get awaitExpression_expression {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get binaryExpression_leftOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get blockFunctionBody_block {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get breakStatement_label {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get cascadeExpression_target {
-    assert(kind == idl.LinkedNodeKind.cascadeExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_body {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get classDeclaration_extendsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get commentReference_identifier {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get compilationUnit_scriptTag {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get conditionalExpression_condition {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get configuration_name {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get constructorFieldInitializer_expression {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get constructorName_name {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get continueStatement_label {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get declaredIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get defaultFormalParameter_defaultValue {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get doStatement_body {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get expressionFunctionBody_expression {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get expressionStatement_expression {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get extendsClause_superclass {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get extensionDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get fieldDeclaration_fields {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get fieldFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get forEachParts_iterable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get forMixin_forLoopParts {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get forParts_condition {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionDeclaration_functionExpression {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionDeclarationStatement_functionDeclaration {
-    assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionExpression_body {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionExpressionInvocation_function {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionTypeAlias_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get functionTypedFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get genericFunctionType_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get genericTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get ifMixin_condition {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get indexExpression_index {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get interpolationExpression_expression {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get isExpression_expression {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get label_label {
-    assert(kind == idl.LinkedNodeKind.label);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get labeledStatement_statement {
-    assert(kind == idl.LinkedNodeKind.labeledStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get libraryDirective_name {
-    assert(kind == idl.LinkedNodeKind.libraryDirective);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get mapLiteralEntry_key {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_body {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get methodInvocation_methodName {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get mixinDeclaration_onClause {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get namedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get nativeClause_name {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get nativeFunctionBody_stringLiteral {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get parenthesizedExpression_expression {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get partOfDirective_libraryName {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get postfixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get prefixedIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get prefixExpression_operand {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get propertyAccess_propertyName {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get redirectingConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get returnStatement_expression {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get simpleFormalParameter_type {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get spreadElement_expression {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get superConstructorInvocation_arguments {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get switchCase_expression {
-    assert(kind == idl.LinkedNodeKind.switchCase);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get throwExpression_expression {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get topLevelVariableDeclaration_variableList {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get tryStatement_body {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get typeName_name {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get typeParameter_bound {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclaration_initializer {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclarationList_type {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclarationStatement_variables {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get whileStatement_body {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get yieldStatement_expression {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
-  idl.LinkedNode get annotation_constructorName {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get asExpression_type {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get assertInitializer_message {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get assertStatement_message {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get assignmentExpression_rightHandSide {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get binaryExpression_rightOperand {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_exceptionParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get classDeclaration_withClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_superclass {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get conditionalExpression_elseExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get configuration_value {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get constructorFieldInitializer_fieldName {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get constructorName_type {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get declaredIdentifier_type {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get defaultFormalParameter_parameter {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get doStatement_condition {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get extensionDeclaration_extendedType {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get extensionOverride_extensionName {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get fieldFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forEachPartsWithDeclaration_loopVariable {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forEachPartsWithIdentifier_identifier {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forElement_body {
-    assert(kind == idl.LinkedNodeKind.forElement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forPartsWithDeclarations_variables {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forPartsWithExpression_initialization {
-    assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get forStatement_body {
-    assert(kind == idl.LinkedNodeKind.forStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionExpression_formalParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionTypeAlias_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get functionTypedFormalParameter_returnType {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get genericFunctionType_returnType {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get genericTypeAlias_functionType {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get ifStatement_elseStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get indexExpression_target {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get instanceCreationExpression_constructorName {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get isExpression_type {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get mapLiteralEntry_value {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_formalParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get methodInvocation_target {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get namedExpression_name {
-    assert(kind == idl.LinkedNodeKind.namedExpression);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get partOfDirective_uri {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get prefixedIdentifier_prefix {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get propertyAccess_target {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get redirectingConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get superConstructorInvocation_constructorName {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get switchStatement_expression {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get tryStatement_finallyBlock {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get whileStatement_condition {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  int get annotation_element {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get genericFunctionType_id {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  idl.LinkedNode get annotation_name {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_exceptionType {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get classDeclaration_nativeClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_withClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get conditionalExpression_thenExpression {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get configuration_uri {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_parameters {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get extensionOverride_typeArguments {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get fieldFormalParameter_formalParameters {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get functionExpression_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get functionTypeAlias_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get functionTypedFormalParameter_typeParameters {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get genericFunctionType_formalParameters {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get ifElement_thenElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get ifStatement_thenStatement {
-    assert(kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get instanceCreationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_8 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
-    return _variantField_8;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get annotation_substitution {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get assignmentExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get binaryExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get constructorName_substitution {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get indexExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get postfixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get prefixExpression_substitution {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution
-      get redirectingConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get simpleIdentifier_substitution {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  idl.LinkedNodeTypeSubstitution get superConstructorInvocation_substitution {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
-        .vTableGet(_bc, _bcOffset, 38, null);
-    return _variantField_38;
-  }
-
-  @override
-  int get assignmentExpression_element {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get binaryExpression_element {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get constructorName_element {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get emptyFunctionBody_fake {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get emptyStatement_fake {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get indexExpression_element {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get nullLiteral_fake {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get postfixExpression_element {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get prefixExpression_element {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get simpleIdentifier_element {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get superConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get typeParameter_variance {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  idl.UnlinkedTokenType get assignmentExpression_operator {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get binaryExpression_operator {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get postfixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get prefixExpression_operator {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  idl.UnlinkedTokenType get propertyAccess_operator {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_28 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_28;
-  }
-
-  @override
-  bool get booleanLiteral_value {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get classDeclaration_isDartObject {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get inheritsCovariant {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get typeAlias_hasSelfReference {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  idl.LinkedNode get catchClause_stackTraceParameter {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get classTypeAlias_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_redirectedConstructor {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get ifElement_elseElement {
-    assert(kind == idl.LinkedNodeKind.ifElement);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get methodDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_9 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
-    return _variantField_9;
-  }
-
-  @override
-  idl.LinkedNode get classOrMixinDeclaration_implementsClause {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_12 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
-    return _variantField_12;
-  }
-
-  @override
-  idl.LinkedNode get invocationExpression_typeArguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_12 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
-    return _variantField_12;
-  }
-
-  @override
-  List<idl.LinkedNode> get classOrMixinDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
-    return _variantField_5;
-  }
-
-  @override
-  List<idl.LinkedNode> get extensionDeclaration_members {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
-    return _variantField_5;
-  }
-
-  @override
-  List<idl.LinkedNode> get forParts_updaters {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
-    return _variantField_5;
-  }
-
-  @override
-  idl.LinkedNode get classOrMixinDeclaration_typeParameters {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_13 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 13, null);
-    return _variantField_13;
-  }
-
-  @override
-  List<String> get comment_tokens {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_33 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 33, const <String>[]);
-    return _variantField_33;
-  }
-
-  @override
-  idl.LinkedNodeCommentType get comment_type {
-    assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_29 ??= const _LinkedNodeCommentTypeReader()
-        .vTableGet(_bc, _bcOffset, 29, idl.LinkedNodeCommentType.block);
-    return _variantField_29;
-  }
-
-  @override
-  List<idl.LinkedNode> get compilationUnit_directives {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get listLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get namespaceDirective_configurations {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get setOrMapLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<idl.LinkedNode> get switchMember_labels {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
-        .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
-    return _variantField_3;
-  }
-
-  @override
-  List<int> get compilationUnit_featureSet {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_41 ??= const fb.Uint32ListReader()
-        .vTableGet(_bc, _bcOffset, 41, const <int>[]);
-    return _variantField_41;
-  }
-
-  @override
-  idl.LinkedLibraryLanguageVersion get compilationUnit_languageVersion {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_40 ??= const _LinkedLibraryLanguageVersionReader()
-        .vTableGet(_bc, _bcOffset, 40, null);
-    return _variantField_40;
-  }
-
-  @override
-  idl.LinkedNode get constructorDeclaration_returnType {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_10 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 10, null);
-    return _variantField_10;
-  }
-
-  @override
-  idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_26 ??= const _LinkedNodeFormalParameterKindReader().vTableGet(
-        _bc,
-        _bcOffset,
-        26,
-        idl.LinkedNodeFormalParameterKind.requiredPositional);
-    return _variantField_26;
-  }
-
-  @override
-  double get doubleLiteral_value {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    _variantField_21 ??=
-        const fb.Float64Reader().vTableGet(_bc, _bcOffset, 21, 0.0);
-    return _variantField_21;
-  }
-
-  @override
-  idl.LinkedNodeType get expression_type {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
-        kind == idl.LinkedNodeKind.asExpression ||
-        kind == idl.LinkedNodeKind.awaitExpression ||
-        kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.cascadeExpression ||
-        kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.indexExpression ||
-        kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.nullLiteral ||
-        kind == idl.LinkedNodeKind.parenthesizedExpression ||
-        kind == idl.LinkedNodeKind.prefixExpression ||
-        kind == idl.LinkedNodeKind.prefixedIdentifier ||
-        kind == idl.LinkedNodeKind.propertyAccess ||
-        kind == idl.LinkedNodeKind.postfixExpression ||
-        kind == idl.LinkedNodeKind.rethrowExpression ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral ||
-        kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.superExpression ||
-        kind == idl.LinkedNodeKind.symbolLiteral ||
-        kind == idl.LinkedNodeKind.thisExpression ||
-        kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_25 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
-    return _variantField_25;
-  }
-
-  @override
-  idl.LinkedNodeType get genericFunctionType_type {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_25 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
-    return _variantField_25;
-  }
-
-  @override
-  String get extensionDeclaration_refName {
-    assert(kind == idl.LinkedNodeKind.extensionDeclaration);
-    _variantField_20 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
-    return _variantField_20;
-  }
-
-  @override
-  String get namespaceDirective_selectedUri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective);
-    _variantField_20 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
-    return _variantField_20;
-  }
-
-  @override
-  String get simpleStringLiteral_value {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    _variantField_20 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
-    return _variantField_20;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get extensionOverride_typeArgumentTypes {
-    assert(kind == idl.LinkedNodeKind.extensionOverride);
-    _variantField_39 ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 39, const <idl.LinkedNodeType>[]);
-    return _variantField_39;
-  }
-
-  @override
-  int get flags {
-    _flags ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _flags;
-  }
-
-  @override
-  String get importDirective_prefix {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_1 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
-    return _variantField_1;
-  }
-
-  @override
-  int get informativeId {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration ||
-        kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_36 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 36, 0);
-    return _variantField_36;
-  }
-
-  @override
-  int get integerLiteral_value {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  String get interpolationString_value {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    _variantField_30 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 30, '');
-    return _variantField_30;
-  }
-
-  @override
-  idl.LinkedNode get invocationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_14 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
-    return _variantField_14;
-  }
-
-  @override
-  idl.LinkedNode get uriBasedDirective_uri {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_14 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
-    return _variantField_14;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind {
-    _kind ??= const _LinkedNodeKindReader()
-        .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
-    return _kind;
-  }
-
-  @override
-  bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_31 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
-    return _variantField_31;
-  }
-
-  @override
-  bool get simplyBoundable_isSimplyBounded {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_31 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
-    return _variantField_31;
-  }
-
-  @override
-  List<String> get mixinDeclaration_superInvokedNames {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_34 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 34, const <String>[]);
-    return _variantField_34;
-  }
-
-  @override
-  List<String> get names {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator ||
-        kind == idl.LinkedNodeKind.symbolLiteral);
-    _variantField_34 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 34, const <String>[]);
-    return _variantField_34;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 37, '');
-    return _name;
-  }
-
-  @override
-  idl.UnlinkedTokenType get spreadElement_spreadOperator {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_35 ??= const _UnlinkedTokenTypeReader()
-        .vTableGet(_bc, _bcOffset, 35, idl.UnlinkedTokenType.NOTHING);
-    return _variantField_35;
-  }
-
-  @override
-  idl.TopLevelInferenceError get topLevelTypeInferenceError {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_32 ??= const _TopLevelInferenceErrorReader()
-        .vTableGet(_bc, _bcOffset, 32, null);
-    return _variantField_32;
-  }
-
-  @override
-  idl.LinkedNodeType get typeName_type {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_23 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
-    return _variantField_23;
-  }
-
-  @override
-  idl.LinkedNodeType get typeParameter_defaultType {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_23 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
-    return _variantField_23;
-  }
-
-  @override
-  idl.LinkedNode get unused11 {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_11 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 11, null);
-    return _variantField_11;
-  }
-
-  @override
-  String get uriBasedDirective_uriContent {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_22 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 22, '');
-    return _variantField_22;
-  }
-
-  @override
-  int get uriBasedDirective_uriElement {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-}
-
-abstract class _LinkedNodeMixin implements idl.LinkedNode {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (flags != 0) {
-      _result["flags"] = flags;
-    }
-    if (kind != idl.LinkedNodeKind.adjacentStrings) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      if (adjacentStrings_strings.isNotEmpty) {
-        _result["adjacentStrings_strings"] =
-            adjacentStrings_strings.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.annotation) {
-      if (annotation_arguments != null) {
-        _result["annotation_arguments"] = annotation_arguments.toJson();
-      }
-      if (annotation_constructorName != null) {
-        _result["annotation_constructorName"] =
-            annotation_constructorName.toJson();
-      }
-      if (annotation_element != 0) {
-        _result["annotation_element"] = annotation_element;
-      }
-      if (annotation_name != null) {
-        _result["annotation_name"] = annotation_name.toJson();
-      }
-      if (annotation_substitution != null) {
-        _result["annotation_substitution"] = annotation_substitution.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.argumentList) {
-      if (argumentList_arguments.isNotEmpty) {
-        _result["argumentList_arguments"] =
-            argumentList_arguments.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.asExpression) {
-      if (asExpression_expression != null) {
-        _result["asExpression_expression"] = asExpression_expression.toJson();
-      }
-      if (asExpression_type != null) {
-        _result["asExpression_type"] = asExpression_type.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.assertInitializer) {
-      if (assertInitializer_condition != null) {
-        _result["assertInitializer_condition"] =
-            assertInitializer_condition.toJson();
-      }
-      if (assertInitializer_message != null) {
-        _result["assertInitializer_message"] =
-            assertInitializer_message.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.assertStatement) {
-      if (assertStatement_condition != null) {
-        _result["assertStatement_condition"] =
-            assertStatement_condition.toJson();
-      }
-      if (assertStatement_message != null) {
-        _result["assertStatement_message"] = assertStatement_message.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      if (assignmentExpression_leftHandSide != null) {
-        _result["assignmentExpression_leftHandSide"] =
-            assignmentExpression_leftHandSide.toJson();
-      }
-      if (assignmentExpression_rightHandSide != null) {
-        _result["assignmentExpression_rightHandSide"] =
-            assignmentExpression_rightHandSide.toJson();
-      }
-      if (assignmentExpression_substitution != null) {
-        _result["assignmentExpression_substitution"] =
-            assignmentExpression_substitution.toJson();
-      }
-      if (assignmentExpression_element != 0) {
-        _result["assignmentExpression_element"] = assignmentExpression_element;
-      }
-      if (assignmentExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["assignmentExpression_operator"] =
-            assignmentExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.awaitExpression) {
-      if (awaitExpression_expression != null) {
-        _result["awaitExpression_expression"] =
-            awaitExpression_expression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.binaryExpression) {
-      if (binaryExpression_invokeType != null) {
-        _result["binaryExpression_invokeType"] =
-            binaryExpression_invokeType.toJson();
-      }
-      if (binaryExpression_leftOperand != null) {
-        _result["binaryExpression_leftOperand"] =
-            binaryExpression_leftOperand.toJson();
-      }
-      if (binaryExpression_rightOperand != null) {
-        _result["binaryExpression_rightOperand"] =
-            binaryExpression_rightOperand.toJson();
-      }
-      if (binaryExpression_substitution != null) {
-        _result["binaryExpression_substitution"] =
-            binaryExpression_substitution.toJson();
-      }
-      if (binaryExpression_element != 0) {
-        _result["binaryExpression_element"] = binaryExpression_element;
-      }
-      if (binaryExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["binaryExpression_operator"] =
-            binaryExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.block) {
-      if (block_statements.isNotEmpty) {
-        _result["block_statements"] =
-            block_statements.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      if (blockFunctionBody_block != null) {
-        _result["blockFunctionBody_block"] = blockFunctionBody_block.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      if (booleanLiteral_value != false) {
-        _result["booleanLiteral_value"] = booleanLiteral_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.breakStatement) {
-      if (breakStatement_label != null) {
-        _result["breakStatement_label"] = breakStatement_label.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      if (cascadeExpression_sections.isNotEmpty) {
-        _result["cascadeExpression_sections"] = cascadeExpression_sections
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (cascadeExpression_target != null) {
-        _result["cascadeExpression_target"] = cascadeExpression_target.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.catchClause) {
-      if (catchClause_body != null) {
-        _result["catchClause_body"] = catchClause_body.toJson();
-      }
-      if (catchClause_exceptionParameter != null) {
-        _result["catchClause_exceptionParameter"] =
-            catchClause_exceptionParameter.toJson();
-      }
-      if (catchClause_exceptionType != null) {
-        _result["catchClause_exceptionType"] =
-            catchClause_exceptionType.toJson();
-      }
-      if (catchClause_stackTraceParameter != null) {
-        _result["catchClause_stackTraceParameter"] =
-            catchClause_stackTraceParameter.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (classDeclaration_extendsClause != null) {
-        _result["classDeclaration_extendsClause"] =
-            classDeclaration_extendsClause.toJson();
-      }
-      if (classDeclaration_withClause != null) {
-        _result["classDeclaration_withClause"] =
-            classDeclaration_withClause.toJson();
-      }
-      if (classDeclaration_nativeClause != null) {
-        _result["classDeclaration_nativeClause"] =
-            classDeclaration_nativeClause.toJson();
-      }
-      if (classDeclaration_isDartObject != false) {
-        _result["classDeclaration_isDartObject"] =
-            classDeclaration_isDartObject;
-      }
-      if (classOrMixinDeclaration_implementsClause != null) {
-        _result["classOrMixinDeclaration_implementsClause"] =
-            classOrMixinDeclaration_implementsClause.toJson();
-      }
-      if (classOrMixinDeclaration_members.isNotEmpty) {
-        _result["classOrMixinDeclaration_members"] =
-            classOrMixinDeclaration_members
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (classOrMixinDeclaration_typeParameters != null) {
-        _result["classOrMixinDeclaration_typeParameters"] =
-            classOrMixinDeclaration_typeParameters.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-      if (unused11 != null) {
-        _result["unused11"] = unused11.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (classTypeAlias_typeParameters != null) {
-        _result["classTypeAlias_typeParameters"] =
-            classTypeAlias_typeParameters.toJson();
-      }
-      if (classTypeAlias_superclass != null) {
-        _result["classTypeAlias_superclass"] =
-            classTypeAlias_superclass.toJson();
-      }
-      if (classTypeAlias_withClause != null) {
-        _result["classTypeAlias_withClause"] =
-            classTypeAlias_withClause.toJson();
-      }
-      if (classTypeAlias_implementsClause != null) {
-        _result["classTypeAlias_implementsClause"] =
-            classTypeAlias_implementsClause.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.comment) {
-      if (comment_references.isNotEmpty) {
-        _result["comment_references"] =
-            comment_references.map((_value) => _value.toJson()).toList();
-      }
-      if (comment_tokens.isNotEmpty) {
-        _result["comment_tokens"] = comment_tokens;
-      }
-      if (comment_type != idl.LinkedNodeCommentType.block) {
-        _result["comment_type"] = comment_type.toString().split('.')[1];
-      }
-    }
-    if (kind == idl.LinkedNodeKind.commentReference) {
-      if (commentReference_identifier != null) {
-        _result["commentReference_identifier"] =
-            commentReference_identifier.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      if (compilationUnit_declarations.isNotEmpty) {
-        _result["compilationUnit_declarations"] = compilationUnit_declarations
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (compilationUnit_scriptTag != null) {
-        _result["compilationUnit_scriptTag"] =
-            compilationUnit_scriptTag.toJson();
-      }
-      if (compilationUnit_directives.isNotEmpty) {
-        _result["compilationUnit_directives"] = compilationUnit_directives
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (compilationUnit_featureSet.isNotEmpty) {
-        _result["compilationUnit_featureSet"] = compilationUnit_featureSet;
-      }
-      if (compilationUnit_languageVersion != null) {
-        _result["compilationUnit_languageVersion"] =
-            compilationUnit_languageVersion.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      if (conditionalExpression_condition != null) {
-        _result["conditionalExpression_condition"] =
-            conditionalExpression_condition.toJson();
-      }
-      if (conditionalExpression_elseExpression != null) {
-        _result["conditionalExpression_elseExpression"] =
-            conditionalExpression_elseExpression.toJson();
-      }
-      if (conditionalExpression_thenExpression != null) {
-        _result["conditionalExpression_thenExpression"] =
-            conditionalExpression_thenExpression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.configuration) {
-      if (configuration_name != null) {
-        _result["configuration_name"] = configuration_name.toJson();
-      }
-      if (configuration_value != null) {
-        _result["configuration_value"] = configuration_value.toJson();
-      }
-      if (configuration_uri != null) {
-        _result["configuration_uri"] = configuration_uri.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      if (constructorDeclaration_initializers.isNotEmpty) {
-        _result["constructorDeclaration_initializers"] =
-            constructorDeclaration_initializers
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (constructorDeclaration_body != null) {
-        _result["constructorDeclaration_body"] =
-            constructorDeclaration_body.toJson();
-      }
-      if (constructorDeclaration_parameters != null) {
-        _result["constructorDeclaration_parameters"] =
-            constructorDeclaration_parameters.toJson();
-      }
-      if (constructorDeclaration_redirectedConstructor != null) {
-        _result["constructorDeclaration_redirectedConstructor"] =
-            constructorDeclaration_redirectedConstructor.toJson();
-      }
-      if (constructorDeclaration_returnType != null) {
-        _result["constructorDeclaration_returnType"] =
-            constructorDeclaration_returnType.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      if (constructorFieldInitializer_expression != null) {
-        _result["constructorFieldInitializer_expression"] =
-            constructorFieldInitializer_expression.toJson();
-      }
-      if (constructorFieldInitializer_fieldName != null) {
-        _result["constructorFieldInitializer_fieldName"] =
-            constructorFieldInitializer_fieldName.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorName) {
-      if (constructorName_name != null) {
-        _result["constructorName_name"] = constructorName_name.toJson();
-      }
-      if (constructorName_type != null) {
-        _result["constructorName_type"] = constructorName_type.toJson();
-      }
-      if (constructorName_substitution != null) {
-        _result["constructorName_substitution"] =
-            constructorName_substitution.toJson();
-      }
-      if (constructorName_element != 0) {
-        _result["constructorName_element"] = constructorName_element;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.continueStatement) {
-      if (continueStatement_label != null) {
-        _result["continueStatement_label"] = continueStatement_label.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (declaredIdentifier_identifier != null) {
-        _result["declaredIdentifier_identifier"] =
-            declaredIdentifier_identifier.toJson();
-      }
-      if (declaredIdentifier_type != null) {
-        _result["declaredIdentifier_type"] = declaredIdentifier_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      if (defaultFormalParameter_defaultValue != null) {
-        _result["defaultFormalParameter_defaultValue"] =
-            defaultFormalParameter_defaultValue.toJson();
-      }
-      if (defaultFormalParameter_parameter != null) {
-        _result["defaultFormalParameter_parameter"] =
-            defaultFormalParameter_parameter.toJson();
-      }
-      if (defaultFormalParameter_kind !=
-          idl.LinkedNodeFormalParameterKind.requiredPositional) {
-        _result["defaultFormalParameter_kind"] =
-            defaultFormalParameter_kind.toString().split('.')[1];
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.doStatement) {
-      if (doStatement_body != null) {
-        _result["doStatement_body"] = doStatement_body.toJson();
-      }
-      if (doStatement_condition != null) {
-        _result["doStatement_condition"] = doStatement_condition.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.dottedName) {
-      if (dottedName_components.isNotEmpty) {
-        _result["dottedName_components"] =
-            dottedName_components.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      if (doubleLiteral_value != 0.0) {
-        _result["doubleLiteral_value"] = doubleLiteral_value.isFinite
-            ? doubleLiteral_value
-            : doubleLiteral_value.toString();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      if (emptyFunctionBody_fake != 0) {
-        _result["emptyFunctionBody_fake"] = emptyFunctionBody_fake;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.emptyStatement) {
-      if (emptyStatement_fake != 0) {
-        _result["emptyStatement_fake"] = emptyStatement_fake;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      if (enumDeclaration_constants.isNotEmpty) {
-        _result["enumDeclaration_constants"] =
-            enumDeclaration_constants.map((_value) => _value.toJson()).toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      if (namespaceDirective_combinators.isNotEmpty) {
-        _result["namespaceDirective_combinators"] =
-            namespaceDirective_combinators
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (namespaceDirective_configurations.isNotEmpty) {
-        _result["namespaceDirective_configurations"] =
-            namespaceDirective_configurations
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (namespaceDirective_selectedUri != '') {
-        _result["namespaceDirective_selectedUri"] =
-            namespaceDirective_selectedUri;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (uriBasedDirective_uri != null) {
-        _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
-      }
-      if (uriBasedDirective_uriContent != '') {
-        _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
-      }
-      if (uriBasedDirective_uriElement != 0) {
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      if (expressionFunctionBody_expression != null) {
-        _result["expressionFunctionBody_expression"] =
-            expressionFunctionBody_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.expressionStatement) {
-      if (expressionStatement_expression != null) {
-        _result["expressionStatement_expression"] =
-            expressionStatement_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extendsClause) {
-      if (extendsClause_superclass != null) {
-        _result["extendsClause_superclass"] = extendsClause_superclass.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (extensionDeclaration_typeParameters != null) {
-        _result["extensionDeclaration_typeParameters"] =
-            extensionDeclaration_typeParameters.toJson();
-      }
-      if (extensionDeclaration_extendedType != null) {
-        _result["extensionDeclaration_extendedType"] =
-            extensionDeclaration_extendedType.toJson();
-      }
-      if (extensionDeclaration_members.isNotEmpty) {
-        _result["extensionDeclaration_members"] = extensionDeclaration_members
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (extensionDeclaration_refName != '') {
-        _result["extensionDeclaration_refName"] = extensionDeclaration_refName;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extensionOverride) {
-      if (extensionOverride_extendedType != null) {
-        _result["extensionOverride_extendedType"] =
-            extensionOverride_extendedType.toJson();
-      }
-      if (extensionOverride_arguments.isNotEmpty) {
-        _result["extensionOverride_arguments"] = extensionOverride_arguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (extensionOverride_extensionName != null) {
-        _result["extensionOverride_extensionName"] =
-            extensionOverride_extensionName.toJson();
-      }
-      if (extensionOverride_typeArguments != null) {
-        _result["extensionOverride_typeArguments"] =
-            extensionOverride_typeArguments.toJson();
-      }
-      if (extensionOverride_typeArgumentTypes.isNotEmpty) {
-        _result["extensionOverride_typeArgumentTypes"] =
-            extensionOverride_typeArgumentTypes
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (fieldDeclaration_fields != null) {
-        _result["fieldDeclaration_fields"] = fieldDeclaration_fields.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (normalFormalParameter_metadata.isNotEmpty) {
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (fieldFormalParameter_type != null) {
-        _result["fieldFormalParameter_type"] =
-            fieldFormalParameter_type.toJson();
-      }
-      if (fieldFormalParameter_typeParameters != null) {
-        _result["fieldFormalParameter_typeParameters"] =
-            fieldFormalParameter_typeParameters.toJson();
-      }
-      if (fieldFormalParameter_formalParameters != null) {
-        _result["fieldFormalParameter_formalParameters"] =
-            fieldFormalParameter_formalParameters.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      if (forEachParts_iterable != null) {
-        _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
-      }
-      if (forEachPartsWithDeclaration_loopVariable != null) {
-        _result["forEachPartsWithDeclaration_loopVariable"] =
-            forEachPartsWithDeclaration_loopVariable.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      if (forEachParts_iterable != null) {
-        _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
-      }
-      if (forEachPartsWithIdentifier_identifier != null) {
-        _result["forEachPartsWithIdentifier_identifier"] =
-            forEachPartsWithIdentifier_identifier.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forElement) {
-      if (forMixin_forLoopParts != null) {
-        _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
-      }
-      if (forElement_body != null) {
-        _result["forElement_body"] = forElement_body.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      if (forParts_condition != null) {
-        _result["forParts_condition"] = forParts_condition.toJson();
-      }
-      if (forPartsWithDeclarations_variables != null) {
-        _result["forPartsWithDeclarations_variables"] =
-            forPartsWithDeclarations_variables.toJson();
-      }
-      if (forParts_updaters.isNotEmpty) {
-        _result["forParts_updaters"] =
-            forParts_updaters.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      if (forParts_condition != null) {
-        _result["forParts_condition"] = forParts_condition.toJson();
-      }
-      if (forPartsWithExpression_initialization != null) {
-        _result["forPartsWithExpression_initialization"] =
-            forPartsWithExpression_initialization.toJson();
-      }
-      if (forParts_updaters.isNotEmpty) {
-        _result["forParts_updaters"] =
-            forParts_updaters.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.forStatement) {
-      if (forMixin_forLoopParts != null) {
-        _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
-      }
-      if (forStatement_body != null) {
-        _result["forStatement_body"] = forStatement_body.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.formalParameterList) {
-      if (formalParameterList_parameters.isNotEmpty) {
-        _result["formalParameterList_parameters"] =
-            formalParameterList_parameters
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (functionDeclaration_functionExpression != null) {
-        _result["functionDeclaration_functionExpression"] =
-            functionDeclaration_functionExpression.toJson();
-      }
-      if (functionDeclaration_returnType != null) {
-        _result["functionDeclaration_returnType"] =
-            functionDeclaration_returnType.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      if (functionDeclarationStatement_functionDeclaration != null) {
-        _result["functionDeclarationStatement_functionDeclaration"] =
-            functionDeclarationStatement_functionDeclaration.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionExpression) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (functionExpression_body != null) {
-        _result["functionExpression_body"] = functionExpression_body.toJson();
-      }
-      if (functionExpression_formalParameters != null) {
-        _result["functionExpression_formalParameters"] =
-            functionExpression_formalParameters.toJson();
-      }
-      if (functionExpression_typeParameters != null) {
-        _result["functionExpression_typeParameters"] =
-            functionExpression_typeParameters.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      if (invocationExpression_invokeType != null) {
-        _result["invocationExpression_invokeType"] =
-            invocationExpression_invokeType.toJson();
-      }
-      if (functionExpressionInvocation_function != null) {
-        _result["functionExpressionInvocation_function"] =
-            functionExpressionInvocation_function.toJson();
-      }
-      if (invocationExpression_typeArguments != null) {
-        _result["invocationExpression_typeArguments"] =
-            invocationExpression_typeArguments.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (invocationExpression_arguments != null) {
-        _result["invocationExpression_arguments"] =
-            invocationExpression_arguments.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (functionTypeAlias_formalParameters != null) {
-        _result["functionTypeAlias_formalParameters"] =
-            functionTypeAlias_formalParameters.toJson();
-      }
-      if (functionTypeAlias_returnType != null) {
-        _result["functionTypeAlias_returnType"] =
-            functionTypeAlias_returnType.toJson();
-      }
-      if (functionTypeAlias_typeParameters != null) {
-        _result["functionTypeAlias_typeParameters"] =
-            functionTypeAlias_typeParameters.toJson();
-      }
-      if (typeAlias_hasSelfReference != false) {
-        _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (normalFormalParameter_metadata.isNotEmpty) {
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (functionTypedFormalParameter_formalParameters != null) {
-        _result["functionTypedFormalParameter_formalParameters"] =
-            functionTypedFormalParameter_formalParameters.toJson();
-      }
-      if (functionTypedFormalParameter_returnType != null) {
-        _result["functionTypedFormalParameter_returnType"] =
-            functionTypedFormalParameter_returnType.toJson();
-      }
-      if (functionTypedFormalParameter_typeParameters != null) {
-        _result["functionTypedFormalParameter_typeParameters"] =
-            functionTypedFormalParameter_typeParameters.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (genericFunctionType_typeParameters != null) {
-        _result["genericFunctionType_typeParameters"] =
-            genericFunctionType_typeParameters.toJson();
-      }
-      if (genericFunctionType_returnType != null) {
-        _result["genericFunctionType_returnType"] =
-            genericFunctionType_returnType.toJson();
-      }
-      if (genericFunctionType_id != 0) {
-        _result["genericFunctionType_id"] = genericFunctionType_id;
-      }
-      if (genericFunctionType_formalParameters != null) {
-        _result["genericFunctionType_formalParameters"] =
-            genericFunctionType_formalParameters.toJson();
-      }
-      if (genericFunctionType_type != null) {
-        _result["genericFunctionType_type"] = genericFunctionType_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (genericTypeAlias_typeParameters != null) {
-        _result["genericTypeAlias_typeParameters"] =
-            genericTypeAlias_typeParameters.toJson();
-      }
-      if (genericTypeAlias_functionType != null) {
-        _result["genericTypeAlias_functionType"] =
-            genericTypeAlias_functionType.toJson();
-      }
-      if (typeAlias_hasSelfReference != false) {
-        _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (names.isNotEmpty) {
-        _result["names"] = names;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.ifElement) {
-      if (ifMixin_condition != null) {
-        _result["ifMixin_condition"] = ifMixin_condition.toJson();
-      }
-      if (ifElement_thenElement != null) {
-        _result["ifElement_thenElement"] = ifElement_thenElement.toJson();
-      }
-      if (ifElement_elseElement != null) {
-        _result["ifElement_elseElement"] = ifElement_elseElement.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.ifStatement) {
-      if (ifMixin_condition != null) {
-        _result["ifMixin_condition"] = ifMixin_condition.toJson();
-      }
-      if (ifStatement_elseStatement != null) {
-        _result["ifStatement_elseStatement"] =
-            ifStatement_elseStatement.toJson();
-      }
-      if (ifStatement_thenStatement != null) {
-        _result["ifStatement_thenStatement"] =
-            ifStatement_thenStatement.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.implementsClause) {
-      if (implementsClause_interfaces.isNotEmpty) {
-        _result["implementsClause_interfaces"] = implementsClause_interfaces
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      if (namespaceDirective_combinators.isNotEmpty) {
-        _result["namespaceDirective_combinators"] =
-            namespaceDirective_combinators
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (namespaceDirective_configurations.isNotEmpty) {
-        _result["namespaceDirective_configurations"] =
-            namespaceDirective_configurations
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (namespaceDirective_selectedUri != '') {
-        _result["namespaceDirective_selectedUri"] =
-            namespaceDirective_selectedUri;
-      }
-      if (importDirective_prefix != '') {
-        _result["importDirective_prefix"] = importDirective_prefix;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (uriBasedDirective_uri != null) {
-        _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
-      }
-      if (uriBasedDirective_uriContent != '') {
-        _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
-      }
-      if (uriBasedDirective_uriElement != 0) {
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.indexExpression) {
-      if (indexExpression_index != null) {
-        _result["indexExpression_index"] = indexExpression_index.toJson();
-      }
-      if (indexExpression_target != null) {
-        _result["indexExpression_target"] = indexExpression_target.toJson();
-      }
-      if (indexExpression_substitution != null) {
-        _result["indexExpression_substitution"] =
-            indexExpression_substitution.toJson();
-      }
-      if (indexExpression_element != 0) {
-        _result["indexExpression_element"] = indexExpression_element;
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      if (instanceCreationExpression_arguments.isNotEmpty) {
-        _result["instanceCreationExpression_arguments"] =
-            instanceCreationExpression_arguments
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (instanceCreationExpression_constructorName != null) {
-        _result["instanceCreationExpression_constructorName"] =
-            instanceCreationExpression_constructorName.toJson();
-      }
-      if (instanceCreationExpression_typeArguments != null) {
-        _result["instanceCreationExpression_typeArguments"] =
-            instanceCreationExpression_typeArguments.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.integerLiteral) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (integerLiteral_value != 0) {
-        _result["integerLiteral_value"] = integerLiteral_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      if (interpolationExpression_expression != null) {
-        _result["interpolationExpression_expression"] =
-            interpolationExpression_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.interpolationString) {
-      if (interpolationString_value != '') {
-        _result["interpolationString_value"] = interpolationString_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.isExpression) {
-      if (isExpression_expression != null) {
-        _result["isExpression_expression"] = isExpression_expression.toJson();
-      }
-      if (isExpression_type != null) {
-        _result["isExpression_type"] = isExpression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.label) {
-      if (label_label != null) {
-        _result["label_label"] = label_label.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.labeledStatement) {
-      if (labeledStatement_labels.isNotEmpty) {
-        _result["labeledStatement_labels"] =
-            labeledStatement_labels.map((_value) => _value.toJson()).toList();
-      }
-      if (labeledStatement_statement != null) {
-        _result["labeledStatement_statement"] =
-            labeledStatement_statement.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (libraryDirective_name != null) {
-        _result["libraryDirective_name"] = libraryDirective_name.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      if (libraryIdentifier_components.isNotEmpty) {
-        _result["libraryIdentifier_components"] = libraryIdentifier_components
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.listLiteral) {
-      if (typedLiteral_typeArguments.isNotEmpty) {
-        _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (listLiteral_elements.isNotEmpty) {
-        _result["listLiteral_elements"] =
-            listLiteral_elements.map((_value) => _value.toJson()).toList();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      if (mapLiteralEntry_key != null) {
-        _result["mapLiteralEntry_key"] = mapLiteralEntry_key.toJson();
-      }
-      if (mapLiteralEntry_value != null) {
-        _result["mapLiteralEntry_value"] = mapLiteralEntry_value.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      if (actualReturnType != null) {
-        _result["actualReturnType"] = actualReturnType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (methodDeclaration_body != null) {
-        _result["methodDeclaration_body"] = methodDeclaration_body.toJson();
-      }
-      if (methodDeclaration_formalParameters != null) {
-        _result["methodDeclaration_formalParameters"] =
-            methodDeclaration_formalParameters.toJson();
-      }
-      if (methodDeclaration_returnType != null) {
-        _result["methodDeclaration_returnType"] =
-            methodDeclaration_returnType.toJson();
-      }
-      if (methodDeclaration_typeParameters != null) {
-        _result["methodDeclaration_typeParameters"] =
-            methodDeclaration_typeParameters.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (methodDeclaration_hasOperatorEqualWithParameterTypeFromObject !=
-          false) {
-        _result["methodDeclaration_hasOperatorEqualWithParameterTypeFromObject"] =
-            methodDeclaration_hasOperatorEqualWithParameterTypeFromObject;
-      }
-      if (topLevelTypeInferenceError != null) {
-        _result["topLevelTypeInferenceError"] =
-            topLevelTypeInferenceError.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.methodInvocation) {
-      if (invocationExpression_invokeType != null) {
-        _result["invocationExpression_invokeType"] =
-            invocationExpression_invokeType.toJson();
-      }
-      if (methodInvocation_methodName != null) {
-        _result["methodInvocation_methodName"] =
-            methodInvocation_methodName.toJson();
-      }
-      if (methodInvocation_target != null) {
-        _result["methodInvocation_target"] = methodInvocation_target.toJson();
-      }
-      if (invocationExpression_typeArguments != null) {
-        _result["invocationExpression_typeArguments"] =
-            invocationExpression_typeArguments.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (invocationExpression_arguments != null) {
-        _result["invocationExpression_arguments"] =
-            invocationExpression_arguments.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (mixinDeclaration_onClause != null) {
-        _result["mixinDeclaration_onClause"] =
-            mixinDeclaration_onClause.toJson();
-      }
-      if (classOrMixinDeclaration_implementsClause != null) {
-        _result["classOrMixinDeclaration_implementsClause"] =
-            classOrMixinDeclaration_implementsClause.toJson();
-      }
-      if (classOrMixinDeclaration_members.isNotEmpty) {
-        _result["classOrMixinDeclaration_members"] =
-            classOrMixinDeclaration_members
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (classOrMixinDeclaration_typeParameters != null) {
-        _result["classOrMixinDeclaration_typeParameters"] =
-            classOrMixinDeclaration_typeParameters.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (simplyBoundable_isSimplyBounded != false) {
-        _result["simplyBoundable_isSimplyBounded"] =
-            simplyBoundable_isSimplyBounded;
-      }
-      if (mixinDeclaration_superInvokedNames.isNotEmpty) {
-        _result["mixinDeclaration_superInvokedNames"] =
-            mixinDeclaration_superInvokedNames;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.namedExpression) {
-      if (namedExpression_expression != null) {
-        _result["namedExpression_expression"] =
-            namedExpression_expression.toJson();
-      }
-      if (namedExpression_name != null) {
-        _result["namedExpression_name"] = namedExpression_name.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.nativeClause) {
-      if (nativeClause_name != null) {
-        _result["nativeClause_name"] = nativeClause_name.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      if (nativeFunctionBody_stringLiteral != null) {
-        _result["nativeFunctionBody_stringLiteral"] =
-            nativeFunctionBody_stringLiteral.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.nullLiteral) {
-      if (nullLiteral_fake != 0) {
-        _result["nullLiteral_fake"] = nullLiteral_fake;
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.onClause) {
-      if (onClause_superclassConstraints.isNotEmpty) {
-        _result["onClause_superclassConstraints"] =
-            onClause_superclassConstraints
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      if (parenthesizedExpression_expression != null) {
-        _result["parenthesizedExpression_expression"] =
-            parenthesizedExpression_expression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (uriBasedDirective_uri != null) {
-        _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
-      }
-      if (uriBasedDirective_uriContent != '') {
-        _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
-      }
-      if (uriBasedDirective_uriElement != 0) {
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (partOfDirective_libraryName != null) {
-        _result["partOfDirective_libraryName"] =
-            partOfDirective_libraryName.toJson();
-      }
-      if (partOfDirective_uri != null) {
-        _result["partOfDirective_uri"] = partOfDirective_uri.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.postfixExpression) {
-      if (postfixExpression_operand != null) {
-        _result["postfixExpression_operand"] =
-            postfixExpression_operand.toJson();
-      }
-      if (postfixExpression_substitution != null) {
-        _result["postfixExpression_substitution"] =
-            postfixExpression_substitution.toJson();
-      }
-      if (postfixExpression_element != 0) {
-        _result["postfixExpression_element"] = postfixExpression_element;
-      }
-      if (postfixExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["postfixExpression_operator"] =
-            postfixExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.prefixExpression) {
-      if (prefixExpression_operand != null) {
-        _result["prefixExpression_operand"] = prefixExpression_operand.toJson();
-      }
-      if (prefixExpression_substitution != null) {
-        _result["prefixExpression_substitution"] =
-            prefixExpression_substitution.toJson();
-      }
-      if (prefixExpression_element != 0) {
-        _result["prefixExpression_element"] = prefixExpression_element;
-      }
-      if (prefixExpression_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["prefixExpression_operator"] =
-            prefixExpression_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      if (prefixedIdentifier_identifier != null) {
-        _result["prefixedIdentifier_identifier"] =
-            prefixedIdentifier_identifier.toJson();
-      }
-      if (prefixedIdentifier_prefix != null) {
-        _result["prefixedIdentifier_prefix"] =
-            prefixedIdentifier_prefix.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.propertyAccess) {
-      if (propertyAccess_propertyName != null) {
-        _result["propertyAccess_propertyName"] =
-            propertyAccess_propertyName.toJson();
-      }
-      if (propertyAccess_target != null) {
-        _result["propertyAccess_target"] = propertyAccess_target.toJson();
-      }
-      if (propertyAccess_operator != idl.UnlinkedTokenType.NOTHING) {
-        _result["propertyAccess_operator"] =
-            propertyAccess_operator.toString().split('.')[1];
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      if (redirectingConstructorInvocation_arguments != null) {
-        _result["redirectingConstructorInvocation_arguments"] =
-            redirectingConstructorInvocation_arguments.toJson();
-      }
-      if (redirectingConstructorInvocation_constructorName != null) {
-        _result["redirectingConstructorInvocation_constructorName"] =
-            redirectingConstructorInvocation_constructorName.toJson();
-      }
-      if (redirectingConstructorInvocation_substitution != null) {
-        _result["redirectingConstructorInvocation_substitution"] =
-            redirectingConstructorInvocation_substitution.toJson();
-      }
-      if (redirectingConstructorInvocation_element != 0) {
-        _result["redirectingConstructorInvocation_element"] =
-            redirectingConstructorInvocation_element;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.returnStatement) {
-      if (returnStatement_expression != null) {
-        _result["returnStatement_expression"] =
-            returnStatement_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      if (typedLiteral_typeArguments.isNotEmpty) {
-        _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-      if (setOrMapLiteral_elements.isNotEmpty) {
-        _result["setOrMapLiteral_elements"] =
-            setOrMapLiteral_elements.map((_value) => _value.toJson()).toList();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (names.isNotEmpty) {
-        _result["names"] = names;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (normalFormalParameter_metadata.isNotEmpty) {
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (simpleFormalParameter_type != null) {
-        _result["simpleFormalParameter_type"] =
-            simpleFormalParameter_type.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (topLevelTypeInferenceError != null) {
-        _result["topLevelTypeInferenceError"] =
-            topLevelTypeInferenceError.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      if (simpleIdentifier_substitution != null) {
-        _result["simpleIdentifier_substitution"] =
-            simpleIdentifier_substitution.toJson();
-      }
-      if (simpleIdentifier_element != 0) {
-        _result["simpleIdentifier_element"] = simpleIdentifier_element;
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      if (simpleStringLiteral_value != '') {
-        _result["simpleStringLiteral_value"] = simpleStringLiteral_value;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.spreadElement) {
-      if (spreadElement_expression != null) {
-        _result["spreadElement_expression"] = spreadElement_expression.toJson();
-      }
-      if (spreadElement_spreadOperator != idl.UnlinkedTokenType.NOTHING) {
-        _result["spreadElement_spreadOperator"] =
-            spreadElement_spreadOperator.toString().split('.')[1];
-      }
-    }
-    if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      if (stringInterpolation_elements.isNotEmpty) {
-        _result["stringInterpolation_elements"] = stringInterpolation_elements
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      if (superConstructorInvocation_arguments != null) {
-        _result["superConstructorInvocation_arguments"] =
-            superConstructorInvocation_arguments.toJson();
-      }
-      if (superConstructorInvocation_constructorName != null) {
-        _result["superConstructorInvocation_constructorName"] =
-            superConstructorInvocation_constructorName.toJson();
-      }
-      if (superConstructorInvocation_substitution != null) {
-        _result["superConstructorInvocation_substitution"] =
-            superConstructorInvocation_substitution.toJson();
-      }
-      if (superConstructorInvocation_element != 0) {
-        _result["superConstructorInvocation_element"] =
-            superConstructorInvocation_element;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.superExpression) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.switchCase) {
-      if (switchMember_statements.isNotEmpty) {
-        _result["switchMember_statements"] =
-            switchMember_statements.map((_value) => _value.toJson()).toList();
-      }
-      if (switchCase_expression != null) {
-        _result["switchCase_expression"] = switchCase_expression.toJson();
-      }
-      if (switchMember_labels.isNotEmpty) {
-        _result["switchMember_labels"] =
-            switchMember_labels.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.switchDefault) {
-      if (switchMember_statements.isNotEmpty) {
-        _result["switchMember_statements"] =
-            switchMember_statements.map((_value) => _value.toJson()).toList();
-      }
-      if (switchMember_labels.isNotEmpty) {
-        _result["switchMember_labels"] =
-            switchMember_labels.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.switchStatement) {
-      if (switchStatement_members.isNotEmpty) {
-        _result["switchStatement_members"] =
-            switchStatement_members.map((_value) => _value.toJson()).toList();
-      }
-      if (switchStatement_expression != null) {
-        _result["switchStatement_expression"] =
-            switchStatement_expression.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-      if (names.isNotEmpty) {
-        _result["names"] = names;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.thisExpression) {
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.throwExpression) {
-      if (throwExpression_expression != null) {
-        _result["throwExpression_expression"] =
-            throwExpression_expression.toJson();
-      }
-      if (expression_type != null) {
-        _result["expression_type"] = expression_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (topLevelVariableDeclaration_variableList != null) {
-        _result["topLevelVariableDeclaration_variableList"] =
-            topLevelVariableDeclaration_variableList.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.tryStatement) {
-      if (tryStatement_catchClauses.isNotEmpty) {
-        _result["tryStatement_catchClauses"] =
-            tryStatement_catchClauses.map((_value) => _value.toJson()).toList();
-      }
-      if (tryStatement_body != null) {
-        _result["tryStatement_body"] = tryStatement_body.toJson();
-      }
-      if (tryStatement_finallyBlock != null) {
-        _result["tryStatement_finallyBlock"] =
-            tryStatement_finallyBlock.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      if (typeArgumentList_arguments.isNotEmpty) {
-        _result["typeArgumentList_arguments"] = typeArgumentList_arguments
-            .map((_value) => _value.toJson())
-            .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeName) {
-      if (typeName_typeArguments.isNotEmpty) {
-        _result["typeName_typeArguments"] =
-            typeName_typeArguments.map((_value) => _value.toJson()).toList();
-      }
-      if (typeName_name != null) {
-        _result["typeName_name"] = typeName_name.toJson();
-      }
-      if (typeName_type != null) {
-        _result["typeName_type"] = typeName_type.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (typeParameter_bound != null) {
-        _result["typeParameter_bound"] = typeParameter_bound.toJson();
-      }
-      if (typeParameter_variance != 0) {
-        _result["typeParameter_variance"] = typeParameter_variance;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (typeParameter_defaultType != null) {
-        _result["typeParameter_defaultType"] =
-            typeParameter_defaultType.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeParameterList) {
-      if (typeParameterList_typeParameters.isNotEmpty) {
-        _result["typeParameterList_typeParameters"] =
-            typeParameterList_typeParameters
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      if (actualType != null) {
-        _result["actualType"] = actualType.toJson();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (variableDeclaration_initializer != null) {
-        _result["variableDeclaration_initializer"] =
-            variableDeclaration_initializer.toJson();
-      }
-      if (inheritsCovariant != false) {
-        _result["inheritsCovariant"] = inheritsCovariant;
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-      if (topLevelTypeInferenceError != null) {
-        _result["topLevelTypeInferenceError"] =
-            topLevelTypeInferenceError.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      if (variableDeclarationList_variables.isNotEmpty) {
-        _result["variableDeclarationList_variables"] =
-            variableDeclarationList_variables
-                .map((_value) => _value.toJson())
-                .toList();
-      }
-      if (annotatedNode_metadata.isNotEmpty) {
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      }
-      if (variableDeclarationList_type != null) {
-        _result["variableDeclarationList_type"] =
-            variableDeclarationList_type.toJson();
-      }
-      if (informativeId != 0) {
-        _result["informativeId"] = informativeId;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      if (variableDeclarationStatement_variables != null) {
-        _result["variableDeclarationStatement_variables"] =
-            variableDeclarationStatement_variables.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.whileStatement) {
-      if (whileStatement_body != null) {
-        _result["whileStatement_body"] = whileStatement_body.toJson();
-      }
-      if (whileStatement_condition != null) {
-        _result["whileStatement_condition"] = whileStatement_condition.toJson();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.withClause) {
-      if (withClause_mixinTypes.isNotEmpty) {
-        _result["withClause_mixinTypes"] =
-            withClause_mixinTypes.map((_value) => _value.toJson()).toList();
-      }
-    }
-    if (kind == idl.LinkedNodeKind.yieldStatement) {
-      if (yieldStatement_expression != null) {
-        _result["yieldStatement_expression"] =
-            yieldStatement_expression.toJson();
-      }
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() {
-    if (kind == idl.LinkedNodeKind.adjacentStrings) {
-      return {
-        "adjacentStrings_strings": adjacentStrings_strings,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.annotation) {
-      return {
-        "annotation_arguments": annotation_arguments,
-        "annotation_constructorName": annotation_constructorName,
-        "annotation_element": annotation_element,
-        "annotation_name": annotation_name,
-        "annotation_substitution": annotation_substitution,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.argumentList) {
-      return {
-        "argumentList_arguments": argumentList_arguments,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.asExpression) {
-      return {
-        "asExpression_expression": asExpression_expression,
-        "asExpression_type": asExpression_type,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.assertInitializer) {
-      return {
-        "assertInitializer_condition": assertInitializer_condition,
-        "assertInitializer_message": assertInitializer_message,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.assertStatement) {
-      return {
-        "assertStatement_condition": assertStatement_condition,
-        "assertStatement_message": assertStatement_message,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.assignmentExpression) {
-      return {
-        "assignmentExpression_leftHandSide": assignmentExpression_leftHandSide,
-        "assignmentExpression_rightHandSide":
-            assignmentExpression_rightHandSide,
-        "assignmentExpression_substitution": assignmentExpression_substitution,
-        "assignmentExpression_element": assignmentExpression_element,
-        "assignmentExpression_operator": assignmentExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.awaitExpression) {
-      return {
-        "awaitExpression_expression": awaitExpression_expression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.binaryExpression) {
-      return {
-        "binaryExpression_invokeType": binaryExpression_invokeType,
-        "binaryExpression_leftOperand": binaryExpression_leftOperand,
-        "binaryExpression_rightOperand": binaryExpression_rightOperand,
-        "binaryExpression_substitution": binaryExpression_substitution,
-        "binaryExpression_element": binaryExpression_element,
-        "binaryExpression_operator": binaryExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.block) {
-      return {
-        "block_statements": block_statements,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.blockFunctionBody) {
-      return {
-        "blockFunctionBody_block": blockFunctionBody_block,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      return {
-        "booleanLiteral_value": booleanLiteral_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.breakStatement) {
-      return {
-        "breakStatement_label": breakStatement_label,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.cascadeExpression) {
-      return {
-        "cascadeExpression_sections": cascadeExpression_sections,
-        "cascadeExpression_target": cascadeExpression_target,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.catchClause) {
-      return {
-        "catchClause_body": catchClause_body,
-        "catchClause_exceptionParameter": catchClause_exceptionParameter,
-        "catchClause_exceptionType": catchClause_exceptionType,
-        "catchClause_stackTraceParameter": catchClause_stackTraceParameter,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "classDeclaration_extendsClause": classDeclaration_extendsClause,
-        "classDeclaration_withClause": classDeclaration_withClause,
-        "classDeclaration_nativeClause": classDeclaration_nativeClause,
-        "classDeclaration_isDartObject": classDeclaration_isDartObject,
-        "classOrMixinDeclaration_implementsClause":
-            classOrMixinDeclaration_implementsClause,
-        "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
-        "classOrMixinDeclaration_typeParameters":
-            classOrMixinDeclaration_typeParameters,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-        "unused11": unused11,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "classTypeAlias_typeParameters": classTypeAlias_typeParameters,
-        "classTypeAlias_superclass": classTypeAlias_superclass,
-        "classTypeAlias_withClause": classTypeAlias_withClause,
-        "classTypeAlias_implementsClause": classTypeAlias_implementsClause,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.comment) {
-      return {
-        "comment_references": comment_references,
-        "comment_tokens": comment_tokens,
-        "comment_type": comment_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.commentReference) {
-      return {
-        "commentReference_identifier": commentReference_identifier,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      return {
-        "compilationUnit_declarations": compilationUnit_declarations,
-        "compilationUnit_scriptTag": compilationUnit_scriptTag,
-        "compilationUnit_directives": compilationUnit_directives,
-        "compilationUnit_featureSet": compilationUnit_featureSet,
-        "compilationUnit_languageVersion": compilationUnit_languageVersion,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.conditionalExpression) {
-      return {
-        "conditionalExpression_condition": conditionalExpression_condition,
-        "conditionalExpression_elseExpression":
-            conditionalExpression_elseExpression,
-        "conditionalExpression_thenExpression":
-            conditionalExpression_thenExpression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.configuration) {
-      return {
-        "configuration_name": configuration_name,
-        "configuration_value": configuration_value,
-        "configuration_uri": configuration_uri,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      return {
-        "constructorDeclaration_initializers":
-            constructorDeclaration_initializers,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "constructorDeclaration_body": constructorDeclaration_body,
-        "constructorDeclaration_parameters": constructorDeclaration_parameters,
-        "constructorDeclaration_redirectedConstructor":
-            constructorDeclaration_redirectedConstructor,
-        "constructorDeclaration_returnType": constructorDeclaration_returnType,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
-      return {
-        "constructorFieldInitializer_expression":
-            constructorFieldInitializer_expression,
-        "constructorFieldInitializer_fieldName":
-            constructorFieldInitializer_fieldName,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorName) {
-      return {
-        "constructorName_name": constructorName_name,
-        "constructorName_type": constructorName_type,
-        "constructorName_substitution": constructorName_substitution,
-        "constructorName_element": constructorName_element,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.continueStatement) {
-      return {
-        "continueStatement_label": continueStatement_label,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.declaredIdentifier) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "declaredIdentifier_identifier": declaredIdentifier_identifier,
-        "declaredIdentifier_type": declaredIdentifier_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      return {
-        "defaultFormalParameter_defaultValue":
-            defaultFormalParameter_defaultValue,
-        "defaultFormalParameter_parameter": defaultFormalParameter_parameter,
-        "defaultFormalParameter_kind": defaultFormalParameter_kind,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.doStatement) {
-      return {
-        "doStatement_body": doStatement_body,
-        "doStatement_condition": doStatement_condition,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.dottedName) {
-      return {
-        "dottedName_components": dottedName_components,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      return {
-        "doubleLiteral_value": doubleLiteral_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      return {
-        "emptyFunctionBody_fake": emptyFunctionBody_fake,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.emptyStatement) {
-      return {
-        "emptyStatement_fake": emptyStatement_fake,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      return {
-        "enumDeclaration_constants": enumDeclaration_constants,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      return {
-        "namespaceDirective_combinators": namespaceDirective_combinators,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "namespaceDirective_configurations": namespaceDirective_configurations,
-        "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
-        "flags": flags,
-        "informativeId": informativeId,
-        "uriBasedDirective_uri": uriBasedDirective_uri,
-        "kind": kind,
-        "name": name,
-        "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
-      return {
-        "expressionFunctionBody_expression": expressionFunctionBody_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.expressionStatement) {
-      return {
-        "expressionStatement_expression": expressionStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extendsClause) {
-      return {
-        "extendsClause_superclass": extendsClause_superclass,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "extensionDeclaration_typeParameters":
-            extensionDeclaration_typeParameters,
-        "extensionDeclaration_extendedType": extensionDeclaration_extendedType,
-        "extensionDeclaration_members": extensionDeclaration_members,
-        "extensionDeclaration_refName": extensionDeclaration_refName,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extensionOverride) {
-      return {
-        "extensionOverride_extendedType": extensionOverride_extendedType,
-        "extensionOverride_arguments": extensionOverride_arguments,
-        "extensionOverride_extensionName": extensionOverride_extensionName,
-        "extensionOverride_typeArguments": extensionOverride_typeArguments,
-        "extensionOverride_typeArgumentTypes":
-            extensionOverride_typeArgumentTypes,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "fieldDeclaration_fields": fieldDeclaration_fields,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      return {
-        "actualType": actualType,
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "fieldFormalParameter_type": fieldFormalParameter_type,
-        "fieldFormalParameter_typeParameters":
-            fieldFormalParameter_typeParameters,
-        "fieldFormalParameter_formalParameters":
-            fieldFormalParameter_formalParameters,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
-      return {
-        "forEachParts_iterable": forEachParts_iterable,
-        "forEachPartsWithDeclaration_loopVariable":
-            forEachPartsWithDeclaration_loopVariable,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
-      return {
-        "forEachParts_iterable": forEachParts_iterable,
-        "forEachPartsWithIdentifier_identifier":
-            forEachPartsWithIdentifier_identifier,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forElement) {
-      return {
-        "forMixin_forLoopParts": forMixin_forLoopParts,
-        "forElement_body": forElement_body,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
-      return {
-        "forParts_condition": forParts_condition,
-        "forPartsWithDeclarations_variables":
-            forPartsWithDeclarations_variables,
-        "forParts_updaters": forParts_updaters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
-      return {
-        "forParts_condition": forParts_condition,
-        "forPartsWithExpression_initialization":
-            forPartsWithExpression_initialization,
-        "forParts_updaters": forParts_updaters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.forStatement) {
-      return {
-        "forMixin_forLoopParts": forMixin_forLoopParts,
-        "forStatement_body": forStatement_body,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.formalParameterList) {
-      return {
-        "formalParameterList_parameters": formalParameterList_parameters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      return {
-        "actualReturnType": actualReturnType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "functionDeclaration_functionExpression":
-            functionDeclaration_functionExpression,
-        "functionDeclaration_returnType": functionDeclaration_returnType,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
-      return {
-        "functionDeclarationStatement_functionDeclaration":
-            functionDeclarationStatement_functionDeclaration,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionExpression) {
-      return {
-        "actualReturnType": actualReturnType,
-        "functionExpression_body": functionExpression_body,
-        "functionExpression_formalParameters":
-            functionExpression_formalParameters,
-        "functionExpression_typeParameters": functionExpression_typeParameters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      return {
-        "invocationExpression_invokeType": invocationExpression_invokeType,
-        "functionExpressionInvocation_function":
-            functionExpressionInvocation_function,
-        "invocationExpression_typeArguments":
-            invocationExpression_typeArguments,
-        "expression_type": expression_type,
-        "flags": flags,
-        "invocationExpression_arguments": invocationExpression_arguments,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      return {
-        "actualReturnType": actualReturnType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "functionTypeAlias_formalParameters":
-            functionTypeAlias_formalParameters,
-        "functionTypeAlias_returnType": functionTypeAlias_returnType,
-        "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
-        "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      return {
-        "actualType": actualType,
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "functionTypedFormalParameter_formalParameters":
-            functionTypedFormalParameter_formalParameters,
-        "functionTypedFormalParameter_returnType":
-            functionTypedFormalParameter_returnType,
-        "functionTypedFormalParameter_typeParameters":
-            functionTypedFormalParameter_typeParameters,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      return {
-        "actualReturnType": actualReturnType,
-        "genericFunctionType_typeParameters":
-            genericFunctionType_typeParameters,
-        "genericFunctionType_returnType": genericFunctionType_returnType,
-        "genericFunctionType_id": genericFunctionType_id,
-        "genericFunctionType_formalParameters":
-            genericFunctionType_formalParameters,
-        "genericFunctionType_type": genericFunctionType_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "genericTypeAlias_typeParameters": genericTypeAlias_typeParameters,
-        "genericTypeAlias_functionType": genericTypeAlias_functionType,
-        "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      return {
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "names": names,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.ifElement) {
-      return {
-        "ifMixin_condition": ifMixin_condition,
-        "ifElement_thenElement": ifElement_thenElement,
-        "ifElement_elseElement": ifElement_elseElement,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.ifStatement) {
-      return {
-        "ifMixin_condition": ifMixin_condition,
-        "ifStatement_elseStatement": ifStatement_elseStatement,
-        "ifStatement_thenStatement": ifStatement_thenStatement,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.implementsClause) {
-      return {
-        "implementsClause_interfaces": implementsClause_interfaces,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      return {
-        "namespaceDirective_combinators": namespaceDirective_combinators,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "namespaceDirective_configurations": namespaceDirective_configurations,
-        "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
-        "flags": flags,
-        "importDirective_prefix": importDirective_prefix,
-        "informativeId": informativeId,
-        "uriBasedDirective_uri": uriBasedDirective_uri,
-        "kind": kind,
-        "name": name,
-        "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.indexExpression) {
-      return {
-        "indexExpression_index": indexExpression_index,
-        "indexExpression_target": indexExpression_target,
-        "indexExpression_substitution": indexExpression_substitution,
-        "indexExpression_element": indexExpression_element,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      return {
-        "instanceCreationExpression_arguments":
-            instanceCreationExpression_arguments,
-        "instanceCreationExpression_constructorName":
-            instanceCreationExpression_constructorName,
-        "instanceCreationExpression_typeArguments":
-            instanceCreationExpression_typeArguments,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.integerLiteral) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "integerLiteral_value": integerLiteral_value,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.interpolationExpression) {
-      return {
-        "interpolationExpression_expression":
-            interpolationExpression_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.interpolationString) {
-      return {
-        "flags": flags,
-        "interpolationString_value": interpolationString_value,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.isExpression) {
-      return {
-        "isExpression_expression": isExpression_expression,
-        "isExpression_type": isExpression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.label) {
-      return {
-        "label_label": label_label,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.labeledStatement) {
-      return {
-        "labeledStatement_labels": labeledStatement_labels,
-        "labeledStatement_statement": labeledStatement_statement,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "libraryDirective_name": libraryDirective_name,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.libraryIdentifier) {
-      return {
-        "libraryIdentifier_components": libraryIdentifier_components,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.listLiteral) {
-      return {
-        "typedLiteral_typeArguments": typedLiteral_typeArguments,
-        "listLiteral_elements": listLiteral_elements,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
-      return {
-        "mapLiteralEntry_key": mapLiteralEntry_key,
-        "mapLiteralEntry_value": mapLiteralEntry_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      return {
-        "actualReturnType": actualReturnType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "methodDeclaration_body": methodDeclaration_body,
-        "methodDeclaration_formalParameters":
-            methodDeclaration_formalParameters,
-        "methodDeclaration_returnType": methodDeclaration_returnType,
-        "methodDeclaration_typeParameters": methodDeclaration_typeParameters,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "methodDeclaration_hasOperatorEqualWithParameterTypeFromObject":
-            methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
-        "name": name,
-        "topLevelTypeInferenceError": topLevelTypeInferenceError,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.methodInvocation) {
-      return {
-        "invocationExpression_invokeType": invocationExpression_invokeType,
-        "methodInvocation_methodName": methodInvocation_methodName,
-        "methodInvocation_target": methodInvocation_target,
-        "invocationExpression_typeArguments":
-            invocationExpression_typeArguments,
-        "expression_type": expression_type,
-        "flags": flags,
-        "invocationExpression_arguments": invocationExpression_arguments,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "mixinDeclaration_onClause": mixinDeclaration_onClause,
-        "classOrMixinDeclaration_implementsClause":
-            classOrMixinDeclaration_implementsClause,
-        "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
-        "classOrMixinDeclaration_typeParameters":
-            classOrMixinDeclaration_typeParameters,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
-        "mixinDeclaration_superInvokedNames":
-            mixinDeclaration_superInvokedNames,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.namedExpression) {
-      return {
-        "namedExpression_expression": namedExpression_expression,
-        "namedExpression_name": namedExpression_name,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nativeClause) {
-      return {
-        "nativeClause_name": nativeClause_name,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
-      return {
-        "nativeFunctionBody_stringLiteral": nativeFunctionBody_stringLiteral,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nullLiteral) {
-      return {
-        "nullLiteral_fake": nullLiteral_fake,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.onClause) {
-      return {
-        "onClause_superclassConstraints": onClause_superclassConstraints,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
-      return {
-        "parenthesizedExpression_expression":
-            parenthesizedExpression_expression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "flags": flags,
-        "informativeId": informativeId,
-        "uriBasedDirective_uri": uriBasedDirective_uri,
-        "kind": kind,
-        "name": name,
-        "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "partOfDirective_libraryName": partOfDirective_libraryName,
-        "partOfDirective_uri": partOfDirective_uri,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.postfixExpression) {
-      return {
-        "postfixExpression_operand": postfixExpression_operand,
-        "postfixExpression_substitution": postfixExpression_substitution,
-        "postfixExpression_element": postfixExpression_element,
-        "postfixExpression_operator": postfixExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.prefixExpression) {
-      return {
-        "prefixExpression_operand": prefixExpression_operand,
-        "prefixExpression_substitution": prefixExpression_substitution,
-        "prefixExpression_element": prefixExpression_element,
-        "prefixExpression_operator": prefixExpression_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
-      return {
-        "prefixedIdentifier_identifier": prefixedIdentifier_identifier,
-        "prefixedIdentifier_prefix": prefixedIdentifier_prefix,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.propertyAccess) {
-      return {
-        "propertyAccess_propertyName": propertyAccess_propertyName,
-        "propertyAccess_target": propertyAccess_target,
-        "propertyAccess_operator": propertyAccess_operator,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
-      return {
-        "redirectingConstructorInvocation_arguments":
-            redirectingConstructorInvocation_arguments,
-        "redirectingConstructorInvocation_constructorName":
-            redirectingConstructorInvocation_constructorName,
-        "redirectingConstructorInvocation_substitution":
-            redirectingConstructorInvocation_substitution,
-        "redirectingConstructorInvocation_element":
-            redirectingConstructorInvocation_element,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.returnStatement) {
-      return {
-        "returnStatement_expression": returnStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      return {
-        "typedLiteral_typeArguments": typedLiteral_typeArguments,
-        "setOrMapLiteral_elements": setOrMapLiteral_elements,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      return {
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "names": names,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      return {
-        "actualType": actualType,
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "simpleFormalParameter_type": simpleFormalParameter_type,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-        "topLevelTypeInferenceError": topLevelTypeInferenceError,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      return {
-        "simpleIdentifier_substitution": simpleIdentifier_substitution,
-        "simpleIdentifier_element": simpleIdentifier_element,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      return {
-        "simpleStringLiteral_value": simpleStringLiteral_value,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.spreadElement) {
-      return {
-        "spreadElement_expression": spreadElement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-        "spreadElement_spreadOperator": spreadElement_spreadOperator,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.stringInterpolation) {
-      return {
-        "stringInterpolation_elements": stringInterpolation_elements,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
-      return {
-        "superConstructorInvocation_arguments":
-            superConstructorInvocation_arguments,
-        "superConstructorInvocation_constructorName":
-            superConstructorInvocation_constructorName,
-        "superConstructorInvocation_substitution":
-            superConstructorInvocation_substitution,
-        "superConstructorInvocation_element":
-            superConstructorInvocation_element,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.superExpression) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.switchCase) {
-      return {
-        "switchMember_statements": switchMember_statements,
-        "switchCase_expression": switchCase_expression,
-        "switchMember_labels": switchMember_labels,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.switchDefault) {
-      return {
-        "switchMember_statements": switchMember_statements,
-        "switchMember_labels": switchMember_labels,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.switchStatement) {
-      return {
-        "switchStatement_members": switchStatement_members,
-        "switchStatement_expression": switchStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "names": names,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.thisExpression) {
-      return {
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.throwExpression) {
-      return {
-        "throwExpression_expression": throwExpression_expression,
-        "expression_type": expression_type,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "topLevelVariableDeclaration_variableList":
-            topLevelVariableDeclaration_variableList,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.tryStatement) {
-      return {
-        "tryStatement_catchClauses": tryStatement_catchClauses,
-        "tryStatement_body": tryStatement_body,
-        "tryStatement_finallyBlock": tryStatement_finallyBlock,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeArgumentList) {
-      return {
-        "typeArgumentList_arguments": typeArgumentList_arguments,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeName) {
-      return {
-        "typeName_typeArguments": typeName_typeArguments,
-        "typeName_name": typeName_name,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-        "typeName_type": typeName_type,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      return {
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "typeParameter_bound": typeParameter_bound,
-        "typeParameter_variance": typeParameter_variance,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-        "typeParameter_defaultType": typeParameter_defaultType,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeParameterList) {
-      return {
-        "typeParameterList_typeParameters": typeParameterList_typeParameters,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      return {
-        "actualType": actualType,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "variableDeclaration_initializer": variableDeclaration_initializer,
-        "inheritsCovariant": inheritsCovariant,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-        "topLevelTypeInferenceError": topLevelTypeInferenceError,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationList) {
-      return {
-        "variableDeclarationList_variables": variableDeclarationList_variables,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "variableDeclarationList_type": variableDeclarationList_type,
-        "flags": flags,
-        "informativeId": informativeId,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
-      return {
-        "variableDeclarationStatement_variables":
-            variableDeclarationStatement_variables,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.whileStatement) {
-      return {
-        "whileStatement_body": whileStatement_body,
-        "whileStatement_condition": whileStatement_condition,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.withClause) {
-      return {
-        "withClause_mixinTypes": withClause_mixinTypes,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.yieldStatement) {
-      return {
-        "yieldStatement_expression": yieldStatement_expression,
-        "flags": flags,
-        "kind": kind,
-        "name": name,
-      };
-    }
-    throw StateError("Unexpected $kind");
-  }
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeBundleBuilder extends Object
-    with _LinkedNodeBundleMixin
-    implements idl.LinkedNodeBundle {
-  List<LinkedNodeLibraryBuilder> _libraries;
-  LinkedNodeReferencesBuilder _references;
-
-  @override
-  List<LinkedNodeLibraryBuilder> get libraries =>
-      _libraries ??= <LinkedNodeLibraryBuilder>[];
-
-  set libraries(List<LinkedNodeLibraryBuilder> value) {
-    this._libraries = value;
-  }
-
-  @override
-  LinkedNodeReferencesBuilder get references => _references;
-
-  /// The shared list of references used in the [libraries].
-  set references(LinkedNodeReferencesBuilder value) {
-    this._references = value;
-  }
-
-  LinkedNodeBundleBuilder(
-      {List<LinkedNodeLibraryBuilder> libraries,
-      LinkedNodeReferencesBuilder references})
-      : _libraries = libraries,
-        _references = references;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _libraries?.forEach((b) => b.flushInformative());
-    _references?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addBool(this._references != null);
-    this._references?.collectApiSignature(signature);
-    if (this._libraries == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._libraries.length);
-      for (var x in this._libraries) {
-        x?.collectApiSignature(signature);
-      }
-    }
-  }
-
-  List<int> toBuffer() {
-    fb.Builder fbBuilder = fb.Builder();
-    return fbBuilder.finish(finish(fbBuilder), "LNBn");
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_libraries;
-    fb.Offset offset_references;
-    if (!(_libraries == null || _libraries.isEmpty)) {
-      offset_libraries = fbBuilder
-          .writeList(_libraries.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_references != null) {
-      offset_references = _references.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_libraries != null) {
-      fbBuilder.addOffset(1, offset_libraries);
-    }
-    if (offset_references != null) {
-      fbBuilder.addOffset(0, offset_references);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-idl.LinkedNodeBundle readLinkedNodeBundle(List<int> buffer) {
-  fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
-  return const _LinkedNodeBundleReader().read(rootRef, 0);
-}
-
-class _LinkedNodeBundleReader extends fb.TableReader<_LinkedNodeBundleImpl> {
-  const _LinkedNodeBundleReader();
-
-  @override
-  _LinkedNodeBundleImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeBundleImpl(bc, offset);
-}
-
-class _LinkedNodeBundleImpl extends Object
-    with _LinkedNodeBundleMixin
-    implements idl.LinkedNodeBundle {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeBundleImpl(this._bc, this._bcOffset);
-
-  List<idl.LinkedNodeLibrary> _libraries;
-  idl.LinkedNodeReferences _references;
-
-  @override
-  List<idl.LinkedNodeLibrary> get libraries {
-    _libraries ??=
-        const fb.ListReader<idl.LinkedNodeLibrary>(_LinkedNodeLibraryReader())
-            .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeLibrary>[]);
-    return _libraries;
-  }
-
-  @override
-  idl.LinkedNodeReferences get references {
-    _references ??=
-        const _LinkedNodeReferencesReader().vTableGet(_bc, _bcOffset, 0, null);
-    return _references;
-  }
-}
-
-abstract class _LinkedNodeBundleMixin implements idl.LinkedNodeBundle {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (libraries.isNotEmpty) {
-      _result["libraries"] =
-          libraries.map((_value) => _value.toJson()).toList();
-    }
-    if (references != null) {
-      _result["references"] = references.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "libraries": libraries,
-        "references": references,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeLibraryBuilder extends Object
-    with _LinkedNodeLibraryMixin
-    implements idl.LinkedNodeLibrary {
-  List<int> _exports;
-  String _name;
-  int _nameLength;
-  int _nameOffset;
-  List<LinkedNodeUnitBuilder> _units;
-  String _uriStr;
-
-  @override
-  List<int> get exports => _exports ??= <int>[];
-
-  set exports(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._exports = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  @override
-  int get nameLength => _nameLength ??= 0;
-
-  set nameLength(int value) {
-    assert(value == null || value >= 0);
-    this._nameLength = value;
-  }
-
-  @override
-  int get nameOffset => _nameOffset ??= 0;
-
-  set nameOffset(int value) {
-    assert(value == null || value >= 0);
-    this._nameOffset = value;
-  }
-
-  @override
-  List<LinkedNodeUnitBuilder> get units => _units ??= <LinkedNodeUnitBuilder>[];
-
-  set units(List<LinkedNodeUnitBuilder> value) {
-    this._units = value;
-  }
-
-  @override
-  String get uriStr => _uriStr ??= '';
-
-  set uriStr(String value) {
-    this._uriStr = value;
-  }
-
-  LinkedNodeLibraryBuilder(
-      {List<int> exports,
-      String name,
-      int nameLength,
-      int nameOffset,
-      List<LinkedNodeUnitBuilder> units,
-      String uriStr})
-      : _exports = exports,
-        _name = name,
-        _nameLength = nameLength,
-        _nameOffset = nameOffset,
-        _units = units,
-        _uriStr = uriStr;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _units?.forEach((b) => b.flushInformative());
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._uriStr ?? '');
-    if (this._units == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._units.length);
-      for (var x in this._units) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    if (this._exports == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._exports.length);
-      for (var x in this._exports) {
-        signature.addInt(x);
-      }
-    }
-    signature.addString(this._name ?? '');
-    signature.addInt(this._nameOffset ?? 0);
-    signature.addInt(this._nameLength ?? 0);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_exports;
-    fb.Offset offset_name;
-    fb.Offset offset_units;
-    fb.Offset offset_uriStr;
-    if (!(_exports == null || _exports.isEmpty)) {
-      offset_exports = fbBuilder.writeListUint32(_exports);
-    }
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    if (!(_units == null || _units.isEmpty)) {
-      offset_units =
-          fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_uriStr != null) {
-      offset_uriStr = fbBuilder.writeString(_uriStr);
-    }
-    fbBuilder.startTable();
-    if (offset_exports != null) {
-      fbBuilder.addOffset(2, offset_exports);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(3, offset_name);
-    }
-    if (_nameLength != null && _nameLength != 0) {
-      fbBuilder.addUint32(5, _nameLength);
-    }
-    if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addUint32(4, _nameOffset);
-    }
-    if (offset_units != null) {
-      fbBuilder.addOffset(1, offset_units);
-    }
-    if (offset_uriStr != null) {
-      fbBuilder.addOffset(0, offset_uriStr);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeLibraryReader extends fb.TableReader<_LinkedNodeLibraryImpl> {
-  const _LinkedNodeLibraryReader();
-
-  @override
-  _LinkedNodeLibraryImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeLibraryImpl(bc, offset);
-}
-
-class _LinkedNodeLibraryImpl extends Object
-    with _LinkedNodeLibraryMixin
-    implements idl.LinkedNodeLibrary {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeLibraryImpl(this._bc, this._bcOffset);
-
-  List<int> _exports;
-  String _name;
-  int _nameLength;
-  int _nameOffset;
-  List<idl.LinkedNodeUnit> _units;
-  String _uriStr;
-
-  @override
-  List<int> get exports {
-    _exports ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
-    return _exports;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
-    return _name;
-  }
-
-  @override
-  int get nameLength {
-    _nameLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
-    return _nameLength;
-  }
-
-  @override
-  int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
-    return _nameOffset;
-  }
-
-  @override
-  List<idl.LinkedNodeUnit> get units {
-    _units ??= const fb.ListReader<idl.LinkedNodeUnit>(_LinkedNodeUnitReader())
-        .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeUnit>[]);
-    return _units;
-  }
-
-  @override
-  String get uriStr {
-    _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _uriStr;
-  }
-}
-
-abstract class _LinkedNodeLibraryMixin implements idl.LinkedNodeLibrary {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (exports.isNotEmpty) {
-      _result["exports"] = exports;
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    if (nameLength != 0) {
-      _result["nameLength"] = nameLength;
-    }
-    if (nameOffset != 0) {
-      _result["nameOffset"] = nameOffset;
-    }
-    if (units.isNotEmpty) {
-      _result["units"] = units.map((_value) => _value.toJson()).toList();
-    }
-    if (uriStr != '') {
-      _result["uriStr"] = uriStr;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "exports": exports,
-        "name": name,
-        "nameLength": nameLength,
-        "nameOffset": nameOffset,
-        "units": units,
-        "uriStr": uriStr,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeReferencesBuilder extends Object
-    with _LinkedNodeReferencesMixin
-    implements idl.LinkedNodeReferences {
-  List<String> _name;
-  List<int> _parent;
-
-  @override
-  List<String> get name => _name ??= <String>[];
-
-  set name(List<String> value) {
-    this._name = value;
-  }
-
-  @override
-  List<int> get parent => _parent ??= <int>[];
-
-  set parent(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._parent = value;
-  }
-
-  LinkedNodeReferencesBuilder({List<String> name, List<int> parent})
-      : _name = name,
-        _parent = parent;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {}
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._parent == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._parent.length);
-      for (var x in this._parent) {
-        signature.addInt(x);
-      }
-    }
-    if (this._name == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._name.length);
-      for (var x in this._name) {
-        signature.addString(x);
-      }
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_name;
-    fb.Offset offset_parent;
-    if (!(_name == null || _name.isEmpty)) {
-      offset_name = fbBuilder
-          .writeList(_name.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    if (!(_parent == null || _parent.isEmpty)) {
-      offset_parent = fbBuilder.writeListUint32(_parent);
-    }
-    fbBuilder.startTable();
-    if (offset_name != null) {
-      fbBuilder.addOffset(1, offset_name);
-    }
-    if (offset_parent != null) {
-      fbBuilder.addOffset(0, offset_parent);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeReferencesReader
-    extends fb.TableReader<_LinkedNodeReferencesImpl> {
-  const _LinkedNodeReferencesReader();
-
-  @override
-  _LinkedNodeReferencesImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeReferencesImpl(bc, offset);
-}
-
-class _LinkedNodeReferencesImpl extends Object
-    with _LinkedNodeReferencesMixin
-    implements idl.LinkedNodeReferences {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeReferencesImpl(this._bc, this._bcOffset);
-
-  List<String> _name;
-  List<int> _parent;
-
-  @override
-  List<String> get name {
-    _name ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 1, const <String>[]);
-    return _name;
-  }
-
-  @override
-  List<int> get parent {
-    _parent ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
-    return _parent;
-  }
-}
-
-abstract class _LinkedNodeReferencesMixin implements idl.LinkedNodeReferences {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (name.isNotEmpty) {
-      _result["name"] = name;
-    }
-    if (parent.isNotEmpty) {
-      _result["parent"] = parent;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "name": name,
-        "parent": parent,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeBuilder extends Object
-    with _LinkedNodeTypeMixin
-    implements idl.LinkedNodeType {
-  List<LinkedNodeTypeFormalParameterBuilder> _functionFormalParameters;
-  LinkedNodeTypeBuilder _functionReturnType;
-  int _functionTypedef;
-  List<LinkedNodeTypeBuilder> _functionTypedefTypeArguments;
-  List<LinkedNodeTypeTypeParameterBuilder> _functionTypeParameters;
-  int _interfaceClass;
-  List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
-  idl.LinkedNodeTypeKind _kind;
-  idl.EntityRefNullabilitySuffix _nullabilitySuffix;
-  int _typeParameterElement;
-  int _typeParameterId;
-
-  @override
-  List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
-      _functionFormalParameters ??= <LinkedNodeTypeFormalParameterBuilder>[];
-
-  set functionFormalParameters(
-      List<LinkedNodeTypeFormalParameterBuilder> value) {
-    this._functionFormalParameters = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionReturnType => _functionReturnType;
-
-  set functionReturnType(LinkedNodeTypeBuilder value) {
-    this._functionReturnType = value;
-  }
-
-  @override
-  int get functionTypedef => _functionTypedef ??= 0;
-
-  /// The typedef this function type is created for.
-  set functionTypedef(int value) {
-    assert(value == null || value >= 0);
-    this._functionTypedef = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get functionTypedefTypeArguments =>
-      _functionTypedefTypeArguments ??= <LinkedNodeTypeBuilder>[];
-
-  set functionTypedefTypeArguments(List<LinkedNodeTypeBuilder> value) {
-    this._functionTypedefTypeArguments = value;
-  }
-
-  @override
-  List<LinkedNodeTypeTypeParameterBuilder> get functionTypeParameters =>
-      _functionTypeParameters ??= <LinkedNodeTypeTypeParameterBuilder>[];
-
-  set functionTypeParameters(List<LinkedNodeTypeTypeParameterBuilder> value) {
-    this._functionTypeParameters = value;
-  }
-
-  @override
-  int get interfaceClass => _interfaceClass ??= 0;
-
-  /// Reference to a [LinkedNodeReferences].
-  set interfaceClass(int value) {
-    assert(value == null || value >= 0);
-    this._interfaceClass = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get interfaceTypeArguments =>
-      _interfaceTypeArguments ??= <LinkedNodeTypeBuilder>[];
-
-  set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) {
-    this._interfaceTypeArguments = value;
-  }
-
-  @override
-  idl.LinkedNodeTypeKind get kind => _kind ??= idl.LinkedNodeTypeKind.dynamic_;
-
-  set kind(idl.LinkedNodeTypeKind value) {
-    this._kind = value;
-  }
-
-  @override
-  idl.EntityRefNullabilitySuffix get nullabilitySuffix =>
-      _nullabilitySuffix ??= idl.EntityRefNullabilitySuffix.starOrIrrelevant;
-
-  set nullabilitySuffix(idl.EntityRefNullabilitySuffix value) {
-    this._nullabilitySuffix = value;
-  }
-
-  @override
-  int get typeParameterElement => _typeParameterElement ??= 0;
-
-  set typeParameterElement(int value) {
-    assert(value == null || value >= 0);
-    this._typeParameterElement = value;
-  }
-
-  @override
-  int get typeParameterId => _typeParameterId ??= 0;
-
-  set typeParameterId(int value) {
-    assert(value == null || value >= 0);
-    this._typeParameterId = value;
-  }
-
-  LinkedNodeTypeBuilder(
-      {List<LinkedNodeTypeFormalParameterBuilder> functionFormalParameters,
-      LinkedNodeTypeBuilder functionReturnType,
-      int functionTypedef,
-      List<LinkedNodeTypeBuilder> functionTypedefTypeArguments,
-      List<LinkedNodeTypeTypeParameterBuilder> functionTypeParameters,
-      int interfaceClass,
-      List<LinkedNodeTypeBuilder> interfaceTypeArguments,
-      idl.LinkedNodeTypeKind kind,
-      idl.EntityRefNullabilitySuffix nullabilitySuffix,
-      int typeParameterElement,
-      int typeParameterId})
-      : _functionFormalParameters = functionFormalParameters,
-        _functionReturnType = functionReturnType,
-        _functionTypedef = functionTypedef,
-        _functionTypedefTypeArguments = functionTypedefTypeArguments,
-        _functionTypeParameters = functionTypeParameters,
-        _interfaceClass = interfaceClass,
-        _interfaceTypeArguments = interfaceTypeArguments,
-        _kind = kind,
-        _nullabilitySuffix = nullabilitySuffix,
-        _typeParameterElement = typeParameterElement,
-        _typeParameterId = typeParameterId;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _functionFormalParameters?.forEach((b) => b.flushInformative());
-    _functionReturnType?.flushInformative();
-    _functionTypedefTypeArguments?.forEach((b) => b.flushInformative());
-    _functionTypeParameters?.forEach((b) => b.flushInformative());
-    _interfaceTypeArguments?.forEach((b) => b.flushInformative());
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._functionFormalParameters == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._functionFormalParameters.length);
-      for (var x in this._functionFormalParameters) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addBool(this._functionReturnType != null);
-    this._functionReturnType?.collectApiSignature(signature);
-    if (this._functionTypeParameters == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._functionTypeParameters.length);
-      for (var x in this._functionTypeParameters) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addInt(this._interfaceClass ?? 0);
-    if (this._interfaceTypeArguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._interfaceTypeArguments.length);
-      for (var x in this._interfaceTypeArguments) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addInt(this._kind == null ? 0 : this._kind.index);
-    signature.addInt(this._typeParameterElement ?? 0);
-    signature.addInt(this._typeParameterId ?? 0);
-    signature.addInt(
-        this._nullabilitySuffix == null ? 0 : this._nullabilitySuffix.index);
-    signature.addInt(this._functionTypedef ?? 0);
-    if (this._functionTypedefTypeArguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._functionTypedefTypeArguments.length);
-      for (var x in this._functionTypedefTypeArguments) {
-        x?.collectApiSignature(signature);
-      }
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_functionFormalParameters;
-    fb.Offset offset_functionReturnType;
-    fb.Offset offset_functionTypedefTypeArguments;
-    fb.Offset offset_functionTypeParameters;
-    fb.Offset offset_interfaceTypeArguments;
-    if (!(_functionFormalParameters == null ||
-        _functionFormalParameters.isEmpty)) {
-      offset_functionFormalParameters = fbBuilder.writeList(
-          _functionFormalParameters.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (_functionReturnType != null) {
-      offset_functionReturnType = _functionReturnType.finish(fbBuilder);
-    }
-    if (!(_functionTypedefTypeArguments == null ||
-        _functionTypedefTypeArguments.isEmpty)) {
-      offset_functionTypedefTypeArguments = fbBuilder.writeList(
-          _functionTypedefTypeArguments
-              .map((b) => b.finish(fbBuilder))
-              .toList());
-    }
-    if (!(_functionTypeParameters == null || _functionTypeParameters.isEmpty)) {
-      offset_functionTypeParameters = fbBuilder.writeList(
-          _functionTypeParameters.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_interfaceTypeArguments == null || _interfaceTypeArguments.isEmpty)) {
-      offset_interfaceTypeArguments = fbBuilder.writeList(
-          _interfaceTypeArguments.map((b) => b.finish(fbBuilder)).toList());
-    }
-    fbBuilder.startTable();
-    if (offset_functionFormalParameters != null) {
-      fbBuilder.addOffset(0, offset_functionFormalParameters);
-    }
-    if (offset_functionReturnType != null) {
-      fbBuilder.addOffset(1, offset_functionReturnType);
-    }
-    if (_functionTypedef != null && _functionTypedef != 0) {
-      fbBuilder.addUint32(9, _functionTypedef);
-    }
-    if (offset_functionTypedefTypeArguments != null) {
-      fbBuilder.addOffset(10, offset_functionTypedefTypeArguments);
-    }
-    if (offset_functionTypeParameters != null) {
-      fbBuilder.addOffset(2, offset_functionTypeParameters);
-    }
-    if (_interfaceClass != null && _interfaceClass != 0) {
-      fbBuilder.addUint32(3, _interfaceClass);
-    }
-    if (offset_interfaceTypeArguments != null) {
-      fbBuilder.addOffset(4, offset_interfaceTypeArguments);
-    }
-    if (_kind != null && _kind != idl.LinkedNodeTypeKind.dynamic_) {
-      fbBuilder.addUint8(5, _kind.index);
-    }
-    if (_nullabilitySuffix != null &&
-        _nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
-      fbBuilder.addUint8(8, _nullabilitySuffix.index);
-    }
-    if (_typeParameterElement != null && _typeParameterElement != 0) {
-      fbBuilder.addUint32(6, _typeParameterElement);
-    }
-    if (_typeParameterId != null && _typeParameterId != 0) {
-      fbBuilder.addUint32(7, _typeParameterId);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeReader extends fb.TableReader<_LinkedNodeTypeImpl> {
-  const _LinkedNodeTypeReader();
-
-  @override
-  _LinkedNodeTypeImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeImpl(bc, offset);
-}
-
-class _LinkedNodeTypeImpl extends Object
-    with _LinkedNodeTypeMixin
-    implements idl.LinkedNodeType {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeImpl(this._bc, this._bcOffset);
-
-  List<idl.LinkedNodeTypeFormalParameter> _functionFormalParameters;
-  idl.LinkedNodeType _functionReturnType;
-  int _functionTypedef;
-  List<idl.LinkedNodeType> _functionTypedefTypeArguments;
-  List<idl.LinkedNodeTypeTypeParameter> _functionTypeParameters;
-  int _interfaceClass;
-  List<idl.LinkedNodeType> _interfaceTypeArguments;
-  idl.LinkedNodeTypeKind _kind;
-  idl.EntityRefNullabilitySuffix _nullabilitySuffix;
-  int _typeParameterElement;
-  int _typeParameterId;
-
-  @override
-  List<idl.LinkedNodeTypeFormalParameter> get functionFormalParameters {
-    _functionFormalParameters ??=
-        const fb.ListReader<idl.LinkedNodeTypeFormalParameter>(
-                _LinkedNodeTypeFormalParameterReader())
-            .vTableGet(
-                _bc, _bcOffset, 0, const <idl.LinkedNodeTypeFormalParameter>[]);
-    return _functionFormalParameters;
-  }
-
-  @override
-  idl.LinkedNodeType get functionReturnType {
-    _functionReturnType ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _functionReturnType;
-  }
-
-  @override
-  int get functionTypedef {
-    _functionTypedef ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
-    return _functionTypedef;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get functionTypedefTypeArguments {
-    _functionTypedefTypeArguments ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 10, const <idl.LinkedNodeType>[]);
-    return _functionTypedefTypeArguments;
-  }
-
-  @override
-  List<idl.LinkedNodeTypeTypeParameter> get functionTypeParameters {
-    _functionTypeParameters ??=
-        const fb.ListReader<idl.LinkedNodeTypeTypeParameter>(
-                _LinkedNodeTypeTypeParameterReader())
-            .vTableGet(
-                _bc, _bcOffset, 2, const <idl.LinkedNodeTypeTypeParameter>[]);
-    return _functionTypeParameters;
-  }
-
-  @override
-  int get interfaceClass {
-    _interfaceClass ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
-    return _interfaceClass;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get interfaceTypeArguments {
-    _interfaceTypeArguments ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNodeType>[]);
-    return _interfaceTypeArguments;
-  }
-
-  @override
-  idl.LinkedNodeTypeKind get kind {
-    _kind ??= const _LinkedNodeTypeKindReader()
-        .vTableGet(_bc, _bcOffset, 5, idl.LinkedNodeTypeKind.dynamic_);
-    return _kind;
-  }
-
-  @override
-  idl.EntityRefNullabilitySuffix get nullabilitySuffix {
-    _nullabilitySuffix ??= const _EntityRefNullabilitySuffixReader().vTableGet(
-        _bc, _bcOffset, 8, idl.EntityRefNullabilitySuffix.starOrIrrelevant);
-    return _nullabilitySuffix;
-  }
-
-  @override
-  int get typeParameterElement {
-    _typeParameterElement ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
-    return _typeParameterElement;
-  }
-
-  @override
-  int get typeParameterId {
-    _typeParameterId ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 7, 0);
-    return _typeParameterId;
-  }
-}
-
-abstract class _LinkedNodeTypeMixin implements idl.LinkedNodeType {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (functionFormalParameters.isNotEmpty) {
-      _result["functionFormalParameters"] =
-          functionFormalParameters.map((_value) => _value.toJson()).toList();
-    }
-    if (functionReturnType != null) {
-      _result["functionReturnType"] = functionReturnType.toJson();
-    }
-    if (functionTypedef != 0) {
-      _result["functionTypedef"] = functionTypedef;
-    }
-    if (functionTypedefTypeArguments.isNotEmpty) {
-      _result["functionTypedefTypeArguments"] = functionTypedefTypeArguments
-          .map((_value) => _value.toJson())
-          .toList();
-    }
-    if (functionTypeParameters.isNotEmpty) {
-      _result["functionTypeParameters"] =
-          functionTypeParameters.map((_value) => _value.toJson()).toList();
-    }
-    if (interfaceClass != 0) {
-      _result["interfaceClass"] = interfaceClass;
-    }
-    if (interfaceTypeArguments.isNotEmpty) {
-      _result["interfaceTypeArguments"] =
-          interfaceTypeArguments.map((_value) => _value.toJson()).toList();
-    }
-    if (kind != idl.LinkedNodeTypeKind.dynamic_) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
-      _result["nullabilitySuffix"] = nullabilitySuffix.toString().split('.')[1];
-    }
-    if (typeParameterElement != 0) {
-      _result["typeParameterElement"] = typeParameterElement;
-    }
-    if (typeParameterId != 0) {
-      _result["typeParameterId"] = typeParameterId;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "functionFormalParameters": functionFormalParameters,
-        "functionReturnType": functionReturnType,
-        "functionTypedef": functionTypedef,
-        "functionTypedefTypeArguments": functionTypedefTypeArguments,
-        "functionTypeParameters": functionTypeParameters,
-        "interfaceClass": interfaceClass,
-        "interfaceTypeArguments": interfaceTypeArguments,
-        "kind": kind,
-        "nullabilitySuffix": nullabilitySuffix,
-        "typeParameterElement": typeParameterElement,
-        "typeParameterId": typeParameterId,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeFormalParameterBuilder extends Object
-    with _LinkedNodeTypeFormalParameterMixin
-    implements idl.LinkedNodeTypeFormalParameter {
-  idl.LinkedNodeFormalParameterKind _kind;
-  String _name;
-  LinkedNodeTypeBuilder _type;
-
-  @override
-  idl.LinkedNodeFormalParameterKind get kind =>
-      _kind ??= idl.LinkedNodeFormalParameterKind.requiredPositional;
-
-  set kind(idl.LinkedNodeFormalParameterKind value) {
-    this._kind = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get type => _type;
-
-  set type(LinkedNodeTypeBuilder value) {
-    this._type = value;
-  }
-
-  LinkedNodeTypeFormalParameterBuilder(
-      {idl.LinkedNodeFormalParameterKind kind,
-      String name,
-      LinkedNodeTypeBuilder type})
-      : _kind = kind,
-        _name = name,
-        _type = type;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _type?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addInt(this._kind == null ? 0 : this._kind.index);
-    signature.addString(this._name ?? '');
-    signature.addBool(this._type != null);
-    this._type?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_name;
-    fb.Offset offset_type;
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    if (_type != null) {
-      offset_type = _type.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (_kind != null &&
-        _kind != idl.LinkedNodeFormalParameterKind.requiredPositional) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(1, offset_name);
-    }
-    if (offset_type != null) {
-      fbBuilder.addOffset(2, offset_type);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeFormalParameterReader
-    extends fb.TableReader<_LinkedNodeTypeFormalParameterImpl> {
-  const _LinkedNodeTypeFormalParameterReader();
-
-  @override
-  _LinkedNodeTypeFormalParameterImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeFormalParameterImpl(bc, offset);
-}
-
-class _LinkedNodeTypeFormalParameterImpl extends Object
-    with _LinkedNodeTypeFormalParameterMixin
-    implements idl.LinkedNodeTypeFormalParameter {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeFormalParameterImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeFormalParameterKind _kind;
-  String _name;
-  idl.LinkedNodeType _type;
-
-  @override
-  idl.LinkedNodeFormalParameterKind get kind {
-    _kind ??= const _LinkedNodeFormalParameterKindReader().vTableGet(_bc,
-        _bcOffset, 0, idl.LinkedNodeFormalParameterKind.requiredPositional);
-    return _kind;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
-    return _name;
-  }
-
-  @override
-  idl.LinkedNodeType get type {
-    _type ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 2, null);
-    return _type;
-  }
-}
-
-abstract class _LinkedNodeTypeFormalParameterMixin
-    implements idl.LinkedNodeTypeFormalParameter {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (kind != idl.LinkedNodeFormalParameterKind.requiredPositional) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    if (type != null) {
-      _result["type"] = type.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "kind": kind,
-        "name": name,
-        "type": type,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeSubstitutionBuilder extends Object
-    with _LinkedNodeTypeSubstitutionMixin
-    implements idl.LinkedNodeTypeSubstitution {
-  bool _isLegacy;
-  List<LinkedNodeTypeBuilder> _typeArguments;
-  List<int> _typeParameters;
-
-  @override
-  bool get isLegacy => _isLegacy ??= false;
-
-  set isLegacy(bool value) {
-    this._isLegacy = value;
-  }
-
-  @override
-  List<LinkedNodeTypeBuilder> get typeArguments =>
-      _typeArguments ??= <LinkedNodeTypeBuilder>[];
-
-  set typeArguments(List<LinkedNodeTypeBuilder> value) {
-    this._typeArguments = value;
-  }
-
-  @override
-  List<int> get typeParameters => _typeParameters ??= <int>[];
-
-  set typeParameters(List<int> value) {
-    assert(value == null || value.every((e) => e >= 0));
-    this._typeParameters = value;
-  }
-
-  LinkedNodeTypeSubstitutionBuilder(
-      {bool isLegacy,
-      List<LinkedNodeTypeBuilder> typeArguments,
-      List<int> typeParameters})
-      : _isLegacy = isLegacy,
-        _typeArguments = typeArguments,
-        _typeParameters = typeParameters;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _typeArguments?.forEach((b) => b.flushInformative());
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (this._typeParameters == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._typeParameters.length);
-      for (var x in this._typeParameters) {
-        signature.addInt(x);
-      }
-    }
-    if (this._typeArguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._typeArguments.length);
-      for (var x in this._typeArguments) {
-        x?.collectApiSignature(signature);
-      }
-    }
-    signature.addBool(this._isLegacy == true);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_typeArguments;
-    fb.Offset offset_typeParameters;
-    if (!(_typeArguments == null || _typeArguments.isEmpty)) {
-      offset_typeArguments = fbBuilder
-          .writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
-    }
-    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
-      offset_typeParameters = fbBuilder.writeListUint32(_typeParameters);
-    }
-    fbBuilder.startTable();
-    if (_isLegacy == true) {
-      fbBuilder.addBool(2, true);
-    }
-    if (offset_typeArguments != null) {
-      fbBuilder.addOffset(1, offset_typeArguments);
-    }
-    if (offset_typeParameters != null) {
-      fbBuilder.addOffset(0, offset_typeParameters);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeSubstitutionReader
-    extends fb.TableReader<_LinkedNodeTypeSubstitutionImpl> {
-  const _LinkedNodeTypeSubstitutionReader();
-
-  @override
-  _LinkedNodeTypeSubstitutionImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeSubstitutionImpl(bc, offset);
-}
-
-class _LinkedNodeTypeSubstitutionImpl extends Object
-    with _LinkedNodeTypeSubstitutionMixin
-    implements idl.LinkedNodeTypeSubstitution {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeSubstitutionImpl(this._bc, this._bcOffset);
-
-  bool _isLegacy;
-  List<idl.LinkedNodeType> _typeArguments;
-  List<int> _typeParameters;
-
-  @override
-  bool get isLegacy {
-    _isLegacy ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
-    return _isLegacy;
-  }
-
-  @override
-  List<idl.LinkedNodeType> get typeArguments {
-    _typeArguments ??=
-        const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
-            .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeType>[]);
-    return _typeArguments;
-  }
-
-  @override
-  List<int> get typeParameters {
-    _typeParameters ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
-    return _typeParameters;
-  }
-}
-
-abstract class _LinkedNodeTypeSubstitutionMixin
-    implements idl.LinkedNodeTypeSubstitution {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (isLegacy != false) {
-      _result["isLegacy"] = isLegacy;
-    }
-    if (typeArguments.isNotEmpty) {
-      _result["typeArguments"] =
-          typeArguments.map((_value) => _value.toJson()).toList();
-    }
-    if (typeParameters.isNotEmpty) {
-      _result["typeParameters"] = typeParameters;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "isLegacy": isLegacy,
-        "typeArguments": typeArguments,
-        "typeParameters": typeParameters,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeTypeParameterBuilder extends Object
-    with _LinkedNodeTypeTypeParameterMixin
-    implements idl.LinkedNodeTypeTypeParameter {
-  LinkedNodeTypeBuilder _bound;
-  String _name;
-
-  @override
-  LinkedNodeTypeBuilder get bound => _bound;
-
-  set bound(LinkedNodeTypeBuilder value) {
-    this._bound = value;
-  }
-
-  @override
-  String get name => _name ??= '';
-
-  set name(String value) {
-    this._name = value;
-  }
-
-  LinkedNodeTypeTypeParameterBuilder({LinkedNodeTypeBuilder bound, String name})
-      : _bound = bound,
-        _name = name;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _bound?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._name ?? '');
-    signature.addBool(this._bound != null);
-    this._bound?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_bound;
-    fb.Offset offset_name;
-    if (_bound != null) {
-      offset_bound = _bound.finish(fbBuilder);
-    }
-    if (_name != null) {
-      offset_name = fbBuilder.writeString(_name);
-    }
-    fbBuilder.startTable();
-    if (offset_bound != null) {
-      fbBuilder.addOffset(1, offset_bound);
-    }
-    if (offset_name != null) {
-      fbBuilder.addOffset(0, offset_name);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeTypeTypeParameterReader
-    extends fb.TableReader<_LinkedNodeTypeTypeParameterImpl> {
-  const _LinkedNodeTypeTypeParameterReader();
-
-  @override
-  _LinkedNodeTypeTypeParameterImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _LinkedNodeTypeTypeParameterImpl(bc, offset);
-}
-
-class _LinkedNodeTypeTypeParameterImpl extends Object
-    with _LinkedNodeTypeTypeParameterMixin
-    implements idl.LinkedNodeTypeTypeParameter {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeTypeTypeParameterImpl(this._bc, this._bcOffset);
-
-  idl.LinkedNodeType _bound;
-  String _name;
-
-  @override
-  idl.LinkedNodeType get bound {
-    _bound ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _bound;
-  }
-
-  @override
-  String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _name;
-  }
-}
-
-abstract class _LinkedNodeTypeTypeParameterMixin
-    implements idl.LinkedNodeTypeTypeParameter {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (bound != null) {
-      _result["bound"] = bound.toJson();
-    }
-    if (name != '') {
-      _result["name"] = name;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "bound": bound,
-        "name": name,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeUnitBuilder extends Object
-    with _LinkedNodeUnitMixin
-    implements idl.LinkedNodeUnit {
-  bool _isSynthetic;
-  LinkedNodeBuilder _node;
-  String _partUriStr;
-  String _uriStr;
-
-  @override
-  bool get isSynthetic => _isSynthetic ??= false;
-
-  set isSynthetic(bool value) {
-    this._isSynthetic = value;
-  }
-
-  @override
-  LinkedNodeBuilder get node => _node;
-
-  set node(LinkedNodeBuilder value) {
-    this._node = value;
-  }
-
-  @override
-  String get partUriStr => _partUriStr ??= '';
-
-  /// If the unit is a part, the URI specified in the `part` directive.
-  /// Otherwise empty.
-  set partUriStr(String value) {
-    this._partUriStr = value;
-  }
-
-  @override
-  String get uriStr => _uriStr ??= '';
-
-  /// The absolute URI.
-  set uriStr(String value) {
-    this._uriStr = value;
-  }
-
-  LinkedNodeUnitBuilder(
-      {bool isSynthetic,
-      LinkedNodeBuilder node,
-      String partUriStr,
-      String uriStr})
-      : _isSynthetic = isSynthetic,
-        _node = node,
-        _partUriStr = partUriStr,
-        _uriStr = uriStr;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _node?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._uriStr ?? '');
-    signature.addBool(this._node != null);
-    this._node?.collectApiSignature(signature);
-    signature.addBool(this._isSynthetic == true);
-    signature.addString(this._partUriStr ?? '');
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_node;
-    fb.Offset offset_partUriStr;
-    fb.Offset offset_uriStr;
-    if (_node != null) {
-      offset_node = _node.finish(fbBuilder);
-    }
-    if (_partUriStr != null) {
-      offset_partUriStr = fbBuilder.writeString(_partUriStr);
-    }
-    if (_uriStr != null) {
-      offset_uriStr = fbBuilder.writeString(_uriStr);
-    }
-    fbBuilder.startTable();
-    if (_isSynthetic == true) {
-      fbBuilder.addBool(2, true);
-    }
-    if (offset_node != null) {
-      fbBuilder.addOffset(1, offset_node);
-    }
-    if (offset_partUriStr != null) {
-      fbBuilder.addOffset(3, offset_partUriStr);
-    }
-    if (offset_uriStr != null) {
-      fbBuilder.addOffset(0, offset_uriStr);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _LinkedNodeUnitReader extends fb.TableReader<_LinkedNodeUnitImpl> {
-  const _LinkedNodeUnitReader();
-
-  @override
-  _LinkedNodeUnitImpl createObject(fb.BufferContext bc, int offset) =>
-      _LinkedNodeUnitImpl(bc, offset);
-}
-
-class _LinkedNodeUnitImpl extends Object
-    with _LinkedNodeUnitMixin
-    implements idl.LinkedNodeUnit {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _LinkedNodeUnitImpl(this._bc, this._bcOffset);
-
-  bool _isSynthetic;
-  idl.LinkedNode _node;
-  String _partUriStr;
-  String _uriStr;
-
-  @override
-  bool get isSynthetic {
-    _isSynthetic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
-    return _isSynthetic;
-  }
-
-  @override
-  idl.LinkedNode get node {
-    _node ??= const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _node;
-  }
-
-  @override
-  String get partUriStr {
-    _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
-    return _partUriStr;
-  }
-
-  @override
-  String get uriStr {
-    _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _uriStr;
-  }
-}
-
-abstract class _LinkedNodeUnitMixin implements idl.LinkedNodeUnit {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (isSynthetic != false) {
-      _result["isSynthetic"] = isSynthetic;
-    }
-    if (node != null) {
-      _result["node"] = node.toJson();
-    }
-    if (partUriStr != '') {
-      _result["partUriStr"] = partUriStr;
-    }
-    if (uriStr != '') {
-      _result["uriStr"] = uriStr;
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "isSynthetic": isSynthetic,
-        "node": node,
-        "partUriStr": partUriStr,
-        "uriStr": uriStr,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class PackageBundleBuilder extends Object
     with _PackageBundleMixin
     implements idl.PackageBundle {
-  LinkedNodeBundleBuilder _bundle2;
-  PackageBundleSdkBuilder _sdk;
+  int _fake;
 
   @override
-  LinkedNodeBundleBuilder get bundle2 => _bundle2;
+  int get fake => _fake ??= 0;
 
   /// The version 2 of the summary.
-  set bundle2(LinkedNodeBundleBuilder value) {
-    this._bundle2 = value;
+  set fake(int value) {
+    assert(value == null || value >= 0);
+    this._fake = value;
   }
 
-  @override
-  PackageBundleSdkBuilder get sdk => _sdk;
-
-  /// The SDK specific data, if this bundle is for SDK.
-  set sdk(PackageBundleSdkBuilder value) {
-    this._sdk = value;
-  }
-
-  PackageBundleBuilder(
-      {LinkedNodeBundleBuilder bundle2, PackageBundleSdkBuilder sdk})
-      : _bundle2 = bundle2,
-        _sdk = sdk;
+  PackageBundleBuilder({int fake}) : _fake = fake;
 
   /// Flush [informative] data recursively.
-  void flushInformative() {
-    _bundle2?.flushInformative();
-    _sdk?.flushInformative();
-  }
+  void flushInformative() {}
 
   /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addBool(this._bundle2 != null);
-    this._bundle2?.collectApiSignature(signature);
-    signature.addBool(this._sdk != null);
-    this._sdk?.collectApiSignature(signature);
+    signature.addInt(this._fake ?? 0);
   }
 
   List<int> toBuffer() {
@@ -17724,20 +4001,9 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_bundle2;
-    fb.Offset offset_sdk;
-    if (_bundle2 != null) {
-      offset_bundle2 = _bundle2.finish(fbBuilder);
-    }
-    if (_sdk != null) {
-      offset_sdk = _sdk.finish(fbBuilder);
-    }
     fbBuilder.startTable();
-    if (offset_bundle2 != null) {
-      fbBuilder.addOffset(0, offset_bundle2);
-    }
-    if (offset_sdk != null) {
-      fbBuilder.addOffset(1, offset_sdk);
+    if (_fake != null && _fake != 0) {
+      fbBuilder.addUint32(0, _fake);
     }
     return fbBuilder.endTable();
   }
@@ -17764,20 +4030,12 @@
 
   _PackageBundleImpl(this._bc, this._bcOffset);
 
-  idl.LinkedNodeBundle _bundle2;
-  idl.PackageBundleSdk _sdk;
+  int _fake;
 
   @override
-  idl.LinkedNodeBundle get bundle2 {
-    _bundle2 ??=
-        const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 0, null);
-    return _bundle2;
-  }
-
-  @override
-  idl.PackageBundleSdk get sdk {
-    _sdk ??= const _PackageBundleSdkReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _sdk;
+  int get fake {
+    _fake ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
+    return _fake;
   }
 }
 
@@ -17785,1862 +4043,21 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (bundle2 != null) {
-      _result["bundle2"] = bundle2.toJson();
-    }
-    if (sdk != null) {
-      _result["sdk"] = sdk.toJson();
+    if (fake != 0) {
+      _result["fake"] = fake;
     }
     return _result;
   }
 
   @override
   Map<String, Object> toMap() => {
-        "bundle2": bundle2,
-        "sdk": sdk,
+        "fake": fake,
       };
 
   @override
   String toString() => convert.json.encode(toJson());
 }
 
-class PackageBundleSdkBuilder extends Object
-    with _PackageBundleSdkMixin
-    implements idl.PackageBundleSdk {
-  String _allowedExperimentsJson;
-  LinkedLanguageVersionBuilder _languageVersion;
-
-  @override
-  String get allowedExperimentsJson => _allowedExperimentsJson ??= '';
-
-  /// The content of the `allowed_experiments.json` from SDK.
-  set allowedExperimentsJson(String value) {
-    this._allowedExperimentsJson = value;
-  }
-
-  @override
-  LinkedLanguageVersionBuilder get languageVersion => _languageVersion;
-
-  /// The language version of the SDK.
-  set languageVersion(LinkedLanguageVersionBuilder value) {
-    this._languageVersion = value;
-  }
-
-  PackageBundleSdkBuilder(
-      {String allowedExperimentsJson,
-      LinkedLanguageVersionBuilder languageVersion})
-      : _allowedExperimentsJson = allowedExperimentsJson,
-        _languageVersion = languageVersion;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _languageVersion?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addString(this._allowedExperimentsJson ?? '');
-    signature.addBool(this._languageVersion != null);
-    this._languageVersion?.collectApiSignature(signature);
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_allowedExperimentsJson;
-    fb.Offset offset_languageVersion;
-    if (_allowedExperimentsJson != null) {
-      offset_allowedExperimentsJson =
-          fbBuilder.writeString(_allowedExperimentsJson);
-    }
-    if (_languageVersion != null) {
-      offset_languageVersion = _languageVersion.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_allowedExperimentsJson != null) {
-      fbBuilder.addOffset(0, offset_allowedExperimentsJson);
-    }
-    if (offset_languageVersion != null) {
-      fbBuilder.addOffset(1, offset_languageVersion);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _PackageBundleSdkReader extends fb.TableReader<_PackageBundleSdkImpl> {
-  const _PackageBundleSdkReader();
-
-  @override
-  _PackageBundleSdkImpl createObject(fb.BufferContext bc, int offset) =>
-      _PackageBundleSdkImpl(bc, offset);
-}
-
-class _PackageBundleSdkImpl extends Object
-    with _PackageBundleSdkMixin
-    implements idl.PackageBundleSdk {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _PackageBundleSdkImpl(this._bc, this._bcOffset);
-
-  String _allowedExperimentsJson;
-  idl.LinkedLanguageVersion _languageVersion;
-
-  @override
-  String get allowedExperimentsJson {
-    _allowedExperimentsJson ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
-    return _allowedExperimentsJson;
-  }
-
-  @override
-  idl.LinkedLanguageVersion get languageVersion {
-    _languageVersion ??=
-        const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 1, null);
-    return _languageVersion;
-  }
-}
-
-abstract class _PackageBundleSdkMixin implements idl.PackageBundleSdk {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (allowedExperimentsJson != '') {
-      _result["allowedExperimentsJson"] = allowedExperimentsJson;
-    }
-    if (languageVersion != null) {
-      _result["languageVersion"] = languageVersion.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "allowedExperimentsJson": allowedExperimentsJson,
-        "languageVersion": languageVersion,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class TopLevelInferenceErrorBuilder extends Object
-    with _TopLevelInferenceErrorMixin
-    implements idl.TopLevelInferenceError {
-  List<String> _arguments;
-  idl.TopLevelInferenceErrorKind _kind;
-
-  @override
-  List<String> get arguments => _arguments ??= <String>[];
-
-  /// The [kind] specific arguments.
-  set arguments(List<String> value) {
-    this._arguments = value;
-  }
-
-  @override
-  idl.TopLevelInferenceErrorKind get kind =>
-      _kind ??= idl.TopLevelInferenceErrorKind.assignment;
-
-  /// The kind of the error.
-  set kind(idl.TopLevelInferenceErrorKind value) {
-    this._kind = value;
-  }
-
-  TopLevelInferenceErrorBuilder(
-      {List<String> arguments, idl.TopLevelInferenceErrorKind kind})
-      : _arguments = arguments,
-        _kind = kind;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {}
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    signature.addInt(this._kind == null ? 0 : this._kind.index);
-    if (this._arguments == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._arguments.length);
-      for (var x in this._arguments) {
-        signature.addString(x);
-      }
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_arguments;
-    if (!(_arguments == null || _arguments.isEmpty)) {
-      offset_arguments = fbBuilder
-          .writeList(_arguments.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    fbBuilder.startTable();
-    if (offset_arguments != null) {
-      fbBuilder.addOffset(1, offset_arguments);
-    }
-    if (_kind != null && _kind != idl.TopLevelInferenceErrorKind.assignment) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _TopLevelInferenceErrorReader
-    extends fb.TableReader<_TopLevelInferenceErrorImpl> {
-  const _TopLevelInferenceErrorReader();
-
-  @override
-  _TopLevelInferenceErrorImpl createObject(fb.BufferContext bc, int offset) =>
-      _TopLevelInferenceErrorImpl(bc, offset);
-}
-
-class _TopLevelInferenceErrorImpl extends Object
-    with _TopLevelInferenceErrorMixin
-    implements idl.TopLevelInferenceError {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _TopLevelInferenceErrorImpl(this._bc, this._bcOffset);
-
-  List<String> _arguments;
-  idl.TopLevelInferenceErrorKind _kind;
-
-  @override
-  List<String> get arguments {
-    _arguments ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 1, const <String>[]);
-    return _arguments;
-  }
-
-  @override
-  idl.TopLevelInferenceErrorKind get kind {
-    _kind ??= const _TopLevelInferenceErrorKindReader().vTableGet(
-        _bc, _bcOffset, 0, idl.TopLevelInferenceErrorKind.assignment);
-    return _kind;
-  }
-}
-
-abstract class _TopLevelInferenceErrorMixin
-    implements idl.TopLevelInferenceError {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (arguments.isNotEmpty) {
-      _result["arguments"] = arguments;
-    }
-    if (kind != idl.TopLevelInferenceErrorKind.assignment) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() => {
-        "arguments": arguments,
-        "kind": kind,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
-class UnlinkedInformativeDataBuilder extends Object
-    with _UnlinkedInformativeDataMixin
-    implements idl.UnlinkedInformativeData {
-  int _variantField_2;
-  int _variantField_3;
-  int _variantField_9;
-  int _variantField_8;
-  List<int> _variantField_7;
-  int _variantField_6;
-  int _variantField_5;
-  String _variantField_10;
-  int _variantField_1;
-  List<String> _variantField_4;
-  idl.LinkedNodeKind _kind;
-
-  @override
-  int get codeLength {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_2 ??= 0;
-  }
-
-  set codeLength(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_2 = value;
-  }
-
-  @override
-  int get codeOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_3 ??= 0;
-  }
-
-  set codeOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_3 = value;
-  }
-
-  @override
-  int get combinatorEnd {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    return _variantField_9 ??= 0;
-  }
-
-  set combinatorEnd(int value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    assert(value == null || value >= 0);
-    _variantField_9 = value;
-  }
-
-  @override
-  int get combinatorKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    return _variantField_8 ??= 0;
-  }
-
-  @override
-  int get importDirective_prefixOffset {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_8 ??= 0;
-  }
-
-  set combinatorKeywordOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    assert(value == null || value >= 0);
-    _variantField_8 = value;
-  }
-
-  set importDirective_prefixOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    assert(value == null || value >= 0);
-    _variantField_8 = value;
-  }
-
-  @override
-  List<int> get compilationUnit_lineStarts {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_7 ??= <int>[];
-  }
-
-  /// Offsets of the first character of each line in the source code.
-  set compilationUnit_lineStarts(List<int> value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    assert(value == null || value.every((e) => e >= 0));
-    _variantField_7 = value;
-  }
-
-  @override
-  int get constructorDeclaration_periodOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_6 ??= 0;
-  }
-
-  set constructorDeclaration_periodOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_6 = value;
-  }
-
-  @override
-  int get constructorDeclaration_returnTypeOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_5 ??= 0;
-  }
-
-  set constructorDeclaration_returnTypeOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_5 = value;
-  }
-
-  @override
-  String get defaultFormalParameter_defaultValueCode {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_10 ??= '';
-  }
-
-  /// If the parameter has a default value, the source text of the constant
-  /// expression in the default value.  Otherwise the empty string.
-  set defaultFormalParameter_defaultValueCode(String value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_10 = value;
-  }
-
-  @override
-  int get directiveKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_1 ??= 0;
-  }
-
-  @override
-  int get nameOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_1 ??= 0;
-  }
-
-  set directiveKeywordOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    assert(value == null || value >= 0);
-    _variantField_1 = value;
-  }
-
-  set nameOffset(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_1 = value;
-  }
-
-  @override
-  List<String> get documentationComment_tokens {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    return _variantField_4 ??= <String>[];
-  }
-
-  set documentationComment_tokens(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_4 = value;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
-
-  /// The kind of the node.
-  set kind(idl.LinkedNodeKind value) {
-    this._kind = value;
-  }
-
-  UnlinkedInformativeDataBuilder.classDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.classDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.classTypeAlias({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.classTypeAlias,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.compilationUnit({
-    int codeLength,
-    int codeOffset,
-    List<int> compilationUnit_lineStarts,
-  })  : _kind = idl.LinkedNodeKind.compilationUnit,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_7 = compilationUnit_lineStarts;
-
-  UnlinkedInformativeDataBuilder.constructorDeclaration({
-    int codeLength,
-    int codeOffset,
-    int constructorDeclaration_periodOffset,
-    int constructorDeclaration_returnTypeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.constructorDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_6 = constructorDeclaration_periodOffset,
-        _variantField_5 = constructorDeclaration_returnTypeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.defaultFormalParameter({
-    int codeLength,
-    int codeOffset,
-    String defaultFormalParameter_defaultValueCode,
-  })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_10 = defaultFormalParameter_defaultValueCode;
-
-  UnlinkedInformativeDataBuilder.enumConstantDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.enumDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.enumDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.exportDirective({
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.exportDirective,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.extensionDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.extensionDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.fieldDeclaration({
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.fieldDeclaration,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.fieldFormalParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.fieldFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.functionDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.functionDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.functionTypeAlias({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.functionTypedFormalParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.genericTypeAlias({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.genericTypeAlias,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.hideCombinator({
-    int combinatorEnd,
-    int combinatorKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.hideCombinator,
-        _variantField_9 = combinatorEnd,
-        _variantField_8 = combinatorKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.importDirective({
-    int importDirective_prefixOffset,
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.importDirective,
-        _variantField_8 = importDirective_prefixOffset,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.libraryDirective({
-    int directiveKeywordOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.libraryDirective,
-        _variantField_1 = directiveKeywordOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.methodDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.methodDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.mixinDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.partDirective({
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.partDirective,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.partOfDirective({
-    int directiveKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.partOfDirective,
-        _variantField_1 = directiveKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.showCombinator({
-    int combinatorEnd,
-    int combinatorKeywordOffset,
-  })  : _kind = idl.LinkedNodeKind.showCombinator,
-        _variantField_9 = combinatorEnd,
-        _variantField_8 = combinatorKeywordOffset;
-
-  UnlinkedInformativeDataBuilder.simpleFormalParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.topLevelVariableDeclaration({
-    List<String> documentationComment_tokens,
-  })  : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
-        _variantField_4 = documentationComment_tokens;
-
-  UnlinkedInformativeDataBuilder.typeParameter({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.typeParameter,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  UnlinkedInformativeDataBuilder.variableDeclaration({
-    int codeLength,
-    int codeOffset,
-    int nameOffset,
-  })  : _kind = idl.LinkedNodeKind.variableDeclaration,
-        _variantField_2 = codeLength,
-        _variantField_3 = codeOffset,
-        _variantField_1 = nameOffset;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {}
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signature) {
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.compilationUnit) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.compilationUnit_lineStarts == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.compilationUnit_lineStarts.length);
-        for (var x in this.compilationUnit_lineStarts) {
-          signature.addInt(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-      signature.addInt(this.constructorDeclaration_returnTypeOffset ?? 0);
-      signature.addInt(this.constructorDeclaration_periodOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      signature.addString(this.defaultFormalParameter_defaultValueCode ?? '');
-    } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.exportDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.hideCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.combinatorKeywordOffset ?? 0);
-      signature.addInt(this.combinatorEnd ?? 0);
-    } else if (kind == idl.LinkedNodeKind.importDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-      signature.addInt(this.importDirective_prefixOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.libraryDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.partDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.partOfDirective) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.directiveKeywordOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.showCombinator) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.combinatorKeywordOffset ?? 0);
-      signature.addInt(this.combinatorEnd ?? 0);
-    } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      if (this.documentationComment_tokens == null) {
-        signature.addInt(0);
-      } else {
-        signature.addInt(this.documentationComment_tokens.length);
-        for (var x in this.documentationComment_tokens) {
-          signature.addString(x);
-        }
-      }
-    } else if (kind == idl.LinkedNodeKind.typeParameter) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      signature.addInt(this.kind == null ? 0 : this.kind.index);
-      signature.addInt(this.nameOffset ?? 0);
-      signature.addInt(this.codeLength ?? 0);
-      signature.addInt(this.codeOffset ?? 0);
-    }
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_variantField_7;
-    fb.Offset offset_variantField_10;
-    fb.Offset offset_variantField_4;
-    if (!(_variantField_7 == null || _variantField_7.isEmpty)) {
-      offset_variantField_7 = fbBuilder.writeListUint32(_variantField_7);
-    }
-    if (_variantField_10 != null) {
-      offset_variantField_10 = fbBuilder.writeString(_variantField_10);
-    }
-    if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
-      offset_variantField_4 = fbBuilder.writeList(
-          _variantField_4.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    fbBuilder.startTable();
-    if (_variantField_2 != null && _variantField_2 != 0) {
-      fbBuilder.addUint32(2, _variantField_2);
-    }
-    if (_variantField_3 != null && _variantField_3 != 0) {
-      fbBuilder.addUint32(3, _variantField_3);
-    }
-    if (_variantField_9 != null && _variantField_9 != 0) {
-      fbBuilder.addUint32(9, _variantField_9);
-    }
-    if (_variantField_8 != null && _variantField_8 != 0) {
-      fbBuilder.addUint32(8, _variantField_8);
-    }
-    if (offset_variantField_7 != null) {
-      fbBuilder.addOffset(7, offset_variantField_7);
-    }
-    if (_variantField_6 != null && _variantField_6 != 0) {
-      fbBuilder.addUint32(6, _variantField_6);
-    }
-    if (_variantField_5 != null && _variantField_5 != 0) {
-      fbBuilder.addUint32(5, _variantField_5);
-    }
-    if (offset_variantField_10 != null) {
-      fbBuilder.addOffset(10, offset_variantField_10);
-    }
-    if (_variantField_1 != null && _variantField_1 != 0) {
-      fbBuilder.addUint32(1, _variantField_1);
-    }
-    if (offset_variantField_4 != null) {
-      fbBuilder.addOffset(4, offset_variantField_4);
-    }
-    if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
-      fbBuilder.addUint8(0, _kind.index);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-class _UnlinkedInformativeDataReader
-    extends fb.TableReader<_UnlinkedInformativeDataImpl> {
-  const _UnlinkedInformativeDataReader();
-
-  @override
-  _UnlinkedInformativeDataImpl createObject(fb.BufferContext bc, int offset) =>
-      _UnlinkedInformativeDataImpl(bc, offset);
-}
-
-class _UnlinkedInformativeDataImpl extends Object
-    with _UnlinkedInformativeDataMixin
-    implements idl.UnlinkedInformativeData {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _UnlinkedInformativeDataImpl(this._bc, this._bcOffset);
-
-  int _variantField_2;
-  int _variantField_3;
-  int _variantField_9;
-  int _variantField_8;
-  List<int> _variantField_7;
-  int _variantField_6;
-  int _variantField_5;
-  String _variantField_10;
-  int _variantField_1;
-  List<String> _variantField_4;
-  idl.LinkedNodeKind _kind;
-
-  @override
-  int get codeLength {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_2 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
-    return _variantField_2;
-  }
-
-  @override
-  int get codeOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.compilationUnit ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.defaultFormalParameter ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_3 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
-    return _variantField_3;
-  }
-
-  @override
-  int get combinatorEnd {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_9 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
-    return _variantField_9;
-  }
-
-  @override
-  int get combinatorKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_8 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
-    return _variantField_8;
-  }
-
-  @override
-  int get importDirective_prefixOffset {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_8 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
-    return _variantField_8;
-  }
-
-  @override
-  List<int> get compilationUnit_lineStarts {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_7 ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 7, const <int>[]);
-    return _variantField_7;
-  }
-
-  @override
-  int get constructorDeclaration_periodOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_6 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
-    return _variantField_6;
-  }
-
-  @override
-  int get constructorDeclaration_returnTypeOffset {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_5 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
-    return _variantField_5;
-  }
-
-  @override
-  String get defaultFormalParameter_defaultValueCode {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_10 ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 10, '');
-    return _variantField_10;
-  }
-
-  @override
-  int get directiveKeywordOffset {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_1 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
-    return _variantField_1;
-  }
-
-  @override
-  int get nameOffset {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter ||
-        kind == idl.LinkedNodeKind.typeParameter ||
-        kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_1 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
-    return _variantField_1;
-  }
-
-  @override
-  List<String> get documentationComment_tokens {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.constructorDeclaration ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
-        kind == idl.LinkedNodeKind.extensionDeclaration ||
-        kind == idl.LinkedNodeKind.fieldDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.methodDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration ||
-        kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_4 ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 4, const <String>[]);
-    return _variantField_4;
-  }
-
-  @override
-  idl.LinkedNodeKind get kind {
-    _kind ??= const _LinkedNodeKindReader()
-        .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
-    return _kind;
-  }
-}
-
-abstract class _UnlinkedInformativeDataMixin
-    implements idl.UnlinkedInformativeData {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    if (kind != idl.LinkedNodeKind.adjacentStrings) {
-      _result["kind"] = kind.toString().split('.')[1];
-    }
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (compilationUnit_lineStarts.isNotEmpty) {
-        _result["compilationUnit_lineStarts"] = compilationUnit_lineStarts;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (constructorDeclaration_periodOffset != 0) {
-        _result["constructorDeclaration_periodOffset"] =
-            constructorDeclaration_periodOffset;
-      }
-      if (constructorDeclaration_returnTypeOffset != 0) {
-        _result["constructorDeclaration_returnTypeOffset"] =
-            constructorDeclaration_returnTypeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (defaultFormalParameter_defaultValueCode != '') {
-        _result["defaultFormalParameter_defaultValueCode"] =
-            defaultFormalParameter_defaultValueCode;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      if (combinatorEnd != 0) {
-        _result["combinatorEnd"] = combinatorEnd;
-      }
-      if (combinatorKeywordOffset != 0) {
-        _result["combinatorKeywordOffset"] = combinatorKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      if (importDirective_prefixOffset != 0) {
-        _result["importDirective_prefixOffset"] = importDirective_prefixOffset;
-      }
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      if (directiveKeywordOffset != 0) {
-        _result["directiveKeywordOffset"] = directiveKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      if (combinatorEnd != 0) {
-        _result["combinatorEnd"] = combinatorEnd;
-      }
-      if (combinatorKeywordOffset != 0) {
-        _result["combinatorKeywordOffset"] = combinatorKeywordOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      if (documentationComment_tokens.isNotEmpty) {
-        _result["documentationComment_tokens"] = documentationComment_tokens;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      if (codeLength != 0) {
-        _result["codeLength"] = codeLength;
-      }
-      if (codeOffset != 0) {
-        _result["codeOffset"] = codeOffset;
-      }
-      if (nameOffset != 0) {
-        _result["nameOffset"] = nameOffset;
-      }
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object> toMap() {
-    if (kind == idl.LinkedNodeKind.classDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.classTypeAlias) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.compilationUnit) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "compilationUnit_lineStarts": compilationUnit_lineStarts,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.constructorDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "constructorDeclaration_periodOffset":
-            constructorDeclaration_periodOffset,
-        "constructorDeclaration_returnTypeOffset":
-            constructorDeclaration_returnTypeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "defaultFormalParameter_defaultValueCode":
-            defaultFormalParameter_defaultValueCode,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.enumDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.exportDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.extensionDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldDeclaration) {
-      return {
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericTypeAlias) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      return {
-        "combinatorEnd": combinatorEnd,
-        "combinatorKeywordOffset": combinatorKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.importDirective) {
-      return {
-        "importDirective_prefixOffset": importDirective_prefixOffset,
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.libraryDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.mixinDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.partOfDirective) {
-      return {
-        "directiveKeywordOffset": directiveKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      return {
-        "combinatorEnd": combinatorEnd,
-        "combinatorKeywordOffset": combinatorKeywordOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
-      return {
-        "documentationComment_tokens": documentationComment_tokens,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.typeParameter) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      return {
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "nameOffset": nameOffset,
-        "kind": kind,
-      };
-    }
-    throw StateError("Unexpected $kind");
-  }
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class UnlinkedNamespaceDirectiveBuilder extends Object
     with _UnlinkedNamespaceDirectiveMixin
     implements idl.UnlinkedNamespaceDirective {
@@ -19926,7 +4343,6 @@
   bool _hasLibraryDirective;
   bool _hasPartOfDirective;
   List<UnlinkedNamespaceDirectiveBuilder> _imports;
-  List<UnlinkedInformativeDataBuilder> _informativeData;
   List<int> _lineStarts;
   String _partOfUri;
   List<String> _parts;
@@ -19976,14 +4392,6 @@
   }
 
   @override
-  List<UnlinkedInformativeDataBuilder> get informativeData =>
-      _informativeData ??= <UnlinkedInformativeDataBuilder>[];
-
-  set informativeData(List<UnlinkedInformativeDataBuilder> value) {
-    this._informativeData = value;
-  }
-
-  @override
   List<int> get lineStarts => _lineStarts ??= <int>[];
 
   /// Offsets of the first character of each line in the source code.
@@ -20014,7 +4422,6 @@
       bool hasLibraryDirective,
       bool hasPartOfDirective,
       List<UnlinkedNamespaceDirectiveBuilder> imports,
-      List<UnlinkedInformativeDataBuilder> informativeData,
       List<int> lineStarts,
       String partOfUri,
       List<String> parts})
@@ -20023,7 +4430,6 @@
         _hasLibraryDirective = hasLibraryDirective,
         _hasPartOfDirective = hasPartOfDirective,
         _imports = imports,
-        _informativeData = informativeData,
         _lineStarts = lineStarts,
         _partOfUri = partOfUri,
         _parts = parts;
@@ -20032,7 +4438,6 @@
   void flushInformative() {
     _exports?.forEach((b) => b.flushInformative());
     _imports?.forEach((b) => b.flushInformative());
-    _informativeData?.forEach((b) => b.flushInformative());
     _lineStarts = null;
   }
 
@@ -20072,14 +4477,6 @@
       }
     }
     signature.addBool(this._hasLibraryDirective == true);
-    if (this._informativeData == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._informativeData.length);
-      for (var x in this._informativeData) {
-        x?.collectApiSignature(signature);
-      }
-    }
     signature.addString(this._partOfUri ?? '');
   }
 
@@ -20092,7 +4489,6 @@
     fb.Offset offset_apiSignature;
     fb.Offset offset_exports;
     fb.Offset offset_imports;
-    fb.Offset offset_informativeData;
     fb.Offset offset_lineStarts;
     fb.Offset offset_partOfUri;
     fb.Offset offset_parts;
@@ -20107,10 +4503,6 @@
       offset_imports = fbBuilder
           .writeList(_imports.map((b) => b.finish(fbBuilder)).toList());
     }
-    if (!(_informativeData == null || _informativeData.isEmpty)) {
-      offset_informativeData = fbBuilder
-          .writeList(_informativeData.map((b) => b.finish(fbBuilder)).toList());
-    }
     if (!(_lineStarts == null || _lineStarts.isEmpty)) {
       offset_lineStarts = fbBuilder.writeListUint32(_lineStarts);
     }
@@ -20137,14 +4529,11 @@
     if (offset_imports != null) {
       fbBuilder.addOffset(2, offset_imports);
     }
-    if (offset_informativeData != null) {
-      fbBuilder.addOffset(7, offset_informativeData);
-    }
     if (offset_lineStarts != null) {
       fbBuilder.addOffset(5, offset_lineStarts);
     }
     if (offset_partOfUri != null) {
-      fbBuilder.addOffset(8, offset_partOfUri);
+      fbBuilder.addOffset(7, offset_partOfUri);
     }
     if (offset_parts != null) {
       fbBuilder.addOffset(4, offset_parts);
@@ -20179,7 +4568,6 @@
   bool _hasLibraryDirective;
   bool _hasPartOfDirective;
   List<idl.UnlinkedNamespaceDirective> _imports;
-  List<idl.UnlinkedInformativeData> _informativeData;
   List<int> _lineStarts;
   String _partOfUri;
   List<String> _parts;
@@ -20222,14 +4610,6 @@
   }
 
   @override
-  List<idl.UnlinkedInformativeData> get informativeData {
-    _informativeData ??= const fb.ListReader<idl.UnlinkedInformativeData>(
-            _UnlinkedInformativeDataReader())
-        .vTableGet(_bc, _bcOffset, 7, const <idl.UnlinkedInformativeData>[]);
-    return _informativeData;
-  }
-
-  @override
   List<int> get lineStarts {
     _lineStarts ??=
         const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 5, const <int>[]);
@@ -20238,7 +4618,7 @@
 
   @override
   String get partOfUri {
-    _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 8, '');
+    _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 7, '');
     return _partOfUri;
   }
 
@@ -20269,10 +4649,6 @@
     if (imports.isNotEmpty) {
       _result["imports"] = imports.map((_value) => _value.toJson()).toList();
     }
-    if (informativeData.isNotEmpty) {
-      _result["informativeData"] =
-          informativeData.map((_value) => _value.toJson()).toList();
-    }
     if (lineStarts.isNotEmpty) {
       _result["lineStarts"] = lineStarts;
     }
@@ -20292,7 +4668,6 @@
         "hasLibraryDirective": hasLibraryDirective,
         "hasPartOfDirective": hasPartOfDirective,
         "imports": imports,
-        "informativeData": informativeData,
         "lineStarts": lineStarts,
         "partOfUri": partOfUri,
         "parts": parts,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index e9c6fe6..bdce0bf 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -39,30 +39,6 @@
   VARIABLE
 }
 
-/// Enum representing nullability suffixes in summaries.
-///
-/// This enum is similar to [NullabilitySuffix], but the order is different so
-/// that [EntityRefNullabilitySuffix.starOrIrrelevant] can be the default.
-enum EntityRefNullabilitySuffix : byte {
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `*`.  Types having this nullability suffix are
-  /// called "legacy types"; it has not yet been determined whether they should
-  /// be unioned with the Null type.
-  ///
-  /// Also used in circumstances where no nullability suffix information is
-  /// needed.
-  starOrIrrelevant,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `?`.  Types having this nullability suffix should
-  /// be interpreted as being unioned with the Null type.
-  question,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration does not end with either `?` or `*`.
-  none
-}
-
 /// Enum used to indicate the kind of an index relation.
 enum IndexRelationKind : byte {
   /// Left: class.
@@ -149,586 +125,6 @@
   unit
 }
 
-/// Types of comments.
-enum LinkedNodeCommentType : byte {
-  block,
-
-  documentation,
-
-  endOfLine
-}
-
-/// Kinds of formal parameters.
-enum LinkedNodeFormalParameterKind : byte {
-  requiredPositional,
-
-  optionalPositional,
-
-  optionalNamed,
-
-  requiredNamed
-}
-
-/// Kinds of [LinkedNode].
-enum LinkedNodeKind : byte {
-  adjacentStrings,
-
-  annotation,
-
-  argumentList,
-
-  asExpression,
-
-  assertInitializer,
-
-  assertStatement,
-
-  assignmentExpression,
-
-  awaitExpression,
-
-  binaryExpression,
-
-  block,
-
-  blockFunctionBody,
-
-  booleanLiteral,
-
-  breakStatement,
-
-  cascadeExpression,
-
-  catchClause,
-
-  classDeclaration,
-
-  classTypeAlias,
-
-  comment,
-
-  commentReference,
-
-  compilationUnit,
-
-  conditionalExpression,
-
-  configuration,
-
-  constructorDeclaration,
-
-  constructorFieldInitializer,
-
-  constructorName,
-
-  continueStatement,
-
-  declaredIdentifier,
-
-  defaultFormalParameter,
-
-  doubleLiteral,
-
-  doStatement,
-
-  dottedName,
-
-  emptyFunctionBody,
-
-  emptyStatement,
-
-  enumConstantDeclaration,
-
-  enumDeclaration,
-
-  exportDirective,
-
-  expressionFunctionBody,
-
-  expressionStatement,
-
-  extendsClause,
-
-  extensionDeclaration,
-
-  fieldDeclaration,
-
-  fieldFormalParameter,
-
-  formalParameterList,
-
-  forEachPartsWithDeclaration,
-
-  forEachPartsWithIdentifier,
-
-  forElement,
-
-  forPartsWithDeclarations,
-
-  forPartsWithExpression,
-
-  forStatement,
-
-  functionDeclaration,
-
-  functionDeclarationStatement,
-
-  functionExpression,
-
-  functionExpressionInvocation,
-
-  functionTypeAlias,
-
-  functionTypedFormalParameter,
-
-  genericFunctionType,
-
-  genericTypeAlias,
-
-  hideCombinator,
-
-  ifElement,
-
-  ifStatement,
-
-  implementsClause,
-
-  importDirective,
-
-  instanceCreationExpression,
-
-  indexExpression,
-
-  integerLiteral,
-
-  interpolationExpression,
-
-  interpolationString,
-
-  isExpression,
-
-  label,
-
-  labeledStatement,
-
-  libraryDirective,
-
-  libraryIdentifier,
-
-  listLiteral,
-
-  mapLiteralEntry,
-
-  methodDeclaration,
-
-  methodInvocation,
-
-  mixinDeclaration,
-
-  namedExpression,
-
-  nativeClause,
-
-  nativeFunctionBody,
-
-  nullLiteral,
-
-  onClause,
-
-  parenthesizedExpression,
-
-  partDirective,
-
-  partOfDirective,
-
-  postfixExpression,
-
-  prefixExpression,
-
-  prefixedIdentifier,
-
-  propertyAccess,
-
-  redirectingConstructorInvocation,
-
-  rethrowExpression,
-
-  returnStatement,
-
-  setOrMapLiteral,
-
-  showCombinator,
-
-  simpleFormalParameter,
-
-  simpleIdentifier,
-
-  simpleStringLiteral,
-
-  spreadElement,
-
-  stringInterpolation,
-
-  superConstructorInvocation,
-
-  superExpression,
-
-  switchCase,
-
-  switchDefault,
-
-  switchStatement,
-
-  symbolLiteral,
-
-  thisExpression,
-
-  throwExpression,
-
-  topLevelVariableDeclaration,
-
-  tryStatement,
-
-  typeArgumentList,
-
-  typeName,
-
-  typeParameter,
-
-  typeParameterList,
-
-  variableDeclaration,
-
-  variableDeclarationList,
-
-  variableDeclarationStatement,
-
-  whileStatement,
-
-  withClause,
-
-  yieldStatement,
-
-  extensionOverride
-}
-
-/// Kinds of [LinkedNodeType]s.
-enum LinkedNodeTypeKind : byte {
-  dynamic_,
-
-  function,
-
-  interface,
-
-  never,
-
-  typeParameter,
-
-  void_
-}
-
-/// Enum used to indicate the kind of the error during top-level inference.
-enum TopLevelInferenceErrorKind : byte {
-  assignment,
-
-  instanceGetter,
-
-  dependencyCycle,
-
-  overrideConflictFieldType,
-
-  overrideNoCombinedSuperSignature
-}
-
-/// Enum of token types, corresponding to AST token types.
-enum UnlinkedTokenType : byte {
-  NOTHING,
-
-  ABSTRACT,
-
-  AMPERSAND,
-
-  AMPERSAND_AMPERSAND,
-
-  AMPERSAND_EQ,
-
-  AS,
-
-  ASSERT,
-
-  ASYNC,
-
-  AT,
-
-  AWAIT,
-
-  BACKPING,
-
-  BACKSLASH,
-
-  BANG,
-
-  BANG_EQ,
-
-  BANG_EQ_EQ,
-
-  BAR,
-
-  BAR_BAR,
-
-  BAR_EQ,
-
-  BREAK,
-
-  CARET,
-
-  CARET_EQ,
-
-  CASE,
-
-  CATCH,
-
-  CLASS,
-
-  CLOSE_CURLY_BRACKET,
-
-  CLOSE_PAREN,
-
-  CLOSE_SQUARE_BRACKET,
-
-  COLON,
-
-  COMMA,
-
-  CONST,
-
-  CONTINUE,
-
-  COVARIANT,
-
-  DEFAULT,
-
-  DEFERRED,
-
-  DO,
-
-  DOUBLE,
-
-  DYNAMIC,
-
-  ELSE,
-
-  ENUM,
-
-  EOF,
-
-  EQ,
-
-  EQ_EQ,
-
-  EQ_EQ_EQ,
-
-  EXPORT,
-
-  EXTENDS,
-
-  EXTERNAL,
-
-  FACTORY,
-
-  FALSE,
-
-  FINAL,
-
-  FINALLY,
-
-  FOR,
-
-  FUNCTION,
-
-  FUNCTION_KEYWORD,
-
-  GET,
-
-  GT,
-
-  GT_EQ,
-
-  GT_GT,
-
-  GT_GT_EQ,
-
-  GT_GT_GT,
-
-  GT_GT_GT_EQ,
-
-  HASH,
-
-  HEXADECIMAL,
-
-  HIDE,
-
-  IDENTIFIER,
-
-  IF,
-
-  IMPLEMENTS,
-
-  IMPORT,
-
-  IN,
-
-  INDEX,
-
-  INDEX_EQ,
-
-  INT,
-
-  INTERFACE,
-
-  IS,
-
-  LATE,
-
-  LIBRARY,
-
-  LT,
-
-  LT_EQ,
-
-  LT_LT,
-
-  LT_LT_EQ,
-
-  MINUS,
-
-  MINUS_EQ,
-
-  MINUS_MINUS,
-
-  MIXIN,
-
-  MULTI_LINE_COMMENT,
-
-  NATIVE,
-
-  NEW,
-
-  NULL,
-
-  OF,
-
-  ON,
-
-  OPEN_CURLY_BRACKET,
-
-  OPEN_PAREN,
-
-  OPEN_SQUARE_BRACKET,
-
-  OPERATOR,
-
-  PART,
-
-  PATCH,
-
-  PERCENT,
-
-  PERCENT_EQ,
-
-  PERIOD,
-
-  PERIOD_PERIOD,
-
-  PERIOD_PERIOD_PERIOD,
-
-  PERIOD_PERIOD_PERIOD_QUESTION,
-
-  PLUS,
-
-  PLUS_EQ,
-
-  PLUS_PLUS,
-
-  QUESTION,
-
-  QUESTION_PERIOD,
-
-  QUESTION_QUESTION,
-
-  QUESTION_QUESTION_EQ,
-
-  REQUIRED,
-
-  RETHROW,
-
-  RETURN,
-
-  SCRIPT_TAG,
-
-  SEMICOLON,
-
-  SET,
-
-  SHOW,
-
-  SINGLE_LINE_COMMENT,
-
-  SLASH,
-
-  SLASH_EQ,
-
-  SOURCE,
-
-  STAR,
-
-  STAR_EQ,
-
-  STATIC,
-
-  STRING,
-
-  STRING_INTERPOLATION_EXPRESSION,
-
-  STRING_INTERPOLATION_IDENTIFIER,
-
-  SUPER,
-
-  SWITCH,
-
-  SYNC,
-
-  THIS,
-
-  THROW,
-
-  TILDE,
-
-  TILDE_SLASH,
-
-  TILDE_SLASH_EQ,
-
-  TRUE,
-
-  TRY,
-
-  TYPEDEF,
-
-  VAR,
-
-  VOID,
-
-  WHILE,
-
-  WITH,
-
-  YIELD,
-
-  INOUT,
-
-  OUT
-}
-
 /// Information about the context of an exception in analysis driver.
 table AnalysisDriverExceptionContext {
   /// The exception string.
@@ -1010,17 +406,6 @@
   shows:[string] (id: 0);
 }
 
-/// Information about linked libraries, a group of libraries that form
-/// a library cycle.
-table CiderLinkedLibraryCycle {
-  bundle:LinkedNodeBundle (id: 1);
-
-  /// The hash signature for this linked cycle. It depends of API signatures
-  /// of all files in the cycle, and on the signatures of the transitive
-  /// closure of the cycle dependencies.
-  signature:[uint] (id: 0);
-}
-
 /// Errors for a single unit.
 table CiderUnitErrors {
   errors:[AnalysisDriverUnitError] (id: 1);
@@ -1063,257 +448,10 @@
   templateValues:[string] (id: 1);
 }
 
-table LinkedLanguageVersion {
-  major:uint (id: 0);
-
-  minor:uint (id: 1);
-}
-
-table LinkedLibraryLanguageVersion {
-  override2:LinkedLanguageVersion (id: 1);
-
-  package:LinkedLanguageVersion (id: 0);
-}
-
-/// Information about a linked AST node.
-table LinkedNode {
-  /// The explicit or inferred return type of a function typed node.
-  variantField_24:LinkedNodeType (id: 24);
-
-  variantField_2:[LinkedNode] (id: 2);
-
-  variantField_4:[LinkedNode] (id: 4);
-
-  variantField_6:LinkedNode (id: 6);
-
-  variantField_7:LinkedNode (id: 7);
-
-  variantField_17:uint (id: 17);
-
-  variantField_8:LinkedNode (id: 8);
-
-  variantField_38:LinkedNodeTypeSubstitution (id: 38);
-
-  variantField_15:uint (id: 15);
-
-  variantField_28:UnlinkedTokenType (id: 28);
-
-  variantField_27:bool (id: 27);
-
-  variantField_9:LinkedNode (id: 9);
-
-  variantField_12:LinkedNode (id: 12);
-
-  variantField_5:[LinkedNode] (id: 5);
-
-  variantField_13:LinkedNode (id: 13);
-
-  variantField_33:[string] (id: 33);
-
-  variantField_29:LinkedNodeCommentType (id: 29);
-
-  variantField_3:[LinkedNode] (id: 3);
-
-  variantField_41:[uint] (id: 41);
-
-  /// The language version information.
-  variantField_40:LinkedLibraryLanguageVersion (id: 40);
-
-  variantField_10:LinkedNode (id: 10);
-
-  variantField_26:LinkedNodeFormalParameterKind (id: 26);
-
-  variantField_21:double (id: 21);
-
-  variantField_25:LinkedNodeType (id: 25);
-
-  variantField_20:string (id: 20);
-
-  variantField_39:[LinkedNodeType] (id: 39);
-
-  flags:uint (id: 18);
-
-  variantField_1:string (id: 1);
-
-  variantField_36:uint (id: 36);
-
-  variantField_16:uint (id: 16);
-
-  variantField_30:string (id: 30);
-
-  variantField_14:LinkedNode (id: 14);
-
-  kind:LinkedNodeKind (id: 0);
-
-  variantField_31:bool (id: 31);
-
-  variantField_34:[string] (id: 34);
-
-  name:string (id: 37);
-
-  variantField_35:UnlinkedTokenType (id: 35);
-
-  variantField_32:TopLevelInferenceError (id: 32);
-
-  variantField_23:LinkedNodeType (id: 23);
-
-  variantField_11:LinkedNode (id: 11);
-
-  variantField_22:string (id: 22);
-
-  variantField_19:uint (id: 19);
-}
-
-/// Information about a group of libraries linked together, for example because
-/// they form a single cycle, or because they represent a single build artifact.
-table LinkedNodeBundle {
-  libraries:[LinkedNodeLibrary] (id: 1);
-
-  /// The shared list of references used in the [libraries].
-  references:LinkedNodeReferences (id: 0);
-}
-
-/// Information about a single library in a [LinkedNodeBundle].
-table LinkedNodeLibrary {
-  exports:[uint] (id: 2);
-
-  name:string (id: 3);
-
-  nameLength:uint (id: 5);
-
-  nameOffset:uint (id: 4);
-
-  units:[LinkedNodeUnit] (id: 1);
-
-  uriStr:string (id: 0);
-}
-
-/// Flattened tree of declarations referenced from [LinkedNode]s.
-table LinkedNodeReferences {
-  name:[string] (id: 1);
-
-  parent:[uint] (id: 0);
-}
-
-/// Information about a Dart type.
-table LinkedNodeType {
-  functionFormalParameters:[LinkedNodeTypeFormalParameter] (id: 0);
-
-  functionReturnType:LinkedNodeType (id: 1);
-
-  /// The typedef this function type is created for.
-  functionTypedef:uint (id: 9);
-
-  functionTypedefTypeArguments:[LinkedNodeType] (id: 10);
-
-  functionTypeParameters:[LinkedNodeTypeTypeParameter] (id: 2);
-
-  /// Reference to a [LinkedNodeReferences].
-  interfaceClass:uint (id: 3);
-
-  interfaceTypeArguments:[LinkedNodeType] (id: 4);
-
-  kind:LinkedNodeTypeKind (id: 5);
-
-  nullabilitySuffix:EntityRefNullabilitySuffix (id: 8);
-
-  typeParameterElement:uint (id: 6);
-
-  typeParameterId:uint (id: 7);
-}
-
-/// Information about a formal parameter in a function type.
-table LinkedNodeTypeFormalParameter {
-  kind:LinkedNodeFormalParameterKind (id: 0);
-
-  name:string (id: 1);
-
-  type:LinkedNodeType (id: 2);
-}
-
-/// Information about a type substitution.
-table LinkedNodeTypeSubstitution {
-  isLegacy:bool (id: 2);
-
-  typeArguments:[LinkedNodeType] (id: 1);
-
-  typeParameters:[uint] (id: 0);
-}
-
-/// Information about a type parameter in a function type.
-table LinkedNodeTypeTypeParameter {
-  bound:LinkedNodeType (id: 1);
-
-  name:string (id: 0);
-}
-
-/// Information about a single library in a [LinkedNodeLibrary].
-table LinkedNodeUnit {
-  isSynthetic:bool (id: 2);
-
-  node:LinkedNode (id: 1);
-
-  /// If the unit is a part, the URI specified in the `part` directive.
-  /// Otherwise empty.
-  partUriStr:string (id: 3);
-
-  /// The absolute URI.
-  uriStr:string (id: 0);
-}
-
 /// Summary information about a package.
 table PackageBundle {
   /// The version 2 of the summary.
-  bundle2:LinkedNodeBundle (id: 0);
-
-  /// The SDK specific data, if this bundle is for SDK.
-  sdk:PackageBundleSdk (id: 1);
-}
-
-/// Summary information about a package.
-table PackageBundleSdk {
-  /// The content of the `allowed_experiments.json` from SDK.
-  allowedExperimentsJson:string (id: 0);
-
-  /// The language version of the SDK.
-  languageVersion:LinkedLanguageVersion (id: 1);
-}
-
-/// Summary information about a top-level type inference error.
-table TopLevelInferenceError {
-  /// The [kind] specific arguments.
-  arguments:[string] (id: 1);
-
-  /// The kind of the error.
-  kind:TopLevelInferenceErrorKind (id: 0);
-}
-
-table UnlinkedInformativeData {
-  variantField_2:uint (id: 2);
-
-  variantField_3:uint (id: 3);
-
-  variantField_9:uint (id: 9);
-
-  variantField_8:uint (id: 8);
-
-  /// Offsets of the first character of each line in the source code.
-  variantField_7:[uint] (id: 7);
-
-  variantField_6:uint (id: 6);
-
-  variantField_5:uint (id: 5);
-
-  /// If the parameter has a default value, the source text of the constant
-  /// expression in the default value.  Otherwise the empty string.
-  variantField_10:string (id: 10);
-
-  variantField_1:uint (id: 1);
-
-  variantField_4:[string] (id: 4);
-
-  /// The kind of the node.
-  kind:LinkedNodeKind (id: 0);
+  fake:uint (id: 0);
 }
 
 /// Unlinked summary information about a namespace directive.
@@ -1357,13 +495,11 @@
   /// URIs of `import` directives.
   imports:[UnlinkedNamespaceDirective] (id: 2);
 
-  informativeData:[UnlinkedInformativeData] (id: 7);
-
   /// Offsets of the first character of each line in the source code.
   lineStarts:[uint] (id: 5);
 
   /// URI of the `part of` directive.
-  partOfUri:string (id: 8);
+  partOfUri:string (id: 7);
 
   /// URIs of `part` directives.
   parts:[string] (id: 4);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 4b84de9..bd9d540 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -40,7 +40,7 @@
 /// Except as otherwise noted, synthetic elements are not stored in the summary;
 /// they are re-synthesized at the time the summary is read.
 import 'base.dart' as base;
-import 'base.dart' show Id, TopLevel, Variant, VariantId;
+import 'base.dart' show Id, TopLevel;
 import 'format.dart' as generated;
 
 /// Annotation describing information which is not part of Dart semantics; in
@@ -448,23 +448,6 @@
   List<String> get shows;
 }
 
-/// Information about linked libraries, a group of libraries that form
-/// a library cycle.
-@TopLevel('CLNB')
-abstract class CiderLinkedLibraryCycle extends base.SummaryClass {
-  factory CiderLinkedLibraryCycle.fromBuffer(List<int> buffer) =>
-      generated.readCiderLinkedLibraryCycle(buffer);
-
-  @Id(1)
-  LinkedNodeBundle get bundle;
-
-  /// The hash signature for this linked cycle. It depends of API signatures
-  /// of all files in the cycle, and on the signatures of the transitive
-  /// closure of the cycle dependencies.
-  @Id(0)
-  List<int> get signature;
-}
-
 /// Errors for a single unit.
 @TopLevel('CUEr')
 abstract class CiderUnitErrors extends base.SummaryClass {
@@ -525,30 +508,6 @@
   List<String> get templateValues;
 }
 
-/// Enum representing nullability suffixes in summaries.
-///
-/// This enum is similar to [NullabilitySuffix], but the order is different so
-/// that [EntityRefNullabilitySuffix.starOrIrrelevant] can be the default.
-enum EntityRefNullabilitySuffix {
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `*`.  Types having this nullability suffix are
-  /// called "legacy types"; it has not yet been determined whether they should
-  /// be unioned with the Null type.
-  ///
-  /// Also used in circumstances where no nullability suffix information is
-  /// needed.
-  starOrIrrelevant,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration ends with `?`.  Types having this nullability suffix should
-  /// be interpreted as being unioned with the Null type.
-  question,
-
-  /// An indication that the canonical representation of the type under
-  /// consideration does not end with either `?` or `*`.
-  none,
-}
-
 /// Enum used to indicate the kind of an index relation.
 enum IndexRelationKind {
   /// Left: class.
@@ -635,1263 +594,6 @@
   unit
 }
 
-abstract class LinkedLanguageVersion extends base.SummaryClass {
-  @Id(0)
-  int get major;
-
-  @Id(1)
-  int get minor;
-}
-
-abstract class LinkedLibraryLanguageVersion extends base.SummaryClass {
-  @Id(1)
-  LinkedLanguageVersion get override2;
-
-  @Id(0)
-  LinkedLanguageVersion get package;
-}
-
-/// Information about a linked AST node.
-@Variant('kind')
-abstract class LinkedNode extends base.SummaryClass {
-  /// The explicit or inferred return type of a function typed node.
-  @VariantId(24, variantList: [
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionExpression,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericFunctionType,
-    LinkedNodeKind.methodDeclaration,
-  ])
-  LinkedNodeType get actualReturnType;
-
-  /// The explicit or inferred type of a variable.
-  @VariantId(24, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  LinkedNodeType get actualType;
-
-  @VariantId(2, variant: LinkedNodeKind.adjacentStrings)
-  List<LinkedNode> get adjacentStrings_strings;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.declaredIdentifier,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldDeclaration,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-    LinkedNodeKind.topLevelVariableDeclaration,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-    LinkedNodeKind.variableDeclarationList,
-  ])
-  List<LinkedNode> get annotatedNode_metadata;
-
-  @VariantId(6, variant: LinkedNodeKind.annotation)
-  LinkedNode get annotation_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.annotation)
-  LinkedNode get annotation_constructorName;
-
-  @VariantId(17, variant: LinkedNodeKind.annotation)
-  int get annotation_element;
-
-  @VariantId(8, variant: LinkedNodeKind.annotation)
-  LinkedNode get annotation_name;
-
-  @VariantId(38, variant: LinkedNodeKind.annotation)
-  LinkedNodeTypeSubstitution get annotation_substitution;
-
-  @VariantId(2, variant: LinkedNodeKind.argumentList)
-  List<LinkedNode> get argumentList_arguments;
-
-  @VariantId(6, variant: LinkedNodeKind.asExpression)
-  LinkedNode get asExpression_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.asExpression)
-  LinkedNode get asExpression_type;
-
-  @VariantId(6, variant: LinkedNodeKind.assertInitializer)
-  LinkedNode get assertInitializer_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.assertInitializer)
-  LinkedNode get assertInitializer_message;
-
-  @VariantId(6, variant: LinkedNodeKind.assertStatement)
-  LinkedNode get assertStatement_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.assertStatement)
-  LinkedNode get assertStatement_message;
-
-  @VariantId(15, variant: LinkedNodeKind.assignmentExpression)
-  int get assignmentExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.assignmentExpression)
-  LinkedNode get assignmentExpression_leftHandSide;
-
-  @VariantId(28, variant: LinkedNodeKind.assignmentExpression)
-  UnlinkedTokenType get assignmentExpression_operator;
-
-  @VariantId(7, variant: LinkedNodeKind.assignmentExpression)
-  LinkedNode get assignmentExpression_rightHandSide;
-
-  @VariantId(38, variant: LinkedNodeKind.assignmentExpression)
-  LinkedNodeTypeSubstitution get assignmentExpression_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.awaitExpression)
-  LinkedNode get awaitExpression_expression;
-
-  @VariantId(15, variant: LinkedNodeKind.binaryExpression)
-  int get binaryExpression_element;
-
-  @VariantId(24, variant: LinkedNodeKind.binaryExpression)
-  LinkedNodeType get binaryExpression_invokeType;
-
-  @VariantId(6, variant: LinkedNodeKind.binaryExpression)
-  LinkedNode get binaryExpression_leftOperand;
-
-  @VariantId(28, variant: LinkedNodeKind.binaryExpression)
-  UnlinkedTokenType get binaryExpression_operator;
-
-  @VariantId(7, variant: LinkedNodeKind.binaryExpression)
-  LinkedNode get binaryExpression_rightOperand;
-
-  @VariantId(38, variant: LinkedNodeKind.binaryExpression)
-  LinkedNodeTypeSubstitution get binaryExpression_substitution;
-
-  @VariantId(2, variant: LinkedNodeKind.block)
-  List<LinkedNode> get block_statements;
-
-  @VariantId(6, variant: LinkedNodeKind.blockFunctionBody)
-  LinkedNode get blockFunctionBody_block;
-
-  @VariantId(27, variant: LinkedNodeKind.booleanLiteral)
-  bool get booleanLiteral_value;
-
-  @VariantId(6, variant: LinkedNodeKind.breakStatement)
-  LinkedNode get breakStatement_label;
-
-  @VariantId(2, variant: LinkedNodeKind.cascadeExpression)
-  List<LinkedNode> get cascadeExpression_sections;
-
-  @VariantId(6, variant: LinkedNodeKind.cascadeExpression)
-  LinkedNode get cascadeExpression_target;
-
-  @VariantId(6, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_body;
-
-  @VariantId(7, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_exceptionParameter;
-
-  @VariantId(8, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_exceptionType;
-
-  @VariantId(9, variant: LinkedNodeKind.catchClause)
-  LinkedNode get catchClause_stackTraceParameter;
-
-  @VariantId(6, variant: LinkedNodeKind.classDeclaration)
-  LinkedNode get classDeclaration_extendsClause;
-
-  @VariantId(27, variant: LinkedNodeKind.classDeclaration)
-  bool get classDeclaration_isDartObject;
-
-  @VariantId(8, variant: LinkedNodeKind.classDeclaration)
-  LinkedNode get classDeclaration_nativeClause;
-
-  @VariantId(7, variant: LinkedNodeKind.classDeclaration)
-  LinkedNode get classDeclaration_withClause;
-
-  @VariantId(12, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  LinkedNode get classOrMixinDeclaration_implementsClause;
-
-  @VariantId(5, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  List<LinkedNode> get classOrMixinDeclaration_members;
-
-  @VariantId(13, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  LinkedNode get classOrMixinDeclaration_typeParameters;
-
-  @VariantId(9, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_implementsClause;
-
-  @VariantId(7, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_superclass;
-
-  @VariantId(6, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_typeParameters;
-
-  @VariantId(8, variant: LinkedNodeKind.classTypeAlias)
-  LinkedNode get classTypeAlias_withClause;
-
-  @VariantId(2, variant: LinkedNodeKind.comment)
-  List<LinkedNode> get comment_references;
-
-  @VariantId(33, variant: LinkedNodeKind.comment)
-  List<String> get comment_tokens;
-
-  @VariantId(29, variant: LinkedNodeKind.comment)
-  LinkedNodeCommentType get comment_type;
-
-  @VariantId(6, variant: LinkedNodeKind.commentReference)
-  LinkedNode get commentReference_identifier;
-
-  @VariantId(2, variant: LinkedNodeKind.compilationUnit)
-  List<LinkedNode> get compilationUnit_declarations;
-
-  @VariantId(3, variant: LinkedNodeKind.compilationUnit)
-  List<LinkedNode> get compilationUnit_directives;
-
-  @VariantId(41, variant: LinkedNodeKind.compilationUnit)
-  List<int> get compilationUnit_featureSet;
-
-  /// The language version information.
-  @VariantId(40, variant: LinkedNodeKind.compilationUnit)
-  LinkedLibraryLanguageVersion get compilationUnit_languageVersion;
-
-  @VariantId(6, variant: LinkedNodeKind.compilationUnit)
-  LinkedNode get compilationUnit_scriptTag;
-
-  @VariantId(6, variant: LinkedNodeKind.conditionalExpression)
-  LinkedNode get conditionalExpression_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.conditionalExpression)
-  LinkedNode get conditionalExpression_elseExpression;
-
-  @VariantId(8, variant: LinkedNodeKind.conditionalExpression)
-  LinkedNode get conditionalExpression_thenExpression;
-
-  @VariantId(6, variant: LinkedNodeKind.configuration)
-  LinkedNode get configuration_name;
-
-  @VariantId(8, variant: LinkedNodeKind.configuration)
-  LinkedNode get configuration_uri;
-
-  @VariantId(7, variant: LinkedNodeKind.configuration)
-  LinkedNode get configuration_value;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_body;
-
-  @VariantId(2, variant: LinkedNodeKind.constructorDeclaration)
-  List<LinkedNode> get constructorDeclaration_initializers;
-
-  @VariantId(8, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_parameters;
-
-  @VariantId(9, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_redirectedConstructor;
-
-  @VariantId(10, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_returnType;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorFieldInitializer)
-  LinkedNode get constructorFieldInitializer_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.constructorFieldInitializer)
-  LinkedNode get constructorFieldInitializer_fieldName;
-
-  @VariantId(15, variant: LinkedNodeKind.constructorName)
-  int get constructorName_element;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorName)
-  LinkedNode get constructorName_name;
-
-  @VariantId(38, variant: LinkedNodeKind.constructorName)
-  LinkedNodeTypeSubstitution get constructorName_substitution;
-
-  @VariantId(7, variant: LinkedNodeKind.constructorName)
-  LinkedNode get constructorName_type;
-
-  @VariantId(6, variant: LinkedNodeKind.continueStatement)
-  LinkedNode get continueStatement_label;
-
-  @VariantId(6, variant: LinkedNodeKind.declaredIdentifier)
-  LinkedNode get declaredIdentifier_identifier;
-
-  @VariantId(7, variant: LinkedNodeKind.declaredIdentifier)
-  LinkedNode get declaredIdentifier_type;
-
-  @VariantId(6, variant: LinkedNodeKind.defaultFormalParameter)
-  LinkedNode get defaultFormalParameter_defaultValue;
-
-  @VariantId(26, variant: LinkedNodeKind.defaultFormalParameter)
-  LinkedNodeFormalParameterKind get defaultFormalParameter_kind;
-
-  @VariantId(7, variant: LinkedNodeKind.defaultFormalParameter)
-  LinkedNode get defaultFormalParameter_parameter;
-
-  @VariantId(6, variant: LinkedNodeKind.doStatement)
-  LinkedNode get doStatement_body;
-
-  @VariantId(7, variant: LinkedNodeKind.doStatement)
-  LinkedNode get doStatement_condition;
-
-  @VariantId(2, variant: LinkedNodeKind.dottedName)
-  List<LinkedNode> get dottedName_components;
-
-  @VariantId(21, variant: LinkedNodeKind.doubleLiteral)
-  double get doubleLiteral_value;
-
-  @VariantId(15, variant: LinkedNodeKind.emptyFunctionBody)
-  int get emptyFunctionBody_fake;
-
-  @VariantId(15, variant: LinkedNodeKind.emptyStatement)
-  int get emptyStatement_fake;
-
-  @VariantId(2, variant: LinkedNodeKind.enumDeclaration)
-  List<LinkedNode> get enumDeclaration_constants;
-
-  @VariantId(25, variantList: [
-    LinkedNodeKind.assignmentExpression,
-    LinkedNodeKind.asExpression,
-    LinkedNodeKind.awaitExpression,
-    LinkedNodeKind.binaryExpression,
-    LinkedNodeKind.cascadeExpression,
-    LinkedNodeKind.conditionalExpression,
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.indexExpression,
-    LinkedNodeKind.instanceCreationExpression,
-    LinkedNodeKind.integerLiteral,
-    LinkedNodeKind.listLiteral,
-    LinkedNodeKind.methodInvocation,
-    LinkedNodeKind.nullLiteral,
-    LinkedNodeKind.parenthesizedExpression,
-    LinkedNodeKind.prefixExpression,
-    LinkedNodeKind.prefixedIdentifier,
-    LinkedNodeKind.propertyAccess,
-    LinkedNodeKind.postfixExpression,
-    LinkedNodeKind.rethrowExpression,
-    LinkedNodeKind.setOrMapLiteral,
-    LinkedNodeKind.simpleIdentifier,
-    LinkedNodeKind.superExpression,
-    LinkedNodeKind.symbolLiteral,
-    LinkedNodeKind.thisExpression,
-    LinkedNodeKind.throwExpression,
-  ])
-  LinkedNodeType get expression_type;
-
-  @VariantId(6, variant: LinkedNodeKind.expressionFunctionBody)
-  LinkedNode get expressionFunctionBody_expression;
-
-  @VariantId(6, variant: LinkedNodeKind.expressionStatement)
-  LinkedNode get expressionStatement_expression;
-
-  @VariantId(6, variant: LinkedNodeKind.extendsClause)
-  LinkedNode get extendsClause_superclass;
-
-  @VariantId(7, variant: LinkedNodeKind.extensionDeclaration)
-  LinkedNode get extensionDeclaration_extendedType;
-
-  @VariantId(5, variant: LinkedNodeKind.extensionDeclaration)
-  List<LinkedNode> get extensionDeclaration_members;
-
-  @VariantId(20, variant: LinkedNodeKind.extensionDeclaration)
-  String get extensionDeclaration_refName;
-
-  @VariantId(6, variant: LinkedNodeKind.extensionDeclaration)
-  LinkedNode get extensionDeclaration_typeParameters;
-
-  @VariantId(2, variant: LinkedNodeKind.extensionOverride)
-  List<LinkedNode> get extensionOverride_arguments;
-
-  @VariantId(24, variant: LinkedNodeKind.extensionOverride)
-  LinkedNodeType get extensionOverride_extendedType;
-
-  @VariantId(7, variant: LinkedNodeKind.extensionOverride)
-  LinkedNode get extensionOverride_extensionName;
-
-  @VariantId(8, variant: LinkedNodeKind.extensionOverride)
-  LinkedNode get extensionOverride_typeArguments;
-
-  @VariantId(39, variant: LinkedNodeKind.extensionOverride)
-  List<LinkedNodeType> get extensionOverride_typeArgumentTypes;
-
-  @VariantId(6, variant: LinkedNodeKind.fieldDeclaration)
-  LinkedNode get fieldDeclaration_fields;
-
-  @VariantId(8, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNode get fieldFormalParameter_formalParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNode get fieldFormalParameter_type;
-
-  @VariantId(7, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNode get fieldFormalParameter_typeParameters;
-
-  @Id(18)
-  int get flags;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.forEachPartsWithDeclaration,
-    LinkedNodeKind.forEachPartsWithIdentifier,
-  ])
-  LinkedNode get forEachParts_iterable;
-
-  @VariantId(7, variant: LinkedNodeKind.forEachPartsWithDeclaration)
-  LinkedNode get forEachPartsWithDeclaration_loopVariable;
-
-  @VariantId(7, variant: LinkedNodeKind.forEachPartsWithIdentifier)
-  LinkedNode get forEachPartsWithIdentifier_identifier;
-
-  @VariantId(7, variant: LinkedNodeKind.forElement)
-  LinkedNode get forElement_body;
-
-  @VariantId(2, variant: LinkedNodeKind.formalParameterList)
-  List<LinkedNode> get formalParameterList_parameters;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.forElement,
-    LinkedNodeKind.forStatement,
-  ])
-  LinkedNode get forMixin_forLoopParts;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.forPartsWithDeclarations,
-    LinkedNodeKind.forPartsWithExpression,
-  ])
-  LinkedNode get forParts_condition;
-
-  @VariantId(5, variantList: [
-    LinkedNodeKind.forPartsWithDeclarations,
-    LinkedNodeKind.forPartsWithExpression,
-  ])
-  List<LinkedNode> get forParts_updaters;
-
-  @VariantId(7, variant: LinkedNodeKind.forPartsWithDeclarations)
-  LinkedNode get forPartsWithDeclarations_variables;
-
-  @VariantId(7, variant: LinkedNodeKind.forPartsWithExpression)
-  LinkedNode get forPartsWithExpression_initialization;
-
-  @VariantId(7, variant: LinkedNodeKind.forStatement)
-  LinkedNode get forStatement_body;
-
-  @VariantId(6, variant: LinkedNodeKind.functionDeclaration)
-  LinkedNode get functionDeclaration_functionExpression;
-
-  @VariantId(7, variant: LinkedNodeKind.functionDeclaration)
-  LinkedNode get functionDeclaration_returnType;
-
-  @VariantId(6, variant: LinkedNodeKind.functionDeclarationStatement)
-  LinkedNode get functionDeclarationStatement_functionDeclaration;
-
-  @VariantId(6, variant: LinkedNodeKind.functionExpression)
-  LinkedNode get functionExpression_body;
-
-  @VariantId(7, variant: LinkedNodeKind.functionExpression)
-  LinkedNode get functionExpression_formalParameters;
-
-  @VariantId(8, variant: LinkedNodeKind.functionExpression)
-  LinkedNode get functionExpression_typeParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.functionExpressionInvocation)
-  LinkedNode get functionExpressionInvocation_function;
-
-  @VariantId(6, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNode get functionTypeAlias_formalParameters;
-
-  @VariantId(7, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNode get functionTypeAlias_returnType;
-
-  @VariantId(8, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNode get functionTypeAlias_typeParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNode get functionTypedFormalParameter_formalParameters;
-
-  @VariantId(7, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNode get functionTypedFormalParameter_returnType;
-
-  @VariantId(8, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNode get functionTypedFormalParameter_typeParameters;
-
-  @VariantId(8, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNode get genericFunctionType_formalParameters;
-
-  @VariantId(17, variant: LinkedNodeKind.genericFunctionType)
-  int get genericFunctionType_id;
-
-  @VariantId(7, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNode get genericFunctionType_returnType;
-
-  @VariantId(25, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNodeType get genericFunctionType_type;
-
-  @VariantId(6, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNode get genericFunctionType_typeParameters;
-
-  @VariantId(7, variant: LinkedNodeKind.genericTypeAlias)
-  LinkedNode get genericTypeAlias_functionType;
-
-  @VariantId(6, variant: LinkedNodeKind.genericTypeAlias)
-  LinkedNode get genericTypeAlias_typeParameters;
-
-  @VariantId(9, variant: LinkedNodeKind.ifElement)
-  LinkedNode get ifElement_elseElement;
-
-  @VariantId(8, variant: LinkedNodeKind.ifElement)
-  LinkedNode get ifElement_thenElement;
-
-  @VariantId(6, variantList: [
-    LinkedNodeKind.ifElement,
-    LinkedNodeKind.ifStatement,
-  ])
-  LinkedNode get ifMixin_condition;
-
-  @VariantId(7, variant: LinkedNodeKind.ifStatement)
-  LinkedNode get ifStatement_elseStatement;
-
-  @VariantId(8, variant: LinkedNodeKind.ifStatement)
-  LinkedNode get ifStatement_thenStatement;
-
-  @VariantId(2, variant: LinkedNodeKind.implementsClause)
-  List<LinkedNode> get implementsClause_interfaces;
-
-  @VariantId(1, variant: LinkedNodeKind.importDirective)
-  String get importDirective_prefix;
-
-  @VariantId(15, variant: LinkedNodeKind.indexExpression)
-  int get indexExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.indexExpression)
-  LinkedNode get indexExpression_index;
-
-  @VariantId(38, variant: LinkedNodeKind.indexExpression)
-  LinkedNodeTypeSubstitution get indexExpression_substitution;
-
-  @VariantId(7, variant: LinkedNodeKind.indexExpression)
-  LinkedNode get indexExpression_target;
-
-  @VariantId(36, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.defaultFormalParameter,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-    LinkedNodeKind.showCombinator,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.topLevelVariableDeclaration,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-    LinkedNodeKind.variableDeclarationList,
-  ])
-  @informative
-  int get informativeId;
-
-  @VariantId(27, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  bool get inheritsCovariant;
-
-  @VariantId(2, variant: LinkedNodeKind.instanceCreationExpression)
-  List<LinkedNode> get instanceCreationExpression_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.instanceCreationExpression)
-  LinkedNode get instanceCreationExpression_constructorName;
-
-  @VariantId(8, variant: LinkedNodeKind.instanceCreationExpression)
-  LinkedNode get instanceCreationExpression_typeArguments;
-
-  @VariantId(16, variant: LinkedNodeKind.integerLiteral)
-  int get integerLiteral_value;
-
-  @VariantId(6, variant: LinkedNodeKind.interpolationExpression)
-  LinkedNode get interpolationExpression_expression;
-
-  @VariantId(30, variant: LinkedNodeKind.interpolationString)
-  String get interpolationString_value;
-
-  @VariantId(14, variantList: [
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.methodInvocation,
-  ])
-  LinkedNode get invocationExpression_arguments;
-
-  @VariantId(24, variantList: [
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.methodInvocation,
-  ])
-  LinkedNodeType get invocationExpression_invokeType;
-
-  @VariantId(12, variantList: [
-    LinkedNodeKind.functionExpressionInvocation,
-    LinkedNodeKind.methodInvocation,
-  ])
-  LinkedNode get invocationExpression_typeArguments;
-
-  @VariantId(6, variant: LinkedNodeKind.isExpression)
-  LinkedNode get isExpression_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.isExpression)
-  LinkedNode get isExpression_type;
-
-  @Id(0)
-  LinkedNodeKind get kind;
-
-  @VariantId(6, variant: LinkedNodeKind.label)
-  LinkedNode get label_label;
-
-  @VariantId(2, variant: LinkedNodeKind.labeledStatement)
-  List<LinkedNode> get labeledStatement_labels;
-
-  @VariantId(6, variant: LinkedNodeKind.labeledStatement)
-  LinkedNode get labeledStatement_statement;
-
-  @VariantId(6, variant: LinkedNodeKind.libraryDirective)
-  LinkedNode get libraryDirective_name;
-
-  @VariantId(2, variant: LinkedNodeKind.libraryIdentifier)
-  List<LinkedNode> get libraryIdentifier_components;
-
-  @VariantId(3, variant: LinkedNodeKind.listLiteral)
-  List<LinkedNode> get listLiteral_elements;
-
-  @VariantId(6, variant: LinkedNodeKind.mapLiteralEntry)
-  LinkedNode get mapLiteralEntry_key;
-
-  @VariantId(7, variant: LinkedNodeKind.mapLiteralEntry)
-  LinkedNode get mapLiteralEntry_value;
-
-  @VariantId(6, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_body;
-
-  @VariantId(7, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_formalParameters;
-
-  @VariantId(31, variant: LinkedNodeKind.methodDeclaration)
-  bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject;
-
-  @VariantId(8, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_returnType;
-
-  @VariantId(9, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_typeParameters;
-
-  @VariantId(6, variant: LinkedNodeKind.methodInvocation)
-  LinkedNode get methodInvocation_methodName;
-
-  @VariantId(7, variant: LinkedNodeKind.methodInvocation)
-  LinkedNode get methodInvocation_target;
-
-  @VariantId(6, variant: LinkedNodeKind.mixinDeclaration)
-  LinkedNode get mixinDeclaration_onClause;
-
-  @VariantId(34, variant: LinkedNodeKind.mixinDeclaration)
-  List<String> get mixinDeclaration_superInvokedNames;
-
-  @Id(37)
-  String get name;
-
-  @VariantId(6, variant: LinkedNodeKind.namedExpression)
-  LinkedNode get namedExpression_expression;
-
-  @VariantId(7, variant: LinkedNodeKind.namedExpression)
-  LinkedNode get namedExpression_name;
-
-  @VariantId(34, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-    LinkedNodeKind.symbolLiteral,
-  ])
-  List<String> get names;
-
-  @VariantId(2, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-  ])
-  List<LinkedNode> get namespaceDirective_combinators;
-
-  @VariantId(3, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-  ])
-  List<LinkedNode> get namespaceDirective_configurations;
-
-  @VariantId(20, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-  ])
-  String get namespaceDirective_selectedUri;
-
-  @VariantId(6, variant: LinkedNodeKind.nativeClause)
-  LinkedNode get nativeClause_name;
-
-  @VariantId(6, variant: LinkedNodeKind.nativeFunctionBody)
-  LinkedNode get nativeFunctionBody_stringLiteral;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-  ])
-  List<LinkedNode> get normalFormalParameter_metadata;
-
-  @VariantId(15, variant: LinkedNodeKind.nullLiteral)
-  int get nullLiteral_fake;
-
-  @VariantId(2, variant: LinkedNodeKind.onClause)
-  List<LinkedNode> get onClause_superclassConstraints;
-
-  @VariantId(6, variant: LinkedNodeKind.parenthesizedExpression)
-  LinkedNode get parenthesizedExpression_expression;
-
-  @VariantId(6, variant: LinkedNodeKind.partOfDirective)
-  LinkedNode get partOfDirective_libraryName;
-
-  @VariantId(7, variant: LinkedNodeKind.partOfDirective)
-  LinkedNode get partOfDirective_uri;
-
-  @VariantId(15, variant: LinkedNodeKind.postfixExpression)
-  int get postfixExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.postfixExpression)
-  LinkedNode get postfixExpression_operand;
-
-  @VariantId(28, variant: LinkedNodeKind.postfixExpression)
-  UnlinkedTokenType get postfixExpression_operator;
-
-  @VariantId(38, variant: LinkedNodeKind.postfixExpression)
-  LinkedNodeTypeSubstitution get postfixExpression_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.prefixedIdentifier)
-  LinkedNode get prefixedIdentifier_identifier;
-
-  @VariantId(7, variant: LinkedNodeKind.prefixedIdentifier)
-  LinkedNode get prefixedIdentifier_prefix;
-
-  @VariantId(15, variant: LinkedNodeKind.prefixExpression)
-  int get prefixExpression_element;
-
-  @VariantId(6, variant: LinkedNodeKind.prefixExpression)
-  LinkedNode get prefixExpression_operand;
-
-  @VariantId(28, variant: LinkedNodeKind.prefixExpression)
-  UnlinkedTokenType get prefixExpression_operator;
-
-  @VariantId(38, variant: LinkedNodeKind.prefixExpression)
-  LinkedNodeTypeSubstitution get prefixExpression_substitution;
-
-  @VariantId(28, variant: LinkedNodeKind.propertyAccess)
-  UnlinkedTokenType get propertyAccess_operator;
-
-  @VariantId(6, variant: LinkedNodeKind.propertyAccess)
-  LinkedNode get propertyAccess_propertyName;
-
-  @VariantId(7, variant: LinkedNodeKind.propertyAccess)
-  LinkedNode get propertyAccess_target;
-
-  @VariantId(6, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  LinkedNode get redirectingConstructorInvocation_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  LinkedNode get redirectingConstructorInvocation_constructorName;
-
-  @VariantId(15, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  int get redirectingConstructorInvocation_element;
-
-  @VariantId(38, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  LinkedNodeTypeSubstitution get redirectingConstructorInvocation_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.returnStatement)
-  LinkedNode get returnStatement_expression;
-
-  @VariantId(3, variant: LinkedNodeKind.setOrMapLiteral)
-  List<LinkedNode> get setOrMapLiteral_elements;
-
-  @VariantId(6, variant: LinkedNodeKind.simpleFormalParameter)
-  LinkedNode get simpleFormalParameter_type;
-
-  @VariantId(15, variant: LinkedNodeKind.simpleIdentifier)
-  int get simpleIdentifier_element;
-
-  @VariantId(38, variant: LinkedNodeKind.simpleIdentifier)
-  LinkedNodeTypeSubstitution get simpleIdentifier_substitution;
-
-  @VariantId(20, variant: LinkedNodeKind.simpleStringLiteral)
-  String get simpleStringLiteral_value;
-
-  @VariantId(31, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  bool get simplyBoundable_isSimplyBounded;
-
-  @VariantId(6, variant: LinkedNodeKind.spreadElement)
-  LinkedNode get spreadElement_expression;
-
-  @VariantId(35, variant: LinkedNodeKind.spreadElement)
-  UnlinkedTokenType get spreadElement_spreadOperator;
-
-  @VariantId(2, variant: LinkedNodeKind.stringInterpolation)
-  List<LinkedNode> get stringInterpolation_elements;
-
-  @VariantId(6, variant: LinkedNodeKind.superConstructorInvocation)
-  LinkedNode get superConstructorInvocation_arguments;
-
-  @VariantId(7, variant: LinkedNodeKind.superConstructorInvocation)
-  LinkedNode get superConstructorInvocation_constructorName;
-
-  @VariantId(15, variant: LinkedNodeKind.superConstructorInvocation)
-  int get superConstructorInvocation_element;
-
-  @VariantId(38, variant: LinkedNodeKind.superConstructorInvocation)
-  LinkedNodeTypeSubstitution get superConstructorInvocation_substitution;
-
-  @VariantId(6, variant: LinkedNodeKind.switchCase)
-  LinkedNode get switchCase_expression;
-
-  @VariantId(3, variantList: [
-    LinkedNodeKind.switchCase,
-    LinkedNodeKind.switchDefault,
-  ])
-  List<LinkedNode> get switchMember_labels;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.switchCase,
-    LinkedNodeKind.switchDefault,
-  ])
-  List<LinkedNode> get switchMember_statements;
-
-  @VariantId(7, variant: LinkedNodeKind.switchStatement)
-  LinkedNode get switchStatement_expression;
-
-  @VariantId(2, variant: LinkedNodeKind.switchStatement)
-  List<LinkedNode> get switchStatement_members;
-
-  @VariantId(6, variant: LinkedNodeKind.throwExpression)
-  LinkedNode get throwExpression_expression;
-
-  @VariantId(32, variantList: [
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  TopLevelInferenceError get topLevelTypeInferenceError;
-
-  @VariantId(6, variant: LinkedNodeKind.topLevelVariableDeclaration)
-  LinkedNode get topLevelVariableDeclaration_variableList;
-
-  @VariantId(6, variant: LinkedNodeKind.tryStatement)
-  LinkedNode get tryStatement_body;
-
-  @VariantId(2, variant: LinkedNodeKind.tryStatement)
-  List<LinkedNode> get tryStatement_catchClauses;
-
-  @VariantId(7, variant: LinkedNodeKind.tryStatement)
-  LinkedNode get tryStatement_finallyBlock;
-
-  @VariantId(27, variantList: [
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-  ])
-  bool get typeAlias_hasSelfReference;
-
-  @VariantId(2, variant: LinkedNodeKind.typeArgumentList)
-  List<LinkedNode> get typeArgumentList_arguments;
-
-  @VariantId(2, variantList: [
-    LinkedNodeKind.listLiteral,
-    LinkedNodeKind.setOrMapLiteral,
-  ])
-  List<LinkedNode> get typedLiteral_typeArguments;
-
-  @VariantId(6, variant: LinkedNodeKind.typeName)
-  LinkedNode get typeName_name;
-
-  @VariantId(23, variant: LinkedNodeKind.typeName)
-  LinkedNodeType get typeName_type;
-
-  @VariantId(2, variant: LinkedNodeKind.typeName)
-  List<LinkedNode> get typeName_typeArguments;
-
-  @VariantId(6, variant: LinkedNodeKind.typeParameter)
-  LinkedNode get typeParameter_bound;
-
-  @VariantId(23, variant: LinkedNodeKind.typeParameter)
-  LinkedNodeType get typeParameter_defaultType;
-
-  @VariantId(15, variant: LinkedNodeKind.typeParameter)
-  int get typeParameter_variance;
-
-  @VariantId(2, variant: LinkedNodeKind.typeParameterList)
-  List<LinkedNode> get typeParameterList_typeParameters;
-
-  @VariantId(11, variantList: [
-    LinkedNodeKind.classDeclaration,
-  ])
-  LinkedNode get unused11;
-
-  @VariantId(14, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.partDirective,
-  ])
-  LinkedNode get uriBasedDirective_uri;
-
-  @VariantId(22, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.partDirective,
-  ])
-  String get uriBasedDirective_uriContent;
-
-  @VariantId(19, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.partDirective,
-  ])
-  int get uriBasedDirective_uriElement;
-
-  @VariantId(6, variant: LinkedNodeKind.variableDeclaration)
-  LinkedNode get variableDeclaration_initializer;
-
-  @VariantId(6, variant: LinkedNodeKind.variableDeclarationList)
-  LinkedNode get variableDeclarationList_type;
-
-  @VariantId(2, variant: LinkedNodeKind.variableDeclarationList)
-  List<LinkedNode> get variableDeclarationList_variables;
-
-  @VariantId(6, variant: LinkedNodeKind.variableDeclarationStatement)
-  LinkedNode get variableDeclarationStatement_variables;
-
-  @VariantId(6, variant: LinkedNodeKind.whileStatement)
-  LinkedNode get whileStatement_body;
-
-  @VariantId(7, variant: LinkedNodeKind.whileStatement)
-  LinkedNode get whileStatement_condition;
-
-  @VariantId(2, variant: LinkedNodeKind.withClause)
-  List<LinkedNode> get withClause_mixinTypes;
-
-  @VariantId(6, variant: LinkedNodeKind.yieldStatement)
-  LinkedNode get yieldStatement_expression;
-}
-
-/// Information about a group of libraries linked together, for example because
-/// they form a single cycle, or because they represent a single build artifact.
-@TopLevel('LNBn')
-abstract class LinkedNodeBundle extends base.SummaryClass {
-  factory LinkedNodeBundle.fromBuffer(List<int> buffer) =>
-      generated.readLinkedNodeBundle(buffer);
-  @Id(1)
-  List<LinkedNodeLibrary> get libraries;
-
-  /// The shared list of references used in the [libraries].
-  @Id(0)
-  LinkedNodeReferences get references;
-}
-
-/// Types of comments.
-enum LinkedNodeCommentType { block, documentation, endOfLine }
-
-/// Kinds of formal parameters.
-enum LinkedNodeFormalParameterKind {
-  requiredPositional,
-  optionalPositional,
-  optionalNamed,
-  requiredNamed
-}
-
-/// Kinds of [LinkedNode].
-enum LinkedNodeKind {
-  adjacentStrings,
-  annotation,
-  argumentList,
-  asExpression,
-  assertInitializer,
-  assertStatement,
-  assignmentExpression,
-  awaitExpression,
-  binaryExpression,
-  block,
-  blockFunctionBody,
-  booleanLiteral,
-  breakStatement,
-  cascadeExpression,
-  catchClause,
-  classDeclaration,
-  classTypeAlias,
-  comment,
-  commentReference,
-  compilationUnit,
-  conditionalExpression,
-  configuration,
-  constructorDeclaration,
-  constructorFieldInitializer,
-  constructorName,
-  continueStatement,
-  declaredIdentifier,
-  defaultFormalParameter,
-  doubleLiteral,
-  doStatement,
-  dottedName,
-  emptyFunctionBody,
-  emptyStatement,
-  enumConstantDeclaration,
-  enumDeclaration,
-  exportDirective,
-  expressionFunctionBody,
-  expressionStatement,
-  extendsClause,
-  extensionDeclaration,
-  fieldDeclaration,
-  fieldFormalParameter,
-  formalParameterList,
-  forEachPartsWithDeclaration,
-  forEachPartsWithIdentifier,
-  forElement,
-  forPartsWithDeclarations,
-  forPartsWithExpression,
-  forStatement,
-  functionDeclaration,
-  functionDeclarationStatement,
-  functionExpression,
-  functionExpressionInvocation,
-  functionTypeAlias,
-  functionTypedFormalParameter,
-  genericFunctionType,
-  genericTypeAlias,
-  hideCombinator,
-  ifElement,
-  ifStatement,
-  implementsClause,
-  importDirective,
-  instanceCreationExpression,
-  indexExpression,
-  integerLiteral,
-  interpolationExpression,
-  interpolationString,
-  isExpression,
-  label,
-  labeledStatement,
-  libraryDirective,
-  libraryIdentifier,
-  listLiteral,
-  mapLiteralEntry,
-  methodDeclaration,
-  methodInvocation,
-  mixinDeclaration,
-  namedExpression,
-  nativeClause,
-  nativeFunctionBody,
-  nullLiteral,
-  onClause,
-  parenthesizedExpression,
-  partDirective,
-  partOfDirective,
-  postfixExpression,
-  prefixExpression,
-  prefixedIdentifier,
-  propertyAccess,
-  redirectingConstructorInvocation,
-  rethrowExpression,
-  returnStatement,
-  setOrMapLiteral,
-  showCombinator,
-  simpleFormalParameter,
-  simpleIdentifier,
-  simpleStringLiteral,
-  spreadElement,
-  stringInterpolation,
-  superConstructorInvocation,
-  superExpression,
-  switchCase,
-  switchDefault,
-  switchStatement,
-  symbolLiteral,
-  thisExpression,
-  throwExpression,
-  topLevelVariableDeclaration,
-  tryStatement,
-  typeArgumentList,
-  typeName,
-  typeParameter,
-  typeParameterList,
-  variableDeclaration,
-  variableDeclarationList,
-  variableDeclarationStatement,
-  whileStatement,
-  withClause,
-  yieldStatement,
-  extensionOverride,
-}
-
-/// Information about a single library in a [LinkedNodeBundle].
-abstract class LinkedNodeLibrary extends base.SummaryClass {
-  @Id(2)
-  List<int> get exports;
-
-  @Id(3)
-  String get name;
-
-  @Id(5)
-  int get nameLength;
-
-  @Id(4)
-  int get nameOffset;
-
-  @Id(1)
-  List<LinkedNodeUnit> get units;
-
-  @Id(0)
-  String get uriStr;
-}
-
-/// Flattened tree of declarations referenced from [LinkedNode]s.
-abstract class LinkedNodeReferences extends base.SummaryClass {
-  @Id(1)
-  List<String> get name;
-
-  @Id(0)
-  List<int> get parent;
-}
-
-/// Information about a Dart type.
-abstract class LinkedNodeType extends base.SummaryClass {
-  @Id(0)
-  List<LinkedNodeTypeFormalParameter> get functionFormalParameters;
-
-  @Id(1)
-  LinkedNodeType get functionReturnType;
-
-  /// The typedef this function type is created for.
-  @Id(9)
-  int get functionTypedef;
-
-  @Id(10)
-  List<LinkedNodeType> get functionTypedefTypeArguments;
-
-  @Id(2)
-  List<LinkedNodeTypeTypeParameter> get functionTypeParameters;
-
-  /// Reference to a [LinkedNodeReferences].
-  @Id(3)
-  int get interfaceClass;
-
-  @Id(4)
-  List<LinkedNodeType> get interfaceTypeArguments;
-
-  @Id(5)
-  LinkedNodeTypeKind get kind;
-
-  @Id(8)
-  EntityRefNullabilitySuffix get nullabilitySuffix;
-
-  @Id(6)
-  int get typeParameterElement;
-
-  @Id(7)
-  int get typeParameterId;
-}
-
-/// Information about a formal parameter in a function type.
-abstract class LinkedNodeTypeFormalParameter extends base.SummaryClass {
-  @Id(0)
-  LinkedNodeFormalParameterKind get kind;
-
-  @Id(1)
-  String get name;
-
-  @Id(2)
-  LinkedNodeType get type;
-}
-
-/// Kinds of [LinkedNodeType]s.
-enum LinkedNodeTypeKind {
-  dynamic_,
-  function,
-  interface,
-  never,
-  typeParameter,
-  void_
-}
-
-/// Information about a type substitution.
-abstract class LinkedNodeTypeSubstitution extends base.SummaryClass {
-  @Id(2)
-  bool get isLegacy;
-
-  @Id(1)
-  List<LinkedNodeType> get typeArguments;
-
-  @Id(0)
-  List<int> get typeParameters;
-}
-
-/// Information about a type parameter in a function type.
-abstract class LinkedNodeTypeTypeParameter extends base.SummaryClass {
-  @Id(1)
-  LinkedNodeType get bound;
-
-  @Id(0)
-  String get name;
-}
-
-/// Information about a single library in a [LinkedNodeLibrary].
-abstract class LinkedNodeUnit extends base.SummaryClass {
-  @Id(2)
-  bool get isSynthetic;
-
-  @Id(1)
-  LinkedNode get node;
-
-  /// If the unit is a part, the URI specified in the `part` directive.
-  /// Otherwise empty.
-  @Id(3)
-  String get partUriStr;
-
-  /// The absolute URI.
-  @Id(0)
-  String get uriStr;
-}
-
 /// Summary information about a package.
 @TopLevel('PBdl')
 abstract class PackageBundle extends base.SummaryClass {
@@ -1900,170 +602,7 @@
 
   /// The version 2 of the summary.
   @Id(0)
-  LinkedNodeBundle get bundle2;
-
-  /// The SDK specific data, if this bundle is for SDK.
-  @Id(1)
-  PackageBundleSdk get sdk;
-}
-
-/// Summary information about a package.
-abstract class PackageBundleSdk extends base.SummaryClass {
-  /// The content of the `allowed_experiments.json` from SDK.
-  @Id(0)
-  String get allowedExperimentsJson;
-
-  /// The language version of the SDK.
-  @Id(1)
-  LinkedLanguageVersion get languageVersion;
-}
-
-/// Summary information about a top-level type inference error.
-abstract class TopLevelInferenceError extends base.SummaryClass {
-  /// The [kind] specific arguments.
-  @Id(1)
-  List<String> get arguments;
-
-  /// The kind of the error.
-  @Id(0)
-  TopLevelInferenceErrorKind get kind;
-}
-
-/// Enum used to indicate the kind of the error during top-level inference.
-enum TopLevelInferenceErrorKind {
-  assignment,
-  instanceGetter,
-  dependencyCycle,
-  overrideConflictFieldType,
-  overrideNoCombinedSuperSignature,
-}
-
-@Variant('kind')
-abstract class UnlinkedInformativeData extends base.SummaryClass {
-  @VariantId(2, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.defaultFormalParameter,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  int get codeLength;
-
-  @VariantId(3, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.compilationUnit,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.defaultFormalParameter,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  int get codeOffset;
-
-  @VariantId(9, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-  ])
-  int get combinatorEnd;
-
-  @VariantId(8, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-  ])
-  int get combinatorKeywordOffset;
-
-  /// Offsets of the first character of each line in the source code.
-  @VariantId(7, variant: LinkedNodeKind.compilationUnit)
-  List<int> get compilationUnit_lineStarts;
-
-  @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_periodOffset;
-
-  @VariantId(5, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_returnTypeOffset;
-
-  /// If the parameter has a default value, the source text of the constant
-  /// expression in the default value.  Otherwise the empty string.
-  @VariantId(10, variant: LinkedNodeKind.defaultFormalParameter)
-  String get defaultFormalParameter_defaultValueCode;
-
-  @VariantId(1, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-  ])
-  int get directiveKeywordOffset;
-
-  @VariantId(4, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldDeclaration,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.topLevelVariableDeclaration,
-  ])
-  List<String> get documentationComment_tokens;
-
-  @VariantId(8, variant: LinkedNodeKind.importDirective)
-  int get importDirective_prefixOffset;
-
-  /// The kind of the node.
-  @Id(0)
-  LinkedNodeKind get kind;
-
-  @VariantId(1, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.constructorDeclaration,
-    LinkedNodeKind.enumConstantDeclaration,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.extensionDeclaration,
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.methodDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-    LinkedNodeKind.simpleFormalParameter,
-    LinkedNodeKind.typeParameter,
-    LinkedNodeKind.variableDeclaration,
-  ])
-  int get nameOffset;
+  int get fake;
 }
 
 /// Unlinked summary information about a namespace directive.
@@ -2095,153 +634,6 @@
   String get value;
 }
 
-/// Enum of token types, corresponding to AST token types.
-enum UnlinkedTokenType {
-  NOTHING,
-  ABSTRACT,
-  AMPERSAND,
-  AMPERSAND_AMPERSAND,
-  AMPERSAND_EQ,
-  AS,
-  ASSERT,
-  ASYNC,
-  AT,
-  AWAIT,
-  BACKPING,
-  BACKSLASH,
-  BANG,
-  BANG_EQ,
-  BANG_EQ_EQ,
-  BAR,
-  BAR_BAR,
-  BAR_EQ,
-  BREAK,
-  CARET,
-  CARET_EQ,
-  CASE,
-  CATCH,
-  CLASS,
-  CLOSE_CURLY_BRACKET,
-  CLOSE_PAREN,
-  CLOSE_SQUARE_BRACKET,
-  COLON,
-  COMMA,
-  CONST,
-  CONTINUE,
-  COVARIANT,
-  DEFAULT,
-  DEFERRED,
-  DO,
-  DOUBLE,
-  DYNAMIC,
-  ELSE,
-  ENUM,
-  EOF,
-  EQ,
-  EQ_EQ,
-  EQ_EQ_EQ,
-  EXPORT,
-  EXTENDS,
-  EXTERNAL,
-  FACTORY,
-  FALSE,
-  FINAL,
-  FINALLY,
-  FOR,
-  FUNCTION,
-  FUNCTION_KEYWORD,
-  GET,
-  GT,
-  GT_EQ,
-  GT_GT,
-  GT_GT_EQ,
-  GT_GT_GT,
-  GT_GT_GT_EQ,
-  HASH,
-  HEXADECIMAL,
-  HIDE,
-  IDENTIFIER,
-  IF,
-  IMPLEMENTS,
-  IMPORT,
-  IN,
-  INDEX,
-  INDEX_EQ,
-  INT,
-  INTERFACE,
-  IS,
-  LATE,
-  LIBRARY,
-  LT,
-  LT_EQ,
-  LT_LT,
-  LT_LT_EQ,
-  MINUS,
-  MINUS_EQ,
-  MINUS_MINUS,
-  MIXIN,
-  MULTI_LINE_COMMENT,
-  NATIVE,
-  NEW,
-  NULL,
-  OF,
-  ON,
-  OPEN_CURLY_BRACKET,
-  OPEN_PAREN,
-  OPEN_SQUARE_BRACKET,
-  OPERATOR,
-  PART,
-  PATCH,
-  PERCENT,
-  PERCENT_EQ,
-  PERIOD,
-  PERIOD_PERIOD,
-  PERIOD_PERIOD_PERIOD,
-  PERIOD_PERIOD_PERIOD_QUESTION,
-  PLUS,
-  PLUS_EQ,
-  PLUS_PLUS,
-  QUESTION,
-  QUESTION_PERIOD,
-  QUESTION_QUESTION,
-  QUESTION_QUESTION_EQ,
-  REQUIRED,
-  RETHROW,
-  RETURN,
-  SCRIPT_TAG,
-  SEMICOLON,
-  SET,
-  SHOW,
-  SINGLE_LINE_COMMENT,
-  SLASH,
-  SLASH_EQ,
-  SOURCE,
-  STAR,
-  STAR_EQ,
-  STATIC,
-  STRING,
-  STRING_INTERPOLATION_EXPRESSION,
-  STRING_INTERPOLATION_IDENTIFIER,
-  SUPER,
-  SWITCH,
-  SYNC,
-  THIS,
-  THROW,
-  TILDE,
-  TILDE_SLASH,
-  TILDE_SLASH_EQ,
-  TRUE,
-  TRY,
-  TYPEDEF,
-  VAR,
-  VOID,
-  WHILE,
-  WITH,
-  YIELD,
-  INOUT,
-  OUT,
-}
-
 /// Unlinked summary information about a compilation unit.
 @TopLevel('UUN2')
 abstract class UnlinkedUnit2 extends base.SummaryClass {
@@ -2269,16 +661,13 @@
   @Id(2)
   List<UnlinkedNamespaceDirective> get imports;
 
-  @Id(7)
-  List<UnlinkedInformativeData> get informativeData;
-
   /// Offsets of the first character of each line in the source code.
   @informative
   @Id(5)
   List<int> get lineStarts;
 
   /// URI of the `part of` directive.
-  @Id(8)
+  @Id(7)
   String get partOfUri;
 
   /// URIs of `part` directives.
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 0aa30cd..b206f48 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -9,7 +9,7 @@
 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/summary/idl.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 
 /// A [ConflictingSummaryException] indicates that two different summaries
 /// provided to a [SummaryDataStore] conflict.
@@ -109,8 +109,8 @@
 /// summary package bundles.  It contains maps which can be used to find linked
 /// and unlinked summaries by URI.
 class SummaryDataStore {
-  /// List of all [PackageBundle]s.
-  final List<PackageBundle> bundles = <PackageBundle>[];
+  /// List of all [PackageBundleReader]s.
+  final List<PackageBundleReader> bundles = [];
 
   /// Map from the URI of a unit to the summary path that contained it.
   final Map<String, String> uriToSummaryPath = <String, String>{};
@@ -126,19 +126,17 @@
   }
 
   /// Add the given [bundle] loaded from the file with the given [path].
-  void addBundle(String path, PackageBundle bundle) {
+  void addBundle(String path, PackageBundleReader bundle) {
     bundles.add(bundle);
 
-    if (bundle.bundle2 != null) {
-      for (var library in bundle.bundle2.libraries) {
-        var libraryUri = library.uriStr;
-        _libraryUris.add(libraryUri);
-        for (var unit in library.units) {
-          var unitUri = unit.uriStr;
-          uriToSummaryPath[unitUri] = path;
-          if (unitUri != libraryUri) {
-            _partUris.add(unitUri);
-          }
+    for (var library in bundle.libraries) {
+      var libraryUri = library.uriStr;
+      _libraryUris.add(libraryUri);
+      for (var unit in library.units) {
+        var unitUri = unit.uriStr;
+        uriToSummaryPath[unitUri] = path;
+        if (unitUri != libraryUri) {
+          _partUris.add(unitUri);
         }
       }
     }
@@ -162,15 +160,15 @@
   }
 
   void _fillMaps(String path, ResourceProvider resourceProvider) {
-    List<int> buffer;
+    List<int> bytes;
     if (resourceProvider != null) {
       var file = resourceProvider.getFile(path);
-      buffer = file.readAsBytesSync();
+      bytes = file.readAsBytesSync();
     } else {
       io.File file = io.File(path);
-      buffer = file.readAsBytesSync();
+      bytes = file.readAsBytesSync();
     }
-    PackageBundle bundle = PackageBundle.fromBuffer(buffer);
+    var bundle = PackageBundleReader(bytes);
     addBundle(path, bundle);
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
deleted file mode 100644
index 1c5a27b..0000000
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ /dev/null
@@ -1,23 +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/src/summary/format.dart';
-
-/// Object that gathers information uses it to assemble a new
-/// [PackageBundleBuilder].
-class PackageBundleAssembler {
-  LinkedNodeBundleBuilder _bundle2;
-
-  /// Assemble a new [PackageBundleBuilder] using the gathered information.
-  PackageBundleBuilder assemble() {
-    return PackageBundleBuilder(bundle2: _bundle2);
-  }
-
-  void setBundle2(LinkedNodeBundleBuilder bundle2) {
-    if (_bundle2 != null) {
-      throw StateError('Bundle2 may be set only once.');
-    }
-    _bundle2 = bundle2;
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 809db0f..2d0bd29 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -5,8 +5,8 @@
 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart' show Source;
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:pub_semver/pub_semver.dart';
 
 /// An implementation of [DartSdk] which provides analysis results for `dart:`
@@ -16,7 +16,7 @@
 class SummaryBasedDartSdk implements DartSdk {
   SummaryDataStore _dataStore;
   InSummaryUriResolver _uriResolver;
-  PackageBundle _bundle;
+  PackageBundleReader _bundle;
   ResourceProvider resourceProvider;
 
   SummaryBasedDartSdk(String summaryPath, bool _, {this.resourceProvider}) {
@@ -26,26 +26,21 @@
     _bundle = _dataStore.bundles.single;
   }
 
-  SummaryBasedDartSdk.fromBundle(bool _, PackageBundle bundle,
-      {this.resourceProvider}) {
-    _dataStore = SummaryDataStore([], resourceProvider: resourceProvider);
-    _dataStore.addBundle('dart_sdk.sum', bundle);
-    _uriResolver = InSummaryUriResolver(resourceProvider, _dataStore);
-    _bundle = bundle;
-  }
-
   @override
   String get allowedExperimentsJson {
     return _bundle.sdk.allowedExperimentsJson;
   }
 
-  /// Return the [PackageBundle] for this SDK, not `null`.
-  PackageBundle get bundle => _bundle;
+  /// Return the [PackageBundleReader] for this SDK, not `null`.
+  PackageBundleReader get bundle => _bundle;
 
   @override
   Version get languageVersion {
-    var version = _bundle.sdk.languageVersion;
-    return Version(version.major, version.minor, 0);
+    return Version(
+      _bundle.sdk.languageVersionMajor,
+      _bundle.sdk.languageVersionMinor,
+      0,
+    );
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
new file mode 100644
index 0000000..7c6d20e
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -0,0 +1,1198 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/task/inference_error.dart';
+
+class ApplyResolutionVisitor extends ThrowingAstVisitor<void> {
+  final LinkedUnitContext _unitContext;
+  final LinkedResolutionReader _resolution;
+
+  /// The stack of [TypeParameterElement]s and [ParameterElement] that are
+  /// available in the scope of [_nextElement] and [_nextType].
+  ///
+  /// This stack is shared with [_resolution].
+  final List<Element> _localElements;
+
+  final List<ElementImpl> _enclosingElements = [];
+
+  ApplyResolutionVisitor(
+    this._unitContext,
+    this._localElements,
+    this._resolution,
+  ) {
+    _enclosingElements.add(_unitContext.element);
+  }
+
+  /// TODO(scheglov) make private
+  void addParentTypeParameters(AstNode node) {
+    var enclosing = node.parent;
+    if (enclosing is ClassOrMixinDeclaration) {
+      var typeParameterList = enclosing.typeParameters;
+      if (typeParameterList == null) return;
+
+      for (var typeParameter in typeParameterList.typeParameters) {
+        var element = typeParameter.declaredElement;
+        _localElements.add(element);
+      }
+    } else if (enclosing is ExtensionDeclaration) {
+      var typeParameterList = enclosing.typeParameters;
+      if (typeParameterList == null) return;
+
+      for (var typeParameter in typeParameterList.typeParameters) {
+        var element = typeParameter.declaredElement;
+        _localElements.add(element);
+      }
+    } else if (enclosing is VariableDeclarationList) {
+      var enclosing2 = enclosing.parent;
+      if (enclosing2 is FieldDeclaration) {
+        return addParentTypeParameters(enclosing2);
+      } else if (enclosing2 is TopLevelVariableDeclaration) {
+        return;
+      } else {
+        throw UnimplementedError('${enclosing2.runtimeType}');
+      }
+    } else {
+      throw UnimplementedError('${enclosing.runtimeType}');
+    }
+  }
+
+  @override
+  void visitAdjacentStrings(AdjacentStrings node) {
+    node.strings.accept(this);
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitAnnotation(Annotation node) {
+    node.name.accept(this);
+    node.constructorName?.accept(this);
+    node.arguments?.accept(this);
+    node.element = _nextElement();
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    node.arguments.accept(this);
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    node.expression.accept(this);
+    node.type.accept(this);
+    _expression(node);
+  }
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {
+    node.condition.accept(this);
+    node.message?.accept(this);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var nodeImpl = node as AssignmentExpressionImpl;
+    node.leftHandSide.accept(this);
+    node.rightHandSide.accept(this);
+    node.staticElement = _nextElement();
+    nodeImpl.readElement = _nextElement();
+    nodeImpl.readType = _nextType();
+    nodeImpl.writeElement = _nextElement();
+    nodeImpl.writeType = _nextType();
+    _expression(node);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    node.leftOperand.accept(this);
+    node.rightOperand.accept(this);
+
+    node.staticElement = _nextElement();
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    node.target.accept(this);
+    node.cascadeSections.accept(this);
+    node.staticType = node.target.staticType;
+  }
+
+  @override
+  visitClassDeclaration(ClassDeclaration node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as ClassElementImpl;
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.extendsClause?.accept(this);
+    node.nativeClause?.accept(this);
+    node.withClause?.accept(this);
+    node.implementsClause?.accept(this);
+    _namedCompilationUnitMember(node);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    _assertNoLocalElements();
+    var element = node.declaredElement as ClassElementImpl;
+    _enclosingElements.add(element);
+
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    node.typeParameters?.accept(this);
+    node.superclass?.accept(this);
+    node.withClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    node.condition.accept(this);
+    node.thenExpression.accept(this);
+    node.elseExpression.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitConfiguration(Configuration node) {
+    node.name?.accept(this);
+    node.value?.accept(this);
+    node.uri?.accept(this);
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    _assertNoLocalElements();
+    _pushEnclosingClassTypeParameters(node);
+
+    var element = node.declaredElement as ConstructorElementImpl;
+    _enclosingElements.add(element.enclosingElement);
+    _enclosingElements.add(element);
+
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+
+    for (var parameter in node.parameters.parameters) {
+      _localElements.add(parameter.declaredElement);
+    }
+
+    node.initializers?.accept(this);
+    node.redirectedConstructor?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    node.fieldName.accept(this);
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitConstructorName(ConstructorName node) {
+    // Rewrite:
+    //   ConstructorName
+    //     type: TypeName
+    //       name: PrefixedIdentifier
+    //     name: null
+    // into:
+    //    ConstructorName
+    //      type: TypeName
+    //        name: SimpleIdentifier
+    //      name: SimpleIdentifier
+    var hasName = _resolution.readByte() != 0;
+    if (hasName && node.name == null) {
+      var typeName = node.type.name as PrefixedIdentifier;
+      NodeReplacer.replace(
+        node.type,
+        astFactory.typeName(typeName.prefix, null),
+      );
+      node.name = typeName.identifier;
+    }
+
+    node.type.accept(this);
+    node.name?.accept(this);
+    node.staticElement = _nextElement();
+  }
+
+  @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    node.type?.accept(this);
+    // node.identifier.accept(this);
+    _declaration(node);
+  }
+
+  @override
+  visitDefaultFormalParameter(DefaultFormalParameter node) {
+    var nodeImpl = node as DefaultFormalParameterImpl;
+
+    var enclosing = _enclosingElements.last;
+    var name = node.identifier?.name ?? '';
+    var reference = node.isNamed && enclosing.reference != null
+        ? enclosing.reference.getChild('@parameter').getChild(name)
+        : null;
+    ParameterElementImpl element;
+    if (node.parameter is FieldFormalParameter) {
+      element = DefaultFieldFormalParameterElementImpl.forLinkedNode(
+          enclosing, reference, node);
+    } else {
+      element =
+          DefaultParameterElementImpl.forLinkedNode(enclosing, reference, node);
+    }
+
+    var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
+    element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+
+    node.parameter.accept(this);
+    node.defaultValue?.accept(this);
+  }
+
+  @override
+  void visitDottedName(DottedName node) {
+    node.components.accept(this);
+  }
+
+  @override
+  void visitDoubleLiteral(DoubleLiteral node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {
+    node.constants.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitExportDirective(ExportDirective node) {
+    _namespaceDirective(node);
+    (node.element as ExportElementImpl).exportedLibrary = _nextElement();
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  visitExtendsClause(ExtendsClause node) {
+    node.superclass.accept(this);
+  }
+
+  @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as ExtensionElementImpl;
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.extendedType?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitExtensionOverride(
+    ExtensionOverride node, {
+    bool readRewrite = true,
+  }) {
+    // Read possible rewrite of `MethodInvocation`.
+    // If we are here, we don't need it.
+    if (readRewrite) {
+      _resolution.readByte();
+    }
+
+    node.extensionName.accept(this);
+    node.typeArguments?.accept(this);
+    node.argumentList.accept(this);
+    (node as ExtensionOverrideImpl).extendedType = _nextType();
+    // TODO(scheglov) typeArgumentTypes?
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    _assertNoLocalElements();
+    _pushEnclosingClassTypeParameters(node);
+
+    node.fields.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    ParameterElement element;
+    if (node.parent is! DefaultFormalParameter) {
+      var enclosing = _enclosingElements.last;
+      element =
+          FieldFormalParameterElementImpl.forLinkedNode(enclosing, null, node);
+    }
+
+    var localElementsLength = _localElements.length;
+
+    node.typeParameters?.accept(this);
+    node.type?.accept(this);
+    node.parameters?.accept(this);
+    _normalFormalParameter(node, element);
+
+    _localElements.length = localElementsLength;
+  }
+
+  @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    node.loopVariable.accept(this);
+    _forEachParts(node);
+  }
+
+  @override
+  void visitForElement(ForElement node) {
+    node.body.accept(this);
+    node.forLoopParts.accept(this);
+  }
+
+  @override
+  visitFormalParameterList(FormalParameterList node) {
+    node.parameters.accept(this);
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    for (var variable in node.variables.variables) {
+      var nameNode = variable.name;
+      nameNode.staticElement = LocalVariableElementImpl(
+        nameNode.name,
+        nameNode.offset,
+      );
+    }
+    node.variables.accept(this);
+    _forParts(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as ExecutableElementImpl;
+    assert(element != null);
+
+    _enclosingElements.add(element);
+
+    node.functionExpression.accept(this);
+    node.returnType?.accept(this);
+
+    node.metadata?.accept(this);
+    element.returnType = _nextType();
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(
+    FunctionExpressionInvocation node, {
+    bool readRewrite = true,
+  }) {
+    // Read possible rewrite of `MethodInvocation`.
+    // If we are here, we don't need it.
+    if (readRewrite) {
+      _resolution.readByte();
+    }
+
+    node.function.accept(this);
+    _invocationExpression(node);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+
+    _enclosingElements.add(element.function);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    _enclosingElements.removeLast();
+
+    node.metadata?.accept(this);
+
+    element.function.returnType = _nextType();
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    element.hasSelfReference = _resolution.readByte() != 0;
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    var element = node.declaredElement;
+    if (node.parent is! DefaultFormalParameter) {
+      var enclosing = _enclosingElements.last;
+      element =
+          ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
+    }
+
+    var localElementsLength = _localElements.length;
+
+    node.typeParameters?.accept(this);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    _normalFormalParameter(node, element);
+
+    _localElements.length = localElementsLength;
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    var nodeImpl = node as GenericFunctionTypeImpl;
+    var localElementsLength = _localElements.length;
+
+    var element = nodeImpl.declaredElement as GenericFunctionTypeElementImpl;
+    element ??= GenericFunctionTypeElementImpl.forLinkedNode(
+        _enclosingElements.last, null, node);
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    nodeImpl.type = _nextType();
+
+    _localElements.length = localElementsLength;
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    _assertNoLocalElements();
+
+    var element = node.declaredElement as TypeAliasElementImpl;
+    assert(element != null);
+
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.type?.accept(this);
+    node.metadata?.accept(this);
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    element.hasSelfReference = _resolution.readByte() != 0;
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    node.hiddenNames.accept(this);
+  }
+
+  @override
+  void visitIfElement(IfElement node) {
+    node.condition.accept(this);
+    node.thenElement.accept(this);
+    node.elseElement?.accept(this);
+  }
+
+  @override
+  visitImplementsClause(ImplementsClause node) {
+    node.interfaces.accept(this);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    _namespaceDirective(node);
+
+    var element = node.element as ImportElementImpl;
+    element.importedLibrary = _nextElement();
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    node.target?.accept(this);
+    node.index.accept(this);
+    node.staticElement = _nextElement();
+    _expression(node);
+  }
+
+  @override
+  void visitInstanceCreationExpression(
+    InstanceCreationExpression node, {
+    bool readRewrite = true,
+  }) {
+    // Read possible rewrite of `MethodInvocation`.
+    // If we are here, we don't need it.
+    if (readRewrite) {
+      _resolution.readByte();
+    }
+
+    node.constructorName.accept(this);
+    (node as InstanceCreationExpressionImpl).typeArguments?.accept(this);
+    node.argumentList.accept(this);
+    node.staticType = _nextType();
+    _resolveNamedExpressions(
+      node.constructorName.staticElement,
+      node.argumentList,
+    );
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitInterpolationString(InterpolationString node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    node.expression.accept(this);
+    node.type.accept(this);
+    _expression(node);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    node.name.accept(this);
+    _directive(node);
+  }
+
+  @override
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    node.components.accept(this);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    node.typeArguments?.accept(this);
+    node.elements.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    node.key.accept(this);
+    node.value.accept(this);
+  }
+
+  @override
+  visitMethodDeclaration(MethodDeclaration node) {
+    _assertNoLocalElements();
+    _pushEnclosingClassTypeParameters(node);
+
+    var element = node.declaredElement as ExecutableElementImpl;
+    _enclosingElements.add(element.enclosingElement);
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    node.metadata?.accept(this);
+
+    element.returnType = _nextType();
+    _setTopLevelInferenceError(element);
+    if (element is MethodElementImpl) {
+      element.isOperatorEqualWithParameterTypeFromObject =
+          _resolution.readByte() != 0;
+    }
+
+    _enclosingElements.removeLast();
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    var rewriteTag = _resolution.readByte();
+    if (rewriteTag == MethodInvocationRewriteTag.none) {
+      // No rewrite necessary.
+    } else if (rewriteTag == MethodInvocationRewriteTag.extensionOverride) {
+      Identifier identifier;
+      if (node.target == null) {
+        identifier = node.methodName;
+      } else {
+        identifier = astFactory.prefixedIdentifier(
+          node.target as SimpleIdentifier,
+          node.operator,
+          node.methodName,
+        );
+      }
+      var replacement = astFactory.extensionOverride(
+        extensionName: identifier,
+        typeArguments: node.typeArguments,
+        argumentList: node.argumentList,
+      );
+      NodeReplacer.replace(node, replacement);
+      visitExtensionOverride(replacement, readRewrite: false);
+      return;
+    } else if (rewriteTag ==
+        MethodInvocationRewriteTag.functionExpressionInvocation) {
+      var target = node.target;
+      Expression expression;
+      if (target == null) {
+        expression = node.methodName;
+      } else {
+        expression = astFactory.propertyAccess(
+          target,
+          node.operator,
+          node.methodName,
+        );
+      }
+      var replacement = astFactory.functionExpressionInvocation(
+        expression,
+        node.typeArguments,
+        node.argumentList,
+      );
+      NodeReplacer.replace(node, replacement);
+      visitFunctionExpressionInvocation(replacement, readRewrite: false);
+      return;
+    } else if (rewriteTag ==
+        MethodInvocationRewriteTag.instanceCreationExpression_withName) {
+      var replacement = astFactory.instanceCreationExpression(
+        null,
+        astFactory.constructorName(
+          astFactory.typeName(node.target as Identifier, null),
+          node.operator,
+          node.methodName,
+        ),
+        node.argumentList,
+      );
+      NodeReplacer.replace(node, replacement);
+      visitInstanceCreationExpression(replacement, readRewrite: false);
+      return;
+    } else if (rewriteTag ==
+        MethodInvocationRewriteTag.instanceCreationExpression_withoutName) {
+      var typeNameName = node.target == null
+          ? node.methodName
+          : astFactory.prefixedIdentifier(
+              node.target as SimpleIdentifier,
+              node.operator,
+              node.methodName,
+            );
+      var replacement = astFactory.instanceCreationExpression(
+        null,
+        astFactory.constructorName(
+          astFactory.typeName(typeNameName, node.typeArguments),
+          null,
+          null,
+        ),
+        node.argumentList,
+      );
+      NodeReplacer.replace(node, replacement);
+      visitInstanceCreationExpression(replacement, readRewrite: false);
+      return;
+    } else {
+      throw StateError('[rewriteTag: $rewriteTag][node: $node]');
+    }
+
+    node.target?.accept(this);
+    node.methodName.accept(this);
+    _invocationExpression(node);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    _assertNoLocalElements();
+    var element = node.declaredElement as MixinElementImpl;
+    element.isSimplyBounded = _resolution.readByte() != 0;
+    element.superInvokedNames = _resolution.readStringList();
+    _enclosingElements.add(element);
+
+    node.typeParameters?.accept(this);
+    node.onClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.metadata?.accept(this);
+
+    _enclosingElements.removeLast();
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitNativeClause(NativeClause node) {
+    node.name.accept(this);
+  }
+
+  @override
+  void visitNullLiteral(NullLiteral node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitOnClause(OnClause node) {
+    node.superclassConstraints.accept(this);
+  }
+
+  @override
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    node.expression.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    _uriBasedDirective(node);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    node.uri?.accept(this);
+    _directive(node);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    var nodeImpl = node as PostfixExpressionImpl;
+    node.operand.accept(this);
+    node.staticElement = _nextElement();
+    if (node.operator.type.isIncrementOperator) {
+      nodeImpl.readElement = _nextElement();
+      nodeImpl.readType = _nextType();
+      nodeImpl.writeElement = _nextElement();
+      nodeImpl.writeType = _nextType();
+    }
+    _expression(node);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    node.prefix.accept(this);
+    node.identifier.accept(this);
+    _expression(node);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    var nodeImpl = node as PrefixExpressionImpl;
+    node.operand.accept(this);
+    node.staticElement = _nextElement();
+    if (node.operator.type.isIncrementOperator) {
+      nodeImpl.readElement = _nextElement();
+      nodeImpl.readType = _nextType();
+      nodeImpl.writeElement = _nextElement();
+      nodeImpl.writeType = _nextType();
+    }
+    _expression(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    node.target?.accept(this);
+    node.propertyName.accept(this);
+
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    node.constructorName?.accept(this);
+    node.argumentList.accept(this);
+    node.staticElement = _nextElement();
+    _resolveNamedExpressions(node.staticElement, node.argumentList);
+  }
+
+  @override
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    var mapOrSetBits = _resolution.readByte();
+    if ((mapOrSetBits & 0x01) != 0) {
+      (node as SetOrMapLiteralImpl).becomeMap();
+    } else if ((mapOrSetBits & 0x02) != 0) {
+      (node as SetOrMapLiteralImpl).becomeSet();
+    }
+
+    node.typeArguments?.accept(this);
+    node.elements.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitShowCombinator(ShowCombinator node) {
+    node.shownNames.accept(this);
+  }
+
+  @override
+  visitSimpleFormalParameter(SimpleFormalParameter node) {
+    var element = node.declaredElement as ParameterElementImpl;
+    if (node.parent is! DefaultFormalParameter) {
+      var enclosing = _enclosingElements.last;
+      element =
+          ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
+    }
+
+    node.type?.accept(this);
+    _normalFormalParameter(node, element);
+
+    element.inheritsCovariant = _resolution.readByte() != 0;
+  }
+
+  @override
+  visitSimpleIdentifier(SimpleIdentifier node) {
+    node.staticElement = _nextElement();
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitSpreadElement(SpreadElement node) {
+    node.expression.accept(this);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    node.elements.accept(this);
+    // TODO(scheglov) type?
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    node.constructorName?.accept(this);
+    node.argumentList.accept(this);
+    node.staticElement = _nextElement();
+    _resolveNamedExpressions(node.staticElement, node.argumentList);
+  }
+
+  @override
+  void visitSuperExpression(SuperExpression node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    node.expression.accept(this);
+    node.staticType = _nextType();
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    node.variables.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  visitTypeArgumentList(TypeArgumentList node) {
+    node.arguments?.accept(this);
+  }
+
+  @override
+  visitTypeName(TypeName node) {
+    node.name.accept(this);
+    node.typeArguments?.accept(this);
+
+    node.type = _nextType();
+  }
+
+  @override
+  visitTypeParameterList(TypeParameterList node) {
+    for (var typeParameter in node.typeParameters) {
+      var element = TypeParameterElementImpl.forLinkedNode(
+        _enclosingElements.last,
+        typeParameter,
+      );
+      _localElements.add(element);
+    }
+
+    for (var node in node.typeParameters) {
+      var nodeImpl = node as TypeParameterImpl;
+      var element = node.declaredElement as TypeParameterElementImpl;
+
+      var summaryData = nodeImpl.summaryData as SummaryDataForTypeParameter;
+      element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+
+      node.bound?.accept(this);
+      element.bound = node.bound?.type;
+
+      node.metadata.accept(this);
+      element.metadata = _buildAnnotations(
+        _unitContext.element,
+        node.metadata,
+      );
+
+      element.variance = _decodeVariance(_resolution.readByte());
+      element.defaultType = _nextType();
+
+      // TODO(scheglov) We used to do this with the previous elements impl.
+      // We probably still do this.
+      // But the code below is bad and incomplete.
+      // And why does this affect MethodMember(s)?
+      {
+        var parent = node.parent;
+        if (parent is ClassDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is ClassTypeAlias) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is ExtensionDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is FunctionExpression) {
+          var parent2 = parent.parent;
+          if (parent2 is FunctionDeclaration) {
+            (parent2.declaredElement as ElementImpl).encloseElement(element);
+          }
+        } else if (parent is FunctionTypeAlias) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is GenericTypeAlias) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is MethodDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        } else if (parent is MixinDeclaration) {
+          (parent.declaredElement as ElementImpl).encloseElement(element);
+        }
+      }
+    }
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    var element = node.declaredElement as VariableElementImpl;
+    element.type = _nextType();
+    _setTopLevelInferenceError(element);
+    if (element is FieldElementImpl) {
+      element.inheritsCovariant = _resolution.readByte() != 0;
+    }
+
+    node.initializer?.accept(this);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    node.type?.accept(this);
+    node.variables.accept(this);
+    node.metadata?.accept(this);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    node.mixinTypes.accept(this);
+  }
+
+  void _annotatedNode(AnnotatedNode node) {
+    node.metadata?.accept(this);
+  }
+
+  void _assertNoLocalElements() {
+    assert(_localElements.isEmpty);
+    assert(_enclosingElements.length == 1 &&
+        _enclosingElements.first is CompilationUnitElement);
+  }
+
+  /// Return annotations for the given [nodeList] in the [unit].
+  List<ElementAnnotation> _buildAnnotations(
+      CompilationUnitElementImpl unit, List<Annotation> nodeList) {
+    var length = nodeList.length;
+    if (length == 0) {
+      return const <ElementAnnotation>[];
+    }
+
+    var annotations = List<ElementAnnotation>.filled(length, null);
+    for (int i = 0; i < length; i++) {
+      var ast = nodeList[i];
+      annotations[i] = ElementAnnotationImpl(unit)
+        ..annotationAst = ast
+        ..element = ast.element;
+    }
+    return annotations;
+  }
+
+  void _compilationUnitMember(CompilationUnitMember node) {
+    _declaration(node);
+  }
+
+  void _declaration(Declaration node) {
+    _annotatedNode(node);
+  }
+
+  void _directive(Directive node) {
+    node.metadata?.accept(this);
+  }
+
+  void _expression(Expression node) {
+    node.staticType = _nextType();
+  }
+
+  void _forEachParts(ForEachParts node) {
+    _forLoopParts(node);
+    node.iterable.accept(this);
+  }
+
+  void _forLoopParts(ForLoopParts node) {}
+
+  void _formalParameter(FormalParameter node) {
+    (node.declaredElement as ParameterElementImpl).type = _nextType();
+  }
+
+  void _forParts(ForParts node) {
+    node.condition?.accept(this);
+    node.updaters.accept(this);
+    _forLoopParts(node);
+  }
+
+  void _invocationExpression(InvocationExpression node) {
+    node.typeArguments?.accept(this);
+    node.argumentList.accept(this);
+    _expression(node);
+    // TODO(scheglov) typeArgumentTypes and staticInvokeType?
+    var nodeImpl = node as InvocationExpressionImpl;
+    nodeImpl.typeArgumentTypes = [];
+  }
+
+  void _namedCompilationUnitMember(NamedCompilationUnitMember node) {
+    _compilationUnitMember(node);
+  }
+
+  void _namespaceDirective(NamespaceDirective node) {
+    node.combinators?.accept(this);
+    node.configurations?.accept(this);
+    _uriBasedDirective(node);
+  }
+
+  Element _nextElement() {
+    return _resolution.nextElement();
+  }
+
+  DartType _nextType() {
+    return _resolution.nextType();
+  }
+
+  void _normalFormalParameter(
+    NormalFormalParameter node,
+    ParameterElementImpl element,
+  ) {
+    if (node.parent is! DefaultFormalParameter) {
+      var nodeImpl = node as NormalFormalParameterImpl;
+      var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
+      element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+    }
+
+    node.metadata?.accept(this);
+    _formalParameter(node);
+  }
+
+  /// TODO(scheglov) also enclosing elements
+  void _pushEnclosingClassTypeParameters(ClassMember node) {
+    var parent = node.parent;
+    if (parent is ClassOrMixinDeclaration) {
+      var classElement = parent.declaredElement;
+      _localElements.addAll(classElement.typeParameters);
+    } else {
+      var extension = parent as ExtensionDeclaration;
+      var classElement = extension.declaredElement;
+      _localElements.addAll(classElement.typeParameters);
+    }
+  }
+
+  TopLevelInferenceError _readTopLevelInferenceError() {
+    var kindIndex = _resolution.readByte();
+    var kind = TopLevelInferenceErrorKind.values[kindIndex];
+    if (kind == TopLevelInferenceErrorKind.none) {
+      return null;
+    }
+    return TopLevelInferenceError(
+      kind: kind,
+      arguments: _resolution.readStringList(),
+    );
+  }
+
+  void _resolveNamedExpressions(
+    Element executable,
+    ArgumentList argumentList,
+  ) {
+    for (var argument in argumentList.arguments) {
+      if (argument is NamedExpression) {
+        var nameNode = argument.name.label;
+        if (executable is ExecutableElement) {
+          var parameters = executable.parameters;
+          var name = nameNode.name;
+          nameNode.staticElement = parameters.firstWhere((e) {
+            return e.name == name;
+          }, orElse: () => null);
+        }
+      }
+    }
+  }
+
+  void _setTopLevelInferenceError(ElementImpl element) {
+    if (element is MethodElementImpl) {
+      element.typeInferenceError = _readTopLevelInferenceError();
+    } else if (element is PropertyInducingElementImpl) {
+      element.typeInferenceError = _readTopLevelInferenceError();
+    }
+  }
+
+  void _uriBasedDirective(UriBasedDirective node) {
+    _directive(node);
+    node.uri.accept(this);
+  }
+
+  static Variance _decodeVariance(int encoding) {
+    if (encoding == 0) {
+      return null;
+    } else if (encoding == 1) {
+      return Variance.unrelated;
+    } else if (encoding == 2) {
+      return Variance.covariant;
+    } else if (encoding == 3) {
+      return Variance.contravariant;
+    } else if (encoding == 4) {
+      return Variance.invariant;
+    } else {
+      throw UnimplementedError('encoding: $encoding');
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
index beac780..9bdefc7 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
@@ -13,13 +13,18 @@
     ForStatement,
   );
 
+  static final _hasConstConstructor = _checkBit(
+    0,
+    ClassDeclaration,
+  );
+
   static final _hasEqual = _checkBit(
     0,
     Configuration,
   );
 
   static final _hasInitializer = _checkBit(
-    0,
+    2,
     DefaultFormalParameter,
     VariableDeclaration,
   );
@@ -27,6 +32,9 @@
   static final _hasName = _checkBit(
     5,
     ConstructorDeclaration,
+    FieldFormalParameter,
+    FunctionTypedFormalParameter,
+    SimpleFormalParameter,
   );
 
   static final _hasNot = _checkBit(
@@ -34,6 +42,11 @@
     IsExpression,
   );
 
+  static final _hasPrefix = _checkBit(
+    1,
+    ImportDirective,
+  );
+
   static final _hasPeriod = _checkBit(
     0,
     IndexExpression,
@@ -163,11 +176,6 @@
     VariableDeclarationList,
   );
 
-  static final _isMap = _checkBit(
-    1,
-    TypedLiteral,
-  );
-
   static final _isNative = _checkBit(
     8,
     MethodDeclaration,
@@ -183,8 +191,14 @@
     MethodDeclaration,
   );
 
+  static final _isPositional = _checkBit(
+    1,
+    DefaultFormalParameter,
+  );
+
   static final _isRequired = _checkBit(
     0,
+    DefaultFormalParameter,
     NormalFormalParameter,
   );
 
@@ -227,12 +241,14 @@
 
   static int encode({
     bool hasAwait = false,
+    bool hasConstConstructor = false,
     bool hasEqual = false,
     bool hasInitializer = false,
     bool hasName = false,
     bool hasNot = false,
     bool hasPeriod = false,
     bool hasPeriod2 = false,
+    bool hasPrefix = false,
     bool hasQuestion = false,
     bool hasSeparatorColon = false,
     bool hasSeparatorEquals = false,
@@ -252,10 +268,10 @@
     bool isGenerator = false,
     bool isGet = false,
     bool isLate = false,
-    bool isMap = false,
     bool isNative = false,
     bool isNew = false,
     bool isOperator = false,
+    bool isPositional = false,
     bool isRequired = false,
     bool isSet = false,
     bool isStar = false,
@@ -268,6 +284,9 @@
     if (hasAwait) {
       result |= _hasAwait;
     }
+    if (hasConstConstructor) {
+      result |= _hasConstConstructor;
+    }
     if (hasEqual) {
       result |= _hasEqual;
     }
@@ -286,6 +305,9 @@
     if (hasPeriod2) {
       result |= _hasPeriod2;
     }
+    if (hasPrefix) {
+      result |= _hasPrefix;
+    }
     if (hasQuestion) {
       result |= _hasQuestion;
     }
@@ -343,9 +365,6 @@
     if (isLate) {
       result |= _isLate;
     }
-    if (isMap) {
-      result |= _isMap;
-    }
     if (isNative) {
       result |= _isNative;
     }
@@ -355,6 +374,9 @@
     if (isOperator) {
       result |= _isOperator;
     }
+    if (isPositional) {
+      result |= _isPositional;
+    }
     if (isRequired) {
       result |= _isRequired;
     }
@@ -383,6 +405,10 @@
     return (flags & _hasAwait) != 0;
   }
 
+  static bool hasConstConstructor(int flags) {
+    return (flags & _hasConstConstructor) != 0;
+  }
+
   static bool hasEqual(int flags) {
     return (flags & _hasEqual) != 0;
   }
@@ -407,6 +433,10 @@
     return (flags & _hasPeriod2) != 0;
   }
 
+  static bool hasPrefix(int flags) {
+    return (flags & _hasPrefix) != 0;
+  }
+
   static bool hasQuestion(int flags) {
     return (flags & _hasQuestion) != 0;
   }
@@ -483,10 +513,6 @@
     return (flags & _isLate) != 0;
   }
 
-  static bool isMap(int flags) {
-    return (flags & _isMap) != 0;
-  }
-
   static bool isNative(int flags) {
     return (flags & _isNative) != 0;
   }
@@ -499,6 +525,10 @@
     return (flags & _isOperator) != 0;
   }
 
+  static bool isPositional(int flags) {
+    return (flags & _isPositional) != 0;
+  }
+
   static bool isRequired(int flags) {
     return (flags & _isRequired) != 0;
   }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 4df499f..3bc726f 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -2,2099 +2,1794 @@
 // for details. 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:typed_data';
+
 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/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/tokens_context.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+import 'package:meta/meta.dart';
 
-var timerAstBinaryReader = Stopwatch();
-var timerAstBinaryReaderClass = Stopwatch();
-var timerAstBinaryReaderDirective = Stopwatch();
-var timerAstBinaryReaderFunctionBody = Stopwatch();
-var timerAstBinaryReaderFunctionDeclaration = Stopwatch();
-var timerAstBinaryReaderMixin = Stopwatch();
-var timerAstBinaryReaderTopLevelVar = Stopwatch();
-
-/// Deserializer of fully resolved ASTs from flat buffers.
+/// Deserializer of ASTs.
 class AstBinaryReader {
-  final LinkedUnitContext _unitContext;
+  static final _noDocumentationComment = Uint32List(0);
 
-  /// Set to `true` when this reader is used to lazily read its unit.
-  bool isLazy = false;
+  final UnitReader _unitReader;
+  final bool _withInformative;
 
-  /// Whether we are reading a directive.
-  ///
-  /// [StringLiteral]s in directives are not actual expressions, and don't need
-  /// a type. Moreover, when we are reading `dart:core` imports, the type
-  /// provider is not ready yet, so we cannot access type `String`.
-  bool _isReadingDirective = false;
+  AstBinaryReader({
+    @required UnitReader reader,
+  })  : _unitReader = reader,
+        _withInformative = reader.withInformative;
 
-  AstBinaryReader(this._unitContext);
-
-  InterfaceType get _boolType => _unitContext.typeProvider.boolType;
-
-  InterfaceType get _doubleType => _unitContext.typeProvider.doubleType;
-
-  InterfaceType get _intType => _unitContext.typeProvider.intType;
-
-  DartType get _nullType => _unitContext.typeProvider.nullType;
-
-  InterfaceType get _stringType => _unitContext.typeProvider.stringType;
-
-  AstNode readNode(LinkedNode data) {
-    timerAstBinaryReader.start();
-    try {
-      return _readNode(data);
-    } finally {
-      timerAstBinaryReader.stop();
-    }
-  }
-
-  DartType readType(LinkedNodeType data) {
-    return _readType(data);
-  }
-
-  Token _combinatorKeyword(LinkedNode data, Keyword keyword, Token def) {
-    var informativeData = _unitContext.getInformativeData(data);
-    if (informativeData != null) {
-      return TokenFactory.tokenFromKeyword(keyword)
-        ..offset = informativeData.combinatorKeywordOffset;
-    }
-    return def;
-  }
-
-  SimpleIdentifier _declaredIdentifier(LinkedNode data) {
-    var informativeData = _unitContext.getInformativeData(data);
-    var offset = informativeData?.nameOffset ?? 0;
-    return astFactory.simpleIdentifier(
-      TokenFactory.tokenFromString(data.name)..offset = offset,
-      isDeclaration: true,
-    );
-  }
-
-  Token _directiveKeyword(LinkedNode data, Keyword keyword, Token def) {
-    var informativeData = _unitContext.getInformativeData(data);
-    if (informativeData != null) {
-      return TokenFactory.tokenFromKeyword(keyword)
-        ..offset = informativeData.directiveKeywordOffset;
-    }
-    return def;
-  }
-
-  Element _elementOfComponents(
-    int rawElementIndex,
-    LinkedNodeTypeSubstitution substitutionNode,
-  ) {
-    var element = _getElement(rawElementIndex);
-    if (substitutionNode == null) return element;
-
-    var typeParameters = substitutionNode.typeParameters
-        .map<TypeParameterElement>(_getElement)
-        .toList();
-    var typeArguments = substitutionNode.typeArguments.map(_readType).toList();
-    var substitution = Substitution.fromPairs(typeParameters, typeArguments);
-
-    var member = ExecutableMember.from2(element, substitution);
-    if (substitutionNode.isLegacy) {
-      member = Member.legacy(member);
-    }
-
-    return member;
-  }
-
-  T _getElement<T extends Element>(int index) {
-    var bundleContext = _unitContext.bundleContext;
-    return bundleContext.elementOfIndex(index);
-  }
-
-  AdjacentStrings _read_adjacentStrings(LinkedNode data) {
-    var node = astFactory.adjacentStrings(
-      _readNodeList(data.adjacentStrings_strings),
-    );
-    if (!_isReadingDirective) {
-      node.staticType = _stringType;
-    }
-    return node;
-  }
-
-  Annotation _read_annotation(LinkedNode data) {
-    return astFactory.annotation(
-      _Tokens.AT,
-      _readNode(data.annotation_name),
-      _Tokens.PERIOD,
-      _readNode(data.annotation_constructorName),
-      _readNode(data.annotation_arguments),
-    )..element = _elementOfComponents(
-        data.annotation_element,
-        data.annotation_substitution,
-      );
-  }
-
-  ArgumentList _read_argumentList(LinkedNode data) {
-    return astFactory.argumentList(
-      _Tokens.OPEN_PAREN,
-      _readNodeList(data.argumentList_arguments),
-      _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  AsExpression _read_asExpression(LinkedNode data) {
-    return astFactory.asExpression(
-      _readNode(data.asExpression_expression),
-      _Tokens.AS,
-      _readNode(data.asExpression_type),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  AssertInitializer _read_assertInitializer(LinkedNode data) {
-    return astFactory.assertInitializer(
-      _Tokens.ASSERT,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.assertInitializer_condition),
-      _Tokens.COMMA,
-      _readNode(data.assertInitializer_message),
-      _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  AssertStatement _read_assertStatement(LinkedNode data) {
-    return astFactory.assertStatement(
-      _Tokens.AS,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.assertStatement_condition),
-      _Tokens.COMMA,
-      _readNode(data.assertStatement_message),
-      _Tokens.CLOSE_PAREN,
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  AssignmentExpression _read_assignmentExpression(LinkedNode data) {
-    return astFactory.assignmentExpression(
-      _readNode(data.assignmentExpression_leftHandSide),
-      _Tokens.fromType(data.assignmentExpression_operator),
-      _readNode(data.assignmentExpression_rightHandSide),
-    )
-      ..staticElement = _elementOfComponents(
-        data.assignmentExpression_element,
-        data.assignmentExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  AwaitExpression _read_awaitExpression(LinkedNode data) {
-    return astFactory.awaitExpression(
-      _Tokens.AWAIT,
-      _readNode(data.awaitExpression_expression),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  BinaryExpression _read_binaryExpression(LinkedNode data) {
-    return astFactory.binaryExpression(
-      _readNode(data.binaryExpression_leftOperand),
-      _Tokens.fromType(data.binaryExpression_operator),
-      _readNode(data.binaryExpression_rightOperand),
-    )
-      ..staticElement = _elementOfComponents(
-        data.binaryExpression_element,
-        data.binaryExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  Block _read_block(LinkedNode data) {
-    return astFactory.block(
-      _Tokens.OPEN_CURLY_BRACKET,
-      _readNodeList(data.block_statements),
-      _Tokens.CLOSE_CURLY_BRACKET,
-    );
-  }
-
-  BlockFunctionBody _read_blockFunctionBody(LinkedNode data) {
-    timerAstBinaryReaderFunctionBody.start();
-    try {
-      return astFactory.blockFunctionBody(
-        _Tokens.choose(
-          AstBinaryFlags.isAsync(data.flags),
-          _Tokens.ASYNC,
-          AstBinaryFlags.isSync(data.flags),
-          _Tokens.SYNC,
-        ),
-        AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
-        _readNode(data.blockFunctionBody_block),
-      );
-    } finally {
-      timerAstBinaryReaderFunctionBody.stop();
-    }
-  }
-
-  BooleanLiteral _read_booleanLiteral(LinkedNode data) {
-    return AstTestFactory.booleanLiteral(data.booleanLiteral_value)
-      ..staticType = _boolType;
-  }
-
-  BreakStatement _read_breakStatement(LinkedNode data) {
-    return astFactory.breakStatement(
-      _Tokens.BREAK,
-      _readNode(data.breakStatement_label),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  CascadeExpression _read_cascadeExpression(LinkedNode data) {
-    return astFactory.cascadeExpression(
-      _readNode(data.cascadeExpression_target),
-      _readNodeList(data.cascadeExpression_sections),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  CatchClause _read_catchClause(LinkedNode data) {
-    var exceptionType = _readNode(data.catchClause_exceptionType);
-    var exceptionParameter = _readNode(data.catchClause_exceptionParameter);
-    var stackTraceParameter = _readNode(data.catchClause_stackTraceParameter);
-    return astFactory.catchClause(
-      exceptionType != null ? _Tokens.ON : null,
-      exceptionType,
-      exceptionParameter != null ? _Tokens.CATCH : null,
-      exceptionParameter != null ? _Tokens.OPEN_PAREN : null,
-      exceptionParameter,
-      stackTraceParameter != null ? _Tokens.COMMA : null,
-      stackTraceParameter,
-      exceptionParameter != null ? _Tokens.CLOSE_PAREN : null,
-      _readNode(data.catchClause_body),
-    );
-  }
-
-  ClassDeclaration _read_classDeclaration(LinkedNode data) {
-    timerAstBinaryReaderClass.start();
-    try {
-      var node = astFactory.classDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
-        _Tokens.CLASS,
-        _declaredIdentifier(data),
-        _readNode(data.classOrMixinDeclaration_typeParameters),
-        _readNodeLazy(data.classDeclaration_extendsClause),
-        _readNodeLazy(data.classDeclaration_withClause),
-        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
-        _Tokens.OPEN_CURLY_BRACKET,
-        _readNodeListLazy(data.classOrMixinDeclaration_members),
-        _Tokens.CLOSE_CURLY_BRACKET,
-      );
-      node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
-      LazyClassDeclaration.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderClass.stop();
-    }
-  }
-
-  ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
-    timerAstBinaryReaderClass.start();
-    try {
-      var node = astFactory.classTypeAlias(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.CLASS,
-        _declaredIdentifier(data),
-        _readNode(data.classTypeAlias_typeParameters),
-        _Tokens.EQ,
-        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
-        _readNodeLazy(data.classTypeAlias_superclass),
-        _readNodeLazy(data.classTypeAlias_withClause),
-        _readNodeLazy(data.classTypeAlias_implementsClause),
-        _Tokens.SEMICOLON,
-      );
-      LazyClassTypeAlias.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderClass.stop();
-    }
-  }
-
-  Comment _read_comment(LinkedNode data) {
-    var tokens = data.comment_tokens
-        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
-        .toList();
-    switch (data.comment_type) {
-      case LinkedNodeCommentType.block:
-        return astFactory.endOfLineComment(
-          tokens,
-        );
-      case LinkedNodeCommentType.documentation:
-        return astFactory.documentationComment(
-          tokens,
-          _readNodeList(data.comment_references),
-        );
-      case LinkedNodeCommentType.endOfLine:
-        return astFactory.endOfLineComment(
-          tokens,
-        );
+  AstNode readNode() {
+    var tag = _readByte();
+    switch (tag) {
+      case Tag.AdjacentStrings:
+        return _readAdjacentStrings();
+      case Tag.Annotation:
+        return _readAnnotation();
+      case Tag.ArgumentList:
+        return _readArgumentList();
+      case Tag.AsExpression:
+        return _readAsExpression();
+      case Tag.AssertInitializer:
+        return _readAssertInitializer();
+      case Tag.AssignmentExpression:
+        return _readAssignmentExpression();
+      case Tag.BinaryExpression:
+        return _readBinaryExpression();
+      case Tag.BooleanLiteral:
+        return _readBooleanLiteral();
+      case Tag.CascadeExpression:
+        return _readCascadeExpression();
+      case Tag.Class:
+        return _readClassDeclaration();
+      case Tag.ClassTypeAlias:
+        return _readClassTypeAlias();
+      case Tag.ConditionalExpression:
+        return _readConditionalExpression();
+      case Tag.Configuration:
+        return _readConfiguration();
+      case Tag.ConstructorDeclaration:
+        return _readConstructorDeclaration();
+      case Tag.ConstructorFieldInitializer:
+        return _readConstructorFieldInitializer();
+      case Tag.ConstructorName:
+        return _readConstructorName();
+      case Tag.DeclaredIdentifier:
+        return _readDeclaredIdentifier();
+      case Tag.DefaultFormalParameter:
+        return _readDefaultFormalParameter();
+      case Tag.DottedName:
+        return _readDottedName();
+      case Tag.DoubleLiteral:
+        return _readDoubleLiteral();
+      case Tag.EnumConstantDeclaration:
+        return _readEnumConstantDeclaration();
+      case Tag.EnumDeclaration:
+        return _readEnumDeclaration();
+      case Tag.ExportDirective:
+        return _readExportDirective();
+      case Tag.ExtendsClause:
+        return _readExtendsClause();
+      case Tag.ExtensionDeclaration:
+        return _readExtensionDeclaration();
+      case Tag.ExtensionOverride:
+        return _readExtensionOverride();
+      case Tag.FieldDeclaration:
+        return _readFieldDeclaration();
+      case Tag.ForEachPartsWithDeclaration:
+        return _readForEachPartsWithDeclaration();
+      case Tag.ForElement:
+        return _readForElement();
+      case Tag.ForPartsWithDeclarations:
+        return _readForPartsWithDeclarations();
+      case Tag.FieldFormalParameter:
+        return _readFieldFormalParameter();
+      case Tag.FormalParameterList:
+        return _readFormalParameterList();
+      case Tag.FunctionDeclaration:
+        return _readFunctionDeclaration();
+      case Tag.FunctionExpression:
+        return _readFunctionExpression();
+      case Tag.FunctionExpressionInvocation:
+        return _readFunctionExpressionInvocation();
+      case Tag.FunctionTypeAlias:
+        return _readFunctionTypeAlias();
+      case Tag.FunctionTypedFormalParameter:
+        return _readFunctionTypedFormalParameter();
+      case Tag.GenericFunctionType:
+        return _readGenericFunctionType();
+      case Tag.GenericTypeAlias:
+        return _readGenericTypeAlias();
+      case Tag.HideCombinator:
+        return _readHideCombinator();
+      case Tag.IfElement:
+        return _readIfElement();
+      case Tag.ImplementsClause:
+        return _readImplementsClause();
+      case Tag.IndexExpression:
+        return _readIndexExpression();
+      case Tag.IntegerLiteralNegative1:
+        return _readIntegerLiteralNegative1();
+      case Tag.IntegerLiteralNull:
+        return _readIntegerLiteralNull();
+      case Tag.IntegerLiteralPositive1:
+        return _readIntegerLiteralPositive1();
+      case Tag.IntegerLiteralPositive:
+        return _readIntegerLiteralPositive();
+      case Tag.IntegerLiteralNegative:
+        return _readIntegerLiteralNegative();
+      case Tag.InterpolationExpression:
+        return _readInterpolationExpression();
+      case Tag.InterpolationString:
+        return _readInterpolationString();
+      case Tag.IsExpression:
+        return _readIsExpression();
+      case Tag.LibraryDirective:
+        return _readLibraryDirective();
+      case Tag.LibraryIdentifier:
+        return _readLibraryIdentifier();
+      case Tag.ListLiteral:
+        return _readListLiteral();
+      case Tag.MapLiteralEntry:
+        return _readMapLiteralEntry();
+      case Tag.MethodDeclaration:
+        return _readMethodDeclaration();
+      case Tag.MixinDeclaration:
+        return _readMixinDeclaration();
+      case Tag.MethodInvocation:
+        return _readMethodInvocation();
+      case Tag.NamedExpression:
+        return _readNamedExpression();
+      case Tag.NativeClause:
+        return _readNativeClause();
+      case Tag.NullLiteral:
+        return _readNullLiteral();
+      case Tag.OnClause:
+        return _readOnClause();
+      case Tag.ImportDirective:
+        return _readImportDirective();
+      case Tag.InstanceCreationExpression:
+        return _readInstanceCreationExpression();
+      case Tag.ParenthesizedExpression:
+        return _readParenthesizedExpression();
+      case Tag.PartDirective:
+        return _readPartDirective();
+      case Tag.PartOfDirective:
+        return _readPartOfDirective();
+      case Tag.PostfixExpression:
+        return _readPostfixExpression();
+      case Tag.PrefixExpression:
+        return _readPrefixExpression();
+      case Tag.PrefixedIdentifier:
+        return _readPrefixedIdentifier();
+      case Tag.PropertyAccess:
+        return _readPropertyAccess();
+      case Tag.RedirectingConstructorInvocation:
+        return _readRedirectingConstructorInvocation();
+      case Tag.SetOrMapLiteral:
+        return _readSetOrMapLiteral();
+      case Tag.ShowCombinator:
+        return _readShowCombinator();
+      case Tag.SimpleFormalParameter:
+        return _readSimpleFormalParameter();
+      case Tag.SimpleIdentifier:
+        return _readSimpleIdentifier();
+      case Tag.SimpleStringLiteral:
+        return _readSimpleStringLiteral();
+      case Tag.SpreadElement:
+        return _readSpreadElement();
+      case Tag.StringInterpolation:
+        return _readStringInterpolation();
+      case Tag.SuperConstructorInvocation:
+        return _readSuperConstructorInvocation();
+      case Tag.SuperExpression:
+        return _readSuperExpression();
+      case Tag.SymbolLiteral:
+        return _readSymbolLiteral();
+      case Tag.ThisExpression:
+        return _readThisExpression();
+      case Tag.ThrowExpression:
+        return _readThrowExpression();
+      case Tag.TypeArgumentList:
+        return _readTypeArgumentList();
+      case Tag.TypeName:
+        return _readTypeName();
+      case Tag.TypeParameter:
+        return _readTypeParameter();
+      case Tag.TypeParameterList:
+        return _readTypeParameterList();
+      case Tag.TopLevelVariableDeclaration:
+        return _readTopLevelVariableDeclaration();
+      case Tag.VariableDeclaration:
+        return _readVariableDeclaration();
+      case Tag.VariableDeclarationList:
+        return _readVariableDeclarationList();
+      case Tag.WithClause:
+        return _readWithClause();
       default:
-        throw StateError('${data.comment_type}');
+        throw UnimplementedError('Unexpected tag: $tag');
     }
   }
 
-  CommentReference _read_commentReference(LinkedNode data) {
-    return astFactory.commentReference(
-      AstBinaryFlags.isNew(data.flags) ? _Tokens.NEW : null,
-      _readNode(data.commentReference_identifier),
+  IntegerLiteral _createIntegerLiteral(int value) {
+    // TODO(scheglov) Write token?
+    return astFactory.integerLiteral(
+      TokenFactory.tokenFromTypeAndString(TokenType.INT, '$value'),
+      value,
     );
   }
 
-  CompilationUnit _read_compilationUnit(LinkedNode data) {
-    var node = astFactory.compilationUnit(
-      beginToken: null,
-      scriptTag: _readNode(data.compilationUnit_scriptTag),
-      directives: _readNodeList(data.compilationUnit_directives),
-      declarations: _readNodeList(data.compilationUnit_declarations),
-      endToken: null,
-      featureSet: ExperimentStatus.fromStorage(
-        data.compilationUnit_featureSet,
-      ),
+  FunctionBody _functionBodyForFlags(int flags) {
+    if (AstBinaryFlags.isNative(flags)) {
+      return AstTestFactory.nativeFunctionBody('');
+    } else if (AstBinaryFlags.isAbstract(flags)) {
+      return AstTestFactory.emptyFunctionBody();
+    } else {
+      return astFactory.blockFunctionBody(
+        AstBinaryFlags.isAsync(flags) ? Tokens.ASYNC : null,
+        AstBinaryFlags.isGenerator(flags) ? Tokens.STAR : null,
+        astFactory.block(
+          Tokens.OPEN_CURLY_BRACKET,
+          const <Statement>[],
+          Tokens.CLOSE_CURLY_BRACKET,
+        ),
+      );
+    }
+  }
+
+  AdjacentStrings _readAdjacentStrings() {
+    var components = _readNodeList<StringLiteral>();
+    return astFactory.adjacentStrings(components);
+  }
+
+  Annotation _readAnnotation() {
+    var name = _readOptionalNode() as Identifier;
+    var constructorName = _readOptionalNode() as SimpleIdentifier;
+    var arguments = _readOptionalNode() as ArgumentList;
+    return astFactory.annotation(
+      Tokens.AT,
+      name,
+      Tokens.PERIOD,
+      constructorName,
+      arguments,
     );
-    LazyCompilationUnit(node, data);
+  }
+
+  ArgumentList _readArgumentList() {
+    var arguments = _readNodeList<Expression>();
+
+    return astFactory.argumentList(
+      Tokens.OPEN_PAREN,
+      arguments,
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  AsExpression _readAsExpression() {
+    var expression = readNode() as Expression;
+    var type = readNode() as TypeAnnotation;
+    return astFactory.asExpression(expression, Tokens.AS, type);
+  }
+
+  AssertInitializer _readAssertInitializer() {
+    var condition = readNode() as Expression;
+    var message = _readOptionalNode() as Expression;
+    return astFactory.assertInitializer(
+      Tokens.ASSERT,
+      Tokens.OPEN_PAREN,
+      condition,
+      Tokens.COMMA,
+      message,
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  AssignmentExpression _readAssignmentExpression() {
+    var leftHandSide = readNode() as Expression;
+    var rightHandSide = readNode() as Expression;
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    return astFactory.assignmentExpression(
+      leftHandSide,
+      Tokens.fromType(operatorType),
+      rightHandSide,
+    );
+  }
+
+  BinaryExpression _readBinaryExpression() {
+    var leftOperand = readNode() as Expression;
+    var rightOperand = readNode() as Expression;
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    return astFactory.binaryExpression(
+      leftOperand,
+      Tokens.fromType(operatorType),
+      rightOperand,
+    );
+  }
+
+  BooleanLiteral _readBooleanLiteral() {
+    var value = _readByte() == 1;
+    // TODO(scheglov) type?
+    return AstTestFactory.booleanLiteral(value);
+  }
+
+  int _readByte() {
+    return _unitReader.astReader.readByte();
+  }
+
+  CascadeExpression _readCascadeExpression() {
+    var target = readNode() as Expression;
+    var sections = _readNodeList<Expression>();
+    return astFactory.cascadeExpression(target, sections);
+  }
+
+  ClassDeclaration _readClassDeclaration() {
+    var flags = _readByte();
+
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var extendsClause = _readOptionalNode() as ExtendsClause;
+    var withClause = _readOptionalNode() as WithClause;
+    var implementsClause = _readOptionalNode() as ImplementsClause;
+    var nativeClause = _readOptionalNode() as NativeClause;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.classDeclaration(
+      null,
+      metadata,
+      AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+      Tokens.CLASS,
+      name,
+      typeParameters,
+      extendsClause,
+      withClause,
+      implementsClause,
+      Tokens.OPEN_CURLY_BRACKET,
+      const <ClassMember>[],
+      Tokens.CLOSE_CURLY_BRACKET,
+    ) as ClassDeclarationImpl;
+    node.nativeClause = nativeClause;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      isClassWithConstConstructor: AstBinaryFlags.hasConstConstructor(flags),
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
     return node;
   }
 
-  ConditionalExpression _read_conditionalExpression(LinkedNode data) {
+  ClassTypeAlias _readClassTypeAlias() {
+    var flags = _readByte();
+
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var superClass = readNode() as TypeName;
+    var withClause = readNode() as WithClause;
+    var implementsClause = _readOptionalNode() as ImplementsClause;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+    var documentationTokenIndexList = _readUint30List();
+
+    var node = astFactory.classTypeAlias(
+      null,
+      metadata,
+      Tokens.CLASS,
+      name,
+      typeParameters,
+      Tokens.EQ,
+      AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+      superClass,
+      withClause,
+      implementsClause,
+      Tokens.SEMICOLON,
+    ) as ClassTypeAliasImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  ConditionalExpression _readConditionalExpression() {
+    var condition = readNode() as Expression;
+    var thenExpression = readNode() as Expression;
+    var elseExpression = readNode() as Expression;
     return astFactory.conditionalExpression(
-      _readNode(data.conditionalExpression_condition),
-      _Tokens.QUESTION,
-      _readNode(data.conditionalExpression_thenExpression),
-      _Tokens.COLON,
-      _readNode(data.conditionalExpression_elseExpression),
-    )..staticType = _readType(data.expression_type);
+      condition,
+      Tokens.QUESTION,
+      thenExpression,
+      Tokens.COLON,
+      elseExpression,
+    );
   }
 
-  Configuration _read_configuration(LinkedNode data) {
+  Configuration _readConfiguration() {
+    var flags = _readByte();
+    var name = readNode() as DottedName;
+    var value = _readOptionalNode() as StringLiteral;
+    var uri = readNode() as StringLiteral;
     return astFactory.configuration(
-      _Tokens.IF,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.configuration_name),
-      AstBinaryFlags.hasEqual(data.flags) ? _Tokens.EQ : null,
-      _readNode(data.configuration_value),
-      _Tokens.CLOSE_PAREN,
-      _readNode(data.configuration_uri),
+      Tokens.IF,
+      Tokens.OPEN_PAREN,
+      name,
+      AstBinaryFlags.hasEqual(flags) ? Tokens.EQ : null,
+      value,
+      Tokens.CLOSE_PAREN,
+      uri,
     );
   }
 
-  ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) {
-    SimpleIdentifier returnType = _readNode(
-      data.constructorDeclaration_returnType,
-    );
+  ConstructorDeclaration _readConstructorDeclaration() {
+    var flags = _readByte();
 
-    var informativeData = _unitContext.getInformativeData(data);
-    returnType.token.offset =
-        informativeData?.constructorDeclaration_returnTypeOffset ?? 0;
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
 
-    Token periodToken;
-    SimpleIdentifier nameIdentifier;
-    if (AstBinaryFlags.hasName(data.flags)) {
-      periodToken = Token(
-        TokenType.PERIOD,
-        informativeData?.constructorDeclaration_periodOffset ?? 0,
-      );
-      nameIdentifier = _declaredIdentifier(data);
+    var returnType = readNode() as SimpleIdentifier;
+
+    Token period;
+    SimpleIdentifier name;
+    if (AstBinaryFlags.hasName(flags)) {
+      var periodOffset = _readInformativeUint30();
+      period = Token(TokenType.PERIOD, periodOffset);
+      name = readNode() as SimpleIdentifier;
     }
 
+    var parameters = readNode() as FormalParameterList;
+    var initializers = _readNodeList<ConstructorInitializer>();
+    var redirectedConstructor = _readOptionalNode() as ConstructorName;
+    var metadata = _readNodeList<Annotation>();
+
     var node = astFactory.constructorDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
-      AstBinaryFlags.isFactory(data.flags) ? _Tokens.FACTORY : null,
+      null,
+      metadata,
+      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+      AstBinaryFlags.isFactory(flags) ? Tokens.FACTORY : null,
       returnType,
-      periodToken,
-      nameIdentifier,
-      _readNodeLazy(data.constructorDeclaration_parameters),
-      _Tokens.choose(
-        AstBinaryFlags.hasSeparatorColon(data.flags),
-        _Tokens.COLON,
-        AstBinaryFlags.hasSeparatorEquals(data.flags),
-        _Tokens.EQ,
+      period,
+      name,
+      parameters,
+      Tokens.choose(
+        AstBinaryFlags.hasSeparatorColon(flags),
+        Tokens.COLON,
+        AstBinaryFlags.hasSeparatorEquals(flags),
+        Tokens.EQ,
       ),
-      _readNodeListLazy(data.constructorDeclaration_initializers),
-      _readNodeLazy(data.constructorDeclaration_redirectedConstructor),
-      _readNodeLazy(data.constructorDeclaration_body),
+      initializers,
+      redirectedConstructor,
+      null,
+    ) as ConstructorDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
     );
-    LazyConstructorDeclaration.setData(node, data);
+
     return node;
   }
 
-  ConstructorFieldInitializer _read_constructorFieldInitializer(
-      LinkedNode data) {
-    var hasThis = AstBinaryFlags.hasThis(data.flags);
+  ConstructorFieldInitializer _readConstructorFieldInitializer() {
+    var flags = _readByte();
+    var fieldName = readNode() as SimpleIdentifier;
+    var expression = readNode() as Expression;
+    var hasThis = AstBinaryFlags.hasThis(flags);
     return astFactory.constructorFieldInitializer(
-      hasThis ? _Tokens.THIS : null,
-      hasThis ? _Tokens.PERIOD : null,
-      _readNode(data.constructorFieldInitializer_fieldName),
-      _Tokens.EQ,
-      _readNode(data.constructorFieldInitializer_expression),
+      hasThis ? Tokens.THIS : null,
+      hasThis ? Tokens.PERIOD : null,
+      fieldName,
+      Tokens.EQ,
+      expression,
     );
   }
 
-  ConstructorName _read_constructorName(LinkedNode data) {
+  ConstructorName _readConstructorName() {
+    var type = readNode() as TypeName;
+    var name = _readOptionalNode() as SimpleIdentifier;
+
     return astFactory.constructorName(
-      _readNode(data.constructorName_type),
-      data.constructorName_name != null ? _Tokens.PERIOD : null,
-      _readNode(data.constructorName_name),
-    )..staticElement = _elementOfComponents(
-        data.constructorName_element,
-        data.constructorName_substitution,
-      );
-  }
-
-  ContinueStatement _read_continueStatement(LinkedNode data) {
-    return astFactory.continueStatement(
-      _Tokens.CONTINUE,
-      _readNode(data.continueStatement_label),
-      _Tokens.SEMICOLON,
+      type,
+      name != null ? Tokens.PERIOD : null,
+      name,
     );
   }
 
-  DeclaredIdentifier _read_declaredIdentifier(LinkedNode data) {
+  DeclaredIdentifier _readDeclaredIdentifier() {
+    var flags = _readByte();
+    var type = _readOptionalNode() as TypeAnnotation;
+    var identifier = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
     return astFactory.declaredIdentifier(
-      _readDocumentationComment(data),
-      _readNodeList(data.annotatedNode_metadata),
-      _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
-      _readNode(data.declaredIdentifier_type),
-      _readNode(data.declaredIdentifier_identifier),
-    );
-  }
-
-  DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) {
-    var node = astFactory.defaultFormalParameter(
-      _readNode(data.defaultFormalParameter_parameter),
-      _toParameterKind(data.defaultFormalParameter_kind),
-      data.defaultFormalParameter_defaultValue != null ? _Tokens.COLON : null,
-      _readNodeLazy(data.defaultFormalParameter_defaultValue),
-    );
-    LazyFormalParameter.setData(node, data);
-    return node;
-  }
-
-  DoStatement _read_doStatement(LinkedNode data) {
-    return astFactory.doStatement(
-      _Tokens.DO,
-      _readNode(data.doStatement_body),
-      _Tokens.WHILE,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.doStatement_condition),
-      _Tokens.CLOSE_PAREN,
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  DottedName _read_dottedName(LinkedNode data) {
-    return astFactory.dottedName(
-      _readNodeList(data.dottedName_components),
-    );
-  }
-
-  DoubleLiteral _read_doubleLiteral(LinkedNode data) {
-    return AstTestFactory.doubleLiteral(data.doubleLiteral_value)
-      ..staticType = _doubleType;
-  }
-
-  EmptyFunctionBody _read_emptyFunctionBody(LinkedNode data) {
-    return astFactory.emptyFunctionBody(
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  EmptyStatement _read_emptyStatement(LinkedNode data) {
-    return astFactory.emptyStatement(
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) {
-    var node = astFactory.enumConstantDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _declaredIdentifier(data),
-    );
-    LazyEnumConstantDeclaration.setData(node, data);
-    return node;
-  }
-
-  EnumDeclaration _read_enumDeclaration(LinkedNode data) {
-    var node = astFactory.enumDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _Tokens.ENUM,
-      _declaredIdentifier(data),
-      _Tokens.OPEN_CURLY_BRACKET,
-      _readNodeListLazy(data.enumDeclaration_constants),
-      _Tokens.CLOSE_CURLY_BRACKET,
-    );
-    LazyEnumDeclaration.setData(node, data);
-    return node;
-  }
-
-  ExportDirective _read_exportDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.exportDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _directiveKeyword(data, Keyword.EXPORT, _Tokens.EXPORT),
-        _readNode(data.uriBasedDirective_uri),
-        _readNodeList(data.namespaceDirective_configurations),
-        _readNodeList(data.namespaceDirective_combinators),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
-    timerAstBinaryReaderFunctionBody.start();
-    try {
-      return astFactory.expressionFunctionBody(
-        _Tokens.choose(
-          AstBinaryFlags.isAsync(data.flags),
-          _Tokens.ASYNC,
-          AstBinaryFlags.isSync(data.flags),
-          _Tokens.SYNC,
-        ),
-        _Tokens.ARROW,
-        _readNode(data.expressionFunctionBody_expression),
-        _Tokens.SEMICOLON,
-      );
-    } finally {
-      timerAstBinaryReaderFunctionBody.stop();
-    }
-  }
-
-  ExpressionStatement _read_expressionStatement(LinkedNode data) {
-    return astFactory.expressionStatement(
-      _readNode(data.expressionStatement_expression),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  ExtendsClause _read_extendsClause(LinkedNode data) {
-    return astFactory.extendsClause(
-      _Tokens.EXTENDS,
-      _readNode(data.extendsClause_superclass),
-    );
-  }
-
-  ExtensionDeclaration _read_extensionDeclaration(LinkedNode data) {
-    timerAstBinaryReaderClass.start();
-    try {
-      var node = astFactory.extensionDeclaration(
-        comment: _readDocumentationComment(data),
-        metadata: _readNodeListLazy(data.annotatedNode_metadata),
-        extensionKeyword: _Tokens.EXTENSION,
-        name: data.name.isNotEmpty ? _declaredIdentifier(data) : null,
-        typeParameters: _readNode(data.extensionDeclaration_typeParameters),
-        onKeyword: _Tokens.ON,
-        extendedType: _readNodeLazy(data.extensionDeclaration_extendedType),
-        leftBracket: _Tokens.OPEN_CURLY_BRACKET,
-        members: _readNodeListLazy(data.extensionDeclaration_members),
-        rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
-      );
-      LazyExtensionDeclaration(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderClass.stop();
-    }
-  }
-
-  ExtensionOverride _read_extensionOverride(LinkedNode data) {
-    var node = astFactory.extensionOverride(
-      extensionName: _readNode(data.extensionOverride_extensionName),
-      argumentList: astFactory.argumentList(
-        _Tokens.OPEN_PAREN,
-        _readNodeList(
-          data.extensionOverride_arguments,
-        ),
-        _Tokens.CLOSE_PAREN,
-      ),
-      typeArguments: _readNode(data.extensionOverride_typeArguments),
-    ) as ExtensionOverrideImpl;
-    node.extendedType = _readType(data.extensionOverride_extendedType);
-    node.typeArgumentTypes =
-        data.extensionOverride_typeArgumentTypes.map(_readType).toList();
-    return node;
-  }
-
-  FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
-    var node = astFactory.fieldDeclaration2(
-      comment: _readDocumentationComment(data),
-      abstractKeyword:
-          AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      externalKeyword:
-          AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      fieldList: _readNode(data.fieldDeclaration_fields),
-      metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      semicolon: _Tokens.SEMICOLON,
-      staticKeyword:
-          AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
-    );
-    LazyFieldDeclaration.setData(node, data);
-    return node;
-  }
-
-  FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
-    var node = astFactory.fieldFormalParameter2(
-      identifier: _declaredIdentifier(data),
-      period: _Tokens.PERIOD,
-      thisKeyword: _Tokens.THIS,
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      typeParameters: _readNode(data.fieldFormalParameter_typeParameters),
-      keyword: _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
-      metadata: _readNodeList(data.normalFormalParameter_metadata),
-      comment: _readDocumentationComment(data),
-      type: _readNodeLazy(data.fieldFormalParameter_type),
-      parameters: _readNodeLazy(data.fieldFormalParameter_formalParameters),
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-      requiredKeyword:
-          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
-    );
-    LazyFormalParameter.setData(node, data);
-    return node;
-  }
-
-  ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration(
-      LinkedNode data) {
-    return astFactory.forEachPartsWithDeclaration(
-      inKeyword: _Tokens.IN,
-      iterable: _readNode(data.forEachParts_iterable),
-      loopVariable: _readNode(data.forEachPartsWithDeclaration_loopVariable),
-    );
-  }
-
-  ForEachPartsWithIdentifier _read_forEachPartsWithIdentifier(LinkedNode data) {
-    return astFactory.forEachPartsWithIdentifier(
-      inKeyword: _Tokens.IN,
-      iterable: _readNode(data.forEachParts_iterable),
-      identifier: _readNode(data.forEachPartsWithIdentifier_identifier),
-    );
-  }
-
-  ForElement _read_forElement(LinkedNode data) {
-    return astFactory.forElement(
-      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
-      body: _readNode(data.forElement_body),
-      forKeyword: _Tokens.FOR,
-      forLoopParts: _readNode(data.forMixin_forLoopParts),
-      leftParenthesis: _Tokens.OPEN_PAREN,
-      rightParenthesis: _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  FormalParameterList _read_formalParameterList(LinkedNode data) {
-    return astFactory.formalParameterList(
-      _Tokens.OPEN_PAREN,
-      _readNodeList(data.formalParameterList_parameters),
-      _Tokens.choose(
-        AstBinaryFlags.isDelimiterCurly(data.flags),
-        _Tokens.OPEN_CURLY_BRACKET,
-        AstBinaryFlags.isDelimiterSquare(data.flags),
-        _Tokens.OPEN_SQUARE_BRACKET,
-      ),
-      _Tokens.choose(
-        AstBinaryFlags.isDelimiterCurly(data.flags),
-        _Tokens.CLOSE_CURLY_BRACKET,
-        AstBinaryFlags.isDelimiterSquare(data.flags),
-        _Tokens.CLOSE_SQUARE_BRACKET,
-      ),
-      _Tokens.CLOSE_PAREN,
-    );
-  }
-
-  ForPartsWithDeclarations _read_forPartsWithDeclarations(LinkedNode data) {
-    return astFactory.forPartsWithDeclarations(
-      condition: _readNode(data.forParts_condition),
-      leftSeparator: _Tokens.SEMICOLON,
-      rightSeparator: _Tokens.SEMICOLON,
-      updaters: _readNodeList(data.forParts_updaters),
-      variables: _readNode(data.forPartsWithDeclarations_variables),
-    );
-  }
-
-  ForPartsWithExpression _read_forPartsWithExpression(LinkedNode data) {
-    return astFactory.forPartsWithExpression(
-      condition: _readNode(data.forParts_condition),
-      initialization: _readNode(data.forPartsWithExpression_initialization),
-      leftSeparator: _Tokens.SEMICOLON,
-      rightSeparator: _Tokens.SEMICOLON,
-      updaters: _readNodeList(data.forParts_updaters),
-    );
-  }
-
-  ForStatement _read_forStatement(LinkedNode data) {
-    return astFactory.forStatement(
-      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
-      forKeyword: _Tokens.FOR,
-      leftParenthesis: _Tokens.OPEN_PAREN,
-      forLoopParts: _readNode(data.forMixin_forLoopParts),
-      rightParenthesis: _Tokens.CLOSE_PAREN,
-      body: _readNode(data.forStatement_body),
-    );
-  }
-
-  FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
-    timerAstBinaryReaderFunctionDeclaration.start();
-    try {
-      var node = astFactory.functionDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-        _readNodeLazy(data.functionDeclaration_returnType),
-        _Tokens.choose(
-          AstBinaryFlags.isGet(data.flags),
-          _Tokens.GET,
-          AstBinaryFlags.isSet(data.flags),
-          _Tokens.SET,
-        ),
-        _declaredIdentifier(data),
-        _readNodeLazy(data.functionDeclaration_functionExpression),
-      );
-      LazyFunctionDeclaration.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderFunctionDeclaration.stop();
-    }
-  }
-
-  FunctionDeclarationStatement _read_functionDeclarationStatement(
-      LinkedNode data) {
-    return astFactory.functionDeclarationStatement(
-      _readNode(data.functionDeclarationStatement_functionDeclaration),
-    );
-  }
-
-  FunctionExpression _read_functionExpression(LinkedNode data) {
-    var node = astFactory.functionExpression(
-      _readNode(data.functionExpression_typeParameters),
-      _readNodeLazy(data.functionExpression_formalParameters),
-      _readNodeLazy(data.functionExpression_body),
-    );
-    LazyFunctionExpression.setData(node, data);
-    return node;
-  }
-
-  FunctionExpressionInvocation _read_functionExpressionInvocation(
-      LinkedNode data) {
-    return astFactory.functionExpressionInvocation(
-      _readNode(data.functionExpressionInvocation_function),
-      _readNode(data.invocationExpression_typeArguments),
-      _readNode(data.invocationExpression_arguments),
-    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
-  }
-
-  FunctionTypeAlias _read_functionTypeAlias(LinkedNode data) {
-    var node = astFactory.functionTypeAlias(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _Tokens.TYPEDEF,
-      _readNodeLazy(data.functionTypeAlias_returnType),
-      _declaredIdentifier(data),
-      _readNode(data.functionTypeAlias_typeParameters),
-      _readNodeLazy(data.functionTypeAlias_formalParameters),
-      _Tokens.SEMICOLON,
-    );
-    LazyFunctionTypeAlias.setData(node, data);
-    LazyFunctionTypeAlias.setHasSelfReference(
-      node,
-      data.typeAlias_hasSelfReference,
-    );
-    return node;
-  }
-
-  FunctionTypedFormalParameter _read_functionTypedFormalParameter(
-      LinkedNode data) {
-    var node = astFactory.functionTypedFormalParameter2(
-      comment: _readDocumentationComment(data),
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      identifier: _declaredIdentifier(data),
-      metadata: _readNodeListLazy(data.normalFormalParameter_metadata),
-      parameters: _readNodeLazy(
-        data.functionTypedFormalParameter_formalParameters,
-      ),
-      requiredKeyword:
-          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
-      returnType: _readNodeLazy(data.functionTypedFormalParameter_returnType),
-      typeParameters: _readNode(
-        data.functionTypedFormalParameter_typeParameters,
-      ),
-    );
-    LazyFormalParameter.setData(node, data);
-    return node;
-  }
-
-  GenericFunctionType _read_genericFunctionType(LinkedNode data) {
-    var id = data.genericFunctionType_id;
-
-    // Read type parameters, without bounds, to avoid forward references.
-    TypeParameterList typeParameterList;
-    var typeParameterListData = data.genericFunctionType_typeParameters;
-    if (typeParameterListData != null) {
-      var dataList = typeParameterListData.typeParameterList_typeParameters;
-      var typeParameters = List<TypeParameter>(dataList.length);
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        typeParameters[i] = astFactory.typeParameter(
-          _readDocumentationComment(data),
-          _readNodeList(data.annotatedNode_metadata),
-          _declaredIdentifier(data),
-          data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
-          null,
-        );
-      }
-      typeParameterList = astFactory.typeParameterList(
-        _Tokens.LT,
-        typeParameters,
-        _Tokens.GT,
-      );
-    }
-
-    GenericFunctionTypeImpl node = astFactory.genericFunctionType(
       null,
-      _Tokens.FUNCTION,
-      typeParameterList,
-      null,
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-    );
-
-    // Create the node element, so now type parameter elements are available.
-    LazyAst.setGenericFunctionTypeId(node, id);
-    _unitContext.createGenericFunctionTypeElement(id, node);
-
-    // Finish reading.
-    if (typeParameterListData != null) {
-      var dataList = typeParameterListData.typeParameterList_typeParameters;
-      var typeParameters = typeParameterList.typeParameters;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        var node = typeParameters[i];
-        node.bound = _readNode(data.typeParameter_bound);
-      }
-    }
-    node.returnType = readNode(data.genericFunctionType_returnType);
-    node.parameters = _readNode(data.genericFunctionType_formalParameters);
-    node.type = _readType(data.genericFunctionType_type);
-
-    return node;
-  }
-
-  GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
-    var node = astFactory.genericTypeAlias(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _Tokens.TYPEDEF,
-      _declaredIdentifier(data),
-      _readNode(data.genericTypeAlias_typeParameters),
-      _Tokens.EQ,
-      _readNodeLazy(data.genericTypeAlias_functionType),
-      _Tokens.SEMICOLON,
-    );
-    LazyGenericTypeAlias.setData(node, data);
-    LazyGenericTypeAlias.setHasSelfReference(
-      node,
-      data.typeAlias_hasSelfReference,
-    );
-    return node;
-  }
-
-  HideCombinator _read_hideCombinator(LinkedNode data) {
-    var node = astFactory.hideCombinator(
-      _combinatorKeyword(data, Keyword.HIDE, _Tokens.HIDE),
-      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
-    );
-    LazyCombinator(node, data);
-    return node;
-  }
-
-  IfElement _read_ifElement(LinkedNode data) {
-    var elseElement = _readNode(data.ifElement_elseElement);
-    return astFactory.ifElement(
-      condition: _readNode(data.ifMixin_condition),
-      elseElement: elseElement,
-      elseKeyword: elseElement != null ? _Tokens.ELSE : null,
-      ifKeyword: _Tokens.IF,
-      leftParenthesis: _Tokens.OPEN_PAREN,
-      rightParenthesis: _Tokens.CLOSE_PAREN,
-      thenElement: _readNode(data.ifElement_thenElement),
-    );
-  }
-
-  IfStatement _read_ifStatement(LinkedNode data) {
-    var elseStatement = _readNode(data.ifStatement_elseStatement);
-    return astFactory.ifStatement(
-      _Tokens.IF,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.ifMixin_condition),
-      _Tokens.CLOSE_PAREN,
-      _readNode(data.ifStatement_thenStatement),
-      elseStatement != null ? _Tokens.ELSE : null,
-      elseStatement,
-    );
-  }
-
-  ImplementsClause _read_implementsClause(LinkedNode data) {
-    return astFactory.implementsClause(
-      _Tokens.IMPLEMENTS,
-      _readNodeList(data.implementsClause_interfaces),
-    );
-  }
-
-  ImportDirective _read_importDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      SimpleIdentifier prefix;
-      if (data.importDirective_prefix.isNotEmpty) {
-        prefix = astFactory.simpleIdentifier(
-          TokenFactory.tokenFromString(data.importDirective_prefix),
-        );
-
-        var informativeData = _unitContext.getInformativeData(data);
-        prefix.token.offset =
-            informativeData?.importDirective_prefixOffset ?? 0;
-      }
-
-      var node = astFactory.importDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _directiveKeyword(data, Keyword.IMPORT, _Tokens.IMPORT),
-        _readNode(data.uriBasedDirective_uri),
-        _readNodeList(data.namespaceDirective_configurations),
-        AstBinaryFlags.isDeferred(data.flags) ? _Tokens.DEFERRED : null,
-        _Tokens.AS,
-        prefix,
-        _readNodeList(data.namespaceDirective_combinators),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  IndexExpression _read_indexExpression(LinkedNode data) {
-    return astFactory.indexExpressionForTarget2(
-      target: _readNode(data.indexExpression_target),
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-      leftBracket: _Tokens.OPEN_SQUARE_BRACKET,
-      index: _readNode(data.indexExpression_index),
-      rightBracket: _Tokens.CLOSE_SQUARE_BRACKET,
-    )
-      ..period =
-          AstBinaryFlags.hasPeriod(data.flags) ? _Tokens.PERIOD_PERIOD : null
-      ..staticElement = _elementOfComponents(
-        data.indexExpression_element,
-        data.indexExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  InstanceCreationExpression _read_instanceCreationExpression(LinkedNode data) {
-    var node = astFactory.instanceCreationExpression(
-      _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isNew(data.flags),
-        _Tokens.NEW,
+      metadata,
+      Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
       ),
-      _readNode(data.instanceCreationExpression_constructorName),
-      astFactory.argumentList(
-        _Tokens.OPEN_PAREN,
-        _readNodeList(
-          data.instanceCreationExpression_arguments,
-        ),
-        _Tokens.CLOSE_PAREN,
-      ),
-      typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
-    );
-    node.staticType = _readType(data.expression_type);
-    return node;
-  }
-
-  IntegerLiteral _read_integerLiteral(LinkedNode data) {
-    // TODO(scheglov) Remove `?? _intType` after internal SDK roll.
-    return AstTestFactory.integer(data.integerLiteral_value)
-      ..staticType = _readType(data.expression_type) ?? _intType;
-  }
-
-  InterpolationExpression _read_interpolationExpression(LinkedNode data) {
-    var isIdentifier =
-        AstBinaryFlags.isStringInterpolationIdentifier(data.flags);
-    return astFactory.interpolationExpression(
-      isIdentifier
-          ? _Tokens.OPEN_CURLY_BRACKET
-          : _Tokens.STRING_INTERPOLATION_EXPRESSION,
-      _readNode(data.interpolationExpression_expression),
-      isIdentifier ? null : _Tokens.CLOSE_CURLY_BRACKET,
+      type,
+      identifier,
     );
   }
 
-  InterpolationString _read_interpolationString(LinkedNode data) {
-    return astFactory.interpolationString(
-      TokenFactory.tokenFromString(data.interpolationString_value),
-      data.interpolationString_value,
-    );
-  }
+  DefaultFormalParameter _readDefaultFormalParameter() {
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var parameter = readNode() as NormalFormalParameter;
+    var defaultValue = _readOptionalNode() as Expression;
 
-  IsExpression _read_isExpression(LinkedNode data) {
-    return astFactory.isExpression(
-      _readNode(data.isExpression_expression),
-      _Tokens.IS,
-      AstBinaryFlags.hasNot(data.flags) ? _Tokens.BANG : null,
-      _readNode(data.isExpression_type),
-    )..staticType = _boolType;
-  }
-
-  Label _read_label(LinkedNode data) {
-    return astFactory.label(
-      _readNode(data.label_label),
-      _Tokens.COLON,
-    );
-  }
-
-  LabeledStatement _read_labeledStatement(LinkedNode data) {
-    return astFactory.labeledStatement(
-      _readNodeList(data.labeledStatement_labels),
-      _readNode(data.labeledStatement_statement),
-    );
-  }
-
-  LibraryDirective _read_libraryDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.libraryDirective(
-        _unitContext.createComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.LIBRARY,
-        _readNode(data.libraryDirective_name),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  LibraryIdentifier _read_libraryIdentifier(LinkedNode data) {
-    return astFactory.libraryIdentifier(
-      _readNodeList(data.libraryIdentifier_components),
-    );
-  }
-
-  ListLiteral _read_listLiteral(LinkedNode data) {
-    return astFactory.listLiteral(
-      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
-      AstBinaryFlags.hasTypeArguments(data.flags)
-          ? astFactory.typeArgumentList(
-              _Tokens.LT,
-              _readNodeList(data.typedLiteral_typeArguments),
-              _Tokens.GT,
-            )
-          : null,
-      _Tokens.OPEN_SQUARE_BRACKET,
-      _readNodeList(data.listLiteral_elements),
-      _Tokens.CLOSE_SQUARE_BRACKET,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  MapLiteralEntry _read_mapLiteralEntry(LinkedNode data) {
-    return astFactory.mapLiteralEntry(
-      _readNode(data.mapLiteralEntry_key),
-      _Tokens.COLON,
-      _readNode(data.mapLiteralEntry_value),
-    );
-  }
-
-  MethodDeclaration _read_methodDeclaration(LinkedNode data) {
-    FunctionBody body;
-    if (AstBinaryFlags.isNative(data.flags)) {
-      body = AstTestFactory.nativeFunctionBody('');
-    } else if (AstBinaryFlags.isAbstract(data.flags)) {
-      body = AstTestFactory.emptyFunctionBody();
+    ParameterKind kind;
+    if (AstBinaryFlags.isPositional(flags)) {
+      kind = AstBinaryFlags.isRequired(flags)
+          ? ParameterKind.REQUIRED
+          : ParameterKind.POSITIONAL;
     } else {
-      body = AstTestFactory.blockFunctionBody(AstTestFactory.block());
+      kind = AstBinaryFlags.isRequired(flags)
+          ? ParameterKind.NAMED_REQUIRED
+          : ParameterKind.NAMED;
     }
 
-    var node = astFactory.methodDeclaration(
-      _readDocumentationComment(data),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
-      _readNodeLazy(data.methodDeclaration_returnType),
-      _Tokens.choose(
-        AstBinaryFlags.isGet(data.flags),
-        _Tokens.GET,
-        AstBinaryFlags.isSet(data.flags),
-        _Tokens.SET,
+    var node = astFactory.defaultFormalParameter(
+      parameter,
+      kind,
+      AstBinaryFlags.hasInitializer(flags) ? Tokens.COLON : null,
+      defaultValue,
+    ) as DefaultFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+    );
+
+    return node;
+  }
+
+  DottedName _readDottedName() {
+    var components = _readNodeList<SimpleIdentifier>();
+    return astFactory.dottedName(components);
+  }
+
+  DoubleLiteral _readDoubleLiteral() {
+    var value = _unitReader.astReader.readDouble();
+    return AstTestFactory.doubleLiteral(value);
+  }
+
+  EnumConstantDeclaration _readEnumConstantDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.enumConstantDeclaration(null, metadata, name)
+        as EnumConstantDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: -1,
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  EnumDeclaration _readEnumDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var constants = _readNodeList<EnumConstantDeclaration>();
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.enumDeclaration(
+      null,
+      metadata,
+      Tokens.ENUM,
+      name,
+      Tokens.OPEN_CURLY_BRACKET,
+      constants,
+      Tokens.CLOSE_CURLY_BRACKET,
+    ) as EnumDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  ExportDirective _readExportDirective() {
+    var combinators = _readNodeList<Combinator>();
+    var configurations = _readNodeList<Configuration>();
+    var uri = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.exportDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.EXPORT, keywordOffset),
+      uri,
+      configurations,
+      combinators,
+      Tokens.SEMICOLON,
+    ) as ExportDirectiveImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      documentationTokenIndexList: _noDocumentationComment,
+      resolutionIndex: _readUInt30(),
+    );
+
+    return node;
+  }
+
+  ExtendsClause _readExtendsClause() {
+    var type = readNode() as TypeName;
+    return astFactory.extendsClause(Tokens.EXTENDS, type);
+  }
+
+  ExtensionDeclaration _readExtensionDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var extendedType = readNode() as TypeAnnotation;
+    var name = _readOptionalNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.extensionDeclaration(
+      comment: null,
+      metadata: metadata,
+      extensionKeyword: Tokens.EXTENSION,
+      name: name,
+      typeParameters: typeParameters,
+      onKeyword: Tokens.ON,
+      extendedType: extendedType,
+      leftBracket: Tokens.OPEN_CURLY_BRACKET,
+      members: const <ClassMember>[],
+      rightBracket: Tokens.CLOSE_CURLY_BRACKET,
+    ) as ExtensionDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  ExtensionOverride _readExtensionOverride() {
+    var extensionName = readNode() as Identifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var argumentList = readNode() as ArgumentList;
+    return astFactory.extensionOverride(
+      extensionName: extensionName,
+      argumentList: argumentList,
+      typeArguments: typeArguments,
+    );
+  }
+
+  FieldDeclaration _readFieldDeclaration() {
+    var flags = _readByte();
+    var codeOffsetLengthList = _readInformativeUint30List();
+    var documentationTokenIndexList = _readUint30List();
+    var fields = readNode() as VariableDeclarationList;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.fieldDeclaration2(
+      comment: null,
+      abstractKeyword:
+          AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      externalKeyword:
+          AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      fieldList: fields,
+      metadata: metadata,
+      semicolon: Tokens.SEMICOLON,
+      staticKeyword: AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
+    ) as FieldDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      codeOffsetLengthList: codeOffsetLengthList,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  FieldFormalParameter _readFieldFormalParameter() {
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var type = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = _readOptionalNode() as FormalParameterList;
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+    var identifier = readNode() as SimpleIdentifier;
+    var node = astFactory.fieldFormalParameter2(
+      identifier: identifier,
+      period: Tokens.PERIOD,
+      thisKeyword: Tokens.THIS,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      typeParameters: typeParameters,
+      keyword: Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
       ),
-      AstBinaryFlags.isOperator(data.flags) ? _Tokens.OPERATOR : null,
-      _declaredIdentifier(data),
-      _readNode(data.methodDeclaration_typeParameters),
-      _readNodeLazy(data.methodDeclaration_formalParameters),
+      metadata: metadata,
+      comment: null,
+      type: type,
+      parameters: formalParameters,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+      requiredKeyword:
+          AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+    ) as FieldFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+    );
+    return node;
+  }
+
+  ForEachPartsWithDeclaration _readForEachPartsWithDeclaration() {
+    var loopVariable = readNode() as DeclaredIdentifier;
+    var iterable = readNode() as Expression;
+    return astFactory.forEachPartsWithDeclaration(
+      inKeyword: Tokens.IN,
+      iterable: iterable,
+      loopVariable: loopVariable,
+    );
+  }
+
+  ForElement _readForElement() {
+    var body = readNode() as CollectionElement;
+    var flags = _readByte();
+    var forLoopParts = readNode() as ForLoopParts;
+    return astFactory.forElement(
+      awaitKeyword: AstBinaryFlags.hasAwait(flags) ? Tokens.AWAIT : null,
+      body: body,
+      forKeyword: Tokens.FOR,
+      forLoopParts: forLoopParts,
+      leftParenthesis: Tokens.OPEN_PAREN,
+      rightParenthesis: Tokens.CLOSE_PAREN,
+    );
+  }
+
+  FormalParameterList _readFormalParameterList() {
+    var flags = _readByte();
+    var parameters = _readNodeList<FormalParameter>();
+
+    return astFactory.formalParameterList(
+      Tokens.OPEN_PAREN,
+      parameters,
+      Tokens.choose(
+        AstBinaryFlags.isDelimiterCurly(flags),
+        Tokens.OPEN_CURLY_BRACKET,
+        AstBinaryFlags.isDelimiterSquare(flags),
+        Tokens.OPEN_SQUARE_BRACKET,
+      ),
+      Tokens.choose(
+        AstBinaryFlags.isDelimiterCurly(flags),
+        Tokens.CLOSE_CURLY_BRACKET,
+        AstBinaryFlags.isDelimiterSquare(flags),
+        Tokens.CLOSE_SQUARE_BRACKET,
+      ),
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  ForPartsWithDeclarations _readForPartsWithDeclarations() {
+    var variables = readNode() as VariableDeclarationList;
+    var condition = _readOptionalNode() as Expression;
+    var updaters = _readNodeList<Expression>();
+    return astFactory.forPartsWithDeclarations(
+      condition: condition,
+      leftSeparator: Tokens.SEMICOLON,
+      rightSeparator: Tokens.SEMICOLON,
+      updaters: updaters,
+      variables: variables,
+    );
+  }
+
+  FunctionDeclaration _readFunctionDeclaration() {
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+    var functionExpression = readNode() as FunctionExpression;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.functionDeclaration(
+      null,
+      metadata,
+      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      returnType,
+      Tokens.choose(
+        AstBinaryFlags.isGet(flags),
+        Tokens.GET,
+        AstBinaryFlags.isSet(flags),
+        Tokens.SET,
+      ),
+      name,
+      functionExpression,
+    ) as FunctionDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  FunctionExpression _readFunctionExpression() {
+    var flags = _readByte();
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var formalParameters = _readOptionalNode() as FormalParameterList;
+    var body = _functionBodyForFlags(flags);
+
+    return astFactory.functionExpression(
+      typeParameters,
+      formalParameters,
       body,
     );
-    LazyMethodDeclaration.setData(node, data);
-    LazyAst.setOperatorEqualParameterTypeFromObject(
+  }
+
+  FunctionExpressionInvocation _readFunctionExpressionInvocation() {
+    var function = readNode() as Expression;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var arguments = readNode() as ArgumentList;
+    return astFactory.functionExpressionInvocation(
+      function,
+      typeArguments,
+      arguments,
+    );
+  }
+
+  FunctionTypeAlias _readFunctionTypeAlias() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = readNode() as FormalParameterList;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.functionTypeAlias(
+      null,
+      metadata,
+      Tokens.TYPEDEF,
+      returnType,
+      name,
+      typeParameters,
+      formalParameters,
+      Tokens.SEMICOLON,
+    ) as FunctionTypeAliasImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
       node,
-      data.methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
     );
+
     return node;
   }
 
-  MethodInvocation _read_methodInvocation(LinkedNode data) {
-    return astFactory.methodInvocation(
-      _readNode(data.methodInvocation_target),
-      _Tokens.choose(
-        AstBinaryFlags.hasPeriod(data.flags),
-        _Tokens.PERIOD,
-        AstBinaryFlags.hasPeriod2(data.flags),
-        _Tokens.PERIOD_PERIOD,
-      ),
-      _readNode(data.methodInvocation_methodName),
-      _readNode(data.invocationExpression_typeArguments),
-      _readNode(data.invocationExpression_arguments),
-    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
-  }
-
-  MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
-    timerAstBinaryReaderMixin.start();
-    try {
-      var node = astFactory.mixinDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.MIXIN,
-        _declaredIdentifier(data),
-        _readNode(data.classOrMixinDeclaration_typeParameters),
-        _readNodeLazy(data.mixinDeclaration_onClause),
-        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
-        _Tokens.OPEN_CURLY_BRACKET,
-        _readNodeListLazy(data.classOrMixinDeclaration_members),
-        _Tokens.CLOSE_CURLY_BRACKET,
-      );
-      LazyMixinDeclaration(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderMixin.stop();
-    }
-  }
-
-  NamedExpression _read_namedExpression(LinkedNode data) {
-    Expression expression = _readNode(data.namedExpression_expression);
-    return astFactory.namedExpression(
-      _readNode(data.namedExpression_name),
-      expression,
-    )..staticType = expression.staticType;
-  }
-
-  NativeClause _read_nativeClause(LinkedNode data) {
-    return astFactory.nativeClause(
-      _Tokens.NATIVE,
-      _readNode(data.nativeClause_name),
-    );
-  }
-
-  NativeFunctionBody _read_nativeFunctionBody(LinkedNode data) {
-    return astFactory.nativeFunctionBody(
-      _Tokens.NATIVE,
-      _readNode(data.nativeFunctionBody_stringLiteral),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  NullLiteral _read_nullLiteral(LinkedNode data) {
-    return astFactory.nullLiteral(
-      _Tokens.NULL,
-    )..staticType = _nullType;
-  }
-
-  OnClause _read_onClause(LinkedNode data) {
-    return astFactory.onClause(
-      _Tokens.ON,
-      _readNodeList(data.onClause_superclassConstraints),
-    );
-  }
-
-  ParenthesizedExpression _read_parenthesizedExpression(LinkedNode data) {
-    return astFactory.parenthesizedExpression(
-      _Tokens.OPEN_PAREN,
-      _readNode(data.parenthesizedExpression_expression),
-      _Tokens.CLOSE_PAREN,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  PartDirective _read_partDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.partDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.PART,
-        _readNode(data.uriBasedDirective_uri),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  PartOfDirective _read_partOfDirective(LinkedNode data) {
-    timerAstBinaryReaderDirective.start();
-    _isReadingDirective = true;
-    try {
-      var node = astFactory.partOfDirective(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _Tokens.PART,
-        _Tokens.OF,
-        _readNode(data.partOfDirective_uri),
-        _readNode(data.partOfDirective_libraryName),
-        _Tokens.SEMICOLON,
-      );
-      LazyDirective.setData(node, data);
-      return node;
-    } finally {
-      _isReadingDirective = false;
-      timerAstBinaryReaderDirective.stop();
-    }
-  }
-
-  PostfixExpression _read_postfixExpression(LinkedNode data) {
-    return astFactory.postfixExpression(
-      _readNode(data.postfixExpression_operand),
-      _Tokens.fromType(data.postfixExpression_operator),
-    )
-      ..staticElement = _elementOfComponents(
-        data.postfixExpression_element,
-        data.postfixExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  PrefixedIdentifier _read_prefixedIdentifier(LinkedNode data) {
-    return astFactory.prefixedIdentifier(
-      _readNode(data.prefixedIdentifier_prefix),
-      _Tokens.PERIOD,
-      _readNode(data.prefixedIdentifier_identifier),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  PrefixExpression _read_prefixExpression(LinkedNode data) {
-    return astFactory.prefixExpression(
-      _Tokens.fromType(data.prefixExpression_operator),
-      _readNode(data.prefixExpression_operand),
-    )
-      ..staticElement = _elementOfComponents(
-        data.prefixExpression_element,
-        data.prefixExpression_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
-
-  PropertyAccess _read_propertyAccess(LinkedNode data) {
-    return astFactory.propertyAccess(
-      _readNode(data.propertyAccess_target),
-      _Tokens.fromType(data.propertyAccess_operator),
-      _readNode(data.propertyAccess_propertyName),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  RedirectingConstructorInvocation _read_redirectingConstructorInvocation(
-      LinkedNode data) {
-    var hasThis = AstBinaryFlags.hasThis(data.flags);
-    return astFactory.redirectingConstructorInvocation(
-      hasThis ? _Tokens.THIS : null,
-      hasThis ? _Tokens.PERIOD : null,
-      _readNode(data.redirectingConstructorInvocation_constructorName),
-      _readNode(data.redirectingConstructorInvocation_arguments),
-    )..staticElement = _elementOfComponents(
-        data.redirectingConstructorInvocation_element,
-        data.redirectingConstructorInvocation_substitution,
-      );
-  }
-
-  RethrowExpression _read_rethrowExpression(LinkedNode data) {
-    return astFactory.rethrowExpression(
-      _Tokens.RETHROW,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  ReturnStatement _read_returnStatement(LinkedNode data) {
-    return astFactory.returnStatement(
-      _Tokens.RETURN,
-      _readNode(data.returnStatement_expression),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  SetOrMapLiteral _read_setOrMapLiteral(LinkedNode data) {
-    SetOrMapLiteralImpl node = astFactory.setOrMapLiteral(
-      constKeyword: AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
-      elements: _readNodeList(data.setOrMapLiteral_elements),
-      leftBracket: _Tokens.OPEN_CURLY_BRACKET,
-      typeArguments: AstBinaryFlags.hasTypeArguments(data.flags)
-          ? astFactory.typeArgumentList(
-              _Tokens.LT,
-              _readNodeList(data.typedLiteral_typeArguments),
-              _Tokens.GT,
-            )
-          : null,
-      rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
-    )..staticType = _readType(data.expression_type);
-    if (AstBinaryFlags.isMap(data.flags)) {
-      node.becomeMap();
-    } else if (AstBinaryFlags.isSet(data.flags)) {
-      node.becomeSet();
-    }
-    return node;
-  }
-
-  ShowCombinator _read_showCombinator(LinkedNode data) {
-    var node = astFactory.showCombinator(
-      _combinatorKeyword(data, Keyword.SHOW, _Tokens.SHOW),
-      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
-    );
-    LazyCombinator(node, data);
-    return node;
-  }
-
-  SimpleFormalParameter _read_simpleFormalParameter(LinkedNode data) {
-    SimpleFormalParameterImpl node = astFactory.simpleFormalParameter2(
-      identifier: _declaredIdentifier(data),
-      type: _readNode(data.simpleFormalParameter_type),
+  FunctionTypedFormalParameter _readFunctionTypedFormalParameter() {
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = readNode() as FormalParameterList;
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+    var identifier = readNode() as SimpleIdentifier;
+    var node = astFactory.functionTypedFormalParameter2(
+      comment: null,
       covariantKeyword:
-          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
-      comment: _readDocumentationComment(data),
-      metadata: _readNodeList(data.normalFormalParameter_metadata),
-      keyword: _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      identifier: identifier,
+      metadata: metadata,
+      parameters: formalParameters,
       requiredKeyword:
-          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
+          AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+      returnType: returnType,
+      typeParameters: typeParameters,
+    ) as FunctionTypedFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
     );
-    LazyFormalParameter.setData(node, data);
-    LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
     return node;
   }
 
-  SimpleIdentifier _read_simpleIdentifier(LinkedNode data) {
-    return astFactory.simpleIdentifier(
-      TokenFactory.tokenFromString(data.name),
-      isDeclaration: AstBinaryFlags.isDeclaration(data.flags),
-    )
-      ..staticElement = _elementOfComponents(
-        data.simpleIdentifier_element,
-        data.simpleIdentifier_substitution,
-      )
-      ..staticType = _readType(data.expression_type);
-  }
+  GenericFunctionType _readGenericFunctionType() {
+    var flags = _readByte();
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = readNode() as FormalParameterList;
 
-  SimpleStringLiteral _read_simpleStringLiteral(LinkedNode data) {
-    var node = AstTestFactory.string2(data.simpleStringLiteral_value);
-    if (!_isReadingDirective) {
-      node.staticType = _stringType;
-    }
-    return node;
-  }
-
-  SpreadElement _read_spreadElement(LinkedNode data) {
-    return astFactory.spreadElement(
-      spreadOperator: _Tokens.fromType(data.spreadElement_spreadOperator),
-      expression: _readNode(data.spreadElement_expression),
+    return astFactory.genericFunctionType(
+      returnType,
+      Tokens.FUNCTION,
+      typeParameters,
+      formalParameters,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
     );
   }
 
-  StringInterpolation _read_stringInterpolation(LinkedNode data) {
-    var node = astFactory.stringInterpolation(
-      _readNodeList(data.stringInterpolation_elements),
+  GenericTypeAlias _readGenericTypeAlias() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var type = _readOptionalNode();
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.genericTypeAlias(
+      null,
+      metadata,
+      Tokens.TYPEDEF,
+      name,
+      typeParameters,
+      Tokens.EQ,
+      type,
+      Tokens.SEMICOLON,
+    ) as GenericTypeAliasImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
     );
-    if (!_isReadingDirective) {
-      node.staticType = _stringType;
-    }
+
     return node;
   }
 
-  SuperConstructorInvocation _read_superConstructorInvocation(LinkedNode data) {
-    return astFactory.superConstructorInvocation(
-      _Tokens.SUPER,
-      _Tokens.PERIOD,
-      _readNode(data.superConstructorInvocation_constructorName),
-      _readNode(data.superConstructorInvocation_arguments),
-    )..staticElement = _elementOfComponents(
-        data.superConstructorInvocation_element,
-        data.superConstructorInvocation_substitution,
+  HideCombinator _readHideCombinator() {
+    var keywordOffset = _readInformativeUint30();
+    return astFactory.hideCombinator(
+      KeywordToken(Keyword.HIDE, keywordOffset),
+      _readNodeList<SimpleIdentifier>(),
+    );
+  }
+
+  IfElement _readIfElement() {
+    var condition = readNode() as Expression;
+    var thenElement = readNode() as CollectionElement;
+    var elseElement = _readOptionalNode() as CollectionElement;
+    return astFactory.ifElement(
+      condition: condition,
+      elseElement: elseElement,
+      elseKeyword: elseElement != null ? Tokens.ELSE : null,
+      ifKeyword: Tokens.IF,
+      leftParenthesis: Tokens.OPEN_PAREN,
+      rightParenthesis: Tokens.CLOSE_PAREN,
+      thenElement: thenElement,
+    );
+  }
+
+  ImplementsClause _readImplementsClause() {
+    var interfaces = _readNodeList<TypeName>();
+    return astFactory.implementsClause(Tokens.IMPLEMENTS, interfaces);
+  }
+
+  ImportDirective _readImportDirective() {
+    var flags = _readByte();
+
+    SimpleIdentifier prefixIdentifier;
+    if (AstBinaryFlags.hasPrefix(flags)) {
+      var prefixName = _readStringReference();
+      var prefixOffset = _readInformativeUint30();
+      prefixIdentifier = astFactory.simpleIdentifier(
+        StringToken(TokenType.STRING, prefixName, prefixOffset),
       );
-  }
-
-  SuperExpression _read_superExpression(LinkedNode data) {
-    return astFactory.superExpression(
-      _Tokens.SUPER,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  SwitchCase _read_switchCase(LinkedNode data) {
-    return astFactory.switchCase(
-      _readNodeList(data.switchMember_labels),
-      _Tokens.CASE,
-      _readNode(data.switchCase_expression),
-      _Tokens.COLON,
-      _readNodeList(data.switchMember_statements),
-    );
-  }
-
-  SwitchDefault _read_switchDefault(LinkedNode data) {
-    return astFactory.switchDefault(
-      _readNodeList(data.switchMember_labels),
-      _Tokens.DEFAULT,
-      _Tokens.COLON,
-      _readNodeList(data.switchMember_statements),
-    );
-  }
-
-  SwitchStatement _read_switchStatement(LinkedNode data) {
-    return astFactory.switchStatement(
-      _Tokens.SWITCH,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.switchStatement_expression),
-      _Tokens.CLOSE_PAREN,
-      _Tokens.OPEN_CURLY_BRACKET,
-      _readNodeList(data.switchStatement_members),
-      _Tokens.CLOSE_CURLY_BRACKET,
-    );
-  }
-
-  SymbolLiteral _read_symbolLiteral(LinkedNode data) {
-    return astFactory.symbolLiteral(
-      _Tokens.HASH,
-      data.names.map((lexeme) => TokenFactory.tokenFromString(lexeme)).toList(),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  ThisExpression _read_thisExpression(LinkedNode data) {
-    return astFactory.thisExpression(
-      _Tokens.THIS,
-    )..staticType = _readType(data.expression_type);
-  }
-
-  ThrowExpression _read_throwExpression(LinkedNode data) {
-    return astFactory.throwExpression(
-      _Tokens.THROW,
-      _readNode(data.throwExpression_expression),
-    )..staticType = _readType(data.expression_type);
-  }
-
-  TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
-      LinkedNode data) {
-    timerAstBinaryReaderTopLevelVar.start();
-    try {
-      var node = astFactory.topLevelVariableDeclaration(
-        _readDocumentationComment(data),
-        _readNodeListLazy(data.annotatedNode_metadata),
-        _readNode(data.topLevelVariableDeclaration_variableList),
-        _Tokens.SEMICOLON,
-        externalKeyword:
-            AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
-      );
-      LazyTopLevelVariableDeclaration.setData(node, data);
-      return node;
-    } finally {
-      timerAstBinaryReaderTopLevelVar.stop();
     }
-  }
 
-  TryStatement _read_tryStatement(LinkedNode data) {
-    return astFactory.tryStatement(
-      _Tokens.TRY,
-      _readNode(data.tryStatement_body),
-      _readNodeList(data.tryStatement_catchClauses),
-      _Tokens.FINALLY,
-      _readNode(data.tryStatement_finallyBlock),
+    var combinators = _readNodeList<Combinator>();
+    var configurations = _readNodeList<Configuration>();
+    var uri = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.importDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.IMPORT, keywordOffset),
+      uri,
+      configurations,
+      AstBinaryFlags.isDeferred(flags) ? Tokens.DEFERRED : null,
+      Tokens.AS,
+      prefixIdentifier,
+      combinators,
+      Tokens.SEMICOLON,
+    ) as ImportDirectiveImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      documentationTokenIndexList: _noDocumentationComment,
+      resolutionIndex: _readUInt30(),
     );
-  }
 
-  TypeArgumentList _read_typeArgumentList(LinkedNode data) {
-    return astFactory.typeArgumentList(
-      _Tokens.LT,
-      _readNodeList(data.typeArgumentList_arguments),
-      _Tokens.GT,
-    );
-  }
-
-  TypeName _read_typeName(LinkedNode data) {
-    return astFactory.typeName(
-      _readNode(data.typeName_name),
-      AstBinaryFlags.hasTypeArguments(data.flags)
-          ? astFactory.typeArgumentList(
-              _Tokens.LT,
-              _readNodeList(data.typeName_typeArguments),
-              _Tokens.GT,
-            )
-          : null,
-      question:
-          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
-    )..type = _readType(data.typeName_type);
-  }
-
-  TypeParameter _read_typeParameter(LinkedNode data) {
-    // TODO (kallentu) : Clean up AstFactoryImpl casting once variance is
-    // added to the interface.
-    var node = (astFactory as AstFactoryImpl).typeParameter2(
-      comment: _readDocumentationComment(data),
-      metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      name: _declaredIdentifier(data),
-      extendsKeyword: _Tokens.EXTENDS,
-      bound: _readNodeLazy(data.typeParameter_bound),
-    );
-    LazyAst.setVariance(node, _decodeVariance(data.typeParameter_variance));
-    LazyTypeParameter.setData(node, data);
     return node;
   }
 
-  TypeParameterList _read_typeParameterList(LinkedNode data) {
-    return astFactory.typeParameterList(
-      _Tokens.LT,
-      _readNodeList(data.typeParameterList_typeParameters),
-      _Tokens.GT,
-    );
+  IndexExpression _readIndexExpression() {
+    var flags = _readByte();
+    var target = _readOptionalNode() as Expression;
+    var index = readNode() as Expression;
+    return astFactory.indexExpressionForTarget2(
+      target: target,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+      leftBracket: Tokens.OPEN_SQUARE_BRACKET,
+      index: index,
+      rightBracket: Tokens.CLOSE_SQUARE_BRACKET,
+    )..period = AstBinaryFlags.hasPeriod(flags) ? Tokens.PERIOD_PERIOD : null;
   }
 
-  VariableDeclaration _read_variableDeclaration(LinkedNode data) {
-    var node = astFactory.variableDeclaration(
-      _declaredIdentifier(data),
-      _Tokens.EQ,
-      _readNodeLazy(data.variableDeclaration_initializer),
-    );
-    LazyVariableDeclaration.setData(node, data);
-    LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
-    return node;
+  int _readInformativeUint30() {
+    if (_withInformative) {
+      return _readUInt30();
+    }
+    return 0;
   }
 
-  VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
-    var node = astFactory.variableDeclarationList2(
-      comment: _readDocumentationComment(data),
-      keyword: _Tokens.choose(
-        AstBinaryFlags.isConst(data.flags),
-        _Tokens.CONST,
-        AstBinaryFlags.isFinal(data.flags),
-        _Tokens.FINAL,
-        AstBinaryFlags.isVar(data.flags),
-        _Tokens.VAR,
-      ),
-      lateKeyword: AstBinaryFlags.isLate(data.flags) ? _Tokens.LATE : null,
-      metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      type: _readNodeLazy(data.variableDeclarationList_type),
-      variables: _readNodeList(data.variableDeclarationList_variables),
-    );
-    LazyVariableDeclarationList.setData(node, data);
-    return node;
-  }
-
-  VariableDeclarationStatement _read_variableDeclarationStatement(
-      LinkedNode data) {
-    return astFactory.variableDeclarationStatement(
-      _readNode(data.variableDeclarationStatement_variables),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  WhileStatement _read_whileStatement(LinkedNode data) {
-    return astFactory.whileStatement(
-      _Tokens.WHILE,
-      _Tokens.OPEN_PAREN,
-      _readNode(data.whileStatement_condition),
-      _Tokens.CLOSE_PAREN,
-      _readNode(data.whileStatement_body),
-    );
-  }
-
-  WithClause _read_withClause(LinkedNode data) {
-    return astFactory.withClause(
-      _Tokens.WITH,
-      _readNodeList(data.withClause_mixinTypes),
-    );
-  }
-
-  YieldStatement _read_yieldStatement(LinkedNode data) {
-    return astFactory.yieldStatement(
-      _Tokens.YIELD,
-      AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
-      _readNode(data.yieldStatement_expression),
-      _Tokens.SEMICOLON,
-    );
-  }
-
-  Comment _readDocumentationComment(LinkedNode data) {
+  Uint32List _readInformativeUint30List() {
+    if (_withInformative) {
+      return _readUint30List();
+    }
     return null;
   }
 
-  AstNode _readNode(LinkedNode data) {
-    if (data == null) return null;
+  InstanceCreationExpression _readInstanceCreationExpression() {
+    var flags = _readByte();
+    var constructorName = readNode() as ConstructorName;
+    var argumentList = readNode() as ArgumentList;
 
-    switch (data.kind) {
-      case LinkedNodeKind.adjacentStrings:
-        return _read_adjacentStrings(data);
-      case LinkedNodeKind.annotation:
-        return _read_annotation(data);
-      case LinkedNodeKind.argumentList:
-        return _read_argumentList(data);
-      case LinkedNodeKind.asExpression:
-        return _read_asExpression(data);
-      case LinkedNodeKind.assertInitializer:
-        return _read_assertInitializer(data);
-      case LinkedNodeKind.assertStatement:
-        return _read_assertStatement(data);
-      case LinkedNodeKind.assignmentExpression:
-        return _read_assignmentExpression(data);
-      case LinkedNodeKind.awaitExpression:
-        return _read_awaitExpression(data);
-      case LinkedNodeKind.binaryExpression:
-        return _read_binaryExpression(data);
-      case LinkedNodeKind.block:
-        return _read_block(data);
-      case LinkedNodeKind.blockFunctionBody:
-        return _read_blockFunctionBody(data);
-      case LinkedNodeKind.booleanLiteral:
-        return _read_booleanLiteral(data);
-      case LinkedNodeKind.breakStatement:
-        return _read_breakStatement(data);
-      case LinkedNodeKind.cascadeExpression:
-        return _read_cascadeExpression(data);
-      case LinkedNodeKind.catchClause:
-        return _read_catchClause(data);
-      case LinkedNodeKind.classDeclaration:
-        return _read_classDeclaration(data);
-      case LinkedNodeKind.classTypeAlias:
-        return _read_classTypeAlias(data);
-      case LinkedNodeKind.comment:
-        return _read_comment(data);
-      case LinkedNodeKind.commentReference:
-        return _read_commentReference(data);
-      case LinkedNodeKind.compilationUnit:
-        return _read_compilationUnit(data);
-      case LinkedNodeKind.conditionalExpression:
-        return _read_conditionalExpression(data);
-      case LinkedNodeKind.configuration:
-        return _read_configuration(data);
-      case LinkedNodeKind.constructorDeclaration:
-        return _read_constructorDeclaration(data);
-      case LinkedNodeKind.constructorFieldInitializer:
-        return _read_constructorFieldInitializer(data);
-      case LinkedNodeKind.constructorName:
-        return _read_constructorName(data);
-      case LinkedNodeKind.continueStatement:
-        return _read_continueStatement(data);
-      case LinkedNodeKind.declaredIdentifier:
-        return _read_declaredIdentifier(data);
-      case LinkedNodeKind.defaultFormalParameter:
-        return _read_defaultFormalParameter(data);
-      case LinkedNodeKind.doStatement:
-        return _read_doStatement(data);
-      case LinkedNodeKind.dottedName:
-        return _read_dottedName(data);
-      case LinkedNodeKind.doubleLiteral:
-        return _read_doubleLiteral(data);
-      case LinkedNodeKind.emptyFunctionBody:
-        return _read_emptyFunctionBody(data);
-      case LinkedNodeKind.emptyStatement:
-        return _read_emptyStatement(data);
-      case LinkedNodeKind.enumConstantDeclaration:
-        return _read_enumConstantDeclaration(data);
-      case LinkedNodeKind.enumDeclaration:
-        return _read_enumDeclaration(data);
-      case LinkedNodeKind.exportDirective:
-        return _read_exportDirective(data);
-      case LinkedNodeKind.expressionFunctionBody:
-        return _read_expressionFunctionBody(data);
-      case LinkedNodeKind.expressionStatement:
-        return _read_expressionStatement(data);
-      case LinkedNodeKind.extendsClause:
-        return _read_extendsClause(data);
-      case LinkedNodeKind.extensionDeclaration:
-        return _read_extensionDeclaration(data);
-      case LinkedNodeKind.extensionOverride:
-        return _read_extensionOverride(data);
-      case LinkedNodeKind.fieldDeclaration:
-        return _read_fieldDeclaration(data);
-      case LinkedNodeKind.fieldFormalParameter:
-        return _read_fieldFormalParameter(data);
-      case LinkedNodeKind.forEachPartsWithDeclaration:
-        return _read_forEachPartsWithDeclaration(data);
-      case LinkedNodeKind.forEachPartsWithIdentifier:
-        return _read_forEachPartsWithIdentifier(data);
-      case LinkedNodeKind.forElement:
-        return _read_forElement(data);
-      case LinkedNodeKind.forPartsWithExpression:
-        return _read_forPartsWithExpression(data);
-      case LinkedNodeKind.forPartsWithDeclarations:
-        return _read_forPartsWithDeclarations(data);
-      case LinkedNodeKind.forStatement:
-        return _read_forStatement(data);
-      case LinkedNodeKind.formalParameterList:
-        return _read_formalParameterList(data);
-      case LinkedNodeKind.functionDeclaration:
-        return _read_functionDeclaration(data);
-      case LinkedNodeKind.functionDeclarationStatement:
-        return _read_functionDeclarationStatement(data);
-      case LinkedNodeKind.functionExpression:
-        return _read_functionExpression(data);
-      case LinkedNodeKind.functionExpressionInvocation:
-        return _read_functionExpressionInvocation(data);
-      case LinkedNodeKind.functionTypeAlias:
-        return _read_functionTypeAlias(data);
-      case LinkedNodeKind.functionTypedFormalParameter:
-        return _read_functionTypedFormalParameter(data);
-      case LinkedNodeKind.genericFunctionType:
-        return _read_genericFunctionType(data);
-      case LinkedNodeKind.genericTypeAlias:
-        return _read_genericTypeAlias(data);
-      case LinkedNodeKind.hideCombinator:
-        return _read_hideCombinator(data);
-      case LinkedNodeKind.ifElement:
-        return _read_ifElement(data);
-      case LinkedNodeKind.ifStatement:
-        return _read_ifStatement(data);
-      case LinkedNodeKind.implementsClause:
-        return _read_implementsClause(data);
-      case LinkedNodeKind.importDirective:
-        return _read_importDirective(data);
-      case LinkedNodeKind.indexExpression:
-        return _read_indexExpression(data);
-      case LinkedNodeKind.instanceCreationExpression:
-        return _read_instanceCreationExpression(data);
-      case LinkedNodeKind.integerLiteral:
-        return _read_integerLiteral(data);
-      case LinkedNodeKind.interpolationString:
-        return _read_interpolationString(data);
-      case LinkedNodeKind.interpolationExpression:
-        return _read_interpolationExpression(data);
-      case LinkedNodeKind.isExpression:
-        return _read_isExpression(data);
-      case LinkedNodeKind.label:
-        return _read_label(data);
-      case LinkedNodeKind.labeledStatement:
-        return _read_labeledStatement(data);
-      case LinkedNodeKind.libraryDirective:
-        return _read_libraryDirective(data);
-      case LinkedNodeKind.libraryIdentifier:
-        return _read_libraryIdentifier(data);
-      case LinkedNodeKind.listLiteral:
-        return _read_listLiteral(data);
-      case LinkedNodeKind.mapLiteralEntry:
-        return _read_mapLiteralEntry(data);
-      case LinkedNodeKind.methodDeclaration:
-        return _read_methodDeclaration(data);
-      case LinkedNodeKind.methodInvocation:
-        return _read_methodInvocation(data);
-      case LinkedNodeKind.mixinDeclaration:
-        return _read_mixinDeclaration(data);
-      case LinkedNodeKind.namedExpression:
-        return _read_namedExpression(data);
-      case LinkedNodeKind.nativeClause:
-        return _read_nativeClause(data);
-      case LinkedNodeKind.nativeFunctionBody:
-        return _read_nativeFunctionBody(data);
-      case LinkedNodeKind.nullLiteral:
-        return _read_nullLiteral(data);
-      case LinkedNodeKind.onClause:
-        return _read_onClause(data);
-      case LinkedNodeKind.parenthesizedExpression:
-        return _read_parenthesizedExpression(data);
-      case LinkedNodeKind.partDirective:
-        return _read_partDirective(data);
-      case LinkedNodeKind.partOfDirective:
-        return _read_partOfDirective(data);
-      case LinkedNodeKind.postfixExpression:
-        return _read_postfixExpression(data);
-      case LinkedNodeKind.prefixExpression:
-        return _read_prefixExpression(data);
-      case LinkedNodeKind.propertyAccess:
-        return _read_propertyAccess(data);
-      case LinkedNodeKind.prefixedIdentifier:
-        return _read_prefixedIdentifier(data);
-      case LinkedNodeKind.redirectingConstructorInvocation:
-        return _read_redirectingConstructorInvocation(data);
-      case LinkedNodeKind.rethrowExpression:
-        return _read_rethrowExpression(data);
-      case LinkedNodeKind.returnStatement:
-        return _read_returnStatement(data);
-      case LinkedNodeKind.setOrMapLiteral:
-        return _read_setOrMapLiteral(data);
-      case LinkedNodeKind.showCombinator:
-        return _read_showCombinator(data);
-      case LinkedNodeKind.simpleFormalParameter:
-        return _read_simpleFormalParameter(data);
-      case LinkedNodeKind.simpleIdentifier:
-        return _read_simpleIdentifier(data);
-      case LinkedNodeKind.simpleStringLiteral:
-        return _read_simpleStringLiteral(data);
-      case LinkedNodeKind.spreadElement:
-        return _read_spreadElement(data);
-      case LinkedNodeKind.stringInterpolation:
-        return _read_stringInterpolation(data);
-      case LinkedNodeKind.superConstructorInvocation:
-        return _read_superConstructorInvocation(data);
-      case LinkedNodeKind.superExpression:
-        return _read_superExpression(data);
-      case LinkedNodeKind.switchCase:
-        return _read_switchCase(data);
-      case LinkedNodeKind.switchDefault:
-        return _read_switchDefault(data);
-      case LinkedNodeKind.switchStatement:
-        return _read_switchStatement(data);
-      case LinkedNodeKind.symbolLiteral:
-        return _read_symbolLiteral(data);
-      case LinkedNodeKind.thisExpression:
-        return _read_thisExpression(data);
-      case LinkedNodeKind.throwExpression:
-        return _read_throwExpression(data);
-      case LinkedNodeKind.topLevelVariableDeclaration:
-        return _read_topLevelVariableDeclaration(data);
-      case LinkedNodeKind.tryStatement:
-        return _read_tryStatement(data);
-      case LinkedNodeKind.typeArgumentList:
-        return _read_typeArgumentList(data);
-      case LinkedNodeKind.typeName:
-        return _read_typeName(data);
-      case LinkedNodeKind.typeParameter:
-        return _read_typeParameter(data);
-      case LinkedNodeKind.typeParameterList:
-        return _read_typeParameterList(data);
-      case LinkedNodeKind.variableDeclaration:
-        return _read_variableDeclaration(data);
-      case LinkedNodeKind.variableDeclarationList:
-        return _read_variableDeclarationList(data);
-      case LinkedNodeKind.variableDeclarationStatement:
-        return _read_variableDeclarationStatement(data);
-      case LinkedNodeKind.whileStatement:
-        return _read_whileStatement(data);
-      case LinkedNodeKind.withClause:
-        return _read_withClause(data);
-      case LinkedNodeKind.yieldStatement:
-        return _read_yieldStatement(data);
-      default:
-        throw UnimplementedError('Expression kind: ${data.kind}');
-    }
+    return astFactory.instanceCreationExpression(
+      Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isNew(flags),
+        Tokens.NEW,
+      ),
+      constructorName,
+      argumentList,
+    );
   }
 
-  AstNode _readNodeLazy(LinkedNode data) {
-    if (isLazy) return null;
-    return _readNode(data);
+  IntegerLiteral _readIntegerLiteralNegative() {
+    var value = (_readUint32() << 32) | _readUint32();
+    return _createIntegerLiteral(-value);
   }
 
-  List<T> _readNodeList<T>(List<LinkedNode> nodeList) {
-    var result = List<T>.filled(nodeList.length, null);
-    for (var i = 0; i < nodeList.length; ++i) {
-      var linkedNode = nodeList[i];
-      result[i] = _readNode(linkedNode) as T;
+  IntegerLiteral _readIntegerLiteralNegative1() {
+    var value = _readByte();
+    return _createIntegerLiteral(-value);
+  }
+
+  IntegerLiteral _readIntegerLiteralNull() {
+    var lexeme = _readStringReference();
+    return astFactory.integerLiteral(
+      TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
+      null,
+    );
+  }
+
+  IntegerLiteral _readIntegerLiteralPositive() {
+    var value = (_readUint32() << 32) | _readUint32();
+    return _createIntegerLiteral(value);
+  }
+
+  IntegerLiteral _readIntegerLiteralPositive1() {
+    var value = _readByte();
+    return _createIntegerLiteral(value);
+  }
+
+  InterpolationExpression _readInterpolationExpression() {
+    var flags = _readByte();
+    var expression = readNode() as Expression;
+    var isIdentifier = AstBinaryFlags.isStringInterpolationIdentifier(flags);
+    return astFactory.interpolationExpression(
+      isIdentifier
+          ? Tokens.OPEN_CURLY_BRACKET
+          : Tokens.STRING_INTERPOLATION_EXPRESSION,
+      expression,
+      isIdentifier ? null : Tokens.CLOSE_CURLY_BRACKET,
+    );
+  }
+
+  InterpolationString _readInterpolationString() {
+    var value = _readStringReference();
+    return astFactory.interpolationString(
+      TokenFactory.tokenFromString(value),
+      value,
+    );
+  }
+
+  IsExpression _readIsExpression() {
+    var flags = _readByte();
+    var expression = readNode() as Expression;
+    var type = readNode() as TypeAnnotation;
+    return astFactory.isExpression(
+      expression,
+      Tokens.IS,
+      AstBinaryFlags.hasNot(flags) ? Tokens.BANG : null,
+      type,
+    );
+  }
+
+  LibraryDirective _readLibraryDirective() {
+    var documentationTokenIndexList = _readUint30List();
+    var name = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.libraryDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.LIBRARY, keywordOffset),
+      name,
+      Tokens.SEMICOLON,
+    );
+    SummaryDataForLibraryDirective(
+      _unitReader,
+      node,
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+    return node;
+  }
+
+  LibraryIdentifier _readLibraryIdentifier() {
+    var components = _readNodeList<SimpleIdentifier>();
+    return astFactory.libraryIdentifier(
+      components,
+    );
+  }
+
+  ListLiteral _readListLiteral() {
+    var flags = _readByte();
+    var typeArguments = _readOptionalNode();
+    var elements = _readNodeList<CollectionElement>();
+
+    return astFactory.listLiteral(
+      AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+      typeArguments,
+      Tokens.OPEN_SQUARE_BRACKET,
+      elements,
+      Tokens.CLOSE_SQUARE_BRACKET,
+    );
+  }
+
+  MapLiteralEntry _readMapLiteralEntry() {
+    var key = readNode() as Expression;
+    var value = readNode() as Expression;
+    return astFactory.mapLiteralEntry(key, Tokens.COLON, value);
+  }
+
+  MethodDeclaration _readMethodDeclaration() {
+    var flags = _readUInt30();
+
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var name = readNode() as SimpleIdentifier;
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var returnType = _readOptionalNode() as TypeAnnotation;
+    var formalParameters = _readOptionalNode() as FormalParameterList;
+    var metadata = _readNodeList<Annotation>();
+    var body = _functionBodyForFlags(flags);
+
+    var node = astFactory.methodDeclaration(
+      null,
+      metadata,
+      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+      AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
+      returnType,
+      Tokens.choose(
+        AstBinaryFlags.isGet(flags),
+        Tokens.GET,
+        AstBinaryFlags.isSet(flags),
+        Tokens.SET,
+      ),
+      AstBinaryFlags.isOperator(flags) ? Tokens.OPERATOR : null,
+      name,
+      typeParameters,
+      formalParameters,
+      body,
+    ) as MethodDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  MethodInvocation _readMethodInvocation() {
+    var flags = _readByte();
+    var target = _readOptionalNode() as Expression;
+    var methodName = readNode() as SimpleIdentifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var arguments = readNode() as ArgumentList;
+
+    return astFactory.methodInvocation(
+      target,
+      Tokens.choose(
+        AstBinaryFlags.hasPeriod(flags),
+        Tokens.PERIOD,
+        AstBinaryFlags.hasPeriod2(flags),
+        Tokens.PERIOD_PERIOD,
+      ),
+      methodName,
+      typeArguments,
+      arguments,
+    );
+  }
+
+  MixinDeclaration _readMixinDeclaration() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var documentationTokenIndexList = _readUint30List();
+
+    var typeParameters = _readOptionalNode() as TypeParameterList;
+    var onClause = _readOptionalNode() as OnClause;
+    var implementsClause = _readOptionalNode() as ImplementsClause;
+    var name = readNode() as SimpleIdentifier;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.mixinDeclaration(
+      null,
+      metadata,
+      Tokens.MIXIN,
+      name,
+      typeParameters,
+      onClause,
+      implementsClause,
+      Tokens.OPEN_CURLY_BRACKET,
+      const <ClassMember>[],
+      Tokens.CLOSE_CURLY_BRACKET,
+    ) as MixinDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  NamedExpression _readNamedExpression() {
+    var name = _readStringReference();
+    var offset = _readInformativeUint30();
+    var nameNode = astFactory.label(
+      astFactory.simpleIdentifier(
+        StringToken(TokenType.STRING, name, offset),
+      ),
+      Tokens.COLON,
+    );
+
+    var expression = readNode() as Expression;
+    return astFactory.namedExpression(nameNode, expression);
+  }
+
+  NativeClause _readNativeClause() {
+    var name = readNode();
+    return astFactory.nativeClause(Tokens.NATIVE, name);
+  }
+
+  List<T> _readNodeList<T>() {
+    var length = _readUInt30();
+    // TODO(scheglov) This will not work for null safety, rewrite.
+    var result = List<T>.filled(length, null);
+    for (var i = 0; i < length; ++i) {
+      result[i] = readNode() as T;
     }
     return result;
   }
 
-  List<T> _readNodeListLazy<T>(List<LinkedNode> nodeList) {
-    if (isLazy) {
-      return List<T>.filled(nodeList.length, null);
-    }
-    return _readNodeList(nodeList);
-  }
-
-  DartType _readType(LinkedNodeType data) {
-    return _unitContext.readType(data);
-  }
-
-  static Variance _decodeVariance(int encoding) {
-    if (encoding == 0) {
-      return null;
-    } else if (encoding == 1) {
-      return Variance.unrelated;
-    } else if (encoding == 2) {
-      return Variance.covariant;
-    } else if (encoding == 3) {
-      return Variance.contravariant;
-    } else if (encoding == 4) {
-      return Variance.invariant;
-    } else {
-      throw UnimplementedError('encoding: $encoding');
-    }
-  }
-
-  static ParameterKind _toParameterKind(LinkedNodeFormalParameterKind kind) {
-    switch (kind) {
-      case LinkedNodeFormalParameterKind.requiredPositional:
-        return ParameterKind.REQUIRED;
-      case LinkedNodeFormalParameterKind.requiredNamed:
-        return ParameterKind.NAMED_REQUIRED;
-        break;
-      case LinkedNodeFormalParameterKind.optionalPositional:
-        return ParameterKind.POSITIONAL;
-        break;
-      case LinkedNodeFormalParameterKind.optionalNamed:
-        return ParameterKind.NAMED;
-      default:
-        throw StateError('Unexpected: $kind');
-    }
-  }
-}
-
-class _Tokens {
-  static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
-  static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
-  static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
-  static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
-  static final AT = TokenFactory.tokenFromType(TokenType.AT);
-  static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
-  static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
-  static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
-  static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
-  static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
-  static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
-  static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
-  static final CLOSE_CURLY_BRACKET =
-      TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
-  static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
-  static final CLOSE_SQUARE_BRACKET =
-      TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
-  static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
-  static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
-  static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
-  static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
-  static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
-  static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
-  static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
-  static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
-  static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
-  static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
-  static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
-  static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
-  static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
-  static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
-  static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
-  static final EXTENSION = TokenFactory.tokenFromKeyword(Keyword.EXTENSION);
-  static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
-  static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
-  static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
-  static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
-  static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
-  static final GT = TokenFactory.tokenFromType(TokenType.GT);
-  static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
-  static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
-  static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
-  static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
-  static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
-  static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
-  static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
-  static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
-  static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
-  static final LT = TokenFactory.tokenFromType(TokenType.LT);
-  static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
-  static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
-  static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
-  static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
-  static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
-  static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
-  static final OPEN_CURLY_BRACKET =
-      TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
-  static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
-  static final OPEN_SQUARE_BRACKET =
-      TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
-  static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
-  static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
-  static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
-  static final PERIOD_PERIOD =
-      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
-  static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
-  static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
-  static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
-  static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
-  static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
-  static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
-  static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
-  static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
-  static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
-  static final STRING_INTERPOLATION_EXPRESSION =
-      TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
-  static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
-  static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
-  static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
-  static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
-  static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
-  static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
-  static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
-  static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
-  static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
-  static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
-  static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
-
-  static Token choose(bool if1, Token then1, bool if2, Token then2,
-      [bool if3, Token then3]) {
-    if (if1) return then1;
-    if (if2) return then2;
-    if (if2 == true) return then3;
-    return null;
-  }
-
-  static Token fromType(UnlinkedTokenType type) {
-    return TokenFactory.tokenFromType(
-      TokensContext.binaryToAstTokenType(type),
+  NullLiteral _readNullLiteral() {
+    return astFactory.nullLiteral(
+      Tokens.NULL,
     );
   }
+
+  OnClause _readOnClause() {
+    var superclassConstraints = _readNodeList<TypeName>();
+    return astFactory.onClause(Tokens.ON, superclassConstraints);
+  }
+
+  AstNode _readOptionalNode() {
+    if (_readOptionTag()) {
+      return readNode();
+    } else {
+      return null;
+    }
+  }
+
+  bool _readOptionTag() {
+    var tag = _readByte();
+    if (tag == Tag.Nothing) {
+      return false;
+    } else if (tag == Tag.Something) {
+      return true;
+    } else {
+      throw UnimplementedError('Unexpected option tag: $tag');
+    }
+  }
+
+  ParenthesizedExpression _readParenthesizedExpression() {
+    var expression = readNode() as Expression;
+    return astFactory.parenthesizedExpression(
+      Tokens.OPEN_PAREN,
+      expression,
+      Tokens.CLOSE_PAREN,
+    );
+  }
+
+  PartDirective _readPartDirective() {
+    var uri = readNode();
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    return astFactory.partDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.PART, keywordOffset),
+      uri,
+      Tokens.SEMICOLON,
+    );
+  }
+
+  PartOfDirective _readPartOfDirective() {
+    var libraryName = _readOptionalNode() as LibraryIdentifier;
+    var uri = _readOptionalNode() as StringLiteral;
+    var keywordOffset = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+
+    return astFactory.partOfDirective(
+      null,
+      metadata,
+      KeywordToken(Keyword.PART, keywordOffset),
+      Tokens.OF,
+      uri,
+      libraryName,
+      Tokens.SEMICOLON,
+    );
+  }
+
+  PostfixExpression _readPostfixExpression() {
+    var operand = readNode() as Expression;
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    return astFactory.postfixExpression(
+      operand,
+      Tokens.fromType(operatorType),
+    );
+  }
+
+  PrefixedIdentifier _readPrefixedIdentifier() {
+    var prefix = readNode() as SimpleIdentifier;
+    var identifier = readNode() as SimpleIdentifier;
+    return astFactory.prefixedIdentifier(
+      prefix,
+      Tokens.PERIOD,
+      identifier,
+    );
+  }
+
+  PrefixExpression _readPrefixExpression() {
+    var operatorType = UnlinkedTokenType.values[_readByte()];
+    var operand = readNode() as Expression;
+    return astFactory.prefixExpression(
+      Tokens.fromType(operatorType),
+      operand,
+    );
+  }
+
+  PropertyAccess _readPropertyAccess() {
+    var flags = _readByte();
+    var target = _readOptionalNode() as Expression;
+    var propertyName = readNode() as SimpleIdentifier;
+    return astFactory.propertyAccess(
+      target,
+      Tokens.choose(
+        AstBinaryFlags.hasPeriod(flags),
+        Tokens.PERIOD,
+        AstBinaryFlags.hasPeriod2(flags),
+        Tokens.PERIOD_PERIOD,
+      ),
+      propertyName,
+    );
+  }
+
+  RedirectingConstructorInvocation _readRedirectingConstructorInvocation() {
+    var flags = _readByte();
+    var constructorName = _readOptionalNode() as SimpleIdentifier;
+    var argumentList = readNode() as ArgumentList;
+    var hasThis = AstBinaryFlags.hasThis(flags);
+    return astFactory.redirectingConstructorInvocation(
+      hasThis ? Tokens.THIS : null,
+      hasThis ? Tokens.PERIOD : null,
+      constructorName,
+      argumentList,
+    );
+  }
+
+  SetOrMapLiteral _readSetOrMapLiteral() {
+    var flags = _readByte();
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+    var elements = _readNodeList<CollectionElement>();
+    var node = astFactory.setOrMapLiteral(
+      constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+      elements: elements,
+      leftBracket: Tokens.OPEN_CURLY_BRACKET,
+      typeArguments: typeArguments,
+      rightBracket: Tokens.CLOSE_CURLY_BRACKET,
+    ) as SetOrMapLiteralImpl;
+    return node;
+  }
+
+  ShowCombinator _readShowCombinator() {
+    var keywordOffset = _readInformativeUint30();
+    return astFactory.showCombinator(
+      KeywordToken(Keyword.SHOW, keywordOffset),
+      _readNodeList<SimpleIdentifier>(),
+    );
+  }
+
+  SimpleFormalParameter _readSimpleFormalParameter() {
+    var type = _readOptionalNode() as TypeAnnotation;
+    var flags = _readByte();
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var metadata = _readNodeList<Annotation>();
+    var identifier =
+        AstBinaryFlags.hasName(flags) ? readNode() as SimpleIdentifier : null;
+
+    var node = astFactory.simpleFormalParameter2(
+      identifier: identifier,
+      type: type,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+      comment: null,
+      metadata: metadata,
+      keyword: Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
+      ),
+      requiredKeyword:
+          AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+    ) as SimpleFormalParameterImpl;
+    node.summaryData = SummaryDataForFormalParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+    );
+    return node;
+  }
+
+  SimpleIdentifier _readSimpleIdentifier() {
+    var name = _readStringReference();
+    var offset = _readInformativeUint30();
+    return astFactory.simpleIdentifier(
+      StringToken(TokenType.STRING, name, offset),
+    );
+  }
+
+  SimpleStringLiteral _readSimpleStringLiteral() {
+    var lexeme = _readStringReference();
+    var value = _readStringReference();
+
+    return astFactory.simpleStringLiteral(
+      TokenFactory.tokenFromString(lexeme),
+      value,
+    );
+  }
+
+  SpreadElement _readSpreadElement() {
+    var flags = _readByte();
+    var expression = readNode() as Expression;
+    return astFactory.spreadElement(
+      spreadOperator: AstBinaryFlags.hasQuestion(flags)
+          ? Tokens.PERIOD_PERIOD_PERIOD_QUESTION
+          : Tokens.PERIOD_PERIOD_PERIOD,
+      expression: expression,
+    );
+  }
+
+  StringInterpolation _readStringInterpolation() {
+    var elements = _readNodeList<InterpolationElement>();
+    return astFactory.stringInterpolation(elements);
+  }
+
+  String _readStringReference() {
+    return _unitReader.astReader.readStringReference();
+  }
+
+  SuperConstructorInvocation _readSuperConstructorInvocation() {
+    var constructorName = _readOptionalNode() as SimpleIdentifier;
+    var argumentList = readNode() as ArgumentList;
+    return astFactory.superConstructorInvocation(
+      Tokens.SUPER,
+      Tokens.PERIOD,
+      constructorName,
+      argumentList,
+    );
+  }
+
+  SuperExpression _readSuperExpression() {
+    return astFactory.superExpression(Tokens.SUPER);
+  }
+
+  SymbolLiteral _readSymbolLiteral() {
+    var components = <Token>[];
+    var length = _readUInt30();
+    for (var i = 0; i < length; i++) {
+      var lexeme = _readStringReference();
+      var token = TokenFactory.tokenFromString(lexeme);
+      components.add(token);
+    }
+    return astFactory.symbolLiteral(Tokens.HASH, components);
+  }
+
+  ThisExpression _readThisExpression() {
+    return astFactory.thisExpression(Tokens.THIS);
+  }
+
+  ThrowExpression _readThrowExpression() {
+    var expression = readNode() as Expression;
+    return astFactory.throwExpression(Tokens.THROW, expression);
+  }
+
+  TopLevelVariableDeclaration _readTopLevelVariableDeclaration() {
+    var flags = _readByte();
+    var codeOffsetLengthList = _readInformativeUint30List();
+    var documentationTokenIndexList = _readUint30List();
+    var variableList = readNode() as VariableDeclarationList;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.topLevelVariableDeclaration(
+      null,
+      metadata,
+      variableList,
+      Tokens.SEMICOLON,
+      externalKeyword:
+          AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+    ) as TopLevelVariableDeclarationImpl;
+
+    node.linkedContext = LinkedContext(
+      _unitReader,
+      node,
+      codeOffset: -1,
+      codeLength: 0,
+      codeOffsetLengthList: codeOffsetLengthList,
+      resolutionIndex: _readUInt30(),
+      documentationTokenIndexList: documentationTokenIndexList,
+    );
+
+    return node;
+  }
+
+  TypeArgumentList _readTypeArgumentList() {
+    var arguments = _readNodeList<TypeAnnotation>();
+    return astFactory.typeArgumentList(Tokens.LT, arguments, Tokens.GT);
+  }
+
+  TypeName _readTypeName() {
+    var flags = _readByte();
+    var name = readNode() as Identifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList;
+
+    return astFactory.typeName(
+      name,
+      typeArguments,
+      question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+    );
+  }
+
+  TypeParameter _readTypeParameter() {
+    var codeOffset = _readInformativeUint30();
+    var codeLength = _readInformativeUint30();
+    var name = readNode() as Identifier;
+    var bound = _readOptionalNode() as TypeAnnotation;
+    var metadata = _readNodeList<Annotation>();
+
+    var node = astFactory.typeParameter(
+      null,
+      metadata,
+      name,
+      bound != null ? Tokens.EXTENDS : null,
+      bound,
+    ) as TypeParameterImpl;
+    node.summaryData = SummaryDataForTypeParameter(
+      codeOffset: codeOffset,
+      codeLength: codeLength,
+    );
+
+    return node;
+  }
+
+  TypeParameterList _readTypeParameterList() {
+    var typeParameters = _readNodeList<TypeParameter>();
+    return astFactory.typeParameterList(
+      Tokens.LT,
+      typeParameters,
+      Tokens.GT,
+    );
+  }
+
+  int _readUInt30() {
+    var byte = _readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | _readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (_readByte() << 16) |
+          (_readByte() << 8) |
+          _readByte();
+    }
+  }
+
+  Uint32List _readUint30List() {
+    var length = _readUInt30();
+    var result = Uint32List(length);
+    for (var i = 0; i < length; ++i) {
+      result[i] = _readUInt30();
+    }
+    return result;
+  }
+
+  int _readUint32() {
+    return (_readByte() << 24) |
+        (_readByte() << 16) |
+        (_readByte() << 8) |
+        _readByte();
+  }
+
+  VariableDeclaration _readVariableDeclaration() {
+    var flags = _readByte();
+    var name = readNode() as SimpleIdentifier;
+    var initializer = _readOptionalNode() as Expression;
+
+    var node = astFactory.variableDeclaration(
+      name,
+      Tokens.EQ,
+      initializer,
+    ) as VariableDeclarationImpl;
+
+    node.hasInitializer = AstBinaryFlags.hasInitializer(flags);
+
+    return node;
+  }
+
+  VariableDeclarationList _readVariableDeclarationList() {
+    var flags = _readByte();
+    var type = _readOptionalNode() as TypeAnnotation;
+    var variables = _readNodeList<VariableDeclaration>();
+    var metadata = _readNodeList<Annotation>();
+
+    return astFactory.variableDeclarationList2(
+      comment: null,
+      keyword: Tokens.choose(
+        AstBinaryFlags.isConst(flags),
+        Tokens.CONST,
+        AstBinaryFlags.isFinal(flags),
+        Tokens.FINAL,
+        AstBinaryFlags.isVar(flags),
+        Tokens.VAR,
+      ),
+      lateKeyword: AstBinaryFlags.isLate(flags) ? Tokens.LATE : null,
+      metadata: metadata,
+      type: type,
+      variables: variables,
+    );
+  }
+
+  WithClause _readWithClause() {
+    var mixins = _readNodeList<TypeName>();
+    return astFactory.withClause(Tokens.WITH, mixins);
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
new file mode 100644
index 0000000..0c19a9e
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A `MethodInvocation` in unresolved AST might be rewritten later as
+/// another kinds of AST node. We store this rewrite with resolution data.
+class MethodInvocationRewriteTag {
+  static const int extensionOverride = 1;
+  static const int functionExpressionInvocation = 2;
+  static const int instanceCreationExpression_withName = 3;
+  static const int instanceCreationExpression_withoutName = 4;
+  static const int none = 5;
+}
+
+class Tag {
+  static const int Nothing = 0;
+  static const int Something = 1;
+
+  static const int AdjacentStrings = 75;
+  static const int Annotation = 2;
+  static const int ArgumentList = 3;
+  static const int AsExpression = 84;
+  static const int AssertInitializer = 82;
+  static const int AssignmentExpression = 96;
+  static const int BinaryExpression = 52;
+  static const int BooleanLiteral = 4;
+  static const int CascadeExpression = 95;
+  static const int Class = 5;
+  static const int ClassTypeAlias = 44;
+  static const int ConditionalExpression = 51;
+  static const int Configuration = 46;
+  static const int ConstructorDeclaration = 6;
+  static const int ConstructorFieldInitializer = 50;
+  static const int ConstructorName = 7;
+  static const int DeclaredIdentifier = 90;
+  static const int DefaultFormalParameter = 8;
+  static const int DottedName = 47;
+  static const int DoubleLiteral = 9;
+  static const int EnumConstantDeclaration = 10;
+  static const int EnumDeclaration = 11;
+  static const int ExportDirective = 12;
+  static const int ExtendsClause = 13;
+  static const int ExtensionDeclaration = 14;
+  static const int ExtensionOverride = 87;
+  static const int FieldDeclaration = 15;
+  static const int FieldFormalParameter = 16;
+  static const int ForEachPartsWithDeclaration = 89;
+  static const int ForElement = 88;
+  static const int ForPartsWithDeclarations = 91;
+  static const int FormalParameterList = 17;
+  static const int FunctionDeclaration = 18;
+  static const int FunctionDeclaration_getter = 57;
+  static const int FunctionDeclaration_setter = 58;
+  static const int FunctionExpression = 19;
+  static const int FunctionExpressionInvocation = 93;
+  static const int FunctionTypeAlias = 55;
+  static const int FunctionTypedFormalParameter = 20;
+  static const int GenericFunctionType = 21;
+  static const int GenericTypeAlias = 22;
+  static const int HideCombinator = 48;
+  static const int IfElement = 63;
+  static const int ImplementsClause = 23;
+  static const int ImportDirective = 24;
+  static const int IndexExpression = 98;
+  static const int InstanceCreationExpression = 25;
+  static const int IntegerLiteralNegative = 73;
+  static const int IntegerLiteralNegative1 = 71;
+  static const int IntegerLiteralNull = 97;
+  static const int IntegerLiteralPositive = 72;
+  static const int IntegerLiteralPositive1 = 26;
+  static const int InterpolationExpression = 77;
+  static const int InterpolationString = 78;
+  static const int IsExpression = 83;
+  static const int Label = 61;
+  static const int LibraryDirective = 27;
+  static const int LibraryIdentifier = 28;
+  static const int ListLiteral = 56;
+  static const int MapLiteralEntry = 66;
+  static const int MethodDeclaration = 29;
+  static const int MethodDeclaration_getter = 85;
+  static const int MethodDeclaration_setter = 86;
+  static const int MethodInvocation = 59;
+  static const int MixinDeclaration = 67;
+  static const int NamedExpression = 60;
+  static const int NativeClause = 92;
+  static const int OnClause = 68;
+  static const int NullLiteral = 49;
+  static const int ParenthesizedExpression = 53;
+  static const int PartDirective = 30;
+  static const int PartOfDirective = 31;
+  static const int PostfixExpression = 94;
+  static const int PrefixExpression = 79;
+  static const int PrefixedIdentifier = 32;
+  static const int PropertyAccess = 62;
+  static const int RedirectingConstructorInvocation = 54;
+  static const int SetOrMapLiteral = 65;
+  static const int ShowCombinator = 33;
+  static const int SimpleFormalParameter = 34;
+  static const int SimpleIdentifier = 35;
+  static const int SimpleStringLiteral = 36;
+  static const int SpreadElement = 64;
+  static const int StringInterpolation = 76;
+  static const int SuperConstructorInvocation = 69;
+  static const int SuperExpression = 80;
+  static const int SymbolLiteral = 74;
+  static const int ThisExpression = 70;
+  static const int ThrowExpression = 81;
+  static const int TopLevelVariableDeclaration = 37;
+  static const int TypeArgumentList = 38;
+  static const int TypeName = 39;
+  static const int TypeParameter = 40;
+  static const int TypeParameterList = 41;
+  static const int VariableDeclaration = 42;
+  static const int VariableDeclarationList = 43;
+  static const int WithClause = 45;
+
+  static const int RawElement = 0;
+  static const int MemberLegacyWithoutTypeArguments = 1;
+  static const int MemberLegacyWithTypeArguments = 2;
+  static const int MemberWithTypeArguments = 3;
+
+  static const int ParameterKindRequiredPositional = 1;
+  static const int ParameterKindOptionalPositional = 2;
+  static const int ParameterKindRequiredNamed = 3;
+  static const int ParameterKindOptionalNamed = 4;
+
+  static const int NullType = 2;
+  static const int DynamicType = 3;
+  static const int FunctionType = 4;
+  static const int NeverType = 5;
+  static const int InterfaceType = 6;
+  static const int InterfaceType_noTypeArguments_none = 7;
+  static const int InterfaceType_noTypeArguments_question = 8;
+  static const int InterfaceType_noTypeArguments_star = 9;
+  static const int TypeParameterType = 10;
+  static const int VoidType = 11;
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart
new file mode 100644
index 0000000..a9a8a69
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/summary2/tokens_context.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+
+class Tokens {
+  static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
+  static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
+  static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
+  static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
+  static final AT = TokenFactory.tokenFromType(TokenType.AT);
+  static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
+  static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
+  static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
+  static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
+  static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
+  static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
+  static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
+  static final CLOSE_CURLY_BRACKET =
+      TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
+  static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
+  static final CLOSE_SQUARE_BRACKET =
+      TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
+  static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
+  static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
+  static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
+  static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
+  static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
+  static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
+  static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
+  static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+  static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
+  static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
+  static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
+  static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
+  static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
+  static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
+  static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
+  static final EXTENSION = TokenFactory.tokenFromKeyword(Keyword.EXTENSION);
+  static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
+  static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
+  static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
+  static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
+  static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
+  static final GT = TokenFactory.tokenFromType(TokenType.GT);
+  static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
+  static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
+  static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
+  static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
+  static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
+  static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
+  static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
+  static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
+  static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
+  static final LT = TokenFactory.tokenFromType(TokenType.LT);
+  static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
+  static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
+  static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
+  static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
+  static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
+  static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
+  static final OPEN_CURLY_BRACKET =
+      TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
+  static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
+  static final OPEN_SQUARE_BRACKET =
+      TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
+  static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
+  static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
+  static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
+  static final PERIOD_PERIOD =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
+  static final PERIOD_PERIOD_PERIOD =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD);
+  static final PERIOD_PERIOD_PERIOD_QUESTION =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD_QUESTION);
+  static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
+  static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
+  static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
+  static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
+  static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
+  static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
+  static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
+  static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
+  static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
+  static final STRING_INTERPOLATION_EXPRESSION =
+      TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
+  static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
+  static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
+  static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
+  static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
+  static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
+  static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
+  static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
+  static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
+  static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
+  static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
+  static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
+
+  static Token choose(bool if1, Token then1, bool if2, Token then2,
+      [bool if3, Token then3]) {
+    if (if1) return then1;
+    if (if2) return then2;
+    if (if2 == true) return then3;
+    return null;
+  }
+
+  static Token fromType(UnlinkedTokenType type) {
+    return TokenFactory.tokenFromType(
+      TokensContext.binaryToAstTokenType(type),
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 0035dd8..06f82b6 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -2,1712 +2,1879 @@
 // for details. All 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/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
 import 'package:analyzer/src/summary2/tokens_writer.dart';
+import 'package:analyzer/src/task/inference_error.dart';
+import 'package:meta/meta.dart';
 
-var timerAstBinaryWriter = Stopwatch();
-var timerAstBinaryWriterClass = Stopwatch();
-var timerAstBinaryWriterDirective = Stopwatch();
-var timerAstBinaryWriterFunctionBody = Stopwatch();
-var timerAstBinaryWriterMixin = Stopwatch();
-var timerAstBinaryWriterTopVar = Stopwatch();
-var timerAstBinaryWriterTypedef = Stopwatch();
+/// Serializer of fully resolved ASTs.
+class AstBinaryWriter extends ThrowingAstVisitor<void> {
+  final bool _withInformative;
+  final BufferedSink _sink;
+  final StringIndexer _stringIndexer;
+  final int Function() _getNextResolutionIndex;
+  final ResolutionSink _resolutionSink;
+  final bool _shouldWriteResolution;
 
-/// Serializer of fully resolved ASTs into flat buffers.
-class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
-  final LinkingBundleContext _linkingContext;
-
-  /// Is `true` if the current [ClassDeclaration] has a const constructor,
-  /// so initializers of final fields should be written.
+  /// TODO(scheglov) Keep it private, and write here, similarly as we do
+  /// for [_classMemberIndexItems]?
+  final List<_UnitMemberIndexItem> unitMemberIndexItems = [];
+  final List<_ClassMemberIndexItem> _classMemberIndexItems = [];
+  bool _isConstField = false;
+  bool _isFinalField = false;
+  bool _isConstTopLevelVariable = false;
   bool _hasConstConstructor = false;
+  int _nextUnnamedExtensionId = 0;
 
-  AstBinaryWriter(this._linkingContext);
+  AstBinaryWriter({
+    @required bool withInformative,
+    @required BufferedSink sink,
+    @required StringIndexer stringIndexer,
+    @required int Function() getNextResolutionIndex,
+    @required ResolutionSink resolutionSink,
+  })  : _withInformative = withInformative,
+        _sink = sink,
+        _stringIndexer = stringIndexer,
+        _getNextResolutionIndex = getNextResolutionIndex,
+        _resolutionSink = resolutionSink,
+        _shouldWriteResolution = resolutionSink != null;
 
   @override
-  LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
-    return LinkedNodeBuilder.adjacentStrings(
-      adjacentStrings_strings: _writeNodeList(node.strings),
-    );
+  void visitAdjacentStrings(AdjacentStrings node) {
+    _writeByte(Tag.AdjacentStrings);
+    _writeNodeList(node.strings);
   }
 
   @override
-  LinkedNodeBuilder visitAnnotation(Annotation node) {
-    var elementComponents = _componentsOfElement(node.element);
+  void visitAnnotation(Annotation node) {
+    _writeByte(Tag.Annotation);
 
-    LinkedNodeBuilder storedArguments;
+    _writeOptionalNode(node.name);
+    _writeOptionalNode(node.constructorName);
+
     var arguments = node.arguments;
     if (arguments != null) {
-      if (arguments.arguments.every(_isSerializableExpression)) {
-        storedArguments = arguments.accept(this);
-      } else {
-        storedArguments = LinkedNodeBuilder.argumentList();
+      if (!arguments.arguments.every(_isSerializableExpression)) {
+        arguments = null;
+      }
+    }
+    _writeOptionalNode(arguments);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.element);
+    }
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    _writeByte(Tag.ArgumentList);
+    _writeNodeList(node.arguments);
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    _writeByte(Tag.AsExpression);
+    _writeNode(node.expression);
+    _writeNode(node.type);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {
+    _writeByte(Tag.AssertInitializer);
+    _writeNode(node.condition);
+    _writeOptionalNode(node.message);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    _writeByte(Tag.AssignmentExpression);
+
+    _writeNode(node.leftHandSide);
+    _writeNode(node.rightHandSide);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+      _resolutionSink.writeElement(node.readElement);
+      _resolutionSink.writeType(node.readType);
+      _resolutionSink.writeElement(node.writeElement);
+      _resolutionSink.writeType(node.writeType);
+    }
+    _storeExpression(node);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    _writeByte(Tag.BinaryExpression);
+
+    _writeNode(node.leftOperand);
+    _writeNode(node.rightOperand);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+      _resolutionSink.writeType(node.staticType);
+    }
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    _writeByte(Tag.BooleanLiteral);
+    _writeByte(node.value ? 1 : 0);
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeType(node.staticType);
+    }
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    _writeByte(Tag.CascadeExpression);
+    _writeNode(node.target);
+    _writeNodeList(node.cascadeSections);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    var classOffset = _sink.offset;
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _hasConstConstructor = false;
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration && member.constKeyword != null) {
+        _hasConstConstructor = true;
+        break;
       }
     }
 
-    return LinkedNodeBuilder.annotation(
-      annotation_arguments: storedArguments,
-      annotation_constructorName: node.constructorName?.accept(this),
-      annotation_element: elementComponents.rawElement,
-      annotation_substitution: elementComponents.substitution,
-      annotation_name: node.name?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitArgumentList(ArgumentList node) {
-    return LinkedNodeBuilder.argumentList(
-      argumentList_arguments: _writeNodeList(node.arguments),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAsExpression(AsExpression node) {
-    return LinkedNodeBuilder.asExpression(
-      asExpression_expression: node.expression.accept(this),
-      asExpression_type: node.type.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAssertInitializer(AssertInitializer node) {
-    return LinkedNodeBuilder.assertInitializer(
-      assertInitializer_condition: node.condition.accept(this),
-      assertInitializer_message: node.message?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAssertStatement(AssertStatement node) {
-    var builder = LinkedNodeBuilder.assertStatement(
-      assertStatement_condition: node.condition.accept(this),
-      assertStatement_message: node.message?.accept(this),
-    );
-    _storeStatement(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.assignmentExpression(
-      assignmentExpression_element: elementComponents.rawElement,
-      assignmentExpression_substitution: elementComponents.substitution,
-      assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
-      assignmentExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
-      ),
-      assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitAwaitExpression(AwaitExpression node) {
-    return LinkedNodeBuilder.awaitExpression(
-      awaitExpression_expression: node.expression.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.binaryExpression(
-      binaryExpression_element: elementComponents.rawElement,
-      binaryExpression_substitution: elementComponents.substitution,
-      binaryExpression_leftOperand: node.leftOperand.accept(this),
-      binaryExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
-      ),
-      binaryExpression_rightOperand: node.rightOperand.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBlock(Block node) {
-    return LinkedNodeBuilder.block(
-      block_statements: _writeNodeList(node.statements),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBlockFunctionBody(BlockFunctionBody node) {
-    timerAstBinaryWriterFunctionBody.start();
-    try {
-      var builder = LinkedNodeBuilder.blockFunctionBody(
-        blockFunctionBody_block: node.block.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isAsync: node.keyword?.keyword == Keyword.ASYNC,
-        isStar: node.star != null,
-        isSync: node.keyword?.keyword == Keyword.SYNC,
-      );
-      return builder;
-    } finally {
-      timerAstBinaryWriterFunctionBody.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitBooleanLiteral(BooleanLiteral node) {
-    return LinkedNodeBuilder.booleanLiteral(
-      booleanLiteral_value: node.value,
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitBreakStatement(BreakStatement node) {
-    var builder = LinkedNodeBuilder.breakStatement(
-      breakStatement_label: node.label?.accept(this),
-    );
-    _storeStatement(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitCascadeExpression(CascadeExpression node) {
-    var builder = LinkedNodeBuilder.cascadeExpression(
-      cascadeExpression_target: node.target.accept(this),
-      cascadeExpression_sections: _writeNodeList(node.cascadeSections),
-    );
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitCatchClause(CatchClause node) {
-    return LinkedNodeBuilder.catchClause(
-      catchClause_body: node.body.accept(this),
-      catchClause_exceptionParameter: node.exceptionParameter?.accept(this),
-      catchClause_exceptionType: node.exceptionType?.accept(this),
-      catchClause_stackTraceParameter: node.stackTraceParameter?.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitClassDeclaration(ClassDeclaration node) {
-    try {
-      timerAstBinaryWriterClass.start();
-
-      _hasConstConstructor = false;
-      for (var member in node.members) {
-        if (member is ConstructorDeclaration && member.constKeyword != null) {
-          _hasConstConstructor = true;
-          break;
-        }
-      }
-
-      var builder = LinkedNodeBuilder.classDeclaration(
-        classDeclaration_extendsClause: node.extendsClause?.accept(this),
-        classDeclaration_nativeClause: node.nativeClause?.accept(this),
-        classDeclaration_withClause: node.withClause?.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
+    _writeByte(Tag.Class);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasConstConstructor: _hasConstConstructor,
         isAbstract: node.abstractKeyword != null,
-      );
-      _storeClassOrMixinDeclaration(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterClass.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitClassTypeAlias(ClassTypeAlias node) {
-    timerAstBinaryWriterClass.start();
-    try {
-      var builder = LinkedNodeBuilder.classTypeAlias(
-        classTypeAlias_implementsClause: node.implementsClause?.accept(this),
-        classTypeAlias_superclass: node.superclass.accept(this),
-        classTypeAlias_typeParameters: node.typeParameters?.accept(this),
-        classTypeAlias_withClause: node.withClause.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isAbstract: node.abstractKeyword != null,
-      );
-      _storeTypeAlias(builder, node);
-      _storeIsSimpleBounded(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterClass.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitComment(Comment node) {
-    LinkedNodeCommentType type;
-    if (node.isBlock) {
-      type = LinkedNodeCommentType.block;
-    } else if (node.isDocumentation) {
-      type = LinkedNodeCommentType.documentation;
-    } else if (node.isEndOfLine) {
-      type = LinkedNodeCommentType.endOfLine;
+      ),
+    );
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeByte(node.declaredElement.isSimplyBounded ? 1 : 0);
     }
 
-    return LinkedNodeBuilder.comment(
-      comment_tokens: node.tokens.map((t) => t.lexeme).toList(),
-      comment_type: type,
-      // TODO(scheglov) restore
-//      comment_references: _writeNodeList(node.references),
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.extendsClause);
+    _writeOptionalNode(node.withClause);
+    _writeOptionalNode(node.implementsClause);
+    _writeOptionalNode(node.nativeClause);
+    _storeNamedCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
+
+    _classMemberIndexItems.clear();
+    _writeNodeList(node.members);
+    _hasConstConstructor = false;
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
+    }
+
+    // TODO(scheglov) write member index
+    var classIndexOffset = _sink.offset;
+    _writeClassMemberIndex();
+
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: classOffset,
+        tag: Tag.Class,
+        name: node.name.name,
+        classIndexOffset: classIndexOffset,
+      ),
     );
   }
 
   @override
-  LinkedNodeBuilder visitCommentReference(CommentReference node) {
-//    var identifier = node.identifier;
-//    _tokensWriter.writeTokens(
-//      node.newKeyword ?? identifier.beginToken,
-//      identifier.endToken,
-//    );
-//
-//    return LinkedNodeBuilder.commentReference(
-//      commentReference_identifier: identifier.accept(this),
-//      commentReference_newKeyword: _getToken(node.newKeyword),
-//    );
-    return null;
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.ClassTypeAlias,
+        name: node.name.name,
+      ),
+    );
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _writeByte(Tag.ClassTypeAlias);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isAbstract: node.abstractKeyword != null,
+      ),
+    );
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeByte(node.declaredElement.isSimplyBounded ? 1 : 0);
+    }
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeNode(node.superclass);
+    _writeNode(node.withClause);
+    _writeOptionalNode(node.implementsClause);
+    _storeTypeAlias(node);
+    _writeDocumentationCommentString(node.documentationComment);
+    _writeUInt30(resolutionIndex);
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
+    }
   }
 
   @override
-  LinkedNodeBuilder visitCompilationUnit(CompilationUnit node) {
+  void visitCompilationUnit(CompilationUnit node) {
     var nodeImpl = node as CompilationUnitImpl;
-    var builder = LinkedNodeBuilder.compilationUnit(
-      compilationUnit_declarations: _writeNodeList(node.declarations),
-      compilationUnit_directives: _writeNodeList(node.directives),
-      compilationUnit_featureSet:
-          (node.featureSet as ExperimentStatus).toStorage(),
-      compilationUnit_languageVersion: LinkedLibraryLanguageVersionBuilder(
-        package: LinkedLanguageVersionBuilder(
-          major: nodeImpl.languageVersion.package.major,
-          minor: nodeImpl.languageVersion.package.minor,
-        ),
-        override2: nodeImpl.languageVersion.override != null
-            ? LinkedLanguageVersionBuilder(
-                major: nodeImpl.languageVersion.override.major,
-                minor: nodeImpl.languageVersion.override.minor,
-              )
-            : null,
+    _writeLanguageVersion(nodeImpl.languageVersion);
+    _writeFeatureSet(node.featureSet);
+    _writeLineInfo(node.lineInfo);
+    _writeUInt30(_withInformative ? node.length : 0);
+    _writeNodeList(node.directives);
+    for (var declaration in node.declarations) {
+      declaration.accept(this);
+    }
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    _writeByte(Tag.ConditionalExpression);
+    _writeNode(node.condition);
+    _writeNode(node.thenExpression);
+    _writeNode(node.elseExpression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitConfiguration(Configuration node) {
+    _writeByte(Tag.Configuration);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasEqual: node.equalToken != null,
       ),
-      compilationUnit_scriptTag: node.scriptTag?.accept(this),
-      informativeId: getInformativeId(node),
     );
-    return builder;
+
+    _writeNode(node.name);
+    _writeOptionalNode(node.value);
+    _writeNode(node.uri);
   }
 
   @override
-  LinkedNodeBuilder visitConditionalExpression(ConditionalExpression node) {
-    var builder = LinkedNodeBuilder.conditionalExpression(
-      conditionalExpression_condition: node.condition.accept(this),
-      conditionalExpression_elseExpression: node.elseExpression.accept(this),
-      conditionalExpression_thenExpression: node.thenExpression.accept(this),
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    _classMemberIndexItems.add(
+      _ClassMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.ConstructorDeclaration,
+        name: node.name?.name ?? '',
+      ),
     );
-    _storeExpression(builder, node);
-    return builder;
+
+    _writeByte(Tag.ConstructorDeclaration);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasName: node.name != null,
+        hasSeparatorColon: node.separator?.type == TokenType.COLON,
+        hasSeparatorEquals: node.separator?.type == TokenType.EQ,
+        isAbstract: node.body is EmptyFunctionBody,
+        isConst: node.constKeyword != null,
+        isExternal: node.externalKeyword != null,
+        isFactory: node.factoryKeyword != null,
+      ),
+    );
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+    _writeNode(node.returnType);
+    if (node.period != null) {
+      _writeInformativeUint30(node.period.offset);
+      _writeDeclarationName(node.name);
+    }
+    _writeNode(node.parameters);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.pushScope();
+      for (var parameter in node.parameters.parameters) {
+        _resolutionSink.localElements.declare(parameter.declaredElement);
+      }
+    }
+
+    // TODO(scheglov) Not nice, we skip both resolution and AST.
+    // But eventually we want to store full AST, and partial resolution.
+    if (node.constKeyword != null) {
+      _writeNodeList(node.initializers);
+    } else {
+      _writeNodeList(const <ConstructorInitializer>[]);
+    }
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
+    }
+
+    _writeOptionalNode(node.redirectedConstructor);
+    _storeClassMember(node);
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitConfiguration(Configuration node) {
-    var builder = LinkedNodeBuilder.configuration(
-      configuration_name: node.name?.accept(this),
-      configuration_value: node.value?.accept(this),
-      configuration_uri: node.uri?.accept(this),
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    _writeByte(Tag.ConstructorFieldInitializer);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasThis: node.thisKeyword != null,
+      ),
     );
-    builder.flags = AstBinaryFlags.encode(
-      hasEqual: node.equalToken != null,
-    );
-    return builder;
+
+    _writeNode(node.fieldName);
+    _writeNode(node.expression);
+    _storeConstructorInitializer(node);
   }
 
   @override
-  LinkedNodeBuilder visitConstructorDeclaration(ConstructorDeclaration node) {
-    var builder = LinkedNodeBuilder.constructorDeclaration(
-      constructorDeclaration_initializers: _writeNodeList(node.initializers),
-      constructorDeclaration_parameters: node.parameters.accept(this),
-      constructorDeclaration_redirectedConstructor:
-          node.redirectedConstructor?.accept(this),
-      constructorDeclaration_returnType: node.returnType.accept(this),
-      informativeId: getInformativeId(node),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasName: node.name != null,
-      hasSeparatorColon: node.separator?.type == TokenType.COLON,
-      hasSeparatorEquals: node.separator?.type == TokenType.EQ,
-      isAbstract: node.body is EmptyFunctionBody,
-      isConst: node.constKeyword != null,
-      isExternal: node.externalKeyword != null,
-      isFactory: node.factoryKeyword != null,
-    );
-    builder.name = node.name?.name;
-    _storeClassMember(builder, node);
-    return builder;
+  void visitConstructorName(ConstructorName node) {
+    _writeByte(Tag.ConstructorName);
+
+    if (_shouldWriteResolution) {
+      // When we parse `C() = A.named` we don't know that `A` is a class name.
+      // We parse it as a `TypeName(PrefixedIdentifier)`.
+      // But when we resolve, we rewrite it.
+      // We need to inform the applier about the right shape of the AST.
+      _resolutionSink.writeByte(node.name != null ? 1 : 0);
+    }
+
+    _writeNode(node.type);
+    _writeOptionalNode(node.name);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+    }
   }
 
   @override
-  LinkedNodeBuilder visitConstructorFieldInitializer(
-      ConstructorFieldInitializer node) {
-    var builder = LinkedNodeBuilder.constructorFieldInitializer(
-      constructorFieldInitializer_expression: node.expression.accept(this),
-      constructorFieldInitializer_fieldName: node.fieldName.accept(this),
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    _writeByte(Tag.DeclaredIdentifier);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.keyword?.keyword == Keyword.CONST,
+        isFinal: node.keyword?.keyword == Keyword.FINAL,
+        isVar: node.keyword?.keyword == Keyword.VAR,
+      ),
     );
-    builder.flags = AstBinaryFlags.encode(
-      hasThis: node.thisKeyword != null,
-    );
-    _storeConstructorInitializer(builder, node);
-    return builder;
+    _writeOptionalNode(node.type);
+    _writeDeclarationName(node.identifier);
+    _storeDeclaration(node);
   }
 
   @override
-  LinkedNodeBuilder visitConstructorName(ConstructorName node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.constructorName(
-      constructorName_element: elementComponents.rawElement,
-      constructorName_substitution: elementComponents.substitution,
-      constructorName_name: node.name?.accept(this),
-      constructorName_type: node.type.accept(this),
-    );
-  }
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _writeByte(Tag.DefaultFormalParameter);
 
-  @override
-  LinkedNodeBuilder visitContinueStatement(ContinueStatement node) {
-    var builder = LinkedNodeBuilder.continueStatement(
-      continueStatement_label: node.label?.accept(this),
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasInitializer: node.defaultValue != null,
+        isPositional: node.isPositional,
+        isRequired: node.isRequired,
+      ),
     );
-    _storeStatement(builder, node);
-    return builder;
-  }
 
-  @override
-  LinkedNodeBuilder visitDeclaredIdentifier(DeclaredIdentifier node) {
-    var builder = LinkedNodeBuilder.declaredIdentifier(
-      declaredIdentifier_identifier: node.identifier.accept(this),
-      declaredIdentifier_type: node.type?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isConst: node.keyword?.keyword == Keyword.CONST,
-      isFinal: node.keyword?.keyword == Keyword.FINAL,
-      isVar: node.keyword?.keyword == Keyword.VAR,
-    );
-    _storeDeclaration(builder, node);
-    return builder;
-  }
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
 
-  @override
-  LinkedNodeBuilder visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _writeNode(node.parameter);
+
     var defaultValue = node.defaultValue;
     if (!_isSerializableExpression(defaultValue)) {
       defaultValue = null;
     }
-
-    var builder = LinkedNodeBuilder.defaultFormalParameter(
-      defaultFormalParameter_defaultValue: defaultValue?.accept(this),
-      defaultFormalParameter_kind: _toParameterKind(node),
-      defaultFormalParameter_parameter: node.parameter.accept(this),
-      informativeId: getInformativeId(node),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasInitializer: node.defaultValue != null,
-    );
-    return builder;
+    _writeOptionalNode(defaultValue);
   }
 
   @override
-  LinkedNodeBuilder visitDoStatement(DoStatement node) {
-    return LinkedNodeBuilder.doStatement(
-      doStatement_body: node.body.accept(this),
-      doStatement_condition: node.condition.accept(this),
-    );
+  void visitDottedName(DottedName node) {
+    _writeByte(Tag.DottedName);
+    _writeNodeList(node.components);
   }
 
   @override
-  LinkedNodeBuilder visitDottedName(DottedName node) {
-    return LinkedNodeBuilder.dottedName(
-      dottedName_components: _writeNodeList(node.components),
-    );
+  void visitDoubleLiteral(DoubleLiteral node) {
+    _writeByte(Tag.DoubleLiteral);
+    _writeDouble(node.value);
   }
 
   @override
-  LinkedNodeBuilder visitDoubleLiteral(DoubleLiteral node) {
-    return LinkedNodeBuilder.doubleLiteral(
-      doubleLiteral_value: node.value,
-    );
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    _writeByte(Tag.EnumConstantDeclaration);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _writeDeclarationName(node.name);
+    _storeDeclaration(node);
   }
 
   @override
-  LinkedNodeBuilder visitEmptyFunctionBody(EmptyFunctionBody node) {
-    var builder = LinkedNodeBuilder.emptyFunctionBody();
-    _storeFunctionBody(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitEmptyStatement(EmptyStatement node) {
-    return LinkedNodeBuilder.emptyStatement();
-  }
-
-  @override
-  LinkedNodeBuilder visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    var builder = LinkedNodeBuilder.enumConstantDeclaration(
-      informativeId: getInformativeId(node),
-    );
-    builder..name = node.name.name;
-    _storeDeclaration(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitEnumDeclaration(EnumDeclaration node) {
-    var builder = LinkedNodeBuilder.enumDeclaration(
-      enumDeclaration_constants: _writeNodeList(node.constants),
-    );
-    _storeNamedCompilationUnitMember(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitExportDirective(ExportDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.exportDirective();
-      _storeNamespaceDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    timerAstBinaryWriterFunctionBody.start();
-    try {
-      var builder = LinkedNodeBuilder.expressionFunctionBody(
-        expressionFunctionBody_expression: node.expression.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isAsync: node.keyword?.keyword == Keyword.ASYNC,
-        isSync: node.keyword?.keyword == Keyword.SYNC,
-      );
-      return builder;
-    } finally {
-      timerAstBinaryWriterFunctionBody.stop();
-    }
-  }
-
-  @override
-  LinkedNodeBuilder visitExpressionStatement(ExpressionStatement node) {
-    return LinkedNodeBuilder.expressionStatement(
-      expressionStatement_expression: node.expression.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitExtendsClause(ExtendsClause node) {
-    return LinkedNodeBuilder.extendsClause(
-      extendsClause_superclass: node.superclass.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitExtensionDeclaration(ExtensionDeclaration node) {
-    var builder = LinkedNodeBuilder.extensionDeclaration(
-      extensionDeclaration_extendedType: node.extendedType.accept(this),
-      extensionDeclaration_members: _writeNodeList(node.members),
-      extensionDeclaration_typeParameters: node.typeParameters?.accept(this),
-    );
-
-    _storeCompilationUnitMember(builder, node);
-    _storeInformativeId(builder, node);
-    builder.name = node.name?.name;
-    LazyExtensionDeclaration.get(node).put(builder);
-
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitExtensionOverride(ExtensionOverride node) {
-    var builder = LinkedNodeBuilder.extensionOverride(
-      extensionOverride_arguments: _writeNodeList(
-        node.argumentList.arguments,
+  void visitEnumDeclaration(EnumDeclaration node) {
+    var resolutionIndex = _getNextResolutionIndex();
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.EnumDeclaration,
+        name: node.name.name,
       ),
-      extensionOverride_extensionName: node.extensionName.accept(this),
-      extensionOverride_typeArguments: node.typeArguments?.accept(this),
-      extensionOverride_typeArgumentTypes:
-          node.typeArgumentTypes.map(_writeType).toList(),
-      extensionOverride_extendedType: _writeType(node.extendedType),
     );
-    return builder;
+
+    _writeByte(Tag.EnumDeclaration);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _writeNodeList(node.constants);
+    _storeNamedCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
   }
 
   @override
-  LinkedNodeBuilder visitFieldDeclaration(FieldDeclaration node) {
-    var builder = LinkedNodeBuilder.fieldDeclaration(
-      fieldDeclaration_fields: node.fields.accept(this),
-      informativeId: getInformativeId(node),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isAbstract: node.abstractKeyword != null,
-      isCovariant: node.covariantKeyword != null,
-      isExternal: node.externalKeyword != null,
-      isStatic: node.staticKeyword != null,
-    );
-    _storeClassMember(builder, node);
+  void visitExportDirective(ExportDirective node) {
+    var resolutionIndex = _getNextResolutionIndex();
 
-    return builder;
-  }
+    _writeByte(Tag.ExportDirective);
+    _storeNamespaceDirective(node);
+    _writeUInt30(resolutionIndex);
 
-  @override
-  LinkedNodeBuilder visitFieldFormalParameter(FieldFormalParameter node) {
-    var builder = LinkedNodeBuilder.fieldFormalParameter(
-      fieldFormalParameter_formalParameters: node.parameters?.accept(this),
-      fieldFormalParameter_type: node.type?.accept(this),
-      fieldFormalParameter_typeParameters: node.typeParameters?.accept(this),
-    );
-    _storeNormalFormalParameter(builder, node, node.keyword);
-    builder.flags |= AstBinaryFlags.encode(hasQuestion: node.question != null);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForEachPartsWithDeclaration(
-      ForEachPartsWithDeclaration node) {
-    var builder = LinkedNodeBuilder.forEachPartsWithDeclaration(
-      forEachPartsWithDeclaration_loopVariable: node.loopVariable.accept(this),
-    );
-    _storeForEachParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForEachPartsWithIdentifier(
-      ForEachPartsWithIdentifier node) {
-    var builder = LinkedNodeBuilder.forEachPartsWithIdentifier(
-      forEachPartsWithIdentifier_identifier: node.identifier.accept(this),
-    );
-    _storeForEachParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForElement(ForElement node) {
-    var builder = LinkedNodeBuilder.forElement(
-      forElement_body: node.body.accept(this),
-    );
-    _storeForMixin(builder, node as ForElementImpl);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFormalParameterList(FormalParameterList node) {
-    var builder = LinkedNodeBuilder.formalParameterList(
-      formalParameterList_parameters: _writeNodeList(node.parameters),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isDelimiterCurly:
-          node.leftDelimiter?.type == TokenType.OPEN_CURLY_BRACKET,
-      isDelimiterSquare:
-          node.leftDelimiter?.type == TokenType.OPEN_SQUARE_BRACKET,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForPartsWithDeclarations(
-      ForPartsWithDeclarations node) {
-    var builder = LinkedNodeBuilder.forPartsWithDeclarations(
-      forPartsWithDeclarations_variables: node.variables.accept(this),
-    );
-    _storeForParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForPartsWithExpression(ForPartsWithExpression node) {
-    var builder = LinkedNodeBuilder.forPartsWithExpression(
-      forPartsWithExpression_initialization: node.initialization?.accept(this),
-    );
-    _storeForParts(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitForStatement(ForStatement node) {
-    var builder = LinkedNodeBuilder.forStatement(
-      forStatement_body: node.body.accept(this),
-    );
-    _storeForMixin(builder, node as ForStatementImpl);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionDeclaration(FunctionDeclaration node) {
-    var builder = LinkedNodeBuilder.functionDeclaration(
-      functionDeclaration_returnType: node.returnType?.accept(this),
-      functionDeclaration_functionExpression:
-          node.functionExpression?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isExternal: node.externalKeyword != null,
-      isGet: node.isGetter,
-      isSet: node.isSetter,
-    );
-    _storeNamedCompilationUnitMember(builder, node);
-    _writeActualReturnType(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionDeclarationStatement(
-      FunctionDeclarationStatement node) {
-    return LinkedNodeBuilder.functionDeclarationStatement(
-      functionDeclarationStatement_functionDeclaration:
-          node.functionDeclaration.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionExpression(FunctionExpression node) {
-    var bodyToStore = node.body;
-    if (node.parent.parent is CompilationUnit) {
-      bodyToStore = null;
-    }
-    var builder = LinkedNodeBuilder.functionExpression(
-      functionExpression_typeParameters: node.typeParameters?.accept(this),
-      functionExpression_formalParameters: node.parameters?.accept(this),
-      functionExpression_body: bodyToStore?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isAsync: node.body?.isAsynchronous ?? false,
-      isGenerator: node.body?.isGenerator ?? false,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionExpressionInvocation(
-      FunctionExpressionInvocation node) {
-    var builder = LinkedNodeBuilder.functionExpressionInvocation(
-      functionExpressionInvocation_function: node.function?.accept(this),
-    );
-    _storeInvocationExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitFunctionTypeAlias(FunctionTypeAlias node) {
-    timerAstBinaryWriterTypedef.start();
-    try {
-      var builder = LinkedNodeBuilder.functionTypeAlias(
-        functionTypeAlias_formalParameters: node.parameters.accept(this),
-        functionTypeAlias_returnType: node.returnType?.accept(this),
-        functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
-        typeAlias_hasSelfReference:
-            LazyFunctionTypeAlias.getHasSelfReference(node),
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(
+        (node.element as ExportElementImpl).exportedLibrary,
       );
-      _storeTypeAlias(builder, node);
-      _writeActualReturnType(builder, node);
-      _storeIsSimpleBounded(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterTypedef.stop();
     }
   }
 
   @override
-  LinkedNodeBuilder visitFunctionTypedFormalParameter(
-      FunctionTypedFormalParameter node) {
-    var builder = LinkedNodeBuilder.functionTypedFormalParameter(
-      functionTypedFormalParameter_formalParameters:
-          node.parameters.accept(this),
-      functionTypedFormalParameter_returnType: node.returnType?.accept(this),
-      functionTypedFormalParameter_typeParameters:
-          node.typeParameters?.accept(this),
-    );
-    _storeNormalFormalParameter(builder, node, null);
-    return builder;
+  void visitExtendsClause(ExtendsClause node) {
+    _writeByte(Tag.ExtendsClause);
+    _writeNode(node.superclass);
   }
 
   @override
-  LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
-    var id = LazyAst.getGenericFunctionTypeId(node);
-    assert(id != null);
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    var classOffset = _sink.offset;
+    var resolutionIndex = _getNextResolutionIndex();
 
-    var builder = LinkedNodeBuilder.genericFunctionType(
-      genericFunctionType_id: id,
-      genericFunctionType_returnType: node.returnType?.accept(this),
-      genericFunctionType_typeParameters: node.typeParameters?.accept(this),
-      genericFunctionType_formalParameters: node.parameters.accept(this),
-      genericFunctionType_type: _writeType(node.type),
+    _writeByte(Tag.ExtensionDeclaration);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeNode(node.extendedType);
+    _writeOptionalDeclarationName(node.name);
+    _storeCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
+
+    _classMemberIndexItems.clear();
+    _writeNodeList(node.members);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
+    }
+
+    // TODO(scheglov) write member index
+    var classIndexOffset = _sink.offset;
+    _writeClassMemberIndex();
+
+    var nameIdentifier = node.name;
+    var indexName = nameIdentifier != null
+        ? nameIdentifier.name
+        : 'extension-${_nextUnnamedExtensionId++}';
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: classOffset,
+        tag: Tag.ExtensionDeclaration,
+        name: indexName,
+        classIndexOffset: classIndexOffset,
+      ),
     );
-    builder.flags = AstBinaryFlags.encode(
+  }
+
+  @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    _writeByte(Tag.ExtensionOverride);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeByte(MethodInvocationRewriteTag.extensionOverride);
+    }
+
+    _writeNode(node.extensionName);
+    _writeOptionalNode(node.typeArguments);
+    _writeNode(node.argumentList);
+    _resolutionSink.writeType(node.extendedType);
+    // TODO(scheglov) typeArgumentTypes?
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    _classMemberIndexItems.add(
+      _ClassMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.FieldDeclaration,
+        fieldNames: node.fields.variables.map((e) => e.name.name).toList(),
+      ),
+    );
+
+    _writeByte(Tag.FieldDeclaration);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isAbstract: node.abstractKeyword != null,
+        isCovariant: node.covariantKeyword != null,
+        isExternal: node.externalKeyword != null,
+        isStatic: node.staticKeyword != null,
+      ),
+    );
+
+    _writeInformativeVariableCodeRanges(node.offset, node.fields);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _isConstField = node.fields.isConst;
+    _isFinalField = node.fields.isFinal;
+    try {
+      _writeNode(node.fields);
+    } finally {
+      _isConstField = false;
+      _isFinalField = false;
+    }
+
+    _storeClassMember(node);
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    _writeByte(Tag.FieldFormalParameter);
+
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.type);
+    _writeOptionalNode(node.parameters);
+    _storeNormalFormalParameter(
+      node,
+      node.keyword,
       hasQuestion: node.question != null,
     );
-    _writeActualReturnType(builder, node);
 
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitGenericTypeAlias(GenericTypeAlias node) {
-    timerAstBinaryWriterTypedef.start();
-    try {
-      var builder = LinkedNodeBuilder.genericTypeAlias(
-        genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
-        genericTypeAlias_functionType: node.functionType?.accept(this),
-        typeAlias_hasSelfReference:
-            LazyGenericTypeAlias.getHasSelfReference(node),
-      );
-      _storeTypeAlias(builder, node);
-      _storeIsSimpleBounded(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterTypedef.stop();
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
     }
   }
 
   @override
-  LinkedNodeBuilder visitHideCombinator(HideCombinator node) {
-    var builder = LinkedNodeBuilder.hideCombinator(
-      names: node.hiddenNames.map((id) => id.name).toList(),
-    );
-    _storeInformativeId(builder, node);
-    return builder;
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _writeByte(Tag.ForEachPartsWithDeclaration);
+    _writeNode(node.loopVariable);
+    _storeForEachParts(node);
   }
 
   @override
-  LinkedNodeBuilder visitIfElement(IfElement node) {
-    var builder = LinkedNodeBuilder.ifElement(
-      ifMixin_condition: node.condition.accept(this),
-      ifElement_elseElement: node.elseElement?.accept(this),
-      ifElement_thenElement: node.thenElement.accept(this),
-    );
-    return builder;
+  void visitForElement(ForElement node) {
+    _writeByte(Tag.ForElement);
+    _writeNode(node.body);
+    _storeForMixin(node as ForElementImpl);
   }
 
   @override
-  LinkedNodeBuilder visitIfStatement(IfStatement node) {
-    var builder = LinkedNodeBuilder.ifStatement(
-      ifMixin_condition: node.condition.accept(this),
-      ifStatement_elseStatement: node.elseStatement?.accept(this),
-      ifStatement_thenStatement: node.thenStatement.accept(this),
+  void visitFormalParameterList(FormalParameterList node) {
+    _writeByte(Tag.FormalParameterList);
+
+    var leftDelimiter = node.leftDelimiter?.type;
+    _writeByte(
+      AstBinaryFlags.encode(
+        isDelimiterCurly: leftDelimiter == TokenType.OPEN_CURLY_BRACKET,
+        isDelimiterSquare: leftDelimiter == TokenType.OPEN_SQUARE_BRACKET,
+      ),
     );
-    return builder;
+
+    _writeNodeList(node.parameters);
   }
 
   @override
-  LinkedNodeBuilder visitImplementsClause(ImplementsClause node) {
-    return LinkedNodeBuilder.implementsClause(
-      implementsClause_interfaces: _writeNodeList(node.interfaces),
-    );
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _writeByte(Tag.ForPartsWithDeclarations);
+    _writeNode(node.variables);
+    _storeForParts(node);
   }
 
   @override
-  LinkedNodeBuilder visitImportDirective(ImportDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.importDirective(
-        importDirective_prefix: node.prefix?.name,
-      );
-      builder.flags = AstBinaryFlags.encode(
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    var indexTag = Tag.FunctionDeclaration;
+    if (node.isGetter) {
+      indexTag = Tag.FunctionDeclaration_getter;
+    } else if (node.isSetter) {
+      indexTag = Tag.FunctionDeclaration_setter;
+    }
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: indexTag,
+        name: node.name.name,
+        variableNames: null,
+      ),
+    );
+
+    _writeByte(Tag.FunctionDeclaration);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isExternal: node.externalKeyword != null,
+        isGet: node.isGetter,
+        isSet: node.isSetter,
+      ),
+    );
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _pushScopeTypeParameters(node.functionExpression.typeParameters);
+
+    _writeNode(node.functionExpression);
+    _writeOptionalNode(node.returnType);
+    _storeNamedCompilationUnitMember(node);
+
+    if (_shouldWriteResolution) {
+      _writeActualReturnType(node.declaredElement.returnType);
+      _resolutionSink.localElements.popScope();
+    }
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    _writeByte(Tag.FunctionExpression);
+
+    var body = node.body;
+    _writeByte(
+      AstBinaryFlags.encode(
+        isAsync: body?.isAsynchronous ?? false,
+        isGenerator: body?.isGenerator ?? false,
+      ),
+    );
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.parameters);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    _writeByte(Tag.FunctionExpressionInvocation);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink
+          .writeByte(MethodInvocationRewriteTag.functionExpressionInvocation);
+    }
+
+    _writeNode(node.function);
+    _storeInvocationExpression(node);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.FunctionTypeAlias,
+        name: node.name.name,
+        variableNames: null,
+      ),
+    );
+
+    _writeByte(Tag.FunctionTypeAlias);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeNode(node.parameters);
+
+    _storeTypeAlias(node);
+
+    if (_shouldWriteResolution) {
+      var element = node.declaredElement as FunctionTypeAliasElementImpl;
+      _writeActualReturnType(element.function.returnType);
+      // TODO(scheglov) pack into one byte
+      _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+      _resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
+
+      _resolutionSink.localElements.popScope();
+    }
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    _writeByte(Tag.FunctionTypedFormalParameter);
+
+    _pushScopeTypeParameters(node.typeParameters);
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeNode(node.parameters);
+    _storeNormalFormalParameter(node, null);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
+    }
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    _writeByte(Tag.GenericFunctionType);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasQuestion: node.question != null,
+      ),
+    );
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeNode(node.parameters);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeType(node.type);
+      _resolutionSink.localElements.popScope();
+    }
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.GenericTypeAlias,
+        name: node.name.name,
+      ),
+    );
+
+    _writeByte(Tag.GenericTypeAlias);
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.type);
+    _storeTypeAlias(node);
+
+    if (_shouldWriteResolution) {
+      var element = node.declaredElement as TypeAliasElementImpl;
+      // TODO(scheglov) pack into one byte
+      _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+      _resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
+      _resolutionSink.localElements.popScope();
+    }
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitHideCombinator(HideCombinator node) {
+    _writeByte(Tag.HideCombinator);
+    _writeInformativeUint30(node.keyword.offset);
+    _writeNodeList(node.hiddenNames);
+  }
+
+  @override
+  void visitIfElement(IfElement node) {
+    _writeByte(Tag.IfElement);
+    _writeNode(node.condition);
+    _writeNode(node.thenElement);
+    _writeOptionalNode(node.elseElement);
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    _writeByte(Tag.ImplementsClause);
+    _writeNodeList(node.interfaces);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _writeByte(Tag.ImportDirective);
+
+    var prefix = node.prefix;
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPrefix: prefix != null,
         isDeferred: node.deferredKeyword != null,
-      );
-      _storeNamespaceDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
+      ),
+    );
+
+    if (prefix != null) {
+      _writeStringReference(prefix.name);
+      _writeInformativeUint30(prefix.offset);
+    }
+
+    _storeNamespaceDirective(node);
+    _writeUInt30(resolutionIndex);
+
+    if (_shouldWriteResolution) {
+      var element = node.element as ImportElementImpl;
+      _resolutionSink.writeElement(element.importedLibrary);
     }
   }
 
   @override
-  LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    var builder = LinkedNodeBuilder.indexExpression(
-      indexExpression_element: elementComponents.rawElement,
-      indexExpression_substitution: elementComponents.substitution,
-      indexExpression_index: node.index.accept(this),
-      indexExpression_target: node.target?.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasPeriod: node.period != null,
-      hasQuestion: node.question != null,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitInstanceCreationExpression(
-      InstanceCreationExpression node) {
-    InstanceCreationExpressionImpl nodeImpl = node;
-    var builder = LinkedNodeBuilder.instanceCreationExpression(
-      instanceCreationExpression_arguments: _writeNodeList(
-        node.argumentList.arguments,
+  void visitIndexExpression(IndexExpression node) {
+    _writeByte(Tag.IndexExpression);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPeriod: node.period != null,
+        hasQuestion: node.question != null,
       ),
-      instanceCreationExpression_constructorName:
-          node.constructorName.accept(this),
-      instanceCreationExpression_typeArguments:
-          nodeImpl.typeArguments?.accept(this),
-      expression_type: _writeType(node.staticType),
     );
-    builder.flags = AstBinaryFlags.encode(
-      isConst: node.keyword?.type == Keyword.CONST,
-      isNew: node.keyword?.type == Keyword.NEW,
-    );
-    return builder;
+    _writeOptionalNode(node.target);
+    _writeNode(node.index);
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+    }
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitIntegerLiteral(IntegerLiteral node) {
-    return LinkedNodeBuilder.integerLiteral(
-      expression_type: _writeType(node.staticType),
-      integerLiteral_value: node.value,
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _writeByte(Tag.InstanceCreationExpression);
+
+    if (_shouldWriteResolution) {
+      if (node.constructorName.name != null) {
+        _resolutionSink.writeByte(
+          MethodInvocationRewriteTag.instanceCreationExpression_withName,
+        );
+      } else {
+        _resolutionSink.writeByte(
+          MethodInvocationRewriteTag.instanceCreationExpression_withoutName,
+        );
+      }
+    }
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.keyword?.type == Keyword.CONST,
+        isNew: node.keyword?.type == Keyword.NEW,
+      ),
     );
+
+    _writeNode(node.constructorName);
+    _writeNode(node.argumentList);
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitInterpolationExpression(InterpolationExpression node) {
-    return LinkedNodeBuilder.interpolationExpression(
-      interpolationExpression_expression: node.expression.accept(this),
-    )..flags = AstBinaryFlags.encode(
+  void visitIntegerLiteral(IntegerLiteral node) {
+    var value = node.value;
+
+    if (value == null) {
+      _writeByte(Tag.IntegerLiteralNull);
+      _writeStringReference(node.literal.lexeme);
+    } else {
+      var isPositive = value >= 0;
+      if (!isPositive) {
+        value = -value;
+      }
+
+      if (value & 0xFF == value) {
+        _writeByte(
+          isPositive
+              ? Tag.IntegerLiteralPositive1
+              : Tag.IntegerLiteralNegative1,
+        );
+        _writeByte(value);
+      } else {
+        _writeByte(
+          isPositive ? Tag.IntegerLiteralPositive : Tag.IntegerLiteralNegative,
+        );
+        _writeUInt32(value >> 32);
+        _writeUInt32(value & 0xFFFFFFFF);
+      }
+    }
+
+    if (_shouldWriteResolution) {
+      // TODO(scheglov) Dont write type, AKA separate true `int` and `double`?
+      _resolutionSink.writeType(node.staticType);
+    }
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    _writeByte(Tag.InterpolationExpression);
+    _writeByte(
+      AstBinaryFlags.encode(
         isStringInterpolationIdentifier:
             node.leftBracket.type == TokenType.STRING_INTERPOLATION_IDENTIFIER,
-      );
+      ),
+    );
+    _writeNode(node.expression);
   }
 
   @override
-  LinkedNodeBuilder visitInterpolationString(InterpolationString node) {
-    return LinkedNodeBuilder.interpolationString(
-      interpolationString_value: node.value,
-    );
+  void visitInterpolationString(InterpolationString node) {
+    _writeByte(Tag.InterpolationString);
+    _writeStringReference(node.value);
   }
 
   @override
-  LinkedNodeBuilder visitIsExpression(IsExpression node) {
-    var builder = LinkedNodeBuilder.isExpression(
-      isExpression_expression: node.expression.accept(this),
-      isExpression_type: node.type.accept(this),
+  void visitIsExpression(IsExpression node) {
+    _writeByte(Tag.IsExpression);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasNot: node.notOperator != null,
+      ),
     );
-    builder.flags = AstBinaryFlags.encode(
-      hasNot: node.notOperator != null,
-    );
-    return builder;
+    _writeNode(node.expression);
+    _writeNode(node.type);
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitLabel(Label node) {
-    return LinkedNodeBuilder.label(
-      label_label: node.label.accept(this),
-    );
+  void visitLibraryDirective(LibraryDirective node) {
+    _writeByte(Tag.LibraryDirective);
+    _writeDocumentationCommentString(node.documentationComment);
+    visitLibraryIdentifier(node.name);
+    _storeDirective(node);
   }
 
   @override
-  LinkedNodeBuilder visitLabeledStatement(LabeledStatement node) {
-    return LinkedNodeBuilder.labeledStatement(
-      labeledStatement_labels: _writeNodeList(node.labels),
-      labeledStatement_statement: node.statement.accept(this),
-    );
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    _writeByte(Tag.LibraryIdentifier);
+    _writeNodeList(node.components);
   }
 
   @override
-  LinkedNodeBuilder visitLibraryDirective(LibraryDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.libraryDirective(
-        informativeId: getInformativeId(node),
-        libraryDirective_name: node.name.accept(this),
-      );
-      _storeDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
+  void visitListLiteral(ListLiteral node) {
+    _writeByte(Tag.ListLiteral);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.constKeyword != null,
+      ),
+    );
+
+    _writeOptionalNode(node.typeArguments);
+    _writeNodeList(node.elements);
+
+    _storeExpression(node);
+  }
+
+  @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    _writeByte(Tag.MapLiteralEntry);
+    _writeNode(node.key);
+    _writeNode(node.value);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    var indexTag = Tag.MethodDeclaration;
+    if (node.isGetter) {
+      indexTag = Tag.MethodDeclaration_getter;
+    } else if (node.isSetter) {
+      indexTag = Tag.MethodDeclaration_setter;
+    }
+    _classMemberIndexItems.add(
+      _ClassMemberIndexItem(
+        offset: _sink.offset,
+        tag: indexTag,
+        name: node.name.name,
+      ),
+    );
+
+    _writeByte(Tag.MethodDeclaration);
+
+    _writeUInt30(
+      AstBinaryFlags.encode(
+        isAbstract: node.body is EmptyFunctionBody,
+        isAsync: node.body?.isAsynchronous ?? false,
+        isExternal: node.externalKeyword != null,
+        isGenerator: node.body?.isGenerator ?? false,
+        isGet: node.isGetter,
+        isNative: node.body is NativeFunctionBody,
+        isOperator: node.operatorKeyword != null,
+        isSet: node.isSetter,
+        isStatic: node.isStatic,
+      ),
+    );
+
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeDeclarationName(node.name);
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.returnType);
+    _writeOptionalNode(node.parameters);
+
+    _storeClassMember(node);
+
+    _writeUInt30(resolutionIndex);
+
+    if (_shouldWriteResolution) {
+      var element = node.declaredElement as ExecutableElementImpl;
+      _writeActualReturnType(element.returnType);
+      _writeTopLevelInferenceError(element);
+      // TODO(scheglov) move this flag into ClassElementImpl?
+      if (element is MethodElementImpl) {
+        _resolutionSink.writeByte(
+          element.isOperatorEqualWithParameterTypeFromObject ? 1 : 0,
+        );
+      }
+      _resolutionSink.localElements.popScope();
     }
   }
 
   @override
-  LinkedNodeBuilder visitLibraryIdentifier(LibraryIdentifier node) {
-    return LinkedNodeBuilder.libraryIdentifier(
-      libraryIdentifier_components: _writeNodeList(node.components),
-    );
-  }
+  void visitMethodInvocation(MethodInvocation node) {
+    _writeByte(Tag.MethodInvocation);
 
-  @override
-  LinkedNodeBuilder visitListLiteral(ListLiteral node) {
-    var builder = LinkedNodeBuilder.listLiteral(
-      listLiteral_elements: _writeNodeList(node.elements),
-    );
-    _storeTypedLiteral(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitMapLiteralEntry(MapLiteralEntry node) {
-    return LinkedNodeBuilder.mapLiteralEntry(
-      mapLiteralEntry_key: node.key.accept(this),
-      mapLiteralEntry_value: node.value.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) {
-    var builder = LinkedNodeBuilder.methodDeclaration(
-      methodDeclaration_returnType: node.returnType?.accept(this),
-      methodDeclaration_typeParameters: node.typeParameters?.accept(this),
-      methodDeclaration_formalParameters: node.parameters?.accept(this),
-      methodDeclaration_hasOperatorEqualWithParameterTypeFromObject:
-          LazyAst.hasOperatorEqualParameterTypeFromObject(node),
-    );
-    builder.name = node.name.name;
-    builder.flags = AstBinaryFlags.encode(
-      isAbstract: node.body is EmptyFunctionBody,
-      isAsync: node.body?.isAsynchronous ?? false,
-      isExternal: node.externalKeyword != null,
-      isGenerator: node.body?.isGenerator ?? false,
-      isGet: node.isGetter,
-      isNative: node.body is NativeFunctionBody,
-      isOperator: node.operatorKeyword != null,
-      isSet: node.isSetter,
-      isStatic: node.isStatic,
-    );
-    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _storeClassMember(builder, node);
-    _storeInformativeId(builder, node);
-    _writeActualReturnType(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitMethodInvocation(MethodInvocation node) {
-    var builder = LinkedNodeBuilder.methodInvocation(
-      methodInvocation_methodName: node.methodName?.accept(this),
-      methodInvocation_target: node.target?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasPeriod: node.operator?.type == TokenType.PERIOD,
-      hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
-    );
-    _storeInvocationExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitMixinDeclaration(MixinDeclaration node) {
-    timerAstBinaryWriterMixin.start();
-    try {
-      var builder = LinkedNodeBuilder.mixinDeclaration(
-        mixinDeclaration_onClause: node.onClause?.accept(this),
-      );
-      _storeClassOrMixinDeclaration(builder, node);
-      LazyMixinDeclaration.get(node).put(builder);
-      return builder;
-    } finally {
-      timerAstBinaryWriterMixin.stop();
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeByte(MethodInvocationRewriteTag.none);
     }
-  }
 
-  @override
-  LinkedNodeBuilder visitNamedExpression(NamedExpression node) {
-    return LinkedNodeBuilder.namedExpression(
-      namedExpression_expression: node.expression.accept(this),
-      namedExpression_name: node.name.accept(this),
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPeriod: node.operator?.type == TokenType.PERIOD,
+        hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+      ),
     );
+    _writeOptionalNode(node.target);
+    _writeNode(node.methodName);
+    _storeInvocationExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitNativeClause(NativeClause node) {
-    return LinkedNodeBuilder.nativeClause(
-      nativeClause_name: node.name.accept(this),
-    );
-  }
+  void visitMixinDeclaration(MixinDeclaration node) {
+    var classOffset = _sink.offset;
+    var resolutionIndex = _getNextResolutionIndex();
 
-  @override
-  LinkedNodeBuilder visitNativeFunctionBody(NativeFunctionBody node) {
-    return LinkedNodeBuilder.nativeFunctionBody(
-      nativeFunctionBody_stringLiteral: node.stringLiteral?.accept(this),
-    );
-  }
+    _writeByte(Tag.MixinDeclaration);
 
-  @override
-  LinkedNodeBuilder visitNullLiteral(NullLiteral node) {
-    return LinkedNodeBuilder.nullLiteral();
-  }
-
-  @override
-  LinkedNodeBuilder visitOnClause(OnClause node) {
-    return LinkedNodeBuilder.onClause(
-      onClause_superclassConstraints:
-          _writeNodeList(node.superclassConstraints),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitParenthesizedExpression(ParenthesizedExpression node) {
-    var builder = LinkedNodeBuilder.parenthesizedExpression(
-      parenthesizedExpression_expression: node.expression.accept(this),
-    );
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitPartDirective(PartDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.partDirective();
-      _storeUriBasedDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
+    if (_shouldWriteResolution) {
+      var element = node.declaredElement as MixinElementImpl;
+      _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+      _resolutionSink.writeStringList(element.superInvokedNames);
     }
-  }
 
-  @override
-  LinkedNodeBuilder visitPartOfDirective(PartOfDirective node) {
-    timerAstBinaryWriterDirective.start();
-    try {
-      var builder = LinkedNodeBuilder.partOfDirective(
-        partOfDirective_libraryName: node.libraryName?.accept(this),
-        partOfDirective_uri: node.uri?.accept(this),
-      );
-      _storeDirective(builder, node);
-      return builder;
-    } finally {
-      timerAstBinaryWriterDirective.stop();
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    _pushScopeTypeParameters(node.typeParameters);
+
+    _writeOptionalNode(node.typeParameters);
+    _writeOptionalNode(node.onClause);
+    _writeOptionalNode(node.implementsClause);
+    _storeNamedCompilationUnitMember(node);
+    _writeUInt30(resolutionIndex);
+
+    _classMemberIndexItems.clear();
+    _writeNodeList(node.members);
+    _hasConstConstructor = false;
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.localElements.popScope();
     }
-  }
 
-  @override
-  LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.postfixExpression(
-      expression_type: _writeType(node.staticType),
-      postfixExpression_element: elementComponents.rawElement,
-      postfixExpression_substitution: elementComponents.substitution,
-      postfixExpression_operand: node.operand.accept(this),
-      postfixExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
+    // TODO(scheglov) write member index
+    var classIndexOffset = _sink.offset;
+    _writeClassMemberIndex();
+
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: classOffset,
+        tag: Tag.MixinDeclaration,
+        name: node.name.name,
+        classIndexOffset: classIndexOffset,
       ),
     );
   }
 
   @override
-  LinkedNodeBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
-    return LinkedNodeBuilder.prefixedIdentifier(
-      prefixedIdentifier_identifier: node.identifier.accept(this),
-      prefixedIdentifier_prefix: node.prefix.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
+  void visitNamedExpression(NamedExpression node) {
+    _writeByte(Tag.NamedExpression);
+
+    var nameNode = node.name.label;
+    _writeStringReference(nameNode.name);
+    _writeInformativeUint30(nameNode.offset);
+
+    _writeNode(node.expression);
   }
 
   @override
-  LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.prefixExpression(
-      expression_type: _writeType(node.staticType),
-      prefixExpression_element: elementComponents.rawElement,
-      prefixExpression_substitution: elementComponents.substitution,
-      prefixExpression_operand: node.operand.accept(this),
-      prefixExpression_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
-      ),
-    );
+  void visitNativeClause(NativeClause node) {
+    _writeByte(Tag.NativeClause);
+    _writeNode(node.name);
   }
 
   @override
-  LinkedNodeBuilder visitPropertyAccess(PropertyAccess node) {
-    var builder = LinkedNodeBuilder.propertyAccess(
-      propertyAccess_operator: TokensWriter.astToBinaryTokenType(
-        node.operator.type,
-      ),
-      propertyAccess_propertyName: node.propertyName.accept(this),
-      propertyAccess_target: node.target?.accept(this),
-    );
-    _storeExpression(builder, node);
-    return builder;
+  void visitNullLiteral(NullLiteral node) {
+    _writeByte(Tag.NullLiteral);
   }
 
   @override
-  LinkedNodeBuilder visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    var builder = LinkedNodeBuilder.redirectingConstructorInvocation(
-      redirectingConstructorInvocation_arguments:
-          node.argumentList.accept(this),
-      redirectingConstructorInvocation_constructorName:
-          node.constructorName?.accept(this),
-      redirectingConstructorInvocation_element: elementComponents.rawElement,
-      redirectingConstructorInvocation_substitution:
-          elementComponents.substitution,
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasThis: node.thisKeyword != null,
-    );
-    _storeConstructorInitializer(builder, node);
-    return builder;
+  void visitOnClause(OnClause node) {
+    _writeByte(Tag.OnClause);
+    _writeNodeList(node.superclassConstraints);
   }
 
   @override
-  LinkedNodeBuilder visitRethrowExpression(RethrowExpression node) {
-    return LinkedNodeBuilder.rethrowExpression(
-      expression_type: _writeType(node.staticType),
-    );
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    _writeByte(Tag.ParenthesizedExpression);
+    _writeNode(node.expression);
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitReturnStatement(ReturnStatement node) {
-    return LinkedNodeBuilder.returnStatement(
-      returnStatement_expression: node.expression?.accept(this),
-    );
+  void visitPartDirective(PartDirective node) {
+    _writeByte(Tag.PartDirective);
+    _storeUriBasedDirective(node);
   }
 
   @override
-  LinkedNodeBuilder visitScriptTag(ScriptTag node) {
-    return null;
+  void visitPartOfDirective(PartOfDirective node) {
+    _writeByte(Tag.PartOfDirective);
+    _writeOptionalNode(node.libraryName);
+    _writeOptionalNode(node.uri);
+    _storeDirective(node);
   }
 
   @override
-  LinkedNodeBuilder visitSetOrMapLiteral(SetOrMapLiteral node) {
-    var builder = LinkedNodeBuilder.setOrMapLiteral(
-      setOrMapLiteral_elements: _writeNodeList(node.elements),
-    );
-    _storeTypedLiteral(builder, node, isMap: node.isMap, isSet: node.isSet);
-    return builder;
+  void visitPostfixExpression(PostfixExpression node) {
+    _writeByte(Tag.PostfixExpression);
+
+    _writeNode(node.operand);
+
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+      if (operatorToken.isIncrementOperator) {
+        _resolutionSink.writeElement(node.readElement);
+        _resolutionSink.writeType(node.readType);
+        _resolutionSink.writeElement(node.writeElement);
+        _resolutionSink.writeType(node.writeType);
+      }
+    }
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitShowCombinator(ShowCombinator node) {
-    var builder = LinkedNodeBuilder.showCombinator(
-      names: node.shownNames.map((id) => id.name).toList(),
-    );
-    _storeInformativeId(builder, node);
-    return builder;
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _writeByte(Tag.PrefixedIdentifier);
+    _writeNode(node.prefix);
+    _writeNode(node.identifier);
+
+    if (_shouldWriteResolution) {
+      // TODO(scheglov) In actual prefixed identifier, the type of the identifier.
+      _resolutionSink.writeType(node.staticType);
+    }
   }
 
   @override
-  LinkedNodeBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
-    var builder = LinkedNodeBuilder.simpleFormalParameter(
-      simpleFormalParameter_type: node.type?.accept(this),
-    );
-    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _storeNormalFormalParameter(builder, node, node.keyword);
-    _storeInheritsCovariant(builder, node);
-    return builder;
-  }
+  void visitPrefixExpression(PrefixExpression node) {
+    _writeByte(Tag.PrefixExpression);
 
-  @override
-  LinkedNodeBuilder visitSimpleIdentifier(SimpleIdentifier node) {
-    Element element;
-    if (!node.inDeclarationContext()) {
-      element = node.staticElement;
-      if (element is MultiplyDefinedElement) {
-        element = null;
+    var operatorToken = node.operator.type;
+    var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+    _writeByte(binaryToken.index);
+
+    _writeNode(node.operand);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+      if (operatorToken.isIncrementOperator) {
+        _resolutionSink.writeElement(node.readElement);
+        _resolutionSink.writeType(node.readType);
+        _resolutionSink.writeElement(node.writeElement);
+        _resolutionSink.writeType(node.writeType);
       }
     }
 
-    var elementComponents = _componentsOfElement(element);
-    var builder = LinkedNodeBuilder.simpleIdentifier(
-      simpleIdentifier_element: elementComponents.rawElement,
-      simpleIdentifier_substitution: elementComponents.substitution,
-      expression_type: _writeType(node.staticType),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isDeclaration: node is DeclaredSimpleIdentifier,
-    );
-    builder.name = node.name;
-    return builder;
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitSimpleStringLiteral(SimpleStringLiteral node) {
-    var builder = LinkedNodeBuilder.simpleStringLiteral(
-      simpleStringLiteral_value: node.value,
-    );
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitSpreadElement(SpreadElement node) {
-    return LinkedNodeBuilder.spreadElement(
-      spreadElement_expression: node.expression.accept(this),
-      spreadElement_spreadOperator: TokensWriter.astToBinaryTokenType(
-        node.spreadOperator.type,
+  void visitPropertyAccess(PropertyAccess node) {
+    _writeByte(Tag.PropertyAccess);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasPeriod: node.operator?.type == TokenType.PERIOD,
+        hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
       ),
     );
+    _writeOptionalNode(node.target);
+    _writeNode(node.propertyName);
+    // TODO(scheglov) Get from the property?
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitStringInterpolation(StringInterpolation node) {
-    return LinkedNodeBuilder.stringInterpolation(
-      stringInterpolation_elements: _writeNodeList(node.elements),
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    _writeByte(Tag.RedirectingConstructorInvocation);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasThis: node.thisKeyword != null,
+      ),
     );
+
+    _writeOptionalNode(node.constructorName);
+    _writeNode(node.argumentList);
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+    }
+    _storeConstructorInitializer(node);
   }
 
   @override
-  LinkedNodeBuilder visitSuperConstructorInvocation(
-      SuperConstructorInvocation node) {
-    var elementComponents = _componentsOfElement(node.staticElement);
-    var builder = LinkedNodeBuilder.superConstructorInvocation(
-      superConstructorInvocation_arguments: node.argumentList.accept(this),
-      superConstructorInvocation_constructorName:
-          node.constructorName?.accept(this),
-      superConstructorInvocation_element: elementComponents.rawElement,
-      superConstructorInvocation_substitution: elementComponents.substitution,
+  void visitSetOrMapLiteral(SetOrMapLiteral node) {
+    _writeByte(Tag.SetOrMapLiteral);
+
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.constKeyword != null,
+      ),
     );
-    _storeConstructorInitializer(builder, node);
-    return builder;
+
+    if (_shouldWriteResolution) {
+      var isMapBit = node.isMap ? (1 << 0) : 0;
+      var isSetBit = node.isSet ? (1 << 1) : 0;
+      _resolutionSink.writeByte(isMapBit | isSetBit);
+    }
+
+    _writeOptionalNode(node.typeArguments);
+    _writeNodeList(node.elements);
+
+    _storeExpression(node);
   }
 
   @override
-  LinkedNodeBuilder visitSuperExpression(SuperExpression node) {
-    var builder = LinkedNodeBuilder.superExpression();
-    _storeExpression(builder, node);
-    return builder;
+  void visitShowCombinator(ShowCombinator node) {
+    _writeByte(Tag.ShowCombinator);
+    _writeInformativeUint30(node.keyword.offset);
+    _writeNodeList(node.shownNames);
   }
 
   @override
-  LinkedNodeBuilder visitSwitchCase(SwitchCase node) {
-    var builder = LinkedNodeBuilder.switchCase(
-      switchCase_expression: node.expression.accept(this),
-    );
-    _storeSwitchMember(builder, node);
-    return builder;
-  }
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    _writeByte(Tag.SimpleFormalParameter);
 
-  @override
-  LinkedNodeBuilder visitSwitchDefault(SwitchDefault node) {
-    var builder = LinkedNodeBuilder.switchDefault();
-    _storeSwitchMember(builder, node);
-    return builder;
-  }
+    _writeOptionalNode(node.type);
+    _storeNormalFormalParameter(node, node.keyword);
 
-  @override
-  LinkedNodeBuilder visitSwitchStatement(SwitchStatement node) {
-    return LinkedNodeBuilder.switchStatement(
-      switchStatement_expression: node.expression.accept(this),
-      switchStatement_members: _writeNodeList(node.members),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitSymbolLiteral(SymbolLiteral node) {
-    var builder = LinkedNodeBuilder.symbolLiteral(
-      names: node.components.map((t) => t.lexeme).toList(),
-    );
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitThisExpression(ThisExpression node) {
-    var builder = LinkedNodeBuilder.thisExpression();
-    _storeExpression(builder, node);
-    return builder;
-  }
-
-  @override
-  LinkedNodeBuilder visitThrowExpression(ThrowExpression node) {
-    return LinkedNodeBuilder.throwExpression(
-      throwExpression_expression: node.expression.accept(this),
-      expression_type: _writeType(node.staticType),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitTopLevelVariableDeclaration(
-      TopLevelVariableDeclaration node) {
-    timerAstBinaryWriterTopVar.start();
-    try {
-      var builder = LinkedNodeBuilder.topLevelVariableDeclaration(
-        informativeId: getInformativeId(node),
-        topLevelVariableDeclaration_variableList: node.variables?.accept(this),
-      );
-      builder.flags = AstBinaryFlags.encode(
-        isExternal: node.externalKeyword != null,
-      );
-      _storeCompilationUnitMember(builder, node);
-
-      return builder;
-    } finally {
-      timerAstBinaryWriterTopVar.stop();
+    if (_shouldWriteResolution) {
+      var element = node.declaredElement as ParameterElementImpl;
+      _resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
     }
   }
 
   @override
-  LinkedNodeBuilder visitTryStatement(TryStatement node) {
-    return LinkedNodeBuilder.tryStatement(
-      tryStatement_body: node.body.accept(this),
-      tryStatement_catchClauses: _writeNodeList(node.catchClauses),
-      tryStatement_finallyBlock: node.finallyBlock?.accept(this),
-    );
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    _writeByte(Tag.SimpleIdentifier);
+    _writeStringReference(node.name);
+    _writeInformativeUint30(node.offset);
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+      // TODO(scheglov) It is inefficient to write many null types.
+      _resolutionSink.writeType(node.staticType);
+    }
   }
 
   @override
-  LinkedNodeBuilder visitTypeArgumentList(TypeArgumentList node) {
-    return LinkedNodeBuilder.typeArgumentList(
-      typeArgumentList_arguments: _writeNodeList(node.arguments),
-    );
+  void visitSimpleStringLiteral(SimpleStringLiteral node) {
+    _writeByte(Tag.SimpleStringLiteral);
+    _writeStringReference(node.literal.lexeme);
+    _writeStringReference(node.value);
   }
 
   @override
-  LinkedNodeBuilder visitTypeName(TypeName node) {
-    return LinkedNodeBuilder.typeName(
-      typeName_name: node.name.accept(this),
-      typeName_type: _writeType(node.type),
-      typeName_typeArguments: _writeNodeList(
-        node.typeArguments?.arguments,
+  void visitSpreadElement(SpreadElement node) {
+    _writeByte(Tag.SpreadElement);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasQuestion:
+            node.spreadOperator.type == TokenType.PERIOD_PERIOD_PERIOD_QUESTION,
       ),
-    )..flags = AstBinaryFlags.encode(
+    );
+    _writeNode(node.expression);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    _writeByte(Tag.StringInterpolation);
+    _writeNodeList(node.elements);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writeByte(Tag.SuperConstructorInvocation);
+
+    _writeOptionalNode(node.constructorName);
+    _writeNode(node.argumentList);
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeElement(node.staticElement);
+    }
+    _storeConstructorInitializer(node);
+  }
+
+  @override
+  void visitSuperExpression(SuperExpression node) {
+    _writeByte(Tag.SuperExpression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    _writeByte(Tag.SymbolLiteral);
+
+    var components = node.components;
+    _writeUInt30(components.length);
+    for (var token in components) {
+      _writeStringReference(token.lexeme);
+    }
+    _storeExpression(node);
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    _writeByte(Tag.ThisExpression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    _writeByte(Tag.ThrowExpression);
+    _writeNode(node.expression);
+    _storeExpression(node);
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    unitMemberIndexItems.add(
+      _UnitMemberIndexItem(
+        offset: _sink.offset,
+        tag: Tag.TopLevelVariableDeclaration,
+        variableNames: node.variables.variables
+            .map((variable) => variable.name.name)
+            .toList(),
+      ),
+    );
+
+    _writeByte(Tag.TopLevelVariableDeclaration);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isExternal: node.externalKeyword != null,
+      ),
+    );
+
+    _writeInformativeVariableCodeRanges(node.offset, node.variables);
+    _writeDocumentationCommentString(node.documentationComment);
+
+    var resolutionIndex = _getNextResolutionIndex();
+
+    _isConstTopLevelVariable = node.variables.isConst;
+    try {
+      _writeNode(node.variables);
+    } finally {
+      _isConstTopLevelVariable = false;
+    }
+
+    _storeCompilationUnitMember(node);
+
+    _writeUInt30(resolutionIndex);
+  }
+
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    _writeByte(Tag.TypeArgumentList);
+    _writeNodeList(node.arguments);
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    _writeByte(Tag.TypeName);
+
+    _writeByte(
+      AstBinaryFlags.encode(
         hasQuestion: node.question != null,
         hasTypeArguments: node.typeArguments != null,
+      ),
+    );
+
+    _writeNode(node.name);
+    _writeOptionalNode(node.typeArguments);
+
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeType(node.type);
+    }
+  }
+
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    _writeByte(Tag.TypeParameter);
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+    _writeDeclarationName(node.name);
+    _writeOptionalNode(node.bound);
+    _storeDeclaration(node);
+
+    if (_shouldWriteResolution) {
+      var element = node.declaredElement as TypeParameterElementImpl;
+      _resolutionSink.writeByte(
+        _encodeVariance(element),
       );
+      _resolutionSink.writeType(element.defaultType);
+    }
   }
 
   @override
-  LinkedNodeBuilder visitTypeParameter(TypeParameter node) {
-    var builder = LinkedNodeBuilder.typeParameter(
-      typeParameter_bound: node.bound?.accept(this),
-      typeParameter_defaultType: _writeType(LazyAst.getDefaultType(node)),
-      typeParameter_variance: _encodeVariance(LazyAst.getVariance(node)),
-      informativeId: getInformativeId(node),
+  void visitTypeParameterList(TypeParameterList node) {
+    _writeByte(Tag.TypeParameterList);
+    _writeNodeList(node.typeParameters);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    _writeByte(Tag.VariableDeclaration);
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasInitializer: node.initializer != null,
+      ),
     );
-    builder.name = node.name.name;
-    _storeDeclaration(builder, node);
-    return builder;
-  }
+    _writeDeclarationName(node.name);
 
-  @override
-  LinkedNodeBuilder visitTypeParameterList(TypeParameterList node) {
-    return LinkedNodeBuilder.typeParameterList(
-      typeParameterList_typeParameters: _writeNodeList(node.typeParameters),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) {
-    var initializer = node.initializer;
-    var declarationList = node.parent as VariableDeclarationList;
-    var declaration = declarationList.parent;
-    if (declaration is TopLevelVariableDeclaration) {
-      if (!declarationList.isConst) {
-        initializer = null;
-      }
-    } else if (declaration is FieldDeclaration) {
-      if (!(declarationList.isConst ||
-          !declaration.isStatic &&
-              declarationList.isFinal &&
-              _hasConstConstructor)) {
-        initializer = null;
+    if (_shouldWriteResolution) {
+      // TODO(scheglov) Enforce not null, remove `?` in `?.type` below.
+      var element = node.declaredElement as VariableElementImpl;
+      _writeActualType(element?.type);
+      _writeTopLevelInferenceError(element);
+      if (element is FieldElementImpl) {
+        _resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
       }
     }
 
-    if (!_isSerializableExpression(initializer)) {
-      initializer = null;
+    Expression initializerToWrite;
+    if (_isConstField ||
+        _hasConstConstructor && _isFinalField ||
+        _isConstTopLevelVariable) {
+      var initializer = node.initializer;
+      if (_isSerializableExpression(initializer)) {
+        initializerToWrite = initializer;
+      }
+    }
+    _writeOptionalNode(initializerToWrite);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    _writeByte(Tag.VariableDeclarationList);
+    _writeByte(
+      AstBinaryFlags.encode(
+        isConst: node.isConst,
+        isFinal: node.isFinal,
+        isLate: node.lateKeyword != null,
+        isVar: node.keyword?.keyword == Keyword.VAR,
+      ),
+    );
+    _writeOptionalNode(node.type);
+    _writeNodeList(node.variables);
+    _storeAnnotatedNode(node);
+  }
+
+  @override
+  void visitWithClause(WithClause node) {
+    _writeByte(Tag.WithClause);
+    _writeNodeList(node.mixinTypes);
+  }
+
+  void _pushScopeTypeParameters(TypeParameterList node) {
+    if (!_shouldWriteResolution) {
+      return;
     }
 
-    var builder = LinkedNodeBuilder.variableDeclaration(
-      informativeId: getInformativeId(node),
-      variableDeclaration_initializer: initializer?.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      hasInitializer: node.initializer != null,
-    );
-    builder.name = node.name.name;
-    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _writeActualType(builder, node);
-    _storeInheritsCovariant(builder, node);
-    return builder;
-  }
+    _resolutionSink.localElements.pushScope();
 
-  @override
-  LinkedNodeBuilder visitVariableDeclarationList(VariableDeclarationList node) {
-    var builder = LinkedNodeBuilder.variableDeclarationList(
-      variableDeclarationList_type: node.type?.accept(this),
-      variableDeclarationList_variables: _writeNodeList(node.variables),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isConst: node.isConst,
-      isFinal: node.isFinal,
-      isLate: node.lateKeyword != null,
-      isVar: node.keyword?.keyword == Keyword.VAR,
-    );
-    _storeAnnotatedNode(builder, node);
-    return builder;
-  }
+    if (node == null) {
+      return;
+    }
 
-  @override
-  LinkedNodeBuilder visitVariableDeclarationStatement(
-      VariableDeclarationStatement node) {
-    return LinkedNodeBuilder.variableDeclarationStatement(
-      variableDeclarationStatement_variables: node.variables.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitWhileStatement(WhileStatement node) {
-    return LinkedNodeBuilder.whileStatement(
-      whileStatement_body: node.body.accept(this),
-      whileStatement_condition: node.condition.accept(this),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitWithClause(WithClause node) {
-    return LinkedNodeBuilder.withClause(
-      withClause_mixinTypes: _writeNodeList(node.mixinTypes),
-    );
-  }
-
-  @override
-  LinkedNodeBuilder visitYieldStatement(YieldStatement node) {
-    var builder = LinkedNodeBuilder.yieldStatement(
-      yieldStatement_expression: node.expression.accept(this),
-    );
-    builder.flags = AstBinaryFlags.encode(
-      isStar: node.star != null,
-    );
-    _storeStatement(builder, node);
-    return builder;
-  }
-
-  LinkedNodeBuilder writeUnit(CompilationUnit unit) {
-    timerAstBinaryWriter.start();
-    try {
-      return unit.accept(this);
-    } finally {
-      timerAstBinaryWriter.stop();
+    for (var typeParameter in node.typeParameters) {
+      _resolutionSink.localElements.declare(typeParameter.declaredElement);
     }
   }
 
-  _ElementComponents _componentsOfElement(Element element) {
-    if (element is ParameterMember) {
-      element = element.declaration;
+  void _storeAnnotatedNode(AnnotatedNode node) {
+    _writeNodeList(node.metadata);
+  }
+
+  void _storeClassMember(ClassMember node) {
+    _storeDeclaration(node);
+  }
+
+  void _storeCompilationUnitMember(CompilationUnitMember node) {
+    _storeDeclaration(node);
+  }
+
+  void _storeConstructorInitializer(ConstructorInitializer node) {}
+
+  void _storeDeclaration(Declaration node) {
+    _storeAnnotatedNode(node);
+  }
+
+  void _storeDirective(Directive node) {
+    _writeInformativeUint30(node.keyword.offset);
+    _storeAnnotatedNode(node);
+  }
+
+  void _storeExpression(Expression node) {
+    if (_shouldWriteResolution) {
+      _resolutionSink.writeType(node.staticType);
     }
+  }
 
-    if (element is Member) {
-      var elementIndex = _indexOfElement(element.declaration);
-      var substitution = element.substitution.map;
-      var substitutionBuilder = LinkedNodeTypeSubstitutionBuilder(
-        isLegacy: element.isLegacy,
-        typeParameters: substitution.keys.map(_indexOfElement).toList(),
-        typeArguments: substitution.values.map(_writeType).toList(),
-      );
-      return _ElementComponents(elementIndex, substitutionBuilder);
+  void _storeForEachParts(ForEachParts node) {
+    _writeNode(node.iterable);
+    _storeForLoopParts(node);
+  }
+
+  void _storeForLoopParts(ForLoopParts node) {}
+
+  void _storeFormalParameter(FormalParameter node) {
+    if (_shouldWriteResolution) {
+      _writeActualType(node.declaredElement.type);
     }
-
-    var elementIndex = _indexOfElement(element);
-    return _ElementComponents(elementIndex, null);
   }
 
-  int _indexOfElement(Element element) {
-    return _linkingContext.indexOfElement(element);
-  }
-
-  void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) {
-    builder.annotatedNode_metadata = _writeNodeList(node.metadata);
-  }
-
-  void _storeClassMember(LinkedNodeBuilder builder, ClassMember node) {
-    _storeDeclaration(builder, node);
-  }
-
-  void _storeClassOrMixinDeclaration(
-      LinkedNodeBuilder builder, ClassOrMixinDeclaration node) {
-    builder
-      ..classOrMixinDeclaration_implementsClause =
-          node.implementsClause?.accept(this)
-      ..classOrMixinDeclaration_members = _writeNodeList(node.members)
-      ..classOrMixinDeclaration_typeParameters =
-          node.typeParameters?.accept(this);
-    _storeNamedCompilationUnitMember(builder, node);
-    _storeIsSimpleBounded(builder, node);
-  }
-
-  void _storeCompilationUnitMember(
-      LinkedNodeBuilder builder, CompilationUnitMember node) {
-    _storeDeclaration(builder, node);
-  }
-
-  void _storeConstructorInitializer(
-      LinkedNodeBuilder builder, ConstructorInitializer node) {}
-
-  void _storeDeclaration(LinkedNodeBuilder builder, Declaration node) {
-    _storeAnnotatedNode(builder, node);
-  }
-
-  void _storeDirective(LinkedNodeBuilder builder, Directive node) {
-    _storeAnnotatedNode(builder, node);
-    _storeInformativeId(builder, node);
-  }
-
-  void _storeExpression(LinkedNodeBuilder builder, Expression node) {
-    builder.expression_type = _writeType(node.staticType);
-  }
-
-  void _storeForEachParts(LinkedNodeBuilder builder, ForEachParts node) {
-    _storeForLoopParts(builder, node);
-    builder..forEachParts_iterable = node.iterable?.accept(this);
-  }
-
-  void _storeForLoopParts(LinkedNodeBuilder builder, ForLoopParts node) {}
-
-  void _storeFormalParameter(LinkedNodeBuilder builder, FormalParameter node) {
-    _writeActualType(builder, node);
-  }
-
-  void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) {
-    builder.flags = AstBinaryFlags.encode(
-      hasAwait: node.awaitKeyword != null,
+  void _storeForMixin(ForMixin node) {
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasAwait: node.awaitKeyword != null,
+      ),
     );
-    builder..forMixin_forLoopParts = node.forLoopParts.accept(this);
+    _writeNode(node.forLoopParts);
   }
 
-  void _storeForParts(LinkedNodeBuilder builder, ForParts node) {
-    _storeForLoopParts(builder, node);
-    builder
-      ..forParts_condition = node.condition?.accept(this)
-      ..forParts_updaters = _writeNodeList(node.updaters);
+  void _storeForParts(ForParts node) {
+    _writeOptionalNode(node.condition);
+    _writeNodeList(node.updaters);
+    _storeForLoopParts(node);
   }
 
-  void _storeFunctionBody(LinkedNodeBuilder builder, FunctionBody node) {}
-
-  void _storeInformativeId(LinkedNodeBuilder builder, AstNode node) {
-    builder.informativeId = getInformativeId(node);
+  void _storeInvocationExpression(InvocationExpression node) {
+    _writeOptionalNode(node.typeArguments);
+    _writeNode(node.argumentList);
+    _storeExpression(node);
+    // TODO(scheglov) typeArgumentTypes and staticInvokeType?
   }
 
-  void _storeInheritsCovariant(LinkedNodeBuilder builder, AstNode node) {
-    var value = LazyAst.getInheritsCovariant(node);
-    builder.inheritsCovariant = value;
+  void _storeNamedCompilationUnitMember(NamedCompilationUnitMember node) {
+    _writeDeclarationName(node.name);
+    _storeCompilationUnitMember(node);
   }
 
-  void _storeInvocationExpression(
-      LinkedNodeBuilder builder, InvocationExpression node) {
-    _storeExpression(builder, node);
-    builder
-      ..invocationExpression_arguments = node.argumentList.accept(this)
-      ..invocationExpression_invokeType = _writeType(node.staticInvokeType)
-      ..invocationExpression_typeArguments = node.typeArguments?.accept(this);
-  }
-
-  void _storeIsSimpleBounded(LinkedNodeBuilder builder, AstNode node) {
-    var flag = LazyAst.isSimplyBounded(node);
-    // TODO(scheglov) Check for `null` when writing resolved AST.
-    builder.simplyBoundable_isSimplyBounded = flag;
-  }
-
-  void _storeNamedCompilationUnitMember(
-      LinkedNodeBuilder builder, NamedCompilationUnitMember node) {
-    _storeCompilationUnitMember(builder, node);
-    _storeInformativeId(builder, node);
-    builder.name = node.name.name;
-  }
-
-  void _storeNamespaceDirective(
-      LinkedNodeBuilder builder, NamespaceDirective node) {
-    _storeUriBasedDirective(builder, node);
-    builder
-      ..namespaceDirective_combinators = _writeNodeList(node.combinators)
-      ..namespaceDirective_configurations = _writeNodeList(node.configurations)
-      ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node);
+  void _storeNamespaceDirective(NamespaceDirective node) {
+    _writeNodeList(node.combinators);
+    _writeNodeList(node.configurations);
+    _storeUriBasedDirective(node);
   }
 
   void _storeNormalFormalParameter(
-      LinkedNodeBuilder builder, NormalFormalParameter node, Token keyword) {
-    _storeFormalParameter(builder, node);
-    builder
-      ..flags = AstBinaryFlags.encode(
+    NormalFormalParameter node,
+    Token keyword, {
+    bool hasQuestion = false,
+  }) {
+    _writeByte(
+      AstBinaryFlags.encode(
+        hasName: node.identifier != null,
+        hasQuestion: hasQuestion,
         isConst: keyword?.type == Keyword.CONST,
         isCovariant: node.covariantKeyword != null,
         isFinal: keyword?.type == Keyword.FINAL,
         isRequired: node.requiredKeyword != null,
         isVar: keyword?.type == Keyword.VAR,
-      )
-      ..informativeId = getInformativeId(node)
-      ..name = node.identifier?.name
-      ..normalFormalParameter_metadata = _writeNodeList(node.metadata);
-  }
-
-  void _storeStatement(LinkedNodeBuilder builder, Statement node) {}
-
-  void _storeSwitchMember(LinkedNodeBuilder builder, SwitchMember node) {
-    builder.switchMember_labels = _writeNodeList(node.labels);
-    builder.switchMember_statements = _writeNodeList(node.statements);
-  }
-
-  void _storeTypeAlias(LinkedNodeBuilder builder, TypeAlias node) {
-    _storeNamedCompilationUnitMember(builder, node);
-  }
-
-  void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node,
-      {bool isMap = false, bool isSet = false}) {
-    _storeExpression(builder, node);
-    builder
-      ..flags = AstBinaryFlags.encode(
-        hasTypeArguments: node.typeArguments != null,
-        isConst: node.constKeyword != null,
-        isMap: isMap,
-        isSet: isSet,
-      )
-      ..typedLiteral_typeArguments = _writeNodeList(
-        node.typeArguments?.arguments,
-      );
-  }
-
-  void _storeUriBasedDirective(
-      LinkedNodeBuilder builder, UriBasedDirective node) {
-    _storeDirective(builder, node);
-    builder
-      ..uriBasedDirective_uri = node.uri.accept(this)
-      ..uriBasedDirective_uriContent = node.uriContent
-      ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement);
-  }
-
-  void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
-    var type = LazyAst.getReturnType(node);
-    // TODO(scheglov) Check for `null` when writing resolved AST.
-    builder.actualReturnType = _writeType(type);
-  }
-
-  void _writeActualType(LinkedNodeBuilder builder, AstNode node) {
-    var type = LazyAst.getType(node);
-    // TODO(scheglov) Check for `null` when writing resolved AST.
-    builder.actualType = _writeType(type);
-  }
-
-  List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) {
-    if (nodeList == null) {
-      return const <LinkedNodeBuilder>[];
-    }
-
-    var result = List<LinkedNodeBuilder>.filled(
-      nodeList.length,
-      null,
-      growable: true,
+      ),
     );
-    for (var i = 0; i < nodeList.length; ++i) {
-      result[i] = nodeList[i].accept(this);
+
+    // TODO(scheglov) Don't store when in DefaultFormalParameter?
+    _writeInformativeUint30(node.offset);
+    _writeInformativeUint30(node.length);
+
+    _writeNodeList(node.metadata);
+    if (node.identifier != null) {
+      _writeDeclarationName(node.identifier);
     }
-    return result;
+    _storeFormalParameter(node);
   }
 
-  LinkedNodeTypeBuilder _writeType(DartType type) {
-    return _linkingContext.writeType(type);
+  void _storeTypeAlias(TypeAlias node) {
+    _storeNamedCompilationUnitMember(node);
   }
 
-  static int _encodeVariance(Variance variance) {
-    if (variance == null) {
+  void _storeUriBasedDirective(UriBasedDirective node) {
+    _writeNode(node.uri);
+    _storeDirective(node);
+  }
+
+  void _writeActualReturnType(DartType type) {
+    // TODO(scheglov) Check for `null` when writing resolved AST.
+    _resolutionSink.writeType(type);
+  }
+
+  void _writeActualType(DartType type) {
+    // TODO(scheglov) Check for `null` when writing resolved AST.
+    _resolutionSink.writeType(type);
+  }
+
+  void _writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
+    _sink.addByte(byte);
+  }
+
+  void _writeClassMemberIndex() {
+    _writeUInt30(_classMemberIndexItems.length);
+    for (var declaration in _classMemberIndexItems) {
+      _writeUInt30(declaration.offset);
+      _writeByte(declaration.tag);
+      if (declaration.name != null) {
+        _writeStringReference(declaration.name);
+      } else {
+        _writeUInt30(declaration.fieldNames.length);
+        for (var name in declaration.fieldNames) {
+          _writeStringReference(name);
+        }
+      }
+    }
+  }
+
+  void _writeDeclarationName(SimpleIdentifier node) {
+    _writeByte(Tag.SimpleIdentifier);
+    _writeStringReference(node.name);
+    _writeInformativeUint30(node.offset);
+  }
+
+  /// We write tokens as a list, so this must be the last entity written.
+  void _writeDocumentationCommentString(Comment node) {
+    if (node != null && _withInformative) {
+      var tokens = node.tokens;
+      _writeUInt30(tokens.length);
+      for (var token in tokens) {
+        _writeStringReference(token.lexeme);
+      }
+    } else {
+      _writeUInt30(0);
+    }
+  }
+
+  _writeDouble(double value) {
+    _sink.addDouble(value);
+  }
+
+  void _writeFeatureSet(FeatureSet featureSet) {
+    var experimentStatus = featureSet as ExperimentStatus;
+    var encoded = experimentStatus.toStorage();
+    _writeUint8List(encoded);
+  }
+
+  void _writeInformativeUint30(int value) {
+    if (_withInformative) {
+      _writeUInt30(value);
+    }
+  }
+
+  void _writeInformativeVariableCodeRanges(
+    int firstOffset,
+    VariableDeclarationList node,
+  ) {
+    if (_withInformative) {
+      var variables = node.variables;
+      _writeUInt30(variables.length * 2);
+      var isFirst = true;
+      for (var variable in variables) {
+        var offset = isFirst ? firstOffset : variable.offset;
+        var end = variable.end;
+        _writeUInt30(offset);
+        _writeUInt30(end - offset);
+        isFirst = false;
+      }
+    }
+  }
+
+  void _writeLanguageVersion(LibraryLanguageVersion languageVersion) {
+    _writeUInt30(languageVersion.package.major);
+    _writeUInt30(languageVersion.package.minor);
+
+    var override = languageVersion.override;
+    if (override != null) {
+      _writeUInt30(override.major + 1);
+      _writeUInt30(override.minor + 1);
+    } else {
+      _writeUInt30(0);
+      _writeUInt30(0);
+    }
+  }
+
+  void _writeLineInfo(LineInfo lineInfo) {
+    if (_withInformative) {
+      _writeUint30List(lineInfo.lineStarts);
+    } else {
+      _writeUint30List(const <int>[0]);
+    }
+  }
+
+  void _writeNode(AstNode node) {
+    node.accept(this);
+  }
+
+  void _writeNodeList(List<AstNode> nodeList) {
+    _writeUInt30(nodeList.length);
+    for (var i = 0; i < nodeList.length; ++i) {
+      nodeList[i].accept(this);
+    }
+  }
+
+  void _writeOptionalDeclarationName(SimpleIdentifier node) {
+    if (node == null) {
+      _writeByte(Tag.Nothing);
+    } else {
+      _writeByte(Tag.Something);
+      _writeDeclarationName(node);
+    }
+  }
+
+  void _writeOptionalNode(AstNode node) {
+    if (node == null) {
+      _writeByte(Tag.Nothing);
+    } else {
+      _writeByte(Tag.Something);
+      _writeNode(node);
+    }
+  }
+
+  void _writeStringReference(String string) {
+    assert(string != null);
+    var index = _stringIndexer[string];
+    _writeUInt30(index);
+  }
+
+  void _writeTopLevelInferenceError(ElementImpl element) {
+    TopLevelInferenceError error;
+    if (element is MethodElementImpl) {
+      error = element.typeInferenceError;
+    } else if (element is PropertyInducingElementImpl) {
+      error = element.typeInferenceError;
+    } else {
+      return;
+    }
+
+    if (error != null) {
+      _resolutionSink.writeByte(error.kind.index);
+      _resolutionSink.writeStringList(error.arguments);
+    } else {
+      _resolutionSink.writeByte(TopLevelInferenceErrorKind.none.index);
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  void _writeUInt30(int value) {
+    _sink.writeUInt30(value);
+  }
+
+  void _writeUint30List(List<int> values) {
+    var length = values.length;
+    _writeUInt30(length);
+    for (var i = 0; i < length; i++) {
+      _writeUInt30(values[i]);
+    }
+  }
+
+  void _writeUInt32(int value) {
+    _sink.addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF,
+        (value >> 8) & 0xFF, value & 0xFF);
+  }
+
+  void _writeUint8List(List<int> values) {
+    var length = values.length;
+    _writeUInt30(length);
+    for (var i = 0; i < length; i++) {
+      _writeByte(values[i]);
+    }
+  }
+
+  static int _encodeVariance(TypeParameterElementImpl element) {
+    if (element.isLegacyCovariant) {
       return 0;
-    } else if (variance == Variance.unrelated) {
+    }
+
+    var variance = element.variance;
+    if (variance == Variance.unrelated) {
       return 1;
     } else if (variance == Variance.covariant) {
       return 2;
@@ -1733,28 +1900,21 @@
     node.accept(visitor);
     return visitor.result;
   }
-
-  static LinkedNodeFormalParameterKind _toParameterKind(FormalParameter node) {
-    if (node.isRequiredPositional) {
-      return LinkedNodeFormalParameterKind.requiredPositional;
-    } else if (node.isRequiredNamed) {
-      return LinkedNodeFormalParameterKind.requiredNamed;
-    } else if (node.isOptionalPositional) {
-      return LinkedNodeFormalParameterKind.optionalPositional;
-    } else if (node.isOptionalNamed) {
-      return LinkedNodeFormalParameterKind.optionalNamed;
-    } else {
-      throw StateError('Unknown kind of parameter');
-    }
-  }
 }
 
-/// Components of a [Member] - the raw element, and the substitution.
-class _ElementComponents {
-  final int rawElement;
-  final LinkedNodeTypeSubstitutionBuilder substitution;
+/// An item in the class index, used to read only requested class members.
+class _ClassMemberIndexItem {
+  final int offset;
+  final int tag;
+  final String name;
+  final List<String> fieldNames;
 
-  _ElementComponents(this.rawElement, this.substitution);
+  _ClassMemberIndexItem({
+    @required this.offset,
+    @required this.tag,
+    this.name,
+    this.fieldNames,
+  });
 }
 
 class _IsSerializableExpressionVisitor extends RecursiveAstVisitor<void> {
@@ -1765,3 +1925,22 @@
     result = false;
   }
 }
+
+/// An item in the unit index, used to read only requested unit members.
+class _UnitMemberIndexItem {
+  final int offset;
+  final int tag;
+  final String name;
+  final List<String> variableNames;
+
+  /// The absolute offset of the index of class members, `0` if not a class.
+  final int classIndexOffset;
+
+  _UnitMemberIndexItem({
+    @required this.offset,
+    @required this.tag,
+    this.name,
+    this.variableNames,
+    this.classIndexOffset = 0,
+  });
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
index 9e1b27e..4e733f9 100644
--- a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
@@ -520,7 +520,7 @@
     node.name.accept(this);
     node.typeParameters?.accept(this);
     _token(node.equals);
-    node.functionType.accept(this);
+    node.type.accept(this);
     _token(node.semicolon);
   }
 
@@ -964,6 +964,7 @@
   @override
   void visitVariableDeclarationList(VariableDeclarationList node) {
     _annotatedNode(node);
+    _token(node.lateKeyword);
     _token(node.keyword);
     node.type?.accept(this);
     _nodeList(node.variables, node.endToken.next);
@@ -1042,6 +1043,7 @@
   void _normalFormalParameter(NormalFormalParameter node) {
     node.documentationComment?.accept(this);
     _nodeList(node.metadata);
+    _token(node.requiredKeyword);
     _token(node.covariantKeyword);
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/binary_format_doc.dart b/pkg/analyzer/lib/src/summary2/binary_format_doc.dart
new file mode 100644
index 0000000..646328e
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/binary_format_doc.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+
+class AstBundle {
+  /// The blob with libraries.
+  ///
+  /// Items of [libraryOffsets] point here.
+  List<AstLibrary> libraries;
+
+  /// Pointers to libraries in the [libraries] blob.
+  ///
+  /// We need these offsets because we read [ResolutionLibrary] only
+  /// partially - URI, offsets of units, but nothing about units. So,
+  /// we don't know where one library ends, and another starts.
+  ///
+  /// TODO(scheglov) too complicated? Read all?
+  List<Uint30> libraryOffsets;
+
+  /// [stringTableOffset] points here.
+  StringTableFormat stringTable;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-4`.
+  Uint32 librariesOffset;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-0`.
+  Uint32 stringTableOffset;
+}
+
+class AstLibrary {
+  /// The name from the `library` directive, might be the empty string.
+  StringRef name;
+
+  /// The offset `+1` of the name in the `library` directive.
+  /// So, `0` if absent, decoded then into `-1`.
+  Uint30 nameOffset;
+
+  /// The length of the name in the `library` directive, `0` if absent.
+  Uint30 nameLength;
+
+  /// Offsets pointing at [AstUnitFormat.headerOffset].
+  List<Uint30> unitOffsets;
+}
+
+class AstUnitFormat {
+  /// The header of the unit, read when create the reader.
+  /// [headerOffset] points here.
+  AstUnitHeader header;
+
+  /// [AstUnitIndexItem.offset] from [indexOfMembers] points into here.
+  Object declarations;
+
+  /// The offset of [header].
+  Uint30 headerOffset;
+
+  /// The index of declarations in the unit.
+  List<AstUnitIndexItem> indexOfMembers;
+}
+
+class AstUnitHeader {
+  /// Four elements: package major/minor, override major/minor.
+  /// The override is `+1`, if `0` then no override.
+  FormatUint32List languageVersion;
+
+  /// Encoded feature set.
+  FormatUint32List featureSet;
+}
+
+class AstUnitIndexItem {
+  /// The offset in [AstUnitFormat.declarations].
+  Uint30 offset;
+
+  /// The tag of the declaration from [Tag].
+  Byte tag;
+
+  /// If not [Tag.TopLevelVariableDeclaration], the name of the declaration.
+  /// Otherwise absent, [topLevelVariableNames] instead.
+  StringRef name;
+
+  /// If [Tag.TopLevelVariableDeclaration], the names of the variables.
+  /// Otherwise absent, [name] instead.
+  List<StringRef> topLevelVariableNames;
+}
+
+class Byte {}
+
+class FormatUint32List {}
+
+class ResolutionBundle {
+  /// The blob with libraries.
+  ///
+  /// [libraryOffsets] points here.
+  List<ResolutionLibrary> libraries;
+
+  /// Pointers to libraries in the [libraries] blob.
+  ///
+  /// We need these offsets because we read [ResolutionLibrary] only
+  /// partially - URI, offsets of units, but nothing about units. So,
+  /// we don't know where one library ends, and another starts.
+  ///
+  /// TODO(scheglov) too complicated? Read all?
+  List<Uint30> libraryOffsets;
+
+  /// The index of the parent reference, so we can add its name from
+  /// the [referenceNames]. Is `0` for the root.
+  ///
+  /// [referencesOffset] points here.
+  List<Uint30> referenceParents;
+
+  /// The name of this component of a reference, e.g. `String` or `@class`.
+  /// Is the empty string for the root.
+  List<StringRef> referenceNames;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-8`.
+  Uint32 librariesOffset;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-4`.
+  ///
+  /// Points at [referenceParents].
+  Uint32 referencesOffset;
+
+  /// We record `uint32` to know exactly the location of this field.
+  /// It is always at the end of the byte buffer `-0`.
+  Uint32 stringTableOffset;
+}
+
+class ResolutionLibrary {
+  /// The blob with units.
+  List<ResolutionUnitFormat> units;
+
+  /// [ResolutionBundle.libraryOffsets] points here.
+  StringRef uriStr;
+
+  /// Indexes of exported elements in [ResolutionBundle.referenceNames].
+  List<Uint30> exportedReferences;
+
+  /// Absolute offsets pointing at [ResolutionUnitFormat.uriStr].
+  List<Uint30> unitOffsets;
+}
+
+class ResolutionUnitFormat {
+  /// [ResolutionLibrary.unitOffsets] points here.
+  StringRef uriStr;
+
+  Byte isSynthetic;
+
+  Byte isPart;
+
+  /// If [isPart], the URI that is used in the `part` directive.
+  /// The empty string for the defining unit.
+  StringRef partUriStr;
+
+  /// The offset of the resolution information for directives.
+  /// For example resolution of metadata.
+  Uint30 directivesResolutionOffset;
+
+  /// Offsets of the resolution information for each declaration.
+  List<Uint30> declarationOffsets;
+}
+
+/// The reference to a [String], in form of [Uint30].
+class StringRef {}
+
+/// Any string is witten as [Uint30] and is an index into the string table.
+/// So, we can write each unique string only once.
+class StringTableFormat {
+  /// The blob with WTF8 encoded strings.
+  Object strings;
+
+  /// The length of [strings] in bytes. So, we know how much to go back in
+  /// the byte buffer from here to start reading strings.
+  Uint30 lengthInBytes;
+
+  /// The length of each string in bytes inside [strings].
+  ///
+  /// This allows us to read strings lazily as they are requested.
+  List<Uint30> lengths;
+}
+
+class Uint30 {}
+
+class Uint32 {}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
new file mode 100644
index 0000000..1b6e4b4
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -0,0 +1,1362 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+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/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.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/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary2/apply_resolution.dart';
+import 'package:analyzer/src/summary2/ast_binary_reader.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
+import 'package:pub_semver/pub_semver.dart';
+
+Map<String, LibraryReader> createLibraryReadersWithAstBytes({
+  @required LinkedElementFactory elementFactory,
+  @required Uint8List resolutionBytes,
+  @required Map<String, Map<String, Uint8List>> uriToLibrary_uriToUnitAstBytes,
+}) {
+  var _resolutionReader = SummaryDataReader(resolutionBytes);
+
+  _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
+  var resolutionLibrariesOffset = _resolutionReader.readUint32();
+  var resolutionReferencesOffset = _resolutionReader.readUint32();
+  var resolutionStringsOffset = _resolutionReader.readUint32();
+  _resolutionReader.createStringTable(resolutionStringsOffset);
+
+  var referenceReader = _ReferenceReader(
+    elementFactory,
+    _resolutionReader,
+    resolutionReferencesOffset,
+  );
+
+  _resolutionReader.offset = resolutionLibrariesOffset;
+  var resolutionLibraryOffsets = _resolutionReader.readUint30List();
+
+  assert(
+    uriToLibrary_uriToUnitAstBytes.length == resolutionLibraryOffsets.length,
+  );
+
+  // TODO(scheglov) Don't read anything, we know URIs.
+  var libraryMap = <String, LibraryReader>{};
+  for (var i = 0; i < resolutionLibraryOffsets.length; i++) {
+    _resolutionReader.offset = resolutionLibraryOffsets[i];
+    var libraryUriStr = _resolutionReader.readStringReference();
+    var resolutionUnitOffsets = _resolutionReader.readUint30List();
+    var exportsIndexList = _resolutionReader.readUint30List();
+
+    var uriToUnitAstBytes = uriToLibrary_uriToUnitAstBytes[libraryUriStr];
+    assert(uriToUnitAstBytes != null, libraryUriStr);
+
+    var reference = elementFactory.rootReference.getChild(libraryUriStr);
+    var libraryReader = LibraryReaderForAstBytes._(
+      elementFactory,
+      uriToUnitAstBytes,
+      _resolutionReader,
+      referenceReader,
+      reference,
+      resolutionUnitOffsets,
+      exportsIndexList,
+    );
+    libraryMap[libraryUriStr] = libraryReader;
+  }
+
+  return libraryMap;
+}
+
+class BundleReader {
+  final SummaryDataReader _astReader;
+  final SummaryDataReader _resolutionReader;
+
+  bool _withInformative = false;
+
+  final Map<String, LibraryReader> libraryMap = {};
+
+  BundleReader({
+    @required LinkedElementFactory elementFactory,
+    @required Uint8List astBytes,
+    @required Uint8List resolutionBytes,
+  })  : _astReader = SummaryDataReader(astBytes),
+        _resolutionReader = SummaryDataReader(resolutionBytes) {
+    _astReader.offset = 0;
+    _withInformative = _astReader.readByte() == 1;
+
+    _astReader.offset = _astReader.bytes.length - 4 * 2;
+    var astLibrariesOffset = _astReader.readUint32();
+    var astStringsOffset = _astReader.readUint32();
+    _astReader.createStringTable(astStringsOffset);
+
+    _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
+    var resolutionLibrariesOffset = _resolutionReader.readUint32();
+    var resolutionReferencesOffset = _resolutionReader.readUint32();
+    var resolutionStringsOffset = _resolutionReader.readUint32();
+    _resolutionReader.createStringTable(resolutionStringsOffset);
+
+    var referenceReader = _ReferenceReader(
+      elementFactory,
+      _resolutionReader,
+      resolutionReferencesOffset,
+    );
+
+    _astReader.offset = astLibrariesOffset;
+    var astLibraryOffsets = _astReader.readUint30List();
+
+    _resolutionReader.offset = resolutionLibrariesOffset;
+    var resolutionLibraryOffsets = _resolutionReader.readUint30List();
+
+    assert(astLibraryOffsets.length == resolutionLibraryOffsets.length);
+
+    for (var i = 0; i < astLibraryOffsets.length; i++) {
+      _astReader.offset = astLibraryOffsets[i];
+      var name = _astReader.readStringReference();
+      var nameOffset = _astReader.readUInt30() - 1;
+      var nameLength = _astReader.readUInt30();
+      var hasPartOfDirective = _astReader.readByte() != 0;
+      var astUnitOffsets = _astReader.readUint30List();
+
+      _resolutionReader.offset = resolutionLibraryOffsets[i];
+      var libraryUriStr = _resolutionReader.readStringReference();
+      var resolutionUnitOffsets = _resolutionReader.readUint30List();
+      assert(astUnitOffsets.length == resolutionUnitOffsets.length);
+      var exportsIndexList = _resolutionReader.readUint30List();
+
+      var reference = elementFactory.rootReference.getChild(libraryUriStr);
+      var libraryReader = LibraryReaderFromBundle._(
+        elementFactory,
+        _withInformative,
+        _astReader,
+        _resolutionReader,
+        referenceReader,
+        reference,
+        name,
+        nameOffset,
+        nameLength,
+        hasPartOfDirective,
+        astUnitOffsets,
+        resolutionUnitOffsets,
+        exportsIndexList,
+      );
+      libraryMap[libraryUriStr] = libraryReader;
+    }
+  }
+
+  LibraryReader getLibrary(String uriStr) {
+    return libraryMap[uriStr];
+  }
+}
+
+class ClassReader {
+  final int membersOffset;
+
+  ClassReader(this.membersOffset);
+}
+
+abstract class LibraryReader {
+  final LinkedElementFactory _elementFactory;
+  final SummaryDataReader _resolutionReader;
+  final _ReferenceReader _referenceReader;
+  final Reference reference;
+
+  final Uint32List _resolutionUnitOffsets;
+  final Uint32List _exportsIndexList;
+  List<Reference> _exports;
+
+  List<UnitReader> _units;
+
+  LibraryReader._(
+    this._elementFactory,
+    this._resolutionReader,
+    this._referenceReader,
+    this.reference,
+    this._resolutionUnitOffsets,
+    this._exportsIndexList,
+  );
+
+  List<Reference> get exports {
+    if (_exports == null) {
+      var length = _exportsIndexList.length;
+      _exports = List.filled(length, null, growable: false);
+      for (var i = 0; i < length; i++) {
+        var index = _exportsIndexList[i];
+        var reference = _referenceReader.referenceOfIndex(index);
+        _exports[i] = reference;
+      }
+    }
+    return _exports;
+  }
+
+  /// Is `true` if the defining unit has [PartOfDirective].
+  bool get hasPartOfDirective;
+
+  String get name;
+
+  int get nameLength;
+
+  int get nameOffset;
+
+  List<UnitReader> get units;
+
+  bool get withInformative;
+}
+
+/// Implementation of [LibraryReader] that reads ASTs for units from separate
+/// byte buffers.
+class LibraryReaderForAstBytes extends LibraryReader {
+  final Map<String, Uint8List> _uriToUnitAstBytes;
+
+  bool _hasNameRead = false;
+  bool _withInformative;
+  String _name;
+  int _nameOffset;
+  int _nameLength;
+  bool _hasPartOfDirective;
+
+  LibraryReaderForAstBytes._(
+    LinkedElementFactory elementFactory,
+    Map<String, Uint8List> uriToUnitAstBytes,
+    SummaryDataReader resolutionReader,
+    _ReferenceReader referenceReader,
+    Reference reference,
+    Uint32List resolutionUnitOffsets,
+    Uint32List exportsIndexList,
+  )   : _uriToUnitAstBytes = uriToUnitAstBytes,
+        super._(
+          elementFactory,
+          resolutionReader,
+          referenceReader,
+          reference,
+          resolutionUnitOffsets,
+          exportsIndexList,
+        ) {
+    // TODO(scheglov) This fails when there are invalid URIs.
+    // assert(_uriToUnitAstBytes.length == _resolutionUnitOffsets.length);
+  }
+
+  @override
+  bool get hasPartOfDirective {
+    _readName();
+    return _hasPartOfDirective;
+  }
+
+  @override
+  String get name {
+    _readName();
+    return _name;
+  }
+
+  @override
+  int get nameLength {
+    _readName();
+    return _nameLength;
+  }
+
+  @override
+  int get nameOffset {
+    _readName();
+    return _nameOffset;
+  }
+
+  @override
+  List<UnitReader> get units {
+    if (_units != null) return _units;
+    _units = [];
+
+    for (var i = 0; i < _resolutionUnitOffsets.length; i++) {
+      _resolutionReader.offset = _resolutionUnitOffsets[i];
+      var unitUriStr = _resolutionReader.readStringReference();
+      var isSynthetic = _resolutionReader.readByte() != 0;
+      var isPart = _resolutionReader.readByte() != 0;
+      var partUriStr = _resolutionReader.readStringReference();
+      if (!isPart) {
+        partUriStr = null;
+      }
+      var resolutionDirectivesOffset = _resolutionReader.readUInt30();
+      var resolutionDeclarationOffsets = _resolutionReader.readUint30List();
+
+      // TODO(scheglov) Is this right?
+      if (unitUriStr.isEmpty) {
+        unitUriStr = 'null';
+      }
+
+      var astBytes = _uriToUnitAstBytes[unitUriStr];
+      var astReader = SummaryDataReader(astBytes);
+      astReader.offset = astBytes.length - 4 * 4;
+      var headerOffset = astReader.readUint32();
+      var indexOffset = astReader.readUint32();
+      astReader.readUint32(); // library data
+      var astStringsOffset = astReader.readUint32();
+      astReader.createStringTable(astStringsOffset);
+
+      _units.add(
+        UnitReader._(
+          this,
+          resolutionDirectivesOffset,
+          resolutionDeclarationOffsets,
+          reference.getChild('@unit').getChild(unitUriStr),
+          isSynthetic,
+          partUriStr,
+          astReader,
+          headerOffset,
+          indexOffset,
+        ),
+      );
+    }
+
+    return _units;
+  }
+
+  @override
+  bool get withInformative {
+    _readName();
+    return _withInformative;
+  }
+
+  void _readName() {
+    if (_hasNameRead) return;
+    _hasNameRead = true;
+
+    var uriStr = reference.name;
+    var definingUnitBytes = _uriToUnitAstBytes[uriStr];
+    var reader = SummaryDataReader(definingUnitBytes);
+    reader.offset = definingUnitBytes.length - 4 * 2;
+    var libraryDataOffset = reader.readUint32();
+    var astStringsOffset = reader.readUint32();
+    reader.createStringTable(astStringsOffset);
+
+    reader.offset = libraryDataOffset;
+    _name = reader.readStringReference();
+    _nameOffset = reader.readUInt30() - 1;
+    _nameLength = reader.readUInt30();
+    _hasPartOfDirective = reader.readByte() != 0;
+    _withInformative = reader.readByte() != 0;
+  }
+}
+
+class LibraryReaderFromBundle extends LibraryReader {
+  final SummaryDataReader _astReader;
+  final Uint32List _astUnitOffsets;
+
+  @override
+  final String name;
+
+  @override
+  final int nameOffset;
+
+  @override
+  final int nameLength;
+
+  @override
+  final bool hasPartOfDirective;
+
+  @override
+  final bool withInformative;
+
+  LibraryReaderFromBundle._(
+    LinkedElementFactory elementFactory,
+    this.withInformative,
+    SummaryDataReader astReader,
+    SummaryDataReader resolutionReader,
+    _ReferenceReader referenceReader,
+    Reference reference,
+    this.name,
+    this.nameOffset,
+    this.nameLength,
+    this.hasPartOfDirective,
+    Uint32List astUnitOffsets,
+    Uint32List resolutionUnitOffsets,
+    Uint32List exportsIndexList,
+  )   : _astReader = astReader,
+        _astUnitOffsets = astUnitOffsets,
+        super._(
+          elementFactory,
+          resolutionReader,
+          referenceReader,
+          reference,
+          resolutionUnitOffsets,
+          exportsIndexList,
+        ) {
+    assert(_astUnitOffsets.length == _resolutionUnitOffsets.length);
+  }
+
+  @override
+  List<UnitReader> get units {
+    if (_units != null) return _units;
+    _units = [];
+
+    for (var i = 0; i < _astUnitOffsets.length; i++) {
+      var astUnitOffset = _astUnitOffsets[i];
+      var resolutionUnitOffset = _resolutionUnitOffsets[i];
+
+      _astReader.offset = astUnitOffset;
+      var headerOffset = _astReader.readUInt30();
+      var indexOffset = _astReader.offset;
+
+      _resolutionReader.offset = resolutionUnitOffset;
+      var unitUriStr = _resolutionReader.readStringReference();
+      var isSynthetic = _resolutionReader.readByte() != 0;
+      var isPart = _resolutionReader.readByte() != 0;
+      var partUriStr = _resolutionReader.readStringReference();
+      if (!isPart) {
+        partUriStr = null;
+      }
+      var resolutionDirectivesOffset = _resolutionReader.readUInt30();
+      var resolutionDeclarationOffsets = _resolutionReader.readUint30List();
+
+      _units.add(
+        UnitReader._(
+          this,
+          resolutionDirectivesOffset,
+          resolutionDeclarationOffsets,
+          reference.getChild('@unit').getChild(unitUriStr),
+          isSynthetic,
+          partUriStr,
+          _astReader,
+          headerOffset,
+          indexOffset,
+        ),
+      );
+    }
+
+    return _units;
+  }
+}
+
+class LinkedContext implements AstLinkedContext {
+  final UnitReader _unitReader;
+  final AstNode _node;
+  final int _resolutionIndex;
+  final Uint32List _codeOffsetLengthList;
+  final Uint32List _documentationTokenIndexList;
+
+  @override
+  final int codeOffset;
+
+  @override
+  final int codeLength;
+
+  @override
+  final bool isClassWithConstConstructor;
+
+  bool _isApplied = false;
+
+  bool _hasDocumentationComment = false;
+
+  _UnitMemberReader _reader;
+
+  LinkedContext(
+    this._unitReader,
+    this._node, {
+    @required this.codeOffset,
+    @required this.codeLength,
+    this.isClassWithConstConstructor = false,
+    Uint32List codeOffsetLengthList,
+    @required int resolutionIndex,
+    @required Uint32List documentationTokenIndexList,
+  })  : _resolutionIndex = resolutionIndex,
+        _codeOffsetLengthList = codeOffsetLengthList,
+        _documentationTokenIndexList = documentationTokenIndexList;
+
+  @override
+  List<ClassMember> get classMembers {
+    var reader = _reader;
+    if (reader is _ClassReader) {
+      return reader.classMembers;
+    } else if (_node is ClassTypeAlias) {
+      return const <ClassMember>[];
+    } else {
+      throw UnimplementedError();
+    }
+  }
+
+  @override
+  // TODO: implement unitDirectives
+  List<Directive> get unitDirectives => throw UnimplementedError();
+
+  @override
+  void applyResolution(LinkedUnitContext unitContext) {
+    if (_isApplied) {
+      return;
+    }
+    _isApplied = true;
+
+    // EnumConstantDeclaration has no separate resolution.
+    // Its metadata is resolved during EnumDeclaration resolution.
+    if (_resolutionIndex == -1) {
+      return;
+    }
+
+    var localElements = <Element>[];
+    var resolutionReader = LinkedResolutionReader(
+      _unitReader,
+      localElements,
+      _unitReader._resolutionDeclarationsOffset[_resolutionIndex],
+    );
+    _node.accept(
+      ApplyResolutionVisitor(
+        unitContext,
+        localElements,
+        resolutionReader,
+      ),
+    );
+  }
+
+  @override
+  int getVariableDeclarationCodeLength(VariableDeclaration node) {
+    var variableList = node.parent as VariableDeclarationList;
+    var variables = variableList.variables;
+    for (var i = 0; i < variables.length; i++) {
+      if (identical(variables[i], node)) {
+        return _codeOffsetLengthList[2 * i + 1];
+      }
+    }
+    throw StateError('No |$node| in: $variableList');
+  }
+
+  @override
+  int getVariableDeclarationCodeOffset(VariableDeclaration node) {
+    var variableList = node.parent as VariableDeclarationList;
+    var variables = variableList.variables;
+    for (var i = 0; i < variables.length; i++) {
+      if (identical(variables[i], node)) {
+        return _codeOffsetLengthList[2 * i + 0];
+      }
+    }
+    throw StateError('No |$node| in: $variableList');
+  }
+
+  @override
+  void readDocumentationComment() {
+    if (_hasDocumentationComment) {
+      return;
+    }
+    _hasDocumentationComment = true;
+
+    if (_documentationTokenIndexList.isEmpty) {
+      return;
+    }
+
+    var tokens = <Token>[];
+    for (var lexemeIndex in _documentationTokenIndexList) {
+      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
+      var token = TokenFactory.tokenFromString(lexeme);
+      tokens.add(token);
+    }
+
+    var comment = astFactory.documentationComment(tokens);
+    (_node as AnnotatedNodeImpl).documentationComment = comment;
+  }
+}
+
+/// Helper for reading elements and types from their binary encoding.
+class LinkedResolutionReader {
+  final UnitReader _unitReader;
+
+  /// The stack of [TypeParameterElement]s and [ParameterElement] that are
+  /// available in the scope of [nextElement] and [nextType].
+  ///
+  /// This stack is shared with the client of the reader, and update mostly
+  /// by the client. However it is also updated during [_readFunctionType].
+  final List<Element> _localElements;
+
+  /// The offset in [_Reader.bytes] from which we read resolution now.
+  int _byteOffset = 0;
+
+  LinkedResolutionReader(
+    this._unitReader,
+    this._localElements,
+    this._byteOffset,
+  );
+
+  Element nextElement() {
+    var memberFlags = readByte();
+    var element = _readRawElement();
+
+    if (memberFlags == Tag.RawElement) {
+      return element;
+    }
+
+    if (memberFlags == Tag.MemberLegacyWithTypeArguments ||
+        memberFlags == Tag.MemberWithTypeArguments) {
+      var arguments = _readTypeList();
+      // TODO(scheglov) why to check for empty? If we have this flags.
+      if (arguments.isNotEmpty) {
+        var typeParameters =
+            (element.enclosingElement as TypeParameterizedElement)
+                .typeParameters;
+        var substitution = Substitution.fromPairs(typeParameters, arguments);
+        element = ExecutableMember.from2(element, substitution);
+      }
+    }
+
+    if (memberFlags == Tag.MemberLegacyWithTypeArguments) {
+      return Member.legacy(element);
+    }
+
+    if (memberFlags == Tag.MemberWithTypeArguments) {
+      return element;
+    }
+
+    throw UnimplementedError('memberFlags: $memberFlags');
+  }
+
+  String nextString() {
+    var index = _readUInt30();
+    return _unitReader._resolutionReader.stringOfIndex(index);
+  }
+
+  DartType nextType() {
+    var tag = readByte();
+    if (tag == Tag.NullType) {
+      return null;
+    } else if (tag == Tag.DynamicType) {
+      return DynamicTypeImpl.instance;
+    } else if (tag == Tag.FunctionType) {
+      return _readFunctionType();
+    } else if (tag == Tag.InterfaceType) {
+      var element = nextElement();
+      var length = _readUInt30();
+      var typeArguments = List<DartType>.filled(length, null);
+      for (var i = 0; i < length; i++) {
+        typeArguments[i] = nextType();
+      }
+      var nullability = _readNullability();
+      return InterfaceTypeImpl(
+        element: element,
+        typeArguments: typeArguments,
+        nullabilitySuffix: nullability,
+      );
+    } else if (tag == Tag.InterfaceType_noTypeArguments_none) {
+      var element = nextElement();
+      return InterfaceTypeImpl(
+        element: element,
+        typeArguments: const <DartType>[],
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+    } else if (tag == Tag.InterfaceType_noTypeArguments_question) {
+      var element = nextElement();
+      return InterfaceTypeImpl(
+        element: element,
+        typeArguments: const <DartType>[],
+        nullabilitySuffix: NullabilitySuffix.question,
+      );
+    } else if (tag == Tag.InterfaceType_noTypeArguments_star) {
+      var element = nextElement();
+      return InterfaceTypeImpl(
+        element: element,
+        typeArguments: const <DartType>[],
+        nullabilitySuffix: NullabilitySuffix.star,
+      );
+    } else if (tag == Tag.NeverType) {
+      var nullability = _readNullability();
+      return NeverTypeImpl.instance.withNullability(nullability);
+    } else if (tag == Tag.TypeParameterType) {
+      var element = nextElement();
+      var nullability = _readNullability();
+      return TypeParameterTypeImpl(
+        element: element,
+        nullabilitySuffix: nullability,
+      );
+    } else if (tag == Tag.VoidType) {
+      return VoidTypeImpl.instance;
+    } else {
+      throw UnimplementedError('$tag');
+    }
+  }
+
+  int readByte() {
+    return _unitReader._resolutionReader.bytes[_byteOffset++];
+  }
+
+  List<String> readStringList() {
+    var values = <String>[];
+    var length = _readUInt30();
+    for (var i = 0; i < length; i++) {
+      var value = _readStringReference();
+      values.add(value);
+    }
+    return values;
+  }
+
+  int readUInt30() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  /// TODO(scheglov) Optimize for write/read of types without type parameters.
+  FunctionType _readFunctionType() {
+    var typeParameters = <TypeParameterElement>[];
+    var typeParametersLength = _readUInt30();
+    for (var i = 0; i < typeParametersLength; i++) {
+      var name = _readStringReference();
+      var element = TypeParameterElementImpl.synthetic(name);
+      typeParameters.add(element);
+      _localElements.add(element);
+    }
+    for (var i = 0; i < typeParametersLength; i++) {
+      var element = typeParameters[i] as TypeParameterElementImpl;
+      var bound = nextType();
+      element.bound = bound;
+    }
+
+    var typedefElement = nextElement();
+    var typeArguments = _readTypeList();
+
+    var returnType = nextType();
+
+    var formalParameters = <ParameterElement>[];
+    var formalParametersLength = _readUInt30();
+    for (var i = 0; i < formalParametersLength; i++) {
+      var kindIndex = readByte();
+      var type = nextType();
+      var name = nextString();
+      formalParameters.add(
+        ParameterElementImpl.synthetic(
+          name,
+          type,
+          _formalParameterKind(kindIndex),
+        ),
+      );
+    }
+
+    var nullability = _readNullability();
+
+    _localElements.length -= typeParametersLength;
+
+    return FunctionTypeImpl(
+      typeFormals: typeParameters,
+      parameters: formalParameters,
+      returnType: returnType,
+      nullabilitySuffix: nullability,
+      element: typedefElement,
+      typeArguments: typeArguments,
+    );
+  }
+
+  NullabilitySuffix _readNullability() {
+    var index = readByte();
+    return NullabilitySuffix.values[index];
+  }
+
+  Element _readRawElement() {
+    var index = _readUInt30();
+
+    if ((index & 0x1) == 0x1) {
+      return _localElements[index >> 1];
+    }
+
+    var referenceIndex = index >> 1;
+    var referenceReader = _unitReader._referenceReader;
+    var reference = referenceReader.referenceOfIndex(referenceIndex);
+
+    var elementFactory = _unitReader.elementFactory;
+    return elementFactory.elementOfReference(reference);
+  }
+
+  String _readStringReference() {
+    var index = _readUInt30();
+    return _unitReader._resolutionReader.stringOfIndex(index);
+  }
+
+  List<DartType> _readTypeList() {
+    var types = <DartType>[];
+    var length = _readUInt30();
+    for (var i = 0; i < length; i++) {
+      var argument = nextType();
+      types.add(argument);
+    }
+    return types;
+  }
+
+  int _readUInt30() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  static ParameterKind _formalParameterKind(int encoding) {
+    if (encoding == Tag.ParameterKindRequiredPositional) {
+      return ParameterKind.REQUIRED;
+    } else if (encoding == Tag.ParameterKindOptionalPositional) {
+      return ParameterKind.POSITIONAL;
+    } else if (encoding == Tag.ParameterKindRequiredNamed) {
+      return ParameterKind.NAMED_REQUIRED;
+    } else if (encoding == Tag.ParameterKindOptionalNamed) {
+      return ParameterKind.NAMED;
+    } else {
+      throw StateError('Unexpected parameter kind encoding: $encoding');
+    }
+  }
+}
+
+class SummaryDataForCompilationUnit {
+  final int codeLength;
+
+  SummaryDataForCompilationUnit(this.codeLength);
+}
+
+class SummaryDataForFormalParameter {
+  final int codeOffset;
+  final int codeLength;
+
+  SummaryDataForFormalParameter({
+    @required this.codeOffset,
+    @required this.codeLength,
+  });
+}
+
+class SummaryDataForLibraryDirective {
+  final UnitReader _unitReader;
+  final LibraryDirectiveImpl _node;
+  final Uint32List _documentationTokenIndexList;
+  bool _hasDocumentationComment = false;
+
+  SummaryDataForLibraryDirective(
+    this._unitReader,
+    this._node, {
+    @required Uint32List documentationTokenIndexList,
+  }) : _documentationTokenIndexList = documentationTokenIndexList {
+    _node.summaryData = this;
+  }
+
+  void readDocumentationComment() {
+    if (_hasDocumentationComment) {
+      return;
+    }
+    _hasDocumentationComment = true;
+
+    if (_documentationTokenIndexList.isEmpty) {
+      return;
+    }
+
+    var tokens = <Token>[];
+    for (var lexemeIndex in _documentationTokenIndexList) {
+      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
+      var token = TokenFactory.tokenFromString(lexeme);
+      tokens.add(token);
+    }
+
+    var comment = astFactory.documentationComment(tokens);
+    _node.documentationComment = comment;
+  }
+}
+
+class SummaryDataForTypeParameter {
+  final int codeOffset;
+  final int codeLength;
+
+  SummaryDataForTypeParameter({
+    @required this.codeOffset,
+    @required this.codeLength,
+  });
+}
+
+class UnitReader implements ReferenceNodeAccessor {
+  final LibraryReader libraryReader;
+
+  final Reference reference;
+
+  final bool isSynthetic;
+
+  /// If a part, the URI that is used in the [PartDirective].
+  /// Or `null` for the defining unit.
+  final String partUriStr;
+
+  final int _directivesResolutionOffset;
+  bool _isDirectivesResolutionApplied = false;
+
+  final Uint32List _resolutionDeclarationsOffset;
+
+  final SummaryDataReader astReader;
+
+  int _directivesOffset;
+  final List<_UnitMemberReader> _memberReaders = [];
+
+  CompilationUnitImpl _unit;
+  bool _hasDirectives = false;
+  bool _hasDeclarations = false;
+
+  UnitReader._(
+    this.libraryReader,
+    this._directivesResolutionOffset,
+    this._resolutionDeclarationsOffset,
+    this.reference,
+    this.isSynthetic,
+    this.partUriStr,
+    this.astReader,
+    int headerOffset,
+    int indexOffset,
+  ) {
+    reference.nodeAccessor = this;
+
+    astReader.offset = headerOffset;
+    var languageVersion = _readLanguageVersion();
+    var featureSetEncoded = astReader.readUint8List();
+    var lineInfo = _readLineInfo();
+    var codeLength = astReader.readUInt30();
+    var featureSet = ExperimentStatus.fromStorage(featureSetEncoded);
+    _directivesOffset = astReader.offset;
+
+    _unit = astFactory.compilationUnit(
+      beginToken: null,
+      // TODO(scheglov)
+      // scriptTag: _readNode(data.compilationUnit_scriptTag),
+      directives: [],
+      declarations: [],
+      endToken: null,
+      featureSet: featureSet,
+    );
+    _unit.languageVersion = languageVersion;
+    _unit.lineInfo = lineInfo;
+    _unit.summaryData = SummaryDataForCompilationUnit(codeLength);
+
+    astReader.offset = indexOffset;
+    _readIndex2();
+  }
+
+  LinkedElementFactory get elementFactory => libraryReader._elementFactory;
+
+  /// TODO(scheglov)
+  /// This methods breaks lazy loading, and loads everything eagerly.
+  /// We use it because of `unitElement.types` for example, when we are
+  /// explicitly asked for all [ClassDeclaration]s and [ClassTypeAlias]s.
+  @Deprecated('review it')
+  @override
+  CompilationUnit get node {
+    readDirectives();
+    readDeclarations();
+    return _unit;
+  }
+
+  CompilationUnit get unit => _unit;
+
+  String get uriStr => reference.name;
+
+  bool get withInformative => libraryReader.withInformative;
+
+  _ReferenceReader get _referenceReader => libraryReader._referenceReader;
+
+  SummaryDataReader get _resolutionReader => libraryReader._resolutionReader;
+
+  /// Apply resolution to directives.
+  void applyDirectivesResolution(LinkedUnitContext unitContext) {
+    if (_isDirectivesResolutionApplied) {
+      return;
+    }
+    _isDirectivesResolutionApplied = true;
+
+    var localElements = <Element>[];
+    var resolutionReader = LinkedResolutionReader(
+      this,
+      localElements,
+      _directivesResolutionOffset,
+    );
+    for (var directive in _unit.directives) {
+      directive.accept(
+        ApplyResolutionVisitor(
+          unitContext,
+          localElements,
+          resolutionReader,
+        ),
+      );
+    }
+  }
+
+  void readDeclarations() {
+    if (!_hasDeclarations) {
+      _hasDeclarations = true;
+      for (var reader in _memberReaders) {
+        reader.node;
+      }
+    }
+  }
+
+  /// Ensure that directives are read in this unit.
+  void readDirectives() {
+    if (!_hasDirectives) {
+      _hasDirectives = true;
+      astReader.offset = _directivesOffset;
+      var length = astReader.readUInt30();
+      for (var i = 0; i < length; i++) {
+        var astReader = AstBinaryReader(
+          reader: this,
+        );
+        var directive = astReader.readNode() as Directive;
+        _unit.directives.add(directive);
+      }
+    }
+  }
+
+  @override
+  void readIndex() {}
+
+  /// Read the index of declarations in this unit, and add `null`s into
+  /// [CompilationUnit.declarations] as placeholders.
+  ///
+  /// TODO(scheglov) we don't need both this method, and [readIndex].
+  void _readIndex2() {
+    var unitReference = reference;
+    var length = astReader.readUInt30();
+    for (var i = 0; i < length; i++) {
+      var offset = astReader.readUInt30();
+      var tag = astReader.readByte();
+      if (tag == Tag.Class) {
+        var name = astReader.readStringReference();
+        var indexOffset = astReader.readUInt30();
+        var reference = unitReference.getChild('@class').getChild(name);
+        _memberReaders.add(
+          _ClassReader(
+            unitReader: this,
+            reference: reference,
+            offset: offset,
+            unit: _unit,
+            indexOffset: indexOffset,
+          ),
+        );
+      } else if (tag == Tag.ClassTypeAlias) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@class').getChild(name).nodeAccessor = reader;
+      } else if (tag == Tag.EnumDeclaration) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@enum').getChild(name).nodeAccessor = reader;
+      } else if (tag == Tag.ExtensionDeclaration) {
+        var name = astReader.readStringReference();
+        var indexOffset = astReader.readUInt30();
+        var reference = unitReference.getChild('@extension').getChild(name);
+        _memberReaders.add(
+          _ClassReader(
+            unitReader: this,
+            reference: reference,
+            offset: offset,
+            unit: _unit,
+            indexOffset: indexOffset,
+          ),
+        );
+      } else if (tag == Tag.FunctionDeclaration) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        var containerRef = unitReference.getChild('@function');
+        containerRef.getChild(name).nodeAccessor = reader;
+      } else if (tag == Tag.FunctionDeclaration_getter) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        var getterRef = unitReference.getChild('@getter');
+        getterRef.getChild(name).nodeAccessor = reader;
+        var variableRef = unitReference.getChild('@variable');
+        variableRef.getChild(name).nodeAccessor ??= reader;
+      } else if (tag == Tag.FunctionDeclaration_setter) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        var setterRef = unitReference.getChild('@setter');
+        setterRef.getChild(name).nodeAccessor = reader;
+        var variableRef = unitReference.getChild('@variable');
+        variableRef.getChild(name).nodeAccessor ??= reader;
+      } else if (tag == Tag.GenericTypeAlias) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
+            reader;
+      } else if (tag == Tag.FunctionTypeAlias) {
+        var name = astReader.readStringReference();
+        var reader = _UnitMemberReader(this, offset, _unit);
+        _memberReaders.add(reader);
+        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
+            reader;
+      } else if (tag == Tag.MixinDeclaration) {
+        var name = astReader.readStringReference();
+        var indexOffset = astReader.readUInt30();
+        var reference = unitReference.getChild('@mixin').getChild(name);
+        _memberReaders.add(
+          _ClassReader(
+            unitReader: this,
+            reference: reference,
+            offset: offset,
+            unit: _unit,
+            indexOffset: indexOffset,
+          ),
+        );
+      } else if (tag == Tag.TopLevelVariableDeclaration) {
+        var reader = _UnitMemberReader(this, offset, _unit);
+        var length = astReader.readUInt30();
+        for (var i = 0; i < length; i++) {
+          var name = astReader.readStringReference();
+          _memberReaders.add(reader);
+          unitReference.getChild('@getter').getChild(name).nodeAccessor =
+              reader;
+          // TODO(scheglov) only if not final/const
+          // Crash in language_2/export/local_export_test.dart
+          unitReference.getChild('@setter').getChild(name).nodeAccessor =
+              reader;
+        }
+      } else {
+        // TODO(scheglov) implement
+      }
+    }
+  }
+
+  LibraryLanguageVersion _readLanguageVersion() {
+    var packageMajor = astReader.readUInt30();
+    var packageMinor = astReader.readUInt30();
+    var overrideMajor = astReader.readUInt30();
+    var overrideMinor = astReader.readUInt30();
+    return LibraryLanguageVersion(
+      package: Version(packageMajor, packageMinor, 0),
+      override: overrideMajor > 0
+          ? Version(overrideMajor - 1, overrideMinor - 1, 0)
+          : null,
+    );
+  }
+
+  LineInfo _readLineInfo() {
+    var lineStarts = astReader.readUint30List();
+    return LineInfo(lineStarts);
+  }
+}
+
+class _ClassMemberReader implements ReferenceNodeAccessor {
+  final UnitReader unitReader;
+  final int offset;
+  final NodeListImpl<ClassMember> _members;
+  final int _membersIndex;
+  ClassMemberImpl _node;
+
+  _ClassMemberReader(this.unitReader, this.offset, this._members)
+      : _membersIndex = _members.length {
+    _members.add(null);
+  }
+
+  @override
+  AstNode get node {
+    if (_node == null) {
+      var astReader = AstBinaryReader(
+        reader: unitReader,
+      );
+      unitReader.astReader.offset = offset;
+      _node = astReader.readNode() as ClassMemberImpl;
+      _members[_membersIndex] = _node;
+    }
+    return _node;
+  }
+
+  @override
+  void readIndex() {}
+}
+
+class _ClassReader extends _UnitMemberReader {
+  final Reference reference;
+  final int indexOffset;
+
+  bool _hasIndex = false;
+  final List<_ClassMemberReader> _classMemberReaders = [];
+  List<ClassMember> _classMembers;
+
+  _ClassReader({
+    @required this.reference,
+    @required UnitReader unitReader,
+    @required int offset,
+    @required CompilationUnit unit,
+    @required this.indexOffset,
+  }) : super(unitReader, offset, unit) {
+    reference.nodeAccessor ??= this;
+  }
+
+  List<_ClassMemberReader> get classMemberReaders {
+    readIndex();
+    return _classMemberReaders;
+  }
+
+  List<ClassMember> get classMembers {
+    return classMemberReaders.map((e) => e.node as ClassMember).toList();
+  }
+
+  @override
+  void readIndex() {
+    if (_hasIndex) return;
+    _hasIndex = true;
+
+    var node = _node;
+    if (node == null) {
+      throw StateError('The class node must be read before reading members.');
+    }
+
+    if (node is ClassDeclarationImpl) {
+      _classMembers = node.members;
+    } else if (node is ExtensionDeclarationImpl) {
+      _classMembers = node.members;
+    } else if (node is MixinDeclarationImpl) {
+      _classMembers = node.members;
+    } else {
+      throw StateError('(${node.runtimeType}) $node');
+    }
+
+    unitReader.astReader.offset = indexOffset;
+
+    var length = unitReader.astReader.readUInt30();
+    for (var i = 0; i < length; i++) {
+      var offset = unitReader.astReader.readUInt30();
+      var tag = unitReader.astReader.readByte();
+      if (tag == Tag.ConstructorDeclaration) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@constructor').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.MethodDeclaration) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@method').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.MethodDeclaration_getter) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@getter').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.MethodDeclaration_setter) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var name = unitReader.astReader.readStringReference();
+        var reference = this.reference.getChild('@setter').getChild(name);
+        reference.nodeAccessor ??= reader;
+      } else if (tag == Tag.FieldDeclaration) {
+        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+        _classMemberReaders.add(reader);
+        var length = unitReader.astReader.readUInt30();
+        for (var i = 0; i < length; i++) {
+          var name = unitReader.astReader.readStringReference();
+          var fieldRef = reference.getChild('@field').getChild(name);
+          fieldRef.nodeAccessor ??= reader;
+          var getterRef = reference.getChild('@getter').getChild(name);
+          getterRef.nodeAccessor ??= reader;
+          var setterRef = reference.getChild('@setter').getChild(name);
+          setterRef.nodeAccessor ??= reader;
+        }
+      } else {
+        throw UnimplementedError('tag: $tag');
+      }
+    }
+  }
+}
+
+class _ReferenceReader {
+  final LinkedElementFactory elementFactory;
+  final SummaryDataReader _reader;
+  Uint32List _parents;
+  Uint32List _names;
+  List<Reference> _references;
+
+  _ReferenceReader(this.elementFactory, this._reader, int offset) {
+    _reader.offset = offset;
+    _parents = _reader.readUint30List();
+    _names = _reader.readUint30List();
+    assert(_parents.length == _names.length);
+
+    _references = List.filled(_names.length, null);
+  }
+
+  Reference referenceOfIndex(int index) {
+    var reference = _references[index];
+    if (reference != null) {
+      return reference;
+    }
+
+    if (index == 0) {
+      reference = elementFactory.rootReference;
+      _references[index] = reference;
+      return reference;
+    }
+
+    var nameIndex = _names[index];
+    var name = _reader.stringOfIndex(nameIndex);
+
+    var parentIndex = _parents[index];
+    var parent = referenceOfIndex(parentIndex);
+
+    reference = parent.getChild(name);
+    _references[index] = reference;
+
+    return reference;
+  }
+}
+
+class _UnitMemberReader implements ReferenceNodeAccessor {
+  final UnitReader unitReader;
+  final int offset;
+  final CompilationUnit _unit;
+  final int _index;
+  CompilationUnitMemberImpl _node;
+
+  _UnitMemberReader(this.unitReader, this.offset, this._unit)
+      : _index = _unit.declarations.length {
+    _unit.declarations.add(null);
+  }
+
+  @override
+  AstNode get node {
+    if (_node == null) {
+      var astReader = AstBinaryReader(
+        reader: unitReader,
+      );
+      unitReader.astReader.offset = offset;
+      _node = astReader.readNode() as CompilationUnitMember;
+      _unit.declarations[_index] = _node;
+
+      var hasLinkedContext = _node as HasAstLinkedContext;
+      var linkedContext = hasLinkedContext.linkedContext as LinkedContext;
+      linkedContext._reader = this;
+    }
+    return _node;
+  }
+
+  @override
+  void readIndex() {}
+}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
new file mode 100644
index 0000000..a21430d
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -0,0 +1,819 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+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/member.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/ast_binary_writer.dart';
+import 'package:analyzer/src/summary2/binary_format_doc.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
+
+Uint8List writeUnitToBytes({@required CompilationUnit unit}) {
+  var byteSink = ByteSink();
+  var sink = BufferedSink(byteSink);
+  var stringIndexer = StringIndexer();
+
+  var headerOffset = sink.offset;
+  var nextResolutionIndex = 0;
+  var unitWriter = AstBinaryWriter(
+    withInformative: true,
+    sink: sink,
+    stringIndexer: stringIndexer,
+    getNextResolutionIndex: () => nextResolutionIndex++,
+    resolutionSink: null,
+  );
+  unit.accept(unitWriter);
+
+  void _writeStringReference(String string) {
+    var index = stringIndexer[string];
+    sink.writeUInt30(index);
+  }
+
+  var indexOffset = sink.offset;
+  sink.writeUInt30(unitWriter.unitMemberIndexItems.length);
+  for (var declaration in unitWriter.unitMemberIndexItems) {
+    sink.writeUInt30(declaration.offset);
+    sink.writeByte(declaration.tag);
+    if (declaration.name != null) {
+      _writeStringReference(declaration.name);
+    } else {
+      sink.writeList(declaration.variableNames, _writeStringReference);
+    }
+    if (declaration.classIndexOffset != 0) {
+      sink.writeUInt30(declaration.classIndexOffset);
+    }
+  }
+
+  var libraryDataOffset = sink.offset;
+  {
+    var name = '';
+    var nameOffset = -1;
+    var nameLength = 0;
+    for (var directive in unit.directives) {
+      if (directive is LibraryDirective) {
+        name = directive.name.components.map((e) => e.name).join('.');
+        nameOffset = directive.name.offset;
+        nameLength = directive.name.length;
+        break;
+      }
+    }
+
+    var hasPartOfDirective = false;
+    for (var directive in unit.directives) {
+      if (directive is PartOfDirective) {
+        hasPartOfDirective = true;
+        break;
+      }
+    }
+    _writeStringReference(name);
+    sink.writeUInt30(nameOffset + 1);
+    sink.writeUInt30(nameLength);
+    sink.writeByte(hasPartOfDirective ? 1 : 0);
+    sink.writeByte(1); // withInformative
+  }
+
+  var stringTableOffset = stringIndexer.write(sink);
+
+  sink.writeUInt32(headerOffset);
+  sink.writeUInt32(indexOffset);
+  sink.writeUInt32(libraryDataOffset);
+  sink.writeUInt32(stringTableOffset);
+
+  sink.flushAndDestroy();
+  return byteSink.builder.takeBytes();
+}
+
+class BundleWriter {
+  final bool withInformative;
+  BundleWriterAst _astWriter;
+  BundleWriterResolution _resolutionWriter;
+
+  BundleWriter(this.withInformative, Reference dynamicReference) {
+    _astWriter = BundleWriterAst(withInformative);
+    _resolutionWriter = BundleWriterResolution(dynamicReference);
+  }
+
+  void addLibraryAst(LibraryToWriteAst library) {
+    var astUnitOffsets = <int>[];
+    for (var unit in library.units) {
+      var offset = _astWriter.writeUnit(unit.node);
+      astUnitOffsets.add(offset);
+    }
+    _astWriter.writeLibrary(library.units[0].node, astUnitOffsets);
+  }
+
+  void addLibraryResolution(LibraryToWriteResolution library) {
+    var resolutionLibrary = _resolutionWriter.enterLibrary(library);
+    for (var unit in library.units) {
+      var resolutionUnit = resolutionLibrary.enterUnit(unit);
+      // TODO(scheglov) Is it better to have a throwaway Object, or null?
+      var notUsedSink = BufferedSink(ByteSink());
+      var notUsedStringIndexer = StringIndexer();
+      var unitWriter = AstBinaryWriter(
+        withInformative: withInformative,
+        sink: notUsedSink,
+        stringIndexer: notUsedStringIndexer,
+        getNextResolutionIndex: resolutionUnit.enterDeclaration,
+        resolutionSink: resolutionUnit.library.sink,
+      );
+      unit.node.accept(unitWriter);
+    }
+  }
+
+  BundleWriterResult finish() {
+    var astBytes = _astWriter.finish();
+    var resolutionBytes = _resolutionWriter.finish();
+    return BundleWriterResult(
+      astBytes: astBytes,
+      resolutionBytes: resolutionBytes,
+    );
+  }
+}
+
+class BundleWriterAst {
+  final bool withInformative;
+  final ByteSink _byteSink = ByteSink();
+  BufferedSink sink;
+  final StringIndexer stringIndexer = StringIndexer();
+
+  final List<int> _libraryOffsets = [];
+
+  BundleWriterAst(this.withInformative) {
+    sink = BufferedSink(_byteSink);
+    sink.writeByte(withInformative ? 1 : 0);
+  }
+
+  Uint8List finish() {
+    var librariesOffset = sink.offset;
+    sink.writeUint30List(_libraryOffsets);
+
+    var stringTableOffset = stringIndexer.write(sink);
+
+    sink.writeUInt32(librariesOffset);
+    sink.writeUInt32(stringTableOffset);
+
+    sink.flushAndDestroy();
+    return _byteSink.builder.takeBytes();
+  }
+
+  /// Write the library name and offset, and pointers to [unitOffsets].
+  void writeLibrary(CompilationUnit definingUnit, List<int> unitOffsets) {
+    _libraryOffsets.add(sink.offset);
+
+    var name = '';
+    var nameOffset = -1;
+    var nameLength = 0;
+    for (var directive in definingUnit.directives) {
+      if (directive is LibraryDirective) {
+        name = directive.name.components.map((e) => e.name).join('.');
+        nameOffset = directive.name.offset;
+        nameLength = directive.name.length;
+        break;
+      }
+    }
+
+    var hasPartOfDirective = false;
+    for (var directive in definingUnit.directives) {
+      if (directive is PartOfDirective) {
+        hasPartOfDirective = true;
+        break;
+      }
+    }
+
+    _writeStringReference(name);
+    sink.writeUInt30(1 + nameOffset);
+    sink.writeUInt30(nameLength);
+    sink.writeByte(hasPartOfDirective ? 1 : 0);
+    sink.writeUint30List(unitOffsets);
+  }
+
+  /// Write the [node] into the [sink].
+  ///
+  /// Return the pointer at [AstUnitFormat.headerOffset].
+  int writeUnit(CompilationUnit node) {
+    var headerOffset = sink.offset;
+
+    var nextResolutionIndex = 0;
+    var unitWriter = AstBinaryWriter(
+      withInformative: withInformative,
+      sink: sink,
+      stringIndexer: stringIndexer,
+      getNextResolutionIndex: () => nextResolutionIndex++,
+      resolutionSink: null,
+    );
+    node.accept(unitWriter);
+
+    var indexOffset = sink.offset;
+    sink.writeUInt30(headerOffset);
+
+    sink.writeUInt30(unitWriter.unitMemberIndexItems.length);
+    for (var declaration in unitWriter.unitMemberIndexItems) {
+      sink.writeUInt30(declaration.offset);
+      sink.writeByte(declaration.tag);
+      if (declaration.name != null) {
+        _writeStringReference(declaration.name);
+      } else {
+        sink.writeList(declaration.variableNames, _writeStringReference);
+      }
+      if (declaration.classIndexOffset != 0) {
+        sink.writeUInt30(declaration.classIndexOffset);
+      }
+    }
+
+    return indexOffset;
+  }
+
+  void _writeStringReference(String string) {
+    var index = stringIndexer[string];
+    sink.writeUInt30(index);
+  }
+}
+
+class BundleWriterResolution {
+  _BundleWriterReferences _references;
+  final ByteSink _byteSink = ByteSink();
+  BufferedSink _sink;
+  ResolutionSink _resolutionSink;
+
+  final StringIndexer _stringIndexer = StringIndexer();
+
+  final List<_ResolutionLibrary> _libraries = [];
+
+  BundleWriterResolution(Reference dynamicReference) {
+    _references = _BundleWriterReferences(dynamicReference);
+
+    _sink = BufferedSink(_byteSink);
+    _resolutionSink = ResolutionSink(
+      stringIndexer: _stringIndexer,
+      sink: _sink,
+      references: _references,
+    );
+  }
+
+  _ResolutionLibrary enterLibrary(LibraryToWriteResolution libraryToWrite) {
+    var library = _ResolutionLibrary(
+      sink: _resolutionSink,
+      library: libraryToWrite,
+    );
+    _libraries.add(library);
+    return library;
+  }
+
+  Uint8List finish() {
+    var libraryOffsets = <int>[];
+    for (var library in _libraries) {
+      var unitOffsets = <int>[];
+      for (var unit in library.units) {
+        unitOffsets.add(_sink.offset);
+        _writeStringReference(unit.unit.uriStr);
+        _sink.writeByte(unit.unit.isSynthetic ? 1 : 0);
+        _sink.writeByte(unit.unit.partUriStr != null ? 1 : 0);
+        _writeStringReference(unit.unit.partUriStr ?? '');
+        _sink.writeUInt30(unit.directivesOffset);
+        _sink.writeUint30List(unit.offsets);
+      }
+      libraryOffsets.add(_sink.offset);
+      _writeStringReference(library.library.uriStr);
+      _sink.writeUint30List(unitOffsets);
+      _writeReferences(library.library.exports);
+    }
+
+    _references._clearIndexes();
+
+    var librariesOffset = _sink.offset;
+    _sink.writeUint30List(libraryOffsets);
+
+    var referencesOffset = _sink.offset;
+    _sink.writeUint30List(_references._referenceParents);
+    _writeStringList(_references._referenceNames);
+
+    var stringTableOffset = _stringIndexer.write(_sink);
+
+    // Write as Uint32 so that we know where it is.
+    _sink.writeUInt32(librariesOffset);
+    _sink.writeUInt32(referencesOffset);
+    _sink.writeUInt32(stringTableOffset);
+
+    _sink.flushAndDestroy();
+    return _byteSink.builder.takeBytes();
+  }
+
+  void _writeReferences(List<Reference> references) {
+    var length = references.length;
+    _sink.writeUInt30(length);
+
+    for (var reference in references) {
+      var index = _references._indexOfReference(reference);
+      _sink.writeUInt30(index);
+    }
+  }
+
+  void _writeStringList(List<String> values) {
+    _sink.writeUInt30(values.length);
+    for (var value in values) {
+      _writeStringReference(value);
+    }
+  }
+
+  void _writeStringReference(String string) {
+    var index = _stringIndexer[string];
+    _sink.writeUInt30(index);
+  }
+}
+
+class BundleWriterResult {
+  final Uint8List astBytes;
+  final Uint8List resolutionBytes;
+
+  BundleWriterResult({
+    @required this.astBytes,
+    @required this.resolutionBytes,
+  });
+}
+
+class LibraryToWriteAst {
+  final List<UnitToWriteAst> units;
+
+  LibraryToWriteAst({
+    @required this.units,
+  });
+}
+
+class LibraryToWriteResolution {
+  final String uriStr;
+  final List<Reference> exports;
+  final List<UnitToWriteResolution> units;
+
+  LibraryToWriteResolution({
+    @required this.uriStr,
+    @required this.exports,
+    @required this.units,
+  });
+}
+
+class ResolutionSink {
+  final StringIndexer _stringIndexer;
+  final BufferedSink _sink;
+  final _BundleWriterReferences _references2;
+  final _LocalElementIndexer localElements = _LocalElementIndexer();
+
+  ResolutionSink({
+    @required StringIndexer stringIndexer,
+    @required BufferedSink sink,
+    @required _BundleWriterReferences references,
+  })  : _stringIndexer = stringIndexer,
+        _sink = sink,
+        _references2 = references;
+
+  int get offset => _sink.offset;
+
+  void writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
+    _sink.addByte(byte);
+  }
+
+  /// TODO(scheglov) Triage places where we write elements.
+  /// Some of then cannot be members, e.g. type names.
+  void writeElement(Element element) {
+    if (element is Member) {
+      var declaration = element.declaration;
+      var isLegacy = element.isLegacy;
+
+      var typeArguments = _enclosingClassTypeArguments(
+        declaration,
+        element.substitution.map,
+      );
+
+      writeByte(
+        isLegacy
+            ? Tag.MemberLegacyWithTypeArguments
+            : Tag.MemberWithTypeArguments,
+      );
+
+      writeElement0(declaration);
+      _writeTypeList(typeArguments);
+    } else {
+      writeByte(Tag.RawElement);
+      writeElement0(element);
+    }
+  }
+
+  void writeElement0(Element element) {
+    assert(element is! Member, 'Use writeMemberOrElement()');
+    var elementIndex = _indexOfElement(element);
+    _sink.writeUInt30(elementIndex);
+  }
+
+  void writeStringList(List<String> values) {
+    _sink.writeUInt30(values.length);
+    for (var value in values) {
+      _writeStringReference(value);
+    }
+  }
+
+  void writeType(DartType type) {
+    if (type == null) {
+      writeByte(Tag.NullType);
+    } else if (type is DynamicType) {
+      writeByte(Tag.DynamicType);
+    } else if (type is FunctionType) {
+      _writeFunctionType(type);
+    } else if (type is InterfaceType) {
+      var typeArguments = type.typeArguments;
+      var nullabilitySuffix = type.nullabilitySuffix;
+      if (typeArguments.isEmpty) {
+        if (nullabilitySuffix == NullabilitySuffix.none) {
+          writeByte(Tag.InterfaceType_noTypeArguments_none);
+        } else if (nullabilitySuffix == NullabilitySuffix.question) {
+          writeByte(Tag.InterfaceType_noTypeArguments_question);
+        } else if (nullabilitySuffix == NullabilitySuffix.star) {
+          writeByte(Tag.InterfaceType_noTypeArguments_star);
+        }
+        // TODO(scheglov) Write raw
+        writeElement(type.element);
+      } else {
+        writeByte(Tag.InterfaceType);
+        // TODO(scheglov) Write raw
+        writeElement(type.element);
+        _sink.writeUInt30(typeArguments.length);
+        for (var i = 0; i < typeArguments.length; ++i) {
+          writeType(typeArguments[i]);
+        }
+        _writeNullabilitySuffix(nullabilitySuffix);
+      }
+    } else if (type is NeverType) {
+      writeByte(Tag.NeverType);
+      _writeNullabilitySuffix(type.nullabilitySuffix);
+    } else if (type is TypeParameterType) {
+      writeByte(Tag.TypeParameterType);
+      writeElement(type.element);
+      _writeNullabilitySuffix(type.nullabilitySuffix);
+    } else if (type is VoidType) {
+      writeByte(Tag.VoidType);
+    } else {
+      // TODO
+      throw UnimplementedError('${type.runtimeType}');
+    }
+  }
+
+  int _indexOfElement(Element element) {
+    if (element == null) return 0;
+    if (element is MultiplyDefinedElement) return 0;
+    assert(element is! Member);
+
+    // Positional parameters cannot be referenced outside of their scope,
+    // so don't have a reference, so are stored as local elements.
+    if (element is ParameterElementImpl && element.reference == null) {
+      return localElements[element] << 1 | 0x1;
+    }
+
+    // Type parameters cannot be referenced outside of their scope,
+    // so don't have a reference, so are stored as local elements.
+    if (element is TypeParameterElement) {
+      return localElements[element] << 1 | 0x1;
+    }
+
+    if (identical(element, DynamicElementImpl.instance)) {
+      return _references2._indexOfReference(_references2.dynamicReference) << 1;
+    }
+
+    var reference = (element as ElementImpl).reference;
+    return _references2._indexOfReference(reference) << 1;
+  }
+
+  void _writeFormalParameterKind(ParameterElement p) {
+    if (p.isRequiredPositional) {
+      writeByte(Tag.ParameterKindRequiredPositional);
+    } else if (p.isOptionalPositional) {
+      writeByte(Tag.ParameterKindOptionalPositional);
+    } else if (p.isRequiredNamed) {
+      writeByte(Tag.ParameterKindRequiredNamed);
+    } else if (p.isOptionalNamed) {
+      writeByte(Tag.ParameterKindOptionalNamed);
+    } else {
+      throw StateError('Unexpected parameter kind: $p');
+    }
+  }
+
+  void _writeFunctionType(FunctionType type) {
+    type = _toSyntheticFunctionType(type);
+
+    writeByte(Tag.FunctionType);
+
+    localElements.pushScope();
+
+    var typeParameters = type.typeFormals;
+    for (var typeParameter in type.typeFormals) {
+      localElements.declare(typeParameter);
+    }
+
+    _sink.writeUInt30(typeParameters.length);
+    for (var typeParameter in type.typeFormals) {
+      _writeStringReference(typeParameter.name);
+    }
+    for (var typeParameter in type.typeFormals) {
+      writeType(typeParameter.bound);
+    }
+
+    Element typedefElement;
+    List<DartType> typedefTypeArguments = const <DartType>[];
+    if (type.element is FunctionTypeAliasElement) {
+      typedefElement = type.element;
+      typedefTypeArguments = type.typeArguments;
+    }
+    // TODO(scheglov) Cleanup to always use FunctionTypeAliasElement.
+    if (type.element is GenericFunctionTypeElement &&
+        type.element.enclosingElement is FunctionTypeAliasElement) {
+      typedefElement = type.element.enclosingElement;
+      typedefTypeArguments = type.typeArguments;
+    }
+
+    writeElement(typedefElement);
+    _writeTypeList(typedefTypeArguments);
+
+    writeType(type.returnType);
+
+    var parameters = type.parameters;
+    _sink.writeUInt30(parameters.length);
+    for (var parameter in parameters) {
+      _writeFormalParameterKind(parameter);
+      assert(parameter.type != null);
+      writeType(parameter.type);
+      // TODO(scheglov) Don't write names of positional parameters
+      _writeStringReference(parameter.name);
+    }
+
+    _writeNullabilitySuffix(type.nullabilitySuffix);
+
+    localElements.popScope();
+  }
+
+  void _writeNullabilitySuffix(NullabilitySuffix suffix) {
+    writeByte(suffix.index);
+  }
+
+  void _writeStringReference(String string) {
+    var index = _stringIndexer[string];
+    _sink.writeUInt30(index);
+  }
+
+  void _writeTypeList(List<DartType> types) {
+    _sink.writeUInt30(types.length);
+    for (var type in types) {
+      writeType(type);
+    }
+  }
+
+  static List<DartType> _enclosingClassTypeArguments(
+    Element declaration,
+    Map<TypeParameterElement, DartType> substitution,
+  ) {
+    var enclosing = declaration.enclosingElement;
+    if (enclosing is TypeParameterizedElement) {
+      if (enclosing is! ClassElement && enclosing is! ExtensionElement) {
+        return const <DartType>[];
+      }
+
+      var typeParameters = enclosing.typeParameters;
+      if (typeParameters.isEmpty) {
+        return const <DartType>[];
+      }
+
+      return typeParameters
+          .map((typeParameter) => substitution[typeParameter])
+          .toList(growable: false);
+    }
+
+    return const <DartType>[];
+  }
+
+  static FunctionType _toSyntheticFunctionType(FunctionType type) {
+    var typeParameters = type.typeFormals;
+
+    if (typeParameters.isEmpty) return type;
+
+    var onlySyntheticTypeParameters = typeParameters.every((e) {
+      return e is TypeParameterElementImpl && e.linkedNode == null;
+    });
+    if (onlySyntheticTypeParameters) return type;
+
+    var parameters = getFreshTypeParameters(typeParameters);
+    return parameters.applyToFunctionType(type);
+  }
+}
+
+class ResolutionUnit {
+  final _ResolutionLibrary library;
+  final UnitToWriteResolution unit;
+
+  /// The offset of the resolution data for directives.
+  final int directivesOffset;
+
+  /// The offsets of resolution data for each declaration - class, method, etc.
+  final List<int> offsets = [];
+
+  ResolutionUnit({
+    @required this.library,
+    @required this.unit,
+    @required this.directivesOffset,
+  });
+
+  /// Should be called on enter into a new declaration on which level
+  /// resolution is stored, e.g. [ClassDeclaration] (header), or
+  /// [MethodDeclaration] (header), or [FieldDeclaration] (all).
+  int enterDeclaration() {
+    var index = offsets.length;
+    offsets.add(library.sink.offset);
+    return index;
+  }
+}
+
+class StringIndexer {
+  final Map<String, int> _index = {};
+
+  int operator [](String string) {
+    var result = _index[string];
+
+    if (result == null) {
+      result = _index.length;
+      _index[string] = result;
+    }
+
+    return result;
+  }
+
+  int write(BufferedSink sink) {
+    var bytesOffset = sink.offset;
+
+    var length = _index.length;
+    var lengths = Uint32List(length);
+    var lengthsIndex = 0;
+    for (var key in _index.keys) {
+      var stringStart = sink.offset;
+      _writeWtf8(sink, key);
+      lengths[lengthsIndex++] = sink.offset - stringStart;
+    }
+
+    var resultOffset = sink.offset;
+
+    var lengthOfBytes = sink.offset - bytesOffset;
+    sink.writeUInt30(lengthOfBytes);
+    sink.writeUint30List(lengths);
+
+    return resultOffset;
+  }
+
+  /// Write [source] string into [sink].
+  static void _writeWtf8(BufferedSink sink, String source) {
+    var end = source.length;
+    if (end == 0) {
+      return;
+    }
+
+    int i = 0;
+    do {
+      var codeUnit = source.codeUnitAt(i++);
+      if (codeUnit < 128) {
+        // ASCII.
+        sink.addByte(codeUnit);
+      } else if (codeUnit < 0x800) {
+        // Two-byte sequence (11-bit unicode value).
+        sink.addByte(0xC0 | (codeUnit >> 6));
+        sink.addByte(0x80 | (codeUnit & 0x3f));
+      } else if ((codeUnit & 0xFC00) == 0xD800 &&
+          i < end &&
+          (source.codeUnitAt(i) & 0xFC00) == 0xDC00) {
+        // Surrogate pair -> four-byte sequence (non-BMP unicode value).
+        int codeUnit2 = source.codeUnitAt(i++);
+        int unicode =
+            0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF);
+        sink.addByte(0xF0 | (unicode >> 18));
+        sink.addByte(0x80 | ((unicode >> 12) & 0x3F));
+        sink.addByte(0x80 | ((unicode >> 6) & 0x3F));
+        sink.addByte(0x80 | (unicode & 0x3F));
+      } else {
+        // Three-byte sequence (16-bit unicode value), including lone
+        // surrogates.
+        sink.addByte(0xE0 | (codeUnit >> 12));
+        sink.addByte(0x80 | ((codeUnit >> 6) & 0x3f));
+        sink.addByte(0x80 | (codeUnit & 0x3f));
+      }
+    } while (i < end);
+  }
+}
+
+class UnitToWriteAst {
+  final CompilationUnit node;
+
+  UnitToWriteAst({
+    @required this.node,
+  });
+}
+
+class UnitToWriteResolution {
+  final String uriStr;
+  final String partUriStr;
+  final CompilationUnit node;
+  final bool isSynthetic;
+
+  UnitToWriteResolution({
+    @required this.uriStr,
+    @required this.partUriStr,
+    @required this.node,
+    @required this.isSynthetic,
+  });
+}
+
+class _BundleWriterReferences {
+  /// The `dynamic` class is declared in `dart:core`, but is not a class.
+  /// Also, it is static, so we cannot set `reference` for it.
+  /// So, we have to push it in a separate way.
+  final Reference dynamicReference;
+
+  /// References used in all libraries being linked.
+  /// Element references in nodes are indexes in this list.
+  final List<Reference> references = [null];
+
+  final List<int> _referenceParents = [0];
+  final List<String> _referenceNames = [''];
+
+  _BundleWriterReferences(this.dynamicReference);
+
+  /// We need indexes for references during linking, but once we are done,
+  /// we must clear indexes to make references ready for linking a next bundle.
+  void _clearIndexes() {
+    for (var reference in references) {
+      if (reference != null) {
+        reference.index = null;
+      }
+    }
+  }
+
+  int _indexOfReference(Reference reference) {
+    if (reference == null) return 0;
+    if (reference.parent == null) return 0;
+    if (reference.index != null) return reference.index;
+
+    var parentIndex = _indexOfReference(reference.parent);
+    _referenceParents.add(parentIndex);
+    _referenceNames.add(reference.name);
+
+    reference.index = references.length;
+    references.add(reference);
+    return reference.index;
+  }
+}
+
+class _LocalElementIndexer {
+  final Map<Element, int> _index = Map.identity();
+  final List<int> _scopes = [];
+  int _stackHeight = 0;
+
+  int operator [](Element element) {
+    return _index[element] ??
+        (throw ArgumentError('Unexpectedly not indexed: $element'));
+  }
+
+  void declare(Element element) {
+    _index[element] = _stackHeight++;
+  }
+
+  void popScope() {
+    _stackHeight = _scopes.removeLast();
+  }
+
+  void pushScope() {
+    _scopes.add(_stackHeight);
+  }
+}
+
+class _ResolutionLibrary {
+  final ResolutionSink sink;
+  final LibraryToWriteResolution library;
+  final List<ResolutionUnit> units = [];
+
+  _ResolutionLibrary({
+    @required this.sink,
+    @required this.library,
+  });
+
+  ResolutionUnit enterUnit(UnitToWriteResolution unitToWrite) {
+    var unit = ResolutionUnit(
+      library: this,
+      unit: unitToWrite,
+      directivesOffset: sink.offset,
+    );
+    units.add(unit);
+    return unit;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
index bb3c11c..0c4cea8 100644
--- a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
@@ -56,15 +56,12 @@
   }
 
   void _initializers() {
-    var initializers = _constructorNode.initializers;
-
     var isConst = _constructorNode.constKeyword != null;
     if (!isConst) {
-      initializers.clear();
       return;
     }
 
-    for (var initializer in initializers) {
+    for (var initializer in _constructorNode.initializers) {
       _astResolver.resolve(
         initializer,
         () => initializer,
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
new file mode 100644
index 0000000..143685b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -0,0 +1,225 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:meta/meta.dart';
+
+/// Helper for reading primitive types from bytes.
+class SummaryDataReader {
+  final Uint8List bytes;
+  int offset = 0;
+
+  _StringTable _stringTable;
+
+  final Float64List _doubleBuffer = Float64List(1);
+  Uint8List _doubleBufferUint8;
+
+  SummaryDataReader(this.bytes);
+
+  void createStringTable(int offset) {
+    _stringTable = _StringTable(bytes: bytes, startOffset: offset);
+  }
+
+  @pragma("vm:prefer-inline")
+  int readByte() {
+    return bytes[offset++];
+  }
+
+  double readDouble() {
+    _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+    _doubleBufferUint8[0] = readByte();
+    _doubleBufferUint8[1] = readByte();
+    _doubleBufferUint8[2] = readByte();
+    _doubleBufferUint8[3] = readByte();
+    _doubleBufferUint8[4] = readByte();
+    _doubleBufferUint8[5] = readByte();
+    _doubleBufferUint8[6] = readByte();
+    _doubleBufferUint8[7] = readByte();
+    return _doubleBuffer[0];
+  }
+
+  String readStringReference() {
+    return _stringTable[readUInt30()];
+  }
+
+  String readStringUtf8() {
+    var bytes = readUint8List();
+    return utf8.decode(bytes);
+  }
+
+  int readUInt30() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  Uint32List readUint30List() {
+    var length = readUInt30();
+    var result = Uint32List(length);
+    for (var i = 0; i < length; ++i) {
+      result[i] = readUInt30();
+    }
+    return result;
+  }
+
+  int readUint32() {
+    return (readByte() << 24) |
+        (readByte() << 16) |
+        (readByte() << 8) |
+        readByte();
+  }
+
+  Uint32List readUint32List() {
+    var length = readUint32();
+    var result = Uint32List(length);
+    for (var i = 0; i < length; ++i) {
+      result[i] = readUint32();
+    }
+    return result;
+  }
+
+  Uint8List readUint8List() {
+    var length = readUInt30();
+    var result = Uint8List.sublistView(bytes, offset, offset + length);
+    offset += length;
+    return result;
+  }
+
+  String stringOfIndex(int index) {
+    return _stringTable[index];
+  }
+}
+
+class _StringTable {
+  final Uint8List _bytes;
+  int _byteOffset;
+
+  Uint32List _offsets;
+  Uint32List _lengths;
+  List<String> _strings;
+
+  /// The structure of the table:
+  ///   <bytes with encoded strings>
+  ///   <the length of the bytes> <-- [startOffset]
+  ///   <the number strings>
+  ///   <the array of lengths of individual strings>
+  _StringTable({
+    @required Uint8List bytes,
+    @required int startOffset,
+  }) : _bytes = bytes {
+    _byteOffset = startOffset;
+
+    var offset = startOffset - _readUInt();
+    var length = _readUInt();
+
+    _offsets = Uint32List(length);
+    _lengths = Uint32List(length);
+    for (var i = 0; i < length; i++) {
+      var stringLength = _readUInt();
+      _offsets[i] = offset;
+      _lengths[i] = stringLength;
+      offset += stringLength;
+    }
+
+    _strings = List.filled(length, null, growable: false);
+  }
+
+  String operator [](int index) {
+    var result = _strings[index];
+
+    if (result == null) {
+      result = _readStringEntry(_offsets[index], _lengths[index]);
+      _strings[index] = result;
+    }
+
+    return result;
+  }
+
+  int _readByte() {
+    return _bytes[_byteOffset++];
+  }
+
+  String _readStringEntry(int start, int numBytes) {
+    var end = start + numBytes;
+    for (var i = start; i < end; i++) {
+      if (_bytes[i] > 127) {
+        return _decodeWtf8(_bytes, start, end);
+      }
+    }
+    return String.fromCharCodes(_bytes, start, end);
+  }
+
+  int _readUInt() {
+    var byte = _readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | _readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (_readByte() << 16) |
+          (_readByte() << 8) |
+          _readByte();
+    }
+  }
+
+  static String _decodeWtf8(Uint8List _bytes, int start, int end) {
+    // WTF-8 decoder that trusts its input, meaning that the correctness of
+    // the code depends on the bytes from start to end being valid and
+    // complete WTF-8. Instead of masking off the control bits from every
+    // byte, it simply xor's the byte values together at their appropriate
+    // bit shifts, and then xor's out all of the control bits at once.
+    Uint16List charCodes = Uint16List(end - start);
+    int i = start;
+    int j = 0;
+    while (i < end) {
+      int byte = _bytes[i++];
+      if (byte < 0x80) {
+        // ASCII.
+        charCodes[j++] = byte;
+      } else if (byte < 0xE0) {
+        // Two-byte sequence (11-bit unicode value).
+        int byte2 = _bytes[i++];
+        int value = (byte << 6) ^ byte2 ^ 0x3080;
+        assert(value >= 0x80 && value < 0x800);
+        charCodes[j++] = value;
+      } else if (byte < 0xF0) {
+        // Three-byte sequence (16-bit unicode value).
+        int byte2 = _bytes[i++];
+        int byte3 = _bytes[i++];
+        int value = (byte << 12) ^ (byte2 << 6) ^ byte3 ^ 0xE2080;
+        assert(value >= 0x800 && value < 0x10000);
+        charCodes[j++] = value;
+      } else {
+        // Four-byte sequence (non-BMP unicode value).
+        int byte2 = _bytes[i++];
+        int byte3 = _bytes[i++];
+        int byte4 = _bytes[i++];
+        int value =
+            (byte << 18) ^ (byte2 << 12) ^ (byte3 << 6) ^ byte4 ^ 0x3C82080;
+        assert(value >= 0x10000 && value < 0x110000);
+        charCodes[j++] = 0xD7C0 + (value >> 10);
+        charCodes[j++] = 0xDC00 + (value & 0x3FF);
+      }
+    }
+    assert(i == end);
+    return String.fromCharCodes(charCodes, 0, j);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart
new file mode 100644
index 0000000..5428e5b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+/// Puts a buffer in front of a [Sink<List<int>>].
+class BufferedSink {
+  static const int SIZE = 100000;
+  static const int SAFE_SIZE = SIZE - 5;
+  static const int SMALL = 10000;
+
+  final Sink<List<int>> _sink;
+
+  int flushedLength = 0;
+
+  Uint8List _buffer = Uint8List(SIZE);
+  int length = 0;
+
+  final Float64List _doubleBuffer = Float64List(1);
+  Uint8List _doubleBufferUint8;
+
+  BufferedSink(this._sink);
+
+  int get offset => flushedLength + length;
+
+  @pragma("vm:prefer-inline")
+  void addByte(int byte) {
+    _buffer[length++] = byte;
+    if (length == SIZE) {
+      _sink.add(_buffer);
+      _buffer = Uint8List(SIZE);
+      length = 0;
+      flushedLength += SIZE;
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  void addByte2(int byte1, int byte2) {
+    if (length < SAFE_SIZE) {
+      _buffer[length++] = byte1;
+      _buffer[length++] = byte2;
+    } else {
+      addByte(byte1);
+      addByte(byte2);
+    }
+  }
+
+  @pragma("vm:prefer-inline")
+  void addByte4(int byte1, int byte2, int byte3, int byte4) {
+    if (length < SAFE_SIZE) {
+      _buffer[length++] = byte1;
+      _buffer[length++] = byte2;
+      _buffer[length++] = byte3;
+      _buffer[length++] = byte4;
+    } else {
+      addByte(byte1);
+      addByte(byte2);
+      addByte(byte3);
+      addByte(byte4);
+    }
+  }
+
+  void addBytes(Uint8List bytes) {
+    // Avoid copying a large buffer into the another large buffer. Also, if
+    // the bytes buffer is too large to fit in our own buffer, just emit both.
+    if (length + bytes.length < SIZE &&
+        (bytes.length < SMALL || length < SMALL)) {
+      _buffer.setRange(length, length + bytes.length, bytes);
+      length += bytes.length;
+    } else if (bytes.length < SMALL) {
+      // Flush as much as we can in the current buffer.
+      _buffer.setRange(length, SIZE, bytes);
+      _sink.add(_buffer);
+      // Copy over the remainder into a new buffer. It is guaranteed to fit
+      // because the input byte array is small.
+      int alreadyEmitted = SIZE - length;
+      int remainder = bytes.length - alreadyEmitted;
+      _buffer = Uint8List(SIZE);
+      _buffer.setRange(0, remainder, bytes, alreadyEmitted);
+      length = remainder;
+      flushedLength += SIZE;
+    } else {
+      flush();
+      _sink.add(bytes);
+      flushedLength += bytes.length;
+    }
+  }
+
+  void addDouble(double value) {
+    _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+    _doubleBuffer[0] = value;
+    addByte4(_doubleBufferUint8[0], _doubleBufferUint8[1],
+        _doubleBufferUint8[2], _doubleBufferUint8[3]);
+    addByte4(_doubleBufferUint8[4], _doubleBufferUint8[5],
+        _doubleBufferUint8[6], _doubleBufferUint8[7]);
+  }
+
+  void flush() {
+    _sink.add(_buffer.sublist(0, length));
+    _buffer = Uint8List(SIZE);
+    flushedLength += length;
+    length = 0;
+  }
+
+  void flushAndDestroy() {
+    _sink.add(_buffer.sublist(0, length));
+  }
+
+  @pragma("vm:prefer-inline")
+  void writeByte(int byte) {
+    assert((byte & 0xFF) == byte);
+    addByte(byte);
+  }
+
+  void writeList<T>(List<T> items, void Function(T x) writeItem) {
+    writeUInt30(items.length);
+    for (var i = 0; i < items.length; i++) {
+      writeItem(items[i]);
+    }
+  }
+
+  /// Write the [value] as UTF8 encoded byte array.
+  void writeStringUtf8(String value) {
+    var bytes = utf8.encode(value);
+    writeUint8List(bytes);
+  }
+
+  @pragma("vm:prefer-inline")
+  void writeUInt30(int value) {
+    assert(value >= 0 && value >> 30 == 0);
+    if (value < 0x80) {
+      addByte(value);
+    } else if (value < 0x4000) {
+      addByte2((value >> 8) | 0x80, value & 0xFF);
+    } else {
+      addByte4((value >> 24) | 0xC0, (value >> 16) & 0xFF, (value >> 8) & 0xFF,
+          value & 0xFF);
+    }
+  }
+
+  void writeUint30List(List<int> values) {
+    var length = values.length;
+    writeUInt30(length);
+    for (var i = 0; i < length; i++) {
+      writeUInt30(values[i]);
+    }
+  }
+
+  void writeUInt32(int value) {
+    addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF,
+        value & 0xFF);
+  }
+
+  void writeUint8List(Uint8List bytes) {
+    writeUInt30(bytes.length);
+    addBytes(bytes);
+  }
+}
+
+/// A [Sink] that directly writes data into a byte builder.
+class ByteSink implements Sink<List<int>> {
+  final BytesBuilder builder = BytesBuilder(copy: false);
+
+  @override
+  void add(List<int> data) {
+    builder.add(data);
+  }
+
+  @override
+  void close() {}
+}
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 4a8d0c5..68cc053 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 import 'package:analyzer/src/util/graph.dart';
@@ -137,10 +136,11 @@
     if (parameterList == null) return;
 
     for (var parameter in parameterList.typeParameters) {
-      var defaultType = LazyAst.getDefaultType(parameter);
+      var element = parameter.declaredElement as TypeParameterElementImpl;
+      var defaultType = element.defaultType;
       if (defaultType is TypeBuilder) {
         var builtType = defaultType.build();
-        LazyAst.setDefaultType(parameter, builtType);
+        element.defaultType = builtType;
       }
     }
   }
@@ -161,8 +161,8 @@
 
     var nodes = parameterList.typeParameters;
     var length = nodes.length;
-    var elements = List<TypeParameterElementImpl>(length);
-    var bounds = List<DartType>(length);
+    var elements = List<TypeParameterElementImpl>.filled(length, null);
+    var bounds = List<DartType>.filled(length, null);
     for (int i = 0; i < length; i++) {
       var node = nodes[i];
       elements[i] = node.declaredElement;
@@ -211,7 +211,8 @@
 
     // Set computed TypeBuilder(s) as default types.
     for (var i = 0; i < length; i++) {
-      LazyAst.setDefaultType(nodes[i], bounds[i]);
+      var element = nodes[i].declaredElement as TypeParameterElementImpl;
+      element.defaultType = bounds[i];
     }
   }
 
@@ -235,6 +236,7 @@
           void recurseParameters(List<TypeParameterElement> parameters) {
             for (TypeParameterElementImpl parameter in parameters) {
               TypeParameter parameterNode = parameter.linkedNode;
+              // TODO(scheglov) How to we skip already linked?
               var bound = parameterNode.bound;
               if (bound != null) {
                 var tails = _findRawTypePathsToDeclaration(
@@ -322,8 +324,8 @@
   ) {
     assert(parameters.length == bounds.length);
 
-    vertices = List<int>(parameters.length);
-    _edges = List<List<int>>(parameters.length);
+    vertices = List<int>.filled(parameters.length, null);
+    _edges = List<List<int>>.filled(parameters.length, null);
     for (int i = 0; i < vertices.length; i++) {
       vertices[i] = i;
       _edges[i] = <int>[];
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index a4c8987..4fd730d 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -12,7 +12,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 
 /// The type builder for a [GenericFunctionType].
@@ -97,7 +96,6 @@
 
     if (node != null) {
       node.type = _type;
-      LazyAst.setReturnType(node, builtReturnType ?? _dynamicType);
     }
 
     return _type;
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
deleted file mode 100644
index c26e114..0000000
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ /dev/null
@@ -1,436 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/summary/format.dart';
-
-/// Create informative data for nodes that need it, and set IDs of this
-/// data to the nodes.
-List<UnlinkedInformativeDataBuilder> createInformativeData(
-    CompilationUnit unit) {
-  var visitor = _SetInformativeId();
-  unit.accept(visitor);
-  return visitor.dataList;
-}
-
-/// If [createInformativeData] set the informative data identifier for the
-/// [node], return it, otherwise return zero.
-int getInformativeId(AstNode node) {
-  int id = node.getProperty(_SetInformativeId.ID);
-  return id ?? 0;
-}
-
-class _SetInformativeId extends SimpleAstVisitor<void> {
-  static final String ID = 'informativeId';
-
-  final List<UnlinkedInformativeDataBuilder> dataList = [];
-
-  void setData(AstNode node, UnlinkedInformativeDataBuilder data) {
-    var id = 1 + dataList.length;
-    node.setProperty(ID, id);
-    dataList.add(data);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.classDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.members.accept(this);
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.classTypeAlias(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-  }
-
-  @override
-  void visitCompilationUnit(CompilationUnit node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.compilationUnit(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        compilationUnit_lineStarts: node.lineInfo.lineStarts,
-      ),
-    );
-
-    node.directives.accept(this);
-    node.declarations.accept(this);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.constructorDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name?.offset ?? 0,
-        constructorDeclaration_periodOffset: node.period?.offset ?? 0,
-        constructorDeclaration_returnTypeOffset: node.returnType.offset,
-      ),
-    );
-
-    node.parameters?.accept(this);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    var defaultValueCode = node.defaultValue?.toSource();
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.defaultFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        defaultFormalParameter_defaultValueCode: defaultValueCode,
-      ),
-    );
-
-    node.parameter.accept(this);
-  }
-
-  @override
-  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.enumConstantDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.enumDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.constants.accept(this);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.exportDirective(
-        directiveKeywordOffset: node.keyword.offset,
-      ),
-    );
-    node.combinators.accept(this);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.extensionDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name?.offset ?? 0,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.members.accept(this);
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.fieldDeclaration(
-        documentationComment_tokens: _nodeCommentTokens(node),
-      ),
-    );
-
-    node.fields.accept(this);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.fieldFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.identifier.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitFormalParameterList(FormalParameterList node) {
-    node.parameters.accept(this);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.functionDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.functionExpression.accept(this);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    node.typeParameters?.accept(this);
-    node.parameters?.accept(this);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.functionTypeAlias(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.parameters.accept(this);
-  }
-
-  @override
-  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.functionTypedFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.identifier.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    node.typeParameters?.accept(this);
-    node.parameters.accept(this);
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.genericTypeAlias(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.functionType?.accept(this);
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.hideCombinator(
-        combinatorEnd: node.end,
-        combinatorKeywordOffset: node.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.importDirective(
-        directiveKeywordOffset: node.keyword.offset,
-        importDirective_prefixOffset: node.prefix?.offset ?? 0,
-      ),
-    );
-    node.combinators.accept(this);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.libraryDirective(
-        documentationComment_tokens: _nodeCommentTokens(node),
-      ),
-    );
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.methodDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.parameters?.accept(this);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.mixinDeclaration(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        documentationComment_tokens: _nodeCommentTokens(node),
-        nameOffset: node.name.offset,
-      ),
-    );
-
-    node.typeParameters?.accept(this);
-    node.members.accept(this);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.partDirective(
-        directiveKeywordOffset: node.keyword.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.partDirective(
-        directiveKeywordOffset: node.keyword.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.showCombinator(
-        combinatorEnd: node.end,
-        combinatorKeywordOffset: node.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitSimpleFormalParameter(SimpleFormalParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.simpleFormalParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.identifier?.offset ?? 0,
-      ),
-    );
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.topLevelVariableDeclaration(
-        documentationComment_tokens: _nodeCommentTokens(node),
-      ),
-    );
-
-    node.variables.accept(this);
-  }
-
-  @override
-  void visitTypeParameter(TypeParameter node) {
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.typeParameter(
-        codeOffset: node.offset,
-        codeLength: node.length,
-        nameOffset: node.name.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitTypeParameterList(TypeParameterList node) {
-    node.typeParameters.accept(this);
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    var variableList = node.parent as VariableDeclarationList;
-    var isFirst = identical(variableList.variables[0], node);
-    var codeOffset = (isFirst ? variableList.parent : node).offset;
-    var codeLength = node.end - codeOffset;
-
-    setData(
-      node,
-      UnlinkedInformativeDataBuilder.variableDeclaration(
-        codeOffset: codeOffset,
-        codeLength: codeLength,
-        nameOffset: node.name.offset,
-      ),
-    );
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    node.variables.accept(this);
-  }
-
-  static List<String> _commentTokens(Comment comment) {
-    if (comment == null) return null;
-    return comment.tokens.map((token) => token.lexeme).toList();
-  }
-
-  static List<String> _nodeCommentTokens(AnnotatedNode node) {
-    return _commentTokens(node.documentationComment);
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
deleted file mode 100644
index dea4fa9..0000000
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ /dev/null
@@ -1,1974 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:pub_semver/pub_semver.dart';
-
-/// Accessor for reading AST lazily, or read data that is stored in IDL, but
-/// cannot be stored in AST, like inferred types.
-class LazyAst {
-  static const _defaultTypeKey = 'lazyAst_defaultType';
-  static const _genericFunctionTypeIdKey = 'lazyAst_genericFunctionTypeId';
-  static const _hasOverrideInferenceKey = 'lazyAst_hasOverrideInference';
-  static const _inheritsCovariantKey = 'lazyAst_isCovariant';
-  static const _isSimplyBoundedKey = 'lazyAst_simplyBounded';
-  static const _isOperatorEqualParameterTypeFromObjectKey =
-      'lazyAst_isOperatorEqualParameterTypeFromObject';
-  static const _rawFunctionTypeKey = 'lazyAst_rawFunctionType';
-  static const _returnTypeKey = 'lazyAst_returnType';
-  static const _typeInferenceErrorKey = 'lazyAst_typeInferenceError';
-  static const _typeKey = 'lazyAst_type';
-  static const _varianceKey = 'lazyAst_variance';
-
-  final LinkedNode data;
-
-  LazyAst(this.data);
-
-  static DartType getDefaultType(TypeParameter node) {
-    return node.getProperty(_defaultTypeKey);
-  }
-
-  static int getGenericFunctionTypeId(GenericFunctionType node) {
-    return node.getProperty(_genericFunctionTypeIdKey);
-  }
-
-  static bool getInheritsCovariant(AstNode node) {
-    return node.getProperty(_inheritsCovariantKey) ?? false;
-  }
-
-  static DartType getRawFunctionType(AstNode node) {
-    return node.getProperty(_rawFunctionTypeKey);
-  }
-
-  static DartType getReturnType(AstNode node) {
-    return node.getProperty(_returnTypeKey);
-  }
-
-  static DartType getType(AstNode node) {
-    return node.getProperty(_typeKey);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(AstNode node) {
-    return node.getProperty(_typeInferenceErrorKey);
-  }
-
-  static Variance getVariance(TypeParameter node) {
-    return node.getProperty(_varianceKey);
-  }
-
-  static bool hasOperatorEqualParameterTypeFromObject(AstNode node) {
-    return node.getProperty(_isOperatorEqualParameterTypeFromObjectKey) ??
-        false;
-  }
-
-  static bool hasOverrideInferenceDone(AstNode node) {
-    return node.getProperty(_hasOverrideInferenceKey) ?? false;
-  }
-
-  static bool isSimplyBounded(AstNode node) {
-    return node.getProperty(_isSimplyBoundedKey);
-  }
-
-  static void setDefaultType(TypeParameter node, DartType type) {
-    node.setProperty(_defaultTypeKey, type);
-  }
-
-  static void setGenericFunctionTypeId(GenericFunctionType node, int id) {
-    node.setProperty(_genericFunctionTypeIdKey, id);
-  }
-
-  static void setInheritsCovariant(AstNode node, bool value) {
-    node.setProperty(_inheritsCovariantKey, value);
-  }
-
-  static void setOperatorEqualParameterTypeFromObject(AstNode node, bool b) {
-    node.setProperty(_isOperatorEqualParameterTypeFromObjectKey, b);
-  }
-
-  static void setOverrideInferenceDone(AstNode node) {
-    node.setProperty(_hasOverrideInferenceKey, true);
-  }
-
-  static void setRawFunctionType(AstNode node, DartType type) {
-    node.setProperty(_rawFunctionTypeKey, type);
-  }
-
-  static void setReturnType(AstNode node, DartType type) {
-    node.setProperty(_returnTypeKey, type);
-  }
-
-  static void setSimplyBounded(AstNode node, bool simplyBounded) {
-    node.setProperty(_isSimplyBoundedKey, simplyBounded);
-  }
-
-  static void setType(AstNode node, DartType type) {
-    node.setProperty(_typeKey, type);
-  }
-
-  static void setTypeInferenceError(
-      AstNode node, TopLevelInferenceError error) {
-    node.setProperty(_typeInferenceErrorKey, error);
-  }
-
-  static void setVariance(TypeParameter node, Variance variance) {
-    return node.setProperty(_varianceKey, variance);
-  }
-}
-
-class LazyClassDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasExtendsClause = false;
-  bool _hasImplementsClause = false;
-  bool _hasMembers = false;
-  bool _hasMetadata = false;
-  bool _hasWithClause = false;
-
-  LazyClassDeclaration(this.data);
-
-  static LazyClassDeclaration get(ClassDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readExtendsClause(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasExtendsClause) {
-      node.extendsClause = reader.readNode(
-        lazy.data.classDeclaration_extendsClause,
-      );
-      lazy._hasExtendsClause = true;
-    }
-  }
-
-  static void readImplementsClause(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasImplementsClause) {
-      node.implementsClause = reader.readNode(
-        lazy.data.classOrMixinDeclaration_implementsClause,
-      );
-      lazy._hasImplementsClause = true;
-    }
-  }
-
-  static void readMembers(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMembers) {
-      var dataList = lazy.data.classOrMixinDeclaration_members;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.members[i] = reader.readNode(data);
-      }
-      lazy._hasMembers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readWithClause(
-    AstBinaryReader reader,
-    ClassDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasWithClause) {
-      node.withClause = reader.readNode(
-        lazy.data.classDeclaration_withClause,
-      );
-      lazy._hasWithClause = true;
-    }
-  }
-
-  static void setData(ClassDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyClassDeclaration(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-}
-
-class LazyClassTypeAlias {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasImplementsClause = false;
-  bool _hasMetadata = false;
-  bool _hasSuperclass = false;
-  bool _hasWithClause = false;
-
-  LazyClassTypeAlias(this.data);
-
-  static LazyClassTypeAlias get(ClassTypeAlias node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readImplementsClause(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasImplementsClause) {
-      node.implementsClause = reader.readNode(
-        lazy.data.classTypeAlias_implementsClause,
-      );
-      lazy._hasImplementsClause = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readSuperclass(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasSuperclass) {
-      node.superclass = reader.readNode(
-        lazy.data.classTypeAlias_superclass,
-      );
-      lazy._hasSuperclass = true;
-    }
-  }
-
-  static void readWithClause(
-    AstBinaryReader reader,
-    ClassTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasWithClause) {
-      node.withClause = reader.readNode(
-        lazy.data.classTypeAlias_withClause,
-      );
-      lazy._hasWithClause = true;
-    }
-  }
-
-  static void setData(ClassTypeAlias node, LinkedNode data) {
-    node.setProperty(_key, LazyClassTypeAlias(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-}
-
-class LazyCombinator {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  LazyCombinator(Combinator node, this.data) {
-    node.setProperty(_key, this);
-  }
-
-  static LazyCombinator get(Combinator node) {
-    return node.getProperty(_key);
-  }
-
-  static int getEnd(
-    LinkedUnitContext context,
-    Combinator node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      var informativeData = context.getInformativeData(lazy.data);
-      return informativeData?.combinatorEnd ?? 0;
-    }
-    return node.end;
-  }
-}
-
-class LazyCompilationUnit {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  LazyCompilationUnit(CompilationUnit node, this.data) {
-    node.setProperty(_key, this);
-  }
-
-  static LazyCompilationUnit get(CompilationUnit node) {
-    return node.getProperty(_key);
-  }
-
-  static LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      var package = lazy.data.compilationUnit_languageVersion.package;
-      var override = lazy.data.compilationUnit_languageVersion.override2;
-      return LibraryLanguageVersion(
-        package: Version(package.major, package.minor, 0),
-        override: override != null
-            ? Version(override.major, override.minor, 0)
-            : null,
-      );
-    }
-    return (node as CompilationUnitImpl).languageVersion;
-  }
-}
-
-class LazyConstructorDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBody = false;
-  bool _hasDocumentationComment = false;
-  bool _hasFormalParameters = false;
-  bool _hasInitializers = false;
-  bool _hasMetadata = false;
-  bool _hasRedirectedConstructor = false;
-
-  LazyConstructorDeclaration(this.data);
-
-  static LazyConstructorDeclaration get(ConstructorDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readBody(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBody) {
-      node.body = reader.readNode(
-        lazy.data.constructorDeclaration_body,
-      );
-      lazy._hasBody = true;
-    }
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.constructorDeclaration_parameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readInitializers(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasInitializers) {
-      var dataList = lazy.data.constructorDeclaration_initializers;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.initializers[i] = reader.readNode(data);
-      }
-      lazy._hasInitializers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readRedirectedConstructor(
-    AstBinaryReader reader,
-    ConstructorDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasRedirectedConstructor) {
-      node.redirectedConstructor = reader.readNode(
-        lazy.data.constructorDeclaration_redirectedConstructor,
-      );
-      lazy._hasRedirectedConstructor = true;
-    }
-  }
-
-  static void setData(ConstructorDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyConstructorDeclaration(data));
-  }
-}
-
-class LazyDirective {
-  static const _key = 'lazyAst';
-  static const _uriKey = 'lazyAst_selectedUri';
-
-  final LinkedNode data;
-
-  bool _hasMetadata = false;
-
-  LazyDirective(this.data);
-
-  static LazyDirective get(Directive node) {
-    return node.getProperty(_key);
-  }
-
-  static String getSelectedUri(UriBasedDirective node) {
-    return node.getProperty(_uriKey);
-  }
-
-  static void readMetadata(AstBinaryReader reader, Directive node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(Directive node, LinkedNode data) {
-    node.setProperty(_key, LazyDirective(data));
-    if (node is NamespaceDirective) {
-      node.setProperty(_uriKey, data.namespaceDirective_selectedUri);
-    }
-  }
-
-  static void setSelectedUri(UriBasedDirective node, String uriStr) {
-    node.setProperty(_uriKey, uriStr);
-  }
-}
-
-class LazyEnumConstantDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyEnumConstantDeclaration(this.data);
-
-  static LazyEnumConstantDeclaration get(EnumConstantDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    EnumConstantDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(EnumConstantDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyEnumConstantDeclaration(data));
-  }
-}
-
-class LazyEnumDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasConstants = false;
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyEnumDeclaration(this.data);
-
-  static LazyEnumDeclaration get(EnumDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readConstants(
-    AstBinaryReader reader,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasConstants) {
-      var dataList = lazy.data.enumDeclaration_constants;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.constants[i] = reader.readNode(data);
-      }
-      lazy._hasConstants = true;
-    }
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    EnumDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(EnumDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyEnumDeclaration(data));
-  }
-}
-
-class LazyExtensionDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasExtendedType = false;
-  bool _hasMembers = false;
-  bool _hasMetadata = false;
-
-  /// The name for use in `Reference`. If the extension is named, the name
-  /// of the extension. If the extension is unnamed, a synthetic name.
-  String _refName;
-
-  LazyExtensionDeclaration(ExtensionDeclaration node, this.data) {
-    node.setProperty(_key, this);
-    if (data != null) {
-      _refName = data.extensionDeclaration_refName;
-    }
-  }
-
-  String get refName => _refName;
-
-  void put(LinkedNodeBuilder builder) {
-    assert(_refName != null);
-    builder.extensionDeclaration_refName = _refName;
-  }
-
-  void setRefName(String referenceName) {
-    _refName = referenceName;
-  }
-
-  static LazyExtensionDeclaration get(ExtensionDeclaration node) {
-    LazyExtensionDeclaration lazy = node.getProperty(_key);
-    if (lazy == null) {
-      return LazyExtensionDeclaration(node, null);
-    }
-    return lazy;
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readExtendedType(
-    AstBinaryReader reader,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasExtendedType) {
-      (node as ExtensionDeclarationImpl).extendedType = reader.readNode(
-        lazy.data.extensionDeclaration_extendedType,
-      );
-      lazy._hasExtendedType = true;
-    }
-  }
-
-  static void readMembers(
-    AstBinaryReader reader,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasMembers) {
-      var dataList = lazy.data.extensionDeclaration_members;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.members[i] = reader.readNode(data);
-      }
-      lazy._hasMembers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    ExtensionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy?.data != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-}
-
-class LazyFieldDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyFieldDeclaration(this.data);
-
-  static LazyFieldDeclaration get(FieldDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    FieldDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FieldDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(FieldDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyFieldDeclaration(data));
-  }
-}
-
-class LazyFormalParameter {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDefaultValue = false;
-  bool _hasFormalParameters = false;
-  bool _hasMetadata = false;
-  bool _hasType = false;
-  bool _hasTypeInferenceError = false;
-  bool _hasTypeNode = false;
-
-  LazyFormalParameter(this.data);
-
-  static LazyFormalParameter get(FormalParameter node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static String getDefaultValueCode(
-    LinkedUnitContext context,
-    DefaultFormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      if (lazy.data.defaultFormalParameter_defaultValue == null) {
-        return null;
-      }
-      return context.getDefaultValueCodeData(lazy.data);
-    } else {
-      return node.defaultValue?.toSource();
-    }
-  }
-
-  static DartType getType(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasType) {
-      var type = reader.readType(lazy.data.actualType);
-      LazyAst.setType(node, type);
-      lazy._hasType = true;
-    }
-    return LazyAst.getType(node);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(FormalParameter node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeInferenceError) {
-      var error = lazy.data.topLevelTypeInferenceError;
-      LazyAst.setTypeInferenceError(node, error);
-      lazy._hasTypeInferenceError = true;
-    }
-    return LazyAst.getTypeInferenceError(node);
-  }
-
-  static bool hasDefaultValue(DefaultFormalParameter node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.hasInitializer(lazy.data.flags);
-    } else {
-      return node.defaultValue != null;
-    }
-  }
-
-  static void readDefaultValue(
-    AstBinaryReader reader,
-    DefaultFormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDefaultValue) {
-      node.defaultValue = reader.readNode(
-        lazy.data.defaultFormalParameter_defaultValue,
-      );
-      lazy._hasDefaultValue = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      if (node is FunctionTypedFormalParameter) {
-        node.parameters = reader.readNode(
-          lazy.data.functionTypedFormalParameter_formalParameters,
-        );
-      } else if (node is FieldFormalParameter) {
-        node.parameters = reader.readNode(
-          lazy.data.fieldFormalParameter_formalParameters,
-        );
-      }
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.normalFormalParameter_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readTypeNode(
-    AstBinaryReader reader,
-    FormalParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeNode) {
-      if (node is SimpleFormalParameter) {
-        node.type = reader.readNode(
-          lazy.data.simpleFormalParameter_type,
-        );
-      }
-      lazy._hasTypeNode = true;
-    }
-  }
-
-  static void setData(FormalParameter node, LinkedNode data) {
-    node.setProperty(_key, LazyFormalParameter(data));
-  }
-}
-
-class LazyFunctionDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = false;
-
-  LazyFunctionDeclaration(this.data);
-
-  static LazyFunctionDeclaration get(FunctionDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static DartType getReturnType(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    readFunctionExpression(reader, node);
-
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnType) {
-      var type = reader.readType(lazy.data.actualReturnType);
-      LazyAst.setReturnType(node, type);
-      lazy._hasReturnType = true;
-    }
-
-    return LazyAst.getReturnType(node);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFunctionExpression(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    if (node.functionExpression == null) {
-      var lazy = get(node);
-      node.functionExpression = reader.readNode(
-        lazy.data.functionDeclaration_functionExpression,
-      );
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readReturnTypeNode(
-    AstBinaryReader reader,
-    FunctionDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.functionDeclaration_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(FunctionDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyFunctionDeclaration(data));
-  }
-}
-
-class LazyFunctionExpression {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBody = false;
-  bool _hasFormalParameters = false;
-
-  LazyFunctionExpression(this.data);
-
-  static LazyFunctionExpression get(FunctionExpression node) {
-    return node.getProperty(_key);
-  }
-
-  static bool isAsynchronous(FunctionExpression node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isAsync(lazy.data.flags);
-    } else {
-      return node.body.isAsynchronous;
-    }
-  }
-
-  static bool isGenerator(FunctionExpression node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isGenerator(lazy.data.flags);
-    } else {
-      return node.body.isGenerator;
-    }
-  }
-
-  static void readBody(
-    AstBinaryReader reader,
-    FunctionExpression node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBody) {
-      node.body = reader.readNode(
-        lazy.data.functionExpression_body,
-      );
-      lazy._hasBody = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    FunctionExpression node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.functionExpression_formalParameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void setData(FunctionExpression node, LinkedNode data) {
-    node.setProperty(_key, LazyFunctionExpression(data));
-  }
-}
-
-class LazyFunctionTypeAlias {
-  static const _key = 'lazyAst';
-  static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasFormalParameters = false;
-  bool _hasMetadata = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = false;
-
-  LazyFunctionTypeAlias(this.data);
-
-  static LazyFunctionTypeAlias get(FunctionTypeAlias node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static bool getHasSelfReference(FunctionTypeAlias node) {
-    return node.getProperty(_hasSelfReferenceKey);
-  }
-
-  static DartType getReturnType(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnType) {
-      var type = reader.readType(lazy.data.actualReturnType);
-      LazyAst.setReturnType(node, type);
-      lazy._hasReturnType = true;
-    }
-    return LazyAst.getReturnType(node);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.functionTypeAlias_formalParameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readReturnTypeNode(
-    AstBinaryReader reader,
-    FunctionTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.functionTypeAlias_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(FunctionTypeAlias node, LinkedNode data) {
-    node.setProperty(_key, LazyFunctionTypeAlias(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-
-  static void setHasSelfReference(FunctionTypeAlias node, bool value) {
-    node.setProperty(_hasSelfReferenceKey, value);
-  }
-}
-
-class LazyGenericTypeAlias {
-  static const _key = 'lazyAst';
-  static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasFunction = false;
-  bool _hasMetadata = false;
-
-  LazyGenericTypeAlias(this.data);
-
-  static LazyGenericTypeAlias get(GenericTypeAlias node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static bool getHasSelfReference(GenericTypeAlias node) {
-    return node.getProperty(_hasSelfReferenceKey);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFunctionType(
-    AstBinaryReader reader,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFunction) {
-      node.functionType = reader.readNode(
-        lazy.data.genericTypeAlias_functionType,
-      );
-      lazy._hasFunction = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    GenericTypeAlias node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(GenericTypeAlias node, LinkedNode data) {
-    node.setProperty(_key, LazyGenericTypeAlias(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
-
-  static void setHasSelfReference(GenericTypeAlias node, bool value) {
-    node.setProperty(_hasSelfReferenceKey, value);
-  }
-}
-
-class LazyMethodDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBody = false;
-  bool _hasDocumentationComment = false;
-  bool _hasFormalParameters = false;
-  bool _hasMetadata = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = false;
-  bool _hasTypeInferenceError = false;
-
-  LazyMethodDeclaration(this.data);
-
-  static LazyMethodDeclaration get(MethodDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static DartType getReturnType(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnType) {
-      var type = reader.readType(lazy.data.actualReturnType);
-      LazyAst.setReturnType(node, type);
-      lazy._hasReturnType = true;
-    }
-    return LazyAst.getReturnType(node);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeInferenceError) {
-      var error = lazy.data.topLevelTypeInferenceError;
-      LazyAst.setTypeInferenceError(node, error);
-      lazy._hasTypeInferenceError = true;
-    }
-    return LazyAst.getTypeInferenceError(node);
-  }
-
-  static bool isAbstract(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isAbstract(lazy.data.flags);
-    } else {
-      return node.isAbstract;
-    }
-  }
-
-  static bool isAsynchronous(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isAsync(lazy.data.flags);
-    } else {
-      return node.body.isAsynchronous;
-    }
-  }
-
-  static bool isGenerator(MethodDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.isGenerator(lazy.data.flags);
-    } else {
-      return node.body.isGenerator;
-    }
-  }
-
-  static void readBody(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBody) {
-      node.body = reader.readNode(
-        lazy.data.methodDeclaration_body,
-      );
-      lazy._hasBody = true;
-    }
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readFormalParameters(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasFormalParameters) {
-      node.parameters = reader.readNode(
-        lazy.data.methodDeclaration_formalParameters,
-      );
-      lazy._hasFormalParameters = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readReturnTypeNode(
-    AstBinaryReader reader,
-    MethodDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.methodDeclaration_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(MethodDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyMethodDeclaration(data));
-  }
-}
-
-class LazyMixinDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasOnClause = false;
-  bool _hasImplementsClause = false;
-  bool _hasMembers = false;
-  bool _hasMetadata = false;
-
-  List<String> _superInvokedNames;
-
-  LazyMixinDeclaration(MixinDeclaration node, this.data) {
-    node.setProperty(_key, this);
-    if (data != null) {
-      LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-    }
-  }
-
-  List<String> getSuperInvokedNames() {
-    return _superInvokedNames ??= data.mixinDeclaration_superInvokedNames;
-  }
-
-  void put(LinkedNodeBuilder builder) {
-    builder.mixinDeclaration_superInvokedNames = _superInvokedNames ?? [];
-  }
-
-  void setSuperInvokedNames(List<String> value) {
-    _superInvokedNames = value;
-  }
-
-  static LazyMixinDeclaration get(MixinDeclaration node) {
-    LazyMixinDeclaration lazy = node.getProperty(_key);
-    if (lazy == null) {
-      return LazyMixinDeclaration(node, null);
-    }
-    return lazy;
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readImplementsClause(
-    AstBinaryReader reader,
-    MixinDeclarationImpl node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasImplementsClause) {
-      node.implementsClause = reader.readNode(
-        lazy.data.classOrMixinDeclaration_implementsClause,
-      );
-      lazy._hasImplementsClause = true;
-    }
-  }
-
-  static void readMembers(
-    AstBinaryReader reader,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasMembers) {
-      var dataList = lazy.data.classOrMixinDeclaration_members;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.members[i] = reader.readNode(data);
-      }
-      lazy._hasMembers = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    MixinDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void readOnClause(
-    AstBinaryReader reader,
-    MixinDeclarationImpl node,
-  ) {
-    var lazy = get(node);
-    if (lazy.data != null && !lazy._hasOnClause) {
-      node.onClause = reader.readNode(
-        lazy.data.mixinDeclaration_onClause,
-      );
-      lazy._hasOnClause = true;
-    }
-  }
-}
-
-class LazyTopLevelVariableDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasDocumentationComment = false;
-  bool _hasMetadata = false;
-
-  LazyTopLevelVariableDeclaration(this.data);
-
-  static LazyTopLevelVariableDeclaration get(TopLevelVariableDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static void readDocumentationComment(
-    LinkedUnitContext context,
-    TopLevelVariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
-      node.documentationComment = context.createComment(lazy.data);
-      lazy._hasDocumentationComment = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    TopLevelVariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(TopLevelVariableDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyTopLevelVariableDeclaration(data));
-  }
-}
-
-class LazyTypeParameter {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasBound = false;
-  bool _hasDefaultType = false;
-  bool _hasMetadata = false;
-
-  LazyTypeParameter(this.data);
-
-  static LazyTypeParameter get(TypeParameter node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    TypeParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    return node.length;
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    TypeParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    return node.offset;
-  }
-
-  static DartType getDefaultType(AstBinaryReader reader, TypeParameter node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasDefaultType) {
-      lazy._hasDefaultType = true;
-      var type = reader.readType(lazy.data.typeParameter_defaultType);
-      LazyAst.setDefaultType(node, type);
-      return type;
-    }
-    return LazyAst.getDefaultType(node);
-  }
-
-  static void readBound(AstBinaryReader reader, TypeParameter node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasBound) {
-      node.bound = reader.readNode(lazy.data.typeParameter_bound);
-      lazy._hasBound = true;
-    }
-  }
-
-  static void readMetadata(
-    AstBinaryReader reader,
-    TypeParameter node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasMetadata) {
-      var dataList = lazy.data.annotatedNode_metadata;
-      for (var i = 0; i < dataList.length; ++i) {
-        var data = dataList[i];
-        node.metadata[i] = reader.readNode(data);
-      }
-      lazy._hasMetadata = true;
-    }
-  }
-
-  static void setData(TypeParameter node, LinkedNode data) {
-    node.setProperty(_key, LazyTypeParameter(data));
-  }
-}
-
-class LazyVariableDeclaration {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasInitializer = false;
-  bool _hasType = false;
-  bool _hasTypeInferenceError = false;
-
-  LazyVariableDeclaration(this.data);
-
-  static LazyVariableDeclaration get(VariableDeclaration node) {
-    return node.getProperty(_key);
-  }
-
-  static int getCodeLength(
-    LinkedUnitContext context,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeLength ?? 0;
-    }
-    VariableDeclarationList parent = node.parent;
-    if (parent.variables[0] == node) {
-      return node.end - parent.offset;
-    } else {
-      return node.end - node.offset;
-    }
-  }
-
-  static int getCodeOffset(
-    LinkedUnitContext context,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
-    }
-    VariableDeclarationList parent = node.parent;
-    if (parent.variables[0] == node) {
-      return parent.offset;
-    } else {
-      return node.offset;
-    }
-  }
-
-  static DartType getType(
-    AstBinaryReader reader,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasType) {
-      var type = reader.readType(lazy.data.actualType);
-      LazyAst.setType(node, type);
-      lazy._hasType = true;
-    }
-    return LazyAst.getType(node);
-  }
-
-  static TopLevelInferenceError getTypeInferenceError(
-      VariableDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeInferenceError) {
-      var error = lazy.data.topLevelTypeInferenceError;
-      LazyAst.setTypeInferenceError(node, error);
-      lazy._hasTypeInferenceError = true;
-    }
-    return LazyAst.getTypeInferenceError(node);
-  }
-
-  static bool hasInitializer(VariableDeclaration node) {
-    var lazy = get(node);
-    if (lazy != null) {
-      return AstBinaryFlags.hasInitializer(lazy.data.flags);
-    } else {
-      return node.initializer != null;
-    }
-  }
-
-  static void readInitializer(
-    AstBinaryReader reader,
-    VariableDeclaration node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasInitializer) {
-      node.initializer = reader.readNode(
-        lazy.data.variableDeclaration_initializer,
-      );
-      lazy._hasInitializer = true;
-    }
-  }
-
-  static void setData(VariableDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyVariableDeclaration(data));
-  }
-}
-
-class LazyVariableDeclarationList {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasTypeNode = false;
-
-  LazyVariableDeclarationList(this.data);
-
-  static LazyVariableDeclarationList get(VariableDeclarationList node) {
-    return node.getProperty(_key);
-  }
-
-  static void readTypeNode(
-    AstBinaryReader reader,
-    VariableDeclarationList node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasTypeNode) {
-      node.type = reader.readNode(
-        lazy.data.variableDeclarationList_type,
-      );
-      lazy._hasTypeNode = true;
-    }
-  }
-
-  static void setData(VariableDeclarationList node, LinkedNode data) {
-    node.setProperty(_key, LazyVariableDeclarationList(data));
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 14ab9ad3..cb2155b0b 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -4,19 +4,17 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart' as ast;
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/scope.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/combinator.dart';
 import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
 import 'package:analyzer/src/summary2/default_value_resolver.dart';
 import 'package:analyzer/src/summary2/export.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/metadata_resolver.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -28,7 +26,7 @@
   final Linker linker;
   final Uri uri;
   final Reference reference;
-  final LinkedNodeLibraryBuilder node;
+  List<Reference> exports;
 
   LinkedLibraryContext context;
 
@@ -43,11 +41,11 @@
 
   final List<Export> exporters = [];
 
-  LibraryBuilder(this.linker, this.uri, this.reference, this.node);
+  LibraryBuilder._(this.linker, this.uri, this.reference);
 
   void addExporters() {
-    var unitContext = context.units[0];
-    for (var directive in unitContext.unit_withDirectives.directives) {
+    var unitContext = context.definingUnit;
+    for (var directive in unitContext.unit.directives) {
       if (directive is ast.ExportDirective) {
         Uri uri;
         try {
@@ -89,8 +87,8 @@
 
   /// Add top-level declaration of the library units to the local scope.
   void addLocalDeclarations() {
-    for (var unitContext in context.units) {
-      var unitRef = reference.getChild('@unit').getChild(unitContext.uriStr);
+    for (var linkingUnit in context.units) {
+      var unitRef = reference.getChild('@unit').getChild(linkingUnit.uriStr);
       var classRef = unitRef.getChild('@class');
       var enumRef = unitRef.getChild('@enum');
       var extensionRef = unitRef.getChild('@extension');
@@ -101,26 +99,34 @@
       var setterRef = unitRef.getChild('@setter');
       var variableRef = unitRef.getChild('@variable');
       var nextUnnamedExtensionId = 0;
-      for (var node in unitContext.unit.declarations) {
+      for (var node in linkingUnit.unit.declarations) {
         if (node is ast.ClassDeclaration) {
           var name = node.name.name;
           var reference = classRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          ClassElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.ClassTypeAlias) {
           var name = node.name.name;
           var reference = classRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          ClassElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.EnumDeclaration) {
           var name = node.name.name;
           var reference = enumRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          EnumElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.ExtensionDeclaration) {
           var name = node.name?.name;
           var refName = name ?? 'extension-${nextUnnamedExtensionId++}';
-          LazyExtensionDeclaration.get(node).setRefName(refName);
 
           var reference = extensionRef.getChild(refName);
           reference.node ??= node;
@@ -128,19 +134,27 @@
           if (name != null) {
             localScope.declare(name, reference);
           }
+
+          ExtensionElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.FunctionDeclaration) {
           var name = node.name.name;
 
-          Reference containerRef;
+          Reference reference;
           if (node.isGetter) {
-            containerRef = getterRef;
+            reference = getterRef.getChild(name);
+            PropertyAccessorElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, node);
           } else if (node.isSetter) {
-            containerRef = setterRef;
+            reference = setterRef.getChild(name);
+            PropertyAccessorElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, node);
           } else {
-            containerRef = functionRef;
+            reference = functionRef.getChild(name);
+            FunctionElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, node);
           }
 
-          var reference = containerRef.getChild(name);
           reference.node ??= node;
 
           if (node.isSetter) {
@@ -152,19 +166,27 @@
           var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
           reference.node ??= node;
-
           localScope.declare(name, reference);
+
+          TypeAliasElementImpl.forLinkedNodeFactory(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.GenericTypeAlias) {
           var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
-          reference.node = node;
+          reference.node ??= node;
 
           localScope.declare(name, reference);
+
+          TypeAliasElementImpl.forLinkedNodeFactory(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.MixinDeclaration) {
           var name = node.name.name;
           var reference = mixinRef.getChild(name);
           reference.node ??= node;
           localScope.declare(name, reference);
+
+          MixinElementImpl.forLinkedNode(
+              linkingUnit.reference.element, reference, node);
         } else if (node is ast.TopLevelVariableDeclaration) {
           for (var variable in node.variables.variables) {
             var name = variable.name.name;
@@ -172,6 +194,9 @@
             var reference = variableRef.getChild(name);
             reference.node ??= node;
 
+            TopLevelVariableElementImpl.forLinkedNode(
+                linkingUnit.reference.element, reference, variable);
+
             var getter = getterRef.getChild(name);
             localScope.declare(name, getter);
 
@@ -181,7 +206,6 @@
             }
           }
         } else {
-          // TODO(scheglov) implement
           throw UnimplementedError('${node.runtimeType}');
         }
       }
@@ -207,9 +231,50 @@
     return true;
   }
 
+  void buildDirectives() {
+    var exports = <ExportElement>[];
+    var imports = <ImportElement>[];
+    var hasCoreImport = false;
+
+    // Build elements directives in all units.
+    // Store elements only for the defining unit of the library.
+    var isDefiningUnit = true;
+    for (var unitContext in context.units) {
+      for (var node in unitContext.unit.directives) {
+        if (node is ast.ExportDirective) {
+          var exportElement = ExportElementImpl.forLinkedNode(element, node);
+          if (isDefiningUnit) {
+            exports.add(exportElement);
+          }
+        } else if (node is ast.ImportDirective) {
+          var importElement = ImportElementImpl.forLinkedNode(element, node);
+          if (isDefiningUnit) {
+            imports.add(importElement);
+            hasCoreImport |= importElement.importedLibrary?.isDartCore ?? false;
+          }
+        }
+      }
+      isDefiningUnit = false;
+    }
+
+    element.exports = exports;
+
+    if (!hasCoreImport) {
+      var dartCore = linker.elementFactory.libraryOfUri('dart:core');
+      imports.add(
+        ImportElementImpl(-1)
+          ..importedLibrary = dartCore
+          ..isSynthetic = true
+          ..uri = 'dart:core',
+      );
+    }
+    element.imports = imports;
+  }
+
   void buildElement() {
-    element = linker.elementFactory.libraryOfUri('$uri');
-    scope = element.scope;
+    linker.elementFactory.createLibraryElementForLinking(context);
+    element = reference.element;
+    assert(element != null);
   }
 
   void buildInitialExportScope() {
@@ -218,6 +283,10 @@
     });
   }
 
+  void buildScope() {
+    scope = element.scope;
+  }
+
   void collectMixinSuperInvokedNames() {
     for (var unitContext in context.units) {
       for (var declaration in unitContext.unit.declarations) {
@@ -229,8 +298,8 @@
               executable.body.accept(collector);
             }
           }
-          var lazy = LazyMixinDeclaration.get(declaration);
-          lazy.setSuperInvokedNames(names.toList());
+          var element = declaration.declaredElement as MixinElementImpl;
+          element.superInvokedNames = names.toList();
         }
       }
     }
@@ -274,7 +343,14 @@
         try {
           var uri = _selectAbsoluteUri(directive);
           if (uri != null) {
-            LazyDirective.setSelectedUri(directive, '$uri');
+            var library = linker.elementFactory.libraryOfUri('$uri');
+            if (directive is ast.ExportDirective) {
+              var exportElement = directive.element as ExportElementImpl;
+              exportElement.exportedLibrary = library;
+            } else if (directive is ast.ImportDirective) {
+              var importElement = directive.element as ImportElementImpl;
+              importElement.importedLibrary = library;
+            }
           }
         } on FormatException {
           // ignored
@@ -284,11 +360,14 @@
   }
 
   void storeExportScope() {
-    var linkingBundleContext = linker.linkingBundleContext;
-    for (var reference in exportScope.map.values) {
-      var index = linkingBundleContext.indexOfReference(reference);
-      node.exports.add(index);
-    }
+    exports = exportScope.map.values.toList();
+    linker.elementFactory.linkingExports['$uri'] = exports;
+
+    // TODO(scheglov) store for serialization
+    // for (var reference in exportScope.map.values) {
+    //   var index = linkingBundleContext.indexOfReference(reference);
+    //   context.exports.add(index);
+    // }
   }
 
   Uri _selectAbsoluteUri(ast.NamespaceDirective directive) {
@@ -318,45 +397,34 @@
   }
 
   static void build(Linker linker, LinkInputLibrary inputLibrary) {
-    var libraryUri = inputLibrary.source.uri;
-    var libraryUriStr = '$libraryUri';
-    var libraryReference = linker.rootReference.getChild(libraryUriStr);
+    var uriStr = inputLibrary.uriStr;
+    var reference = linker.rootReference.getChild(uriStr);
 
-    var libraryNode = LinkedNodeLibraryBuilder(
-      uriStr: libraryUriStr,
-    );
+    var elementFactory = linker.elementFactory;
+    var context = LinkedLibraryContext(elementFactory, uriStr, reference);
 
-    var definingUnit = inputLibrary.units[0].unit;
-    for (var directive in definingUnit.directives) {
-      if (directive is ast.LibraryDirective) {
-        var name = directive.name;
-        libraryNode.name = name.components.map((id) => id.name).join('.');
-        libraryNode.nameOffset = name.offset;
-        libraryNode.nameLength = name.length;
-        break;
-      }
+    var unitRef = reference.getChild('@unit');
+    var unitIndex = 0;
+    for (var inputUnit in inputLibrary.units) {
+      var source = inputUnit.source;
+      var uriStr = source != null ? '${source.uri}' : '';
+      var reference = unitRef.getChild(uriStr);
+      context.units.add(
+        LinkedUnitContext(
+          context,
+          unitIndex++,
+          inputUnit.partUriStr,
+          uriStr,
+          reference,
+          inputUnit.isSynthetic,
+          unit: inputUnit.unit,
+          unitReader: null,
+        ),
+      );
     }
 
-    var builder = LibraryBuilder(
-      linker,
-      libraryUri,
-      libraryReference,
-      libraryNode,
-    );
+    var builder = LibraryBuilder._(linker, inputLibrary.uri, reference);
     linker.builders[builder.uri] = builder;
-
-    builder.context = linker.bundleContext.addLinkingLibrary(
-      libraryUriStr,
-      libraryNode,
-      inputLibrary,
-    );
+    builder.context = context;
   }
 }
-
-class UnitBuilder {
-  final Uri uri;
-  final LinkedUnitContext context;
-  final LinkedNode node;
-
-  UnitBuilder(this.uri, this.context, this.node);
-}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 281f0dc..96e45c6 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -2,24 +2,24 @@
 // for details. 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:typed_data';
+
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary2/ast_binary_writer.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
 import 'package:analyzer/src/summary2/library_builder.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/simply_bounded.dart';
 import 'package:analyzer/src/summary2/top_level_inference.dart';
 import 'package:analyzer/src/summary2/type_alias.dart';
 import 'package:analyzer/src/summary2/types_builder.dart';
 import 'package:analyzer/src/summary2/variance_builder.dart';
+import 'package:meta/meta.dart';
 
 var timerLinkingLinkingBundle = Stopwatch();
 var timerLinkingRemoveBundle = Stopwatch();
@@ -27,34 +27,30 @@
 LinkResult link(
   LinkedElementFactory elementFactory,
   List<LinkInputLibrary> inputLibraries,
+  bool withInformative,
 ) {
-  var linker = Linker(elementFactory);
+  var linker = Linker(elementFactory, withInformative);
   linker.link(inputLibraries);
-  return LinkResult(linker.linkingBundle);
+  return LinkResult(
+    astBytes: linker.astBytes,
+    resolutionBytes: linker.resolutionBytes,
+  );
 }
 
 class Linker {
   final LinkedElementFactory elementFactory;
-
-  LinkedNodeBundleBuilder linkingBundle;
-  LinkedBundleContext bundleContext;
-  LinkingBundleContext linkingBundleContext;
+  final bool withInformative;
 
   /// Libraries that are being linked.
   final Map<Uri, LibraryBuilder> builders = {};
 
   InheritanceManager3 inheritance; // TODO(scheglov) cache it
 
-  Linker(this.elementFactory) {
-    linkingBundleContext = LinkingBundleContext(
-      elementFactory.dynamicRef,
-    );
+  BundleWriter bundleWriter;
+  Uint8List astBytes;
+  Uint8List resolutionBytes;
 
-    bundleContext = LinkedBundleContext.forAst(
-      elementFactory,
-      linkingBundleContext.references,
-    );
-  }
+  Linker(this.elementFactory, this.withInformative);
 
   AnalysisContextImpl get analysisContext {
     return elementFactory.analysisContext;
@@ -67,30 +63,33 @@
   Reference get rootReference => elementFactory.rootReference;
 
   void link(List<LinkInputLibrary> inputLibraries) {
+    bundleWriter = BundleWriter(
+      withInformative,
+      elementFactory.dynamicRef,
+    );
+    _writeAst(inputLibraries);
+
     for (var inputLibrary in inputLibraries) {
       LibraryBuilder.build(this, inputLibrary);
     }
-    // TODO(scheglov) do in build() ?
-    elementFactory.addBundle(bundleContext);
 
     _buildOutlines();
 
     timerLinkingLinkingBundle.start();
-    _createLinkingBundle();
+    _writeResolution();
     timerLinkingLinkingBundle.stop();
 
     timerLinkingRemoveBundle.start();
-    linkingBundleContext.clearIndexes();
-    elementFactory.removeBundle(bundleContext);
+    elementFactory.removeBundle(
+      inputLibraries.map((e) => e.uriStr).toSet(),
+    );
     timerLinkingRemoveBundle.stop();
   }
 
   void _buildOutlines() {
-    _resolveUriDirectives();
     _computeLibraryScopes();
     _createTypeSystem();
     _resolveTypes();
-    TypeAliasSelfReferenceFinder().perform(this);
     _performTopLevelInference();
     _resolveConstructors();
     _resolveConstantInitializers();
@@ -107,10 +106,19 @@
 
   void _computeLibraryScopes() {
     for (var library in builders.values) {
+      library.buildElement();
+    }
+
+    for (var library in builders.values) {
+      library.buildDirectives();
       library.addLocalDeclarations();
     }
 
     for (var library in builders.values) {
+      library.resolveUriDirectives();
+    }
+
+    for (var library in builders.values) {
       library.buildInitialExportScope();
     }
 
@@ -159,36 +167,10 @@
     }
 
     for (var library in builders.values) {
-      library.buildElement();
+      library.buildScope();
     }
   }
 
-  void _createLinkingBundle() {
-    var linkingLibraries = <LinkedNodeLibraryBuilder>[];
-    for (var builder in builders.values) {
-      linkingLibraries.add(builder.node);
-
-      for (var unitContext in builder.context.units) {
-        var unit = unitContext.unit;
-
-        var writer = AstBinaryWriter(linkingBundleContext);
-        var unitLinkedNode = writer.writeUnit(unit);
-        builder.node.units.add(
-          LinkedNodeUnitBuilder(
-            isSynthetic: unitContext.isSynthetic,
-            partUriStr: unitContext.partUriStr,
-            uriStr: unitContext.uriStr,
-            node: unitLinkedNode,
-          ),
-        );
-      }
-    }
-    linkingBundle = LinkedNodeBundleBuilder(
-      references: linkingBundleContext.referencesBuilder,
-      libraries: linkingLibraries,
-    );
-  }
-
   void _createTypeSystem() {
     var coreLib = elementFactory.libraryOfUri('dart:core');
     var asyncLib = elementFactory.libraryOfUri('dart:async');
@@ -229,15 +211,47 @@
       library.resolveTypes(nodesToBuildType);
     }
     VarianceBuilder().perform(this);
-    computeSimplyBounded(bundleContext, builders.values);
+    computeSimplyBounded(builders.values);
+    TypeAliasSelfReferenceFinder().perform(this);
     TypesBuilder().build(nodesToBuildType);
   }
 
-  void _resolveUriDirectives() {
-    for (var library in builders.values) {
-      library.resolveUriDirectives();
+  void _writeAst(List<LinkInputLibrary> inputLibraries) {
+    for (var inputLibrary in inputLibraries) {
+      bundleWriter.addLibraryAst(
+        LibraryToWriteAst(
+          units: inputLibrary.units.map((e) {
+            return UnitToWriteAst(
+              node: e.unit,
+            );
+          }).toList(),
+        ),
+      );
     }
   }
+
+  void _writeResolution() {
+    for (var builder in builders.values) {
+      bundleWriter.addLibraryResolution(
+        LibraryToWriteResolution(
+          uriStr: '${builder.uri}',
+          exports: builder.exports,
+          units: builder.context.units.map((e) {
+            return UnitToWriteResolution(
+              uriStr: e.uriStr,
+              partUriStr: e.partUriStr,
+              node: e.unit,
+              isSynthetic: e.isSynthetic,
+            );
+          }).toList(),
+        ),
+      );
+    }
+
+    var writeWriterResult = bundleWriter.finish();
+    astBytes = writeWriterResult.astBytes;
+    resolutionBytes = writeWriterResult.resolutionBytes;
+  }
 }
 
 class LinkInputLibrary {
@@ -245,6 +259,10 @@
   final List<LinkInputUnit> units;
 
   LinkInputLibrary(this.source, this.units);
+
+  Uri get uri => source.uri;
+
+  String get uriStr => '$uri';
 }
 
 class LinkInputUnit {
@@ -259,10 +277,21 @@
     this.isSynthetic,
     this.unit,
   );
+
+  String get uriStr {
+    if (source == null) {
+      return '';
+    }
+    return '${source.uri}';
+  }
 }
 
 class LinkResult {
-  final LinkedNodeBundleBuilder bundle;
+  final Uint8List astBytes;
+  final Uint8List resolutionBytes;
 
-  LinkResult(this.bundle);
+  LinkResult({
+    @required this.astBytes,
+    @required this.resolutionBytes,
+  });
 }
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
deleted file mode 100644
index 7047fb0..0000000
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-
-/// The context of a linked bundle, with shared references.
-class LinkedBundleContext {
-  final LinkedElementFactory elementFactory;
-  final LinkedNodeBundle _bundle;
-  final List<Reference> _references;
-  final Map<String, LinkedLibraryContext> libraryMap = {};
-
-  LinkedBundleContext(this.elementFactory, this._bundle)
-      : _references = List<Reference>(_bundle.references.name.length) {
-    for (var library in _bundle.libraries) {
-      var uriStr = library.uriStr;
-      var reference = elementFactory.rootReference.getChild(uriStr);
-      var libraryContext = LinkedLibraryContext(
-        this,
-        uriStr,
-        reference,
-        library,
-      );
-      libraryMap[uriStr] = libraryContext;
-
-      var unitRef = reference.getChild('@unit');
-      var units = library.units;
-      for (var unitIndex = 0; unitIndex < units.length; ++unitIndex) {
-        var unit = units[unitIndex];
-        var uriStr = unit.uriStr;
-        var reference = unitRef.getChild(uriStr);
-        var unitContext = LinkedUnitContext(
-          this,
-          libraryContext,
-          unitIndex,
-          unit.partUriStr,
-          uriStr,
-          reference,
-          unit.isSynthetic,
-          unit,
-        );
-        libraryContext.units.add(unitContext);
-      }
-    }
-  }
-
-  LinkedBundleContext.forAst(this.elementFactory, this._references)
-      : _bundle = null;
-
-  /// Return `true` if this bundle is being linked.
-  bool get isLinking => _bundle == null;
-
-  LinkedLibraryContext addLinkingLibrary(
-    String uriStr,
-    LinkedNodeLibraryBuilder data,
-    LinkInputLibrary inputLibrary,
-  ) {
-    var uriStr = data.uriStr;
-    var reference = elementFactory.rootReference.getChild(uriStr);
-    var libraryContext = LinkedLibraryContext(this, uriStr, reference, data);
-    libraryMap[uriStr] = libraryContext;
-
-    var unitRef = reference.getChild('@unit');
-    var unitIndex = 0;
-    for (var inputUnit in inputLibrary.units) {
-      var source = inputUnit.source;
-      var uriStr = source != null ? '${source.uri}' : '';
-      var reference = unitRef.getChild(uriStr);
-      createInformativeData(inputUnit.unit);
-      libraryContext.units.add(
-        LinkedUnitContext(
-          this,
-          libraryContext,
-          unitIndex++,
-          inputUnit.partUriStr,
-          uriStr,
-          reference,
-          inputUnit.isSynthetic,
-          null,
-          unit: inputUnit.unit,
-        ),
-      );
-    }
-    return libraryContext;
-  }
-
-  T elementOfIndex<T extends Element>(int index) {
-    var reference = referenceOfIndex(index);
-    return elementFactory.elementOfReference(reference);
-  }
-
-  List<T> elementsOfIndexes<T extends Element>(List<int> indexList) {
-    var result = List<T>(indexList.length);
-    for (var i = 0; i < indexList.length; ++i) {
-      var index = indexList[i];
-      result[i] = elementOfIndex(index);
-    }
-    return result;
-  }
-
-  Reference referenceOfIndex(int index) {
-    var reference = _references[index];
-    if (reference != null) return reference;
-
-    if (index == 0) {
-      reference = elementFactory.rootReference;
-      _references[index] = reference;
-      return reference;
-    }
-
-    var parentIndex = _bundle.references.parent[index];
-    var parent = referenceOfIndex(parentIndex);
-
-    var name = _bundle.references.name[index];
-    reference = parent.getChild(name);
-    _references[index] = reference;
-
-    return reference;
-  }
-}
-
-class LinkedLibraryContext {
-  final LinkedBundleContext context;
-  final String uriStr;
-  final Reference reference;
-  final LinkedNodeLibrary node;
-  final List<LinkedUnitContext> units = [];
-
-  LinkedLibraryContext(this.context, this.uriStr, this.reference, this.node);
-
-  LinkedUnitContext get definingUnit => units.first;
-}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index abfaeec..0e9ad99 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -9,9 +9,8 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 
@@ -19,7 +18,8 @@
   final AnalysisContextImpl analysisContext;
   final AnalysisSessionImpl analysisSession;
   final Reference rootReference;
-  final Map<String, LinkedLibraryContext> libraryMap = {};
+  final Map<String, List<Reference>> linkingExports = {};
+  final Map<String, LibraryReader> libraryReaders = {};
 
   LinkedElementFactory(
     this.analysisContext,
@@ -36,11 +36,15 @@
   }
 
   bool get hasDartCore {
-    return libraryMap.containsKey('dart:core');
+    return libraryReaders.containsKey('dart:core');
   }
 
-  void addBundle(LinkedBundleContext context) {
-    libraryMap.addAll(context.libraryMap);
+  void addBundle(BundleReader bundle) {
+    addLibraries(bundle.libraryMap);
+  }
+
+  void addLibraries(Map<String, LibraryReader> libraries) {
+    libraryReaders.addAll(libraries);
   }
 
   Namespace buildExportNamespace(Uri uri) {
@@ -64,6 +68,147 @@
     return Namespace(exportedNames);
   }
 
+  LibraryElementImpl createLibraryElementForLinking(
+    LinkedLibraryContext libraryContext,
+  ) {
+    var sourceFactory = analysisContext.sourceFactory;
+    var libraryUriStr = libraryContext.uriStr;
+    var librarySource = sourceFactory.forUri(libraryUriStr);
+
+    // The URI cannot be resolved, we don't know the library.
+    if (librarySource == null) return null;
+
+    var definingUnitContext = libraryContext.units[0];
+    var definingUnitNode = definingUnitContext.unit;
+
+    // TODO(scheglov) Do we need this?
+    var name = '';
+    var nameOffset = -1;
+    var nameLength = 0;
+    for (var directive in definingUnitNode.directives) {
+      if (directive is LibraryDirective) {
+        name = directive.name.components.map((e) => e.name).join('.');
+        nameOffset = directive.name.offset;
+        nameLength = directive.name.length;
+        break;
+      }
+    }
+
+    var libraryElement = LibraryElementImpl.forLinkedNode(
+      analysisContext,
+      analysisSession,
+      name,
+      nameOffset,
+      nameLength,
+      definingUnitContext,
+      libraryContext.reference,
+      definingUnitNode,
+    );
+    _setLibraryTypeSystem(libraryElement);
+
+    var units = <CompilationUnitElementImpl>[];
+    var unitContainerRef = libraryContext.reference.getChild('@unit');
+    for (var unitContext in libraryContext.units) {
+      var unitNode = unitContext.unit;
+
+      var unitSource = sourceFactory.forUri(unitContext.uriStr);
+      var unitElement = CompilationUnitElementImpl.forLinkedNode(
+        libraryElement,
+        unitContext,
+        unitContext.reference,
+        unitNode,
+      );
+      unitElement.lineInfo = unitNode.lineInfo;
+      unitElement.source = unitSource;
+      unitElement.librarySource = librarySource;
+      unitElement.uri = unitContext.partUriStr;
+      units.add(unitElement);
+      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
+    }
+
+    libraryElement.definingCompilationUnit = units[0];
+    libraryElement.parts = units.skip(1).toList();
+    libraryContext.reference.element = libraryElement;
+
+    return libraryElement;
+  }
+
+  LibraryElementImpl createLibraryElementForReading(String uriStr) {
+    var sourceFactory = analysisContext.sourceFactory;
+    var librarySource = sourceFactory.forUri(uriStr);
+
+    // The URI cannot be resolved, we don't know the library.
+    if (librarySource == null) return null;
+
+    var reader = libraryReaders[uriStr];
+    if (reader == null) {
+      throw ArgumentError(
+        'Missing library: $uriStr\n'
+        'Available libraries: ${libraryReaders.keys.toList()}',
+      );
+    }
+
+    var libraryContext = LinkedLibraryContext(this, uriStr, reader.reference);
+    var unitContainerRef = reader.reference.getChild('@unit');
+
+    var unitContexts = <LinkedUnitContext>[];
+    var indexInLibrary = 0;
+    var unitReaders = reader.units;
+    for (var unitReader in unitReaders) {
+      var unitReference = unitContainerRef.getChild(unitReader.uriStr);
+      var unitContext = LinkedUnitContext(
+        libraryContext,
+        indexInLibrary++,
+        unitReader.partUriStr,
+        unitReader.uriStr,
+        unitReference,
+        unitReader.isSynthetic,
+        unit: unitReader.unit,
+        unitReader: unitReader,
+      );
+      unitContexts.add(unitContext);
+      libraryContext.units.add(unitContext);
+    }
+
+    var definingUnitContext = unitContexts[0];
+    var libraryElement = LibraryElementImpl.forLinkedNode(
+      analysisContext,
+      analysisSession,
+      reader.name,
+      reader.nameOffset,
+      reader.nameLength,
+      definingUnitContext,
+      reader.reference,
+      unitReaders.first.unit,
+    );
+    _setLibraryTypeSystem(libraryElement);
+
+    var units = <CompilationUnitElementImpl>[];
+    for (var unitContext in unitContexts) {
+      var unitNode = unitContext.unit;
+
+      var unitSource = sourceFactory.forUri(unitContext.uriStr);
+      var unitElement = CompilationUnitElementImpl.forLinkedNode(
+        libraryElement,
+        unitContext,
+        unitContext.reference,
+        unitNode,
+      );
+      unitElement.lineInfo = unitNode.lineInfo;
+      unitElement.source = unitSource;
+      unitElement.librarySource = librarySource;
+      unitElement.uri = unitContext.partUriStr;
+      units.add(unitElement);
+      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
+    }
+
+    libraryElement.definingCompilationUnit = units[0];
+    libraryElement.parts = units.skip(1).toList();
+    reader.reference.element = libraryElement;
+
+    return libraryElement;
+  }
+
   void createTypeProviders(
     LibraryElementImpl dartCore,
     LibraryElementImpl dartAsync,
@@ -103,34 +248,142 @@
       return null;
     }
 
-    return _ElementRequest(this, reference).elementOfReference(reference);
+    if (reference.isLibrary) {
+      var uriStr = reference.name;
+      return createLibraryElementForReading(uriStr);
+    }
+
+    var parent = reference.parent.parent;
+    var parentElement = elementOfReference(parent);
+
+    // Named formal parameters are created when we apply resolution to the
+    // executable declaration, e.g. a constructor, or a method.
+    if (reference.isParameter) {
+      (parentElement as ExecutableElement).parameters;
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    // The default constructor might be synthetic, and has no node.
+    // TODO(scheglov) We resynthesize all constructors here.
+    if (reference.isConstructor && reference.name == '') {
+      return (parentElement as ClassElement).unnamedConstructor;
+    }
+
+    if (parentElement is EnumElementImpl) {
+      parentElement.constants;
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    if (reference.element != null) {
+      return reference.element;
+    }
+
+    if (reference.isUnit) {
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    if (reference.isPrefix) {
+      (parentElement as LibraryElement).prefixes;
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    // For class, mixin, extension - index members.
+    parent.nodeAccessor.readIndex();
+
+    // For any element - class, method, etc - read the node.
+    var node = reference.nodeAccessor.node;
+
+    if (node is ClassDeclaration) {
+      ClassElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is ClassTypeAlias) {
+      ClassElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is ConstructorDeclaration) {
+      ConstructorElementImpl.forLinkedNode(parentElement, reference, node);
+      var element = reference.element as ConstructorElementImpl;
+      assert(element != null);
+      return element;
+    } else if (node is EnumDeclaration) {
+      EnumElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is ExtensionDeclaration) {
+      ExtensionElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is FieldDeclaration) {
+      var variable = _variableDeclaration(node.fields, reference.name);
+      if (variable.isConst) {
+        ConstFieldElementImpl.forLinkedNode(parentElement, reference, variable);
+      } else {
+        FieldElementImpl.forLinkedNodeFactory(
+            parentElement, reference, variable);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is FunctionDeclaration) {
+      if (node.propertyKeyword != null) {
+        _topLevelPropertyAccessor(parent, parentElement, reference, node);
+      } else {
+        FunctionElementImpl.forLinkedNode(parentElement, reference, node);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is FunctionTypeAlias || node is GenericTypeAlias) {
+      TypeAliasElementImpl.forLinkedNodeFactory(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is MethodDeclaration) {
+      if (node.propertyKeyword != null) {
+        PropertyAccessorElementImpl.forLinkedNode(
+            parentElement, reference, node);
+      } else {
+        MethodElementImpl.forLinkedNode(parentElement, reference, node);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is MixinDeclaration) {
+      MixinElementImpl.forLinkedNode(parentElement, reference, node);
+      assert(reference.element != null);
+      return reference.element;
+    } else if (node is TopLevelVariableDeclaration) {
+      var variable = _variableDeclaration(node.variables, reference.name);
+      if (variable.isConst) {
+        ConstTopLevelVariableElementImpl.forLinkedNode(
+            parentElement, reference, variable);
+      } else {
+        TopLevelVariableElementImpl.forLinkedNode(
+            parentElement, reference, variable);
+      }
+      assert(reference.element != null);
+      return reference.element;
+    }
+
+    throw UnimplementedError('$reference');
   }
 
   List<Reference> exportsOfLibrary(String uriStr) {
-    var library = libraryMap[uriStr];
+    var linkingExportedReferences = linkingExports[uriStr];
+    if (linkingExportedReferences != null) {
+      return linkingExportedReferences;
+    }
+
+    var library = libraryReaders[uriStr];
     if (library == null) return const [];
 
-    // Ask for source to trigger dependency tracking.
-    //
-    // Usually we record a dependency because we request an element from a
-    // library, so we build its library element, so request its source.
-    // However if a library is just exported, and the exporting library is not
-    // imported itself, we just copy references, without computing elements.
-    analysisContext.sourceFactory.forUri(uriStr);
-
-    var exportIndexList = library.node.exports;
-    var exportReferences = List<Reference>(exportIndexList.length);
-    for (var i = 0; i < exportIndexList.length; ++i) {
-      var index = exportIndexList[i];
-      var reference = library.context.referenceOfIndex(index);
-      exportReferences[i] = reference;
-    }
-    return exportReferences;
+    return library.exports;
   }
 
   bool isLibraryUri(String uriStr) {
-    var libraryContext = libraryMap[uriStr];
-    return !libraryContext.definingUnit.hasPartOfDirective;
+    var libraryContext = libraryReaders[uriStr];
+    return !libraryContext.hasPartOfDirective;
   }
 
   LibraryElementImpl libraryOfUri(String uriStr) {
@@ -140,8 +393,7 @@
 
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
-  void removeBundle(LinkedBundleContext context) {
-    var uriStrSet = context.libraryMap.keys.toSet();
+  void removeBundle(Set<String> uriStrSet) {
     removeLibraries(uriStrSet);
 
     // This is the bundle with dart:core and dart:async, based on full ASTs.
@@ -154,10 +406,10 @@
           '${uriStrSet.toList()}',
         );
       }
-      if (libraryMap.isNotEmpty) {
+      if (libraryReaders.isNotEmpty) {
         throw StateError(
           'Expected to link dart:core and dart:async first: '
-          '${libraryMap.keys.toList()}',
+          '${libraryReaders.keys.toList()}',
         );
       }
       analysisContext.clearTypeProvider();
@@ -169,7 +421,8 @@
   /// any session level caches.
   void removeLibraries(Set<String> uriStrSet) {
     for (var uriStr in uriStrSet) {
-      libraryMap.remove(uriStr);
+      libraryReaders.remove(uriStr);
+      linkingExports.remove(uriStr);
       rootReference.removeChild(uriStr);
     }
 
@@ -177,23 +430,6 @@
     analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
   }
 
-  /// Set optional informative data for the unit.
-  void setInformativeData(
-    String libraryUriStr,
-    String unitUriStr,
-    List<UnlinkedInformativeData> informativeData,
-  ) {
-    var libraryContext = libraryMap[libraryUriStr];
-    if (libraryContext != null) {
-      for (var unitContext in libraryContext.units) {
-        if (unitContext.uriStr == unitUriStr) {
-          unitContext.informativeData = informativeData;
-          return;
-        }
-      }
-    }
-  }
-
   void _declareDartCoreDynamicNever() {
     var dartCoreRef = rootReference.getChild('dart:core');
     dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
@@ -218,341 +454,49 @@
 
     libraryElement.createLoadLibraryFunction();
   }
-}
 
-class _ElementRequest {
-  final LinkedElementFactory elementFactory;
-  final Reference input;
-
-  _ElementRequest(this.elementFactory, this.input);
-
-  ElementImpl elementOfReference(Reference reference) {
-    if (reference.element != null) {
-      return reference.element;
-    }
-
-    var parent2 = reference.parent.parent;
-    if (parent2 == null) {
-      return _createLibraryElement(reference);
-    }
-
-    var parentName = reference.parent.name;
-
-    if (parentName == '@class') {
-      var unit = elementOfReference(parent2);
-      return _class(unit, reference);
-    }
-
-    if (parentName == '@constructor') {
-      var class_ = elementOfReference(parent2);
-      return _constructor(class_, reference);
-    }
-
-    if (parentName == '@enum') {
-      var unit = elementOfReference(parent2);
-      return _enum(unit, reference);
-    }
-
-    if (parentName == '@extension') {
-      var unit = elementOfReference(parent2);
-      return _extension(unit, reference);
-    }
-
-    if (parentName == '@field') {
-      var enclosing = elementOfReference(parent2);
-      return _field(enclosing, reference);
-    }
-
-    if (parentName == '@function') {
-      CompilationUnitElementImpl enclosing = elementOfReference(parent2);
-      return _function(enclosing, reference);
-    }
-
-    if (parentName == '@getter' || parentName == '@setter') {
-      var enclosing = elementOfReference(parent2);
-      return _accessor(enclosing, reference);
-    }
-
-    if (parentName == '@method') {
-      var enclosing = elementOfReference(parent2);
-      return _method(enclosing, reference);
-    }
-
-    if (parentName == '@mixin') {
-      var unit = elementOfReference(parent2);
-      return _mixin(unit, reference);
-    }
-
-    if (parentName == '@parameter') {
-      ExecutableElementImpl enclosing = elementOfReference(parent2);
-      return _parameter(enclosing, reference);
-    }
-
-    if (parentName == '@prefix') {
-      LibraryElementImpl enclosing = elementOfReference(parent2);
-      return _prefix(enclosing, reference);
-    }
-
-    if (parentName == '@typeAlias') {
-      var unit = elementOfReference(parent2);
-      return _typeAlias(unit, reference);
-    }
-
-    if (parentName == '@typeParameter') {
-      var enclosing = elementOfReference(parent2);
-      if (enclosing is ParameterElement) {
-        (enclosing as ParameterElement).typeParameters;
-      } else {
-        (enclosing as TypeParameterizedElement).typeParameters;
-      }
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    if (parentName == '@unit') {
-      elementOfReference(parent2);
-      // Creating a library fills all its units.
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    if (reference.name == '@function' && parent2.name == '@typeAlias') {
-      var parent = reference.parent;
-      FunctionTypeAliasElementImpl alias = elementOfReference(parent);
-      return alias.function;
-    }
-
-    throw StateError('Not found: $input');
-  }
-
-  PropertyAccessorElementImpl _accessor(
-      ElementImpl enclosing, Reference reference) {
-    if (enclosing is ClassElementImpl) {
-      enclosing.accessors;
-    } else if (enclosing is CompilationUnitElementImpl) {
-      enclosing.accessors;
-    } else if (enclosing is EnumElementImpl) {
-      enclosing.accessors;
-    } else if (enclosing is ExtensionElementImpl) {
-      enclosing.accessors;
-    } else {
-      throw StateError('${enclosing.runtimeType}');
-    }
-    // Requesting accessors sets elements for accessors and variables.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  ClassElementImpl _class(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    ClassElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  ConstructorElementImpl _constructor(
-      ClassElementImpl enclosing, Reference reference) {
-    enclosing.constructors;
-    // Requesting constructors sets elements for all of them.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  LibraryElementImpl _createLibraryElement(Reference reference) {
-    var uriStr = reference.name;
-
-    var sourceFactory = elementFactory.analysisContext.sourceFactory;
-    var librarySource = sourceFactory.forUri(uriStr);
-
-    // The URI cannot be resolved, we don't know the library.
-    if (librarySource == null) return null;
-
-    var libraryContext = elementFactory.libraryMap[uriStr];
-    if (libraryContext == null) {
-      throw ArgumentError(
-        'Missing library: $uriStr\n'
-        'Available libraries: ${elementFactory.libraryMap.keys.toList()}',
-      );
-    }
-    var libraryNode = libraryContext.node;
-    var hasName = libraryNode.name.isNotEmpty;
-
-    var definingUnitContext = libraryContext.definingUnit;
-
-    var libraryElement = LibraryElementImpl.forLinkedNode(
-      elementFactory.analysisContext,
-      elementFactory.analysisSession,
-      libraryNode.name,
-      hasName ? libraryNode.nameOffset : -1,
-      libraryNode.nameLength,
-      definingUnitContext,
-      reference,
-      definingUnitContext.unit_withDeclarations,
-    );
-    elementFactory._setLibraryTypeSystem(libraryElement);
-
-    var units = <CompilationUnitElementImpl>[];
-    var unitContainerRef = reference.getChild('@unit');
-    for (var unitContext in libraryContext.units) {
-      var unitNode = unitContext.unit_withDeclarations;
-
-      var unitSource = sourceFactory.forUri(unitContext.uriStr);
-      var unitElement = CompilationUnitElementImpl.forLinkedNode(
-        libraryElement,
-        unitContext,
-        unitContext.reference,
-        unitNode,
-      );
-      unitElement.lineInfo = unitNode.lineInfo;
-      unitElement.source = unitSource;
-      unitElement.librarySource = librarySource;
-      unitElement.uri = unitContext.partUriStr;
-      units.add(unitElement);
-      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
-    }
-
-    libraryElement.definingCompilationUnit = units[0];
-    libraryElement.parts = units.skip(1).toList();
-    reference.element = libraryElement;
-
-    return libraryElement;
-  }
-
-  EnumElementImpl _enum(CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    EnumElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  ExtensionElementImpl _extension(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    ExtensionElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  FieldElementImpl _field(ClassElementImpl enclosing, Reference reference) {
-    enclosing.fields;
-    // Requesting fields sets elements for all fields.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  Element _function(CompilationUnitElementImpl enclosing, Reference reference) {
-    enclosing.functions;
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  void _indexUnitElementDeclarations(CompilationUnitElementImpl unit) {
-    var unitContext = unit.linkedContext;
-    var unitRef = unit.reference;
-    var unitNode = unit.linkedNode;
-    _indexUnitDeclarations(unitContext, unitRef, unitNode);
-  }
-
-  MethodElementImpl _method(ElementImpl enclosing, Reference reference) {
-    if (enclosing is ClassElementImpl) {
-      enclosing.methods;
-    } else if (enclosing is ExtensionElementImpl) {
-      enclosing.methods;
-    } else {
-      throw StateError('${enclosing.runtimeType}');
-    }
-    // Requesting methods sets elements for all of them.
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  MixinElementImpl _mixin(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    MixinElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  Element _parameter(ExecutableElementImpl enclosing, Reference reference) {
-    enclosing.parameters;
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  PrefixElementImpl _prefix(LibraryElementImpl library, Reference reference) {
-    for (var import in library.imports) {
-      import.prefix;
-    }
-    assert(reference.element != null);
-    return reference.element;
-  }
-
-  FunctionTypeAliasElementImpl _typeAlias(
-      CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
-      _indexUnitElementDeclarations(unit);
-      assert(reference.node != null, '$reference');
-    }
-    FunctionTypeAliasElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
-  }
-
-  /// Index nodes for which we choose to create elements individually,
-  /// for example [ClassDeclaration], so that its [Reference] has the node,
-  /// and we can call the [ClassElementImpl] constructor.
-  static void _indexUnitDeclarations(
-    LinkedUnitContext unitContext,
-    Reference unitRef,
-    CompilationUnit unitNode,
+  void _topLevelPropertyAccessor(
+    Reference parentReference,
+    CompilationUnitElementImpl parentElement,
+    Reference reference,
+    FunctionDeclaration node,
   ) {
-    var classRef = unitRef.getChild('@class');
-    var enumRef = unitRef.getChild('@enum');
-    var extensionRef = unitRef.getChild('@extension');
-    var functionRef = unitRef.getChild('@function');
-    var mixinRef = unitRef.getChild('@mixin');
-    var typeAliasRef = unitRef.getChild('@typeAlias');
-    var variableRef = unitRef.getChild('@variable');
-    for (var declaration in unitNode.declarations) {
-      if (declaration is ClassDeclaration) {
-        var name = declaration.name.name;
-        classRef.getChild(name).node = declaration;
-      } else if (declaration is ClassTypeAlias) {
-        var name = declaration.name.name;
-        classRef.getChild(name).node = declaration;
-      } else if (declaration is ExtensionDeclaration) {
-        var refName = LazyExtensionDeclaration.get(declaration).refName;
-        extensionRef.getChild(refName).node = declaration;
-      } else if (declaration is EnumDeclaration) {
-        var name = declaration.name.name;
-        enumRef.getChild(name).node = declaration;
-      } else if (declaration is FunctionDeclaration) {
-        var name = declaration.name.name;
-        functionRef.getChild(name).node = declaration;
-      } else if (declaration is FunctionTypeAlias) {
-        var name = declaration.name.name;
-        typeAliasRef.getChild(name).node = declaration;
-      } else if (declaration is GenericTypeAlias) {
-        var name = declaration.name.name;
-        typeAliasRef.getChild(name).node = declaration;
-      } else if (declaration is MixinDeclaration) {
-        var name = declaration.name.name;
-        mixinRef.getChild(name).node = declaration;
-      } else if (declaration is TopLevelVariableDeclaration) {
-        for (var variable in declaration.variables.variables) {
-          var name = variable.name.name;
-          variableRef.getChild(name).node = declaration;
-        }
+    var accessor = PropertyAccessorElementImpl.forLinkedNode(
+        parentElement, reference, node);
+
+    var name = reference.name;
+    var fieldRef = parentReference.getChild('@field').getChild(name);
+    var field = fieldRef.element as TopLevelVariableElementImpl;
+    if (field == null) {
+      field = TopLevelVariableElementImpl(name, -1);
+      fieldRef.element = field;
+      field.enclosingElement = parentElement;
+      field.isFinal = true;
+      field.isSynthetic = true;
+    }
+
+    var isSetter = node.isSetter;
+    if (isSetter) {
+      field.isFinal = false;
+    }
+
+    accessor.variable = field;
+    if (isSetter) {
+      field.setter = accessor;
+    } else {
+      field.getter = accessor;
+    }
+  }
+
+  static VariableDeclaration _variableDeclaration(
+    VariableDeclarationList variableList,
+    String name,
+  ) {
+    for (var variable in variableList.variables) {
+      if (variable.name.name == name) {
+        return variable;
       }
     }
+    throw StateError('No "$name" in: $variableList');
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/linked_library_context.dart b/pkg/analyzer/lib/src/summary2/linked_library_context.dart
new file mode 100644
index 0000000..e9c7e77
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/linked_library_context.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+
+class LinkedLibraryContext {
+  final LinkedElementFactory elementFactory;
+  final String uriStr;
+  final Reference reference;
+  final List<LinkedUnitContext> units = [];
+
+  LinkedLibraryContext(this.elementFactory, this.uriStr, this.reference);
+
+  LinkedUnitContext get definingUnit => units.first;
+}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ff54b07..cf7722d 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -3,69 +3,41 @@
 // 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/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/type_builder.dart';
+import 'package:meta/meta.dart';
 
 /// The context of a unit - the context of the bundle, and the unit tokens.
 class LinkedUnitContext {
-  final LinkedBundleContext bundleContext;
   final LinkedLibraryContext libraryContext;
   final int indexInLibrary;
   final String partUriStr;
   final String uriStr;
   final Reference reference;
   final bool isSynthetic;
-  final LinkedNodeUnit data;
+  final CompilationUnit unit;
+  final UnitReader unitReader;
 
-  /// Optional informative data for the unit.
-  List<UnlinkedInformativeData> informativeData;
-
-  AstBinaryReader _astReader;
-
-  CompilationUnit _unit;
   bool _hasDirectivesRead = false;
 
-  /// Mapping from identifiers to synthetic type parameters.
-  ///
-  /// Synthetic type parameters are added when [readType] begins reading a
-  /// [FunctionType], and removed when reading is done.
-  final Map<int, TypeParameterElementImpl> _typeParameters = {};
+  LinkedUnitContext(this.libraryContext, this.indexInLibrary, this.partUriStr,
+      this.uriStr, this.reference, this.isSynthetic,
+      {@required this.unit, @required this.unitReader});
 
-  int _nextSyntheticTypeParameterId = 0x10000;
-
-  LinkedUnitContext(
-      this.bundleContext,
-      this.libraryContext,
-      this.indexInLibrary,
-      this.partUriStr,
-      this.uriStr,
-      this.reference,
-      this.isSynthetic,
-      this.data,
-      {CompilationUnit unit}) {
-    _astReader = AstBinaryReader(this);
-    _astReader.isLazy = unit == null;
-
-    _unit = unit;
-    _hasDirectivesRead = _unit != null;
+  CompilationUnitElementImpl get element {
+    return reference.element;
   }
 
+  LinkedElementFactory get elementFactory => libraryContext.elementFactory;
+
   bool get hasPartOfDirective {
     for (var directive in unit_withDirectives.directives) {
       if (directive is PartOfDirective) {
@@ -76,7 +48,7 @@
   }
 
   /// Return `true` if this unit is a part of a bundle that is being linked.
-  bool get isLinking => bundleContext.isLinking;
+  bool get isLinking => unitReader == null;
 
   TypeProvider get typeProvider {
     var libraryReference = libraryContext.reference;
@@ -84,37 +56,42 @@
     return libraryElement.typeProvider;
   }
 
-  CompilationUnit get unit => _unit;
-
   CompilationUnit get unit_withDeclarations {
-    _ensureUnitWithDeclarations();
-    return _unit;
+    unitReader?.readDeclarations();
+    return unit;
   }
 
+  /// Ensure that [unit] has directives ready (because we are linking,
+  /// and so always have full AST, or, if we are reading, we make sure
+  /// that we have them read).
   CompilationUnit get unit_withDirectives {
-    _ensureUnitWithDeclarations();
-    if (!_hasDirectivesRead) {
-      var directiveDataList = data.node.compilationUnit_directives;
-      for (var i = 0; i < directiveDataList.length; ++i) {
-        var directiveData = directiveDataList[i];
-        _unit.directives[i] = _astReader.readNode(directiveData);
-      }
+    if (unitReader != null && !_hasDirectivesRead) {
       _hasDirectivesRead = true;
+      unitReader.readDirectives();
+      var libraryElement = libraryContext.reference.element;
+      for (var directive in unit.directives) {
+        if (directive is ExportDirective) {
+          if (directive.element == null) {
+            ExportElementImpl.forLinkedNode(libraryElement, directive);
+          }
+        } else if (directive is ImportDirective) {
+          if (directive.element == null) {
+            ImportElementImpl.forLinkedNode(libraryElement, directive);
+          }
+        }
+      }
     }
-    return _unit;
+    return unit;
   }
 
-  Comment createComment(LinkedNode data) {
-    var informativeData = getInformativeData(data);
-    var tokenStringList = informativeData?.documentationComment_tokens;
-    if (tokenStringList == null || tokenStringList.isEmpty) {
-      return null;
+  void applyResolution(AstNode node) {
+    if (node is VariableDeclaration) {
+      node = node.parent.parent;
     }
-
-    var tokens = tokenStringList
-        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
-        .toList();
-    return astFactory.documentationComment(tokens);
+    if (node is HasAstLinkedContext) {
+      var astLinkedContext = (node as HasAstLinkedContext).linkedContext;
+      astLinkedContext?.applyResolution(this);
+    }
   }
 
   void createGenericFunctionTypeElement(int id, GenericFunctionTypeImpl node) {
@@ -128,133 +105,72 @@
     node.declaredElement = element;
   }
 
-  /// Return the [LibraryElement] referenced in the [node].
-  LibraryElement directiveLibrary(UriBasedDirective node) {
-    var uriStr = LazyDirective.getSelectedUri(node);
-    if (uriStr == null) return null;
-    return bundleContext.elementFactory.libraryOfUri(uriStr);
-  }
-
   int getCodeLength(AstNode node) {
-    if (node is ClassDeclaration) {
-      return LazyClassDeclaration.getCodeLength(this, node);
-    } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.getCodeLength(this, node);
-    } else if (node is CompilationUnit) {
+    if (node is HasAstLinkedContext) {
+      var linked = (node as HasAstLinkedContext).linkedContext;
+      return linked != null ? linked.codeLength : node.length;
+    }
+
+    if (node is CompilationUnitImpl) {
+      var data = node.summaryData as SummaryDataForCompilationUnit;
       if (data != null) {
-        return getInformativeData(data.node)?.codeLength ?? 0;
+        return data.codeLength;
       } else {
         return node.length;
       }
-    } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.getCodeLength(this, node);
     } else if (node is EnumConstantDeclaration) {
-      return LazyEnumConstantDeclaration.getCodeLength(this, node);
-    } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.getCodeLength(this, node);
-    } else if (node is ExtensionDeclaration) {
-      return LazyExtensionDeclaration.getCodeLength(this, node);
+      return node.length;
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.getCodeLength(this, node);
-    } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.getCodeLength(this, node);
-    } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.getCodeLength(this, node);
-    } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.getCodeLength(this, node);
-    } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getCodeLength(this, node);
-    } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.getCodeLength(this, node);
+      return node.length;
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.getCodeLength(this, node);
+      return node.length;
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getCodeLength(this, node);
+      var parent2 = node.parent.parent;
+      var linked = (parent2 as HasAstLinkedContext).linkedContext;
+      return linked.getVariableDeclarationCodeLength(node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
   int getCodeOffset(AstNode node) {
-    if (node is ClassDeclaration) {
-      return LazyClassDeclaration.getCodeOffset(this, node);
-    } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.getCodeOffset(this, node);
-    } else if (node is CompilationUnit) {
+    if (node is HasAstLinkedContext) {
+      var linked = (node as HasAstLinkedContext).linkedContext;
+      return linked != null ? linked.codeOffset : node.offset;
+    }
+
+    if (node is CompilationUnit) {
       return 0;
-    } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.getCodeOffset(this, node);
     } else if (node is EnumConstantDeclaration) {
-      return LazyEnumConstantDeclaration.getCodeOffset(this, node);
-    } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.getCodeOffset(this, node);
-    } else if (node is ExtensionDeclaration) {
-      return LazyExtensionDeclaration.getCodeOffset(this, node);
+      return node.offset;
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.getCodeOffset(this, node);
-    } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.getCodeOffset(this, node);
-    } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.getCodeOffset(this, node);
-    } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.getCodeOffset(this, node);
-    } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getCodeOffset(this, node);
-    } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.getCodeOffset(this, node);
+      return node.offset;
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.getCodeOffset(this, node);
+      return node.offset;
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getCodeOffset(this, node);
+      var parent2 = node.parent.parent;
+      var linked = (parent2 as HasAstLinkedContext).linkedContext;
+      return linked.getVariableDeclarationCodeOffset(node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  int getCombinatorEnd(ShowCombinator node) {
-    return LazyCombinator.getEnd(this, node);
-  }
-
   List<ConstructorInitializer> getConstructorInitializers(
     ConstructorDeclaration node,
   ) {
-    LazyConstructorDeclaration.readInitializers(_astReader, node);
     return node.initializers;
   }
 
   ConstructorName getConstructorRedirected(ConstructorDeclaration node) {
-    LazyConstructorDeclaration.readRedirectedConstructor(_astReader, node);
     return node.redirectedConstructor;
   }
 
-  Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* {
+  List<ConstructorDeclaration> getConstructors(AstNode node) {
     if (node is ClassOrMixinDeclaration) {
-      var members = _getClassOrExtensionOrMixinMembers(node);
-      for (var member in members) {
-        if (member is ConstructorDeclaration) {
-          yield member;
-        }
-      }
+      return _getClassOrExtensionOrMixinMembers(node)
+          .whereType<ConstructorDeclaration>()
+          .toList();
     }
-  }
-
-  DartType getDefaultType(TypeParameter 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) {
-    if (node is DefaultFormalParameter) {
-      return LazyFormalParameter.getDefaultValueCode(this, node);
-    }
-    return null;
-  }
-
-  String getDefaultValueCodeData(LinkedNode data) {
-    var informativeData = getInformativeData(data);
-    return informativeData?.defaultFormalParameter_defaultValueCode;
+    return const <ConstructorDeclaration>[];
   }
 
   int getDirectiveOffset(Directive node) {
@@ -262,72 +178,17 @@
   }
 
   Comment getDocumentationComment(AstNode node) {
-    if (node is ClassDeclaration) {
-      LazyClassDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is ConstructorDeclaration) {
-      LazyConstructorDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is EnumConstantDeclaration) {
-      LazyEnumConstantDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is EnumDeclaration) {
-      LazyEnumDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is ExtensionDeclaration) {
-      LazyExtensionDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is GenericTypeAlias) {
-      LazyGenericTypeAlias.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
-    } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readDocumentationComment(this, node);
-      return node.documentationComment;
+    if (node is HasAstLinkedContext) {
+      var linkedContext = (node as HasAstLinkedContext).linkedContext;
+      linkedContext?.readDocumentationComment();
+      return (node as AnnotatedNode).documentationComment;
     } else if (node is VariableDeclaration) {
-      var parent2 = node.parent.parent;
-      if (parent2 is FieldDeclaration) {
-        LazyFieldDeclaration.readDocumentationComment(this, parent2);
-        return parent2.documentationComment;
-      } else if (parent2 is TopLevelVariableDeclaration) {
-        LazyTopLevelVariableDeclaration.readDocumentationComment(
-          this,
-          parent2,
-        );
-        return parent2.documentationComment;
-      } else {
-        throw UnimplementedError('${parent2.runtimeType}');
-      }
+      return getDocumentationComment(node.parent.parent);
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) {
-    LazyEnumDeclaration.readConstants(_astReader, node);
-    return node.constants;
-  }
-
-  TypeAnnotation getExtendedType(ExtensionDeclaration node) {
-    LazyExtensionDeclaration.readExtendedType(_astReader, node);
-    return node.extendedType;
-  }
-
-  String getExtensionRefName(ExtensionDeclaration node) {
-    return LazyExtensionDeclaration.get(node).refName;
-  }
-
   String getFieldFormalParameterName(AstNode node) {
     if (node is DefaultFormalParameter) {
       return getFieldFormalParameterName(node.parameter);
@@ -338,125 +199,97 @@
     }
   }
 
-  Iterable<VariableDeclaration> getFields(CompilationUnitMember node) sync* {
+  List<VariableDeclaration> getFields(CompilationUnitMember node) {
+    var fields = <VariableDeclaration>[];
     var members = _getClassOrExtensionOrMixinMembers(node);
     for (var member in members) {
       if (member is FieldDeclaration) {
-        for (var field in member.fields.variables) {
-          yield field;
-        }
+        fields.addAll(member.fields.variables);
       }
     }
+    return fields;
+  }
+
+  String getFormalParameterName(FormalParameter node) {
+    if (node is DefaultFormalParameter) {
+      return getFormalParameterName(node.parameter);
+    } else if (node is NormalFormalParameter) {
+      return node.identifier?.name ?? '';
+    }
+    return null;
   }
 
   List<FormalParameter> getFormalParameters(AstNode node) {
     if (node is ConstructorDeclaration) {
-      LazyConstructorDeclaration.readFormalParameters(_astReader, node);
       return node.parameters.parameters;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return getFormalParameters(node.functionExpression);
     } else if (node is FunctionExpression) {
-      LazyFunctionExpression.readFormalParameters(_astReader, node);
       return node.parameters?.parameters;
     } else if (node is FormalParameter) {
       if (node is DefaultFormalParameter) {
         return getFormalParameters(node.parameter);
       } else if (node is FieldFormalParameter) {
-        LazyFormalParameter.readFormalParameters(_astReader, node);
         return node.parameters?.parameters;
       } else if (node is FunctionTypedFormalParameter) {
-        LazyFormalParameter.readFormalParameters(_astReader, node);
         return node.parameters.parameters;
       } else {
         return null;
       }
     } else if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
       return node.parameters.parameters;
     } else if (node is GenericFunctionType) {
       return node.parameters.parameters;
     } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readFormalParameters(_astReader, node);
       return node.parameters?.parameters;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  Reference getGenericFunctionTypeReference(GenericFunctionType node) {
-    var containerRef = reference.getChild('@genericFunctionType');
-    var id = LazyAst.getGenericFunctionTypeId(node);
-    return containerRef.getChild('$id');
-  }
-
-  GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) {
-    LazyGenericTypeAlias.readFunctionType(_astReader, node);
-    return node.functionType;
-  }
-
-  bool getHasTypedefSelfReference(AstNode node) {
-    if (node is FunctionTypeAlias) {
-      return LazyFunctionTypeAlias.getHasSelfReference(node);
-    } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.getHasSelfReference(node);
-    }
-    return false;
-  }
-
   ImplementsClause getImplementsClause(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readImplementsClause(_astReader, node);
       return node.implementsClause;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readImplementsClause(_astReader, node);
       return node.implementsClause;
     } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readImplementsClause(_astReader, node);
       return node.implementsClause;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  UnlinkedInformativeData getInformativeData(LinkedNode data) {
-    if (informativeData == null) return null;
-
-    var id = data.informativeId;
-    if (id == 0) return null;
-
-    return informativeData[id - 1];
-  }
-
-  bool getInheritsCovariant(AstNode node) {
+  Expression getInitializer(AstNode node) {
     if (node is DefaultFormalParameter) {
-      return getInheritsCovariant(node.parameter);
-    } else if (node is FormalParameter) {
-      return LazyAst.getInheritsCovariant(node);
+      return node.defaultValue;
     } else if (node is VariableDeclaration) {
-      return LazyAst.getInheritsCovariant(node);
+      return node.initializer;
     } else {
       throw StateError('${node.runtimeType}');
     }
   }
 
   LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
-    return LazyCompilationUnit.getLanguageVersion(node);
+    return (node as CompilationUnitImpl).languageVersion;
   }
 
-  Comment getLibraryDocumentationComment(CompilationUnit unit) {
-    for (var directive in unit.directives) {
-      if (directive is LibraryDirective) {
+  Comment getLibraryDocumentationComment() {
+    for (var directive in unit_withDirectives.directives) {
+      if (directive is LibraryDirectiveImpl) {
+        var data = directive.summaryData as SummaryDataForLibraryDirective;
+        data.readDocumentationComment();
         return directive.documentationComment;
       }
     }
     return null;
   }
 
-  List<Annotation> getLibraryMetadata(CompilationUnit unit) {
+  List<Annotation> getLibraryMetadata() {
+    unit_withDirectives;
+    unitReader.applyDirectivesResolution(this);
     for (var directive in unit.directives) {
       if (directive is LibraryDirective) {
-        return getMetadata(directive);
+        return directive.metadata;
       }
     }
     return const <Annotation>[];
@@ -464,80 +297,57 @@
 
   List<Annotation> getMetadata(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is CompilationUnit) {
-      assert(node == _unit);
+      assert(node == unit);
       if (indexInLibrary != 0) {
         return _getPartDirectiveAnnotation();
       } else {
         return const <Annotation>[];
       }
     } else if (node is ConstructorDeclaration) {
-      LazyConstructorDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is DefaultFormalParameter) {
       return getMetadata(node.parameter);
     } else if (node is Directive) {
-      LazyDirective.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is EnumConstantDeclaration) {
-      LazyEnumConstantDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is EnumDeclaration) {
-      LazyEnumDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is ExtensionDeclaration) {
-      LazyExtensionDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is FormalParameter) {
-      LazyFormalParameter.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is GenericTypeAlias) {
-      LazyGenericTypeAlias.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is TypeParameter) {
-      LazyTypeParameter.readMetadata(_astReader, node);
       return node.metadata;
     } else if (node is VariableDeclaration) {
       var parent2 = node.parent.parent;
       if (parent2 is FieldDeclaration) {
-        LazyFieldDeclaration.readMetadata(_astReader, parent2);
         return parent2.metadata;
       } else if (parent2 is TopLevelVariableDeclaration) {
-        LazyTopLevelVariableDeclaration.readMetadata(_astReader, parent2);
         return parent2.metadata;
       }
     }
     return const <Annotation>[];
   }
 
-  Iterable<MethodDeclaration> getMethods(CompilationUnitMember node) sync* {
-    var members = _getClassOrExtensionOrMixinMembers(node);
-    for (var member in members) {
-      if (member is MethodDeclaration) {
-        yield member;
-      }
-    }
-  }
-
-  List<String> getMixinSuperInvokedNames(MixinDeclaration node) {
-    return LazyMixinDeclaration.get(node).getSuperInvokedNames();
+  List<MethodDeclaration> getMethods(CompilationUnitMember node) {
+    return _getClassOrExtensionOrMixinMembers(node)
+        .whereType<MethodDeclaration>()
+        .toList();
   }
 
   int getNameOffset(AstNode node) {
@@ -565,87 +375,24 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  OnClause getOnClause(MixinDeclaration node) {
-    LazyMixinDeclaration.readOnClause(_astReader, node);
-    return node.onClause;
-  }
-
   /// Return the actual return type for the [node] - explicit or inferred.
   DartType getReturnType(AstNode node) {
-    if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.getReturnType(_astReader, node);
-    } else if (node is FunctionTypeAlias) {
-      return LazyFunctionTypeAlias.getReturnType(_astReader, node);
-    } else if (node is GenericFunctionType) {
+    if (node is GenericFunctionType) {
       return node.returnType?.type ?? DynamicTypeImpl.instance;
-    } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getReturnType(_astReader, node);
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
     }
-  }
-
-  TypeAnnotation getReturnTypeNode(AstNode node) {
-    if (node is FunctionTypeAlias) {
-      LazyFunctionTypeAlias.readReturnTypeNode(_astReader, node);
-      return node.returnType;
-    } else if (node is GenericFunctionType) {
-      return node.returnType;
-    } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
-      return node.returnType;
-    } else if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
-      return node.returnType;
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
-    }
-  }
-
-  String getSelectedUri(UriBasedDirective node) {
-    return LazyDirective.getSelectedUri(node);
+    throw UnimplementedError('${node.runtimeType}');
   }
 
   TypeName getSuperclass(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readExtendsClause(_astReader, node);
       return node.extendsClause?.superclass;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readSuperclass(_astReader, node);
       return node.superclass;
     } else {
       throw StateError('${node.runtimeType}');
     }
   }
 
-  /// Return the actual type for the [node] - explicit or inferred.
-  DartType getType(AstNode node) {
-    if (node is DefaultFormalParameter) {
-      return getType(node.parameter);
-    } else if (node is FormalParameter) {
-      return LazyFormalParameter.getType(_astReader, node);
-    } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getType(_astReader, node);
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
-    }
-  }
-
-  TopLevelInferenceError getTypeInferenceError(AstNode node) {
-    if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.getTypeInferenceError(node);
-    } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.getTypeInferenceError(node);
-    } else {
-      return null;
-    }
-  }
-
-  TypeAnnotation getTypeParameterBound(TypeParameter node) {
-    LazyTypeParameter.readBound(_astReader, node);
-    return node.bound;
-  }
-
   TypeParameterList getTypeParameters2(AstNode node) {
     if (node is ClassDeclaration) {
       return node.typeParameters;
@@ -660,7 +407,6 @@
     } else if (node is FieldFormalParameter) {
       return node.typeParameters;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return getTypeParameters2(node.functionExpression);
     } else if (node is FunctionExpression) {
       return node.typeParameters;
@@ -683,36 +429,21 @@
     }
   }
 
-  Variance getTypeParameterVariance(TypeParameter node) {
-    return LazyAst.getVariance(node);
-  }
-
   WithClause getWithClause(AstNode node) {
     if (node is ClassDeclaration) {
-      LazyClassDeclaration.readWithClause(_astReader, node);
       return node.withClause;
     } else if (node is ClassTypeAlias) {
-      LazyClassTypeAlias.readWithClause(_astReader, node);
       return node.withClause;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  bool hasDefaultValue(FormalParameter node) {
-    if (node is DefaultFormalParameter) {
-      return LazyFormalParameter.hasDefaultValue(node);
-    }
-    return false;
-  }
-
   bool hasImplicitReturnType(AstNode node) {
     if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
       return node.returnType == null;
     }
     if (node is MethodDeclaration) {
-      LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
       return node.returnType == null;
     }
     return false;
@@ -725,38 +456,26 @@
       return node.type == null;
     } else if (node is VariableDeclaration) {
       VariableDeclarationList parent = node.parent;
-      LazyVariableDeclarationList.readTypeNode(_astReader, parent);
       return parent.type == null;
     }
     return false;
   }
 
-  bool hasInitializer(VariableDeclaration node) {
-    return LazyVariableDeclaration.hasInitializer(node);
-  }
-
-  bool hasOperatorEqualParameterTypeFromObject(MethodDeclaration node) {
-    return LazyAst.hasOperatorEqualParameterTypeFromObject(node);
-  }
-
-  bool hasOverrideInferenceDone(AstNode node) {
-    // Only nodes in the libraries being linked might be not inferred yet.
-    if (_astReader.isLazy) return true;
-
-    return LazyAst.hasOverrideInferenceDone(node);
+  bool hasInitializer(VariableDeclarationImpl node) {
+    return node.initializer != null || node.hasInitializer;
   }
 
   bool isAbstract(AstNode node) {
     if (node is ClassDeclaration) {
-      return node.abstractKeyword != null;
+      return node.isAbstract;
     } else if (node is ClassTypeAlias) {
-      return node.abstractKeyword != null;
+      return node.isAbstract;
     } else if (node is ConstructorDeclaration) {
       return false;
     } else if (node is FunctionDeclaration) {
       return false;
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.isAbstract(node);
+      return node.isAbstract;
     } else if (node is VariableDeclaration) {
       var parent = node.parent;
       if (parent is VariableDeclarationList) {
@@ -779,12 +498,11 @@
     if (node is ConstructorDeclaration) {
       return false;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return isAsynchronous(node.functionExpression);
     } else if (node is FunctionExpression) {
-      return LazyFunctionExpression.isAsynchronous(node);
+      return node.body.isAsynchronous;
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.isAsynchronous(node);
+      return node.body.isAsynchronous;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
@@ -859,12 +577,11 @@
     if (node is ConstructorDeclaration) {
       return false;
     } else if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
       return isGenerator(node.functionExpression);
     } else if (node is FunctionExpression) {
-      return LazyFunctionExpression.isGenerator(node);
+      return node.body.isGenerator;
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.isGenerator(node);
+      return node.body.isGenerator;
     } else {
       throw UnimplementedError('${node.runtimeType}');
     }
@@ -908,10 +625,6 @@
     }
   }
 
-  bool isSimplyBounded(AstNode node) {
-    return LazyAst.isSimplyBounded(node);
-  }
-
   bool isStatic(AstNode node) {
     if (node is FunctionDeclaration) {
       return true;
@@ -924,141 +637,6 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  Expression readInitializer(AstNode node) {
-    if (node is DefaultFormalParameter) {
-      LazyFormalParameter.readDefaultValue(_astReader, node);
-      return node.defaultValue;
-    } else if (node is VariableDeclaration) {
-      LazyVariableDeclaration.readInitializer(_astReader, node);
-      return node.initializer;
-    } else {
-      throw StateError('${node.runtimeType}');
-    }
-  }
-
-  DartType readType(LinkedNodeType linkedType) {
-    if (linkedType == null) return null;
-
-    var kind = linkedType.kind;
-    if (kind == LinkedNodeTypeKind.dynamic_) {
-      return DynamicTypeImpl.instance;
-    } else if (kind == LinkedNodeTypeKind.function) {
-      var typeParameterDataList = linkedType.functionTypeParameters;
-
-      var typeParametersLength = typeParameterDataList.length;
-      var typeParameters = List<TypeParameterElement>(typeParametersLength);
-      for (var i = 0; i < typeParametersLength; ++i) {
-        var typeParameterData = typeParameterDataList[i];
-        var element = TypeParameterElementImpl(typeParameterData.name, -1);
-        typeParameters[i] = element;
-        _typeParameters[_nextSyntheticTypeParameterId++] = element;
-      }
-
-      // Type parameters might use each other in bounds, including forward
-      // references. So, we read bounds after reading all type parameters.
-      for (var i = 0; i < typeParametersLength; ++i) {
-        var typeParameterData = typeParameterDataList[i];
-        TypeParameterElementImpl element = typeParameters[i];
-        element.bound = readType(typeParameterData.bound);
-      }
-
-      var returnType = readType(linkedType.functionReturnType);
-      var formalParameters = linkedType.functionFormalParameters.map((p) {
-        var type = readType(p.type);
-        var kind = _formalParameterKind(p.kind);
-        return ParameterElementImpl.synthetic(p.name, type, kind);
-      }).toList();
-
-      for (var i = 0; i < typeParametersLength; ++i) {
-        _typeParameters.remove(--_nextSyntheticTypeParameterId);
-      }
-
-      FunctionTypeAliasElement typedefElement;
-      List<DartType> typedefTypeArguments = const <DartType>[];
-      if (linkedType.functionTypedef != 0) {
-        typedefElement =
-            bundleContext.elementOfIndex(linkedType.functionTypedef);
-        typedefTypeArguments =
-            linkedType.functionTypedefTypeArguments.map(readType).toList();
-      }
-
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-
-      return FunctionTypeImpl(
-        typeFormals: typeParameters,
-        parameters: formalParameters,
-        returnType: returnType,
-        nullabilitySuffix: nullabilitySuffix,
-        element: typedefElement,
-        typeArguments: typedefTypeArguments,
-      );
-    } else if (kind == LinkedNodeTypeKind.interface) {
-      var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-      return InterfaceTypeImpl(
-        element: element,
-        typeArguments: linkedType.interfaceTypeArguments.map(readType).toList(),
-        nullabilitySuffix: nullabilitySuffix,
-      );
-    } else if (kind == LinkedNodeTypeKind.never) {
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-      return NeverTypeImpl.instance.withNullability(nullabilitySuffix);
-    } else if (kind == LinkedNodeTypeKind.typeParameter) {
-      TypeParameterElement element;
-      var id = linkedType.typeParameterId;
-      if (id != 0) {
-        element = _typeParameters[id];
-        assert(element != null);
-      } else {
-        var index = linkedType.typeParameterElement;
-        element = bundleContext.elementOfIndex(index);
-      }
-      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-      return TypeParameterTypeImpl(
-        element: element,
-        nullabilitySuffix: nullabilitySuffix,
-      );
-    } else if (kind == LinkedNodeTypeKind.void_) {
-      return VoidTypeImpl.instance;
-    } else {
-      throw UnimplementedError('$kind');
-    }
-  }
-
-  void setInheritsCovariant(AstNode node, bool value) {
-    if (node is DefaultFormalParameter) {
-      setInheritsCovariant(node.parameter, value);
-    } else if (node is FormalParameter) {
-      LazyAst.setInheritsCovariant(node, value);
-    } else if (node is VariableDeclaration) {
-      LazyAst.setInheritsCovariant(node, value);
-    } else {
-      throw StateError('${node.runtimeType}');
-    }
-  }
-
-  void setOperatorEqualParameterTypeFromObject(AstNode node, bool value) {
-    LazyAst.setOperatorEqualParameterTypeFromObject(node, value);
-  }
-
-  void setOverrideInferenceDone(AstNode node) {
-    // TODO(scheglov) This assert fails, check how to avoid this.
-//    assert(!_astReader.isLazy);
-    LazyAst.setOverrideInferenceDone(node);
-  }
-
-  void setReturnType(AstNode node, DartType type) {
-    LazyAst.setReturnType(node, type);
-  }
-
-  void setVariableType(AstNode node, DartType type) {
-    if (node is DefaultFormalParameter) {
-      setVariableType(node.parameter, type);
-    } else {
-      LazyAst.setType(node, type);
-    }
-  }
-
   bool shouldBeConstFieldElement(AstNode node) {
     if (node is VariableDeclaration) {
       VariableDeclarationList variableList = node.parent;
@@ -1069,11 +647,19 @@
 
       if (variableList.isFinal) {
         var class_ = fieldDeclaration.parent;
-        if (class_ is ClassOrMixinDeclaration) {
-          for (var member in class_.members) {
-            if (member is ConstructorDeclaration &&
-                member.constKeyword != null) {
-              return true;
+        if (class_ is ClassDeclaration) {
+          var hasLinkedContext = class_ as HasAstLinkedContext;
+          var linkedContext = hasLinkedContext.linkedContext;
+          // TODO(scheglov) Get rid of this check, exists only for linking.
+          // Maybe we should pre-create all elements before linking.
+          if (linkedContext != null) {
+            return linkedContext.isClassWithConstConstructor;
+          } else {
+            for (var member in class_.members) {
+              if (member is ConstructorDeclaration &&
+                  member.constKeyword != null) {
+                return true;
+              }
             }
           }
         }
@@ -1082,85 +668,49 @@
     return false;
   }
 
-  Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* {
+  List<VariableDeclaration> topLevelVariables(CompilationUnit unit) {
+    var variables = <VariableDeclaration>[];
     for (var declaration in unit.declarations) {
       if (declaration is TopLevelVariableDeclaration) {
-        for (var variable in declaration.variables.variables) {
-          yield variable;
-        }
+        variables.addAll(declaration.variables.variables);
       }
     }
-  }
-
-  void _ensureUnitWithDeclarations() {
-    if (_unit == null) {
-      _unit = _astReader.readNode(data.node);
-
-      var informativeData = getInformativeData(data.node);
-      var lineStarts = informativeData?.compilationUnit_lineStarts ?? [];
-      if (lineStarts.isEmpty) {
-        lineStarts = [0];
-      }
-      _unit.lineInfo = LineInfo(lineStarts);
-    }
-  }
-
-  ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
-    if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
-      return ParameterKind.NAMED;
-    } else if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
-      return ParameterKind.POSITIONAL;
-    } else if (kind == LinkedNodeFormalParameterKind.requiredNamed) {
-      return ParameterKind.NAMED_REQUIRED;
-    }
-    return ParameterKind.REQUIRED;
+    return variables;
   }
 
   List<ClassMember> _getClassOrExtensionOrMixinMembers(
     CompilationUnitMember node,
   ) {
-    if (node is ClassDeclaration) {
-      LazyClassDeclaration.readMembers(_astReader, node);
-      return node.members;
-    } else if (node is ClassTypeAlias) {
-      return <ClassMember>[];
-    } else if (node is ExtensionDeclaration) {
-      LazyExtensionDeclaration.readMembers(_astReader, node);
-      return node.members;
-    } else if (node is MixinDeclaration) {
-      LazyMixinDeclaration.readMembers(_astReader, node);
-      return node.members;
+    var linkedContext = (node as HasAstLinkedContext).linkedContext;
+    if (linkedContext != null) {
+      return linkedContext.classMembers;
     } else {
-      throw StateError('${node.runtimeType}');
+      if (node is ClassDeclaration) {
+        return node.members;
+      } else if (node is ClassTypeAlias) {
+        return <ClassMember>[];
+      } else if (node is ExtensionDeclaration) {
+        return node.members;
+      } else if (node is MixinDeclaration) {
+        return node.members;
+      } else {
+        throw StateError('${node.runtimeType}');
+      }
     }
   }
 
   NodeList<Annotation> _getPartDirectiveAnnotation() {
     var definingContext = libraryContext.definingUnit;
-    var unit = definingContext.unit;
+    var definingUnit = definingContext.unit_withDirectives;
     var partDirectiveIndex = 0;
-    for (var directive in unit.directives) {
+    for (var directive in definingUnit.directives) {
       if (directive is PartDirective) {
         partDirectiveIndex++;
         if (partDirectiveIndex == indexInLibrary) {
-          LazyDirective.readMetadata(definingContext._astReader, directive);
           return directive.metadata;
         }
       }
     }
     throw StateError('Expected to find $indexInLibrary part directive.');
   }
-
-  static NullabilitySuffix _nullabilitySuffix(EntityRefNullabilitySuffix data) {
-    switch (data) {
-      case EntityRefNullabilitySuffix.starOrIrrelevant:
-        return NullabilitySuffix.star;
-      case EntityRefNullabilitySuffix.question:
-        return NullabilitySuffix.question;
-      case EntityRefNullabilitySuffix.none:
-        return NullabilitySuffix.none;
-      default:
-        throw StateError('$data');
-    }
-  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
deleted file mode 100644
index 81cf9c2b..0000000
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/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/member.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-
-class LinkingBundleContext {
-  /// The `dynamic` class is declared in `dart:core`, but is not a class.
-  /// Also, it is static, so we cannot set `reference` for it.
-  /// So, we have to push it in a separate way.
-  final Reference dynamicReference;
-
-  /// References used in all libraries being linked.
-  /// Element references in nodes are indexes in this list.
-  final List<Reference> references = [null];
-
-  /// Data about [references].
-  final LinkedNodeReferencesBuilder referencesBuilder =
-      LinkedNodeReferencesBuilder(
-    parent: [0],
-    name: [''],
-  );
-
-  final Map<TypeParameterElement, int> _typeParameters = Map.identity();
-  int _nextSyntheticTypeParameterId = 0x10000;
-
-  LinkingBundleContext(this.dynamicReference);
-
-  /// We need indexes for references during linking, but once we are done,
-  /// we must clear indexes to make references ready for linking a next bundle.
-  void clearIndexes() {
-    for (var reference in references) {
-      if (reference != null) {
-        reference.index = null;
-      }
-    }
-  }
-
-  int idOfTypeParameter(TypeParameterElement element) {
-    return _typeParameters[element];
-  }
-
-  int indexOfElement(Element element) {
-    if (element == null) return 0;
-    if (element is MultiplyDefinedElement) return 0;
-    assert(element is! Member);
-
-    if (identical(element, DynamicElementImpl.instance)) {
-      return indexOfReference(dynamicReference);
-    }
-
-    var reference = (element as ElementImpl).reference;
-    return indexOfReference(reference);
-  }
-
-  int indexOfReference(Reference reference) {
-    if (reference == null) return 0;
-    if (reference.parent == null) return 0;
-    if (reference.index != null) return reference.index;
-
-    var parentIndex = indexOfReference(reference.parent);
-    referencesBuilder.parent.add(parentIndex);
-    referencesBuilder.name.add(reference.name);
-
-    reference.index = references.length;
-    references.add(reference);
-    return reference.index;
-  }
-
-  LinkedNodeTypeBuilder writeType(DartType type) {
-    if (type == null) return null;
-
-    if (type.isDynamic) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.dynamic_,
-      );
-    } else if (type is FunctionType) {
-      return _writeFunctionType(type);
-    } else if (type is InterfaceType) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.interface,
-        interfaceClass: indexOfElement(type.element),
-        interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
-        nullabilitySuffix: _nullabilitySuffix(type),
-      );
-    } else if (type is NeverType) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.never,
-        nullabilitySuffix: _nullabilitySuffix(type),
-      );
-    } else if (type is TypeParameterType) {
-      TypeParameterElementImpl element = type.element;
-      var id = _typeParameters[element];
-      if (id != null) {
-        return LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.typeParameter,
-          nullabilitySuffix: _nullabilitySuffix(type),
-          typeParameterId: id,
-        );
-      } else {
-        var index = indexOfElement(element);
-        return LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.typeParameter,
-          nullabilitySuffix: _nullabilitySuffix(type),
-          typeParameterElement: index,
-        );
-      }
-    } else if (type is VoidType) {
-      return LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.void_,
-      );
-    } else {
-      throw UnimplementedError('(${type.runtimeType}) $type');
-    }
-  }
-
-  LinkedNodeFormalParameterKind _formalParameterKind(ParameterElement p) {
-    if (p.isRequiredPositional) {
-      return LinkedNodeFormalParameterKind.requiredPositional;
-    } else if (p.isRequiredNamed) {
-      return LinkedNodeFormalParameterKind.requiredNamed;
-    } else if (p.isOptionalPositional) {
-      return LinkedNodeFormalParameterKind.optionalPositional;
-    } else if (p.isOptionalNamed) {
-      return LinkedNodeFormalParameterKind.optionalNamed;
-    } else {
-      throw StateError('Unexpected parameter kind: $p');
-    }
-  }
-
-  FunctionType _toSyntheticFunctionType(FunctionType type) {
-    var typeParameters = type.typeFormals;
-
-    if (typeParameters.isEmpty) return type;
-
-    var onlySyntheticTypeParameters = typeParameters.every((e) {
-      return e is TypeParameterElementImpl && e.linkedNode == null;
-    });
-    if (onlySyntheticTypeParameters) return type;
-
-    var parameters = getFreshTypeParameters(typeParameters);
-    return parameters.applyToFunctionType(type);
-  }
-
-  LinkedNodeTypeBuilder _writeFunctionType(FunctionType type) {
-    type = _toSyntheticFunctionType(type);
-
-    var typeParameterBuilders = <LinkedNodeTypeTypeParameterBuilder>[];
-
-    var typeParameters = type.typeFormals;
-    for (var i = 0; i < typeParameters.length; ++i) {
-      var typeParameter = typeParameters[i];
-      _typeParameters[typeParameter] = _nextSyntheticTypeParameterId++;
-      typeParameterBuilders.add(
-        LinkedNodeTypeTypeParameterBuilder(name: typeParameter.name),
-      );
-    }
-
-    for (var i = 0; i < typeParameters.length; ++i) {
-      var typeParameter = typeParameters[i];
-      typeParameterBuilders[i].bound = writeType(typeParameter.bound);
-    }
-
-    Element typedefElement;
-    List<DartType> typedefTypeArguments = const <DartType>[];
-    if (type.element is FunctionTypeAliasElement) {
-      typedefElement = type.element;
-      typedefTypeArguments = type.typeArguments;
-    }
-    // TODO(scheglov) Cleanup to always use FunctionTypeAliasElement.
-    if (type.element is GenericFunctionTypeElement &&
-        type.element.enclosingElement is FunctionTypeAliasElement) {
-      typedefElement = type.element.enclosingElement;
-      typedefTypeArguments = type.typeArguments;
-    }
-
-    var result = LinkedNodeTypeBuilder(
-      kind: LinkedNodeTypeKind.function,
-      functionFormalParameters: type.parameters
-          .map((p) => LinkedNodeTypeFormalParameterBuilder(
-                kind: _formalParameterKind(p),
-                name: p.name,
-                type: writeType(p.type),
-              ))
-          .toList(),
-      functionReturnType: writeType(type.returnType),
-      functionTypeParameters: typeParameterBuilders,
-      functionTypedef: indexOfElement(typedefElement),
-      functionTypedefTypeArguments:
-          typedefTypeArguments.map(writeType).toList(),
-      nullabilitySuffix: _nullabilitySuffix(type),
-    );
-
-    for (var typeParameter in typeParameters) {
-      _typeParameters.remove(typeParameter);
-      --_nextSyntheticTypeParameterId;
-    }
-
-    return result;
-  }
-
-  static EntityRefNullabilitySuffix _nullabilitySuffix(DartType type) {
-    var nullabilitySuffix = type.nullabilitySuffix;
-    switch (nullabilitySuffix) {
-      case NullabilitySuffix.question:
-        return EntityRefNullabilitySuffix.question;
-      case NullabilitySuffix.star:
-        return EntityRefNullabilitySuffix.starOrIrrelevant;
-      case NullabilitySuffix.none:
-        return EntityRefNullabilitySuffix.none;
-      default:
-        throw StateError('$nullabilitySuffix');
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index a4182c5..61fd6d1 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -145,7 +145,10 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.functionType?.accept(this);
+    // TODO(eernst): Extend this visitor to visit types.
+    // E.g., `List<Function<@m X>()> Function()` is not included now.
+    var type = node.type;
+    if (type is GenericFunctionType) type.accept(this);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index fdf0073..d67f186 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -10,15 +11,15 @@
 import 'package:analyzer/src/dart/ast/extensions.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_system.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 import 'package:meta/meta.dart';
 
 /// The type builder for a [TypeName].
 class NamedTypeBuilder extends TypeBuilder {
+  /// TODO(scheglov) Replace with `DartType` in `TypeAliasElementImpl`.
+  static const _aliasedTypeKey = '_aliasedType';
   static DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
 
   /// The type system of the library with the type name.
@@ -65,6 +66,13 @@
         node: node);
   }
 
+  /// TODO(scheglov) Only when enabled both in the element, and target?
+  bool get _isNonFunctionTypeAliasesEnabled {
+    return element.library.featureSet.isEnabled(
+      Feature.nonfunction_type_aliases,
+    );
+  }
+
   @override
   R accept<R>(TypeVisitor<R> visitor) {
     if (visitor is LinkingTypeVisitor<R>) {
@@ -91,20 +99,15 @@
       );
       type = typeSystem.toLegacyType(type);
       _type = type;
-    } else if (element is FunctionTypeAliasElement) {
-      var rawType = _getRawFunctionType(element);
-      if (rawType is FunctionType) {
+    } else if (element is TypeAliasElementImpl) {
+      var aliasedType = _getAliasedType(element);
+      if (aliasedType != null) {
         var parameters = element.typeParameters;
         var arguments = _buildArguments(parameters);
-        var substitution = Substitution.fromPairs(parameters, arguments);
-        var instantiated = substitution.substituteType(rawType) as FunctionType;
-        var type = FunctionTypeImpl(
-          typeFormals: instantiated.typeFormals,
-          parameters: instantiated.parameters,
-          returnType: instantiated.returnType,
-          nullabilitySuffix: nullabilitySuffix,
-          element: element,
+        element.aliasedType = aliasedType;
+        var type = element.instantiate(
           typeArguments: arguments,
+          nullabilitySuffix: nullabilitySuffix,
         );
         type = typeSystem.toLegacyType(type);
         _type = type;
@@ -152,13 +155,34 @@
         node: node);
   }
 
+  DartType _buildAliasedType(TypeAnnotation node) {
+    if (_isNonFunctionTypeAliasesEnabled) {
+      if (node != null) {
+        return _buildType(node?.type);
+      } else {
+        return _dynamicType;
+      }
+    } else {
+      if (node is GenericFunctionType) {
+        return _buildType(node?.type);
+      } else {
+        return FunctionTypeImpl(
+          typeFormals: const <TypeParameterElement>[],
+          parameters: const <ParameterElement>[],
+          returnType: _dynamicType,
+          nullabilitySuffix: NullabilitySuffix.none,
+        );
+      }
+    }
+  }
+
   /// Build arguments that correspond to the type [parameters].
   List<DartType> _buildArguments(List<TypeParameterElement> parameters) {
     if (parameters.isEmpty) {
       return const <DartType>[];
     } else if (arguments.isNotEmpty) {
       if (arguments.length == parameters.length) {
-        var result = List<DartType>(parameters.length);
+        var result = List<DartType>.filled(parameters.length, null);
         for (int i = 0; i < result.length; ++i) {
           var type = arguments[i];
           result[i] = _buildType(type);
@@ -168,7 +192,7 @@
         return _listOfDynamic(parameters.length);
       }
     } else {
-      var result = List<DartType>(parameters.length);
+      var result = List<DartType>.filled(parameters.length, null);
       for (int i = 0; i < result.length; ++i) {
         TypeParameterElementImpl parameter = parameters[i];
         var defaultType = parameter.defaultType;
@@ -214,19 +238,6 @@
     );
   }
 
-  DartType _buildGenericFunctionType(GenericFunctionType node) {
-    if (node != null) {
-      return _buildType(node?.type);
-    } else {
-      return FunctionTypeImpl(
-        typeFormals: const <TypeParameterElement>[],
-        parameters: const <ParameterElement>[],
-        returnType: _dynamicType,
-        nullabilitySuffix: NullabilitySuffix.none,
-      );
-    }
-  }
-
   DartType _buildNodeType(TypeAnnotation node) {
     if (node == null) {
       return _dynamicType;
@@ -245,32 +256,22 @@
     }).toList();
   }
 
-  NullabilitySuffix _getNullabilitySuffix(bool hasQuestion) {
-    if (hasQuestion) {
-      return NullabilitySuffix.question;
-    } else if (typeSystem.isNonNullableByDefault) {
-      return NullabilitySuffix.none;
-    } else {
-      return NullabilitySuffix.star;
-    }
-  }
-
-  DartType _getRawFunctionType(FunctionTypeAliasElementImpl element) {
+  DartType _getAliasedType(TypeAliasElementImpl element) {
     // If the element is not being linked, there is no reason (or a way,
     // because the linked node might be read only partially) to go through
     // its node - all its types have already been built.
     if (!element.linkedContext.isLinking) {
-      return element.function.type;
+      return element.aliasedType;
     }
 
     var typedefNode = element.linkedNode;
 
     // Break a possible recursion.
-    var existing = LazyAst.getRawFunctionType(typedefNode);
+    var existing = typedefNode.getProperty(_aliasedTypeKey) as DartType;
     if (existing != null) {
       return existing;
     } else {
-      LazyAst.setRawFunctionType(typedefNode, _dynamicType);
+      _setAliasedType(typedefNode, _dynamicType);
     }
 
     if (typedefNode is FunctionTypeAlias) {
@@ -280,18 +281,28 @@
         parameterList: typedefNode.parameters,
         hasQuestion: false,
       );
-      LazyAst.setRawFunctionType(typedefNode, result);
+      _setAliasedType(typedefNode, result);
       return result;
     } else if (typedefNode is GenericTypeAlias) {
-      var functionNode = typedefNode.functionType;
-      var functionType = _buildGenericFunctionType(functionNode);
-      LazyAst.setRawFunctionType(typedefNode, functionType);
-      return functionType;
+      var aliasedTypeNode = typedefNode.type;
+      var aliasedType = _buildAliasedType(aliasedTypeNode);
+      _setAliasedType(typedefNode, aliasedType);
+      return aliasedType;
     } else {
       throw StateError('(${element.runtimeType}) $element');
     }
   }
 
+  NullabilitySuffix _getNullabilitySuffix(bool hasQuestion) {
+    if (hasQuestion) {
+      return NullabilitySuffix.question;
+    } else if (typeSystem.isNonNullableByDefault) {
+      return NullabilitySuffix.none;
+    } else {
+      return NullabilitySuffix.star;
+    }
+  }
+
   /// If the [type] is a [TypeBuilder], build it; otherwise return as is.
   static DartType _buildType(DartType type) {
     if (type is TypeBuilder) {
@@ -305,6 +316,10 @@
     return List<DartType>.filled(length, _dynamicType);
   }
 
+  static void _setAliasedType(AstNode node, DartType type) {
+    node.setProperty(_aliasedTypeKey, type);
+  }
+
   static List<TypeParameterElement> _typeParameters(TypeParameterList node) {
     if (node != null) {
       return node.typeParameters
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_format.dart b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
new file mode 100644
index 0000000..cb47263
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:meta/meta.dart';
+
+class PackageBundleBuilder {
+  final List<PackageBundleLibrary> _libraries = [];
+
+  void addLibrary(String uriStr, List<String> unitUriStrList) {
+    _libraries.add(
+      PackageBundleLibrary(
+        uriStr,
+        unitUriStrList.map((e) => PackageBundleUnit(e)).toList(),
+      ),
+    );
+  }
+
+  Uint8List finish({
+    @required Uint8List astBytes,
+    @required Uint8List resolutionBytes,
+    PackageBundleSdk sdk,
+  }) {
+    var byteSink = ByteSink();
+    var sink = BufferedSink(byteSink);
+
+    if (sdk != null) {
+      sink.writeByte(1);
+      sdk._write(sink);
+    } else {
+      sink.writeByte(0);
+    }
+
+    sink.writeList(_libraries, (PackageBundleLibrary library) {
+      sink.writeStringUtf8(library.uriStr);
+      sink.writeList(
+        library.units,
+        (PackageBundleUnit unit) => sink.writeStringUtf8(unit.uriStr),
+      );
+    });
+
+    sink.writeUint8List(astBytes);
+    sink.writeUint8List(resolutionBytes);
+
+    sink.flushAndDestroy();
+    return byteSink.builder.takeBytes();
+  }
+}
+
+@internal
+class PackageBundleLibrary {
+  final String uriStr;
+  final List<PackageBundleUnit> units;
+
+  PackageBundleLibrary(this.uriStr, this.units);
+}
+
+class PackageBundleReader {
+  final List<PackageBundleLibrary> libraries = [];
+  PackageBundleSdk _sdk;
+  Uint8List _astBytes;
+  Uint8List _resolutionBytes;
+
+  PackageBundleReader(Uint8List bytes) {
+    var reader = SummaryDataReader(bytes);
+
+    var hasSdk = reader.readByte() != 0;
+    if (hasSdk) {
+      _sdk = PackageBundleSdk._fromReader(reader);
+    }
+
+    var librariesLength = reader.readUInt30();
+    for (var i = 0; i < librariesLength; i++) {
+      var uriStr = reader.readStringUtf8();
+      var unitsLength = reader.readUInt30();
+      var units = List.generate(unitsLength, (_) {
+        var uriStr = reader.readStringUtf8();
+        return PackageBundleUnit(uriStr);
+      });
+      libraries.add(
+        PackageBundleLibrary(uriStr, units),
+      );
+    }
+
+    _astBytes = reader.readUint8List();
+    _resolutionBytes = reader.readUint8List();
+  }
+
+  Uint8List get astBytes => _astBytes;
+
+  Uint8List get resolutionBytes => _resolutionBytes;
+
+  PackageBundleSdk get sdk => _sdk;
+}
+
+class PackageBundleSdk {
+  final int languageVersionMajor;
+  final int languageVersionMinor;
+
+  /// The content of the `allowed_experiments.json` from SDK.
+  final String allowedExperimentsJson;
+
+  PackageBundleSdk({
+    @required this.languageVersionMajor,
+    @required this.languageVersionMinor,
+    @required this.allowedExperimentsJson,
+  });
+
+  factory PackageBundleSdk._fromReader(SummaryDataReader reader) {
+    return PackageBundleSdk(
+      languageVersionMajor: reader.readUInt30(),
+      languageVersionMinor: reader.readUInt30(),
+      allowedExperimentsJson: reader.readStringUtf8(),
+    );
+  }
+
+  void _write(BufferedSink sink) {
+    sink.writeUInt30(languageVersionMajor);
+    sink.writeUInt30(languageVersionMinor);
+    sink.writeStringUtf8(allowedExperimentsJson);
+  }
+}
+
+@internal
+class PackageBundleUnit {
+  final String uriStr;
+
+  PackageBundleUnit(this.uriStr);
+}
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
new file mode 100644
index 0000000..ec05912
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
+
+class PackageBundle extends PackageBundleReader {
+  PackageBundle.fromBuffer(Uint8List bytes) : super(bytes);
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 7eb7f68..6cd096b 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -32,6 +32,10 @@
   /// The simple name of the reference in its [parent].
   final String name;
 
+  /// The node accessor, used to read nodes lazily.
+  /// Or `null` if a named container.
+  ReferenceNodeAccessor nodeAccessor;
+
   /// The corresponding [AstNode], or `null` if a named container.
   AstNode node;
 
@@ -59,16 +63,28 @@
 
   bool get isClass => parent != null && parent.name == '@class';
 
+  bool get isConstructor => parent != null && parent.name == '@constructor';
+
   bool get isDynamic => name == 'dynamic' && parent?.name == 'dart:core';
 
   bool get isEnum => parent != null && parent.name == '@enum';
 
+  bool get isGetter => parent != null && parent.name == '@getter';
+
+  bool get isLibrary => parent != null && parent.isRoot;
+
+  bool get isParameter => parent != null && parent.name == '@parameter';
+
   bool get isPrefix => parent != null && parent.name == '@prefix';
 
+  bool get isRoot => parent == null;
+
   bool get isSetter => parent != null && parent.name == '@setter';
 
   bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
 
+  bool get isUnit => parent != null && parent.name == '@unit';
+
   /// Return the child with the given name, or `null` if does not exist.
   Reference operator [](String name) {
     return _children != null ? _children[name] : null;
@@ -102,3 +118,13 @@
   @override
   String toString() => parent == null ? 'root' : '$parent::$name';
 }
+
+abstract class ReferenceNodeAccessor {
+  /// Return the node that corresponds to this [Reference], read it if not yet.
+  AstNode get node;
+
+  /// Fill [Reference.nodeAccessor] for children.
+  ///
+  /// TODO(scheglov) only class reader has a meaningful implementation.
+  void readIndex();
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 451dcb1..73818f7 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -12,9 +12,7 @@
 import 'package:analyzer/src/dart/element/scope.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
@@ -45,9 +43,6 @@
   Reference reference;
   Scope scope;
 
-  /// Is `true` if the current [ClassDeclaration] has a const constructor.
-  bool _hasConstConstructor = false;
-
   ReferenceResolver(
     this.nodesToBuildType,
     this.elementFactory,
@@ -72,7 +67,7 @@
     element.constructors; // create elements
     element.methods; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.typeParameters?.accept(this);
@@ -83,14 +78,6 @@
     scope = ClassScope(scope, element);
     LinkingNodeContext(node, scope);
 
-    _hasConstConstructor = false;
-    for (var member in node.members) {
-      if (member is ConstructorDeclaration && member.constKeyword != null) {
-        _hasConstConstructor = true;
-        break;
-      }
-    }
-
     node.members.accept(this);
     nodesToBuildType.addDeclaration(node);
 
@@ -106,7 +93,7 @@
     var element = node.declaredElement as ClassElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
 
@@ -139,9 +126,6 @@
     LinkingNodeContext(node, scope);
 
     node.parameters?.accept(this);
-    node.initializers.accept(
-      _SetGenericFunctionTypeIdVisitor(this),
-    );
 
     scope = outerScope;
     reference = outerReference;
@@ -150,9 +134,6 @@
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     node.parameter.accept(this);
-    node.defaultValue?.accept(
-      _SetGenericFunctionTypeIdVisitor(this),
-    );
   }
 
   @override
@@ -174,7 +155,7 @@
     var element = node.declaredElement as ExtensionElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.typeParameters?.accept(this);
@@ -193,12 +174,6 @@
   @override
   void visitFieldDeclaration(FieldDeclaration node) {
     node.fields.accept(this);
-
-    if (node.fields.isConst ||
-        !node.isStatic && node.fields.isFinal && _hasConstConstructor) {
-      var visitor = _SetGenericFunctionTypeIdVisitor(this);
-      node.fields.variables.accept(visitor);
-    }
   }
 
   @override
@@ -210,7 +185,7 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.type?.accept(this);
@@ -236,7 +211,10 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.functionExpression.typeParameters);
+    _createTypeParameterElements(
+      element,
+      node.functionExpression.typeParameters,
+    );
     scope = TypeParameterScope(outerScope, element.typeParameters);
     LinkingNodeContext(node, scope);
 
@@ -262,7 +240,7 @@
     var element = node.declaredElement as FunctionTypeAliasElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -288,7 +266,7 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -305,9 +283,8 @@
     var outerScope = scope;
     var outerReference = reference;
 
+    // TODO(scheglov) remove reference
     var id = _nextGenericFunctionTypeId++;
-    LazyAst.setGenericFunctionTypeId(node, id);
-
     var containerRef = unitReference.getChild('@genericFunctionType');
     reference = containerRef.getChild('$id');
 
@@ -316,10 +293,9 @@
       reference,
       node,
     );
-    (node as GenericFunctionTypeImpl).declaredElement = element;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -340,16 +316,23 @@
     var outerScope = scope;
     var outerReference = reference;
 
-    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
     reference = element.reference;
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.typeParameters?.accept(this);
-    node.functionType?.accept(this);
+    node.type?.accept(this);
     nodesToBuildType.addDeclaration(node);
 
+    var aliasedType = node.type;
+    if (aliasedType is GenericFunctionTypeImpl) {
+      element.encloseElement(
+        aliasedType.declaredElement as GenericFunctionTypeElementImpl,
+      );
+    }
+
     scope = outerScope;
     reference = outerReference;
   }
@@ -368,7 +351,7 @@
     reference = element.reference;
     element.parameters; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
 
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
@@ -393,7 +376,7 @@
     element.constructors; // create elements
     element.methods; // create elements
 
-    _createTypeParameterElements(node.typeParameters);
+    _createTypeParameterElements(element, node.typeParameters);
     scope = TypeParameterScope(scope, element.typeParameters);
 
     node.typeParameters?.accept(this);
@@ -424,10 +407,6 @@
   @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     node.variables.accept(this);
-    if (node.variables.isConst) {
-      var visitor = _SetGenericFunctionTypeIdVisitor(this);
-      node.variables.variables.accept(visitor);
-    }
   }
 
   @override
@@ -507,25 +486,25 @@
     node.mixinTypes.accept(this);
   }
 
-  void _createTypeParameterElement(TypeParameter node) {
-    var outerReference = this.reference;
-    var containerRef = outerReference.getChild('@typeParameter');
-    var reference = containerRef.getChild(node.name.name);
-    reference.node = node;
-
+  void _createTypeParameterElement(
+    ElementImpl enclosingElement,
+    TypeParameter node,
+  ) {
     var element = TypeParameterElementImpl.forLinkedNode(
-      outerReference.element,
-      reference,
+      enclosingElement,
       node,
     );
     node.name.staticElement = element;
   }
 
-  void _createTypeParameterElements(TypeParameterList typeParameterList) {
+  void _createTypeParameterElements(
+    ElementImpl enclosingElement,
+    TypeParameterList typeParameterList,
+  ) {
     if (typeParameterList == null) return;
 
     for (var typeParameter in typeParameterList.typeParameters) {
-      _createTypeParameterElement(typeParameter);
+      _createTypeParameterElement(enclosingElement, typeParameter);
     }
   }
 
@@ -541,20 +520,3 @@
     }
   }
 }
-
-/// For consistency we set identifiers for [GenericFunctionType]s in constant
-/// variable initializers, and instance final fields of classes with constant
-/// constructors.
-class _SetGenericFunctionTypeIdVisitor extends RecursiveAstVisitor<void> {
-  final ReferenceResolver resolver;
-
-  _SetGenericFunctionTypeIdVisitor(this.resolver);
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    var id = resolver._nextGenericFunctionTypeId++;
-    LazyAst.setGenericFunctionTypeId(node, id);
-
-    super.visitGenericFunctionType(node);
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index bb5b05d..03be657 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -7,18 +7,15 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/library_builder.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 
 /// Compute simple-boundedness for all classes and generic types aliases in
 /// the source [libraryBuilders].  There might be dependencies between them,
 /// so they all should be processed simultaneously.
 void computeSimplyBounded(
-  LinkedBundleContext bundleContext,
   Iterable<LibraryBuilder> libraryBuilders,
 ) {
-  var walker = SimplyBoundedDependencyWalker(bundleContext);
+  var walker = SimplyBoundedDependencyWalker();
   var nodes = <SimplyBoundedNode>[];
   for (var libraryBuilder in libraryBuilders) {
     for (var unit in libraryBuilder.element.units) {
@@ -41,18 +38,30 @@
     if (!node.isEvaluated) {
       walker.walk(node);
     }
-    LazyAst.setSimplyBounded(node._node, node.isSimplyBounded);
+    var node2 = node._node;
+    if (node2 is ClassOrMixinDeclaration) {
+      var element = node2.declaredElement as ClassElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else if (node2 is ClassTypeAlias) {
+      var element = node2.declaredElement as ClassElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else if (node2 is GenericTypeAlias) {
+      var element = node2.declaredElement as TypeAliasElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else if (node2 is FunctionTypeAlias) {
+      var element = node2.declaredElement as TypeAliasElementImpl;
+      element.isSimplyBounded = node.isSimplyBounded;
+    } else {
+      throw UnimplementedError('${node2.runtimeType}');
+    }
   }
 }
 
 /// The graph walker for evaluating whether types are simply bounded.
 class SimplyBoundedDependencyWalker
     extends graph.DependencyWalker<SimplyBoundedNode> {
-  final LinkedBundleContext bundleContext;
   final Map<Element, SimplyBoundedNode> nodeMap = Map.identity();
 
-  SimplyBoundedDependencyWalker(this.bundleContext);
-
   @override
   void evaluate(SimplyBoundedNode v) {
     v._evaluate();
@@ -158,11 +167,15 @@
       collector.visitParameters(node.parameters);
       return collector.types;
     } else if (node is GenericTypeAlias) {
-      var functionType = node.functionType;
-      if (functionType != null) {
+      var type = node.type;
+      if (type != null) {
         var collector = _TypeCollector();
-        collector.addType(functionType.returnType);
-        collector.visitParameters(functionType.parameters);
+        if (type is GenericFunctionType) {
+          collector.addType(type.returnType);
+          collector.visitParameters(type.parameters);
+        } else {
+          collector.addType(type);
+        }
         return collector.types;
       } else {
         return const <TypeAnnotation>[];
diff --git a/pkg/analyzer/lib/src/summary2/tokens_context.dart b/pkg/analyzer/lib/src/summary2/tokens_context.dart
index ab8ad17..95fd9c6 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_context.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_context.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
 
 /// The context for reading tokens.
 class TokensContext {
diff --git a/pkg/analyzer/lib/src/summary2/tokens_writer.dart b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
index 3e8bc74..e115141 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
 
 class TokensWriter {
   static UnlinkedTokenType astToBinaryTokenType(TokenType type) {
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 6639055..cafca28 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -11,14 +11,12 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/ast_resolver.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:meta/meta.dart';
 
@@ -159,7 +157,8 @@
             _parameters.add(parameterNode);
             _fields.add(fieldElement);
           } else {
-            LazyAst.setType(parameterNode, DynamicTypeImpl.instance);
+            (parameterElement as ParameterElementImpl).type =
+                DynamicTypeImpl.instance;
           }
         }
       }
@@ -179,7 +178,6 @@
     for (var i = 0; i < _parameters.length; ++i) {
       var parameter = _parameters[i];
       var type = _fields[i].type;
-      LazyAst.setType(parameter, type);
       (parameter.declaredElement as ParameterElementImpl).type = type;
     }
     isEvaluated = true;
@@ -189,7 +187,8 @@
   void markCircular(List<_InferenceNode> cycle) {
     for (var i = 0; i < _parameters.length; ++i) {
       var parameterNode = _parameters[i];
-      LazyAst.setType(parameterNode, DynamicTypeImpl.instance);
+      (parameterNode.declaredElement as ParameterElementImpl).type =
+          DynamicTypeImpl.instance;
     }
     isEvaluated = true;
   }
@@ -322,8 +321,11 @@
   void _addVariableNode(PropertyInducingElement element) {
     if (element.isSynthetic) return;
 
-    VariableDeclaration node = _getLinkedNode(element);
-    if (LazyAst.getType(node) != null) return;
+    var node = _getLinkedNode(element) as VariableDeclaration;
+    var variableList = node.parent as VariableDeclarationList;
+    if (variableList.type != null) {
+      return;
+    }
 
     if (node.initializer != null) {
       var inferenceNode =
@@ -332,7 +334,7 @@
       (element as PropertyInducingElementImpl).typeInference =
           _PropertyInducingElementTypeInference(inferenceNode);
     } else {
-      LazyAst.setType(node, DynamicTypeImpl.instance);
+      (element as PropertyInducingElementImpl).type = DynamicTypeImpl.instance;
     }
   }
 }
@@ -382,6 +384,10 @@
     return false;
   }
 
+  PropertyInducingElementImpl get _elementImpl {
+    return _node.declaredElement as PropertyInducingElementImpl;
+  }
+
   @override
   List<_InferenceNode> computeDependencies() {
     _resolveInitializer(forDependencies: true);
@@ -401,7 +407,7 @@
     for (var node in dependencies) {
       if (node is _VariableInferenceNode &&
           node.isImplicitlyTypedInstanceField) {
-        LazyAst.setType(_node, DynamicTypeImpl.instance);
+        _elementImpl.type = DynamicTypeImpl.instance;
         isEvaluated = true;
         return const <_InferenceNode>[];
       }
@@ -414,10 +420,10 @@
   void evaluate() {
     _resolveInitializer(forDependencies: false);
 
-    if (LazyAst.getType(_node) == null) {
+    if (!_elementImpl.hasTypeInferred) {
       var initializerType = _node.initializer.staticType;
       initializerType = _refineType(initializerType);
-      LazyAst.setType(_node, initializerType);
+      _elementImpl.type = initializerType;
     }
 
     isEvaluated = true;
@@ -425,19 +431,16 @@
 
   @override
   void markCircular(List<_InferenceNode> cycle) {
-    LazyAst.setType(_node, DynamicTypeImpl.instance);
+    _elementImpl.type = DynamicTypeImpl.instance;
 
     var cycleNames = <String>{};
     for (var inferenceNode in cycle) {
       cycleNames.add(inferenceNode.displayName);
     }
 
-    LazyAst.setTypeInferenceError(
-      _node,
-      TopLevelInferenceErrorBuilder(
-        kind: TopLevelInferenceErrorKind.dependencyCycle,
-        arguments: cycleNames.toList(),
-      ),
+    _elementImpl.typeInferenceError = TopLevelInferenceError(
+      kind: TopLevelInferenceErrorKind.dependencyCycle,
+      arguments: cycleNames.toList(),
     );
 
     isEvaluated = true;
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index 0ee7be4..f69f097 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -2,66 +2,31 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 
 class TypeAliasSelfReferenceFinder {
-  NullabilitySuffix _unitNullability;
-
   /// Check typedefs and mark the ones having self references.
   void perform(Linker linker) {
     for (var builder in linker.builders.values) {
       for (var unitContext in builder.context.units) {
-        _unitNullability =
-            unitContext.unit.featureSet.isEnabled(Feature.non_nullable)
-                ? NullabilitySuffix.none
-                : NullabilitySuffix.star;
         for (var node in unitContext.unit.declarations) {
           if (node is FunctionTypeAlias) {
             var finder = _Finder(node);
             finder.functionTypeAlias(node);
-            LazyFunctionTypeAlias.setHasSelfReference(
-              node,
-              finder.hasSelfReference,
-            );
+            var element = node.declaredElement as TypeAliasElementImpl;
+            element.hasSelfReference = finder.hasSelfReference;
           } else if (node is GenericTypeAlias) {
             var finder = _Finder(node);
             finder.genericTypeAlias(node);
-            LazyGenericTypeAlias.setHasSelfReference(
-              node,
-              finder.hasSelfReference,
-            );
-            if (finder.hasSelfReference) {
-              _sanitizeGenericTypeAlias(node);
-            }
+            var element = node.declaredElement as TypeAliasElementImpl;
+            element.hasSelfReference = finder.hasSelfReference;
           }
         }
       }
     }
   }
-
-  void _sanitizeGenericTypeAlias(GenericTypeAlias node) {
-    var typeParameterList = node.typeParameters;
-    if (typeParameterList != null) {
-      for (var typeParameter in typeParameterList.typeParameters) {
-        typeParameter.bound = null;
-      }
-    }
-    node.functionType.returnType = null;
-    node.functionType.parameters.parameters.clear();
-    (node.functionType as GenericFunctionTypeImpl).type = FunctionTypeImpl(
-      typeFormals: const [],
-      parameters: const [],
-      returnType: DynamicTypeImpl.instance,
-      nullabilitySuffix: _unitNullability,
-    );
-  }
 }
 
 class _Finder {
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 249c4eb..9ad85a2 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/summary2/default_types_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 
 class NodesToBuildType {
@@ -90,7 +89,8 @@
           returnType = _dynamicType;
         }
       }
-      LazyAst.setReturnType(node, returnType);
+      var element = node.declaredElement as ExecutableElementImpl;
+      element.returnType = returnType;
     } else if (node is FunctionTypeAlias) {
       _functionTypeAlias(node);
     } else if (node is FunctionTypedFormalParameter) {
@@ -108,16 +108,18 @@
           returnType = _dynamicType;
         }
       }
-      LazyAst.setReturnType(node, returnType);
+      var element = node.declaredElement as ExecutableElementImpl;
+      element.returnType = returnType;
     } else if (node is MixinDeclaration) {
       // TODO(scheglov) ???
     } else if (node is SimpleFormalParameter) {
-      LazyAst.setType(node, node.type?.type ?? _dynamicType);
+      var element = node.declaredElement as ParameterElementImpl;
+      element.type = node.type?.type ?? _dynamicType;
     } else if (node is VariableDeclarationList) {
       var type = node.type?.type;
       if (type != null) {
         for (var variable in node.variables) {
-          LazyAst.setType(variable, type);
+          (variable.declaredElement as VariableElementImpl).type = type;
         }
       }
     } else {
@@ -136,25 +138,24 @@
         parameterList,
         _nullability(node, node.question != null),
       );
-      LazyAst.setType(node, type);
+      var element = node.declaredElement as ParameterElementImpl;
+      element.type = type;
     } else {
-      LazyAst.setType(node, node.type?.type ?? _dynamicType);
+      var element = node.declaredElement as ParameterElementImpl;
+      element.type = node.type?.type ?? _dynamicType;
     }
   }
 
-  List<ParameterElementImpl> _formalParameters(FormalParameterList node) {
+  List<ParameterElement> _formalParameters(FormalParameterList node) {
     return node.parameters.asImpl.map((parameter) {
-      return ParameterElementImpl.synthetic(
-        parameter.identifier?.name ?? '',
-        _getType(parameter),
-        parameter.kind,
-      );
+      return parameter.declaredElement;
     }).toList();
   }
 
   void _functionTypeAlias(FunctionTypeAlias node) {
     var returnTypeNode = node.returnType;
-    LazyAst.setReturnType(node, returnTypeNode?.type ?? _dynamicType);
+    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    element.function.returnType = returnTypeNode?.type ?? _dynamicType;
   }
 
   void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
@@ -164,7 +165,8 @@
       node.parameters,
       _nullability(node, node.question != null),
     );
-    LazyAst.setType(node, type);
+    var element = node.declaredElement as ParameterElementImpl;
+    element.type = type;
   }
 
   bool _isNonNullableByDefault(AstNode node) {
@@ -193,13 +195,6 @@
         .map<TypeParameterElement>((p) => p.declaredElement)
         .toList();
   }
-
-  static DartType _getType(FormalParameter node) {
-    if (node is DefaultFormalParameter) {
-      return _getType(node.parameter);
-    }
-    return LazyAst.getType(node);
-  }
 }
 
 /// Performs mixins inference in a [ClassDeclaration].
diff --git a/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart b/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart
new file mode 100644
index 0000000..e11b1e0
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart
@@ -0,0 +1,146 @@
+/// Enum of token types, corresponding to AST token types.
+enum UnlinkedTokenType {
+  NOTHING,
+  ABSTRACT,
+  AMPERSAND,
+  AMPERSAND_AMPERSAND,
+  AMPERSAND_EQ,
+  AS,
+  ASSERT,
+  ASYNC,
+  AT,
+  AWAIT,
+  BACKPING,
+  BACKSLASH,
+  BANG,
+  BANG_EQ,
+  BANG_EQ_EQ,
+  BAR,
+  BAR_BAR,
+  BAR_EQ,
+  BREAK,
+  CARET,
+  CARET_EQ,
+  CASE,
+  CATCH,
+  CLASS,
+  CLOSE_CURLY_BRACKET,
+  CLOSE_PAREN,
+  CLOSE_SQUARE_BRACKET,
+  COLON,
+  COMMA,
+  CONST,
+  CONTINUE,
+  COVARIANT,
+  DEFAULT,
+  DEFERRED,
+  DO,
+  DOUBLE,
+  DYNAMIC,
+  ELSE,
+  ENUM,
+  EOF,
+  EQ,
+  EQ_EQ,
+  EQ_EQ_EQ,
+  EXPORT,
+  EXTENDS,
+  EXTERNAL,
+  FACTORY,
+  FALSE,
+  FINAL,
+  FINALLY,
+  FOR,
+  FUNCTION,
+  FUNCTION_KEYWORD,
+  GET,
+  GT,
+  GT_EQ,
+  GT_GT,
+  GT_GT_EQ,
+  GT_GT_GT,
+  GT_GT_GT_EQ,
+  HASH,
+  HEXADECIMAL,
+  HIDE,
+  IDENTIFIER,
+  IF,
+  IMPLEMENTS,
+  IMPORT,
+  IN,
+  INDEX,
+  INDEX_EQ,
+  INT,
+  INTERFACE,
+  IS,
+  LATE,
+  LIBRARY,
+  LT,
+  LT_EQ,
+  LT_LT,
+  LT_LT_EQ,
+  MINUS,
+  MINUS_EQ,
+  MINUS_MINUS,
+  MIXIN,
+  MULTI_LINE_COMMENT,
+  NATIVE,
+  NEW,
+  NULL,
+  OF,
+  ON,
+  OPEN_CURLY_BRACKET,
+  OPEN_PAREN,
+  OPEN_SQUARE_BRACKET,
+  OPERATOR,
+  PART,
+  PATCH,
+  PERCENT,
+  PERCENT_EQ,
+  PERIOD,
+  PERIOD_PERIOD,
+  PERIOD_PERIOD_PERIOD,
+  PERIOD_PERIOD_PERIOD_QUESTION,
+  PLUS,
+  PLUS_EQ,
+  PLUS_PLUS,
+  QUESTION,
+  QUESTION_PERIOD,
+  QUESTION_QUESTION,
+  QUESTION_QUESTION_EQ,
+  REQUIRED,
+  RETHROW,
+  RETURN,
+  SCRIPT_TAG,
+  SEMICOLON,
+  SET,
+  SHOW,
+  SINGLE_LINE_COMMENT,
+  SLASH,
+  SLASH_EQ,
+  SOURCE,
+  STAR,
+  STAR_EQ,
+  STATIC,
+  STRING,
+  STRING_INTERPOLATION_EXPRESSION,
+  STRING_INTERPOLATION_IDENTIFIER,
+  SUPER,
+  SWITCH,
+  SYNC,
+  THIS,
+  THROW,
+  TILDE,
+  TILDE_SLASH,
+  TILDE_SLASH_EQ,
+  TRUE,
+  TRY,
+  TYPEDEF,
+  VAR,
+  VOID,
+  WHILE,
+  WITH,
+  YIELD,
+  INOUT,
+  OUT,
+}
diff --git a/pkg/analyzer/lib/src/summary2/variance_builder.dart b/pkg/analyzer/lib/src/summary2/variance_builder.dart
index 51d0100..755f4c9 100644
--- a/pkg/analyzer/lib/src/summary2/variance_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/variance_builder.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 import 'package:meta/meta.dart';
@@ -74,8 +73,8 @@
           }
         }
         return result;
-      } else if (element is FunctionTypeAliasElementImpl) {
-        _functionTypeAliasElement(element);
+      } else if (element is TypeAliasElementImpl) {
+        _typeAliasElement(element);
 
         var result = Variance.unrelated;
 
@@ -149,7 +148,7 @@
     // Recursion detected, recover.
     if (_visit.contains(node)) {
       for (var parameter in parameterList.typeParameters) {
-        LazyAst.setVariance(parameter, Variance.covariant);
+        _setVariance(parameter, Variance.covariant);
       }
       return;
     }
@@ -171,24 +170,13 @@
             node.parameters,
           ),
         );
-        LazyAst.setVariance(parameter, variance);
+        _setVariance(parameter, variance);
       }
     } finally {
       _visit.remove(node);
     }
   }
 
-  void _functionTypeAliasElement(FunctionTypeAliasElementImpl element) {
-    var node = element.linkedNode;
-    if (node is GenericTypeAlias) {
-      _genericTypeAlias(node);
-    } else if (node is FunctionTypeAlias) {
-      _functionTypeAlias(node);
-    } else {
-      throw UnimplementedError('(${node.runtimeType}) $node');
-    }
-  }
-
   void _genericTypeAlias(GenericTypeAlias node) {
     var parameterList = node.typeParameters;
     if (parameterList == null) {
@@ -198,7 +186,7 @@
     // Recursion detected, recover.
     if (_visit.contains(node)) {
       for (var parameter in parameterList.typeParameters) {
-        LazyAst.setVariance(parameter, Variance.covariant);
+        _setVariance(parameter, Variance.covariant);
       }
       return;
     }
@@ -213,7 +201,7 @@
     // Not a function type, recover.
     if (type == null) {
       for (var parameter in parameterList.typeParameters) {
-        LazyAst.setVariance(parameter, Variance.covariant);
+        _setVariance(parameter, Variance.covariant);
       }
     }
 
@@ -221,13 +209,24 @@
     try {
       for (var parameter in parameterList.typeParameters) {
         var variance = _compute(parameter.declaredElement, type);
-        LazyAst.setVariance(parameter, variance);
+        _setVariance(parameter, variance);
       }
     } finally {
       _visit.remove(node);
     }
   }
 
+  void _typeAliasElement(TypeAliasElementImpl element) {
+    var node = element.linkedNode;
+    if (node is GenericTypeAlias) {
+      _genericTypeAlias(node);
+    } else if (node is FunctionTypeAlias) {
+      _functionTypeAlias(node);
+    } else {
+      throw UnimplementedError('(${node.runtimeType}) $node');
+    }
+  }
+
   void _typeParameters(TypeParameterList parameterList) {
     if (parameterList == null) {
       return;
@@ -238,8 +237,13 @@
       var varianceKeyword = parameterImpl.varianceKeyword;
       if (varianceKeyword != null) {
         var variance = Variance.fromKeywordString(varianceKeyword.lexeme);
-        LazyAst.setVariance(parameter, variance);
+        _setVariance(parameter, variance);
       }
     }
   }
+
+  static void _setVariance(TypeParameter node, Variance variance) {
+    var element = node.declaredElement as TypeParameterElementImpl;
+    element.variance = variance;
+  }
 }
diff --git a/pkg/analyzer/lib/src/task/inference_error.dart b/pkg/analyzer/lib/src/task/inference_error.dart
new file mode 100644
index 0000000..4a686ff
--- /dev/null
+++ b/pkg/analyzer/lib/src/task/inference_error.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// The top-level type inference error.
+class TopLevelInferenceError {
+  /// The kind of the error.
+  final TopLevelInferenceErrorKind kind;
+
+  /// The [kind] specific arguments.
+  final List<String> arguments;
+
+  TopLevelInferenceError({
+    @required this.kind,
+    @required this.arguments,
+  });
+}
+
+/// Enum used to indicate the kind of the error during top-level inference.
+enum TopLevelInferenceErrorKind {
+  none,
+  assignment,
+  instanceGetter,
+  dependencyCycle,
+  overrideConflictFieldType,
+  overrideNoCombinedSuperSignature,
+}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 7db1cf7..7e57d0c 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -20,7 +20,7 @@
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart'
     show CompileTimeErrorCode, StrongModeCode;
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:meta/meta.dart';
 
 DartType _elementType(Element e) {
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index e6a5f7c..b303bf0 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -11,9 +11,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 
 /// An object used to infer the type of instance fields and the return types of
 /// instance methods within a single compilation unit.
@@ -287,11 +285,9 @@
             type = typeSystem.nonNullifyLegacy(type);
             field.type = type;
           } else {
-            LazyAst.setTypeInferenceError(
-              field.linkedNode,
-              TopLevelInferenceErrorBuilder(
-                kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
-              ),
+            field.typeInferenceError = TopLevelInferenceError(
+              kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
+              arguments: const <String>[],
             );
           }
           return;
@@ -429,12 +425,9 @@
           }
         }
 
-        LazyAst.setTypeInferenceError(
-          element.linkedNode,
-          TopLevelInferenceErrorBuilder(
-            kind: TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature,
-            arguments: [conflictExplanation],
-          ),
+        element.typeInferenceError = TopLevelInferenceError(
+          kind: TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature,
+          arguments: [conflictExplanation],
         );
       }
     }
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index ce24cde..6add61d 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -541,6 +541,15 @@
     throw StateError('Not found: $name');
   }
 
+  TypeAliasElement typeAlias(String name) {
+    for (var element in unitElement.typeAliases) {
+      if (element.name == name) {
+        return element;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
   ConstructorElement unnamedConstructor(String name) {
     return class_(name).unnamedConstructor;
   }
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index cd29202..5007cde 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -253,7 +253,7 @@
 
 class ArgumentError extends Error {
   ArgumentError([message]);
-  
+
   static T checkNotNull<T>(T argument, [String, name]) => argument;
 }
 
diff --git a/pkg/analyzer/lib/src/util/sdk.dart b/pkg/analyzer/lib/src/util/sdk.dart
index 7f6bdea..e1dd259 100644
--- a/pkg/analyzer/lib/src/util/sdk.dart
+++ b/pkg/analyzer/lib/src/util/sdk.dart
@@ -6,23 +6,6 @@
 
 import 'package:path/path.dart' as path;
 
-/// Return `true` if the given [sdkPath] is valid, i.e. has all required
-/// artifacts.
-String computePlatformBinariesPath(String sdkPath) {
-  // Try the given SDK path.
-  {
-    String location = path.join(sdkPath, 'lib', '_internal');
-    if (File(path.join(location, 'vm_platform_strong.dill')).existsSync()) {
-      return location;
-    }
-  }
-
-  // The given SDK path does not work.
-  // Then we're probably running on bots, in 'xcodebuild/ReleaseX64'.
-  // In this case 'vm_platform_strong.dill' is next to the 'dart'.
-  return path.dirname(Platform.resolvedExecutable);
-}
-
 String getSdkPath([List<String> args]) {
   // Look for --dart-sdk on the command line.
   if (args != null) {
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 7240390..17ac171 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -297,7 +297,16 @@
               provider.pathContext.join(generatedRootPath, packageName);
           return PackageBuildWorkspace._(provider, packageMap, folder.path,
               packageName, generatedRootPath, generatedThisPath);
-        } catch (_) {}
+        } catch (_) {
+          return null;
+        }
+      }
+
+      // We found `pubspec.yaml`, but not `.dart_tool/build`.
+      // Stop going up, this package does not have package:build results.
+      // We don't want to find results of a parent package.
+      if (pubspec.exists) {
+        return null;
       }
 
       // Go up the folder.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 0ad2ec6..c14bbd5 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,13 +1,13 @@
 name: analyzer
-version: 0.41.0
+version: 0.41.1
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
 environment:
-  sdk: '>=2.7.0 <3.0.0'
+  sdk: '>=2.9.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^12.0.0
+  _fe_analyzer_shared: ^14.0.0
   args: ^1.0.0
   cli_util: '>=0.1.4 <0.3.0'
   collection: ^1.10.1
@@ -20,10 +20,10 @@
   pub_semver: ^1.4.2
   source_span: ^1.2.0
   watcher: ^0.9.6
-  yaml: ^2.1.2
+  yaml: ">=2.1.2 <4.0.0"
 dev_dependencies:
-  analysis_tool:
-    path: ../analysis_tool
+  analyzer_utilities:
+    path: ../analyzer_utilities
   linter: any
   matcher: ^0.12.3
   pedantic: ^1.9.0
diff --git a/pkg/analyzer/test/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart
index 0c2dbf0..da03e22 100644
--- a/pkg/analyzer/test/dart/analysis/utilities_test.dart
+++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:path/path.dart' as p;
+import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -91,7 +92,10 @@
     String content = '''
 int? f() => 1;
 ''';
-    var featureSet = FeatureSet.forTesting(sdkVersion: '2.3.0');
+    var featureSet = FeatureSet.fromEnableFlags2(
+      sdkLanguageVersion: Version.parse('2.9.0'),
+      flags: [],
+    );
     expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
     ParseStringResult result = _withMemoryFile(
         content,
@@ -179,7 +183,10 @@
     String content = '''
 int? f() => 1;
 ''';
-    var featureSet = FeatureSet.forTesting(sdkVersion: '2.3.0');
+    var featureSet = FeatureSet.fromEnableFlags2(
+      sdkLanguageVersion: Version.parse('2.9.0'),
+      flags: [],
+    );
     expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
     ParseStringResult result = parseString(
         content: content, throwIfDiagnostics: false, featureSet: featureSet);
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 635d7ff..ba3b7ed 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -1693,7 +1693,8 @@
     VariableDeclaration varDecl = AstTestFactory.variableDeclaration("a");
     TopLevelVariableDeclaration decl =
         AstTestFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
-    Comment comment = astFactory.documentationComment(List<Token>(0));
+    Comment comment =
+        astFactory.documentationComment(List<Token>.filled(0, null));
     expect(varDecl.documentationComment, isNull);
     decl.documentationComment = comment;
     expect(varDecl.documentationComment, isNotNull);
@@ -1702,7 +1703,8 @@
 
   void test_getDocumentationComment_onNode() {
     VariableDeclaration decl = AstTestFactory.variableDeclaration("a");
-    Comment comment = astFactory.documentationComment(List<Token>(0));
+    Comment comment =
+        astFactory.documentationComment(List<Token>.filled(0, null));
     decl.documentationComment = comment;
     expect(decl.documentationComment, isNotNull);
   }
diff --git a/pkg/analyzer/test/file_system/physical_file_system_test.dart b/pkg/analyzer/test/file_system/physical_file_system_test.dart
index 81e3c67..8f41e08 100644
--- a/pkg/analyzer/test/file_system/physical_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/physical_file_system_test.dart
@@ -56,7 +56,7 @@
   /// Create the resource provider to be used by the tests. Subclasses can
   /// override this method to change the class of resource provider that is
   /// used.
-  PhysicalResourceProvider createProvider() => PhysicalResourceProvider(null);
+  PhysicalResourceProvider createProvider() => PhysicalResourceProvider();
 
   @override
   File getFile({@required bool exists, String content, String filePath}) {
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 0706fb6..d6c1131 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader;
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -176,48 +175,6 @@
     expect(source1 == source2, isTrue);
   }
 
-  test_fileReadMode() async {
-    expect(FileBasedSource.fileReadMode('a'), 'a');
-    expect(FileBasedSource.fileReadMode('a\n'), 'a\n');
-    expect(FileBasedSource.fileReadMode('ab'), 'ab');
-    expect(FileBasedSource.fileReadMode('abc'), 'abc');
-    expect(FileBasedSource.fileReadMode('a\nb'), 'a\nb');
-    expect(FileBasedSource.fileReadMode('a\rb'), 'a\rb');
-    expect(FileBasedSource.fileReadMode('a\r\nb'), 'a\r\nb');
-  }
-
-  test_fileReadMode_changed() async {
-    FileBasedSource.fileReadMode = (String s) => s + 'xyz';
-    expect(FileBasedSource.fileReadMode('a'), 'axyz');
-    expect(FileBasedSource.fileReadMode('a\n'), 'a\nxyz');
-    expect(FileBasedSource.fileReadMode('ab'), 'abxyz');
-    expect(FileBasedSource.fileReadMode('abc'), 'abcxyz');
-    FileBasedSource.fileReadMode = (String s) => s;
-  }
-
-  test_fileReadMode_normalize_eol_always() async {
-    FileBasedSource.fileReadMode =
-        PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS;
-    expect(FileBasedSource.fileReadMode('a'), 'a');
-
-    // '\n' -> '\n' as first, last and only character
-    expect(FileBasedSource.fileReadMode('\n'), '\n');
-    expect(FileBasedSource.fileReadMode('a\n'), 'a\n');
-    expect(FileBasedSource.fileReadMode('\na'), '\na');
-
-    // '\r\n' -> '\n' as first, last and only character
-    expect(FileBasedSource.fileReadMode('\r\n'), '\n');
-    expect(FileBasedSource.fileReadMode('a\r\n'), 'a\n');
-    expect(FileBasedSource.fileReadMode('\r\na'), '\na');
-
-    // '\r' -> '\n' as first, last and only character
-    expect(FileBasedSource.fileReadMode('\r'), '\n');
-    expect(FileBasedSource.fileReadMode('a\r'), 'a\n');
-    expect(FileBasedSource.fileReadMode('\ra'), '\na');
-
-    FileBasedSource.fileReadMode = (String s) => s;
-  }
-
   test_getFullName() async {
     String fullPath = "/does/not/exist.dart";
     JavaFile file = FileUtilities2.createFile(fullPath);
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 0476d18..c139b6e 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -215,27 +215,6 @@
     );
   }
 
-  FunctionTypeAliasElementImpl functionTypeAlias({
-    @required String name,
-    List<TypeParameterElement> typeParameters = const [],
-    @required GenericFunctionTypeElement function,
-  }) {
-    return FunctionTypeAliasElementImpl(name, 0)
-      ..typeParameters = typeParameters
-      ..function = function as GenericFunctionTypeElementImpl;
-  }
-
-  FunctionType functionTypeAliasType(
-    FunctionTypeAliasElement element, {
-    List<DartType> typeArguments = const [],
-    NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
-  }) {
-    return element.instantiate(
-      typeArguments: typeArguments,
-      nullabilitySuffix: nullabilitySuffix,
-    );
-  }
-
   FunctionTypeImpl functionTypeNone({
     List<TypeParameterElement> typeFormals = const [],
     List<ParameterElement> parameters = const [],
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 7c6e3d9..07a3c23 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -81,7 +81,7 @@
 
   test_ignore_for_file_whitespace_variant() async {
     await assertNoErrorsInCode('''
-//ignore_for_file:   $ignoredCode , unnecessary_cast
+//ignore_for_file:   unused_element , unnecessary_cast
 int x = (0 as int);  //UNNECESSARY_CAST
 String _foo; //UNUSED_ELEMENT
 ''');
@@ -97,7 +97,7 @@
     await assertErrorsInCode('''
 //UNNECESSARY_CAST
 int x = (0 as int);
-// ignore: $ignoredCode
+// ignore: unused_element
 String _foo; //UNUSED_ELEMENT
 ''', [
       error(HintCode.UNNECESSARY_CAST, 28, 8),
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index a116216..6fd7955 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -79,6 +79,25 @@
 ''');
   }
 
+  test_extensionOverrideInAnnotationContext_importedWithPrefix() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+extension E on Object {
+  int f() => 0;
+}
+''');
+    await _assertCanBeAnalyzed('''
+import 'a.dart' as prefix;
+
+class A {
+  const A(int x);
+}
+
+@R(prefix.E(null).f())
+void g() {}
+}
+''');
+  }
+
   test_extensionOverrideInConstContext() async {
     await _assertCanBeAnalyzed('''
 extension E on Object {
@@ -196,11 +215,11 @@
 ''');
   }
 
-  @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
     // read fully.
+    // Fixed 2020-11-12.
     await _assertCanBeAnalyzed(r'''
 void f({a = [for (@b c = 0;;)]}) {}
 ''');
@@ -294,6 +313,13 @@
 ''');
   }
 
+  test_invalidPart_withPart() async {
+    await _assertCanBeAnalyzed('''
+part of a;
+part 'test.dart';
+''');
+  }
+
   test_keywordInConstructorInitializer_assert() async {
     await _assertCanBeAnalyzed('''
 class C {
@@ -337,6 +363,12 @@
 ''');
   }
 
+  test_syntheticImportPrefix() async {
+    await _assertCanBeAnalyzed('''
+import 'dart:math' as;
+''');
+  }
+
   test_typeBeforeAnnotation() async {
     await _assertCanBeAnalyzed('''
 class A {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 95d7b3e..8bfa672 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2045,7 +2045,7 @@
   List<E> m();
 }
 class B extends A<dynamic> {
-  List<dynamic> m() { return new List<dynamic>(); }
+  List<dynamic> m() { return <dynamic>[]; }
 }
 ''');
   }
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index bd32129..e283dd5 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -67,7 +67,7 @@
     await assertNoErrorsInCode(r'''
 class A { }
 class X<T> {
-  final x = new List<T>();
+  final x = <T>[];
 }
 class Z {
   final X<A> y = new X<A>();
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index d054a17..34b6b84 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1142,8 +1142,7 @@
     expect(thenExpression, isParenthesizedExpression);
     Expression elseExpression = expression.elseExpression;
     expect(elseExpression, isSimpleIdentifier);
-    assertErrors(
-        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 9, 1)]);
+    assertNoErrors();
   }
 
   void test_conditionalExpression_precedence_nullableType_as3() {
@@ -1158,8 +1157,7 @@
     expect(thenExpression, isParenthesizedExpression);
     Expression elseExpression = expression.elseExpression;
     expect(elseExpression, isSimpleIdentifier);
-    assertErrors(
-        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 10, 1)]);
+    assertNoErrors();
   }
 
   void test_conditionalExpression_precedence_nullableType_is2() {
@@ -1173,8 +1171,7 @@
     expect(thenExpression, isParenthesizedExpression);
     Expression elseExpression = expression.elseExpression;
     expect(elseExpression, isSimpleIdentifier);
-    assertErrors(
-        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 11, 1)]);
+    assertNoErrors();
   }
 
   void test_conditionalExpression_precedence_nullableType_is3() {
@@ -1189,8 +1186,7 @@
     expect(thenExpression, isParenthesizedExpression);
     Expression elseExpression = expression.elseExpression;
     expect(elseExpression, isSimpleIdentifier);
-    assertErrors(
-        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 12, 1)]);
+    assertNoErrors();
   }
 }
 
@@ -1877,17 +1873,16 @@
     implements AbstractParserTestCase {
   static final List<ErrorCode> NO_ERROR_COMPARISON = <ErrorCode>[];
 
-  final controlFlow = FeatureSet.forTesting(
-      sdkVersion: '2.0.0',
-      additionalFeatures: [Feature.control_flow_collections]);
+  final controlFlow = FeatureSet.latestLanguageVersion();
 
-  final spread = FeatureSet.forTesting(
-      sdkVersion: '2.0.0', additionalFeatures: [Feature.spread_collections]);
+  final spread = FeatureSet.latestLanguageVersion();
 
-  final nonNullable = FeatureSet.forTesting(
-      sdkVersion: '2.2.2', additionalFeatures: [Feature.non_nullable]);
+  final nonNullable = FeatureSet.latestLanguageVersion();
 
-  final preNonNullable = FeatureSet.forTesting(sdkVersion: '2.2.2');
+  final preNonNullable = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.9.0'),
+    flags: [],
+  );
 
   ParserProxy _parserProxy;
 
@@ -2169,7 +2164,8 @@
 
   @override
   FormalParameter parseFormalParameter(String code, ParameterKind kind,
-      {List<ErrorCode> errorCodes = const <ErrorCode>[]}) {
+      {List<ErrorCode> errorCodes = const <ErrorCode>[],
+      FeatureSet featureSet}) {
     String parametersCode;
     if (kind == ParameterKind.REQUIRED) {
       parametersCode = '($code)';
@@ -2181,7 +2177,7 @@
       fail('$kind');
     }
     FormalParameterList list = parseFormalParameterList(parametersCode,
-        inFunctionType: false, errorCodes: errorCodes);
+        inFunctionType: false, errorCodes: errorCodes, featureSet: featureSet);
     return list.parameters.single;
   }
 
@@ -2189,8 +2185,9 @@
   FormalParameterList parseFormalParameterList(String code,
       {bool inFunctionType = false,
       List<ErrorCode> errorCodes = const <ErrorCode>[],
-      List<ExpectedError> errors}) {
-    createParser(code);
+      List<ExpectedError> errors,
+      FeatureSet featureSet}) {
+    createParser(code, featureSet: featureSet);
     FormalParameterList result =
         _parserProxy.parseFormalParameterList(inFunctionType: inFunctionType);
     assertErrors(codes: errors != null ? null : errorCodes, errors: errors);
@@ -2456,6 +2453,7 @@
   void test_functionTyped_named_nullable_disabled() {
     ParameterKind kind = ParameterKind.NAMED;
     var defaultParameter = parseFormalParameter('a()? : null', kind,
+            featureSet: preNonNullable,
             errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED])
         as DefaultFormalParameter;
     var functionParameter =
@@ -2474,6 +2472,7 @@
   void test_functionTyped_positional_nullable_disabled() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     var defaultParameter = parseFormalParameter('a()? = null', kind,
+            featureSet: preNonNullable,
             errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED])
         as DefaultFormalParameter;
     var functionParameter =
@@ -2492,6 +2491,7 @@
   void test_functionTyped_required_nullable_disabled() {
     ParameterKind kind = ParameterKind.REQUIRED;
     var functionParameter = parseFormalParameter('a()?', kind,
+            featureSet: preNonNullable,
             errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED])
         as FunctionTypedFormalParameter;
     expect(functionParameter.returnType, isNull);
@@ -2676,7 +2676,9 @@
           List<ExpectedError> errors,
           FeatureSet featureSet}) =>
       super.parseCompilationUnit(content,
-          codes: codes, errors: errors, featureSet: featureSet ?? nonNullable);
+          codes: codes,
+          errors: errors,
+          featureSet: featureSet ?? FeatureSet.latestLanguageVersion());
 
   void test_assignment_complex() {
     parseCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 3f1b6d7..340cb84 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2354,8 +2354,7 @@
     createParser('abstract C f;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener.assertErrors(
-        [expectedError(ParserErrorCode.ABSTRACT_CLASS_MEMBER, 0, 8)]);
+    assertNoErrors();
   }
 
   void test_abstractClassMember_getter() {
@@ -3342,10 +3341,8 @@
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
     if (usingFastaParser) {
-      listener.assertErrors([
-        expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8),
-        expectedError(CompileTimeErrorCode.CONST_NOT_INITIALIZED, 17, 1)
-      ]);
+      listener.assertErrors(
+          [expectedError(CompileTimeErrorCode.CONST_NOT_INITIALIZED, 17, 1)]);
     } else {
       listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]);
     }
@@ -3355,32 +3352,28 @@
     createParser('external final A f;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener
-        .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]);
+    assertNoErrors();
   }
 
   void test_externalField_static() {
     createParser('external static A f;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener
-        .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]);
+    assertNoErrors();
   }
 
   void test_externalField_typed() {
     createParser('external A f;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener
-        .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]);
+    assertNoErrors();
   }
 
   void test_externalField_untyped() {
     createParser('external var f;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener
-        .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]);
+    assertNoErrors();
   }
 
   void test_externalGetterWithBody() {
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index d1ca7a3..3453f53 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -16,7 +16,6 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/dart/resolution/context_collection_resolution.dart';
-import 'resolver_test_case.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -78,34 +77,6 @@
   }
 }
 
-/// Tests for generic method and function resolution that do not use strong
-/// mode.
-@reflectiveTest
-class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared {
-  test_genericMethod_propagatedType_promotion() async {
-    // Regression test for:
-    // https://github.com/dart-lang/sdk/issues/25340
-    //
-    // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
-    // strong mode example won't work, as we now compute a static type and
-    // therefore discard the propagated type.
-    //
-    // So this test does not use strong mode.
-    await assertNoErrorsInCode(r'''
-abstract class Iter {
-  List<S> map<S>(S f(x));
-}
-class C {}
-C toSpan(dynamic element) {
-  if (element is Iter) {
-    var y = element.map(toSpan);
-  }
-  return null;
-}''');
-    expectIdentifierType('y = ', 'dynamic');
-  }
-}
-
 @reflectiveTest
 class PrefixedNamespaceTest extends PubPackageResolutionTest {
   void test_lookup_missing() {
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 050de16..f93c5d8 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -284,17 +284,6 @@
 
 /// Shared infrastructure for [StaticTypeAnalyzer2Test].
 class StaticTypeAnalyzer2TestShared extends PubPackageResolutionTest {
-  /// Find the expression that starts at the offset of [search] and validate its
-  /// that its static type matches the given [type].
-  ///
-  /// If [type] is a string, validates that the expression's static type
-  /// stringifies to that text. Otherwise, [type] is used directly a [Matcher]
-  /// to match the type.
-  void expectExpressionType(String search, type) {
-    Expression expression = findNode.expression(search);
-    _expectType(expression.staticType, type);
-  }
-
   /// Looks up the identifier with [name] and validates that its type type
   /// stringifies to [type] and that its generics match the given stringified
   /// output.
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 408930a..819c49a 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart' show ResolverVisitor;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
@@ -23,15 +22,12 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'elements_types_mixin.dart';
-import 'resolver_test_case.dart';
 import 'test_analysis_context.dart';
 import 'test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(SetLiteralsTest);
     defineReflectiveTests(StaticTypeAnalyzerTest);
-    defineReflectiveTests(StaticTypeAnalyzer2Test);
   });
 }
 
@@ -45,188 +41,6 @@
 }
 
 @reflectiveTest
-class SetLiteralsTest extends StaticTypeAnalyzer2TestShared {
-  test_emptySetLiteral_parameter_typed() async {
-    await assertNoErrorsInCode(r'''
-main() {
-  useSet({});
-}
-void useSet(Set<int> s) {
-}
-''');
-    expectExpressionType('{}', 'Set<int>');
-  }
-}
-
-/// Like [StaticTypeAnalyzerTest], but as end-to-end tests.
-@reflectiveTest
-class StaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
-  test_emptyListLiteral_inferredFromLinkedList() async {
-    await assertErrorsInCode(r'''
-abstract class ListImpl<T> implements List<T> {}
-ListImpl<int> f() => [];
-''', [
-      error(CompileTimeErrorCode.INVALID_CAST_LITERAL_LIST, 70, 2),
-    ]);
-    expectExpressionType('[]', 'List<dynamic>');
-  }
-
-  test_emptyMapLiteral_inferredFromLinkedHashMap() async {
-    await assertErrorsInCode(r'''
-import 'dart:collection';
-LinkedHashMap<int, int> f() => {};
-''', [
-      error(CompileTimeErrorCode.INVALID_CAST_LITERAL_MAP, 57, 2),
-    ]);
-    expectExpressionType('{}', 'Map<dynamic, dynamic>');
-  }
-
-  test_emptyMapLiteral_initializer_var() async {
-    await assertErrorsInCode(r'''
-main() {
-  var v = {};
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 1),
-    ]);
-    expectExpressionType('{}', 'Map<dynamic, dynamic>');
-  }
-
-  test_emptyMapLiteral_parameter_typed() async {
-    await assertNoErrorsInCode(r'''
-main() {
-  useMap({});
-}
-void useMap(Map<int, int> m) {
-}
-''');
-    expectExpressionType('{}', 'Map<int, int>');
-  }
-
-  test_emptySetLiteral_inferredFromLinkedHashSet() async {
-    await assertErrorsInCode(r'''
-import 'dart:collection';
-LinkedHashSet<int> f() => {};
-''', [
-      error(CompileTimeErrorCode.INVALID_CAST_LITERAL_SET, 52, 2),
-    ]);
-    expectExpressionType('{}', 'Set<dynamic>');
-  }
-
-  test_emptySetLiteral_initializer_typed_nested() async {
-    await assertNoErrorsInCode(r'''
-Set<Set<int>> ints = {{}};
-''');
-    expectExpressionType('{}', 'Set<int>');
-    expectExpressionType('{{}}', 'Set<Set<int>>');
-  }
-
-  test_FunctionExpressionInvocation_block() async {
-    await assertErrorsInCode(r'''
-main() {
-  var foo = (() { return 1; })();
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 3),
-    ]);
-    expectInitializerType('foo', 'int');
-  }
-
-  test_FunctionExpressionInvocation_curried() async {
-    await assertErrorsInCode(r'''
-typedef int F();
-F f() => null;
-main() {
-  var foo = f()();
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 47, 3),
-    ]);
-    expectInitializerType('foo', 'int');
-  }
-
-  test_FunctionExpressionInvocation_expression() async {
-    await assertErrorsInCode(r'''
-main() {
-  var foo = (() => 1)();
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 3),
-    ]);
-    expectInitializerType('foo', 'int');
-  }
-
-  test_MethodInvocation_nameType_localVariable() async {
-    await assertNoErrorsInCode(r"""
-typedef Foo();
-main() {
-  Foo foo;
-  foo();
-}
-""");
-    // "foo" should be resolved to the "Foo" type
-    expectIdentifierType("foo();", TypeMatcher<FunctionType>());
-  }
-
-  test_MethodInvocation_nameType_parameter_FunctionTypeAlias() async {
-    await assertNoErrorsInCode(r"""
-typedef Foo();
-main(Foo foo) {
-  foo();
-}
-""");
-    // "foo" should be resolved to the "Foo" type
-    expectIdentifierType("foo();", TypeMatcher<FunctionType>());
-  }
-
-  test_MethodInvocation_nameType_parameter_propagatedType() async {
-    await assertNoErrorsInCode(r"""
-typedef Foo();
-main(p) {
-  if (p is Foo) {
-    p();
-  }
-}
-""");
-    expectIdentifierType("p()", 'dynamic Function()');
-  }
-
-  test_staticMethods_classTypeParameters() async {
-    await assertNoErrorsInCode(r'''
-class C<T> {
-  static void m() => null;
-}
-main() {
-  print(C.m);
-}
-''');
-    assertType(findNode.simple('m);'), 'void Function()');
-  }
-
-  test_staticMethods_classTypeParameters_genericMethod() async {
-    await assertNoErrorsInCode(r'''
-class C<T> {
-  static void m<S>(S s) {
-    void f<U>(S s, U u) {}
-    print(f);
-  }
-}
-main() {
-  print(C.m);
-}
-''');
-    assertType(
-      findNode.simple('f);'),
-      'void Function<U>(S, U)',
-    );
-    assertType(
-      findNode.simple('m);'),
-      'void Function<S>(S)',
-    );
-  }
-}
-
-@reflectiveTest
 class StaticTypeAnalyzerTest with ResourceProviderMixin, ElementsTypesMixin {
   /// The error listener to which errors will be reported.
   GatheringErrorListener _listener;
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 90c2bb1..c291ea0 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -114,14 +114,15 @@
       if (body is ExpressionFunctionBody) {
         returnExp = body.expression;
       } else {
-        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+        var stmt =
+            (body as BlockFunctionBody).block.statements[0] as ReturnStatement;
         returnExp = stmt.expression;
       }
       DartType type = returnExp.staticType;
       if (returnExp is AwaitExpression) {
         type = returnExp.expression.staticType;
       }
-      typeTest(type);
+      typeTest(type as InterfaceType);
     }
 
     check("f0", _isFutureOfDynamic);
@@ -168,14 +169,15 @@
       if (body is ExpressionFunctionBody) {
         returnExp = body.expression;
       } else {
-        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+        var stmt =
+            (body as BlockFunctionBody).block.statements[0] as ReturnStatement;
         returnExp = stmt.expression;
       }
       DartType type = returnExp.staticType;
       if (returnExp is AwaitExpression) {
         type = returnExp.expression.staticType;
       }
-      typeTest(type);
+      typeTest(type as InterfaceType);
     }
 
     check("f0", _isFutureOfDynamic);
@@ -209,9 +211,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     CascadeExpression fetch(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      CascadeExpression exp = decl.initializer;
+      var exp = decl.initializer as CascadeExpression;
       return exp;
     }
 
@@ -219,10 +221,10 @@
 
     CascadeExpression cascade = fetch(0);
     _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
-    MethodInvocation invoke = cascade.cascadeSections[0];
-    FunctionExpression function = invoke.argumentList.arguments[1];
+    var invoke = cascade.cascadeSections[0] as MethodInvocation;
+    var function = invoke.argumentList.arguments[1] as FunctionExpression;
     ExecutableElement f0 = function.declaredElement;
-    _isListOf(_isInt)(f0.type.returnType);
+    _isListOf(_isInt)(f0.type.returnType as InterfaceType);
     expect(f0.type.normalParameterTypes[0], typeProvider.intType);
   }
 
@@ -240,7 +242,7 @@
 
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
+    var stmt = statements[0] as VariableDeclarationStatement;
     VariableDeclaration decl = stmt.variables.variables[0];
     Expression call = decl.initializer;
     _isInt(call.staticType);
@@ -260,7 +262,7 @@
 
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
+    var stmt = statements[0] as VariableDeclarationStatement;
     VariableDeclaration decl = stmt.variables.variables[0];
     Expression call = decl.initializer;
     _isInt(call.staticType);
@@ -277,7 +279,7 @@
 
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
+    var stmt = statements[0] as VariableDeclarationStatement;
     VariableDeclaration decl = stmt.variables.variables[0];
     Expression call = decl.initializer;
     _isInt(call.staticType);
@@ -299,7 +301,7 @@
 
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
+    var stmt = statements[0] as VariableDeclarationStatement;
     VariableDeclaration decl = stmt.variables.variables[0];
     Expression call = decl.initializer;
     _isInt(call.staticType);
@@ -323,7 +325,7 @@
 
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
+    var stmt = statements[0] as VariableDeclarationStatement;
     VariableDeclaration decl = stmt.variables.variables[0];
     Expression call = decl.initializer;
     _isDynamic(call.staticType);
@@ -339,9 +341,9 @@
     await assertNoErrorsInCode(code);
     ConstructorDeclaration constructor =
         AstFinder.getConstructorInClass(unit, "A", null);
-    ConstructorFieldInitializer assignment = constructor.initializers[0];
+    var assignment = constructor.initializers[0] as ConstructorFieldInitializer;
     Expression exp = assignment.expression;
-    _isListOf(_isString)(exp.staticType);
+    _isListOf(_isString)(exp.staticType as InterfaceType);
   }
 
   test_factoryConstructor_propagation() async {
@@ -358,9 +360,9 @@
 
     ConstructorDeclaration constructor =
         AstFinder.getConstructorInClass(unit, "A", null);
-    BlockFunctionBody body = constructor.body;
-    ReturnStatement stmt = body.block.statements[0];
-    InstanceCreationExpression exp = stmt.expression;
+    var body = constructor.body as BlockFunctionBody;
+    var stmt = body.block.statements[0] as ReturnStatement;
+    var exp = stmt.expression as InstanceCreationExpression;
     ClassElement elementB = AstFinder.getClass(unit, "B").declaredElement;
     ClassElement elementA = AstFinder.getClass(unit, "A").declaredElement;
     expect(exp.constructorName.type.type.element, elementB);
@@ -380,7 +382,7 @@
 
     VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
 
-    _isListOf(_isString)(field.initializer.staticType);
+    _isListOf(_isString)(field.initializer.staticType as InterfaceType);
   }
 
   test_functionDeclaration_body_propagation() async {
@@ -403,22 +405,23 @@
     Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
 
     FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
-    ExpressionFunctionBody body = test1.functionExpression.body;
-    assertListOfInt(body.expression.staticType);
+    var body = test1.functionExpression.body as ExpressionFunctionBody;
+    assertListOfInt(body.expression.staticType as InterfaceType);
 
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test2");
 
     FunctionDeclaration inner =
         (statements[0] as FunctionDeclarationStatement).functionDeclaration;
-    BlockFunctionBody body0 = inner.functionExpression.body;
-    ReturnStatement return0 = body0.block.statements[0];
+    var body0 = inner.functionExpression.body as BlockFunctionBody;
+    var return0 = body0.block.statements[0] as ReturnStatement;
     Expression anon0 = return0.expression;
-    FunctionType type0 = anon0.staticType;
+    var type0 = anon0.staticType as FunctionType;
     expect(type0.returnType, typeProvider.intType);
     expect(type0.normalParameterTypes[0], typeProvider.stringType);
 
-    FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
+    var anon1 =
+        (statements[1] as ReturnStatement).expression as FunctionExpression;
     FunctionType type1 = anon1.declaredElement.type;
     expect(type1.returnType, typeProvider.intType);
     expect(type1.normalParameterTypes[0], typeProvider.intType);
@@ -450,9 +453,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
+      var exp = decl.initializer as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -488,9 +491,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
+      var exp = decl.initializer as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -525,9 +528,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     Expression functionReturnValue(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
+      var exp = decl.initializer as FunctionExpression;
       FunctionBody body = exp.body;
       if (body is ExpressionFunctionBody) {
         return body.expression;
@@ -538,10 +541,10 @@
     }
 
     Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
-    assertListOfString(functionReturnValue(0).staticType);
-    assertListOfString(functionReturnValue(1).staticType);
-    assertListOfString(functionReturnValue(2).staticType);
-    assertListOfString(functionReturnValue(3).staticType);
+    assertListOfString(functionReturnValue(0).staticType as InterfaceType);
+    assertListOfString(functionReturnValue(1).staticType as InterfaceType);
+    assertListOfString(functionReturnValue(2).staticType as InterfaceType);
+    assertListOfString(functionReturnValue(3).staticType as InterfaceType);
   }
 
   test_functionLiteral_functionExpressionInvocation_typedArguments() async {
@@ -567,9 +570,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      FunctionExpressionInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
+      var stmt = statements[i] as ExpressionStatement;
+      var invk = stmt.expression as FunctionExpressionInvocation;
+      var exp = invk.argumentList.arguments[0] as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -602,9 +605,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      FunctionExpressionInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
+      var stmt = statements[i] as ExpressionStatement;
+      var invk = stmt.expression as FunctionExpressionInvocation;
+      var exp = invk.argumentList.arguments[0] as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -636,9 +639,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
+      var stmt = statements[i] as ExpressionStatement;
+      var invk = stmt.expression as MethodInvocation;
+      var exp = invk.argumentList.arguments[0] as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -669,9 +672,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
+      var stmt = statements[i] as ExpressionStatement;
+      var invk = stmt.expression as MethodInvocation;
+      var exp = invk.argumentList.arguments[0] as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -705,9 +708,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
+      var stmt = statements[i] as ExpressionStatement;
+      var invk = stmt.expression as MethodInvocation;
+      var exp = invk.argumentList.arguments[0] as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -740,9 +743,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
+      var stmt = statements[i] as ExpressionStatement;
+      var invk = stmt.expression as MethodInvocation;
+      var exp = invk.argumentList.arguments[0] as FunctionExpression;
       return exp.declaredElement.type;
     }
 
@@ -778,9 +781,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     Expression functionReturnValue(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
+      var exp = decl.initializer as FunctionExpression;
       FunctionBody body = exp.body;
       if (body is ExpressionFunctionBody) {
         return body.expression;
@@ -803,7 +806,7 @@
     FutureOr<T> mk<T>(Future<T> x) => x;
     test() => mk(new Future<int>.value(42));
     ''');
-    _isFutureOrOfInt(invoke.staticType);
+    _isFutureOrOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_assignFromValue() async {
@@ -812,7 +815,7 @@
     FutureOr<T> mk<T>(T x) => x;
     test() => mk(42);
     ''');
-    _isFutureOrOfInt(invoke.staticType);
+    _isFutureOrOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_asyncExpressionBody() async {
@@ -821,7 +824,7 @@
     Future<T> mk<T>(FutureOr<T> x) async => x;
     test() => mk(42);
     ''');
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_asyncReturn() async {
@@ -830,7 +833,7 @@
     Future<T> mk<T>(FutureOr<T> x) async { return x; }
     test() => mk(42);
     ''');
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_await() async {
@@ -839,7 +842,7 @@
     Future<T> mk<T>(FutureOr<T> x) async => await x;
     test() => mk(42);
     ''');
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_downwards1() async {
@@ -849,7 +852,7 @@
     Future<T> mk<T>(FutureOr<T> x) => null;
     Future<int> test() => mk(new Future<int>.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_downwards2() async {
@@ -859,7 +862,7 @@
     Future<T> mk<T>(FutureOr<T> x) => null;
     FutureOr<int> test() => mk(new Future<int>.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_downwards3() async {
@@ -869,8 +872,9 @@
     Future<T> mk<T>(FutureOr<T> x) => null;
     Future<int> test() => mk(new Future.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
+    _isFutureOfInt(
+        invoke.argumentList.arguments[0].staticType as InterfaceType);
   }
 
   test_futureOr_downwards4() async {
@@ -880,8 +884,9 @@
     Future<T> mk<T>(FutureOr<T> x) => null;
     FutureOr<int> test() => mk(new Future.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
+    _isFutureOfInt(
+        invoke.argumentList.arguments[0].staticType as InterfaceType);
   }
 
   test_futureOr_downwards5() async {
@@ -891,8 +896,9 @@
     Future<T> mk<T>(FutureOr<T> x) => null;
     FutureOr<num> test() => mk(new Future.value(42));
     ''');
-    _isFutureOf([_isNum])(invoke.staticType);
-    _isFutureOf([_isNum])(invoke.argumentList.arguments[0].staticType);
+    _isFutureOf([_isNum])(invoke.staticType as InterfaceType);
+    _isFutureOf([_isNum])(
+        invoke.argumentList.arguments[0].staticType as InterfaceType);
   }
 
   test_futureOr_downwards6() async {
@@ -902,8 +908,9 @@
     T mk<T>(T x) => null;
     FutureOr<int> test() => mk(new Future.value(42));
     ''');
-    _isFutureOrOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+    _isFutureOrOfInt(invoke.staticType as InterfaceType);
+    _isFutureOfInt(
+        invoke.argumentList.arguments[0].staticType as InterfaceType);
   }
 
   test_futureOr_downwards7() async {
@@ -913,8 +920,9 @@
       T mk<T extends Future<int>>(T x) => null;
       FutureOr<int> test() => mk(new Future.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
+    _isFutureOfInt(
+        invoke.argumentList.arguments[0].staticType as InterfaceType);
   }
 
   test_futureOr_downwards8() async {
@@ -926,8 +934,9 @@
     T mk<T extends Future<Object>>(T x) => null;
     FutureOr<int> test() => mk(new Future.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
+    _isFutureOfInt(
+        invoke.argumentList.arguments[0].staticType as InterfaceType);
   }
 
   test_futureOr_downwards9() async {
@@ -937,7 +946,7 @@
     List<T> mk<T>(T x) => null;
     FutureOr<List<int>> test() => mk(3);
     ''');
-    _isListOf(_isInt)(invoke.staticType);
+    _isListOf(_isInt)(invoke.staticType as InterfaceType);
     _isInt(invoke.argumentList.arguments[0].staticType);
   }
 
@@ -987,7 +996,7 @@
     ''');
     _isFunction2Of(_isInt, _isNull)(
         invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
+    _isFutureOfNull(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_no_return_value() async {
@@ -998,7 +1007,7 @@
     ''');
     _isFunction2Of(_isInt, _isNull)(
         invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
+    _isFutureOfNull(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_return_null() async {
@@ -1009,7 +1018,7 @@
     ''');
     _isFunction2Of(_isInt, _isNull)(
         invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
+    _isFutureOfNull(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_upwards1() async {
@@ -1019,7 +1028,7 @@
     Future<T> mk<T>(FutureOr<T> x) => null;
     dynamic test() => mk(new Future<int>.value(42));
     ''');
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOr_upwards2() async {
@@ -1031,7 +1040,7 @@
     ''', expectedErrors: [
       error(CompileTimeErrorCode.COULD_NOT_INFER, 111, 2),
     ]);
-    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.staticType as InterfaceType);
   }
 
   test_futureOrNull_no_return() async {
@@ -1042,7 +1051,7 @@
     ''');
     _isFunction2Of(_isInt, _isNull)(
         invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
+    _isFutureOfNull(invoke.staticType as InterfaceType);
   }
 
   test_futureOrNull_no_return_value() async {
@@ -1053,7 +1062,7 @@
     ''');
     _isFunction2Of(_isInt, _isNull)(
         invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
+    _isFutureOfNull(invoke.staticType as InterfaceType);
   }
 
   test_futureOrNull_return_null() async {
@@ -1064,7 +1073,7 @@
     ''');
     _isFunction2Of(_isInt, _isNull)(
         invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
+    _isFutureOfNull(invoke.staticType as InterfaceType);
   }
 
   test_generic_partial() async {
@@ -1106,7 +1115,7 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
     void check(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
       Expression init = decl.initializer;
       _isInstantiationOf(_hasElement(elementA))([_isInt])(init.staticType);
@@ -1332,9 +1341,9 @@
     var body = AstFinder.getTopLevelFunction(unit, '_mergeSort')
         .functionExpression
         .body as BlockFunctionBody;
-    var stmts = body.block.statements;
+    var stmts = body.block.statements.cast<ExpressionStatement>();
     for (ExpressionStatement stmt in stmts) {
-      MethodInvocation invoke = stmt.expression;
+      var invoke = stmt.expression as MethodInvocation;
       assertInvokeType(invoke,
           'void Function(T Function(T), int Function(T, T), T Function(T))');
     }
@@ -1359,9 +1368,9 @@
     var body = AstFinder.getTopLevelFunction(unit, '_mergeSort')
         .functionExpression
         .body as BlockFunctionBody;
-    var stmts = body.block.statements;
+    var stmts = body.block.statements.cast<ExpressionStatement>();
     for (ExpressionStatement stmt in stmts) {
-      MethodInvocation invoke = stmt.expression;
+      var invoke = stmt.expression as MethodInvocation;
       assertInvokeType(
           invoke, 'void Function(List<T>, int Function(T, T), List<T>)');
     }
@@ -1386,9 +1395,9 @@
     var body = AstFinder.getTopLevelFunction(unit, '_mergeSort')
         .functionExpression
         .body as BlockFunctionBody;
-    var stmts = body.block.statements;
+    var stmts = body.block.statements.cast<ExpressionStatement>();
     for (ExpressionStatement stmt in stmts) {
-      MethodInvocation invoke = stmt.expression;
+      var invoke = stmt.expression as MethodInvocation;
       assertInvokeType(invoke, 'void Function(T, int Function(T, T), T)');
     }
   }
@@ -1459,26 +1468,26 @@
     await assertNoErrorsInCode(code);
 
     Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-    Asserter<InterfaceType> assertMapOfIntToListOfInt =
-        _isMapOf(_isInt, (DartType type) => assertListOfInt(type));
+    Asserter<InterfaceType> assertMapOfIntToListOfInt = _isMapOf(
+        _isInt, (DartType type) => assertListOfInt(type as InterfaceType));
 
     VariableDeclaration mapB = AstFinder.getFieldInClass(unit, "B", "map");
     MethodDeclaration mapC = AstFinder.getMethodInClass(unit, "C", "map");
-    assertMapOfIntToListOfInt(mapB.declaredElement.type);
-    assertMapOfIntToListOfInt(mapC.declaredElement.returnType);
+    assertMapOfIntToListOfInt(mapB.declaredElement.type as InterfaceType);
+    assertMapOfIntToListOfInt(mapC.declaredElement.returnType as InterfaceType);
 
-    SetOrMapLiteral mapLiteralB = mapB.initializer;
-    SetOrMapLiteral mapLiteralC =
-        (mapC.body as ExpressionFunctionBody).expression;
-    assertMapOfIntToListOfInt(mapLiteralB.staticType);
-    assertMapOfIntToListOfInt(mapLiteralC.staticType);
+    var mapLiteralB = mapB.initializer as SetOrMapLiteral;
+    var mapLiteralC =
+        (mapC.body as ExpressionFunctionBody).expression as SetOrMapLiteral;
+    assertMapOfIntToListOfInt(mapLiteralB.staticType as InterfaceType);
+    assertMapOfIntToListOfInt(mapLiteralC.staticType as InterfaceType);
 
-    ListLiteral listLiteralB =
-        (mapLiteralB.elements[0] as MapLiteralEntry).value;
-    ListLiteral listLiteralC =
-        (mapLiteralC.elements[0] as MapLiteralEntry).value;
-    assertListOfInt(listLiteralB.staticType);
-    assertListOfInt(listLiteralC.staticType);
+    var listLiteralB =
+        (mapLiteralB.elements[0] as MapLiteralEntry).value as ListLiteral;
+    var listLiteralC =
+        (mapLiteralC.elements[0] as MapLiteralEntry).value as ListLiteral;
+    assertListOfInt(listLiteralB.staticType as InterfaceType);
+    assertListOfInt(listLiteralC.staticType as InterfaceType);
   }
 
   test_instanceCreation() async {
@@ -1671,7 +1680,8 @@
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test0");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test0")
+              .cast<VariableDeclarationStatement>();
 
       hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
       hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
@@ -1684,14 +1694,15 @@
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test1");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test1")
+              .cast<VariableDeclarationStatement>();
       hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
       hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
     }
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test2").cast<VariableDeclarationStatement>();
       hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
       hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
       hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
@@ -1702,14 +1713,14 @@
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test3");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test3").cast<VariableDeclarationStatement>();
       hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
       hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
     }
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test4");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test4").cast<VariableDeclarationStatement>();
       hasType(assertCOf([_isInt]), rhs(statements[0]));
       hasType(assertCOf([_isInt]), rhs(statements[1]));
       hasType(assertCOf([_isInt]), rhs(statements[2]));
@@ -1720,7 +1731,7 @@
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test5");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test5").cast<VariableDeclarationStatement>();
       hasType(assertCOf([_isInt]), rhs(statements[0]));
       hasType(assertCOf([_isInt]), rhs(statements[1]));
     }
@@ -1730,7 +1741,7 @@
       // context.  We could choose a tighter type, but currently
       // we just use dynamic.
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test6");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test6").cast<VariableDeclarationStatement>();
       hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
       hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
       hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
@@ -1741,20 +1752,20 @@
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test7");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test7").cast<VariableDeclarationStatement>();
       hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
       hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
     }
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test8");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test8").cast<VariableDeclarationStatement>();
       hasType(assertEOf([_isInt, _isString]), rhs(statements[0]));
     }
 
     {
       List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test9");
+          AstFinder.getStatementsInTopLevelFunction(unit, "test9").cast<VariableDeclarationStatement>();
       hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
       hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
       hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
@@ -1784,9 +1795,9 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     ListLiteral literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
+      var exp = decl.initializer as ListLiteral;
       return exp;
     }
 
@@ -1794,14 +1805,14 @@
     Asserter<InterfaceType> assertListOfListOfInt =
         _isListOf((DartType type) => assertListOfInt(type));
 
-    assertListOfListOfInt(literal(0).staticType);
-    assertListOfListOfInt(literal(1).staticType);
-    assertListOfListOfInt(literal(2).staticType);
-    assertListOfListOfInt(literal(3).staticType);
+    assertListOfListOfInt(literal(0).staticType as InterfaceType);
+    assertListOfListOfInt(literal(1).staticType as InterfaceType);
+    assertListOfListOfInt(literal(2).staticType as InterfaceType);
+    assertListOfListOfInt(literal(3).staticType as InterfaceType);
 
-    assertListOfInt((literal(1).elements[0] as Expression).staticType);
-    assertListOfInt((literal(2).elements[0] as Expression).staticType);
-    assertListOfInt((literal(3).elements[0] as Expression).staticType);
+    assertListOfInt((literal(1).elements[0] as Expression).staticType as InterfaceType);
+    assertListOfInt((literal(2).elements[0] as Expression).staticType as InterfaceType);
+    assertListOfInt((literal(3).elements[0] as Expression).staticType as InterfaceType);
   }
 
   test_listLiteral_simple() async {
@@ -1825,18 +1836,18 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
+      var exp = decl.initializer as ListLiteral;
       return exp.staticType;
     }
 
     Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
 
-    assertListOfInt(literal(0));
-    assertListOfInt(literal(1));
-    assertListOfInt(literal(2));
-    assertListOfInt(literal(3));
+    assertListOfInt(literal(0) as InterfaceType);
+    assertListOfInt(literal(1) as InterfaceType);
+    assertListOfInt(literal(2) as InterfaceType);
+    assertListOfInt(literal(3) as InterfaceType);
   }
 
   test_listLiteral_simple_const() async {
@@ -1860,18 +1871,18 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
+      var exp = decl.initializer as ListLiteral;
       return exp.staticType;
     }
 
     Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
 
-    assertListOfInt(literal(0));
-    assertListOfInt(literal(1));
-    assertListOfInt(literal(2));
-    assertListOfInt(literal(3));
+    assertListOfInt(literal(0) as InterfaceType);
+    assertListOfInt(literal(1) as InterfaceType);
+    assertListOfInt(literal(2) as InterfaceType);
+    assertListOfInt(literal(3) as InterfaceType);
   }
 
   test_listLiteral_simple_disabled() async {
@@ -1897,16 +1908,16 @@
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "main");
     DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
+      var stmt = statements[i] as VariableDeclarationStatement;
       VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
+      var exp = decl.initializer as ListLiteral;
       return exp.staticType;
     }
 
-    _isListOf(_isNum)(literal(0));
-    _isListOf(_isNum)(literal(1));
-    _isListOf(_isString)(literal(2));
-    _isListOf(_isDynamic)(literal(3));
+    _isListOf(_isNum)(literal(0) as InterfaceType);
+    _isListOf(_isNum)(literal(1) as InterfaceType);
+    _isListOf(_isString)(literal(2) as InterfaceType);
+    _isListOf(_isDynamic)(literal(3) as InterfaceType);
   }
 
   test_listLiteral_simple_subtype() async {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 1bb1df6..9bf5576b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -3808,7 +3808,7 @@
 
   void test_printListOfQuotedNames_empty() {
     expect(() {
-      StringUtilities.printListOfQuotedNames(List<String>(0));
+      StringUtilities.printListOfQuotedNames(List<String>.filled(0, null));
     }, throwsArgumentError);
   }
 
diff --git a/pkg/analyzer/test/src/clients/angular_analyzer_plugin/resolve_template_node_test.dart b/pkg/analyzer/test/src/clients/angular_analyzer_plugin/resolve_template_node_test.dart
deleted file mode 100644
index 810e4e7..0000000
--- a/pkg/analyzer/test/src/clients/angular_analyzer_plugin/resolve_template_node_test.dart
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/analysis/utilities.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/clients/angular_analyzer_plugin/angular_analyzer_plugin.dart';
-import 'package:analyzer/src/test_utilities/find_node.dart';
-import 'package:meta/meta.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../dart/resolution/context_collection_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ResolveTemplateNodeTest);
-  });
-}
-
-@reflectiveTest
-class ResolveTemplateNodeTest extends PubPackageResolutionTest {
-  test_asExpression() async {
-    await assertNoErrorsInCode(r'''
-class MyComponent {}
-''');
-
-    var source = findElement.unitElement.source;
-    var errorListener = RecordingErrorListener();
-
-    var template = _parseTemplate('var x = 0 as int;');
-    var node = template.findNode.variableDeclaration('x = ').initializer;
-
-    var overrideAsExpressionInvoked = false;
-
-    resolveTemplateNode(
-      componentClass: findElement.class_('MyComponent'),
-      templateSource: source,
-      localVariables: [],
-      node: node,
-      errorListener: errorListener,
-      errorReporter: ErrorReporter(errorListener, source),
-      overrideAsExpression: ({node, invokeSuper}) {
-        overrideAsExpressionInvoked = true;
-        expect(invokeSuper, isNotNull);
-      },
-    );
-
-    expect(overrideAsExpressionInvoked, isTrue);
-  }
-
-  test_references() async {
-    await assertNoErrorsInCode(r'''
-class MyComponent {
-  void someContext() {
-    // ignore:unused_local_variable
-    var foo = 0;
-  }
-
-  void bar(int a) {}
-}
-''');
-
-    var source = findElement.unitElement.source;
-    var errorListener = RecordingErrorListener();
-
-    var template = _parseTemplate('var x = bar(foo);');
-    var node = template.findNode.variableDeclaration('x = ').initializer;
-    assertElementNull(template.findNode.simple('foo'));
-    assertElementNull(template.findNode.methodInvocation('bar'));
-
-    resolveTemplateNode(
-      componentClass: findElement.class_('MyComponent'),
-      templateSource: source,
-      localVariables: [
-        findElement.localVar('foo'),
-      ],
-      node: node,
-      errorListener: errorListener,
-      errorReporter: ErrorReporter(errorListener, source),
-    );
-
-    assertElement(
-      template.findNode.simple('foo'),
-      findElement.localVar('foo'),
-    );
-
-    assertElement(
-      template.findNode.methodInvocation('bar'),
-      findElement.method('bar'),
-    );
-  }
-
-  _ParsedTemplate _parseTemplate(String templateCode) {
-    var templateUnit = parseString(
-      content: templateCode,
-      featureSet: result.unit.featureSet,
-    ).unit;
-
-    return _ParsedTemplate(
-      content: templateCode,
-      unit: templateUnit,
-      findNode: FindNode(templateCode, templateUnit),
-    );
-  }
-}
-
-class _ParsedTemplate {
-  final String content;
-  final CompilationUnit unit;
-  final FindNode findNode;
-
-  _ParsedTemplate({
-    @required this.content,
-    @required this.unit,
-    @required this.findNode,
-  });
-}
diff --git a/pkg/analyzer/test/src/clients/angular_analyzer_plugin/test_all.dart b/pkg/analyzer/test/src/clients/angular_analyzer_plugin/test_all.dart
deleted file mode 100644
index 1494e1f..0000000
--- a/pkg/analyzer/test/src/clients/angular_analyzer_plugin/test_all.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolve_template_node_test.dart' as resolve_template_node;
-
-main() {
-  defineReflectiveSuite(() {
-    resolve_template_node.main();
-  }, name: 'angular_analyzer_plugin');
-}
diff --git a/pkg/analyzer/test/src/clients/test_all.dart b/pkg/analyzer/test/src/clients/test_all.dart
deleted file mode 100644
index 6ba96a8..0000000
--- a/pkg/analyzer/test/src/clients/test_all.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'angular_analyzer_plugin/test_all.dart' as angular_analyzer_plugin;
-
-main() {
-  defineReflectiveSuite(() {
-    angular_analyzer_plugin.main();
-  }, name: 'clients');
-}
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
index e3d502f..4f8ada1 100644
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ b/pkg/analyzer/test/src/command_line/arguments_test.dart
@@ -5,10 +5,8 @@
 import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:args/args.dart';
-import 'package:cli_util/cli_util.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -82,26 +80,6 @@
     expect(defaultOptions.implicitDynamic, true);
   }
 
-  void test_createDartSdkManager_noPath() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [];
-    ArgResults result = parse(resourceProvider, parser, args);
-    DartSdkManager manager = createDartSdkManager(resourceProvider, result);
-    expect(manager, isNotNull);
-    expect(manager.defaultSdkDirectory, getSdkPath());
-  }
-
-  void test_createDartSdkManager_path() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = ['--dart-sdk=x'];
-    ArgResults result = parse(resourceProvider, parser, args);
-    DartSdkManager manager = createDartSdkManager(resourceProvider, result);
-    expect(manager, isNotNull);
-    expect(manager.defaultSdkDirectory, 'x');
-  }
-
   void test_defineAnalysisArguments() {
     ArgParser parser = ArgParser();
     defineAnalysisArguments(parser);
diff --git a/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart b/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
index 38435ac..42bc17b 100644
--- a/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
@@ -14,7 +14,7 @@
 }
 
 List<int> _b(int length) {
-  return List<int>(length);
+  return List<int>.filled(length, null);
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/analysis/cache_test.dart b/pkg/analyzer/test/src/dart/analysis/cache_test.dart
index 67ec341..b966f63 100644
--- a/pkg/analyzer/test/src/dart/analysis/cache_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/cache_test.dart
@@ -13,7 +13,7 @@
 }
 
 List<int> _b(int length) {
-  return List<int>(length);
+  return List<int>.filled(length, null);
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index d477df0..a54fa1a 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:io' as io;
-
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -36,7 +34,6 @@
   }
 
   void setUp() {
-    newFile(io.Platform.resolvedExecutable); // create folders
     var folder = newFolder('/home/test');
     contextBuilder = ContextBuilderImpl(resourceProvider: resourceProvider);
     contextRoot = ContextRootImpl(resourceProvider, folder);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
index 5a7be88..30433aa 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
@@ -22,6 +22,39 @@
     return driver.test.libraryContext.linkedCycles;
   }
 
+  test_change_functionBody() async {
+    useEmptyByteStore();
+
+    newFile(testFilePath, content: r'''
+void f() {
+  print(0);
+}
+''');
+
+    await resolveTestFile();
+    expect(findNode.integerLiteral('0'), isNotNull);
+
+    // The summary for the library was linked.
+    _assertContainsLinkedCycle({testFilePath}, andClear: true);
+
+    // Dispose the collection, with its driver.
+    // The next analysis will recreate it.
+    // We will reuse the byte store, so can reuse summaries.
+    disposeAnalysisContextCollection();
+
+    newFile(testFilePath, content: r'''
+void f() {
+  print(1);
+}
+''');
+
+    await resolveTestFile();
+    expect(findNode.integerLiteral('1'), isNotNull);
+
+    // We changed only the function body, nothing should be linked.
+    _assertNoLinkedCycles();
+  }
+
   test_lints() async {
     useEmptyByteStore();
 
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 16cf839..e47b257 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -3325,7 +3325,7 @@
 
   ImportElement _getImportElement(CompilationUnit unit, int directiveIndex) {
     var import = unit.directives[directiveIndex] as ImportDirective;
-    return import.element as ImportElement;
+    return import.element;
   }
 
   Source _getImportSource(CompilationUnit unit, int directiveIndex) {
diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
index 37172b1..441fe5b 100644
--- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
@@ -38,68 +38,36 @@
     _createSourceFactory();
   }
 
-  test_packages_allowedExperiments() {
-    var packages = Packages(
-      {
-        'aaa': Package(
-          name: 'aaa',
-          rootFolder: newFolder('/packages/aaa'),
-          libFolder: newFolder('/packages/aaa/lib'),
-          languageVersion: Version(2, 7, 0),
-        ),
-        'bbb': Package(
-          name: 'bbb',
-          rootFolder: newFolder('/packages/bbb'),
-          libFolder: newFolder('/packages/bbb/lib'),
-          languageVersion: Version(2, 7, 0),
-        ),
-      },
-    );
-
-    _createSourceFactory(
-      packageUriResolver: _createPackageMapUriResolver(packages),
+  test_getFeatureSet_allowedExperiments() {
+    var feature_a = ExperimentalFeature(
+      index: 0,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: null,
+      releaseVersion: null,
     );
 
     _newSdkExperimentsFile(r'''
 {
   "version": 1,
   "experimentSets": {
-    "nullSafety": ["non-nullable"]
+    "with_a": ["a"]
   },
   "sdk": {
     "default": {
-      "experimentSet": "nullSafety"
+      "experimentSet": "with_a"
     }
   },
   "packages": {
     "aaa": {
-      "experimentSet": "nullSafety"
+      "experimentSet": "with_a"
     }
   }
 }
 ''');
 
-    provider = FeatureSetProvider.build(
-      sourceFactory: sourceFactory,
-      resourceProvider: resourceProvider,
-      packages: packages,
-      packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
-      nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
-      nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
-    );
-
-    _assertNonNullableForPath('/packages/aaa/lib/a.dart', true);
-    _assertNonNullableForPath('/packages/aaa/bin/b.dart', true);
-    _assertNonNullableForPath('/packages/aaa/test/c.dart', true);
-
-    _assertNonNullableForPath('/packages/bbb/lib/a.dart', false);
-    _assertNonNullableForPath('/packages/bbb/bin/b.dart', false);
-    _assertNonNullableForPath('/packages/bbb/test/c.dart', false);
-
-    _assertNonNullableForPath('/other/file.dart', false);
-  }
-
-  test_packages_contextExperiments_empty() {
     var packages = Packages(
       {
         'aaa': Package(
@@ -112,13 +80,7 @@
           name: 'bbb',
           rootFolder: newFolder('/packages/bbb'),
           libFolder: newFolder('/packages/bbb/lib'),
-          languageVersion: Version(2, 7, 0),
-        ),
-        'ccc': Package(
-          name: 'ccc',
-          rootFolder: newFolder('/packages/ccc'),
-          libFolder: newFolder('/packages/ccc/lib'),
-          languageVersion: Version(2, 8, 0),
+          languageVersion: null,
         ),
       },
     );
@@ -127,28 +89,145 @@
       packageUriResolver: _createPackageMapUriResolver(packages),
     );
 
-    provider = FeatureSetProvider.build(
-      sourceFactory: sourceFactory,
-      resourceProvider: resourceProvider,
-      packages: packages,
-      packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
-      nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
-      nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
+    overrideKnownFeatures({'a': feature_a}, () {
+      provider = FeatureSetProvider.build(
+        sourceFactory: sourceFactory,
+        resourceProvider: resourceProvider,
+        packages: packages,
+        packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
+        nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
+        nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
+      );
+
+      void assertHasFeature(String path, bool expected) {
+        _assertHasFeatureForPath(path, feature_a, expected);
+      }
+
+      assertHasFeature('/packages/aaa/lib/a.dart', true);
+      assertHasFeature('/packages/aaa/bin/b.dart', true);
+      assertHasFeature('/packages/aaa/test/c.dart', true);
+
+      assertHasFeature('/packages/bbb/lib/a.dart', false);
+      assertHasFeature('/packages/bbb/bin/b.dart', false);
+      assertHasFeature('/packages/bbb/test/c.dart', false);
+
+      assertHasFeature('/other/file.dart', false);
+    });
+  }
+
+  test_getFeatureSet_defaultForContext_hasExperiment() {
+    var feature_a = ExperimentalFeature(
+      index: 0,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: Version.parse('2.12.0'),
+      releaseVersion: null,
     );
 
-    _assertNonNullableForPath('/packages/aaa/a.dart', false);
-    _assertNonNullableForPath('/packages/aaa/lib/b.dart', false);
-    _assertNonNullableForPath('/packages/aaa/test/c.dart', false);
+    var packages = Packages(
+      {
+        'aaa': Package(
+          name: 'aaa',
+          rootFolder: newFolder('/packages/aaa'),
+          libFolder: newFolder('/packages/aaa/lib'),
+          languageVersion: null,
+        ),
+        'bbb': Package(
+          name: 'bbb',
+          rootFolder: newFolder('/packages/bbb'),
+          libFolder: newFolder('/packages/bbb/lib'),
+          languageVersion: Version(2, 12, 0),
+        ),
+      },
+    );
 
-    _assertNonNullableForPath('/packages/bbb/a.dart', false);
-    _assertNonNullableForPath('/packages/bbb/lib/b.dart', false);
-    _assertNonNullableForPath('/packages/bbb/test/c.dart', false);
+    _createSourceFactory(
+      packageUriResolver: _createPackageMapUriResolver(packages),
+    );
 
-    _assertNonNullableForPath('/packages/ccc/a.dart', false);
-    _assertNonNullableForPath('/packages/ccc/lib/b.dart', false);
-    _assertNonNullableForPath('/packages/ccc/test/c.dart', false);
+    overrideKnownFeatures({'a': feature_a}, () {
+      provider = FeatureSetProvider.build(
+        sourceFactory: sourceFactory,
+        resourceProvider: resourceProvider,
+        packages: packages,
+        packageDefaultFeatureSet: FeatureSet.fromEnableFlags2(
+          sdkLanguageVersion: Version.parse('2.12.0'),
+          flags: [feature_a.enableString],
+        ),
+        nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
+        nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
+      );
 
-    _assertNonNullableForPath('/other/file.dart', false);
+      void assertHasFeature(String path, bool expected) {
+        _assertHasFeatureForPath(path, feature_a, expected);
+      }
+
+      assertHasFeature('/packages/aaa/a.dart', true);
+      assertHasFeature('/packages/aaa/lib/b.dart', true);
+      assertHasFeature('/packages/aaa/test/c.dart', true);
+
+      assertHasFeature('/packages/bbb/a.dart', true);
+      assertHasFeature('/packages/bbb/lib/b.dart', true);
+      assertHasFeature('/packages/bbb/test/c.dart', true);
+    });
+  }
+
+  test_getFeatureSet_defaultForContext_noExperiments() {
+    var feature_a = ExperimentalFeature(
+      index: 0,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: Version.parse('2.12.0'),
+      releaseVersion: null,
+    );
+
+    var packages = Packages(
+      {
+        'aaa': Package(
+          name: 'aaa',
+          rootFolder: newFolder('/packages/aaa'),
+          libFolder: newFolder('/packages/aaa/lib'),
+          languageVersion: null,
+        ),
+        'bbb': Package(
+          name: 'bbb',
+          rootFolder: newFolder('/packages/bbb'),
+          libFolder: newFolder('/packages/bbb/lib'),
+          languageVersion: Version(2, 12, 0),
+        ),
+      },
+    );
+
+    _createSourceFactory(
+      packageUriResolver: _createPackageMapUriResolver(packages),
+    );
+
+    overrideKnownFeatures({'a': feature_a}, () {
+      provider = FeatureSetProvider.build(
+        sourceFactory: sourceFactory,
+        resourceProvider: resourceProvider,
+        packages: packages,
+        packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
+        nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
+        nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
+      );
+
+      void assertHasFeature(String path, bool expected) {
+        _assertHasFeatureForPath(path, feature_a, expected);
+      }
+
+      assertHasFeature('/packages/aaa/a.dart', false);
+      assertHasFeature('/packages/aaa/lib/b.dart', false);
+      assertHasFeature('/packages/aaa/test/c.dart', false);
+
+      assertHasFeature('/packages/bbb/a.dart', false);
+      assertHasFeature('/packages/bbb/lib/b.dart', false);
+      assertHasFeature('/packages/bbb/test/c.dart', false);
+    });
   }
 
   test_packages_contextExperiments_nested() {
@@ -228,38 +307,6 @@
     );
   }
 
-  test_packages_contextExperiments_nonNullable() {
-    var packages = Packages(
-      {
-        'aaa': Package(
-          name: 'aaa',
-          rootFolder: newFolder('/packages/aaa'),
-          libFolder: newFolder('/packages/aaa/lib'),
-          languageVersion: null,
-        ),
-      },
-    );
-
-    _createSourceFactory(
-      packageUriResolver: _createPackageMapUriResolver(packages),
-    );
-
-    provider = FeatureSetProvider.build(
-      sourceFactory: sourceFactory,
-      resourceProvider: resourceProvider,
-      packages: packages,
-      packageDefaultFeatureSet: ExperimentStatus.latestWithNullSafety,
-      nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
-      nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
-    );
-
-    _assertNonNullableForPath('/packages/aaa/a.dart', true);
-    _assertNonNullableForPath('/packages/aaa/lib/b.dart', true);
-    _assertNonNullableForPath('/packages/aaa/test/c.dart', true);
-
-    _assertNonNullableForPath('/other/file.dart', false);
-  }
-
   test_sdk_allowedExperiments_default() {
     var feature_a = ExperimentalFeature(
       index: 0,
@@ -366,9 +413,9 @@
     expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
   }
 
-  void _assertNonNullableForPath(String path, bool expected) {
+  _assertHasFeatureForPath(String path, Feature feature, bool expected) {
     var featureSet = _getPathFeatureSet(path);
-    expect(featureSet.isEnabled(Feature.non_nullable), expected);
+    expect(featureSet.isEnabled(feature), expected);
   }
 
   PackageMapUriResolver _createPackageMapUriResolver(Packages packages) {
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 b2a098a..bcea8e7 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -506,6 +506,19 @@
     _assertLibraryCycle(fb, [fb], [fa.libraryCycle]);
   }
 
+  test_libraryCycle_invalidPart_withPart() {
+    var pa = convertPath('/aaa/lib/a.dart');
+
+    newFile(pa, content: r'''
+part of lib;
+part 'a.dart';
+''');
+
+    var fa = fileSystemState.getFileForPath(pa);
+
+    _assertLibraryCycle(fa, [fa], []);
+  }
+
   test_referencedNames() {
     String path = convertPath('/aaa/lib/a.dart');
     newFile(path, content: r'''
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
index 612a392..83e8192 100644
--- a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -192,6 +192,46 @@
 ''');
   }
 
+  test_class_constructor_redirectedConstructor_const() {
+    assertNotSameSignature(r'''
+class A {
+  const factory A() = B.foo;
+}
+class B implements A {
+  const B.foo();
+  const B.bar();
+}
+''', r'''
+class A {
+  const factory A() = B.bar;
+}
+class B implements A {
+  const B.foo();
+  const B.bar();
+}
+''');
+  }
+
+  test_class_constructor_redirectedConstructor_notConst() {
+    assertNotSameSignature(r'''
+class A {
+  factory A() = B.foo;
+}
+class B implements A {
+  B.foo();
+  B.bar();
+}
+''', r'''
+class A {
+  factory A() = B.bar;
+}
+class B implements A {
+  B.foo();
+  B.bar();
+}
+''');
+  }
+
   test_class_extends() {
     assertNotSameSignature(r'''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index a1753b8..30e51fb 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -1083,8 +1083,6 @@
     writeTestPackageAnalysisOptionsFile(
       AnalysisOptionsFileConfig(
         experiments: [
-          // TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-          EnableString.non_nullable,
           EnableString.triple_shift,
         ],
       ),
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 5b35e23..b4e5635 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -36,6 +36,7 @@
     defineReflectiveTests(ElementImplTest);
     defineReflectiveTests(LibraryElementImplTest);
     defineReflectiveTests(TopLevelVariableElementImplTest);
+    defineReflectiveTests(UniqueLocationTest);
   });
 }
 
@@ -1060,23 +1061,6 @@
     expect(typeStr, expected);
   }
 
-  void test_equality_recursive() {
-    var s = ElementFactory.functionTypeAliasElement('s');
-    var t = ElementFactory.functionTypeAliasElement('t');
-    var u = ElementFactory.functionTypeAliasElement('u');
-    var v = ElementFactory.functionTypeAliasElement('v');
-    s.function.returnType = functionTypeAliasType(t);
-    t.function.returnType = functionTypeAliasType(s);
-    u.function.returnType = functionTypeAliasType(v);
-    v.function.returnType = functionTypeAliasType(u);
-    // We don't care whether the types compare equal or not.  We just need the
-    // computation to terminate.
-    expect(
-      functionTypeAliasType(s) == functionTypeAliasType(u),
-      TypeMatcher<bool>(),
-    );
-  }
-
   void test_getNamedParameterTypes_namedParameters() {
     var type = functionTypeNone(
       typeFormals: [],
@@ -1205,30 +1189,6 @@
     // Returns this.
     expect(type.resolveToBound(null), same(type));
   }
-
-  void test_toString_recursive() {
-    var t = ElementFactory.functionTypeAliasElement("t");
-    var s = ElementFactory.functionTypeAliasElement("s");
-    t.function.returnType = functionTypeAliasType(s);
-    s.function.returnType = functionTypeAliasType(t);
-    assertType(
-      functionTypeAliasType(t),
-      'dynamic Function() Function()',
-    );
-  }
-
-  void test_toString_recursive_via_interface_type() {
-    var f = ElementFactory.functionTypeAliasElement('f');
-    ClassElementImpl c = ElementFactory.classElement2('C', ['T']);
-    f.function.returnType = c.instantiate(
-      typeArguments: [functionTypeAliasType(f)],
-      nullabilitySuffix: NullabilitySuffix.star,
-    );
-    assertType(
-      functionTypeAliasType(f),
-      'dynamic Function()',
-    );
-  }
 }
 
 @reflectiveTest
@@ -2289,6 +2249,50 @@
 }
 
 @reflectiveTest
+class UniqueLocationTest extends PubPackageResolutionTest {
+  test_ambiguous_closure_in_executable() async {
+    await resolveTestCode('''
+void f() => [() => 0, () => 1];
+''');
+    expect(findNode.functionExpression('() => 0').declaredElement.location,
+        isNot(findNode.functionExpression('() => 1').declaredElement.location));
+  }
+
+  test_ambiguous_closure_in_local_variable() async {
+    await resolveTestCode('''
+void f() {
+  var x = [() => 0, () => 1];
+}
+''');
+    expect(findNode.functionExpression('() => 0').declaredElement.location,
+        isNot(findNode.functionExpression('() => 1').declaredElement.location));
+  }
+
+  test_ambiguous_closure_in_top_level_variable() async {
+    await resolveTestCode('''
+var x = [() => 0, () => 1];
+''');
+    expect(findNode.functionExpression('() => 0').declaredElement.location,
+        isNot(findNode.functionExpression('() => 1').declaredElement.location));
+  }
+
+  test_ambiguous_local_variable_in_executable() async {
+    await resolveTestCode('''
+f() {
+  {
+    int x = 0;
+  }
+  {
+    int x = 1;
+  }
+}
+''');
+    expect(findNode.variableDeclaration('x = 0').declaredElement.location,
+        isNot(findNode.variableDeclaration('x = 1').declaredElement.location));
+  }
+}
+
+@reflectiveTest
 class VoidTypeImplTest extends AbstractTypeTest {
   /// Reference {code VoidTypeImpl.getInstance()}.
   final DartType _voidType = VoidTypeImpl.instance;
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index 803d055..609d293 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -6,7 +6,6 @@
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:test/test.dart';
@@ -75,25 +74,6 @@
     expect(f.typeFormals, typeFormals, reason: 'typeFormals');
   }
 
-  FunctionTypeAliasElementImpl functionTypeAliasElement(
-    String name, {
-    List<ParameterElement> parameters = const [],
-    DartType returnType,
-    List<TypeParameterElement> typeParameters = const [],
-    List<TypeParameterElement> innerTypeParameters = const [],
-  }) {
-    var aliasElement = FunctionTypeAliasElementImpl(name, 0);
-    aliasElement.typeParameters = typeParameters;
-
-    var functionElement = GenericFunctionTypeElementImpl.forOffset(0);
-    aliasElement.function = functionElement;
-    functionElement.typeParameters = innerTypeParameters;
-    functionElement.parameters = parameters;
-    functionElement.returnType = returnType;
-
-    return aliasElement;
-  }
-
   DartType listOf(DartType elementType) => listElement.instantiate(
         typeArguments: [elementType],
         nullabilitySuffix: NullabilitySuffix.star,
diff --git a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
index 30418ae..d99c0e8 100644
--- a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
@@ -15,16 +15,104 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InterfaceLeastUpperBoundHelperTest);
+    defineReflectiveTests(PathToObjectTest);
+    defineReflectiveTests(SuperinterfaceSetTest);
   });
 }
 
 @reflectiveTest
-class InterfaceLeastUpperBoundHelperTest extends AbstractTypeSystemTest {
+class PathToObjectTest extends AbstractTypeSystemTest {
   @override
   final TestTypeProvider typeProvider = TestTypeProvider();
 
-  void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
+  void test_class_mixins1() {
+    var M1 = mixin_(name: 'M1');
+    expect(_longestPathToObject(M1), 1);
+
+    var A = class_(name: 'A');
+    expect(_longestPathToObject(A), 1);
+
+    // class _X&A&M1 extends A implements M1 {}
+    //    length: 2
+    // class X extends _X&A&M1 {}
+    //    length: 3
+    var X = class_(
+      name: 'X',
+      superType: interfaceTypeNone(A),
+      mixins: [
+        interfaceTypeNone(M1),
+      ],
+    );
+
+    expect(_longestPathToObject(X), 3);
+  }
+
+  void test_class_mixins2() {
+    var M1 = mixin_(name: 'M1');
+    var M2 = mixin_(name: 'M2');
+    expect(_longestPathToObject(M1), 1);
+    expect(_longestPathToObject(M2), 1);
+
+    var A = class_(name: 'A');
+    expect(_longestPathToObject(A), 1);
+
+    // class _X&A&M1 extends A implements M1 {}
+    //    length: 2
+    // class _X&A&M1&M2 extends _X&A&M1 implements M2 {}
+    //    length: 3
+    // class X extends _X&A&M1&M2 {}
+    //    length: 4
+    var X = class_(
+      name: 'X',
+      superType: interfaceTypeNone(A),
+      mixins: [
+        interfaceTypeNone(M1),
+        interfaceTypeNone(M2),
+      ],
+    );
+
+    expect(_longestPathToObject(X), 4);
+  }
+
+  void test_class_mixins_longerViaSecondMixin() {
+    var I1 = class_(name: 'I1');
+    var I2 = class_(name: 'I2', superType: interfaceTypeNone(I1));
+    var I3 = class_(name: 'I3', superType: interfaceTypeNone(I2));
+
+    expect(_longestPathToObject(I1), 1);
+    expect(_longestPathToObject(I2), 2);
+    expect(_longestPathToObject(I3), 3);
+
+    var M1 = mixin_(name: 'M1');
+    var M2 = mixin_(
+      name: 'M2',
+      interfaces: [interfaceTypeNone(I3)],
+    );
+    expect(_longestPathToObject(M1), 1);
+    expect(_longestPathToObject(M2), 4);
+
+    var A = class_(name: 'A'); // length: 1
+    expect(_longestPathToObject(A), 1);
+
+    // class _X&A&M1 extends A implements M1 {}
+    //    length: 2
+    // class _X&A&M1&M2 extends _X&A&M1 implements M2 {}
+    //    length: 5 = max(1 + _X&A&M1, 1 + M2)
+    // class X extends _X&A&M1&M2 {}
+    //    length: 6
+    var X = class_(
+      name: 'X',
+      superType: interfaceTypeNone(A),
+      mixins: [
+        interfaceTypeNone(M1),
+        interfaceTypeNone(M2),
+      ],
+    );
+
+    expect(_longestPathToObject(X), 6);
+  }
+
+  void test_class_multipleInterfacePaths() {
     //
     //   Object
     //     |
@@ -55,7 +143,7 @@
     expect(_longestPathToObject(classE), 4);
   }
 
-  void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
+  void test_class_multipleSuperclassPaths() {
     //
     //   Object
     //     |
@@ -84,11 +172,11 @@
     expect(_longestPathToObject(classE), 4);
   }
 
-  void test_computeLongestInheritancePathToObject_object() {
+  void test_class_object() {
     expect(_longestPathToObject(typeProvider.objectType.element), 0);
   }
 
-  void test_computeLongestInheritancePathToObject_recursion() {
+  void test_class_recursion() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
@@ -96,7 +184,7 @@
     expect(_longestPathToObject(classA), 2);
   }
 
-  void test_computeLongestInheritancePathToObject_singleInterfacePath() {
+  void test_class_singleInterfacePath() {
     //
     //   Object
     //     |
@@ -116,7 +204,7 @@
     expect(_longestPathToObject(classC), 3);
   }
 
-  void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
+  void test_class_singleSuperclassPath() {
     //
     //   Object
     //     |
@@ -136,7 +224,138 @@
     expect(_longestPathToObject(classC), 3);
   }
 
-  void test_computeSuperinterfaceSet_genericInterfacePath() {
+  void test_mixin_constraints_interfaces_allSame() {
+    var A = class_(name: 'A');
+    var B = class_(name: 'B');
+    var I = class_(name: 'I');
+    var J = class_(name: 'J');
+    expect(_longestPathToObject(A), 1);
+    expect(_longestPathToObject(B), 1);
+    expect(_longestPathToObject(I), 1);
+    expect(_longestPathToObject(J), 1);
+
+    // The interface of M is:
+    // class _M&A&A implements A, B, I, J {}
+    var M = mixin_(
+      name: 'M',
+      constraints: [
+        interfaceTypeNone(A),
+        interfaceTypeNone(B),
+      ],
+      interfaces: [
+        interfaceTypeNone(I),
+        interfaceTypeNone(J),
+      ],
+    );
+    expect(_longestPathToObject(M), 2);
+  }
+
+  void test_mixin_longerConstraint_1() {
+    var A1 = class_(name: 'A1');
+    var A = class_(
+      name: 'A',
+      superType: interfaceTypeNone(A1),
+    );
+    var B = class_(name: 'B');
+    var I = class_(name: 'I');
+    var J = class_(name: 'J');
+    expect(_longestPathToObject(A), 2);
+    expect(_longestPathToObject(B), 1);
+    expect(_longestPathToObject(I), 1);
+    expect(_longestPathToObject(J), 1);
+
+    // The interface of M is:
+    // class _M&A&A implements A, B, I, J {}
+    var M = mixin_(
+      name: 'M',
+      constraints: [
+        interfaceTypeNone(A),
+        interfaceTypeNone(B),
+      ],
+      interfaces: [
+        interfaceTypeNone(I),
+        interfaceTypeNone(J),
+      ],
+    );
+    expect(_longestPathToObject(M), 3);
+  }
+
+  void test_mixin_longerConstraint_2() {
+    var A = class_(name: 'A');
+    var B1 = class_(name: 'B1');
+    var B = class_(
+      name: 'B',
+      interfaces: [
+        interfaceTypeNone(B1),
+      ],
+    );
+    var I = class_(name: 'I');
+    var J = class_(name: 'J');
+    expect(_longestPathToObject(A), 1);
+    expect(_longestPathToObject(B), 2);
+    expect(_longestPathToObject(I), 1);
+    expect(_longestPathToObject(J), 1);
+
+    // The interface of M is:
+    // class _M&A&A implements A, B, I, J {}
+    var M = mixin_(
+      name: 'M',
+      constraints: [
+        interfaceTypeNone(A),
+        interfaceTypeNone(B),
+      ],
+      interfaces: [
+        interfaceTypeNone(I),
+        interfaceTypeNone(J),
+      ],
+    );
+    expect(_longestPathToObject(M), 3);
+  }
+
+  void test_mixin_longerInterface_1() {
+    var A = class_(name: 'A');
+    var B = class_(name: 'B');
+    var I1 = class_(name: 'I1');
+    var I = class_(
+      name: 'I',
+      interfaces: [
+        interfaceTypeNone(I1),
+      ],
+    );
+    var J = class_(name: 'J');
+    expect(_longestPathToObject(A), 1);
+    expect(_longestPathToObject(B), 1);
+    expect(_longestPathToObject(I), 2);
+    expect(_longestPathToObject(J), 1);
+
+    // The interface of M is:
+    // class _M&A&A implements A, B, I, J {}
+    var M = mixin_(
+      name: 'M',
+      constraints: [
+        interfaceTypeNone(A),
+        interfaceTypeNone(B),
+      ],
+      interfaces: [
+        interfaceTypeNone(I),
+        interfaceTypeNone(J),
+      ],
+    );
+    expect(_longestPathToObject(M), 3);
+  }
+
+  int _longestPathToObject(ClassElement element) {
+    return InterfaceLeastUpperBoundHelper.computeLongestInheritancePathToObject(
+        element);
+  }
+}
+
+@reflectiveTest
+class SuperinterfaceSetTest extends AbstractTypeSystemTest {
+  @override
+  final TestTypeProvider typeProvider = TestTypeProvider();
+
+  void test_genericInterfacePath() {
     //
     //  A
     //  | implements
@@ -200,7 +419,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_genericSuperclassPath() {
+  void test_genericSuperclassPath() {
     //
     //  A
     //  |
@@ -261,7 +480,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_mixin_constraints() {
+  void test_mixin_constraints() {
     var instObject = InstantiatedClass.of(typeProvider.objectType);
 
     var classA = ElementFactory.classElement3(name: 'A');
@@ -291,7 +510,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_mixin_constraints_object() {
+  void test_mixin_constraints_object() {
     var instObject = InstantiatedClass.of(typeProvider.objectType);
 
     var mixinM = mixin_(name: 'M');
@@ -303,7 +522,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_mixin_interfaces() {
+  void test_mixin_interfaces() {
     var instObject = InstantiatedClass.of(typeProvider.objectType);
 
     var classA = ElementFactory.classElement3(name: 'A');
@@ -333,7 +552,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_multipleInterfacePaths() {
+  void test_multipleInterfacePaths() {
     var instObject = InstantiatedClass.of(typeProvider.objectType);
 
     var classA = ElementFactory.classElement3(name: 'A');
@@ -379,7 +598,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
+  void test_multipleSuperclassPaths() {
     var instObject = InstantiatedClass.of(typeProvider.objectType);
 
     var classA = ElementFactory.classElement3(name: 'A');
@@ -425,7 +644,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_recursion() {
+  void test_recursion() {
     var classA = ElementFactory.classElement3(name: 'A');
     var instA = InstantiatedClass(classA, const []);
 
@@ -448,7 +667,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_singleInterfacePath() {
+  void test_singleInterfacePath() {
     var instObject = InstantiatedClass.of(typeProvider.objectType);
 
     var classA = ElementFactory.classElement3(name: 'A');
@@ -485,7 +704,7 @@
     );
   }
 
-  void test_computeSuperinterfaceSet_singleSuperclassPath() {
+  void test_singleSuperclassPath() {
     //
     //  A
     //  |
@@ -529,11 +748,6 @@
     );
   }
 
-  int _longestPathToObject(ClassElement element) {
-    return InterfaceLeastUpperBoundHelper.computeLongestInheritancePathToObject(
-        element);
-  }
-
   Set<InstantiatedClass> _superInterfaces(InstantiatedClass type) {
     var helper = InterfaceLeastUpperBoundHelper(typeSystem);
     return helper.computeSuperinterfaceSet(type);
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index 3372610..77f2918 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -2214,6 +2214,73 @@
     assertLUB(aNone, aNone, aNone);
   }
 
+  void test_sharedMixin1() {
+    // mixin M {}
+    // class B with M {}
+    // class C with M {}
+
+    var M = mixin_(name: 'M');
+    var M_none = interfaceTypeNone(M);
+
+    var B = class_(name: 'B', mixins: [M_none]);
+    var B_none = interfaceTypeNone(B);
+
+    var C = class_(name: 'C', mixins: [M_none]);
+    var C_none = interfaceTypeNone(C);
+
+    _checkLeastUpperBound(B_none, C_none, M_none);
+  }
+
+  void test_sharedMixin2() {
+    // mixin M1 {}
+    // mixin M2 {}
+    // mixin M3 {}
+    // class A with M1, M2 {}
+    // class B with M1, M3 {}
+
+    var M1 = mixin_(name: 'M1');
+    var M1_none = interfaceTypeNone(M1);
+
+    var M2 = mixin_(name: 'M2');
+    var M2_none = interfaceTypeNone(M2);
+
+    var M3 = mixin_(name: 'M3');
+    var M3_none = interfaceTypeNone(M3);
+
+    var A = class_(name: 'A', mixins: [M1_none, M2_none]);
+    var A_none = interfaceTypeNone(A);
+
+    var B = class_(name: 'B', mixins: [M1_none, M3_none]);
+    var B_none = interfaceTypeNone(B);
+
+    _checkLeastUpperBound(A_none, B_none, M1_none);
+  }
+
+  void test_sharedMixin3() {
+    // mixin M1 {}
+    // mixin M2 {}
+    // mixin M3 {}
+    // class A with M2, M1 {}
+    // class B with M3, M1 {}
+
+    var M1 = mixin_(name: 'M1');
+    var M1_none = interfaceTypeNone(M1);
+
+    var M2 = mixin_(name: 'M2');
+    var M2_none = interfaceTypeNone(M2);
+
+    var M3 = mixin_(name: 'M3');
+    var M3_none = interfaceTypeNone(M3);
+
+    var A = class_(name: 'A', mixins: [M2_none, M1_none]);
+    var A_none = interfaceTypeNone(A);
+
+    var B = class_(name: 'B', mixins: [M3_none, M1_none]);
+    var B_none = interfaceTypeNone(B);
+
+    _checkLeastUpperBound(A_none, B_none, M1_none);
+  }
+
   void test_sharedSuperclass1() {
     // class A {}
     // class B extends A {}
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index b03a488..1cf1d10 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -22,7 +22,7 @@
 class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
   static final String _testFile = '/workspace/dart/test/lib/test.dart';
 
-  final CiderByteStore byteStore =
+  final CiderCachedByteStore byteStore =
       CiderCachedByteStore(20 * 1024 * 1024 /* 20 MB */);
 
   final StringBuffer logBuffer = StringBuffer();
@@ -45,6 +45,7 @@
       convertPath(_testFile),
     );
 
+    byteStore.testView = CiderByteStoreTestView();
     fileResolver = FileResolver.from(
       logger: logger,
       resourceProvider: resourceProvider,
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 549701d..b462f39 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:matcher/matcher.dart';
@@ -309,6 +310,19 @@
     assertType(findElement.topVar('b').type, 'int');
   }
 
+  test_collectSharedDataIdentifiers() async {
+    var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
+
+    newFile(aPath, content: r'''
+class A {}
+''');
+
+    await resolveFile(aPath);
+    fileResolver.collectSharedDataIdentifiers();
+    expect(fileResolver.removedCacheIds.length,
+        (fileResolver.byteStore as CiderCachedByteStore).testView.length);
+  }
+
   test_getErrors() {
     addTestFile(r'''
 var a = b;
@@ -569,4 +583,65 @@
       error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 9),
     ]);
   }
+
+  test_unusedFiles() async {
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+    var cPath = convertPath('/workspace/dart/aaa/lib/c.dart');
+
+    newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
+class A {}
+''');
+
+    newFile(bPath, content: r'''
+import 'a.dart';
+''');
+
+    newFile(cPath, content: r'''
+import 'a.dart';
+''');
+
+    await resolveFile(bPath);
+    await resolveFile(cPath);
+    fileResolver.removeFilesNotNecessaryForAnalysisOf([cPath]);
+    expect(fileResolver.fsState.testView.unusedFiles.contains(bPath), true);
+    expect(fileResolver.fsState.testView.unusedFiles.length, 1);
+  }
+
+  test_unusedFiles_mutilple() async {
+    var dPath = convertPath('/workspace/dart/aaa/lib/d.dart');
+    var ePath = convertPath('/workspace/dart/aaa/lib/e.dart');
+    var fPath = convertPath('/workspace/dart/aaa/lib/f.dart');
+
+    newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
+class A {}
+''');
+
+    newFile('/workspace/dart/aaa/lib/b.dart', content: r'''
+class B {}
+''');
+
+    newFile('/workspace/dart/aaa/lib/c.dart', content: r'''
+class C {}
+''');
+
+    newFile(dPath, content: r'''
+import 'a.dart';
+''');
+
+    newFile(ePath, content: r'''
+import 'a.dart';
+import 'b.dart';
+''');
+
+    newFile(fPath, content: r'''
+import 'c.dart';
+ ''');
+
+    await resolveFile(dPath);
+    await resolveFile(ePath);
+    await resolveFile(fPath);
+    fileResolver.removeFilesNotNecessaryForAnalysisOf([dPath, fPath]);
+    expect(fileResolver.fsState.testView.unusedFiles.contains(ePath), true);
+    expect(fileResolver.fsState.testView.unusedFiles.length, 2);
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 16d21b17..d7f4445 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
@@ -359,16 +358,13 @@
   }
 }
 
-mixin WithNullSafetyMixin on PubPackageResolutionTest {
+mixin WithNonFunctionTypeAliasesMixin on PubPackageResolutionTest {
   @override
-  String get testPackageLanguageVersion =>
-      Feature.non_nullable.isEnabledByDefault ? '2.12' : '2.11';
+  String get testPackageLanguageVersion => null;
 
   @override
   bool get typeToStringWithNullability => true;
 
-  /// TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-  /// Remove when Null Safety is enabled by default.
   @nonVirtual
   @override
   void setUp() {
@@ -376,8 +372,16 @@
 
     writeTestPackageAnalysisOptionsFile(
       AnalysisOptionsFileConfig(
-        experiments: [EnableString.non_nullable],
+        experiments: [EnableString.nonfunction_type_aliases],
       ),
     );
   }
 }
+
+mixin WithNullSafetyMixin on PubPackageResolutionTest {
+  @override
+  String get testPackageLanguageVersion => null;
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
index 8c2193c..71c3ecb 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
@@ -122,6 +122,7 @@
 ''', [
       error(ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 13, 1),
       error(ParserErrorCode.EXPECTED_TYPE_NAME, 15, 1),
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 15, 0),
       error(CompileTimeErrorCode.UNDEFINED_GETTER, 33, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index 9652773..fc67be62 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -16,6 +16,19 @@
 
 @reflectiveTest
 class IndexExpressionTest extends PubPackageResolutionTest {
+  test_invalid_inDefaultValue_nullAware() async {
+    await assertInvalidTestCode(r'''
+void f({a = b?[0]}) {}
+''');
+
+    assertIndexExpression(
+      findNode.index('[0]'),
+      readElement: null,
+      writeElement: null,
+      type: 'dynamic',
+    );
+  }
+
   test_read() async {
     await assertNoErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart b/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
index 9f18387..d7f3f98 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
@@ -13,7 +13,8 @@
 }
 
 @reflectiveTest
-class MethodDeclarationResolutionTest extends PubPackageResolutionTest {
+class MethodDeclarationResolutionTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
   test_formalParameterScope_defaultValue() async {
     await assertNoErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 18dc935..bdd82f2 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -755,6 +755,7 @@
   math?.loadLibrary();
 }
 ''', [
+      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 49, 4),
     ]);
 
@@ -1309,13 +1310,15 @@
   }
 
   test_hasReceiver_deferredImportPrefix_loadLibrary() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 import 'dart:math' deferred as math;
 
 main() {
   math.loadLibrary();
 }
-''');
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 11),
+    ]);
 
     var import = findElement.importFind('dart:math');
 
@@ -1337,6 +1340,7 @@
   math.loadLibrary(1 + 2);
 }
 ''', [
+      error(HintCode.UNUSED_IMPORT, 7, 11),
       error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 65, 7),
     ]);
 
@@ -1697,6 +1701,20 @@
     assertSuperExpression(invocation.target);
   }
 
+  test_invalid_inDefaultValue_nullAware() async {
+    await assertInvalidTestCode('''
+void f({a = b?.foo()}) {}
+''');
+
+    assertMethodInvocation2(
+      findNode.methodInvocation('?.foo()'),
+      element: null,
+      typeArgumentTypes: [],
+      invokeType: 'dynamic',
+      type: 'dynamic',
+    );
+  }
+
   test_namedArgument() async {
     var question = typeToStringWithNullability ? '?' : '';
     await assertNoErrorsInCode('''
@@ -1907,6 +1925,29 @@
     }
   }
 
+  test_noReceiver_parameter_functionTyped_typedef() async {
+    await assertNoErrorsInCode(r'''
+typedef F = void Function();
+
+void f(F a) {
+  a();
+}
+''');
+
+    var invocation = findNode.functionExpressionInvocation('a();');
+    assertFunctionExpressionInvocation(
+      invocation,
+      element: null,
+      typeArgumentTypes: [],
+      invokeType: 'void Function()',
+      type: 'void',
+    );
+
+    var aRef = invocation.function as SimpleIdentifier;
+    assertElement(aRef, findElement.parameter('a'));
+    assertType(aRef, 'void Function()');
+  }
+
   test_noReceiver_topFunction() async {
     await assertNoErrorsInCode(r'''
 void foo(int _) {}
@@ -2309,14 +2350,16 @@
 class A {}
 ''');
 
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 // @dart = 2.7
 import 'a.dart' deferred as a;
 
 main() {
   a.loadLibrary();
 }
-''');
+''', [
+      error(HintCode.UNUSED_IMPORT, 22, 8),
+    ]);
 
     var import = findElement.importFind('package:test/a.dart');
 
diff --git a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
index ff8104f..50f5527 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
@@ -104,6 +104,72 @@
     );
   }
 
+  test_read_staticMethod_generic() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  static void foo<U>(int a, U u) {}
+}
+
+void f() {
+  A.foo;
+}
+''');
+
+    var prefixed = findNode.prefixed('A.foo');
+    assertPrefixedIdentifier(
+      prefixed,
+      element: findElement.method('foo'),
+      type: 'void Function<U>(int, U)',
+    );
+
+    assertSimpleIdentifier(
+      prefixed.prefix,
+      readElement: findElement.class_('A'),
+      writeElement: null,
+      type: null,
+    );
+
+    assertSimpleIdentifier(
+      prefixed.identifier,
+      readElement: findElement.method('foo'),
+      writeElement: null,
+      type: 'void Function<U>(int, U)',
+    );
+  }
+
+  test_read_staticMethod_ofGenericClass() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  static void foo(int a) {}
+}
+
+void f() {
+  A.foo;
+}
+''');
+
+    var prefixed = findNode.prefixed('A.foo');
+    assertPrefixedIdentifier(
+      prefixed,
+      element: findElement.method('foo'),
+      type: 'void Function(int)',
+    );
+
+    assertSimpleIdentifier(
+      prefixed.prefix,
+      readElement: findElement.class_('A'),
+      writeElement: null,
+      type: null,
+    );
+
+    assertSimpleIdentifier(
+      prefixed.identifier,
+      readElement: findElement.method('foo'),
+      writeElement: null,
+      type: 'void Function(int)',
+    );
+  }
+
   test_readWrite_assignment() async {
     await assertNoErrorsInCode('''
 class A {
@@ -212,14 +278,16 @@
 class A {}
 ''');
 
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 // @dart = 2.7
 import 'a.dart' deferred as a;
 
 main() {
   a.loadLibrary;
 }
-''');
+''', [
+      error(HintCode.UNUSED_IMPORT, 22, 8),
+    ]);
 
     var import = findElement.importFind('package:test/a.dart');
 
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index 313cd97..645d77a 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -238,6 +238,30 @@
     }
   }
 
+  test_invalid_inDefaultValue_nullAware() async {
+    await assertInvalidTestCode('''
+void f({a = b?.foo}) {}
+''');
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('?.foo'),
+      element: null,
+      type: 'dynamic',
+    );
+  }
+
+  test_invalid_inDefaultValue_nullAware_cascade() async {
+    await assertInvalidTestCode('''
+void f({a = b?..foo}) {}
+''');
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('?..foo'),
+      element: null,
+      type: 'dynamic',
+    );
+  }
+
   test_ofExtension_read() async {
     await assertNoErrorsInCode('''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index b91cab9..5e7e81c 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -448,6 +448,13 @@
         expectedPrefix: expectedPrefix);
   }
 
+  /// Resolve the [code], and ensure that it can be resolved without a crash,
+  /// and is invalid, i.e. produces a diagnostic.
+  Future<void> assertInvalidTestCode(String code) async {
+    await resolveTestCode(code);
+    assertHasTestErrors();
+  }
+
   void assertInvokeType(Expression node, String expected) {
     DartType actual;
     if (node is BinaryExpression) {
diff --git a/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
index 1214c58..88deb9e 100644
--- a/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
@@ -83,6 +83,21 @@
     assertType(identifier, 'A');
   }
 
+  test_localFunction_generic() async {
+    await assertNoErrorsInCode('''
+class C<T> {
+  static void foo<S>(S s) {
+    void f<U>(S s, U u) {}
+    f;
+  }
+}
+''');
+
+    var identifier = findNode.simple('f;');
+    assertElement(identifier, findElement.localFunction('f'));
+    assertType(identifier, 'void Function<U>(S, U)');
+  }
+
   test_tearOff_function_topLevel() async {
     await assertNoErrorsInCode('''
 void foo(int a) {}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
index 6e1258e..a4ac9d6 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
@@ -32,7 +32,16 @@
     assertType(findNode.listLiteral('['), 'List<int>');
   }
 
-  test_context_noTypeArgs_noElements() async {
+  test_context_noTypeArgs_noElements_fromReturnType() async {
+    await assertNoErrorsInCode('''
+List<int> f() {
+  return [];
+}
+''');
+    assertType(findNode.listLiteral('[]'), 'List<int>');
+  }
+
+  test_context_noTypeArgs_noElements_fromVariableType() async {
     await assertNoErrorsInCode('''
 List<String> a = [];
 ''');
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
index eb7d745..b58f912 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
@@ -55,7 +55,17 @@
     assertType(setOrMapLiteral('{};'), 'Map<int, String>');
   }
 
-  test_context_noTypeArgs_noEntries() async {
+  test_context_noTypeArgs_noEntries_fromParameterType() async {
+    await assertNoErrorsInCode('''
+void f() {
+  useMap({});
+}
+void useMap(Map<int, String> _) {}
+''');
+    assertType(setOrMapLiteral('{})'), 'Map<int, String>');
+  }
+
+  test_context_noTypeArgs_noEntries_fromVariableType() async {
     await assertNoErrorsInCode('''
 Map<String, String> a = {};
 ''');
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
index 0b119df..2b46b42 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
@@ -35,13 +35,31 @@
     assertType(setLiteral('{'), 'Set<int>');
   }
 
-  test_context_noTypeArgs_noElements() async {
+  test_context_noTypeArgs_noElements_fromParameterType() async {
+    await assertNoErrorsInCode('''
+void f() {
+  useSet({});
+}
+void useSet(Set<int> _) {}
+''');
+    assertType(setLiteral('{});'), 'Set<int>');
+  }
+
+  test_context_noTypeArgs_noElements_fromVariableType() async {
     await assertNoErrorsInCode('''
 Set<String> a = {};
 ''');
     assertType(setLiteral('{'), 'Set<String>');
   }
 
+  test_context_noTypeArgs_noElements_fromVariableType_nested() async {
+    await assertNoErrorsInCode('''
+Set<Set<String>> a = {{}};
+''');
+    assertType(setLiteral('{}'), 'Set<String>');
+    assertType(setLiteral('{{}}'), 'Set<Set<String>>');
+  }
+
   test_context_noTypeArgs_noElements_futureOr() async {
     await resolveTestCode('''
 import 'dart:async';
diff --git a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
index 562aebb..a58eac5 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
@@ -12,6 +12,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(TypeNameResolutionTest);
     defineReflectiveTests(TypeNameResolutionWithNullSafetyTest);
+    defineReflectiveTests(TypeNameResolutionWithNonFunctionTypeAliasesTest);
   });
 }
 
@@ -288,6 +289,112 @@
 }
 
 @reflectiveTest
+class TypeNameResolutionWithNonFunctionTypeAliasesTest
+    extends PubPackageResolutionTest with WithNonFunctionTypeAliasesMixin {
+  test_typeAlias_asParameter_Never_none() async {
+    await assertNoErrorsInCode(r'''
+typedef X = Never;
+void f(X a, X? b) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('X a'),
+      findElement.typeAlias('X'),
+      'Never',
+    );
+
+    assertTypeName(
+      findNode.typeName('X? b'),
+      findElement.typeAlias('X'),
+      'Never?',
+    );
+  }
+
+  test_typeAlias_asParameter_Never_question() async {
+    await assertNoErrorsInCode(r'''
+typedef X = Never?;
+void f(X a, X? b) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('X a'),
+      findElement.typeAlias('X'),
+      'Never?',
+    );
+
+    assertTypeName(
+      findNode.typeName('X? b'),
+      findElement.typeAlias('X'),
+      'Never?',
+    );
+  }
+
+  test_typeAlias_asParameterType_interfaceType_none() async {
+    await assertNoErrorsInCode(r'''
+typedef X<T> = Map<int, T>;
+void f(X<String> a, X<String?> b) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('X<String>'),
+      findElement.typeAlias('X'),
+      'Map<int, String>',
+    );
+
+    assertTypeName(
+      findNode.typeName('X<String?>'),
+      findElement.typeAlias('X'),
+      'Map<int, String?>',
+    );
+  }
+
+  test_typeAlias_asParameterType_interfaceType_question() async {
+    await assertNoErrorsInCode(r'''
+typedef X<T> = List<T?>;
+void f(X<int> a, X<int?> b) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('X<int>'),
+      findElement.typeAlias('X'),
+      'List<int?>',
+    );
+
+    assertTypeName(
+      findNode.typeName('X<int?>'),
+      findElement.typeAlias('X'),
+      'List<int?>',
+    );
+  }
+
+  test_typeAlias_asReturnType_interfaceType() async {
+    await assertNoErrorsInCode(r'''
+typedef X<T> = Map<int, T>;
+X<String> f() => {};
+''');
+
+    assertTypeName(
+      findNode.typeName('X<String>'),
+      findElement.typeAlias('X'),
+      'Map<int, String>',
+    );
+  }
+
+  test_typeAlias_asReturnType_void() async {
+    await assertNoErrorsInCode(r'''
+typedef Nothing = void;
+Nothing f() {}
+''');
+
+    assertTypeName(
+      findNode.typeName('Nothing f()'),
+      findElement.typeAlias('Nothing'),
+      'void',
+    );
+  }
+}
+
+@reflectiveTest
 class TypeNameResolutionWithNullSafetyTest extends TypeNameResolutionTest
     with WithNullSafetyMixin {
   ImportFindElement get import_a {
diff --git a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
index 28cd25a..75d3b88 100644
--- a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
+++ b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -140,15 +141,20 @@
 
   CompilationUnit _wrapExpression(Expression e, {bool nonNullable = false}) {
     return AstTestFactory.compilationUnit9(
-        declarations: [
-          AstTestFactory.functionDeclaration(
-              null,
-              null,
-              null,
-              AstTestFactory.functionExpression2(
-                  null, AstTestFactory.expressionFunctionBody(e)))
-        ],
-        featureSet: FeatureSet.forTesting(
-            additionalFeatures: nonNullable ? [Feature.non_nullable] : []));
+      declarations: [
+        AstTestFactory.functionDeclaration(
+            null,
+            null,
+            null,
+            AstTestFactory.functionExpression2(
+                null, AstTestFactory.expressionFunctionBody(e)))
+      ],
+      featureSet: nonNullable
+          ? FeatureSet.latestLanguageVersion()
+          : FeatureSet.fromEnableFlags2(
+              sdkLanguageVersion: Version.parse('2.9.0'),
+              flags: [],
+            ),
+    );
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
index 664891c..e72359b 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
@@ -238,7 +238,6 @@
   }
 
   test_topLevelVariable_libraryAnnotation() async {
-    testFilePath;
     newFile('$testPackageLibPath/library.dart', content: '''
 @doNotStore
 library lib;
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
new file mode 100644
index 0000000..60961c5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DuplicateFieldFormalParameterTest);
+  });
+}
+
+@reflectiveTest
+class DuplicateFieldFormalParameterTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
+  test_optional_named() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A({this.a = 0, this.a = 1});
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
+    ]);
+  }
+
+  test_optional_positional() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A([this.a = 0, this.a = 1]);
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
+    ]);
+  }
+
+  test_required_named() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A({required this.a, required this.a});
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 55, 1),
+    ]);
+  }
+
+  test_required_positional() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A(this.a, this.a);
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 36, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/for_in_with_const_variable_test.dart b/pkg/analyzer/test/src/diagnostics/for_in_with_const_variable_test.dart
index e2630c9..2289e70 100644
--- a/pkg/analyzer/test/src/diagnostics/for_in_with_const_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/for_in_with_const_variable_test.dart
@@ -18,11 +18,12 @@
   test_forEach_loopVariable() async {
     await assertErrorsInCode(r'''
 f() {
-  for (const x in [0, 1, 2]) {}
+  for (const x in [0, 1, 2]) {
+    print(x);
+  }
 }
 ''', [
-      error(CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, 13, 7),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 19, 1),
+      error(CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, 13, 5),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/import_of_legacy_library_into_null_safe_test.dart b/pkg/analyzer/test/src/diagnostics/import_of_legacy_library_into_null_safe_test.dart
index 2119b9f..cde53c9 100644
--- a/pkg/analyzer/test/src/diagnostics/import_of_legacy_library_into_null_safe_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/import_of_legacy_library_into_null_safe_test.dart
@@ -65,4 +65,17 @@
 void f(A a) {}
 ''');
   }
+
+  test_nullSafe_into_nullSafe_part() async {
+    newFile('$testPackageLibPath/a.dart', content: '');
+
+    newFile('$testPackageLibPath/b.dart', content: r'''
+part of 'test.dart';
+import 'a.dart';
+''');
+
+    await assertNoErrorsInCode(r'''
+part 'b.dart';
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart
index 5bde8d7..8791394 100644
--- a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart
@@ -30,6 +30,39 @@
     ]);
   }
 
+  test_property() async {
+    await assertErrorsInCode(r'''
+class A {
+  int m;
+  A();
+  factory A.make() {
+    m;
+    return new A();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 51, 1),
+    ]);
+  }
+
+  test_property_fromClosure() async {
+    await assertErrorsInCode(r'''
+class A {
+  int m;
+  A();
+  factory A.make() {
+    void f() {
+      m;
+    }
+    f();
+    return new A();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 68, 1),
+    ]);
+  }
+
   test_unnamed() async {
     await assertErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_language_override_greater_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_language_override_greater_test.dart
index 03e35bc..dd1ee88 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_language_override_greater_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_language_override_greater_test.dart
@@ -38,12 +38,12 @@
   test_greaterThanPackage() async {
     _configureTestPackageLanguageVersion('2.5');
     await assertNoErrorsInCode(r'''
-// @dart = 2.10
+// @dart = 2.12
 int? a;
 ''');
     _assertUnitLanguageVersion(
       package: Version.parse('2.5.0'),
-      override: Version.parse('2.10.0'),
+      override: Version.parse('2.12.0'),
     );
   }
 
@@ -70,18 +70,9 @@
   }
 
   void _configureTestPackageLanguageVersion(String versionStr) {
-    newFile('$testPackageRootPath/.dart_tool/package_config.json', content: '''
-{
-  "configVersion": 2,
-  "packages": [
-    {
-      "name": "test",
-      "rootUri": "../",
-      "packageUri": "lib/",
-      "languageVersion": "$versionStr"
-    }
-  ]
-}
-''');
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: versionStr,
+    );
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_required_positional_param_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_required_positional_param_test.dart
index 39caa76..072131e 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_required_positional_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_required_positional_param_test.dart
@@ -21,7 +21,7 @@
     writeTestPackageConfigWithMeta();
   }
 
-  test_requiredPositionalParameter() async {
+  test_ofFunction_first() async {
     await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
 
@@ -31,7 +31,7 @@
     ]);
   }
 
-  test_requiredPositionalParameter_asSecond() async {
+  test_ofFunction_second() async {
     await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
 
@@ -41,6 +41,26 @@
     ]);
   }
 
+  test_ofGenericFunctionType_named() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+typedef F = void Function(@required int a);
+''', [
+      error(HintCode.INVALID_REQUIRED_POSITIONAL_PARAM, 60, 15),
+    ]);
+  }
+
+  test_ofGenericFunctionType_unnamed() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+typedef F = void Function(@required int);
+''', [
+      error(HintCode.INVALID_REQUIRED_POSITIONAL_PARAM, 60, 13),
+    ]);
+  }
+
   test_valid() async {
     await assertNoErrorsInCode(r'''
 m1() => null;
diff --git a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
index dec4111..25c55d6 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
@@ -163,6 +163,86 @@
 ''');
   }
 
+  test_function_external_nonNullable_named_optional_default() async {
+    await assertNoErrorsInCode('''
+external void f({int a = 0});
+''');
+  }
+
+  test_function_external_nonNullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+external void f({int a});
+''');
+  }
+
+  test_function_external_nonNullable_named_required_noDefault() async {
+    await assertNoErrorsInCode('''
+external void f({required int a});
+''');
+  }
+
+  test_function_external_nonNullable_positional_optional_default() async {
+    await assertNoErrorsInCode('''
+external void f([int a = 0]);
+''');
+  }
+
+  test_function_external_nonNullable_positional_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+external void f([int a]);
+''');
+  }
+
+  test_function_external_nonNullable_positional_required_noDefault() async {
+    await assertNoErrorsInCode('''
+external void f(int a);
+''');
+  }
+
+  test_function_external_nullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+external void f({int? a});
+''');
+  }
+
+  test_function_external_nullable_positional_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+external void f([int? a]);
+''');
+  }
+
+  test_function_native_nonNullable_named_optional_default() async {
+    await assertErrorsInCode('''
+void f({int a = 0}) native;
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 20, 7),
+    ]);
+  }
+
+  test_function_native_nonNullable_named_optional_noDefault() async {
+    await assertErrorsInCode('''
+void f({int a}) native;
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 16, 7),
+    ]);
+  }
+
+  test_function_native_nonNullable_positional_optional_default() async {
+    await assertErrorsInCode('''
+void f([int a = 0]) native;
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 20, 7),
+    ]);
+  }
+
+  test_function_native_nonNullable_positional_optional_noDefault() async {
+    await assertErrorsInCode('''
+void f([int a]) native;
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 16, 7),
+    ]);
+  }
+
   test_function_nonNullable_named_optional_default() async {
     await assertNoErrorsInCode('''
 void f({int a = 0}) {}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart b/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart
index 33df17a..86eee40 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_enum_constant_in_switch_test.dart
@@ -78,6 +78,23 @@
       error(StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, 44, 10),
     ]);
   }
+
+  test_parenthesized() async {
+    await assertNoErrorsInCode('''
+enum E { one, two, three }
+
+void f(E e) {
+  switch (e) {
+    case (E.one):
+      break;
+    case (E.two):
+      break;
+    case (E.three):
+      break;
+  }
+}
+''');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart b/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart
index 4f01073..1979034 100644
--- a/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/prefix_identifier_not_followed_by_dot_test.dart
@@ -133,6 +133,7 @@
   p?.loadLibrary();
 }
 ''', [
+      error(HintCode.UNUSED_IMPORT, 7, 10),
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 41, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
index c8b9dbc..1fa9c76 100644
--- a/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
@@ -23,7 +23,7 @@
 }
 ''', [
       error(HintCode.UNUSED_FIELD, 16, 2),
-      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 25, 7),
+      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 30, 2),
     ]);
   }
 
@@ -31,7 +31,7 @@
     await assertErrorsInCode('''
 f({var _p}) {}
 ''', [
-      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 3, 6),
+      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 7, 2),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
index 6ea9193..5f103da 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
@@ -28,8 +28,6 @@
     writeTestPackageAnalysisOptionsFile(
       AnalysisOptionsFileConfig(
         experiments: [
-          // TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-          EnableString.non_nullable,
           EnableString.triple_shift,
         ],
       ),
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3d1585b..05d7fb0 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -126,6 +126,8 @@
 import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
 import 'division_optimization_test.dart' as division_optimization;
 import 'duplicate_definition_test.dart' as duplicate_definition;
+import 'duplicate_field_formal_parameter_test.dart'
+    as duplicate_field_formal_parameter;
 import 'duplicate_hidden_name_test.dart' as duplicate_hidden_name;
 import 'duplicate_ignore_test.dart' as duplicate_ignore;
 import 'duplicate_import_test.dart' as duplicate_import;
@@ -742,6 +744,7 @@
     deprecated_mixin_function.main();
     division_optimization.main();
     duplicate_definition.main();
+    duplicate_field_formal_parameter.main();
     duplicate_hidden_name.main();
     duplicate_ignore.main();
     duplicate_import.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart b/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
index c8b634c..af8a61a 100644
--- a/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
@@ -33,7 +33,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 37),
-      error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 101, 1),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 38, 37),
     ]);
   }
 
@@ -147,7 +147,6 @@
 typedef A<T extends A<int>>();
 ''', [
       error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 30),
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 22, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index 814771c..1c3e268 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -47,6 +48,18 @@
     ]);
   }
 
+  test_emptyName() async {
+    await assertErrorsInCode('''
+class A {
+}
+main() {
+  print(A().);
+}
+''', [
+      error(ParserErrorCode.MISSING_IDENTIFIER, 33, 1),
+    ]);
+  }
+
   test_extension_instance_extendedHasSetter_extensionHasGetter() async {
     await assertErrorsInCode('''
 class C {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
index fc48249..95cf0b8 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
@@ -957,26 +957,13 @@
     ]);
   }
 
-  test_optionalParameter_constructor_named_notUsed() async {
-    await assertErrorsInCode(r'''
-class A {
-  A._([int a]);
-}
-f() => A._();
-''', [
-      error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1),
-    ]);
-  }
-
-  test_optionalParameter_constructor_unnamed_notUsed() async {
-    await assertErrorsInCode(r'''
+  test_optionalParameter_isUsed_constructor() async {
+    await assertNoErrorsInCode(r'''
 class _A {
-  _A([int a]);
+  _A([int a = 0]);
 }
-f() => _A();
-''', [
-      error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1),
-    ]);
+f() => _A(0);
+''');
   }
 
   test_optionalParameter_isUsed_functionTearoff() async {
@@ -1104,6 +1091,28 @@
 ''');
   }
 
+  test_optionalParameter_notUsed_constructor_named() async {
+    await assertErrorsInCode(r'''
+class A {
+  A._([int a]);
+}
+f() => A._();
+''', [
+      error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1),
+    ]);
+  }
+
+  test_optionalParameter_notUsed_constructor_unnamed() async {
+    await assertErrorsInCode(r'''
+class _A {
+  _A([int a]);
+}
+f() => _A();
+''', [
+      error(HintCode.UNUSED_ELEMENT_PARAMETER, 21, 1),
+    ]);
+  }
+
   test_optionalParameter_notUsed_extension() async {
     await assertErrorsInCode(r'''
 extension E on String {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
index f574819..04fd740 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
@@ -41,7 +41,6 @@
   }
 
   test_as_equalPrefixes_referenced() async {
-    // 18818
     newFile('$testPackageLibPath/lib1.dart', content: r'''
 class A {}
 ''');
@@ -56,9 +55,25 @@
 ''');
   }
 
-  @failingTest
+  test_as_equalPrefixes_referenced_via_export() async {
+    newFile('$testPackageLibPath/lib1.dart', content: r'''
+class A {}
+''');
+    newFile('$testPackageLibPath/lib2.dart', content: r'''
+class B {}
+''');
+    newFile('$testPackageLibPath/lib3.dart', content: r'''
+export 'lib2.dart';
+''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as one;
+import 'lib3.dart' as one;
+one.A a;
+one.B b;
+''');
+  }
+
   test_as_equalPrefixes_unreferenced() async {
-    // See todo at ImportsVerifier.prefixElementMap.
     newFile('$testPackageLibPath/lib1.dart', content: r'''
 class A {}
 ''');
@@ -70,7 +85,59 @@
 import 'lib2.dart' as one;
 one.A a;
 ''', [
-      error(HintCode.UNUSED_IMPORT, 32, 11),
+      error(HintCode.UNUSED_IMPORT, 34, 11),
+    ]);
+  }
+
+  test_as_show_multipleElements() async {
+    newFile('$testPackageLibPath/lib1.dart', content: r'''
+class A {}
+class B {}
+''');
+    await assertNoErrorsInCode(r'''
+import 'lib1.dart' as one show A, B;
+one.A a = one.A();
+one.B b = one.B();
+''');
+  }
+
+  test_as_showTopLevelFunction() async {
+    newFile('$testPackageLibPath/lib1.dart', content: r'''
+class One {}
+topLevelFunction() {}
+''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' hide topLevelFunction;
+import 'lib1.dart' as one show topLevelFunction;
+class A {
+  static void x() {
+    One o;
+    one.topLevelFunction();
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 129, 1),
+    ]);
+  }
+
+  test_as_showTopLevelFunction_multipleDirectives() async {
+    newFile('$testPackageLibPath/lib1.dart', content: r'''
+class One {}
+topLevelFunction() {}
+''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' hide topLevelFunction;
+import 'lib1.dart' as one show topLevelFunction;
+import 'lib1.dart' as two show topLevelFunction;
+class A {
+  static void x() {
+    One o;
+    one.topLevelFunction();
+    two.topLevelFunction();
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 178, 1),
     ]);
   }
 
@@ -251,6 +318,34 @@
 ''');
   }
 
+  test_extension_prefixed_isUsed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: r'''
+extension E on String {
+  String empty() => '';
+}
+''');
+    await assertNoErrorsInCode('''
+import 'lib1.dart' as lib1;
+
+f() {
+  ''.empty();
+}
+''');
+  }
+
+  test_extension_prefixed_notUsed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: r'''
+extension E on String {
+  String empty() => '';
+}
+''');
+    await assertErrorsInCode('''
+import 'lib1.dart' as lib1;
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 11),
+    ]);
+  }
+
   test_extension_static_field() async {
     newFile('$testPackageLibPath/lib1.dart', content: r'''
 extension E on String {
@@ -323,46 +418,6 @@
     ]);
   }
 
-  test_prefix_topLevelFunction() async {
-    newFile('$testPackageLibPath/lib1.dart', content: r'''
-class One {}
-topLevelFunction() {}
-''');
-    await assertErrorsInCode(r'''
-import 'lib1.dart' hide topLevelFunction;
-import 'lib1.dart' as one show topLevelFunction;
-class A {
-  static void x() {
-    One o;
-    one.topLevelFunction();
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 129, 1),
-    ]);
-  }
-
-  test_prefix_topLevelFunction2() async {
-    newFile('$testPackageLibPath/lib1.dart', content: r'''
-class One {}
-topLevelFunction() {}
-''');
-    await assertErrorsInCode(r'''
-import 'lib1.dart' hide topLevelFunction;
-import 'lib1.dart' as one show topLevelFunction;
-import 'lib1.dart' as two show topLevelFunction;
-class A {
-  static void x() {
-    One o;
-    one.topLevelFunction();
-    two.topLevelFunction();
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 178, 1),
-    ]);
-  }
-
   test_show() async {
     newFile('$testPackageLibPath/lib1.dart', content: r'''
 class A {}
diff --git a/pkg/analyzer/test/src/fasta/message_coverage_test.dart b/pkg/analyzer/test/src/fasta/message_coverage_test.dart
index ad28b0e..73a7fac 100644
--- a/pkg/analyzer/test/src/fasta/message_coverage_test.dart
+++ b/pkg/analyzer/test/src/fasta/message_coverage_test.dart
@@ -6,13 +6,13 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:yaml/yaml.dart';
 
 import '../../generated/parser_fasta_test.dart';
-import '../../utils/package_root.dart' as package_root;
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
index 8e8944a..e815d5e 100644
--- a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -505,6 +505,23 @@
 ''');
   }
 
+  test_pathNotPosix_error() {
+    newFolder('/foo');
+    newFile('/foo/pubspec.yaml', content: '''
+name: foo
+''');
+    assertErrors(r'''
+name: sample
+version: 0.1.0
+publish_to: none
+dependencies:
+  foo:
+    path: \foo
+''', [
+      PubspecWarningCode.PATH_NOT_POSIX,
+    ]);
+  }
+
   test_unnecessaryDevDependency_error() {
     assertErrors('''
 name: sample
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index 29cbc93..5e6f3ec 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -63,28 +62,6 @@
     FileSource.fileReadMode = (String s) => s;
   }
 
-  void test_fileReadMode_normalize_eol_always() {
-    FileSource.fileReadMode = PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS;
-    expect(FileSource.fileReadMode('a'), 'a');
-
-    // '\n' -> '\n' as first, last and only character
-    expect(FileSource.fileReadMode('\n'), '\n');
-    expect(FileSource.fileReadMode('a\n'), 'a\n');
-    expect(FileSource.fileReadMode('\na'), '\na');
-
-    // '\r\n' -> '\n' as first, last and only character
-    expect(FileSource.fileReadMode('\r\n'), '\n');
-    expect(FileSource.fileReadMode('a\r\n'), 'a\n');
-    expect(FileSource.fileReadMode('\r\na'), '\na');
-
-    // '\r' -> '\n' as first, last and only character
-    expect(FileSource.fileReadMode('\r'), '\n');
-    expect(FileSource.fileReadMode('a\r'), 'a\n');
-    expect(FileSource.fileReadMode('\ra'), '\na');
-
-    FileSource.fileReadMode = (String s) => s;
-  }
-
   void test_getFullName() {
     File file = getFile("/does/not/exist.dart");
     FileSource source = FileSource(file);
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 45d46f2..d225f1a 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -11,7 +11,7 @@
 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/task/inference_error.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
@@ -413,33 +413,6 @@
     buffer.writeln(' {}');
   }
 
-  void writeFunctionTypeAliasElement(FunctionTypeAliasElement e) {
-    writeDocumentation(e);
-    writeMetadata(e, '', '\n');
-    writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
-
-    if (e is FunctionTypeAliasElement) {
-      buffer.write('typedef ');
-      writeName(e);
-      writeCodeRange(e);
-      writeTypeParameterElements(e.typeParameters, withDefault: true);
-
-      buffer.write(' = ');
-
-      var function = e.function;
-      if (function != null) {
-        writeType(function.returnType);
-        buffer.write(' Function');
-        writeTypeParameterElements(function.typeParameters, withDefault: false);
-        writeParameterElements(function.parameters);
-      } else {
-        buffer.write('<null>');
-      }
-    }
-
-    buffer.writeln(';');
-  }
-
   void writeIf(bool flag, String str) {
     if (flag) {
       buffer.write(str);
@@ -465,6 +438,12 @@
       e.combinators.forEach(writeNamespaceCombinator);
 
       buffer.writeln(';');
+
+      if (withFullyResolvedAst) {
+        _withIndent(() {
+          _writeResolvedMetadata(e.metadata);
+        });
+      }
     }
   }
 
@@ -605,6 +584,10 @@
         writeList('(', ')', e.arguments.arguments, ', ', writeNode,
             includeEmpty: true);
       }
+    } else if (e is AsExpression) {
+      writeNode(e.expression);
+      buffer.write(' as ');
+      writeNode(e.type);
     } else if (e is AssertInitializer) {
       buffer.write('assert(');
       writeNode(e.condition);
@@ -669,6 +652,10 @@
       buffer.write(r'}');
     } else if (e is InterpolationString) {
       buffer.write(e.value.replaceAll("'", r"\'"));
+    } else if (e is IsExpression) {
+      writeNode(e.expression);
+      buffer.write(e.notOperator == null ? ' is ' : ' is! ');
+      writeNode(e.type);
     } else if (e is ListLiteral) {
       if (e.constKeyword != null) {
         buffer.write('const ');
@@ -1030,6 +1017,32 @@
     buffer.write(' ');
   }
 
+  void writeTypeAliasElement(TypeAliasElement e) {
+    writeDocumentation(e);
+    writeMetadata(e, '', '\n');
+    writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
+
+    buffer.write('typedef ');
+    writeName(e);
+    writeCodeRange(e);
+    writeTypeParameterElements(e.typeParameters, withDefault: true);
+
+    buffer.write(' = ');
+
+    var aliasedElement = e.aliasedElement;
+    if (aliasedElement is GenericFunctionTypeElement) {
+      writeType(aliasedElement.returnType);
+      buffer.write(' Function');
+      writeTypeParameterElements(aliasedElement.typeParameters,
+          withDefault: false);
+      writeParameterElements(aliasedElement.parameters);
+    } else {
+      writeType(e.aliasedType);
+    }
+
+    buffer.writeln(';');
+  }
+
   void writeTypeInferenceError(Element e) {
     TopLevelInferenceError inferenceError;
     if (e is MethodElementImpl) {
@@ -1095,7 +1108,7 @@
       buffer.writeln('unit: ${e.source?.shortName}');
       buffer.writeln();
     }
-    e.functionTypeAliases.forEach(writeFunctionTypeAliasElement);
+    e.typeAliases.forEach(writeTypeAliasElement);
     e.enums.forEach(writeClassElement);
     e.types.forEach(writeClassElement);
     e.mixins.forEach(writeClassElement);
@@ -1203,6 +1216,7 @@
         selfUriStr: selfUriStr,
         sink: buffer,
         indent: indent,
+        withNullability: annotateNullability,
       ),
     );
   }
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index af3b5a9..b8eaf24 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -34,6 +34,9 @@
   /// The optional provider for code lines, might be `null`.
   final CodeLinesProvider _codeLinesProvider;
 
+  /// If `true`, types should be printed with nullability suffixes.
+  final bool _withNullability;
+
   String _indent = '';
 
   ResolvedAstPrinter({
@@ -41,9 +44,11 @@
     @required StringSink sink,
     @required String indent,
     CodeLinesProvider codeLinesProvider,
+    bool withNullability = false,
   })  : _selfUriStr = selfUriStr,
         _sink = sink,
         _codeLinesProvider = codeLinesProvider,
+        _withNullability = withNullability,
         _indent = indent;
 
   @override
@@ -126,6 +131,10 @@
       properties.addNode('leftHandSide', node.leftHandSide);
       properties.addToken('operator', node.operator);
       properties.addNode('rightHandSide', node.rightHandSide);
+      properties.addElement('readElement', node.readElement);
+      properties.addType('readType', node.readType);
+      properties.addElement('writeElement', node.writeElement);
+      properties.addType('writeType', node.writeType);
       _addExpression(properties, node);
       _addMethodReferenceExpression(properties, node);
       _writeProperties(properties);
@@ -1030,6 +1039,12 @@
       var properties = _Properties();
       properties.addNode('operand', node.operand);
       properties.addToken('operator', node.operator);
+      if (node.operator.type.isIncrementOperator) {
+        properties.addElement('readElement', node.readElement);
+        properties.addType('readType', node.readType);
+        properties.addElement('writeElement', node.writeElement);
+        properties.addType('writeType', node.writeType);
+      }
       _addExpression(properties, node);
       _addMethodReferenceExpression(properties, node);
       _writeProperties(properties);
@@ -1058,6 +1073,12 @@
       var properties = _Properties();
       properties.addNode('operand', node.operand);
       properties.addToken('operator', node.operator);
+      if (node.operator.type.isIncrementOperator) {
+        properties.addElement('readElement', node.readElement);
+        properties.addType('readType', node.readType);
+        properties.addElement('writeElement', node.writeElement);
+        properties.addType('writeType', node.writeType);
+      }
       _addExpression(properties, node);
       _addMethodReferenceExpression(properties, node);
       _writeProperties(properties);
@@ -1666,7 +1687,7 @@
   }
 
   String _typeStr(DartType type) {
-    return type?.getDisplayString(withNullability: false);
+    return type?.getDisplayString(withNullability: _withNullability);
   }
 
   void _withIndent(void Function() f) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 7b6be4a..aab0156 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:typed_data';
+
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
@@ -12,12 +14,11 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'resynthesize_common.dart';
@@ -30,25 +31,17 @@
 }
 
 @reflectiveTest
-class ResynthesizeAst2Test extends ResynthesizeTestStrategyTwoPhase
+class ResynthesizeAst2Test extends AbstractResynthesizeTest
     with ResynthesizeTestCases {
   /// The shared SDK bundle, computed once and shared among test invocations.
-  static LinkedNodeBundle _sdkBundleNnbd;
+  static _SdkBundle _sdkBundle;
 
-  /// The shared SDK bundle, computed once and shared among test invocations.
-  static LinkedNodeBundle _sdkBundleLegacy;
-
-  LinkedNodeBundle get sdkBundle {
-    if (featureSet.isEnabled(Feature.non_nullable)) {
-      if (_sdkBundleNnbd != null) {
-        return _sdkBundleNnbd;
-      }
-    } else {
-      if (_sdkBundleLegacy != null) {
-        return _sdkBundleLegacy;
-      }
+  _SdkBundle get sdkBundle {
+    if (_sdkBundle != null) {
+      return _sdkBundle;
     }
 
+    var featureSet = FeatureSet.latestLanguageVersion();
     var inputLibraries = <LinkInputLibrary>[];
     for (var sdkLibrary in sdk.sdkLibraries) {
       var source = sourceFactory.resolveUri(null, sdkLibrary.shortName);
@@ -56,7 +49,7 @@
       var unit = parseText(text, featureSet);
 
       var inputUnits = <LinkInputUnit>[];
-      _addLibraryUnits(source, unit, inputUnits);
+      _addLibraryUnits(source, unit, inputUnits, featureSet);
       inputLibraries.add(
         LinkInputLibrary(source, inputUnits),
       );
@@ -74,15 +67,12 @@
       Reference.root(),
     );
 
-    var sdkLinkResult = link(elementFactory, inputLibraries);
+    var sdkLinkResult = link(elementFactory, inputLibraries, true);
 
-    var bytes = sdkLinkResult.bundle.toBuffer();
-    var sdkBundle = LinkedNodeBundle.fromBuffer(bytes);
-    if (featureSet.isEnabled(Feature.non_nullable)) {
-      return _sdkBundleNnbd = sdkBundle;
-    } else {
-      return _sdkBundleLegacy = sdkBundle;
-    }
+    return _sdkBundle = _SdkBundle(
+      astBytes: sdkLinkResult.astBytes,
+      resolutionBytes: sdkLinkResult.resolutionBytes,
+    );
   }
 
   @override
@@ -107,46 +97,39 @@
       Reference.root(),
     );
     elementFactory.addBundle(
-      LinkedBundleContext(elementFactory, sdkBundle),
+      BundleReader(
+        elementFactory: elementFactory,
+        astBytes: sdkBundle.astBytes,
+        resolutionBytes: sdkBundle.resolutionBytes,
+      ),
     );
 
     var linkResult = NullSafetyUnderstandingFlag.enableNullSafetyTypes(
       () {
-        return link(
-          elementFactory,
-          inputLibraries,
-        );
+        return link(elementFactory, inputLibraries, true);
       },
     );
 
     elementFactory.addBundle(
-      LinkedBundleContext(elementFactory, linkResult.bundle),
+      BundleReader(
+        elementFactory: elementFactory,
+        astBytes: linkResult.astBytes,
+        resolutionBytes: linkResult.resolutionBytes,
+      ),
     );
 
-    // Set informative data.
-    for (var inputLibrary in inputLibraries) {
-      var libraryUriStr = '${inputLibrary.source.uri}';
-      for (var inputUnit in inputLibrary.units) {
-        var unitSource = inputUnit.source;
-        if (unitSource != null) {
-          var unitUriStr = '${unitSource.uri}';
-          var informativeData = createInformativeData(inputUnit.unit);
-          elementFactory.setInformativeData(
-            libraryUriStr,
-            unitUriStr,
-            informativeData,
-          );
-        }
-      }
-    }
-
     return elementFactory.libraryOfUri('${source.uri}');
   }
 
+  void setUp() {
+    featureSet = FeatureSets.beforeNullSafe;
+  }
+
   void _addLibraryUnits(
     Source definingSource,
     CompilationUnit definingUnit,
     List<LinkInputUnit> units,
+    FeatureSet featureSet,
   ) {
     units.add(
       LinkInputUnit(null, definingSource, false, definingUnit),
@@ -191,7 +174,7 @@
     var unit = parseText(text, featureSet);
 
     var units = <LinkInputUnit>[];
-    _addLibraryUnits(source, unit, units);
+    _addLibraryUnits(source, unit, units, featureSet);
     libraries.add(
       LinkInputLibrary(source, units),
     );
@@ -232,3 +215,13 @@
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
+
+class _SdkBundle {
+  final Uint8List astBytes;
+  final Uint8List resolutionBytes;
+
+  _SdkBundle({
+    @required this.astBytes,
+    @required this.resolutionBytes,
+  });
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index a3cfc3c..7ff0b3a 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8,32 +8,32 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'element_text.dart';
-import 'test_strategies.dart';
 
 /// Abstract base class for resynthesizing and comparing elements.
 ///
 /// The return type separator: →
 abstract class AbstractResynthesizeTest with ResourceProviderMixin {
-  DeclaredVariables declaredVariables = DeclaredVariables();
-  SourceFactory sourceFactory;
-  MockSdk sdk;
+  /// The set of features enabled in this test.
+  FeatureSet featureSet;
 
-  String testFile;
+  DeclaredVariables declaredVariables = DeclaredVariables();
+  /*late final*/ SourceFactory sourceFactory;
+  /*late final*/ MockSdk sdk;
+
+  /*late final*/ String testFile;
   Source testSource;
   Set<Source> otherLibrarySources = <Source>{};
 
-  /// Tests may set this to `true` to indicate that a missing file at the time
-  /// of summary resynthesis shouldn't trigger an error.
-  bool allowMissingFiles = false;
-
   AbstractResynthesizeTest() {
     sdk = MockSdk(resourceProvider: resourceProvider);
 
@@ -68,17 +68,31 @@
     testSource = addSource(testFile, code);
     return testSource;
   }
+
+  Future<LibraryElementImpl /*!*/ > checkLibrary(String text,
+      {bool allowErrors = false});
+}
+
+class FeatureSets {
+  static final FeatureSet beforeNullSafe = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.9.0'),
+    flags: [],
+  );
+
+  static final FeatureSet nullSafe = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.12.0'),
+    flags: [],
+  );
+
+  static final FeatureSet nonFunctionTypeAliases = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.12.0'),
+    flags: [EnableString.nonfunction_type_aliases],
+  );
 }
 
 /// Mixin containing test cases exercising summary resynthesis.  Intended to be
-/// applied to a class implementing [ResynthesizeTestStrategy], along with the
-/// mixin [ResynthesizeTestHelpers].
-mixin ResynthesizeTestCases implements ResynthesizeTestHelpers {
-  FeatureSet get disableNnbd => FeatureSet.forTesting(sdkVersion: '2.2.2');
-
-  FeatureSet get enableNnbd =>
-      FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
-
+/// applied to a class implementing [AbstractResynthesizeTest].
+mixin ResynthesizeTestCases on AbstractResynthesizeTest {
   test_class_abstract() async {
     var library = await checkLibrary('abstract class C {}');
     checkElementText(library, r'''
@@ -913,7 +927,7 @@
   }
 
   test_class_field_const_late() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library =
         await checkLibrary('class C { static late const int i = 0; }');
     checkElementText(library, r'''
@@ -933,7 +947,7 @@
   }
 
   test_class_field_implicit_type_late() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('class C { late var x; }');
     checkElementText(library, r'''
 class C {
@@ -952,7 +966,7 @@
   }
 
   test_class_field_static_late() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('class C { static late int i; }');
     checkElementText(library, r'''
 class C {
@@ -972,7 +986,7 @@
   }
 
   test_class_fields_late() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C {
   late int foo;
@@ -991,7 +1005,7 @@
   }
 
   test_class_fields_late_final() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C {
   late final int foo;
@@ -1010,7 +1024,7 @@
   }
 
   test_class_fields_late_final_initialized() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C {
   late final int foo = 0;
@@ -1288,8 +1302,8 @@
 typedef F(C value);
 ''');
     checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(C<dynamic> value);
-notSimplyBounded class C<T extends dynamic Function(C<dynamic>) = dynamic Function(C<dynamic>)> {
+notSimplyBounded typedef F = dynamic Function(C<dynamic Function()> value);
+notSimplyBounded class C<T extends dynamic Function() = dynamic Function()> {
 }
 ''');
   }
@@ -1400,9 +1414,9 @@
 typedef G(F value);
 ''');
     checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic) value);
-notSimplyBounded typedef G = dynamic Function(dynamic value);
-notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic)) = dynamic Function(dynamic Function(dynamic))> {
+notSimplyBounded typedef F = dynamic Function(dynamic Function() value);
+notSimplyBounded typedef G = dynamic Function(dynamic Function() value);
+notSimplyBounded class C<T extends dynamic Function() = dynamic Function()> {
 }
 ''');
   }
@@ -1455,7 +1469,7 @@
   }
 
   test_class_ref_nullability_none() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C {}
 C c;
@@ -1471,7 +1485,7 @@
   }
 
   test_class_ref_nullability_question() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C {}
 C? c;
@@ -1487,7 +1501,7 @@
   }
 
   test_class_ref_nullability_star() async {
-    featureSet = disableNnbd;
+    featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary('''
 class C {}
 C c;
@@ -1783,7 +1797,7 @@
   }
 
   test_class_typeParameters_defaultType_functionTypeAlias_contravariant_nullSafe() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 typedef F<X> = void Function(X);
 
@@ -1816,7 +1830,7 @@
   }
 
   test_class_typeParameters_defaultType_functionTypeAlias_invariant_nullSafe() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 typedef F<X> = X Function(X);
 
@@ -1843,7 +1857,7 @@
   }
 
   test_class_typeParameters_defaultType_genericFunctionType_both_nullSafe() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 class A<X extends X Function(X)> {}
 ''');
@@ -1864,7 +1878,7 @@
   }
 
   test_class_typeParameters_defaultType_genericFunctionType_contravariant_nullSafe() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 class A<X extends void Function(X)> {}
 ''');
@@ -1885,7 +1899,7 @@
   }
 
   test_class_typeParameters_defaultType_genericFunctionType_covariant_nullSafe() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 class A<X extends X Function()> {}
 ''');
@@ -2700,7 +2714,7 @@
   }
 
   test_compilationUnit_nnbd_disabled_via_dart_directive() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 // @dart=2.2
 ''');
@@ -2708,17 +2722,108 @@
   }
 
   test_compilationUnit_nnbd_disabled_via_feature_set() async {
-    featureSet = disableNnbd;
+    featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary('');
     expect(library.isNonNullableByDefault, isFalse);
   }
 
   test_compilationUnit_nnbd_enabled() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('');
     expect(library.isNonNullableByDefault, isTrue);
   }
 
+  test_const_asExpression() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary('''
+const num a = 0;
+const b = a as int;
+''');
+    checkElementText(library, '''
+const num a = 0;
+const int b =
+        a/*location: test.dart;a?*/ as
+        int/*location: dart:core;int*/;
+''');
+  }
+
+  test_const_assignmentExpression() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = (a += 1);
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    ParenthesizedExpression
+      expression: AssignmentExpression
+        leftHandSide: SimpleIdentifier
+          staticElement: <null>
+          staticType: null
+          token: a
+        operator: +=
+        readElement: self::@getter::a
+        readType: int
+        rightHandSide: IntegerLiteral
+          literal: 1
+          staticType: int
+        staticElement: dart:core::@class::num::@method::+
+        staticType: int
+        writeElement: self::@getter::a
+        writeType: dynamic
+      staticType: int
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_cascadeExpression() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+const a = 0..isEven..abs();
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    CascadeExpression
+      cascadeSections
+        PropertyAccess
+          operator: ..
+          propertyName: SimpleIdentifier
+            staticElement: dart:core::@class::int::@getter::isEven
+            staticType: bool
+            token: isEven
+          staticType: bool
+        MethodInvocation
+          argumentList: ArgumentList
+          methodName: SimpleIdentifier
+            staticElement: dart:core::@class::int::@method::abs
+            staticType: int Function()
+            token: abs
+          operator: ..
+          staticInvokeType: null
+          staticType: int
+      staticType: int
+      target: IntegerLiteral
+        literal: 0
+        staticType: int
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_classField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -2791,6 +2896,50 @@
 ''');
   }
 
+  test_const_indexExpression() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+const a = [0];
+const b = 0;
+const c = a[b];
+''');
+    checkElementText(
+      library,
+      r'''
+const List<int> a;
+  constantInitializer
+    ListLiteral
+      elements
+        IntegerLiteral
+          literal: 0
+          staticType: int
+      staticType: List<int>
+const int b;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int c;
+  constantInitializer
+    IndexExpression
+      index: SimpleIdentifier
+        staticElement: self::@getter::b
+        staticType: int
+        token: b
+      staticElement: MethodMember
+        base: dart:core::@class::List::@method::[]
+        substitution: {E: int}
+      staticType: int
+      target: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: List<int>
+        token: a
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_inference_downward_list() async {
     var library = await checkLibrary('''
 class P<T> {
@@ -3253,6 +3402,20 @@
 ''');
   }
 
+  test_const_isExpression() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary('''
+const a = 0;
+const b = a is int;
+''');
+    checkElementText(library, '''
+const int a = 0;
+const bool b =
+        a/*location: test.dart;a?*/ is
+        int/*location: dart:core;int*/;
+''');
+  }
+
   test_const_length_ofClassConstField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -3527,6 +3690,44 @@
         withTypes: true);
   }
 
+  test_const_methodInvocation() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+T f<T>(T a) => a;
+const b = f<int>(0);
+''');
+    checkElementText(
+      library,
+      r'''
+const int b;
+  constantInitializer
+    MethodInvocation
+      argumentList: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      methodName: SimpleIdentifier
+        staticElement: self::@function::f
+        staticType: T Function<T>(T)
+        token: f
+      staticInvokeType: null
+      staticType: int
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+T f(T a) {}
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
     var library = await checkLibrary(r'''
 class C {
@@ -3598,6 +3799,104 @@
 ''');
   }
 
+  test_const_postfixExpression_increment() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = a++;
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PostfixExpression
+      operand: SimpleIdentifier
+        staticElement: <null>
+        staticType: null
+        token: a
+      operator: ++
+      readElement: self::@getter::a
+      readType: int
+      staticElement: dart:core::@class::num::@method::+
+      staticType: int
+      writeElement: self::@getter::a
+      writeType: dynamic
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_postfixExpression_nullCheck() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a!;
+''');
+    checkElementText(
+      library,
+      r'''
+const int? a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PostfixExpression
+      operand: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: int?
+        token: a
+      operator: !
+      staticElement: <null>
+      staticType: int
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_prefixExpression_increment() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = ++a;
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PrefixExpression
+      operand: SimpleIdentifier
+        staticElement: <null>
+        staticType: null
+        token: a
+      operator: ++
+      readElement: self::@getter::a
+      readType: int
+      staticElement: dart:core::@class::num::@method::+
+      staticType: int
+      writeElement: self::@getter::a
+      writeType: dynamic
+''',
+      annotateNullability: true,
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_reference_staticField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -4131,9 +4430,11 @@
 const vNull = null;
 const vBoolFalse = false;
 const vBoolTrue = true;
-const vInt = 1;
+const vIntPositive = 1;
+const vIntNegative = -2;
 const vIntLong1 = 0x7FFFFFFFFFFFFFFF;
 const vIntLong2 = 0xFFFFFFFFFFFFFFFF;
+const vIntLong3 = 0x8000000000000000;
 const vDouble = 2.3;
 const vString = 'abc';
 const vStringConcat = 'aaa' 'bbb';
@@ -4144,9 +4445,11 @@
 const dynamic vNull = null;
 const bool vBoolFalse = false;
 const bool vBoolTrue = true;
-const int vInt = 1;
+const int vIntPositive = 1;
+const int vIntNegative = -2;
 const int vIntLong1 = 9223372036854775807;
 const int vIntLong2 = -1;
+const int vIntLong3 = -9223372036854775808;
 const double vDouble = 2.3;
 const String vString = 'abc';
 const String vStringConcat = 'aaabbb';
@@ -4156,7 +4459,7 @@
   }
 
   test_const_topLevel_nullSafe_nullAware_propertyAccess() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 const String? a = '';
 
@@ -4517,6 +4820,35 @@
 ''');
   }
 
+  test_constructor_initializers_field_optionalPositionalParameter() async {
+    var library = await checkLibrary('''
+class A {
+  final int _f;
+  const A([int f = 0]) : _f = f;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  final int _f;
+  const A([int f = 0]);
+    constantInitializers
+      ConstructorFieldInitializer
+        equals: =
+        expression: SimpleIdentifier
+          staticElement: f@41
+          staticType: int
+          token: f
+        fieldName: SimpleIdentifier
+          staticElement: self::@class::A::@field::_f
+          staticType: null
+          token: _f
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_constructor_initializers_field_withParameter() async {
     var library = await checkLibrary('''
 class C {
@@ -5194,7 +5526,7 @@
   }
 
   test_defaultValue_eliminateTypeParameters() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class A<T> {
   const X({List<T> a = const []});
@@ -6014,7 +6346,6 @@
   }
 
   test_export_uri() async {
-    allowMissingFiles = true;
     var library = await checkLibrary('''
 export 'foo.dart';
 ''');
@@ -6201,7 +6532,7 @@
   }
 
   test_field_abstract() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 abstract class C {
   abstract int i;
@@ -6245,7 +6576,7 @@
   }
 
   test_field_external() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 abstract class C {
   external int i;
@@ -6355,6 +6686,46 @@
 ''');
   }
 
+  test_field_inferred_type_nonStatic_inherited_resolveInitializer() async {
+    var library = await checkLibrary(r'''
+const a = 0;
+abstract class A {
+  const A();
+  List<int> get f;
+}
+class B extends A {
+  const B();
+  final f = [a];
+}
+''');
+    checkElementText(
+        library,
+        r'''
+abstract class A {
+  List<int> get f;
+  const A();
+}
+class B extends A {
+  final List<int> f;
+    constantInitializer
+      ListLiteral
+        elements
+          SimpleIdentifier
+            staticElement: self::@getter::a
+            staticType: int
+            token: a
+        staticType: List<int>
+  const B();
+}
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_field_inferred_type_static_implicit_initialized() async {
     var library = await checkLibrary('class C { static var v = 0; }');
     checkElementText(library, r'''
@@ -6446,7 +6817,7 @@
   }
 
   test_field_type_inferred_Never() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 class C {
   var a = throw 42;
@@ -6464,7 +6835,7 @@
   }
 
   test_field_type_inferred_nonNullify() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
 
     addSource('/a.dart', '''
 // @dart = 2.7
@@ -6747,6 +7118,38 @@
 ''');
   }
 
+  test_functionTypeAlias_enclosingElements() async {
+    var library = await checkLibrary(r'''
+typedef void F<T>(int a);
+''');
+    var unit = library.definingCompilationUnit;
+
+    var F = unit.functionTypeAliases[0];
+    expect(F.name, 'F');
+
+    var T = F.typeParameters[0];
+    expect(T.name, 'T');
+    expect(T.enclosingElement, same(F));
+
+    var function = F.function;
+    expect(function.enclosingElement, same(F));
+
+    var a = function.parameters[0];
+    expect(a.name, 'a');
+    expect(a.enclosingElement, same(function));
+  }
+
+  test_functionTypeAlias_type_element() async {
+    var library = await checkLibrary(r'''
+typedef T F<T>();
+F<int> a;
+''');
+    var unit = library.definingCompilationUnit;
+    var type = unit.topLevelVariables[0].type as FunctionType;
+    expect(type.element.enclosingElement, same(unit.functionTypeAliases[0]));
+    _assertTypeStrings(type.typeArguments, ['int*']);
+  }
+
   test_functionTypeAlias_typeParameters_variance_contravariant() async {
     var library = await checkLibrary(r'''
 typedef void F<T>(T a);
@@ -6927,7 +7330,7 @@
   }
 
   test_generic_function_type_nullability_none() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 void Function() f;
 ''');
@@ -6940,7 +7343,7 @@
   }
 
   test_generic_function_type_nullability_question() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 void Function()? f;
 ''');
@@ -6953,7 +7356,7 @@
   }
 
   test_generic_function_type_nullability_star() async {
-    featureSet = disableNnbd;
+    featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary('''
 void Function() f;
 ''');
@@ -7050,12 +7453,37 @@
 ''');
   }
 
+  test_genericTypeAlias_enclosingElements() async {
+    var library = await checkLibrary(r'''
+typedef F<T> = void Function<U>(int a);
+''');
+    var unit = library.definingCompilationUnit;
+
+    var F = unit.functionTypeAliases[0];
+    expect(F.name, 'F');
+
+    var T = F.typeParameters[0];
+    expect(T.name, 'T');
+    expect(T.enclosingElement, same(F));
+
+    var function = F.function;
+    expect(function.enclosingElement, same(F));
+
+    var U = function.typeParameters[0];
+    expect(U.name, 'U');
+    expect(U.enclosingElement, same(function));
+
+    var a = function.parameters[0];
+    expect(a.name, 'a');
+    expect(a.enclosingElement, same(function));
+  }
+
   test_genericTypeAlias_recursive() async {
     var library = await checkLibrary('''
 typedef F<X extends F> = Function(F);
 ''');
     checkElementText(library, r'''
-notSimplyBounded typedef F<X> = dynamic Function();
+notSimplyBounded typedef F<X extends dynamic Function()> = dynamic Function(dynamic Function() );
 ''');
   }
 
@@ -7429,7 +7857,6 @@
   }
 
   test_import_invalidUri_metadata() async {
-    allowMissingFiles = true;
     var library = await checkLibrary('''
 @foo
 import 'ht:';
@@ -7511,8 +7938,17 @@
 ''');
   }
 
+  test_import_show_offsetEnd() async {
+    var library = await checkLibrary('''
+import "dart:math" show e, pi;
+''');
+    var import = library.imports[0];
+    var combinator = import.combinators[0] as ShowElementCombinator;
+    expect(combinator.offset, 19);
+    expect(combinator.end, 29);
+  }
+
   test_import_uri() async {
-    allowMissingFiles = true;
     var library = await checkLibrary('''
 import 'foo.dart';
 ''');
@@ -7773,7 +8209,7 @@
   }
 
   test_inferred_type_functionExpressionInvocation_oppositeOrder() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class A {
   static final foo = bar(1.2);
@@ -7822,7 +8258,7 @@
   }
 
   test_inferred_type_nullability_class_ref_none() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addSource('/a.dart', 'int f() => 0;');
     var library = await checkLibrary('''
 import 'a.dart';
@@ -7838,7 +8274,7 @@
   }
 
   test_inferred_type_nullability_class_ref_question() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addSource('/a.dart', 'int? f() => 0;');
     var library = await checkLibrary('''
 import 'a.dart';
@@ -7854,7 +8290,7 @@
   }
 
   test_inferred_type_nullability_function_type_none() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addSource('/a.dart', 'void Function() f() => () {};');
     var library = await checkLibrary('''
 import 'a.dart';
@@ -7870,7 +8306,7 @@
   }
 
   test_inferred_type_nullability_function_type_question() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addSource('/a.dart', 'void Function()? f() => () {};');
     var library = await checkLibrary('''
 import 'a.dart';
@@ -8194,69 +8630,141 @@
 ''');
   }
 
-  test_instanceInference_operator_equal_legacy() async {
-    var library = await checkLibrary(r'''
-class A1 {
+  test_instanceInference_operator_equal_legacy_from_legacy() async {
+    addLibrarySource('/legacy.dart', r'''
+// @dart = 2.7
+class LegacyDefault {
   bool operator==(other) => false;
 }
-class A2 {
+class LegacyObject {
+  bool operator==(Object other) => false;
+}
+class LegacyInt {
   bool operator==(int other) => false;
 }
-class B1 extends A1 {
+''');
+    var library = await checkLibrary(r'''
+import 'legacy.dart';
+class X1 extends LegacyDefault  {
   bool operator==(other) => false;
 }
-class B2 extends A2 {
+class X2 extends LegacyObject {
+  bool operator==(other) => false;
+}
+class X3 extends LegacyInt {
   bool operator==(other) => false;
 }
 ''');
     checkElementText(
         library,
         r'''
-class A1 {
+import 'legacy.dart';
+class X1 extends LegacyDefault* {
   bool* ==(dynamic other) {}
 }
-class A2 {
-  bool* ==(int* other) {}
+class X2 extends LegacyObject* {
+  bool* ==(Object* other) {}
 }
-class B1 extends A1* {
-  bool* ==(dynamic other) {}
-}
-class B2 extends A2* {
+class X3 extends LegacyInt* {
   bool* ==(int* other) {}
 }
 ''',
         annotateNullability: true);
   }
 
-  test_instanceInference_operator_equal_nnbd() async {
-    featureSet = enableNnbd;
-    var library = await checkLibrary(r'''
-class A1 {
+  test_instanceInference_operator_equal_legacy_from_legacy_nullSafe() async {
+    featureSet = FeatureSets.nullSafe;
+    addLibrarySource('/legacy.dart', r'''
+// @dart = 2.7
+class LegacyDefault {
   bool operator==(other) => false;
 }
-class A2 {
+class LegacyObject {
+  bool operator==(Object other) => false;
+}
+class LegacyInt {
   bool operator==(int other) => false;
 }
-class B1 extends A1 {
+''');
+    addLibrarySource('/nullSafe.dart', r'''
+class NullSafeDefault {
   bool operator==(other) => false;
 }
-class B2 extends A2 {
+class NullSafeObject {
+  bool operator==(Object other) => false;
+}
+class NullSafeInt {
+  bool operator==(int other) => false;
+}
+''');
+    var library = await checkLibrary(r'''
+// @dart = 2.7
+import 'legacy.dart';
+import 'nullSafe.dart';
+class X1 extends LegacyDefault implements NullSafeDefault {
+  bool operator==(other) => false;
+}
+class X2 extends LegacyObject implements NullSafeObject {
+  bool operator==(other) => false;
+}
+class X3 extends LegacyInt implements NullSafeInt {
   bool operator==(other) => false;
 }
 ''');
     checkElementText(
         library,
         r'''
-class A1 {
+import 'legacy.dart';
+import 'nullSafe.dart';
+class X1 extends LegacyDefault* implements NullSafeDefault* {
+  bool* ==(dynamic other) {}
+}
+class X2 extends LegacyObject* implements NullSafeObject* {
+  bool* ==(Object* other) {}
+}
+class X3 extends LegacyInt* implements NullSafeInt* {
+  bool* ==(int* other) {}
+}
+''',
+        annotateNullability: true);
+  }
+
+  test_instanceInference_operator_equal_nullSafe_from_nullSafe() async {
+    featureSet = FeatureSets.nullSafe;
+    addLibrarySource('/nullSafe.dart', r'''
+class NullSafeDefault {
+  bool operator==(other) => false;
+}
+class NullSafeObject {
+  bool operator==(Object other) => false;
+}
+class NullSafeInt {
+  bool operator==(int other) => false;
+}
+''');
+    var library = await checkLibrary(r'''
+import 'nullSafe.dart';
+class X1 extends NullSafeDefault {
+  bool operator==(other) => false;
+}
+class X2 extends NullSafeObject {
+  bool operator==(other) => false;
+}
+class X3 extends NullSafeInt {
+  bool operator==(other) => false;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'nullSafe.dart';
+class X1 extends NullSafeDefault {
   bool ==(Object other) {}
 }
-class A2 {
-  bool ==(int other) {}
-}
-class B1 extends A1 {
+class X2 extends NullSafeObject {
   bool ==(Object other) {}
 }
-class B2 extends A2 {
+class X3 extends NullSafeInt {
   bool ==(int other) {}
 }
 ''',
@@ -8529,7 +9037,6 @@
   }
 
   test_invalidUris() async {
-    allowMissingFiles = true;
     var library = await checkLibrary(r'''
 import ':[invaliduri]';
 import ':[invaliduri]:foo.dart';
@@ -9295,15 +9802,54 @@
   }
 
   test_metadata_importDirective() async {
-    addLibrarySource('/foo.dart', 'const b = null;');
+    addLibrarySource('/foo.dart', 'const b = 0;');
     var library = await checkLibrary('@a import "foo.dart"; const a = b;');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
+    checkElementText(
+        library,
+        '''
 import 'foo.dart';
-const dynamic a =
-        b/*location: foo.dart;b?*/;
+  metadata
+    Annotation
+      element: self::@getter::a
+      name: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: null
+        token: a
+const int a;
+  constantInitializer
+    SimpleIdentifier
+      staticElement: ${toUriStr('/foo.dart')}::@getter::b
+      staticType: int
+      token: b
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_importDirective_hasShow() async {
+    var library = await checkLibrary(r'''
+@a
+import "dart:math" show Random;
+
+const a = 0;
 ''');
+    checkElementText(
+        library,
+        r'''
+import 'dart:math' show Random;
+  metadata
+    Annotation
+      element: self::@getter::a
+      name: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: null
+        token: a
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_invalid_classDeclaration() async {
@@ -9498,6 +10044,23 @@
 ''');
   }
 
+  test_metadata_partDirective2() async {
+    addSource('/a.dart', r'''
+part of 'test.dart';
+''');
+    addSource('/b.dart', r'''
+part of 'test.dart';
+''');
+    var library = await checkLibrary('''
+part 'a.dart';
+part 'b.dart';
+''');
+
+    // The difference with the test above is that we ask the part first.
+    // There was a bug that we were not loading library directives.
+    expect(library.parts[0].metadata, isEmpty);
+  }
+
   test_metadata_prefixed_variable() async {
     addLibrarySource('/a.dart', 'const b = null;');
     var library = await checkLibrary('import "a.dart" as a; @a.b class C {}');
@@ -9806,7 +10369,7 @@
   }
 
   test_mixin_inference_nullSafety() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 class A<T> {}
 mixin M<U> on A<U> {}
@@ -9827,7 +10390,7 @@
   }
 
   test_mixin_inference_nullSafety2() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addLibrarySource('/a.dart', r'''
 class A<T> {}
 
@@ -9852,7 +10415,7 @@
   }
 
   test_mixin_inference_nullSafety_mixed_inOrder() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addLibrarySource('/a.dart', r'''
 class A<T> {}
 mixin M<U> on A<U> {}
@@ -9875,7 +10438,7 @@
 
   @FailingTest(reason: 'Out-of-order inference is not specified yet')
   test_mixin_inference_nullSafety_mixed_outOfOrder() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     addLibrarySource('/a.dart', r'''
 // @dart = 2.8
 class A<T> {}
@@ -10102,6 +10665,26 @@
 ''');
   }
 
+  test_new_typedef_notSimplyBounded_functionType_returnType() async {
+    var library = await checkLibrary('''
+typedef F = G Function();
+typedef G = F Function();
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = dynamic Function() Function();
+notSimplyBounded typedef G = dynamic Function() Function();
+''');
+  }
+
+  test_new_typedef_notSimplyBounded_functionType_returnType_viaInterfaceType() async {
+    var library = await checkLibrary('''
+typedef F = List<F> Function();
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = List<dynamic Function()> Function();
+''');
+  }
+
   test_new_typedef_notSimplyBounded_self() async {
     var library = await checkLibrary('''
 typedef F<T extends F> = void Function();
@@ -10134,7 +10717,7 @@
 typedef void F<T extends F>();
 ''');
     checkElementText(library, r'''
-notSimplyBounded typedef F<T extends void Function()> = void Function();
+notSimplyBounded typedef F<T extends dynamic Function()> = void Function();
 ''');
   }
 
@@ -10427,7 +11010,6 @@
   }
 
   test_part_emptyUri() async {
-    allowMissingFiles = true;
     var library = await checkLibrary(r'''
 part '';
 class B extends A {}
@@ -10442,7 +11024,6 @@
   }
 
   test_part_uri() async {
-    allowMissingFiles = true;
     var library = await checkLibrary('''
 part 'foo.dart';
 ''');
@@ -10468,7 +11049,6 @@
   }
 
   test_parts_invalidUri() async {
-    allowMissingFiles = true;
     addSource('/foo/bar.dart', 'part of my.lib;');
     var library = await checkLibrary('library my.lib; part "foo/";');
     checkElementText(library, r'''
@@ -10481,7 +11061,6 @@
   }
 
   test_parts_invalidUri_nullStringValue() async {
-    allowMissingFiles = true;
     addSource('/foo/bar.dart', 'part of my.lib;');
     var library = await checkLibrary(r'''
 library my.lib;
@@ -10683,7 +11262,7 @@
   }
 
   test_top_level_variable_external() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 external int i;
 ''');
@@ -10970,7 +11549,7 @@
   }
 
   test_type_never_disableNnbd() async {
-    featureSet = disableNnbd;
+    featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary('Never d;');
     checkElementText(
         library,
@@ -10981,7 +11560,7 @@
   }
 
   test_type_never_enableNnbd() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('Never d;');
     checkElementText(
         library,
@@ -10992,7 +11571,7 @@
   }
 
   test_type_param_ref_nullability_none() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C<T> {
   T t;
@@ -11009,7 +11588,7 @@
   }
 
   test_type_param_ref_nullability_question() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('''
 class C<T> {
   T? t;
@@ -11026,7 +11605,7 @@
   }
 
   test_type_param_ref_nullability_star() async {
-    featureSet = disableNnbd;
+    featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary('''
 class C<T> {
   T t;
@@ -11409,6 +11988,189 @@
 ''');
   }
 
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_asInterfaceType_interfaceType_none() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef X<T> = A<int, T>;
+class A<T, U> {}
+class B implements X<String> {}
+''');
+    checkElementText(library, r'''
+typedef X<T> = A<int, T>;
+class A<T, U> {
+}
+class B implements A<int, String> {
+}
+''');
+  }
+
+  @failingTest
+  test_typedef_nonFunction_asInterfaceType_interfaceType_question() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef X<T> = A<T>?;
+class A<T> {}
+class B implements X<int> {}
+''');
+    checkElementText(library, r'''
+typedef X<T> = A<int, T>;
+class A<T, U> {
+}
+class B implements A<int, String> {
+}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_asInterfaceType_void() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef X = void;
+class A {}
+class B {}
+class C implements A, X, B {}
+''');
+    checkElementText(library, r'''
+typedef X = void;
+class A {
+}
+class B {
+}
+class C implements A, B {
+}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_asMixinType() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef X = A<int>;
+class A<T> {}
+class B with X {}
+''');
+    checkElementText(library, r'''
+typedef X = A<int>;
+class A<T> {
+}
+class B extends Object with A<int> {
+  synthetic B();
+}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_asSuperType_interfaceType() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef X = A<int>;
+class A<T> {}
+class B extends X {}
+''');
+    checkElementText(library, r'''
+typedef X = A<int>;
+class A<T> {
+}
+class B extends A<int> {
+}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_using_dynamic() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A = dynamic;
+void f(A a) {}
+''');
+    checkElementText(library, r'''
+typedef A = dynamic;
+void f(dynamic a) {}
+''');
+  }
+
+  test_typedef_nonFunction_using_interface_disabled() async {
+    featureSet = FeatureSets.nullSafe;
+    var library = await checkLibrary(r'''
+typedef A = int;
+void f(A a) {}
+''');
+
+    var alias = library.definingCompilationUnit.typeAliases[0];
+    _assertTypeStr(alias.aliasedType, 'dynamic Function()');
+
+    checkElementText(library, r'''
+typedef A = dynamic Function();
+void f(dynamic Function() a) {}
+''');
+  }
+
+  test_typedef_nonFunction_using_interface_noTypeParameters() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A = int;
+void f(A a) {}
+''');
+    checkElementText(library, r'''
+typedef A = int;
+void f(int a) {}
+''');
+  }
+
+  test_typedef_nonFunction_using_interface_withTypeParameters() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A<T> = Map<int, T>;
+void f(A<String> a) {}
+''');
+    checkElementText(library, r'''
+typedef A<T> = Map<int, T>;
+void f(Map<int, String> a) {}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_using_Never() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A = Never;
+void f(A a) {}
+''');
+    checkElementText(library, r'''
+typedef A = Never;
+void f(Never a) {}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_using_typeParameter() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A<T> = T;
+void f1(A a) {}
+void f2(A<int> a) {}
+''');
+    checkElementText(library, r'''
+typedef A<T> = T;
+void f1(dynamic a) {}
+void f2(int a) {}
+''');
+  }
+
+  /// TODO(scheglov) add `?` cases.
+  test_typedef_nonFunction_using_void() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A = void;
+void f(A a) {}
+''');
+    checkElementText(library, r'''
+typedef A = void;
+void f(void a) {}
+''');
+  }
+
   test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
     // F is considered "not simply bounded" because it expands to a type that
     // refers to C, which is not simply bounded.
@@ -11577,7 +12339,7 @@
     var library = await checkLibrary('typedef void F<T extends F>();');
     // Typedefs cannot reference themselves.
     checkElementText(library, r'''
-notSimplyBounded typedef F<T extends void Function()> = void Function();
+notSimplyBounded typedef F<T extends dynamic Function()> = void Function();
 ''');
   }
 
@@ -11585,7 +12347,7 @@
     var library = await checkLibrary('typedef void F<T extends List<F>>();');
     // Typedefs cannot reference themselves.
     checkElementText(library, r'''
-notSimplyBounded typedef F<T extends List<void Function()>> = void Function();
+notSimplyBounded typedef F<T extends List<dynamic Function()>> = void Function();
 ''');
   }
 
@@ -11834,7 +12596,6 @@
   }
 
   test_unresolved_export() async {
-    allowMissingFiles = true;
     var library = await checkLibrary("export 'foo.dart';", allowErrors: true);
     checkElementText(library, r'''
 export 'foo.dart';
@@ -11842,7 +12603,6 @@
   }
 
   test_unresolved_import() async {
-    allowMissingFiles = true;
     var library = await checkLibrary("import 'foo.dart';", allowErrors: true);
     LibraryElement importedLibrary = library.imports[0].importedLibrary;
     expect(importedLibrary.loadLibraryFunction, isNotNull);
@@ -11854,7 +12614,6 @@
   }
 
   test_unresolved_part() async {
-    allowMissingFiles = true;
     var library = await checkLibrary("part 'foo.dart';", allowErrors: true);
     checkElementText(library, r'''
 part 'foo.dart';
@@ -11902,7 +12661,7 @@
   }
 
   test_variable_const_late() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('late const int i = 0;');
     checkElementText(library, r'''
 late const int i = 0;
@@ -11992,6 +12751,21 @@
 ''');
   }
 
+  test_variable_implicit() async {
+    var library = await checkLibrary('int get x => 0;');
+
+    // We intentionally don't check the text, because we want to test
+    // requesting individual elements, not all accessors/variables at once.
+    var getter = _elementOfDefiningUnit(library, '@getter', 'x')
+        as PropertyAccessorElementImpl;
+    var variable = getter.variable as TopLevelVariableElementImpl;
+    expect(variable, isNotNull);
+    expect(variable.isFinal, isTrue);
+    expect(variable.getter, same(getter));
+    expect('${variable.type}', 'int*');
+    expect(variable, same(_elementOfDefiningUnit(library, '@field', 'x')));
+  }
+
   test_variable_implicit_type() async {
     var library = await checkLibrary('var x;');
     checkElementText(library, r'''
@@ -12053,7 +12827,7 @@
   }
 
   test_variable_late() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('late int x = 0;');
     checkElementText(
         library,
@@ -12066,7 +12840,7 @@
   }
 
   test_variable_late_final() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('late final int x;');
     checkElementText(
         library,
@@ -12079,7 +12853,7 @@
   }
 
   test_variable_late_final_initialized() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary('late final int x = 0;');
     checkElementText(
         library,
@@ -12160,7 +12934,7 @@
   }
 
   test_variable_type_inferred_Never() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
     var library = await checkLibrary(r'''
 var a = throw 42;
 ''');
@@ -12184,7 +12958,7 @@
   }
 
   test_variable_type_inferred_nonNullify() async {
-    featureSet = enableNnbd;
+    featureSet = FeatureSets.nullSafe;
 
     addSource('/a.dart', '''
 // @dart = 2.7
@@ -12253,16 +13027,24 @@
     var typeStr = type.getDisplayString(withNullability: false);
     expect(typeStr, expected);
   }
-}
 
-/// Mixin containing helper methods for testing summary resynthesis.  Intended
-/// to be applied to a class implementing [ResynthesizeTestStrategy].
-mixin ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
-  Future<LibraryElementImpl> checkLibrary(String text,
-      {bool allowErrors = false, bool dumpSummaries = false}) async {
-    throw 42;
-//    Source source = addTestSource(text);
-//    SummaryResynthesizer resynthesizer = encodeLibrary(source);
-//    return resynthesizer.getLibraryElement(source.uri.toString());
+  void _assertTypeStrings(List<DartType> types, List<String> expected) {
+    var typeStringList = types.map((e) {
+      return e.getDisplayString(withNullability: true);
+    }).toList();
+    expect(typeStringList, expected);
+  }
+
+  Element _elementOfDefiningUnit(LibraryElementImpl library,
+      [String name1, String name2, String name3]) {
+    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
+    var reference = unit.reference;
+
+    [name1, name2, name3].takeWhile((e) => e != null).forEach((name) {
+      reference = reference.getChild(name);
+    });
+
+    var elementFactory = unit.linkedContext.elementFactory;
+    return elementFactory.elementOfReference(reference);
   }
 }
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 8ec7cc3..a503d24 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -2,22 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.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/summary/summarize_elements.dart';
-
-import 'resynthesize_common.dart';
 
 CompilationUnit parseText(
   String text,
@@ -50,44 +45,3 @@
 
   return unit;
 }
-
-/// Abstract base class for tests of summary resynthesis.
-///
-/// 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 ResynthesizeTestStrategy {
-  /// The set of features enabled in this test.
-  FeatureSet featureSet;
-
-  set allowMissingFiles(bool value);
-
-  set declaredVariables(DeclaredVariables declaredVariables);
-
-  MemoryResourceProvider get resourceProvider;
-
-  set testFile(String value);
-
-  Source get testSource;
-
-  void addLibrary(String uri);
-
-  Source addLibrarySource(String filePath, String contents);
-
-  Source addSource(String path, String contents);
-
-  Source addTestSource(String code, [Uri uri]);
-}
-
-/// Implementation of [ResynthesizeTestStrategy] that drives summary
-/// generation using the old two-phase API.
-class ResynthesizeTestStrategyTwoPhase extends AbstractResynthesizeTest
-    implements ResynthesizeTestStrategy {
-  @override
-  FeatureSet featureSet = FeatureSet.forTesting(sdkVersion: '2.7.0');
-
-  final Set<Source> serializedSources = <Source>{};
-
-  PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
-}
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 e1a5601..b9bf27d 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -2688,7 +2688,7 @@
     String path = convertPath('/test/lib/test.dart');
     newFile(path, content: text);
     UnitElementResult result = await driver.getUnitElement(path);
-    return result.element.library;
+    return result.element.library /*!*/;
   }
 }
 
diff --git a/pkg/analyzer/test/src/summary2/ast_text_printer_integration_test.dart b/pkg/analyzer/test/src/summary2/ast_text_printer_integration_test.dart
index 6d415cf..64623f8 100644
--- a/pkg/analyzer/test/src/summary2/ast_text_printer_integration_test.dart
+++ b/pkg/analyzer/test/src/summary2/ast_text_printer_integration_test.dart
@@ -5,9 +5,9 @@
 import 'dart:io';
 
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
 import 'package:test/test.dart';
 
-import '../../utils/package_root.dart' as package_root;
 import '../dart/ast/parse_base.dart';
 import 'ast_text_printer_test.dart';
 
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 9188c8c..73d9ac2 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -152,9 +152,6 @@
     var errorTypeMap = <Type, List<ErrorCode>>{};
     for (ErrorCode code in errorCodeValues) {
       Type type = code.runtimeType;
-      if (type == HintCodeWithUniqueName) {
-        type = HintCode;
-      }
       errorTypeMap.putIfAbsent(type, () => <ErrorCode>[]).add(code);
     }
 
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index fbe501e..02ae355 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -4,7 +4,6 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'clients/test_all.dart' as clients;
 import 'command_line/test_all.dart' as command_line;
 import 'context/test_all.dart' as context;
 import 'dart/test_all.dart' as dart;
@@ -27,7 +26,6 @@
 
 main() {
   defineReflectiveSuite(() {
-    clients.main();
     command_line.main();
     context.main();
     dart.main();
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index 42c46c4..2a9000a 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -444,6 +444,21 @@
     );
   }
 
+  void test_find_hasBuild_hasPubspec_malformed_dontGoToUp() {
+    newFolder('/workspace/.dart_tool/build/generated');
+    newFile('/workspace/pubspec.yaml', content: 'name: project');
+
+    newFolder('/workspace/aaa/.dart_tool/build/generated');
+    newFile('/workspace/aaa/pubspec.yaml', content: '*');
+
+    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
+      resourceProvider,
+      {},
+      convertPath('/workspace/aaa/lib'),
+    );
+    expect(workspace, isNull);
+  }
+
   void test_find_hasDartToolAndPubspec() {
     newFolder('/workspace/.dart_tool/build/generated/project/lib');
     newFile('/workspace/pubspec.yaml', content: 'name: project');
@@ -471,22 +486,6 @@
     expect(workspace.projectPackageName, 'subproject');
   }
 
-  void
-      test_find_hasDartToolAndPubspec_inParentDirectory_ignoresMalformedPubspec() {
-    newFolder('/workspace/.dart_tool/build/generated/project/lib');
-    newFolder('/workspace/opened/up/a/child/dir/.dart_tool/build');
-    newFile('/workspace/opened/up/a/child/dir/pubspec.yaml',
-        content: 'not: yaml: here!!! 111');
-    newFile('/workspace/pubspec.yaml', content: 'name: project');
-    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
-      resourceProvider,
-      {},
-      convertPath('/workspace/opened/up/a/child/dir'),
-    );
-    expect(workspace.root, convertPath('/workspace'));
-    expect(workspace.projectPackageName, 'project');
-  }
-
   void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloDartTool() {
     newFolder('/workspace/.dart_tool/build/generated/project/lib');
     newFolder('/workspace/opened/up/a/child/dir');
@@ -501,21 +500,6 @@
     expect(workspace.projectPackageName, 'project');
   }
 
-  void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloPubspec() {
-    newFolder('/workspace/.dart_tool/build/generated/project/lib');
-    newFolder('/workspace/opened/up/a/child/dir');
-    newFile('/workspace/opened/up/a/child/dir/pubspec.yaml',
-        content: 'name: subproject');
-    newFile('/workspace/pubspec.yaml', content: 'name: project');
-    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
-      resourceProvider,
-      {},
-      convertPath('/workspace/opened/up/a/child/dir'),
-    );
-    expect(workspace.root, convertPath('/workspace'));
-    expect(workspace.projectPackageName, 'project');
-  }
-
   void test_find_hasDartToolNoBuild() {
     // Edge case: an empty .dart_tool directory. Don't assume package:build.
     newFolder('/workspace/.dart_tool');
@@ -561,6 +545,20 @@
     expect(workspace, isNull);
   }
 
+  void test_find_hasPubspec_noDartTool_dontGoUp() {
+    newFolder('/workspace/.dart_tool/build/generated');
+    newFile('/workspace/pubspec.yaml', content: 'name: project');
+
+    newFile('/workspace/aaa/pubspec.yaml', content: '*');
+
+    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
+      resourceProvider,
+      {},
+      convertPath('/workspace/aaa/lib'),
+    );
+    expect(workspace, isNull);
+  }
+
   void test_find_hasPubspecNoDartTool() {
     newFile('/workspace/pubspec.yaml', content: 'name: project');
     PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
diff --git a/pkg/analyzer/test/utils/package_root.dart b/pkg/analyzer/test/utils/package_root.dart
deleted file mode 100644
index 8055970..0000000
--- a/pkg/analyzer/test/utils/package_root.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:path/path.dart' as pathos;
-
-/// Returns a path to the directory containing source code for packages such as
-/// kernel, front_end, and analyzer.
-String get packageRoot {
-  // If the package root directory is specified on the command line using
-  // -DpkgRoot=..., use it.
-  String pkgRootVar = const bool.hasEnvironment('pkgRoot')
-      ? const String.fromEnvironment('pkgRoot')
-      : null;
-  if (pkgRootVar != null) {
-    String path = pathos.join(Directory.current.path, pkgRootVar);
-    if (!path.endsWith(pathos.separator)) path += pathos.separator;
-    return path;
-  }
-  // Otherwise try to guess based on the script path.
-  String scriptPath = pathos.fromUri(Platform.script);
-  List<String> parts = pathos.split(scriptPath);
-  int pkgIndex = parts.indexOf('pkg');
-  if (pkgIndex != -1) {
-    return pathos.joinAll(parts.sublist(0, pkgIndex + 1)) + pathos.separator;
-  }
-  throw StateError('Unable to find sdk/pkg/ in $scriptPath');
-}
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index de52dc3..af40e72 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -65,6 +65,10 @@
   /// be enabled for a snippet.
   static const String experimentsPrefix = '%experiments=';
 
+  /// The prefix used on directive lines to specify the language version for
+  /// the snippet.
+  static const String languagePrefix = '%language=';
+
   /// The prefix used on directive lines to indicate the uri of an auxiliary
   /// file that is needed for testing purposes.
   static const String uriDirectivePrefix = '%uri="';
@@ -144,19 +148,26 @@
     return docs;
   }
 
-  _SnippetData _extractSnippetData(String snippet, bool errorRequired,
-      Map<String, String> auxiliaryFiles, List<String> experiments) {
+  _SnippetData _extractSnippetData(
+    String snippet,
+    bool errorRequired,
+    Map<String, String> auxiliaryFiles,
+    List<String> experiments,
+    String languageVersion,
+  ) {
     int rangeStart = snippet.indexOf(errorRangeStart);
     if (rangeStart < 0) {
       if (errorRequired) {
         _reportProblem('No error range in example');
       }
-      return _SnippetData(snippet, -1, 0, auxiliaryFiles, experiments);
+      return _SnippetData(
+          snippet, -1, 0, auxiliaryFiles, experiments, languageVersion);
     }
     int rangeEnd = snippet.indexOf(errorRangeEnd, rangeStart + 1);
     if (rangeEnd < 0) {
       _reportProblem('No end of error range in example');
-      return _SnippetData(snippet, -1, 0, auxiliaryFiles, experiments);
+      return _SnippetData(
+          snippet, -1, 0, auxiliaryFiles, experiments, languageVersion);
     } else if (snippet.indexOf(errorRangeStart, rangeEnd) > 0) {
       _reportProblem('More than one error range in example');
     }
@@ -167,7 +178,8 @@
         rangeStart,
         rangeEnd - rangeStart - 2,
         auxiliaryFiles,
-        experiments);
+        experiments,
+        languageVersion);
   }
 
   /// Extract the snippets of Dart code between the start (inclusive) and end
@@ -177,6 +189,7 @@
     var snippets = <_SnippetData>[];
     var auxiliaryFiles = <String, String>{};
     List<String> experiments;
+    String languageVersion;
     var currentStart = -1;
     for (var i = start; i < end; i++) {
       var line = lines[i];
@@ -199,10 +212,13 @@
                 .map((e) => e.trim())
                 .toList();
             currentStart++;
+          } else if (secondLine.startsWith(languagePrefix)) {
+            languageVersion = secondLine.substring(languagePrefix.length);
+            currentStart++;
           }
           var content = lines.sublist(currentStart + 1, i).join('\n');
-          snippets.add(_extractSnippetData(
-              content, errorRequired, auxiliaryFiles, experiments));
+          snippets.add(_extractSnippetData(content, errorRequired,
+              auxiliaryFiles, experiments, languageVersion));
           auxiliaryFiles = <String, String>{};
         }
         currentStart = -1;
@@ -394,9 +410,10 @@
   final int length;
   final Map<String, String> auxiliaryFiles;
   final List<String> experiments;
+  final String languageVersion;
 
   _SnippetData(this.content, this.offset, this.length, this.auxiliaryFiles,
-      this.experiments);
+      this.experiments, this.languageVersion);
 }
 
 /// A test class that creates an environment suitable for analyzing the
@@ -407,7 +424,6 @@
 
   /// Initialize a newly created test to test the given [snippet].
   _SnippetTest(this.snippet) {
-    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
     writeTestPackageAnalysisOptionsFile(
       AnalysisOptionsFileConfig(
         experiments: snippet.experiments,
@@ -417,8 +433,7 @@
 
   @override
   String get testPackageLanguageVersion {
-    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-    return snippet.experiments == null ? '2.9' : null;
+    return snippet.languageVersion;
   }
 
   @override
diff --git a/pkg/analyzer/test/verify_docs_test.dart b/pkg/analyzer/test/verify_docs_test.dart
index 5107cd6..32e6bc1 100644
--- a/pkg/analyzer/test/verify_docs_test.dart
+++ b/pkg/analyzer/test/verify_docs_test.dart
@@ -12,10 +12,9 @@
 import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
 import 'package:test/test.dart';
 
-import 'utils/package_root.dart' as package_root;
-
 main() async {
   SnippetTester tester = SnippetTester();
   await tester.verify();
diff --git a/pkg/analyzer/test/verify_tests_test.dart b/pkg/analyzer/test/verify_tests_test.dart
index a25248d..3db4bb7 100644
--- a/pkg/analyzer/test/verify_tests_test.dart
+++ b/pkg/analyzer/test/verify_tests_test.dart
@@ -2,90 +2,28 @@
 // for details. All 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/analysis_context.dart';
-import 'package:analyzer/dart/analysis/analysis_context_collection.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/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-import 'utils/package_root.dart' as package_root;
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:analyzer_utilities/verify_tests.dart';
 
 main() {
-  PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
-  String packageRoot = provider.pathContext.normalize(package_root.packageRoot);
-  String analyzerPath = provider.pathContext.join(packageRoot, 'analyzer');
-  String testDirPath = provider.pathContext.join(analyzerPath, 'test');
-
-  AnalysisContextCollection collection = AnalysisContextCollection(
-      includedPaths: <String>[testDirPath], resourceProvider: provider);
-  List<AnalysisContext> contexts = collection.contexts;
-  if (contexts.length != 1) {
-    fail('The test directory contains multiple analysis contexts.');
-  }
-
-  buildTestsIn(
-      contexts[0].currentSession, testDirPath, provider.getFolder(testDirPath));
+  var provider = PhysicalResourceProvider.INSTANCE;
+  var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
+  var pathToAnalyze = provider.pathContext.join(packageRoot, 'analyzer');
+  var testDirPath = provider.pathContext.join(pathToAnalyze, 'test');
+  _VerifyTests(testDirPath).build();
 }
 
-void buildTestsIn(
-    AnalysisSession session, String testDirPath, Folder directory) {
-  List<String> testFileNames = [];
-  File testAllFile;
-  List<Resource> children = directory.getChildren();
-  children.sort((first, second) => first.shortName.compareTo(second.shortName));
-  for (Resource child in children) {
-    if (child is Folder) {
-      if (child.getChildAssumingFile('test_all.dart').exists) {
-        testFileNames.add('${child.shortName}/test_all.dart');
-      }
-      buildTestsIn(session, testDirPath, child);
-    } else if (child is File) {
-      String name = child.shortName;
-      if (name == 'test_all.dart') {
-        testAllFile = child;
-      } else if (name.endsWith('_integration_test.dart')) {
-        // ignored
-      } else if (name.endsWith('_test.dart')) {
-        testFileNames.add(name);
-      }
-    }
-  }
-  String relativePath = path.relative(directory.path, from: testDirPath);
-  test(relativePath, () {
-    if (testFileNames.isEmpty) {
-      return;
-    }
-    if (testAllFile == null) {
-      if (relativePath != 'id_tests') {
-        fail('Missing "test_all.dart" in $relativePath');
-      } else {
-        // The tests in the id_tests folder don't have a test_all.dart file
-        // because they don't use the package:test framework.
-        return;
-      }
-    }
-    ParsedUnitResult result = session.getParsedUnit(testAllFile.path);
-    if (result.state != ResultState.VALID) {
-      fail('Could not parse ${testAllFile.path}');
-    }
-    List<String> importedFiles = [];
-    for (var directive in result.unit.directives) {
-      if (directive is ImportDirective) {
-        importedFiles.add(directive.uri.stringValue);
-      }
-    }
-    List<String> missingFiles = [];
-    for (String testFileName in testFileNames) {
-      if (!importedFiles.contains(testFileName)) {
-        missingFiles.add(testFileName);
-      }
-    }
-    if (missingFiles.isNotEmpty) {
-      fail('Tests missing from "test_all.dart": ${missingFiles.join(', ')}');
-    }
-  });
+class _VerifyTests extends VerifyTests {
+  _VerifyTests(String testDirPath, {List<String> excludedPaths})
+      : super(testDirPath, excludedPaths: excludedPaths);
+
+  @override
+  bool isExpensive(Resource resource) =>
+      resource.shortName.endsWith('_integration_test.dart');
+
+  @override
+  bool isOkForTestAllToBeMissing(Folder folder) =>
+      folder.shortName == 'id_tests';
 }
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 5b680ce..eb96917 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -5289,8 +5289,8 @@
 
 ### missing_default_value_for_parameter
 
-_The parameter '{0}' can't have a value of 'null' because of its type, and no
-non-null default value is provided._
+_The parameter '{0}' can't have a value of 'null' because of its type, but the
+implicit default value is 'null'._
 
 #### Description
 
@@ -5645,6 +5645,8 @@
 {% endprettify %}
 
 If the instances of the class should be mutable, then remove the
+annotation, or choose a different superclass if the annotation is
+inherited:
 
 {% prettify dart tag=pre+code %}
 class C {
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 5ed14e0..7571b56 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -10,10 +10,9 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
 import 'package:path/src/context.dart';
 
-import '../../test/utils/package_root.dart' as package_root;
-
 /// Generate the file `diagnostics.md` based on the documentation associated
 /// with the declarations of the error codes.
 void main() async {
diff --git a/pkg/analyzer/tool/experiments/experiments_test.dart b/pkg/analyzer/tool/experiments/experiments_test.dart
index 4f77ee3..575c084 100644
--- a/pkg/analyzer/tool/experiments/experiments_test.dart
+++ b/pkg/analyzer/tool/experiments/experiments_test.dart
@@ -4,7 +4,7 @@
 
 import "dart:io" show Platform;
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate.dart';
diff --git a/pkg/analyzer/tool/experiments/generate.dart b/pkg/analyzer/tool/experiments/generate.dart
index 6ef4373..6e28018 100644
--- a/pkg/analyzer/tool/experiments/generate.dart
+++ b/pkg/analyzer/tool/experiments/generate.dart
@@ -4,12 +4,11 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
     show $MINUS, $_;
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/package_root.dart' as pkg_root;
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
 
-import '../../test/utils/package_root.dart' as pkg_root;
-
 main() async {
   await GeneratedContent.generateAll(
       normalize(join(pkg_root.packageRoot, 'analyzer')), allTargets);
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 31d96ef..fb3bfe7 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -13,14 +13,13 @@
 import 'dart:io';
 
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
-import 'package:analysis_tool/tools.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer_utilities/package_root.dart' as pkg_root;
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 import 'package:yaml/yaml.dart' show loadYaml;
 
-import '../../test/utils/package_root.dart' as pkg_root;
-
 main() async {
   String analyzerPkgPath = normalize(join(pkg_root.packageRoot, 'analyzer'));
   String frontEndPkgPath = normalize(join(pkg_root.packageRoot, 'front_end'));
@@ -188,7 +187,7 @@
   }
 
   void generateFastaAnalyzerErrorCodeList() {
-    final sorted = List<Map>(translatedEntries.length);
+    final sorted = List<Map>.filled(translatedEntries.length, null);
     for (var entry in translatedEntries) {
       var index = entry['index'];
       if (index is int && index >= 1 && index <= sorted.length) {
diff --git a/pkg/analyzer/tool/summary/check_test.dart b/pkg/analyzer/tool/summary/check_test.dart
index e93bb33..a5d0473 100644
--- a/pkg/analyzer/tool/summary/check_test.dart
+++ b/pkg/analyzer/tool/summary/check_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 
-import '../../test/utils/package_root.dart' as package_root;
 import 'generate.dart';
 
 /// Check that the target file has been code generated.  If it hasn't tell the
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 945b34c..3bba6a2 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -20,7 +20,7 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'idl_model.dart' as idl_model;
 import 'mini_ast.dart';
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index c8d5635..1993ae8 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -478,7 +478,7 @@
       int count, Token leftBracket, Token constKeyword, Token rightBracket) {
     debugEvent("LiteralList");
 
-    var elements = List<Object>(count);
+    var elements = List<Object>.filled(count, null);
     popList(count, elements);
     pop(); // type arguments
 
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 3098758..ec2ad2b 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io' as io;
 import 'dart:isolate';
+import 'dart:typed_data';
 
 import 'package:analyzer/dart/analysis/context_locator.dart' as api;
 import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -20,19 +21,17 @@
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 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/source/source_resource.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.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;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart' as summary2;
-import 'package:analyzer/src/summary2/linked_element_factory.dart' as summary2;
-import 'package:analyzer/src/summary2/reference.dart' as summary2;
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
+import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer_cli/src/context_cache.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/error_formatter.dart';
@@ -170,15 +169,12 @@
   AnalysisOptionsImpl analysisOptions;
   Map<Uri, File> uriToFileMap;
   final List<Source> explicitSources = <Source>[];
-  final List<PackageBundle> unlinkedBundles = <PackageBundle>[];
 
   SourceFactory sourceFactory;
   DeclaredVariables declaredVariables;
   AnalysisDriver analysisDriver;
 
-  PackageBundleAssembler assembler;
-
-  summary2.LinkedElementFactory elementFactory;
+  LinkedElementFactory elementFactory;
 
   // May be null.
   final DependencyTracker dependencyTracker;
@@ -244,24 +240,20 @@
       }
 
       // Write summary.
-      assembler = PackageBundleAssembler();
       if (_shouldOutputSummary) {
         await logger.runAsync('Build and write output summary', () async {
           // Build and assemble linked libraries.
-          _computeLinkedLibraries2();
+          var bytes = _computeLinkedLibraries2();
 
           // Write the whole package bundle.
-          var bundle = assembler.assemble();
+          // TODO(scheglov) Remove support for `buildSummaryOutput`.
           if (options.buildSummaryOutput != null) {
             var file = io.File(options.buildSummaryOutput);
-            file.writeAsBytesSync(bundle.toBuffer(),
-                mode: io.FileMode.writeOnly);
+            file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
           }
           if (options.buildSummaryOutputSemantic != null) {
-            bundle.flushInformative();
             var file = io.File(options.buildSummaryOutputSemantic);
-            file.writeAsBytesSync(bundle.toBuffer(),
-                mode: io.FileMode.writeOnly);
+            file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
           }
         });
       } else {
@@ -290,10 +282,10 @@
   }
 
   /// Use [elementFactory] filled with input summaries, and link libraries
-  /// in [explicitSources] to produce linked libraries in [assembler].
-  void _computeLinkedLibraries2() {
-    logger.run('Link output summary2', () {
-      var inputLibraries = <summary2.LinkInputLibrary>[];
+  /// in [explicitSources] to produce linked summary bytes.
+  Uint8List _computeLinkedLibraries2() {
+    return logger.run('Link output summary2', () {
+      var inputLibraries = <LinkInputLibrary>[];
 
       for (var librarySource in explicitSources) {
         var path = librarySource.fullName;
@@ -309,9 +301,9 @@
           continue;
         }
 
-        var inputUnits = <summary2.LinkInputUnit>[];
+        var inputUnits = <LinkInputUnit>[];
         inputUnits.add(
-          summary2.LinkInputUnit(null, librarySource, false, unit),
+          LinkInputUnit(null, librarySource, false, unit),
         );
 
         for (var directive in unit.directives) {
@@ -323,7 +315,7 @@
             if (partSource == null) {
               var unit = analysisDriver.fsState.unresolvedFile.parse();
               inputUnits.add(
-                summary2.LinkInputUnit(partUri, null, true, unit),
+                LinkInputUnit(partUri, null, true, unit),
               );
               continue;
             }
@@ -334,7 +326,7 @@
               throw ArgumentError('No parsed unit for part $partPath in $path');
             }
             inputUnits.add(
-              summary2.LinkInputUnit(
+              LinkInputUnit(
                 partUri,
                 partSource,
                 false,
@@ -345,12 +337,23 @@
         }
 
         inputLibraries.add(
-          summary2.LinkInputLibrary(librarySource, inputUnits),
+          LinkInputLibrary(librarySource, inputUnits),
         );
       }
 
-      var linkResult = summary2.link(elementFactory, inputLibraries);
-      assembler.setBundle2(linkResult.bundle);
+      var linkResult = link(elementFactory, inputLibraries, false);
+
+      var bundleBuilder = PackageBundleBuilder();
+      for (var library in inputLibraries) {
+        bundleBuilder.addLibrary(
+          library.uriStr,
+          library.units.map((e) => e.uriStr).toList(),
+        );
+      }
+      return bundleBuilder.finish(
+        astBytes: linkResult.astBytes,
+        resolutionBytes: linkResult.resolutionBytes,
+      );
     });
   }
 
@@ -376,7 +379,7 @@
     summaryDataStore = SummaryDataStore(<String>[]);
 
     // Adds a bundle at `path` to `summaryDataStore`.
-    PackageBundle addBundle(String path) {
+    PackageBundleReader addBundle(String path) {
       var bundle = packageBundleProvider.get(path);
       summaryDataStore.addBundle(path, bundle);
       return bundle;
@@ -441,15 +444,19 @@
       sourceFactory,
     );
 
-    elementFactory = summary2.LinkedElementFactory(
+    elementFactory = LinkedElementFactory(
       analysisContext,
       AnalysisSessionImpl(null),
-      summary2.Reference.root(),
+      Reference.root(),
     );
 
     for (var bundle in summaryDataStore.bundles) {
       elementFactory.addBundle(
-        summary2.LinkedBundleContext(elementFactory, bundle.bundle2),
+        BundleReader(
+          elementFactory: elementFactory,
+          astBytes: bundle.astBytes,
+          resolutionBytes: bundle.resolutionBytes,
+        ),
       );
     }
   }
@@ -567,9 +574,9 @@
   DirectPackageBundleProvider(this.resourceProvider);
 
   @override
-  PackageBundle get(String path) {
+  PackageBundleReader get(String path) {
     var bytes = io.File(path).readAsBytesSync();
-    return PackageBundle.fromBuffer(bytes);
+    return PackageBundleReader(bytes);
   }
 }
 
@@ -610,10 +617,10 @@
   }
 }
 
-/// Provider for [PackageBundle]s by file paths.
+/// Provider for [PackageBundleReader]s by file paths.
 abstract class PackageBundleProvider {
-  /// Return the [PackageBundle] for the file with the given [path].
-  PackageBundle get(String path);
+  /// Return the [PackageBundleReader] for the file with the given [path].
+  PackageBundleReader get(String path);
 }
 
 /// Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
@@ -667,7 +674,7 @@
 /// Value object for [WorkerPackageBundleCache].
 class WorkerPackageBundle {
   final List<int> bytes;
-  final PackageBundle bundle;
+  final PackageBundleReader bundle;
 
   WorkerPackageBundle(this.bytes, this.bundle);
 
@@ -675,7 +682,7 @@
   int get size => bytes.length * 3;
 }
 
-/// Cache of [PackageBundle]s.
+/// Cache of [PackageBundleReader]s.
 class WorkerPackageBundleCache {
   final ResourceProvider resourceProvider;
   final PerformanceLog logger;
@@ -685,23 +692,25 @@
       : _cache = Cache<WorkerInput, WorkerPackageBundle>(
             maxSizeBytes, (value) => value.size);
 
-  /// Get the [PackageBundle] from the file with the given [path] in the context
+  /// Get the [PackageBundleReader] from the file with the given [path] in the context
   /// of the given worker [inputs].
-  PackageBundle get(Map<String, WorkerInput> inputs, String path) {
+  PackageBundleReader get(Map<String, WorkerInput> inputs, String path) {
     var input = inputs[path];
 
     // The input must be not null, otherwise we're not expected to read
     // this file, but we check anyway to be safe.
     if (input == null) {
       logger.writeln('Read $path outside of the inputs.');
-      var bytes = resourceProvider.getFile(path).readAsBytesSync();
-      return PackageBundle.fromBuffer(bytes);
+      var file = resourceProvider.getFile(path);
+      var bytes = file.readAsBytesSync() as Uint8List;
+      return PackageBundleReader(bytes);
     }
 
     return _cache.get(input, () {
       logger.writeln('Read $input.');
-      var bytes = resourceProvider.getFile(path).readAsBytesSync();
-      var bundle = PackageBundle.fromBuffer(bytes);
+      var file = resourceProvider.getFile(path);
+      var bytes = file.readAsBytesSync() as Uint8List;
+      var bundle = PackageBundleReader(bytes);
       return WorkerPackageBundle(bytes, bundle);
     }).bundle;
   }
@@ -716,7 +725,7 @@
   WorkerPackageBundleProvider(this.cache, this.inputs);
 
   @override
-  PackageBundle get(String path) {
+  PackageBundleReader get(String path) {
     return cache.get(inputs, path);
   }
 }
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 4a8c027..da7989b 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -8,23 +8,21 @@
   sdk: "^2.7.0"
 
 dependencies:
-  analyzer: any
+  analyzer:
+    path: ../analyzer
   args: '>=0.13.0 <2.0.0'
   bazel_worker: ^0.1.0
   collection: ^1.14.1
   convert: any
   linter: ^0.1.16
-  meta: any
+  meta:
+    path: ../meta
   path: any
   pub_semver: ^1.4.2
-  yaml: ^2.1.2
+  yaml: any
 
 dev_dependencies:
   pedantic: ^1.9.0
   protobuf: ^0.13.0
   test_reflective_loader: ^0.1.8
   test: ^1.0.0
-
-dependency_overrides:
-  analyzer:
-    path: ../analyzer
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 33f0529..0ec7a94 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -10,7 +10,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/driver.dart';
@@ -248,39 +248,25 @@
   Future<void> test_import2_usedAsSupertype() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
-      var b = await _buildPackage('b', [a], '''
+      var b = await _buildPackage('b', [], 'class B {}');
+      var c = await _buildPackage('c', [a], '''
 import 'package:a/a.dart';
-class B extends A {}
+import 'package:b/b.dart';
+class C1 extends A {}
+class C2 extends B {}
 ''');
 
-      // We don't invoke anything on class `B`, so don't ask its supertype.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-B x;
-''', [b]);
-
-      // We infer the type of `x` to `B`.
-      // But we don't ask `B` for its supertype.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-var x = B();
-''', [b]);
-
-      // We perform full analysis, and check that `new B()` is assignable
-      // to `B x`. This is trivially true, we don't need the supertype of `B`.
-      // So, no dependency on "a".
-      await _assertDependencies(
-        'c',
-        [a, b],
-        '''
-import 'package:b/b.dart';
-var x = B();
-''',
-        [b],
-        summaryOnly: false,
-      );
+      // When we instantiate `C1`, we ask `C1` for its type parameters.
+      // So, we apply resolution to the whole `C1` header (not members).
+      // So, we request `A` that is the superclass of `C1`.
+      // So, dependency on "a".
+      //
+      // But we don't access `C2`, so don't use its supertype `B`.
+      // So, no dependency on "b".
+      await _assertDependencies('d', [a, b, c], '''
+import 'package:c/c.dart';
+C1 x;
+''', [a, c]);
     });
   }
 
@@ -442,13 +428,12 @@
       ]);
       var output = File(outputPath);
       expect(output.existsSync(), isTrue);
-      var bundle = PackageBundle.fromBuffer(await output.readAsBytes());
+      var bundle = PackageBundleReader(await output.readAsBytes());
       var testFileUri = 'file:///test_file.dart';
 
-      var bundle2 = bundle.bundle2;
-      expect(_linkedLibraryUriList(bundle2), [testFileUri]);
+      expect(_linkedLibraryUriList(bundle), [testFileUri]);
       expect(
-        _linkedLibraryUnitUriList(bundle2, testFileUri),
+        _linkedLibraryUnitUriList(bundle, testFileUri),
         [testFileUri],
       );
 
@@ -472,10 +457,9 @@
           fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
       expect(exitCode, ErrorSeverity.ERROR.ordinal);
       var bytes = File(aSum).readAsBytesSync();
-      var bundle = PackageBundle.fromBuffer(bytes);
-      var bundle2 = bundle.bundle2;
-      expect(_linkedLibraryUriList(bundle2), [aUri]);
-      expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
+      var bundle = PackageBundleReader(bytes);
+      expect(_linkedLibraryUriList(bundle), [aUri]);
+      expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri, '']);
     });
   }
 
@@ -522,10 +506,9 @@
             fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
         expect(exitCode, 0);
         var bytes = File(aSum).readAsBytesSync();
-        var bundle = PackageBundle.fromBuffer(bytes);
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [aUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri]);
+        var bundle = PackageBundleReader(bytes);
+        expect(_linkedLibraryUriList(bundle), [aUri]);
+        expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri]);
       }
 
       // Analyze package:bbb/b.dart and compute summary.
@@ -536,10 +519,9 @@
         ]);
         expect(exitCode, 0);
         var bytes = File(bSum).readAsBytesSync();
-        var bundle = PackageBundle.fromBuffer(bytes);
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [bUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, bUri), [bUri]);
+        var bundle = PackageBundleReader(bytes);
+        expect(_linkedLibraryUriList(bundle), [bUri]);
+        expect(_linkedLibraryUnitUriList(bundle, bUri), [bUri]);
       }
 
       // Analyze package:ccc/c.dart and compute summary.
@@ -550,10 +532,9 @@
         ]);
         expect(exitCode, 0);
         var bytes = File(cSum).readAsBytesSync();
-        var bundle = PackageBundle.fromBuffer(bytes);
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [cUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, cUri), [cUri]);
+        var bundle = PackageBundleReader(bytes);
+        expect(_linkedLibraryUriList(bundle), [cUri]);
+        expect(_linkedLibraryUnitUriList(bundle, cUri), [cUri]);
       }
     });
   }
@@ -715,16 +696,16 @@
   }
 
   Iterable<String> _linkedLibraryUnitUriList(
-    LinkedNodeBundle bundle2,
+    PackageBundleReader bundle,
     String libraryUriStr,
   ) {
-    var libraries = bundle2.libraries;
+    var libraries = bundle.libraries;
     var library = libraries.singleWhere((l) => l.uriStr == libraryUriStr);
     return library.units.map((u) => u.uriStr).toList();
   }
 
-  Iterable<String> _linkedLibraryUriList(LinkedNodeBundle bundle2) {
-    var libraries = bundle2.libraries;
+  Iterable<String> _linkedLibraryUriList(PackageBundleReader bundle) {
+    var libraries = bundle.libraries;
     return libraries.map((l) => l.uriStr).toList();
   }
 }
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index 8f0d5e3..2b49d2b 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -1,10 +1,10 @@
-## 0.3.1-dev
+## 0.4.0
 - Deprecated the class `DartChangeBuilder` and enhanced `ChangeBuilder` to be
   the replacement for it.
 - Deprecated the method `ChangeBuilder.addFileEdit` and introduced
   `ChangeBuilder.addDartFileEdit` and `ChangeBuilder.addGenericFileEdit` to be
   the replacements for it.
-- Bump maximum supported version of the analyzer to `<0.41.0`.
+- Changed the support version range of the analyzer to `>=0.41.0 <0.42.0`.
 
 ## 0.3.0
 - Removed deprecated `Plugin.getResolveResult`. Use `getResolvedUnitResult`.
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 76ba245..6aaac51 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1174,7 +1174,10 @@
         <p>
           An overriding implementation of a class member is being suggested.
         </p>
-      </dd><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextRoot">ContextRoot: object</a></dt><dd>
+      </dd><dt class="value">PARAMETER</dt><dt class="value">PACKAGE_NAME</dt><dd>
+        
+        <p>The name of a pub package is being suggested.</p>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_ContextRoot">ContextRoot: object</a></dt><dd>
     <p>
       A description of an analysis context.
     </p>
@@ -1354,152 +1357,47 @@
     
   <dl><dt class="value">ANNOTATION</dt><dt class="value">BUILT_IN</dt><dt class="value">CLASS</dt><dt class="value">COMMENT_BLOCK</dt><dt class="value">COMMENT_DOCUMENTATION</dt><dt class="value">COMMENT_END_OF_LINE</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">DIRECTIVE</dt><dt class="value">DYNAMIC_TYPE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FIELD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INVALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">METHOD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">PARAMETER</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">SETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_FIELD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">VALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
     <p>
       This object matches the format and documentation of the Entry object
       documented in the
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 6e2aeae..56bcadd 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -1217,6 +1217,7 @@
 ///   OPTIONAL_ARGUMENT
 ///   OVERRIDE
 ///   PARAMETER
+///   PACKAGE_NAME
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -1266,6 +1267,10 @@
   static const CompletionSuggestionKind PARAMETER =
       CompletionSuggestionKind._('PARAMETER');
 
+  /// The name of a pub package is being suggested.
+  static const CompletionSuggestionKind PACKAGE_NAME =
+      CompletionSuggestionKind._('PACKAGE_NAME');
+
   /// A list containing all of the enum values that are defined.
   static const List<CompletionSuggestionKind> VALUES =
       <CompletionSuggestionKind>[
@@ -1277,7 +1282,8 @@
     NAMED_ARGUMENT,
     OPTIONAL_ARGUMENT,
     OVERRIDE,
-    PARAMETER
+    PARAMETER,
+    PACKAGE_NAME
   ];
 
   @override
@@ -1305,6 +1311,8 @@
         return OVERRIDE;
       case 'PARAMETER':
         return PARAMETER;
+      case 'PACKAGE_NAME':
+        return PACKAGE_NAME;
     }
     throw Exception('Illegal enum value: $name');
   }
@@ -2307,23 +2315,19 @@
   static const HighlightRegionType DIRECTIVE =
       HighlightRegionType._('DIRECTIVE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType DYNAMIC_TYPE =
       HighlightRegionType._('DYNAMIC_TYPE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_DECLARATION =
       HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_REFERENCE =
       HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_PARAMETER_DECLARATION =
       HighlightRegionType._('DYNAMIC_PARAMETER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_PARAMETER_REFERENCE =
       HighlightRegionType._('DYNAMIC_PARAMETER_REFERENCE');
 
@@ -2332,24 +2336,24 @@
   static const HighlightRegionType ENUM_CONSTANT =
       HighlightRegionType._('ENUM_CONSTANT');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FIELD = HighlightRegionType._('FIELD');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FIELD_STATIC =
       HighlightRegionType._('FIELD_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FUNCTION = HighlightRegionType._('FUNCTION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FUNCTION_DECLARATION =
       HighlightRegionType._('FUNCTION_DECLARATION');
 
   static const HighlightRegionType FUNCTION_TYPE_ALIAS =
       HighlightRegionType._('FUNCTION_TYPE_ALIAS');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType GETTER_DECLARATION =
       HighlightRegionType._('GETTER_DECLARATION');
 
@@ -2359,39 +2363,30 @@
   static const HighlightRegionType IMPORT_PREFIX =
       HighlightRegionType._('IMPORT_PREFIX');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_FIELD_DECLARATION =
       HighlightRegionType._('INSTANCE_FIELD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_FIELD_REFERENCE =
       HighlightRegionType._('INSTANCE_FIELD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_GETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_GETTER_REFERENCE =
       HighlightRegionType._('INSTANCE_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_METHOD_DECLARATION =
       HighlightRegionType._('INSTANCE_METHOD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_METHOD_REFERENCE =
       HighlightRegionType._('INSTANCE_METHOD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_SETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_SETTER_REFERENCE =
       HighlightRegionType._('INSTANCE_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INVALID_STRING_ESCAPE =
       HighlightRegionType._('INVALID_STRING_ESCAPE');
 
@@ -2399,7 +2394,6 @@
 
   static const HighlightRegionType LABEL = HighlightRegionType._('LABEL');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LIBRARY_NAME =
       HighlightRegionType._('LIBRARY_NAME');
 
@@ -2421,113 +2415,94 @@
   static const HighlightRegionType LITERAL_STRING =
       HighlightRegionType._('LITERAL_STRING');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_FUNCTION_DECLARATION =
       HighlightRegionType._('LOCAL_FUNCTION_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_FUNCTION_REFERENCE =
       HighlightRegionType._('LOCAL_FUNCTION_REFERENCE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType LOCAL_VARIABLE =
       HighlightRegionType._('LOCAL_VARIABLE');
 
   static const HighlightRegionType LOCAL_VARIABLE_DECLARATION =
       HighlightRegionType._('LOCAL_VARIABLE_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_VARIABLE_REFERENCE =
       HighlightRegionType._('LOCAL_VARIABLE_REFERENCE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD = HighlightRegionType._('METHOD');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_DECLARATION =
       HighlightRegionType._('METHOD_DECLARATION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_DECLARATION_STATIC =
       HighlightRegionType._('METHOD_DECLARATION_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_STATIC =
       HighlightRegionType._('METHOD_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType PARAMETER =
       HighlightRegionType._('PARAMETER');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType SETTER_DECLARATION =
       HighlightRegionType._('SETTER_DECLARATION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType TOP_LEVEL_VARIABLE =
       HighlightRegionType._('TOP_LEVEL_VARIABLE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType PARAMETER_DECLARATION =
       HighlightRegionType._('PARAMETER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType PARAMETER_REFERENCE =
       HighlightRegionType._('PARAMETER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_FIELD_DECLARATION =
       HighlightRegionType._('STATIC_FIELD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_GETTER_DECLARATION =
       HighlightRegionType._('STATIC_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_GETTER_REFERENCE =
       HighlightRegionType._('STATIC_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_METHOD_DECLARATION =
       HighlightRegionType._('STATIC_METHOD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_METHOD_REFERENCE =
       HighlightRegionType._('STATIC_METHOD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_SETTER_DECLARATION =
       HighlightRegionType._('STATIC_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_SETTER_REFERENCE =
       HighlightRegionType._('STATIC_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_FUNCTION_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_FUNCTION_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_GETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_GETTER_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_SETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_SETTER_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_VARIABLE_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_VARIABLE_DECLARATION');
 
@@ -2537,11 +2512,9 @@
   static const HighlightRegionType TYPE_PARAMETER =
       HighlightRegionType._('TYPE_PARAMETER');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType UNRESOLVED_INSTANCE_MEMBER_REFERENCE =
       HighlightRegionType._('UNRESOLVED_INSTANCE_MEMBER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType VALID_STRING_ESCAPE =
       HighlightRegionType._('VALID_STRING_ESCAPE');
 
diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
index a1d5445..5615b1b 100644
--- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer_plugin/protocol/protocol.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart';
+import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
 
 final Map<String, RefactoringKind> REQUEST_ID_REFACTORING_KINDS =
     HashMap<String, RefactoringKind>();
@@ -18,13 +19,46 @@
   edits.forEach(sourceFileEdit.add);
 }
 
-/// Adds the given [sourceEdit] to the list in [sourceFileEdit].
+/// Adds the given [sourceEdit] to the list in [sourceFileEdit] while preserving
+/// two invariants:
+/// - the list is sorted such that edits with a larger offset appear earlier in
+///   the list, and
+/// - no two edits in the list overlap each other.
+///
+/// If the invariants can't be preserved, then a [ConflictingEditException] is
+/// thrown.
 void addEditForSource(SourceFileEdit sourceFileEdit, SourceEdit sourceEdit) {
   var edits = sourceFileEdit.edits;
+  var length = edits.length;
   var index = 0;
-  while (index < edits.length && edits[index].offset > sourceEdit.offset) {
+  while (index < length && edits[index].offset > sourceEdit.offset) {
     index++;
   }
+  if (index > 0) {
+    var previousEdit = edits[index - 1];
+    // The [previousEdit] has an offset that is strictly greater than the offset
+    // of the [sourceEdit] so we only need to look at the end of the
+    // [sourceEdit] to know whether they overlap.
+    if (sourceEdit.offset + sourceEdit.length > previousEdit.offset) {
+      throw ConflictingEditException(
+          newEdit: sourceEdit, existingEdit: previousEdit);
+    }
+  }
+  if (index < length) {
+    var nextEdit = edits[index];
+    // The [nextEdit] has an offset that is less than or equal to the offset of
+    // the [sourceEdit]. If they're equal, then we consider it to be a conflict.
+    // Otherwise the offset of [nextEdit] is strictly less than the offset of
+    // the [sourceEdit] so we need to look at the end of the [nextEdit] to know
+    // whether they overlap.
+    if ((sourceEdit.offset == nextEdit.offset &&
+            sourceEdit.length > 0 &&
+            nextEdit.length > 0) ||
+        nextEdit.offset + nextEdit.length > sourceEdit.offset) {
+      throw ConflictingEditException(
+          newEdit: sourceEdit, existingEdit: nextEdit);
+    }
+  }
   edits.insert(index, sourceEdit);
 }
 
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
index ed00442..58d3a20 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
@@ -128,6 +128,43 @@
     }
   }
 
+  @override
+  ChangeBuilder copy() {
+    var copy = ChangeBuilderImpl(workspace: workspace, eol: eol);
+    for (var entry in _linkedEditGroups.entries) {
+      copy._linkedEditGroups[entry.key] = _copyLinkedEditGroup(entry.value);
+    }
+    copy._selection = _copyPosition(_selection);
+    copy._selectionRange = _selectionRange;
+    copy._lockedPositions.addAll(_lockedPositions);
+    for (var entry in _genericFileEditBuilders.entries) {
+      copy._genericFileEditBuilders[entry.key] = entry.value.copyWith(copy);
+    }
+    //
+    // The file edit builders for libraries (those whose [libraryChangeBuilder]
+    // is `null`) are copied first so that the copies exist when we copy the
+    // builders for parts and the structure can be preserved.
+    //
+    var editBuilderMap = <DartFileEditBuilderImpl, DartFileEditBuilderImpl>{};
+    for (var entry in _dartFileEditBuilders.entries) {
+      var oldBuilder = entry.value;
+      if (oldBuilder.libraryChangeBuilder == null) {
+        var newBuilder = oldBuilder.copyWith(copy);
+        copy._dartFileEditBuilders[entry.key] = newBuilder;
+        editBuilderMap[oldBuilder] = newBuilder;
+      }
+    }
+    for (var entry in _dartFileEditBuilders.entries) {
+      var oldBuilder = entry.value;
+      if (oldBuilder.libraryChangeBuilder != null) {
+        var newBuilder =
+            oldBuilder.copyWith(copy, editBuilderMap: editBuilderMap);
+        copy._dartFileEditBuilders[entry.key] = newBuilder;
+      }
+    }
+    return copy;
+  }
+
   /// Create and return a [DartFileEditBuilder] that can be used to build edits
   /// to the Dart file with the given [path].
   Future<DartFileEditBuilderImpl> createDartFileEditBuilder(String path) async {
@@ -188,6 +225,17 @@
     _selection = position;
   }
 
+  /// Return a copy of the linked edit [group].
+  LinkedEditGroup _copyLinkedEditGroup(LinkedEditGroup group) {
+    return LinkedEditGroup(group.positions.map(_copyPosition).toList(),
+        group.length, group.suggestions.toList());
+  }
+
+  /// Return a copy of the [position].
+  Position _copyPosition(Position position) {
+    return position == null ? null : Position(position.file, position.offset);
+  }
+
   void _setSelectionRange(SourceRange range) {
     _selectionRange = range;
   }
@@ -393,6 +441,13 @@
     }
   }
 
+  FileEditBuilderImpl copyWith(ChangeBuilderImpl changeBuilder) {
+    var copy =
+        FileEditBuilderImpl(changeBuilder, fileEdit.file, fileEdit.fileStamp);
+    copy.fileEdit.edits.addAll(fileEdit.edits);
+    return copy;
+  }
+
   EditBuilderImpl createEditBuilder(int offset, int length) {
     return EditBuilderImpl(this, offset, length);
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 4c68006..993cf7e 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1312,6 +1312,23 @@
   }
 
   @override
+  DartFileEditBuilderImpl copyWith(ChangeBuilderImpl changeBuilder,
+      {Map<DartFileEditBuilderImpl, DartFileEditBuilderImpl> editBuilderMap =
+          const {}}) {
+    var copy = DartFileEditBuilderImpl(changeBuilder, resolvedUnit,
+        fileEdit.fileStamp, editBuilderMap[libraryChangeBuilder]);
+    copy.fileEdit.edits.addAll(fileEdit.edits);
+    copy.importPrefixGenerator = importPrefixGenerator;
+    for (var entry in librariesToImport.entries) {
+      copy.librariesToImport[entry.key] = entry.value;
+    }
+    for (var entry in librariesToRelativelyImport.entries) {
+      copy.librariesToRelativelyImport[entry.key] = entry.value;
+    }
+    return copy;
+  }
+
+  @override
   DartEditBuilderImpl createEditBuilder(int offset, int length) {
     return DartEditBuilderImpl(this, offset, length);
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 43c56a1..e122c98 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
-import 'package:analyzer_plugin/utilities/completion/relevance.dart';
 
 typedef SuggestionsFilter = int Function(DartType dartType, int relevance);
 
@@ -45,13 +44,6 @@
   /// have a non-[void] return type should be suggested.
   bool includeReturnValueSuggestions = false;
 
-  /// If [includeReturnValueSuggestions] is set to true, then this function may
-  /// be set to a non-default function to filter out potential suggestions
-  /// (null) based on their static [DartType], or change the relative relevance
-  /// by returning a higher or lower relevance.
-  SuggestionsFilter returnValueSuggestionsFilter =
-      (DartType _, int relevance) => relevance;
-
   /// Indicates whether named arguments should be suggested.
   bool includeNamedArgumentSuggestions = false;
 
@@ -190,17 +182,6 @@
       _requiredType = null;
       return;
     }
-
-    returnValueSuggestionsFilter = (DartType dartType, int relevance) {
-      if (dartType != null) {
-        if (dartType == _requiredType) {
-          return relevance + DART_RELEVANCE_BOOST_TYPE;
-        } else if (_isSubtypeOf(dartType, _requiredType)) {
-          return relevance + DART_RELEVANCE_BOOST_SUBTYPE;
-        }
-      }
-      return relevance;
-    };
   }
 
   /// Return `true` if the [leftType] is a subtype of the [rightType].
@@ -902,9 +883,7 @@
     if (identical(entity, node.expression)) {
       optype.completionLocation = 'InterpolationExpression_expression';
       optype.includeReturnValueSuggestions = true;
-      // Only include type names in a ${ } expression
-      optype.includeTypeNameSuggestions =
-          node.leftBracket != null && node.leftBracket.length > 1;
+      optype.includeTypeNameSuggestions = true;
     }
   }
 
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index a7ea7ee..c561be1 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -109,6 +109,23 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    var forLoopParts = node.forLoopParts;
+    if (forLoopParts is ForEachPartsWithDeclaration) {
+      var loopVariable = forLoopParts.loopVariable;
+      declaredLocalVar(loopVariable.identifier, loopVariable.type);
+    } else if (forLoopParts is ForPartsWithDeclarations) {
+      var varList = forLoopParts.variables;
+      if (varList != null) {
+        varList.variables.forEach((VariableDeclaration varDecl) {
+          declaredLocalVar(varDecl.name, varList.type);
+        });
+      }
+    }
+    visitNode(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     var forLoopParts = node.forLoopParts;
     if (forLoopParts is ForEachPartsWithDeclaration) {
@@ -133,11 +150,18 @@
 
   @override
   void visitFunctionExpression(FunctionExpression node) {
+    _visitTypeParameters(node, node.typeParameters);
     _visitParamList(node.parameters);
     visitNode(node);
   }
 
   @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    _visitTypeParameters(node, node.typeParameters);
+    visitNode(node);
+  }
+
+  @override
   void visitInterpolationExpression(InterpolationExpression node) {
     visitNode(node);
   }
@@ -152,6 +176,7 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
+    _visitTypeParameters(node, node.typeParameters);
     _visitParamList(node.parameters);
     visitNode(node);
   }
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index f7347d2..a46f3bd 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/element/element.dart' as analyzer;
-import 'package:analyzer/dart/element/type.dart' as analyzer;
 import 'package:analyzer/diagnostic/diagnostic.dart' as analyzer;
 import 'package:analyzer/error/error.dart' as analyzer;
 import 'package:analyzer/exception/exception.dart' as analyzer;
@@ -11,10 +10,7 @@
 import 'package:analyzer/source/line_info.dart' as analyzer;
 import 'package:analyzer/src/generated/engine.dart' as analyzer;
 import 'package:analyzer/src/generated/source.dart' as analyzer;
-import 'package:analyzer/src/generated/utilities_dart.dart' as analyzer;
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 
 /// An object used to convert between objects defined by the 'analyzer' package
 /// and those defined by the plugin protocol.
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart
index 0d310b5..d4e9f29 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart
@@ -56,6 +56,10 @@
   Future<void> addGenericFileEdit(
       String path, void Function(FileEditBuilder builder) buildFileEdit);
 
+  /// Return a copy of this change builder that is constructed in such as was
+  /// that changes to the copy will not effect this change builder.
+  ChangeBuilder copy();
+
   /// Set the selection for the change being built to the given [position].
   void setSelection(Position position);
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/conflicting_edit_exception.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/conflicting_edit_exception.dart
new file mode 100644
index 0000000..db5a55f
--- /dev/null
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/conflicting_edit_exception.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:meta/meta.dart';
+
+/// An exception that is thrown when a change builder is asked to include an
+/// edit that conflicts with a previous edit.
+class ConflictingEditException implements Exception {
+  /// The new edit that was being added.
+  final SourceEdit newEdit;
+
+  /// The existing edit with which it conflicts.
+  final SourceEdit existingEdit;
+
+  /// Initialize a newly created exception indicating that the [newEdit].
+  ConflictingEditException(
+      {@required this.newEdit, @required this.existingEdit});
+
+  @override
+  String toString() =>
+      'ConflictingEditException: $newEdit conflicts with $existingEdit';
+}
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
index 3d9bbd2..33fc86ea 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
@@ -6,35 +6,9 @@
 // Constant values used for relevance values when creating completion
 // suggestions in Dart code.
 //
-
-/// The relevance boost for available declarations with the matching tag.
-const int DART_RELEVANCE_BOOST_AVAILABLE_DECLARATION = 10;
-
-/// The relevance boost for available enum constants with the matching tag.
-///
-/// It is so large to move enum constants to the very top.
-const int DART_RELEVANCE_BOOST_AVAILABLE_ENUM = 1100;
-
-const int DART_RELEVANCE_BOOST_SUBTYPE = 100;
-const int DART_RELEVANCE_BOOST_TYPE = 200;
-const int DART_RELEVANCE_COMMON_USAGE = 1200;
 const int DART_RELEVANCE_DEFAULT = 1000;
 const int DART_RELEVANCE_HIGH = 2000;
-const int DART_RELEVANCE_INHERITED_ACCESSOR = 1057;
-const int DART_RELEVANCE_INHERITED_FIELD = 1058;
-const int DART_RELEVANCE_INHERITED_METHOD = 1057;
-const int DART_RELEVANCE_KEYWORD = 1055;
-const int DART_RELEVANCE_LOCAL_ACCESSOR = 1057;
-const int DART_RELEVANCE_LOCAL_FIELD = 1058;
-const int DART_RELEVANCE_LOCAL_FUNCTION = 1056;
-const int DART_RELEVANCE_LOCAL_METHOD = 1057;
-const int DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE = 1056;
-const int DART_RELEVANCE_LOCAL_VARIABLE = 1059;
 const int DART_RELEVANCE_LOW = 500;
-const int DART_RELEVANCE_NAMED_PARAMETER = 1060;
-const int DART_RELEVANCE_NAMED_PARAMETER_REQUIRED = 1065;
-const int DART_RELEVANCE_PARAMETER = 1059;
-const int DART_RELEVANCE_TYPE_PARAMETER = 1058;
 
 /// A name scope for constants that are related to the relevance of completion
 /// suggestions. The values are required to be in the range [0, 1000].
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index b5f2d6c..1fe66bc 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -277,7 +277,7 @@
 
   @override
   void visitExportDirective(ExportDirective node) {
-    var exportElement = node.element as ExportElement;
+    var exportElement = node.element;
     if (exportElement != null) {
       Element libraryElement = exportElement.exportedLibrary;
       _addUriDirectiveRegion(node, libraryElement);
@@ -287,7 +287,7 @@
 
   @override
   void visitImportDirective(ImportDirective node) {
-    var importElement = node.element as ImportElement;
+    var importElement = node.element;
     if (importElement != null) {
       Element libraryElement = importElement.importedLibrary;
       _addUriDirectiveRegion(node, libraryElement);
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index f763f70..2401bdb 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,22 +1,22 @@
 name: analyzer_plugin
 description: A framework and support code for building plugins for the analysis server.
-version: 0.3.0
+version: 0.4.0
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_plugin
 
 environment:
-  sdk: '>=2.3.0 <3.0.0'
+  sdk: '>=2.9.0 <3.0.0'
 
 dependencies:
-  analyzer: '>=0.39.12 <0.41.0'
+  analyzer: '>=0.41.0 <0.42.0'
   dart_style: '^1.2.0'
+  meta: ^1.2.3
   pub_semver: '^1.3.2'
 
 dev_dependencies:
-  analysis_tool:
-    path: ../analysis_tool
+  analyzer_utilities:
+    path: ../analyzer_utilities
   html: '>=0.13.1 <0.15.0'
-  meta: '^1.1.8'
   path: '^1.4.1'
   test_reflective_loader: ^0.1.8
   test: ^1.0.0
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index 092d411..d495c4f 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -175,6 +175,7 @@
 ///   OPTIONAL_ARGUMENT
 ///   OVERRIDE
 ///   PARAMETER
+///   PACKAGE_NAME
 /// }
 final Matcher isCompletionSuggestionKind =
     MatchesEnum('CompletionSuggestionKind', [
@@ -186,7 +187,8 @@
   'NAMED_ARGUMENT',
   'OPTIONAL_ARGUMENT',
   'OVERRIDE',
-  'PARAMETER'
+  'PARAMETER',
+  'PACKAGE_NAME'
 ]);
 
 /// ContextRoot
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
index 711cf55..0e27f7f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,6 +21,75 @@
 
 @reflectiveTest
 class ChangeBuilderImplTest {
+  void test_copy_empty() {
+    var builder = ChangeBuilderImpl();
+    var copy = builder.copy() as ChangeBuilderImpl;
+    expect(identical(copy, builder), isFalse);
+    expect(copy.workspace, builder.workspace);
+    expect(copy.eol, builder.eol);
+  }
+
+  Future<void> test_copy_newEdit() async {
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit('/test.dart', (builder) {
+      builder.addSimpleInsertion(0, 'x');
+    });
+    var copy = builder.copy() as ChangeBuilderImpl;
+    await copy.addGenericFileEdit('/test.dart', (builder) {
+      builder.addSimpleInsertion(10, 'x');
+    });
+    var change = builder.sourceChange;
+    expect(change.edits[0].edits, hasLength(1));
+  }
+
+  Future<void> test_copy_newFile() async {
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit('/test1.dart', (builder) {
+      builder.addSimpleInsertion(0, 'x');
+    });
+    var copy = builder.copy() as ChangeBuilderImpl;
+    await copy.addGenericFileEdit('/test2.dart', (builder) {
+      builder.addSimpleInsertion(0, 'x');
+    });
+    var change = builder.sourceChange;
+    expect(change.edits, hasLength(1));
+  }
+
+  Future<void> test_copy_newLinkedEditGroup() async {
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit('/test.dart', (builder) {
+      builder.addLinkedPosition(SourceRange(1, 2), 'a');
+    });
+    var copy = builder.copy() as ChangeBuilderImpl;
+    await copy.addGenericFileEdit('/test.dart', (builder) {
+      builder.addLinkedPosition(SourceRange(3, 4), 'b');
+    });
+    var change = builder.sourceChange;
+    expect(change.linkedEditGroups, hasLength(1));
+  }
+
+  Future<void> test_copy_newLinkedPosition() async {
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit('/test.dart', (builder) {
+      builder.addLinkedPosition(SourceRange(1, 2), 'a');
+    });
+    var copy = builder.copy() as ChangeBuilderImpl;
+    await copy.addGenericFileEdit('/test.dart', (builder) {
+      builder.addLinkedPosition(SourceRange(3, 4), 'a');
+    });
+    var change = builder.sourceChange;
+    expect(change.linkedEditGroups[0].positions, hasLength(1));
+  }
+
+  Future<void> test_copy_selection() async {
+    var builder = ChangeBuilderImpl();
+    builder.setSelection(Position('/test.dart', 5));
+    var copy = builder.copy() as ChangeBuilderImpl;
+    copy.setSelection(Position('/test.dart', 10));
+    var change = builder.sourceChange;
+    expect(change.selection.offset, 5);
+  }
+
   Future<void> test_createFileEditBuilder() async {
     var builder = ChangeBuilderImpl();
     var path = '/test.dart';
@@ -259,6 +329,71 @@
     expect(edits[0].replacement, isEmpty);
   }
 
+  Future<void> test_addDeletion_adjacent_lowerOffsetFirst() async {
+    // TODO(brianwilkerson) This should also merge the deletions, but is written
+    //  to ensure that existing uses of FileEditBuilder continue to work even
+    //  without that change.
+    var firstOffset = 23;
+    var firstLength = 7;
+    var secondOffset = 30;
+    var secondLength = 5;
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addDeletion(SourceRange(firstOffset, firstLength));
+      builder.addDeletion(SourceRange(secondOffset, secondLength));
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(2));
+    expect(edits[0].offset, secondOffset);
+    expect(edits[0].length, secondLength);
+    expect(edits[0].replacement, isEmpty);
+    expect(edits[1].offset, firstOffset);
+    expect(edits[1].length, firstLength);
+    expect(edits[1].replacement, isEmpty);
+  }
+
+  Future<void> test_addDeletion_adjacent_lowerOffsetSecond() async {
+    // TODO(brianwilkerson) This should also merge the deletions, but is written
+    //  to ensure that existing uses of FileEditBuilder continue to work even
+    //  without that change.
+    var firstOffset = 23;
+    var firstLength = 7;
+    var secondOffset = 30;
+    var secondLength = 5;
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addDeletion(SourceRange(secondOffset, secondLength));
+      builder.addDeletion(SourceRange(firstOffset, firstLength));
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(2));
+    expect(edits[0].offset, secondOffset);
+    expect(edits[0].length, secondLength);
+    expect(edits[0].replacement, isEmpty);
+    expect(edits[1].offset, firstOffset);
+    expect(edits[1].length, firstLength);
+    expect(edits[1].replacement, isEmpty);
+  }
+
+  @failingTest
+  Future<void> test_addDeletion_overlapping() async {
+    // This support is not yet implemented.
+    var firstOffset = 23;
+    var firstLength = 7;
+    var secondOffset = 27;
+    var secondLength = 8;
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addDeletion(SourceRange(firstOffset, firstLength));
+      builder.addDeletion(SourceRange(secondOffset, secondLength));
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(1));
+    expect(edits[0].offset, firstOffset);
+    expect(edits[0].length, secondOffset + secondLength - firstOffset);
+    expect(edits[0].replacement, isEmpty);
+  }
+
   Future<void> test_addInsertion() async {
     var builder = ChangeBuilderImpl();
     await builder.addGenericFileEdit(path, (builder) {
@@ -307,6 +442,24 @@
     expect(edits[0].replacement, text);
   }
 
+  Future<void> test_addSimpleInsertion_sameOffset() async {
+    var offset = 23;
+    var text = 'xyz';
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleInsertion(offset, text);
+      builder.addSimpleInsertion(offset, 'abc');
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(2));
+    expect(edits[0].offset, offset);
+    expect(edits[0].length, 0);
+    expect(edits[0].replacement, 'abc');
+    expect(edits[1].offset, offset);
+    expect(edits[1].length, 0);
+    expect(edits[1].replacement, text);
+  }
+
   Future<void> test_addSimpleReplacement() async {
     var offset = 23;
     var length = 7;
@@ -322,6 +475,64 @@
     expect(edits[0].replacement, text);
   }
 
+  Future<void> test_addSimpleReplacement_adjacent() async {
+    var firstOffset = 23;
+    var firstLength = 7;
+    var secondOffset = firstOffset + firstLength;
+    var secondLength = 5;
+    var text = 'xyz';
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleReplacement(SourceRange(firstOffset, firstLength), text);
+      builder.addSimpleReplacement(
+          SourceRange(secondOffset, secondLength), text);
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(2));
+    expect(edits[0].offset, secondOffset);
+    expect(edits[0].length, secondLength);
+    expect(edits[0].replacement, text);
+    expect(edits[1].offset, firstOffset);
+    expect(edits[1].length, firstLength);
+    expect(edits[1].replacement, text);
+  }
+
+  Future<void> test_addSimpleReplacement_overlapsHead() async {
+    var offset = 23;
+    var length = 7;
+    var text = 'xyz';
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleReplacement(SourceRange(offset, length), text);
+      expect(() {
+        builder.addSimpleReplacement(SourceRange(offset - 2, length), text);
+      }, throwsA(isA<ConflictingEditException>()));
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(1));
+    expect(edits[0].offset, offset);
+    expect(edits[0].length, length);
+    expect(edits[0].replacement, text);
+  }
+
+  Future<void> test_addSimpleReplacement_overlapsTail() async {
+    var offset = 23;
+    var length = 7;
+    var text = 'xyz';
+    var builder = ChangeBuilderImpl();
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleReplacement(SourceRange(offset, length), text);
+      expect(() {
+        builder.addSimpleReplacement(SourceRange(offset + 2, length), text);
+      }, throwsA(isA<ConflictingEditException>()));
+    });
+    var edits = builder.sourceChange.edits[0].edits;
+    expect(edits, hasLength(1));
+    expect(edits[0].offset, offset);
+    expect(edits[0].length, length);
+    expect(edits[0].replacement, text);
+  }
+
   Future<void> test_createEditBuilder() async {
     var builder = ChangeBuilderImpl();
     await builder.addGenericFileEdit(path, (builder) {
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index 6970a80..f95ad22 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart' as analyzer;
-import 'package:analyzer/src/generated/parser.dart' as analyzer;
 import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:test/test.dart';
@@ -642,11 +641,7 @@
   Future<void> test_IfStatement_droppedToken() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('main() { if (v i^) }');
-    if (usingFastaParser) {
-      assertTarget(')', 'if (v) ;', droppedToken: 'i');
-    } else {
-      assertTarget('i;', 'if (v) i;');
-    }
+    assertTarget(')', 'if (v) ;', droppedToken: 'i');
   }
 
   Future<void> test_InstanceCreationExpression_identifier() async {
@@ -908,8 +903,6 @@
   CompletionTarget target;
   FindElement findElement;
 
-  bool get usingFastaParser => analyzer.Parser.useFasta;
-
   void assertTarget(
     String entityText,
     String nodeText, {
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 4703fda..57a6f59 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -1686,7 +1686,8 @@
     await assertOpType(
         completionLocation: 'InterpolationExpression_expression',
         constructors: true,
-        returnValue: true);
+        returnValue: true,
+        typeNames: true);
   }
 
   Future<void> test_interpolationExpression_block() async {
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index e2e289b..a634551 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -4,25 +4,22 @@
 
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/element_search.dart';
 import 'package:analyzer/src/test_utilities/mock_packages.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:meta/meta.dart';
 
 /// Finds an [Element] with the given [name].
 Element findChildElement(Element root, String name, [ElementKind kind]) {
@@ -67,10 +64,8 @@
 
   String get workspaceRootPath => convertPath('/home');
 
-  Source addSource(String path, String content, [Uri uri]) {
-    var file = newFile(path, content: content);
-    var source = file.createSource(uri);
-    return source;
+  void addSource(String path, String content) {
+    newFile(path, content: content);
   }
 
   AnalysisContext contextFor(String path) {
@@ -107,6 +102,15 @@
         .single;
   }
 
+  @override
+  File newFile(String path, {String content = ''}) {
+    if (_analysisContextCollection != null && !path.endsWith('.dart')) {
+      throw StateError('Only dart files can be changed after analysis.');
+    }
+
+    return super.newFile(path, content: content);
+  }
+
   Future<ResolvedUnitResult> resolveFile(String path) async {
     return contextFor(path).currentSession.getResolvedUnit(path);
   }
@@ -174,23 +178,7 @@
 
 mixin WithNullSafetyMixin on AbstractContextTest {
   @override
-  String get testPackageLanguageVersion =>
-      Feature.non_nullable.isEnabledByDefault ? '2.12' : '2.11';
-
-  bool get withPackageMeta => false;
-
-  /// TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
-  /// Remove when Null Safety is enabled by default.
-  @nonVirtual
-  @override
-  void setUp() {
-    super.setUp();
-    writeTestPackageConfig(
-      languageVersion: testPackageLanguageVersion,
-      meta: withPackageMeta,
-    );
-    createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
-  }
+  String get testPackageLanguageVersion => '2.12';
 }
 
 /// Wraps the given [_ElementVisitorFunction] into an instance of
diff --git a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
index 4a8ea64..03082d7 100644
--- a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:test/test.dart';
 
 import 'abstract_context.dart';
@@ -19,14 +18,13 @@
 
   String testCode;
   String testFile;
-  Source testSource;
   CompilationUnit testUnit;
   CompilationUnitElement testUnitElement;
   LibraryElement testLibraryElement;
 
-  void addTestSource(String code, [Uri uri]) {
+  void addTestSource(String code) {
     testCode = code;
-    testSource = addSource(testFile, code, uri);
+    addSource(testFile, code);
   }
 
   Element findElement(String name, [ElementKind kind]) {
diff --git a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
index b1992c4..2697933 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_core.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -23,7 +22,6 @@
 abstract class DartCompletionContributorTest extends AbstractContextTest {
   static const String _UNCHECKED = '__UNCHECKED__';
   String testFile;
-  Source testSource;
   int completionOffset;
   int replacementOffset;
   int replacementLength;
@@ -46,7 +44,7 @@
     expect(nextOffset, equals(-1), reason: 'too many ^');
     content = content.substring(0, completionOffset) +
         content.substring(completionOffset + 1);
-    testSource = addSource(testFile, content);
+    addSource(testFile, content);
   }
 
   void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
@@ -414,7 +412,6 @@
 
   Future computeSuggestions() async {
     var result = await resolveFile(testFile);
-    testSource = result.unit.declaredElement.source;
     request =
         DartCompletionRequestImpl(resourceProvider, completionOffset, result);
 
diff --git a/pkg/analyzer_plugin/test/utils/package_root.dart b/pkg/analyzer_plugin/test/utils/package_root.dart
deleted file mode 100644
index 8ef4cfc..0000000
--- a/pkg/analyzer_plugin/test/utils/package_root.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:path/path.dart' as pathos;
-
-/// Returns a path to the directory containing source code for packages such as
-/// kernel, front_end, and analyzer.
-String get packageRoot {
-  // If the package root directory is specified on the command line using
-  // -DpkgRoot=..., use it.
-  var pkgRootVar = bool.hasEnvironment('pkgRoot')
-      ? const String.fromEnvironment('pkgRoot')
-      : null;
-  if (pkgRootVar != null) {
-    var path = pathos.join(Directory.current.path, pkgRootVar);
-    if (!path.endsWith(pathos.separator)) path += pathos.separator;
-    return path;
-  }
-  // Otherwise try to guess based on the script path.
-  var scriptPath = pathos.fromUri(Platform.script);
-  var parts = pathos.split(scriptPath);
-  var pkgIndex = parts.indexOf('pkg');
-  if (pkgIndex != -1) {
-    return pathos.joinAll(parts.sublist(0, pkgIndex + 1)) + pathos.separator;
-  }
-  throw StateError('Unable to find sdk/pkg/ in $scriptPath');
-}
diff --git a/pkg/analyzer_plugin/test/verify_tests_test.dart b/pkg/analyzer_plugin/test/verify_tests_test.dart
index 2a05ff6..48657ce 100644
--- a/pkg/analyzer_plugin/test/verify_tests_test.dart
+++ b/pkg/analyzer_plugin/test/verify_tests_test.dart
@@ -2,84 +2,34 @@
 // for details. All 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/analysis_context_collection.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/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-import 'utils/package_root.dart' as package_root;
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:analyzer_utilities/verify_tests.dart';
 
 void main() {
   var provider = PhysicalResourceProvider.INSTANCE;
   var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
-  var analysisServerPath =
-      provider.pathContext.join(packageRoot, 'analyzer_plugin');
-  var testDirPath = provider.pathContext.join(analysisServerPath, 'test');
-
-  var collection = AnalysisContextCollection(
-      includedPaths: <String>[testDirPath], resourceProvider: provider);
-  var contexts = collection.contexts;
-  if (contexts.length != 1) {
-    fail('The test directory contains multiple analysis contexts.');
-  }
-
-  buildTestsIn(
-      contexts[0].currentSession, testDirPath, provider.getFolder(testDirPath));
+  var pathToAnalyze = provider.pathContext.join(packageRoot, 'analyzer_plugin');
+  var testDirPath = provider.pathContext.join(pathToAnalyze, 'test');
+  _VerifyTests(testDirPath).build();
 }
 
-void buildTestsIn(
-    AnalysisSession session, String testDirPath, Folder directory) {
-  var testFileNames = <String>[];
-  File testAllFile;
-  var children = directory.getChildren();
-  children.sort((first, second) => first.shortName.compareTo(second.shortName));
-  for (var child in children) {
-    if (child is Folder) {
-      if (child.shortName == 'integration') {
-        continue;
-      } else if (child.getChildAssumingFile('test_all.dart').exists) {
-        testFileNames.add('${child.shortName}/test_all.dart');
-      }
-      buildTestsIn(session, testDirPath, child);
-    } else if (child is File) {
-      var name = child.shortName;
-      if (name == 'test_all.dart') {
-        testAllFile = child;
-      } else if (name.endsWith('_test.dart')) {
-        testFileNames.add(name);
-      }
+class _VerifyTests extends VerifyTests {
+  _VerifyTests(String testDirPath, {List<String> excludedPaths})
+      : super(testDirPath, excludedPaths: excludedPaths);
+
+  @override
+  bool isExpensive(Resource resource) => resource.shortName == 'integration';
+
+  @override
+  bool isOkAsAdditionalTestAllImport(Folder folder, String uri) {
+    if (folder.path == testDirPath &&
+        uri == '../tool/spec/check_all_test.dart') {
+      // The topmost `test_all.dart` also runs this one test in `tool` for
+      // convenience.
+      return true;
     }
+    return super.isOkAsAdditionalTestAllImport(folder, uri);
   }
-  var relativePath = path.relative(directory.path, from: testDirPath);
-  test(relativePath, () {
-    if (testFileNames.isEmpty) {
-      return;
-    }
-    if (testAllFile == null) {
-      fail('Missing "test_all.dart" in $relativePath');
-    }
-    var result = session.getParsedUnit(testAllFile.path);
-    if (result.state != ResultState.VALID) {
-      fail('Could not parse ${testAllFile.path}');
-    }
-    var importedFiles = <String>[];
-    for (var directive in result.unit.directives) {
-      if (directive is ImportDirective) {
-        importedFiles.add(directive.uri.stringValue);
-      }
-    }
-    var missingFiles = <String>[];
-    for (var testFileName in testFileNames) {
-      if (!importedFiles.contains(testFileName)) {
-        missingFiles.add(testFileName);
-      }
-    }
-    if (missingFiles.isNotEmpty) {
-      fail('Tests missing from "test_all.dart": ${missingFiles.join(', ')}');
-    }
-  });
 }
diff --git a/pkg/analyzer_plugin/tool/spec/check_all_test.dart b/pkg/analyzer_plugin/tool/spec/check_all_test.dart
index 2d4f184..24b06fa 100644
--- a/pkg/analyzer_plugin/tool/spec/check_all_test.dart
+++ b/pkg/analyzer_plugin/tool/spec/check_all_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate_all.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
index 93c58c0..6497fe8 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
@@ -4,7 +4,7 @@
 
 import 'dart:convert';
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:path/path.dart' as path;
 
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
index add730b..fe65490 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code generation for the file "integration_test_methods.dart".
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart' as path;
 
 import 'api.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
index 00110bc..9e3e2fd 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code generation for the file "matchers.dart".
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 import 'from_html.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart
index ae017a6..a872b10 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart' as path;
 
 import 'api.dart';
@@ -10,7 +10,16 @@
 import 'from_html.dart';
 import 'implied_types.dart';
 
-GeneratedFile target(bool responseRequiresRequestTime) =>
+GeneratedFile clientTarget(bool responseRequiresRequestTime) => GeneratedFile(
+        '../analysis_server_client/lib/src/protocol/protocol_common.dart',
+        (String pkgPath) async {
+      var visitor = CodegenCommonVisitor(
+          path.basename(pkgPath), responseRequiresRequestTime, readApi(pkgPath),
+          forClient: true);
+      return visitor.collectCode(visitor.visitApi);
+    });
+
+GeneratedFile pluginTarget(bool responseRequiresRequestTime) =>
     GeneratedFile('lib/protocol/protocol_common.dart', (String pkgPath) async {
       var visitor = CodegenCommonVisitor(path.basename(pkgPath),
           responseRequiresRequestTime, readApi(pkgPath));
@@ -20,21 +29,34 @@
 /// A visitor that produces Dart code defining the common types associated with
 /// the API.
 class CodegenCommonVisitor extends CodegenProtocolVisitor {
+  final bool forClient;
+
   /// Initialize a newly created visitor to generate code in the package with
   /// the given [packageName] corresponding to the types in the given [api] that
   /// are common to multiple protocols.
   CodegenCommonVisitor(
-      String packageName, bool responseRequiresRequestTime, Api api)
+      String packageName, bool responseRequiresRequestTime, Api api,
+      {this.forClient = false})
       : super(packageName, responseRequiresRequestTime, api);
 
   @override
   void emitImports() {
     writeln("import 'dart:convert' hide JsonDecoder;");
     writeln();
-    writeln("import 'package:analyzer/src/generated/utilities_general.dart';");
-    writeln("import 'package:$packageName/protocol/protocol.dart';");
-    writeln(
-        "import 'package:$packageName/src/protocol/protocol_internal.dart';");
+    if (forClient) {
+      writeln(
+          "import 'package:analysis_server_client/src/protocol/protocol_util.dart';");
+      writeln(
+          "import 'package:analysis_server_client/src/protocol/protocol_base.dart';");
+      writeln(
+          "import 'package:analysis_server_client/src/protocol/protocol_internal.dart';");
+    } else {
+      writeln(
+          "import 'package:analyzer/src/generated/utilities_general.dart';");
+      writeln("import 'package:$packageName/protocol/protocol.dart';");
+      writeln(
+          "import 'package:$packageName/src/protocol/protocol_internal.dart';");
+    }
   }
 
   @override
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
index 2c6718f..52618ac 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 import 'codegen_dart.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index f4acea4..b1c7056 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -6,7 +6,7 @@
 </head>
 <body>
 <h1>Common Types</h1>
-<version>1.3.0</version>
+<version>1.4.0</version>
 <p>
   This document contains a specification of the types that are common between
   the analysis server wire protocol and the analysis server plugin wire
@@ -414,6 +414,10 @@
         </p>
       </value>
       <value><code>PARAMETER</code></value>
+      <value>
+        <code>PACKAGE_NAME</code>
+        <p>The name of a pub package is being suggested.</p>
+      </value>
     </enum>
   </type>
   <type name="DiagnosticMessage">
@@ -645,90 +649,76 @@
       <value><code>DIRECTIVE</code></value>
       <value>
         <code>DYNAMIC_TYPE</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>DYNAMIC_LOCAL_VARIABLE_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>DYNAMIC_LOCAL_VARIABLE_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>DYNAMIC_PARAMETER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>DYNAMIC_PARAMETER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>ENUM</code></value>
       <value><code>ENUM_CONSTANT</code></value>
       <value>
         <code>FIELD</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>FIELD_STATIC</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>FUNCTION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>FUNCTION_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value><code>FUNCTION_TYPE_ALIAS</code></value>
       <value>
         <code>GETTER_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value><code>IDENTIFIER_DEFAULT</code></value>
       <value><code>IMPORT_PREFIX</code></value>
       <value>
         <code>INSTANCE_FIELD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_FIELD_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_GETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_GETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_METHOD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_METHOD_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_SETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_SETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INVALID_STRING_ESCAPE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>KEYWORD</code></value>
       <value><code>LABEL</code></value>
       <value>
         <code>LIBRARY_NAME</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>LITERAL_BOOLEAN</code></value>
       <value><code>LITERAL_DOUBLE</code></value>
@@ -738,122 +728,101 @@
       <value><code>LITERAL_STRING</code></value>
       <value>
         <code>LOCAL_FUNCTION_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>LOCAL_FUNCTION_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>LOCAL_VARIABLE</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value><code>LOCAL_VARIABLE_DECLARATION</code></value>
       <value>
         <code>LOCAL_VARIABLE_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>METHOD</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>METHOD_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>METHOD_DECLARATION_STATIC</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>METHOD_STATIC</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>PARAMETER</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>SETTER_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>TOP_LEVEL_VARIABLE</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>PARAMETER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>PARAMETER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_FIELD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_GETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_GETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_METHOD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_METHOD_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_SETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_SETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_FUNCTION_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_FUNCTION_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_GETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_GETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_SETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_SETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_VARIABLE_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>TYPE_NAME_DYNAMIC</code></value>
       <value><code>TYPE_PARAMETER</code></value>
       <value>
         <code>UNRESOLVED_INSTANCE_MEMBER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>VALID_STRING_ESCAPE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
     </enum>
   </type>
diff --git a/pkg/analyzer_plugin/tool/spec/from_html.dart b/pkg/analyzer_plugin/tool/spec/from_html.dart
index 86d0ebb..977737b 100644
--- a/pkg/analyzer_plugin/tool/spec/from_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/from_html.dart
@@ -5,7 +5,7 @@
 /// Code for reading an HTML API description.
 import 'dart:io';
 
-import 'package:analysis_tool/html.dart';
+import 'package:analyzer_utilities/html.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:html/parser.dart' as parser;
 import 'package:path/path.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/generate_all.dart b/pkg/analyzer_plugin/tool/spec/generate_all.dart
index 4083370..6507475 100644
--- a/pkg/analyzer_plugin/tool/spec/generate_all.dart
+++ b/pkg/analyzer_plugin/tool/spec/generate_all.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:path/path.dart';
 
 import 'codegen_dart_protocol.dart' as codegen_dart_protocol;
@@ -27,7 +27,8 @@
   targets.add(codegen_dart_protocol.target(true));
   targets.add(codegen_inttest_methods.target);
   targets.add(codegen_matchers.target);
-  targets.add(codegen_protocol_common.target(true));
+  targets.add(codegen_protocol_common.pluginTarget(true));
+  targets.add(codegen_protocol_common.clientTarget(true));
   targets.add(codegen_protocol_constants.target);
   targets.add(to_html.target);
   return targets;
diff --git a/pkg/analyzer_plugin/tool/spec/implied_types.dart b/pkg/analyzer_plugin/tool/spec/implied_types.dart
index 0eb3e4b..04f217c 100644
--- a/pkg/analyzer_plugin/tool/spec/implied_types.dart
+++ b/pkg/analyzer_plugin/tool/spec/implied_types.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Code for enumerating the set of types implied by the API.
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/tools.dart';
 
 import 'api.dart';
 
diff --git a/pkg/analyzer_plugin/tool/spec/to_html.dart b/pkg/analyzer_plugin/tool/spec/to_html.dart
index 115b3ec..923e34b 100644
--- a/pkg/analyzer_plugin/tool/spec/to_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/to_html.dart
@@ -7,8 +7,8 @@
 /// in generated code.
 import 'dart:convert';
 
-import 'package:analysis_tool/html.dart';
-import 'package:analysis_tool/tools.dart';
+import 'package:analyzer_utilities/html.dart';
+import 'package:analyzer_utilities/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_tool/README.md b/pkg/analyzer_utilities/README.md
similarity index 100%
rename from pkg/analysis_tool/README.md
rename to pkg/analyzer_utilities/README.md
diff --git a/pkg/analysis_tool/analysis_options.yaml b/pkg/analyzer_utilities/analysis_options.yaml
similarity index 100%
rename from pkg/analysis_tool/analysis_options.yaml
rename to pkg/analyzer_utilities/analysis_options.yaml
diff --git a/pkg/analysis_tool/lib/html.dart b/pkg/analyzer_utilities/lib/html.dart
similarity index 100%
rename from pkg/analysis_tool/lib/html.dart
rename to pkg/analyzer_utilities/lib/html.dart
diff --git a/pkg/analysis_server/test/utils/package_root.dart b/pkg/analyzer_utilities/lib/package_root.dart
similarity index 100%
rename from pkg/analysis_server/test/utils/package_root.dart
rename to pkg/analyzer_utilities/lib/package_root.dart
diff --git a/pkg/analyzer_utilities/lib/text_formatter.dart b/pkg/analyzer_utilities/lib/text_formatter.dart
new file mode 100644
index 0000000..a35920b
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/text_formatter.dart
@@ -0,0 +1,245 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Code for converting HTML into text, for use during code generation of
+ * analyzer and analysis server.
+ */
+
+import 'package:analyzer_utilities/tools.dart';
+import 'package:html/dom.dart' as dom;
+
+final RegExp whitespace = new RegExp(r'\s');
+
+/**
+ * Convert the HTML in [desc] into text, word wrapping at width [width].
+ *
+ * If [javadocStyle] is true, then the output is compatible with Javadoc,
+ * which understands certain HTML constructs.
+ */
+String nodesToText(List<dom.Node> desc, int width, bool javadocStyle,
+    {bool removeTrailingNewLine: false}) {
+  _TextFormatter formatter = new _TextFormatter(width, javadocStyle);
+  return formatter.collectCode(() {
+    formatter.addAll(desc);
+    formatter.lineBreak(false);
+  }, removeTrailingNewLine: removeTrailingNewLine);
+}
+
+/**
+ * Engine that transforms HTML to text.  The input HTML is processed one
+ * character at a time, gathering characters into words and words into lines.
+ */
+class _TextFormatter extends CodeGenerator {
+  /**
+   * Word-wrapping width.
+   */
+  final int width;
+
+  /**
+   * The word currently being gathered.
+   */
+  String word = '';
+
+  /**
+   * The line currently being gathered.
+   */
+  String line = '';
+
+  /**
+   * True if a blank line should be inserted before the next word.
+   */
+  bool verticalSpaceNeeded = false;
+
+  /**
+   * True if no text has been output yet.  This suppresses blank lines.
+   */
+  bool atStart = true;
+
+  /**
+   * True if we are processing a <pre> element, thus whitespace should be
+   * preserved.
+   */
+  bool preserveSpaces = false;
+
+  /**
+   * True if the output should be Javadoc compatible.
+   */
+  final bool javadocStyle;
+
+  _TextFormatter(this.width, this.javadocStyle);
+
+  /**
+   * Process an HTML node.
+   */
+  void add(dom.Node node) {
+    if (node is dom.Text) {
+      for (String char in node.text.split('')) {
+        if (preserveSpaces) {
+          wordBreak();
+          write(escape(char));
+        } else if (whitespace.hasMatch(char)) {
+          wordBreak();
+        } else {
+          resolveVerticalSpace();
+          word += escape(char);
+        }
+      }
+    } else if (node is dom.Element) {
+      switch (node.localName) {
+        case 'br':
+          lineBreak(false);
+          break;
+        case 'dl':
+        case 'dt':
+        case 'h1':
+        case 'h2':
+        case 'h3':
+        case 'h4':
+        case 'p':
+          lineBreak(true);
+          addAll(node.nodes);
+          lineBreak(true);
+          break;
+        case 'div':
+          lineBreak(false);
+          if (node.classes.contains('hangingIndent')) {
+            resolveVerticalSpace();
+            indentSpecial('', '        ', () {
+              addAll(node.nodes);
+              lineBreak(false);
+            });
+          } else {
+            addAll(node.nodes);
+            lineBreak(false);
+          }
+          break;
+        case 'ul':
+          lineBreak(false);
+          addAll(node.nodes);
+          lineBreak(false);
+          break;
+        case 'li':
+          lineBreak(false);
+          resolveVerticalSpace();
+          indentSpecial('- ', '  ', () {
+            addAll(node.nodes);
+            lineBreak(false);
+          });
+          break;
+        case 'dd':
+          lineBreak(true);
+          indent(() {
+            addAll(node.nodes);
+            lineBreak(true);
+          });
+          break;
+        case 'pre':
+          lineBreak(false);
+          resolveVerticalSpace();
+          if (javadocStyle) {
+            writeln('<pre>');
+          }
+          bool oldPreserveSpaces = preserveSpaces;
+          try {
+            preserveSpaces = true;
+            addAll(node.nodes);
+          } finally {
+            preserveSpaces = oldPreserveSpaces;
+          }
+          writeln();
+          if (javadocStyle) {
+            writeln('</pre>');
+          }
+          lineBreak(false);
+          break;
+        case 'a':
+        case 'b':
+        case 'body':
+        case 'html':
+        case 'i':
+        case 'span':
+        case 'tt':
+          addAll(node.nodes);
+          break;
+        case 'head':
+          break;
+        default:
+          throw new Exception('Unexpected HTML element: ${node.localName}');
+      }
+    } else {
+      throw new Exception('Unexpected HTML: $node');
+    }
+  }
+
+  /**
+   * Process a list of HTML nodes.
+   */
+  void addAll(List<dom.Node> nodes) {
+    for (dom.Node node in nodes) {
+      add(node);
+    }
+  }
+
+  /**
+   * Escape the given character for HTML.
+   */
+  String escape(String char) {
+    if (javadocStyle) {
+      switch (char) {
+        case '<':
+          return '&lt;';
+        case '>':
+          return '&gt;';
+        case '&':
+          return '&amp;';
+      }
+    }
+    return char;
+  }
+
+  /**
+   * Terminate the current word and/or line, if either is in progress.
+   */
+  void lineBreak(bool gap) {
+    wordBreak();
+    if (line.isNotEmpty) {
+      writeln(line);
+      line = '';
+    }
+    if (gap && !atStart) {
+      verticalSpaceNeeded = true;
+    }
+  }
+
+  /**
+   * Insert vertical space if necessary.
+   */
+  void resolveVerticalSpace() {
+    if (verticalSpaceNeeded) {
+      writeln();
+      verticalSpaceNeeded = false;
+    }
+  }
+
+  /**
+   * Terminate the current word, if a word is in progress.
+   */
+  void wordBreak() {
+    if (word.isNotEmpty) {
+      atStart = false;
+      if (line.isNotEmpty) {
+        if (indentWidth + line.length + 1 + word.length <= width) {
+          line += ' $word';
+        } else {
+          writeln(line);
+          line = word;
+        }
+      } else {
+        line = word;
+      }
+      word = '';
+    }
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/tools.dart b/pkg/analyzer_utilities/lib/tools.dart
new file mode 100644
index 0000000..c26e5a5
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/tools.dart
@@ -0,0 +1,648 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Tools for generating code in analyzer and analysis server.
+ */
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analyzer_utilities/html.dart';
+import 'package:analyzer_utilities/text_formatter.dart';
+import 'package:html/dom.dart' as dom;
+import 'package:path/path.dart';
+
+final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
+final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
+
+/**
+ * Join the given strings using camelCase.  If [doCapitalize] is true, the first
+ * part will be capitalized as well.
+ */
+String camelJoin(List<String> parts, {bool doCapitalize: false}) {
+  List<String> upcasedParts = <String>[];
+  for (int i = 0; i < parts.length; i++) {
+    if (i == 0 && !doCapitalize) {
+      upcasedParts.add(parts[i]);
+    } else {
+      upcasedParts.add(capitalize(parts[i]));
+    }
+  }
+  return upcasedParts.join();
+}
+
+/**
+ * Capitalize and return the passed String.
+ */
+String capitalize(String string) {
+  return string[0].toUpperCase() + string.substring(1);
+}
+
+/**
+ * Type of functions used to compute the contents of a set of generated files.
+ * [pkgPath] is the path to the current package.
+ */
+typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
+    String pkgPath);
+
+/**
+ * Type of functions used to compute the contents of a generated file.
+ * [pkgPath] is the path to the current package.
+ */
+typedef Future<String> FileContentsComputer(String pkgPath);
+
+/**
+ * Mixin class for generating code.
+ */
+class CodeGenerator {
+  _CodeGeneratorState _state;
+
+  /**
+   * Settings that specialize code generation behavior for a given
+   * programming language.
+   */
+  CodeGeneratorSettings codeGeneratorSettings = new CodeGeneratorSettings();
+
+  /**
+   * Measure the width of the current indentation level.
+   */
+  int get indentWidth => _state.nextIndent.length;
+
+  /**
+   * Execute [callback], collecting any code that is output using [write]
+   * or [writeln], and return the result as a string.
+   */
+  String collectCode(void callback(), {bool removeTrailingNewLine: false}) {
+    _CodeGeneratorState oldState = _state;
+    try {
+      _state = new _CodeGeneratorState();
+      callback();
+      var text =
+          _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, '');
+      if (!removeTrailingNewLine) {
+        return text;
+      } else {
+        return text.replaceAll(trailingWhitespaceRegExp, '');
+      }
+    } finally {
+      _state = oldState;
+    }
+  }
+
+  /**
+   * Generate a doc comment based on the HTML in [docs].
+   *
+   * When generating java code, the output is compatible with Javadoc, which
+   * understands certain HTML constructs.
+   */
+  void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
+    if (containsOnlyWhitespace(docs)) return;
+    if (codeGeneratorSettings.docCommentStartMarker != null)
+      writeln(codeGeneratorSettings.docCommentStartMarker);
+    int width = codeGeneratorSettings.commentLineLength;
+    bool javadocStyle = codeGeneratorSettings.languageName == 'java';
+    indentBy(codeGeneratorSettings.docCommentLineLeader, () {
+      write(nodesToText(docs, width - _state.indent.length, javadocStyle,
+          removeTrailingNewLine: removeTrailingNewLine));
+    });
+    if (codeGeneratorSettings.docCommentEndMarker != null)
+      writeln(codeGeneratorSettings.docCommentEndMarker);
+  }
+
+  /**
+   * Execute [callback], indenting any code it outputs.
+   */
+  void indent(void callback()) {
+    indentSpecial(
+        codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback);
+  }
+
+  /**
+   * Execute [callback], using [additionalIndent] to indent any code it outputs.
+   */
+  void indentBy(String additionalIndent, void callback()) =>
+      indentSpecial(additionalIndent, additionalIndent, callback);
+
+  /**
+   * Execute [callback], using [additionalIndent] to indent any code it outputs.
+   * The first line of output is indented by [firstAdditionalIndent] instead of
+   * [additionalIndent].
+   */
+  void indentSpecial(
+      String firstAdditionalIndent, String additionalIndent, void callback()) {
+    String oldNextIndent = _state.nextIndent;
+    String oldIndent = _state.indent;
+    try {
+      _state.nextIndent += firstAdditionalIndent;
+      _state.indent += additionalIndent;
+      callback();
+    } finally {
+      _state.nextIndent = oldNextIndent;
+      _state.indent = oldIndent;
+    }
+  }
+
+  void lineComment(List<dom.Node> docs) {
+    if (containsOnlyWhitespace(docs)) {
+      return;
+    }
+    write(codeGeneratorSettings.lineCommentLineLeader);
+    int width = codeGeneratorSettings.commentLineLength;
+    indentBy(codeGeneratorSettings.lineCommentLineLeader, () {
+      write(nodesToText(docs, width - _state.indent.length, false));
+    });
+  }
+
+  void outputHeader({bool javaStyle: false, String year = null}) {
+    String header;
+    if (codeGeneratorSettings.languageName == 'java') {
+      header = '''
+/*
+ * Copyright (c) ${year ?? '2019'}, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */''';
+    } else if (codeGeneratorSettings.languageName == 'python') {
+      header = '''
+# Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# This file has been automatically generated. Please do not edit it manually.
+# To regenerate the file, use the script
+# "pkg/analysis_server/tool/spec/generate_files".
+''';
+    } else {
+      header = '''
+// Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/spec/generate_files".
+''';
+    }
+    writeln(header.trim());
+  }
+
+  /**
+   * Output text without ending the current line.
+   */
+  void write(Object obj) {
+    _state.write(obj.toString());
+  }
+
+  /**
+   * Output text, ending the current line.
+   */
+  void writeln([Object obj = '']) {
+    _state.write('$obj\n');
+  }
+}
+
+/**
+ * Controls several settings of [CodeGenerator].
+ *
+ * The default settings are valid for generating Java and Dart code.
+ */
+class CodeGeneratorSettings {
+  /**
+   * Name of the language being generated. Lowercase.
+   */
+  String languageName;
+
+  /**
+   * Marker used in line comments.
+   */
+  String lineCommentLineLeader;
+
+  /**
+   * Start marker for doc comments.
+   */
+  String docCommentStartMarker;
+
+  /**
+   * Line leader for body lines in doc comments.
+   */
+  String docCommentLineLeader;
+
+  /**
+   * End marker for doc comments.
+   */
+  String docCommentEndMarker;
+
+  /**
+   * Line length for doc comment lines.
+   */
+  int commentLineLength;
+
+  /**
+   * String used for indenting code.
+   */
+  String indent;
+
+  CodeGeneratorSettings(
+      {this.languageName: 'java',
+      this.lineCommentLineLeader: '// ',
+      this.docCommentStartMarker: '/**',
+      this.docCommentLineLeader: ' * ',
+      this.docCommentEndMarker: ' */',
+      this.commentLineLength: 99,
+      this.indent: '  '});
+}
+
+/**
+ * A utility class for invoking dartfmt.
+ */
+class DartFormat {
+  static String get _dartfmtPath {
+    String binName = Platform.isWindows ? 'dartfmt.bat' : 'dartfmt';
+    for (var loc in [binName, join('dart-sdk', 'bin', binName)]) {
+      var candidatePath = join(dirname(Platform.resolvedExecutable), loc);
+      if (new File(candidatePath).existsSync()) {
+        return candidatePath;
+      }
+    }
+    throw new StateError('Could not find dartfmt executable');
+  }
+
+  static void formatFile(File file) {
+    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
+    if (result.exitCode != 0) throw result.stderr;
+  }
+
+  static String formatText(String text) {
+    File file = new File(join(Directory.systemTemp.path, 'gen.dart'));
+    file.writeAsStringSync(text);
+    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
+    if (result.exitCode != 0) throw result.stderr;
+    return file.readAsStringSync();
+  }
+}
+
+/**
+ * Abstract base class representing behaviors common to generated files and
+ * generated directories.
+ */
+abstract class GeneratedContent {
+  /**
+   * Check whether the [output] has the correct contents, and return true if it
+   * does.  [pkgPath] is the path to the current package.
+   */
+  Future<bool> check(String pkgPath);
+
+  /**
+   * Replace the [output] with the correct contents.  [pkgPath] is the path to
+   * the current package.
+   */
+  Future<void> generate(String pkgPath);
+
+  /**
+   * Get a [FileSystemEntity] representing the output file or directory.
+   * [pkgPath] is the path to the current package.
+   */
+  FileSystemEntity output(String pkgPath);
+
+  /**
+   * Check that all of the [targets] are up to date.  If they are not, print
+   * out a message instructing the user to regenerate them, and exit with a
+   * nonzero error code.
+   *
+   * [pkgPath] is the path to the current package.  [generatorPath] is the path
+   * to a .dart script the user may use to regenerate the targets.
+   *
+   * To avoid mistakes when run on Windows, [generatorPath] always uses
+   * POSIX directory separators.
+   */
+  static Future<void> checkAll(
+      String pkgPath, String generatorPath, Iterable<GeneratedContent> targets,
+      {List<String> args = const []}) async {
+    bool generateNeeded = false;
+    for (GeneratedContent target in targets) {
+      bool ok = await target.check(pkgPath);
+      if (!ok) {
+        print("${target.output(pkgPath).absolute}"
+            " doesn't have expected contents.");
+        generateNeeded = true;
+      }
+    }
+    if (generateNeeded) {
+      print('Please regenerate using:');
+      String executable = Platform.executable;
+      String packageRoot = '';
+      // ignore: deprecated_member_use
+      if (Platform.packageRoot != null) {
+        // ignore: deprecated_member_use
+        packageRoot = ' --package-root=${Platform.packageRoot}';
+      }
+      String generateScript = normalize(joinAll(posix.split(generatorPath)));
+      print('  $executable$packageRoot $generateScript ${args.join(" ")}');
+      exit(1);
+    } else {
+      print('All generated files up to date.');
+    }
+  }
+
+  /**
+   * Regenerate all of the [targets].  [pkgPath] is the path to the current
+   * package.
+   */
+  static Future<void> generateAll(
+      String pkgPath, Iterable<GeneratedContent> targets) async {
+    print("Generating...");
+    for (GeneratedContent target in targets) {
+      await target.generate(pkgPath);
+    }
+  }
+}
+
+/**
+ * Class representing a single output directory (either generated code or
+ * generated HTML). No other content should exist in the directory.
+ */
+class GeneratedDirectory extends GeneratedContent {
+  /**
+   * The path to the directory that will have the generated content.
+   */
+  final String outputDirPath;
+
+  /**
+   * Callback function that computes the directory contents.
+   */
+  final DirectoryContentsComputer directoryContentsComputer;
+
+  GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
+
+  @override
+  Future<bool> check(String pkgPath) async {
+    Directory outputDirectory = output(pkgPath);
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
+    try {
+      for (String file in map.keys) {
+        FileContentsComputer fileContentsComputer = map[file];
+        String expectedContents = await fileContentsComputer(pkgPath);
+        File outputFile = new File(posix.join(outputDirectory.path, file));
+        String actualContents = outputFile.readAsStringSync();
+        // Normalize Windows line endings to Unix line endings so that the
+        // comparison doesn't fail on Windows.
+        actualContents = actualContents.replaceAll('\r\n', '\n');
+        if (expectedContents != actualContents) {
+          return false;
+        }
+      }
+      int nonHiddenFileCount = 0;
+      outputDirectory
+          .listSync(recursive: false, followLinks: false)
+          .forEach((FileSystemEntity fileSystemEntity) {
+        if (fileSystemEntity is File &&
+            !basename(fileSystemEntity.path).startsWith('.')) {
+          nonHiddenFileCount++;
+        }
+      });
+      if (nonHiddenFileCount != map.length) {
+        // The number of files generated doesn't match the number we expected to
+        // generate.
+        return false;
+      }
+    } catch (e) {
+      // There was a problem reading the file (most likely because it didn't
+      // exist).  Treat that the same as if the file doesn't have the expected
+      // contents.
+      return false;
+    }
+    return true;
+  }
+
+  @override
+  Future<void> generate(String pkgPath) async {
+    Directory outputDirectory = output(pkgPath);
+    try {
+      // delete the contents of the directory (and the directory itself)
+      outputDirectory.deleteSync(recursive: true);
+    } catch (e) {
+      // Error caught while trying to delete the directory, this can happen if
+      // it didn't yet exist.
+    }
+    // re-create the empty directory
+    outputDirectory.createSync(recursive: true);
+
+    // generate all of the files in the directory
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
+    for (String file in map.keys) {
+      FileContentsComputer fileContentsComputer = map[file];
+      File outputFile = new File(posix.join(outputDirectory.path, file));
+      print('  ${outputFile.path}');
+      String contents = await fileContentsComputer(pkgPath);
+      outputFile.writeAsStringSync(contents);
+    }
+  }
+
+  @override
+  Directory output(String pkgPath) =>
+      new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
+}
+
+/**
+ * Class representing a single output file (either generated code or generated
+ * HTML).
+ */
+class GeneratedFile extends GeneratedContent {
+  /**
+   * The output file to which generated output should be written, relative to
+   * the "tool/spec" directory.  This filename uses the posix path separator
+   * ('/') regardless of the OS.
+   */
+  final String outputPath;
+
+  /**
+   * Callback function which computes the file.
+   */
+  final FileContentsComputer computeContents;
+
+  GeneratedFile(this.outputPath, this.computeContents);
+
+  bool get isDartFile => outputPath.endsWith('.dart');
+
+  @override
+  Future<bool> check(String pkgPath) async {
+    File outputFile = output(pkgPath);
+    String expectedContents = await computeContents(pkgPath);
+    if (isDartFile) {
+      expectedContents = DartFormat.formatText(expectedContents);
+    }
+    try {
+      String actualContents = outputFile.readAsStringSync();
+      // Normalize Windows line endings to Unix line endings so that the
+      // comparison doesn't fail on Windows.
+      actualContents = actualContents.replaceAll('\r\n', '\n');
+      return expectedContents == actualContents;
+    } catch (e) {
+      // There was a problem reading the file (most likely because it didn't
+      // exist).  Treat that the same as if the file doesn't have the expected
+      // contents.
+      return false;
+    }
+  }
+
+  @override
+  Future<void> generate(String pkgPath) async {
+    File outputFile = output(pkgPath);
+    print('  ${outputFile.path}');
+    String contents = await computeContents(pkgPath);
+    outputFile.writeAsStringSync(contents);
+    if (isDartFile) {
+      DartFormat.formatFile(outputFile);
+    }
+  }
+
+  @override
+  File output(String pkgPath) =>
+      new File(join(pkgPath, joinAll(posix.split(outputPath))));
+}
+
+/**
+ * Mixin class for generating HTML representations of code that are suitable
+ * for enclosing inside a <pre> element.
+ */
+abstract class HtmlCodeGenerator {
+  _HtmlCodeGeneratorState _state;
+
+  /**
+   * Add the given [node] to the HTML output.
+   */
+  void add(dom.Node node) {
+    _state.add(node);
+  }
+
+  /**
+   * Add the given [nodes] to the HTML output.
+   */
+  void addAll(Iterable<dom.Node> nodes) {
+    for (dom.Node node in nodes) {
+      _state.add(node);
+    }
+  }
+
+  /**
+   * Execute [callback], collecting any code that is output using [write],
+   * [writeln], [add], or [addAll], and return the result as a list of DOM
+   * nodes.
+   */
+  List<dom.Node> collectHtml(void callback()) {
+    _HtmlCodeGeneratorState oldState = _state;
+    try {
+      _state = new _HtmlCodeGeneratorState();
+      if (callback != null) {
+        callback();
+      }
+      return _state.buffer;
+    } finally {
+      _state = oldState;
+    }
+  }
+
+  /**
+   * Execute [callback], wrapping its output in an element with the given
+   * [name] and [attributes].
+   */
+  void element(String name, Map<dynamic, String> attributes,
+      [void callback()]) {
+    add(makeElement(name, attributes, collectHtml(callback)));
+  }
+
+  /**
+   * Execute [callback], indenting any code it outputs by two spaces.
+   */
+  void indent(void callback()) {
+    String oldIndent = _state.indent;
+    try {
+      _state.indent += '  ';
+      callback();
+    } finally {
+      _state.indent = oldIndent;
+    }
+  }
+
+  /**
+   * Output text without ending the current line.
+   */
+  void write(Object obj) {
+    _state.write(obj.toString());
+  }
+
+  /**
+   * Output text, ending the current line.
+   */
+  void writeln([Object obj = '']) {
+    _state.write('$obj\n');
+  }
+}
+
+/**
+ * State used by [CodeGenerator].
+ */
+class _CodeGeneratorState {
+  StringBuffer buffer = new StringBuffer();
+  String nextIndent = '';
+  String indent = '';
+  bool indentNeeded = true;
+
+  void write(String text) {
+    List<String> lines = text.split('\n');
+    for (int i = 0; i < lines.length; i++) {
+      if (i == lines.length - 1 && lines[i].isEmpty) {
+        break;
+      }
+      if (indentNeeded) {
+        buffer.write(nextIndent);
+        nextIndent = indent;
+      }
+      indentNeeded = false;
+      buffer.write(lines[i]);
+      if (i != lines.length - 1) {
+        buffer.writeln();
+        indentNeeded = true;
+      }
+    }
+  }
+}
+
+/**
+ * State used by [HtmlCodeGenerator].
+ */
+class _HtmlCodeGeneratorState {
+  List<dom.Node> buffer = <dom.Node>[];
+  String indent = '';
+  bool indentNeeded = true;
+
+  void add(dom.Node node) {
+    if (node is dom.Text) {
+      write(node.text);
+    } else {
+      buffer.add(node);
+    }
+  }
+
+  void write(String text) {
+    if (text.isEmpty) {
+      return;
+    }
+    if (indentNeeded) {
+      buffer.add(new dom.Text(indent));
+    }
+    List<String> lines = text.split('\n');
+    if (lines.last.isEmpty) {
+      lines.removeLast();
+      buffer.add(new dom.Text(lines.join('\n$indent') + '\n'));
+      indentNeeded = true;
+    } else {
+      buffer.add(new dom.Text(lines.join('\n$indent')));
+      indentNeeded = false;
+    }
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/verify_tests.dart b/pkg/analyzer_utilities/lib/verify_tests.dart
new file mode 100644
index 0000000..ca6fe74
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/verify_tests.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/analysis_context_collection.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/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+/// Helper class to test that `test_all.dart` files are properly set up in the
+/// `analyzer` package (and related packages).
+class VerifyTests {
+  /// Path to the package's `test` subdirectory.
+  final String testDirPath;
+
+  /// Paths to exclude from analysis completely.
+  final List<String> excludedPaths;
+
+  VerifyTests(this.testDirPath, {this.excludedPaths});
+
+  /// Build tests.
+  void build() {
+    var provider = PhysicalResourceProvider.INSTANCE;
+    var collection = AnalysisContextCollection(
+        resourceProvider: provider,
+        includedPaths: <String>[testDirPath],
+        excludedPaths: excludedPaths);
+    var contexts = collection.contexts;
+    if (contexts.length != 1) {
+      fail('The test directory contains multiple analysis contexts.');
+    }
+
+    _buildTestsIn(contexts[0].currentSession, testDirPath,
+        provider.getFolder(testDirPath));
+  }
+
+  /// May be overridden in a derived class to indicate whether the test file or
+  /// directory indicated by [resource] is so expensive to run that it shouldn't
+  /// be included in `test_all.dart` files.
+  ///
+  /// Default behavior is not to consider any test files or directories
+  /// expensive.
+  bool isExpensive(Resource resource) => false;
+
+  /// May be overridden in a derived class to indicate whether it is ok for a
+  /// `test_all.dart` file in [folder] to import [uri], even if there is no
+  /// corresponding test file inside [folder].
+  ///
+  /// Default behavior is to allow imports of test framework URIs.
+  bool isOkAsAdditionalTestAllImport(Folder folder, String uri) => const [
+        'package:test/test.dart',
+        'package:test_reflective_loader/test_reflective_loader.dart'
+      ].contains(uri);
+
+  /// May be overridden in a derived class to indicate whether it is ok for
+  /// a `test_all.dart` file to be missing from [folder].
+  ///
+  /// Default beahvior is not to allow `test_all.dart` to be missing from any
+  /// folder.
+  bool isOkForTestAllToBeMissing(Folder folder) => false;
+
+  void _buildTestsIn(
+      AnalysisSession session, String testDirPath, Folder directory) {
+    var testFileNames = <String>[];
+    File testAllFile;
+    var children = directory.getChildren();
+    children
+        .sort((first, second) => first.shortName.compareTo(second.shortName));
+    for (var child in children) {
+      if (child is Folder) {
+        if (child.getChildAssumingFile('test_all.dart').exists &&
+            !isExpensive(child)) {
+          testFileNames.add('${child.shortName}/test_all.dart');
+        }
+        _buildTestsIn(session, testDirPath, child);
+      } else if (child is File) {
+        var name = child.shortName;
+        if (name == 'test_all.dart') {
+          testAllFile = child;
+        } else if (name.endsWith('_test.dart') && !isExpensive(child)) {
+          testFileNames.add(name);
+        }
+      }
+    }
+    var relativePath = path.relative(directory.path, from: testDirPath);
+    test(relativePath, () {
+      if (testFileNames.isEmpty) {
+        return;
+      }
+      if (testAllFile == null) {
+        if (!isOkForTestAllToBeMissing(directory)) {
+          fail('Missing "test_all.dart" in $relativePath');
+        } else {
+          // Ok that the `test_all.dart` file is missing; there's nothing else to
+          // check.
+          return;
+        }
+      }
+      if (isOkForTestAllToBeMissing(directory)) {
+        fail('Found "test_all.dart" in $relativePath but did not expect one');
+      }
+      var result = session.getParsedUnit(testAllFile.path);
+      if (result.state != ResultState.VALID) {
+        fail('Could not parse ${testAllFile.path}');
+      }
+      var importedFiles = <String>[];
+      for (var directive in result.unit.directives) {
+        if (directive is ImportDirective) {
+          importedFiles.add(directive.uri.stringValue);
+        }
+      }
+      var missingFiles = <String>[];
+      for (var testFileName in testFileNames) {
+        if (!importedFiles.contains(testFileName)) {
+          missingFiles.add(testFileName);
+        }
+      }
+      if (missingFiles.isNotEmpty) {
+        fail('Tests missing from "test_all.dart": ${missingFiles.join(', ')}');
+      }
+      var extraImports = <String>[];
+      for (var importedFile in importedFiles) {
+        if (!testFileNames.contains(importedFile) &&
+            !isOkAsAdditionalTestAllImport(directory, importedFile)) {
+          extraImports.add(importedFile);
+        }
+      }
+      if (extraImports.isNotEmpty) {
+        fail('Extra tests in "test_all.dart": ${extraImports.join(', ')}');
+      }
+    });
+  }
+}
diff --git a/pkg/analyzer_utilities/pubspec.yaml b/pkg/analyzer_utilities/pubspec.yaml
new file mode 100644
index 0000000..7142157
--- /dev/null
+++ b/pkg/analyzer_utilities/pubspec.yaml
@@ -0,0 +1,13 @@
+name: analyzer_utilities
+# This package is not intended for consumption on pub.dev. DO NOT publish.
+publish_to: none
+
+environment:
+  sdk: '>=2.1.0 <3.0.0'
+
+dependencies:
+  analyzer:
+    path: ../analyzer
+  html: any
+  path: any
+  test: any
diff --git a/pkg/build_integration/pubspec.yaml b/pkg/build_integration/pubspec.yaml
index b741a4b..a7b79b1 100644
--- a/pkg/build_integration/pubspec.yaml
+++ b/pkg/build_integration/pubspec.yaml
@@ -9,11 +9,8 @@
   sdk: '>=2.1.0 <3.0.0'
 
 dependencies:
-  front_end: any
+  front_end:
+    path: ../front_end
 
 dev_dependencies:
   test: any
-
-dependency_overrides:
-  front_end:
-    path: ../front_end
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index b042613..1c7d0ed 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -104,6 +104,8 @@
   static const String dillDependencies = '--dill-dependencies';
   static const String readData = '--read-data';
   static const String writeData = '--write-data';
+  static const String writeClosedWorld = '--write-closed-world';
+  static const String readClosedWorld = '--read-closed-world';
   static const String readCodegen = '--read-codegen';
   static const String writeCodegen = '--write-codegen';
   static const String codegenShard = '--codegen-shard';
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 7b7387c..8d84fe7 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -595,6 +595,13 @@
   /// compilation.
   bool isNamedListConstructor(String name, ConstructorEntity element);
 
+  /// Returns `true` if [element] is the named constructor of `JSArray`,
+  /// e.g. `JSArray.fixed`.
+  ///
+  /// This will not resolve the constructor if it hasn't been seen yet during
+  /// compilation.
+  bool isNamedJSArrayConstructor(String name, ConstructorEntity element);
+
   bool isDefaultEqualityImplementation(MemberEntity element);
 
   /// Returns `true` if [selector] applies to `JSIndexable.length`.
@@ -885,6 +892,14 @@
   bool isNamedListConstructor(String name, ConstructorEntity element) =>
       element.name == name && element.enclosingClass == listClass;
 
+  /// Returns `true` if [element] is the [name]d constructor of `JSArray`.
+  ///
+  /// This will not resolve the constructor if it hasn't been seen yet during
+  /// compilation.
+  @override
+  bool isNamedJSArrayConstructor(String name, ConstructorEntity element) =>
+      element.name == name && element.enclosingClass == jsArrayClass;
+
   @override
   DynamicType get dynamicType => _env.dynamicType;
 
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 62d62d5..05bf1ff 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -8,6 +8,7 @@
 
 import 'package:front_end/src/api_unstable/dart2js.dart'
     show clearStringTokenCanonicalizer;
+import 'package:kernel/ast.dart' as ir;
 
 import '../compiler_new.dart' as api;
 import 'backend_strategy.dart';
@@ -37,6 +38,7 @@
 import 'js_backend/backend.dart' show CodegenInputs, JavaScriptImpactStrategy;
 import 'js_backend/inferred_data.dart';
 import 'js_model/js_strategy.dart';
+import 'js_model/js_world.dart';
 import 'kernel/kernel_strategy.dart';
 import 'kernel/loader.dart' show KernelLoaderTask, KernelResult;
 import 'null_compiler_output.dart' show NullCompilerOutput;
@@ -140,7 +142,7 @@
     abstractValueStrategy = options.useTrivialAbstractValueDomain
         ? const TrivialAbstractValueStrategy()
         : const TypeMaskStrategy();
-    if (options.experimentalWrapped) {
+    if (options.experimentalWrapped || options.testMode) {
       abstractValueStrategy =
           WrappedAbstractValueStrategy(abstractValueStrategy);
     } else if (options.experimentalPowersets) {
@@ -228,16 +230,46 @@
         });
       });
 
+  bool get onlyPerformGlobalTypeInference {
+    return options.readClosedWorldUri != null &&
+        options.readDataUri == null &&
+        options.readCodegenUri == null;
+  }
+
   Future runInternal(Uri uri) async {
     clearState();
     assert(uri != null);
-    // As far as I can tell, this branch is only used by test code.
     reporter.log('Compiling $uri (${options.buildId})');
 
-    if (options.readDataUri != null) {
+    if (onlyPerformGlobalTypeInference) {
+      ir.Component component =
+          await serializationTask.deserializeComponentAndUpdateOptions();
+      JsClosedWorld closedWorld =
+          await serializationTask.deserializeClosedWorld(
+              environment, abstractValueStrategy, component);
       GlobalTypeInferenceResults globalTypeInferenceResults =
-          await serializationTask.deserializeGlobalTypeInference(
-              environment, abstractValueStrategy);
+          performGlobalTypeInference(closedWorld);
+      if (options.writeDataUri != null) {
+        serializationTask
+            .serializeGlobalTypeInference(globalTypeInferenceResults);
+        return;
+      }
+      await generateJavaScriptCode(globalTypeInferenceResults);
+    } else if (options.readDataUri != null) {
+      GlobalTypeInferenceResults globalTypeInferenceResults;
+      if (options.readClosedWorldUri != null) {
+        ir.Component component =
+            await serializationTask.deserializeComponentAndUpdateOptions();
+        JsClosedWorld closedWorld =
+            await serializationTask.deserializeClosedWorld(
+                environment, abstractValueStrategy, component);
+        globalTypeInferenceResults =
+            await serializationTask.deserializeGlobalAnalysis(
+                environment, abstractValueStrategy, component, closedWorld);
+      } else {
+        globalTypeInferenceResults = await serializationTask
+            .deserializeGlobalTypeInference(environment, abstractValueStrategy);
+      }
       if (options.debugGlobalInference) {
         performGlobalTypeInference(globalTypeInferenceResults.closedWorld);
         return;
@@ -362,9 +394,6 @@
 
     JClosedWorld closedWorld =
         closeResolution(mainFunction, resolutionEnqueuer.worldBuilder);
-    if (retainDataForTesting) {
-      backendClosedWorldForTesting = closedWorld;
-    }
     return closedWorld;
   }
 
@@ -409,37 +438,50 @@
     checkQueue(codegenEnqueuer);
   }
 
+  GlobalTypeInferenceResults globalTypeInferenceResultsTestMode(
+      GlobalTypeInferenceResults results) {
+    SerializationStrategy strategy = const BytesInMemorySerializationStrategy();
+    List<int> irData = strategy.unpackAndSerializeComponent(results);
+    List worldData = strategy.serializeGlobalTypeInferenceResults(results);
+    return strategy.deserializeGlobalTypeInferenceResults(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        strategy.deserializeComponent(irData),
+        worldData);
+  }
+
   void compileFromKernel(Uri rootLibraryUri, Iterable<Uri> libraries) {
     _userCodeLocations.add(new CodeLocation(rootLibraryUri));
     selfTask.measureSubtask("compileFromKernel", () {
-      JClosedWorld closedWorld = selfTask.measureSubtask("computeClosedWorld",
+      JsClosedWorld closedWorld = selfTask.measureSubtask("computeClosedWorld",
           () => computeClosedWorld(rootLibraryUri, libraries));
-      if (stopAfterClosedWorld) return;
-      if (closedWorld != null) {
-        GlobalTypeInferenceResults globalInferenceResults =
-            performGlobalTypeInference(closedWorld);
-        if (options.writeDataUri != null) {
-          serializationTask
-              .serializeGlobalTypeInference(globalInferenceResults);
-          return;
-        }
-        if (options.testMode) {
-          SerializationStrategy strategy =
-              const BytesInMemorySerializationStrategy();
-          List<int> irData =
-              strategy.serializeComponent(globalInferenceResults);
-          List worldData = strategy.serializeData(globalInferenceResults);
-          globalInferenceResults = strategy.deserializeData(
-              options,
-              reporter,
-              environment,
-              abstractValueStrategy,
-              strategy.deserializeComponent(irData),
-              worldData);
-        }
-        if (stopAfterTypeInference) return;
-        generateJavaScriptCode(globalInferenceResults);
+      if (closedWorld == null) return;
+
+      if (retainDataForTesting) {
+        backendClosedWorldForTesting = closedWorld;
       }
+
+      if (options.writeClosedWorldUri != null) {
+        serializationTask.serializeComponent(
+            closedWorld.elementMap.programEnv.mainComponent);
+        serializationTask.serializeClosedWorld(closedWorld);
+        return;
+      }
+      if (stopAfterClosedWorld) return;
+      GlobalTypeInferenceResults globalInferenceResults =
+          performGlobalTypeInference(closedWorld);
+      if (options.writeDataUri != null) {
+        serializationTask.serializeGlobalTypeInference(globalInferenceResults);
+        return;
+      }
+      if (options.testMode) {
+        globalInferenceResults =
+            globalTypeInferenceResultsTestMode(globalInferenceResults);
+      }
+      if (stopAfterTypeInference) return;
+      generateJavaScriptCode(globalInferenceResults);
     });
   }
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 7142b49..11b8c5d 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -107,6 +107,8 @@
   Uri sourceMapOut;
   Uri readDataUri;
   Uri writeDataUri;
+  Uri readClosedWorldUri;
+  Uri writeClosedWorldUri;
   Uri readCodegenUri;
   Uri writeCodegenUri;
   int codegenShard;
@@ -115,7 +117,7 @@
   List<Uri> multiRoots;
   String multiRootScheme = 'org-dartlang-app';
   Uri packageConfig = null;
-  List<String> options = new List<String>();
+  List<String> options = <String>[];
   bool wantHelp = false;
   bool wantVersion = false;
   bool trustTypeAnnotations = false;
@@ -267,6 +269,14 @@
     }
   }
 
+  void setReadClosedWorld(String argument) {
+    if (argument != Flags.readClosedWorld) {
+      readClosedWorldUri =
+          fe.nativeToUri(extractPath(argument, isDirectory: false));
+    }
+    readStrategy = ReadStrategy.fromClosedWorld;
+  }
+
   void setDillDependencies(String argument) {
     String dependencies = extractParameter(argument);
     String uriDependencies = dependencies.splitMapJoin(',',
@@ -275,6 +285,10 @@
   }
 
   void setCfeOnly(String argument) {
+    if (writeStrategy == WriteStrategy.toClosedWorld) {
+      fail("Cannot use ${Flags.cfeOnly} "
+          "and write serialized closed world simultaneously.");
+    }
     if (writeStrategy == WriteStrategy.toData) {
       fail("Cannot use ${Flags.cfeOnly} "
           "and write serialized data simultaneously.");
@@ -299,6 +313,9 @@
       fail("Cannot use ${Flags.cfeOnly} "
           "and write serialized data simultaneously.");
     }
+    if (writeStrategy == WriteStrategy.toClosedWorld) {
+      fail("Cannot write closed world and data simultaneously.");
+    }
     if (writeStrategy == WriteStrategy.toCodegen) {
       fail("Cannot write serialized data and codegen simultaneously.");
     }
@@ -308,11 +325,32 @@
     writeStrategy = WriteStrategy.toData;
   }
 
+  void setWriteClosedWorld(String argument) {
+    if (writeStrategy == WriteStrategy.toKernel) {
+      fail("Cannot use ${Flags.cfeOnly} "
+          "and write serialized data simultaneously.");
+    }
+    if (writeStrategy == WriteStrategy.toData) {
+      fail("Cannot write both closed world and data");
+    }
+    if (writeStrategy == WriteStrategy.toCodegen) {
+      fail("Cannot write serialized data and codegen simultaneously.");
+    }
+    if (argument != Flags.writeClosedWorld) {
+      writeClosedWorldUri =
+          fe.nativeToUri(extractPath(argument, isDirectory: false));
+    }
+    writeStrategy = WriteStrategy.toClosedWorld;
+  }
+
   void setWriteCodegen(String argument) {
     if (writeStrategy == WriteStrategy.toKernel) {
       fail("Cannot use ${Flags.cfeOnly} "
           "and write serialized codegen simultaneously.");
     }
+    if (writeStrategy == WriteStrategy.toClosedWorld) {
+      fail("Cannot write closed world and codegen simultaneously.");
+    }
     if (writeStrategy == WriteStrategy.toData) {
       fail("Cannot write serialized data and codegen data simultaneously.");
     }
@@ -415,6 +453,10 @@
     new OptionHandler('${Flags.dillDependencies}=.+', setDillDependencies),
     new OptionHandler('${Flags.readData}|${Flags.readData}=.+', setReadData),
     new OptionHandler('${Flags.writeData}|${Flags.writeData}=.+', setWriteData),
+    new OptionHandler('${Flags.readClosedWorld}|${Flags.readClosedWorld}=.+',
+        setReadClosedWorld),
+    new OptionHandler('${Flags.writeClosedWorld}|${Flags.writeClosedWorld}=.+',
+        setWriteClosedWorld),
     new OptionHandler(
         '${Flags.readCodegen}|${Flags.readCodegen}=.+', setReadCodegen),
     new OptionHandler(
@@ -606,7 +648,10 @@
     case WriteStrategy.toKernel:
       out ??= Uri.base.resolve('out.dill');
       options.add(Flags.cfeOnly);
-      if (readStrategy == ReadStrategy.fromData) {
+      if (readStrategy == ReadStrategy.fromClosedWorld) {
+        fail("Cannot use ${Flags.cfeOnly} "
+            "and read serialized closed world simultaneously.");
+      } else if (readStrategy == ReadStrategy.fromData) {
         fail("Cannot use ${Flags.cfeOnly} "
             "and read serialized data simultaneously.");
       } else if (readStrategy == ReadStrategy.fromCodegen) {
@@ -614,6 +659,19 @@
             "and read serialized codegen simultaneously.");
       }
       break;
+    case WriteStrategy.toClosedWorld:
+      out ??= Uri.base.resolve('out.dill');
+      writeClosedWorldUri ??= Uri.base.resolve('$out.world');
+      options.add('${Flags.writeClosedWorld}=${writeClosedWorldUri}');
+      if (readStrategy == ReadStrategy.fromClosedWorld) {
+        fail("Cannot read and write serialized data simultaneously.");
+      } else if (readStrategy == ReadStrategy.fromData) {
+        fail("Cannot read from both closed world and data");
+      } else if (readStrategy == ReadStrategy.fromCodegen) {
+        fail("Cannot read serialized codegen and "
+            "write serialized data simultaneously.");
+      }
+      break;
     case WriteStrategy.toData:
       out ??= Uri.base.resolve('out.dill');
       writeDataUri ??= Uri.base.resolve('$out.data');
@@ -657,10 +715,20 @@
   switch (readStrategy) {
     case ReadStrategy.fromDart:
       break;
+    case ReadStrategy.fromClosedWorld:
+      readClosedWorldUri ??= Uri.base.resolve('$scriptName.world');
+      options.add('${Flags.readClosedWorld}=${readClosedWorldUri}');
+      break;
     case ReadStrategy.fromData:
       readDataUri ??= Uri.base.resolve('$scriptName.data');
       options.add('${Flags.readData}=${readDataUri}');
       break;
+    case ReadStrategy.fromDataAndClosedWorld:
+      readClosedWorldUri ??= Uri.base.resolve('$scriptName.world');
+      options.add('${Flags.readClosedWorld}=${readClosedWorldUri}');
+      readDataUri ??= Uri.base.resolve('$scriptName.data');
+      options.add('${Flags.readData}=${readDataUri}');
+      break;
     case ReadStrategy.fromCodegen:
       readDataUri ??= Uri.base.resolve('$scriptName.data');
       options.add('${Flags.readData}=${readDataUri}');
@@ -673,6 +741,22 @@
         fail("${Flags.codegenShards} must be a positive integer.");
       }
       options.add('${Flags.codegenShards}=$codegenShards');
+      break;
+    case ReadStrategy.fromCodegenAndClosedWorld:
+      readClosedWorldUri ??= Uri.base.resolve('$scriptName.world');
+      options.add('${Flags.readClosedWorld}=${readClosedWorldUri}');
+      readDataUri ??= Uri.base.resolve('$scriptName.data');
+      options.add('${Flags.readData}=${readDataUri}');
+      readCodegenUri ??= Uri.base.resolve('$scriptName.code');
+      options.add('${Flags.readCodegen}=${readCodegenUri}');
+      if (codegenShards == null) {
+        fail("Cannot write serialized codegen without setting "
+            "${Flags.codegenShards}.");
+      } else if (codegenShards <= 0) {
+        fail("${Flags.codegenShards} must be a positive integer.");
+      }
+      options.add('${Flags.codegenShards}=$codegenShards');
+      break;
   }
   options.add('--out=$out');
   if (writeStrategy == WriteStrategy.toJs) {
@@ -707,6 +791,13 @@
         inputSize = inputProvider.dartCharactersRead;
         summary = 'Dart file $input ';
         break;
+      case ReadStrategy.fromClosedWorld:
+        inputName = 'bytes data';
+        inputSize = inputProvider.dartCharactersRead;
+        String dataInput =
+            fe.relativizeUri(Uri.base, readClosedWorldUri, Platform.isWindows);
+        summary = 'Data files $input and $dataInput ';
+        break;
       case ReadStrategy.fromData:
         inputName = 'bytes data';
         inputSize = inputProvider.dartCharactersRead;
@@ -714,6 +805,15 @@
             fe.relativizeUri(Uri.base, readDataUri, Platform.isWindows);
         summary = 'Data files $input and $dataInput ';
         break;
+      case ReadStrategy.fromDataAndClosedWorld:
+        inputName = 'bytes data';
+        inputSize = inputProvider.dartCharactersRead;
+        String worldInput =
+            fe.relativizeUri(Uri.base, readClosedWorldUri, Platform.isWindows);
+        String dataInput =
+            fe.relativizeUri(Uri.base, readDataUri, Platform.isWindows);
+        summary = 'Data files $input, $worldInput, and $dataInput ';
+        break;
       case ReadStrategy.fromCodegen:
         inputName = 'bytes data';
         inputSize = inputProvider.dartCharactersRead;
@@ -724,6 +824,18 @@
         summary = 'Data files $input, $dataInput and '
             '${codeInput}[0-${codegenShards - 1}] ';
         break;
+      case ReadStrategy.fromCodegenAndClosedWorld:
+        inputName = 'bytes data';
+        inputSize = inputProvider.dartCharactersRead;
+        String worldInput =
+            fe.relativizeUri(Uri.base, readClosedWorldUri, Platform.isWindows);
+        String dataInput =
+            fe.relativizeUri(Uri.base, readDataUri, Platform.isWindows);
+        String codeInput =
+            fe.relativizeUri(Uri.base, readCodegenUri, Platform.isWindows);
+        summary = 'Data files $input, $worldInput, $dataInput and '
+            '${codeInput}[0-${codegenShards - 1}] ';
+        break;
     }
 
     switch (writeStrategy) {
@@ -742,6 +854,15 @@
         String output = fe.relativizeUri(Uri.base, out, Platform.isWindows);
         summary += 'compiled to dill: ${output}.';
         break;
+      case WriteStrategy.toClosedWorld:
+        processName = 'Serialized';
+        outputName = 'bytes data';
+        outputSize = outputProvider.totalDataWritten;
+        String output = fe.relativizeUri(Uri.base, out, Platform.isWindows);
+        String dataOutput =
+            fe.relativizeUri(Uri.base, writeClosedWorldUri, Platform.isWindows);
+        summary += 'serialized to dill and data: ${output} and ${dataOutput}.';
+        break;
       case WriteStrategy.toData:
         processName = 'Serialized';
         outputName = 'bytes data';
@@ -1235,5 +1356,12 @@
   });
 }
 
-enum ReadStrategy { fromDart, fromData, fromCodegen }
-enum WriteStrategy { toKernel, toData, toCodegen, toJs }
+enum ReadStrategy {
+  fromDart,
+  fromClosedWorld,
+  fromData,
+  fromDataAndClosedWorld,
+  fromCodegen,
+  fromCodegenAndClosedWorld
+}
+enum WriteStrategy { toKernel, toClosedWorld, toData, toCodegen, toJs }
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index bc001f7..3e82de2 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -442,7 +442,7 @@
   void reportInlined(FunctionEntity element, MemberEntity inlinedFrom) {
     inlineCount.putIfAbsent(element, () => 0);
     inlineCount[element] += 1;
-    inlineMap.putIfAbsent(inlinedFrom, () => new List<Entity>());
+    inlineMap.putIfAbsent(inlinedFrom, () => <Entity>[]);
     inlineMap[inlinedFrom].add(element);
   }
 
@@ -486,9 +486,7 @@
   void registerEntityAst(Entity entity, jsAst.Node code,
       {LibraryEntity library}) {
     if (compiler.options.dumpInfo) {
-      _entityToNodes
-          .putIfAbsent(entity, () => new List<jsAst.Node>())
-          .add(code);
+      _entityToNodes.putIfAbsent(entity, () => <jsAst.Node>[]).add(code);
       _nodeData[code] ??= useBinaryFormat ? new CodeSpan() : new _CodeData();
     }
   }
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 7cb8bc2..8a660e2 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -28,7 +28,7 @@
   List<DartType> _readDartTypes(
       List<FunctionTypeVariable> functionTypeVariables) {
     int count = readInt();
-    List<DartType> types = List<DartType>(count);
+    List<DartType> types = List<DartType>.filled(count, null);
     for (int index = 0; index < count; index++) {
       types[index] = DartType.readFromDataSource(this, functionTypeVariables);
     }
@@ -717,7 +717,8 @@
         source._readDartTypes(functionTypeVariables);
     List<DartType> namedParameterTypes =
         source._readDartTypes(functionTypeVariables);
-    List<String> namedParameters = List<String>(namedParameterTypes.length);
+    List<String> namedParameters =
+        List<String>.filled(namedParameterTypes.length, null);
     var requiredNamedParameters = <String>{};
     for (int i = 0; i < namedParameters.length; i++) {
       namedParameters[i] = source.readString();
@@ -1036,7 +1037,7 @@
     var length = oldTypeVariables.length;
 
     List<FunctionTypeVariable> typeVariables =
-        List<FunctionTypeVariable>(length);
+        List<FunctionTypeVariable>.filled(length, null);
     List<FunctionTypeVariable> erasableTypeVariables = [];
     List<FunctionTypeVariable> erasedTypeVariables = [];
     for (int i = 0; i < length; i++) {
diff --git a/pkg/compiler/lib/src/helpers/expensive_map.dart b/pkg/compiler/lib/src/helpers/expensive_map.dart
index 149e811..91098f5 100644
--- a/pkg/compiler/lib/src/helpers/expensive_map.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_map.dart
@@ -10,7 +10,7 @@
 class ExpensiveMap<K, V> extends MapBase<K, V> {
   final List _maps;
 
-  ExpensiveMap([int copies = 10]) : _maps = new List(copies) {
+  ExpensiveMap([int copies = 10]) : _maps = new List.filled(copies, null) {
     assert(copies > 0);
     for (int i = 0; i < _maps.length; i++) {
       _maps[i] = new Map<K, V>();
diff --git a/pkg/compiler/lib/src/helpers/expensive_set.dart b/pkg/compiler/lib/src/helpers/expensive_set.dart
index 4c5101e..cc41f8b 100644
--- a/pkg/compiler/lib/src/helpers/expensive_set.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_set.dart
@@ -10,7 +10,7 @@
 class ExpensiveSet<E> extends SetBase<E> {
   final List _sets;
 
-  ExpensiveSet([int copies = 10]) : _sets = new List(copies) {
+  ExpensiveSet([int copies = 10]) : _sets = new List.filled(copies, null) {
     assert(copies > 0);
     for (int i = 0; i < _sets.length; i++) {
       _sets[i] = new Set<E>();
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index afc24a3..55d7ab6 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1296,10 +1296,11 @@
       // We have something like `List.empty(growable: true)`.
       TypeInformation baseType =
           _listBaseType(arguments, defaultGrowable: false);
+      TypeInformation elementType = _types.nonNullEmpty(); // No elements!
       return _inferrer.concreteTypes.putIfAbsent(
           node,
           () => _types.allocateList(
-              baseType, node, _analyzedMember, _types.nonNullEmpty(), 0));
+              baseType, node, _analyzedMember, elementType, 0));
     }
     if (commonElements.isNamedListConstructor('of', constructor) ||
         commonElements.isNamedListConstructor('from', constructor)) {
@@ -1314,6 +1315,44 @@
           () => _types.allocateList(
               baseType, node, _analyzedMember, elementType));
     }
+
+    // `JSArray.fixed` corresponds to `new Array(length)`, which is a list
+    // filled with `null`.
+    if (commonElements.isNamedJSArrayConstructor('fixed', constructor)) {
+      int length = _findLength(arguments);
+      TypeInformation elementType = _types.nullType;
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(_types.fixedListType, node, _analyzedMember,
+              elementType, length));
+    }
+
+    // `JSArray.allocateFixed` creates an array with 'no elements'. The contract
+    // is that the caller will assign a value to each member before any element
+    // is accessed. We can start tracking the element type as 'bottom'.
+    if (commonElements.isNamedJSArrayConstructor(
+        'allocateFixed', constructor)) {
+      int length = _findLength(arguments);
+      TypeInformation elementType = _types.nonNullEmpty();
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(_types.fixedListType, node, _analyzedMember,
+              elementType, length));
+    }
+
+    // `JSArray.allocateGrowable` creates an array with 'no elements'. The
+    // contract is that the caller will assign a value to each member before any
+    // element is accessed. We can start tracking the element type as 'bottom'.
+    if (commonElements.isNamedJSArrayConstructor(
+        'allocateGrowable', constructor)) {
+      int length = _findLength(arguments);
+      TypeInformation elementType = _types.nonNullEmpty();
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(_types.growableListType, node,
+              _analyzedMember, elementType, length));
+    }
+
     if (_isConstructorOfTypedArraySubclass(constructor)) {
       // We have something like `Uint32List(len)`.
       int length = _findLength(arguments);
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 809b850..18eb0ca 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -15,7 +15,7 @@
 class ClosureTracerVisitor extends TracerVisitor {
   final Iterable<FunctionEntity> tracedElements;
   final List<CallSiteTypeInformation> _callsToAnalyze =
-      new List<CallSiteTypeInformation>();
+      <CallSiteTypeInformation>[];
 
   ClosureTracerVisitor(this.tracedElements, ApplyableTypeInformation tracedType,
       InferrerEngine inferrer)
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index db86752..17bb7ed 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -6,6 +6,7 @@
 
 import '../common/names.dart';
 import '../elements/entities.dart';
+import '../native/behavior.dart';
 import '../universe/selector.dart' show Selector;
 import '../util/util.dart' show Setlet;
 import 'node_tracer.dart';
@@ -162,10 +163,16 @@
   @override
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
     super.visitStaticCallSiteTypeInformation(info);
+    final commonElements = inferrer.closedWorld.commonElements;
     MemberEntity called = info.calledElement;
-    if (inferrer.closedWorld.commonElements.isForeign(called) &&
-        called.name == Identifiers.JS) {
-      bailout('Used in JS ${info.debugName}');
+    if (commonElements.isForeign(called) && called.name == Identifiers.JS) {
+      NativeBehavior nativeBehavior = inferrer.closedWorld.elementMap
+          .getNativeBehaviorForJsCall(info.invocationNode);
+      // Assume side-effects means that the list has escaped to some unknown
+      // location.
+      if (nativeBehavior.sideEffects.hasSideEffects()) {
+        bailout('Used in JS ${info.debugName}');
+      }
     }
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index c215ca1..ac9c901 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -136,7 +136,7 @@
 class _GraphGenerator extends TypeInformationVisitor {
   final TypeGraphDump global;
   final Set<TypeInformation> seen = new Set<TypeInformation>();
-  final List<TypeInformation> worklist = new List<TypeInformation>();
+  final List<TypeInformation> worklist = <TypeInformation>[];
   final Map<TypeInformation, int> nodeId = <TypeInformation, int>{};
   final String Function(AbstractValue) formatType;
   int usedIds = 0;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 365500e..f791743 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -115,7 +115,8 @@
 
   // The below is not a compile time constant to make it differentiable
   // from other empty lists of [TypeInformation].
-  static final STOP_TRACKING_INPUTS_MARKER = new List<TypeInformation>(0);
+  static final STOP_TRACKING_INPUTS_MARKER =
+      new List<TypeInformation>.filled(0, null);
 
   bool areInputsTracked() {
     return inputs != STOP_TRACKING_INPUTS_MARKER;
@@ -968,6 +969,8 @@
       : super(abstractValueDomain, context, call, enclosing, selector,
             arguments, inLoop);
 
+  ir.StaticInvocation get invocationNode => _call as ir.StaticInvocation;
+
   MemberTypeInformation _getCalledTypeInfo(InferrerEngine inferrer) {
     return inferrer.types.getInferredTypeOfMember(calledElement);
   }
diff --git a/pkg/compiler/lib/src/io/source_map_builder.dart b/pkg/compiler/lib/src/io/source_map_builder.dart
index 654c87b..a630dd5 100644
--- a/pkg/compiler/lib/src/io/source_map_builder.dart
+++ b/pkg/compiler/lib/src/io/source_map_builder.dart
@@ -22,7 +22,7 @@
   final Uri targetFileUri;
 
   final LocationProvider locationProvider;
-  final List<SourceMapEntry> entries = new List<SourceMapEntry>();
+  final List<SourceMapEntry> entries = <SourceMapEntry>[];
 
   /// Extension used to deobfuscate minified names in error messages.
   final Map<String, String> minifiedGlobalNames;
diff --git a/pkg/compiler/lib/src/ir/cached_static_type.dart b/pkg/compiler/lib/src/ir/cached_static_type.dart
index 9e12e6c..2aca746 100644
--- a/pkg/compiler/lib/src/ir/cached_static_type.dart
+++ b/pkg/compiler/lib/src/ir/cached_static_type.dart
@@ -3,9 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 import 'static_type_base.dart';
 import 'static_type_cache.dart';
diff --git a/pkg/compiler/lib/src/ir/element_map.dart b/pkg/compiler/lib/src/ir/element_map.dart
index 9ef5260..4a782ce 100644
--- a/pkg/compiler/lib/src/ir/element_map.dart
+++ b/pkg/compiler/lib/src/ir/element_map.dart
@@ -3,9 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
 import '../common_elements.dart';
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index b5a7e94..2dd1fcb 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -3,8 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 import '../serialization/serialization.dart';
 import '../util/enumset.dart';
diff --git a/pkg/compiler/lib/src/ir/modular.dart b/pkg/compiler/lib/src/ir/modular.dart
index 37eb213..ed49fcb 100644
--- a/pkg/compiler/lib/src/ir/modular.dart
+++ b/pkg/compiler/lib/src/ir/modular.dart
@@ -3,10 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 import '../js_backend/annotations.dart';
 import '../util/enumset.dart';
diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart
index 7806fae..d2f8225 100644
--- a/pkg/compiler/lib/src/ir/scope_visitor.dart
+++ b/pkg/compiler/lib/src/ir/scope_visitor.dart
@@ -4,7 +4,6 @@
 
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
-import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
 
 import '../ir/constants.dart';
 import 'closure.dart';
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 2b6981c..9527cd2 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -4,7 +4,6 @@
 
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
 import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 import '../common/names.dart';
@@ -645,7 +644,8 @@
     if (arguments.positional.isEmpty) {
       positional = const <ir.DartType>[];
     } else {
-      positional = new List<ir.DartType>(arguments.positional.length);
+      positional =
+          new List<ir.DartType>.filled(arguments.positional.length, null);
       int index = 0;
       for (ir.Expression argument in arguments.positional) {
         positional[index++] = visitNode(argument);
@@ -654,7 +654,7 @@
     if (arguments.named.isEmpty) {
       named = const <ir.DartType>[];
     } else {
-      named = new List<ir.DartType>(arguments.named.length);
+      named = new List<ir.DartType>.filled(arguments.named.length, null);
       int index = 0;
       for (ir.NamedExpression argument in arguments.named) {
         named[index++] = visitNode(argument);
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index 246ed21..fe3d62b 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -3,9 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
 /// Special bottom type used to signal that an expression or statement does
diff --git a/pkg/compiler/lib/src/ir/static_type_cache.dart b/pkg/compiler/lib/src/ir/static_type_cache.dart
index 2e25d65..dc20d4b 100644
--- a/pkg/compiler/lib/src/ir/static_type_cache.dart
+++ b/pkg/compiler/lib/src/ir/static_type_cache.dart
@@ -3,10 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 import '../serialization/serialization.dart';
 
diff --git a/pkg/compiler/lib/src/ir/static_type_provider.dart b/pkg/compiler/lib/src/ir/static_type_provider.dart
index ee0db10..2dc7ace 100644
--- a/pkg/compiler/lib/src/ir/static_type_provider.dart
+++ b/pkg/compiler/lib/src/ir/static_type_provider.dart
@@ -3,10 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 /// Interface for accessing static types on expressions.
 abstract class StaticTypeProvider {
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index fc79ee4..1db528a 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -3,9 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
 import '../elements/entities.dart';
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index d375fed..8d3d497 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -3,10 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index c2f8403..dd31e3b 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -18,11 +18,14 @@
 String prettyPrint(Node node,
     {bool enableMinification: false,
     bool allowVariableMinification: true,
+    bool preferSemicolonToNewlineInMinifiedOutput: false,
     Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) {
   // TODO(johnniwinther): Do we need all the options here?
   JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
       shouldCompressOutput: enableMinification,
       minifyLocalVariables: allowVariableMinification,
+      preferSemicolonToNewlineInMinifiedOutput:
+          preferSemicolonToNewlineInMinifiedOutput,
       renamerForNames: renamerForNames);
   SimpleJavaScriptPrintingContext context =
       new SimpleJavaScriptPrintingContext();
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 60e8c84..53e156a 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1400,7 +1400,7 @@
     breakLabels[node] = after;
 
     beginLabel(before);
-    List<int> labels = new List<int>(node.cases.length);
+    List<int> labels = new List<int>.filled(node.cases.length, null);
 
     bool anyCaseExpressionTransformed = node.cases.any(
         (js.SwitchClause x) => x is js.Case && shouldTransform(x.expression));
diff --git a/pkg/compiler/lib/src/js/size_estimator.dart b/pkg/compiler/lib/src/js/size_estimator.dart
new file mode 100644
index 0000000..60d0354
--- /dev/null
+++ b/pkg/compiler/lib/src/js/size_estimator.dart
@@ -0,0 +1,1042 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library js.size_estimator;
+
+import 'package:js_ast/js_ast.dart';
+import 'package:js_ast/src/characters.dart' as charCodes;
+import 'package:js_ast/src/precedence.dart';
+
+import '../js_backend/string_reference.dart';
+import '../js_backend/type_reference.dart';
+import '../js_emitter/metadata_collector.dart';
+
+/// [SizeEstimator] is a [NodeVisitor] designed to produce a consistent size
+/// estimate for a given JavaScript AST. [SizeEstimator] trades accuracy for
+/// stability and performance. In addition, [SizeEstimator] assumes we will emit
+/// production quality minified JavaScript.
+class SizeEstimator implements NodeVisitor {
+  int charCount = 0;
+  bool inForInit = false;
+  bool atStatementBegin = false;
+  bool pendingSemicolon = false;
+  bool pendingSpace = false;
+
+  static final String variableSizeEstimate = '#';
+  static final String nameSizeEstimate = '###';
+
+  String sizeEstimate(Node node) {
+    if (node is VariableDeclaration || node is VariableUse) {
+      // We assume all [VariableDeclaration] and [VariableUse] nodes are
+      // locals.
+      return variableSizeEstimate;
+    } else if (node is Name ||
+        node is Parameter ||
+        node is VariableDeclaration ||
+        node is VariableUse) {
+      return nameSizeEstimate;
+    } else if (node is LiteralString) {
+      assert(!node.isFinalized);
+      // We assume all non-final literal strings are minified names, and thus
+      // use the nameSizeEstimate.
+      return nameSizeEstimate;
+    } else if (node is BoundMetadataEntry) {
+      // Value is an int.
+      return '####';
+    } else if (node is TypeReference) {
+      // Type references vary in size. Some references look like:
+      // '<typeHolder>$.<type>' where <typeHolder> is a one byte local and
+      // <type> is roughly 3 bytes. However, we also have to initialize the type
+      // in the holder, some like ab:f("QQ<b7c>"), ie 16 bytes. For two
+      // occurences we will have on average 13 bytes. For a more detailed
+      // estimate, we'd have to partially finalize the results.
+      return '###_###_###_#';
+    } else if (node is StringReference) {
+      // Worst case we have to inline the string so size of string + 2 bytes for
+      // quotes.
+      return "'${node.constant}'";
+    } else {
+      throw UnsupportedError('$node type is not supported');
+    }
+  }
+
+  /// Always emit a newline, even under `enableMinification`.
+  void forceLine() {
+    out('\n'); // '\n'
+  }
+
+  void out(String s) {
+    if (s.length > 0) {
+      // We can elide a semicolon in some cases, but for simplicity we
+      // assume a semicolon is needed here.
+      if (pendingSemicolon) {
+        emit(';'); // ';'
+      }
+
+      // We can elide a pending space in some cases, but for simplicity we
+      // assume a space is needed here.
+      if (pendingSpace) {
+        emit(' '); // ' '
+      }
+      pendingSpace = false;
+      pendingSemicolon = false;
+      emit(s); // str
+    }
+  }
+
+  void outSemicolonLn() {
+    pendingSemicolon = true;
+  }
+
+  void emit(String s) {
+    charCount += s.length;
+  }
+
+  void visit(Node node) {
+    node.accept(this);
+  }
+
+  void visitCommaSeparated(List<Node> nodes, int hasRequiredType,
+      {bool newInForInit, bool newAtStatementBegin}) {
+    for (int i = 0; i < nodes.length; i++) {
+      if (i != 0) {
+        atStatementBegin = false;
+        out(','); // ','
+      }
+      visitNestedExpression(nodes[i], hasRequiredType,
+          newInForInit: newInForInit, newAtStatementBegin: newAtStatementBegin);
+    }
+  }
+
+  void visitAll(List<Node> nodes) {
+    nodes.forEach(visit);
+  }
+
+  @override
+  void visitProgram(Program program) {
+    if (program.body.isNotEmpty) {
+      visitAll(program.body);
+    }
+  }
+
+  Statement unwrapBlockIfSingleStatement(Statement body) {
+    Statement result = body;
+    while (result is Block) {
+      Block block = result;
+      if (block.statements.length != 1) break;
+      result = block.statements.single;
+    }
+    return result;
+  }
+
+  bool blockBody(Statement body, {bool needsSeparation}) {
+    if (body is Block) {
+      blockOut(body);
+      return true;
+    }
+    if (needsSeparation) {
+      out(' '); // ' '
+    }
+    visit(body);
+    return false;
+  }
+
+  void blockOutWithoutBraces(Node node) {
+    if (node is Block) {
+      Block block = node;
+      block.statements.forEach(blockOutWithoutBraces);
+    } else {
+      visit(node);
+    }
+  }
+
+  int blockOut(Block node) {
+    out('{'); // '{'
+    node.statements.forEach(blockOutWithoutBraces);
+    out('}'); // '}'
+    int closingPosition = charCount - 1;
+    return closingPosition;
+  }
+
+  @override
+  void visitBlock(Block block) {
+    blockOut(block);
+  }
+
+  @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    visitNestedExpression(node.expression, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: true);
+    outSemicolonLn();
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {
+    out(';'); // ';'
+  }
+
+  void ifOut(If node) {
+    Statement then = unwrapBlockIfSingleStatement(node.then);
+    Statement elsePart = node.otherwise;
+    bool hasElse = node.hasElse;
+
+    out('if('); // 'if('
+    visitNestedExpression(node.condition, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+    blockBody(then, needsSeparation: false);
+    if (hasElse) {
+      out('else'); // 'else'
+      if (elsePart is If) {
+        pendingSpace = true;
+        ifOut(elsePart);
+      } else {
+        blockBody(unwrapBlockIfSingleStatement(elsePart),
+            needsSeparation: true);
+      }
+    }
+  }
+
+  @override
+  void visitIf(If node) {
+    ifOut(node);
+  }
+
+  @override
+  void visitFor(For loop) {
+    out('for('); // 'for('
+    if (loop.init != null) {
+      visitNestedExpression(loop.init, EXPRESSION,
+          newInForInit: true, newAtStatementBegin: false);
+    }
+    out(';'); // ';'
+    if (loop.condition != null) {
+      visitNestedExpression(loop.condition, EXPRESSION,
+          newInForInit: false, newAtStatementBegin: false);
+    }
+    out(';'); // ';'
+    if (loop.update != null) {
+      visitNestedExpression(loop.update, EXPRESSION,
+          newInForInit: false, newAtStatementBegin: false);
+    }
+    out(')'); // ')'
+    blockBody(unwrapBlockIfSingleStatement(loop.body), needsSeparation: false);
+  }
+
+  @override
+  void visitForIn(ForIn loop) {
+    out('for('); // 'for('
+    visitNestedExpression(loop.leftHandSide, EXPRESSION,
+        newInForInit: true, newAtStatementBegin: false);
+    out(' in'); // ' in'
+    pendingSpace = true;
+    visitNestedExpression(loop.object, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+    blockBody(unwrapBlockIfSingleStatement(loop.body), needsSeparation: false);
+  }
+
+  @override
+  void visitWhile(While loop) {
+    out('while('); // 'while('
+    visitNestedExpression(loop.condition, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+    blockBody(unwrapBlockIfSingleStatement(loop.body), needsSeparation: false);
+  }
+
+  @override
+  void visitDo(Do loop) {
+    out('do'); // 'do'
+    if (blockBody(unwrapBlockIfSingleStatement(loop.body),
+        needsSeparation: true)) {}
+    out('while('); // 'while('
+    visitNestedExpression(loop.condition, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+    outSemicolonLn();
+  }
+
+  @override
+  void visitContinue(Continue node) {
+    if (node.targetLabel == null) {
+      out('continue'); // 'continue'
+    } else {
+      out('continue ${node.targetLabel}'); // 'continue ${node.targetLabel}'
+    }
+    outSemicolonLn();
+  }
+
+  @override
+  void visitBreak(Break node) {
+    if (node.targetLabel == null) {
+      out('break');
+    } else {
+      out('break ${node.targetLabel}');
+    }
+    outSemicolonLn();
+  }
+
+  @override
+  void visitReturn(Return node) {
+    out('return'); // 'return'
+    if (node.value != null) {
+      pendingSpace = true;
+      visitNestedExpression(node.value, EXPRESSION,
+          newInForInit: false, newAtStatementBegin: false);
+    }
+    outSemicolonLn();
+  }
+
+  @override
+  void visitDartYield(DartYield node) {
+    if (node.hasStar) {
+      out('yield*'); // 'yield*'
+    } else {
+      out('yield'); // 'yield'
+    }
+    pendingSpace = true;
+    visitNestedExpression(node.expression, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    outSemicolonLn();
+  }
+
+  @override
+  void visitThrow(Throw node) {
+    out('throw'); // 'throw'
+    pendingSpace = true;
+    visitNestedExpression(node.expression, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    outSemicolonLn();
+  }
+
+  @override
+  void visitTry(Try node) {
+    out('try'); // 'try'
+    blockBody(node.body, needsSeparation: true);
+    if (node.catchPart != null) {
+      visit(node.catchPart);
+    }
+    if (node.finallyPart != null) {
+      out('finally'); // 'finally'
+      blockBody(node.finallyPart, needsSeparation: true);
+    }
+  }
+
+  @override
+  void visitCatch(Catch node) {
+    out('catch('); // 'catch('
+    visitNestedExpression(node.declaration, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+    blockBody(node.body, needsSeparation: false);
+  }
+
+  @override
+  void visitSwitch(Switch node) {
+    out('switch('); // 'switch('
+    visitNestedExpression(node.key, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out('){'); // '){
+    visitAll(node.cases);
+    out('}'); // '}'
+  }
+
+  @override
+  void visitCase(Case node) {
+    out('case'); // 'case'
+    pendingSpace = true;
+    visitNestedExpression(node.expression, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(':'); // ':'
+    if (!node.body.statements.isEmpty) {
+      blockOutWithoutBraces(node.body);
+    }
+  }
+
+  @override
+  void visitDefault(Default node) {
+    out('default:'); // 'default:'
+    if (!node.body.statements.isEmpty) {
+      blockOutWithoutBraces(node.body);
+    }
+  }
+
+  @override
+  void visitLabeledStatement(LabeledStatement node) {
+    Statement body = unwrapBlockIfSingleStatement(node.body);
+    // `label: break label;`
+    // Does not work on IE. The statement is a nop, so replace it by an empty
+    // statement.
+    // See:
+    // https://connect.microsoft.com/IE/feedback/details/891889/parser-bugs
+    if (body is Break && body.targetLabel == node.label) {
+      visit(new EmptyStatement());
+      return;
+    }
+    out('${node.label}:');
+    blockBody(body, needsSeparation: false);
+  }
+
+  int functionOut(Fun fun, Node name, VarCollector vars) {
+    out('function'); // 'function'
+    if (name != null) {
+      out(' '); // ' '
+      // Name must be a [Decl]. Therefore only test for primary expressions.
+      visitNestedExpression(name, PRIMARY,
+          newInForInit: false, newAtStatementBegin: false);
+    }
+    out('('); // '('
+    if (fun.params != null) {
+      visitCommaSeparated(fun.params, PRIMARY,
+          newInForInit: false, newAtStatementBegin: false);
+    }
+    out(')'); // ')'
+    switch (fun.asyncModifier) {
+      case AsyncModifier.sync:
+        break;
+      case AsyncModifier.async:
+        out(' async'); // ' async'
+        break;
+      case AsyncModifier.syncStar:
+        out(' sync*'); // ' sync*'
+        break;
+      case AsyncModifier.asyncStar:
+        out(' async*'); // ' async*'
+        break;
+    }
+    int closingPosition = blockOut(fun.body);
+    return closingPosition;
+  }
+
+  @override
+  visitFunctionDeclaration(FunctionDeclaration declaration) {
+    VarCollector vars = new VarCollector();
+    vars.visitFunctionDeclaration(declaration);
+    functionOut(declaration.function, declaration.name, vars);
+  }
+
+  visitNestedExpression(Expression node, int requiredPrecedence,
+      {bool newInForInit, bool newAtStatementBegin}) {
+    bool needsParentheses = !node.isFinalized ||
+        // a - (b + c).
+        (requiredPrecedence != EXPRESSION &&
+            node.precedenceLevel < requiredPrecedence) ||
+        // for (a = (x in o); ... ; ... ) { ... }
+        (newInForInit && node is Binary && node.op == "in") ||
+        // (function() { ... })().
+        // ({a: 2, b: 3}.toString()).
+        (newAtStatementBegin &&
+            (node is NamedFunction ||
+                node is Fun ||
+                node is ObjectInitializer));
+    if (needsParentheses) {
+      inForInit = false;
+      atStatementBegin = false;
+      out('('); // '('
+      visit(node);
+      out(')'); // ')'
+    } else {
+      inForInit = newInForInit;
+      atStatementBegin = newAtStatementBegin;
+      visit(node);
+    }
+  }
+
+  @override
+  visitVariableDeclarationList(VariableDeclarationList list) {
+    out('var '); // 'var '
+    List<Node> nodes = list.declarations;
+    if (inForInit) {
+      visitCommaSeparated(nodes, ASSIGNMENT,
+          newInForInit: inForInit, newAtStatementBegin: false);
+    } else {
+      for (int i = 0; i < nodes.length; i++) {
+        Node node = nodes[i];
+        if (i > 0) {
+          atStatementBegin = false;
+          out(','); // ','
+        }
+        visitNestedExpression(node, ASSIGNMENT,
+            newInForInit: inForInit, newAtStatementBegin: false);
+      }
+    }
+  }
+
+  void _outputIncDec(String op, Expression variable, [Expression alias]) {
+    // We can eliminate the space preceding the inc/dec in some cases,
+    // but for estimation purposes we assume the worst case.
+    if (op == '+') {
+      out(' ++');
+    } else {
+      out(' --');
+    }
+    visitNestedExpression(variable, UNARY,
+        newInForInit: inForInit, newAtStatementBegin: false);
+  }
+
+  @override
+  visitAssignment(Assignment assignment) {
+    /// To print assignments like `a = a + 1` and `a = a + b` compactly as
+    /// `++a` and `a += b` in the face of [DeferredExpression]s we detect the
+    /// pattern of the undeferred assignment.
+    String op = assignment.op;
+    Node leftHandSide = assignment.leftHandSide;
+    Node rightHandSide = assignment.value;
+    if ((op == '+' || op == '-') &&
+        leftHandSide is VariableUse &&
+        rightHandSide is LiteralNumber &&
+        rightHandSide.value == "1") {
+      // Output 'a += 1' as '++a' and 'a -= 1' as '--a'.
+      _outputIncDec(op, assignment.leftHandSide);
+      return;
+    }
+    if (!assignment.isCompound &&
+        leftHandSide is VariableUse &&
+        rightHandSide is Binary) {
+      Node rLeft = rightHandSide.left;
+      Node rRight = rightHandSide.right;
+      String op = rightHandSide.op;
+      if (op == '+' ||
+          op == '-' ||
+          op == '/' ||
+          op == '*' ||
+          op == '%' ||
+          op == '^' ||
+          op == '&' ||
+          op == '|') {
+        if (rLeft is VariableUse && rLeft.name == leftHandSide.name) {
+          // Output 'a = a + 1' as '++a' and 'a = a - 1' as '--a'.
+          if ((op == '+' || op == '-') &&
+              rRight is LiteralNumber &&
+              rRight.value == "1") {
+            _outputIncDec(op, assignment.leftHandSide, rightHandSide.left);
+            return;
+          }
+          // Output 'a = a + b' as 'a += b'.
+          visitNestedExpression(assignment.leftHandSide, CALL,
+              newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+          assert(op.length == 1);
+          out('$op='); // '$op='
+          visitNestedExpression(rRight, ASSIGNMENT,
+              newInForInit: inForInit, newAtStatementBegin: false);
+          return;
+        }
+      }
+    }
+    visitNestedExpression(assignment.leftHandSide, CALL,
+        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+    if (assignment.value != null) {
+      if (op != null) out(op);
+      out('='); // '='
+      visitNestedExpression(assignment.value, ASSIGNMENT,
+          newInForInit: inForInit, newAtStatementBegin: false);
+    }
+  }
+
+  @override
+  visitVariableInitialization(VariableInitialization initialization) {
+    visitAssignment(initialization);
+  }
+
+  @override
+  visitConditional(Conditional cond) {
+    visitNestedExpression(cond.condition, LOGICAL_OR,
+        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+    out('?'); // '?'
+    // The then part is allowed to have an 'in'.
+    visitNestedExpression(cond.then, ASSIGNMENT,
+        newInForInit: false, newAtStatementBegin: false);
+    out(':'); // ':'
+    visitNestedExpression(cond.otherwise, ASSIGNMENT,
+        newInForInit: inForInit, newAtStatementBegin: false);
+  }
+
+  @override
+  visitNew(New node) {
+    out('new'); // 'new'
+    visitNestedExpression(node.target, LEFT_HAND_SIDE,
+        newInForInit: inForInit, newAtStatementBegin: false);
+    out('('); // '('
+    visitCommaSeparated(node.arguments, ASSIGNMENT,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+  }
+
+  @override
+  visitCall(Call call) {
+    visitNestedExpression(call.target, CALL,
+        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+    out('('); // '('
+    visitCommaSeparated(call.arguments, ASSIGNMENT,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+  }
+
+  @override
+  void visitBinary(Binary binary) {
+    Expression left = binary.left;
+    Expression right = binary.right;
+    String op = binary.op;
+    int leftPrecedenceRequirement;
+    int rightPrecedenceRequirement;
+    switch (op) {
+      case ',':
+        //  x, (y, z) <=> (x, y), z.
+        leftPrecedenceRequirement = EXPRESSION;
+        rightPrecedenceRequirement = EXPRESSION;
+        break;
+      case "||":
+        leftPrecedenceRequirement = LOGICAL_OR;
+        // x || (y || z) <=> (x || y) || z.
+        rightPrecedenceRequirement = LOGICAL_OR;
+        break;
+      case "&&":
+        leftPrecedenceRequirement = LOGICAL_AND;
+        // x && (y && z) <=> (x && y) && z.
+        rightPrecedenceRequirement = LOGICAL_AND;
+        break;
+      case "|":
+        leftPrecedenceRequirement = BIT_OR;
+        // x | (y | z) <=> (x | y) | z.
+        rightPrecedenceRequirement = BIT_OR;
+        break;
+      case "^":
+        leftPrecedenceRequirement = BIT_XOR;
+        // x ^ (y ^ z) <=> (x ^ y) ^ z.
+        rightPrecedenceRequirement = BIT_XOR;
+        break;
+      case "&":
+        leftPrecedenceRequirement = BIT_AND;
+        // x & (y & z) <=> (x & y) & z.
+        rightPrecedenceRequirement = BIT_AND;
+        break;
+      case "==":
+      case "!=":
+      case "===":
+      case "!==":
+        leftPrecedenceRequirement = EQUALITY;
+        rightPrecedenceRequirement = RELATIONAL;
+        break;
+      case "<":
+      case ">":
+      case "<=":
+      case ">=":
+      case "instanceof":
+      case "in":
+        leftPrecedenceRequirement = RELATIONAL;
+        rightPrecedenceRequirement = SHIFT;
+        break;
+      case ">>":
+      case "<<":
+      case ">>>":
+        leftPrecedenceRequirement = SHIFT;
+        rightPrecedenceRequirement = ADDITIVE;
+        break;
+      case "+":
+      case "-":
+        leftPrecedenceRequirement = ADDITIVE;
+        // We cannot remove parenthesis for "+" because
+        //   x + (y + z) <!=> (x + y) + z:
+        // Example:
+        //   "a" + (1 + 2) => "a3";
+        //   ("a" + 1) + 2 => "a12";
+        rightPrecedenceRequirement = MULTIPLICATIVE;
+        break;
+      case "*":
+      case "/":
+      case "%":
+        leftPrecedenceRequirement = MULTIPLICATIVE;
+        // We cannot remove parenthesis for "*" because of precision issues.
+        rightPrecedenceRequirement = UNARY;
+        break;
+      default:
+        throw UnsupportedError("Forgot operator: $op");
+    }
+
+    visitNestedExpression(left, leftPrecedenceRequirement,
+        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+
+    if (op == "in" || op == "instanceof") {
+      // There are cases where the space is not required but without further
+      // analysis we cannot know.
+      out(' $op '); // ' $op '
+    } else {
+      out(op); // '$op'
+    }
+    visitNestedExpression(right, rightPrecedenceRequirement,
+        newInForInit: inForInit, newAtStatementBegin: false);
+  }
+
+  @override
+  void visitPrefix(Prefix unary) {
+    String op = unary.op;
+    switch (op) {
+      case "delete":
+      case "void":
+      case "typeof":
+      case "+":
+      case "++":
+      case "-":
+      case "--":
+        // We may be able to eliminate the space in some cases, but for
+        // estimation we assume the worst case.
+        out('$op '); // '$op '
+        break;
+      default:
+        out('$op'); // '$op'
+    }
+    visitNestedExpression(unary.argument, UNARY,
+        newInForInit: inForInit, newAtStatementBegin: false);
+  }
+
+  @override
+  void visitPostfix(Postfix postfix) {
+    visitNestedExpression(postfix.argument, CALL,
+        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+    out(postfix.op); // '${postfix.op}'
+  }
+
+  @override
+  void visitVariableUse(VariableUse ref) {
+    // For simplicity and stability we use a constant name size estimate.
+    // In production this is:
+    // '${localNamer.getName(ref.name)'
+    out(sizeEstimate(ref));
+  }
+
+  @override
+  void visitThis(This node) {
+    out('this'); // 'this'
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration decl) {
+    // '${localNamer.getName(decl.name)'
+    out(sizeEstimate(decl));
+  }
+
+  @override
+  void visitParameter(Parameter param) {
+    // For simplicity and stability we use a constant name size estimate.
+    // In production this is:
+    // '${localNamer.getName(param.name)'
+    out(sizeEstimate(param));
+  }
+
+  bool isDigit(int charCode) {
+    return charCodes.$0 <= charCode && charCode <= charCodes.$9;
+  }
+
+  bool isValidJavaScriptId(String field) {
+    if (field.length < 3) return false;
+    // Ignore the leading and trailing string-delimiter.
+    for (int i = 1; i < field.length - 1; i++) {
+      // TODO(floitsch): allow more characters.
+      int charCode = field.codeUnitAt(i);
+      if (!(charCodes.$a <= charCode && charCode <= charCodes.$z ||
+          charCodes.$A <= charCode && charCode <= charCodes.$Z ||
+          charCode == charCodes.$$ ||
+          charCode == charCodes.$_ ||
+          i != 1 && isDigit(charCode))) {
+        return false;
+      }
+    }
+    // TODO(floitsch): normally we should also check that the field is not a
+    // reserved word.  We don't generate fields with reserved word names except
+    // for 'super'.
+    if (field == '"super"') return false;
+    if (field == '"catch"') return false;
+    return true;
+  }
+
+  @override
+  void visitAccess(PropertyAccess access) {
+    visitNestedExpression(access.receiver, CALL,
+        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+    Node selector = access.selector;
+    if (selector is LiteralString) {
+      String fieldWithQuotes = selector.value;
+      if (isValidJavaScriptId(fieldWithQuotes)) {
+        if (access.receiver is LiteralNumber) {
+          // We can eliminate the space in some cases, but for simplicity we
+          // always assume it is necessary.
+          out(' '); // ' '
+        }
+
+        // '.${fieldWithQuotes.substring(1, fieldWithQuotes.length - 1)}'
+        out('.${fieldWithQuotes.substring(1, fieldWithQuotes.length - 1)}');
+        return;
+      }
+    } else if (selector is Name) {
+      Node receiver = access.receiver;
+      if (receiver is LiteralNumber) {
+        // We can eliminate the space in some cases, but for simplicity we
+        // always assume it is necessary.
+        out(' '); // ' '
+      }
+      out('.'); // '.'
+      selector.accept(this);
+      return;
+    }
+    out('['); // '['
+    visitNestedExpression(access.selector, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(']'); // ']
+  }
+
+  @override
+  void visitNamedFunction(NamedFunction namedFunction) {
+    VarCollector vars = new VarCollector();
+    vars.visitNamedFunction(namedFunction);
+    functionOut(namedFunction.function, namedFunction.name, vars);
+  }
+
+  @override
+  void visitFun(Fun fun) {
+    VarCollector vars = new VarCollector();
+    vars.visitFun(fun);
+    functionOut(fun, null, vars);
+  }
+
+  @override
+  visitDeferredExpression(DeferredExpression node) {
+    if (node.isFinalized) {
+      // Continue printing with the expression value.
+      assert(node.precedenceLevel == node.value.precedenceLevel);
+      node.value.accept(this);
+    } else {
+      out(sizeEstimate(node));
+    }
+  }
+
+  outputNumberWithRequiredWhitespace(String number) {
+    int charCode = number.codeUnitAt(0);
+    if (charCode == charCodes.$MINUS) {
+      // We can eliminate the space in some cases, but for simplicity we
+      // always assume it is necessary.
+      out(' ');
+    }
+    out(number); // '${number}'
+  }
+
+  @override
+  visitDeferredNumber(DeferredNumber node) {
+    if (node.isFinalized) {
+      outputNumberWithRequiredWhitespace("${node.value}");
+    } else {
+      out(sizeEstimate(node));
+    }
+  }
+
+  @override
+  visitDeferredString(DeferredString node) {
+    if (node.isFinalized) {
+      out(node.value);
+    } else {
+      out(sizeEstimate(node));
+    }
+  }
+
+  @override
+  visitLiteralBool(LiteralBool node) {
+    out(node.value ? '!0' : '!1');
+  }
+
+  @override
+  void visitLiteralString(LiteralString node) {
+    if (node.isFinalized) {
+      out(node.value); // '${node.value}'
+    } else {
+      out(sizeEstimate(node));
+    }
+  }
+
+  @override
+  visitStringConcatenation(StringConcatenation node) {
+    node.visitChildren(this);
+  }
+
+  @override
+  visitName(Name node) {
+    // For simplicity and stability we use a constant name size estimate.
+    // In production this is:
+    // '${options.renamerForNames(node)}'
+    out(sizeEstimate(node));
+  }
+
+  @override
+  visitParentheses(Parentheses node) {
+    out('('); // '('
+    visitNestedExpression(node.enclosed, EXPRESSION,
+        newInForInit: false, newAtStatementBegin: false);
+    out(')'); // ')'
+  }
+
+  @override
+  visitLiteralNumber(LiteralNumber node) {
+    outputNumberWithRequiredWhitespace(node.value);
+  }
+
+  @override
+  void visitLiteralNull(LiteralNull node) {
+    out('null'); // 'null'
+  }
+
+  @override
+  void visitArrayInitializer(ArrayInitializer node) {
+    out('['); // '['
+    List<Expression> elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      Expression element = elements[i];
+      if (element is ArrayHole) {
+        // Note that array holes must have a trailing "," even if they are
+        // in last position. Otherwise `[,]` (having length 1) would become
+        // equal to `[]` (the empty array)
+        // and [1,,] (array with 1 and a hole) would become [1,] = [1].
+        out(','); // ','
+        continue;
+      }
+      visitNestedExpression(element, ASSIGNMENT,
+          newInForInit: false, newAtStatementBegin: false);
+      // We can skip the trailing "," for the last element (since it's not
+      // an array hole).
+      if (i != elements.length - 1) out(','); // ','
+    }
+    out(']'); // ']'
+  }
+
+  @override
+  void visitArrayHole(ArrayHole node) {
+    throw UnsupportedError("Unreachable");
+  }
+
+  @override
+  void visitObjectInitializer(ObjectInitializer node) {
+    // Print all the properties on one line until we see a function-valued
+    // property.  Ideally, we would use a proper pretty-printer to make the
+    // decision based on layout.
+    bool exitOneLinerMode(Expression value) {
+      return value is Fun ||
+          value is ArrayInitializer && value.elements.any((e) => e is Fun);
+    }
+
+    bool isOneLiner = true;
+    List<Property> properties = node.properties;
+    out('{'); // '{'
+    for (int i = 0; i < properties.length; i++) {
+      Node value = properties[i].value;
+      if (isOneLiner && exitOneLinerMode(value)) isOneLiner = false;
+      if (i != 0) {
+        out(','); // ','
+      }
+      if (!isOneLiner) {
+        forceLine();
+      }
+      visit(properties[i]);
+    }
+    out('}'); // '}'
+  }
+
+  @override
+  void visitProperty(Property node) {
+    Node name = node.name;
+    if (name is LiteralString) {
+      String text = name.value;
+      if (isValidJavaScriptId(text)) {
+        // '${text.substring(1, text.length - 1)}
+        out('${text.substring(1, text.length - 1)}');
+      } else {
+        out(text); // '$text'
+      }
+    } else if (name is Name) {
+      node.name.accept(this);
+    } else if (name is DeferredExpression) {
+      out(sizeEstimate(name));
+    } else {
+      assert(name is LiteralNumber);
+      LiteralNumber nameNumber = node.name;
+      out(nameNumber.value); // '${nameNumber.value}'
+    }
+    out(':'); // ':'
+    visitNestedExpression(node.value, ASSIGNMENT,
+        newInForInit: false, newAtStatementBegin: false);
+  }
+
+  @override
+  void visitRegExpLiteral(RegExpLiteral node) {
+    out(node.pattern); // '${node.pattern}'
+  }
+
+  @override
+  void visitLiteralExpression(LiteralExpression node) {
+    String template = node.template;
+    List<Expression> inputs = node.inputs;
+
+    List<String> parts = template.split('#');
+    int inputsLength = inputs == null ? 0 : inputs.length;
+    if (parts.length != inputsLength + 1) {
+      throw UnsupportedError('Wrong number of arguments for JS: $template');
+    }
+    // Code that uses JS must take care of operator precedences, and
+    // put parenthesis if needed.
+    out(parts[0]); // '${parts[0]}'
+    for (int i = 0; i < inputsLength; i++) {
+      visit(inputs[i]);
+      out(parts[i + 1]); // '${parts[i + 1]}'
+    }
+  }
+
+  @override
+  void visitLiteralStatement(LiteralStatement node) {
+    out(node.code); // '${node.code}'
+  }
+
+  void visitInterpolatedNode(InterpolatedNode node) {
+    throw UnsupportedError('InterpolatedStatements are not supported');
+  }
+
+  @override
+  void visitInterpolatedExpression(InterpolatedExpression node) =>
+      visitInterpolatedNode(node);
+
+  @override
+  void visitInterpolatedLiteral(InterpolatedLiteral node) =>
+      visitInterpolatedNode(node);
+
+  @override
+  void visitInterpolatedParameter(InterpolatedParameter node) =>
+      visitInterpolatedNode(node);
+
+  @override
+  void visitInterpolatedSelector(InterpolatedSelector node) =>
+      visitInterpolatedNode(node);
+
+  @override
+  void visitInterpolatedStatement(InterpolatedStatement node) {
+    throw UnsupportedError('InterpolatedStatements are not supported');
+  }
+
+  @override
+  void visitInterpolatedDeclaration(InterpolatedDeclaration node) {
+    visitInterpolatedNode(node);
+  }
+
+  @override
+  void visitComment(Comment node) {
+    // We assume output is compressed and thus do not output comments.
+  }
+
+  @override
+  void visitAwait(Await node) {
+    out('await '); // 'await '
+    visit(node.expression);
+  }
+}
+
+int EstimateSize(Node node) {
+  var estimator = SizeEstimator();
+  estimator.visit(node);
+  return estimator.charCount;
+}
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index f80bbbf..8955a8d 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -102,6 +102,14 @@
       14, 'downcast:check',
       forFunctionsOnly: false, internalOnly: false);
 
+  static const PragmaAnnotation indexBoundsTrust = const PragmaAnnotation(
+      15, 'index-bounds:trust',
+      forFunctionsOnly: false, internalOnly: false);
+
+  static const PragmaAnnotation indexBoundsCheck = const PragmaAnnotation(
+      16, 'index-bounds:check',
+      forFunctionsOnly: false, internalOnly: false);
+
   static const List<PragmaAnnotation> values = [
     noInline,
     tryInline,
@@ -118,6 +126,8 @@
     parameterCheck,
     downcastTrust,
     downcastCheck,
+    indexBoundsTrust,
+    indexBoundsCheck,
   ];
 
   static const Map<PragmaAnnotation, Set<PragmaAnnotation>> implies = {
@@ -319,6 +329,12 @@
   ///
   /// If [member] is `null`, the default policy is returned.
   CheckPolicy getExplicitCastCheckPolicy(MemberEntity member);
+
+  /// What should the compiler do with index bounds checks `[]`, `[]=` and
+  /// `removeLast()` operations in the body of [member].
+  ///
+  /// If [member] is `null`, the default policy is returned.
+  CheckPolicy getIndexBoundsCheckPolicy(MemberEntity member);
 }
 
 class AnnotationsDataImpl implements AnnotationsData {
@@ -330,6 +346,7 @@
   final CheckPolicy _defaultImplicitDowncastCheckPolicy;
   final CheckPolicy _defaultConditionCheckPolicy;
   final CheckPolicy _defaultExplicitCastCheckPolicy;
+  final CheckPolicy _defaultIndexBoundsCheckPolicy;
   final Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations;
 
   AnnotationsDataImpl(CompilerOptions options, this.pragmaAnnotations)
@@ -338,7 +355,9 @@
             options.defaultImplicitDowncastCheckPolicy,
         this._defaultConditionCheckPolicy = options.defaultConditionCheckPolicy,
         this._defaultExplicitCastCheckPolicy =
-            options.defaultExplicitCastCheckPolicy;
+            options.defaultExplicitCastCheckPolicy,
+        this._defaultIndexBoundsCheckPolicy =
+            options.defaultIndexBoundsCheckPolicy;
 
   factory AnnotationsDataImpl.readFromDataSource(
       CompilerOptions options, DataSource source) {
@@ -504,6 +523,21 @@
     }
     return _defaultExplicitCastCheckPolicy;
   }
+
+  @override
+  CheckPolicy getIndexBoundsCheckPolicy(MemberEntity member) {
+    if (member != null) {
+      EnumSet<PragmaAnnotation> annotations = pragmaAnnotations[member];
+      if (annotations != null) {
+        if (annotations.contains(PragmaAnnotation.indexBoundsTrust)) {
+          return CheckPolicy.trusted;
+        } else if (annotations.contains(PragmaAnnotation.indexBoundsCheck)) {
+          return CheckPolicy.checked;
+        }
+      }
+    }
+    return _defaultIndexBoundsCheckPolicy;
+  }
 }
 
 class AnnotationsDataBuilder {
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index a0fb0b3..3954c4c 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -48,7 +48,7 @@
 
   int globalCount = 0;
 
-  final List<jsAst.Name> nameStore = new List<jsAst.Name>();
+  final List<jsAst.Name> nameStore = <jsAst.Name>[];
 
   _FieldNamingRegistry(this.namer);
 
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index f929e7a..9d0eb71 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -9,7 +9,7 @@
     implements jsAst.TokenFinalizer {
   @override
   _FieldNamingRegistry fieldRegistry;
-  List<TokenName> tokens = new List<TokenName>();
+  List<TokenName> tokens = <TokenName>[];
 
   Map<NamingScope, TokenScope> _tokenScopes =
       new Maplet<NamingScope, TokenScope>();
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index dd8c765..ce57087 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.dart
@@ -83,6 +83,9 @@
   int get hashCode => base.hashCode * 13 + prefix.hashCode;
 
   @override
+  bool get isFinalized => prefix.isFinalized && base.isFinalized;
+
+  @override
   int compareTo(jsAst.Name other) {
     _NamerName otherNamerName;
     if (other is ModularName) {
@@ -209,6 +212,7 @@
 
   TokenName(this._scope, this.key);
 
+  @override
   bool get isFinalized => _name != null;
 
   @override
@@ -276,6 +280,9 @@
   }
 
   @override
+  bool get isFinalized => _target.isFinalized;
+
+  @override
   bool operator ==(other) => _target == other;
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/string_reference.dart b/pkg/compiler/lib/src/js_backend/string_reference.dart
index 95fa795..b8c41aa 100644
--- a/pkg/compiler/lib/src/js_backend/string_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/string_reference.dart
@@ -115,16 +115,19 @@
   }
 
   set value(js.Expression value) {
-    assert(_value == null && value != null);
+    assert(!isFinalized && value != null);
     _value = value;
   }
 
   @override
   js.Expression get value {
-    assert(_value != null, 'StringReference is unassigned');
+    assert(isFinalized, 'StringReference is unassigned');
     return _value;
   }
 
+  @override
+  bool get isFinalized => _value != null;
+
   // Precedence will be CALL or LEFT_HAND_SIDE depending on what expression the
   // reference is resolved to.
   @override
@@ -139,7 +142,7 @@
   }
 
   @override
-  Iterable<js.Node> get containedNodes => _value == null ? const [] : [_value];
+  Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
 }
 
 /// A [StringReferenceResource] is a deferred JavaScript expression determined
@@ -159,13 +162,13 @@
   StringReferenceResource._(this._value, this.sourceInformation);
 
   set value(js.Expression value) {
-    assert(_value == null && value != null);
+    assert(!isFinalized && value != null);
     _value = value;
   }
 
   @override
   js.Expression get value {
-    assert(_value != null, 'StringReferenceResource is unassigned');
+    assert(isFinalized, 'StringReferenceResource is unassigned');
     return _value;
   }
 
@@ -173,6 +176,9 @@
   int get precedenceLevel => value.precedenceLevel;
 
   @override
+  bool get isFinalized => _value != null;
+
+  @override
   StringReferenceResource withSourceInformation(
       js.JavaScriptNodeSourceInformation newSourceInformation) {
     if (newSourceInformation == sourceInformation) return this;
@@ -181,7 +187,7 @@
   }
 
   @override
-  Iterable<js.Node> get containedNodes => _value == null ? const [] : [_value];
+  Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
 
   @override
   void visitChildren<T>(js.NodeVisitor<T> visitor) {
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index de1a5f3..f33591d 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -132,16 +132,19 @@
   }
 
   set value(js.Expression value) {
-    assert(_value == null && value != null);
+    assert(!isFinalized && value != null);
     _value = value;
   }
 
   @override
   js.Expression get value {
-    assert(_value != null, 'TypeReference is unassigned');
+    assert(isFinalized, 'TypeReference is unassigned');
     return _value;
   }
 
+  @override
+  bool get isFinalized => _value != null;
+
   // Precedence will be CALL or LEFT_HAND_SIDE depending on what expression the
   // reference is resolved to.
   @override
@@ -156,7 +159,7 @@
   }
 
   @override
-  Iterable<js.Node> get containedNodes => _value == null ? const [] : [_value];
+  Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
 }
 
 /// A [TypeReferenceResource] is a deferred JavaScript expression determined by
@@ -176,17 +179,20 @@
   TypeReferenceResource._(this._value, this.sourceInformation);
 
   set value(js.Expression value) {
-    assert(_value == null && value != null);
+    assert(!isFinalized && value != null);
     _value = value;
   }
 
   @override
   js.Expression get value {
-    assert(_value != null, 'TypeReferenceResource is unassigned');
+    assert(isFinalized, 'TypeReferenceResource is unassigned');
     return _value;
   }
 
   @override
+  bool get isFinalized => _value != null;
+
+  @override
   int get precedenceLevel => value.precedenceLevel;
 
   @override
@@ -198,7 +204,7 @@
   }
 
   @override
-  Iterable<js.Node> get containedNodes => _value == null ? const [] : [_value];
+  Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
 
   @override
   void visitChildren<T>(js.NodeVisitor<T> visitor) {
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 8066ff1..6fac2f9 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -41,15 +41,16 @@
   void markSeen(jsAst.TokenCounter visitor);
 }
 
-class _BoundMetadataEntry extends _MetadataEntry {
+class BoundMetadataEntry extends _MetadataEntry {
   int _value = -1;
   @override
   int _rc = 0;
   @override
   final jsAst.Expression entry;
 
-  _BoundMetadataEntry(this.entry);
+  BoundMetadataEntry(this.entry);
 
+  @override
   bool get isFinalized => _value != -1;
 
   finalize(int value) {
@@ -75,7 +76,7 @@
   int compareTo(covariant _MetadataEntry other) => other._rc - this._rc;
 
   @override
-  String toString() => '_BoundMetadataEntry($hashCode,rc=$_rc,_value=$_value)';
+  String toString() => 'BoundMetadataEntry($hashCode,rc=$_rc,_value=$_value)';
 }
 
 class _MetadataList extends jsAst.DeferredExpression {
@@ -114,8 +115,8 @@
   }
 
   /// A map used to canonicalize the entries of metadata.
-  Map<OutputUnit, Map<String, _BoundMetadataEntry>> _metadataMap =
-      <OutputUnit, Map<String, _BoundMetadataEntry>>{};
+  Map<OutputUnit, Map<String, BoundMetadataEntry>> _metadataMap =
+      <OutputUnit, Map<String, BoundMetadataEntry>>{};
 
   /// A map with a token for a lists of JS expressions, one token for each
   /// output unit. Once finalized, the entries represent types including
@@ -128,8 +129,8 @@
   }
 
   /// A map used to canonicalize the entries of types.
-  Map<OutputUnit, Map<DartType, _BoundMetadataEntry>> _typesMap =
-      <OutputUnit, Map<DartType, _BoundMetadataEntry>>{};
+  Map<OutputUnit, Map<DartType, BoundMetadataEntry>> _typesMap =
+      <OutputUnit, Map<DartType, BoundMetadataEntry>>{};
 
   MetadataCollector(this._options, this.reporter, this._emitter,
       this._rtiRecipeEncoder, this._elementEnvironment);
@@ -165,9 +166,9 @@
     String printed = jsAst.prettyPrint(node,
         enableMinification: _options.enableMinification,
         renamerForNames: nameToKey);
-    _metadataMap[outputUnit] ??= new Map<String, _BoundMetadataEntry>();
+    _metadataMap[outputUnit] ??= new Map<String, BoundMetadataEntry>();
     return _metadataMap[outputUnit].putIfAbsent(printed, () {
-      return new _BoundMetadataEntry(node);
+      return new BoundMetadataEntry(node);
     });
   }
 
@@ -177,36 +178,36 @@
   }
 
   jsAst.Expression addTypeInOutputUnit(DartType type, OutputUnit outputUnit) {
-    _typesMap[outputUnit] ??= new Map<DartType, _BoundMetadataEntry>();
+    _typesMap[outputUnit] ??= new Map<DartType, BoundMetadataEntry>();
     return _typesMap[outputUnit].putIfAbsent(type, () {
-      return new _BoundMetadataEntry(_computeTypeRepresentationNewRti(type));
+      return new BoundMetadataEntry(_computeTypeRepresentationNewRti(type));
     });
   }
 
   @override
   void finalizeTokens() {
-    void countTokensInTypes(Iterable<_BoundMetadataEntry> entries) {
+    void countTokensInTypes(Iterable<BoundMetadataEntry> entries) {
       jsAst.TokenCounter counter = new jsAst.TokenCounter();
       entries
-          .where((_BoundMetadataEntry e) => e._rc > 0)
-          .map((_BoundMetadataEntry e) => e.entry)
+          .where((BoundMetadataEntry e) => e._rc > 0)
+          .map((BoundMetadataEntry e) => e.entry)
           .forEach(counter.countTokens);
     }
 
-    jsAst.ArrayInitializer finalizeMap(Map<dynamic, _BoundMetadataEntry> map) {
-      bool isUsed(_BoundMetadataEntry entry) => entry.isUsed;
-      List<_BoundMetadataEntry> entries = map.values.where(isUsed).toList();
+    jsAst.ArrayInitializer finalizeMap(Map<dynamic, BoundMetadataEntry> map) {
+      bool isUsed(BoundMetadataEntry entry) => entry.isUsed;
+      List<BoundMetadataEntry> entries = map.values.where(isUsed).toList();
       entries.sort();
 
       // TODO(herhut): Bucket entries by index length and use a stable
       //               distribution within buckets.
       int count = 0;
-      for (_BoundMetadataEntry entry in entries) {
+      for (BoundMetadataEntry entry in entries) {
         entry.finalize(count++);
       }
 
       List<jsAst.Node> values =
-          entries.map((_BoundMetadataEntry e) => e.entry).toList();
+          entries.map((BoundMetadataEntry e) => e.entry).toList();
 
       return new jsAst.ArrayInitializer(values);
     }
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 1016f9a..cef6e37 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -112,15 +112,17 @@
     String receiverArgumentName = r'$receiver';
 
     // The parameters that this stub takes.
-    List<jsAst.Parameter> stubParameters = new List<jsAst.Parameter>(
+    List<jsAst.Parameter> stubParameters = new List<jsAst.Parameter>.filled(
         extraArgumentCount +
             selector.argumentCount +
-            selector.typeArgumentCount);
+            selector.typeArgumentCount,
+        null);
     // The arguments that will be passed to the real method.
-    List<jsAst.Expression> targetArguments = new List<jsAst.Expression>(
+    List<jsAst.Expression> targetArguments = new List<jsAst.Expression>.filled(
         extraArgumentCount +
             parameterStructure.totalParameters +
-            parameterStructure.typeParameters);
+            parameterStructure.typeParameters,
+        null);
 
     int count = 0;
     if (isInterceptedMethod) {
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 0d0b438..351d6bc 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
@@ -250,7 +250,8 @@
     Iterable<Fragment> deferredFragments =
         _registry.deferredLibrariesMap.map(_buildDeferredFragment);
 
-    List<Fragment> fragments = new List<Fragment>(_registry.librariesMapCount);
+    List<Fragment> fragments =
+        new List<Fragment>.filled(_registry.librariesMapCount, null);
     fragments[0] = mainFragment;
     fragments.setAll(1, deferredFragments);
 
@@ -480,7 +481,8 @@
   }
 
   List<Library> _buildLibraries(LibrariesMap librariesMap) {
-    List<Library> libraries = new List<Library>(librariesMap.length);
+    List<Library> libraries =
+        new List<Library>.filled(librariesMap.length, null);
     int count = 0;
     librariesMap.forEach((LibraryEntity library, List<ClassEntity> classes,
         List<MemberEntity> members, List<ClassEntity> classTypeElements) {
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index a7ad980..b5a67dd 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -10,7 +10,6 @@
 import 'package:kernel/core_types.dart' as ir;
 import 'package:kernel/src/bounds_checks.dart' as ir;
 
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../closure.dart' show BoxLocal, ThisLocal;
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 07cb160..ce387d5 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -17,6 +17,7 @@
 import 'package:kernel/target/targets.dart';
 
 import 'invocation_mirror_constants.dart';
+import 'transformations/lowering.dart' as lowering show transformLibraries;
 
 const Iterable<String> _allowedDartSchemePaths = const <String>[
   'async',
@@ -66,7 +67,7 @@
   bool get enableNoSuchMethodForwarders => true;
 
   @override
-  bool get supportsLateFields => false;
+  int get enabledLateLowerings => LateLowering.all;
 
   @override
   bool get supportsLateLoweringSentinel => false;
@@ -83,6 +84,12 @@
   List<String> get extraRequiredLibraries => _requiredLibraries[name];
 
   @override
+  List<String> get extraIndexedLibraries => const [
+        'dart:_interceptors',
+        'dart:_js_helper',
+      ];
+
+  @override
   bool mayDefineRestrictedType(Uri uri) =>
       uri.scheme == 'dart' &&
       (uri.path == 'core' || uri.path == '_interceptors');
@@ -118,6 +125,9 @@
               diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>)
           .visitLibrary(library);
     }
+    lowering.transformLibraries(
+        libraries, coreTypes, hierarchy, flags.enableNullSafety);
+    logger?.call("Lowering transformations performed");
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 05e5686..e1afb79 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -11,7 +11,6 @@
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
 import 'package:kernel/src/bounds_checks.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
diff --git a/pkg/compiler/lib/src/kernel/transformations/factory_specializer.dart b/pkg/compiler/lib/src/kernel/transformations/factory_specializer.dart
new file mode 100644
index 0000000..ebc00ae
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/transformations/factory_specializer.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart';
+import 'list_factory_specializer.dart';
+
+typedef SpecializerTransformer = TreeNode Function(
+    StaticInvocation node, Member contextMember);
+
+abstract class BaseSpecializer {
+  // Populated in constructors of subclasses.
+  final Map<Member, SpecializerTransformer> transformers = {};
+}
+
+class FactorySpecializer extends BaseSpecializer {
+  final ListFactorySpecializer _listFactorySpecializer;
+
+  FactorySpecializer(CoreTypes coreTypes, ClassHierarchy hierarchy)
+      : _listFactorySpecializer = ListFactorySpecializer(coreTypes, hierarchy) {
+    transformers.addAll(_listFactorySpecializer.transformers);
+  }
+
+  TreeNode transformStaticInvocation(
+      StaticInvocation invocation, Member contextMember) {
+    final target = invocation.target;
+    if (target == null) {
+      return invocation;
+    }
+
+    final transformer = transformers[target];
+    if (transformer != null) {
+      return transformer(invocation, contextMember);
+    }
+    return invocation;
+  }
+}
diff --git a/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart b/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart
new file mode 100644
index 0000000..5c10d5f
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart
@@ -0,0 +1,356 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'factory_specializer.dart';
+
+/// Replaces invocation of List factory constructors.
+///
+/// Expands `List.generate` to a loop when the function argument is a function
+/// expression (immediate closure).
+///
+class ListFactorySpecializer extends BaseSpecializer {
+  final CoreTypes coreTypes;
+  final ClassHierarchy hierarchy;
+
+  final Class _intClass;
+  final Class _jsArrayClass;
+  final Procedure _listGenerateFactory;
+  final Procedure _arrayAllocateFixedFactory;
+  final Procedure _arrayAllocateGrowableFactory;
+
+  ListFactorySpecializer(this.coreTypes, this.hierarchy)
+      : _listGenerateFactory =
+            coreTypes.index.getMember('dart:core', 'List', 'generate'),
+        _arrayAllocateFixedFactory = coreTypes.index
+            .getMember('dart:_interceptors', 'JSArray', 'allocateFixed'),
+        _arrayAllocateGrowableFactory = coreTypes.index
+            .getMember('dart:_interceptors', 'JSArray', 'allocateGrowable'),
+        _jsArrayClass =
+            coreTypes.index.getClass('dart:_interceptors', 'JSArray'),
+        _intClass = coreTypes.index.getClass('dart:core', 'int') {
+    assert(_listGenerateFactory.isFactory);
+    assert(_arrayAllocateGrowableFactory.isFactory);
+    assert(_arrayAllocateFixedFactory.isFactory);
+    transformers.addAll({
+      _listGenerateFactory: transformListGenerateFactory,
+    });
+  }
+
+  Member _intPlus;
+  Member get intPlus =>
+      _intPlus ??= hierarchy.getInterfaceMember(_intClass, Name('+'));
+
+  Member _intLess;
+  Member get intLess =>
+      _intLess ??= hierarchy.getInterfaceMember(_intClass, Name('<'));
+
+  Member _jsArrayIndexSet;
+  Member get jsArrayIndexSet => _jsArrayIndexSet ??=
+      hierarchy.getInterfaceMember(_jsArrayClass, Name('[]='));
+
+  /// Replace calls to `List.generate(length, (i) => e)` with an expansion
+  ///
+  ///     BlockExpression
+  ///       Block
+  ///         var _length = <length>;
+  ///         var _list = List.allocate(_length);
+  ///         for (var _i = 0; _i < _length; _i++) {
+  ///           _list[_i] = e;
+  ///         }
+  ///       => _list
+  ///
+  /// Declines to expand if:
+  ///  - the function argument is not a simple closure,
+  ///  - the `growable:` argument cannot be determined.
+  TreeNode transformListGenerateFactory(
+      StaticInvocation node, Member contextMember) {
+    final args = node.arguments;
+    assert(args.positional.length == 2);
+    final length = args.positional[0];
+    final generator = args.positional[1];
+    final bool growable =
+        _getConstantNamedOptionalArgument(args, 'growable', true);
+    if (growable == null) return node;
+
+    if (generator is! FunctionExpression) return node;
+
+    if (!ListGenerateLoopBodyInliner.suitableFunctionExpression(generator)) {
+      return node;
+    }
+
+    final intType = contextMember.isNonNullableByDefault
+        ? coreTypes.intLegacyRawType
+        : coreTypes.intNonNullableRawType;
+
+    // If the length is a constant, use the constant directly so that the
+    // inferrer can see the constant length.
+    int /*?*/ lengthConstant = _getLengthArgument(args);
+    VariableDeclaration lengthVariable;
+
+    Expression getLength() {
+      if (lengthConstant != null) return IntLiteral(lengthConstant);
+      lengthVariable ??= VariableDeclaration('_length',
+          initializer: length, isFinal: true, type: intType)
+        ..fileOffset = node.fileOffset;
+      return VariableGet(lengthVariable)..fileOffset = node.fileOffset;
+    }
+
+    TreeNode allocation = StaticInvocation(
+        growable ? _arrayAllocateGrowableFactory : _arrayAllocateFixedFactory,
+        Arguments(
+          [getLength()],
+          types: args.types,
+        ))
+      ..fileOffset = node.fileOffset;
+
+    final listVariable = VariableDeclaration(
+      _listNameFromContext(node),
+      initializer: allocation,
+      isFinal: true,
+      type: InterfaceType(
+          _jsArrayClass, Nullability.nonNullable, [...args.types]),
+    )..fileOffset = node.fileOffset;
+
+    final indexVariable = VariableDeclaration(
+      _indexNameFromContext(generator),
+      initializer: IntLiteral(0),
+      type: intType,
+    )..fileOffset = node.fileOffset;
+    indexVariable.fileOffset = (generator as FunctionExpression)
+        .function
+        .positionalParameters
+        .first
+        .fileOffset;
+
+    final loop = ForStatement(
+      // initializers: _i = 0
+      [indexVariable],
+      // condition: _i < _length
+      MethodInvocation(
+        VariableGet(indexVariable)..fileOffset = node.fileOffset,
+        Name('<'),
+        Arguments([getLength()]),
+      )..interfaceTarget = intLess,
+      // updates: _i++
+      [
+        VariableSet(
+          indexVariable,
+          MethodInvocation(
+            VariableGet(indexVariable)..fileOffset = node.fileOffset,
+            Name('+'),
+            Arguments([IntLiteral(1)]),
+          )..interfaceTarget = intPlus,
+        )..fileOffset = node.fileOffset,
+      ],
+      // body, e.g. _list[_i] = expression;
+      _loopBody(node.fileOffset, listVariable, indexVariable, generator),
+    )..fileOffset = node.fileOffset;
+
+    return BlockExpression(
+      Block([
+        if (lengthVariable != null) lengthVariable,
+        listVariable,
+        loop,
+      ]),
+      VariableGet(listVariable)..fileOffset = node.fileOffset,
+    );
+  }
+
+  Statement _loopBody(
+      int constructorFileOffset,
+      VariableDeclaration listVariable,
+      VariableDeclaration indexVariable,
+      FunctionExpression generator) {
+    final inliner = ListGenerateLoopBodyInliner(
+        this, constructorFileOffset, listVariable, generator.function);
+    inliner.bind(indexVariable);
+    return inliner.run();
+  }
+
+  /// Returns constant value of the first argument in [args], or null if it is
+  /// not a constant.
+  int /*?*/ _getLengthArgument(Arguments args) {
+    if (args.positional.length < 1) return null;
+    final value = args.positional.first;
+    if (value is IntLiteral) {
+      return value.value;
+    } else if (value is ConstantExpression) {
+      final constant = value.constant;
+      if (constant is IntConstant) {
+        return constant.value;
+      }
+    }
+    return null;
+  }
+
+  /// Returns constant value of the only named optional argument in [args], or
+  /// null if it is not a bool constant. Returns [defaultValue] if optional
+  /// argument is not passed. Argument is asserted to have the given [name].
+  bool /*?*/ _getConstantNamedOptionalArgument(
+      Arguments args, String name, bool defaultValue) {
+    if (args.named.isEmpty) {
+      return defaultValue;
+    }
+    final namedArg = args.named.single;
+    assert(namedArg.name == name);
+    final value = namedArg.value;
+    if (value is BoolLiteral) {
+      return value.value;
+    } else if (value is ConstantExpression) {
+      final constant = value.constant;
+      if (constant is BoolConstant) {
+        return constant.value;
+      }
+    }
+    return null;
+  }
+
+  /// Choose a name for the `_list` temporary. If the `List.generate` expression
+  /// is an initializer for a variable, use that name so that dart2js can try to
+  /// use one JavaScript variable with the source name for 'both' variables.
+  String _listNameFromContext(Expression node) {
+    TreeNode parent = node.parent;
+    if (parent is VariableDeclaration) return parent.name;
+    return '_list';
+  }
+
+  String _indexNameFromContext(FunctionExpression generator) {
+    final function = generator.function;
+    String /*?*/ candidate = function.positionalParameters.first.name;
+    if (candidate == null || candidate == '' || candidate == '_') return '_i';
+    return candidate;
+  }
+}
+
+/// Inliner for function expressions of `List.generate` calls.
+class ListGenerateLoopBodyInliner extends CloneVisitorNotMembers {
+  final ListFactorySpecializer listFactorySpecializer;
+
+  /// Offset for the constructor call, used for all nodes that carry the value of the list.
+  final int constructorFileOffset;
+  final VariableDeclaration listVariable;
+  final FunctionNode function;
+  VariableDeclaration argument;
+  VariableDeclaration parameter;
+  int functionNestingLevel = 0;
+
+  ListGenerateLoopBodyInliner(this.listFactorySpecializer,
+      this.constructorFileOffset, this.listVariable, this.function);
+
+  static bool suitableFunctionExpression(FunctionExpression node) {
+    final function = node.function;
+    // These conditions should be satisfied by language rules.
+    if (function.typeParameters.isNotEmpty) return false;
+    if (function.requiredParameterCount != 1) return false;
+    if (function.positionalParameters.length != 1) return false;
+    if (function.namedParameters.isNotEmpty) return false;
+
+    final body = function.body;
+
+    // Arrow functions.
+    if (body is ReturnStatement) return true;
+
+    if (body is Block) {
+      // Simple body containing just a return.
+      final statements = body.statements;
+      if (statements.length == 1 && statements.single is ReturnStatement) {
+        return true;
+      }
+
+      // TODO(sra): We can accept more complex closures but, with diminishing
+      // returns. It would probably be best to handle more complex cases by
+      // improving environment design and inlining.
+    }
+
+    return false;
+  }
+
+  void bind(VariableDeclaration argument) {
+    // The [argument] is the loop index variable. In the general case this needs
+    // to be copied to a variable for the closure parameter as that is a
+    // separate location that may be mutated.  In the usual case the closure
+    // parameter is not modified. We use the same name for the parameter and
+    // argument to help dart2js allocate both locations to the same JavaScript
+    // variable. The argument is usually named after the closure parameter.
+    final closureParameter = function.positionalParameters.single;
+    parameter = VariableDeclaration(argument.name,
+        initializer: VariableGet(argument)..fileOffset = argument.fileOffset,
+        type: closureParameter.type)
+      ..fileOffset = closureParameter.fileOffset;
+    this.argument = argument;
+    variables[closureParameter] = parameter;
+  }
+
+  Statement run() {
+    final body = cloneInContext(function.body);
+    return Block([parameter, body]);
+  }
+
+  @override
+  visitReturnStatement(ReturnStatement node) {
+    // Do the default for return statements in nested functions.
+    if (functionNestingLevel > 0) return super.visitReturnStatement(node);
+
+    // We don't use a variable for the returned value. In the simple case it is
+    // not necessary, and it is not clear that the rules for definite assignment
+    // are not a perfect match for the locations of return statements. Instead
+    // we expand
+    //
+    //     return expression;
+    //
+    // to
+    //
+    //     list[index] = expression;
+    //
+    // TODO(sra): Currently this inliner accepts only arrow functions (a single
+    // return). If a wider variety is accepted, we might need to break after the
+    // assignment to 'exit' the inlined code.
+
+    final expression = node.expression;
+    final value = expression == null ? NullLiteral() : clone(expression);
+    // TODO(sra): Indicate that this indexed setter is safe.
+    return ExpressionStatement(
+      MethodInvocation(
+        VariableGet(listVariable)..fileOffset = constructorFileOffset,
+        Name('[]='),
+        Arguments([
+          VariableGet(argument)..fileOffset = node.fileOffset,
+          value,
+        ]),
+      )
+        ..interfaceTarget = listFactorySpecializer.jsArrayIndexSet
+        ..isInvariant = true
+        ..isBoundsSafe = true
+        ..fileOffset = constructorFileOffset,
+    );
+  }
+
+  /// Nested functions.
+  @override
+  visitFunctionNode(FunctionNode node) {
+    functionNestingLevel++;
+    final cloned = super.visitFunctionNode(node);
+    functionNestingLevel--;
+    return cloned;
+  }
+
+  @override
+  visitVariableGet(VariableGet node) {
+    // Unmapped variables are from an outer scope.
+    var mapped = variables[node.variable] ?? node.variable;
+    return VariableGet(mapped, visitOptionalType(node.promotedType))
+      ..fileOffset = node.fileOffset;
+  }
+
+  @override
+  visitVariableSet(VariableSet node) {
+    // Unmapped variables are from an outer scope.
+    var mapped = variables[node.variable] ?? node.variable;
+    return VariableSet(mapped, clone(node.value))..fileOffset = node.fileOffset;
+  }
+}
diff --git a/pkg/compiler/lib/src/kernel/transformations/lowering.dart b/pkg/compiler/lib/src/kernel/transformations/lowering.dart
new file mode 100644
index 0000000..72c4f15
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/transformations/lowering.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:kernel/type_environment.dart'
+    show StaticTypeContext, TypeEnvironment;
+import 'factory_specializer.dart';
+
+/// dart2js-specific lowering transformations and optimizations combined into a
+/// single transformation pass.
+///
+/// Each transformation is applied locally to AST nodes of certain types after
+/// transforming children nodes.
+void transformLibraries(List<Library> libraries, CoreTypes coreTypes,
+    ClassHierarchy hierarchy, bool nullSafety) {
+  final transformer = _Lowering(coreTypes, hierarchy, nullSafety);
+  libraries.forEach(transformer.visitLibrary);
+}
+
+class _Lowering extends Transformer {
+  final TypeEnvironment env;
+  final bool nullSafety;
+  final FactorySpecializer factorySpecializer;
+
+  Member _currentMember;
+  StaticTypeContext _cachedStaticTypeContext;
+
+  _Lowering(CoreTypes coreTypes, ClassHierarchy hierarchy, this.nullSafety)
+      : env = TypeEnvironment(coreTypes, hierarchy),
+        factorySpecializer = FactorySpecializer(coreTypes, hierarchy);
+
+  // ignore: unused_element
+  StaticTypeContext get _staticTypeContext =>
+      _cachedStaticTypeContext ??= StaticTypeContext(_currentMember, env);
+
+  @override
+  defaultMember(Member node) {
+    _currentMember = node;
+    _cachedStaticTypeContext = null;
+
+    final result = super.defaultMember(node);
+
+    _currentMember = null;
+    _cachedStaticTypeContext = null;
+    return result;
+  }
+
+  @override
+  visitStaticInvocation(StaticInvocation node) {
+    node.transformChildren(this);
+    return factorySpecializer.transformStaticInvocation(node, _currentMember);
+  }
+}
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 9157cbf..47b0985 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -77,6 +77,17 @@
   /// If this is set, the compilation stops after type inference.
   Uri writeDataUri;
 
+  /// Location from which the serialized closed world is read.
+  ///
+  /// If this is set, the [entryPoint] is expected to be a .dill file and the
+  /// frontend work is skipped.
+  Uri readClosedWorldUri;
+
+  /// Location to which inference data is serialized.
+  ///
+  /// If this is set, the compilation stops after computing the closed world.
+  Uri writeClosedWorldUri;
+
   /// Location from which codegen data is read.
   ///
   /// If this is set, the compilation starts at codegen enqueueing.
@@ -308,6 +319,11 @@
   /// This is an internal configuration option derived from other flags.
   CheckPolicy defaultExplicitCastCheckPolicy;
 
+  /// What should the compiler do with List index bounds checks.
+  ///
+  /// This is an internal configuration option derived from other flags.
+  CheckPolicy defaultIndexBoundsCheckPolicy;
+
   /// Whether to generate code compliant with content security policy (CSP).
   bool useContentSecurityPolicy = false;
 
@@ -497,6 +513,10 @@
           _extractUriListOption(options, '${Flags.dillDependencies}')
       ..readDataUri = _extractUriOption(options, '${Flags.readData}=')
       ..writeDataUri = _extractUriOption(options, '${Flags.writeData}=')
+      ..readClosedWorldUri =
+          _extractUriOption(options, '${Flags.readClosedWorld}=')
+      ..writeClosedWorldUri =
+          _extractUriOption(options, '${Flags.writeClosedWorld}=')
       ..readCodegenUri = _extractUriOption(options, '${Flags.readCodegen}=')
       ..writeCodegenUri = _extractUriOption(options, '${Flags.writeCodegen}=')
       ..codegenShard = _extractIntOption(options, '${Flags.codegenShard}=')
@@ -595,6 +615,11 @@
     } else {
       defaultExplicitCastCheckPolicy = CheckPolicy.checked;
     }
+    if (trustPrimitives) {
+      defaultIndexBoundsCheckPolicy = CheckPolicy.trusted;
+    } else {
+      defaultIndexBoundsCheckPolicy = CheckPolicy.checked;
+    }
 
     if (_disableMinification) {
       enableMinification = false;
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index dcbcf37..8be4970 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -55,7 +55,7 @@
 
     int levelCount = source.readInt();
     List<Link<InterfaceType>> levels =
-        new List<Link<InterfaceType>>(levelCount);
+        new List<Link<InterfaceType>>.filled(levelCount, null);
     for (int i = 0; i < levelCount; i++) {
       levels[i] = links[source.readInt()];
     }
@@ -90,7 +90,8 @@
   factory OrderedTypeSet.singleton(InterfaceType type) {
     Link<InterfaceType> types =
         new LinkEntry<InterfaceType>(type, const Link<InterfaceType>());
-    List<Link<InterfaceType>> list = new List<Link<InterfaceType>>(1);
+    List<Link<InterfaceType>> list =
+        new List<Link<InterfaceType>>.filled(1, null);
     list[0] = types;
     return new OrderedTypeSet.internal(list, types);
   }
@@ -107,7 +108,8 @@
             'OrderedTypeSet.extendClass'));
     Link<InterfaceType> extendedTypes =
         new LinkEntry<InterfaceType>(type, types);
-    List<Link<InterfaceType>> list = new List<Link<InterfaceType>>(levels + 1);
+    List<Link<InterfaceType>> list =
+        new List<Link<InterfaceType>>.filled(levels + 1, null);
     for (int i = 0; i < levels; i++) {
       list[i] = _levels[i];
     }
@@ -257,7 +259,7 @@
 
   OrderedTypeSet toTypeSet() {
     List<Link<InterfaceType>> levels =
-        new List<Link<InterfaceType>>(maxDepth + 1);
+        new List<Link<InterfaceType>>.filled(maxDepth + 1, null);
     if (maxDepth < 0) {
       return new OrderedTypeSet.internal(levels, const Link<InterfaceType>());
     }
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index b3ad306..c1e8ea1 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -143,7 +143,7 @@
   List<ir.DartType> _readDartTypeNodes(
       List<ir.TypeParameter> functionTypeVariables) {
     int count = readInt();
-    List<ir.DartType> types = new List<ir.DartType>(count);
+    List<ir.DartType> types = new List<ir.DartType>.filled(count, null);
     for (int index = 0; index < count; index++) {
       types[index] = _readDartTypeNode(functionTypeVariables);
     }
@@ -229,7 +229,7 @@
             _readDartTypeNodes(functionTypeVariables);
         int namedParameterCount = readInt();
         List<ir.NamedType> namedParameters =
-            new List<ir.NamedType>(namedParameterCount);
+            new List<ir.NamedType>.filled(namedParameterCount, null);
         for (int index = 0; index < namedParameterCount; index++) {
           String name = readString();
           bool isRequired = readBool();
@@ -427,7 +427,7 @@
       {bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
       list[i] = node;
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index 3718e25..d7d5d87 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -19,7 +19,7 @@
   List<E> readList<E>(E f(), {bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = f();
     }
@@ -48,7 +48,7 @@
   List<String> readStrings({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<String> list = new List<String>(count);
+    List<String> list = new List<String>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readString();
     }
@@ -59,7 +59,7 @@
   List<DartType> readDartTypes({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<DartType> list = new List<DartType>(count);
+    List<DartType> list = new List<DartType>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readDartType();
     }
@@ -70,7 +70,8 @@
   List<ir.TypeParameter> readTypeParameterNodes({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<ir.TypeParameter> list = new List<ir.TypeParameter>(count);
+    List<ir.TypeParameter> list =
+        new List<ir.TypeParameter>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readTypeParameterNode();
     }
@@ -81,7 +82,7 @@
   List<E> readMembers<E extends MemberEntity>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       MemberEntity member = readMember();
       list[i] = member;
@@ -93,7 +94,7 @@
   List<E> readMemberNodes<E extends ir.Member>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ir.Member value = readMemberNode();
       list[i] = value;
@@ -105,7 +106,7 @@
   List<E> readClasses<E extends ClassEntity>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ClassEntity cls = readClass();
       list[i] = cls;
@@ -187,7 +188,7 @@
   List<E> readLocals<E extends Local>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       Local local = readLocal();
       list[i] = local;
@@ -212,7 +213,7 @@
   List<E> readTreeNodes<E extends ir.TreeNode>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ir.TreeNode node = readTreeNode();
       list[i] = node;
@@ -282,7 +283,7 @@
   List<E> readConstants<E extends ConstantValue>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ConstantValue value = readConstant();
       list[i] = value;
@@ -326,7 +327,7 @@
   List<ImportEntity> readImports({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<ImportEntity> list = new List<ImportEntity>(count);
+    List<ImportEntity> list = new List<ImportEntity>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readImport();
     }
@@ -350,7 +351,7 @@
   List<ir.DartType> readDartTypeNodes({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<ir.DartType> list = new List<ir.DartType>(count);
+    List<ir.DartType> list = new List<ir.DartType>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readDartTypeNode();
     }
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 6663884..6cc9a51 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -6,8 +6,6 @@
 import 'dart:typed_data';
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/binary/ast_from_binary.dart' as ir;
-import 'package:kernel/binary/ast_to_binary.dart' as ir;
 import '../closure.dart';
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
diff --git a/pkg/compiler/lib/src/serialization/strategies.dart b/pkg/compiler/lib/src/serialization/strategies.dart
index 0c159f9..37fbe89 100644
--- a/pkg/compiler/lib/src/serialization/strategies.dart
+++ b/pkg/compiler/lib/src/serialization/strategies.dart
@@ -24,13 +24,18 @@
 abstract class SerializationStrategy<T> {
   const SerializationStrategy();
 
-  List<int> serializeComponent(GlobalTypeInferenceResults results) {
+  List<int> unpackAndSerializeComponent(GlobalTypeInferenceResults results) {
     JsClosedWorld closedWorld = results.closedWorld;
     ir.Component component = closedWorld.elementMap.programEnv.mainComponent;
-    return ir.serializeComponent(component);
+    return serializeComponent(component);
   }
 
-  List<T> serializeData(GlobalTypeInferenceResults results);
+  List<T> serializeGlobalTypeInferenceResults(
+      GlobalTypeInferenceResults results);
+
+  List<int> serializeComponent(ir.Component component) {
+    return ir.serializeComponent(component);
+  }
 
   ir.Component deserializeComponent(List<int> data) {
     ir.Component component = new ir.Component();
@@ -38,7 +43,17 @@
     return component;
   }
 
-  GlobalTypeInferenceResults deserializeData(
+  GlobalTypeInferenceResults deserializeGlobalTypeInferenceResults(
+      CompilerOptions options,
+      DiagnosticReporter reporter,
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy,
+      ir.Component component,
+      List<T> data);
+
+  List<T> serializeClosedWorld(JsClosedWorld closedWorld);
+
+  JsClosedWorld deserializeClosedWorld(
       CompilerOptions options,
       DiagnosticReporter reporter,
       Environment environment,
@@ -53,15 +68,16 @@
   const BytesInMemorySerializationStrategy({this.useDataKinds: false});
 
   @override
-  List<int> serializeData(GlobalTypeInferenceResults results) {
+  List<int> serializeGlobalTypeInferenceResults(
+      GlobalTypeInferenceResults results) {
     ByteSink byteSink = new ByteSink();
     DataSink sink = new BinarySink(byteSink, useDataKinds: useDataKinds);
-    serializeGlobalTypeInferenceResults(results, sink);
+    serializeGlobalTypeInferenceResultsToSink(results, sink);
     return byteSink.builder.takeBytes();
   }
 
   @override
-  GlobalTypeInferenceResults deserializeData(
+  GlobalTypeInferenceResults deserializeGlobalTypeInferenceResults(
       CompilerOptions options,
       DiagnosticReporter reporter,
       Environment environment,
@@ -69,7 +85,28 @@
       ir.Component component,
       List<int> data) {
     DataSource source = new BinarySourceImpl(data, useDataKinds: useDataKinds);
-    return deserializeGlobalTypeInferenceResults(options, reporter, environment,
+    return deserializeGlobalTypeInferenceResultsFromSource(options, reporter,
+        environment, abstractValueStrategy, component, source);
+  }
+
+  @override
+  List<int> serializeClosedWorld(JsClosedWorld closedWorld) {
+    ByteSink byteSink = new ByteSink();
+    DataSink sink = new BinarySink(byteSink, useDataKinds: useDataKinds);
+    serializeClosedWorldToSink(closedWorld, sink);
+    return byteSink.builder.takeBytes();
+  }
+
+  @override
+  JsClosedWorld deserializeClosedWorld(
+      CompilerOptions options,
+      DiagnosticReporter reporter,
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy,
+      ir.Component component,
+      List<int> data) {
+    DataSource source = new BinarySourceImpl(data, useDataKinds: useDataKinds);
+    return deserializeClosedWorldFromSource(options, reporter, environment,
         abstractValueStrategy, component, source);
   }
 }
@@ -80,17 +117,18 @@
   const BytesOnDiskSerializationStrategy({this.useDataKinds: false});
 
   @override
-  List<int> serializeData(GlobalTypeInferenceResults results) {
+  List<int> serializeGlobalTypeInferenceResults(
+      GlobalTypeInferenceResults results) {
     Uri uri = Uri.base.resolve('world.data');
     DataSink sink = new BinarySink(
         new BinaryOutputSinkAdapter(new RandomAccessBinaryOutputSink(uri)),
         useDataKinds: useDataKinds);
-    serializeGlobalTypeInferenceResults(results, sink);
+    serializeGlobalTypeInferenceResultsToSink(results, sink);
     return new File.fromUri(uri).readAsBytesSync();
   }
 
   @override
-  GlobalTypeInferenceResults deserializeData(
+  GlobalTypeInferenceResults deserializeGlobalTypeInferenceResults(
       CompilerOptions options,
       DiagnosticReporter reporter,
       Environment environment,
@@ -98,7 +136,30 @@
       ir.Component component,
       List<int> data) {
     DataSource source = new BinarySourceImpl(data, useDataKinds: useDataKinds);
-    return deserializeGlobalTypeInferenceResults(options, reporter, environment,
+    return deserializeGlobalTypeInferenceResultsFromSource(options, reporter,
+        environment, abstractValueStrategy, component, source);
+  }
+
+  @override
+  List<int> serializeClosedWorld(JsClosedWorld closedWorld) {
+    Uri uri = Uri.base.resolve('closed_world.data');
+    DataSink sink = new BinarySink(
+        new BinaryOutputSinkAdapter(new RandomAccessBinaryOutputSink(uri)),
+        useDataKinds: useDataKinds);
+    serializeClosedWorldToSink(closedWorld, sink);
+    return new File.fromUri(uri).readAsBytesSync();
+  }
+
+  @override
+  JsClosedWorld deserializeClosedWorld(
+      CompilerOptions options,
+      DiagnosticReporter reporter,
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy,
+      ir.Component component,
+      List<int> data) {
+    DataSource source = new BinarySourceImpl(data, useDataKinds: useDataKinds);
+    return deserializeClosedWorldFromSource(options, reporter, environment,
         abstractValueStrategy, component, source);
   }
 }
@@ -110,15 +171,16 @@
   const ObjectsInMemorySerializationStrategy({this.useDataKinds: true});
 
   @override
-  List<Object> serializeData(GlobalTypeInferenceResults results) {
+  List<Object> serializeGlobalTypeInferenceResults(
+      GlobalTypeInferenceResults results) {
     List<Object> data = [];
     DataSink sink = new ObjectSink(data, useDataKinds: useDataKinds);
-    serializeGlobalTypeInferenceResults(results, sink);
+    serializeGlobalTypeInferenceResultsToSink(results, sink);
     return data;
   }
 
   @override
-  GlobalTypeInferenceResults deserializeData(
+  GlobalTypeInferenceResults deserializeGlobalTypeInferenceResults(
       CompilerOptions options,
       DiagnosticReporter reporter,
       Environment environment,
@@ -126,7 +188,28 @@
       ir.Component component,
       List<Object> data) {
     DataSource source = new ObjectSource(data, useDataKinds: useDataKinds);
-    return deserializeGlobalTypeInferenceResults(options, reporter, environment,
+    return deserializeGlobalTypeInferenceResultsFromSource(options, reporter,
+        environment, abstractValueStrategy, component, source);
+  }
+
+  @override
+  List<Object> serializeClosedWorld(JsClosedWorld closedWorld) {
+    List<Object> data = [];
+    DataSink sink = new ObjectSink(data, useDataKinds: useDataKinds);
+    serializeClosedWorldToSink(closedWorld, sink);
+    return data;
+  }
+
+  @override
+  JsClosedWorld deserializeClosedWorld(
+      CompilerOptions options,
+      DiagnosticReporter reporter,
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy,
+      ir.Component component,
+      List<Object> data) {
+    DataSource source = new ObjectSource(data, useDataKinds: useDataKinds);
+    return deserializeClosedWorldFromSource(options, reporter, environment,
         abstractValueStrategy, component, source);
   }
 }
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 8a081d7..28d3224 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -24,7 +24,7 @@
 import '../world.dart';
 import 'serialization.dart';
 
-void serializeGlobalTypeInferenceResults(
+void serializeGlobalTypeInferenceResultsToSink(
     GlobalTypeInferenceResults results, DataSink sink) {
   JsClosedWorld closedWorld = results.closedWorld;
   InferredData inferredData = results.inferredData;
@@ -34,7 +34,21 @@
   sink.close();
 }
 
-GlobalTypeInferenceResults deserializeGlobalTypeInferenceResults(
+GlobalTypeInferenceResults deserializeGlobalAnalysisFromSource(
+    CompilerOptions options,
+    DiagnosticReporter reporter,
+    Environment environment,
+    AbstractValueStrategy abstractValueStrategy,
+    ir.Component component,
+    JsClosedWorld newClosedWorld,
+    DataSource source) {
+  InferredData newInferredData =
+      InferredData.readFromDataSource(source, newClosedWorld);
+  return GlobalTypeInferenceResults.readFromDataSource(
+      source, newClosedWorld.elementMap, newClosedWorld, newInferredData);
+}
+
+GlobalTypeInferenceResults deserializeGlobalTypeInferenceResultsFromSource(
     CompilerOptions options,
     DiagnosticReporter reporter,
     Environment environment,
@@ -49,6 +63,22 @@
       source, newClosedWorld.elementMap, newClosedWorld, newInferredData);
 }
 
+void serializeClosedWorldToSink(JsClosedWorld closedWorld, DataSink sink) {
+  closedWorld.writeToDataSink(sink);
+  sink.close();
+}
+
+JsClosedWorld deserializeClosedWorldFromSource(
+    CompilerOptions options,
+    DiagnosticReporter reporter,
+    Environment environment,
+    AbstractValueStrategy abstractValueStrategy,
+    ir.Component component,
+    DataSource source) {
+  return new JsClosedWorld.readFromDataSource(
+      options, reporter, environment, abstractValueStrategy, component, source);
+}
+
 class SerializationTask extends CompilerTask {
   final CompilerOptions _options;
   final DiagnosticReporter _reporter;
@@ -62,7 +92,7 @@
   @override
   String get name => 'Serialization';
 
-  void serializeGlobalTypeInference(GlobalTypeInferenceResults results) {
+  void serializeComponent(ir.Component component) {
     measureSubtask('serialize dill', () {
       // TODO(sigmund): remove entirely: we will do this immediately as soon as
       // we get the component in the kernel/loader.dart task once we refactor
@@ -70,28 +100,15 @@
       _reporter.log('Writing dill to ${_options.outputUri}');
       api.BinaryOutputSink dillOutput =
           _outputProvider.createBinarySink(_options.outputUri);
-      JsClosedWorld closedWorld = results.closedWorld;
-      ir.Component component = closedWorld.elementMap.programEnv.mainComponent;
       BinaryOutputSinkAdapter irSink = new BinaryOutputSinkAdapter(dillOutput);
       ir.BinaryPrinter printer = new ir.BinaryPrinter(irSink);
       printer.writeComponentFile(component);
       irSink.close();
     });
-
-    measureSubtask('serialize data', () {
-      _reporter.log('Writing data to ${_options.writeDataUri}');
-      api.BinaryOutputSink dataOutput =
-          _outputProvider.createBinarySink(_options.writeDataUri);
-      DataSink sink = new BinarySink(new BinaryOutputSinkAdapter(dataOutput));
-      serializeGlobalTypeInferenceResults(results, sink);
-    });
   }
 
-  Future<GlobalTypeInferenceResults> deserializeGlobalTypeInference(
-      Environment environment,
-      AbstractValueStrategy abstractValueStrategy) async {
-    ir.Component component =
-        await measureIoSubtask('deserialize dill', () async {
+  Future<ir.Component> deserializeComponent() async {
+    return measureIoSubtask('deserialize dill', () async {
       _reporter.log('Reading dill from ${_options.entryPoint}');
       api.Input<List<int>> dillInput = await _provider
           .readFromUri(_options.entryPoint, inputKind: api.InputKind.binary);
@@ -99,7 +116,9 @@
       new ir.BinaryBuilder(dillInput.data).readComponent(component);
       return component;
     });
+  }
 
+  void updateOptionsFromComponent(ir.Component component) {
     var isStrongDill =
         component.mode == ir.NonNullableByDefaultCompiledMode.Strong;
     var incompatibleNullSafetyMode =
@@ -118,14 +137,80 @@
     } else {
       _options.nullSafetyMode = NullSafetyMode.unsound;
     }
+  }
+
+  Future<ir.Component> deserializeComponentAndUpdateOptions() async {
+    ir.Component component = await deserializeComponent();
+    updateOptionsFromComponent(component);
+    return component;
+  }
+
+  void serializeClosedWorld(JsClosedWorld closedWorld) {
+    measureSubtask('serialize closed world', () {
+      _reporter.log('Writing closed world to ${_options.writeClosedWorldUri}');
+      api.BinaryOutputSink dataOutput =
+          _outputProvider.createBinarySink(_options.writeClosedWorldUri);
+      DataSink sink = new BinarySink(new BinaryOutputSinkAdapter(dataOutput));
+      serializeClosedWorldToSink(closedWorld, sink);
+    });
+  }
+
+  Future<JsClosedWorld> deserializeClosedWorld(
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy,
+      ir.Component component) async {
+    return await measureIoSubtask('deserialize closed world', () async {
+      _reporter.log('Reading data from ${_options.readClosedWorldUri}');
+      api.Input<List<int>> dataInput = await _provider.readFromUri(
+          _options.readClosedWorldUri,
+          inputKind: api.InputKind.binary);
+      DataSource source = new BinarySourceImpl(dataInput.data);
+      return deserializeClosedWorldFromSource(_options, _reporter, environment,
+          abstractValueStrategy, component, source);
+    });
+  }
+
+  void serializeGlobalTypeInference(GlobalTypeInferenceResults results) {
+    JsClosedWorld closedWorld = results.closedWorld;
+    ir.Component component = closedWorld.elementMap.programEnv.mainComponent;
+    serializeComponent(component);
+
+    measureSubtask('serialize data', () {
+      _reporter.log('Writing data to ${_options.writeDataUri}');
+      api.BinaryOutputSink dataOutput =
+          _outputProvider.createBinarySink(_options.writeDataUri);
+      DataSink sink = new BinarySink(new BinaryOutputSinkAdapter(dataOutput));
+      serializeGlobalTypeInferenceResultsToSink(results, sink);
+    });
+  }
+
+  Future<GlobalTypeInferenceResults> deserializeGlobalTypeInference(
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy) async {
+    ir.Component component = await deserializeComponentAndUpdateOptions();
 
     return await measureIoSubtask('deserialize data', () async {
       _reporter.log('Reading data from ${_options.readDataUri}');
       api.Input<List<int>> dataInput = await _provider
           .readFromUri(_options.readDataUri, inputKind: api.InputKind.binary);
       DataSource source = new BinarySourceImpl(dataInput.data);
-      return deserializeGlobalTypeInferenceResults(_options, _reporter,
-          environment, abstractValueStrategy, component, source);
+      return deserializeGlobalTypeInferenceResultsFromSource(_options,
+          _reporter, environment, abstractValueStrategy, component, source);
+    });
+  }
+
+  Future<GlobalTypeInferenceResults> deserializeGlobalAnalysis(
+      Environment environment,
+      AbstractValueStrategy abstractValueStrategy,
+      ir.Component component,
+      JsClosedWorld closedWorld) async {
+    return await measureIoSubtask('deserialize data', () async {
+      _reporter.log('Reading data from ${_options.readDataUri}');
+      api.Input<List<int>> dataInput = await _provider
+          .readFromUri(_options.readDataUri, inputKind: api.InputKind.binary);
+      DataSource source = BinarySourceImpl(dataInput.data);
+      return deserializeGlobalAnalysisFromSource(_options, _reporter,
+          environment, abstractValueStrategy, component, closedWorld, source);
     });
   }
 
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index fb0b04b..7c66c12 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -1981,6 +1981,8 @@
           _sourceInformationBuilder.buildForInCurrent(node);
       HInstruction index = localsHandler.readLocal(indexVariable,
           sourceInformation: sourceInformation);
+      // No bound check is necessary on indexer as it is immediately guarded by
+      // the condition.
       HInstruction value = new HIndex(array, index, type)
         ..sourceInformation = sourceInformation;
       add(value);
@@ -3882,7 +3884,10 @@
       if (_abstractValueDomain.isFixedArray(resultType).isDefinitelyTrue) {
         // These constructors all take a length as the first argument.
         if (_commonElements.isNamedListConstructor('filled', function) ||
-            _commonElements.isNamedListConstructor('generate', function)) {
+            _commonElements.isNamedListConstructor('generate', function) ||
+            _commonElements.isNamedJSArrayConstructor('fixed', function) ||
+            _commonElements.isNamedJSArrayConstructor(
+                'allocateFixed', function)) {
           isFixedList = true;
         }
       }
@@ -4963,22 +4968,29 @@
 
     AbstractValue resultType =
         _typeInferenceMap.resultTypeOfSelector(selector, receiverType);
+    HInvokeDynamic invoke;
     if (selector.isGetter) {
-      push(new HInvokeDynamicGetter(selector, receiverType, element, inputs,
-          isIntercepted, resultType, sourceInformation));
+      invoke = HInvokeDynamicGetter(selector, receiverType, element, inputs,
+          isIntercepted, resultType, sourceInformation);
     } else if (selector.isSetter) {
-      push(new HInvokeDynamicSetter(selector, receiverType, element, inputs,
-          isIntercepted, resultType, sourceInformation));
+      invoke = HInvokeDynamicSetter(selector, receiverType, element, inputs,
+          isIntercepted, resultType, sourceInformation);
     } else if (selector.isClosureCall) {
       assert(!isIntercepted);
-      push(new HInvokeClosure(
+      invoke = HInvokeClosure(
           selector, receiverType, inputs, resultType, typeArguments)
-        ..sourceInformation = sourceInformation);
+        ..sourceInformation = sourceInformation;
     } else {
-      push(new HInvokeDynamicMethod(selector, receiverType, inputs, resultType,
+      invoke = HInvokeDynamicMethod(selector, receiverType, inputs, resultType,
           typeArguments, sourceInformation,
-          isIntercepted: isIntercepted));
+          isIntercepted: isIntercepted);
     }
+    invoke.instructionContext = _currentFrame.member;
+    if (node is ir.MethodInvocation) {
+      invoke.isInvariant = node.isInvariant;
+      invoke.isBoundsSafe = node.isBoundsSafe;
+    }
+    push(invoke);
   }
 
   HInstruction _invokeJsInteropFunction(
@@ -5203,7 +5215,7 @@
     var argumentsInstruction = _buildLiteralList(arguments);
     add(argumentsInstruction);
 
-    var argumentNames = new List<HInstruction>();
+    var argumentNames = <HInstruction>[];
     for (String argumentName in selector.namedArguments) {
       ConstantValue argumentNameConstant =
           constant_system.createString(argumentName);
@@ -5853,10 +5865,11 @@
     ParameterStructure parameterStructure = function.parameterStructure;
     List<String> selectorArgumentNames =
         selector.callStructure.getOrderedNamedArguments();
-    List<HInstruction> compiledArguments = new List<HInstruction>(
+    List<HInstruction> compiledArguments = new List<HInstruction>.filled(
         parameterStructure.totalParameters +
             parameterStructure.typeParameters +
-            1); // Plus one for receiver.
+            1,
+        null); // Plus one for receiver.
 
     int compiledArgumentIndex = 0;
 
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 7c50116..098531f 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -642,7 +642,7 @@
   List<js.Expression> visitArguments(List<HInstruction> inputs,
       {int start: HInvoke.ARGUMENTS_OFFSET}) {
     assert(inputs.length >= start);
-    List<js.Expression> result = new List<js.Expression>(inputs.length - start);
+    List<js.Expression> result = new List<js.Expression>.filled(inputs.length - start, null);
     for (int i = start; i < inputs.length; i++) {
       use(inputs[i]);
       result[i - start] = pop();
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 6aa5a3c..cb8a95e 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -886,7 +886,7 @@
 
     // The expectedInputs list holds non-trivial instructions that may
     // be generated at their use site, if they occur in the correct order.
-    if (expectedInputs == null) expectedInputs = new List<HInstruction>();
+    if (expectedInputs == null) expectedInputs = <HInstruction>[];
     if (pureInputs == null) pureInputs = new Set<HInstruction>();
 
     // Pop instructions from expectedInputs until instruction is found.
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 49e534a..7311e2e 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -84,6 +84,7 @@
         int argumentCount = selector.argumentCount;
         if (argumentCount == 0) {
           if (name == 'abs') return const AbsSpecializer();
+          if (name == 'removeLast') return const RemoveLastSpecializer();
           if (name == 'round') return const RoundSpecializer();
           if (name == 'toInt') return const ToIntSpecializer();
           if (name == 'trim') return const TrimSpecializer();
@@ -107,6 +108,34 @@
     }
     return const InvokeDynamicSpecializer();
   }
+
+  bool requiresBoundsCheck(HInvokeDynamic node, JClosedWorld closedWorld) {
+    if (node.isBoundsSafe) return false;
+    return closedWorld.annotationsData
+        .getIndexBoundsCheckPolicy(node.instructionContext)
+        .isEmitted;
+  }
+
+  HBoundsCheck insertBoundsCheck(HInstruction indexerNode, HInstruction array,
+      HInstruction indexArgument, JClosedWorld closedWorld) {
+    final abstractValueDomain = closedWorld.abstractValueDomain;
+    HGetLength length = HGetLength(array, abstractValueDomain.positiveIntType,
+        isAssignable: abstractValueDomain
+            .isFixedLengthJsIndexable(array.instructionType)
+            .isPotentiallyFalse);
+    indexerNode.block.addBefore(indexerNode, length);
+
+    AbstractValue type =
+        indexArgument.isPositiveInteger(abstractValueDomain).isDefinitelyTrue
+            ? indexArgument.instructionType
+            : abstractValueDomain.positiveIntType;
+    HBoundsCheck check = HBoundsCheck(indexArgument, length, array, type)
+      ..sourceInformation = indexerNode.sourceInformation;
+    indexerNode.block.addBefore(indexerNode, check);
+    // TODO(sra): This should be useful but causes some crashes. Figure out why:
+    //     indexArgument.replaceAllUsersDominatedBy(indexerNode, check);
+    return check;
+  }
 }
 
 bool canBeNegativeZero(HInstruction input) {
@@ -178,8 +207,14 @@
         return null;
       }
     }
-    HIndexAssign converted = new HIndexAssign(
-        closedWorld.abstractValueDomain, receiver, index, value);
+
+    HInstruction checkedIndex = index;
+    if (requiresBoundsCheck(instruction, closedWorld)) {
+      checkedIndex =
+          insertBoundsCheck(instruction, receiver, index, closedWorld);
+    }
+    HIndexAssign converted = HIndexAssign(
+        closedWorld.abstractValueDomain, receiver, checkedIndex, value);
     log?.registerIndexAssign(instruction, converted);
     return converted;
   }
@@ -192,6 +227,9 @@
       HInstruction value,
       JCommonElements commonElements,
       JClosedWorld closedWorld) {
+    if (instruction.isInvariant) {
+      return true;
+    }
     // Handle typed arrays by recognizing the exact implementation of `[]=` and
     // checking if [value] has the appropriate type.
     if (instruction.element != null) {
@@ -228,36 +266,82 @@
       JCommonElements commonElements,
       JClosedWorld closedWorld,
       OptimizationTestLog log) {
+    HInstruction receiver = instruction.getDartReceiver(closedWorld);
     var abstractValueDomain = closedWorld.abstractValueDomain;
-    if (instruction.inputs[1]
-        .isIndexablePrimitive(abstractValueDomain)
-        .isPotentiallyFalse) {
+    if (receiver.isIndexablePrimitive(abstractValueDomain).isPotentiallyFalse) {
       return null;
     }
-    if (instruction.inputs[2]
-            .isInteger(abstractValueDomain)
-            .isPotentiallyFalse &&
+    HInstruction index = instruction.inputs.last;
+    if (index.isInteger(abstractValueDomain).isPotentiallyFalse &&
         // TODO(johnniwinther): Support annotations on the possible targets
         // and used their parameter check policy here.
         closedWorld.annotationsData.getParameterCheckPolicy(null).isEmitted) {
       // We want the right checked mode error.
       return null;
     }
-    AbstractValue receiverType =
-        instruction.getDartReceiver(closedWorld).instructionType;
+    AbstractValue receiverType = receiver.instructionType;
     AbstractValue elementType =
         AbstractValueFactory.inferredResultTypeForSelector(
             instruction.selector, receiverType, results);
     if (abstractValueDomain.isTypedArray(receiverType).isDefinitelyTrue) {
       elementType = abstractValueDomain.excludeNull(elementType);
     }
-    HIndex converted =
-        new HIndex(instruction.inputs[1], instruction.inputs[2], elementType);
+
+    HInstruction checkedIndex = index;
+    if (requiresBoundsCheck(instruction, closedWorld)) {
+      checkedIndex =
+          insertBoundsCheck(instruction, receiver, index, closedWorld);
+    }
+    HIndex converted = HIndex(receiver, checkedIndex, elementType);
     log?.registerIndex(instruction, converted);
     return converted;
   }
 }
 
+class RemoveLastSpecializer extends InvokeDynamicSpecializer {
+  const RemoveLastSpecializer();
+
+  @override
+  HInstruction tryConvertToBuiltin(
+      HInvokeDynamic instruction,
+      HGraph graph,
+      GlobalTypeInferenceResults results,
+      JCommonElements commonElements,
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
+    HInstruction receiver = instruction.getDartReceiver(closedWorld);
+    final abstractValueDomain = closedWorld.abstractValueDomain;
+    if (receiver.isExtendableArray(abstractValueDomain).isPotentiallyFalse) {
+      return null;
+    }
+
+    // We are essentially inlining `result = a[a.length - 1]`. `0` is the only
+    // index that can fail so we check zero directly, but we want to report the
+    // error index as `-1`, so we add `-1` as an extra input that to the check.
+    if (requiresBoundsCheck(instruction, closedWorld)) {
+      HConstant zeroIndex = graph.addConstantInt(0, closedWorld);
+      HBoundsCheck check =
+          insertBoundsCheck(instruction, receiver, zeroIndex, closedWorld);
+      HInstruction minusOne = graph.addConstantInt(-1, closedWorld);
+      check.inputs.add(minusOne);
+      minusOne.usedBy.add(check);
+    }
+    // `Array.pop` is encoded as a non-intercepted call to `JSArray.removeLast`.
+    // TODO(sra): Add a better encoding for `Array.pop`, perhaps a HInstruction.
+    HInvokeDynamic converted = HInvokeDynamicMethod(
+        instruction.selector,
+        instruction.receiverType,
+        [receiver], // Drop interceptor.
+        instruction.instructionType,
+        instruction.typeArguments,
+        instruction.sourceInformation,
+        isIntercepted: false)
+      ..element = commonElements.jsArrayRemoveLast;
+    log?.registerRemoveLast(instruction, converted);
+    return converted;
+  }
+}
+
 class BitNotSpecializer extends InvokeDynamicSpecializer {
   const BitNotSpecializer();
 
diff --git a/pkg/compiler/lib/src/ssa/logging.dart b/pkg/compiler/lib/src/ssa/logging.dart
index e857648..d7c7e54 100644
--- a/pkg/compiler/lib/src/ssa/logging.dart
+++ b/pkg/compiler/lib/src/ssa/logging.dart
@@ -114,6 +114,10 @@
     _registerSpecializer(original, converted, 'Index');
   }
 
+  void registerRemoveLast(HInvokeDynamic original, HInvokeDynamic converted) {
+    _registerSpecializer(original, converted, 'RemoveLast');
+  }
+
   void registerBitNot(HInvokeDynamic original, HBitNot converted) {
     _registerSpecializer(original, converted, 'BitNot');
   }
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 6a551f89..25b48a8 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -1389,6 +1389,15 @@
   String toString() => '${this.runtimeType}()';
 }
 
+/// An interface implemented by certain kinds of [HInstruction]. This makes it
+/// possible to discover which annotations were in force in the code from which
+/// the instruction originated.
+// TODO(sra): It would be easier to use a mostly-shared Map-like structure that
+// surfaces the ambient annotations at any point in the code.
+abstract class InstructionContext {
+  MemberEntity instructionContext;
+}
+
 /// The set of uses of [source] that are dominated by [dominator].
 class DominatedUses {
   final HInstruction _source;
@@ -1702,13 +1711,24 @@
   }
 }
 
-abstract class HInvokeDynamic extends HInvoke {
+abstract class HInvokeDynamic extends HInvoke implements InstructionContext {
   final InvokeDynamicSpecializer specializer;
 
   Selector _selector;
   AbstractValue _receiverType;
   final AbstractValue _originalReceiverType;
 
+  /// `true` if the type parameters at the call known to be invariant with
+  /// respect to the type parameters of the receiver instance. This corresponds
+  /// to the [ir.MethodInvocation.isInvariant] property and may be updated with
+  /// additional analysis.
+  bool isInvariant = false;
+
+  /// `true` for an indexed getter or setter if the index is known to be in
+  /// range. This corresponds to the [ir.MethodInvocation.isBoundsSafe] property
+  /// but and may updated with additional analysis.
+  bool isBoundsSafe = false;
+
   // Cached target when non-nullable receiver type and selector determine a
   // single target. This is in effect a direct call (except for a possible
   // `null` receiver). The element should only be set if the inputs are correct
@@ -1717,6 +1737,9 @@
   // stub.
   MemberEntity element;
 
+  @override
+  MemberEntity instructionContext;
+
   HInvokeDynamic(Selector selector, this._receiverType, this.element,
       List<HInstruction> inputs, bool isIntercepted, AbstractValue resultType)
       : this._selector = selector,
@@ -3766,8 +3789,8 @@
   HLoopBlockInformation loopBlockInformation;
 
   HLoopInformation(this.header, this.target, this.labels)
-      : blocks = new List<HBasicBlock>(),
-        backEdges = new List<HBasicBlock>();
+      : blocks = <HBasicBlock>[],
+        backEdges = <HBasicBlock>[];
 
   void addBackEdge(HBasicBlock predecessor) {
     backEdges.add(predecessor);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index aff9860..b855b90 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -72,8 +72,6 @@
       assert(graph.isValid(), 'Graph not valid after ${phase.name}');
     }
 
-    bool trustPrimitives = _options.trustPrimitives;
-    Set<HInstruction> boundsChecked = new Set<HInstruction>();
     SsaCodeMotion codeMotion;
     SsaLoadElimination loadElimination;
 
@@ -114,7 +112,6 @@
             typeRecipeDomain,
             registry,
             log),
-        new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
         new SsaInstructionSimplifier(
             globalInferenceResults,
             _options,
@@ -123,7 +120,6 @@
             typeRecipeDomain,
             registry,
             log),
-        new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
         new SsaTypePropagator(globalInferenceResults,
             closedWorld.commonElements, closedWorld, log),
         // Run a dead code eliminator before LICM because dead
@@ -155,7 +151,6 @@
             typeRecipeDomain,
             registry,
             log),
-        new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
       ];
       phases.forEach(runPhase);
 
@@ -184,7 +179,6 @@
               typeRecipeDomain,
               registry,
               log),
-          new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
           new SsaSimplifyInterceptors(closedWorld, member.enclosingClass),
           new SsaDeadCodeEliminator(closedWorld, this),
         ];
@@ -676,15 +670,16 @@
     if (selector.isCall || selector.isOperator) {
       FunctionEntity target;
       if (input.isExtendableArray(_abstractValueDomain).isDefinitelyTrue) {
-        if (applies(commonElements.jsArrayRemoveLast)) {
-          target = commonElements.jsArrayRemoveLast;
-        } else if (applies(commonElements.jsArrayAdd)) {
-          // The codegen special cases array calls, but does not
-          // inline argument type checks.
-          if (!_closedWorld.annotationsData
+        if (applies(commonElements.jsArrayAdd)) {
+          // Codegen special cases array calls to `Array.push`, but does not
+          // inline argument type checks. We lower if the check always passes
+          // (due to invariance or being a top-type), or if the check is not
+          // emitted.
+          if (node.isInvariant ||
+              input is HLiteralList ||
+              !_closedWorld.annotationsData
                   .getParameterCheckPolicy(commonElements.jsArrayAdd)
-                  .isEmitted ||
-              input is HLiteralList) {
+                  .isEmitted) {
             target = commonElements.jsArrayAdd;
           }
         }
@@ -715,6 +710,7 @@
         // bounds check on removeLast). Once we start inlining, the
         // bounds check will become explicit, so we won't need this
         // optimization.
+        // TODO(sra): Fix comment - SsaCheckInserter is deleted.
         HInvokeDynamicMethod result = new HInvokeDynamicMethod(
             node.selector,
             node.receiverType,
@@ -2285,99 +2281,6 @@
   }
 }
 
-class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase {
-  final Set<HInstruction> boundsChecked;
-  final bool trustPrimitives;
-  final JClosedWorld closedWorld;
-  @override
-  final String name = "SsaCheckInserter";
-  HGraph graph;
-
-  SsaCheckInserter(this.trustPrimitives, this.closedWorld, this.boundsChecked);
-
-  AbstractValueDomain get _abstractValueDomain =>
-      closedWorld.abstractValueDomain;
-
-  @override
-  void visitGraph(HGraph graph) {
-    this.graph = graph;
-
-    // In --trust-primitives mode we don't add bounds checks.  This is better
-    // than trying to remove them later as the limit expression would become
-    // dead and require DCE.
-    if (trustPrimitives) return;
-
-    visitDominatorTree(graph);
-  }
-
-  @override
-  void visitBasicBlock(HBasicBlock block) {
-    HInstruction instruction = block.first;
-    while (instruction != null) {
-      HInstruction next = instruction.next;
-      instruction = instruction.accept(this);
-      instruction = next;
-    }
-  }
-
-  HBoundsCheck insertBoundsCheck(
-      HInstruction indexNode, HInstruction array, HInstruction indexArgument) {
-    HGetLength length = new HGetLength(
-        array, closedWorld.abstractValueDomain.positiveIntType,
-        isAssignable: !isFixedLength(array.instructionType, closedWorld));
-    indexNode.block.addBefore(indexNode, length);
-
-    AbstractValue type =
-        indexArgument.isPositiveInteger(_abstractValueDomain).isDefinitelyTrue
-            ? indexArgument.instructionType
-            : closedWorld.abstractValueDomain.positiveIntType;
-    HBoundsCheck check = new HBoundsCheck(indexArgument, length, array, type)
-      ..sourceInformation = indexNode.sourceInformation;
-    indexNode.block.addBefore(indexNode, check);
-    // If the index input to the bounds check was not known to be an integer
-    // then we replace its uses with the bounds check, which is known to be an
-    // integer.  However, if the input was already an integer we don't do this
-    // because putting in a check instruction might obscure the real nature of
-    // the index eg. if it is a constant.  The range information from the
-    // BoundsCheck instruction is attached to the input directly by
-    // visitBoundsCheck in the SsaValueRangeAnalyzer.
-    if (indexArgument.isInteger(_abstractValueDomain).isPotentiallyFalse) {
-      indexArgument.replaceAllUsersDominatedBy(indexNode, check);
-    }
-    boundsChecked.add(indexNode);
-    return check;
-  }
-
-  @override
-  void visitIndex(HIndex node) {
-    if (boundsChecked.contains(node)) return;
-    HInstruction index = node.index;
-    index = insertBoundsCheck(node, node.receiver, index);
-  }
-
-  @override
-  void visitIndexAssign(HIndexAssign node) {
-    if (boundsChecked.contains(node)) return;
-    HInstruction index = node.index;
-    index = insertBoundsCheck(node, node.receiver, index);
-  }
-
-  @override
-  void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
-    MemberEntity element = node.element;
-    if (node.isInterceptedCall) return;
-    if (element != closedWorld.commonElements.jsArrayRemoveLast) return;
-    if (boundsChecked.contains(node)) return;
-    // `0` is the index we want to check, but we want to report `-1`, as if we
-    // executed `a[a.length-1]`
-    HBoundsCheck check = insertBoundsCheck(
-        node, node.receiver, graph.addConstantInt(0, closedWorld));
-    HInstruction minusOne = graph.addConstantInt(-1, closedWorld);
-    check.inputs.add(minusOne);
-    minusOne.usedBy.add(check);
-  }
-}
-
 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
   @override
   final String name = "SsaDeadCodeEliminator";
@@ -3061,8 +2964,8 @@
     // loop changes flags list to zero so we can use bitwise or when
     // propagating loop changes upwards.
     final int length = graph.blocks.length;
-    blockChangesFlags = new List<int>(length);
-    loopChangesFlags = new List<int>(length);
+    blockChangesFlags = new List<int>.filled(length, null);
+    loopChangesFlags = new List<int>.filled(length, null);
     for (int i = 0; i < length; i++) loopChangesFlags[i] = 0;
 
     // Run through all the basic blocks in the graph and fill in the
@@ -3143,7 +3046,7 @@
 
   @override
   void visitGraph(HGraph graph) {
-    values = new List<ValueSet>(graph.blocks.length);
+    values = new List<ValueSet>.filled(graph.blocks.length, null);
     for (int i = 0; i < graph.blocks.length; i++) {
       values[graph.blocks[i].id] = new ValueSet();
     }
@@ -3412,7 +3315,7 @@
   @override
   void visitGraph(HGraph graph) {
     _graph = graph;
-    memories = new List<MemorySet>(graph.blocks.length);
+    memories = new List<MemorySet>.filled(graph.blocks.length, null);
     List<HBasicBlock> blocks = graph.blocks;
     for (int i = 0; i < blocks.length; i++) {
       HBasicBlock block = blocks[i];
@@ -3628,14 +3531,14 @@
   @override
   void visitIndex(HIndex instruction) {
     HInstruction receiver = instruction.receiver.nonCheck();
-    HInstruction existing =
-        memorySet.lookupKeyedValue(receiver, instruction.index);
+    HInstruction index = instruction.index.nonCheck();
+    HInstruction existing = memorySet.lookupKeyedValue(receiver, index);
     if (existing != null) {
       checkNewGvnCandidates(instruction, existing);
       instruction.block.rewriteWithBetterUser(instruction, existing);
       instruction.block.remove(instruction);
     } else {
-      memorySet.registerKeyedValue(receiver, instruction.index, instruction);
+      memorySet.registerKeyedValue(receiver, index, instruction);
     }
   }
 
@@ -3643,7 +3546,7 @@
   void visitIndexAssign(HIndexAssign instruction) {
     HInstruction receiver = instruction.receiver.nonCheck();
     memorySet.registerKeyedValueUpdate(
-        receiver, instruction.index, instruction.value);
+        receiver, instruction.index.nonCheck(), instruction.value);
   }
 
   // Pure operations that do not escape their inputs.
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 12fabcf..a5a1581 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -31,7 +31,7 @@
 // targeted conditioning checks.
 class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
   final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
-  final List<int> worklist = new List<int>();
+  final List<int> worklist = <int>[];
   final Map<HInstruction, Function> pendingOptimizations =
       new Map<HInstruction, Function>();
 
diff --git a/pkg/compiler/lib/src/ssa/value_set.dart b/pkg/compiler/lib/src/ssa/value_set.dart
index b24a560..f2a6148 100644
--- a/pkg/compiler/lib/src/ssa/value_set.dart
+++ b/pkg/compiler/lib/src/ssa/value_set.dart
@@ -9,7 +9,7 @@
   int size = 0;
   List<HInstruction> table;
   ValueSetNode collisions;
-  ValueSet() : table = new List<HInstruction>(8);
+  ValueSet() : table = new List<HInstruction>.filled(8, null);
 
   bool get isEmpty => size == 0;
   int get length => size;
@@ -138,7 +138,7 @@
     // Reset the table with a bigger capacity.
     assert(capacity > table.length);
     size = 0;
-    table = new List<HInstruction>(capacity);
+    table = new List<HInstruction>.filled(capacity, null);
     collisions = null;
     // Add the old instructions to the new table.
     copyTo(this, oldTable, oldCollisions);
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index 338204e..c279758 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -59,7 +59,7 @@
 
   @override
   String toString() {
-    List<String> res = new List<String>();
+    List<String> res = <String>[];
     for (final interval in ranges) res.add(interval.toString());
     return '(${res.join(", ")})';
   }
@@ -376,8 +376,8 @@
   final List<Copy<HInstruction>> assignments;
 
   CopyHandler()
-      : copies = new List<Copy<HInstruction>>(),
-        assignments = new List<Copy<HInstruction>>();
+      : copies = <Copy<HInstruction>>[],
+        assignments = <Copy<HInstruction>>[];
 
   void addCopy(HInstruction source, HInstruction destination) {
     copies.add(new Copy<HInstruction>(source, destination));
@@ -458,7 +458,7 @@
 
   VariableNamer(LiveEnvironment environment, this.names, this._namer)
       : usedNames = new Set<String>(),
-        freeTemporaryNames = new List<String>() {
+        freeTemporaryNames = <String>[] {
     // [VariableNames.swapTemp] is used when there is a cycle in a copy handler.
     // Therefore we make sure no one uses it.
     usedNames.add(names.swapTemp);
diff --git a/pkg/compiler/lib/src/util/maplet.dart b/pkg/compiler/lib/src/util/maplet.dart
index 329853c..6c46fed 100644
--- a/pkg/compiler/lib/src/util/maplet.dart
+++ b/pkg/compiler/lib/src/util/maplet.dart
@@ -99,7 +99,7 @@
       } else if (_key == key) {
         _value = value;
       } else {
-        List list = new List(CAPACITY * 2);
+        List list = new List.filled(CAPACITY * 2, null);
         list[0] = _key;
         list[1] = key;
         list[CAPACITY] = _value;
diff --git a/pkg/compiler/lib/src/util/setlet.dart b/pkg/compiler/lib/src/util/setlet.dart
index e35c12b..a2870a4 100644
--- a/pkg/compiler/lib/src/util/setlet.dart
+++ b/pkg/compiler/lib/src/util/setlet.dart
@@ -91,7 +91,7 @@
         // Do nothing.
         return false;
       } else {
-        List list = new List(CAPACITY);
+        List list = new List.filled(CAPACITY, null);
         list[0] = _contents;
         list[1] = element;
         _contents = list;
diff --git a/pkg/compiler/lib/src/util/util.dart b/pkg/compiler/lib/src/util/util.dart
index 423c0b2..7b5e9fd 100644
--- a/pkg/compiler/lib/src/util/util.dart
+++ b/pkg/compiler/lib/src/util/util.dart
@@ -88,7 +88,7 @@
   /// [existing].
   static int unorderedMapHash(Map map, [int existing = 0]) {
     if (map.length == 0) return existing;
-    List<int> hashCodes = List(map.length);
+    List<int> hashCodes = List.filled(map.length, null);
     int i = 0;
     for (var entry in map.entries) {
       hashCodes[i++] = objectHash(entry.key, objectHash(entry.value));
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 58607bb..8a61bf9 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -13,8 +13,10 @@
   collection: any
   crypto: any
   dart2js_info: any
-  front_end: any
-  kernel: any
+  front_end:
+    path: ../front_end
+  kernel:
+    path: ../kernel
 
   # Unpublished packages that can be used via path dependency
   _fe_analyzer_shared:
@@ -30,10 +32,12 @@
   # Published packages - repo version ensured via dependency_overrides
   args: any
   http: any
-  js: any
+  js:
+    path: ../js
   package_config: any
   path: any
   source_maps: any
+  test: any
   # Unpublished packages that can be used via path dependency
   async_helper:
     path: ../async_helper
@@ -53,7 +57,7 @@
   front_end:
     path: ../front_end
   kernel:
-    path: ../../pkg/kernel
+    path: ../kernel
   meta:
     path: ../meta
 
diff --git a/pkg/compiler/test/analyses/analysis_helper.dart b/pkg/compiler/test/analyses/analysis_helper.dart
index 06e356a..2b854ab 100644
--- a/pkg/compiler/test/analyses/analysis_helper.dart
+++ b/pkg/compiler/test/analyses/analysis_helper.dart
@@ -26,7 +26,6 @@
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../helpers/args_helper.dart';
diff --git a/pkg/compiler/test/annotations/data/directives.dart b/pkg/compiler/test/annotations/data/directives.dart
index fadf7d8..5a11424 100644
--- a/pkg/compiler/test/annotations/data/directives.dart
+++ b/pkg/compiler/test/annotations/data/directives.dart
@@ -13,6 +13,8 @@
   downcastCheck();
   parameterTrust();
   parameterCheck();
+  indexBoundsTrust();
+  indexBoundsCheck();
 }
 
 /*member: typesTrust:types:trust*/
@@ -46,3 +48,11 @@
 /*member: parameterCheck:parameter:check*/
 @pragma('dart2js:parameter:check')
 parameterCheck() {}
+
+/*member: indexBoundsTrust:index-bounds:trust*/
+@pragma('dart2js:index-bounds:trust')
+indexBoundsTrust() {}
+
+/*member: indexBoundsCheck:index-bounds:check*/
+@pragma('dart2js:index-bounds:check')
+indexBoundsCheck() {}
diff --git a/pkg/compiler/test/codegen/expect_annotations_test.dart b/pkg/compiler/test/codegen/expect_annotations_test.dart
index 5fc56d7..9ed3517 100644
--- a/pkg/compiler/test/codegen/expect_annotations_test.dart
+++ b/pkg/compiler/test/codegen/expect_annotations_test.dart
@@ -10,7 +10,6 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/abstract_value_domain.dart';
-import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/inferrer/types.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
 import '../inference/type_mask_test_helper.dart';
@@ -50,16 +49,19 @@
   AbstractValueDomain commonMasks = closedWorld.abstractValueDomain;
   Expect.isFalse(compiler.compilationFailed, 'Unsuccessful compilation');
 
-  void testTypeMatch(FunctionEntity function, TypeMask expectedParameterType,
-      TypeMask expectedReturnType, GlobalTypeInferenceResults results) {
+  void testTypeMatch(
+      FunctionEntity function,
+      AbstractValue expectedParameterType,
+      AbstractValue expectedReturnType,
+      GlobalTypeInferenceResults results) {
     closedWorld.elementEnvironment.forEachParameterAsLocal(
         closedWorld.globalLocalsMap, function, (Local parameter) {
-      TypeMask type = results.resultOfParameter(parameter);
+      AbstractValue type = results.resultOfParameter(parameter);
       Expect.equals(
           expectedParameterType, simplify(type, commonMasks), "$parameter");
     });
     if (expectedReturnType != null) {
-      TypeMask type = results.resultOfMember(function).returnType;
+      AbstractValue type = results.resultOfMember(function).returnType;
       Expect.equals(
           expectedReturnType, simplify(type, commonMasks), "$function");
     }
@@ -67,8 +69,8 @@
 
   void test(String name,
       {bool expectNoInline: false,
-      TypeMask expectedParameterType: null,
-      TypeMask expectedReturnType: null,
+      AbstractValue expectedParameterType: null,
+      AbstractValue expectedReturnType: null,
       bool expectAssumeDynamic: false}) {
     LibraryEntity mainApp = closedWorld.elementEnvironment.mainLibrary;
     FunctionEntity method =
diff --git a/pkg/compiler/test/end_to_end/command_line_test.dart b/pkg/compiler/test/end_to_end/command_line_test.dart
index 57d4161..5f0b7e9 100644
--- a/pkg/compiler/test/end_to_end/command_line_test.dart
+++ b/pkg/compiler/test/end_to_end/command_line_test.dart
@@ -27,10 +27,16 @@
     await test([Flags.cfeOnly], exitCode: 1);
     await test([Flags.cfeOnly, 'foo.dart'], out: 'out.dill');
     await test([Flags.cfeOnly, 'foo.dart', '--out=out.dill'], out: 'out.dill');
+    await test([Flags.cfeOnly, 'foo.dart', Flags.readClosedWorld], exitCode: 1);
+    await test(['foo.dart', Flags.readClosedWorld, Flags.cfeOnly], exitCode: 1);
     await test([Flags.cfeOnly, 'foo.dart', Flags.readData], exitCode: 1);
     await test(['foo.dart', Flags.readData, Flags.cfeOnly], exitCode: 1);
     await test([Flags.cfeOnly, 'foo.dart', Flags.readCodegen], exitCode: 1);
     await test(['foo.dart', Flags.readCodegen, Flags.cfeOnly], exitCode: 1);
+    await test([Flags.cfeOnly, 'foo.dart', Flags.writeClosedWorld],
+        exitCode: 1);
+    await test(['foo.dart', Flags.writeClosedWorld, Flags.cfeOnly],
+        exitCode: 1);
     await test([Flags.cfeOnly, 'foo.dart', Flags.writeData], exitCode: 1);
     await test(['foo.dart', Flags.writeData, Flags.cfeOnly], exitCode: 1);
     await test([Flags.cfeOnly, 'foo.dart', Flags.writeCodegen], exitCode: 1);
@@ -40,11 +46,51 @@
         out: 'out.dill', writeData: 'out.dill.data');
     await test(['${Flags.writeData}=foo.data', 'foo.dart', '--out=foo.dill'],
         out: 'foo.dill', writeData: 'foo.data');
+    await test([Flags.readClosedWorld, Flags.writeClosedWorld, 'foo.dart'],
+        exitCode: 1);
+    await test([Flags.writeClosedWorld, Flags.readClosedWorld, 'foo.dart'],
+        exitCode: 1);
     await test([Flags.readData, Flags.writeData, 'foo.dart'], exitCode: 1);
     await test([Flags.writeData, Flags.readData, 'foo.dart'], exitCode: 1);
+    await test([Flags.readCodegen, Flags.writeClosedWorld, 'foo.dart'],
+        exitCode: 1);
     await test([Flags.readCodegen, Flags.writeData, 'foo.dart'], exitCode: 1);
+    await test([Flags.writeClosedWorld, Flags.readData, 'foo.dart'],
+        exitCode: 1);
+    await test([Flags.writeClosedWorld, Flags.readCodegen, 'foo.dart'],
+        exitCode: 1);
     await test([Flags.writeData, Flags.readCodegen, 'foo.dart'], exitCode: 1);
 
+    await test([
+      Flags.writeClosedWorld,
+      'foo.dart',
+    ], out: 'out.dill', writeClosedWorld: 'out.dill.world');
+    await test(
+        ['${Flags.writeClosedWorld}=foo.world', 'foo.dart', '--out=foo.dill'],
+        out: 'foo.dill', writeClosedWorld: 'foo.world');
+
+    await test([Flags.readClosedWorld, 'foo.dill'],
+        out: 'out.js', readClosedWorld: 'foo.dill.world');
+    await test([Flags.readClosedWorld, 'foo.dill', '--out=foo.js'],
+        out: 'foo.js', readClosedWorld: 'foo.dill.world');
+    await test(['${Flags.readClosedWorld}=out.world', 'foo.world'],
+        out: 'out.js', readClosedWorld: 'out.world');
+    await test(
+        ['${Flags.readClosedWorld}=out.world', 'foo.world', '--out=foo.js'],
+        out: 'foo.js', readClosedWorld: 'out.world');
+    await test(
+      [Flags.readClosedWorld, Flags.writeData, 'foo.dill'],
+      out: 'out.dill',
+      readClosedWorld: 'foo.dill.world',
+      writeData: 'out.dill.data',
+    );
+    await test([
+      '${Flags.readClosedWorld}=foo.world',
+      '${Flags.writeData}=foo.data',
+      'foo.dart',
+      '--out=foo.dill'
+    ], out: 'foo.dill', readClosedWorld: 'foo.world', writeData: 'foo.data');
+
     await test([Flags.readData, 'foo.dill'],
         out: 'out.js', readData: 'foo.dill.data');
     await test([Flags.readData, 'foo.dill', '--out=foo.js'],
@@ -199,6 +245,8 @@
 Future test(List<String> arguments,
     {int exitCode,
     String out,
+    String readClosedWorld,
+    String writeClosedWorld,
     String readData,
     String writeData,
     String readCodegen,
@@ -231,6 +279,10 @@
   if (actualExitCode == null) {
     Expect.isNotNull(options, "Missing options object");
     Expect.equals(toUri(out), options.outputUri, "Unexpected output uri.");
+    Expect.equals(toUri(readClosedWorld), options.readClosedWorldUri,
+        "Unexpected readClosedWorld uri");
+    Expect.equals(toUri(writeClosedWorld), options.writeClosedWorldUri,
+        "Unexpected writeClosedWorld uri");
     Expect.equals(
         toUri(readData), options.readDataUri, "Unexpected readData uri");
     Expect.equals(
diff --git a/pkg/compiler/test/equivalence/id_testing_test.dart b/pkg/compiler/test/equivalence/id_testing_test.dart
index bf8b007..ff453fe 100644
--- a/pkg/compiler/test/equivalence/id_testing_test.dart
+++ b/pkg/compiler/test/equivalence/id_testing_test.dart
@@ -14,10 +14,6 @@
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
 
diff --git a/pkg/compiler/test/helpers/ir_types.dart b/pkg/compiler/test/helpers/ir_types.dart
index 65a87a4..dc991fe 100644
--- a/pkg/compiler/test/helpers/ir_types.dart
+++ b/pkg/compiler/test/helpers/ir_types.dart
@@ -5,10 +5,6 @@
 // @dart = 2.7
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
-import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
-import 'package:kernel/type_environment.dart' as ir;
 
 class TypeTextVisitor implements ir.DartTypeVisitor1<void, StringBuffer> {
   const TypeTextVisitor();
diff --git a/pkg/compiler/test/inference/data/closure_tracer.dart b/pkg/compiler/test/inference/data/closure_tracer.dart
index 08105f7..edccdb3 100644
--- a/pkg/compiler/test/inference/data/closure_tracer.dart
+++ b/pkg/compiler/test/inference/data/closure_tracer.dart
@@ -51,22 +51,22 @@
   return res;
 }
 
-/*member: testStoredInMapOfList:[null|subclass=Object]*/
+/*member: testStoredInMapOfList:[null|exact=JSUInt31]*/
 testStoredInMapOfList() {
   var res;
-  /*[null|subclass=Object]*/ closure(/*[null|subclass=Object]*/ a) => res = a;
+  /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
   dynamic a = <dynamic>[closure];
   dynamic b = <dynamic, dynamic>{'foo': 1};
 
   b
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
       ['bar'] = a;
 
   b
-          /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+          /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
           ['bar']
 
-      /*Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+      /*Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)*/
       [0](42);
   return res;
 }
diff --git a/pkg/compiler/test/inference/data/list2.dart b/pkg/compiler/test/inference/data/list2.dart
index 16b21d8..81d7d8f 100644
--- a/pkg/compiler/test/inference/data/list2.dart
+++ b/pkg/compiler/test/inference/data/list2.dart
@@ -23,6 +23,7 @@
     listGenerateGrowable,
     listGenerateFixed,
     listGenerateEither,
+    listGenerateBigClosure,
     listOfDefault,
     listOfGrowable,
     listOfFixed,
@@ -72,24 +73,37 @@
 // -------- List.generate --------
 
 /*member: listGenerateDefault:Container([exact=JSExtendableArray], element: [exact=JSString], length: 8)*/
-get listGenerateDefault => List.generate(
-    8, /*[exact=JSString]*/ (/*[subclass=JSPositiveInt]*/ i) => 'x$i');
+get listGenerateDefault => List
+    . /*update: Container([exact=JSExtendableArray], element: [exact=JSString], length: 8)*/ generate(
+        8, (i) => 'x$i');
 
 /*member: listGenerateGrowable:Container([exact=JSExtendableArray], element: [exact=JSString], length: 8)*/
-get listGenerateGrowable => List.generate(
-    8, /*[exact=JSString]*/ (/*[subclass=JSPositiveInt]*/ i) => 'g$i',
-    growable: true);
+get listGenerateGrowable => List
+    . /*update: Container([exact=JSExtendableArray], element: [exact=JSString], length: 8)*/ generate(
+        8, (i) => 'g$i',
+        growable: true);
 
 /*member: listGenerateFixed:Container([exact=JSFixedArray], element: [exact=JSString], length: 8)*/
-get listGenerateFixed => List.generate(
-    8, /*[exact=JSString]*/ (/*[subclass=JSPositiveInt]*/ i) => 'f$i',
-    growable: false);
+get listGenerateFixed => List
+    . /*update: Container([exact=JSFixedArray], element: [exact=JSString], length: 8)*/ generate(
+        8, (i) => 'f$i',
+        growable: false);
 
 /*member: listGenerateEither:Container([subclass=JSMutableArray], element: [exact=JSString], length: 8)*/
 get listGenerateEither => List.generate(
     8, /*[exact=JSString]*/ (/*[subclass=JSPositiveInt]*/ i) => 'e$i',
     growable: boolFlag);
 
+/*member: listGenerateBigClosure:Container([exact=JSExtendableArray], element: [exact=JSString], length: 8)*/
+get listGenerateBigClosure => List.generate(
+      8,
+      /*[exact=JSString]*/ (/*[subclass=JSPositiveInt]*/ i) {
+        if (i /*invoke: [subclass=JSPositiveInt]*/ == 1) return 'one';
+        if (i /*invoke: [subclass=JSPositiveInt]*/ == 2) return 'two';
+        return '$i';
+      },
+    );
+
 // -------- List.of --------
 
 /*member: listOfDefault:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
diff --git a/pkg/compiler/test/inference/data/list_js.dart b/pkg/compiler/test/inference/data/list_js.dart
new file mode 100644
index 0000000..9b64060
--- /dev/null
+++ b/pkg/compiler/test/inference/data/list_js.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test effect of NativeBehavior on list tracing.
+
+/// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_foreign_helper' show JS;
+
+/*member: main:[null]*/
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+}
+
+/*member: test1:[null]*/
+test1() {
+  var list = [42];
+  JS('', '#', list); // '#' is by default a no-op.
+  witness1(list);
+}
+
+/*member: witness1:[null]*/
+witness1(
+    /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) {}
+
+/*member: test2:[null]*/
+test2() {
+  var list = [42];
+  JS('effects:all;depends:all', '#', list);
+  witness2(list);
+}
+
+/*member: witness2:[null]*/
+witness2(
+    /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) {}
+
+/*member: test3:[null]*/
+test3() {
+  var list = [42];
+  JS('', '#.slice(0)', list);
+  witness3(list);
+}
+
+/*member: witness3:[null]*/
+witness3(
+    /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) {}
+
+/*member: test4:[null]*/
+test4() {
+  var list = [42];
+  JS('effects:none;depends:all', '#.slice(0)', list);
+  witness4(list);
+}
+
+/*member: witness4:[null]*/
+witness4(
+    /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) {}
diff --git a/pkg/compiler/test/inference/data/map_tracer_keys.dart b/pkg/compiler/test/inference/data/map_tracer_keys.dart
index 20e469e..3f183a6 100644
--- a/pkg/compiler/test/inference/data/map_tracer_keys.dart
+++ b/pkg/compiler/test/inference/data/map_tracer_keys.dart
@@ -79,28 +79,28 @@
 /*member: aDouble3:Union(null, [exact=JSDouble], [exact=JSExtendableArray])*/
 dynamic aDouble3 = 42.5;
 
-/*member: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList3:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 dynamic aList3 = [42];
 
-/*member: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume3:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 consume3(
-        /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
+        /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
     x;
 
 /*member: test3:[null]*/
 test3() {
   dynamic theMap = <dynamic, dynamic>{'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
-      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+      /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       ['d'] = aList3;
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
   /*current: [exact=LinkedHashMapKeyIterator]*/
   /*moveNext: [exact=LinkedHashMapKeyIterator]*/
   for (var key in theMap.
-      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+      /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
       keys) {
     aDouble3 = theMap
-        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+        /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
         [key];
   }
   // We have to reference it somewhere, so that it always gets resolved.
diff --git a/pkg/compiler/test/inference/list_tracer_test.dart b/pkg/compiler/test/inference/list_tracer_test.dart
index 9658374..4e23f1b 100644
--- a/pkg/compiler/test/inference/list_tracer_test.dart
+++ b/pkg/compiler/test/inference/list_tracer_test.dart
@@ -237,9 +237,7 @@
   checkType('listEscapingInSetterValue', commonMasks.numType);
   checkType('listEscapingInIndex', commonMasks.numType);
   checkType('listEscapingInIndexSet', commonMasks.uint31Type);
-  // TODO(johnniwinther): Since Iterable.iterableToString is part of the closed
-  // world we find the `dynamicType` instead of `numType`.
-  checkType('listEscapingTwiceInIndexSet', commonMasks.dynamicType);
+  checkType('listEscapingTwiceInIndexSet', commonMasks.numType);
   checkType('listSetInNonFinalField', commonMasks.numType);
   checkType('listWithChangedLength', commonMasks.uint31Type.nullable());
 
diff --git a/pkg/compiler/test/inference/map_tracer_test.dart b/pkg/compiler/test/inference/map_tracer_test.dart
index 4cb4c1e..5e0ebf4 100644
--- a/pkg/compiler/test/inference/map_tracer_test.dart
+++ b/pkg/compiler/test/inference/map_tracer_test.dart
@@ -258,7 +258,7 @@
 
   K(TypeMask other) => simplify(keyType.union(other, commonMasks), commonMasks);
   V(TypeMask other) =>
-      simplify(valueType.union(other, commonMasks), commonMasks).nullable();
+      simplify(valueType.union(other, commonMasks).nullable(), commonMasks);
 
   checkType('mapInField', K(aKeyType), V(commonMasks.numType));
   checkType('mapPassedToMethod', K(aKeyType), V(commonMasks.numType));
diff --git a/pkg/compiler/test/inference/type_mask_test_helper.dart b/pkg/compiler/test/inference/type_mask_test_helper.dart
index 9e5d665..ba29b08 100644
--- a/pkg/compiler/test/inference/type_mask_test_helper.dart
+++ b/pkg/compiler/test/inference/type_mask_test_helper.dart
@@ -6,19 +6,19 @@
 
 library type_mask_test_helper;
 
+import 'package:compiler/src/inferrer/abstract_value_domain.dart';
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
 
 export 'package:compiler/src/inferrer/types.dart';
 
-TypeMask simplify(TypeMask mask, CommonMasks commonMasks) {
-  if (mask is ForwardingTypeMask) {
-    return simplify(mask.forwardTo, commonMasks);
-  } else if (mask is UnionTypeMask) {
-    return UnionTypeMask.flatten(
-        mask.disjointMasks, mask.isNullable, commonMasks);
+AbstractValue simplify(AbstractValue value, AbstractValueDomain domain) {
+  if (value is ForwardingTypeMask) {
+    return simplify(value.forwardTo, domain);
+  } else if (value is UnionTypeMask) {
+    return UnionTypeMask.flatten(value.disjointMasks, value.isNullable, domain);
   } else {
-    return mask;
+    return value;
   }
 }
 
diff --git a/pkg/compiler/test/js/debug_size_estimator.dart b/pkg/compiler/test/js/debug_size_estimator.dart
new file mode 100644
index 0000000..86b528c
--- /dev/null
+++ b/pkg/compiler/test/js/debug_size_estimator.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:compiler/src/js/size_estimator.dart';
+
+/// This class is supposed to be identical to [SizeEstimator] with the sole
+/// difference that it builds up strings to help debug estimates.
+class DebugSizeEstimator extends SizeEstimator {
+  StringBuffer resultBuffer = StringBuffer();
+  String get resultString => resultBuffer.toString();
+
+  @override
+  void emit(String s) {
+    resultBuffer.write(s);
+    super.emit(s);
+  }
+}
diff --git a/pkg/compiler/test/js/js_size_estimator_test.dart b/pkg/compiler/test/js/js_size_estimator_test.dart
new file mode 100644
index 0000000..cb5ce76
--- /dev/null
+++ b/pkg/compiler/test/js/js_size_estimator_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+import 'dart:convert' as json;
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:compiler/src/js/js.dart';
+import 'package:compiler/src/js/size_estimator.dart';
+import 'debug_size_estimator.dart';
+
+const String expressionsKey = 'expressions';
+const String statementsKey = 'statements';
+const String originalKey = 'original';
+const String expectedKey = 'expected';
+const String minifiedKey = 'minified';
+
+DebugSizeEstimator debugSizeEstimator(Node node) {
+  DebugSizeEstimator debugSizeEstimator = DebugSizeEstimator();
+  debugSizeEstimator.visit(node);
+
+  // Always verify the actual results from the [SizeEstimator].
+  // This is the actual test, though DebugSizeEstimator is pretty trivial.
+  int actualEstimate = EstimateSize(node);
+  Expect.equals(actualEstimate, debugSizeEstimator.charCount);
+  return debugSizeEstimator;
+}
+
+abstract class TestSuite {
+  String get key;
+  Node parse(String testCase);
+
+  String generateExpected(Node node) {
+    return debugSizeEstimator(node).resultString;
+  }
+
+  String generateMinified(Node node) {
+    return prettyPrint(node,
+        enableMinification: true,
+        preferSemicolonToNewlineInMinifiedOutput: true);
+  }
+
+  Map<String, String> goldenTestCase(goldenTestCaseJson) {
+    String original = goldenTestCaseJson[originalKey];
+    Node node = parse(original);
+    return {
+      originalKey: original,
+      expectedKey: generateExpected(node),
+      minifiedKey: generateMinified(node),
+    };
+  }
+
+  List<Map<String, String>> regenerateGoldens(currentGoldensJson) {
+    List<Map<String, String>> newGoldens = [];
+    for (var testCaseJson in currentGoldensJson) {
+      newGoldens.add(goldenTestCase(testCaseJson));
+    }
+    return newGoldens;
+  }
+
+  void verifyGoldens(goldensJson) {
+    for (var goldenTestCase in goldensJson) {
+      test(goldenTestCase[originalKey], goldenTestCase[expectedKey]);
+    }
+  }
+
+  void test(String original, String expected) {
+    var debugResults = debugSizeEstimator(parse(original));
+    Expect.equals(expected, debugResults.resultString);
+    Expect.equals(expected.length, debugResults.charCount);
+  }
+}
+
+class ExpressionTestSuite extends TestSuite {
+  @override
+  String get key => expressionsKey;
+
+  @override
+  Node parse(String expression) => js(expression);
+}
+
+class StatementTestSuite extends TestSuite {
+  @override
+  String get key => statementsKey;
+
+  @override
+  Node parse(String statement) => js.statement(statement);
+}
+
+List<TestSuite> testSuites = [
+  ExpressionTestSuite(),
+  StatementTestSuite(),
+];
+
+void generateGoldens(currentGoldens,
+    Map<String, List<Map<String, String>>> newGoldens, List<TestSuite> suites) {
+  for (var suite in suites) {
+    newGoldens[suite.key] = suite.regenerateGoldens(currentGoldens[suite.key]);
+  }
+}
+
+void testGoldens(currentGoldens, List<TestSuite> suites) {
+  for (var suite in suites) {
+    suite.verifyGoldens(currentGoldens[suite.key]);
+  }
+}
+
+void main(List<String> args) {
+  var goldenFile = 'pkg/compiler/test/js/size_estimator_expectations.json';
+  bool generate = args.contains('-g');
+  var currentGoldens = json.jsonDecode(File(goldenFile).readAsStringSync());
+
+  if (generate) {
+    Map<String, List<Map<String, String>>> newGoldens = {};
+    generateGoldens(currentGoldens, newGoldens, testSuites);
+
+    File(goldenFile).writeAsStringSync(
+        json.JsonEncoder.withIndent('  ').convert(newGoldens));
+  } else {
+    testGoldens(currentGoldens, testSuites);
+  }
+}
diff --git a/pkg/compiler/test/js/size_estimator_expectations.json b/pkg/compiler/test/js/size_estimator_expectations.json
new file mode 100644
index 0000000..57b911f
--- /dev/null
+++ b/pkg/compiler/test/js/size_estimator_expectations.json
@@ -0,0 +1,196 @@
+{
+  "expressions": [
+    {
+      "original": "1",
+      "expected": "1",
+      "minified": "1"
+    },
+    {
+      "original": "123456789",
+      "expected": "123456789",
+      "minified": "123456789"
+    },
+    {
+      "original": "true",
+      "expected": "!0",
+      "minified": "true"
+    },
+    {
+      "original": "false",
+      "expected": "!1",
+      "minified": "false"
+    },
+    {
+      "original": "a || b",
+      "expected": "#||#",
+      "minified": "a||b"
+    },
+    {
+      "original": "(a || b) && c",
+      "expected": "(#||#)&&#",
+      "minified": "(a||b)&&c"
+    },
+    {
+      "original": "a == true ? b : c",
+      "expected": "#==!0?#:#",
+      "minified": "a==true?b:c"
+    },
+    {
+      "original": "x = a + b * c",
+      "expected": "#=#+#*#",
+      "minified": "x=a+b*c"
+    },
+    {
+      "original": "a + (b == c) + d",
+      "expected": "#+(#==#)+#",
+      "minified": "a+(b==c)+d"
+    },
+    {
+      "original": "foo(bar)",
+      "expected": "#(#)",
+      "minified": "foo(bar)"
+    },
+    {
+      "original": "foo.bar(baz)",
+      "expected": "#.bar(#)",
+      "minified": "foo.bar(baz)"
+    },
+    {
+      "original": "foo({meaning: 42})",
+      "expected": "#({meaning:42})",
+      "minified": "foo({meaning:42})"
+    },
+    {
+      "original": "x = !x",
+      "expected": "#=!#",
+      "minified": "x=!x"
+    },
+    {
+      "original": "delete foo.bar",
+      "expected": "delete #.bar",
+      "minified": "delete foo.bar"
+    },
+    {
+      "original": "x in y",
+      "expected": "# in #",
+      "minified": "x in y"
+    },
+    {
+      "original": "x instanceof y",
+      "expected": "# instanceof #",
+      "minified": "x instanceof y"
+    },
+    {
+      "original": "x &= ~mask",
+      "expected": "#&=~#",
+      "minified": "x&=~mask"
+    },
+    {
+      "original": "await x++",
+      "expected": "await #++",
+      "minified": "await x++"
+    },
+    {
+      "original": "foo[x[bar]]",
+      "expected": "#[#[#]]",
+      "minified": "foo[x[bar]]"
+    },
+    {
+      "original": "x << 5",
+      "expected": "#<<5",
+      "minified": "x<<5"
+    },
+    {
+      "original": "x = ['a', 'b', 'c']",
+      "expected": "#=['a','b','c']",
+      "minified": "x=['a','b','c']"
+    },
+    {
+      "original": "a = {'b': 1, 'c': 2}",
+      "expected": "#={b:1,c:2}",
+      "minified": "a={b:1,c:2}"
+    },
+    {
+      "original": "foo([1, 2, 3])",
+      "expected": "#([1,2,3])",
+      "minified": "foo([1,2,3])"
+    },
+    {
+      "original": "a = b = c",
+      "expected": "#=#=#",
+      "minified": "a=b=c"
+    },
+    {
+      "original": "var a = \"\"",
+      "expected": "var #=\"\"",
+      "minified": "var a=\"\""
+    }
+  ],
+  "statements": [
+    {
+      "original": "{ 1; 2; 3; }",
+      "expected": "{1;2;3;}",
+      "minified": "{1;2;3}"
+    },
+    {
+      "original": "function foo() { /a/; 1; 2; }",
+      "expected": "function #(){/a/;1;2;}",
+      "minified": "function foo(){/a/;1;2}"
+    },
+    {
+      "original": "function foo() { return function bar() { return null; } }",
+      "expected": "function #(){return function #(){return null;};}",
+      "minified": "function foo(){return function bar(){return null}}"
+    },
+    {
+      "original": "if (x == true) { bar(); }",
+      "expected": "if(#==!0)#()",
+      "minified": "if(x==true)bar()"
+    },
+    {
+      "original": "if (x > 4 && y < 5) { 1; 2; }",
+      "expected": "if(#>4&&#<5){1;2;}",
+      "minified": "if(x>4&&y<5){1;2}"
+    },
+    {
+      "original": "if (x == true) { return true; } else if (y < 3 || z > 5) { return l != null ? 'a' : 4; } else { foo(); return; }",
+      "expected": "if(#==!0)return !0;else if(#<3||#>5)return #!=null?'a':4;else{#();return;}",
+      "minified": "if(x==true)return true;else if(y<3||z>5)return l!=null?'a':4;else{foo();return}"
+    },
+    {
+      "original": "for (var a = 0; a < 10; a++) { foo(a); }",
+      "expected": "for(var #=0;#<10;#++)#(#)",
+      "minified": "for(var a=0;a<10;a++)foo(a)"
+    },
+    {
+      "original": "for (var b in c) { var e = 1; foo(e); }",
+      "expected": "for(var # in #){var #=1;#(#);}",
+      "minified": "for(var b in c){var e=1;foo(e)}"
+    },
+    {
+      "original": "while (x != null) { foo(); }",
+      "expected": "while(#!=null)#()",
+      "minified": "while(x!=null)foo()"
+    },
+    {
+      "original": "do { print(1); do while (true) ; while (false); } while (a != b);",
+      "expected": "do{#(1);do while(!0);while(!1);}while(#!=#)",
+      "minified": "do{print(1);do while(true);while(false)}while(a!=b)"
+    },
+    {
+      "original": "switch (foo) { case 'a': case 'b': bar(); break; case 'c': 1; break; default: boo(); }",
+      "expected": "switch(#){case 'a':case 'b':#();break;case 'c':1;break;default:#();}",
+      "minified": "switch(foo){case'a':case'b':bar();break;case'c':1;break;default:boo()}"
+    },
+    {
+      "original": "foo.prototype.Goo = function(a) { return a.bar(); }",
+      "expected": "#.prototype.Goo=function(#){return #.bar();}",
+      "minified": "foo.prototype.Goo=function(a){return a.bar()}"
+    },
+    {
+      "original": "try { null = 4; } catch (e) { print(e); }",
+      "expected": "try{null=4;}catch(#){#(#);}",
+      "minified": "try{null=4}catch(e){print(e)}"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/pkg/compiler/test/kernel/common_test_utils.dart b/pkg/compiler/test/kernel/common_test_utils.dart
new file mode 100644
index 0000000..ed7c9e5
--- /dev/null
+++ b/pkg/compiler/test/kernel/common_test_utils.dart
@@ -0,0 +1,135 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:front_end/src/api_unstable/dart2js.dart'
+    show
+        CompilerOptions,
+        DiagnosticMessage,
+        computePlatformBinariesLocation,
+        kernelForProgram,
+        parseExperimentalArguments,
+        parseExperimentalFlags;
+import 'package:kernel/ast.dart';
+import 'package:kernel/text/ast_to_text.dart' show Printer;
+import 'package:kernel/target/targets.dart';
+import 'package:test/test.dart';
+
+import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+
+/// Environment define to update expectation files on failures.
+const kUpdateExpectations = 'updateExpectations';
+
+/// Environment define to dump actual results alongside expectations.
+const kDumpActualResult = 'dump.actual.result';
+
+class TestingDart2jsTarget extends Dart2jsTarget {
+  TestingDart2jsTarget(TargetFlags flags) : super('dart2js', flags);
+}
+
+Future<Component> compileTestCaseToKernelProgram(Uri sourceUri,
+    {Target target,
+    bool enableSuperMixins = false,
+    List<String> experimentalFlags,
+    Map<String, String> environmentDefines}) async {
+  final platformKernel =
+      computePlatformBinariesLocation().resolve('dart2js_platform.dill');
+  target ??= TestingDart2jsTarget(TargetFlags());
+  environmentDefines ??= <String, String>{};
+  final options = CompilerOptions()
+    ..target = target
+    ..additionalDills = <Uri>[platformKernel]
+    ..environmentDefines = environmentDefines
+    ..explicitExperimentalFlags =
+        parseExperimentalFlags(parseExperimentalArguments(experimentalFlags),
+            onError: (String message) {
+      throw message;
+    })
+    ..onDiagnostic = (DiagnosticMessage message) {
+      fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
+    };
+
+  final Component component =
+      (await kernelForProgram(sourceUri, options)).component;
+
+  // Make sure the library name is the same and does not depend on the order
+  // of test cases.
+  component.mainMethod.enclosingLibrary.name = '#lib';
+
+  return component;
+}
+
+String kernelLibraryToString(Library library) {
+  final buffer = StringBuffer();
+  Printer(buffer, showMetadata: true).writeLibraryFile(library);
+  return buffer
+      .toString()
+      .replaceAll(library.importUri.toString(), library.name);
+}
+
+String kernelComponentToString(Component component) {
+  final buffer = StringBuffer();
+  Printer(buffer, showMetadata: true).writeComponentFile(component);
+  final mainLibrary = component.mainMethod.enclosingLibrary;
+  return buffer
+      .toString()
+      .replaceAll(mainLibrary.importUri.toString(), mainLibrary.name);
+}
+
+class Difference {
+  final int line;
+  final String actual;
+  final String expected;
+
+  Difference(this.line, this.actual, this.expected);
+}
+
+Difference findFirstDifference(String actual, String expected) {
+  final actualLines = actual.split('\n');
+  final expectedLines = expected.split('\n');
+  int i = 0;
+  for (; i < actualLines.length && i < expectedLines.length; ++i) {
+    if (actualLines[i] != expectedLines[i]) {
+      return Difference(i + 1, actualLines[i], expectedLines[i]);
+    }
+  }
+  return Difference(i + 1, i < actualLines.length ? actualLines[i] : '<END>',
+      i < expectedLines.length ? expectedLines[i] : '<END>');
+}
+
+void compareResultWithExpectationsFile(Uri source, String actual) {
+  final expectFile = File(source.toFilePath() + '.expect');
+  final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';
+
+  if (actual != expected) {
+    if (bool.fromEnvironment(kUpdateExpectations)) {
+      expectFile.writeAsStringSync(actual);
+      print("  Updated $expectFile");
+    } else {
+      if (bool.fromEnvironment(kDumpActualResult)) {
+        File(source.toFilePath() + '.actual').writeAsStringSync(actual);
+      }
+      Difference diff = findFirstDifference(actual, expected);
+      fail("""
+
+Result is different for the test case $source
+
+The first difference is at line ${diff.line}.
+Actual:   ${diff.actual}
+Expected: ${diff.expected}
+
+This failure can be caused by changes in the front-end if it starts generating
+different kernel AST for the same Dart programs.
+
+In order to re-generate expectations run tests with -D$kUpdateExpectations=true VM option:
+
+  sdk/bin/dart -D$kUpdateExpectations=true pkg/compiler/test/kernel/goldens_test.dart
+
+In order to dump actual results into .actual files run tests with -D$kDumpActualResult=true VM option.
+""");
+    }
+  }
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_1.dart b/pkg/compiler/test/kernel/data/list_generate_1.dart
new file mode 100644
index 0000000..3365cf5
--- /dev/null
+++ b/pkg/compiler/test/kernel/data/list_generate_1.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var list1 = List<int>.generate(10, (i) => i);
+var list2 = List<int>.generate(10, (i) => i, growable: true);
+var list3 = List<int>.generate(10, (i) => i, growable: false);
+var list4 = List<int>.generate(10, (i) => i, growable: someGrowable);
+
+bool someGrowable = true;
+
+void main() {
+  someGrowable = !someGrowable;
+  print([list1, list2, list3, list4]);
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_1.dart.expect b/pkg/compiler/test/kernel/data/list_generate_1.dart.expect
new file mode 100644
index 0000000..be2484b
--- /dev/null
+++ b/pkg/compiler/test/kernel/data/list_generate_1.dart.expect
@@ -0,0 +1,32 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static field core::List<core::int*>* list1 = block {
+  final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int* i = i;
+    _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i);
+  }
+} =>_list;
+static field core::List<core::int*>* list2 = block {
+  final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int* i = i;
+    _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i);
+  }
+} =>_list;
+static field core::List<core::int*>* list3 = block {
+  final _in::JSArray<core::int*> _list = _in::JSArray::allocateFixed<core::int*>(10);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int* i = i;
+    _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i);
+  }
+} =>_list;
+static field core::List<core::int*>* list4 = core::List::generate<core::int*>(10, (core::int* i) → core::int* => i, growable: self::someGrowable);
+static field core::bool* someGrowable = true;
+static method main() → void {
+  self::someGrowable = !self::someGrowable;
+  core::print(<core::List<core::int*>*>[self::list1, self::list2, self::list3, self::list4]);
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_2.dart b/pkg/compiler/test/kernel/data/list_generate_2.dart
new file mode 100644
index 0000000..af9196d
--- /dev/null
+++ b/pkg/compiler/test/kernel/data/list_generate_2.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  // 'nested' List.generate calls.
+  print(List.generate(10, (i) => List.generate(i, (i) => i + 1)));
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_2.dart.expect b/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
new file mode 100644
index 0000000..e2a2196
--- /dev/null
+++ b/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
@@ -0,0 +1,21 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static method main() → void {
+  core::print( block {
+    final _in::JSArray<core::List<core::int*>*> _list = _in::JSArray::allocateGrowable<core::List<core::int*>*>(10);
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+      core::int* i = i;
+      _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, block {
+        final core::int _length = i;
+        final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(_length);
+        for (core::int i = 0; i.{core::num::<}(_length); i = i.{core::num::+}(1)) {
+          core::int* i = i;
+          _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::+}(1));
+        }
+      } =>_list);
+    }
+  } =>_list);
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_3.dart b/pkg/compiler/test/kernel/data/list_generate_3.dart
new file mode 100644
index 0000000..dd6ce5c
--- /dev/null
+++ b/pkg/compiler/test/kernel/data/list_generate_3.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var list1 = List<int>.generate(10, (i) {
+  return i;
+});
+
+var list2 = List<int>.generate(10, (i) {
+  return i;
+}, growable: true);
+
+var list3 = List<int>.generate(10, (i) {
+  return i;
+}, growable: false);
+
+var list4 = List<int>.generate(10, (i) {
+  return i;
+}, growable: someGrowable);
+
+// Not expanded - complex closure.
+var list5 = List<int>.generate(10, (i) {
+  if (i.isEven) return i + 1;
+  return i - 1;
+});
+
+// Not expanded - inscrutable closure.
+var list6 = List<int>.generate(10, foo);
+int foo(int i) => i;
+
+// Not expanded - inscrutable closure.
+var list7 = List<int>.generate(10, bar);
+int Function(int) get bar => foo;
+
+bool someGrowable = true;
+
+void main() {
+  someGrowable = !someGrowable;
+  print([list1, list2, list3, list4, list5, list6, list7]);
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_3.dart.expect b/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
new file mode 100644
index 0000000..05df05d
--- /dev/null
+++ b/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
@@ -0,0 +1,51 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static field core::List<core::int*>* list1 = block {
+  final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int* i = i;
+    {
+      _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i);
+    }
+  }
+} =>_list;
+static field core::List<core::int*>* list2 = block {
+  final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int* i = i;
+    {
+      _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i);
+    }
+  }
+} =>_list;
+static field core::List<core::int*>* list3 = block {
+  final _in::JSArray<core::int*> _list = _in::JSArray::allocateFixed<core::int*>(10);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int* i = i;
+    {
+      _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i);
+    }
+  }
+} =>_list;
+static field core::List<core::int*>* list4 = core::List::generate<core::int*>(10, (core::int* i) → core::int* {
+  return i;
+}, growable: self::someGrowable);
+static field core::List<core::int*>* list5 = core::List::generate<core::int*>(10, (core::int* i) → core::int* {
+  if(i.{core::int::isEven})
+    return i.{core::num::+}(1);
+  return i.{core::num::-}(1);
+});
+static field core::List<core::int*>* list6 = core::List::generate<core::int*>(10, #C1);
+static field core::List<core::int*>* list7 = core::List::generate<core::int*>(10, self::bar);
+static field core::bool* someGrowable = true;
+static method foo(core::int* i) → core::int*
+  return i;
+static get bar() → (core::int*) →* core::int*
+  return #C1;
+static method main() → void {
+  self::someGrowable = !self::someGrowable;
+  core::print(<core::List<core::int*>*>[self::list1, self::list2, self::list3, self::list4, self::list5, self::list6, self::list7]);
+}
diff --git a/pkg/compiler/test/kernel/goldens_test.dart b/pkg/compiler/test/kernel/goldens_test.dart
new file mode 100644
index 0000000..a945729
--- /dev/null
+++ b/pkg/compiler/test/kernel/goldens_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/kernel.dart';
+import 'package:test/test.dart';
+
+import 'common_test_utils.dart';
+
+final String testRootDir = Platform.script.resolve('.').toFilePath();
+
+runTestCase(
+    Uri source, List<String> experimentalFlags, bool enableNullSafety) async {
+  final target =
+      TestingDart2jsTarget(TargetFlags(enableNullSafety: enableNullSafety));
+  Component component = await compileTestCaseToKernelProgram(source,
+      target: target, experimentalFlags: experimentalFlags);
+
+  String actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
+
+  compareResultWithExpectationsFile(source, actual);
+}
+
+main() {
+  group('goldens', () {
+    final testCasesDir = new Directory(testRootDir + '/data');
+
+    for (var entry
+        in testCasesDir.listSync(recursive: true, followLinks: false)) {
+      final path = entry.path;
+      if (path.endsWith('.dart')) {
+        final bool enableNullSafety = path.endsWith('_nnbd_strong.dart');
+        final bool enableNNBD = enableNullSafety || path.endsWith('_nnbd.dart');
+        final List<String> experimentalFlags = [
+          if (enableNNBD) 'non-nullable',
+        ];
+        test(path,
+            () => runTestCase(entry.uri, experimentalFlags, enableNullSafety));
+      }
+    }
+  }, timeout: Timeout.none);
+}
diff --git a/pkg/compiler/test/model/cfe_constant_test.dart b/pkg/compiler/test/model/cfe_constant_test.dart
index 50abef9..4ae3771 100644
--- a/pkg/compiler/test/model/cfe_constant_test.dart
+++ b/pkg/compiler/test/model/cfe_constant_test.dart
@@ -15,7 +15,6 @@
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
diff --git a/pkg/compiler/test/optimization/data/remove_last.dart b/pkg/compiler/test/optimization/data/remove_last.dart
new file mode 100644
index 0000000..a4f073f
--- /dev/null
+++ b/pkg/compiler/test/optimization/data/remove_last.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+import 'dart:collection';
+import 'dart:typed_data';
+
+/*member: dynamicIndex:Specializer=[!RemoveLast]*/
+@pragma('dart2js:noInline')
+dynamicIndex(var list) {
+  return list.removeLast(); // This is not known to be an indexable primitive.
+}
+
+/*member: unknownList:Specializer=[!RemoveLast]*/
+@pragma('dart2js:noInline')
+unknownList(List list) {
+  return list.removeLast(); // This is not known to be an indexable primitive.
+}
+
+/*member: possiblyNullMutableList:Specializer=[RemoveLast]*/
+@pragma('dart2js:noInline')
+possiblyNullMutableList(bool b) {
+  var list = b ? [0] : null;
+  return list.removeLast();
+}
+
+/*member: mutableList:Specializer=[RemoveLast]*/
+@pragma('dart2js:noInline')
+mutableList() {
+  var list = [0];
+  return list.removeLast();
+}
+
+/*member: typedList:Specializer=[!RemoveLast]*/
+@pragma('dart2js:noInline')
+typedList() {
+  var list = Uint8List(10);
+  return list.removeLast();
+}
+
+main() {
+  dynamicIndex([]);
+  dynamicIndex({});
+  unknownList([]);
+  unknownList(new MyList());
+  possiblyNullMutableList(true);
+  possiblyNullMutableList(false);
+  mutableList();
+  typedList();
+}
+
+class MyList<E> extends ListBase<E> {
+  E operator [](int index) => null;
+  void operator []=(int index, E value) {}
+  int get length => 0;
+  void set length(int value) {}
+}
diff --git a/pkg/compiler/test/serialization/serialization_test_helper.dart b/pkg/compiler/test/serialization/serialization_test_helper.dart
index 389d370..a3d44ea 100644
--- a/pkg/compiler/test/serialization/serialization_test_helper.dart
+++ b/pkg/compiler/test/serialization/serialization_test_helper.dart
@@ -101,20 +101,21 @@
 
 GlobalTypeInferenceResults cloneInferenceResults(Compiler compiler,
     GlobalTypeInferenceResults results, SerializationStrategy strategy) {
-  List<int> irData = strategy.serializeComponent(results);
+  List<int> irData = strategy.unpackAndSerializeComponent(results);
 
-  List worldData = strategy.serializeData(results);
+  List worldData = strategy.serializeGlobalTypeInferenceResults(results);
   print('data size: ${worldData.length}');
 
   ir.Component newComponent = strategy.deserializeComponent(irData);
-  GlobalTypeInferenceResults newResults = strategy.deserializeData(
-      compiler.options,
-      compiler.reporter,
-      compiler.environment,
-      compiler.abstractValueStrategy,
-      newComponent,
-      worldData);
-  List newWorldData = strategy.serializeData(newResults);
+  GlobalTypeInferenceResults newResults =
+      strategy.deserializeGlobalTypeInferenceResults(
+          compiler.options,
+          compiler.reporter,
+          compiler.environment,
+          compiler.abstractValueStrategy,
+          newComponent,
+          worldData);
+  List newWorldData = strategy.serializeGlobalTypeInferenceResults(newResults);
   Expect.equals(worldData.length, newWorldData.length,
       "Reserialization data length mismatch.");
   for (int i = 0; i < worldData.length; i++) {
diff --git a/pkg/compiler/test/static_type/static_type_test.dart b/pkg/compiler/test/static_type/static_type_test.dart
index a2c679e..220b990 100644
--- a/pkg/compiler/test/static_type/static_type_test.dart
+++ b/pkg/compiler/test/static_type/static_type_test.dart
@@ -17,7 +17,6 @@
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
diff --git a/pkg/compiler/test/static_type/type_promotion_test.dart b/pkg/compiler/test/static_type/type_promotion_test.dart
index 06c6bf3..9584f53 100644
--- a/pkg/compiler/test/static_type/type_promotion_test.dart
+++ b/pkg/compiler/test/static_type/type_promotion_test.dart
@@ -15,7 +15,6 @@
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
-import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
diff --git a/pkg/compiler/tool/modular_test_suite.dart b/pkg/compiler/tool/modular_test_suite.dart
index eb8953b..2809f33 100644
--- a/pkg/compiler/tool/modular_test_suite.dart
+++ b/pkg/compiler/tool/modular_test_suite.dart
@@ -6,6 +6,7 @@
 ///
 /// This is a shell that runs multiple tests, one per folder under `data/`.
 import 'dart:io';
+import 'dart:async';
 
 import 'package:compiler/src/commandline_options.dart';
 import 'package:front_end/src/compute_platform_binaries_location.dart'
@@ -30,22 +31,41 @@
   _options = Options.parse(args);
   _packageConfig = await loadPackageConfigUri(packageConfigUri);
   await _resolveScripts();
-  await runSuite(
-      sdkRoot.resolve('tests/modular/'),
-      'tests/modular',
-      _options,
-      new IOPipeline([
-        SourceToDillStep(),
-        GlobalAnalysisStep(),
-        Dart2jsCodegenStep(codeId0),
-        Dart2jsCodegenStep(codeId1),
-        Dart2jsEmissionStep(),
-        RunD8(),
-      ], cacheSharedModules: true));
+  await Future.wait([
+    runSuite(
+        sdkRoot.resolve('tests/modular/'),
+        'tests/modular',
+        _options,
+        new IOPipeline([
+          SourceToDillStep(),
+          ComputeClosedWorldStep(),
+          GlobalAnalysisStep(),
+          Dart2jsCodegenStep(codeId0),
+          Dart2jsCodegenStep(codeId1),
+          Dart2jsEmissionStep(),
+          RunD8(),
+        ], cacheSharedModules: true)),
+    // TODO(joshualitt) Delete this when we stop supporting this way of running
+    // the compiler.
+    runSuite(
+        sdkRoot.resolve('tests/modular/'),
+        'tests/modular',
+        _options,
+        new IOPipeline([
+          SourceToDillStep(),
+          ComputeClosedWorldStep(),
+          GlobalAnalysisStep(),
+          LegacyDart2jsCodegenStep(codeId0),
+          LegacyDart2jsCodegenStep(codeId1),
+          LegacyDart2jsEmissionStep(),
+          RunD8(),
+        ], cacheSharedModules: true)),
+  ]);
 }
 
 const dillId = const DataId("dill");
 const updatedDillId = const DataId("udill");
+const closedWorldId = const DataId("world");
 const globalDataId = const DataId("gdata");
 const codeId = const ShardsDataId("code", 2);
 const codeId0 = const ShardDataId(codeId, 0);
@@ -213,11 +233,10 @@
   }
 }
 
-// Step that invokes the dart2js global analysis on the main module by providing
-// the .dill files of all transitive modules as inputs.
-class GlobalAnalysisStep implements IOModularStep {
+// Step that invokes the dart2js closed world computation.
+class ComputeClosedWorldStep implements IOModularStep {
   @override
-  List<DataId> get resultData => const [globalDataId, updatedDillId];
+  List<DataId> get resultData => const [closedWorldId, updatedDillId];
 
   @override
   bool get needsSources => false;
@@ -234,7 +253,8 @@
   @override
   Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
       List<String> flags) async {
-    if (_options.verbose) print("\nstep: dart2js global analysis on $module");
+    if (_options.verbose)
+      print("\nstep: dart2js compute closed world on $module");
     Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
     Iterable<String> dillDependencies =
         transitiveDependencies.map((m) => '${toUri(m, dillId)}');
@@ -246,7 +266,7 @@
       '${toUri(module, dillId)}',
       for (String flag in flags) '--enable-experiment=$flag',
       '${Flags.dillDependencies}=${dillDependencies.join(',')}',
-      '${Flags.writeData}=${toUri(module, globalDataId)}',
+      '${Flags.writeClosedWorld}=${toUri(module, closedWorldId)}',
       '--out=${toUri(module, updatedDillId)}',
     ];
     var result =
@@ -258,6 +278,51 @@
   @override
   void notifyCached(Module module) {
     if (_options.verbose)
+      print("\ncached step: dart2js compute closed world on $module");
+  }
+}
+
+// Step that invokes the dart2js global analysis on the main module by providing
+// the .dill files of all transitive modules as inputs.
+class GlobalAnalysisStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [globalDataId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [updatedDillId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [closedWorldId, updatedDillId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: dart2js global analysis on $module");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      // TODO(sigmund): remove this dependency on libraries.json
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${toUri(module, updatedDillId)}',
+      for (String flag in flags) '--enable-experiment=$flag',
+      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
+      '${Flags.writeData}=${toUri(module, globalDataId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose)
       print("\ncached step: dart2js global analysis on $module");
   }
 }
@@ -280,6 +345,106 @@
   List<DataId> get dependencyDataNeeded => const [];
 
   @override
+  List<DataId> get moduleDataNeeded =>
+      const [updatedDillId, closedWorldId, globalDataId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: dart2js backend on $module");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${toUri(module, updatedDillId)}',
+      for (String flag in flags) '--enable-experiment=$flag',
+      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
+      '${Flags.readData}=${toUri(module, globalDataId)}',
+      '${Flags.writeCodegen}=${toUri(module, codeId.dataId)}',
+      '${Flags.codegenShard}=${codeId.shard}',
+      '${Flags.codegenShards}=${codeId.dataId.shards}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) print("cached step: dart2js backend on $module");
+  }
+}
+
+// Step that invokes the dart2js codegen enqueuer and emitter on the main module
+// given the results of the global analysis step and codegen shards.
+class Dart2jsEmissionStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [jsId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded =>
+      const [updatedDillId, closedWorldId, globalDataId, codeId0, codeId1];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("step: dart2js backend on $module");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${toUri(module, updatedDillId)}',
+      for (String flag in flags) '${Flags.enableLanguageExperiments}=$flag',
+      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
+      '${Flags.readData}=${toUri(module, globalDataId)}',
+      '${Flags.readCodegen}=${toUri(module, codeId)}',
+      '${Flags.codegenShards}=${codeId.shards}',
+      '--out=${toUri(module, jsId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) print("\ncached step: dart2js backend on $module");
+  }
+}
+
+// Step that invokes the dart2js code generation on the main module given the
+// results of the global analysis step and produces one shard of the codegen
+// output.
+// Note: Legacy.
+class LegacyDart2jsCodegenStep implements IOModularStep {
+  final ShardDataId codeId;
+
+  LegacyDart2jsCodegenStep(this.codeId);
+
+  @override
+  List<DataId> get resultData => [codeId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
   List<DataId> get moduleDataNeeded => const [updatedDillId, globalDataId];
 
   @override
@@ -314,7 +479,8 @@
 
 // Step that invokes the dart2js codegen enqueuer and emitter on the main module
 // given the results of the global analysis step and codegen shards.
-class Dart2jsEmissionStep implements IOModularStep {
+// Note: Legacy.
+class LegacyDart2jsEmissionStep implements IOModularStep {
   @override
   List<DataId> get resultData => const [jsId];
 
diff --git a/pkg/dartdev/benchmark/bench.dart b/pkg/dartdev/benchmark/bench.dart
new file mode 100644
index 0000000..fc62a89
--- /dev/null
+++ b/pkg/dartdev/benchmark/bench.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io' as io;
+
+import 'package:args/args.dart';
+import 'package:meta/meta.dart';
+
+List<Benchmark> benchmarks = [
+  DartStartup(),
+  DartRunStartup(),
+  SdkSize(),
+];
+
+void main(List<String> args) async {
+  ArgParser argParser = _createArgParser();
+
+  ArgResults argResults;
+
+  try {
+    argResults = argParser.parse(args);
+  } on FormatException catch (e) {
+    print(e.message);
+    print('');
+    printUsage(argParser, includeDescription: false);
+    io.exit(1);
+  }
+
+  if (argResults['help'] || argResults.arguments.isEmpty) {
+    printUsage(argParser);
+    io.exit(0);
+  }
+
+  if (!argResults.wasParsed('dart-sdk')) {
+    print('No value passed for \`dart-sdk\`.');
+    print('');
+    printUsage(argParser);
+    io.exit(1);
+  }
+
+  if (!argResults.wasParsed('run')) {
+    print('No value passed for \`run\`.');
+    print('');
+    printUsage(argParser);
+    io.exit(1);
+  }
+
+  Context context = Context(argResults['dart-sdk']);
+
+  String benchmarkName = argResults['run'];
+  Benchmark benchmark = benchmarks.singleWhere((b) => b.id == benchmarkName);
+
+  BenchmarkResult result = await benchmark.run(context);
+  print(result.toJson());
+  io.exit(0);
+}
+
+void printUsage(ArgParser argParser, {bool includeDescription = true}) {
+  print('usage: dart bin/bench.dart <options>');
+  print('');
+  if (includeDescription) {
+    print('Run benchmarks for the dartdev tool.');
+    print('');
+  }
+  print('Options:');
+  print(argParser.usage);
+}
+
+ArgParser _createArgParser() {
+  ArgParser argParser = ArgParser(usageLineLength: io.stdout.terminalColumns);
+  argParser.addFlag(
+    'help',
+    abbr: 'h',
+    negatable: false,
+    help: 'Print this usage information.',
+  );
+  argParser.addOption(
+    'dart-sdk',
+    valueHelp: 'sdk path',
+    help: 'The path to the Dart SDK to use for benchmarking.',
+  );
+  argParser.addOption(
+    'run',
+    valueHelp: 'benchmark',
+    allowed: benchmarks.map((b) => b.id).toList(),
+    allowedHelp: {
+      for (var benchmark in benchmarks) benchmark.id: benchmark.description,
+    },
+    help: 'The benchmark to run.',
+  );
+  return argParser;
+}
+
+abstract class Benchmark {
+  final String id;
+  final String description;
+
+  Benchmark(this.id, this.description);
+
+  Future<BenchmarkResult> run(Context context);
+}
+
+class DartStartup extends Benchmark {
+  DartStartup()
+      : super(
+          'script-startup',
+          'Benchmark the startup time of a minimal Dart script (μs).',
+        );
+
+  @override
+  Future<BenchmarkResult> run(Context context) async {
+    // setup
+    io.Directory dir = io.Directory.systemTemp.createTempSync('dartdev');
+    io.File file = io.File('${dir.path}/hello.dart');
+    file.writeAsStringSync('void main() => print(\'hello\');');
+
+    // perform the benchmark
+    Stopwatch timer = Stopwatch()..start();
+    io.Process.runSync(
+      '${context.sdkPath}/bin/dart',
+      [file.absolute.path],
+    );
+    timer.stop();
+
+    // cleanup
+    dir.deleteSync(recursive: true);
+
+    // report the result
+    int micros = timer.elapsedMicroseconds;
+    return BenchmarkResult(
+      id: id,
+      value: micros,
+      units: 'microseconds',
+      userDescription: '${(micros / 1000.0).toStringAsFixed(2)}ms',
+    );
+  }
+}
+
+class DartRunStartup extends Benchmark {
+  DartRunStartup()
+      : super(
+          'run-script-startup',
+          'Benchmark the startup time of a minimal Dart script, executed with '
+              '\`dart run\` (μs).',
+        );
+
+  @override
+  Future<BenchmarkResult> run(Context context) async {
+    // setup
+    io.Directory dir = io.Directory.systemTemp.createTempSync('dartdev');
+    io.File file = io.File('${dir.path}/hello.dart');
+    file.writeAsStringSync('void main() => print(\'hello\');');
+
+    // perform the benchmark
+    Stopwatch timer = Stopwatch()..start();
+    io.Process.runSync(
+      '${context.sdkPath}/bin/dart',
+      ['run', file.absolute.path],
+    );
+    timer.stop();
+
+    // cleanup
+    dir.deleteSync(recursive: true);
+
+    // report the result
+    int micros = timer.elapsedMicroseconds;
+    return BenchmarkResult(
+      id: id,
+      value: micros,
+      units: 'microseconds',
+      userDescription: '${(micros / 1000.0).toStringAsFixed(2)}ms',
+    );
+  }
+}
+
+class SdkSize extends Benchmark {
+  SdkSize()
+      : super(
+          'sdk-size',
+          'Benchmark the compressed size of the Dart SDK (bytes).',
+        );
+
+  @override
+  Future<BenchmarkResult> run(Context context) async {
+    // setup
+    io.Directory tempDir = io.Directory.systemTemp.createTempSync('dartdev');
+
+    // perform the benchmark
+    io.File sdkArchive = compress(io.Directory(context.sdkPath), tempDir);
+    int bytes = sdkArchive.lengthSync();
+
+    // cleanup
+    tempDir.deleteSync(recursive: true);
+
+    // report the result
+    return BenchmarkResult(
+      id: id,
+      value: bytes,
+      units: 'bytes',
+      userDescription: '${(bytes / (1024.0 * 1024.0)).toStringAsFixed(1)}MB',
+    );
+  }
+
+  io.File compress(io.Directory sourceDir, io.Directory targetDir) {
+    String name = sourceDir.path.substring(sourceDir.path.lastIndexOf('/') + 1);
+    io.File outFile = io.File('${targetDir.absolute.path}/$name.zip');
+
+    if (io.Platform.isMacOS || io.Platform.isLinux) {
+      io.Process.runSync('zip', [
+        '-r',
+        '-9', // optimized for compressed size
+        outFile.absolute.path,
+        sourceDir.absolute.path,
+      ]);
+    } else {
+      throw Exception('platform not supported: ${io.Platform.operatingSystem}');
+    }
+
+    return outFile;
+  }
+}
+
+class Context {
+  final String sdkPath;
+
+  Context(this.sdkPath);
+}
+
+class BenchmarkResult {
+  final String id;
+  final int value;
+  final String units;
+  final String userDescription;
+
+  BenchmarkResult({
+    @required this.id,
+    @required this.value,
+    @required this.units,
+    @required this.userDescription,
+  });
+
+  String toJson() {
+    Map m = {
+      'id': id,
+      'value': value,
+      'units': units,
+      'userDescription': userDescription,
+    };
+    return JsonEncoder.withIndent('  ').convert(m);
+  }
+}
diff --git a/pkg/dartdev/doc/dart-fix.md b/pkg/dartdev/doc/dart-fix.md
new file mode 100644
index 0000000..95dbf1a
--- /dev/null
+++ b/pkg/dartdev/doc/dart-fix.md
@@ -0,0 +1,44 @@
+# `dart fix`
+
+## What is it?
+
+`dart fix` is a command line tool and part of the regular `dart` tool. It is used
+to batch apply fixes for analysis issues.
+
+## How does it work?
+
+`dart fix` runs over your project looking for analysis issues. For each issue
+it checks whether there is an automated fix that can be applied. These fixes
+are generaly either in response to a lint or hint in your code, or part of
+upgrading your source to newer package APIs.
+
+For the first type of change, the fixes are generally in response to the set
+of lints and analysis configuration specified in your [analysis_options.yaml]
+file.
+
+The second type of change - upgrading to newer package APIs - is performed
+based on API changes defined for specific packages. This declarative definition
+of the API changes lives in a `fix_data.yaml` file in the package's `lib/`
+directory (documentation forthcoming).
+
+## Command line usage
+
+```
+Fix Dart source code.
+
+This tool looks for and fixes analysis issues that have associated automated
+fixes or issues that have associated package API migration information.
+
+To use the tool, run one of:
+- 'dart fix --dry-run' for a preview of the proposed changes for a project
+- 'dart fix --apply' to apply the changes
+
+Usage: dart fix [arguments]
+-h, --help       Print this usage information.
+-n, --dry-run    Show which files would be modified but make no changes.
+    --apply      Apply the proposed changes.
+
+Run "dart help" to see global options.
+```
+
+[analysis_options.yaml]: https://dart.dev/guides/language/analysis-options
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index e2229b4..5e8f2a9 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -32,138 +32,44 @@
 /// analytics logic, it has been moved here.
 Future<void> runDartdev(List<String> args, SendPort port) async {
   VmInteropHandler.initialize(port);
-
-  int result;
-
-  // The exit code for the dartdev process; null indicates that it has not been
-  // set yet. The value is set in the catch and finally blocks below.
-  int exitCode;
-
-  // Any caught non-UsageExceptions when running the sub command.
-  Object exception;
-  StackTrace stackTrace;
-
-  // The Analytics instance used to report information back to Google Analytics;
-  // see lib/src/analytics.dart.
-  final analytics = createAnalyticsInstance(
-    args.contains('--disable-dartdev-analytics'),
-  );
-
-  // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
-  // the user is on a terminal, and the machine is not a bot, then print the
-  // disclosure and set analytics.disclosureShownOnTerminal to true.
-  if (analytics is DartdevAnalytics &&
-      !analytics.disclosureShownOnTerminal &&
-      io.stdout.hasTerminal &&
-      !isBot()) {
-    print(analyticsNoticeOnFirstRunMessage);
-    analytics.disclosureShownOnTerminal = true;
+  if (args.contains('run')) {
+    // These flags have a format that can't be handled by package:args, so while
+    // they are valid flags we'll assume the VM has verified them by this point.
+    args = args
+        .where(
+          (element) => !(element.contains('--observe') ||
+              element.contains('--enable-vm-service')),
+        )
+        .toList();
   }
 
-  // When `--disable-analytics` or `--enable-analytics` are called we perform
-  // the respective intention and print any notices to standard out and exit.
-  if (args.contains('--disable-analytics')) {
-    // This block also potentially catches the case of (disableAnalytics &&
-    // enableAnalytics), in which we favor the disabling of analytics.
-    analytics.enabled = false;
+  // Finally, call the runner to execute the command; see DartdevRunner.
 
-    // Alert the user that analytics has been disabled.
-    print(analyticsDisabledNoticeMessage);
-    VmInteropHandler.exit(0);
-    return;
-  } else if (args.contains('--enable-analytics')) {
-    analytics.enabled = true;
-
-    // Alert the user again that anonymous data will be collected.
-    print(analyticsNoticeOnFirstRunMessage);
-    VmInteropHandler.exit(0);
-    return;
-  }
-
+  final runner = DartdevRunner(args);
+  var exitCode = 1;
   try {
-    final runner = DartdevRunner(args, analytics);
-
-    // Run can't be called with the '--disable-dartdev-analytics' flag; remove
-    // it if it is contained in args.
-    if (args.contains('--disable-dartdev-analytics')) {
-      args = List.from(args)..remove('--disable-dartdev-analytics');
-    }
-
-    if (args.contains('run')) {
-      // These flags have a format that can't be handled by package:args, so while
-      // they are valid flags we'll assume the VM has verified them by this point.
-      args = args
-          .where(
-            (element) => !(element.contains('--observe') ||
-                element.contains('--enable-vm-service')),
-          )
-          .toList();
-    }
-
-    // If ... help pub ... is in the args list, remove 'help', and add '--help'
-    // to the end of the list. This will make it possible to use the help
-    // command to access subcommands of pub such as `dart help pub publish`; see
-    // https://github.com/dart-lang/sdk/issues/42965.
-    if (PubUtils.shouldModifyArgs(args, runner.commands.keys.toList())) {
-      args = PubUtils.modifyArgs(args);
-    }
-
-    // Finally, call the runner to execute the command; see DartdevRunner.
-    result = await runner.run(args);
-  } catch (e, st) {
-    if (e is UsageException) {
-      io.stderr.writeln('$e');
-      exitCode = 64;
-    } else {
-      // Set the exception and stack trace only for non-UsageException cases:
-      exception = e;
-      stackTrace = st;
-      io.stderr.writeln('$e');
-      io.stderr.writeln('$st');
-      exitCode = 1;
-    }
+    exitCode = await runner.run(args);
+  } on UsageException catch (e) {
+    // TODO(sigurdm): It is unclear when a UsageException gets to here, and
+    // when it is in DartdevRunner.runCommand.
+    io.stderr.writeln('$e');
+    exitCode = 64;
   } finally {
-    // Set the exitCode, if it wasn't set in the catch block above.
-    exitCode ??= result ?? 0;
-
-    // Send analytics before exiting
-    if (analytics.enabled) {
-      // And now send the exceptions and events to Google Analytics:
-      if (exception != null) {
-        unawaited(
-          analytics.sendException(
-              '${exception.runtimeType}\n${sanitizeStacktrace(stackTrace)}',
-              fatal: true),
-        );
-      }
-
-      await analytics.waitForLastPing(
-          timeout: const Duration(milliseconds: 200));
-    }
-
-    // Set the enabled flag in the analytics object to true. Note: this will not
-    // enable the analytics unless the disclosure was shown (terminal detected),
-    // and the machine is not detected to be a bot.
-    if (analytics.firstRun) {
-      analytics.enabled = true;
-    }
-    analytics.close();
     VmInteropHandler.exit(exitCode);
   }
 }
 
 class DartdevRunner extends CommandRunner<int> {
-  final Analytics analytics;
-
   @override
-  final ArgParser argParser =
-      ArgParser(usageLineLength: dartdevUsageLineLength);
+  final ArgParser argParser = ArgParser(
+    usageLineLength: dartdevUsageLineLength,
+    allowTrailingOptions: false,
+  );
 
   static const String dartdevDescription =
       'A command-line utility for Dart development';
 
-  DartdevRunner(List<String> args, this.analytics)
-      : super('dart', '$dartdevDescription.') {
+  DartdevRunner(List<String> args) : super('dart', '$dartdevDescription.') {
     final bool verbose = args.contains('-v') || args.contains('--verbose');
 
     argParser.addFlag('verbose',
@@ -178,20 +84,17 @@
     argParser.addFlag('diagnostics',
         negatable: false, help: 'Show tool diagnostic output.', hide: !verbose);
 
-    // A hidden flag to disable analytics on this run, this constructor can be
-    // called with this flag, but should be removed before run() is called as
-    // the flag has not been added to all sub-commands.
     argParser.addFlag(
-      'disable-dartdev-analytics',
-      negatable: false,
+      'analytics',
+      negatable: true,
       help: 'Disable anonymous analytics for this `dart *` run',
       hide: true,
     );
 
-    addCommand(AnalyzeCommand());
+    addCommand(AnalyzeCommand(verbose: verbose));
     addCommand(CreateCommand(verbose: verbose));
     addCommand(CompileCommand(verbose: verbose));
-    addCommand(FixCommand());
+    addCommand(FixCommand(verbose: verbose));
     addCommand(FormatCommand(verbose: verbose));
     addCommand(MigrateCommand(verbose: verbose));
     addCommand(pubCommand());
@@ -210,7 +113,38 @@
   @override
   Future<int> runCommand(ArgResults topLevelResults) async {
     final stopwatch = Stopwatch()..start();
-    assert(!topLevelResults.arguments.contains('--disable-dartdev-analytics'));
+    // The Analytics instance used to report information back to Google Analytics;
+    // see lib/src/analytics.dart.
+    final analytics = createAnalyticsInstance(!topLevelResults['analytics']);
+
+    // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
+    // the user is on a terminal, and the machine is not a bot, then print the
+    // disclosure and set analytics.disclosureShownOnTerminal to true.
+    if (analytics is DartdevAnalytics &&
+        !analytics.disclosureShownOnTerminal &&
+        io.stdout.hasTerminal &&
+        !isBot()) {
+      print(analyticsNoticeOnFirstRunMessage);
+      analytics.disclosureShownOnTerminal = true;
+    }
+
+    // When `--disable-analytics` or `--enable-analytics` are called we perform
+    // the respective intention and print any notices to standard out and exit.
+    if (topLevelResults['disable-analytics']) {
+      // This block also potentially catches the case of (disableAnalytics &&
+      // enableAnalytics), in which we favor the disabling of analytics.
+      analytics.enabled = false;
+
+      // Alert the user that analytics has been disabled.
+      print(analyticsDisabledNoticeMessage);
+      return 0;
+    } else if (topLevelResults['enable-analytics']) {
+      analytics.enabled = true;
+
+      // Alert the user again that anonymous data will be collected.
+      print(analyticsNoticeOnFirstRunMessage);
+      return 0;
+    }
 
     if (topLevelResults.command == null &&
         topLevelResults.arguments.isNotEmpty) {
@@ -220,14 +154,12 @@
         io.stderr.writeln(
             "Error when reading '$firstArg': No such file or directory.");
         // This is the exit code used by the frontend.
-        VmInteropHandler.exit(254);
+        return 254;
       }
     }
 
-    isDiagnostics = topLevelResults['diagnostics'];
-
     final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
-    log = isDiagnostics
+    log = topLevelResults['diagnostics']
         ? Logger.verbose(ansi: ansi)
         : Logger.standard(ansi: ansi);
 
@@ -245,8 +177,15 @@
       analytics.sendScreenView(path),
     );
 
+    // The exit code for the dartdev process; null indicates that it has not been
+    // set yet. The value is set in the catch and finally blocks below.
+    int exitCode;
+
+    // Any caught non-UsageExceptions when running the sub command.
+    Object exception;
+    StackTrace stackTrace;
     try {
-      final exitCode = await super.runCommand(topLevelResults);
+      exitCode = await super.runCommand(topLevelResults);
 
       if (path != null && analytics.enabled) {
         // Send the event to analytics
@@ -266,8 +205,16 @@
           ),
         );
       }
-
-      return exitCode;
+    } on UsageException catch (e) {
+      io.stderr.writeln('$e');
+      exitCode = 64;
+    } catch (e, st) {
+      // Set the exception and stack trace only for non-UsageException cases:
+      exception = e;
+      stackTrace = st;
+      io.stderr.writeln('$e');
+      io.stderr.writeln('$st');
+      exitCode = 1;
     } finally {
       stopwatch.stop();
       if (analytics.enabled) {
@@ -279,6 +226,32 @@
           ),
         );
       }
+      // Set the exitCode, if it wasn't set in the catch block above.
+      exitCode ??= 0;
+
+      // Send analytics before exiting
+      if (analytics.enabled) {
+        // And now send the exceptions and events to Google Analytics:
+        if (exception != null) {
+          unawaited(
+            analytics.sendException(
+                '${exception.runtimeType}\n${sanitizeStacktrace(stackTrace)}',
+                fatal: true),
+          );
+        }
+
+        await analytics.waitForLastPing(
+            timeout: const Duration(milliseconds: 200));
+      }
+
+      // Set the enabled flag in the analytics object to true. Note: this will not
+      // enable the analytics unless the disclosure was shown (terminal detected),
+      // and the machine is not detected to be a bot.
+      if (analytics.firstRun) {
+        analytics.enabled = true;
+      }
+      analytics.close();
+      return exitCode;
     }
   }
 }
diff --git a/pkg/dartdev/lib/src/analysis_server.dart b/pkg/dartdev/lib/src/analysis_server.dart
index 907b5104..e5cfacd 100644
--- a/pkg/dartdev/lib/src/analysis_server.dart
+++ b/pkg/dartdev/lib/src/analysis_server.dart
@@ -257,6 +257,8 @@
 
   int get offset => json['location']['offset'] as int;
 
+  int get length => json['location']['length'] as int;
+
   String get messageSentenceFragment => trimEnd(message, '.');
 
   String get url => json['url'] as String;
diff --git a/pkg/dartdev/lib/src/analytics.dart b/pkg/dartdev/lib/src/analytics.dart
index f8e8ffc..c9b1edf 100644
--- a/pkg/dartdev/lib/src/analytics.dart
+++ b/pkg/dartdev/lib/src/analytics.dart
@@ -15,17 +15,21 @@
 const String analyticsNoticeOnFirstRunMessage = '''
   ╔════════════════════════════════════════════════════════════════════════════╗
   ║ The Dart tool uses Google Analytics to anonymously report feature usage    ║
-  ║ statistics, and crash reporting to send basic crash reports. This data is  ║
-  ║ used to help improve the Dart platform and tools over time.                ║
+  ║ statistics and to send basic crash reports. This data is used to help      ║
+  ║ improve the Dart platform and tools over time.                             ║
   ║                                                                            ║
-  ║ To disable reporting of anonymous tool usage statistics in general, run    ║
-  ║ the command: `dart --disable-analytics`.                                   ║
+  ║ To disable reporting of anonymous analytics, run:                          ║
+  ║                                                                            ║
+  ║   dart --disable-analytics                                                 ║
+  ║                                                                            ║
   ╚════════════════════════════════════════════════════════════════════════════╝
 ''';
 const String analyticsDisabledNoticeMessage = '''
   ╔════════════════════════════════════════════════════════════════════════════╗
-  ║ Anonymous analytics disabled. To enable again, run the command:            ║
-  ║ `dart --enable-analytics`                                                  ║
+  ║ Anonymous analytics reporting disabled. In order to enable it, run:        ║
+  ║                                                                            ║
+  ║   dart --enable-analytics                                                  ║
+  ║                                                                            ║
   ╚════════════════════════════════════════════════════════════════════════════╝
 ''';
 const String _appName = 'dartdev';
@@ -34,8 +38,8 @@
 const String _trackingId = 'UA-26406144-37';
 const String _readmeFileName = 'README.txt';
 const String _readmeFileContents = '''
-The present directory contains user-level settings for the
-Dart programming language (https://dart.dev).
+This directory contains user-level settings for the Dart programming language
+(https://dart.dev).
 ''';
 
 const String eventCategory = 'dartdev';
@@ -53,10 +57,12 @@
   }
 
   if (disableAnalytics) {
-    // Dartdev tests pass a hidden 'disable-dartdev-analytics' flag which is
+    // Dartdev tests pass a hidden 'no-analytics' flag which is
     // handled here.
-    // Also, stdout.hasTerminal is checked, if there is no terminal we infer that
-    // a machine is running dartdev so we return analytics shouldn't be set.
+    //
+    // Also, stdout.hasTerminal is checked; if there is no terminal we infer
+    // that a machine is running dartdev so we return that analytics shouldn't
+    // be set enabled.
     return DisabledAnalytics(_trackingId, _appName);
   }
 
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index 554d623..5e533f4 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -5,6 +5,8 @@
 import 'dart:async';
 import 'dart:io' as io;
 
+import 'package:cli_util/cli_logging.dart';
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 
 import '../analysis_server.dart';
@@ -22,12 +24,42 @@
   /// message. The width left for the severity label plus the separator width.
   static const int _bodyIndentWidth = _severityWidth + 3;
 
-  AnalyzeCommand() : super(cmdName, "Analyze the project's Dart code.") {
+  static final String _bodyIndent = ' ' * _bodyIndentWidth;
+
+  static final int _pipeCodeUnit = '|'.codeUnitAt(0);
+
+  static final int _slashCodeUnit = '\\'.codeUnitAt(0);
+
+  static final int _newline = '\n'.codeUnitAt(0);
+
+  static final int _return = '\r'.codeUnitAt(0);
+
+  AnalyzeCommand({bool verbose = false})
+      : super(cmdName, "Analyze the project's Dart code.") {
     argParser
       ..addFlag('fatal-infos',
           help: 'Treat info level issues as fatal.', negatable: false)
       ..addFlag('fatal-warnings',
-          help: 'Treat warning level issues as fatal.', defaultsTo: true);
+          help: 'Treat warning level issues as fatal.', defaultsTo: true)
+
+      // Options hidden by default.
+      ..addOption(
+        'format',
+        valueHelp: 'value',
+        help: 'Specifies the format to display errors.',
+        allowed: ['default', 'machine'],
+        allowedHelp: {
+          'default':
+              'The default output format. This format is intended to be user '
+                  'consumable.\nThe format is not specified and can change '
+                  'between releases.',
+          'machine': 'A machine readable output. The format is:\n\n'
+              'SEVERITY|TYPE|ERROR_CODE|FILE_PATH|LINE|COLUMN|LENGTH|ERROR_MESSAGE\n\n'
+              'Note that the pipe character is escaped with backslashes for '
+              'the file path and error message fields.',
+        },
+        hide: !verbose,
+      );
   }
 
   @override
@@ -49,7 +81,11 @@
 
     final List<AnalysisError> errors = <AnalysisError>[];
 
-    var progress = log.progress('Analyzing ${path.basename(dir.path)}');
+    final machineFormat = argResults['format'] == 'machine';
+
+    var progress = machineFormat
+        ? null
+        : log.progress('Analyzing ${path.basename(dir.path)}');
 
     final AnalysisServer server = AnalysisServer(
       io.Directory(sdk.sdkPath),
@@ -78,63 +114,33 @@
 
     await server.shutdown(timeout: Duration(milliseconds: 100));
 
-    progress.finish(showTiming: true);
+    progress?.finish(showTiming: true);
 
     errors.sort();
 
     if (errors.isEmpty) {
-      log.stdout('No issues found!');
+      if (!machineFormat) {
+        log.stdout('No issues found!');
+      }
       return 0;
     }
 
-    final bullet = log.ansi.bullet;
-
-    log.stdout('');
+    if (machineFormat) {
+      emitMachineFormat(log, errors);
+    } else {
+      emitDefaultFormat(log, errors, relativeToDir: dir, verbose: verbose);
+    }
 
     bool hasErrors = false;
     bool hasWarnings = false;
     bool hasInfos = false;
 
     for (final AnalysisError error in errors) {
-      // error • Message ... at path.dart:line:col • (code)
-
-      var filePath = path.relative(error.file, from: dir.path);
-      var severity = error.severity.toLowerCase().padLeft(_severityWidth);
-      if (error.isError) {
-        severity = log.ansi.error(severity);
-      }
-
-      log.stdout(
-        '$severity $bullet '
-        '${log.ansi.emphasized(error.messageSentenceFragment)} '
-        'at $filePath:${error.startLine}:${error.startColumn} $bullet '
-        '(${error.code})',
-      );
-
-      if (verbose) {
-        var padding = ' ' * _bodyIndentWidth;
-        for (var message in error.contextMessages) {
-          log.stdout('$padding${message.message} '
-              'at ${message.filePath}:${message.line}:${message.column}');
-        }
-        if (error.correction != null) {
-          log.stdout('$padding${error.correction}');
-        }
-        if (error.url != null) {
-          log.stdout('$padding${error.url}');
-        }
-      }
-
       hasErrors |= error.isError;
       hasWarnings |= error.isWarning;
       hasInfos |= error.isInfo;
     }
 
-    log.stdout('');
-
-    final errorCount = errors.length;
-    log.stdout('$errorCount ${pluralize('issue', errorCount)} found.');
-
     // Return an error code in the range [0-3] dependent on the severity of
     // the issue(s) found.
     if (hasErrors) {
@@ -152,4 +158,100 @@
       return 0;
     }
   }
+
+  @visibleForTesting
+  static void emitDefaultFormat(
+    Logger log,
+    List<AnalysisError> errors, {
+    io.Directory relativeToDir,
+    bool verbose = false,
+  }) {
+    final bullet = log.ansi.bullet;
+
+    log.stdout('');
+
+    final wrapWidth = dartdevUsageLineLength == null
+        ? null
+        : (dartdevUsageLineLength - _bodyIndentWidth);
+
+    for (final AnalysisError error in errors) {
+      // error • Message ... at path.dart:line:col • (code)
+
+      var filePath = path.relative(error.file, from: relativeToDir?.path);
+      var severity = error.severity.toLowerCase().padLeft(_severityWidth);
+      if (error.isError) {
+        severity = log.ansi.error(severity);
+      }
+
+      log.stdout(
+        '$severity $bullet '
+        '${log.ansi.emphasized(error.messageSentenceFragment)} '
+        'at $filePath:${error.startLine}:${error.startColumn} $bullet '
+        '(${error.code})',
+      );
+
+      if (verbose) {
+        for (var message in error.contextMessages) {
+          // Wrap longer context messages.
+          var contextMessage = wrapText(
+              '${message.message} at '
+              '${message.filePath}:${message.line}:${message.column}',
+              width: wrapWidth);
+          log.stdout('$_bodyIndent'
+              '${contextMessage.replaceAll('\n', '\n$_bodyIndent')}');
+        }
+      }
+
+      if (error.correction != null) {
+        // Wrap longer correction messages.
+        var correction = wrapText(error.correction, width: wrapWidth);
+        log.stdout(
+            '$_bodyIndent${correction.replaceAll('\n', '\n$_bodyIndent')}');
+      }
+
+      if (verbose) {
+        if (error.url != null) {
+          log.stdout('$_bodyIndent${error.url}');
+        }
+      }
+    }
+
+    log.stdout('');
+
+    final errorCount = errors.length;
+    log.stdout('$errorCount ${pluralize('issue', errorCount)} found.');
+  }
+
+  @visibleForTesting
+  static void emitMachineFormat(Logger log, List<AnalysisError> errors) {
+    for (final AnalysisError error in errors) {
+      log.stdout([
+        error.severity,
+        error.type,
+        error.code.toUpperCase(),
+        _escapeForMachineMode(error.file),
+        error.startLine.toString(),
+        error.startColumn.toString(),
+        error.length.toString(),
+        _escapeForMachineMode(error.message),
+      ].join('|'));
+    }
+  }
+
+  static String _escapeForMachineMode(String input) {
+    var result = StringBuffer();
+    for (var c in input.codeUnits) {
+      if (c == _newline) {
+        result.write(r'\n');
+      } else if (c == _return) {
+        result.write(r'\r');
+      } else {
+        if (c == _slashCodeUnit || c == _pipeCodeUnit) {
+          result.write('\\');
+        }
+        result.writeCharCode(c);
+      }
+    }
+    return result.toString();
+  }
 }
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index c0fdea3..6edd82b 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -92,12 +92,15 @@
       return 1;
     }
 
-    VmInteropHandler.run(sdk.dart2jsSnapshot, [
-      '--libraries-spec=$librariesPath',
-      if (argResults.enabledExperiments.isNotEmpty)
-        "--enable-experiment=${argResults.enabledExperiments.join(',')}",
-      ...argResults.arguments,
-    ]);
+    VmInteropHandler.run(
+        sdk.dart2jsSnapshot,
+        [
+          '--libraries-spec=$librariesPath',
+          if (argResults.enabledExperiments.isNotEmpty)
+            "--enable-experiment=${argResults.enabledExperiments.join(',')}",
+          ...argResults.arguments,
+        ],
+        packageConfigOverride: null);
 
     return 0;
   }
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index 3419c75..f6fa451 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -6,6 +6,7 @@
 import 'dart:io' as io;
 
 import 'package:analysis_server_client/protocol.dart' hide AnalysisError;
+import 'package:intl/intl.dart';
 import 'package:path/path.dart' as path;
 
 import '../analysis_server.dart';
@@ -16,33 +17,79 @@
 class FixCommand extends DartdevCommand {
   static const String cmdName = 'fix';
 
-  // This command is hidden as its currently experimental.
-  FixCommand() : super(cmdName, 'Fix Dart source code.', hidden: true) {
+  static final NumberFormat _numberFormat = NumberFormat.decimalPattern();
+
+  static const String cmdDescription = '''Fix Dart source code.
+
+This tool looks for and fixes analysis issues that have associated automated fixes or issues that have associated package API migration information. See dart.dev/go/dart-fix for more information about how automated package API changes work.
+
+To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed changes for a project, or ['dart fix --apply'] to apply the changes.''';
+
+  @override
+  String get description {
+    if (log != null && log.ansi.useAnsi) {
+      return cmdDescription
+          .replaceAll('[', log.ansi.bold)
+          .replaceAll(']', log.ansi.none);
+    } else {
+      return cmdDescription.replaceAll('[', '').replaceAll(']', '');
+    }
+  }
+
+  // This command is hidden as it's currently experimental.
+  FixCommand({bool verbose = false})
+      : super(cmdName, cmdDescription, hidden: true) {
     argParser.addFlag('dry-run',
         abbr: 'n',
         defaultsTo: false,
-        help: 'Show which files would be modified but make no changes.');
+        negatable: false,
+        help: 'Preview the proposed changes but make no changes.');
+    argParser.addFlag(
+      'apply',
+      defaultsTo: false,
+      negatable: false,
+      help: 'Apply the proposed changes.',
+    );
+    argParser.addFlag(
+      'compare-to-golden',
+      defaultsTo: false,
+      negatable: false,
+      help:
+          'Compare the result of applying fixes to a golden file for testing.',
+      hide: !verbose,
+    );
   }
 
   @override
   FutureOr<int> run() async {
-    log.stdout('\n*** The `fix` command is provisional and subject to change '
-        'or removal in future releases. ***\n');
+    log.stdout('\n${log.ansi.emphasized('Note:')} The `fix` command is '
+        'provisional and subject to change or removal in future releases.\n');
 
     var dryRun = argResults['dry-run'];
-    if (argResults.rest.length - (dryRun ? 1 : 0) > 1) {
+    var testMode = argResults['compare-to-golden'];
+    var apply = argResults['apply'];
+    var arguments = argResults.rest;
+    var argumentCount = arguments.length;
+    if (argumentCount > 1) {
       usageException('Only one file or directory is expected.');
     }
 
-    var dir = argResults.rest.isEmpty
-        ? io.Directory.current
-        : io.Directory(argResults.rest.single);
+    if (!apply && !dryRun && !testMode) {
+      printUsage();
+      return 0;
+    }
+
+    var dir =
+        argumentCount == 0 ? io.Directory.current : io.Directory(arguments[0]);
     if (!dir.existsSync()) {
       usageException("Directory doesn't exist: ${dir.path}");
     }
 
+    var modeText = dryRun ? ' (dry run)' : '';
+
+    final projectName = path.basename(path.canonicalize(dir.path));
     var progress = log.progress(
-        'Computing fixes in ${path.basename(path.canonicalize(dir.path))}');
+        'Computing fixes in ${log.ansi.emphasized(projectName)}$modeText');
 
     var server = AnalysisServer(
       io.Directory(sdk.sdkPath),
@@ -67,44 +114,113 @@
 
     progress.finish(showTiming: true);
 
-    if (edits.isEmpty) {
+    if (testMode) {
+      if (_compareFixes(edits)) {
+        return 1;
+      }
+    } else if (edits.isEmpty) {
       log.stdout('Nothing to fix!');
     } else {
+      var details = fixes.details;
+      details.sort((f1, f2) => path
+          .relative(f1.path, from: dir.path)
+          .compareTo(path.relative(f2.path, from: dir.path)));
+
+      var fileCount = 0;
+      var fixCount = 0;
+
+      details.forEach((d) {
+        ++fileCount;
+        d.fixes.forEach((f) {
+          fixCount += f.occurrences;
+        });
+      });
+
       if (dryRun) {
-        log.stdout("Running 'dart fix' without '--dry-run' would apply changes "
-            'in the following files:');
-        var files = <String>{};
-        for (var edit in edits) {
-          var file = edit.file;
-          files.add(path.relative(file, from: dir.path));
-        }
-        var paths = files.toList()..sort();
-        for (var path in paths) {
-          log.stdout(path);
-        }
+        log.stdout('');
+        log.stdout('${_format(fixCount)} proposed ${_pluralFix(fixCount)} '
+            'in ${_format(fileCount)} ${pluralize("file", fileCount)}.');
+        _printDetails(details, dir);
       } else {
         progress = log.progress('Applying fixes');
-        var fileCount = await _applyFixes(edits);
+        _applyFixes(edits);
         progress.finish(showTiming: true);
-        if (fileCount > 0) {
-          log.stdout('Fixed $fileCount ${pluralize("file", fileCount)}.');
-        }
+        _printDetails(details, dir);
+        log.stdout('${_format(fixCount)} ${_pluralFix(fixCount)} made in '
+            '${_format(fileCount)} ${pluralize("file", fileCount)}.');
       }
     }
 
     return 0;
   }
 
-  Future<int> _applyFixes(List<SourceFileEdit> edits) async {
-    var files = <String>{};
+  void _applyFixes(List<SourceFileEdit> edits) {
     for (var edit in edits) {
       var fileName = edit.file;
-      files.add(fileName);
       var file = io.File(fileName);
-      var code = await file.exists() ? await file.readAsString() : '';
+      var code = file.existsSync() ? file.readAsStringSync() : '';
       code = SourceEdit.applySequence(code, edit.edits);
-      await file.writeAsString(code);
+      file.writeAsStringSync(code);
     }
-    return files.length;
   }
+
+  /// Return `true` if any of the fixes fail to create the same content as is
+  /// found in the golden file.
+  bool _compareFixes(List<SourceFileEdit> edits) {
+    var passCount = 0;
+    var failCount = 0;
+    for (var edit in edits) {
+      var filePath = edit.file;
+      var baseName = path.basename(filePath);
+      var expectFileName = baseName + '.expect';
+      var expectFilePath = path.join(path.dirname(filePath), expectFileName);
+      try {
+        var originalCode = io.File(filePath).readAsStringSync();
+        var expectedCode = io.File(expectFilePath).readAsStringSync();
+        var actualCode = SourceEdit.applySequence(originalCode, edit.edits);
+        if (actualCode != expectedCode) {
+          failCount++;
+          _reportFailure(filePath, actualCode, expectedCode);
+        } else {
+          passCount++;
+        }
+      } on io.FileSystemException {
+        // Ignored for now.
+      }
+    }
+    log.stdout('Passed: $passCount, Failed: $failCount');
+    return failCount > 0;
+  }
+
+  String _pluralFix(int count) => count == 1 ? 'fix' : 'fixes';
+
+  void _printDetails(List<BulkFix> details, io.Directory workingDir) {
+    log.stdout('');
+
+    final bullet = log.ansi.bullet;
+
+    for (var detail in details) {
+      log.stdout(path.relative(detail.path, from: workingDir.path));
+      final fixes = detail.fixes.toList();
+      fixes.sort((a, b) => a.code.compareTo(b.code));
+      for (var fix in fixes) {
+        log.stdout('  ${fix.code} $bullet '
+            '${_format(fix.occurrences)} ${_pluralFix(fix.occurrences)}');
+      }
+      log.stdout('');
+    }
+  }
+
+  /// Report that the [actualCode] produced by applying fixes to the content of
+  /// [filePath] did not match the [expectedCode].
+  void _reportFailure(String filePath, String actualCode, String expectedCode) {
+    log.stdout('Failed when applying fixes to $filePath');
+    log.stdout('Expected:');
+    log.stdout(expectedCode);
+    log.stdout('');
+    log.stdout('Actual:');
+    log.stdout(actualCode);
+  }
+
+  static String _format(int value) => _numberFormat.format(value);
 }
diff --git a/pkg/dartdev/lib/src/commands/pub.dart b/pkg/dartdev/lib/src/commands/pub.dart
deleted file mode 100644
index d77dce6..0000000
--- a/pkg/dartdev/lib/src/commands/pub.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:args/args.dart';
-
-import '../core.dart';
-import '../experiments.dart';
-import '../sdk.dart';
-import '../vm_interop_handler.dart';
-
-class PubCommand extends DartdevCommand {
-  static const String cmdName = 'pub';
-
-  PubCommand() : super(cmdName, 'Work with packages.');
-
-  // TODO(jwren) as soon as pub commands are are implemented directly in
-  //  dartdev, remove this static list.
-  /// A list of all subcommands, used only for the implementation of
-  /// [usagePath], see below.
-  static List<String> pubSubcommands = [
-    'cache',
-    'deps',
-    'downgrade',
-    'get',
-    'global',
-    'logout',
-    'outdated',
-    'publish',
-    'run',
-    'upgrade',
-    'uploader',
-    'version',
-  ];
-
-  @override
-  ArgParser createArgParser() => ArgParser.allowAnything();
-
-  @override
-  void printUsage() {
-    // Override [printUsage] for invocations of 'dart help pub' which won't
-    // execute [run] below.  Without this, the 'dart help pub' reports the
-    // command pub with no commands or flags.
-    if (!Sdk.checkArtifactExists(sdk.pubSnapshot)) {
-      return;
-    }
-    final command = sdk.pubSnapshot;
-    final args = ['help'];
-
-    log.trace('$command ${args.first}');
-
-    // Call 'pub help'
-    VmInteropHandler.run(command, args);
-  }
-
-  @override
-  FutureOr<int> run() async {
-    if (!Sdk.checkArtifactExists(sdk.pubSnapshot)) {
-      return 255;
-    }
-    final command = sdk.pubSnapshot;
-    var args = argResults.arguments;
-
-    // Pass any --enable-experiment options along.
-    if (args.isNotEmpty && wereExperimentsSpecified) {
-      List<String> experimentIds = specifiedExperiments;
-
-      if (args.first == 'run') {
-        args = [
-          ...args.sublist(0, 1),
-          '--$experimentFlagName=${experimentIds.join(',')}',
-          ...args.sublist(1),
-        ];
-      } else if (args.length > 1 && args[0] == 'global' && args[0] == 'run') {
-        args = [
-          ...args.sublist(0, 2),
-          '--$experimentFlagName=${experimentIds.join(',')}',
-          ...args.sublist(2),
-        ];
-      }
-    }
-
-    log.trace('$command ${args.join(' ')}');
-    VmInteropHandler.run(command, args);
-    return 0;
-  }
-}
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 8d92c83..80ca891 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -191,18 +191,42 @@
     }
 
     String path;
+    String packagesConfigOverride;
+
     try {
-      path = await getExecutableForCommand(mainCommand);
+      final filename = maybeUriToFilename(mainCommand);
+      if (File(filename).existsSync()) {
+        // TODO(sigurdm): getExecutableForCommand is able to figure this out,
+        // but does not return a package config override.
+        path = filename;
+        packagesConfigOverride = null;
+      } else {
+        path = await getExecutableForCommand(mainCommand);
+        packagesConfigOverride =
+            join(current, '.dart_tool', 'package_config.json');
+      }
     } on CommandResolutionFailedException catch (e) {
       log.stderr(e.message);
       return errorExitCode;
     }
-
-    VmInteropHandler.run(path, runArgs);
+    VmInteropHandler.run(
+      path,
+      runArgs,
+      packageConfigOverride: packagesConfigOverride,
+    );
     return 0;
   }
 }
 
+/// Try parsing [maybeUri] as a file uri or [maybeUri] itself if that fails.
+String maybeUriToFilename(String maybeUri) {
+  try {
+    return Uri.parse(maybeUri).toFilePath();
+  } catch (_) {
+    return maybeUri;
+  }
+}
+
 class _DebuggingSession {
   Future<bool> start(
       String host, String port, bool disableServiceAuthCodes) async {
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index b4fe29c..b5b7c6a 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -5,10 +5,10 @@
 import 'dart:async';
 
 import 'package:args/args.dart';
+import 'package:path/path.dart';
+import 'package:pub/pub.dart';
 
 import '../core.dart';
-import '../experiments.dart';
-import '../sdk.dart';
 import '../vm_interop_handler.dart';
 
 /// Implement `dart test`.
@@ -19,110 +19,40 @@
 
   TestCommand() : super(cmdName, 'Run tests in this package.');
 
+  // This argument parser is here solely to ensure that VM specific flags are
+  // provided before any command and to provide a more consistent help message
+  // with the rest of the tool.
   @override
-  final ArgParser argParser = ArgParser.allowAnything();
-
-  @override
-  void printUsage() {
-    _runImpl(['-h']);
+  ArgParser createArgParser() {
+    return ArgParser.allowAnything();
   }
 
   @override
   FutureOr<int> run() async {
-    return _runImpl(argResults.arguments.toList());
-  }
-
-  int _runImpl(List<String> testArgs) {
-    if (!Sdk.checkArtifactExists(sdk.pubSnapshot)) {
-      return 255;
+    if (argResults.rest.contains('-h') || argResults.rest.contains('--help')) {
+      printUsage();
+      return 0;
     }
-
-    final pubSnapshot = sdk.pubSnapshot;
-
-    bool isHelpCommand = testArgs.contains('--help') || testArgs.contains('-h');
-
-    // Check for no pubspec.yaml file.
     if (!project.hasPubspecFile) {
-      _printNoPubspecMessage(isHelpCommand);
-      return 65;
-    }
-
-    // Handle the case of no .dart_tool/package_config.json file.
-    if (!project.hasPackageConfigFile) {
-      _printRunPubGetInstructions(isHelpCommand);
-      return 65;
-    }
-
-    // "Could not find package "test". Did you forget to add a dependency?"
-    if (!project.packageConfig.hasDependency('test')) {
-      _printMissingDepInstructions(isHelpCommand);
-      return 65;
-    }
-    List<String> enabledExperiments = [];
-    if (!(testArgs.length == 1 && testArgs[0] == '-h')) {
-      enabledExperiments = argResults.enabledExperiments;
-    }
-    final args = [
-      'run',
-      if (enabledExperiments.isNotEmpty)
-        '--$experimentFlagName=${enabledExperiments.join(',')}',
-      'test',
-      ...testArgs,
-    ];
-
-    log.trace('$pubSnapshot ${args.join(' ')}');
-    VmInteropHandler.run(pubSnapshot, args);
-    return 0;
-  }
-
-  void _printNoPubspecMessage(bool wasHelpCommand) {
-    log.stdout('''
+      log.stdout('''
 No pubspec.yaml file found; please run this command from the root of your project.
 ''');
 
-    if (wasHelpCommand) {
-      log.stdout(_terseHelp);
-      log.stdout('');
+      printUsage();
+      return 65;
     }
-
-    log.stdout(_usageHelp);
-  }
-
-  void _printRunPubGetInstructions(bool wasHelpCommand) {
-    log.stdout('''
-No .dart_tool/package_config.json file found, please run 'dart pub get'.
-''');
-
-    if (wasHelpCommand) {
-      log.stdout(_terseHelp);
-      log.stdout('');
+    try {
+      final testExecutable = await getExecutableForCommand('test:test');
+      log.trace('dart $testExecutable ${argResults.rest.join(' ')}');
+      VmInteropHandler.run(testExecutable, argResults.rest,
+          packageConfigOverride:
+              join(current, '.dart_tool', 'package_config.json'));
+      return 0;
+    } on CommandResolutionFailedException catch (e) {
+      print(e.message);
+      print('You need to add a dependency on package:test.');
+      print('Try running `dart pub add test`.');
+      return 65;
     }
-
-    log.stdout(_usageHelp);
-  }
-
-  void _printMissingDepInstructions(bool wasHelpCommand) {
-    final ansi = log.ansi;
-
-    log.stdout('''
-No dependency on package:test found. In order to run tests, you need to add a dependency
-on package:test in your pubspec.yaml file:
-
-${ansi.emphasized('dev_dependencies:\n  test: ^1.0.0')}
-
-See https://pub.dev/packages/test/install for more information on adding package:test,
-and https://dart.dev/guides/testing for general information on testing.
-''');
-
-    if (wasHelpCommand) {
-      log.stdout(_terseHelp);
-      log.stdout('');
-    }
-
-    log.stdout(_usageHelp);
   }
 }
-
-const String _terseHelp = 'Run tests in this package.';
-
-const String _usageHelp = 'Usage: dart test [files or directories...]';
diff --git a/pkg/dartdev/lib/src/events.dart b/pkg/dartdev/lib/src/events.dart
index b2c936a..26e47df 100644
--- a/pkg/dartdev/lib/src/events.dart
+++ b/pkg/dartdev/lib/src/events.dart
@@ -10,9 +10,12 @@
 const String _dartdev = 'dartdev';
 
 /// The collection of custom dimensions understood by the analytics backend.
-/// When adding to this list, first ensure that the custom dimension is
-/// defined in the backend, or will be defined shortly after the relevant PR
-/// lands. The pattern here matches the flutter cli.
+/// When adding to this list, first ensure that the custom dimension is defined
+/// in the backend (or will be defined shortly after the relevant PR lands).
+///
+/// The pattern here matches the flutter cli.
+///
+/// Note: do not re-order the elements in this enum!
 enum _CustomDimensions {
   commandExitCode, // cd1
   enabledExperiments, // cd2
diff --git a/pkg/dartdev/lib/src/utils.dart b/pkg/dartdev/lib/src/utils.dart
index 88b80ed..c168bf4 100644
--- a/pkg/dartdev/lib/src/utils.dart
+++ b/pkg/dartdev/lib/src/utils.dart
@@ -38,33 +38,44 @@
   return s;
 }
 
-/// Static util methods used in dartdev to potentially modify the order of the
-/// arguments passed into dartdev.
-class PubUtils {
-  /// If [doModifyArgs] returns true, then this method returns a modified copy
-  /// of the argument list, 'help' is removed from the interior of the list, and
-  /// '--help' is added to the end of the list of arguments. This method returns
-  /// a modified copy of the list, the list itself is not modified.
-  static List<String> modifyArgs(List<String> args) => List.from(args)
-    ..remove('help')
-    ..add('--help');
-
-  /// If ... help pub ..., and no other verb (such as 'analyze') appears before
-  /// the ... help pub ... in the argument list, then return true.
-  static bool shouldModifyArgs(List<String> args, List<String> allCmds) =>
-      args != null &&
-      allCmds != null &&
-      args.isNotEmpty &&
-      allCmds.isNotEmpty &&
-      args.firstWhere((arg) => allCmds.contains(arg), orElse: () => '') ==
-          'help' &&
-      args.contains('help') &&
-      args.contains('pub') &&
-      args.indexOf('help') + 1 == args.indexOf('pub');
-}
-
 extension FileSystemEntityExtension on FileSystemEntity {
   String get name => p.basename(path);
 
   bool get isDartFile => this is File && p.extension(path) == '.dart';
 }
+
+/// Wraps [text] to the given [width], if provided.
+String wrapText(String text, {int width}) {
+  if (width == null) {
+    return text;
+  }
+
+  var buffer = StringBuffer();
+  var lineMaxEndIndex = width;
+  var lineStartIndex = 0;
+
+  while (true) {
+    if (lineMaxEndIndex >= text.length) {
+      buffer.write(text.substring(lineStartIndex, text.length));
+      break;
+    } else {
+      var lastSpaceIndex = text.lastIndexOf(' ', lineMaxEndIndex);
+      if (lastSpaceIndex == -1 || lastSpaceIndex <= lineStartIndex) {
+        // No space between [lineStartIndex] and [lineMaxEndIndex]. Get the
+        // _next_ space.
+        lastSpaceIndex = text.indexOf(' ', lineMaxEndIndex);
+        if (lastSpaceIndex == -1) {
+          // No space at all after [lineStartIndex].
+          lastSpaceIndex = text.length;
+          buffer.write(text.substring(lineStartIndex, lastSpaceIndex));
+          break;
+        }
+      }
+      buffer.write(text.substring(lineStartIndex, lastSpaceIndex));
+      buffer.writeln();
+      lineStartIndex = lastSpaceIndex + 1;
+    }
+    lineMaxEndIndex = lineStartIndex + width;
+  }
+  return buffer.toString();
+}
diff --git a/pkg/dartdev/lib/src/vm_interop_handler.dart b/pkg/dartdev/lib/src/vm_interop_handler.dart
index fcf419c..6ff7bfa 100644
--- a/pkg/dartdev/lib/src/vm_interop_handler.dart
+++ b/pkg/dartdev/lib/src/vm_interop_handler.dart
@@ -4,6 +4,8 @@
 
 import 'dart:isolate';
 
+import 'package:meta/meta.dart';
+
 /// Contains methods used to communicate DartDev results back to the VM.
 abstract class VmInteropHandler {
   /// Initializes [VmInteropHandler] to utilize [port] to communicate with the
@@ -11,14 +13,22 @@
   static void initialize(SendPort port) => _port = port;
 
   /// Notifies the VM to run [script] with [args] upon DartDev exit.
-  static void run(String script, List<String> args) {
+  ///
+  /// If [packageConfigOverride] is given, that is where the packageConfig is found.
+  static void run(
+    String script,
+    List<String> args, {
+    @required String packageConfigOverride,
+  }) {
     assert(_port != null);
     if (_port == null) return;
-    final message = List<dynamic>.filled(3, null)
-      ..[0] = _kResultRun
-      ..[1] = script
+    final message = <dynamic>[
+      _kResultRun,
+      script,
+      packageConfigOverride,
       // Copy the list so it doesn't get GC'd underneath us.
-      ..[2] = args.toList();
+      args.toList()
+    ];
     _port.send(message);
   }
 
@@ -27,9 +37,7 @@
   static void exit(int exitCode) {
     assert(_port != null);
     if (_port == null) return;
-    final message = List<dynamic>.filled(2, null)
-      ..[0] = _kResultExit
-      ..[1] = exitCode;
+    final message = <dynamic>[_kResultExit, exitCode];
     _port.send(message);
   }
 
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index e5b9295..d6347db 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -15,6 +15,7 @@
   dart2native:
     path: ../dart2native
   dart_style: any
+  intl: any
   meta:
     path: ../meta
   nnbd_migration:
@@ -23,7 +24,7 @@
   pedantic: ^1.9.0
   pub:
     path: ../../third_party/pkg/pub
-  stagehand: 3.3.7
+  stagehand: any
   telemetry:
     path: ../telemetry
   usage: ^3.4.0
diff --git a/pkg/dartdev/test/analytics_test.dart b/pkg/dartdev/test/analytics_test.dart
index 26d9822..8c74972 100644
--- a/pkg/dartdev/test/analytics_test.dart
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -23,7 +23,7 @@
   group('Sending analytics', () {
     test('help', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('help', []);
+      final result = p.runSync(['help']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -51,7 +51,7 @@
     });
     test('create', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('create', ['-tpackage-simple', 'name']);
+      final result = p.runSync(['create', '-tpackage-simple', 'name']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -82,7 +82,7 @@
 
     test('pub get', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('pub', ['get', '--dry-run']);
+      final result = p.runSync(['pub', 'get', '--dry-run']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -113,7 +113,7 @@
 
     test('format', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('format', ['-l80']);
+      final result = p.runSync(['format', '-l80']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -146,7 +146,8 @@
       final p = project(
           mainSrc: 'void main(List<String> args) => print(args)',
           logAnalytics: true);
-      final result = p.runSync('run', [
+      final result = p.runSync([
+        'run',
         '--no-pause-isolates-on-exit',
         '--enable-asserts',
         'lib/main.dart',
@@ -184,7 +185,8 @@
       final p = project(
           mainSrc: 'void main(List<String> args) => print(args);',
           logAnalytics: true);
-      final result = p.runSync('run', [
+      final result = p.runSync([
+        'run',
         '--enable-experiment=non-nullable',
         'lib/main.dart',
       ]);
@@ -221,7 +223,7 @@
           mainSrc: 'void main(List<String> args) => print(args);',
           logAnalytics: true);
       final result = p
-          .runSync('compile', ['kernel', 'lib/main.dart', '-o', 'main.kernel']);
+          .runSync(['compile', 'kernel', 'lib/main.dart', '-o', 'main.kernel']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index 2d88b65..f2d9895 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -2,7 +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:cli_util/cli_logging.dart';
 import 'package:dartdev/src/analysis_server.dart';
+import 'package:dartdev/src/commands/analyze.dart';
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -62,7 +64,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('analyze', ['--help']);
+    var result = p.runSync(['analyze', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -72,7 +74,7 @@
 
   test('multiple directories', () {
     p = project();
-    var result = p.runSync('analyze', ['/no/such/dir1/', '/no/such/dir2/']);
+    var result = p.runSync(['analyze', '/no/such/dir1/', '/no/such/dir2/']);
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
@@ -82,7 +84,7 @@
 
   test('no such directory', () {
     p = project();
-    var result = p.runSync('analyze', ['/no/such/dir1/']);
+    var result = p.runSync(['analyze', '/no/such/dir1/']);
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
@@ -93,7 +95,7 @@
   test('current working directory', () {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = p.runSync('analyze', [], workingDir: p.dirPath);
+    var result = p.runSync(['analyze'], workingDir: p.dirPath);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -102,7 +104,7 @@
 
   test('no errors', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -111,7 +113,7 @@
 
   test('one error', () {
     p = project(mainSrc: "int get foo => 'str';\n");
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
@@ -123,7 +125,7 @@
 
   test('two errors', () {
     p = project(mainSrc: "int get foo => 'str';\nint get bar => 'str';\n");
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
@@ -134,7 +136,7 @@
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync('analyze', ['--fatal-warnings', p.dirPath]);
+    var result = p.runSync(['analyze', '--fatal-warnings', p.dirPath]);
 
     expect(result.exitCode, equals(2));
     expect(result.stderr, isEmpty);
@@ -145,7 +147,7 @@
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, equals(2));
     expect(result.stderr, isEmpty);
@@ -156,7 +158,7 @@
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync('analyze', ['--no-fatal-warnings', p.dirPath]);
+    var result = p.runSync(['analyze', '--no-fatal-warnings', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -165,7 +167,7 @@
 
   test('info implicit no --fatal-infos', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -174,7 +176,7 @@
 
   test('info --fatal-infos', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
-    var result = p.runSync('analyze', ['--fatal-infos', p.dirPath]);
+    var result = p.runSync(['analyze', '--fatal-infos', p.dirPath]);
 
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
@@ -188,7 +190,7 @@
   var one = 1;
   return result;
 }''');
-    var result = p.runSync('analyze', ['--verbose', p.dirPath]);
+    var result = p.runSync(['analyze', '--verbose', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
@@ -201,4 +203,96 @@
         contains(
             'https://dart.dev/tools/diagnostic-messages#referenced_before_declaration'));
   });
+
+  group('display mode', () {
+    final sampleInfoJson = {
+      'severity': 'INFO',
+      'type': 'TODO',
+      'code': 'dead_code',
+      'location': {
+        'file': 'lib/test.dart',
+        'offset': 362,
+        'length': 72,
+        'startLine': 15,
+        'startColumn': 4
+      },
+      'message': 'Foo bar baz.',
+      'hasFix': false,
+    };
+
+    test('default', () {
+      final logger = TestLogger(false);
+      final errors = [AnalysisError(sampleInfoJson)];
+
+      AnalyzeCommand.emitDefaultFormat(logger, errors);
+
+      expect(logger.stderrBuffer, isEmpty);
+      expect(
+        logger.stdoutBuffer.toString().trim(),
+        contains('info - Foo bar baz at lib/test.dart:15:4 - (dead_code)'),
+      );
+    });
+
+    test('machine', () {
+      final logger = TestLogger(false);
+      final errors = [AnalysisError(sampleInfoJson)];
+
+      AnalyzeCommand.emitMachineFormat(logger, errors);
+
+      expect(logger.stderrBuffer, isEmpty);
+      expect(
+        logger.stdoutBuffer.toString().trim(),
+        'INFO|TODO|DEAD_CODE|lib/test.dart|15|4|72|Foo bar baz.',
+      );
+    });
+  });
+}
+
+class TestLogger implements Logger {
+  final stdoutBuffer = StringBuffer();
+
+  final stderrBuffer = StringBuffer();
+
+  @override
+  final bool isVerbose;
+
+  TestLogger(this.isVerbose);
+
+  @override
+  Ansi get ansi => Ansi(false);
+
+  @override
+  void flush() {}
+
+  @override
+  Progress progress(String message) {
+    return SimpleProgress(this, message);
+  }
+
+  @override
+  void stderr(String message) {
+    stderrBuffer.writeln(message);
+  }
+
+  @override
+  void stdout(String message) {
+    stdoutBuffer.writeln(message);
+  }
+
+  @override
+  void trace(String message) {
+    if (isVerbose) {
+      stdoutBuffer.writeln(message);
+    }
+  }
+
+  @override
+  void write(String message) {
+    stdoutBuffer.write(message);
+  }
+
+  @override
+  void writeCharCode(int charCode) {
+    stdoutBuffer.writeCharCode(charCode);
+  }
 }
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index 57e669a..f2f5f31 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -27,8 +27,9 @@
   test('Implicit --help', () {
     final p = project();
     var result = p.runSync(
-      'compile',
-      [],
+      [
+        'compile',
+      ],
     );
     expect(result.stderr, contains('Compile Dart'));
     expect(result.exitCode, compileErrorExitCode);
@@ -37,8 +38,7 @@
   test('--help', () {
     final p = project();
     final result = p.runSync(
-      'compile',
-      ['--help'],
+      ['compile', '--help'],
     );
     expect(result.stdout, contains('Compile Dart'));
     expect(result.exitCode, 0);
@@ -48,8 +48,8 @@
     final p = project(mainSrc: 'void main() { print("I love jit"); }');
     final outFile = path.join(p.dirPath, 'main.jit');
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'jit-snapshot',
         '-o',
         outFile,
@@ -61,7 +61,7 @@
     expect(File(outFile).existsSync(), true,
         reason: 'File not found: $outFile');
 
-    result = p.runSync('run', ['main.jit']);
+    result = p.runSync(['run', 'main.jit']);
     expect(result.stdout, contains('I love jit'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
@@ -73,8 +73,8 @@
     final outFile = path.canonicalize(path.join(p.dirPath, 'lib', 'main.exe'));
 
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'exe',
         inFile,
       ],
@@ -102,8 +102,8 @@
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'exe',
         '--define',
         'life=42',
@@ -134,8 +134,8 @@
     final outFile = path.canonicalize(path.join(p.dirPath, 'main.aot'));
 
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'aot-snapshot',
         '-o',
         'main.aot',
@@ -163,8 +163,8 @@
     final p = project(mainSrc: 'void main() { print("I love kernel"); }');
     final outFile = path.join(p.dirPath, 'main.dill');
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'kernel',
         '-o',
         outFile,
@@ -176,7 +176,7 @@
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
 
-    result = p.runSync('run', ['main.dill']);
+    result = p.runSync(['run', 'main.dill']);
     expect(result.stdout, contains('I love kernel'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
@@ -187,7 +187,8 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'main.js'));
 
-    final result = p.runSync('compile', [
+    final result = p.runSync([
+      'compile',
       'js',
       '-m',
       '-o',
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 38a8ebd..7f5c846 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -36,7 +36,7 @@
   test('list templates', () {
     p = project();
 
-    ProcessResult result = p.runSync('create', ['--list-templates']);
+    ProcessResult result = p.runSync(['create', '--list-templates']);
     expect(result.exitCode, 0);
 
     String output = result.stdout.toString();
@@ -50,7 +50,9 @@
   test('no directory given', () {
     p = project();
 
-    ProcessResult result = p.runSync('create', []);
+    ProcessResult result = p.runSync([
+      'create',
+    ]);
     expect(result.exitCode, 1);
   });
 
@@ -58,7 +60,7 @@
     p = project();
 
     ProcessResult result = p.runSync(
-        'create', ['--template', CreateCommand.defaultTemplateId, p.dir.path]);
+        ['create', '--template', CreateCommand.defaultTemplateId, p.dir.path]);
     expect(result.exitCode, 73);
   });
 
@@ -66,7 +68,7 @@
     p = project();
 
     ProcessResult result =
-        p.runSync('create', ['--no-pub', '--template', 'foo-bar', p.dir.path]);
+        p.runSync(['create', '--no-pub', '--template', 'foo-bar', p.dir.path]);
     expect(result.exitCode, isNot(0));
   });
 
@@ -76,7 +78,7 @@
       p = project();
 
       ProcessResult result = p
-          .runSync('create', ['--force', '--template', templateId, p.dir.path]);
+          .runSync(['create', '--force', '--template', templateId, p.dir.path]);
       expect(result.exitCode, 0);
 
       String projectName = path.basename(p.dir.path);
diff --git a/pkg/dartdev/test/commands/fix_test.dart b/pkg/dartdev/test/commands/fix_test.dart
index 5450742..8a92d7b 100644
--- a/pkg/dartdev/test/commands/fix_test.dart
+++ b/pkg/dartdev/test/commands/fix_test.dart
@@ -4,6 +4,8 @@
 
 import 'dart:io';
 
+import 'package:cli_util/cli_logging.dart';
+import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -12,22 +14,47 @@
   group('fix', defineFix, timeout: longTimeout);
 }
 
+/// Enable to run from local source (useful in development).
+const runFromSource = false;
+
 void defineFix() {
   TestProject p;
 
+  final bullet = Logger.standard().ansi.bullet;
+
   setUp(() => p = null);
 
   tearDown(() => p?.dispose());
 
+  ProcessResult runFix(List<String> args, {String workingDir}) {
+    if (runFromSource) {
+      var binary = path.join(Directory.current.path, 'bin', 'dartdev.dart');
+      return p.runSync([binary, 'fix', ...?args], workingDir: workingDir);
+    }
+    return p.runSync(['fix', ...args], workingDir: workingDir);
+  }
+
   test('none', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('fix', [p.dirPath]);
+
+    var result = runFix([p.dirPath]);
+
+    expect(result.exitCode, 0);
+    expect(result.stderr, isEmpty);
+    expect(result.stdout, contains('Fix Dart source code.'));
+  });
+
+  test('--apply (none)', () {
+    p = project(mainSrc: 'int get foo => 1;\n');
+
+    var result = runFix(['--apply', p.dirPath]);
+
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Nothing to fix!'));
   });
 
-  test('no args', () {
+  test('--apply (no args)', () {
     p = project(
       mainSrc: '''
 var x = "";
@@ -38,34 +65,51 @@
     - prefer_single_quotes
 ''',
     );
-    var result = p.runSync('fix', [], workingDir: p.dirPath);
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('Fixed 1 file.'));
-  });
 
-  test('dry-run', () {
-    p = project(
-      mainSrc: '''
-var x = "";
-''',
-      analysisOptions: '''
-linter:
-  rules:
-    - prefer_single_quotes
-''',
-    );
-    var result = p.runSync('fix', ['--dry-run', '.'], workingDir: p.dirPath);
+    var result = runFix(['--apply'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
         result.stdout,
-        contains("Running 'dart fix' without '--dry-run' "
-            'would apply changes in the following files:'));
-    expect(result.stdout, contains('lib${Platform.pathSeparator}main.dart'));
+        stringContainsInOrder([
+          'Applying fixes...',
+          'lib${Platform.pathSeparator}main.dart',
+          '  prefer_single_quotes $bullet 1 fix',
+        ]));
   });
 
-  test('.', () {
+  test('--dry-run', () {
+    p = project(
+      mainSrc: '''
+class A {
+  String a() => "";
+}
+
+class B extends A {
+  String a() => "";
+}
+''',
+      analysisOptions: '''
+linter:
+  rules:
+    - annotate_overrides
+    - prefer_single_quotes
+''',
+    );
+    var result = runFix(['--dry-run', '.'], workingDir: p.dirPath);
+    expect(result.exitCode, 0);
+    expect(result.stderr, isEmpty);
+    expect(
+        result.stdout,
+        stringContainsInOrder([
+          '3 proposed fixes in 1 file.',
+          'lib${Platform.pathSeparator}main.dart',
+          '  annotate_overrides $bullet 1 fix',
+          '  prefer_single_quotes $bullet 2 fixes',
+        ]));
+  });
+
+  test('--apply (.)', () {
     p = project(
       mainSrc: '''
 var x = "";
@@ -76,13 +120,20 @@
     - prefer_single_quotes
 ''',
     );
-    var result = p.runSync('fix', ['.'], workingDir: p.dirPath);
+    var result = runFix(['--apply', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('Fixed 1 file.'));
+    expect(
+        result.stdout,
+        stringContainsInOrder([
+          'Applying fixes...',
+          'lib${Platform.pathSeparator}main.dart',
+          '  prefer_single_quotes $bullet 1 fix',
+          '1 fix made in 1 file.',
+        ]));
   });
 
-  test('excludes', () {
+  test('--apply (excludes)', () {
     p = project(
       mainSrc: '''
 var x = "";
@@ -96,13 +147,13 @@
     - prefer_single_quotes
 ''',
     );
-    var result = p.runSync('fix', ['.'], workingDir: p.dirPath);
+    var result = runFix(['--apply', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Nothing to fix!'));
   });
 
-  test('ignores', () {
+  test('--apply (ignores)', () {
     p = project(
       mainSrc: '''
 // ignore: prefer_single_quotes
@@ -114,9 +165,76 @@
     - prefer_single_quotes
 ''',
     );
-    var result = p.runSync('fix', ['.'], workingDir: p.dirPath);
+    var result = runFix(['--apply', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Nothing to fix!'));
   });
+
+  group('compare-to-golden', () {
+    test('different', () {
+      p = project(
+        mainSrc: '''
+class A {
+  String a() => "";
+}
+
+class B extends A {
+  String a() => "";
+}
+''',
+        analysisOptions: '''
+linter:
+  rules:
+    - annotate_overrides
+    - prefer_single_quotes
+''',
+      );
+      p.file('lib/main.dart.expect', '''
+class A {
+  String a() => '';
+}
+
+class B extends A {
+  String a() => '';
+}
+''');
+      var result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      expect(result.exitCode, 1);
+      expect(result.stderr, isEmpty);
+    });
+
+    test('same', () {
+      p = project(
+        mainSrc: '''
+class A {
+  String a() => "";
+}
+
+class B extends A {
+  String a() => "";
+}
+''',
+        analysisOptions: '''
+linter:
+  rules:
+    - annotate_overrides
+    - prefer_single_quotes
+''',
+      );
+      p.file('lib/main.dart.expect', '''
+class A {
+  String a() => '';
+}
+
+class B extends A {
+  @override
+  String a() => '';
+}
+''');
+      var result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+    });
+  });
 }
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 6416ffc..0475ee3 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
-import 'package:dartdev/src/analytics.dart' show disabledAnalytics;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -20,7 +19,7 @@
   // For each command description, assert that the values are not empty, don't
   // have trailing white space and end with a period.
   test('description formatting', () {
-    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+    DartdevRunner(['--no-analytics'])
         .commands
         .forEach((String commandKey, Command command) {
       expect(commandKey, isNotEmpty);
@@ -32,7 +31,7 @@
 
   // Assert that all found usageLineLengths are the same and null
   test('argParser usageLineLength', () {
-    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+    DartdevRunner(['--no-analytics'])
         .commands
         .forEach((String commandKey, Command command) {
       if (command.argParser != null) {
@@ -62,7 +61,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('--help', []);
+    var result = p.runSync(['--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -80,7 +79,7 @@
 
   test('--help --verbose', () {
     p = project();
-    var result = p.runSync('--help', ['--verbose']);
+    var result = p.runSync(['--help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, isEmpty);
@@ -90,7 +89,7 @@
 
   test('--help -v', () {
     p = project();
-    var result = p.runSync('--help', ['-v']);
+    var result = p.runSync(['--help', '-v']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, isEmpty);
@@ -100,7 +99,7 @@
 
   test('help', () {
     p = project();
-    var result = p.runSync('help', []);
+    var result = p.runSync(['help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -118,7 +117,7 @@
 
   test('help --verbose', () {
     p = project();
-    var result = p.runSync('help', ['--verbose']);
+    var result = p.runSync(['help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains('migrate '));
@@ -126,7 +125,7 @@
 
   test('help -v', () {
     p = project();
-    var result = p.runSync('help', ['-v']);
+    var result = p.runSync(['help', '-v']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains('migrate '));
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
index cded95b..6f36795 100644
--- a/pkg/dartdev/test/commands/format_test.dart
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -19,7 +19,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('format', ['--help']);
+    var result = p.runSync(['format', '--help']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Idiomatically format Dart source code.'));
@@ -32,7 +32,7 @@
 
   test('--help --verbose', () {
     p = project();
-    var result = p.runSync('format', ['--help', '--verbose']);
+    var result = p.runSync(['format', '--help', '--verbose']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Idiomatically format Dart source code.'));
@@ -45,7 +45,7 @@
 
   test('unchanged', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    ProcessResult result = p.runSync('format', [p.relativeFilePath]);
+    ProcessResult result = p.runSync(['format', p.relativeFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, startsWith('Formatted 1 file (0 changed) in '));
@@ -53,7 +53,7 @@
 
   test('formatted', () {
     p = project(mainSrc: 'int get foo =>       1;\n');
-    ProcessResult result = p.runSync('format', [p.relativeFilePath]);
+    ProcessResult result = p.runSync(['format', p.relativeFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
@@ -65,7 +65,7 @@
   test('unknown file', () {
     p = project(mainSrc: 'int get foo => 1;\n');
     var unknownFilePath = '${p.relativeFilePath}-unknown-file.dart';
-    ProcessResult result = p.runSync('format', [unknownFilePath]);
+    ProcessResult result = p.runSync(['format', unknownFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr,
         startsWith('No file or directory found at "$unknownFilePath".'));
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index c272e43..afbaf09 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
-import 'package:dartdev/src/analytics.dart' show disabledAnalytics;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -22,14 +21,14 @@
   List<String> _commandsNotTested = <String>[
     'help', // `dart help help` is redundant
   ];
-  DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+  DartdevRunner(['--no-analytics'])
       .commands
       .forEach((String commandKey, Command command) {
     if (!_commandsNotTested.contains(commandKey)) {
       test('(help $commandKey == $commandKey --help)', () {
         p = project();
-        var result = p.runSync('help', [commandKey]);
-        var verbHelpResult = p.runSync(commandKey, ['--help']);
+        var result = p.runSync(['help', commandKey]);
+        var verbHelpResult = p.runSync([commandKey, '--help']);
 
         expect(result.stdout, contains(verbHelpResult.stdout));
         expect(result.stderr, contains(verbHelpResult.stderr));
@@ -39,15 +38,15 @@
 
   test('(help pub == pub --help)', () {
     p = project();
-    var result = p.runSync('help', ['pub']);
-    var pubHelpResult = p.runSync('pub', ['--help']);
+    var result = p.runSync(['help', 'pub']);
+    var pubHelpResult = p.runSync(['pub', '--help']);
 
     expect(result.stdout, contains(pubHelpResult.stdout));
     expect(result.stderr, contains(pubHelpResult.stderr));
   });
 
   test('(--help flags also have -h abbr)', () {
-    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+    DartdevRunner(['--no-analytics'])
         .commands
         .forEach((String commandKey, Command command) {
       var helpOption = command.argParser.options['help'];
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 8101640..681d550 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -21,7 +21,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('migrate', ['--help']);
+    var result = p.runSync(['migrate', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -34,7 +34,7 @@
   test('directory implicit', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'int get foo => 1;\n');
     var result =
-        p.runSync('migrate', ['--no-web-preview'], workingDir: p.dirPath);
+        p.runSync(['migrate', '--no-web-preview'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Generating migration suggestions'));
@@ -42,7 +42,7 @@
 
   test('directory explicit', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'int get foo => 1;\n');
-    var result = p.runSync('migrate', ['--no-web-preview', p.dirPath]);
+    var result = p.runSync(['migrate', '--no-web-preview', p.dirPath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Generating migration suggestions'));
@@ -50,7 +50,7 @@
 
   test('bad directory', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('migrate', ['foo_bar_dir']);
+    var result = p.runSync(['migrate', 'foo_bar_dir']);
     expect(result.exitCode, 1);
     expect(result.stderr, contains('foo_bar_dir does not exist'));
     expect(result.stdout, isEmpty);
@@ -58,7 +58,7 @@
 
   test('pub get needs running', () {
     p = project(mainSrc: 'import "package:foo/foo.dart";\n');
-    var result = p.runSync('migrate', [p.dirPath]);
+    var result = p.runSync(['migrate', p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, runPubGet);
@@ -67,7 +67,7 @@
 
   test('non-pub-related error', () {
     p = project(mainSrc: 'var missing = "semicolon"\n');
-    var result = p.runSync('migrate', [p.dirPath]);
+    var result = p.runSync(['migrate', p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, runPubGet);
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index 82f00d0..e164858 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -26,7 +26,7 @@
   }
 
   test('implicit --help', () {
-    final result = project().runSync('pub', []);
+    final result = project().runSync(['pub']);
     expect(result, isNotNull);
     expect(result.exitCode, 64);
     expect(result.stderr, contains('Missing subcommand for "dart pub".'));
@@ -35,17 +35,17 @@
   });
 
   test('--help', () {
-    _assertPubHelpInvoked(project().runSync('pub', ['--help']));
+    _assertPubHelpInvoked(project().runSync(['pub', '--help']));
   });
 
   test('-h', () {
-    _assertPubHelpInvoked(project().runSync('pub', ['-h']));
+    _assertPubHelpInvoked(project().runSync(['pub', '-h']));
   });
 
   test('help cache', () {
     p = project();
-    var result = p.runSync('help', ['pub', 'cache']);
-    var result2 = p.runSync('pub', ['cache', '--help']);
+    var result = p.runSync(['help', 'pub', 'cache']);
+    var result2 = p.runSync(['pub', 'cache', '--help']);
 
     expect(result.exitCode, 0);
 
@@ -58,8 +58,8 @@
 
   test('help publish', () {
     p = project();
-    var result = p.runSync('help', ['pub', 'publish']);
-    var result2 = p.runSync('pub', ['publish', '--help']);
+    var result = p.runSync(['help', 'pub', 'publish']);
+    var result2 = p.runSync(['pub', 'publish', '--help']);
 
     expect(result.exitCode, 0);
 
@@ -77,10 +77,10 @@
         "void main() { int? a; a = null; print('a is \$a.'); }");
 
     // run 'pub get'
-    p.runSync('pub', ['get']);
+    p.runSync(['pub', 'get']);
 
     var result = p.runSync(
-        'pub', ['run', '--enable-experiment=no-non-nullable', 'main.dart']);
+        ['pub', 'run', '--enable-experiment=no-non-nullable', 'main.dart']);
 
     expect(result.exitCode, 254);
     expect(result.stdout, isEmpty);
@@ -93,7 +93,7 @@
 
   test('failure', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('pub', ['deps']);
+    var result = p.runSync(['pub', 'deps']);
     expect(result.exitCode, 65);
     expect(result.stdout, isEmpty);
     expect(result.stderr, contains('No pubspec.lock file found'));
@@ -101,7 +101,7 @@
 
   test('failure unknown option', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('pub', ['deps', '--foo']);
+    var result = p.runSync(['pub', 'deps', '--foo']);
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
     expect(result.stderr, startsWith('Could not find an option named "foo".'));
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index e1b441e..59bffba 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -20,7 +20,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('run', ['--help']);
+    var result = p.runSync(['run', '--help']);
 
     expect(result.stdout, contains('Run a Dart program.'));
     expect(result.stdout, contains('Debugging options:'));
@@ -30,7 +30,7 @@
 
   test("'Hello World'", () {
     p = project(mainSrc: "void main() { print('Hello World'); }");
-    ProcessResult result = p.runSync('run', [p.relativeFilePath]);
+    ProcessResult result = p.runSync(['run', p.relativeFilePath]);
 
     expect(result.stdout, contains('Hello World'));
     expect(result.stderr, isEmpty);
@@ -40,7 +40,7 @@
   test('no such file', () {
     p = project(mainSrc: "void main() { print('Hello World'); }");
     ProcessResult result =
-        p.runSync('run', ['no/such/file/${p.relativeFilePath}']);
+        p.runSync(['run', 'no/such/file/${p.relativeFilePath}']);
 
     expect(result.stderr, isNotEmpty);
     expect(result.exitCode, isNot(0));
@@ -51,7 +51,7 @@
     // name (package name) will be the name of the temporary directory on disk
     p = project(mainSrc: "void main() { print('Hello World'); }");
     p.file('bin/main.dart', "void main() { print('Hello main.dart'); }");
-    ProcessResult result = p.runSync('run', []);
+    ProcessResult result = p.runSync(['run']);
 
     expect(result.stdout, contains('Hello main.dart'));
     expect(result.stderr, isEmpty);
@@ -62,20 +62,21 @@
   test('missing implicit packageName.dart', () {
     p = project(mainSrc: "void main() { print('Hello World'); }");
     p.file('bin/foo.dart', "void main() { print('Hello main.dart'); }");
-    ProcessResult result = p.runSync('run', []);
+    ProcessResult result = p.runSync(['run']);
 
     expect(result.stdout, isEmpty);
     expect(
         result.stderr,
-        contains(
-            'Could not find `bin/dartdev_temp.dart` in package `dartdev_temp`.'));
+        contains('Could not find `bin${path.separator}dartdev_temp.dart` in '
+            'package `dartdev_temp`.'));
     expect(result.exitCode, 255);
   });
 
   test('arguments are properly passed', () {
     p = project();
     p.file('main.dart', 'void main(args) { print(args); }');
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--enable-experiment=triple-shift',
       'main.dart',
       'argument1',
@@ -88,12 +89,46 @@
     expect(result.exitCode, 0);
   });
 
+  test('from path-dependency with cyclic dependency', () {
+    p = project(name: 'foo');
+    final bar = TestProject(name: 'bar');
+    p.file('pubspec.yaml', '''
+name: foo
+environment:
+  sdk: '>=2.9.0<3.0.0'
+
+dependencies: { 'bar': {'path': '${bar.dir.path}'}}
+''');
+    p.file('lib/foo.dart', r'''
+import 'package:bar/bar.dart';
+final b = "FOO $bar";
+''');
+
+    try {
+      bar.file('lib/bar.dart', 'final bar = "BAR";');
+
+      bar.file('bin/main.dart', r'''
+import 'package:foo/foo.dart';
+void main(List<String> args) => print("$b $args");
+''');
+
+      ProcessResult result = p.runSync(['run', 'bar:main', '--arg1', 'arg2']);
+
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('FOO BAR [--arg1, arg2]'));
+      expect(result.exitCode, 0);
+    } finally {
+      bar.dispose();
+    }
+  });
+
   test('with absolute file path', () async {
     p = project();
     p.file('main.dart', 'void main(args) { print(args); }');
     // Test with absolute path
     final name = path.join(p.dirPath, 'main.dart');
-    final result = p.runSync('run', [
+    final result = p.runSync([
+      'run',
       '--enable-experiment=triple-shift',
       name,
       '--argument1',
@@ -101,8 +136,8 @@
     ]);
 
     // --enable-experiment and main.dart should not be passed.
-    expect(result.stdout, equals('[--argument1, argument2]\n'));
     expect(result.stderr, isEmpty);
+    expect(result.stdout, equals('[--argument1, argument2]\n'));
     expect(result.exitCode, 0);
   });
 
@@ -111,15 +146,16 @@
     p.file('main.dart', 'void main(args) { print(args); }');
     // Test with File uri
     final name = path.join(p.dirPath, 'main.dart');
-    final result = p.runSync('run', [
+    final result = p.runSync([
+      'run',
       Uri.file(name).toString(),
       '--argument1',
       'argument2',
     ]);
 
     // --enable-experiment and main.dart should not be passed.
-    expect(result.stdout, equals('[--argument1, argument2]\n'));
     expect(result.stderr, isEmpty);
+    expect(result.stdout, equals('[--argument1, argument2]\n'));
     expect(result.exitCode, 0);
   });
 
@@ -134,7 +170,8 @@
     //
     // This test ensures that allowed arguments for dart run which are valid VM
     // arguments are properly handled by the VM.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--observe',
       '--pause-isolates-on-start',
       // This should negate the above flag.
@@ -153,7 +190,8 @@
     expect(result.exitCode, 0);
 
     // Again, with --disable-service-auth-codes.
-    result = p.runSync('run', [
+    result = p.runSync([
+      'run',
       '--observe',
       '--pause-isolates-on-start',
       // This should negate the above flag.
@@ -178,7 +216,8 @@
 
     // Any VM flags not listed under 'dart run help --verbose' should be passed
     // before a dartdev command.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--vm-name=foo',
       p.relativeFilePath,
     ]);
@@ -196,7 +235,8 @@
 
     // Any VM flags not listed under 'dart run help --verbose' should be passed
     // before a dartdev command.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--verbose_gc',
       p.relativeFilePath,
     ]);
@@ -214,7 +254,8 @@
 
     // Ensure --enable-asserts doesn't cause the dartdev isolate to fail to
     // load. Regression test for: https://github.com/dart-lang/sdk/issues/42831
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--enable-asserts',
       p.relativeFilePath,
     ]);
@@ -228,7 +269,8 @@
     p = project(mainSrc: 'void main() { assert(false); }');
 
     // Any VM flags passed after the script shouldn't be interpreted by the VM.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       p.relativeFilePath,
       '--enable-asserts',
     ]);
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index cf7aea9..00be2bc 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -21,10 +21,7 @@
   test('--help', () {
     p = project();
 
-    var result = p.runSync('pub', ['get']);
-    expect(result.exitCode, 0);
-
-    result = p.runSync('test', ['--help']);
+    final result = p.runSync(['test', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains(' tests in this package'));
@@ -34,10 +31,7 @@
   test('dart help test', () {
     p = project();
 
-    var result = p.runSync('pub', ['get']);
-    expect(result.exitCode, 0);
-
-    result = p.runSync('help', ['test']);
+    final result = p.runSync(['help', 'test']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains(' tests in this package'));
@@ -49,22 +43,30 @@
     var pubspec = File(path.join(p.dirPath, 'pubspec.yaml'));
     pubspec.deleteSync();
 
-    var result = p.runSync('help', ['test']);
+    var result = p.runSync(['test']);
 
-    expect(result.exitCode, 0);
-    expect(result.stdout, contains('No pubspec.yaml file found'));
     expect(result.stderr, isEmpty);
+    expect(result.stdout, contains('No pubspec.yaml file found'));
+    expect(result.exitCode, 65);
   });
 
-  test('no .dart_tool/package_config.json', () {
+  test('runs test', () {
     p = project();
+    p.file('test/foo_test.dart', '''
+import 'package:test/test.dart';
 
-    var result = p.runSync('help', ['test']);
+void main() {
+  test('', () {
+    expect(1,1);
+  });
+}
+''');
 
-    expect(result.exitCode, 0);
-    expect(result.stdout,
-        contains('No .dart_tool/package_config.json file found'));
+    // An implicit `pub get` will happen.
+    final result = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
     expect(result.stderr, isEmpty);
+    expect(result.stdout, contains('All tests passed!'));
+    expect(result.exitCode, 0);
   });
 
   test('no package:test dependency', () {
@@ -74,16 +76,32 @@
 environment:
   sdk: '>=2.10.0 <3.0.0'
 ''');
+    p.file('test/foo_test.dart', '''
+import 'package:test/test.dart';
 
-    var result = p.runSync('pub', ['get']);
-    expect(result.exitCode, 0);
+void main() {
+  test('', () {
+    expect(1,1);
+  });
+}
+''');
 
-    result = p.runSync('test', []);
+    final result = p.runSync(['test']);
     expect(result.exitCode, 65);
     expect(
       result.stdout,
-      contains('In order to run tests, you need to add a dependency'),
+      contains('You need to add a dependency on package:test'),
     );
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 65);
+
+    final resultPubAdd = p.runSync(['pub', 'add', 'test']);
+
+    expect(resultPubAdd.exitCode, 0);
+    final result2 = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
+    expect(result2.stderr, isEmpty);
+    expect(result2.stdout, contains('All tests passed!'));
+    expect(result2.exitCode, 0);
   });
 
   test('has package:test dependency', () {
@@ -100,10 +118,7 @@
 }
 ''');
 
-    var result = p.runSync('pub', ['get']);
-    expect(result.exitCode, 0);
-
-    result = p.runSync('test', ['--no-color', '--reporter', 'expanded']);
+    final result = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
     expect(result.exitCode, 0);
     expect(result.stdout, contains('All tests passed!'));
     expect(result.stderr, isEmpty);
@@ -123,11 +138,15 @@
 }
 ''');
 
-    var result = p.runSync('pub', ['get']);
-    expect(result.exitCode, 0);
-
-    result = p.runSync('--enable-experiment=non-nullable',
-        ['test', '--no-color', '--reporter', 'expanded']);
+    final result = p.runSync(
+      [
+        '--enable-experiment=non-nullable',
+        'test',
+        '--no-color',
+        '--reporter',
+        'expanded',
+      ],
+    );
     expect(result.exitCode, 1);
   });
 }
diff --git a/pkg/dartdev/test/fix_driver_test.dart b/pkg/dartdev/test/fix_driver_test.dart
new file mode 100644
index 0000000..35ec72a
--- /dev/null
+++ b/pkg/dartdev/test/fix_driver_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import '../tool/fix_driver.dart';
+import 'utils.dart';
+
+void main() {
+  group('Driver', _driver);
+}
+
+Future<FixOutput> runFix(List<String> args) async {
+  var runner = FixRunner(logger: CapturingLogger());
+  var result = await runner.runFix(args);
+  return FixOutput(result);
+}
+
+void _driver() {
+  TestProject p;
+  tearDown(() => p?.dispose());
+
+  test('no fixes', () async {
+    p = project(mainSrc: 'int get foo => 1;\n');
+    var result = await runFix(['--apply', p.dirPath]);
+    expect(result.stdout, contains('Nothing to fix!'));
+    expect(result.returnCode, 0);
+  });
+}
+
+class FixOutput {
+  final FixResult<CapturingLogger> result;
+  FixOutput(this.result);
+
+  int get returnCode => result.returnCode;
+  String get stderr => result.logger.output.stderr.toString();
+  String get stdout => result.logger.output.stdout.toString();
+}
diff --git a/pkg/dartdev/test/no_such_file_test.dart b/pkg/dartdev/test/no_such_file_test.dart
new file mode 100644
index 0000000..b5a3452
--- /dev/null
+++ b/pkg/dartdev/test/no_such_file_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+void main() {
+  TestProject p;
+
+  tearDown(() => p?.dispose());
+
+  test('Ensure parsing fails after encountering invalid file', () {
+    // Regression test for https://github.com/dart-lang/sdk/issues/43991
+    p = project();
+    final noArgsResult = p.runSync(['foo.dart']);
+    expect(noArgsResult.stderr, isNotEmpty);
+    expect(noArgsResult.stdout, isEmpty);
+    expect(noArgsResult.exitCode, 64);
+
+    final argsResult = p.runSync(['foo.dart', '--bar']);
+    expect(argsResult.stderr, noArgsResult.stderr);
+    expect(argsResult.stdout, isEmpty);
+    expect(argsResult.exitCode, 64);
+  });
+
+  test('Providing --snapshot VM option with invalid script fails gracefully',
+      () {
+    // Regression test for https://github.com/dart-lang/sdk/issues/43785
+    p = project();
+    final result = p.runSync(['--snapshot=abc', 'foo.dart']);
+    expect(result.stderr, isNotEmpty);
+    expect(result.stderr, contains("Error when reading 'foo.dart':"));
+    expect(result.stdout, isEmpty);
+    expect(result.exitCode, 254);
+  });
+}
diff --git a/pkg/dartdev/test/test_all.dart b/pkg/dartdev/test/test_all.dart
index 291bd05..edd644b 100644
--- a/pkg/dartdev/test/test_all.dart
+++ b/pkg/dartdev/test/test_all.dart
@@ -18,6 +18,8 @@
 import 'commands/test_test.dart' as test;
 import 'core_test.dart' as core;
 import 'experiments_test.dart' as experiments;
+import 'fix_driver_test.dart' as fix_driver;
+import 'no_such_file_test.dart' as no_such_file;
 import 'sdk_test.dart' as sdk;
 import 'smoke/implicit_smoke_test.dart' as implicit_smoke;
 import 'smoke/invalid_smoke_test.dart' as invalid_smoke;
@@ -31,12 +33,14 @@
     create.main();
     experiments.main();
     fix.main();
+    fix_driver.main();
     flag.main();
     format.main();
     help.main();
     implicit_smoke.main();
     invalid_smoke.main();
     migrate.main();
+    no_such_file.main();
     pub.main();
     run.main();
     compile.main();
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index bbc46df..48dcfd7 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -17,20 +17,23 @@
 const String dartVersionFilePrefix2_9 = '// @dart = 2.9\n';
 
 TestProject project(
-        {String mainSrc, String analysisOptions, bool logAnalytics = false}) =>
+        {String mainSrc,
+        String analysisOptions,
+        bool logAnalytics = false,
+        String name = TestProject._defaultProjectName}) =>
     TestProject(
         mainSrc: mainSrc,
         analysisOptions: analysisOptions,
         logAnalytics: logAnalytics);
 
 class TestProject {
-  static String get defaultProjectName => 'dartdev_temp';
+  static const String _defaultProjectName = 'dartdev_temp';
 
   Directory dir;
 
   String get dirPath => dir.path;
 
-  String get name => defaultProjectName;
+  final String name;
 
   String get relativeFilePath => 'lib/main.dart';
 
@@ -39,9 +42,10 @@
   TestProject({
     String mainSrc,
     String analysisOptions,
+    this.name = _defaultProjectName,
     this.logAnalytics = false,
   }) {
-    dir = Directory.systemTemp.createTempSync('dartdev');
+    dir = Directory.systemTemp.createTempSync(name);
     file('pubspec.yaml', '''
 name: $name
 environment:
@@ -71,17 +75,15 @@
   }
 
   ProcessResult runSync(
-    String command,
-    List<String> args, {
+    List<String> arguments, {
     String workingDir,
   }) {
-    var arguments = [
-      command,
-      ...?args,
-    ];
-
-    arguments.add('--disable-dartdev-analytics');
-    return Process.runSync(Platform.resolvedExecutable, arguments,
+    return Process.runSync(
+        Platform.resolvedExecutable,
+        [
+          '--no-analytics',
+          ...arguments,
+        ],
         workingDirectory: workingDir ?? dir.path,
         environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
   }
diff --git a/pkg/dartdev/test/utils_test.dart b/pkg/dartdev/test/utils_test.dart
index 9740dd1..111326b 100644
--- a/pkg/dartdev/test/utils_test.dart
+++ b/pkg/dartdev/test/utils_test.dart
@@ -6,7 +6,7 @@
 import 'dart:io';
 
 import 'package:dartdev/src/utils.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
 void main() {
@@ -32,7 +32,7 @@
 
     test('nested', () {
       var dir = Directory('foo');
-      expect(relativePath(join(dir.absolute.path, 'path'), dir), 'path');
+      expect(relativePath(path.join(dir.absolute.path, 'path'), dir), 'path');
     });
   });
 
@@ -93,44 +93,71 @@
     test('name', () {
       expect(Directory('').name, '');
       expect(Directory('dirName').name, 'dirName');
-      expect(Directory('dirName$separator').name, 'dirName');
+      expect(Directory('dirName${path.separator}').name, 'dirName');
       expect(File('').name, '');
       expect(File('foo.dart').name, 'foo.dart');
-      expect(File('${separator}foo.dart').name, 'foo.dart');
+      expect(File('${path.separator}foo.dart').name, 'foo.dart');
       expect(File('bar.bart').name, 'bar.bart');
     });
   });
 
-  group('PubUtils', () {
-    test('doModifyArgs', () {
-      const allCmds = ['analyze', 'help', 'pub', 'migrate'];
-      expect(PubUtils.shouldModifyArgs(null, null), isFalse);
-      expect(PubUtils.shouldModifyArgs([], null), isFalse);
-      expect(PubUtils.shouldModifyArgs(null, []), isFalse);
-      expect(PubUtils.shouldModifyArgs([], []), isFalse);
-      expect(PubUtils.shouldModifyArgs(['-h'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['--help'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['help'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['pub'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['analyze', 'help', 'pub'], allCmds),
-          isFalse);
-
-      expect(PubUtils.shouldModifyArgs(['--some-flag', 'help', 'pub'], allCmds),
-          isTrue);
-      expect(PubUtils.shouldModifyArgs(['help', 'pub'], allCmds), isTrue);
-      expect(PubUtils.shouldModifyArgs(['help', 'pub', 'publish'], allCmds),
-          isTrue);
-      expect(PubUtils.shouldModifyArgs(['help', 'pub', 'analyze'], allCmds),
-          isTrue);
+  group('wrapText', () {
+    test('oneLine_wordLongerThanLine', () {
+      expect(wrapText('http://long-url', width: 10), equals('http://long-url'));
     });
 
-    test('modifyArgs', () {
-      expect(PubUtils.modifyArgs(['--some-flag', 'help', 'pub']),
-          orderedEquals(['--some-flag', 'pub', '--help']));
-      expect(PubUtils.modifyArgs(['help', 'pub']),
-          orderedEquals(['pub', '--help']));
-      expect(PubUtils.modifyArgs(['help', 'pub', 'publish']),
-          orderedEquals(['pub', 'publish', '--help']));
+    test('singleLine', () {
+      expect(wrapText('one two', width: 10), equals('one two'));
+    });
+
+    test('singleLine_exactLength', () {
+      expect(wrapText('one twoooo', width: 10), equals('one twoooo'));
+    });
+
+    test('singleLine_exactLength_minusOne', () {
+      expect(wrapText('one twooo', width: 10), equals('one twooo'));
+    });
+
+    test('singleLine_exactLength_plusOne', () {
+      expect(wrapText('one twooooo', width: 10), equals('one\ntwooooo'));
+    });
+
+    test('twoLines_exactLength', () {
+      expect(wrapText('one two three four', width: 10),
+          equals('one two\nthree four'));
+    });
+
+    test('twoLines_exactLength_minusOne', () {
+      expect(wrapText('one two three fou', width: 10),
+          equals('one two\nthree fou'));
+    });
+
+    test('twoLines_exactLength_plusOne', () {
+      expect(wrapText('one two three fourr', width: 10),
+          equals('one two\nthree\nfourr'));
+    });
+
+    test('twoLines_lastLineEndsWithSpace', () {
+      expect(wrapText('one two three ', width: 10), equals('one two\nthree '));
+    });
+
+    test('twoLines_multipleSpacesAtSplit', () {
+      expect(
+          wrapText('one two.  Three', width: 10), equals('one two. \nThree'));
+    });
+
+    test('twoLines_noSpaceLastLine', () {
+      expect(wrapText('one two three', width: 10), equals('one two\nthree'));
+    });
+
+    test('twoLines_wordLongerThanLine_firstLine', () {
+      expect(wrapText('http://long-url word', width: 10),
+          equals('http://long-url\nword'));
+    });
+
+    test('twoLines_wordLongerThanLine_lastLine', () {
+      expect(wrapText('word http://long-url', width: 10),
+          equals('word\nhttp://long-url'));
     });
   });
 }
diff --git a/pkg/dartdev/tool/fix_driver.dart b/pkg/dartdev/tool/fix_driver.dart
new file mode 100644
index 0000000..17f246a
--- /dev/null
+++ b/pkg/dartdev/tool/fix_driver.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:args/args.dart';
+import 'package:args/command_runner.dart';
+import 'package:cli_util/cli_logging.dart';
+import 'package:dartdev/src/commands/fix.dart';
+import 'package:dartdev/src/core.dart';
+import 'package:dartdev/src/utils.dart';
+import 'package:meta/meta.dart';
+
+Future<void> main(List<String> args) async {
+  var runner = FixRunner(logger: Logger.standard());
+  var result = await runner.runFix(args);
+  return result.returnCode;
+}
+
+class CapturedProgress extends Progress {
+  final LoggerOutput output;
+
+  bool canceled = false;
+  bool finished = false;
+
+  CapturedProgress(this.output, String message) : super(message) {
+    output.progress.writeln(message);
+  }
+
+  @override
+  void cancel() {
+    canceled = true;
+  }
+
+  @override
+  void finish({String message, bool showTiming = false}) {
+    // todo (pq): consider capturing / tracking finish display updates.
+    finished = true;
+  }
+}
+
+class CapturingLogger implements Logger {
+  final LoggerOutput output = LoggerOutput();
+
+  @override
+  final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
+
+  @override
+  bool isVerbose;
+
+  CapturingLogger({this.isVerbose = false});
+
+  @override
+  void flush() {
+    // deprecated.
+  }
+
+  @override
+  Progress progress(String message) => CapturedProgress(output, message);
+
+  @override
+  void stderr(String message) {
+    output.stderr.writeln(message);
+  }
+
+  @override
+  void stdout(String message) {
+    output.stdout.writeln(message);
+  }
+
+  @override
+  void trace(String message) {
+    output.trace.writeln(message);
+  }
+
+  @override
+  void write(String message) {
+    output.stdout.write(message);
+  }
+
+  @override
+  void writeCharCode(int charCode) {
+    output.stdout.writeCharCode(charCode);
+  }
+}
+
+class FixResult<T extends Logger> {
+  /// The value returned by [FixCommand.run].
+  final int returnCode;
+
+  /// The logger used in driving fixes.
+  final T logger;
+
+  FixResult(this.logger, this.returnCode);
+}
+
+class FixRunner<T extends Logger> extends CommandRunner<int> {
+  final _supportedOptions = ['dry-run', 'apply'];
+
+  T logger;
+
+  @override
+  final ArgParser argParser = ArgParser(
+    usageLineLength: dartdevUsageLineLength,
+    allowTrailingOptions: false,
+  );
+
+  FixRunner({@required this.logger})
+      : super('fix_runner',
+            'A command-line utility for testing the `dart fix` command.') {
+    addCommand(FixCommand());
+    _supportedOptions.forEach(argParser.addOption);
+  }
+
+  @override
+  Future<int> runCommand(ArgResults topLevelResults) async {
+    var result = await super.runCommand(topLevelResults);
+    return result;
+  }
+
+  Future<FixResult<T>> runFix(List<String> args) async {
+    log = logger;
+    var argResults = argParser.parse(['fix', ...?args]);
+    var result = await runCommand(argResults);
+    return FixResult(logger, result);
+  }
+}
+
+class LoggerOutput {
+  /// Messages reported to progress.
+  final StringBuffer progress = StringBuffer();
+
+  /// Messages reported to stdout.
+  final StringBuffer stdout = StringBuffer();
+
+  /// Messages reported to stderr.
+  final StringBuffer stderr = StringBuffer();
+
+  /// Messages reported to trace.
+  final StringBuffer trace = StringBuffer();
+}
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 32be6a6..c88de17 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,15 @@
+# 1.6.1
+- Fixed unhandled `StateError` that could be thrown if the VM service disconnected
+  while a request was outstanding.
+
+# 1.6.0
+- Added `errorCode` to `DartDevelopmentServiceException` to communicate the
+  underlying reason of the failure.
+
+# 1.5.1
+- Improve internal error handling for situations with less than graceful
+  shutdowns.
+
 # 1.5.0
 - Added event caching for `Stdout`, `Stderr`, and `Extension` streams. When a
 client subscribes to one of these streams, they will be sent up to 10,000
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 0f716c6..29cc288 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -159,9 +159,36 @@
 }
 
 class DartDevelopmentServiceException implements Exception {
-  DartDevelopmentServiceException._(this.message);
+  /// Set when `DartDeveloperService.startDartDevelopmentService` is called and
+  /// the target VM service already has a Dart Developer Service instance
+  /// connected.
+  static const int existingDdsInstanceError = 1;
+
+  /// Set when the connection to the remote VM service terminates unexpectedly
+  /// during Dart Development Service startup.
+  static const int failedToStartError = 2;
+
+  /// Set when a connection error has occurred after startup.
+  static const int connectionError = 3;
+
+  factory DartDevelopmentServiceException._existingDdsInstanceError(
+      String message) {
+    return DartDevelopmentServiceException._(existingDdsInstanceError, message);
+  }
+
+  factory DartDevelopmentServiceException._failedToStartError() {
+    return DartDevelopmentServiceException._(
+        failedToStartError, 'Failed to start Dart Development Service');
+  }
+
+  factory DartDevelopmentServiceException._connectionError(String message) {
+    return DartDevelopmentServiceException._(connectionError, message);
+  }
+
+  DartDevelopmentServiceException._(this.errorCode, this.message);
 
   String toString() => 'DartDevelopmentServiceException: $message';
 
+  final int errorCode;
   final String message;
 }
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 2c85aae..9637058 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -240,8 +240,14 @@
 
     // Unless otherwise specified, the request is forwarded to the VM service.
     // NOTE: This must be the last fallback registered.
-    _clientPeer.registerFallback((parameters) async =>
-        await _vmServicePeer.sendRequest(parameters.method, parameters.value));
+    _clientPeer.registerFallback((parameters) async {
+      try {
+        return await _vmServicePeer.sendRequest(
+            parameters.method, parameters.value);
+      } on StateError {
+        await dds.shutdown();
+      }
+    });
   }
 
   static int _idCounter = 0;
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index d2a6dcb..ad0e46f 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -4,6 +4,27 @@
 
 part of dds;
 
+@visibleForTesting
+typedef PeerBuilder = Future<json_rpc.Peer> Function(WebSocketChannel, dynamic);
+
+@visibleForTesting
+typedef WebSocketBuilder = WebSocketChannel Function(Uri);
+
+@visibleForTesting
+PeerBuilder peerBuilder = _defaultPeerBuilder;
+
+@visibleForTesting
+WebSocketBuilder webSocketBuilder = _defaultWebSocketBuilder;
+
+Future<json_rpc.Peer> _defaultPeerBuilder(
+    WebSocketChannel ws, dynamic streamManager) async {
+  return _BinaryCompatiblePeer(ws, streamManager);
+}
+
+WebSocketChannel _defaultWebSocketBuilder(Uri uri) {
+  return WebSocketChannel.connect(uri.replace(scheme: 'ws'));
+}
+
 class _DartDevelopmentService implements DartDevelopmentService {
   _DartDevelopmentService(
       this._remoteVmServiceUri, this._uri, this._authCodesEnabled, this._ipv6) {
@@ -19,8 +40,8 @@
     final completer = Completer<void>();
     // TODO(bkonyi): throw if we've already shutdown.
     // Establish the connection to the VM service.
-    _vmServiceSocket = WebSocketChannel.connect(remoteVmServiceWsUri);
-    _vmServiceClient = _BinaryCompatiblePeer(_vmServiceSocket, _streamManager);
+    _vmServiceSocket = webSocketBuilder(remoteVmServiceWsUri);
+    _vmServiceClient = await peerBuilder(_vmServiceSocket, _streamManager);
     // Setup the JSON RPC client with the VM service.
     unawaited(
       _vmServiceClient.listen().then(
@@ -28,20 +49,21 @@
           shutdown();
           if (!started && !completer.isCompleted) {
             completer.completeError(
-              DartDevelopmentServiceException._(
-                'Failed to start Dart Development Service',
-              ),
-            );
+                DartDevelopmentServiceException._failedToStartError());
           }
         },
         onError: (e, st) {
           shutdown();
           if (!completer.isCompleted) {
-            completer.completeError(e, st);
+            completer.completeError(
+              DartDevelopmentServiceException._connectionError(e.toString()),
+              st,
+            );
           }
         },
       ),
     );
+
     try {
       // Setup stream event handling.
       await streamManager.listen();
@@ -93,7 +115,9 @@
     } on json_rpc.RpcException catch (e) {
       await _server.close(force: true);
       // _yieldControlToDDS fails if DDS is not the only VM service client.
-      throw DartDevelopmentServiceException._(e.data['details']);
+      throw DartDevelopmentServiceException._existingDdsInstanceError(
+        e.data != null ? e.data['details'] : e.toString(),
+      );
     }
 
     _uri = tmpUri;
@@ -113,7 +137,7 @@
     await clientManager.shutdown();
 
     // Close connection to VM service.
-    await _vmServiceSocket.sink.close();
+    await _vmServiceSocket?.sink?.close();
 
     _done.complete();
   }
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 542fe91..20be940 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -208,9 +208,7 @@
         (_) => null,
         // Ignore 'stream not subscribed' errors and StateErrors which arise
         // when DDS is shutting down.
-        test: (e) =>
-            (e is json_rpc.RpcException) ||
-            (dds._shuttingDown && e is StateError),
+        test: (e) => (e is json_rpc.RpcException) || (e is StateError),
       );
     }
     // Notify other service clients of service extensions that are being
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index d2fdbdb..d0e85c6 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 1.5.0
+version: 1.6.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
@@ -25,5 +25,5 @@
 dev_dependencies:
   shelf_static: ^0.2.8
   test: ^1.0.0
-  vm_service: ^4.0.0
+  vm_service: ^5.0.0
   webdriver: ^2.1.2
diff --git a/pkg/dds/test/common/fakes.dart b/pkg/dds/test/common/fakes.dart
new file mode 100644
index 0000000..7e11f9d
--- /dev/null
+++ b/pkg/dds/test/common/fakes.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
+import 'package:test/fake.dart';
+import 'package:vm_service/vm_service.dart';
+
+/// [FakePeer] implements the bare minimum of the [Peer] interface needed for
+/// [DartDevelopmentService] to establish a connection with a VM service.
+///
+/// `sendRequest` can be overridden to provide custom handling for VM service
+/// RPCs and custom RPCs to control the state of the [FakePeer] instance from a
+/// VM service client request routed through a [DartDevelopmentService] instance.
+class FakePeer extends Fake implements json_rpc.Peer {
+  @override
+  Future<void> get done => doneCompleter.future;
+  final Completer<void> doneCompleter = Completer<void>();
+
+  bool get isClosed => doneCompleter.isCompleted;
+
+  @override
+  Future<void> listen() {
+    return done;
+  }
+
+  @override
+  void registerMethod(String name, Function callback) {}
+
+  @override
+  Future<dynamic> sendRequest(String method, [args]) async {
+    switch (method) {
+      case 'getVM':
+        return _buildResponse(VM(
+          name: 'Test',
+          architectureBits: 0,
+          hostCPU: '',
+          operatingSystem: '',
+          targetCPU: '',
+          version: '',
+          pid: 0,
+          startTime: 0,
+          isolates: [],
+          isolateGroups: [],
+          systemIsolateGroups: [],
+          systemIsolates: [],
+        ));
+      default:
+        return _buildResponse(Success());
+    }
+  }
+
+  Map<String, dynamic> _buildResponse(dynamic serviceObject) {
+    return {
+      'json_rpc': '2.0',
+      'id': _idCount++,
+      ...serviceObject.toJson(),
+    };
+  }
+
+  int _idCount = 0;
+}
diff --git a/pkg/dds/test/handles_client_disconnect_state_error_test.dart b/pkg/dds/test/handles_client_disconnect_state_error_test.dart
new file mode 100644
index 0000000..f500711
--- /dev/null
+++ b/pkg/dds/test/handles_client_disconnect_state_error_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:dds/dds.dart';
+import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
+import 'package:pedantic/pedantic.dart';
+import 'package:test/test.dart';
+import 'package:web_socket_channel/web_socket_channel.dart';
+
+import 'common/fakes.dart';
+
+class StreamCancelDisconnectPeer extends FakePeer {
+  @override
+  Future<dynamic> sendRequest(String method, [args]) async {
+    final completer = Completer<dynamic>();
+    switch (method) {
+      case 'streamCancel':
+        completer.completeError(
+          StateError('The client closed with pending request "streamCancel".'),
+        );
+        // Notify listeners that this client is closed.
+        doneCompleter.complete();
+        break;
+      case 'foo':
+        completer.completeError(
+          StateError('The client closed with pending request "foo".'),
+        );
+        break;
+      default:
+        completer.complete(await super.sendRequest(method, args));
+    }
+    return completer.future;
+  }
+}
+
+void main() {
+  webSocketBuilder = (Uri _) => null;
+  peerBuilder =
+      (WebSocketChannel _, dynamic __) async => StreamCancelDisconnectPeer();
+
+  test('StateError handled by _StreamManager.clientDisconnect', () async {
+    final dds = await DartDevelopmentService.startDartDevelopmentService(
+        Uri(scheme: 'http'));
+    final ws = await WebSocketChannel.connect(dds.uri.replace(scheme: 'ws'));
+
+    // Create a VM service client that connects to DDS.
+    final client = json_rpc.Client(ws.cast<String>());
+    unawaited(client.listen());
+
+    // Listen to a non-core DDS stream so that DDS will cancel it once the
+    // client disconnects.
+    await client.sendRequest('streamListen', {
+      'streamId': 'Service',
+    });
+
+    // Closing the client should result in DDS cleaning up stream subscriptions
+    // with no more clients subscribed to them. This will result in
+    // streamCancel being invoked, which StreamCancelDisconnectPeer overrides
+    // to act as if the VM service has shutdown with the request in flight
+    // which would result in a StateError being thrown by sendRequest. This
+    // test ensures that this exception is handled and doesn't escape outside
+    // of DDS.
+    await client.close();
+    await dds.done;
+  });
+
+  test('StateError handled by _DartDevelopmentServiceClient request forwarder',
+      () async {
+    final dds = await DartDevelopmentService.startDartDevelopmentService(
+        Uri(scheme: 'http'));
+    final ws = await WebSocketChannel.connect(dds.uri.replace(scheme: 'ws'));
+
+    // Create a VM service client that connects to DDS.
+    final client = json_rpc.Client(ws.cast<String>());
+    unawaited(client.listen());
+
+    // Make a request that causes the VM service peer to close in the middle of
+    // handling a request. This is meant to mimic a device being disconnected
+    // unexpectedly.
+    try {
+      await client.sendRequest('foo');
+    } on StateError {
+      // This state error is expected. This test is ensuring that DDS exits
+      // gracefully even if the VM service disappears.
+    }
+
+    // DDS should shutdown if the VM service peer disconnects.
+    await dds.done;
+  });
+}
diff --git a/pkg/dds/test/handles_connection_closed_before_full_header.dart b/pkg/dds/test/handles_connection_closed_before_full_header.dart
new file mode 100644
index 0000000..80f1744
--- /dev/null
+++ b/pkg/dds/test/handles_connection_closed_before_full_header.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:dds/dds.dart';
+import 'package:test/test.dart';
+
+/// Simple socket server which immediately closes the first connection and
+/// shuts down. This causes the HTTP request to the server to fail with a
+/// WebSocketChannelException: connection closed before full header was
+/// received failure, which should be caught and surfaced in a
+/// [DartDevelopmentServiceException].
+Future<Uri> startTestServer() async {
+  final server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
+  server.listen((Socket request) async {
+    await request.destroy();
+    await server.close();
+  });
+  return Uri(scheme: 'http', host: server.address.host, port: server.port);
+}
+
+/// Reproduction case for https://github.com/flutter/flutter/issues/69433
+void main() async {
+  test('Handle connection closed before full header received', () async {
+    final uri = await startTestServer();
+    try {
+      await DartDevelopmentService.startDartDevelopmentService(uri);
+      fail('Unexpected successful connection.');
+    } on DartDevelopmentServiceException catch (e) {
+      expect(e.errorCode, DartDevelopmentServiceException.connectionError);
+      expect(e.toString().contains('WebSocketChannelException'), true);
+    }
+  });
+}
diff --git a/pkg/dds/test/smoke_test.dart b/pkg/dds/test/smoke_test.dart
index 0a7347c..d317893 100644
--- a/pkg/dds/test/smoke_test.dart
+++ b/pkg/dds/test/smoke_test.dart
@@ -107,6 +107,8 @@
       } on DartDevelopmentServiceException catch (e) {
         expect(e.message,
             'Existing VM service clients prevent DDS from taking control.');
+        expect(e.errorCode,
+            DartDevelopmentServiceException.existingDdsInstanceError);
       }
     });
   });
diff --git a/pkg/dds/test/web/sse_smoke_driver.dart.js b/pkg/dds/test/web/sse_smoke_driver.dart.js
index 1fc9758..bab6993 100644
--- a/pkg/dds/test/web/sse_smoke_driver.dart.js
+++ b/pkg/dds/test/web/sse_smoke_driver.dart.js
@@ -4479,7 +4479,7 @@
     },
     Iterator: function Iterator() {
     },
-    List: function List() {
+    List: function [] {
     },
     Map: function Map() {
     },
diff --git a/pkg/dev_compiler/lib/src/compiler/module_containers.dart b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
new file mode 100644
index 0000000..6c76688
--- /dev/null
+++ b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
@@ -0,0 +1,259 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import '../compiler/js_names.dart' as js_ast;
+import '../js_ast/js_ast.dart' as js_ast;
+import '../js_ast/js_ast.dart' show js;
+
+/// Represents a top-level property hoisted to a top-level object.
+class ModuleItemData {
+  /// The container that holds this module item in the emitted JS.
+  js_ast.Identifier id;
+
+  /// This module item's key in the emitted JS.
+  ///
+  /// A LiteralString if this object is backed by a JS Object/Map.
+  /// A LiteralNumber if this object is backed by a JS Array.
+  js_ast.Literal jsKey;
+
+  /// This module item's value in the emitted JS.
+  js_ast.Expression jsValue;
+
+  ModuleItemData(this.id, this.jsKey, this.jsValue);
+}
+
+/// Holds variables emitted during code gen.
+///
+/// Associates a [K] with a container-unique JS key and arbitrary JS value.
+/// The container is emitted as a single object:
+/// ```
+/// var C = {
+///   jsKey: jsValue,
+///   ...
+/// };
+/// ```
+class ModuleItemContainer<K> {
+  /// Name of the container in the emitted JS.
+  String name;
+
+  /// If null, this container will be automatically renamed based on [name].
+  js_ast.Identifier containerId;
+
+  final Map<K, ModuleItemData> moduleItems = {};
+
+  /// Holds keys that will not be emitted when calling [emit].
+  final Set<K> _noEmit = {};
+
+  ModuleItemContainer._(this.name, this.containerId);
+
+  /// Creates an automatically sharding container backed by JS Objects.
+  factory ModuleItemContainer.asObject(String name,
+      {String Function(K) keyToString}) {
+    return ModuleItemObjectContainer<K>(name, keyToString);
+  }
+
+  /// Creates a container backed by a JS Array.
+  factory ModuleItemContainer.asArray(String name) {
+    return ModuleItemArrayContainer<K>(name);
+  }
+
+  bool get isNotEmpty => moduleItems.isNotEmpty;
+
+  Iterable<K> get keys => moduleItems.keys;
+
+  int get length => moduleItems.keys.length;
+
+  js_ast.Expression operator [](K key) => moduleItems[key]?.jsValue;
+
+  void operator []=(K key, js_ast.Expression value) {
+    if (moduleItems.containsKey(key)) {
+      moduleItems[key].jsValue = value;
+      return;
+    }
+    var fieldString = '$key';
+    // Avoid shadowing common JS properties.
+    if (js_ast.objectProperties.contains(fieldString)) {
+      fieldString += '\$';
+    }
+    moduleItems[key] = ModuleItemData(
+        containerId, js_ast.LiteralString("'$fieldString'"), value);
+  }
+
+  /// Returns the expression that retrieves [key]'s corresponding JS value via
+  /// a property access through its container.
+  js_ast.Expression access(K key) {
+    return js.call('#.#', [containerId, moduleItems[key].jsKey]);
+  }
+
+  /// Emit the container declaration/initializer.
+  ///
+  /// May be multiple statements if the container is automatically sharded.
+  List<js_ast.Statement> emit() {
+    var properties = <js_ast.Property>[];
+    moduleItems.forEach((k, v) {
+      if (!_noEmit.contains(k)) return;
+      properties.add(js_ast.Property(v.jsKey, v.jsValue));
+    });
+    var containerObject =
+        js_ast.ObjectInitializer(properties, multiline: properties.length > 1);
+    return [
+      js.statement('var # = Object.create(#)', [containerId, containerObject])
+    ];
+  }
+
+  bool contains(K key) => moduleItems.containsKey(key);
+
+  bool canEmit(K key) => !_noEmit.contains(key);
+
+  /// Indicates that [K] should be treated as if it weren't hoisted.
+  ///
+  /// Used when we are managing the variable declarations manually (such as
+  /// unhoisting specific symbols for performance reasons).
+  void setNoEmit(K key) {
+    _noEmit.add(key);
+  }
+}
+
+/// Associates a [K] with a container-unique JS key and arbitrary JS value.
+///
+/// Emitted as a series of JS Objects, splitting them into groups of 500 for
+/// JS optimization purposes:
+/// ```
+/// var C = {
+///   jsKey: jsValue,
+///   ...
+/// };
+/// var C$1 = { ... };
+/// ```
+class ModuleItemObjectContainer<K> extends ModuleItemContainer<K> {
+  /// Holds the TemporaryId for the current container shard.
+  js_ast.Identifier _currentContainerId;
+
+  /// Tracks how often JS emitted field names appear.
+  ///
+  /// [keyToString] may resolve multiple unique keys to the same JS string.
+  /// When this occurs, the resolved JS string will automatically be renamed.
+  final Map<String, int> _nameFrequencies = {};
+
+  /// Transforms a [K] into a valid name for a JS object property key.
+  ///
+  /// Non-unique generated strings are automatically renamed.
+  String Function(K) keyToString;
+
+  ModuleItemObjectContainer(String name, this.keyToString)
+      : super._(name, null);
+
+  @override
+  void operator []=(K key, js_ast.Expression value) {
+    if (this.contains(key)) {
+      moduleItems[key].jsValue = value;
+      return;
+    }
+    if (length % 500 == 0) _currentContainerId = js_ast.TemporaryId(name);
+    // Create a unique name for K when emitted as a JS field.
+    var fieldString = keyToString(key);
+    _nameFrequencies.update(fieldString, (v) {
+      fieldString += '\$${v + 1}';
+      return v + 1;
+    }, ifAbsent: () {
+      // Avoid shadowing common JS properties.
+      if (js_ast.objectProperties.contains(fieldString)) {
+        fieldString += '\$';
+      }
+      return 0;
+    });
+    moduleItems[key] = ModuleItemData(
+        _currentContainerId, js_ast.LiteralString("'$fieldString'"), value);
+  }
+
+  @override
+  js_ast.Expression access(K key) {
+    return js.call('#.#', [moduleItems[key].id, moduleItems[key].jsKey]);
+  }
+
+  @override
+  List<js_ast.Statement> emit() {
+    var containersToProperties = <js_ast.Identifier, List<js_ast.Property>>{};
+    moduleItems.forEach((k, v) {
+      if (_noEmit.contains(k)) return;
+      if (!containersToProperties.containsKey(v.id)) {
+        containersToProperties[v.id] = <js_ast.Property>[];
+      }
+      containersToProperties[v.id].add(js_ast.Property(v.jsKey, v.jsValue));
+    });
+
+    var statements = <js_ast.Statement>[];
+    containersToProperties.forEach((containerId, properties) {
+      var containerObject = js_ast.ObjectInitializer(properties,
+          multiline: properties.length > 1);
+      statements.add(js.statement(
+          'var # = Object.create(#)', [containerId, containerObject]));
+    });
+    return statements;
+  }
+}
+
+/// Associates a unique [K] with an arbitrary JS value.
+///
+/// Emitted as a JS Array:
+/// ```
+/// var C = [
+///   jsValue,
+///   ...
+/// ];
+/// ```
+class ModuleItemArrayContainer<K> extends ModuleItemContainer<K> {
+  ModuleItemArrayContainer(String name)
+      : super._(name, js_ast.TemporaryId(name));
+
+  @override
+  void operator []=(K key, js_ast.Expression value) {
+    if (moduleItems.containsKey(key)) {
+      moduleItems[key].jsValue = value;
+      return;
+    }
+    moduleItems[key] =
+        ModuleItemData(containerId, js_ast.LiteralNumber('$length'), value);
+  }
+
+  @override
+  js_ast.Expression access(K key) {
+    return js.call('#[#]', [containerId, moduleItems[key].jsKey]);
+  }
+
+  @override
+  List<js_ast.Statement> emit() {
+    if (moduleItems.isEmpty) return [];
+    var properties = List<js_ast.Expression>.filled(length, null);
+
+    // If the entire array holds just one value, generate a short initializer.
+    var valueSet = <js_ast.Expression>{};
+    moduleItems.forEach((k, v) {
+      if (_noEmit.contains(k)) return;
+      valueSet.add(v.jsValue);
+      properties[int.parse((v.jsKey as js_ast.LiteralNumber).value)] =
+          v.jsValue;
+    });
+
+    if (valueSet.length == 1 && moduleItems.length > 1) {
+      return [
+        js.statement('var # = Array(#).fill(#)', [
+          containerId,
+          js_ast.LiteralNumber('${properties.length}'),
+          valueSet.first
+        ])
+      ];
+    }
+    // Array containers are not sharded, as we do not expect to hit V8's
+    // dictionary-mode limit of 99999 elements.
+    return [
+      js.statement('var # = #', [
+        containerId,
+        js_ast.ArrayInitializer(properties, multiline: properties.length > 1)
+      ])
+    ];
+  }
+}
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 0269dd30..2fcad3e 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -8,6 +8,7 @@
 import 'package:meta/meta.dart';
 
 import '../compiler/js_names.dart' as js_ast;
+import '../compiler/module_containers.dart' show ModuleItemContainer;
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 
@@ -25,6 +26,10 @@
   /// Private member names in this module, organized by their library.
   final _privateNames = HashMap<Library, HashMap<String, js_ast.TemporaryId>>();
 
+  /// Holds all top-level JS symbols (used for caching or indexing fields).
+  final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject('S',
+      keyToString: (js_ast.Identifier i) => '${i.name}');
+
   /// Extension member symbols for adding Dart members to JS types.
   ///
   /// These are added to the [extensionSymbolsModule]; see that field for more
@@ -51,11 +56,18 @@
   /// Whether we're currently building the SDK, which may require special
   /// bootstrapping logic.
   ///
-  /// This is initialized by [startModule], which must be called before
+  /// This is initialized by [emitModule], which must be called before
   /// accessing this field.
   @protected
   bool isBuildingSdk;
 
+  /// Whether or not to move top level symbols into top-level containers.
+  ///
+  /// This is set in both [emitModule] and [emitLibrary].
+  /// Depends on [isBuildingSdk].
+  @protected
+  bool containerizeSymbols;
+
   /// The temporary variable that stores named arguments (these are passed via a
   /// JS object literal, to match JS conventions).
   @protected
@@ -250,10 +262,16 @@
       var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
       idName = idName.replaceAll(js_ast.invalidCharInIdentifier, '_');
       id ??= js_ast.TemporaryId(idName);
-      // TODO(vsm): Change back to `const`.
-      // See https://github.com/dart-lang/sdk/issues/40380.
-      moduleItems.add(js.statement('var # = #.privateName(#, #)',
-          [id, runtimeModule, emitLibraryName(library), js.string(name)]));
+      addSymbol(
+          id,
+          js.call('#.privateName(#, #)',
+              [runtimeModule, emitLibraryName(library), js.string(name)]));
+      if (!containerizeSymbols) {
+        // TODO(vsm): Change back to `const`.
+        // See https://github.com/dart-lang/sdk/issues/40380.
+        moduleItems.add(js.statement('var # = #.privateName(#, #)',
+            [id, runtimeModule, emitLibraryName(library), js.string(name)]));
+      }
       return id;
     }
 
@@ -338,9 +356,13 @@
     var name = js.escapedString(symbolName, "'");
     js_ast.Expression result;
     if (last.startsWith('_')) {
-      var nativeSymbol = emitPrivateNameSymbol(currentLibrary, last);
-      result = js.call('new #.new(#, #)',
-          [emitConstructorAccess(privateSymbolType), name, nativeSymbol]);
+      var nativeSymbolAccessor =
+          getSymbol(emitPrivateNameSymbol(currentLibrary, last));
+      result = js.call('new #.new(#, #)', [
+        emitConstructorAccess(privateSymbolType),
+        name,
+        nativeSymbolAccessor
+      ]);
     } else {
       result = js.call(
           'new #.new(#)', [emitConstructorAccess(internalSymbolType), name]);
@@ -366,12 +388,11 @@
   /// symbols into the list returned by this method. Finally, [finishModule]
   /// can be called to complete the module and return the resulting JS AST.
   ///
-  /// This also initializes several fields: [isBuildingSdk], [runtimeModule],
-  /// [extensionSymbolsModule], as well as the [_libraries] map needed by
+  /// This also initializes several fields: [runtimeModule],
+  /// [extensionSymbolsModule], and the [_libraries] map needed by
   /// [emitLibraryName].
   @protected
   List<js_ast.ModuleItem> startModule(Iterable<Library> libraries) {
-    isBuildingSdk = libraries.any(isSdkInternalRuntime);
     if (isBuildingSdk) {
       // Don't allow these to be renamed when we're building the SDK.
       // There is JS code in dart:* that depends on their names.
@@ -447,7 +468,6 @@
   }
 
   /// Returns the canonical name to refer to the Dart library.
-  @protected
   js_ast.Identifier emitLibraryName(Library library) {
     // Avoid adding the dart:_runtime to _imports when our runtime unit tests
     // import it explicitly. It will always be implicitly imported.
@@ -506,9 +526,13 @@
       if (isBuildingSdk) {
         value = js.call('# = Symbol(#)', [value, js.string('dartx.$name')]);
       }
-      // TODO(vsm): Change back to `const`.
-      // See https://github.com/dart-lang/sdk/issues/40380.
-      items.add(js.statement('var # = #;', [id, value]));
+      if (!_symbolContainer.canEmit(id)) {
+        // Extension symbols marked with noEmit are managed manually.
+        // TODO(vsm): Change back to `const`.
+        // See https://github.com/dart-lang/sdk/issues/40380.
+        items.add(js.statement('var # = #;', [id, value]));
+      }
+      _symbolContainer[id] = value;
     });
   }
 
@@ -535,6 +559,28 @@
         [runtimeModule, js.string(name), module, partMap]));
   }
 
+  /// Returns an accessor for [id] via the symbol container.
+  /// E.g., transforms $sym to S$5.$sym.
+  ///
+  /// A symbol lookup on an id marked no emit omits the symbol accessor.
+  js_ast.Expression getSymbol(js_ast.Identifier id) {
+    return _symbolContainer.canEmit(id) ? _symbolContainer.access(id) : id;
+  }
+
+  /// Returns the raw JS value associated with [id].
+  js_ast.Expression getSymbolValue(js_ast.Identifier id) {
+    return _symbolContainer[id];
+  }
+
+  /// Inserts a symbol into the symbol table.
+  js_ast.Expression addSymbol(js_ast.Identifier id, js_ast.Expression symbol) {
+    _symbolContainer[id] = symbol;
+    if (!containerizeSymbols) {
+      _symbolContainer.setNoEmit(id);
+    }
+    return _symbolContainer[id];
+  }
+
   /// Finishes the module created by [startModule], by combining the preable
   /// [items] with the [moduleItems] that have been emitted.
   ///
@@ -553,6 +599,9 @@
     // code between `startModule` and `finishModule` is very similar in both.
     _emitDebuggerExtensionInfo(moduleName);
 
+    // Emit all top-level JS symbol containers.
+    items.addAll(_symbolContainer.emit());
+
     // Add the module's code (produced by visiting compilation units, above)
     _copyAndFlattenBlocks(items, moduleItems);
     moduleItems.clear();
@@ -583,10 +632,13 @@
   /// handle the many details involved in naming.
   @protected
   js_ast.TemporaryId getExtensionSymbolInternal(String name) {
-    return _extensionSymbols.putIfAbsent(
-        name,
-        () => js_ast.TemporaryId(
-            '\$${js_ast.friendlyNameForDartOperator[name] ?? name}'));
+    if (!_extensionSymbols.containsKey(name)) {
+      var id = js_ast.TemporaryId(
+          '\$${js_ast.friendlyNameForDartOperator[name] ?? name}');
+      _extensionSymbols[name] = id;
+      addSymbol(id, id);
+    }
+    return _extensionSymbols[name];
   }
 
   /// Shorthand for identifier-like property names.
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index ed3c8e3..42a4511 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -1676,7 +1676,7 @@
     Expression key = parseExpression();
     expectCategory(RPAREN);
     expectCategory(LBRACE);
-    var clauses = List<SwitchCase>();
+    var clauses = <SwitchCase>[];
     while (lastCategory != RBRACE) {
       clauses.add(parseSwitchClause());
     }
@@ -1701,7 +1701,7 @@
       heritage = parseConditional();
     }
     expectCategory(LBRACE);
-    var methods = List<Method>();
+    var methods = <Method>[];
     while (lastCategory != RBRACE) {
       methods.add(parseMethodOrProperty(onlyMethods: true) as Method);
     }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 16cd2fe..8800d4c 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -22,6 +22,7 @@
 import '../compiler/js_utils.dart' as js_ast;
 import '../compiler/module_builder.dart'
     show isSdkInternalRuntimeUri, libraryUriToJsIdentifier, pathToJSIdentifier;
+import '../compiler/module_containers.dart' show ModuleItemContainer;
 import '../compiler/shared_command.dart' show SharedCompilerOptions;
 import '../compiler/shared_compiler.dart';
 import '../js_ast/js_ast.dart' as js_ast;
@@ -69,11 +70,14 @@
   /// Let variables collected for the given function.
   List<js_ast.TemporaryId> _letVariables;
 
-  final _constTable = _emitTemporaryId('CT');
+  final _constTable = js_ast.TemporaryId('CT');
 
-  // Constant getters used to populate the constant table.
+  /// Constant getters used to populate the constant table.
   final _constLazyAccessors = <js_ast.Method>[];
 
+  /// Container for holding the results of lazily-evaluated constants.
+  final _constTableCache = ModuleItemContainer<String>.asArray('C');
+
   /// Tracks the index in [moduleItems] where the const table must be inserted.
   /// Required for SDK builds due to internal circular dependencies.
   /// E.g., dart.constList depends on JSArray.
@@ -105,6 +109,14 @@
 
   FunctionNode _currentFunction;
 
+  /// Whether the current function needs to insert parameter checks.
+  ///
+  /// Used to avoid adding checks for formal parameters inside a synthetic
+  /// function that is generated during expression compilation in the
+  /// incremental compiler, since those checks would already be done in
+  /// the original code.
+  bool _checkParameters = true;
+
   /// Whether we are currently generating code for the body of a `JS()` call.
   bool _isInForeignJS = false;
 
@@ -208,7 +220,7 @@
   final constAliasCache = HashMap<Constant, js_ast.Expression>();
 
   /// Maps uri strings in asserts and elsewhere to hoisted identifiers.
-  final _uriMap = HashMap<String, js_ast.Identifier>();
+  final _uriContainer = ModuleItemContainer<String>.asArray('I');
 
   final Class _jsArrayClass;
   final Class _privateSymbolClass;
@@ -315,7 +327,32 @@
 
     var libraries = component.libraries;
 
-    // Initialize our library variables.
+    // Initialize library variables.
+    isBuildingSdk = libraries.any(isSdkInternalRuntime);
+
+    // For runtime performance reasons, we only containerize SDK symbols in web
+    // libraries. Otherwise, we use a 600-member cutoff before a module is
+    // containerized. This is somewhat arbitrary but works promisingly for the
+    // SDK and Flutter Web.
+    if (!isBuildingSdk) {
+      // The number of DDC top-level symbols scales with the number of
+      // non-static class members across an entire module.
+      var uniqueNames = HashSet<String>();
+      libraries.forEach((Library l) {
+        l.classes.forEach((Class c) {
+          c.members.forEach((m) {
+            var isStatic =
+                m is Field ? m.isStatic : (m is Procedure ? m.isStatic : false);
+            if (isStatic) return;
+            var name = js_ast.toJSIdentifier(
+                m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_'));
+            uniqueNames.add(name);
+          });
+        });
+      });
+      containerizeSymbols = uniqueNames.length > 600;
+    }
+
     var items = startModule(libraries);
     _nullableInference.allowNotNullDeclarations = isBuildingSdk;
     _typeTable = TypeTable(runtimeModule);
@@ -327,10 +364,12 @@
       _pendingClasses.addAll(l.classes);
     }
 
-    // TODO(markzipan): Don't emit this when compiling the SDK.
-    moduleItems
-        .add(js.statement('const # = Object.create(null);', [_constTable]));
-    _constTableInsertionIndex = moduleItems.length;
+    // Record a safe index after the declaration of type generators and
+    // top-level symbols but before the declaration of any functions.
+    // Various preliminary data structures must be inserted here prior before
+    // referenced by the rest of the module.
+    var safeDeclarationIndex = moduleItems.length;
+    _constTableInsertionIndex = safeDeclarationIndex;
 
     // Add implicit dart:core dependency so it is first.
     emitLibraryName(_coreTypes.coreLibrary);
@@ -342,21 +381,25 @@
     // This is done by forward declaring items.
     libraries.forEach(_emitLibrary);
 
+    // Emit hoisted assert strings
+    moduleItems.insertAll(safeDeclarationIndex, _uriContainer.emit());
+
+    if (_constTableCache.isNotEmpty) {
+      moduleItems.insertAll(safeDeclarationIndex, _constTableCache.emit());
+    }
+
     // This can cause problems if it's ever true during the SDK build, as it's
     // emitted before dart.defineLazy.
     if (_constLazyAccessors.isNotEmpty) {
+      var constTableDeclaration =
+          js.statement('const # = Object.create(null);', [_constTable]);
       var constTableBody = runtimeStatement(
           'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]);
-      moduleItems.insert(_constTableInsertionIndex, constTableBody);
+      moduleItems.insertAll(
+          _constTableInsertionIndex, [constTableDeclaration, constTableBody]);
       _constLazyAccessors.clear();
     }
 
-    // Add assert locations
-    _uriMap.forEach((location, id) {
-      moduleItems.insert(_constTableInsertionIndex,
-          js.statement('var # = #;', [id, js.escapedString(location)]));
-    });
-
     moduleItems.addAll(afterClassDefItems);
     afterClassDefItems.clear();
 
@@ -366,9 +409,8 @@
     // Declare imports and extension symbols
     emitImportsAndExtensionSymbols(items);
 
-    // Discharge the type table cache variables and
-    // hoisted definitions.
-    items.addAll(_typeTable.discharge());
+    // Emit the hoisted type table cache variables
+    items.addAll(_typeTable.dischargeBoundTypes());
 
     return finishModule(items, _options.moduleName);
   }
@@ -433,6 +475,10 @@
     _currentLibrary = library;
     _staticTypeContext.enterLibrary(_currentLibrary);
 
+    if (isBuildingSdk) {
+      containerizeSymbols = _isWebLibrary(library.importUri);
+    }
+
     if (isSdkInternalRuntime(library)) {
       // `dart:_runtime` uses a different order for bootstrapping.
       //
@@ -557,10 +603,29 @@
     _classProperties =
         ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, c);
 
+    var body = <js_ast.Statement>[];
+
+    // ClassPropertyModel.build introduces symbols for virtual field accessors.
+    _classProperties.virtualFields.forEach((field, virtualField) {
+      // TODO(vsm): Clean up this logic.
+      //
+      // Typically, [emitClassPrivateNameSymbol] creates a new symbol.  If it
+      // is called multiple times, that symbol is cached.  If the former,
+      // assign directly to [virtualField].  If the latter, copy the old
+      // variable to [virtualField].
+      var symbol = emitClassPrivateNameSymbol(c.enclosingLibrary,
+          getLocalClassName(c), field.name.text, virtualField);
+      if (symbol != virtualField) {
+        addSymbol(virtualField, getSymbolValue(symbol));
+        if (!containerizeSymbols) {
+          body.add(js.statement('const # = #;', [virtualField, symbol]));
+        }
+      }
+    });
+
     var jsCtors = _defineConstructors(c, className);
     var jsMethods = _emitClassMethods(c);
 
-    var body = <js_ast.Statement>[];
     _emitSuperHelperSymbols(body);
     // Deferred supertypes must be evaluated lazily while emitting classes to
     // prevent evaluating a JS expression for a deferred type from influencing
@@ -584,7 +649,6 @@
     // Attach caches on all canonicalized types.
     body.add(runtimeStatement('addTypeCaches(#)', [className]));
 
-    _emitVirtualFieldSymbols(c, body);
     _emitClassSignature(c, className, body);
     _initExtensionSymbols(c);
     if (!c.isMixinDeclaration) {
@@ -635,7 +699,7 @@
 
     var typeConstructor = js.call('(#) => { #; #; return #; }', [
       jsFormals,
-      _typeTable.discharge(formals),
+      _typeTable.dischargeFreeTypes(formals),
       body,
       className ?? _emitIdentifier(name)
     ]);
@@ -1516,7 +1580,13 @@
 
     var body = <js_ast.Statement>[];
     void emitFieldInit(Field f, Expression initializer, TreeNode hoverInfo) {
-      var access = _classProperties.virtualFields[f] ?? _declareMemberName(f);
+      var virtualField = _classProperties.virtualFields[f];
+
+      // Avoid calling getSymbol on _declareMemberName since _declareMemberName
+      // calls _emitMemberName downstream, which already invokes getSymbol.
+      var access = virtualField == null
+          ? _declareMemberName(f)
+          : getSymbol(virtualField);
       var jsInit = _visitInitializer(initializer, f.annotations);
       body.add(jsInit
           .toAssignExpression(js.call('this.#', [access])
@@ -1903,14 +1973,16 @@
   /// wrong behavior if a new field was declared.
   List<js_ast.Method> _emitVirtualFieldAccessor(Field field) {
     var virtualField = _classProperties.virtualFields[field];
+    var virtualFieldSymbol = getSymbol(virtualField);
     var name = _declareMemberName(field);
 
-    var getter = js.fun('function() { return this[#]; }', [virtualField]);
+    var getter = js.fun('function() { return this[#]; }', [virtualFieldSymbol]);
     var jsGetter = js_ast.Method(name, getter, isGetter: true)
       ..sourceInformation = _nodeStart(field);
 
-    var args =
-        field.isFinal ? [js_ast.Super(), name] : [js_ast.This(), virtualField];
+    var args = field.isFinal
+        ? [js_ast.Super(), name]
+        : [js_ast.This(), virtualFieldSymbol];
 
     js_ast.Expression value = _emitIdentifier('value');
     if (!field.isFinal && isCovariantField(field)) {
@@ -2226,13 +2298,13 @@
       var memberLibrary = member?.name?.library ??
           memberClass?.enclosingLibrary ??
           _currentLibrary;
-      return emitPrivateNameSymbol(memberLibrary, name);
+      return getSymbol(emitPrivateNameSymbol(memberLibrary, name));
     }
 
     useExtension ??= _isSymbolizedMember(memberClass, name);
     name = js_ast.memberNameForDartMember(name, _isExternal(member));
     if (useExtension) {
-      return getExtensionSymbolInternal(name);
+      return getSymbol(getExtensionSymbolInternal(name));
     }
     return propertyName(name);
   }
@@ -2639,6 +2711,7 @@
       {bool emitNullability = true}) {
     var c = type.classNode;
     _declareBeforeUse(c);
+    js_ast.Expression typeRep;
 
     // Type parameters don't matter as JS interop types cannot be reified.
     // We have to use lazy JS types because until we have proper module
@@ -2654,17 +2727,25 @@
     // Anonymous JS types do not have a corresponding concrete JS type so we
     // have to use a helper to define them.
     if (isJSAnonymousType(c)) {
-      return runtimeCall(
+      typeRep = runtimeCall(
           'anonymousJSType(#)', [js.escapedString(getLocalClassName(c))]);
+    } else {
+      var jsName = _jsNameWithoutGlobal(c);
+      if (jsName != null) {
+        typeRep = runtimeCall('lazyJSType(() => #, #)',
+            [_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
+      }
     }
-    var jsName = _jsNameWithoutGlobal(c);
-    if (jsName != null) {
-      return runtimeCall('lazyJSType(() => #, #)',
-          [_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
+
+    if (typeRep != null) {
+      // JS types are not currently cached in the type table like other types
+      // are below.
+      return emitNullability
+          ? _emitNullabilityWrapper(typeRep, type.nullability)
+          : typeRep;
     }
 
     var args = type.typeArguments;
-    js_ast.Expression typeRep;
     Iterable<js_ast.Expression> jsArgs;
     if (args.any((a) => a != const DynamicType())) {
       jsArgs = args.map(_emitType);
@@ -2840,7 +2921,7 @@
 
       js_ast.Expression addTypeFormalsAsParameters(
           List<js_ast.Expression> elements) {
-        var names = _typeTable.discharge(typeFormals);
+        var names = _typeTable.dischargeFreeTypes(typeFormals);
         return names.isEmpty
             ? js.call('(#) => [#]', [tf, elements])
             : js.call('(#) => {#; return [#];}', [tf, names, elements]);
@@ -2973,6 +3054,12 @@
     _staticTypeContext.enterLibrary(_currentLibrary);
     _currentClass = cls;
 
+    // Do not add formal parameter checks for the top-level synthetic function
+    // generated for expression evaluation, as those parameters are a set of
+    // variables from the current scope, and should alredy be checked in the
+    // original code.
+    _checkParameters = false;
+
     // Emit function with additional information, such as types that are used
     // in the expression. Note that typeTable can be null if this function is
     // called from the expression compilation service, since we currently do
@@ -2982,9 +3069,8 @@
     // Issue: https://github.com/dart-lang/sdk/issues/43288
     var fun = _emitFunction(functionNode, name);
 
-    var types = _typeTable.discharge();
+    var types = _typeTable?.dischargeFreeTypes();
     var constants = _dischargeConstTable();
-
     var body = js_ast.Block([...?types, ...?constants, ...fun.body.statements]);
     return js_ast.Fun(fun.params, body);
   }
@@ -3078,22 +3164,6 @@
     return result;
   }
 
-  void _emitVirtualFieldSymbols(Class c, List<js_ast.Statement> body) {
-    _classProperties.virtualFields.forEach((field, virtualField) {
-      // TODO(vsm): Clean up this logic.  See comments on the following method.
-      //
-      // Typically, [emitClassPrivateNameSymbol] creates a new symbol.  If it
-      // is called multiple times, that symbol is cached.  If the former,
-      // assign directly to [virtualField].  If the latter, copy the old
-      // variable to [virtualField].
-      var symbol = emitClassPrivateNameSymbol(c.enclosingLibrary,
-          getLocalClassName(c), field.name.text, virtualField);
-      if (symbol != virtualField) {
-        body.add(js.statement('const # = #;', [virtualField, symbol]));
-      }
-    });
-  }
-
   List<js_ast.Identifier> _emitTypeFormals(List<TypeParameter> typeFormals) {
     return typeFormals
         .map((t) => _emitIdentifier(getTypeParameterName(t)))
@@ -3332,13 +3402,16 @@
         // The check on `p.type` is per:
         // https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
         var condition = js.call('# == null', [jsParam]);
+        // Offsets are not available for compiler-generated variables
+        // Get the best available location even if the offset is missing.
+        // https://github.com/dart-lang/sdk/issues/34942
         var location = p.location;
         var check = js.statement(' if (#) #.nullFailed(#, #, #, #);', [
           condition,
           runtimeModule,
-          _cacheUri(location.file.toString()),
-          js.number(location.line),
-          js.number(location.column),
+          _cacheUri(location?.file?.toString()),
+          js.number(location?.line ?? -1),
+          js.number(location?.column ?? -1),
           js.escapedString('${p.name}'),
         ]);
         body.add(check);
@@ -3347,7 +3420,9 @@
 
     for (var p in f.positionalParameters) {
       var jsParam = _emitVariableDef(p);
-      initParameter(p, jsParam);
+      if (_checkParameters) {
+        initParameter(p, jsParam);
+      }
     }
     for (var p in f.namedParameters) {
       // Parameters will be passed using their real names, not the (possibly
@@ -3374,8 +3449,18 @@
           paramName,
         ]));
       }
-      initParameter(p, jsParam);
+      if (_checkParameters) {
+        initParameter(p, jsParam);
+      }
     }
+
+    // '_checkParametes = false' is only needed once, while processing formal
+    // parameters of the synthetic function from expression evalaluation - it
+    // will be called from emitFunctionIncremental, which is a top-level API
+    // for expression compilation.
+    // Here we either are done with processing those formals, or compiling
+    // something else (in which case _checkParameters is already true).
+    _checkParameters = true;
     return body;
   }
 
@@ -3605,14 +3690,11 @@
 
   // Replace a string `uri` literal with a cached top-level variable containing
   // the value to reduce overall code size.
-  js_ast.Identifier _cacheUri(String uri) {
-    var id = _uriMap[uri];
-    if (id == null) {
-      var name = 'L${_uriMap.length}';
-      id = js_ast.TemporaryId(name);
-      _uriMap[uri] = id;
+  js_ast.Expression _cacheUri(String uri) {
+    if (!_uriContainer.contains(uri)) {
+      _uriContainer[uri] = js_ast.LiteralString('"$uri"');
     }
-    return id;
+    return _uriContainer.access(uri);
   }
 
   @override
@@ -4389,6 +4471,33 @@
   js_ast.Expression _emitMethodCall(Expression receiver, Member target,
       Arguments arguments, InvocationExpression node) {
     var name = node.name.text;
+
+    /// Returns `true` when [node] represents an invocation of `List.add()` that
+    /// can be optimized.
+    ///
+    /// The optimized add operation can skip checks for a growable or modifiable
+    /// list and the element type is known to be invariant so it can skip the
+    /// type check.
+    bool isNativeListInvariantAdd(InvocationExpression node) {
+      if (node is MethodInvocation &&
+          node.isInvariant &&
+          node.name.name == 'add') {
+        // The call to add is marked as invariant, so the type check on the
+        // parameter to add is not needed.
+        var receiver = node.receiver;
+        if (receiver is VariableGet && receiver.variable.isFinal) {
+          // The receiver is a final variable, so it only contains the
+          // initializer value.
+          if (receiver.variable.initializer is ListLiteral) {
+            // The initializer is a list literal, so we know the list can be
+            // grown, modified, and is represented by a JavaScript Array.
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+
     if (isOperatorMethodName(name) && arguments.named.isEmpty) {
       var argLength = arguments.positional.length;
       if (argLength == 0) {
@@ -4402,6 +4511,10 @@
     var jsReceiver = _visitExpression(receiver);
     var args = _emitArgumentList(arguments, target: target);
 
+    if (isNativeListInvariantAdd(node)) {
+      return js.call('#.push(#)', [jsReceiver, args]);
+    }
+
     var isCallingDynamicField = target is Member &&
         target.hasGetter &&
         _isDynamicOrFunction(target.getterType);
@@ -4934,7 +5047,7 @@
           return _emitType(firstArg.type);
         }
         if (name == 'extensionSymbol' && firstArg is StringLiteral) {
-          return getExtensionSymbolInternal(firstArg.value);
+          return getSymbol(getExtensionSymbolInternal(firstArg.value));
         }
 
         if (name == 'compileTimeFlag' && firstArg is StringLiteral) {
@@ -5416,8 +5529,29 @@
   @override
   js_ast.Expression visitAsExpression(AsExpression node) {
     var fromExpr = node.operand;
-    var to = node.type;
     var jsFrom = _visitExpression(fromExpr);
+
+    // The `_EventStreamSubscription.cancel()` method dart:html returns null in
+    // weak mode. This causes unwanted warnings/failures when you turn on the
+    // weak mode warnings/errors so we remove these specific runtime casts.
+    // TODO(44157) Remove this workaround once it returns a consistent type.
+    if (_isWebLibrary(currentLibraryUri) && node.parent is ReturnStatement) {
+      var parent = node.parent;
+      while (parent != null && parent is! FunctionNode) {
+        parent = parent?.parent;
+      }
+      parent = parent?.parent;
+      if (parent is Procedure) {
+        if (parent.enclosingClass != null &&
+            parent.enclosingClass.name == '_EventStreamSubscription' &&
+            parent.name.name == 'cancel') {
+          // Ignore these casts and just emit the expression.
+          return jsFrom;
+        }
+      }
+    }
+
+    var to = node.type;
     var from = fromExpr.getStaticType(_staticTypeContext);
 
     // If the check was put here by static analysis to ensure soundness, we
@@ -5789,19 +5923,19 @@
     }
     var constAliasString = 'C${constAliasCache.length}';
     var constAliasProperty = propertyName(constAliasString);
-    var constAliasId = _emitTemporaryId(constAliasString);
-    var constAccessor =
-        js.call('# || #.#', [constAliasId, _constTable, constAliasProperty]);
+
+    _constTableCache[constAliasString] = js.call('void 0');
+    var constAliasAccessor = _constTableCache.access(constAliasString);
+
+    var constAccessor = js.call(
+        '# || #.#', [constAliasAccessor, _constTable, constAliasProperty]);
     constAliasCache[node] = constAccessor;
     var constJs = super.visitConstant(node);
-    // TODO(vsm): Change back to `let`.
-    // See https://github.com/dart-lang/sdk/issues/40380.
-    moduleItems.add(js.statement('var #;', [constAliasId]));
 
     var func = js_ast.Fun(
         [],
         js_ast.Block([
-          js.statement('return # = #;', [constAliasId, constJs])
+          js.statement('return # = #;', [constAliasAccessor, constJs])
         ]));
     var accessor = js_ast.Method(constAliasProperty, func, isGetter: true);
     _constLazyAccessors.add(accessor);
@@ -5887,8 +6021,8 @@
       // was overridden.
       var symbol = cls.isEnum
           ? _emitMemberName(member.name.text, member: member)
-          : emitClassPrivateNameSymbol(
-              cls.enclosingLibrary, getLocalClassName(cls), member.name.text);
+          : getSymbol(emitClassPrivateNameSymbol(
+              cls.enclosingLibrary, getLocalClassName(cls), member.name.text));
       return js_ast.Property(symbol, constant);
     }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
index 9d8b566..eb746a7 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -253,8 +253,16 @@
   }
 }
 
+/// Collect private fields and libraries used in expression.
+///
+/// Used during expression evaluation to find symbols
+/// for private fields. The symbols are used in the ddc
+/// compilation of the expression, are not always avalable
+/// in the JavaScript scope, so we need to redefine them.
+///
+/// See [_addSymbolDefinitions]
 class PrivateFieldsVisitor extends Visitor<void> {
-  final Map<String, String> privateFields = {};
+  final Map<String, Library> privateFields = {};
 
   @override
   void defaultNode(Node node) {
@@ -263,33 +271,31 @@
 
   @override
   void visitFieldReference(Field node) {
-    if (node.name.isPrivate) {
-      var library = node.enclosingLibrary?.importUri;
-      privateFields[node.name.text] = library?.toString();
+    if (node.name.isPrivate && !node.isStatic) {
+      privateFields[node.name.text] = node.enclosingLibrary;
     }
   }
 
   @override
   void visitField(Field node) {
-    if (node.name.isPrivate) {
-      var library = node.enclosingLibrary?.importUri;
-      privateFields[node.name.text] = library?.toString();
+    if (node.name.isPrivate && !node.isStatic) {
+      privateFields[node.name.text] = node.enclosingLibrary;
     }
   }
 
   @override
   void visitPropertyGet(PropertyGet node) {
-    if (node.name.isPrivate) {
-      var library = node.interfaceTarget?.enclosingLibrary?.importUri;
-      privateFields[node.name.text] = library?.toString();
+    var member = node.interfaceTarget;
+    if (node.name.isPrivate && member != null && member.isInstanceMember) {
+      privateFields[node.name.text] = node.interfaceTarget?.enclosingLibrary;
     }
   }
 
   @override
   void visitPropertySet(PropertySet node) {
-    if (node.name.isPrivate) {
-      var library = node.interfaceTarget?.enclosingLibrary?.importUri;
-      privateFields[node.name.text] = library?.toString();
+    var member = node.interfaceTarget;
+    if (node.name.isPrivate && member != null && member.isInstanceMember) {
+      privateFields[node.name.text] = node.interfaceTarget?.enclosingLibrary;
     }
   }
 }
@@ -329,31 +335,18 @@
   /// Values listed in [jsFrameValues] are substituted for their names in the
   /// [expression].
   ///
-  /// Ensures that all [jsModules] are loaded and accessible inside the
-  /// expression.
-  ///
   /// Returns expression compiled to JavaScript or null on error.
-  /// Errors are reported using onDiagnostic function
-  /// [moduleName] is of the form 'packages/hello_world_main.dart'
+  /// Errors are reported using onDiagnostic function.
+  ///
   /// [jsFrameValues] is a map from js variable name to its primitive value
   /// or another variable name, for example
   /// { 'x': '1', 'y': 'y', 'o': 'null' }
-  /// [jsModules] is a map from variable name to the module name, where
-  /// variable name is the name originally used in JavaScript to contain the
-  /// module object, for example:
-  /// { 'dart':'dart_sdk', 'main': 'packages/hello_world_main.dart' }
-  Future<String> compileExpressionToJs(
-      String libraryUri,
-      int line,
-      int column,
-      Map<String, String> jsModules,
-      Map<String, String> jsScope,
-      String moduleName,
-      String expression) async {
+  Future<String> compileExpressionToJs(String libraryUri, int line, int column,
+      Map<String, String> jsScope, String expression) async {
     try {
       // 1. find dart scope where debugger is paused
 
-      _log('Compiling expression in $moduleName:\n$expression');
+      _log('Compiling expression \n$expression');
 
       var dartScope = await _findScopeAt(Uri.parse(libraryUri), line, column);
       if (dartScope == null) {
@@ -382,11 +375,10 @@
 
       // 3. compile dart expression to JS
 
-      var jsExpression = await _compileExpression(
-          dartScope, jsModules, moduleName, expression);
+      var jsExpression = await _compileExpression(dartScope, expression);
 
       if (jsExpression == null) {
-        _log('Failed to compile expression in $moduleName:\n$expression');
+        _log('Failed to compile expression: \n$expression');
         return null;
       }
 
@@ -472,19 +464,9 @@
 
   /// Return a JS function that returns the evaluated results when called.
   ///
-  /// [scope] current dart scope information
-  /// [modules] map from module variable names to module names in JavaScript
-  /// code. For example,
-  /// { 'dart':'dart_sdk', 'main': 'packages/hello_world_main.dart' }
-  /// [currentModule] current js module name.
-  /// For example, in library package:hello_world/main.dart:
-  /// 'packages/hello_world/main.dart'
+  /// [scope] current dart scope information.
   /// [expression] expression to compile in given [scope].
-  Future<String> _compileExpression(
-      DartScope scope,
-      Map<String, String> modules,
-      String currentModule,
-      String expression) async {
+  Future<String> _compileExpression(DartScope scope, String expression) async {
     var procedure = await _compiler.compileExpression(
         expression,
         scope.definitions,
@@ -513,7 +495,7 @@
 
     _log('Generated JavaScript for expression');
 
-    var jsFunModified = _addSymbolDefinitions(procedure, jsFun, scope, modules);
+    var jsFunModified = _addSymbolDefinitions(procedure, jsFun, scope);
 
     _log('Added symbol definitions to JavaScript');
 
@@ -531,85 +513,48 @@
 
   /// Add symbol definitions for all symbols in compiled expression
   ///
+  /// Example:
+  ///
+  ///   compilation of this._field from library 'main'
+  ///
+  /// Symbol definition:
+  ///
+  ///   let _f = dart.privateName(main, "_f");
+  ///
+  /// Expression generated by ddc:
+  ///
+  ///   this[_f]
+  ///
   /// TODO: this is a temporary workaround to make JavaScript produced
   /// by the ProgramCompiler self-contained.
   /// Issue: https://github.com/dart-lang/sdk/issues/41480
-  js_ast.Fun _addSymbolDefinitions(Procedure procedure, js_ast.Fun jsFun,
-      DartScope scope, Map<String, String> modules) {
+  js_ast.Fun _addSymbolDefinitions(
+      Procedure procedure, js_ast.Fun jsFun, DartScope scope) {
     // get private fields accessed by the evaluated expression
     var fieldsCollector = PrivateFieldsVisitor();
     procedure.accept(fieldsCollector);
     var privateFields = fieldsCollector.privateFields;
 
-    // collect libraries where private fields are defined
-    var currentLibraries = <String, String>{};
-    var currentModules = <String, String>{};
-    for (var variable in modules.keys) {
-      var module = modules[variable];
-      for (var field in privateFields.keys) {
-        var library = privateFields[field];
-        if (library != null) {
-          var libraryVariable =
-              library.replaceAll('.dart', '').replaceAll('/', '__');
-          if (libraryVariable.endsWith(variable)) {
-            if (currentLibraries[field] != null) {
-              onDiagnostic(_createInternalError(
-                  scope.library.importUri,
-                  0,
-                  0,
-                  'ExpressionCompiler: $field defined in more than one library: '
-                  '${currentLibraries[field]}, $variable'));
-              return null;
-            }
-            currentLibraries[field] = variable;
-            currentModules[variable] = module;
-          }
-        }
-      }
-    }
+    // collect library names where private symbols are defined
+    var libraryForField = privateFields.map((field, library) =>
+        MapEntry(field, _kernel2jsCompiler.emitLibraryName(library).name));
 
     var body = js_ast.Block([
-      // require modules used in evaluated expression
-      ...currentModules.keys.map((String variable) =>
-          _createRequireModuleStatement(
-              currentModules[variable], variable, variable)),
       // re-create private field accessors
-      ...currentLibraries.keys
-          .map((String k) => _createPrivateField(k, currentLibraries[k])),
+      ...libraryForField.keys.map(
+          (String field) => _createPrivateField(field, libraryForField[field])),
       // statements generated by the FE
       ...jsFun.body.statements
     ]);
-
     return js_ast.Fun(jsFun.params, body);
   }
 
-  /// Creates a library symbol definition
-  ///
-  /// example:
-  /// let dart = require('dart_sdk').dart;
-  js_ast.Statement _createRequireModuleStatement(
-      String moduleName, String moduleVariable, String fieldName) {
-    var variableName = moduleVariable.replaceFirst('.dart', '');
-    var rhs = js_ast.PropertyAccess.field(
-        js_ast.Call(js_ast.Identifier('require'),
-            [js_ast.LiteralExpression('\'$moduleName\'')]),
-        '$fieldName');
-
-    return rhs.toVariableDeclaration(js_ast.Identifier('$variableName'));
-  }
-
   /// Creates a private symbol definition
   ///
   /// example:
   /// let _f = dart.privateName(main, "_f");
   js_ast.Statement _createPrivateField(String field, String library) {
-    var libraryName = library.replaceFirst('.dart', '');
-    var rhs = js_ast.Call(
-        js_ast.PropertyAccess.field(js_ast.Identifier('dart'), 'privateName'), [
-      js_ast.LiteralExpression(libraryName),
-      js_ast.LiteralExpression('"$field"')
-    ]);
-
-    return rhs.toVariableDeclaration(js_ast.Identifier('$field'));
+    return js_ast.js.statement('let # = dart.privateName(#, #)',
+        [field, library, js_ast.js.string(field)]);
   }
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
index 9e77102..fbd7ba6 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -108,8 +108,13 @@
   final CompilerOptions _compilerOptions;
   final Component _sdkComponent;
 
-  ExpressionCompilerWorker._(this._processedOptions, this._compilerOptions,
-      this._sdkComponent, this.requestStream, this.sendResponse);
+  ExpressionCompilerWorker._(
+    this._processedOptions,
+    this._compilerOptions,
+    this._sdkComponent,
+    this.requestStream,
+    this.sendResponse,
+  );
 
   static Future<ExpressionCompilerWorker> createFromArgs(
     List<String> args, {
@@ -243,8 +248,6 @@
   /// Handles a `CompileExpression` request.
   Future<Map<String, dynamic>> _compileExpression(
       CompileExpressionRequest request) async {
-    _processedOptions.ticker.logMs('Compiling expression to JavaScript');
-
     var libraryUri = Uri.parse(request.libraryUri);
     if (libraryUri.scheme == 'dart') {
       // compiling expressions inside the SDK currently fails because
@@ -259,7 +262,8 @@
       throw ArgumentError(
           'Unable to find library `$libraryUri`, it must be loaded first.');
     }
-
+    _processedOptions.ticker.logMs(
+        'Compiling expression to JavaScript in module ${request.moduleName}');
     var component = _sdkComponent;
 
     if (libraryUri.scheme != 'dart') {
@@ -297,7 +301,13 @@
       finalComponent,
       incrementalCompiler.getClassHierarchy(),
       SharedCompilerOptions(
-          sourceMap: true, summarizeApi: false, moduleName: request.moduleName),
+          sourceMap: true,
+          summarizeApi: false,
+          moduleName: request.moduleName,
+          // Disable asserts due to failures to load source and
+          // locations on kernel loaded from dill files in DDC.
+          // https://github.com/dart-lang/sdk/issues/43986
+          enableAsserts: false),
       _componentForLibrary,
       _componentModuleNames,
       coreTypes: incrementalCompiler.getCoreTypes(),
@@ -318,9 +328,7 @@
         request.libraryUri,
         request.line,
         request.column,
-        request.jsModules,
         request.jsScope,
-        request.moduleName,
         request.expression);
 
     _processedOptions.ticker.logMs('Compiled expression to JavaScript');
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index f389110..d22ded9 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -34,7 +34,7 @@
   bool get enableSuperMixins => true;
 
   @override
-  bool get supportsLateFields => false;
+  int get enabledLateLowerings => LateLowering.all;
 
   @override
   bool get supportsLateLoweringSentinel => false;
@@ -151,8 +151,7 @@
       ChangedStructureNotifier changedStructureNotifier}) {
     for (var library in libraries) {
       _CovarianceTransformer(library).transform();
-      JsInteropChecks(
-              coreTypes,
+      JsInteropChecks(coreTypes,
               diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>)
           .visitLibrary(library);
     }
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index ddaf27f..b9b73fd 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -4,13 +4,17 @@
 
 // @dart = 2.9
 
+import 'dart:collection';
+
 import 'package:kernel/kernel.dart';
 
 import '../compiler/js_names.dart' as js_ast;
+import '../compiler/module_containers.dart' show ModuleItemContainer;
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import 'kernel_helpers.dart';
 
+/// Returns all non-locally defined type parameters referred to by [t].
 Set<TypeParameter> freeTypeParameters(DartType t) {
   assert(isKnownDartTypeImplementor(t));
   var result = <TypeParameter>{};
@@ -36,160 +40,144 @@
   return result;
 }
 
-/// _CacheTable tracks cache variables for variables that
-/// are emitted in place with a hoisted variable for a cache.
-class _CacheTable {
-  /// Mapping from types to their canonical names.
-  // Use a LinkedHashMap to maintain key insertion order so the generated code
-  // is stable under slight perturbation.  (If this is not good enough we could
-  // sort by name to canonicalize order.)
-  final _names = <DartType, js_ast.TemporaryId>{};
-  Iterable<DartType> get keys => _names.keys.toList();
-
-  js_ast.Statement _dischargeType(DartType type) {
-    var name = _names.remove(type);
-    if (name != null) {
-      return js.statement('let #;', [name]);
-    }
-    return null;
+/// A name for a type made of JS identifier safe characters.
+///
+/// 'L' and 'N' are prepended to a type name to represent a legacy or nullable
+/// flavor of a type.
+String _typeString(DartType type, {bool flat = false}) {
+  var nullability = type.declaredNullability == Nullability.legacy
+      ? 'L'
+      : type.declaredNullability == Nullability.nullable
+          ? 'N'
+          : '';
+  assert(isKnownDartTypeImplementor(type));
+  if (type is InterfaceType) {
+    var name = '${type.classNode.name}$nullability';
+    var typeArgs = type.typeArguments;
+    if (typeArgs == null) return name;
+    if (typeArgs.every((p) => p == const DynamicType())) return name;
+    return "${name}Of${typeArgs.map(_typeString).join("\$")}";
   }
-
-  /// Emit a list of statements declaring the cache variables for
-  /// types tracked by this table.  If [typeFilter] is given,
-  /// only emit the types listed in the filter.
-  List<js_ast.Statement> discharge([Iterable<DartType> typeFilter]) {
-    var decls = <js_ast.Statement>[];
-    var types = typeFilter ?? keys;
-    for (var t in types) {
-      var stmt = _dischargeType(t);
-      if (stmt != null) decls.add(stmt);
-    }
-    return decls;
+  if (type is FutureOrType) {
+    var name = 'FutureOr$nullability';
+    if (type.typeArgument == const DynamicType()) return name;
+    return '${name}Of${_typeString(type.typeArgument)}';
   }
-
-  bool isNamed(DartType type) => _names.containsKey(type);
-
-  /// A name for a type made of JS identifier safe characters.
-  ///
-  /// 'L' and 'N' are prepended to a type name to represent a legacy or nullable
-  /// flavor of a type.
-  String _typeString(DartType type, {bool flat = false}) {
-    var nullability = type.declaredNullability == Nullability.legacy
-        ? 'L'
-        : type.declaredNullability == Nullability.nullable
-            ? 'N'
-            : '';
-    assert(isKnownDartTypeImplementor(type));
-    if (type is InterfaceType) {
-      var name = '${type.classNode.name}$nullability';
-      var typeArgs = type.typeArguments;
-      if (typeArgs == null) return name;
-      if (typeArgs.every((p) => p == const DynamicType())) return name;
-      return "${name}Of${typeArgs.map(_typeString).join("\$")}";
-    }
-    if (type is FutureOrType) {
-      var name = 'FutureOr$nullability';
-      if (type.typeArgument == const DynamicType()) return name;
-      return '${name}Of${_typeString(type.typeArgument)}';
-    }
-    if (type is TypedefType) {
-      var name = '${type.typedefNode.name}$nullability';
-      var typeArgs = type.typeArguments;
-      if (typeArgs == null) return name;
-      if (typeArgs.every((p) => p == const DynamicType())) return name;
-      return "${name}Of${typeArgs.map(_typeString).join("\$")}";
-    }
-    if (type is FunctionType) {
-      if (flat) return 'Fn';
-      var rType = _typeString(type.returnType, flat: true);
-      var params = type.positionalParameters
-          .take(3)
-          .map((p) => _typeString(p, flat: true));
-      var paramList = params.join('And');
-      var count = type.positionalParameters.length;
-      if (count > 3 || type.namedParameters.isNotEmpty) {
-        paramList = '${paramList}__';
-      } else if (count == 0) {
-        paramList = 'Void';
-      }
-      return '${paramList}To$nullability$rType';
-    }
-    if (type is TypeParameterType) return '${type.parameter.name}$nullability';
-    if (type is DynamicType) return 'dynamic';
-    if (type is VoidType) return 'void';
-    if (type is NeverType) return 'Never$nullability';
-    if (type is BottomType) return 'bottom';
-    if (type is NullType) return 'Null';
-    return 'invalid';
+  if (type is TypedefType) {
+    var name = '${type.typedefNode.name}$nullability';
+    var typeArgs = type.typeArguments;
+    if (typeArgs == null) return name;
+    if (typeArgs.every((p) => p == const DynamicType())) return name;
+    return "${name}Of${typeArgs.map(_typeString).join("\$")}";
   }
-
-  /// Heuristically choose a good name for the cache and generator
-  /// variables.
-  js_ast.TemporaryId chooseTypeName(DartType type) {
-    return js_ast.TemporaryId(escapeIdentifier(_typeString(type)));
-  }
-}
-
-/// _GeneratorTable tracks types which have been
-/// named and hoisted.
-class _GeneratorTable extends _CacheTable {
-  final _defs = <DartType, js_ast.Expression>{};
-
-  final js_ast.Identifier _runtimeModule;
-
-  _GeneratorTable(this._runtimeModule);
-
-  @override
-  js_ast.Statement _dischargeType(DartType t) {
-    var name = _names.remove(t);
-    if (name != null) {
-      var init = _defs.remove(t);
-      assert(init != null);
-      // TODO(vsm): Change back to `let`.
-      // See https://github.com/dart-lang/sdk/issues/40380.
-      return js.statement('var # = () => ((# = #.constFn(#))());',
-          [name, name, _runtimeModule, init]);
+  if (type is FunctionType) {
+    if (flat) return 'Fn';
+    var rType = _typeString(type.returnType, flat: true);
+    var params = type.positionalParameters
+        .take(3)
+        .map((p) => _typeString(p, flat: true));
+    var paramList = params.join('And');
+    var count = type.positionalParameters.length;
+    if (count > 3 || type.namedParameters.isNotEmpty) {
+      paramList = '${paramList}__';
+    } else if (count == 0) {
+      paramList = 'Void';
     }
-    return null;
+    return '${paramList}To$nullability$rType';
   }
-
-  /// If [type] does not already have a generator name chosen for it,
-  /// assign it one, using [typeRep] as the initializer for it.
-  /// Emit the generator name.
-  js_ast.TemporaryId _nameType(DartType type, js_ast.Expression typeRep) {
-    var temp = _names[type];
-    if (temp == null) {
-      _names[type] = temp = chooseTypeName(type);
-      _defs[type] = typeRep;
-    }
-    return temp;
-  }
+  if (type is TypeParameterType) return '${type.parameter.name}$nullability';
+  if (type is DynamicType) return 'dynamic';
+  if (type is VoidType) return 'void';
+  if (type is NeverType) return 'Never$nullability';
+  if (type is BottomType) return 'bottom';
+  if (type is NullType) return 'Null';
+  return 'invalid';
 }
 
 class TypeTable {
-  /// Generator variable names for hoisted types.
-  final _GeneratorTable _generators;
-
   /// Mapping from type parameters to the types which must have their
   /// cache/generator variables discharged at the binding site for the
   /// type variable since the type definition depends on the type
   /// parameter.
   final _scopeDependencies = <TypeParameter, List<DartType>>{};
 
-  TypeTable(js_ast.Identifier runtime) : _generators = _GeneratorTable(runtime);
+  /// Contains types with any free type parameters and maps them to a unique
+  /// JS identifier.
+  ///
+  /// Used to reference types hoisted to the top of a generic class or generic
+  /// function (as opposed to the top of the entire module).
+  final _unboundTypeIds = HashMap<DartType, js_ast.Identifier>();
 
-  /// Emit a list of statements declaring the cache variables and generator
-  /// definitions tracked by the table.  If [formals] is present, only
-  /// emit the definitions which depend on the formals.
-  List<js_ast.Statement> discharge([List<TypeParameter> formals]) {
-    var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]);
-    var stmts = _generators.discharge(filter);
-    formals?.forEach(_scopeDependencies.remove);
-    return stmts;
+  /// Holds JS type generators keyed by their underlying DartType.
+  final typeContainer = ModuleItemContainer<DartType>.asObject('T',
+      keyToString: (DartType t) => escapeIdentifier(_typeString(t)));
+
+  final js_ast.Identifier _runtimeModule;
+
+  TypeTable(this._runtimeModule);
+
+  /// Returns true if [type] is already recorded in the table.
+  bool _isNamed(DartType type) =>
+      typeContainer.contains(type) || _unboundTypeIds.containsKey(type);
+
+  /// Emit the initializer statements for the type container, which contains
+  /// all named types with fully bound type parameters.
+  List<js_ast.Statement> dischargeBoundTypes() {
+    for (var t in typeContainer.keys) {
+      typeContainer[t] = js.call('() => ((# = #.constFn(#))())',
+          [typeContainer.access(t), _runtimeModule, typeContainer[t]]);
+    }
+    return typeContainer.emit();
   }
 
-  /// Record the dependencies of the type on its free variables
+  js_ast.Statement _dischargeFreeType(DartType type) {
+    typeContainer.setNoEmit(type);
+    var init = typeContainer[type];
+    var id = _unboundTypeIds[type];
+    // TODO(vsm): Change back to `let`.
+    // See https://github.com/dart-lang/sdk/issues/40380.
+    return js.statement('var # = () => ((# = #.constFn(#))());',
+        [id, id, _runtimeModule, init]);
+  }
+
+  /// Emit a list of statements declaring the cache variables and generator
+  /// definitions tracked by the table so far.
+  ///
+  /// If [formals] is present, only emit the definitions which depend on the
+  /// formals.
+  List<js_ast.Statement> dischargeFreeTypes([Iterable<TypeParameter> formals]) {
+    var decls = <js_ast.Statement>[];
+    var types = formals == null
+        ? typeContainer.keys.where((p) => freeTypeParameters(p).isNotEmpty)
+        : formals.expand((p) => _scopeDependencies[p] ?? <DartType>[]).toSet();
+
+    for (var t in types) {
+      var stmt = _dischargeFreeType(t);
+      if (stmt != null) decls.add(stmt);
+    }
+    return decls;
+  }
+
+  /// Emit a JS expression that evaluates to the generator for [type].
+  ///
+  /// If [type] does not already have a generator name chosen for it,
+  /// assign it one, using [typeRep] as its initializer.
+  js_ast.Expression _nameType(DartType type, js_ast.Expression typeRep) {
+    if (!typeContainer.contains(type)) {
+      typeContainer[type] = typeRep;
+    }
+    return _unboundTypeIds[type] ?? typeContainer.access(type);
+  }
+
+  /// Record the dependencies of the type on its free variables.
+  ///
+  /// Returns true if [type] is a free type parameter (but not a bound) and so
+  /// is not locally hoisted.
   bool recordScopeDependencies(DartType type) {
+    if (_isNamed(type)) {
+      return false;
+    }
+
     var freeVariables = freeTypeParameters(type);
     // TODO(leafp): This is a hack to avoid trying to hoist out of
     // generic functions and generic function types.  This often degrades
@@ -200,6 +188,17 @@
       return true;
     }
 
+    // This is only reached when [type] is itself a bound that depends on a
+    // free type parameter.
+    // TODO(markzipan): Bounds are locally hoisted to their own JS identifiers,
+    // but we don't do this this for other types that depend on free variables,
+    // resulting in some duplicated runtime code. We may get some performance
+    // wins if we just locally hoist everything.
+    if (freeVariables.isNotEmpty) {
+      _unboundTypeIds[type] =
+          js_ast.TemporaryId(escapeIdentifier(_typeString(type)));
+    }
+
     for (var free in freeVariables) {
       // If `free` is a promoted type parameter, get the original one so we can
       // find it in our map.
@@ -212,10 +211,10 @@
   /// add the type and its representation to the table, returning an
   /// expression which implements the type (but which caches the value).
   js_ast.Expression nameType(DartType type, js_ast.Expression typeRep) {
-    if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
+    if (recordScopeDependencies(type)) {
       return typeRep;
     }
-    var name = _generators._nameType(type, typeRep);
+    var name = _nameType(type, typeRep);
     return js.call('#()', [name]);
   }
 
@@ -228,10 +227,10 @@
   js_ast.Expression nameFunctionType(
       FunctionType type, js_ast.Expression typeRep,
       {bool lazy = false}) {
-    if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
+    if (recordScopeDependencies(type)) {
       return lazy ? js_ast.ArrowFun([], typeRep) : typeRep;
     }
-    var name = _generators._nameType(type, typeRep);
+    var name = _nameType(type, typeRep);
     return lazy ? name : js.call('#()', [name]);
   }
 }
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 73cdcc9..155491d 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -19,7 +19,8 @@
     path: ../front_end
   kernel:
     path: ../kernel
-  meta: any
+  meta:
+    path: ../meta
   path: any
   source_maps: any
   source_span: any
@@ -27,10 +28,12 @@
     path: ../vm
 
 dev_dependencies:
-  analyzer: any
+  analyzer:
+    path: ../analyzer
   expect:
     path: ../expect
-  js: any
+  js:
+    path: ../js
   modular_test:
     path: ../modular_test
   package_config: any
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index ff0b230..236a3ef 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -8,12 +8,13 @@
 
 import 'package:cli_util/cli_util.dart';
 import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/module_builder.dart';
 import 'package:front_end/src/api_unstable/ddc.dart';
 import 'package:front_end/src/api_prototype/compiler_options.dart'
     show CompilerOptions;
 import 'package:front_end/src/compute_platform_binaries_location.dart';
 import 'package:front_end/src/fasta/incremental_serializer.dart';
-import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/ast.dart' show Component, Library;
 import 'package:kernel/target/targets.dart';
 import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
@@ -49,27 +50,36 @@
 
 class SetupCompilerOptions {
   static final sdkRoot = computePlatformBinariesLocation();
-  static final sdkSummaryPath = p.join(sdkRoot.path, 'ddc_sdk.dill');
+  static final sdkUnsoundSummaryPath = p.join(sdkRoot.path, 'ddc_sdk.dill');
+  static final sdkSoundSummaryPath =
+      p.join(sdkRoot.path, 'ddc_outline_sound.dill');
   static final librariesSpecificationUri =
       p.join(p.dirname(p.dirname(getSdkPath())), 'libraries.json');
 
-  static CompilerOptions getOptions() {
+  static CompilerOptions getOptions(bool soundNullSafety) {
     var options = CompilerOptions()
       ..verbose = false // set to true for debugging
       ..sdkRoot = sdkRoot
       ..target = DevCompilerTarget(TargetFlags())
       ..librariesSpecificationUri = Uri.base.resolve('sdk/lib/libraries.json')
       ..omitPlatform = true
-      ..sdkSummary = sdkRoot.resolve(sdkSummaryPath)
+      ..sdkSummary = sdkRoot.resolve(
+          soundNullSafety ? sdkSoundSummaryPath : sdkUnsoundSummaryPath)
       ..environmentDefines = const {};
     return options;
   }
 
-  List<String> errors;
-  final CompilerOptions options;
+  static final String dartUnsoundComment = '// @dart = 2.9';
+  static final String dartSoundComment = '//';
 
-  SetupCompilerOptions() : options = getOptions() {
-    errors = <String>[];
+  final List<String> errors = [];
+  final CompilerOptions options;
+  final String dartLangComment;
+
+  SetupCompilerOptions(bool soundNullSafety)
+      : options = getOptions(soundNullSafety),
+        dartLangComment =
+            soundNullSafety ? dartSoundComment : dartUnsoundComment {
     options.onDiagnostic = (DiagnosticMessage m) {
       errors.addAll(m.plainTextFormatted);
     };
@@ -97,7 +107,7 @@
   final Uri importUri;
 
   Module(this.importUri, this.fileUri)
-      : name = importUri.pathSegments.last.replaceAll('.dart', ''),
+      : name = libraryUriToJsIdentifier(importUri),
         path = importUri.scheme == 'package'
             ? 'packages/${importUri.path}'
             : importUri.path;
@@ -124,20 +134,31 @@
 
   Future<TestCompilationResult> compile(
       {Uri input,
+      Uri packages,
       int line,
       int column,
       Map<String, String> scope,
       String expression}) async {
     // initialize incremental compiler and create component
+    setup.options.packagesFileUri = packages;
     var compiler = DevelopmentIncrementalCompiler(setup.options, input);
     var component = await compiler.computeDelta();
+    component.computeCanonicalNames();
 
     // initialize ddc
     var classHierarchy = compiler.getClassHierarchy();
     var compilerOptions = SharedCompilerOptions(replCompile: true);
     var coreTypes = compiler.getCoreTypes();
-    var kernel2jsCompiler = ProgramCompiler(
-        component, classHierarchy, compilerOptions, const {}, const {},
+
+    final importToSummary = Map<Library, Component>.identity();
+    final summaryToModule = Map<Component, String>.identity();
+    for (var lib in component.libraries) {
+      importToSummary[lib] = component;
+    }
+    summaryToModule[component] = 'foo.dart';
+
+    var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
+        compilerOptions, importToSummary, summaryToModule,
         coreTypes: coreTypes);
     kernel2jsCompiler.emitModule(component);
 
@@ -152,19 +173,13 @@
 
     // collect all module names and paths
     var moduleInfo = _collectModules(component);
-
-    var modules =
-        moduleInfo.map((k, v) => MapEntry<String, String>(v.name, v.path));
-    modules['dart'] = 'dart_sdk';
-    modules['core'] = 'dart_sdk';
-
     var module = moduleInfo[input];
 
     setup.errors.clear();
 
     // compile
     var jsExpression = await evaluator.compileExpressionToJs(
-        module.package, line, column, modules, scope, module.name, expression);
+        module.package, line, column, scope, expression);
 
     if (setup.errors.isNotEmpty) {
       jsExpression = setup.errors.toString().replaceAll(
@@ -193,6 +208,7 @@
   Directory tempDir;
   final String source;
   Uri input;
+  Uri packages;
   File file;
   int line;
 
@@ -204,6 +220,21 @@
     input = tempDir.uri.resolve('foo.dart');
     file = File.fromUri(input)..createSync();
     file.writeAsStringSync(source);
+
+    packages = tempDir.uri.resolve('package_config.json');
+    file = File.fromUri(packages)..createSync();
+    file.writeAsStringSync('''
+      {
+        "configVersion": 2,
+        "packages": [
+          {
+            "name": "foo",
+            "rootUri": "./",
+            "packageUri": "./"
+          }
+        ]
+      }
+      ''');
   }
 
   void delete() {
@@ -217,6 +248,7 @@
       String expectedResult}) async {
     var result = await TestCompiler(options).compile(
         input: input,
+        packages: packages,
         line: line,
         column: 1,
         scope: scope,
@@ -233,7 +265,9 @@
   }
 
   String _normalize(String text) {
-    return text.replaceAll(RegExp('\'.*foo.dart\''), '\'foo.dart\'');
+    return text
+        .replaceAll(RegExp('\'.*foo.dart\''), '\'foo.dart\'')
+        .replaceAll(RegExp('\".*foo.dart\"'), '\'foo.dart\'');
   }
 
   Matcher _matches(String text) {
@@ -256,1584 +290,1604 @@
 }
 
 void main() {
-  var options = SetupCompilerOptions();
+  group('Unsound null safety:', () {
+    var options = SetupCompilerOptions(false);
 
-  group('Expression compiler tests in extension method:', () {
-    const source = '''
-      // @dart = 2.9
-      extension NumberParsing on String {
-        int parseInt() {
-          var ret = int.parse(this);
-          /* evaluation placeholder */
-          return ret;
-        }
-      }
-      main() => 0;
-    ''';
-
-    TestDriver driver;
-
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'ret': '1234'},
-          expression: 'typo',
-          expectedError: "Error: Getter not found: 'typo'");
-    });
-
-    test('local (trimmed scope)', () async {
-      // Test that current expression evaluation works in extension methods.
-      //
-      // Note: the actual scope is {#this, ret}, but #this is effectively
-      // removed in the expression compilator because it does not exist
-      // in JavaScript code.
-      // See (full scope) tests for what will the evaluation will look like
-      // when the mapping from dart symbols to JavaScipt symbols is added.
-      await driver.check(
-          scope: <String, String>{'ret': '1234'},
-          expression: 'ret',
-          expectedResult: '''
-          (function(ret) {
+    group('Expression compiler tests in extension method:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            var ret = int.parse(this);
+            /* evaluation placeholder */
             return ret;
-          }(
-            1234
-          ))
-          ''');
-    });
-
-    test('local (full scope)', () async {
-      // Test evalution in extension methods in the future when the mapping
-      // from kernel symbols to dartdevc symbols is added.
-      //
-      // Note: this currently fails due to
-      // - incremental compiler not allowing #this as a parameter name
-      await driver.check(
-          scope: <String, String>{'ret': '1234', '#this': 'this'},
-          expression: 'ret',
-          expectedError:
-              "Illegal parameter name '#this' found during expression compilation.");
-    });
-
-    test('this (full scope)', () async {
-      // Test evalution in extension methods in the future when the mapping
-      // from kernel symbols to dartdevc symbols is added.
-      //
-      // Note: this currently fails due to
-      // - incremental compiler not allowing #this as a parameter name
-      // - incremental compiler not mapping 'this' from user input to '#this'
-      await driver.check(
-          scope: <String, String>{'ret': '1234', '#this': 'this'},
-          expression: 'this',
-          expectedError:
-              "Illegal parameter name '#this' found during expression compilation.");
-    });
-  });
-
-  group('Expression compiler tests in static function:', () {
-    const source = '''
-      // @dart = 2.9
-      int foo(int x, {int y}) {
-        int z = 0;
-        /* evaluation placeholder */
-        return x + y + z;
-      }
-
-      main() => 0;
+          }
+        }
+        main() => 0;
       ''';
 
-    TestDriver driver;
+      TestDriver driver;
 
-    setUp(() {
-      driver = TestDriver(options, source);
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'ret': '1234'},
+            expression: 'typo',
+            expectedError: "Error: Getter not found: 'typo'");
+      });
+
+      test('local (trimmed scope)', () async {
+        // Test that current expression evaluation works in extension methods.
+        //
+        // Note: the actual scope is {#this, ret}, but #this is effectively
+        // removed in the expression compilator because it does not exist
+        // in JavaScript code.
+        // See (full scope) tests for what will the evaluation will look like
+        // when the mapping from dart symbols to JavaScipt symbols is added.
+        await driver.check(
+            scope: <String, String>{'ret': '1234'},
+            expression: 'ret',
+            expectedResult: '''
+            (function(ret) {
+              return ret;
+            }(
+              1234
+            ))
+            ''');
+      });
+
+      test('local (full scope)', () async {
+        // Test evalution in extension methods in the future when the mapping
+        // from kernel symbols to dartdevc symbols is added.
+        //
+        // Note: this currently fails due to
+        // - incremental compiler not allowing #this as a parameter name
+        await driver.check(
+            scope: <String, String>{'ret': '1234', '#this': 'this'},
+            expression: 'ret',
+            expectedError:
+                "Illegal parameter name '#this' found during expression compilation.");
+      });
+
+      test('this (full scope)', () async {
+        // Test evalution in extension methods in the future when the mapping
+        // from kernel symbols to dartdevc symbols is added.
+        //
+        // Note: this currently fails due to
+        // - incremental compiler not allowing #this as a parameter name
+        // - incremental compiler not mapping 'this' from user input to '#this'
+        await driver.check(
+            scope: <String, String>{'ret': '1234', '#this': 'this'},
+            expression: 'this',
+            expectedError:
+                "Illegal parameter name '#this' found during expression compilation.");
+      });
     });
 
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
-          expression: 'typo',
-          expectedError: "Getter not found: \'typo\'");
-    });
-
-    test('local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
-          expression: 'x',
-          expectedResult: '''
-          (function(x, y, z) {
-            return x;
-          }(
-            1,
-            2,
-            3
-          ))
-          ''');
-    });
-
-    test('formal', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
-          expression: 'y',
-          expectedResult: '''
-          (function(x, y, z) {
-            return y;
-          }(
-            1,
-            2,
-            3
-          ))
-          ''');
-    });
-
-    test('named formal', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
-          expression: 'z',
-          expectedResult: '''
-          (function(x, y, z) {
-            return z;
-          }(
-            1,
-            2,
-            3
-          ))
-          ''');
-    });
-
-    test('function', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
-          expression: 'main',
-          expectedResult: '''
-          (function(x, y, z) {
-            var VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))();
-            dart.defineLazy(CT, {
-              get C0() {
-                return C0 = dart.fn(foo.main, VoidTodynamic());
-              }
-            }, false);
-            var C0;
-            return C0 || CT.C0;
-          }(
-            1,
-            2,
-            3
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in method:', () {
-    const source = '''
-      // @dart = 2.9
-      extension NumberParsing on String {
-        int parseInt() {
-          return int.parse(this);
-        }
-      }
-
-      int global = 42;
-
-      class C {
-        C(int this.field, int this._field);
-
-        static int staticField = 0;
-        static int _staticField = 1;
-
-        int _field;
-        int field;
-
-        int methodFieldAccess(int x) {
+    group('Expression compiler tests in static function:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int foo(int x, {int y}) {
+          int z = 0;
           /* evaluation placeholder */
-          return x + _field + _staticField;
+          return x + y + z;
         }
 
-        Future<int> asyncMethod(int x) async {
-          return x;
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'typo',
+            expectedError: "Getter not found: \'typo\'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x, y, z) {
+              return x;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+
+      test('formal', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'y',
+            expectedResult: '''
+            (function(x, y, z) {
+              return y;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+
+      test('named formal', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'z',
+            expectedResult: '''
+            (function(x, y, z) {
+              return z;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+
+      test('function', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'main',
+            expectedResult: '''
+            (function(x, y, z) {
+              var VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))();
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C0 = dart.fn(foo.main, VoidTodynamic());
+                }
+              }, false);
+              var C0;
+              return C0 || CT.C0;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in method:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
         }
-      }
 
-      main() => 0;
-      ''';
+        int global = 42;
 
-    TestDriver driver;
+        class C {
+          C(int this.field, int this._field);
 
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
+          static int staticField = 0;
+          static int _staticField = 1;
 
-    tearDown(() {
-      driver.delete();
-    });
+          int _field;
+          int field;
 
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'typo',
-          expectedError: "The getter 'typo' isn't defined for the class 'C'");
-    });
+          int methodFieldAccess(int x) {
+            /* evaluation placeholder */
+            return x + _field + _staticField;
+          }
 
-    test('local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x',
-          expectedResult: '''
-          (function(x) {
+          Future<int> asyncMethod(int x) async {
             return x;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('this', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'this',
-          expectedResult: '''
-          (function(x) {
-            return this;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using locals', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + 1',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + 1;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + staticField',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(foo.C.staticField);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using private static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + _staticField',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _staticField = dart.privateName(foo, "_staticField");
-            return dart.notNull(x) + dart.notNull(foo.C._staticField);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + field',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(this.field);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using private fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + _field',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return dart.notNull(x) + dart.notNull(this[_field]);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using globals', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + global',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(foo.global);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'methodFieldAccess(2)',
-          expectedResult: '''
-          (function(x) {
-            return this.methodFieldAccess(2);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('async method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'asyncMethod(2)',
-          expectedResult: '''
-          (function(x) {
-            return this.asyncMethod(2);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('extension method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '"1234".parseInt()',
-          expectedResult: '''
-          (function(x) {
-            return foo['NumberParsing|parseInt']("1234");
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('private field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '_field = 2',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return this[_field] = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'field = 2',
-          expectedResult: '''
-          (function(x) {
-            return this.field = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('private static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '_staticField = 2',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _staticField = dart.privateName(foo, "_staticField");
-            return foo.C._staticField = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'staticField = 2',
-          expectedResult: '''
-          (function(x) {
-            return foo.C.staticField = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in method with no field access:', () {
-    const source = '''
-      // @dart = 2.9
-      extension NumberParsing on String {
-        int parseInt() {
-          return int.parse(this);
+          }
         }
-      }
 
-      int global = 42;
+        main() => 0;
+        ''';
 
-      class C {
-        C(int this.field, int this._field);
+      TestDriver driver;
 
-        static int staticField = 0;
-        static int _staticField = 1;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
 
-        int _field;
-        int field;
+      tearDown(() {
+        driver.delete();
+      });
 
-        int methodNoFieldAccess(int x) {
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x) {
+              return x;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('this', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'this',
+            expectedResult: '''
+            (function(x) {
+              return this;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using locals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + 1',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + 1;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C.staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C._staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + field',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(this.field);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _field',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return dart.notNull(x) + dart.notNull(this[_field]);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using globals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + global',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.global);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'methodFieldAccess(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.methodFieldAccess(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('async method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'asyncMethod(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.asyncMethod(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('extension method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '"1234".parseInt()',
+            expectedResult: '''
+            (function(x) {
+              return foo['NumberParsing|parseInt']("1234");
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_field = 2',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return this[_field] = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'field = 2',
+            expectedResult: '''
+            (function(x) {
+              return this.field = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C._staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C.staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in method with no field access:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
+
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field);
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodNoFieldAccess(int x) {
+            /* evaluation placeholder */
+            return x;
+          }
+
+          Future<int> asyncMethod(int x) async {
+            return x;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('expression using static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C.staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C._staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + field',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(this.field);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _field',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return dart.notNull(x) + dart.notNull(this[_field]);
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_field = 2',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return this[_field] = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'field = 2',
+            expectedResult: '''
+            (function(x) {
+              return this.field = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C._staticField = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C.staticField = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in async method:', () {
+      var source = '''
+        ${options.dartLangComment}
+        class C {
+          C(int this.field, int this._field);
+
+          int _field;
+          int field;
+
+          Future<int> asyncMethod(int x) async {
+            /* evaluation placeholder */
+            return x;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x) {
+              return x;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('this', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'this',
+            expectedResult: '''
+            (function(x) {
+              return this;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in global function:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
+
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field);
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodFieldAccess(int x) {
+            return (x + _field + _staticField);
+          }
+          int methodFieldAccess(int x) {
+            return (x)
+          }
+
+          Future<int> asyncMethod(int x) async {
+            return x;
+          }
+        }
+
+        int main() {
+          int x = 15;
+          var c = C(1, 2);
           /* evaluation placeholder */
-          return x;
+          return 0;
         }
+        ''';
 
-        Future<int> asyncMethod(int x) async {
-          return x;
-        }
-      }
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
 
-      main() => 0;
-      ''';
+      tearDown(() {
+        driver.delete();
+      });
 
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'typo',
+            expectedError: "Getter not found: 'typo'.");
+      });
 
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'typo',
-          expectedError: "The getter 'typo' isn't defined for the class 'C'");
-    });
-
-    test('expression using static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + staticField',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(foo.C.staticField);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using private static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + _staticField',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _staticField = dart.privateName(foo, "_staticField");
-            return dart.notNull(x) + dart.notNull(foo.C._staticField);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + field',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(this.field);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using private fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + _field',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return dart.notNull(x) + dart.notNull(this[_field]);
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-
-    test('private field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '_field = 2',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return this[_field] = 2;
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-
-    test('field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'field = 2',
-          expectedResult: '''
-          (function(x) {
-            return this.field = 2;
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-
-    test('private static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '_staticField = 2',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _staticField = dart.privateName(foo, "_staticField");
-            return foo.C._staticField = 2;
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-
-    test('static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'staticField = 2',
-          expectedResult: '''
-          (function(x) {
-            return foo.C.staticField = 2;
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in async method:', () {
-    const source = '''
-      // @dart = 2.9
-      class C {
-        C(int this.field, int this._field);
-
-        int _field;
-        int field;
-
-        Future<int> asyncMethod(int x) async {
-          /* evaluation placeholder */
-          return x;
-        }
-      }
-
-      main() => 0;
-      ''';
-
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'typo',
-          expectedError: "The getter 'typo' isn't defined for the class 'C'");
-    });
-
-    test('local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x',
-          expectedResult: '''
-          (function(x) {
-            return x;
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-
-    test('this', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'this',
-          expectedResult: '''
-          (function(x) {
-            return this;
-          }.bind(this)(
-          1
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in global function:', () {
-    const source = '''
-      // @dart = 2.9
-      extension NumberParsing on String {
-        int parseInt() {
-          return int.parse(this);
-        }
-      }
-
-      int global = 42;
-
-      class C {
-        C(int this.field, int this._field);
-
-        static int staticField = 0;
-        static int _staticField = 1;
-
-        int _field;
-        int field;
-
-        int methodFieldAccess(int x) {
-          return (x + _field + _staticField);
-        }
-        int methodFieldAccess(int x) {
-          return (x)
-        }
-
-        Future<int> asyncMethod(int x) async {
-          return x;
-        }
-      }
-
-      int main() {
-        int x = 15;
-        var c = C(1, 2);
-        /* evaluation placeholder */
-        return 0;
-      }
-      ''';
-
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'typo',
-          expectedError: "Getter not found: 'typo'.");
-    });
-
-    test('local with primitive type', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'x',
-          expectedResult: '''
-          (function(x, c) {
-            return x;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('local object', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c',
-          expectedResult: '''
-          (function(x, c) {
-            return c;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('create new object', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'C(1,3)',
-          expectedResult: '''
+      test('local with primitive type', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'x',
+            expectedResult: '''
             (function(x, c) {
-              return new foo.C.new(1, 3);
+              return x;
             }(
               1,
               null
             ))
             ''');
-    });
+      });
 
-    test('access field of new object', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'C(1,3)._field',
-          expectedResult: '''
-          (function(x, c) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return new foo.C.new(1, 3)[_field];
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('access static field', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'C.staticField',
-          expectedResult: '''
-          (function(x, c) {
-            return foo.C.staticField;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('expression using private static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'C._staticField',
-          expectedError: "Error: Getter not found: '_staticField'.");
-    });
-
-    test('access field', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c.field',
-          expectedResult: '''
-          (function(x, c) {
-            return c.field;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('access private field', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c._field',
-          expectedResult: '''
-          (function(x, c) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return c[_field];
-          }(
+      test('local object', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c',
+            expectedResult: '''
+            (function(x, c) {
+              return c;
+            }(
               1,
               null
-          ))
-          ''');
+            ))
+            ''');
+      });
+
+      test('create new object', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C(1,3)',
+            expectedResult: '''
+              (function(x, c) {
+                return new foo.C.new(1, 3);
+              }(
+                1,
+                null
+              ))
+              ''');
+      });
+
+      test('access field of new object', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C(1,3)._field',
+            expectedResult: '''
+            (function(x, c) {
+              let _field = dart.privateName(foo, "_field");
+              return new foo.C.new(1, 3)[_field];
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('access static field', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C.staticField',
+            expectedResult: '''
+            (function(x, c) {
+              return foo.C.staticField;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C._staticField',
+            expectedError: "Error: Getter not found: '_staticField'.");
+      });
+
+      test('access field', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.field',
+            expectedResult: '''
+            (function(x, c) {
+              return c.field;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('access private field', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c._field',
+            expectedResult: '''
+            (function(x, c) {
+              let _field = dart.privateName(foo, "_field");
+              return c[_field];
+            }(
+                1,
+                null
+            ))
+            ''');
+      });
+
+      test('method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.methodFieldAccess(2)',
+            expectedResult: '''
+            (function(x, c) {
+              return c.methodFieldAccess(2);
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('async method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.asyncMethod(2)',
+            expectedResult: '''
+            (function(x, c) {
+              return c.asyncMethod(2);
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('extension method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: '"1234".parseInt()',
+            expectedResult: '''
+            (function(x, c) {
+              return foo['NumberParsing|parseInt']("1234");
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c._field = 2',
+            expectedResult: '''
+            (function(x, c) {
+              let _field = dart.privateName(foo, "_field");
+              return c[_field] = 2;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.field = 2',
+            expectedResult: '''
+            (function(x, c) {
+              return c.field = 2;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C._staticField = 2',
+            expectedError: "Setter not found: '_staticField'.");
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C.staticField = 2',
+            expectedResult: '''
+            (function(x, c) {
+              return foo.C.staticField = 2;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('call global function from core library', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'print(x)',
+            expectedResult: '''
+            (function(x, c) {
+              return core.print(x);
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
     });
 
-    test('method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c.methodFieldAccess(2)',
-          expectedResult: '''
-          (function(x, c) {
-            return c.methodFieldAccess(2);
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('async method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c.asyncMethod(2)',
-          expectedResult: '''
-          (function(x, c) {
-            return c.asyncMethod(2);
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('extension method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: '"1234".parseInt()',
-          expectedResult: '''
-          (function(x, c) {
-            return foo['NumberParsing|parseInt']("1234");
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('private field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c._field = 2',
-          expectedResult: '''
-          (function(x, c) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return c[_field] = 2;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'c.field = 2',
-          expectedResult: '''
-          (function(x, c) {
-            return c.field = 2;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('private static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'C._staticField = 2',
-          expectedError: "Setter not found: '_staticField'.");
-    });
-
-    test('static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'C.staticField = 2',
-          expectedResult: '''
-          (function(x, c) {
-            return foo.C.staticField = 2;
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-
-    test('call global function from core library', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'print(x)',
-          expectedResult: '''
-          (function(x, c) {
-            return core.print(x);
-          }(
-            1,
-            null
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in closures:', () {
-    const source = r'''
-      // @dart = 2.9
-      int globalFunction() {
-      int x = 15;
-      var c = C(1, 2);
-
-      var outerClosure = (int y) {
-        var closureCaptureInner = (int z) {
-          /* evaluation placeholder */
-          print('$y+$z');
-        };
-        closureCaptureInner(0);
-      };
-
-      outerClosure(3);
-      return 0;
-    }
-
-    main() => 0;
-    ''';
-
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
-          expression: 'typo',
-          expectedError: "Getter not found: 'typo'.");
-    });
-
-    test('expression using uncaptured variables', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
-          expression: r"'$x+$y+$z'",
-          expectedResult: '''
-          (function(x, c, y, z) {
-            return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
-          }(
-            1,
-            null,
-            3,
-            0
-          ))
-          ''');
-    });
-
-    test('expression using captured variables', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
-          expression: r"'$y+$z'",
-          expectedResult: '''
-          (function(x, c, y, z) {
-            return dart.str(y) + "+" + dart.str(z);
-          }(
-            1,
-            null,
-            3,
-            0
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in method with no type use', () {
-    const source = '''
-      // @dart = 2.9
-      abstract class Key {
-        const factory Key(String value) = ValueKey;
-        const Key.empty();
-      }
-
-      abstract class LocalKey extends Key {
-        const LocalKey() : super.empty();
-      }
-
-      class ValueKey implements LocalKey {
-        const ValueKey(this.value);
-        final String value;
-      }
-
-      class MyClass {
-        const MyClass(this._t);
-        final int _t;
-      }
-
-      int bar(int p){
-        return p;
-      }
-      int baz(String t){
-        return t;
-      }
-      void main() {
-        var k = Key('t');
-        MyClass c = MyClass(0);
-        int p = 1;
-        const t = 1;
-
-        /* evaluation placeholder */
-        print('\$c, \$k, \$t');
-      }
-      ''';
-
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('call function using type', () async {
-      await driver.check(
-          scope: <String, String>{'p': '1'},
-          expression: 'bar(p)',
-          expectedResult: '''
-          (function(p) {
-            return foo.bar(p);
-          }(
-            1
-          ))
-          ''');
-    });
-
-    test('call function using type', () async {
-      await driver.check(
-          scope: <String, String>{'p': '0'},
-          expression: 'baz(p as String)',
-          expectedResult: '''
-          (function(p) {
-            var StringL = () => (StringL = dart.constFn(dart.legacy(core.String)))();
-            return foo.baz(StringL().as(p));
-          }(
-          0
-          ))
-          ''');
-    });
-
-    test('evaluate new const expression', () async {
-      await driver.check(
-          scope: <String, String>{'p': '1'},
-          expression: 'const MyClass(1)',
-          expectedResult: '''
-          (function(p) {
-             dart.defineLazy(CT, {
-               get C0() {
-                 return C0 = dart.const({
-                   __proto__: foo.MyClass.prototype,
-                   [_t]: 1
-                 });
-               }
-             }, false);
-             var C0;
-             return C0 || CT.C0;
-          }(
-            1
-          ))
-          ''');
-    });
-
-    test('evaluate optimized const expression', () async {
-      await driver.check(
-          scope: <String, String>{},
-          expression: 't',
-          expectedResult: '''
-          (function() {
-            return 1;
-          }(
-          ))
-          ''');
-    },
-        skip: 'Cannot compile constants optimized away by the frontend. '
-            'Issue: https://github.com/dart-lang/sdk/issues/41999');
-
-    test('evaluate factory constructor call', () async {
-      await driver.check(
-          scope: <String, String>{'p': '1'},
-          expression: "Key('t')",
-          expectedResult: '''
-          (function(p) {
-            return new foo.ValueKey.new("t");
-          }(
-            1
-          ))
-          ''');
-    });
-
-    test('evaluate const factory constructor call', () async {
-      await driver.check(
-          scope: <String, String>{'p': '1'},
-          expression: "const Key('t')",
-          expectedResult: '''
-          (function(p) {
-            dart.defineLazy(CT, {
-              get C0() {
-                return C0 = dart.const({
-                  __proto__: foo.ValueKey.prototype,
-                  [value]: "t"
-                  });
-                }
-            }, false);
-            var C0;
-            return C0 || CT.C0;
-          }(
-            1
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in constructor:', () {
-    const source = '''
-      // @dart = 2.9
-      extension NumberParsing on String {
-        int parseInt() {
-          return int.parse(this);
-        }
-      }
-
-      int global = 42;
-
-      class C {
-        C(int this.field, int this._field) {
-          int x = 1;
-          /* evaluation placeholder */
-          print(this.field);
-        }
-
-        static int staticField = 0;
-        static int _staticField = 1;
-
-        int _field;
-        int field;
-
-        int methodFieldAccess(int t) {
-          return t + _field + _staticField;
-        }
-
-        Future<int> asyncMethod(int t) async {
-          return t;
-        }
-      }
-
-      main() => 0;
-      ''';
-
-    TestDriver driver;
-
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('compilation error', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'typo',
-          expectedError: "The getter 'typo' isn't defined for the class 'C'");
-    });
-
-    test('local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x',
-          expectedResult: '''
-          (function(x) {
-            return x;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('this', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'this',
-          expectedResult: '''
-          (function(x) {
-            return this;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using locals', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + 1',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + 1;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + staticField',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(foo.C.staticField);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using private static fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + _staticField',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _staticField = dart.privateName(foo, "_staticField");
-            return dart.notNull(x) + dart.notNull(foo.C._staticField);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + field',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(this.field);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('expression using private fields', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + _field',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _field = dart.privateName(foo, "_field");
-            return dart.notNull(x) + dart.notNull(this[_field]);
-          }.bind(this)(
-              1
-          ))
-          ''');
-    });
-
-    test('expression using globals', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'x + global',
-          expectedResult: '''
-          (function(x) {
-            return dart.notNull(x) + dart.notNull(foo.global);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'methodFieldAccess(2)',
-          expectedResult: '''
-          (function(x) {
-            return this.methodFieldAccess(2);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('async method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'asyncMethod(2)',
-          expectedResult: '''
-          (function(x) {
-            return this.asyncMethod(2);
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('extension method call', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '"1234".parseInt()',
-          expectedResult: '''
-        (function(x) {
-          return foo['NumberParsing|parseInt']("1234");
-        }.bind(this)(
-          1
-        ))
-        ''');
-    });
-
-    test('private field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '_field = 2',
-          expectedResult: '''
-        (function(x) {
-          let foo = require('foo.dart').foo;
-          let _field = dart.privateName(foo, "_field");
-          return this[_field] = 2;
-        }.bind(this)(
-          1
-        ))
-        ''');
-    });
-
-    test('field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'field = 2',
-          expectedResult: '''
-          (function(x) {
-            return this.field = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('private static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: '_staticField = 2',
-          expectedResult: '''
-          (function(x) {
-            let foo = require('foo.dart').foo;
-            let _staticField = dart.privateName(foo, "_staticField");
-            return foo.C._staticField = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-
-    test('static field modification', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1'},
-          expression: 'staticField = 2',
-          expectedResult: '''
-          (function(x) {
-            return foo.C.staticField = 2;
-          }.bind(this)(
-            1
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in loops:', () {
-    const source = r'''
-      // @dart = 2.9
-      int globalFunction() {
+    group('Expression compiler tests in closures:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
         int x = 15;
         var c = C(1, 2);
 
-        for(int i = 0; i < 10; i++) {
-          /* evaluation placeholder */
-          print('$i+$x');
+        var outerClosure = (int y) {
+          var closureCaptureInner = (int z) {
+            /* evaluation placeholder */
+            print('\$y+\$z');
+          };
+          closureCaptureInner(0);
         };
+
+        outerClosure(3);
         return 0;
       }
 
       main() => 0;
       ''';
 
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
+            expression: 'typo',
+            expectedError: "Getter not found: 'typo'.");
+      });
+
+      test('expression using uncaptured variables', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
+            expression: r"'$x+$y+$z'",
+            expectedResult: '''
+            (function(x, c, y, z) {
+              return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
+            }(
+              1,
+              null,
+              3,
+              0
+            ))
+            ''');
+      });
+
+      test('expression using captured variables', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
+            expression: r"'$y+$z'",
+            expectedResult: '''
+            (function(x, c, y, z) {
+              return dart.str(y) + "+" + dart.str(z);
+            }(
+              1,
+              null,
+              3,
+              0
+            ))
+            ''');
+      });
     });
 
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('expression using local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
-          expression: 'x',
-          expectedResult: '''
-          (function(x, c, i) {
-            return x;
-          }(
-            1,
-            null,
-            0
-          ))
-          ''');
-    });
-
-    test('expression using loop variable', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
-          expression: 'i',
-          expectedResult: '''
-          (function(x, c, i) {
-            return i;
-          }(
-            1,
-            null,
-            0
-          ))
-          ''');
-    });
-  });
-
-  group('Expression compiler tests in conditional (then):', () {
-    const source = r'''
-      // @dart = 2.9
-      int globalFunction() {
-        int x = 1;
-        var c = C(1, 2);
-
-        if (x == 14) {
-          int y = 3;
-          /* evaluation placeholder */
-          print('$y+$x');
-        } else {
-          int z = 3;
-          print('$z+$x');
+    group('Expression compiler tests in method with no type use:', () {
+      var source = '''
+        ${options.dartLangComment}
+        abstract class Key {
+          const factory Key(String value) = ValueKey;
+          const Key.empty();
         }
-        return 0;
-      }
 
-      main() => 0;
-      ''';
-
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
-
-    tearDown(() {
-      driver.delete();
-    });
-
-    test('expression using local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
-          expression: 'y',
-          expectedResult: '''
-          (function(x, c, y) {
-            return y;
-          }(
-            1,
-            null,
-            3
-          ))
-          ''');
-    });
-
-    test('expression using local out of scope', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
-          expression: 'z',
-          expectedError: "Error: Getter not found: 'z'");
-    });
-  });
-
-  group('Expression compiler tests in conditional (else):', () {
-    const source = r'''
-      // @dart = 2.9
-      int globalFunction() {
-        int x = 1;
-        var c = C(1, 2);
-
-        if (x == 14) {
-          int y = 3;
-          print('$y+$x');
-        } else {
-          int z = 3;
-          /* evaluation placeholder */
-          print('$z+$x');
+        abstract class LocalKey extends Key {
+          const LocalKey() : super.empty();
         }
-        return 0;
-      }
 
-      main() => 0;
-      ''';
+        class ValueKey implements LocalKey {
+          const ValueKey(this.value);
+          final String value;
+        }
 
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
+        class MyClass {
+          const MyClass(this._t);
+          final int _t;
+        }
+
+        int bar(int p){
+          return p;
+        }
+        int baz(String t){
+          return t;
+        }
+        void main() {
+          var k = Key('t');
+          MyClass c = MyClass(0);
+          int p = 1;
+          const t = 1;
+
+          /* evaluation placeholder */
+          print('\$c, \$k, \$t');
+        }
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('call function using type', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: 'bar(p)',
+            expectedResult: '''
+            (function(p) {
+              return foo.bar(p);
+            }(
+              1
+            ))
+            ''');
+      });
+
+      test('call function using type', () async {
+        await driver.check(
+            scope: <String, String>{'p': '0'},
+            expression: 'baz(p as String)',
+            expectedResult: '''
+            (function(p) {
+              var StringL = () => (StringL = dart.constFn(dart.legacy(core.String)))();
+              return foo.baz(StringL().as(p));
+            }(
+            0
+            ))
+            ''');
+      });
+
+      test('evaluate new const expression', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: 'const MyClass(1)',
+            expectedResult: '''
+            (function(p) {
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C0 = dart.const({
+                    __proto__: foo.MyClass.prototype,
+                    [_t]: 1
+                  });
+                }
+              }, false);
+              var C0;
+              return C0 || CT.C0;
+            }(
+              1
+            ))
+            ''');
+      });
+
+      test('evaluate optimized const expression', () async {
+        await driver.check(
+            scope: <String, String>{},
+            expression: 't',
+            expectedResult: '''
+            (function() {
+              return 1;
+            }(
+            ))
+            ''');
+      },
+          skip: 'Cannot compile constants optimized away by the frontend. '
+              'Issue: https://github.com/dart-lang/sdk/issues/41999');
+
+      test('evaluate factory constructor call', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: "Key('t')",
+            expectedResult: '''
+            (function(p) {
+              return new foo.ValueKey.new("t");
+            }(
+              1
+            ))
+            ''');
+      });
+
+      test('evaluate const factory constructor call', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: "const Key('t')",
+            expectedResult: '''
+            (function(p) {
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C0 = dart.const({
+                    __proto__: foo.ValueKey.prototype,
+                    [value]: "t"
+                    });
+                  }
+              }, false);
+              var C0;
+              return C0 || CT.C0;
+            }(
+              1
+            ))
+            ''');
+      });
     });
 
-    tearDown(() {
-      driver.delete();
-    });
+    group('Expression compiler tests in constructor:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
 
-    test('expression using local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
-          expression: 'z',
-          expectedResult: '''
-          (function(x, c, z) {
-            return z;
-          }(
-            1,
-            null,
-            3
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field) {
+            int x = 1;
+            /* evaluation placeholder */
+            print(this.field);
+          }
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodFieldAccess(int t) {
+            return t + _field + _staticField;
+          }
+
+          Future<int> asyncMethod(int t) async {
+            return t;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x) {
+              return x;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('this', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'this',
+            expectedResult: '''
+            (function(x) {
+              return this;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using locals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + 1',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + 1;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C.staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C._staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + field',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(this.field);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _field',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return dart.notNull(x) + dart.notNull(this[_field]);
+            }.bind(this)(
+                1
+            ))
+            ''');
+      });
+
+      test('expression using globals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + global',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.global);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'methodFieldAccess(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.methodFieldAccess(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('async method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'asyncMethod(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.asyncMethod(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('extension method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '"1234".parseInt()',
+            expectedResult: '''
+          (function(x) {
+            return foo['NumberParsing|parseInt']("1234");
+          }.bind(this)(
+            1
           ))
           ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_field = 2',
+            expectedResult: '''
+          (function(x) {
+            let _field = dart.privateName(foo, "_field");
+            return this[_field] = 2;
+          }.bind(this)(
+            1
+          ))
+          ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'field = 2',
+            expectedResult: '''
+            (function(x) {
+              return this.field = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C._staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C.staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
     });
 
-    test('expression using local out of scope', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
-          expression: 'y',
-          expectedError: "Error: Getter not found: 'y'");
-    });
-  });
+    group('Expression compiler tests in simple loops:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 15;
+          var c = C(1, 2);
 
-  group('Expression compiler tests after conditionals:', () {
-    const source = r'''
-      // @dart = 2.9
+          for(int i = 0; i < 10; i++) {
+            /* evaluation placeholder */
+            print('\$i+\$x');
+          };
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x, c, i) {
+              return x;
+            }(
+              1,
+              null,
+              0
+            ))
+            ''');
+      });
+
+      test('expression using loop variable', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+            expression: 'i',
+            expectedResult: '''
+            (function(x, c, i) {
+              return i;
+            }(
+              1,
+              null,
+              0
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in iterator loops:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          var l = <String>['1', '2', '3'];
+
+          for(var e in l) {
+            /* evaluation placeholder */
+            print(e);
+          };
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression loop variable', () async {
+        await driver.check(
+            scope: <String, String>{'l': 'null', 'e': '1'},
+            expression: 'e',
+            expectedResult: '''
+            (function(l, e) {
+              return e;
+            }(
+              null,
+              1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in conditional (then):', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 1;
+          var c = C(1, 2);
+
+          if (x == 14) {
+            int y = 3;
+            /* evaluation placeholder */
+            print('\$y+\$x');
+          } else {
+            int z = 3;
+            print('\$z+\$x');
+          }
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+            expression: 'y',
+            expectedResult: '''
+            (function(x, c, y) {
+              return y;
+            }(
+              1,
+              null,
+              3
+            ))
+            ''');
+      });
+
+      test('expression using local out of scope', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+            expression: 'z',
+            expectedError: "Error: Getter not found: 'z'");
+      });
+    });
+
+    group('Expression compiler tests in conditional (else):', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 1;
+          var c = C(1, 2);
+
+          if (x == 14) {
+            int y = 3;
+            print('\$y+\$x');
+          } else {
+            int z = 3;
+            /* evaluation placeholder */
+            print('\$z+\$x');
+          }
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+            expression: 'z',
+            expectedResult: '''
+            (function(x, c, z) {
+              return z;
+            }(
+              1,
+              null,
+              3
+            ))
+            ''');
+      });
+
+      test('expression using local out of scope', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+            expression: 'y',
+            expectedError: "Error: Getter not found: 'y'");
+      });
+    });
+
+    group('Expression compiler tests after conditionals:', () {
+      var source = '''
+      ${options.dartLangComment}
       int globalFunction() {
         int x = 1;
         var c = C(1, 2);
 
         if (x == 14) {
           int y = 3;
-          print('$y+$x');
+          print('\$y+\$x');
         } else {
           int z = 3;
-          print('$z+$x');
+          print('\$z+\$x');
         }
         /* evaluation placeholder */
         return 0;
@@ -1842,20 +1896,20 @@
       main() => 0;
       ''';
 
-    TestDriver driver;
-    setUp(() {
-      driver = TestDriver(options, source);
-    });
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
 
-    tearDown(() {
-      driver.delete();
-    });
+      tearDown(() {
+        driver.delete();
+      });
 
-    test('expression using local', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'x',
-          expectedResult: '''
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'x',
+            expectedResult: '''
           (function(x, c) {
             return x;
           }(
@@ -1863,13 +1917,1651 @@
             null
           ))
           ''');
+      });
+
+      test('expression using local out of scope', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'z',
+            expectedError: "Error: Getter not found: 'z'");
+      });
+    });
+  });
+
+  group('Sound null safety:', () {
+    var options = SetupCompilerOptions(true);
+
+    group('Expression compiler tests in extension method:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            var ret = int.parse(this);
+            /* evaluation placeholder */
+            return ret;
+          }
+        }
+        main() => 0;
+      ''';
+
+      TestDriver driver;
+
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'ret': '1234'},
+            expression: 'typo',
+            expectedError: "Error: Getter not found: 'typo'");
+      });
+
+      test('local (trimmed scope)', () async {
+        // Test that current expression evaluation works in extension methods.
+        //
+        // Note: the actual scope is {#this, ret}, but #this is effectively
+        // removed in the expression compilator because it does not exist
+        // in JavaScript code.
+        // See (full scope) tests for what will the evaluation will look like
+        // when the mapping from dart symbols to JavaScipt symbols is added.
+        await driver.check(
+            scope: <String, String>{'ret': '1234'},
+            expression: 'ret',
+            expectedResult: '''
+            (function(ret) {
+              return ret;
+            }(
+              1234
+            ))
+            ''');
+      });
+
+      test('local (full scope)', () async {
+        // Test evalution in extension methods in the future when the mapping
+        // from kernel symbols to dartdevc symbols is added.
+        //
+        // Note: this currently fails due to
+        // - incremental compiler not allowing #this as a parameter name
+        await driver.check(
+            scope: <String, String>{'ret': '1234', '#this': 'this'},
+            expression: 'ret',
+            expectedError:
+                "Illegal parameter name '#this' found during expression compilation.");
+      });
+
+      test('this (full scope)', () async {
+        // Test evalution in extension methods in the future when the mapping
+        // from kernel symbols to dartdevc symbols is added.
+        //
+        // Note: this currently fails due to
+        // - incremental compiler not allowing #this as a parameter name
+        // - incremental compiler not mapping 'this' from user input to '#this'
+        await driver.check(
+            scope: <String, String>{'ret': '1234', '#this': 'this'},
+            expression: 'this',
+            expectedError:
+                "Illegal parameter name '#this' found during expression compilation.");
+      });
     });
 
-    test('expression using local out of scope', () async {
-      await driver.check(
-          scope: <String, String>{'x': '1', 'c': 'null'},
-          expression: 'z',
-          expectedError: "Error: Getter not found: 'z'");
+    group('Expression compiler tests in static function:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int foo(int x, {int y}) {
+          int z = 0;
+          /* evaluation placeholder */
+          return x + y + z;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'typo',
+            expectedError: "Getter not found: \'typo\'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x, y, z) {
+              return x;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+
+      test('formal', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'y',
+            expectedResult: '''
+            (function(x, y, z) {
+              return y;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+
+      test('named formal', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'z',
+            expectedResult: '''
+            (function(x, y, z) {
+              return z;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+
+      test('function', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+            expression: 'main',
+            expectedResult: '''
+            (function(x, y, z) {
+              var VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))();
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C0 = dart.fn(foo.main, VoidTodynamic());
+                }
+              }, false);
+              var C0;
+              return C0 || CT.C0;
+            }(
+              1,
+              2,
+              3
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in method:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
+
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field);
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodFieldAccess(int x) {
+            /* evaluation placeholder */
+            return x + _field + _staticField;
+          }
+
+          Future<int> asyncMethod(int x) async {
+            return x;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x) {
+              return x;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('this', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'this',
+            expectedResult: '''
+            (function(x) {
+              return this;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using locals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + 1',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + 1;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C.staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C._staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + field',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(this.field);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _field',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return dart.notNull(x) + dart.notNull(this[_field]);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using globals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + global',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.global);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'methodFieldAccess(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.methodFieldAccess(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('async method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'asyncMethod(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.asyncMethod(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('extension method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '"1234".parseInt()',
+            expectedResult: '''
+            (function(x) {
+              return foo['NumberParsing|parseInt']("1234");
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_field = 2',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return this[_field] = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'field = 2',
+            expectedResult: '''
+            (function(x) {
+              return this.field = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C._staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C.staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in method with no field access:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
+
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field);
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodNoFieldAccess(int x) {
+            /* evaluation placeholder */
+            return x;
+          }
+
+          Future<int> asyncMethod(int x) async {
+            return x;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('expression using static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C.staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C._staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + field',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(this.field);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _field',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return dart.notNull(x) + dart.notNull(this[_field]);
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_field = 2',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return this[_field] = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'field = 2',
+            expectedResult: '''
+            (function(x) {
+              return this.field = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C._staticField = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C.staticField = 2;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in async method:', () {
+      var source = '''
+        ${options.dartLangComment}
+        class C {
+          C(int this.field, int this._field);
+
+          int _field;
+          int field;
+
+          Future<int> asyncMethod(int x) async {
+            /* evaluation placeholder */
+            return x;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x) {
+              return x;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+
+      test('this', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'this',
+            expectedResult: '''
+            (function(x) {
+              return this;
+            }.bind(this)(
+            1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in global function:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
+
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field);
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodFieldAccess(int x) {
+            return (x + _field + _staticField);
+          }
+          int methodFieldAccess(int x) {
+            return (x)
+          }
+
+          Future<int> asyncMethod(int x) async {
+            return x;
+          }
+        }
+
+        int main() {
+          int x = 15;
+          var c = C(1, 2);
+          /* evaluation placeholder */
+          return 0;
+        }
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'typo',
+            expectedError: "Getter not found: 'typo'.");
+      });
+
+      test('local with primitive type', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x, c) {
+              return x;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('local object', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c',
+            expectedResult: '''
+            (function(x, c) {
+              return c;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('create new object', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C(1,3)',
+            expectedResult: '''
+              (function(x, c) {
+                return new foo.C.new(1, 3);
+              }(
+                1,
+                null
+              ))
+              ''');
+      });
+
+      test('access field of new object', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C(1,3)._field',
+            expectedResult: '''
+            (function(x, c) {
+              let _field = dart.privateName(foo, "_field");
+              return new foo.C.new(1, 3)[_field];
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('access static field', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C.staticField',
+            expectedResult: '''
+            (function(x, c) {
+              return foo.C.staticField;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C._staticField',
+            expectedError: "Error: Getter not found: '_staticField'.");
+      });
+
+      test('access field', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.field',
+            expectedResult: '''
+            (function(x, c) {
+              return c.field;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('access private field', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c._field',
+            expectedResult: '''
+            (function(x, c) {
+              let _field = dart.privateName(foo, "_field");
+              return c[_field];
+            }(
+                1,
+                null
+            ))
+            ''');
+      });
+
+      test('method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.methodFieldAccess(2)',
+            expectedResult: '''
+            (function(x, c) {
+              return c.methodFieldAccess(2);
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('async method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.asyncMethod(2)',
+            expectedResult: '''
+            (function(x, c) {
+              return c.asyncMethod(2);
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('extension method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: '"1234".parseInt()',
+            expectedResult: '''
+            (function(x, c) {
+              return foo['NumberParsing|parseInt']("1234");
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c._field = 2',
+            expectedResult: '''
+            (function(x, c) {
+              let _field = dart.privateName(foo, "_field");
+              return c[_field] = 2;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'c.field = 2',
+            expectedResult: '''
+            (function(x, c) {
+              return c.field = 2;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C._staticField = 2',
+            expectedError: "Setter not found: '_staticField'.");
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'C.staticField = 2',
+            expectedResult: '''
+            (function(x, c) {
+              return foo.C.staticField = 2;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('call global function from core library', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'print(x)',
+            expectedResult: '''
+            (function(x, c) {
+              return core.print(x);
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in closures:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+        int x = 15;
+        var c = C(1, 2);
+
+        var outerClosure = (int y) {
+          var closureCaptureInner = (int z) {
+            /* evaluation placeholder */
+            print('\$y+\$z');
+          };
+          closureCaptureInner(0);
+        };
+
+        outerClosure(3);
+        return 0;
+      }
+
+      main() => 0;
+      ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
+            expression: 'typo',
+            expectedError: "Getter not found: 'typo'.");
+      });
+
+      test('expression using uncaptured variables', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
+            expression: r"'$x+$y+$z'",
+            expectedResult: '''
+            (function(x, c, y, z) {
+              return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
+            }(
+              1,
+              null,
+              3,
+              0
+            ))
+            ''');
+      });
+
+      test('expression using captured variables', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
+            expression: r"'$y+$z'",
+            expectedResult: '''
+            (function(x, c, y, z) {
+              return dart.str(y) + "+" + dart.str(z);
+            }(
+              1,
+              null,
+              3,
+              0
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in method with no type use:', () {
+      var source = '''
+        ${options.dartLangComment}
+        abstract class Key {
+          const factory Key(String value) = ValueKey;
+          const Key.empty();
+        }
+
+        abstract class LocalKey extends Key {
+          const LocalKey() : super.empty();
+        }
+
+        class ValueKey implements LocalKey {
+          const ValueKey(this.value);
+          final String value;
+        }
+
+        class MyClass {
+          const MyClass(this._t);
+          final int _t;
+        }
+
+        int bar(int p){
+          return p;
+        }
+        int baz(String t){
+          return t;
+        }
+        void main() {
+          var k = Key('t');
+          MyClass c = MyClass(0);
+          int p = 1;
+          const t = 1;
+
+          /* evaluation placeholder */
+          print('\$c, \$k, \$t');
+        }
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('call function not using type', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: 'bar(p)',
+            expectedResult: '''
+            (function(p) {
+              return foo.bar(p);
+            }(
+              1
+            ))
+            ''');
+      });
+
+      test('call function using type', () async {
+        await driver.check(
+            scope: <String, String>{'p': '0'},
+            expression: 'baz(p as String)',
+            expectedResult: '''
+            (function(p) {
+              return foo.baz(core.String.as(p));
+            }(
+              0
+            ))
+            ''');
+      });
+
+      test('evaluate new const expression', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: 'const MyClass(1)',
+            expectedResult: '''
+            (function(p) {
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C0 = dart.const({
+                    __proto__: foo.MyClass.prototype,
+                    [_t]: 1
+                  });
+                }
+              }, false);
+              var C0;
+              return C0 || CT.C0;
+            }(
+              1
+            ))
+            ''');
+      });
+
+      test('evaluate optimized const expression', () async {
+        await driver.check(
+            scope: <String, String>{},
+            expression: 't',
+            expectedResult: '''
+            (function() {
+              return 1;
+            }(
+            ))
+            ''');
+      },
+          skip: 'Cannot compile constants optimized away by the frontend. '
+              'Issue: https://github.com/dart-lang/sdk/issues/41999');
+
+      test('evaluate factory constructor call', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: "Key('t')",
+            expectedResult: '''
+            (function(p) {
+              return new foo.ValueKey.new("t");
+            }(
+              1
+            ))
+            ''');
+      });
+
+      test('evaluate const factory constructor call', () async {
+        await driver.check(
+            scope: <String, String>{'p': '1'},
+            expression: "const Key('t')",
+            expectedResult: '''
+            (function(p) {
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C0 = dart.const({
+                    __proto__: foo.ValueKey.prototype,
+                    [value]: "t"
+                    });
+                  }
+              }, false);
+              var C0;
+              return C0 || CT.C0;
+            }(
+              1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in constructor:', () {
+      var source = '''
+        ${options.dartLangComment}
+        extension NumberParsing on String {
+          int parseInt() {
+            return int.parse(this);
+          }
+        }
+
+        int global = 42;
+
+        class C {
+          C(int this.field, int this._field) {
+            int x = 1;
+            /* evaluation placeholder */
+            print(this.field);
+          }
+
+          static int staticField = 0;
+          static int _staticField = 1;
+
+          int _field;
+          int field;
+
+          int methodFieldAccess(int t) {
+            return t + _field + _staticField;
+          }
+
+          Future<int> asyncMethod(int t) async {
+            return t;
+          }
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('compilation error', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'typo',
+            expectedError: "The getter 'typo' isn't defined for the class 'C'");
+      });
+
+      test('local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x) {
+              return x;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('this', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'this',
+            expectedResult: '''
+            (function(x) {
+              return this;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using locals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + 1',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + 1;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C.staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private static fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _staticField',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.C._staticField);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + field',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(this.field);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('expression using private fields', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + _field',
+            expectedResult: '''
+            (function(x) {
+              let _field = dart.privateName(foo, "_field");
+              return dart.notNull(x) + dart.notNull(this[_field]);
+            }.bind(this)(
+                1
+            ))
+            ''');
+      });
+
+      test('expression using globals', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'x + global',
+            expectedResult: '''
+            (function(x) {
+              return dart.notNull(x) + dart.notNull(foo.global);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'methodFieldAccess(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.methodFieldAccess(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('async method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'asyncMethod(2)',
+            expectedResult: '''
+            (function(x) {
+              return this.asyncMethod(2);
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('extension method call', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '"1234".parseInt()',
+            expectedResult: '''
+          (function(x) {
+            return foo['NumberParsing|parseInt']("1234");
+          }.bind(this)(
+            1
+          ))
+          ''');
+      });
+
+      test('private field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_field = 2',
+            expectedResult: '''
+          (function(x) {
+            let _field = dart.privateName(foo, "_field");
+            return this[_field] = 2;
+          }.bind(this)(
+            1
+          ))
+          ''');
+      });
+
+      test('field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'field = 2',
+            expectedResult: '''
+            (function(x) {
+              return this.field = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('private static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: '_staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C._staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+
+      test('static field modification', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1'},
+            expression: 'staticField = 2',
+            expectedResult: '''
+            (function(x) {
+              return foo.C.staticField = 2;
+            }.bind(this)(
+              1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in loops:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 15;
+          var c = C(1, 2);
+
+          for(int i = 0; i < 10; i++) {
+            /* evaluation placeholder */
+            print('\$i+\$x');
+          };
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x, c, i) {
+              return x;
+            }(
+              1,
+              null,
+              0
+            ))
+            ''');
+      });
+
+      test('expression using loop variable', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+            expression: 'i',
+            expectedResult: '''
+            (function(x, c, i) {
+              return i;
+            }(
+              1,
+              null,
+              0
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in iterator loops:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          var l = <String>['1', '2', '3'];
+
+          for(var e in l) {
+            /* evaluation placeholder */
+            print(e);
+          };
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression loop variable', () async {
+        await driver.check(
+            scope: <String, String>{'l': 'null', 'e': '1'},
+            expression: 'e',
+            expectedResult: '''
+            (function(l, e) {
+              return e;
+            }(
+              null,
+              1
+            ))
+            ''');
+      });
+    });
+
+    group('Expression compiler tests in conditional (then):', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 1;
+          var c = C(1, 2);
+
+          if (x == 14) {
+            int y = 3;
+            /* evaluation placeholder */
+            print('\$y+\$x');
+          } else {
+            int z = 3;
+            print('\$z+\$x');
+          }
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+            expression: 'y',
+            expectedResult: '''
+            (function(x, c, y) {
+              return y;
+            }(
+              1,
+              null,
+              3
+            ))
+            ''');
+      });
+
+      test('expression using local out of scope', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+            expression: 'z',
+            expectedError: "Error: Getter not found: 'z'");
+      });
+    });
+
+    group('Expression compiler tests in conditional (else):', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 1;
+          var c = C(1, 2);
+
+          if (x == 14) {
+            int y = 3;
+            print('\$y+\$x');
+          } else {
+            int z = 3;
+            /* evaluation placeholder */
+            print('\$z+\$x');
+          }
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+            expression: 'z',
+            expectedResult: '''
+            (function(x, c, z) {
+              return z;
+            }(
+              1,
+              null,
+              3
+            ))
+            ''');
+      });
+
+      test('expression using local out of scope', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+            expression: 'y',
+            expectedError: "Error: Getter not found: 'y'");
+      });
+    });
+
+    group('Expression compiler tests after conditionals:', () {
+      var source = '''
+        ${options.dartLangComment}
+        int globalFunction() {
+          int x = 1;
+          var c = C(1, 2);
+
+          if (x == 14) {
+            int y = 3;
+            print('\$y+\$x');
+          } else {
+            int z = 3;
+            print('\$z+\$x');
+          }
+          /* evaluation placeholder */
+          return 0;
+        }
+
+        main() => 0;
+        ''';
+
+      TestDriver driver;
+      setUp(() {
+        driver = TestDriver(options, source);
+      });
+
+      tearDown(() {
+        driver.delete();
+      });
+
+      test('expression using local', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'x',
+            expectedResult: '''
+            (function(x, c) {
+              return x;
+            }(
+              1,
+              null
+            ))
+            ''');
+      });
+
+      test('expression using local out of scope', () async {
+        await driver.check(
+            scope: <String, String>{'x': '1', 'c': 'null'},
+            expression: 'z',
+            expectedError: "Error: Getter not found: 'z'");
+      });
     });
   });
 }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
index 1735621..68357f8 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
@@ -393,158 +393,6 @@
           ]));
     });
   });
-
-  group('Expression compiler worker (google3 simulation) - ', () {
-    ExpressionCompilerWorker worker;
-    Future workerDone;
-    StreamController<Map<String, dynamic>> requestController;
-    StreamController<Map<String, dynamic>> responseController;
-    Directory tempDir;
-    TestProjectConfiguration config;
-    List inputs;
-
-    setUpAll(() async {
-      tempDir = Directory.systemTemp.createTempSync('foo bar');
-      config = TestProjectConfiguration(tempDir);
-
-      // simulate google3
-      config.createTestProject();
-      var kernelGenerator = BazelKernelWorkerGenerator(config);
-      await kernelGenerator.generate();
-
-      inputs = [
-        {
-          'path': config.mainModule.fullDillPath.path,
-          'moduleName': config.mainModule.moduleName
-        },
-      ];
-    });
-
-    tearDownAll(() async {
-      tempDir.deleteSync(recursive: true);
-    });
-
-    setUp(() async {
-      var fileSystem = MultiRootFileSystem(
-          'org-dartlang-app', [tempDir.uri], StandardFileSystem.instance);
-
-      requestController = StreamController<Map<String, dynamic>>();
-      responseController = StreamController<Map<String, dynamic>>();
-      worker = await ExpressionCompilerWorker.create(
-        librariesSpecificationUri: config.librariesPath,
-        packagesFile: null,
-        sdkSummary: config.sdkSummaryPath,
-        fileSystem: fileSystem,
-        requestStream: requestController.stream,
-        sendResponse: responseController.add,
-        verbose: verbose,
-      );
-      workerDone = worker.start();
-    });
-
-    tearDown(() async {
-      unawaited(requestController.close());
-      await workerDone;
-      unawaited(responseController.close());
-    });
-
-    test('can load dependencies and compile expressions in sdk', () async {
-      requestController.add({
-        'command': 'UpdateDeps',
-        'inputs': inputs,
-      });
-
-      requestController.add({
-        'command': 'CompileExpression',
-        'expression': 'other',
-        'line': 107,
-        'column': 1,
-        'jsModules': {},
-        'jsScope': {'other': 'other'},
-        'libraryUri': 'dart:collection',
-        'moduleName': 'dart_sdk',
-      });
-
-      expect(
-          responseController.stream,
-          emitsInOrder([
-            equals({
-              'succeeded': true,
-            }),
-            equals({
-              'succeeded': true,
-              'errors': isEmpty,
-              'warnings': isEmpty,
-              'compiledProcedure': contains('return other;'),
-            })
-          ]));
-    }, skip: 'Evaluating expressions in SDK is not supported yet');
-
-    test('can load dependencies and compile expressions in a library',
-        () async {
-      requestController.add({
-        'command': 'UpdateDeps',
-        'inputs': inputs,
-      });
-
-      requestController.add({
-        'command': 'CompileExpression',
-        'expression': 'formal',
-        'line': 5,
-        'column': 1,
-        'jsModules': {},
-        'jsScope': {'formal': 'formal'},
-        'libraryUri': config.testModule.libraryUri,
-        'moduleName': config.mainModule.moduleName,
-      });
-
-      expect(
-          responseController.stream,
-          emitsInOrder([
-            equals({
-              'succeeded': true,
-            }),
-            equals({
-              'succeeded': true,
-              'errors': isEmpty,
-              'warnings': isEmpty,
-              'compiledProcedure': contains('return formal;'),
-            })
-          ]));
-    });
-
-    test('can load dependencies and compile expressions in main', () async {
-      requestController.add({
-        'command': 'UpdateDeps',
-        'inputs': inputs,
-      });
-
-      requestController.add({
-        'command': 'CompileExpression',
-        'expression': 'count',
-        'line': 8,
-        'column': 1,
-        'jsModules': {},
-        'jsScope': {'count': 'count'},
-        'libraryUri': config.mainModule.libraryUri,
-        'moduleName': config.mainModule.moduleName,
-      });
-
-      expect(
-          responseController.stream,
-          emitsInOrder([
-            equals({
-              'succeeded': true,
-            }),
-            equals({
-              'succeeded': true,
-              'errors': isEmpty,
-              'warnings': isEmpty,
-              'compiledProcedure': contains('return count;'),
-            })
-          ]));
-    });
-  }, skip: 'bazel kernel worker does not support full kernel generation yet');
 }
 
 /// Uses DDC to generate kernel from the test code
@@ -641,47 +489,6 @@
   }
 }
 
-/// Uses bazel kernel worker to generate kernel from test code
-/// in order to simulate google3 environment
-/// TODO: split into 3 modules
-class BazelKernelWorkerGenerator {
-  TestProjectConfiguration config;
-
-  BazelKernelWorkerGenerator(this.config);
-
-  Future<void> generate() async {
-    var dart = Platform.resolvedExecutable;
-    var kernelWorker =
-        p.join(p.dirname(dart), 'snapshots', 'kernel_worker.dart.snapshot');
-
-    var args = [
-      kernelWorker,
-      '--target',
-      'ddc',
-      '--output',
-      config.mainModule.fullDillPath.path,
-      '--dart-sdk-summary',
-      config.sdkSummaryPath.path,
-      '--exclude-non-sources',
-      '--source',
-      config.mainModule.libraryUri,
-      '--source',
-      config.testModule.libraryUri,
-      '--source',
-      config.testModule2.libraryUri,
-      '--multi-root',
-      '${config.root}',
-      '--multi-root-scheme',
-      'org-dartlang-app',
-      '--packages-file',
-      '.packages',
-      '--verbose'
-    ];
-
-    return await runProcess(dart, args, config.rootPath);
-  }
-}
-
 Future<int> runProcess(
     String command, List<String> args, String workingDirectory) async {
   if (verbose) {
diff --git a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
index bf80618..d85029a 100644
--- a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
@@ -1,12 +1,12 @@
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1659|7|5|Superinterfaces don't have a valid override for '&': JSNumber.& (num Function(num)), int.& (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1659|7|5|Superinterfaces don't have a valid override for '<<': JSNumber.<< (num Function(num)), int.<< (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1659|7|5|Superinterfaces don't have a valid override for '>>': JSNumber.>> (num Function(num)), int.>> (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1659|7|5|Superinterfaces don't have a valid override for '\|': JSNumber.\| (num Function(num)), int.\| (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1659|7|5|Superinterfaces don't have a valid override for '^': JSNumber.^ (num Function(num)), int.^ (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_runtime/lib/interceptors.dart|1514|14|45|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
-ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_runtime/lib/interceptors.dart|1516|14|45|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1676|28|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1678|27|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1681|17|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1686|18|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1686|44|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1706|7|5|Superinterfaces don't have a valid override for '&': JSNumber.& (num Function(num)), int.& (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1706|7|5|Superinterfaces don't have a valid override for '<<': JSNumber.<< (num Function(num)), int.<< (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1706|7|5|Superinterfaces don't have a valid override for '>>': JSNumber.>> (num Function(num)), int.>> (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1706|7|5|Superinterfaces don't have a valid override for '\|': JSNumber.\| (num Function(num)), int.\| (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1706|7|5|Superinterfaces don't have a valid override for '^': JSNumber.^ (num Function(num)), int.^ (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_runtime/lib/interceptors.dart|1561|14|45|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
+ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_runtime/lib/interceptors.dart|1563|14|45|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1723|28|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1725|27|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1728|17|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1733|18|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1733|44|1|The operator '&' isn't defined for the type 'JSInt'.
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index 39bf88b..0336282 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1,11 +1,11 @@
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3679|5|94|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7880|5|97|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7878|5|97|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|893|5|95|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|926|5|94|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|INVALID_ASSIGNMENT|lib/_internal/js_dev_runtime/private/interceptors.dart|1358|18|27|A value of type 'double' can't be assigned to a variable of type 'int'.
 ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_dev_runtime/private/interceptors.dart|1225|14|38|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
 ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_dev_runtime/private/interceptors.dart|1227|14|38|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3677|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7878|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7876|3|5|Only redirecting factory constructors can be declared to be 'const'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|891|3|5|Only redirecting factory constructors can be declared to be 'const'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|924|3|5|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 65888a8..023d555 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -49,18 +49,18 @@
     ..addFlag('sound-null-safety',
         help: 'Compile for sound null safety at runtime. Passed through to the '
             'DDC binary. Defaults to false.',
-        defaultsTo: false,
-        negatable: true)
+        defaultsTo: false)
     ..addFlag('null-assertions',
         help: 'Run with assertions that values passed to non-nullable method '
             'parameters are not null.',
-        defaultsTo: false,
-        negatable: true)
+        defaultsTo: false)
     ..addFlag('native-null-assertions',
         help: 'Run with assertions on non-nullable values returned from native '
             'APIs.',
         defaultsTo: true,
         negatable: true)
+    ..addFlag('weak-null-safety-errors',
+        help: 'Treat weak null safety warnings as errors.', defaultsTo: false)
     ..addFlag('observe',
         help:
             'Run the compiler in the Dart VM with --observe. Implies --debug.',
@@ -86,7 +86,6 @@
         abbr: 'v',
         help: 'Echos the commands, arguments, and environment this script is '
             'running.',
-        negatable: false,
         defaultsTo: false)
     ..addOption('vm-service-port',
         help: 'Specify the observatory port. Implied --observe.');
@@ -115,19 +114,10 @@
   var compile = mode == 'compile' || mode == 'all';
   var run = mode == 'run' || mode == 'all';
   var verbose = options['verbose'] as bool;
+  var soundNullSafety = options['sound-null-safety'] as bool;
   var nonNullAsserts = options['null-assertions'] as bool;
   var nativeNonNullAsserts = options['null-assertions'] as bool;
-
-  var soundNullSafety = options['sound-null-safety'] as bool;
-  // Enable null safety either by passing the `non-nullable` experiment flag or
-  // `sound-null-safety`.
-  var nnbd = experiments.contains('non-nullable') || soundNullSafety;
-
-  // Ensure non-nullable is passed as a flag.
-  if (soundNullSafety && !experiments.contains('non-nullable')) {
-    experiments.add('non-nullable');
-  }
-
+  var weakNullSafetyErrors = options['weak-null-safety-errors'] as bool;
   var entry = p.canonicalize(options.rest.first);
   var out = (options['out'] as String) ?? p.setExtension(entry, '.js');
   var libRoot = p.dirname(entry);
@@ -275,11 +265,12 @@
   require(['dart_sdk', '$basename'],
         function(sdk, app) {
     'use strict';
-    if ($nnbd) {
-      sdk.dart.weakNullSafetyWarnings(!$soundNullSafety);
-      sdk.dart.nonNullAsserts($nonNullAsserts);
-      sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
-    }
+
+    sdk.dart.weakNullSafetyWarnings(
+        !($weakNullSafetyErrors || $soundNullSafety));
+    sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
+    sdk.dart.nonNullAsserts($nonNullAsserts);
+    sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
     sdk._debugger.registerDevtoolsFormatter();
     app.$libname.main([]);
   });
@@ -311,11 +302,11 @@
 sdk.dart.global.self = sdk.dart.global;
 let main = require(\"./$basename\").$libname.main;
 try {
-  if ($nnbd) {
-    sdk.dart.weakNullSafetyWarnings(!$soundNullSafety);
-    sdk.dart.nonNullAsserts($nonNullAsserts);
-    sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
-  }
+  sdk.dart.weakNullSafetyWarnings(
+      !($weakNullSafetyErrors || $soundNullSafety));
+  sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
+  sdk.dart.nonNullAsserts($nonNullAsserts);
+  sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
   sdk._isolate_helper.startRootIsolate(main, []);
 } catch(e) {
   if (!source_maps) {
@@ -346,14 +337,14 @@
 load("$sdkJsPath/dart_sdk.js");
 load("$out");
 
-let dart_sdk = dart_library.import('dart_sdk');
+let sdk = dart_library.import('dart_sdk');
 // Create a self reference for JS interop tests that set fields on self.
-dart_sdk.dart.global.self = dart_sdk.dart.global;
-if ($nnbd) {
-  dart_sdk.dart.weakNullSafetyWarnings(!$soundNullSafety);
-  dart_sdk.dart.nonNullAsserts($nonNullAsserts);
-  dart_sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
-}
+sdk.dart.global.self = sdk.dart.global;
+sdk.dart.weakNullSafetyWarnings(
+    !($weakNullSafetyErrors || $soundNullSafety));
+sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
+sdk.dart.nonNullAsserts($nonNullAsserts);
+sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
 dart_library.start('$basename', '$libname');
 ''';
       var d8File = p.setExtension(out, '.d8.js');
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index a030354..47ada71 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -440,6 +440,17 @@
     _fail("$defaultMessage$diff");
   }
 
+  /// Checks that [haystack] contains a given substring [needle].
+  ///
+  /// For example, this succeeds:
+  ///
+  ///     Expect.contains("a", "abcdefg");
+  static void contains(String needle, String haystack) {
+    if (!haystack.contains(needle)) {
+      _fail("String '$needle' not found within '$haystack'");
+    }
+  }
+
   /// Checks that [actual] contains a given list of [substrings] in order.
   ///
   /// For example, this succeeds:
@@ -618,19 +629,6 @@
         f, (error) => error.toString().startsWith('ReachabilityError'), reason);
   }
 
-  /// Checks that [f] throws an appropriate error on a null argument.
-  ///
-  /// With sound null safety, this is expected to be a [TypeError] when casting
-  /// the `null` to some non-nullable type. In weak mode, that cast is ignored
-  /// and some later explicit validation should handle it and [ArgumentError].
-  static void throwsNullCheckError(void f()) {
-    if (hasSoundNullSafety) {
-      throwsTypeError(f);
-    } else {
-      throwsArgumentError(f);
-    }
-  }
-
   static void throwsRangeError(void f(), [String reason = "RangeError"]) {
     Expect.throws(f, (error) => error is RangeError, reason);
   }
diff --git a/pkg/expect/pubspec.yaml b/pkg/expect/pubspec.yaml
index b1b5bd1..6a8f0bc 100644
--- a/pkg/expect/pubspec.yaml
+++ b/pkg/expect/pubspec.yaml
@@ -12,4 +12,5 @@
   sdk: '>=2.0.0'
 
 dependencies:
-  meta: any
+  meta:
+    path: ../meta
diff --git a/pkg/front_end/README.md b/pkg/front_end/README.md
index 6c4e0ed..c7be0eb 100644
--- a/pkg/front_end/README.md
+++ b/pkg/front_end/README.md
@@ -6,13 +6,12 @@
 with the analyzer package--this will be accomplished by having the analyzer
 package import (and re-export) parts of this package's private implementation.
 
-End-users should use the [dartanalyzer][analyzercli] command-line tool to
-analyze their Dart code.
+End-users should use the [`dart analyze`](https://dart.dev/tools/dart-tool)
+command-line tool to analyze their Dart code.
 
 Integrators that want to write tools that analyze Dart code should use the
-[analyzer] package.
+[analyzer](https://pub.dev/packages/analyzer) package.
 
-_Note:_ The APIs in this package are in an early state; developers should be
-careful about depending on this package.  In particular, there is no semver
-contract for release versions of this package.  Please depend directly on individual
-versions.
+_Note:_ A previous version of this package was published on pub.dev. It has now
+been marked DISCONTINUED as it is not intended for direct consumption, as per
+the notes above.
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
index c208be1..28122d7 100644
--- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -4,8 +4,7 @@
 
 import 'package:kernel/ast.dart';
 import '../fasta/kernel/late_lowering.dart';
-
-// TODO(johnniwinther): Add support for recognizing late lowered locals?
+import '../fasta/source/source_extension_builder.dart' show extensionThisName;
 
 /// Returns `true` if [node] is the field holding the value of a lowered late
 /// field.
@@ -128,3 +127,251 @@
   }
   return false;
 }
+
+/// Returns `true` if [node] is the local variable holding the value of a
+/// lowered late variable.
+///
+/// For instance
+///
+///    late int local;
+///
+/// is lowered to (simplified):
+///
+///    int? #local = null;
+///    int #local#get() => #local != null ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///    }
+///
+/// where '#local' is the local variable holding that value.
+///
+/// The default value of this variable is `null`.
+bool isLateLoweredLocal(VariableDeclaration node) {
+  assert(node.isLowered ||
+      node.name == null ||
+      !isLateLoweredLocalName(node.name));
+  return node.isLowered && isLateLoweredLocalName(node.name);
+}
+
+/// Returns `true` if [name] is the name of a local variable holding the value
+/// of a lowered late variable.
+bool isLateLoweredLocalName(String name) {
+  return name != extensionThisName &&
+      name.startsWith(lateLocalPrefix) &&
+      !name.endsWith(lateIsSetSuffix) &&
+      !name.endsWith(lateLocalGetterSuffix) &&
+      !name.endsWith(lateLocalSetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable holding the value of the lowered late variable.
+///
+/// This method assumes that `isLateLoweredLocalName(name)` is `true`.
+String extractLocalNameFromLateLoweredLocal(String name) {
+  return name.substring(lateLocalPrefix.length);
+}
+
+/// Returns `true` if [node] is the local variable holding the marker for
+/// whether a lowered late local variable has been set or not.
+///
+/// For instance
+///
+///    late int? local;
+///
+/// is lowered to (simplified):
+///
+///    bool #local#isSet = false;
+///    int? #local = null;
+///    int #local#get() => _#field#isSet ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///      #local#isSet = true;
+///    }
+///
+/// where '#local#isSet' is the local variable holding the marker.
+///
+/// The default value of this variable is `false`.
+bool isLateLoweredIsSetLocal(VariableDeclaration node) {
+  assert(node.isLowered ||
+      node.name == null ||
+      !isLateLoweredIsSetLocalName(node.name));
+  return node.isLowered && isLateLoweredIsSetLocalName(node.name);
+}
+
+/// Returns `true` if [name] is the name of a local variable holding the marker
+/// for whether a lowered late local variable has been set or not.
+bool isLateLoweredIsSetLocalName(String name) {
+  return name.startsWith(lateLocalPrefix) && name.endsWith(lateIsSetSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable holding the marker for whether the lowered late local
+/// variable has been set or not.
+///
+/// This method assumes that `isLateLoweredIsSetName(name)` is `true`.
+String extractLocalNameFromLateLoweredIsSet(String name) {
+  return name.substring(
+      lateLocalPrefix.length, name.length - lateIsSetSuffix.length);
+}
+
+/// Returns `true` if [node] is the local variable for the local function for
+/// reading the value of a lowered late variable.
+///
+/// For instance
+///
+///    late int local;
+///
+/// is lowered to (simplified):
+///
+///    int? #local = null;
+///    int #local#get() => #local != null ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///    }
+///
+/// where '#local#get' is the local function for reading the variable.
+bool isLateLoweredLocalGetter(VariableDeclaration node) {
+  assert(node.isLowered ||
+      node.name == null ||
+      !isLateLoweredLocalGetterName(node.name));
+  return node.isLowered && isLateLoweredLocalGetterName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the local variable for the local
+/// function for reading the value of a lowered late variable.
+bool isLateLoweredLocalGetterName(String name) {
+  return name.startsWith(lateLocalPrefix) &&
+      name.endsWith(lateLocalGetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable for the local function for reading the value of the lowered
+/// late variable.
+///
+/// This method assumes that `isLateLoweredGetterName(name)` is `true`.
+String extractLocalNameFromLateLoweredGetter(String name) {
+  return name.substring(
+      lateLocalPrefix.length, name.length - lateLocalGetterSuffix.length);
+}
+
+/// Returns `true` if [node] is the local variable for the local function for
+/// setting the value of a lowered late variable.
+///
+/// For instance
+///
+///    late int local;
+///
+/// is lowered to (simplified):
+///
+///    int? #local = null;
+///    int #local#get() => #local != null ? #local : throw 'Uninitialized';
+///    void #local#set(int value) {
+///      #local = value;
+///    }
+///
+/// where '#local#set' is the local function for setting the value of the
+/// variable.
+bool isLateLoweredLocalSetter(VariableDeclaration node) {
+  assert(node.isLowered ||
+      node.name == null ||
+      !isLateLoweredLocalSetterName(node.name));
+  return node.isLowered && isLateLoweredLocalSetterName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the local variable for the local
+/// function for setting the value of a lowered late variable.
+bool isLateLoweredLocalSetterName(String name) {
+  return name.startsWith(lateLocalPrefix) &&
+      name.endsWith(lateLocalSetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable for the local function for setting the value of the lowered
+/// late variable.
+///
+/// This method assumes that `isLateLoweredSetterName(name)` is `true`.
+String extractLocalNameFromLateLoweredSetter(String name) {
+  return name.substring(
+      lateLocalPrefix.length, name.length - lateLocalSetterSuffix.length);
+}
+
+/// Returns `true` if [node] is the synthetic parameter holding the `this` value
+/// in the encoding of extension instance members.
+///
+/// For instance
+///
+///     extension Extension on int {
+///        int method() => this;
+///     }
+///
+/// is encoded as
+///
+///     int Extension|method(int #this) => #this;
+///
+/// where '#this' is the synthetic "extension this" parameter.
+bool isExtensionThis(VariableDeclaration node) {
+  assert(
+      node.isLowered || node.name == null || !isExtensionThisName(node.name));
+  return node.isLowered && isExtensionThisName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the synthetic parameter holding the
+/// `this` value in the encoding of extension instance members.
+bool isExtensionThisName(String name) {
+  return name == extensionThisName;
+}
+
+/// Returns the name of the original variable from the [name] of the synthetic
+/// parameter holding the `this` value in the encoding of extension instance
+/// members.
+///
+/// This method assumes that `isExtensionThisName(name)` is `true`.
+String extractLocalNameForExtensionThis(String name) {
+  return 'this';
+}
+
+/// Returns the original name of the variable [node].
+///
+/// If [node] is a lowered variable then the name before lowering is returned.
+/// Otherwise the name of the variable itself is returned.
+///
+/// Note that the name can be `null` in case of a synthetic variable created
+/// for instance for encoding of `?.`.
+String extractLocalNameFromVariable(VariableDeclaration node) {
+  if (node.isLowered) {
+    String name = _extractLocalName(node.name);
+    if (name == null) {
+      throw new UnsupportedError("Unrecognized lowered local $node");
+    }
+    return name;
+  }
+  return node.name;
+}
+
+/// Returns the original name of a variable by the given [name].
+///
+/// If [name] is the name of a lowered variable then the name before lowering is
+/// returned. Otherwise the name of the variable itself is returned.
+///
+/// This assumed that [name] is non-null.
+String extractLocalName(String name) {
+  return _extractLocalName(name) ?? name;
+}
+
+/// Returns the original name of a lowered variable by the given [name].
+///
+/// If [name] doesn't correspond to a lowered name `null` is returned.
+String _extractLocalName(String name) {
+  if (isExtensionThisName(name)) {
+    return extractLocalNameForExtensionThis(name);
+  } else if (isLateLoweredLocalName(name)) {
+    return extractLocalNameFromLateLoweredLocal(name);
+  } else if (isLateLoweredLocalGetterName(name)) {
+    return extractLocalNameFromLateLoweredGetter(name);
+  } else if (isLateLoweredLocalSetterName(name)) {
+    return extractLocalNameFromLateLoweredSetter(name);
+  } else if (isLateLoweredIsSetLocalName(name)) {
+    return extractLocalNameFromLateLoweredIsSet(name);
+  }
+  return null;
+}
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index d4445e4..48df5c9 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -77,7 +77,7 @@
     bool verbose: false,
     NnbdMode nnbdMode: NnbdMode.Weak}) async {
   List<Component> outputLoadedAdditionalDills =
-      new List<Component>(additionalDills.length);
+      new List<Component>.filled(additionalDills.length, null);
   Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
       parseExperimentalArguments(experiments),
       onError: (e) => throw e);
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
index 691483d..eb80f97 100644
--- a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -156,7 +156,7 @@
       if (trackNeededDillLibraries) {
         libraryToInputDill = new Map<Uri, Uri>();
       }
-      List<int> loadFromDillIndexes = new List<int>();
+      List<int> loadFromDillIndexes = <int>[];
 
       // Notice that the ordering of the input summaries matter, so we need to
       // keep them in order.
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index baa6b72..7414b1c 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -216,7 +216,8 @@
         command_line_reporting.format(message, severity, location: location);
     List<FormattedMessage> formattedContext;
     if (context != null && context.isNotEmpty) {
-      formattedContext = new List<FormattedMessage>(context.length);
+      formattedContext =
+          new List<FormattedMessage>.filled(context.length, null);
       for (int i = 0; i < context.length; i++) {
         formattedContext[i] = format(context[i], Severity.context, null);
       }
@@ -561,8 +562,7 @@
             templateCantReadFile.withArguments(uri, e.message), Severity.error);
       }
     } catch (e) {
-      Message message =
-          templateExceptionReadingFile.withArguments(uri, e.message);
+      Message message = templateExceptionReadingFile.withArguments(uri, '$e');
       reportWithoutLocation(message, Severity.error);
       // We throw a new exception to ensure that the message include the uri
       // that led to the exception. Exceptions in Uri don't include the
@@ -675,11 +675,22 @@
     }
 
     Future<Uri> checkInDir(Uri dir) async {
-      Uri candidate = dir.resolve('.dart_tool/package_config.json');
-      if (await fileSystem.entityForUri(candidate).exists()) return candidate;
-      candidate = dir.resolve('.packages');
-      if (await fileSystem.entityForUri(candidate).exists()) return candidate;
-      return null;
+      Uri candidate;
+      try {
+        candidate = dir.resolve('.dart_tool/package_config.json');
+        if (await fileSystem.entityForUri(candidate).exists()) return candidate;
+        candidate = dir.resolve('.packages');
+        if (await fileSystem.entityForUri(candidate).exists()) return candidate;
+        return null;
+      } catch (e) {
+        Message message =
+            templateExceptionReadingFile.withArguments(candidate, '$e');
+        reportWithoutLocation(message, Severity.error);
+        // We throw a new exception to ensure that the message include the uri
+        // that led to the exception. Exceptions in Uri don't include the
+        // offending uri in the exception message.
+        throw new ArgumentError(message.message);
+      }
     }
 
     // Check for $cwd/.packages
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
index 2c0f031..03f46c7 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
@@ -263,7 +263,7 @@
     FunctionNode functionNode = super.buildFunction(library);
     ClassBuilder enclosingClassBuilder = parent;
     Class enclosingClass = enclosingClassBuilder.cls;
-    List<DartType> typeParameterTypes = new List<DartType>();
+    List<DartType> typeParameterTypes = <DartType>[];
     for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
       TypeParameter typeParameter = enclosingClass.typeParameters[i];
       typeParameterTypes.add(
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 63f82eb..833753c 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -136,7 +136,10 @@
           isCovariant: isCovariant,
           isNonNullableByDefault: library.isNonNullableByDefault);
     } else if (isLate &&
-        !libraryBuilder.loader.target.backendTarget.supportsLateFields) {
+        libraryBuilder.loader.target.backendTarget.isLateFieldLoweringEnabled(
+            hasInitializer: hasInitializer,
+            isFinal: isFinal,
+            isStatic: (isStatic || isTopLevel))) {
       if (hasInitializer) {
         if (isFinal) {
           _fieldEncoding = new LateFinalFieldWithInitializerEncoding(
@@ -229,6 +232,8 @@
     }
   }
 
+  bool get isLateLowered => _fieldEncoding.isLateLowering;
+
   bool _typeEnsured = false;
   Set<ClassMember> _overrideDependencies;
 
@@ -424,8 +429,7 @@
       // `fieldType` may have changed if a circularity was detected when
       // [inferredType] was computed.
       if (!library.isNonNullableByDefault) {
-        inferredType = legacyErasure(
-            library.loader.typeInferenceEngine.coreTypes, inferredType);
+        inferredType = legacyErasure(inferredType);
       }
       fieldType = implicitFieldType.checkInferred(inferredType);
 
@@ -570,6 +574,9 @@
   /// Ensures that the signatures all members created by this field encoding
   /// are fully typed.
   void completeSignature(CoreTypes coreTypes);
+
+  /// Returns `true` if this encoding is a late lowering.
+  bool get isLateLowering;
 }
 
 class RegularFieldEncoding implements FieldEncoding {
@@ -695,6 +702,9 @@
       fieldBuilder.isAssignable
           ? <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: true)]
           : const <ClassMember>[];
+
+  @override
+  bool get isLateLowering => false;
 }
 
 class SourceFieldMember extends BuilderClassMember {
@@ -800,6 +810,7 @@
       ..isInternalImplementation = true;
     switch (_isSetStrategy) {
       case late_lowering.IsSetStrategy.useSentinelOrNull:
+      case late_lowering.IsSetStrategy.forceUseSentinel:
         // [_lateIsSetField] is never needed.
         break;
       case late_lowering.IsSetStrategy.forceUseIsSetField:
@@ -933,7 +944,8 @@
       {bool isCovariant}) {
     assert(isCovariant != null);
     VariableDeclaration parameter = new VariableDeclaration(null)
-      ..isCovariant = isCovariant;
+      ..isCovariant = isCovariant
+      ..fileOffset = fileOffset;
     return new Procedure(
         null,
         ProcedureKind.Setter,
@@ -1146,6 +1158,9 @@
     }
     return list;
   }
+
+  @override
+  bool get isLateLowering => true;
 }
 
 mixin NonFinalLate on AbstractLateFieldEncoding {
@@ -1323,7 +1338,8 @@
         createIsSetRead: () => _createFieldGet(_lateIsSetField),
         createIsSetWrite: (Expression value) =>
             _createFieldSet(_lateIsSetField, value),
-        isSetEncoding: isSetEncoding);
+        isSetEncoding: isSetEncoding,
+        forField: true);
   }
 
   @override
@@ -1523,7 +1539,8 @@
     if (!isFinal) {
       VariableDeclaration parameter =
           new VariableDeclaration("#externalFieldValue")
-            ..isCovariant = isCovariant;
+            ..isCovariant = isCovariant
+            ..fileOffset = charOffset;
       _setter = new Procedure(
           null,
           ProcedureKind.Setter,
@@ -1684,6 +1701,9 @@
                   forSetter: true, isInternalImplementation: false)
             ]
           : const <ClassMember>[];
+
+  @override
+  bool get isLateLowering => false;
 }
 
 enum _SynthesizedFieldMemberKind {
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index ff976c0..626190e 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -74,9 +74,11 @@
   /// True if the initializer was declared by the programmer.
   bool hasDeclaredInitializer = false;
 
+  final bool isExtensionThis;
+
   FormalParameterBuilder(this.metadata, this.modifiers, this.type, this.name,
       LibraryBuilder compilationUnit, int charOffset,
-      [Uri fileUri])
+      {Uri fileUri, this.isExtensionThis: false})
       : super(compilationUnit, charOffset, fileUri);
 
   String get debugName => "FormalParameterBuilder";
@@ -122,7 +124,8 @@
           isFieldFormal: isInitializingFormal,
           isCovariant: isCovariant,
           isRequired: isNamedRequired,
-          hasDeclaredInitializer: hasDeclaredInitializer)
+          hasDeclaredInitializer: hasDeclaredInitializer,
+          isLowered: isExtensionThis)
         ..fileOffset = charOffset;
     }
     return variable;
@@ -131,8 +134,9 @@
   FormalParameterBuilder clone(List<TypeBuilder> newTypes) {
     // TODO(dmitryas):  It's not clear how [metadata] is used currently, and
     // how it should be cloned.  Consider cloning it instead of reusing it.
-    return new FormalParameterBuilder(metadata, modifiers,
-        type?.clone(newTypes), name, parent, charOffset, fileUri)
+    return new FormalParameterBuilder(
+        metadata, modifiers, type?.clone(newTypes), name, parent, charOffset,
+        fileUri: fileUri, isExtensionThis: isExtensionThis)
       ..kind = kind;
   }
 
@@ -147,7 +151,8 @@
             name,
             null,
             charOffset,
-            fileUri)
+            fileUri: fileUri,
+            isExtensionThis: isExtensionThis)
           ..parent = parent
           ..variable = variable);
   }
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index 2fea24a..129c01a 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -461,7 +461,7 @@
       _extensionThis = result.positionalParameters.first;
       if (extensionBuilder.typeParameters != null) {
         int count = extensionBuilder.typeParameters.length;
-        _extensionTypeParameters = new List<TypeParameter>(count);
+        _extensionTypeParameters = new List<TypeParameter>.filled(count, null);
         for (int index = 0; index < count; index++) {
           _extensionTypeParameters[index] = result.typeParameters[index];
         }
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index f56ac53..3143c2d 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -59,13 +59,13 @@
     buffer.write("(");
     if (formals != null) {
       bool isFirst = true;
-      for (dynamic t in formals) {
+      for (FormalParameterBuilder t in formals) {
         if (!isFirst) {
           buffer.write(", ");
         } else {
           isFirst = false;
         }
-        buffer.write(t?.fullNameForErrors);
+        buffer.write(t.fullNameForErrors);
       }
     }
     buffer.write(") ->");
@@ -130,14 +130,16 @@
   FunctionTypeBuilder clone(List<TypeBuilder> newTypes) {
     List<TypeVariableBuilder> clonedTypeVariables;
     if (typeVariables != null) {
-      clonedTypeVariables = new List<TypeVariableBuilder>(typeVariables.length);
+      clonedTypeVariables =
+          new List<TypeVariableBuilder>.filled(typeVariables.length, null);
       for (int i = 0; i < clonedTypeVariables.length; i++) {
         clonedTypeVariables[i] = typeVariables[i].clone(newTypes);
       }
     }
     List<FormalParameterBuilder> clonedFormals;
     if (formals != null) {
-      clonedFormals = new List<FormalParameterBuilder>(formals.length);
+      clonedFormals =
+          new List<FormalParameterBuilder>.filled(formals.length, null);
       for (int i = 0; i < clonedFormals.length; i++) {
         FormalParameterBuilder formal = formals[i];
         clonedFormals[i] = formal.clone(newTypes);
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index e09e091..54cd164 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -399,7 +399,7 @@
   NamedTypeBuilder clone(List<TypeBuilder> newTypes) {
     List<TypeBuilder> clonedArguments;
     if (arguments != null) {
-      clonedArguments = new List<TypeBuilder>(arguments.length);
+      clonedArguments = new List<TypeBuilder>.filled(arguments.length, null);
       for (int i = 0; i < clonedArguments.length; i++) {
         clonedArguments[i] = arguments[i].clone(newTypes);
       }
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index d1c7d3b..4857e5e 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -482,7 +482,9 @@
         VariableDeclaration parameter, DartType type,
         {bool isOptional}) {
       VariableDeclaration newParameter = new VariableDeclaration(parameter.name,
-          type: type, isFinal: parameter.isFinal)
+          type: type,
+          isFinal: parameter.isFinal,
+          isLowered: parameter.isLowered)
         ..fileOffset = parameter.fileOffset;
       _extensionTearOffParameterMap[parameter] = newParameter;
       return newParameter;
@@ -722,7 +724,7 @@
                   actualOrigin.function.typeParameters[i], library.library);
         }
         List<DartType> newTypeArguments =
-            new List<DartType>(typeArguments.length);
+            new List<DartType>.filled(typeArguments.length, null);
         for (int i = 0; i < newTypeArguments.length; i++) {
           newTypeArguments[i] = substitute(typeArguments[i], substitution);
         }
@@ -755,8 +757,8 @@
     }
     _procedure.isRedirectingFactoryConstructor = true;
     if (redirectionTarget.typeArguments != null) {
-      typeArguments =
-          new List<DartType>(redirectionTarget.typeArguments.length);
+      typeArguments = new List<DartType>.filled(
+          redirectionTarget.typeArguments.length, null);
       for (int i = 0; i < typeArguments.length; i++) {
         typeArguments[i] = redirectionTarget.typeArguments[i].build(library);
       }
@@ -822,7 +824,8 @@
             function.returnType,
             charOffset,
             target.function.computeFunctionType(Nullability.nonNullable),
-            targetInvocationArguments);
+            targetInvocationArguments,
+            staticTarget: target);
         List<DartType> typeArguments;
         if (result.inferredType is InterfaceType) {
           typeArguments = (result.inferredType as InterfaceType).typeArguments;
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
index 137ecd1..1247aea 100644
--- a/pkg/front_end/lib/src/fasta/command_line_reporting.dart
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
@@ -24,7 +24,7 @@
 import 'package:_fe_analyzer_shared/src/util/relativize.dart'
     show isWindows, relativizeUri;
 
-import 'package:kernel/ast.dart' show Location, TreeNode;
+import 'package:kernel/ast.dart' show Location, Source, TreeNode;
 
 import '../compute_platform_binaries_location.dart' show translateSdk;
 
@@ -43,7 +43,8 @@
 /// Formats [message] as a string that is suitable for output from a
 /// command-line tool. This includes source snippets and different colors based
 /// on [severity].
-String format(LocatedMessage message, Severity severity, {Location location}) {
+String format(LocatedMessage message, Severity severity,
+    {Location location, Map<Uri, Source> uriToSource}) {
   try {
     int length = message.length;
     if (length < 1) {
@@ -85,7 +86,7 @@
       if (location?.line == TreeNode.noOffset) {
         location = null;
       }
-      String sourceLine = getSourceLine(location);
+      String sourceLine = getSourceLine(location, uriToSource);
       return formatErrorMessage(
           sourceLine, location, length, path, messageText);
     } else {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 73c8433..a548f80 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -149,7 +149,7 @@
     if (cls.implementedTypes.isEmpty) return null;
     if (super.interfaceBuilders == null) {
       List<TypeBuilder> result =
-          new List<TypeBuilder>(cls.implementedTypes.length);
+          new List<TypeBuilder>.filled(cls.implementedTypes.length, null);
       for (int i = 0; i < result.length; i++) {
         result[i] = computeTypeBuilder(library, cls.implementedTypes[i]);
       }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
index 64581cce..f7adca0 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
@@ -3936,7 +3936,9 @@
             Message Function(
                 String name, DartType _type, bool isNonNullableByDefault)>(
         messageTemplate:
-            r"""Optional parameter '#name' should have a default value because its type '#type' doesn't allow null.""",
+            r"""The parameter '#name' can't have a value of 'null' because of its type '#type', but the implicit default value is 'null'.""",
+        tipTemplate:
+            r"""Try adding either an explicit non-'null' default value or the 'required' modifier.""",
         withArguments:
             _withArgumentsOptionalNonNullableWithoutInitializerError);
 
@@ -3945,11 +3947,11 @@
         Message Function(
             String name, DartType _type, bool isNonNullableByDefault)>
     codeOptionalNonNullableWithoutInitializerError = const Code<
-        Message Function(
-            String name, DartType _type, bool isNonNullableByDefault)>(
-  "OptionalNonNullableWithoutInitializerError",
-  templateOptionalNonNullableWithoutInitializerError,
-);
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        "OptionalNonNullableWithoutInitializerError",
+        templateOptionalNonNullableWithoutInitializerError,
+        analyzerCodes: <String>["MISSING_DEFAULT_VALUE_FOR_PARAMETER"]);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 Message _withArgumentsOptionalNonNullableWithoutInitializerError(
@@ -3961,8 +3963,9 @@
   String type = typeParts.join();
   return new Message(codeOptionalNonNullableWithoutInitializerError,
       message:
-          """Optional parameter '${name}' should have a default value because its type '${type}' doesn't allow null.""" +
+          """The parameter '${name}' can't have a value of 'null' because of its type '${type}', but the implicit default value is 'null'.""" +
               labeler.originMessages,
+      tip: """Try adding either an explicit non-'null' default value or the 'required' modifier.""",
       arguments: {'name': name, 'type': _type});
 }
 
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 906d131..35c074e 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -537,7 +537,7 @@
         }
       }
     } else {
-      outputLibraries = new List<Library>();
+      outputLibraries = <Library>[];
       allLibraries = computeTransitiveClosure(
               compiledLibraries,
               entryPoints,
@@ -895,7 +895,7 @@
       ExperimentalInvalidation experimentalInvalidation,
       ReusageResult reusedResult) {
     if (hierarchy != null) {
-      List<Library> removedLibraries = new List<Library>();
+      List<Library> removedLibraries = <Library>[];
       // TODO(jensj): For now remove all the original from the class hierarchy
       // to avoid the class hierarchy getting confused.
       if (experimentalInvalidation != null) {
@@ -1232,7 +1232,7 @@
     if (hierarchy is ClosedWorldClassHierarchy && !hierarchy.allBetsOff) {
       neededDillLibraries ??= new Set<Library>();
       Set<Class> classes = new Set<Class>();
-      List<Class> worklist = new List<Class>();
+      List<Class> worklist = <Class>[];
       // Get all classes touched by kernel class hierarchy.
       List<Class> usedClasses = hierarchy.getUsedClasses();
       worklist.addAll(usedClasses);
@@ -1447,7 +1447,7 @@
       UriTranslator uriTranslator,
       Map<Uri, Source> uriToSource,
       [List<Library> inputLibrariesFiltered]) {
-    List<Library> result = new List<Library>();
+    List<Library> result = <Library>[];
     Map<Uri, Library> libraryMap = <Uri, Library>{};
     Map<Uri, Library> potentiallyReferencedLibraries = <Uri, Library>{};
     Map<Uri, Library> potentiallyReferencedInputLibraries = <Uri, Library>{};
@@ -1462,7 +1462,7 @@
       }
     }
 
-    List<Uri> worklist = new List<Uri>();
+    List<Uri> worklist = <Uri>[];
     worklist.addAll(entries);
     for (LibraryBuilder libraryBuilder in reusedLibraries) {
       if (libraryBuilder.importUri.scheme == "dart" &&
@@ -1499,7 +1499,7 @@
       }
     }
 
-    List<Library> removedLibraries = new List<Library>();
+    List<Library> removedLibraries = <Library>[];
     bool removedDillBuilders = false;
     for (Uri uri in potentiallyReferencedLibraries.keys) {
       if (uri.scheme == "package") continue;
@@ -1690,7 +1690,7 @@
         if (message.uri != null) {
           List<DiagnosticMessageFromJson> messages =
               remainingComponentProblems[message.uri] ??=
-                  new List<DiagnosticMessageFromJson>();
+                  <DiagnosticMessageFromJson>[];
           messages.add(message);
         }
         if (message.involvedFiles != null) {
@@ -1701,7 +1701,7 @@
           for (Uri uri in message.involvedFiles) {
             List<DiagnosticMessageFromJson> messages =
                 remainingComponentProblems[uri] ??=
-                    new List<DiagnosticMessageFromJson>();
+                    <DiagnosticMessageFromJson>[];
             messages.add(message);
           }
         }
@@ -1792,6 +1792,7 @@
               templateIncrementalCompilerIllegalParameter.withArguments(name),
               // TODO: pass variable declarations instead of
               // parameter names for proper location detection.
+              // https://github.com/dart-lang/sdk/issues/44158
               -1,
               -1,
               libraryUri);
@@ -1849,11 +1850,16 @@
       MemoryFileSystem fs = hfs.memory;
       fs.entityForUri(debugExprUri).writeAsStringSync(expression);
 
+      // TODO: pass variable declarations instead of
+      // parameter names for proper location detection.
+      // https://github.com/dart-lang/sdk/issues/44158
       FunctionNode parameters = new FunctionNode(null,
           typeParameters: typeDefinitions,
           positionalParameters: definitions.keys
               .map((name) =>
-                  new VariableDeclarationImpl(name, 0, type: definitions[name]))
+                  new VariableDeclarationImpl(name, 0, type: definitions[name])
+                    ..fileOffset =
+                        cls?.fileOffset ?? libraryBuilder.library.fileOffset)
               .toList());
 
       debugLibrary.build(userCode.loader.coreLibrary, modifyTarget: false);
@@ -1909,7 +1915,7 @@
       return new ReusageResult({}, [], false, reusedLibraries);
     }
     bool invalidatedBecauseOfPackageUpdate = false;
-    List<LibraryBuilder> directlyInvalidated = new List<LibraryBuilder>();
+    List<LibraryBuilder> directlyInvalidated = <LibraryBuilder>[];
     Set<LibraryBuilder> notReusedLibraries = new Set<LibraryBuilder>();
 
     // Maps all non-platform LibraryBuilders from their import URI.
diff --git a/pkg/front_end/lib/src/fasta/incremental_serializer.dart b/pkg/front_end/lib/src/fasta/incremental_serializer.dart
index e22b912..4581f16 100644
--- a/pkg/front_end/lib/src/fasta/incremental_serializer.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_serializer.dart
@@ -62,7 +62,7 @@
     // Add groups. Wrap in try because an exception will be thrown if a group
     // has a dependency that isn't being met.
     try {
-      List<SerializationGroup> newGroups = new List<SerializationGroup>();
+      List<SerializationGroup> newGroups = <SerializationGroup>[];
       for (int i = 0; i < goodViews.length; i++) {
         SubComponentView view = goodViews[i];
         List<int> data = new Uint8List(view.componentFileSize);
@@ -113,8 +113,8 @@
     component.computeCanonicalNames();
 
     // Split into package and non-package libraries.
-    List<Library> packageLibraries = new List<Library>();
-    List<Library> nonPackageLibraries = new List<Library>();
+    List<Library> packageLibraries = <Library>[];
+    List<Library> nonPackageLibraries = <Library>[];
     for (Library lib in component.libraries) {
       Uri uri = lib.importUri;
       if (uri.scheme == "package") {
@@ -196,7 +196,7 @@
   void removeInvalidated() {
     // Remove all directly invalidated entries.
     Set<SerializationGroup> removed = new Set<SerializationGroup>();
-    List<SerializationGroup> workList = new List<SerializationGroup>();
+    List<SerializationGroup> workList = <SerializationGroup>[];
     for (Uri uri in invalidatedUris) {
       removeUriFromMap(uri, removed, workList);
     }
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 d65d47e..ede2b69 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1389,12 +1389,13 @@
     List<FormalParameterBuilder> formals =
         parameters.positionalParameters.length == 0
             ? null
-            : new List<FormalParameterBuilder>(
-                parameters.positionalParameters.length);
+            : new List<FormalParameterBuilder>.filled(
+                parameters.positionalParameters.length, null);
     for (int i = 0; i < parameters.positionalParameters.length; i++) {
       VariableDeclaration formal = parameters.positionalParameters[i];
       formals[i] = new FormalParameterBuilder(
-          null, 0, null, formal.name, libraryBuilder, formal.fileOffset, uri)
+          null, 0, null, formal.name, libraryBuilder, formal.fileOffset,
+          fileUri: uri)
         ..variable = formal;
     }
     enterLocalScope(
@@ -1415,7 +1416,11 @@
     }
 
     ReturnStatementImpl fakeReturn = new ReturnStatementImpl(true, expression);
-
+    if (formals != null) {
+      for (int i = 0; i < formals.length; i++) {
+        typeInferrer?.flowAnalysis?.declare(formals[i].variable, true);
+      }
+    }
     Statement inferredStatement = typeInferrer?.inferFunctionBody(
         this, fileOffset, const DynamicType(), AsyncMarker.Sync, fakeReturn);
     assert(
@@ -3129,7 +3134,8 @@
     if (isSet) {
       buildLiteralSet(typeArguments, constKeyword, leftBrace, setOrMapEntries);
     } else {
-      List<MapEntry> mapEntries = new List<MapEntry>(setOrMapEntries.length);
+      List<MapEntry> mapEntries =
+          new List<MapEntry>.filled(setOrMapEntries.length, null);
       for (int i = 0; i < setOrMapEntries.length; ++i) {
         if (setOrMapEntries[i] is MapEntry) {
           mapEntries[i] = setOrMapEntries[i];
@@ -3562,7 +3568,8 @@
       }
     } else {
       parameter = new FormalParameterBuilder(null, modifiers, type?.builder,
-          name?.name, libraryBuilder, offsetForToken(nameToken), uri)
+          name?.name, libraryBuilder, offsetForToken(nameToken),
+          fileUri: uri)
         ..hasDeclaredInitializer = (initializerStart != null);
     }
     VariableDeclaration variable = parameter.build(
@@ -5452,7 +5459,8 @@
     int count = labelCount + expressionCount;
     List<Object> labelsAndExpressions =
         const FixedNullableList<Object>().pop(stack, count);
-    List<Label> labels = labelCount == 0 ? null : new List<Label>(labelCount);
+    List<Label> labels =
+        labelCount == 0 ? null : new List<Label>.filled(labelCount, null);
     List<Expression> expressions =
         new List<Expression>.filled(expressionCount, null, growable: true);
     int labelIndex = 0;
@@ -5946,11 +5954,12 @@
     if (builder?.next != null) {
       // Duplicated name, already reported.
       return <Initializer>[
-        new LocalInitializer(new VariableDeclaration.forValue(buildProblem(
-            fasta.templateDuplicatedDeclarationUse.withArguments(name),
-            fieldNameOffset,
-            name.length)))
-          ..fileOffset = fieldNameOffset
+        buildInvalidInitializer(
+            buildProblem(
+                fasta.templateDuplicatedDeclarationUse.withArguments(name),
+                fieldNameOffset,
+                name.length),
+            fieldNameOffset)
       ];
     } else if (builder is FieldBuilder && builder.isDeclarationInstanceMember) {
       initializedFields ??= <String, int>{};
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 5c5223c..387a16c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -280,7 +280,7 @@
   if (typeParameterCount != bTypeParameters.length) return false;
   Substitution substitution;
   if (typeParameterCount != 0) {
-    List<DartType> types = new List<DartType>(typeParameterCount);
+    List<DartType> types = new List<DartType>.filled(typeParameterCount, null);
     for (int i = 0; i < typeParameterCount; i++) {
       types[i] = new TypeParameterType.forAlphaRenaming(
           bTypeParameters[i], aTypeParameters[i]);
@@ -790,7 +790,8 @@
           }
           Substitution methodSubstitution;
           if (typeParameterCount != 0) {
-            List<DartType> types = new List<DartType>(typeParameterCount);
+            List<DartType> types =
+                new List<DartType>.filled(typeParameterCount, null);
             for (int i = 0; i < typeParameterCount; i++) {
               types[i] = new TypeParameterType.forAlphaRenaming(
                   overriddenTypeParameters[i], declaredTypeParameters[i]);
@@ -1265,7 +1266,7 @@
             norm(hierarchy.coreTypes, inheritedType));
       }
     } else {
-      inheritedType = legacyErasure(hierarchy.coreTypes, inheritedType);
+      inheritedType = legacyErasure(inheritedType);
       if (inferredType == null) {
         return inheritedType;
       } else {
@@ -1682,13 +1683,14 @@
     bool hasInterfaces = false;
     if (supernode == null) {
       // This should be Object.
-      superclasses = new List<Supertype>(0);
-      interfaces = new List<Supertype>(0);
+      superclasses = new List<Supertype>.filled(0, null);
+      interfaces = new List<Supertype>.filled(0, null);
       maxInheritancePath = 0;
     } else {
       maxInheritancePath = supernode.maxInheritancePath + 1;
 
-      superclasses = new List<Supertype>(supernode.superclasses.length + 1);
+      superclasses =
+          new List<Supertype>.filled(supernode.superclasses.length + 1, null);
       Supertype supertype = classBuilder.supertypeBuilder.buildSupertype(
           classBuilder.library, classBuilder.charOffset, classBuilder.fileUri);
       if (supertype == null) {
@@ -1703,8 +1705,7 @@
       if (!classBuilder.library.isNonNullableByDefault &&
           supernode.classBuilder.library.isNonNullableByDefault) {
         for (int i = 0; i < superclasses.length; i++) {
-          superclasses[i] =
-              legacyErasureSupertype(hierarchy.coreTypes, superclasses[i]);
+          superclasses[i] = legacyErasureSupertype(superclasses[i]);
         }
       }
 
@@ -2329,9 +2330,10 @@
       substitutions[cls] = Substitution.empty;
     } else {
       List<DartType> arguments = supertype.typeArguments;
-      List<DartType> typeArguments = new List<DartType>(arguments.length);
+      List<DartType> typeArguments =
+          new List<DartType>.filled(arguments.length, null);
       List<TypeParameter> typeParameters =
-          new List<TypeParameter>(arguments.length);
+          new List<TypeParameter>.filled(arguments.length, null);
       for (int i = 0; i < arguments.length; i++) {
         typeParameters[i] = supertypeTypeParameters[i];
         typeArguments[i] = arguments[i];
@@ -2377,7 +2379,7 @@
       Supertype type) {
     if (type == null) return null;
     if (!classBuilder.library.isNonNullableByDefault) {
-      type = legacyErasureSupertype(hierarchy.coreTypes, type);
+      type = legacyErasureSupertype(type);
     }
     ClassHierarchyNode node = hierarchy.getNodeFromClass(type.classNode);
     if (node == null) return null;
@@ -2475,7 +2477,7 @@
                 mixedInType.classNode.typeParameters, cls.enclosingLibrary))
         .infer(cls);
     List<TypeBuilder> inferredArguments =
-        new List<TypeBuilder>(typeArguments.length);
+        new List<TypeBuilder>.filled(typeArguments.length, null);
     for (int i = 0; i < typeArguments.length; i++) {
       inferredArguments[i] =
           hierarchy.loader.computeTypeBuilder(typeArguments[i]);
@@ -2558,8 +2560,8 @@
   /// Returns a list of all supertypes of [classBuilder], including this node.
   List<ClassHierarchyNode> computeAllSuperNodes(
       ClassHierarchyBuilder hierarchy) {
-    List<ClassHierarchyNode> result = new List<ClassHierarchyNode>(
-        1 + superclasses.length + interfaces.length);
+    List<ClassHierarchyNode> result = new List<ClassHierarchyNode>.filled(
+        1 + superclasses.length + interfaces.length, null);
     for (int i = 0; i < superclasses.length; i++) {
       Supertype type = superclasses[i];
       result[i] = hierarchy.getNodeFromClass(type.classNode);
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index f89b4e8..5924d4a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -89,6 +89,8 @@
 
   bool _neededNnbdTopMerge = false;
 
+  bool _containsNnbdTypes = false;
+
   bool _needsCovarianceMerging = false;
 
   bool _isCombinedMemberSignatureCovarianceComputed = false;
@@ -222,6 +224,43 @@
     return _neededNnbdTopMerge;
   }
 
+  /// Returns `true` if the type of combined member signature has nnbd types.
+  ///
+  /// If the combined member signature for an opt-in class is computed from
+  /// identical legacy types, that is, without the need for nnbd top merge, then
+  /// the type will be copied over directly and a member created from the
+  /// combined member signature will therefore be a legacy member, even though
+  /// it is declared in an opt in class.
+  ///
+  /// To avoid reporting errors as if the member was an opt-in member, it is
+  /// marked as nullable-by-default.
+  ///
+  /// For instance
+  ///
+  ///    // opt out:
+  ///    mixin Mixin {
+  ///      void method({int named}) {}
+  ///    }
+  ///    // opt in:
+  ///    class Super {
+  ///      void method({required covariant int named}) {}
+  ///    }
+  ///    class Class extends Super with Mixin {
+  ///      // A forwarding stop for Mixin.method will be inserted here:
+  ///      // void method({covariant int named}) -> Mixin.method
+  ///    }
+  ///    class SubClass extends Class {
+  ///      // This is a valid override since `Class.method` should should
+  ///      // not be considered as _not_ having a required named parameter -
+  ///      // it is legacy and doesn't know about required named parameters.
+  ///      void method({required int named}) {}
+  ///    }
+  ///
+  bool get containsNnbdTypes {
+    _ensureCombinedMemberSignatureType();
+    return _containsNnbdTypes;
+  }
+
   /// Returns `true` if the covariance of the combined member signature is
   /// different from the covariance of the overridden member in the superclass.
   ///
@@ -254,7 +293,7 @@
   /// Returns type of the [index]th member in [members] as inherited in
   /// [classBuilder].
   DartType getMemberType(int index) {
-    _memberTypes ??= new List<DartType>(members.length);
+    _memberTypes ??= new List<DartType>.filled(members.length, null);
     DartType candidateType = _memberTypes[index];
     if (candidateType == null) {
       Member target = _getMember(index);
@@ -262,7 +301,15 @@
           "No member computed for index ${index} in ${members}");
       candidateType = _computeMemberType(thisType, target);
       if (!classBuilder.library.isNonNullableByDefault) {
-        DartType legacyErasure = rawLegacyErasure(_coreTypes, candidateType);
+        DartType legacyErasure;
+        if (target == hierarchy.coreTypes.objectEquals) {
+          // In legacy code we special case `Object.==` to infer `dynamic`
+          // instead `Object!`.
+          legacyErasure = new FunctionType([const DynamicType()],
+              hierarchy.coreTypes.boolLegacyRawType, Nullability.legacy);
+        } else {
+          legacyErasure = rawLegacyErasure(candidateType);
+        }
         if (legacyErasure != null) {
           _neededLegacyErasureIndices ??= {};
           _neededLegacyErasureIndices.add(index);
@@ -283,6 +330,8 @@
       if (classBuilder.library.isNonNullableByDefault) {
         DartType canonicalMemberType =
             _combinedMemberSignatureType = getMemberType(_canonicalMemberIndex);
+        _containsNnbdTypes =
+            _getMember(_canonicalMemberIndex).isNonNullableByDefault;
         if (_mutualSubtypes != null) {
           _combinedMemberSignatureType =
               norm(_coreTypes, _combinedMemberSignatureType);
@@ -296,6 +345,7 @@
           }
           _neededNnbdTopMerge =
               canonicalMemberType != _combinedMemberSignatureType;
+          _containsNnbdTypes = _neededNnbdTopMerge;
         }
       } else {
         _combinedMemberSignatureType = getMemberType(_canonicalMemberIndex);
@@ -370,7 +420,8 @@
       if (typeParameterCount == 0) {
         return type;
       }
-      List<DartType> types = new List<DartType>(typeParameterCount);
+      List<DartType> types =
+          new List<DartType>.filled(typeParameterCount, null);
       for (int i = 0; i < typeParameterCount; i++) {
         types[i] = new TypeParameterType.forAlphaRenaming(
             signatureTypeParameters[i], typeParameters[i]);
@@ -479,15 +530,15 @@
       ProcedureKind.Getter,
       new FunctionNode(null, returnType: type),
       isAbstract: true,
-      isMemberSignature: true,
       fileUri: fileUri,
-      memberSignatureOrigin: member.memberSignatureOrigin ?? member,
       reference: referenceFrom?.reference,
+      isSynthetic: true,
+      stubKind: ProcedureStubKind.MemberSignature,
+      stubTarget: member.memberSignatureOrigin ?? member,
     )
       ..startFileOffset = startFileOffset
       ..fileOffset = fileOffset
-      ..isNonNullableByDefault =
-          enclosingClass.enclosingLibrary.isNonNullableByDefault
+      ..isNonNullableByDefault = containsNnbdTypes
       ..parent = enclosingClass;
   }
 
@@ -521,24 +572,25 @@
       fileOffset = startFileOffset = enclosingClass.fileOffset;
     }
     return new Procedure(
-        member.name,
-        ProcedureKind.Setter,
-        new FunctionNode(null,
-            returnType: const VoidType(),
-            positionalParameters: [
-              new VariableDeclaration(parameterName ?? 'value',
-                  type: type, isCovariant: isCovariant)
-                ..isGenericCovariantImpl = isGenericCovariantImpl
-            ]),
-        isAbstract: true,
-        isMemberSignature: true,
-        fileUri: fileUri,
-        memberSignatureOrigin: member.memberSignatureOrigin ?? member,
-        reference: referenceFrom?.reference)
+      member.name,
+      ProcedureKind.Setter,
+      new FunctionNode(null,
+          returnType: const VoidType(),
+          positionalParameters: [
+            new VariableDeclaration(parameterName ?? 'value',
+                type: type, isCovariant: isCovariant)
+              ..isGenericCovariantImpl = isGenericCovariantImpl
+          ]),
+      isAbstract: true,
+      fileUri: fileUri,
+      reference: referenceFrom?.reference,
+      isSynthetic: true,
+      stubKind: ProcedureStubKind.MemberSignature,
+      stubTarget: member.memberSignatureOrigin ?? member,
+    )
       ..startFileOffset = startFileOffset
       ..fileOffset = fileOffset
-      ..isNonNullableByDefault =
-          enclosingClass.enclosingLibrary.isNonNullableByDefault
+      ..isNonNullableByDefault = containsNnbdTypes
       ..parent = enclosingClass;
   }
 
@@ -567,11 +619,6 @@
     for (int i = 0; i < function.positionalParameters.length; i++) {
       VariableDeclaration parameter = function.positionalParameters[i];
       DartType parameterType = functionType.positionalParameters[i];
-      if (i == 0 && procedure == hierarchy.coreTypes.objectEquals) {
-        // In legacy code we special case `Object.==` to infer `dynamic`
-        // instead `Object!`.
-        parameterType = const DynamicType();
-      }
       positionalParameters.add(new VariableDeclaration(parameter.name,
           type: parameterType, isCovariant: parameter.isCovariant)
         ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
@@ -602,23 +649,24 @@
       }
     }
     return new Procedure(
-        procedure.name,
-        procedure.kind,
-        new FunctionNode(null,
-            typeParameters: functionType.typeParameters,
-            returnType: functionType.returnType,
-            positionalParameters: positionalParameters,
-            namedParameters: namedParameters,
-            requiredParameterCount: function.requiredParameterCount),
-        isAbstract: true,
-        isMemberSignature: true,
-        fileUri: fileUri,
-        memberSignatureOrigin: procedure.memberSignatureOrigin ?? procedure,
-        reference: referenceFrom?.reference)
+      procedure.name,
+      procedure.kind,
+      new FunctionNode(null,
+          typeParameters: functionType.typeParameters,
+          returnType: functionType.returnType,
+          positionalParameters: positionalParameters,
+          namedParameters: namedParameters,
+          requiredParameterCount: function.requiredParameterCount),
+      isAbstract: true,
+      fileUri: fileUri,
+      reference: referenceFrom?.reference,
+      isSynthetic: true,
+      stubKind: ProcedureStubKind.MemberSignature,
+      stubTarget: procedure.memberSignatureOrigin ?? procedure,
+    )
       ..startFileOffset = startFileOffset
       ..fileOffset = fileOffset
-      ..isNonNullableByDefault =
-          enclosingClass.enclosingLibrary.isNonNullableByDefault
+      ..isNonNullableByDefault = containsNnbdTypes
       ..parent = enclosingClass;
   }
 
@@ -732,7 +780,7 @@
 
   @override
   Covariance _getMemberCovariance(int index) {
-    _memberCovariances ??= new List<Covariance>(members.length);
+    _memberCovariances ??= new List<Covariance>.filled(members.length, null);
     Covariance covariance = _memberCovariances[index];
     if (covariance == null) {
       _memberCovariances[index] = covariance =
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
index 8f0a84bb..f10419d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
@@ -53,6 +53,18 @@
         entries = spread.entries;
       } else if (spread is SetConstant) {
         entries = spread.entries;
+      } else if (evaluator.backend.isLoweredListConstant(spread)) {
+        entries = <Constant>[];
+        evaluator.backend.forEachLoweredListConstantElement(spread,
+            (Constant element) {
+          entries.add(element);
+        });
+      } else if (evaluator.backend.isLoweredSetConstant(constant)) {
+        entries = <Constant>[];
+        evaluator.backend.forEachLoweredSetConstantElement(spread,
+            (Constant element) {
+          entries.add(element);
+        });
       } else {
         // Not list or set in spread
         return evaluator.createErrorConstant(
@@ -176,26 +188,7 @@
       // Fully evaluated
       List<Constant> entries = parts.single;
       SetConstant result = new SetConstant(elementType, entries);
-      if (evaluator.desugarSets) {
-        final List<ConstantMapEntry> mapEntries =
-            new List<ConstantMapEntry>(entries.length);
-        for (int i = 0; i < entries.length; ++i) {
-          mapEntries[i] =
-              new ConstantMapEntry(entries[i], evaluator.nullConstant);
-        }
-        Constant map = evaluator.lowerMapConstant(
-            new MapConstant(elementType, const NullType(), mapEntries));
-        return evaluator.lower(
-            result,
-            new InstanceConstant(
-                evaluator.unmodifiableSetMap.enclosingClass.reference, [
-              elementType
-            ], <Reference, Constant>{
-              evaluator.unmodifiableSetMap.getterReference: map
-            }));
-      } else {
-        return evaluator.lowerSetConstant(result);
-      }
+      return evaluator.lowerSetConstant(result);
     }
     List<Expression> sets = <Expression>[];
     for (Object part in parts) {
@@ -271,6 +264,13 @@
               entry.key, entry.value, spreadExpression, spreadExpression);
           if (error != null) return error;
         }
+      } else if (evaluator.backend.isLoweredMapConstant(spread)) {
+        AbortConstant error;
+        evaluator.backend.forEachLoweredMapConstantEntry(spread,
+            (Constant key, Constant value) {
+          error ??= addConstant(key, value, spreadExpression, spreadExpression);
+        });
+        if (error != null) return error;
       } else {
         // Not map in spread
         return evaluator.createErrorConstant(
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 bca4392..a92f302 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -97,14 +97,13 @@
 
   transformLibraries(component.libraries, backend, environmentDefines,
       typeEnvironment, errorReporter, evaluationMode,
-      desugarSets: desugarSets,
       enableTripleShift: enableTripleShift,
       errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
       evaluateAnnotations: evaluateAnnotations);
   return component;
 }
 
-void transformLibraries(
+ConstantCoverage transformLibraries(
     List<Library> libraries,
     ConstantsBackend backend,
     Map<String, String> environmentDefines,
@@ -112,18 +111,15 @@
     ErrorReporter errorReporter,
     EvaluationMode evaluationMode,
     {bool evaluateAnnotations,
-    bool desugarSets,
     bool enableTripleShift,
     bool errorOnUnevaluatedConstant}) {
   assert(evaluateAnnotations != null);
-  assert(desugarSets != null);
   assert(enableTripleShift != null);
   assert(errorOnUnevaluatedConstant != null);
   final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
       backend,
       environmentDefines,
       evaluateAnnotations,
-      desugarSets,
       enableTripleShift,
       errorOnUnevaluatedConstant,
       typeEnvironment,
@@ -132,6 +128,7 @@
   for (final Library library in libraries) {
     constantsTransformer.convertLibrary(library);
   }
+  return constantsTransformer.constantEvaluator.getConstantCoverage();
 }
 
 void transformProcedure(
@@ -142,18 +139,15 @@
     ErrorReporter errorReporter,
     EvaluationMode evaluationMode,
     {bool evaluateAnnotations: true,
-    bool desugarSets: false,
     bool enableTripleShift: false,
     bool errorOnUnevaluatedConstant: false}) {
   assert(evaluateAnnotations != null);
-  assert(desugarSets != null);
   assert(enableTripleShift != null);
   assert(errorOnUnevaluatedConstant != null);
   final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
       backend,
       environmentDefines,
       evaluateAnnotations,
-      desugarSets,
       enableTripleShift,
       errorOnUnevaluatedConstant,
       typeEnvironment,
@@ -173,8 +167,6 @@
 
   ConstantWeakener(this._evaluator);
 
-  CoreTypes get _coreTypes => _evaluator.coreTypes;
-
   Constant processValue(Constant node, Constant value) {
     if (value != null) {
       value = _evaluator.canonicalize(value);
@@ -206,8 +198,8 @@
 
   @override
   Constant visitMapConstant(MapConstant node) {
-    DartType keyType = rawLegacyErasure(_coreTypes, node.keyType);
-    DartType valueType = rawLegacyErasure(_coreTypes, node.valueType);
+    DartType keyType = rawLegacyErasure(node.keyType);
+    DartType valueType = rawLegacyErasure(node.valueType);
     List<ConstantMapEntry> entries;
     for (int index = 0; index < node.entries.length; index++) {
       ConstantMapEntry entry = node.entries[index];
@@ -228,7 +220,7 @@
 
   @override
   Constant visitListConstant(ListConstant node) {
-    DartType typeArgument = rawLegacyErasure(_coreTypes, node.typeArgument);
+    DartType typeArgument = rawLegacyErasure(node.typeArgument);
     List<Constant> entries;
     for (int index = 0; index < node.entries.length; index++) {
       Constant entry = visitConstant(node.entries[index]);
@@ -246,7 +238,7 @@
 
   @override
   Constant visitSetConstant(SetConstant node) {
-    DartType typeArgument = rawLegacyErasure(_coreTypes, node.typeArgument);
+    DartType typeArgument = rawLegacyErasure(node.typeArgument);
     List<Constant> entries;
     for (int index = 0; index < node.entries.length; index++) {
       Constant entry = visitConstant(node.entries[index]);
@@ -266,8 +258,7 @@
   Constant visitInstanceConstant(InstanceConstant node) {
     List<DartType> typeArguments;
     for (int index = 0; index < node.typeArguments.length; index++) {
-      DartType typeArgument =
-          rawLegacyErasure(_coreTypes, node.typeArguments[index]);
+      DartType typeArgument = rawLegacyErasure(node.typeArguments[index]);
       if (typeArgument != null) {
         typeArguments ??= node.typeArguments.toList(growable: false);
         typeArguments[index] = typeArgument;
@@ -293,7 +284,7 @@
       PartialInstantiationConstant node) {
     List<DartType> types;
     for (int index = 0; index < node.types.length; index++) {
-      DartType type = rawLegacyErasure(_coreTypes, node.types[index]);
+      DartType type = rawLegacyErasure(node.types[index]);
       if (type != null) {
         types ??= node.types.toList(growable: false);
         types[index] = type;
@@ -310,7 +301,7 @@
 
   @override
   Constant visitTypeLiteralConstant(TypeLiteralConstant node) {
-    DartType type = rawLegacyErasure(_coreTypes, node.type);
+    DartType type = rawLegacyErasure(node.type);
     if (type != null) {
       return new TypeLiteralConstant(type);
     }
@@ -328,7 +319,6 @@
   StaticTypeContext _staticTypeContext;
 
   final bool evaluateAnnotations;
-  final bool desugarSets;
   final bool enableTripleShift;
   final bool errorOnUnevaluatedConstant;
 
@@ -336,7 +326,6 @@
       this.backend,
       Map<String, String> environmentDefines,
       this.evaluateAnnotations,
-      this.desugarSets,
       this.enableTripleShift,
       this.errorOnUnevaluatedConstant,
       this.typeEnvironment,
@@ -344,7 +333,6 @@
       EvaluationMode evaluationMode)
       : constantEvaluator = new ConstantEvaluator(
             backend, environmentDefines, typeEnvironment, errorReporter,
-            desugarSets: desugarSets,
             enableTripleShift: enableTripleShift,
             errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
             evaluationMode: evaluationMode);
@@ -761,9 +749,6 @@
   final ErrorReporter errorReporter;
   final EvaluationMode evaluationMode;
 
-  final bool desugarSets;
-  final Field unmodifiableSetMap;
-
   final bool enableTripleShift;
 
   final bool Function(DartType) isInstantiated =
@@ -798,19 +783,14 @@
 
   ConstantEvaluator(this.backend, this.environmentDefines, this.typeEnvironment,
       this.errorReporter,
-      {this.desugarSets = false,
-      this.enableTripleShift = false,
+      {this.enableTripleShift = false,
       this.errorOnUnevaluatedConstant = false,
       this.evaluationMode: EvaluationMode.weak})
       : numberSemantics = backend.numberSemantics,
         coreTypes = typeEnvironment.coreTypes,
         canonicalizationCache = <Constant, Constant>{},
         nodeCache = <Node, Constant>{},
-        env = new EvaluationEnvironment(),
-        unmodifiableSetMap = desugarSets
-            ? typeEnvironment.coreTypes.index
-                .getMember('dart:collection', '_UnmodifiableSet', '_map')
-            : null {
+        env = new EvaluationEnvironment() {
     if (environmentDefines == null && !backend.supportsUnevaluatedConstants) {
       throw new ArgumentError(
           "No 'environmentDefines' passed to the constant evaluator but the "
@@ -839,7 +819,7 @@
       case EvaluationMode.agnostic:
         return type;
       case EvaluationMode.weak:
-        return legacyErasure(coreTypes, type);
+        return legacyErasure(type);
     }
     throw new UnsupportedError(
         "Unexpected evaluation mode: ${evaluationMode}.");
@@ -851,9 +831,7 @@
       case EvaluationMode.agnostic:
         return types;
       case EvaluationMode.weak:
-        return types
-            .map((DartType type) => legacyErasure(coreTypes, type))
-            .toList();
+        return types.map((DartType type) => legacyErasure(type)).toList();
     }
     throw new UnsupportedError(
         "Unexpected evaluation mode: ${evaluationMode}.");
@@ -1010,6 +988,18 @@
     return lower(constant, backend.lowerMapConstant(constant));
   }
 
+  Map<Uri, Set<Reference>> _constructorCoverage = {};
+
+  ConstantCoverage getConstantCoverage() {
+    return new ConstantCoverage(_constructorCoverage);
+  }
+
+  void _recordConstructorCoverage(Constructor constructor, TreeNode caller) {
+    Uri currentUri = getFileUri(caller);
+    Set<Reference> uriCoverage = _constructorCoverage[currentUri] ??= {};
+    uriCoverage.add(constructor.reference);
+  }
+
   /// Evaluate [node] and possibly cache the evaluation result.
   ///
   /// Returns [_AbortDueToErrorConstant] or
@@ -1344,13 +1334,13 @@
       if (shouldBeUnevaluated) {
         enterLazy();
         AbortConstant error = handleConstructorInvocation(
-            constructor, typeArguments, positionals, named);
+            constructor, typeArguments, positionals, named, node);
         if (error != null) return error;
         leaveLazy();
         return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
       }
       AbortConstant error = handleConstructorInvocation(
-          constructor, typeArguments, positionals, named);
+          constructor, typeArguments, positionals, named, node);
       if (error != null) return error;
       if (shouldBeUnevaluated) {
         return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
@@ -1547,11 +1537,15 @@
       Constructor constructor,
       List<DartType> typeArguments,
       List<Constant> positionalArguments,
-      Map<String, Constant> namedArguments) {
+      Map<String, Constant> namedArguments,
+      TreeNode caller) {
     return withNewEnvironment(() {
       final Class klass = constructor.enclosingClass;
       final FunctionNode function = constructor.function;
 
+      // Mark in file of the caller that we evaluate this specific constructor.
+      _recordConstructorCoverage(constructor, caller);
+
       // We simulate now the constructor invocation.
 
       // Step 1) Map type arguments and normal arguments from caller to
@@ -1626,8 +1620,8 @@
           }
           assert(_gotError == null);
           assert(namedArguments != null);
-          error = handleConstructorInvocation(
-              init.target, types, positionalArguments, namedArguments);
+          error = handleConstructorInvocation(init.target, types,
+              positionalArguments, namedArguments, constructor);
           if (error != null) return error;
         } else if (init is RedirectingInitializer) {
           // Since a redirecting constructor targets a constructor of the same
@@ -1654,8 +1648,8 @@
           assert(_gotError == null);
           assert(namedArguments != null);
 
-          error = handleConstructorInvocation(
-              init.target, typeArguments, positionalArguments, namedArguments);
+          error = handleConstructorInvocation(init.target, typeArguments,
+              positionalArguments, namedArguments, constructor);
           if (error != null) return error;
         } else if (init is AssertInitializer) {
           AbortConstant error = checkAssert(init.statement);
@@ -2170,7 +2164,7 @@
     }
     if (concatenated.length > 1) {
       final List<Expression> expressions =
-          new List<Expression>(concatenated.length);
+          new List<Expression>.filled(concatenated.length, null);
       for (int i = 0; i < concatenated.length; i++) {
         Object value = concatenated[i];
         if (value is StringBuffer) {
@@ -2591,7 +2585,7 @@
   bool isSubtype(Constant constant, DartType type, SubtypeCheckMode mode) {
     DartType constantType = constant.getType(_staticTypeContext);
     if (mode == SubtypeCheckMode.ignoringNullabilities) {
-      constantType = rawLegacyErasure(coreTypes, constantType) ?? constantType;
+      constantType = rawLegacyErasure(constantType) ?? constantType;
     }
     bool result = typeEnvironment.isSubtypeOf(constantType, type, mode);
     if (targetingJavaScript && !result) {
@@ -2742,9 +2736,9 @@
   Arguments unevaluatedArguments(List<Constant> positionalArgs,
       Map<String, Constant> namedArgs, List<DartType> types) {
     final List<Expression> positional =
-        new List<Expression>(positionalArgs.length);
+        new List<Expression>.filled(positionalArgs.length, null);
     final List<NamedExpression> named =
-        new List<NamedExpression>(namedArgs.length);
+        new List<NamedExpression>.filled(namedArgs.length, null);
     for (int i = 0; i < positionalArgs.length; ++i) {
       positional[i] = extract(positionalArgs[i]);
     }
@@ -2824,6 +2818,12 @@
   }
 }
 
+class ConstantCoverage {
+  final Map<Uri, Set<Reference>> constructorCoverage;
+
+  ConstantCoverage(this.constructorCoverage);
+}
+
 /// Holds the necessary information for a constant object, namely
 ///   * the [klass] being instantiated
 ///   * the [typeArguments] used for the instantiation
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 06237ec..509c236 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -3036,7 +3036,7 @@
 
     List<TypeBuilder> argumentBuilders;
     if (arguments != null) {
-      argumentBuilders = new List<TypeBuilder>(arguments.length);
+      argumentBuilders = new List<TypeBuilder>.filled(arguments.length, null);
       for (int i = 0; i < argumentBuilders.length; i++) {
         argumentBuilders[i] = _helper
             .validateTypeUse(arguments[i],
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 0b4a166..9ee07dd 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -14,6 +14,7 @@
         NamedExpression,
         Procedure,
         ProcedureKind,
+        ProcedureStubKind,
         ReturnStatement,
         SuperMethodInvocation,
         SuperPropertyGet,
@@ -94,10 +95,8 @@
           finalTarget =
               interfaceMember.memberSignatureOrigin ?? interfaceMember;
         }
-        stub.isMemberSignature = false;
-        stub.memberSignatureOrigin = null;
-        stub.isForwardingStub = true;
-        stub.forwardingStubInterfaceTarget = finalTarget;
+        stub.stubKind = ProcedureStubKind.ForwardingStub;
+        stub.stubTarget = finalTarget;
         if (_combinedMemberSignature.needsSuperImpl) {
           _createForwardingImplIfNeeded(
               stub.function, stub.name, classBuilder.cls);
@@ -140,13 +139,6 @@
       superTarget = superTarget.memberSignatureOrigin ?? superTarget;
     }
     procedure.isAbstract = false;
-    if (!procedure.isForwardingStub) {
-      // This procedure exists abstractly in the source code; we need to make it
-      // concrete and give it a body that is a forwarding stub.  This situation
-      // is called a "forwarding semi-stub".
-      procedure.isForwardingStub = true;
-      procedure.isForwardingSemiStub = true;
-    }
     List<Expression> positionalArguments = function.positionalParameters
         .map<Expression>((parameter) => new VariableGet(parameter))
         .toList();
@@ -186,6 +178,7 @@
     }
     function.body = new ReturnStatement(superCall)..parent = function;
     procedure.transformerFlags |= TransformerFlag.superCalls;
-    procedure.forwardingStubSuperTarget = superTarget;
+    procedure.stubKind = ProcedureStubKind.ForwardingSuperStub;
+    procedure.stubTarget = superTarget;
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index 971b0e5..a636968 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -112,8 +112,7 @@
       for (ImplicitFieldType overridden in _overriddenFields) {
         DartType overriddenType = overridden.inferType();
         if (!fieldBuilder.library.isNonNullableByDefault) {
-          overriddenType = legacyErasure(
-              fieldBuilder.library.loader.coreTypes, overriddenType);
+          overriddenType = legacyErasure(overriddenType);
         }
         if (inferredType == null) {
           inferredType = overriddenType;
@@ -166,8 +165,7 @@
       for (ImplicitFieldType overridden in _overriddenFields) {
         DartType overriddenType = overridden.inferType();
         if (!fieldBuilder.library.isNonNullableByDefault) {
-          overriddenType = legacyErasure(
-              fieldBuilder.library.loader.coreTypes, overriddenType);
+          overriddenType = legacyErasure(overriddenType);
         }
         if (type != overriddenType) {
           String name = fieldBuilder.fullNameForErrors;
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 f64bdf2..76afeea 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -422,7 +422,7 @@
         computeConstructorReturnType(node.target, inferrer.coreTypes));
     InvocationInferenceResult result = inferrer.inferInvocation(
         typeContext, node.fileOffset, functionType, node.arguments,
-        isConst: node.isConst);
+        isConst: node.isConst, staticTarget: node.target);
     if (!inferrer.isTopLevel) {
       SourceLibraryBuilder library = inferrer.library;
       if (!hasExplicitTypeArguments) {
@@ -450,7 +450,8 @@
             [], const DynamicType(), inferrer.library.nonNullable);
     TypeArgumentsInfo typeArgumentsInfo = getTypeArgumentsInfo(node.arguments);
     InvocationInferenceResult result = inferrer.inferInvocation(
-        typeContext, node.fileOffset, calleeType, node.arguments);
+        typeContext, node.fileOffset, calleeType, node.arguments,
+        staticTarget: node.target);
     Expression replacement = new StaticInvocation(node.target, node.arguments);
     if (!inferrer.isTopLevel && node.target != null) {
       inferrer.library.checkBoundsInStaticInvocation(
@@ -711,7 +712,7 @@
 
     InvocationInferenceResult result = inferrer.inferInvocation(
         typeContext, node.fileOffset, functionType, node.arguments,
-        isConst: node.isConst);
+        isConst: node.isConst, staticTarget: node.target);
     node.hasBeenInferred = true;
     Expression resultNode = node;
     if (!inferrer.isTopLevel) {
@@ -742,7 +743,7 @@
     calleeType = replaceReturnType(calleeType, calleeType.returnType.unalias);
     InvocationInferenceResult result = inferrer.inferInvocation(
         typeContext, node.fileOffset, calleeType, node.arguments,
-        isConst: node.isConst);
+        isConst: node.isConst, staticTarget: node.target);
     node.hasBeenInferred = true;
     Expression resultNode = node;
     if (!inferrer.isTopLevel) {
@@ -770,7 +771,7 @@
     calleeType = replaceReturnType(calleeType, calleeType.returnType.unalias);
     InvocationInferenceResult result = inferrer.inferInvocation(
         typeContext, node.fileOffset, calleeType, node.arguments,
-        isConst: node.isConst);
+        isConst: node.isConst, staticTarget: node.target);
     node.hasBeenInferred = true;
     Expression resultNode = node;
     if (!inferrer.isTopLevel) {
@@ -1149,8 +1150,12 @@
             lhsResult.inferredType, equalsName, node.fileOffset)
         .member;
 
+    // This ends any shorting in `node.left`.
+    Expression left = lhsResult.expression;
+
     inferrer.flowAnalysis
         .ifNullExpression_rightBegin(node.left, lhsResult.inferredType);
+
     // - Let J = T0 if K is `?` else K.
     // - Infer e1 in context J to get T1
     ExpressionInferenceResult rhsResult;
@@ -1173,15 +1178,13 @@
         .getStandardUpperBound(nonNullableLhsType, rhsResult.inferredType,
             inferrer.library.library);
     Expression replacement;
-    if (lhsResult.expression is ThisExpression) {
-      replacement = lhsResult.expression;
+    if (left is ThisExpression) {
+      replacement = left;
     } else {
       VariableDeclaration variable =
-          createVariable(lhsResult.expression, lhsResult.inferredType);
+          createVariable(left, lhsResult.inferredType);
       MethodInvocation equalsNull = createEqualsNull(
-          lhsResult.expression.fileOffset,
-          createVariableGet(variable),
-          equalsMember);
+          left.fileOffset, createVariableGet(variable), equalsMember);
       VariableGet variableGet = createVariableGet(variable);
       if (inferrer.library.isNonNullableByDefault &&
           !identical(nonNullableLhsType, originalLhsType)) {
@@ -2536,19 +2539,11 @@
   ExpressionInferenceResult visitMethodInvocation(
       MethodInvocation node, DartType typeContext) {
     assert(node.name != unaryMinusName);
-    ExpressionInferenceResult result =
-        inferrer.inferExpression(node.receiver, const UnknownType(), true);
-    Expression receiver;
-    DartType receiverType;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = result.nullAwareGuards;
-      receiver = result.nullAwareAction;
-      receiverType = result.nullAwareActionType;
-    } else {
-      receiver = result.expression;
-      receiverType = result.inferredType;
-    }
+    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
+        node.receiver, const UnknownType(), true);
+    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
+    Expression receiver = result.nullAwareAction;
+    DartType receiverType = result.nullAwareActionType;
     return inferrer.inferMethodInvocation(node.fileOffset, nullAwareGuards,
         receiver, receiverType, node.name, node.arguments, typeContext,
         isExpressionInvocation: false, isImplicitCall: false);
@@ -2556,19 +2551,11 @@
 
   ExpressionInferenceResult visitExpressionInvocation(
       ExpressionInvocation node, DartType typeContext) {
-    ExpressionInferenceResult result =
-        inferrer.inferExpression(node.expression, const UnknownType(), true);
-    Expression receiver;
-    DartType receiverType;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = result.nullAwareGuards;
-      receiver = result.nullAwareAction;
-      receiverType = result.nullAwareActionType;
-    } else {
-      receiver = result.expression;
-      receiverType = result.inferredType;
-    }
+    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
+        node.expression, const UnknownType(), true);
+    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
+    Expression receiver = result.nullAwareAction;
+    DartType receiverType = result.nullAwareActionType;
     return inferrer.inferMethodInvocation(node.fileOffset, nullAwareGuards,
         receiver, receiverType, callName, node.arguments, typeContext,
         isExpressionInvocation: true, isImplicitCall: true);
@@ -2601,19 +2588,13 @@
   @override
   ExpressionInferenceResult visitNullCheck(
       NullCheck node, DartType typeContext) {
-    ExpressionInferenceResult operandResult = inferrer.inferExpression(
+    ExpressionInferenceResult operandResult = inferrer.inferNullAwareExpression(
         node.operand, inferrer.computeNullable(typeContext), true);
-    Link<NullAwareGuard> nullAwareGuards;
-    Expression operand;
-    DartType operandType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = operandResult.nullAwareGuards;
-      operand = operandResult.nullAwareAction;
-      operandType = operandResult.nullAwareActionType;
-    } else {
-      operand = operandResult.expression;
-      operandType = operandResult.inferredType;
-    }
+
+    Link<NullAwareGuard> nullAwareGuards = operandResult.nullAwareGuards;
+    Expression operand = operandResult.nullAwareAction;
+    DartType operandType = operandResult.nullAwareActionType;
+
     node.operand = operand..parent = node;
     reportNonNullableInNullAwareWarningIfNeeded(
         operandType, "!", node.operand.fileOffset);
@@ -2748,21 +2729,13 @@
 
   ExpressionInferenceResult visitCompoundPropertySet(
       CompoundPropertySet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: false);
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: false);
 
-    Link<NullAwareGuard> nullAwareGuards;
-    Expression receiver;
-    DartType receiverType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
 
     VariableDeclaration receiverVariable;
     Expression readReceiver;
@@ -2820,21 +2793,13 @@
 
   ExpressionInferenceResult visitIfNullPropertySet(
       IfNullPropertySet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: false);
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: false);
 
-    Link<NullAwareGuard> nullAwareGuards;
-    Expression receiver;
-    DartType receiverType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
 
     VariableDeclaration receiverVariable =
         createVariable(receiver, receiverType);
@@ -2923,20 +2888,14 @@
   ExpressionInferenceResult visitIfNullSet(
       IfNullSet node, DartType typeContext) {
     ExpressionInferenceResult readResult =
-        inferrer.inferExpression(node.read, const UnknownType(), true);
+        inferrer.inferNullAwareExpression(node.read, const UnknownType(), true);
     reportNonNullableInNullAwareWarningIfNeeded(
         readResult.inferredType, "??=", node.read.fileOffset);
-    Link<NullAwareGuard> nullAwareGuards;
-    Expression read;
-    DartType readType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = readResult.nullAwareGuards;
-      read = readResult.nullAwareAction;
-      readType = readResult.nullAwareActionType;
-    } else {
-      read = readResult.expression;
-      readType = readResult.inferredType;
-    }
+
+    Link<NullAwareGuard> nullAwareGuards = readResult.nullAwareGuards;
+    Expression read = readResult.nullAwareAction;
+    DartType readType = readResult.nullAwareActionType;
+
     inferrer.flowAnalysis.ifNullExpression_rightBegin(read, readType);
     ExpressionInferenceResult writeResult = inferrer
         .inferExpression(node.write, typeContext, true, isVoidAllowed: true);
@@ -2991,20 +2950,13 @@
   }
 
   ExpressionInferenceResult visitIndexGet(IndexGet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: true);
-    Expression receiver;
-    DartType receiverType;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: true);
+
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
 
     ObjectAccessTarget indexGetTarget = inferrer.findInterfaceMember(
         receiverType, indexGetName, node.fileOffset,
@@ -3028,20 +2980,14 @@
   }
 
   ExpressionInferenceResult visitIndexSet(IndexSet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: true);
-    Expression receiver;
-    DartType receiverType;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: true);
+
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
+
     VariableDeclaration receiverVariable;
     if (!node.forEffect && !node.readOnlyReceiver) {
       receiverVariable = createVariable(receiver, receiverType);
@@ -3233,21 +3179,14 @@
 
   ExpressionInferenceResult visitIfNullIndexSet(
       IfNullIndexSet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: true);
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: true);
 
-    Expression receiver;
-    DartType receiverType;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
+
     VariableDeclaration receiverVariable;
     Expression readReceiver = receiver;
     Expression writeReceiver;
@@ -3899,7 +3838,7 @@
     }
 
     if (!inferrer.isNonNullableByDefault) {
-      binaryType = legacyErasure(inferrer.coreTypes, binaryType);
+      binaryType = legacyErasure(binaryType);
     }
 
     if (!inferrer.isTopLevel && binaryTarget.isNullable) {
@@ -3996,7 +3935,7 @@
     }
 
     if (!inferrer.isNonNullableByDefault) {
-      unaryType = legacyErasure(inferrer.coreTypes, unaryType);
+      unaryType = legacyErasure(unaryType);
     }
 
     if (!inferrer.isTopLevel && unaryTarget.isNullable) {
@@ -4084,7 +4023,7 @@
     }
 
     if (!inferrer.isNonNullableByDefault) {
-      readType = legacyErasure(inferrer.coreTypes, readType);
+      readType = legacyErasure(readType);
     }
 
     if (!inferrer.isTopLevel && readTarget.isNullable) {
@@ -4282,7 +4221,7 @@
     }
 
     if (!inferrer.isNonNullableByDefault) {
-      readType = legacyErasure(inferrer.coreTypes, readType);
+      readType = legacyErasure(readType);
     }
 
     readResult ??= new ExpressionInferenceResult(readType, read);
@@ -4384,20 +4323,14 @@
 
   ExpressionInferenceResult visitCompoundIndexSet(
       CompoundIndexSet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: true);
-    Expression receiver;
-    Link<NullAwareGuard> nullAwareGuards;
-    DartType receiverType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: true);
+
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
+
     VariableDeclaration receiverVariable;
     Expression readReceiver = receiver;
     Expression writeReceiver;
@@ -4542,24 +4475,15 @@
 
   ExpressionInferenceResult visitNullAwareCompoundSet(
       NullAwareCompoundSet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: true);
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: true);
     reportNonNullableInNullAwareWarningIfNeeded(
         receiverResult.inferredType, "?.", node.receiver.fileOffset);
 
-    Expression receiver;
-    DartType receiverType;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-      nullAwareGuards = receiverResult.nullAwareGuards;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-      nullAwareGuards = const Link<NullAwareGuard>();
-    }
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
 
     VariableDeclaration receiverVariable =
         createVariable(receiver, receiverType);
@@ -5027,20 +4951,14 @@
   @override
   ExpressionInferenceResult visitPropertySet(
       covariant PropertySetImpl node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: false);
-    DartType receiverType;
-    Expression receiver;
-    Link<NullAwareGuard> nullAwareGuards;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: false);
+
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
+
     ObjectAccessTarget target = inferrer.findInterfaceMember(
         receiverType, node.name, node.fileOffset,
         setter: true, instrumented: true, includeExtensionMethods: true);
@@ -5073,24 +4991,15 @@
 
   ExpressionInferenceResult visitNullAwareIfNullSet(
       NullAwareIfNullSet node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        node.receiver, const UnknownType(), true,
-        isVoidAllowed: false);
+    ExpressionInferenceResult receiverResult = inferrer
+        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
+            isVoidAllowed: false);
     reportNonNullableInNullAwareWarningIfNeeded(
         receiverResult.inferredType, "?.", node.receiver.fileOffset);
 
-    Link<NullAwareGuard> nullAwareGuards;
-    Expression receiver;
-    DartType receiverType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = receiverResult.nullAwareGuards;
-      receiver = receiverResult.nullAwareAction;
-      receiverType = receiverResult.nullAwareActionType;
-    } else {
-      nullAwareGuards = const Link<NullAwareGuard>();
-      receiver = receiverResult.expression;
-      receiverType = receiverResult.inferredType;
-    }
+    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
+    Expression receiver = receiverResult.nullAwareAction;
+    DartType receiverType = receiverResult.nullAwareActionType;
 
     VariableDeclaration receiverVariable =
         createVariable(receiver, receiverType);
@@ -5184,19 +5093,13 @@
   @override
   ExpressionInferenceResult visitPropertyGet(
       PropertyGet node, DartType typeContext) {
-    ExpressionInferenceResult result =
-        inferrer.inferExpression(node.receiver, const UnknownType(), true);
-    Link<NullAwareGuard> nullAwareGuards;
-    Expression receiver;
-    DartType receiverType;
-    if (inferrer.isNonNullableByDefault) {
-      nullAwareGuards = result.nullAwareGuards;
-      receiver = result.nullAwareAction;
-      receiverType = result.nullAwareActionType;
-    } else {
-      receiver = result.expression;
-      receiverType = result.inferredType;
-    }
+    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
+        node.receiver, const UnknownType(), true);
+
+    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
+    Expression receiver = result.nullAwareAction;
+    DartType receiverType = result.nullAwareActionType;
+
     node.receiver = receiver..parent = node;
     ExpressionInferenceResult readResult = _computePropertyGet(
         node.fileOffset, receiver, receiverType, node.name, typeContext,
@@ -5211,7 +5114,7 @@
     List<TypeParameter> classTypeParameters =
         node.target.enclosingClass.typeParameters;
     List<DartType> typeArguments =
-        new List<DartType>(classTypeParameters.length);
+        new List<DartType>.filled(classTypeParameters.length, null);
     for (int i = 0; i < typeArguments.length; i++) {
       typeArguments[i] = new TypeParameterType.withDefaultNullabilityForLibrary(
           classTypeParameters[i], inferrer.library.library);
@@ -5224,7 +5127,7 @@
             node.target.enclosingClass, inferrer.library.nonNullable));
     inferrer.inferInvocation(
         null, node.fileOffset, functionType, node.arguments,
-        skipTypeArgumentInference: true);
+        skipTypeArgumentInference: true, staticTarget: node.target);
     ArgumentsImpl.removeNonInferrableArgumentTypes(node.arguments);
   }
 
@@ -5373,7 +5276,7 @@
     DartType type = target.getterType;
 
     if (!inferrer.isNonNullableByDefault) {
-      type = legacyErasure(inferrer.coreTypes, type);
+      type = legacyErasure(type);
     }
 
     if (target is Procedure && target.kind == ProcedureKind.Method) {
@@ -5392,7 +5295,8 @@
             [], const DynamicType(), inferrer.library.nonNullable);
     TypeArgumentsInfo typeArgumentsInfo = getTypeArgumentsInfo(node.arguments);
     InvocationInferenceResult result = inferrer.inferInvocation(
-        typeContext, node.fileOffset, calleeType, node.arguments);
+        typeContext, node.fileOffset, calleeType, node.arguments,
+        staticTarget: node.target);
     if (!inferrer.isTopLevel && node.target != null) {
       inferrer.library.checkBoundsInStaticInvocation(
           node,
@@ -5439,7 +5343,7 @@
         inferrer.thisType);
     inferrer.inferInvocation(
         null, node.fileOffset, functionType, node.arguments,
-        skipTypeArgumentInference: true);
+        skipTypeArgumentInference: true, staticTarget: node.target);
   }
 
   @override
@@ -5886,7 +5790,10 @@
       }
     }
     if (node.isLate &&
-        !inferrer.library.loader.target.backendTarget.supportsLateFields) {
+        inferrer.library.loader.target.backendTarget.isLateLocalLoweringEnabled(
+            hasInitializer: node.hasDeclaredInitializer,
+            isFinal: node.isFinal,
+            isPotentiallyNullable: node.type.isPotentiallyNullable)) {
       int fileOffset = node.fileOffset;
 
       List<Statement> result = <Statement>[];
@@ -5898,11 +5805,10 @@
       VariableDeclaration isSetVariable;
       if (isSetEncoding == late_lowering.IsSetEncoding.useIsSetField) {
         isSetVariable = new VariableDeclaration(
-            '${late_lowering.lateLocalPrefix}'
-            '${node.name}'
-            '${late_lowering.lateIsSetSuffix}',
+            late_lowering.computeLateLocalIsSetName(node.name),
             initializer: new BoolLiteral(false)..fileOffset = fileOffset,
-            type: inferrer.coreTypes.boolRawType(inferrer.library.nonNullable))
+            type: inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
+            isLowered: true)
           ..fileOffset = fileOffset;
         result.add(isSetVariable);
       }
@@ -5922,11 +5828,10 @@
       Expression createIsSetWrite(Expression value) =>
           new VariableSet(isSetVariable, value);
 
-      VariableDeclaration getVariable =
-          new VariableDeclaration('${late_lowering.lateLocalPrefix}'
-              '${node.name}'
-              '${late_lowering.lateLocalGetterSuffix}')
-            ..fileOffset = fileOffset;
+      VariableDeclaration getVariable = new VariableDeclaration(
+          late_lowering.computeLateLocalGetterName(node.name),
+          isLowered: true)
+        ..fileOffset = fileOffset;
       FunctionDeclaration getter = new FunctionDeclaration(
           getVariable,
           new FunctionNode(
@@ -5937,17 +5842,30 @@
                       createIsSetRead: createIsSetRead,
                       isSetEncoding: isSetEncoding,
                       forField: false)
-                  : late_lowering.createGetterWithInitializer(
-                      inferrer.coreTypes,
-                      fileOffset,
-                      node.name,
-                      node.type,
-                      node.initializer,
-                      createVariableRead: createVariableRead,
-                      createVariableWrite: createVariableWrite,
-                      createIsSetRead: createIsSetRead,
-                      createIsSetWrite: createIsSetWrite,
-                      isSetEncoding: isSetEncoding),
+                  : (node.isFinal
+                      ? late_lowering.createGetterWithInitializerWithRecheck(
+                          inferrer.coreTypes,
+                          fileOffset,
+                          node.name,
+                          node.type,
+                          node.initializer,
+                          createVariableRead: createVariableRead,
+                          createVariableWrite: createVariableWrite,
+                          createIsSetRead: createIsSetRead,
+                          createIsSetWrite: createIsSetWrite,
+                          isSetEncoding: isSetEncoding,
+                          forField: false)
+                      : late_lowering.createGetterWithInitializer(
+                          inferrer.coreTypes,
+                          fileOffset,
+                          node.name,
+                          node.type,
+                          node.initializer,
+                          createVariableRead: createVariableRead,
+                          createVariableWrite: createVariableWrite,
+                          createIsSetRead: createIsSetRead,
+                          createIsSetWrite: createIsSetWrite,
+                          isSetEncoding: isSetEncoding)),
               returnType: node.type))
         ..fileOffset = fileOffset;
       getVariable.type =
@@ -5958,11 +5876,10 @@
       if (!node.isFinal || node.initializer == null) {
         node.isLateFinalWithoutInitializer =
             node.isFinal && node.initializer == null;
-        VariableDeclaration setVariable =
-            new VariableDeclaration('${late_lowering.lateLocalPrefix}'
-                '${node.name}'
-                '${late_lowering.lateLocalSetterSuffix}')
-              ..fileOffset = fileOffset;
+        VariableDeclaration setVariable = new VariableDeclaration(
+            late_lowering.computeLateLocalSetterName(node.name),
+            isLowered: true)
+          ..fileOffset = fileOffset;
         VariableDeclaration setterParameter =
             new VariableDeclaration(null, type: node.type)
               ..fileOffset = fileOffset;
@@ -6012,6 +5929,9 @@
         node.initializer = null;
       }
       node.type = inferrer.computeNullable(node.type);
+      node.lateName = node.name;
+      node.isLowered = true;
+      node.name = late_lowering.computeLateLocalName(node.name);
 
       return new StatementInferenceResult.multiple(node.fileOffset, result);
     }
@@ -6084,14 +6004,14 @@
             declaredOrInferredType is! InvalidType) {
           if (variable.isLate || variable.lateGetter != null) {
             if (isDefinitelyUnassigned) {
+              String name = variable.lateName ?? variable.name;
               return new ExpressionInferenceResult(
                   resultType,
                   inferrer.helper.wrapInProblem(
                       resultExpression,
-                      templateLateDefinitelyUnassignedError
-                          .withArguments(node.variable.name),
+                      templateLateDefinitelyUnassignedError.withArguments(name),
                       node.fileOffset,
-                      node.variable.name.length));
+                      name.length));
             }
           } else {
             if (isUnassigned) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index dc9dfa1..9504a6e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1428,6 +1428,7 @@
       bool isLocalFunction: false,
       bool isLate: false,
       bool isRequired: false,
+      bool isLowered: false,
       this.isStaticLate: false})
       : isImplicitlyTyped = type == null,
         isLocalFunction = isLocalFunction,
@@ -1439,7 +1440,8 @@
             isFieldFormal: isFieldFormal,
             isCovariant: isCovariant,
             isLate: isLate,
-            isRequired: isRequired);
+            isRequired: isRequired,
+            isLowered: isLowered);
 
   VariableDeclarationImpl.forEffect(Expression initializer)
       : forSyntheticToken = false,
@@ -1484,6 +1486,12 @@
   // lowering is enabled.
   DartType lateType;
 
+  // The original name of a lowered late variable.
+  //
+  // This is set in `InferenceVisitor.visitVariableDeclaration` when late
+  // lowering is enabled.
+  String lateName;
+
   @override
   bool get isAssignable {
     if (isStaticLate) return true;
@@ -1937,6 +1945,17 @@
   String toString() {
     return "CompoundPropertySet(${toStringInternal()})";
   }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver);
+    printer.write('.');
+    printer.writeName(propertyName);
+    printer.write(' ');
+    printer.writeName(binaryName);
+    printer.write('= ');
+    printer.writeExpression(rhs);
+  }
 }
 
 /// Internal expression representing an compound property assignment.
@@ -2939,6 +2958,28 @@
   String toString() {
     return "NullAwareCompoundSet(${toStringInternal()})";
   }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver);
+    printer.write('?.');
+    printer.writeName(propertyName);
+    if (forPostIncDec &&
+        rhs is IntLiteral &&
+        (rhs as IntLiteral).value == 1 &&
+        (binaryName == plusName || binaryName == minusName)) {
+      if (binaryName == plusName) {
+        printer.write('++');
+      } else {
+        printer.write('--');
+      }
+    } else {
+      printer.write(' ');
+      printer.writeName(binaryName);
+      printer.write('= ');
+      printer.writeExpression(rhs);
+    }
+  }
 }
 
 /// Internal expression representing an null-aware if-null property set.
@@ -3026,6 +3067,15 @@
   String toString() {
     return "NullAwareIfNullSet(${toStringInternal()})";
   }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver);
+    printer.write('?.');
+    printer.writeName(name);
+    printer.write(' ??= ');
+    printer.writeExpression(value);
+  }
 }
 
 /// Internal expression representing a compound super index assignment.
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index a1167d5..5f55924 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -105,7 +105,11 @@
 import '../target_implementation.dart' show TargetImplementation;
 import '../uri_translator.dart' show UriTranslator;
 import 'constant_evaluator.dart' as constants
-    show EvaluationMode, transformLibraries, transformProcedure;
+    show
+        EvaluationMode,
+        transformLibraries,
+        transformProcedure,
+        ConstantCoverage;
 import 'kernel_constants.dart' show KernelConstantErrorReporter;
 import 'metadata_collector.dart' show MetadataCollector;
 import 'verifier.dart' show verifyComponent, verifyGetStaticType;
@@ -126,6 +130,10 @@
 
   Component component;
 
+  /// Temporary field meant for testing only. Follow-up CLs should get rid of
+  /// this and integrate coverage properly.
+  constants.ConstantCoverage constantCoverageForTesting;
+
   // 'dynamic' is always nullable.
   // TODO(johnniwinther): Why isn't this using a FixedTypeBuilder?
   final TypeBuilder dynamicType = new NamedTypeBuilder(
@@ -190,7 +198,7 @@
 
   /// Return list of same size as input with possibly translated uris.
   List<Uri> setEntryPoints(List<Uri> entryPoints) {
-    List<Uri> result = new List<Uri>();
+    List<Uri> result = <Uri>[];
     for (Uri entryPoint in entryPoints) {
       Uri translatedEntryPoint =
           getEntryPointUri(entryPoint, issueProblem: true);
@@ -749,7 +757,15 @@
 
     Class cls = classBuilder.cls;
     Constructor constructor = memberBuilder.member;
-    bool isConst = constructor.isConst && mixin.fields.isEmpty;
+    bool isConst = constructor.isConst;
+    if (isConst && mixin.fields.isNotEmpty) {
+      for (Field field in mixin.fields) {
+        if (!field.isStatic) {
+          isConst = false;
+          break;
+        }
+      }
+    }
     List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
     List<VariableDeclaration> namedParameters = <VariableDeclaration>[];
     List<Expression> positional = <Expression>[];
@@ -792,8 +808,8 @@
             isSynthetic: true,
             isConst: isConst,
             reference: referenceFrom?.reference)
-          ..isNonNullableByDefault =
-              cls.enclosingLibrary.isNonNullableByDefault,
+          ..isNonNullableByDefault = cls.enclosingLibrary.isNonNullableByDefault
+          ..fileUri = cls.fileUri,
         // If the constructor is constant, the default values must be part of
         // the outline expressions. We pass on the original constructor and
         // cloned function nodes to ensure that the default values are computed
@@ -826,7 +842,7 @@
   }
 
   DartType makeConstructorReturnType(Class enclosingClass) {
-    List<DartType> typeParameterTypes = new List<DartType>();
+    List<DartType> typeParameterTypes = <DartType>[];
     for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
       TypeParameter typeParameter = enclosingClass.typeParameters[i];
       typeParameterTypes.add(
@@ -1184,8 +1200,8 @@
           name,
           isInstanceMember: fieldBuilder.isClassInstanceMember,
           className: builder.name,
-          isSynthesized: fieldBuilder.isLate &&
-              !builder.library.loader.target.backendTarget.supportsLateFields,
+          isSynthesized:
+              fieldBuilder is SourceFieldBuilder && fieldBuilder.isLateLowered,
         ));
       });
       builder.forEach((String name, Builder builder) {
@@ -1223,7 +1239,7 @@
         new TypeEnvironment(loader.coreTypes, loader.hierarchy);
     constants.EvaluationMode evaluationMode = _getConstantEvaluationMode();
 
-    constants.transformLibraries(
+    constants.ConstantCoverage coverage = constants.transformLibraries(
         loader.libraries,
         backendTarget.constantsBackend(loader.coreTypes),
         environmentDefines,
@@ -1231,11 +1247,20 @@
         new KernelConstantErrorReporter(loader),
         evaluationMode,
         evaluateAnnotations: true,
-        desugarSets: !backendTarget.supportsSetLiterals,
         enableTripleShift:
             isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
     ticker.logMs("Evaluated constants");
+    constantCoverageForTesting = coverage;
+
+    coverage.constructorCoverage.forEach((Uri fileUri, Set<Reference> value) {
+      Source source = uriToSource[fileUri];
+      if (source != null && fileUri != null) {
+        source.constantCoverageConstructors ??= new Set<Reference>();
+        source.constantCoverageConstructors.addAll(value);
+      }
+    });
+    ticker.logMs("Added constant coverage");
 
     if (loader.target.context.options
         .isExperimentEnabledGlobally(ExperimentalFlag.valueClass)) {
@@ -1271,7 +1296,6 @@
         new KernelConstantErrorReporter(loader),
         evaluationMode,
         evaluateAnnotations: true,
-        desugarSets: !backendTarget.supportsSetLiterals,
         enableTripleShift:
             isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index f1b548e..02ee9f2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -16,13 +16,10 @@
 const String lateLocalSetterSuffix = '#set';
 
 /// Creates the body for the synthesized getter used to encode the lowering
-/// of a late non-final field with an initializer or a late local with an
-/// initializer.
+/// of a late non-final field or local with an initializer.
 ///
-/// Late final field needs to detect writes during initialization and therefore
-/// uses [createGetterWithInitializerWithRecheck] instead. Late final locals
-/// cannot have writes during initialization since they are not in scope in
-/// their own initializer.
+/// Late final fields and locals need to detect writes during initialization and
+/// therefore uses [createGetterWithInitializerWithRecheck] instead.
 Statement createGetterWithInitializer(CoreTypes coreTypes, int fileOffset,
     String name, DartType type, Expression initializer,
     {Expression createVariableRead({bool needsPromotion}),
@@ -120,23 +117,23 @@
 }
 
 /// Creates the body for the synthesized getter used to encode the lowering
-/// of a late final field with an initializer.
-///
-/// A late final field needs to detect writes during initialization for
-/// which a `LateInitializationError` should be thrown. Late final locals
-/// cannot have writes during initialization since they are not in scope in
-/// their own initializer.
+/// of a late final field or local with an initializer.
 Statement createGetterWithInitializerWithRecheck(CoreTypes coreTypes,
     int fileOffset, String name, DartType type, Expression initializer,
     {Expression createVariableRead({bool needsPromotion}),
     Expression createVariableWrite(Expression value),
     Expression createIsSetRead(),
     Expression createIsSetWrite(Expression value),
-    IsSetEncoding isSetEncoding}) {
+    IsSetEncoding isSetEncoding,
+    bool forField}) {
+  assert(forField != null);
+  Constructor constructor = forField
+      ? coreTypes.lateInitializationFieldAssignedDuringInitializationConstructor
+      : coreTypes
+          .lateInitializationLocalAssignedDuringInitializationConstructor;
   Expression exception = new Throw(
       new ConstructorInvocation(
-          coreTypes
-              .lateInitializationFieldAssignedDuringInitializationConstructor,
+          constructor,
           new Arguments(
               <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
             ..fileOffset = fileOffset)
@@ -538,6 +535,11 @@
   /// been initialized.
   forceUseIsSetField,
 
+  /// Always use `createSentinel`and `isSentinel` from `dart:_internal` to
+  /// generate and check a sentinel value to signal an uninitialized
+  /// field/local.
+  forceUseSentinel,
+
   /// For potentially nullable fields/locals use an `isSet` field/local to track
   /// whether the field/local has been initialized. Otherwise use `null` as
   /// sentinel value to signal an uninitialized field/local.
@@ -557,7 +559,13 @@
 IsSetStrategy computeIsSetStrategy(SourceLibraryBuilder libraryBuilder) {
   IsSetStrategy isSetStrategy = IsSetStrategy.useIsSetFieldOrNull;
   if (libraryBuilder.loader.target.backendTarget.supportsLateLoweringSentinel) {
-    isSetStrategy = IsSetStrategy.useSentinelOrNull;
+    if (libraryBuilder.loader.nnbdMode != NnbdMode.Strong) {
+      // Non-nullable fields/locals might contain `null` so we always use the
+      // sentinel.
+      isSetStrategy = IsSetStrategy.forceUseSentinel;
+    } else {
+      isSetStrategy = IsSetStrategy.useSentinelOrNull;
+    }
   } else if (libraryBuilder.loader.nnbdMode != NnbdMode.Strong) {
     isSetStrategy = IsSetStrategy.forceUseIsSetField;
   }
@@ -568,6 +576,8 @@
   switch (isSetStrategy) {
     case IsSetStrategy.forceUseIsSetField:
       return IsSetEncoding.useIsSetField;
+    case IsSetStrategy.forceUseSentinel:
+      return IsSetEncoding.useSentinel;
     case IsSetStrategy.useIsSetFieldOrNull:
       return type.isPotentiallyNullable
           ? IsSetEncoding.useIsSetField
@@ -579,3 +589,27 @@
   }
   throw new UnsupportedError("Unexpected IsSetStrategy $isSetStrategy");
 }
+
+/// Returns the name used for the variable that holds the value of a late
+/// lowered local by the given [name].
+String computeLateLocalName(String name) {
+  return '${lateLocalPrefix}$name';
+}
+
+/// Returns the name used for the 'isSet' variable of a late lowered local by
+/// the given [name].
+String computeLateLocalIsSetName(String name) {
+  return '${lateLocalPrefix}${name}${lateIsSetSuffix}';
+}
+
+/// Returns the name used for the getter function of a late lowered local by
+/// the given [name].
+String computeLateLocalGetterName(String name) {
+  return '${lateLocalPrefix}${name}${lateLocalGetterSuffix}';
+}
+
+/// Returns the name used for the setter function of a late lowered local by
+/// the given [name].
+String computeLateLocalSetterName(String name) {
+  return '${lateLocalPrefix}${name}${lateLocalSetterSuffix}';
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
index 5d1d77f..6a5eaaf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
@@ -208,8 +208,9 @@
     } else if (other._positionalParameters == null) {
       positionalParameters = _positionalParameters;
     } else {
-      positionalParameters = new List<int>(max(
-          _positionalParameters.length, other._positionalParameters.length));
+      positionalParameters = new List<int>.filled(
+          max(_positionalParameters.length, other._positionalParameters.length),
+          null);
       for (int index = 0; index < positionalParameters.length; index++) {
         positionalParameters[index] =
             getPositionalVariance(index) | other.getPositionalVariance(index);
@@ -237,8 +238,8 @@
     } else if (other._typeParameters == null) {
       typeParameters = _typeParameters;
     } else {
-      typeParameters = new List<bool>(
-          max(_typeParameters.length, other._typeParameters.length));
+      typeParameters = new List<bool>.filled(
+          max(_typeParameters.length, other._typeParameters.length), null);
       for (int index = 0; index < typeParameters.length; index++) {
         typeParameters[index] = isTypeParameterGenericCovariantImpl(index) ||
             other.isTypeParameterGenericCovariantImpl(index);
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index 0d758a1..a7a85b9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -72,18 +72,22 @@
 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
 
 class CollectionTransformer extends Transformer {
-  final CoreTypes coreTypes;
-  final TypeEnvironment typeEnvironment;
-  final Procedure listAdd;
-  final Procedure setFactory;
-  final Procedure setAdd;
-  final Procedure objectEquals;
-  final Procedure mapEntries;
-  final Procedure mapPut;
-  final Class mapEntryClass;
-  final Field mapEntryKey;
-  final Field mapEntryValue;
-  final SourceLoaderDataForTesting dataForTesting;
+  final SourceLoader _loader;
+  final TypeEnvironment _typeEnvironment;
+  final Procedure _listAdd;
+  final Procedure _listAddAll;
+  final Procedure _listOf;
+  final Procedure _setFactory;
+  final Procedure _setAdd;
+  final Procedure _setAddAll;
+  final Procedure _setOf;
+  final Procedure _objectEquals;
+  final Procedure _mapEntries;
+  final Procedure _mapPut;
+  final Class _mapEntryClass;
+  final Field _mapEntryKey;
+  final Field _mapEntryValue;
+  final SourceLoaderDataForTesting _dataForTesting;
 
   /// Library that contains the transformed nodes.
   ///
@@ -91,63 +95,126 @@
   /// the library.
   Library _currentLibrary;
 
-  static Procedure _findSetFactory(CoreTypes coreTypes) {
-    Procedure factory = coreTypes.index.getMember('dart:core', 'Set', '');
+  static Procedure _findSetFactory(CoreTypes coreTypes, String name) {
+    Procedure factory = coreTypes.index.getMember('dart:core', 'Set', name);
     RedirectingFactoryBody body = factory?.function?.body;
     return body?.target;
   }
 
-  CollectionTransformer(SourceLoader loader)
-      : coreTypes = loader.coreTypes,
-        typeEnvironment = loader.typeInferenceEngine.typeSchemaEnvironment,
-        listAdd = loader.coreTypes.index.getMember('dart:core', 'List', 'add'),
-        setFactory = _findSetFactory(loader.coreTypes),
-        setAdd = loader.coreTypes.index.getMember('dart:core', 'Set', 'add'),
-        objectEquals =
-            loader.coreTypes.index.getMember('dart:core', 'Object', '=='),
-        mapEntries =
-            loader.coreTypes.index.getMember('dart:core', 'Map', 'get:entries'),
-        mapPut = loader.coreTypes.index.getMember('dart:core', 'Map', '[]='),
-        mapEntryClass =
-            loader.coreTypes.index.getClass('dart:core', 'MapEntry'),
-        mapEntryKey =
-            loader.coreTypes.index.getMember('dart:core', 'MapEntry', 'key'),
-        mapEntryValue =
-            loader.coreTypes.index.getMember('dart:core', 'MapEntry', 'value'),
-        dataForTesting = loader.dataForTesting;
+  CollectionTransformer(this._loader)
+      : _typeEnvironment = _loader.typeInferenceEngine.typeSchemaEnvironment,
+        _listAdd =
+            _loader.coreTypes.index.getMember('dart:core', 'List', 'add'),
+        _listAddAll =
+            _loader.coreTypes.index.getMember('dart:core', 'List', 'addAll'),
+        _listOf = _loader.coreTypes.index.getMember('dart:core', 'List', 'of'),
+        _setFactory = _findSetFactory(_loader.coreTypes, ''),
+        _setAdd = _loader.coreTypes.index.getMember('dart:core', 'Set', 'add'),
+        _setAddAll =
+            _loader.coreTypes.index.getMember('dart:core', 'Set', 'addAll'),
+        _setOf = _findSetFactory(_loader.coreTypes, 'of'),
+        _objectEquals =
+            _loader.coreTypes.index.getMember('dart:core', 'Object', '=='),
+        _mapEntries = _loader.coreTypes.index
+            .getMember('dart:core', 'Map', 'get:entries'),
+        _mapPut = _loader.coreTypes.index.getMember('dart:core', 'Map', '[]='),
+        _mapEntryClass =
+            _loader.coreTypes.index.getClass('dart:core', 'MapEntry'),
+        _mapEntryKey =
+            _loader.coreTypes.index.getMember('dart:core', 'MapEntry', 'key'),
+        _mapEntryValue =
+            _loader.coreTypes.index.getMember('dart:core', 'MapEntry', 'value'),
+        _dataForTesting = _loader.dataForTesting;
 
   TreeNode _translateListOrSet(
       Expression node, DartType elementType, List<Expression> elements,
       {bool isSet: false}) {
     // Translate elements in place up to the first non-expression, if any.
-    int i = 0;
-    for (; i < elements.length; ++i) {
-      if (elements[i] is ControlFlowElement) break;
-      elements[i] = elements[i].accept<TreeNode>(this)..parent = node;
+    int index = 0;
+    for (; index < elements.length; ++index) {
+      if (elements[index] is ControlFlowElement) break;
+      elements[index] = elements[index].accept<TreeNode>(this)..parent = node;
     }
 
     // If there were only expressions, we are done.
-    if (i == elements.length) return node;
+    if (index == elements.length) return node;
 
-    // Build a block expression and create an empty list or set.
     VariableDeclaration result;
-    if (isSet) {
-      result = _createVariable(
-          _createSetLiteral(node.fileOffset, elementType, []),
-          typeEnvironment.setType(elementType, _currentLibrary.nonNullable));
-    } else {
-      result = _createVariable(
-          _createListLiteral(node.fileOffset, elementType, []),
-          typeEnvironment.listType(elementType, _currentLibrary.nonNullable));
+    if (index == 0 && elements[index] is SpreadElement) {
+      SpreadElement initialSpread = elements[index];
+      final bool typeMatches = initialSpread.elementType != null &&
+          _typeEnvironment.isSubtypeOf(initialSpread.elementType, elementType,
+              SubtypeCheckMode.withNullabilities);
+      if (typeMatches && !initialSpread.isNullAware) {
+        // Create a list or set of the initial spread element.
+        Expression value = initialSpread.expression.accept<TreeNode>(this);
+        index++;
+        if (isSet) {
+          result = _createVariable(
+              new StaticInvocation(
+                  _setOf,
+                  new Arguments([value], types: [elementType])
+                    ..fileOffset = node.fileOffset)
+                ..fileOffset = node.fileOffset,
+              _typeEnvironment.setType(
+                  elementType, _currentLibrary.nonNullable));
+        } else {
+          result = _createVariable(
+              new StaticInvocation(
+                  _listOf,
+                  new Arguments([value], types: [elementType])
+                    ..fileOffset = node.fileOffset)
+                ..fileOffset = node.fileOffset,
+              _typeEnvironment.listType(
+                  elementType, _currentLibrary.nonNullable));
+        }
+      }
     }
-    List<Statement> body = [result];
-    // Add the elements up to the first non-expression.
-    for (int j = 0; j < i; ++j) {
-      _addExpressionElement(elements[j], isSet, result, body);
+    List<Statement> body;
+    if (result == null) {
+      // Create a list or set with the elements up to the first non-expression.
+      if (isSet) {
+        if (_loader.target.backendTarget.supportsSetLiterals) {
+          // Include the elements up to the first non-expression in the set
+          // literal.
+          result = _createVariable(
+              _createSetLiteral(
+                  node.fileOffset, elementType, elements.sublist(0, index)),
+              _typeEnvironment.setType(
+                  elementType, _currentLibrary.nonNullable));
+        } else {
+          // TODO(johnniwinther): When all the back ends handle set literals we
+          //  can use remove this branch.
+
+          // Create an empty set using the [setFactory] constructor.
+          result = _createVariable(
+              new StaticInvocation(
+                  _setFactory,
+                  new Arguments([], types: [elementType])
+                    ..fileOffset = node.fileOffset)
+                ..fileOffset = node.fileOffset,
+              _typeEnvironment.setType(
+                  elementType, _currentLibrary.nonNullable));
+          body = [result];
+          // Add the elements up to the first non-expression.
+          for (int j = 0; j < index; ++j) {
+            _addExpressionElement(elements[j], isSet, result, body);
+          }
+        }
+      } else {
+        // Include the elements up to the first non-expression in the list
+        // literal.
+        result = _createVariable(
+            _createListLiteral(
+                node.fileOffset, elementType, elements.sublist(0, index)),
+            _typeEnvironment.listType(
+                elementType, _currentLibrary.nonNullable));
+      }
     }
+    body ??= [result];
     // Translate the elements starting with the first non-expression.
-    for (; i < elements.length; ++i) {
-      _translateElement(elements[i], elementType, isSet, result, body);
+    for (; index < elements.length; ++index) {
+      _translateElement(elements[index], elementType, isSet, result, body);
     }
 
     return _createBlockExpression(
@@ -212,7 +279,7 @@
         loopBody);
     transformList(loop.variables, this, loop);
     transformList(loop.updates, this, loop);
-    dataForTesting?.registerAlias(element, loop);
+    _dataForTesting?.registerAlias(element, loop);
     body.add(loop);
   }
 
@@ -237,7 +304,7 @@
     ForInStatement loop = _createForInStatement(element.fileOffset,
         element.variable, element.iterable.accept<TreeNode>(this), loopBody,
         isAsync: element.isAsync);
-    dataForTesting?.registerAlias(element, loop);
+    _dataForTesting?.registerAlias(element, loop);
     body.add(loop);
   }
 
@@ -246,49 +313,77 @@
     Expression value = element.expression.accept<TreeNode>(this);
 
     final bool typeMatches = element.elementType != null &&
-        typeEnvironment.isSubtypeOf(element.elementType, elementType,
+        _typeEnvironment.isSubtypeOf(element.elementType, elementType,
             SubtypeCheckMode.withNullabilities);
+    if (typeMatches) {
+      // If the type guarantees that all elements are of the required type, use
+      // a single 'addAll' call instead of a for-loop with calls to 'add'.
 
-    // Null-aware spreads require testing the subexpression's value.
-    VariableDeclaration temp;
-    if (element.isNullAware) {
-      temp = _createVariable(
-          value,
-          typeEnvironment.iterableType(
-              typeMatches ? elementType : const DynamicType(),
-              _currentLibrary.nullable));
-      body.add(temp);
-      value = _createNullCheckedVariableGet(temp);
-    }
+      // Null-aware spreads require testing the subexpression's value.
+      VariableDeclaration temp;
+      if (element.isNullAware) {
+        temp = _createVariable(
+            value,
+            _typeEnvironment.iterableType(
+                typeMatches ? elementType : const DynamicType(),
+                _currentLibrary.nullable));
+        body.add(temp);
+        value = _createNullCheckedVariableGet(temp);
+      }
 
-    VariableDeclaration variable;
-    Statement loopBody;
-    if (!typeMatches) {
-      variable = _createForInVariable(element.fileOffset, const DynamicType());
-      VariableDeclaration castedVar = _createVariable(
-          _createImplicitAs(element.expression.fileOffset,
-              _createVariableGet(variable), elementType),
-          elementType);
-      loopBody = _createBlock(<Statement>[
-        castedVar,
-        _createExpressionStatement(_createAdd(
-            _createVariableGet(result), _createVariableGet(castedVar), isSet))
-      ]);
+      Statement statement = _createExpressionStatement(
+          _createAddAll(_createVariableGet(result), value, isSet));
+
+      if (element.isNullAware) {
+        statement = _createIf(
+            temp.fileOffset,
+            _createEqualsNull(_createVariableGet(temp), notEquals: true),
+            statement);
+      }
+      body.add(statement);
     } else {
-      variable = _createForInVariable(element.fileOffset, elementType);
-      loopBody = _createExpressionStatement(_createAdd(
-          _createVariableGet(result), _createVariableGet(variable), isSet));
-    }
-    Statement statement =
-        _createForInStatement(element.fileOffset, variable, value, loopBody);
+      // Null-aware spreads require testing the subexpression's value.
+      VariableDeclaration temp;
+      if (element.isNullAware) {
+        temp = _createVariable(
+            value,
+            _typeEnvironment.iterableType(
+                typeMatches ? elementType : const DynamicType(),
+                _currentLibrary.nullable));
+        body.add(temp);
+        value = _createNullCheckedVariableGet(temp);
+      }
 
-    if (element.isNullAware) {
-      statement = _createIf(
-          temp.fileOffset,
-          _createEqualsNull(_createVariableGet(temp), notEquals: true),
-          statement);
+      VariableDeclaration variable;
+      Statement loopBody;
+      if (!typeMatches) {
+        variable =
+            _createForInVariable(element.fileOffset, const DynamicType());
+        VariableDeclaration castedVar = _createVariable(
+            _createImplicitAs(element.expression.fileOffset,
+                _createVariableGet(variable), elementType),
+            elementType);
+        loopBody = _createBlock(<Statement>[
+          castedVar,
+          _createExpressionStatement(_createAdd(
+              _createVariableGet(result), _createVariableGet(castedVar), isSet))
+        ]);
+      } else {
+        variable = _createForInVariable(element.fileOffset, elementType);
+        loopBody = _createExpressionStatement(_createAdd(
+            _createVariableGet(result), _createVariableGet(variable), isSet));
+      }
+      Statement statement =
+          _createForInStatement(element.fileOffset, variable, value, loopBody);
+
+      if (element.isNullAware) {
+        statement = _createIf(
+            temp.fileOffset,
+            _createEqualsNull(_createVariableGet(temp), notEquals: true),
+            statement);
+      }
+      body.add(statement);
     }
-    body.add(statement);
   }
 
   @override
@@ -332,7 +427,7 @@
     // Build a block expression and create an empty map.
     VariableDeclaration result = _createVariable(
         _createMapLiteral(node.fileOffset, node.keyType, node.valueType, []),
-        typeEnvironment.mapType(
+        _typeEnvironment.mapType(
             node.keyType, node.valueType, _currentLibrary.nonNullable));
     List<Statement> body = [result];
     // Add all the entries up to the first control-flow entry.
@@ -397,7 +492,7 @@
         statements.length == 1 ? statements.first : _createBlock(statements);
     ForStatement loop = _createForStatement(entry.fileOffset, entry.variables,
         entry.condition?.accept<TreeNode>(this), entry.updates, loopBody);
-    dataForTesting?.registerAlias(entry, loop);
+    _dataForTesting?.registerAlias(entry, loop);
     transformList(loop.variables, this, loop);
     transformList(loop.updates, this, loop);
     body.add(loop);
@@ -424,7 +519,7 @@
     ForInStatement loop = _createForInStatement(entry.fileOffset,
         entry.variable, entry.iterable.accept<TreeNode>(this), loopBody,
         isAsync: entry.isAsync);
-    dataForTesting?.registerAlias(entry, loop);
+    _dataForTesting?.registerAlias(entry, loop);
     body.add(loop);
   }
 
@@ -432,10 +527,10 @@
       DartType valueType, VariableDeclaration result, List<Statement> body) {
     Expression value = entry.expression.accept<TreeNode>(this);
 
-    final DartType entryType = new InterfaceType(mapEntryClass,
+    final DartType entryType = new InterfaceType(_mapEntryClass,
         _currentLibrary.nonNullable, <DartType>[keyType, valueType]);
     final bool typeMatches = entry.entryType != null &&
-        typeEnvironment.isSubtypeOf(
+        _typeEnvironment.isSubtypeOf(
             entry.entryType, entryType, SubtypeCheckMode.withNullabilities);
 
     // Null-aware spreads require testing the subexpression's value.
@@ -443,7 +538,7 @@
     if (entry.isNullAware) {
       temp = _createVariable(
           value,
-          typeEnvironment.mapType(
+          _typeEnvironment.mapType(
               typeMatches ? keyType : const DynamicType(),
               typeMatches ? valueType : const DynamicType(),
               _currentLibrary.nullable));
@@ -456,7 +551,7 @@
     if (!typeMatches) {
       variable = _createForInVariable(
           entry.fileOffset,
-          new InterfaceType(mapEntryClass, _currentLibrary.nonNullable,
+          new InterfaceType(_mapEntryClass, _currentLibrary.nonNullable,
               <DartType>[const DynamicType(), const DynamicType()]));
       VariableDeclaration keyVar = _createVariable(
           _createImplicitAs(
@@ -531,7 +626,7 @@
     List<Expression> currentPart = i > 0 ? elements.sublist(0, i) : null;
 
     DartType iterableType =
-        typeEnvironment.iterableType(elementType, _currentLibrary.nonNullable);
+        _typeEnvironment.iterableType(elementType, _currentLibrary.nonNullable);
 
     for (; i < elements.length; ++i) {
       Expression element = elements[i];
@@ -544,7 +639,7 @@
         if (element.isNullAware) {
           VariableDeclaration temp = _createVariable(
               spreadExpression,
-              typeEnvironment.iterableType(
+              _typeEnvironment.iterableType(
                   elementType, _currentLibrary.nullable));
           parts.add(_createNullAwareGuard(element.fileOffset, temp,
               makeLiteral(element.fileOffset, []), iterableType));
@@ -607,7 +702,7 @@
     List<Expression> parts = [];
     List<MapEntry> currentPart = i > 0 ? node.entries.sublist(0, i) : null;
 
-    DartType collectionType = typeEnvironment.mapType(
+    DartType collectionType = _typeEnvironment.mapType(
         node.keyType, node.valueType, _currentLibrary.nonNullable);
 
     for (; i < node.entries.length; ++i) {
@@ -724,17 +819,15 @@
   Expression _createSetLiteral(
       int fileOffset, DartType elementType, List<Expression> elements,
       {bool isConst: false}) {
+    assert(fileOffset != null);
+    assert(fileOffset != TreeNode.noOffset);
     if (isConst) {
       return new SetLiteral(elements,
           typeArgument: elementType, isConst: isConst)
         ..fileOffset = fileOffset;
     } else {
-      // TODO(kmillikin): When all the back ends handle set literals we can use
-      // one here.
-      return new StaticInvocation(
-          setFactory,
-          new Arguments(elements, types: [elementType])
-            ..fileOffset = fileOffset)
+      return new SetLiteral(elements,
+          typeArgument: elementType, isConst: isConst)
         ..fileOffset = fileOffset;
     }
   }
@@ -753,7 +846,19 @@
     assert(argument.fileOffset != TreeNode.noOffset,
         "No fileOffset on ${argument}.");
     return new MethodInvocation(receiver, new Name('add'),
-        new Arguments([argument]), isSet ? setAdd : listAdd)
+        new Arguments([argument]), isSet ? _setAdd : _listAdd)
+      ..fileOffset = argument.fileOffset
+      ..isInvariant = true;
+  }
+
+  MethodInvocation _createAddAll(
+      Expression receiver, Expression argument, bool isSet) {
+    assert(receiver != null);
+    assert(argument != null);
+    assert(argument.fileOffset != TreeNode.noOffset,
+        "No fileOffset on ${argument}.");
+    return new MethodInvocation(receiver, new Name('addAll'),
+        new Arguments([argument]), isSet ? _setAddAll : _listAddAll)
       ..fileOffset = argument.fileOffset
       ..isInvariant = true;
   }
@@ -765,7 +870,7 @@
         expression,
         new Name('=='),
         new Arguments([new NullLiteral()..fileOffset = expression.fileOffset]),
-        objectEquals)
+        _objectEquals)
       ..fileOffset = expression.fileOffset;
     if (notEquals) {
       check = new Not(check)..fileOffset = expression.fileOffset;
@@ -778,7 +883,7 @@
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
     return new MethodInvocation(
-        receiver, new Name('[]='), new Arguments([key, value]), mapPut)
+        receiver, new Name('[]='), new Arguments([key, value]), _mapPut)
       ..fileOffset = fileOffset
       ..isInvariant = true;
   }
@@ -803,21 +908,21 @@
   PropertyGet _createGetKey(int fileOffset, Expression receiver) {
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    return new PropertyGet(receiver, new Name('key'), mapEntryKey)
+    return new PropertyGet(receiver, new Name('key'), _mapEntryKey)
       ..fileOffset = fileOffset;
   }
 
   PropertyGet _createGetValue(int fileOffset, Expression receiver) {
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    return new PropertyGet(receiver, new Name('value'), mapEntryValue)
+    return new PropertyGet(receiver, new Name('value'), _mapEntryValue)
       ..fileOffset = fileOffset;
   }
 
   PropertyGet _createGetEntries(int fileOffset, Expression receiver) {
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    return new PropertyGet(receiver, new Name('entries'), mapEntries)
+    return new PropertyGet(receiver, new Name('entries'), _mapEntries)
       ..fileOffset = fileOffset;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 1fd20cd..48a5c3f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -293,11 +293,13 @@
   } else if (type is FunctionTypeBuilder) {
     List<TypeVariableBuilder> variables;
     if (type.typeVariables != null) {
-      variables = new List<TypeVariableBuilder>(type.typeVariables.length);
+      variables =
+          new List<TypeVariableBuilder>.filled(type.typeVariables.length, null);
     }
     List<FormalParameterBuilder> formals;
     if (type.formals != null) {
-      formals = new List<FormalParameterBuilder>(type.formals.length);
+      formals =
+          new List<FormalParameterBuilder>.filled(type.formals.length, null);
     }
     TypeBuilder returnType;
     bool changed = false;
@@ -349,7 +351,8 @@
               formal.name,
               formal.parent,
               formal.charOffset,
-              formal.fileUri);
+              fileUri: formal.fileUri,
+              isExtensionThis: formal.isExtensionThis);
           changed = true;
         } else {
           formals[i] = formal;
@@ -391,7 +394,8 @@
 /// of the algorithm for details.
 List<TypeBuilder> calculateBounds(List<TypeVariableBuilder> variables,
     TypeBuilder dynamicType, TypeBuilder bottomType, ClassBuilder objectClass) {
-  List<TypeBuilder> bounds = new List<TypeBuilder>(variables.length);
+  List<TypeBuilder> bounds =
+      new List<TypeBuilder>.filled(variables.length, null);
 
   for (int i = 0; i < variables.length; i++) {
     bounds[i] = variables[i].bound ?? dynamicType;
@@ -449,10 +453,10 @@
   TypeVariablesGraph(this.variables, this.bounds) {
     assert(variables.length == bounds.length);
 
-    vertices = new List<int>(variables.length);
+    vertices = new List<int>.filled(variables.length, null);
     Map<TypeVariableBuilder, int> variableIndices =
         <TypeVariableBuilder, int>{};
-    edges = new List<List<int>>(variables.length);
+    edges = new List<List<int>>.filled(variables.length, null);
     for (int i = 0; i < vertices.length; i++) {
       vertices[i] = i;
       variableIndices[variables[i]] = i;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
index a02abb4..ee11a13 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
@@ -120,7 +120,7 @@
     List<TypeBuilder> arguments;
     List<DartType> kernelArguments = node.typeArguments;
     if (kernelArguments.isNotEmpty) {
-      arguments = new List<TypeBuilder>(kernelArguments.length);
+      arguments = new List<TypeBuilder>.filled(kernelArguments.length, null);
       for (int i = 0; i < kernelArguments.length; i++) {
         arguments[i] = kernelArguments[i].accept(this);
       }
@@ -154,23 +154,34 @@
     List<TypeVariableBuilder> typeVariables = null;
     List<DartType> positionalParameters = node.positionalParameters;
     List<NamedType> namedParameters = node.namedParameters;
-    List<FormalParameterBuilder> formals = new List<FormalParameterBuilder>(
-        positionalParameters.length + namedParameters.length);
+    List<FormalParameterBuilder> formals =
+        new List<FormalParameterBuilder>.filled(
+            positionalParameters.length + namedParameters.length, null);
     for (int i = 0; i < positionalParameters.length; i++) {
       TypeBuilder type = positionalParameters[i].accept(this);
       FormalParameterKind kind = FormalParameterKind.mandatory;
       if (i >= node.requiredParameterCount) {
         kind = FormalParameterKind.optionalPositional;
       }
-      formals[i] =
-          new FormalParameterBuilder(null, 0, type, null, null, -1, null)
-            ..kind = kind;
+      formals[i] = new FormalParameterBuilder(
+          /* metadata = */ null,
+          /* modifiers = */ 0,
+          type,
+          /* name = */ null,
+          /* compilationUnit = */ null,
+          /* charOffset = */ TreeNode.noOffset)
+        ..kind = kind;
     }
     for (int i = 0; i < namedParameters.length; i++) {
       NamedType parameter = namedParameters[i];
       TypeBuilder type = parameter.type.accept(this);
       formals[i + positionalParameters.length] = new FormalParameterBuilder(
-          null, 0, type, parameter.name, null, -1, null)
+          /* metadata = */ null,
+          /* modifiers = */ 0,
+          type,
+          parameter.name,
+          /* compilationUnit = */ null,
+          /* charOffset = */ TreeNode.noOffset)
         ..kind = FormalParameterKind.optionalNamed;
     }
     return new FunctionTypeBuilder(
@@ -179,7 +190,7 @@
         formals,
         new NullabilityBuilder.fromNullability(node.nullability),
         /* fileUri = */ null,
-        /* charOffset = */ null);
+        /* charOffset = */ TreeNode.noOffset);
   }
 
   TypeBuilder visitTypeParameterType(TypeParameterType node) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 68fdfc8..a15a5c9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -289,7 +289,9 @@
           origin: remoteContext);
     }
 
-    bool isTypeCast = localContext != null &&
+    // TODO(johnniwinther): This check wasn't called from InterfaceType and
+    // is currently very broken. Disabling for now.
+    /*bool isTypeCast = localContext != null &&
         localContext is AsExpression &&
         localContext.isTypeError;
     // Don't check cases like foo(x as{TypeError} T).  In cases where foo comes
@@ -329,7 +331,7 @@
             "Found a legacy type '${node}' in an opted-in library.",
             origin: remoteContext);
       }
-    }
+    }*/
 
     super.defaultDartType(node);
   }
diff --git a/pkg/front_end/lib/src/fasta/messages.dart b/pkg/front_end/lib/src/fasta/messages.dart
index a689553..396f054 100644
--- a/pkg/front_end/lib/src/fasta/messages.dart
+++ b/pkg/front_end/lib/src/fasta/messages.dart
@@ -4,7 +4,8 @@
 
 library fasta.messages;
 
-import 'package:kernel/ast.dart' show Library, Location, Component, TreeNode;
+import 'package:kernel/ast.dart'
+    show Library, Location, Component, Source, TreeNode;
 
 import 'compiler_context.dart' show CompilerContext;
 
@@ -21,10 +22,10 @@
   return getLocation(uri, charOffset);
 }
 
-String getSourceLine(Location location) {
+String getSourceLine(Location location, [Map<Uri, Source> uriToSource]) {
   if (location == null) return null;
-  return CompilerContext.current.uriToSource[location.file]
-      ?.getTextLine(location.line);
+  uriToSource ??= CompilerContext.current.uriToSource;
+  return uriToSource[location.file]?.getTextLine(location.line);
 }
 
 Location getLocationFromNode(TreeNode node) {
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 471859f..98a5907 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -80,6 +80,8 @@
 
 import '../problems.dart' show unhandled;
 
+import 'source_extension_builder.dart';
+
 import 'source_library_builder.dart'
     show
         TypeParameterScopeBuilder,
@@ -125,7 +127,7 @@
 
   List<String> popIdentifierList(int count) {
     if (count == 0) return null;
-    List<String> list = new List<String>(count);
+    List<String> list = new List<String>.filled(count, null);
     bool isParserRecovery = false;
     for (int i = count - 1; i >= 0; i--) {
       popCharOffset();
@@ -387,7 +389,7 @@
   @override
   void handleStringJuxtaposition(Token startToken, int literalCount) {
     debugEvent("StringJuxtaposition");
-    List<String> list = new List<String>(literalCount);
+    List<String> list = new List<String>.filled(literalCount, null);
     int charOffset = -1;
     for (int i = literalCount - 1; i >= 0; i--) {
       charOffset = pop();
@@ -1170,7 +1172,8 @@
         libraryBuilder.boundlessTypeVariables.addAll(unboundTypeVariables);
       }
       synthesizedFormals.add(new FormalParameterBuilder(
-          null, finalMask, thisType, "#this", null, charOffset, uri));
+          null, finalMask, thisType, extensionThisName, null, charOffset,
+          fileUri: uri, isExtensionThis: true));
       if (formals != null) {
         synthesizedFormals.addAll(formals);
       }
@@ -1489,7 +1492,7 @@
         formals = last;
       } else if (last is! ParserRecovery) {
         assert(last != null);
-        formals = new List<FormalParameterBuilder>(1);
+        formals = new List<FormalParameterBuilder>.filled(1, null);
         formals[0] = last;
       }
     } else if (count > 1) {
@@ -1833,7 +1836,7 @@
 
   List<FieldInfo> popFieldInfos(int count) {
     if (count == 0) return null;
-    List<FieldInfo> fieldInfos = new List<FieldInfo>(count);
+    List<FieldInfo> fieldInfos = new List<FieldInfo>.filled(count, null);
     bool isParserRecovery = false;
     for (int i = count - 1; i != -1; i--) {
       int charEndOffset = pop();
@@ -1928,7 +1931,7 @@
           }
           if (bound == builder && bound.bound != null) {
             // Write out cycle.
-            List<String> via = new List<String>();
+            List<String> via = <String>[];
             bound = typeVariablesByName[builder.bound.name];
             while (bound != builder) {
               via.add(bound.name);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 31186d8..b2645dd 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -828,13 +828,8 @@
     procedure.function.dartAsyncMarker = AsyncMarker.Sync;
 
     procedure.isAbstract = false;
-    procedure.isNoSuchMethodForwarder = true;
-    procedure.isMemberSignature = false;
-    procedure.isForwardingStub = false;
-    procedure.isForwardingSemiStub = false;
-    procedure.memberSignatureOrigin = null;
-    procedure.forwardingStubInterfaceTarget = null;
-    procedure.forwardingStubSuperTarget = null;
+    procedure.stubKind = ProcedureStubKind.NoSuchMethodForwarder;
+    procedure.stubTarget = null;
   }
 
   void _addRedirectingConstructor(ProcedureBuilder constructorBuilder,
@@ -1239,8 +1234,7 @@
           }
           DartType computedBound = substitution.substituteType(interfaceBound);
           if (!library.isNonNullableByDefault) {
-            computedBound =
-                legacyErasure(types.hierarchy.coreTypes, computedBound);
+            computedBound = legacyErasure(computedBound);
           }
           if (!types
               .performNullabilityAwareMutualSubtypesCheck(
@@ -1310,7 +1304,7 @@
 
     if (!declaredMember.isNonNullableByDefault &&
         interfaceMember.isNonNullableByDefault) {
-      interfaceType = legacyErasure(types.hierarchy.coreTypes, interfaceType);
+      interfaceType = legacyErasure(interfaceType);
     }
 
     bool inParameter = declaredParameter != null || asIfDeclaredParameter;
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index f3c9943..28b3fb8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -35,6 +35,8 @@
 
 import 'source_library_builder.dart';
 
+const String extensionThisName = '#this';
+
 class SourceExtensionBuilder extends ExtensionBuilderImpl {
   final Extension _extension;
 
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 e4d81e4..fdc6b3a 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
@@ -248,8 +248,7 @@
   // default nullability of the corresponding type-parameter types.  This list
   // is used to collect such type-parameter types in order to set the
   // nullability after the bounds are built.
-  final List<TypeParameterType> pendingNullabilities =
-      new List<TypeParameterType>();
+  final List<TypeParameterType> pendingNullabilities = <TypeParameterType>[];
 
   // A library to use for Names generated when compiling code in this library.
   // This allows code generated in one library to use the private namespace of
@@ -480,6 +479,7 @@
     'ffi_2',
     'language_2/',
     'lib_2/',
+    'samples_2/',
     'service_2/',
     'standalone_2/',
     'vm/dart_2/', // in runtime/tests
@@ -2119,7 +2119,10 @@
     Procedure getterReferenceFrom;
     Procedure setterReferenceFrom;
     final bool fieldIsLateWithLowering = (modifiers & lateMask) != 0 &&
-        !loader.target.backendTarget.supportsLateFields;
+        loader.target.backendTarget.isLateFieldLoweringEnabled(
+            hasInitializer: hasInitializer,
+            isFinal: (modifiers & finalMask) != 0,
+            isStatic: isTopLevel || (modifiers & staticMask) != 0);
     final bool isInstanceMember = currentTypeParameterScopeBuilder.kind ==
             TypeParameterScopeKind.classDeclaration &&
         (modifiers & staticMask) == 0;
@@ -2584,7 +2587,8 @@
       modifiers |= initializingFormalMask;
     }
     FormalParameterBuilder formal = new FormalParameterBuilder(
-        metadata, modifiers, type, name, this, charOffset, fileUri)
+        metadata, modifiers, type, name, this, charOffset,
+        fileUri: fileUri)
       ..initializerToken = initializerToken
       ..hasDeclaredInitializer = (initializerToken != null);
     return formal;
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 16123b0..54420e8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1106,7 +1106,7 @@
     // TODO(ahe): Move this to [ClassHierarchyBuilder].
     if (!target.backendTarget.enableNoSuchMethodForwarders) return;
 
-    List<Class> changedClasses = new List<Class>();
+    List<Class> changedClasses = <Class>[];
     for (SourceClassBuilder builder in sourceClasses) {
       if (builder.library.loader == this && !builder.isPatch) {
         if (builder.addNoSuchMethodForwarders(target, hierarchy)) {
@@ -1438,6 +1438,8 @@
 
 print(object) {}
 
+bool identical(a, b) => false;
+
 class Iterator<E> {
   bool moveNext() => null;
   E get current => null;
@@ -1447,24 +1449,29 @@
   Iterator<E> get iterator => null;
 }
 
-class List<E> extends Iterable {
+class List<E> extends Iterable<E> {
   factory List() => null;
   factory List.unmodifiable(elements) => null;
+  factory List.empty({bool growable = false}) => null;
   factory List.filled(int length, E fill, {bool growable = false}) => null;
   factory List.generate(int length, E generator(int index),
       {bool growable = true}) => null;
-  void add(E) {}
+  factory List.of() => null;
+  void add(E element) {}
+  void addAll(Iterable<E> iterable) {}
   E operator [](int index) => null;
 }
 
 class _GrowableList<E> {
   factory _GrowableList() => null;
+  factory _GrowableList.empty() => null;
   factory _GrowableList.filled() => null;
   factory _GrowableList.generate(int length, E generator(int index)) => null;
 }
 
 class _List<E> {
   factory _List() => null;
+  factory _List.empty() => null;
   factory _List.filled() => null;
   factory _List.generate(int length, E generator(int index)) => null;
 }
@@ -1512,7 +1519,9 @@
 class Set<E> {
   factory Set() = Set<E>._fake;
   external factory Set._fake();
-  void add(E) {}
+  external factory Set.of();
+  void add(E element) {}
+  void addAll(Iterable<E> iterable) {}
 }
 
 class Type {}
@@ -1547,8 +1556,6 @@
 
 void _asyncStarMoveNextHelper(var stream) {}
 
-_asyncStackTraceHelper(async_op) {}
-
 _asyncThenWrapperHelper(continuation) {}
 
 _awaitHelper(object, thenCallback, errorCallback, awaiter) {}
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 2e1cf37..4061bce 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -84,15 +84,19 @@
     TypeBuilder type = this.type;
     if (type is FunctionTypeBuilder) {
       List<TypeParameter> typeParameters =
-          new List<TypeParameter>(type.typeVariables?.length ?? 0);
+          new List<TypeParameter>.filled(type.typeVariables?.length ?? 0, null);
       for (int i = 0; i < typeParameters.length; ++i) {
         TypeVariableBuilder typeVariable = type.typeVariables[i];
         typeParameters[i] = typeVariable.parameter;
       }
       FreshTypeParameters freshTypeParameters =
           getFreshTypeParameters(typeParameters);
-      typedef.typeParametersOfFunctionType
-          .addAll(freshTypeParameters.freshTypeParameters);
+      for (int i = 0; i < freshTypeParameters.freshTypeParameters.length; i++) {
+        TypeParameter typeParameter =
+            freshTypeParameters.freshTypeParameters[i];
+        typedef.typeParametersOfFunctionType
+            .add(typeParameter..parent = typedef);
+      }
 
       if (type.formals != null) {
         for (FormalParameterBuilder formal in type.formals) {
@@ -103,6 +107,7 @@
           } else {
             typedef.positionalParameters.add(parameter);
           }
+          parameter.parent = typedef;
         }
       }
     } else if (type is NamedTypeBuilder || type is FixedTypeBuilder) {
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 d9c7b80..addccd7 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
@@ -1644,17 +1644,13 @@
       VariableDeclarationImpl variable) {
     assert(variable.isImplicitlyTyped);
     assert(variable.initializer != null);
-    ExpressionInferenceResult result = inferExpression(
+    ExpressionInferenceResult result = inferNullAwareExpression(
         variable.initializer, const UnknownType(), true,
         isVoidAllowed: true);
-    Link<NullAwareGuard> nullAwareGuards;
-    if (isNonNullableByDefault) {
-      variable.initializer = result.nullAwareAction..parent = variable;
-      nullAwareGuards = result.nullAwareGuards;
-    } else {
-      variable.initializer = result.expression..parent = variable;
-      nullAwareGuards = const Link<NullAwareGuard>();
-    }
+
+    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
+    variable.initializer = result.nullAwareAction..parent = variable;
+
     DartType inferredType =
         inferDeclarationType(result.inferredType, forSyntheticVariable: true);
     instrumentation?.record(uriForInstrumentation, variable.fileOffset, 'type',
@@ -1713,7 +1709,7 @@
   ///
   /// Derived classes should override this method with logic that dispatches on
   /// the expression type and calls the appropriate specialized "infer" method.
-  ExpressionInferenceResult inferExpression(
+  ExpressionInferenceResult _inferExpression(
       Expression expression, DartType typeContext, bool typeNeeded,
       {bool isVoidAllowed: false, bool forEffect: false}) {
     registerIfUnreachableForTesting(expression);
@@ -1768,6 +1764,28 @@
     return result;
   }
 
+  ExpressionInferenceResult inferExpression(
+      Expression expression, DartType typeContext, bool typeNeeded,
+      {bool isVoidAllowed: false, bool forEffect: false}) {
+    ExpressionInferenceResult result = _inferExpression(
+        expression, typeContext, typeNeeded,
+        isVoidAllowed: isVoidAllowed, forEffect: forEffect);
+    return result.stopShorting();
+  }
+
+  ExpressionInferenceResult inferNullAwareExpression(
+      Expression expression, DartType typeContext, bool typeNeeded,
+      {bool isVoidAllowed: false, bool forEffect: false}) {
+    ExpressionInferenceResult result = _inferExpression(
+        expression, typeContext, typeNeeded,
+        isVoidAllowed: isVoidAllowed, forEffect: forEffect);
+    if (isNonNullableByDefault) {
+      return result;
+    } else {
+      return result.stopShorting();
+    }
+  }
+
   @override
   Expression inferFieldInitializer(
     InferenceHelper helper,
@@ -1816,7 +1834,8 @@
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false,
-      bool isImplicitCall: false}) {
+      bool isImplicitCall: false,
+      Member staticTarget}) {
     int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
     if (extensionTypeParameterCount != 0) {
       return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
@@ -1836,7 +1855,8 @@
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst,
         isImplicitExtensionMember: isImplicitExtensionMember,
-        isImplicitCall: isImplicitCall);
+        isImplicitCall: isImplicitCall,
+        staticTarget: staticTarget);
   }
 
   InvocationInferenceResult _inferGenericExtensionMethodInvocation(
@@ -1852,7 +1872,8 @@
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false,
-      bool isImplicitCall: false}) {
+      bool isImplicitCall: false,
+      Member staticTarget}) {
     FunctionType extensionFunctionType = new FunctionType(
         [calleeType.positionalParameters.first],
         const DynamicType(),
@@ -1869,7 +1890,8 @@
         skipTypeArgumentInference: skipTypeArgumentInference,
         receiverType: receiverType,
         isImplicitExtensionMember: isImplicitExtensionMember,
-        isImplicitCall: isImplicitCall);
+        isImplicitCall: isImplicitCall,
+        staticTarget: staticTarget);
     Substitution extensionSubstitution = Substitution.fromPairs(
         extensionFunctionType.typeParameters, extensionArguments.types);
 
@@ -1896,7 +1918,8 @@
         isSpecialCasedTernaryOperator: isSpecialCasedTernaryOperator,
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst,
-        isImplicitCall: isImplicitCall);
+        isImplicitCall: isImplicitCall,
+        staticTarget: staticTarget);
     arguments.positional.clear();
     arguments.positional.addAll(extensionArguments.positional);
     arguments.positional.addAll(targetArguments.positional);
@@ -1924,7 +1947,8 @@
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false,
-      bool isImplicitCall}) {
+      bool isImplicitCall,
+      Member staticTarget}) {
     List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
     if (calleeTypeParameters.isNotEmpty) {
       // It's possible that one of the callee type parameters might match a type
@@ -1967,7 +1991,7 @@
       typeSchemaEnvironment.inferGenericFunctionOrType(
           isNonNullableByDefault
               ? calleeType.returnType
-              : legacyErasure(coreTypes, calleeType.returnType),
+              : legacyErasure(calleeType.returnType),
           calleeTypeParameters,
           null,
           null,
@@ -1986,6 +2010,8 @@
           new List<DartType>.filled(
               calleeTypeParameters.length, const DynamicType()));
     }
+    bool isIdentical =
+        staticTarget == typeSchemaEnvironment.coreTypes.identicalProcedure;
     // TODO(paulberry): if we are doing top level inference and type arguments
     // were omitted, report an error.
     for (int position = 0; position < arguments.positional.length; position++) {
@@ -2016,16 +2042,24 @@
             arguments.positional[position],
             isNonNullableByDefault
                 ? inferredFormalType
-                : legacyErasure(coreTypes, inferredFormalType),
+                : legacyErasure(inferredFormalType),
             inferenceNeeded ||
                 isSpecialCasedBinaryOperator ||
                 isSpecialCasedTernaryOperator ||
                 typeChecksNeeded);
         inferredType = result.inferredType == null || isNonNullableByDefault
             ? result.inferredType
-            : legacyErasure(coreTypes, result.inferredType);
+            : legacyErasure(result.inferredType);
         Expression expression =
             _hoist(result.expression, inferredType, hoistedExpressions);
+        if (isIdentical && arguments.positional.length == 2) {
+          if (position == 0) {
+            flowAnalysis?.equalityOp_rightBegin(expression, inferredType);
+          } else {
+            flowAnalysis?.equalityOp_end(
+                arguments.parent, expression, inferredType);
+          }
+        }
         arguments.positional[position] = expression..parent = arguments;
       }
       if (inferenceNeeded || typeChecksNeeded) {
@@ -2055,12 +2089,12 @@
           namedArgument.value,
           isNonNullableByDefault
               ? inferredFormalType
-              : legacyErasure(coreTypes, inferredFormalType),
+              : legacyErasure(inferredFormalType),
           inferenceNeeded || isSpecialCasedBinaryOperator || typeChecksNeeded);
       DartType inferredType =
           result.inferredType == null || isNonNullableByDefault
               ? result.inferredType
-              : legacyErasure(coreTypes, result.inferredType);
+              : legacyErasure(result.inferredType);
       Expression expression =
           _hoist(result.expression, inferredType, hoistedExpressions);
       namedArgument.value = expression..parent = namedArgument;
@@ -2198,7 +2232,7 @@
         "Inferred function type: $calleeType.");
 
     if (!isNonNullableByDefault) {
-      inferredType = legacyErasure(coreTypes, inferredType);
+      inferredType = legacyErasure(inferredType);
     }
 
     return new SuccessfulInferenceResult(inferredType);
@@ -3965,6 +3999,8 @@
 
   DartType get nullAwareActionType => inferredType;
 
+  ExpressionInferenceResult stopShorting() => this;
+
   String toString() => 'ExpressionInferenceResult($inferredType,$expression)';
 }
 
@@ -4045,24 +4081,26 @@
   @override
   final Expression nullAwareAction;
 
-  Expression _expression;
-
   NullAwareExpressionInferenceResult(this.inferredType,
       this.nullAwareActionType, this.nullAwareGuards, this.nullAwareAction)
       : assert(nullAwareGuards.isNotEmpty),
         assert(nullAwareAction != null);
 
   Expression get expression {
-    if (_expression == null) {
-      _expression = nullAwareAction;
-      Link<NullAwareGuard> nullAwareGuard = nullAwareGuards;
-      while (nullAwareGuard.isNotEmpty) {
-        _expression =
-            nullAwareGuard.head.createExpression(inferredType, _expression);
-        nullAwareGuard = nullAwareGuard.tail;
-      }
+    throw new UnsupportedError('Shorting must be explicitly stopped before'
+        'accessing the expression result of a '
+        'NullAwareExpressionInferenceResult');
+  }
+
+  ExpressionInferenceResult stopShorting() {
+    Expression expression = nullAwareAction;
+    Link<NullAwareGuard> nullAwareGuard = nullAwareGuards;
+    while (nullAwareGuard.isNotEmpty) {
+      expression =
+          nullAwareGuard.head.createExpression(inferredType, expression);
+      nullAwareGuard = nullAwareGuard.tail;
     }
-    return _expression;
+    return new ExpressionInferenceResult(inferredType, expression);
   }
 
   String toString() =>
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
index 68b390d..3331e01 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
@@ -6,6 +6,9 @@
 
 import 'dart:io' show File;
 
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ScannerConfiguration;
+
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show ClassMemberParser, Parser;
 
@@ -14,18 +17,24 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
 
-import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart'
-    show
-        AbstractDirectParserASTListener,
-        DirectParserASTContent,
-        DirectParserASTType;
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
 
-DirectParserASTContent getAST(List<int> rawBytes, {bool includeBody: true}) {
+DirectParserASTContentCompilationUnitEnd getAST(List<int> rawBytes,
+    {bool includeBody: true,
+    bool includeComments: false,
+    bool enableExtensionMethods: false,
+    bool enableNonNullable: false,
+    bool enableTripleShift: false}) {
   Uint8List bytes = new Uint8List(rawBytes.length + 1);
   bytes.setRange(0, rawBytes.length, rawBytes);
 
-  Utf8BytesScanner scanner =
-      new Utf8BytesScanner(bytes, includeComments: false);
+  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+      enableExtensionMethods: enableExtensionMethods,
+      enableNonNullable: enableNonNullable,
+      enableTripleShift: enableTripleShift);
+
+  Utf8BytesScanner scanner = new Utf8BytesScanner(bytes,
+      includeComments: includeComments, configuration: scannerConfiguration);
   Token firstToken = scanner.tokenize();
   if (firstToken == null) {
     throw "firstToken is null";
@@ -42,6 +51,796 @@
   return listener.data.single;
 }
 
+extension GeneralASTContentExtension on DirectParserASTContent {
+  bool isClass() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentClassDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentClassDeclarationEnd asClass() {
+    if (!isClass()) throw "Not class";
+    return children.last;
+  }
+
+  bool isImport() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentImportEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentImportEnd asImport() {
+    if (!isImport()) throw "Not import";
+    return children.last;
+  }
+
+  bool isExport() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentExportEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentExportEnd asExport() {
+    if (!isExport()) throw "Not export";
+    return children.last;
+  }
+
+  bool isEnum() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentEnumEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentEnumEnd asEnum() {
+    if (!isEnum()) throw "Not enum";
+    return children.last;
+  }
+
+  bool isTypedef() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentFunctionTypeAliasEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentFunctionTypeAliasEnd asTypedef() {
+    if (!isTypedef()) throw "Not typedef";
+    return children.last;
+  }
+
+  bool isScript() {
+    if (this is! DirectParserASTContentScriptHandle) {
+      return false;
+    }
+    return true;
+  }
+
+  DirectParserASTContentScriptHandle asScript() {
+    if (!isScript()) throw "Not script";
+    return this;
+  }
+
+  bool isExtension() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentExtensionDeclarationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentExtensionDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentExtensionDeclarationEnd asExtension() {
+    if (!isExtension()) throw "Not extension";
+    return children.last;
+  }
+
+  bool isInvalidTopLevelDeclaration() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+      return false;
+    }
+    if (children.last
+        is! DirectParserASTContentInvalidTopLevelDeclarationHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isRecoverableError() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentRecoverableErrorHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isRecoverImport() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentRecoverImportHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isMixinDeclaration() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentMixinDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentMixinDeclarationEnd asMixinDeclaration() {
+    if (!isMixinDeclaration()) throw "Not mixin declaration";
+    return children.last;
+  }
+
+  bool isNamedMixinDeclaration() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentNamedMixinApplicationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentNamedMixinApplicationEnd asNamedMixinDeclaration() {
+    if (!isNamedMixinDeclaration()) throw "Not named mixin declaration";
+    return children.last;
+  }
+
+  bool isTopLevelMethod() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentTopLevelMethodEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentTopLevelMethodEnd asTopLevelMethod() {
+    if (!isTopLevelMethod()) throw "Not top level method";
+    return children.last;
+  }
+
+  bool isTopLevelFields() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentTopLevelFieldsEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentTopLevelFieldsEnd asTopLevelFields() {
+    if (!isTopLevelFields()) throw "Not top level fields";
+    return children.last;
+  }
+
+  bool isLibraryName() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentLibraryNameEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentLibraryNameEnd asLibraryName() {
+    if (!isLibraryName()) throw "Not library name";
+    return children.last;
+  }
+
+  bool isPart() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentPartEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentPartEnd asPart() {
+    if (!isPart()) throw "Not part";
+    return children.last;
+  }
+
+  bool isPartOf() {
+    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children.first
+        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children.last is! DirectParserASTContentPartOfEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DirectParserASTContentPartOfEnd asPartOf() {
+    if (!isPartOf()) throw "Not part of";
+    return children.last;
+  }
+
+  bool isMetadata() {
+    if (this is! DirectParserASTContentMetadataStarEnd) {
+      return false;
+    }
+    if (children.first is! DirectParserASTContentMetadataStarBegin) {
+      return false;
+    }
+    return true;
+  }
+
+  DirectParserASTContentMetadataStarEnd asMetadata() {
+    if (!isMetadata()) throw "Not metadata";
+    return this;
+  }
+
+  bool isFunctionBody() {
+    if (this is DirectParserASTContentBlockFunctionBodyEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentBlockFunctionBodyEnd asFunctionBody() {
+    if (!isFunctionBody()) throw "Not function body";
+    return this;
+  }
+
+  List<E> recursivelyFind<E extends DirectParserASTContent>() {
+    Set<E> result = {};
+    _recursivelyFindInternal(this, result);
+    return result.toList();
+  }
+
+  static void _recursivelyFindInternal<E extends DirectParserASTContent>(
+      DirectParserASTContent node, Set<E> result) {
+    if (node is E) {
+      result.add(node);
+      return;
+    }
+    if (node.children == null) return;
+    for (DirectParserASTContent child in node.children) {
+      _recursivelyFindInternal(child, result);
+    }
+  }
+
+  void debugDumpNodeRecursively({String indent = ""}) {
+    print("$indent${runtimeType} (${what}) "
+        "(${deprecatedArguments})");
+    if (children == null) return;
+    for (DirectParserASTContent child in children) {
+      child.debugDumpNodeRecursively(indent: "  $indent");
+    }
+  }
+}
+
+extension MetadataStarExtension on DirectParserASTContentMetadataStarEnd {
+  List<DirectParserASTContentMetadataEnd> getMetadataEntries() {
+    List<DirectParserASTContentMetadataEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (topLevel is! DirectParserASTContentMetadataEnd) continue;
+      result.add(topLevel);
+    }
+    return result;
+  }
+}
+
+extension CompilationUnitExtension on DirectParserASTContentCompilationUnitEnd {
+  List<DirectParserASTContentTopLevelDeclarationEnd> getClasses() {
+    List<DirectParserASTContentTopLevelDeclarationEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isClass()) continue;
+      result.add(topLevel);
+    }
+    return result;
+  }
+
+  List<DirectParserASTContentTopLevelDeclarationEnd> getMixinDeclarations() {
+    List<DirectParserASTContentTopLevelDeclarationEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isMixinDeclaration()) continue;
+      result.add(topLevel);
+    }
+    return result;
+  }
+
+  List<DirectParserASTContentImportEnd> getImports() {
+    List<DirectParserASTContentImportEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isImport()) continue;
+      result.add(topLevel.children.last);
+    }
+    return result;
+  }
+
+  List<DirectParserASTContentExportEnd> getExports() {
+    List<DirectParserASTContentExportEnd> result = [];
+    for (DirectParserASTContent topLevel in children) {
+      if (!topLevel.isExport()) continue;
+      result.add(topLevel.children.last);
+    }
+    return result;
+  }
+
+  // List<DirectParserASTContentMetadataStarEnd> getMetadata() {
+  //   List<DirectParserASTContentMetadataStarEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isMetadata()) continue;
+  //     result.add(topLevel);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentEnumEnd> getEnums() {
+  //   List<DirectParserASTContentEnumEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isEnum()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentFunctionTypeAliasEnd> getTypedefs() {
+  //   List<DirectParserASTContentFunctionTypeAliasEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isTypedef()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentMixinDeclarationEnd> getMixinDeclarations() {
+  //   List<DirectParserASTContentMixinDeclarationEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isMixinDeclaration()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<DirectParserASTContentTopLevelMethodEnd> getTopLevelMethods() {
+  //   List<DirectParserASTContentTopLevelMethodEnd> result = [];
+  //   for (DirectParserASTContent topLevel in children) {
+  //     if (!topLevel.isTopLevelMethod()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  DirectParserASTContentCompilationUnitBegin getBegin() {
+    return children.first;
+  }
+}
+
+extension TopLevelDeclarationExtension
+    on DirectParserASTContentTopLevelDeclarationEnd {
+  DirectParserASTContentIdentifierHandle getIdentifier() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentIdentifierHandle) return child;
+    }
+    throw "Not found.";
+  }
+
+  DirectParserASTContentClassDeclarationEnd getClassDeclaration() {
+    if (!isClass()) {
+      throw "Not a class";
+    }
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassDeclarationEnd) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+}
+
+extension MixinDeclarationExtension
+    on DirectParserASTContentMixinDeclarationEnd {
+  DirectParserASTContentClassOrMixinBodyEnd getClassOrMixinBody() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassOrMixinBodyEnd) return child;
+    }
+    throw "Not found.";
+  }
+}
+
+extension ClassDeclarationExtension
+    on DirectParserASTContentClassDeclarationEnd {
+  DirectParserASTContentClassOrMixinBodyEnd getClassOrMixinBody() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassOrMixinBodyEnd) return child;
+    }
+    throw "Not found.";
+  }
+
+  DirectParserASTContentClassExtendsHandle getClassExtends() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassExtendsHandle) return child;
+    }
+    throw "Not found.";
+  }
+
+  DirectParserASTContentClassOrMixinImplementsHandle getClassImplements() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassOrMixinImplementsHandle) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+
+  DirectParserASTContentClassWithClauseHandle getClassWithClause() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentClassWithClauseHandle) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
+extension ClassOrMixinBodyExtension
+    on DirectParserASTContentClassOrMixinBodyEnd {
+  List<DirectParserASTContentMemberEnd> getMembers() {
+    List<DirectParserASTContentMemberEnd> members = [];
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentMemberEnd) {
+        members.add(child);
+      }
+    }
+    return members;
+  }
+}
+
+extension MemberExtension on DirectParserASTContentMemberEnd {
+  bool isClassConstructor() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassConstructorEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentClassConstructorEnd getClassConstructor() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassConstructorEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassFactoryMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentClassFactoryMethodEnd getClassFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassFactoryMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassFields() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassFieldsEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentClassFieldsEnd getClassFields() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassFieldsEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinFields() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFieldsEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinFieldsEnd getMixinFields() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFieldsEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinMethodEnd getMixinMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFactoryMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinFactoryMethodEnd getMixinFactoryMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinFactoryMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinConstructor() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinConstructorEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentMixinConstructorEnd getMixinConstructor() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentMixinConstructorEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassMethodEnd) return true;
+    return false;
+  }
+
+  DirectParserASTContentClassMethodEnd getClassMethod() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentClassMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassRecoverableError() {
+    DirectParserASTContent child = children[1];
+    if (child is DirectParserASTContentRecoverableErrorHandle) return true;
+    return false;
+  }
+}
+
+extension ClassFieldsExtension on DirectParserASTContentClassFieldsEnd {
+  List<DirectParserASTContentIdentifierHandle> getFieldIdentifiers() {
+    // For now blindly assume that the last count identifiers are the names
+    // of the fields.
+    int countLeft = count;
+    List<DirectParserASTContentIdentifierHandle> identifiers =
+        new List<DirectParserASTContentIdentifierHandle>.filled(count, null);
+    for (int i = children.length - 1; i >= 0; i--) {
+      DirectParserASTContent child = children[i];
+      if (child is DirectParserASTContentIdentifierHandle) {
+        countLeft--;
+        identifiers[countLeft] = child;
+        if (countLeft == 0) break;
+      }
+    }
+    if (countLeft != 0) throw "Didn't find the expected number of identifiers";
+    return identifiers;
+  }
+
+  DirectParserASTContentTypeHandle getFirstType() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentTypeHandle) return child;
+    }
+    return null;
+  }
+
+  DirectParserASTContentFieldInitializerEnd getFieldInitializer() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentFieldInitializerEnd) return child;
+    }
+    return null;
+  }
+}
+
+extension ClassMethodExtension on DirectParserASTContentClassMethodEnd {
+  DirectParserASTContentBlockFunctionBodyEnd getBlockFunctionBody() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentBlockFunctionBodyEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
+extension ClassConstructorExtension
+    on DirectParserASTContentClassConstructorEnd {
+  DirectParserASTContentFormalParametersEnd getFormalParameters() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentFormalParametersEnd) {
+        return child;
+      }
+    }
+    throw "Not found";
+  }
+
+  DirectParserASTContentInitializersEnd getInitializers() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentInitializersEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+
+  DirectParserASTContentBlockFunctionBodyEnd getBlockFunctionBody() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentBlockFunctionBodyEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
+extension FormalParametersExtension
+    on DirectParserASTContentFormalParametersEnd {
+  List<DirectParserASTContentFormalParameterEnd> getFormalParameters() {
+    List<DirectParserASTContentFormalParameterEnd> result = [];
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentFormalParameterEnd) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+
+  DirectParserASTContentOptionalFormalParametersEnd
+      getOptionalFormalParameters() {
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentOptionalFormalParametersEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
+extension FormalParameterExtension on DirectParserASTContentFormalParameterEnd {
+  DirectParserASTContentFormalParameterBegin getBegin() {
+    return children.first;
+  }
+}
+
+extension OptionalFormalParametersExtension
+    on DirectParserASTContentOptionalFormalParametersEnd {
+  List<DirectParserASTContentFormalParameterEnd> getFormalParameters() {
+    List<DirectParserASTContentFormalParameterEnd> result = [];
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentFormalParameterEnd) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+}
+
+extension InitializersExtension on DirectParserASTContentInitializersEnd {
+  List<DirectParserASTContentInitializerEnd> getInitializers() {
+    List<DirectParserASTContentInitializerEnd> result = [];
+    for (DirectParserASTContent child in children) {
+      if (child is DirectParserASTContentInitializerEnd) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+
+  DirectParserASTContentInitializersBegin getBegin() {
+    return children.first;
+  }
+}
+
+extension InitializerExtension on DirectParserASTContentInitializerEnd {
+  DirectParserASTContentInitializerBegin getBegin() {
+    return children.first;
+  }
+}
+
 main(List<String> args) {
   File f = new File(args[0]);
   Uint8List data = f.readAsBytesSync();
@@ -75,17 +874,13 @@
 }
 
 class DirectParserASTListener extends AbstractDirectParserASTListener {
-  void seen(
-      String what, DirectParserASTType type, Map<String, Object> arguments) {
-    switch (type) {
+  void seen(DirectParserASTContent entry) {
+    switch (entry.type) {
       case DirectParserASTType.BEGIN:
       case DirectParserASTType.HANDLE:
         // This just adds stuff.
-        data.add(new DirectParserASTContent(what, type, arguments));
+        data.add(entry);
         break;
-      case DirectParserASTType.DONE:
-        // This shouldn't be seen. It's artificial.
-        throw new StateError("Saw type 'DONE'");
       case DirectParserASTType.END:
         // End should gobble up everything until the corresponding begin (which
         // should be the latest begin).
@@ -97,11 +892,11 @@
           }
         }
         if (beginIndex == null) {
-          throw "Couldn't find a begin for $what. Has:\n"
+          throw "Couldn't find a begin for ${entry.what}. Has:\n"
               "${data.map((e) => "${e.what}: ${e.type}").join("\n")}";
         }
         String begin = data[beginIndex].what;
-        String end = what;
+        String end = entry.what;
         if (begin == end) {
           // Exact match.
         } else if (end == "TopLevelDeclaration" &&
@@ -154,11 +949,9 @@
         } else {
           throw "Unknown combination: begin$begin and end$end";
         }
-        List<DirectParserASTContent> content = data.sublist(beginIndex);
+        List<DirectParserASTContent> children = data.sublist(beginIndex);
         data.length = beginIndex;
-        data.add(new DirectParserASTContent(
-            what, DirectParserASTType.DONE, arguments)
-          ..content = content);
+        data.add(entry..children = children);
         break;
     }
   }
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
index 7da31a4..70be181 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
@@ -13,6 +13,8 @@
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:front_end/src/fasta/messages.dart';
 
+// ignore_for_file: lines_longer_than_80_chars
+
 // THIS FILE IS AUTO GENERATED BY
 // 'tool/_fasta/direct_parser_ast_helper_creator.dart'
 // Run e.g.
@@ -22,339 +24,493 @@
       > pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
 */
 
-class DirectParserASTContent {
+abstract class DirectParserASTContent {
   final String what;
   final DirectParserASTType type;
-  final Map<String, Object> arguments;
-  List<DirectParserASTContent> content;
+  Map<String, Object> get deprecatedArguments;
+  List<DirectParserASTContent> children;
 
-  DirectParserASTContent(this.what, this.type, this.arguments);
+  DirectParserASTContent(this.what, this.type);
 
   // TODO(jensj): Compare two ASTs.
 }
 
-enum DirectParserASTType { BEGIN, END, HANDLE, DONE }
+enum DirectParserASTType { BEGIN, END, HANDLE }
 
 abstract class AbstractDirectParserASTListener implements Listener {
   List<DirectParserASTContent> data = [];
 
-  void seen(
-      String what, DirectParserASTType type, Map<String, Object> arguments);
+  void seen(DirectParserASTContent entry);
 
   void beginArguments(Token token) {
-    seen("Arguments", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentArgumentsBegin data =
+        new DirectParserASTContentArgumentsBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endArguments(int count, Token beginToken, Token endToken) {
-    seen("Arguments", DirectParserASTType.END,
-        {"count": count, "beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentArgumentsEnd data =
+        new DirectParserASTContentArgumentsEnd(DirectParserASTType.END,
+            count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void handleAsyncModifier(Token asyncToken, Token starToken) {
-    seen("AsyncModifier", DirectParserASTType.HANDLE,
-        {"asyncToken": asyncToken, "starToken": starToken});
+    DirectParserASTContentAsyncModifierHandle data =
+        new DirectParserASTContentAsyncModifierHandle(
+            DirectParserASTType.HANDLE,
+            asyncToken: asyncToken,
+            starToken: starToken);
+    seen(data);
   }
 
   void beginAwaitExpression(Token token) {
-    seen("AwaitExpression", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentAwaitExpressionBegin data =
+        new DirectParserASTContentAwaitExpressionBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endAwaitExpression(Token beginToken, Token endToken) {
-    seen("AwaitExpression", DirectParserASTType.END,
-        {"beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentAwaitExpressionEnd data =
+        new DirectParserASTContentAwaitExpressionEnd(DirectParserASTType.END,
+            beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void endInvalidAwaitExpression(
       Token beginToken, Token endToken, MessageCode errorCode) {
-    seen("InvalidAwaitExpression", DirectParserASTType.END, {
-      "beginToken": beginToken,
-      "endToken": endToken,
-      "errorCode": errorCode
-    });
+    DirectParserASTContentInvalidAwaitExpressionEnd data =
+        new DirectParserASTContentInvalidAwaitExpressionEnd(
+            DirectParserASTType.END,
+            beginToken: beginToken,
+            endToken: endToken,
+            errorCode: errorCode);
+    seen(data);
   }
 
   void beginBlock(Token token, BlockKind blockKind) {
-    seen("Block", DirectParserASTType.BEGIN,
-        {"token": token, "blockKind": blockKind});
+    DirectParserASTContentBlockBegin data =
+        new DirectParserASTContentBlockBegin(DirectParserASTType.BEGIN,
+            token: token, blockKind: blockKind);
+    seen(data);
   }
 
   void endBlock(
       int count, Token beginToken, Token endToken, BlockKind blockKind) {
-    seen("Block", DirectParserASTType.END, {
-      "count": count,
-      "beginToken": beginToken,
-      "endToken": endToken,
-      "blockKind": blockKind
-    });
+    DirectParserASTContentBlockEnd data = new DirectParserASTContentBlockEnd(
+        DirectParserASTType.END,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken,
+        blockKind: blockKind);
+    seen(data);
   }
 
   void handleInvalidTopLevelBlock(Token token) {
-    seen("InvalidTopLevelBlock", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentInvalidTopLevelBlockHandle data =
+        new DirectParserASTContentInvalidTopLevelBlockHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginCascade(Token token) {
-    seen("Cascade", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentCascadeBegin data =
+        new DirectParserASTContentCascadeBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endCascade() {
-    seen("Cascade", DirectParserASTType.END, {});
+    DirectParserASTContentCascadeEnd data =
+        new DirectParserASTContentCascadeEnd(DirectParserASTType.END);
+    seen(data);
   }
 
   void beginCaseExpression(Token caseKeyword) {
-    seen("CaseExpression", DirectParserASTType.BEGIN,
-        {"caseKeyword": caseKeyword});
+    DirectParserASTContentCaseExpressionBegin data =
+        new DirectParserASTContentCaseExpressionBegin(DirectParserASTType.BEGIN,
+            caseKeyword: caseKeyword);
+    seen(data);
   }
 
   void endCaseExpression(Token colon) {
-    seen("CaseExpression", DirectParserASTType.END, {"colon": colon});
+    DirectParserASTContentCaseExpressionEnd data =
+        new DirectParserASTContentCaseExpressionEnd(DirectParserASTType.END,
+            colon: colon);
+    seen(data);
   }
 
   void beginClassOrMixinBody(DeclarationKind kind, Token token) {
-    seen("ClassOrMixinBody", DirectParserASTType.BEGIN,
-        {"kind": kind, "token": token});
+    DirectParserASTContentClassOrMixinBodyBegin data =
+        new DirectParserASTContentClassOrMixinBodyBegin(
+            DirectParserASTType.BEGIN,
+            kind: kind,
+            token: token);
+    seen(data);
   }
 
   void endClassOrMixinBody(
       DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
-    seen("ClassOrMixinBody", DirectParserASTType.END, {
-      "kind": kind,
-      "memberCount": memberCount,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentClassOrMixinBodyEnd data =
+        new DirectParserASTContentClassOrMixinBodyEnd(DirectParserASTType.END,
+            kind: kind,
+            memberCount: memberCount,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginClassOrNamedMixinApplicationPrelude(Token token) {
-    seen("ClassOrNamedMixinApplicationPrelude", DirectParserASTType.BEGIN,
-        {"token": token});
+    DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin data =
+        new DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
-    seen("ClassDeclaration", DirectParserASTType.BEGIN,
-        {"begin": begin, "abstractToken": abstractToken, "name": name});
+    DirectParserASTContentClassDeclarationBegin data =
+        new DirectParserASTContentClassDeclarationBegin(
+            DirectParserASTType.BEGIN,
+            begin: begin,
+            abstractToken: abstractToken,
+            name: name);
+    seen(data);
   }
 
   void handleClassExtends(Token extendsKeyword, int typeCount) {
-    seen("ClassExtends", DirectParserASTType.HANDLE,
-        {"extendsKeyword": extendsKeyword, "typeCount": typeCount});
+    DirectParserASTContentClassExtendsHandle data =
+        new DirectParserASTContentClassExtendsHandle(DirectParserASTType.HANDLE,
+            extendsKeyword: extendsKeyword, typeCount: typeCount);
+    seen(data);
   }
 
   void handleClassOrMixinImplements(
       Token implementsKeyword, int interfacesCount) {
-    seen("ClassOrMixinImplements", DirectParserASTType.HANDLE, {
-      "implementsKeyword": implementsKeyword,
-      "interfacesCount": interfacesCount
-    });
+    DirectParserASTContentClassOrMixinImplementsHandle data =
+        new DirectParserASTContentClassOrMixinImplementsHandle(
+            DirectParserASTType.HANDLE,
+            implementsKeyword: implementsKeyword,
+            interfacesCount: interfacesCount);
+    seen(data);
   }
 
   void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
-    seen("ClassHeader", DirectParserASTType.HANDLE, {
-      "begin": begin,
-      "classKeyword": classKeyword,
-      "nativeToken": nativeToken
-    });
+    DirectParserASTContentClassHeaderHandle data =
+        new DirectParserASTContentClassHeaderHandle(DirectParserASTType.HANDLE,
+            begin: begin, classKeyword: classKeyword, nativeToken: nativeToken);
+    seen(data);
   }
 
   void handleRecoverClassHeader() {
-    seen("RecoverClassHeader", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentRecoverClassHeaderHandle data =
+        new DirectParserASTContentRecoverClassHeaderHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 
   void endClassDeclaration(Token beginToken, Token endToken) {
-    seen("ClassDeclaration", DirectParserASTType.END,
-        {"beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentClassDeclarationEnd data =
+        new DirectParserASTContentClassDeclarationEnd(DirectParserASTType.END,
+            beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void beginMixinDeclaration(Token mixinKeyword, Token name) {
-    seen("MixinDeclaration", DirectParserASTType.BEGIN,
-        {"mixinKeyword": mixinKeyword, "name": name});
+    DirectParserASTContentMixinDeclarationBegin data =
+        new DirectParserASTContentMixinDeclarationBegin(
+            DirectParserASTType.BEGIN,
+            mixinKeyword: mixinKeyword,
+            name: name);
+    seen(data);
   }
 
   void handleMixinOn(Token onKeyword, int typeCount) {
-    seen("MixinOn", DirectParserASTType.HANDLE,
-        {"onKeyword": onKeyword, "typeCount": typeCount});
+    DirectParserASTContentMixinOnHandle data =
+        new DirectParserASTContentMixinOnHandle(DirectParserASTType.HANDLE,
+            onKeyword: onKeyword, typeCount: typeCount);
+    seen(data);
   }
 
   void handleMixinHeader(Token mixinKeyword) {
-    seen("MixinHeader", DirectParserASTType.HANDLE,
-        {"mixinKeyword": mixinKeyword});
+    DirectParserASTContentMixinHeaderHandle data =
+        new DirectParserASTContentMixinHeaderHandle(DirectParserASTType.HANDLE,
+            mixinKeyword: mixinKeyword);
+    seen(data);
   }
 
   void handleRecoverMixinHeader() {
-    seen("RecoverMixinHeader", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentRecoverMixinHeaderHandle data =
+        new DirectParserASTContentRecoverMixinHeaderHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 
   void endMixinDeclaration(Token mixinKeyword, Token endToken) {
-    seen("MixinDeclaration", DirectParserASTType.END,
-        {"mixinKeyword": mixinKeyword, "endToken": endToken});
+    DirectParserASTContentMixinDeclarationEnd data =
+        new DirectParserASTContentMixinDeclarationEnd(DirectParserASTType.END,
+            mixinKeyword: mixinKeyword, endToken: endToken);
+    seen(data);
   }
 
   void beginUncategorizedTopLevelDeclaration(Token token) {
-    seen("UncategorizedTopLevelDeclaration", DirectParserASTType.BEGIN,
-        {"token": token});
+    DirectParserASTContentUncategorizedTopLevelDeclarationBegin data =
+        new DirectParserASTContentUncategorizedTopLevelDeclarationBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void beginExtensionDeclarationPrelude(Token extensionKeyword) {
-    seen("ExtensionDeclarationPrelude", DirectParserASTType.BEGIN,
-        {"extensionKeyword": extensionKeyword});
+    DirectParserASTContentExtensionDeclarationPreludeBegin data =
+        new DirectParserASTContentExtensionDeclarationPreludeBegin(
+            DirectParserASTType.BEGIN,
+            extensionKeyword: extensionKeyword);
+    seen(data);
   }
 
   void beginExtensionDeclaration(Token extensionKeyword, Token name) {
-    seen("ExtensionDeclaration", DirectParserASTType.BEGIN,
-        {"extensionKeyword": extensionKeyword, "name": name});
+    DirectParserASTContentExtensionDeclarationBegin data =
+        new DirectParserASTContentExtensionDeclarationBegin(
+            DirectParserASTType.BEGIN,
+            extensionKeyword: extensionKeyword,
+            name: name);
+    seen(data);
   }
 
   void endExtensionDeclaration(
       Token extensionKeyword, Token onKeyword, Token endToken) {
-    seen("ExtensionDeclaration", DirectParserASTType.END, {
-      "extensionKeyword": extensionKeyword,
-      "onKeyword": onKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentExtensionDeclarationEnd data =
+        new DirectParserASTContentExtensionDeclarationEnd(
+            DirectParserASTType.END,
+            extensionKeyword: extensionKeyword,
+            onKeyword: onKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginCombinators(Token token) {
-    seen("Combinators", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentCombinatorsBegin data =
+        new DirectParserASTContentCombinatorsBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endCombinators(int count) {
-    seen("Combinators", DirectParserASTType.END, {"count": count});
+    DirectParserASTContentCombinatorsEnd data =
+        new DirectParserASTContentCombinatorsEnd(DirectParserASTType.END,
+            count: count);
+    seen(data);
   }
 
   void beginCompilationUnit(Token token) {
-    seen("CompilationUnit", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentCompilationUnitBegin data =
+        new DirectParserASTContentCompilationUnitBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void handleDirectivesOnly() {
-    seen("DirectivesOnly", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentDirectivesOnlyHandle data =
+        new DirectParserASTContentDirectivesOnlyHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 
   void endCompilationUnit(int count, Token token) {
-    seen("CompilationUnit", DirectParserASTType.END,
-        {"count": count, "token": token});
+    DirectParserASTContentCompilationUnitEnd data =
+        new DirectParserASTContentCompilationUnitEnd(DirectParserASTType.END,
+            count: count, token: token);
+    seen(data);
   }
 
   void beginConstLiteral(Token token) {
-    seen("ConstLiteral", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentConstLiteralBegin data =
+        new DirectParserASTContentConstLiteralBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endConstLiteral(Token token) {
-    seen("ConstLiteral", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentConstLiteralEnd data =
+        new DirectParserASTContentConstLiteralEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginConstructorReference(Token start) {
-    seen("ConstructorReference", DirectParserASTType.BEGIN, {"start": start});
+    DirectParserASTContentConstructorReferenceBegin data =
+        new DirectParserASTContentConstructorReferenceBegin(
+            DirectParserASTType.BEGIN,
+            start: start);
+    seen(data);
   }
 
   void endConstructorReference(
       Token start, Token periodBeforeName, Token endToken) {
-    seen("ConstructorReference", DirectParserASTType.END, {
-      "start": start,
-      "periodBeforeName": periodBeforeName,
-      "endToken": endToken
-    });
+    DirectParserASTContentConstructorReferenceEnd data =
+        new DirectParserASTContentConstructorReferenceEnd(
+            DirectParserASTType.END,
+            start: start,
+            periodBeforeName: periodBeforeName,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginDoWhileStatement(Token token) {
-    seen("DoWhileStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentDoWhileStatementBegin data =
+        new DirectParserASTContentDoWhileStatementBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endDoWhileStatement(
       Token doKeyword, Token whileKeyword, Token endToken) {
-    seen("DoWhileStatement", DirectParserASTType.END, {
-      "doKeyword": doKeyword,
-      "whileKeyword": whileKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentDoWhileStatementEnd data =
+        new DirectParserASTContentDoWhileStatementEnd(DirectParserASTType.END,
+            doKeyword: doKeyword,
+            whileKeyword: whileKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginDoWhileStatementBody(Token token) {
-    seen("DoWhileStatementBody", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentDoWhileStatementBodyBegin data =
+        new DirectParserASTContentDoWhileStatementBodyBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endDoWhileStatementBody(Token token) {
-    seen("DoWhileStatementBody", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentDoWhileStatementBodyEnd data =
+        new DirectParserASTContentDoWhileStatementBodyEnd(
+            DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginWhileStatementBody(Token token) {
-    seen("WhileStatementBody", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentWhileStatementBodyBegin data =
+        new DirectParserASTContentWhileStatementBodyBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endWhileStatementBody(Token token) {
-    seen("WhileStatementBody", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentWhileStatementBodyEnd data =
+        new DirectParserASTContentWhileStatementBodyEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginEnum(Token enumKeyword) {
-    seen("Enum", DirectParserASTType.BEGIN, {"enumKeyword": enumKeyword});
+    DirectParserASTContentEnumBegin data = new DirectParserASTContentEnumBegin(
+        DirectParserASTType.BEGIN,
+        enumKeyword: enumKeyword);
+    seen(data);
   }
 
   void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    seen("Enum", DirectParserASTType.END,
-        {"enumKeyword": enumKeyword, "leftBrace": leftBrace, "count": count});
+    DirectParserASTContentEnumEnd data = new DirectParserASTContentEnumEnd(
+        DirectParserASTType.END,
+        enumKeyword: enumKeyword,
+        leftBrace: leftBrace,
+        count: count);
+    seen(data);
   }
 
   void beginExport(Token token) {
-    seen("Export", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentExportBegin data =
+        new DirectParserASTContentExportBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endExport(Token exportKeyword, Token semicolon) {
-    seen("Export", DirectParserASTType.END,
-        {"exportKeyword": exportKeyword, "semicolon": semicolon});
+    DirectParserASTContentExportEnd data = new DirectParserASTContentExportEnd(
+        DirectParserASTType.END,
+        exportKeyword: exportKeyword,
+        semicolon: semicolon);
+    seen(data);
   }
 
   void handleExtraneousExpression(Token token, Message message) {
-    seen("ExtraneousExpression", DirectParserASTType.HANDLE,
-        {"token": token, "message": message});
+    DirectParserASTContentExtraneousExpressionHandle data =
+        new DirectParserASTContentExtraneousExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            message: message);
+    seen(data);
   }
 
   void handleExpressionStatement(Token token) {
-    seen("ExpressionStatement", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentExpressionStatementHandle data =
+        new DirectParserASTContentExpressionStatementHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginFactoryMethod(
       Token lastConsumed, Token externalToken, Token constToken) {
-    seen("FactoryMethod", DirectParserASTType.BEGIN, {
-      "lastConsumed": lastConsumed,
-      "externalToken": externalToken,
-      "constToken": constToken
-    });
+    DirectParserASTContentFactoryMethodBegin data =
+        new DirectParserASTContentFactoryMethodBegin(DirectParserASTType.BEGIN,
+            lastConsumed: lastConsumed,
+            externalToken: externalToken,
+            constToken: constToken);
+    seen(data);
   }
 
   void endClassFactoryMethod(
       Token beginToken, Token factoryKeyword, Token endToken) {
-    seen("ClassFactoryMethod", DirectParserASTType.END, {
-      "beginToken": beginToken,
-      "factoryKeyword": factoryKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentClassFactoryMethodEnd data =
+        new DirectParserASTContentClassFactoryMethodEnd(DirectParserASTType.END,
+            beginToken: beginToken,
+            factoryKeyword: factoryKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void endMixinFactoryMethod(
       Token beginToken, Token factoryKeyword, Token endToken) {
-    seen("MixinFactoryMethod", DirectParserASTType.END, {
-      "beginToken": beginToken,
-      "factoryKeyword": factoryKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentMixinFactoryMethodEnd data =
+        new DirectParserASTContentMixinFactoryMethodEnd(DirectParserASTType.END,
+            beginToken: beginToken,
+            factoryKeyword: factoryKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void endExtensionFactoryMethod(
       Token beginToken, Token factoryKeyword, Token endToken) {
-    seen("ExtensionFactoryMethod", DirectParserASTType.END, {
-      "beginToken": beginToken,
-      "factoryKeyword": factoryKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentExtensionFactoryMethodEnd data =
+        new DirectParserASTContentExtensionFactoryMethodEnd(
+            DirectParserASTType.END,
+            beginToken: beginToken,
+            factoryKeyword: factoryKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginFormalParameter(Token token, MemberKind kind, Token requiredToken,
       Token covariantToken, Token varFinalOrConst) {
-    seen("FormalParameter", DirectParserASTType.BEGIN, {
-      "token": token,
-      "kind": kind,
-      "requiredToken": requiredToken,
-      "covariantToken": covariantToken,
-      "varFinalOrConst": varFinalOrConst
-    });
+    DirectParserASTContentFormalParameterBegin data =
+        new DirectParserASTContentFormalParameterBegin(
+            DirectParserASTType.BEGIN,
+            token: token,
+            kind: kind,
+            requiredToken: requiredToken,
+            covariantToken: covariantToken,
+            varFinalOrConst: varFinalOrConst);
+    seen(data);
   }
 
   void endFormalParameter(
@@ -365,35 +521,45 @@
       Token initializerEnd,
       FormalParameterKind kind,
       MemberKind memberKind) {
-    seen("FormalParameter", DirectParserASTType.END, {
-      "thisKeyword": thisKeyword,
-      "periodAfterThis": periodAfterThis,
-      "nameToken": nameToken,
-      "initializerStart": initializerStart,
-      "initializerEnd": initializerEnd,
-      "kind": kind,
-      "memberKind": memberKind
-    });
+    DirectParserASTContentFormalParameterEnd data =
+        new DirectParserASTContentFormalParameterEnd(DirectParserASTType.END,
+            thisKeyword: thisKeyword,
+            periodAfterThis: periodAfterThis,
+            nameToken: nameToken,
+            initializerStart: initializerStart,
+            initializerEnd: initializerEnd,
+            kind: kind,
+            memberKind: memberKind);
+    seen(data);
   }
 
   void handleNoFormalParameters(Token token, MemberKind kind) {
-    seen("NoFormalParameters", DirectParserASTType.HANDLE,
-        {"token": token, "kind": kind});
+    DirectParserASTContentNoFormalParametersHandle data =
+        new DirectParserASTContentNoFormalParametersHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            kind: kind);
+    seen(data);
   }
 
   void beginFormalParameters(Token token, MemberKind kind) {
-    seen("FormalParameters", DirectParserASTType.BEGIN,
-        {"token": token, "kind": kind});
+    DirectParserASTContentFormalParametersBegin data =
+        new DirectParserASTContentFormalParametersBegin(
+            DirectParserASTType.BEGIN,
+            token: token,
+            kind: kind);
+    seen(data);
   }
 
   void endFormalParameters(
       int count, Token beginToken, Token endToken, MemberKind kind) {
-    seen("FormalParameters", DirectParserASTType.END, {
-      "count": count,
-      "beginToken": beginToken,
-      "endToken": endToken,
-      "kind": kind
-    });
+    DirectParserASTContentFormalParametersEnd data =
+        new DirectParserASTContentFormalParametersEnd(DirectParserASTType.END,
+            count: count,
+            beginToken: beginToken,
+            endToken: endToken,
+            kind: kind);
+    seen(data);
   }
 
   void endClassFields(
@@ -406,17 +572,18 @@
       int count,
       Token beginToken,
       Token endToken) {
-    seen("ClassFields", DirectParserASTType.END, {
-      "abstractToken": abstractToken,
-      "externalToken": externalToken,
-      "staticToken": staticToken,
-      "covariantToken": covariantToken,
-      "lateToken": lateToken,
-      "varFinalOrConst": varFinalOrConst,
-      "count": count,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentClassFieldsEnd data =
+        new DirectParserASTContentClassFieldsEnd(DirectParserASTType.END,
+            abstractToken: abstractToken,
+            externalToken: externalToken,
+            staticToken: staticToken,
+            covariantToken: covariantToken,
+            lateToken: lateToken,
+            varFinalOrConst: varFinalOrConst,
+            count: count,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void endMixinFields(
@@ -429,17 +596,18 @@
       int count,
       Token beginToken,
       Token endToken) {
-    seen("MixinFields", DirectParserASTType.END, {
-      "abstractToken": abstractToken,
-      "externalToken": externalToken,
-      "staticToken": staticToken,
-      "covariantToken": covariantToken,
-      "lateToken": lateToken,
-      "varFinalOrConst": varFinalOrConst,
-      "count": count,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentMixinFieldsEnd data =
+        new DirectParserASTContentMixinFieldsEnd(DirectParserASTType.END,
+            abstractToken: abstractToken,
+            externalToken: externalToken,
+            staticToken: staticToken,
+            covariantToken: covariantToken,
+            lateToken: lateToken,
+            varFinalOrConst: varFinalOrConst,
+            count: count,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void endExtensionFields(
@@ -452,658 +620,1018 @@
       int count,
       Token beginToken,
       Token endToken) {
-    seen("ExtensionFields", DirectParserASTType.END, {
-      "abstractToken": abstractToken,
-      "externalToken": externalToken,
-      "staticToken": staticToken,
-      "covariantToken": covariantToken,
-      "lateToken": lateToken,
-      "varFinalOrConst": varFinalOrConst,
-      "count": count,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentExtensionFieldsEnd data =
+        new DirectParserASTContentExtensionFieldsEnd(DirectParserASTType.END,
+            abstractToken: abstractToken,
+            externalToken: externalToken,
+            staticToken: staticToken,
+            covariantToken: covariantToken,
+            lateToken: lateToken,
+            varFinalOrConst: varFinalOrConst,
+            count: count,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void handleForInitializerEmptyStatement(Token token) {
-    seen("ForInitializerEmptyStatement", DirectParserASTType.HANDLE,
-        {"token": token});
+    DirectParserASTContentForInitializerEmptyStatementHandle data =
+        new DirectParserASTContentForInitializerEmptyStatementHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleForInitializerExpressionStatement(Token token, bool forIn) {
-    seen("ForInitializerExpressionStatement", DirectParserASTType.HANDLE,
-        {"token": token, "forIn": forIn});
+    DirectParserASTContentForInitializerExpressionStatementHandle data =
+        new DirectParserASTContentForInitializerExpressionStatementHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            forIn: forIn);
+    seen(data);
   }
 
   void handleForInitializerLocalVariableDeclaration(Token token, bool forIn) {
-    seen("ForInitializerLocalVariableDeclaration", DirectParserASTType.HANDLE,
-        {"token": token, "forIn": forIn});
+    DirectParserASTContentForInitializerLocalVariableDeclarationHandle data =
+        new DirectParserASTContentForInitializerLocalVariableDeclarationHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            forIn: forIn);
+    seen(data);
   }
 
   void beginForStatement(Token token) {
-    seen("ForStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentForStatementBegin data =
+        new DirectParserASTContentForStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void handleForLoopParts(Token forKeyword, Token leftParen,
       Token leftSeparator, int updateExpressionCount) {
-    seen("ForLoopParts", DirectParserASTType.HANDLE, {
-      "forKeyword": forKeyword,
-      "leftParen": leftParen,
-      "leftSeparator": leftSeparator,
-      "updateExpressionCount": updateExpressionCount
-    });
+    DirectParserASTContentForLoopPartsHandle data =
+        new DirectParserASTContentForLoopPartsHandle(DirectParserASTType.HANDLE,
+            forKeyword: forKeyword,
+            leftParen: leftParen,
+            leftSeparator: leftSeparator,
+            updateExpressionCount: updateExpressionCount);
+    seen(data);
   }
 
   void endForStatement(Token endToken) {
-    seen("ForStatement", DirectParserASTType.END, {"endToken": endToken});
+    DirectParserASTContentForStatementEnd data =
+        new DirectParserASTContentForStatementEnd(DirectParserASTType.END,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginForStatementBody(Token token) {
-    seen("ForStatementBody", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentForStatementBodyBegin data =
+        new DirectParserASTContentForStatementBodyBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endForStatementBody(Token token) {
-    seen("ForStatementBody", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentForStatementBodyEnd data =
+        new DirectParserASTContentForStatementBodyEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void handleForInLoopParts(Token awaitToken, Token forToken,
       Token leftParenthesis, Token inKeyword) {
-    seen("ForInLoopParts", DirectParserASTType.HANDLE, {
-      "awaitToken": awaitToken,
-      "forToken": forToken,
-      "leftParenthesis": leftParenthesis,
-      "inKeyword": inKeyword
-    });
+    DirectParserASTContentForInLoopPartsHandle data =
+        new DirectParserASTContentForInLoopPartsHandle(
+            DirectParserASTType.HANDLE,
+            awaitToken: awaitToken,
+            forToken: forToken,
+            leftParenthesis: leftParenthesis,
+            inKeyword: inKeyword);
+    seen(data);
   }
 
   void endForIn(Token endToken) {
-    seen("ForIn", DirectParserASTType.END, {"endToken": endToken});
+    DirectParserASTContentForInEnd data = new DirectParserASTContentForInEnd(
+        DirectParserASTType.END,
+        endToken: endToken);
+    seen(data);
   }
 
   void beginForInExpression(Token token) {
-    seen("ForInExpression", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentForInExpressionBegin data =
+        new DirectParserASTContentForInExpressionBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endForInExpression(Token token) {
-    seen("ForInExpression", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentForInExpressionEnd data =
+        new DirectParserASTContentForInExpressionEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginForInBody(Token token) {
-    seen("ForInBody", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentForInBodyBegin data =
+        new DirectParserASTContentForInBodyBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endForInBody(Token token) {
-    seen("ForInBody", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentForInBodyEnd data =
+        new DirectParserASTContentForInBodyEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginNamedFunctionExpression(Token token) {
-    seen(
-        "NamedFunctionExpression", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentNamedFunctionExpressionBegin data =
+        new DirectParserASTContentNamedFunctionExpressionBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endNamedFunctionExpression(Token endToken) {
-    seen("NamedFunctionExpression", DirectParserASTType.END,
-        {"endToken": endToken});
+    DirectParserASTContentNamedFunctionExpressionEnd data =
+        new DirectParserASTContentNamedFunctionExpressionEnd(
+            DirectParserASTType.END,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginLocalFunctionDeclaration(Token token) {
-    seen("LocalFunctionDeclaration", DirectParserASTType.BEGIN,
-        {"token": token});
+    DirectParserASTContentLocalFunctionDeclarationBegin data =
+        new DirectParserASTContentLocalFunctionDeclarationBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endLocalFunctionDeclaration(Token endToken) {
-    seen("LocalFunctionDeclaration", DirectParserASTType.END,
-        {"endToken": endToken});
+    DirectParserASTContentLocalFunctionDeclarationEnd data =
+        new DirectParserASTContentLocalFunctionDeclarationEnd(
+            DirectParserASTType.END,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginBlockFunctionBody(Token token) {
-    seen("BlockFunctionBody", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentBlockFunctionBodyBegin data =
+        new DirectParserASTContentBlockFunctionBodyBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
-    seen("BlockFunctionBody", DirectParserASTType.END,
-        {"count": count, "beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentBlockFunctionBodyEnd data =
+        new DirectParserASTContentBlockFunctionBodyEnd(DirectParserASTType.END,
+            count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void handleNoFunctionBody(Token token) {
-    seen("NoFunctionBody", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoFunctionBodyHandle data =
+        new DirectParserASTContentNoFunctionBodyHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
-    seen("FunctionBodySkipped", DirectParserASTType.HANDLE,
-        {"token": token, "isExpressionBody": isExpressionBody});
+    DirectParserASTContentFunctionBodySkippedHandle data =
+        new DirectParserASTContentFunctionBodySkippedHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            isExpressionBody: isExpressionBody);
+    seen(data);
   }
 
   void beginFunctionName(Token token) {
-    seen("FunctionName", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentFunctionNameBegin data =
+        new DirectParserASTContentFunctionNameBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endFunctionName(Token beginToken, Token token) {
-    seen("FunctionName", DirectParserASTType.END,
-        {"beginToken": beginToken, "token": token});
+    DirectParserASTContentFunctionNameEnd data =
+        new DirectParserASTContentFunctionNameEnd(DirectParserASTType.END,
+            beginToken: beginToken, token: token);
+    seen(data);
   }
 
   void beginFunctionTypeAlias(Token token) {
-    seen("FunctionTypeAlias", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentFunctionTypeAliasBegin data =
+        new DirectParserASTContentFunctionTypeAliasBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endFunctionTypeAlias(
       Token typedefKeyword, Token equals, Token endToken) {
-    seen("FunctionTypeAlias", DirectParserASTType.END, {
-      "typedefKeyword": typedefKeyword,
-      "equals": equals,
-      "endToken": endToken
-    });
+    DirectParserASTContentFunctionTypeAliasEnd data =
+        new DirectParserASTContentFunctionTypeAliasEnd(DirectParserASTType.END,
+            typedefKeyword: typedefKeyword, equals: equals, endToken: endToken);
+    seen(data);
   }
 
   void handleClassWithClause(Token withKeyword) {
-    seen("ClassWithClause", DirectParserASTType.HANDLE,
-        {"withKeyword": withKeyword});
+    DirectParserASTContentClassWithClauseHandle data =
+        new DirectParserASTContentClassWithClauseHandle(
+            DirectParserASTType.HANDLE,
+            withKeyword: withKeyword);
+    seen(data);
   }
 
   void handleClassNoWithClause() {
-    seen("ClassNoWithClause", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentClassNoWithClauseHandle data =
+        new DirectParserASTContentClassNoWithClauseHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 
   void beginNamedMixinApplication(
       Token begin, Token abstractToken, Token name) {
-    seen("NamedMixinApplication", DirectParserASTType.BEGIN,
-        {"begin": begin, "abstractToken": abstractToken, "name": name});
+    DirectParserASTContentNamedMixinApplicationBegin data =
+        new DirectParserASTContentNamedMixinApplicationBegin(
+            DirectParserASTType.BEGIN,
+            begin: begin,
+            abstractToken: abstractToken,
+            name: name);
+    seen(data);
   }
 
   void handleNamedMixinApplicationWithClause(Token withKeyword) {
-    seen("NamedMixinApplicationWithClause", DirectParserASTType.HANDLE,
-        {"withKeyword": withKeyword});
+    DirectParserASTContentNamedMixinApplicationWithClauseHandle data =
+        new DirectParserASTContentNamedMixinApplicationWithClauseHandle(
+            DirectParserASTType.HANDLE,
+            withKeyword: withKeyword);
+    seen(data);
   }
 
   void endNamedMixinApplication(Token begin, Token classKeyword, Token equals,
       Token implementsKeyword, Token endToken) {
-    seen("NamedMixinApplication", DirectParserASTType.END, {
-      "begin": begin,
-      "classKeyword": classKeyword,
-      "equals": equals,
-      "implementsKeyword": implementsKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentNamedMixinApplicationEnd data =
+        new DirectParserASTContentNamedMixinApplicationEnd(
+            DirectParserASTType.END,
+            begin: begin,
+            classKeyword: classKeyword,
+            equals: equals,
+            implementsKeyword: implementsKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginHide(Token hideKeyword) {
-    seen("Hide", DirectParserASTType.BEGIN, {"hideKeyword": hideKeyword});
+    DirectParserASTContentHideBegin data = new DirectParserASTContentHideBegin(
+        DirectParserASTType.BEGIN,
+        hideKeyword: hideKeyword);
+    seen(data);
   }
 
   void endHide(Token hideKeyword) {
-    seen("Hide", DirectParserASTType.END, {"hideKeyword": hideKeyword});
+    DirectParserASTContentHideEnd data = new DirectParserASTContentHideEnd(
+        DirectParserASTType.END,
+        hideKeyword: hideKeyword);
+    seen(data);
   }
 
   void handleIdentifierList(int count) {
-    seen("IdentifierList", DirectParserASTType.HANDLE, {"count": count});
+    DirectParserASTContentIdentifierListHandle data =
+        new DirectParserASTContentIdentifierListHandle(
+            DirectParserASTType.HANDLE,
+            count: count);
+    seen(data);
   }
 
   void beginTypeList(Token token) {
-    seen("TypeList", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentTypeListBegin data =
+        new DirectParserASTContentTypeListBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endTypeList(int count) {
-    seen("TypeList", DirectParserASTType.END, {"count": count});
+    DirectParserASTContentTypeListEnd data =
+        new DirectParserASTContentTypeListEnd(DirectParserASTType.END,
+            count: count);
+    seen(data);
   }
 
   void beginIfStatement(Token token) {
-    seen("IfStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentIfStatementBegin data =
+        new DirectParserASTContentIfStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endIfStatement(Token ifToken, Token elseToken) {
-    seen("IfStatement", DirectParserASTType.END,
-        {"ifToken": ifToken, "elseToken": elseToken});
+    DirectParserASTContentIfStatementEnd data =
+        new DirectParserASTContentIfStatementEnd(DirectParserASTType.END,
+            ifToken: ifToken, elseToken: elseToken);
+    seen(data);
   }
 
   void beginThenStatement(Token token) {
-    seen("ThenStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentThenStatementBegin data =
+        new DirectParserASTContentThenStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endThenStatement(Token token) {
-    seen("ThenStatement", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentThenStatementEnd data =
+        new DirectParserASTContentThenStatementEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginElseStatement(Token token) {
-    seen("ElseStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentElseStatementBegin data =
+        new DirectParserASTContentElseStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endElseStatement(Token token) {
-    seen("ElseStatement", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentElseStatementEnd data =
+        new DirectParserASTContentElseStatementEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginImport(Token importKeyword) {
-    seen("Import", DirectParserASTType.BEGIN, {"importKeyword": importKeyword});
+    DirectParserASTContentImportBegin data =
+        new DirectParserASTContentImportBegin(DirectParserASTType.BEGIN,
+            importKeyword: importKeyword);
+    seen(data);
   }
 
   void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
-    seen("ImportPrefix", DirectParserASTType.HANDLE,
-        {"deferredKeyword": deferredKeyword, "asKeyword": asKeyword});
+    DirectParserASTContentImportPrefixHandle data =
+        new DirectParserASTContentImportPrefixHandle(DirectParserASTType.HANDLE,
+            deferredKeyword: deferredKeyword, asKeyword: asKeyword);
+    seen(data);
   }
 
   void endImport(Token importKeyword, Token semicolon) {
-    seen("Import", DirectParserASTType.END,
-        {"importKeyword": importKeyword, "semicolon": semicolon});
+    DirectParserASTContentImportEnd data = new DirectParserASTContentImportEnd(
+        DirectParserASTType.END,
+        importKeyword: importKeyword,
+        semicolon: semicolon);
+    seen(data);
   }
 
   void handleRecoverImport(Token semicolon) {
-    seen("RecoverImport", DirectParserASTType.HANDLE, {"semicolon": semicolon});
+    DirectParserASTContentRecoverImportHandle data =
+        new DirectParserASTContentRecoverImportHandle(
+            DirectParserASTType.HANDLE,
+            semicolon: semicolon);
+    seen(data);
   }
 
   void beginConditionalUris(Token token) {
-    seen("ConditionalUris", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentConditionalUrisBegin data =
+        new DirectParserASTContentConditionalUrisBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endConditionalUris(int count) {
-    seen("ConditionalUris", DirectParserASTType.END, {"count": count});
+    DirectParserASTContentConditionalUrisEnd data =
+        new DirectParserASTContentConditionalUrisEnd(DirectParserASTType.END,
+            count: count);
+    seen(data);
   }
 
   void beginConditionalUri(Token ifKeyword) {
-    seen("ConditionalUri", DirectParserASTType.BEGIN, {"ifKeyword": ifKeyword});
+    DirectParserASTContentConditionalUriBegin data =
+        new DirectParserASTContentConditionalUriBegin(DirectParserASTType.BEGIN,
+            ifKeyword: ifKeyword);
+    seen(data);
   }
 
   void endConditionalUri(Token ifKeyword, Token leftParen, Token equalSign) {
-    seen("ConditionalUri", DirectParserASTType.END, {
-      "ifKeyword": ifKeyword,
-      "leftParen": leftParen,
-      "equalSign": equalSign
-    });
+    DirectParserASTContentConditionalUriEnd data =
+        new DirectParserASTContentConditionalUriEnd(DirectParserASTType.END,
+            ifKeyword: ifKeyword, leftParen: leftParen, equalSign: equalSign);
+    seen(data);
   }
 
   void handleDottedName(int count, Token firstIdentifier) {
-    seen("DottedName", DirectParserASTType.HANDLE,
-        {"count": count, "firstIdentifier": firstIdentifier});
+    DirectParserASTContentDottedNameHandle data =
+        new DirectParserASTContentDottedNameHandle(DirectParserASTType.HANDLE,
+            count: count, firstIdentifier: firstIdentifier);
+    seen(data);
   }
 
   void beginImplicitCreationExpression(Token token) {
-    seen("ImplicitCreationExpression", DirectParserASTType.BEGIN,
-        {"token": token});
+    DirectParserASTContentImplicitCreationExpressionBegin data =
+        new DirectParserASTContentImplicitCreationExpressionBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endImplicitCreationExpression(Token token) {
-    seen("ImplicitCreationExpression", DirectParserASTType.END,
-        {"token": token});
+    DirectParserASTContentImplicitCreationExpressionEnd data =
+        new DirectParserASTContentImplicitCreationExpressionEnd(
+            DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginInitializedIdentifier(Token token) {
-    seen("InitializedIdentifier", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentInitializedIdentifierBegin data =
+        new DirectParserASTContentInitializedIdentifierBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endInitializedIdentifier(Token nameToken) {
-    seen("InitializedIdentifier", DirectParserASTType.END,
-        {"nameToken": nameToken});
+    DirectParserASTContentInitializedIdentifierEnd data =
+        new DirectParserASTContentInitializedIdentifierEnd(
+            DirectParserASTType.END,
+            nameToken: nameToken);
+    seen(data);
   }
 
   void beginFieldInitializer(Token token) {
-    seen("FieldInitializer", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentFieldInitializerBegin data =
+        new DirectParserASTContentFieldInitializerBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endFieldInitializer(Token assignment, Token token) {
-    seen("FieldInitializer", DirectParserASTType.END,
-        {"assignment": assignment, "token": token});
+    DirectParserASTContentFieldInitializerEnd data =
+        new DirectParserASTContentFieldInitializerEnd(DirectParserASTType.END,
+            assignment: assignment, token: token);
+    seen(data);
   }
 
   void handleNoFieldInitializer(Token token) {
-    seen("NoFieldInitializer", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoFieldInitializerHandle data =
+        new DirectParserASTContentNoFieldInitializerHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginVariableInitializer(Token token) {
-    seen("VariableInitializer", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentVariableInitializerBegin data =
+        new DirectParserASTContentVariableInitializerBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endVariableInitializer(Token assignmentOperator) {
-    seen("VariableInitializer", DirectParserASTType.END,
-        {"assignmentOperator": assignmentOperator});
+    DirectParserASTContentVariableInitializerEnd data =
+        new DirectParserASTContentVariableInitializerEnd(
+            DirectParserASTType.END,
+            assignmentOperator: assignmentOperator);
+    seen(data);
   }
 
   void handleNoVariableInitializer(Token token) {
-    seen("NoVariableInitializer", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoVariableInitializerHandle data =
+        new DirectParserASTContentNoVariableInitializerHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginInitializer(Token token) {
-    seen("Initializer", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentInitializerBegin data =
+        new DirectParserASTContentInitializerBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endInitializer(Token token) {
-    seen("Initializer", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentInitializerEnd data =
+        new DirectParserASTContentInitializerEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginInitializers(Token token) {
-    seen("Initializers", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentInitializersBegin data =
+        new DirectParserASTContentInitializersBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endInitializers(int count, Token beginToken, Token endToken) {
-    seen("Initializers", DirectParserASTType.END,
-        {"count": count, "beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentInitializersEnd data =
+        new DirectParserASTContentInitializersEnd(DirectParserASTType.END,
+            count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void handleNoInitializers() {
-    seen("NoInitializers", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentNoInitializersHandle data =
+        new DirectParserASTContentNoInitializersHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 
   void handleInvalidExpression(Token token) {
-    seen("InvalidExpression", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentInvalidExpressionHandle data =
+        new DirectParserASTContentInvalidExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleInvalidFunctionBody(Token token) {
-    seen("InvalidFunctionBody", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentInvalidFunctionBodyHandle data =
+        new DirectParserASTContentInvalidFunctionBodyHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleInvalidTypeReference(Token token) {
-    seen("InvalidTypeReference", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentInvalidTypeReferenceHandle data =
+        new DirectParserASTContentInvalidTypeReferenceHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleLabel(Token token) {
-    seen("Label", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentLabelHandle data =
+        new DirectParserASTContentLabelHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginLabeledStatement(Token token, int labelCount) {
-    seen("LabeledStatement", DirectParserASTType.BEGIN,
-        {"token": token, "labelCount": labelCount});
+    DirectParserASTContentLabeledStatementBegin data =
+        new DirectParserASTContentLabeledStatementBegin(
+            DirectParserASTType.BEGIN,
+            token: token,
+            labelCount: labelCount);
+    seen(data);
   }
 
   void endLabeledStatement(int labelCount) {
-    seen("LabeledStatement", DirectParserASTType.END,
-        {"labelCount": labelCount});
+    DirectParserASTContentLabeledStatementEnd data =
+        new DirectParserASTContentLabeledStatementEnd(DirectParserASTType.END,
+            labelCount: labelCount);
+    seen(data);
   }
 
   void beginLibraryName(Token token) {
-    seen("LibraryName", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentLibraryNameBegin data =
+        new DirectParserASTContentLibraryNameBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endLibraryName(Token libraryKeyword, Token semicolon) {
-    seen("LibraryName", DirectParserASTType.END,
-        {"libraryKeyword": libraryKeyword, "semicolon": semicolon});
+    DirectParserASTContentLibraryNameEnd data =
+        new DirectParserASTContentLibraryNameEnd(DirectParserASTType.END,
+            libraryKeyword: libraryKeyword, semicolon: semicolon);
+    seen(data);
   }
 
   void handleLiteralMapEntry(Token colon, Token endToken) {
-    seen("LiteralMapEntry", DirectParserASTType.HANDLE,
-        {"colon": colon, "endToken": endToken});
+    DirectParserASTContentLiteralMapEntryHandle data =
+        new DirectParserASTContentLiteralMapEntryHandle(
+            DirectParserASTType.HANDLE,
+            colon: colon,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginLiteralString(Token token) {
-    seen("LiteralString", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentLiteralStringBegin data =
+        new DirectParserASTContentLiteralStringBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void handleInterpolationExpression(Token leftBracket, Token rightBracket) {
-    seen("InterpolationExpression", DirectParserASTType.HANDLE,
-        {"leftBracket": leftBracket, "rightBracket": rightBracket});
+    DirectParserASTContentInterpolationExpressionHandle data =
+        new DirectParserASTContentInterpolationExpressionHandle(
+            DirectParserASTType.HANDLE,
+            leftBracket: leftBracket,
+            rightBracket: rightBracket);
+    seen(data);
   }
 
   void endLiteralString(int interpolationCount, Token endToken) {
-    seen("LiteralString", DirectParserASTType.END,
-        {"interpolationCount": interpolationCount, "endToken": endToken});
+    DirectParserASTContentLiteralStringEnd data =
+        new DirectParserASTContentLiteralStringEnd(DirectParserASTType.END,
+            interpolationCount: interpolationCount, endToken: endToken);
+    seen(data);
   }
 
   void handleStringJuxtaposition(Token startToken, int literalCount) {
-    seen("StringJuxtaposition", DirectParserASTType.HANDLE,
-        {"startToken": startToken, "literalCount": literalCount});
+    DirectParserASTContentStringJuxtapositionHandle data =
+        new DirectParserASTContentStringJuxtapositionHandle(
+            DirectParserASTType.HANDLE,
+            startToken: startToken,
+            literalCount: literalCount);
+    seen(data);
   }
 
   void beginMember() {
-    seen("Member", DirectParserASTType.BEGIN, {});
+    DirectParserASTContentMemberBegin data =
+        new DirectParserASTContentMemberBegin(DirectParserASTType.BEGIN);
+    seen(data);
   }
 
   void handleInvalidMember(Token endToken) {
-    seen("InvalidMember", DirectParserASTType.HANDLE, {"endToken": endToken});
+    DirectParserASTContentInvalidMemberHandle data =
+        new DirectParserASTContentInvalidMemberHandle(
+            DirectParserASTType.HANDLE,
+            endToken: endToken);
+    seen(data);
   }
 
   void endMember() {
-    seen("Member", DirectParserASTType.END, {});
+    DirectParserASTContentMemberEnd data =
+        new DirectParserASTContentMemberEnd(DirectParserASTType.END);
+    seen(data);
   }
 
   void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
       Token varFinalOrConst, Token getOrSet, Token name) {
-    seen("Method", DirectParserASTType.BEGIN, {
-      "externalToken": externalToken,
-      "staticToken": staticToken,
-      "covariantToken": covariantToken,
-      "varFinalOrConst": varFinalOrConst,
-      "getOrSet": getOrSet,
-      "name": name
-    });
+    DirectParserASTContentMethodBegin data =
+        new DirectParserASTContentMethodBegin(DirectParserASTType.BEGIN,
+            externalToken: externalToken,
+            staticToken: staticToken,
+            covariantToken: covariantToken,
+            varFinalOrConst: varFinalOrConst,
+            getOrSet: getOrSet,
+            name: name);
+    seen(data);
   }
 
   void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
-    seen("ClassMethod", DirectParserASTType.END, {
-      "getOrSet": getOrSet,
-      "beginToken": beginToken,
-      "beginParam": beginParam,
-      "beginInitializers": beginInitializers,
-      "endToken": endToken
-    });
+    DirectParserASTContentClassMethodEnd data =
+        new DirectParserASTContentClassMethodEnd(DirectParserASTType.END,
+            getOrSet: getOrSet,
+            beginToken: beginToken,
+            beginParam: beginParam,
+            beginInitializers: beginInitializers,
+            endToken: endToken);
+    seen(data);
   }
 
   void endMixinMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
-    seen("MixinMethod", DirectParserASTType.END, {
-      "getOrSet": getOrSet,
-      "beginToken": beginToken,
-      "beginParam": beginParam,
-      "beginInitializers": beginInitializers,
-      "endToken": endToken
-    });
+    DirectParserASTContentMixinMethodEnd data =
+        new DirectParserASTContentMixinMethodEnd(DirectParserASTType.END,
+            getOrSet: getOrSet,
+            beginToken: beginToken,
+            beginParam: beginParam,
+            beginInitializers: beginInitializers,
+            endToken: endToken);
+    seen(data);
   }
 
   void endExtensionMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
-    seen("ExtensionMethod", DirectParserASTType.END, {
-      "getOrSet": getOrSet,
-      "beginToken": beginToken,
-      "beginParam": beginParam,
-      "beginInitializers": beginInitializers,
-      "endToken": endToken
-    });
+    DirectParserASTContentExtensionMethodEnd data =
+        new DirectParserASTContentExtensionMethodEnd(DirectParserASTType.END,
+            getOrSet: getOrSet,
+            beginToken: beginToken,
+            beginParam: beginParam,
+            beginInitializers: beginInitializers,
+            endToken: endToken);
+    seen(data);
   }
 
   void endClassConstructor(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
-    seen("ClassConstructor", DirectParserASTType.END, {
-      "getOrSet": getOrSet,
-      "beginToken": beginToken,
-      "beginParam": beginParam,
-      "beginInitializers": beginInitializers,
-      "endToken": endToken
-    });
+    DirectParserASTContentClassConstructorEnd data =
+        new DirectParserASTContentClassConstructorEnd(DirectParserASTType.END,
+            getOrSet: getOrSet,
+            beginToken: beginToken,
+            beginParam: beginParam,
+            beginInitializers: beginInitializers,
+            endToken: endToken);
+    seen(data);
   }
 
   void endMixinConstructor(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
-    seen("MixinConstructor", DirectParserASTType.END, {
-      "getOrSet": getOrSet,
-      "beginToken": beginToken,
-      "beginParam": beginParam,
-      "beginInitializers": beginInitializers,
-      "endToken": endToken
-    });
+    DirectParserASTContentMixinConstructorEnd data =
+        new DirectParserASTContentMixinConstructorEnd(DirectParserASTType.END,
+            getOrSet: getOrSet,
+            beginToken: beginToken,
+            beginParam: beginParam,
+            beginInitializers: beginInitializers,
+            endToken: endToken);
+    seen(data);
   }
 
   void endExtensionConstructor(Token getOrSet, Token beginToken,
       Token beginParam, Token beginInitializers, Token endToken) {
-    seen("ExtensionConstructor", DirectParserASTType.END, {
-      "getOrSet": getOrSet,
-      "beginToken": beginToken,
-      "beginParam": beginParam,
-      "beginInitializers": beginInitializers,
-      "endToken": endToken
-    });
+    DirectParserASTContentExtensionConstructorEnd data =
+        new DirectParserASTContentExtensionConstructorEnd(
+            DirectParserASTType.END,
+            getOrSet: getOrSet,
+            beginToken: beginToken,
+            beginParam: beginParam,
+            beginInitializers: beginInitializers,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginMetadataStar(Token token) {
-    seen("MetadataStar", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentMetadataStarBegin data =
+        new DirectParserASTContentMetadataStarBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endMetadataStar(int count) {
-    seen("MetadataStar", DirectParserASTType.END, {"count": count});
+    DirectParserASTContentMetadataStarEnd data =
+        new DirectParserASTContentMetadataStarEnd(DirectParserASTType.END,
+            count: count);
+    seen(data);
   }
 
   void beginMetadata(Token token) {
-    seen("Metadata", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentMetadataBegin data =
+        new DirectParserASTContentMetadataBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
-    seen("Metadata", DirectParserASTType.END, {
-      "beginToken": beginToken,
-      "periodBeforeName": periodBeforeName,
-      "endToken": endToken
-    });
+    DirectParserASTContentMetadataEnd data =
+        new DirectParserASTContentMetadataEnd(DirectParserASTType.END,
+            beginToken: beginToken,
+            periodBeforeName: periodBeforeName,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginOptionalFormalParameters(Token token) {
-    seen("OptionalFormalParameters", DirectParserASTType.BEGIN,
-        {"token": token});
+    DirectParserASTContentOptionalFormalParametersBegin data =
+        new DirectParserASTContentOptionalFormalParametersBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endOptionalFormalParameters(
       int count, Token beginToken, Token endToken) {
-    seen("OptionalFormalParameters", DirectParserASTType.END,
-        {"count": count, "beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentOptionalFormalParametersEnd data =
+        new DirectParserASTContentOptionalFormalParametersEnd(
+            DirectParserASTType.END,
+            count: count,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginPart(Token token) {
-    seen("Part", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentPartBegin data = new DirectParserASTContentPartBegin(
+        DirectParserASTType.BEGIN,
+        token: token);
+    seen(data);
   }
 
   void endPart(Token partKeyword, Token semicolon) {
-    seen("Part", DirectParserASTType.END,
-        {"partKeyword": partKeyword, "semicolon": semicolon});
+    DirectParserASTContentPartEnd data = new DirectParserASTContentPartEnd(
+        DirectParserASTType.END,
+        partKeyword: partKeyword,
+        semicolon: semicolon);
+    seen(data);
   }
 
   void beginPartOf(Token token) {
-    seen("PartOf", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentPartOfBegin data =
+        new DirectParserASTContentPartOfBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endPartOf(
       Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
-    seen("PartOf", DirectParserASTType.END, {
-      "partKeyword": partKeyword,
-      "ofKeyword": ofKeyword,
-      "semicolon": semicolon,
-      "hasName": hasName
-    });
+    DirectParserASTContentPartOfEnd data = new DirectParserASTContentPartOfEnd(
+        DirectParserASTType.END,
+        partKeyword: partKeyword,
+        ofKeyword: ofKeyword,
+        semicolon: semicolon,
+        hasName: hasName);
+    seen(data);
   }
 
   void beginRedirectingFactoryBody(Token token) {
-    seen("RedirectingFactoryBody", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentRedirectingFactoryBodyBegin data =
+        new DirectParserASTContentRedirectingFactoryBodyBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endRedirectingFactoryBody(Token beginToken, Token endToken) {
-    seen("RedirectingFactoryBody", DirectParserASTType.END,
-        {"beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentRedirectingFactoryBodyEnd data =
+        new DirectParserASTContentRedirectingFactoryBodyEnd(
+            DirectParserASTType.END,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginReturnStatement(Token token) {
-    seen("ReturnStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentReturnStatementBegin data =
+        new DirectParserASTContentReturnStatementBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
-    seen("NativeFunctionBody", DirectParserASTType.HANDLE,
-        {"nativeToken": nativeToken, "semicolon": semicolon});
+    DirectParserASTContentNativeFunctionBodyHandle data =
+        new DirectParserASTContentNativeFunctionBodyHandle(
+            DirectParserASTType.HANDLE,
+            nativeToken: nativeToken,
+            semicolon: semicolon);
+    seen(data);
   }
 
   void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
-    seen("NativeFunctionBodyIgnored", DirectParserASTType.HANDLE,
-        {"nativeToken": nativeToken, "semicolon": semicolon});
+    DirectParserASTContentNativeFunctionBodyIgnoredHandle data =
+        new DirectParserASTContentNativeFunctionBodyIgnoredHandle(
+            DirectParserASTType.HANDLE,
+            nativeToken: nativeToken,
+            semicolon: semicolon);
+    seen(data);
   }
 
   void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
-    seen("NativeFunctionBodySkipped", DirectParserASTType.HANDLE,
-        {"nativeToken": nativeToken, "semicolon": semicolon});
+    DirectParserASTContentNativeFunctionBodySkippedHandle data =
+        new DirectParserASTContentNativeFunctionBodySkippedHandle(
+            DirectParserASTType.HANDLE,
+            nativeToken: nativeToken,
+            semicolon: semicolon);
+    seen(data);
   }
 
   void handleEmptyFunctionBody(Token semicolon) {
-    seen("EmptyFunctionBody", DirectParserASTType.HANDLE,
-        {"semicolon": semicolon});
+    DirectParserASTContentEmptyFunctionBodyHandle data =
+        new DirectParserASTContentEmptyFunctionBodyHandle(
+            DirectParserASTType.HANDLE,
+            semicolon: semicolon);
+    seen(data);
   }
 
   void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
-    seen("ExpressionFunctionBody", DirectParserASTType.HANDLE,
-        {"arrowToken": arrowToken, "endToken": endToken});
+    DirectParserASTContentExpressionFunctionBodyHandle data =
+        new DirectParserASTContentExpressionFunctionBodyHandle(
+            DirectParserASTType.HANDLE,
+            arrowToken: arrowToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void endReturnStatement(
       bool hasExpression, Token beginToken, Token endToken) {
-    seen("ReturnStatement", DirectParserASTType.END, {
-      "hasExpression": hasExpression,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentReturnStatementEnd data =
+        new DirectParserASTContentReturnStatementEnd(DirectParserASTType.END,
+            hasExpression: hasExpression,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void handleSend(Token beginToken, Token endToken) {
-    seen("Send", DirectParserASTType.HANDLE,
-        {"beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentSendHandle data =
+        new DirectParserASTContentSendHandle(DirectParserASTType.HANDLE,
+            beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void beginShow(Token showKeyword) {
-    seen("Show", DirectParserASTType.BEGIN, {"showKeyword": showKeyword});
+    DirectParserASTContentShowBegin data = new DirectParserASTContentShowBegin(
+        DirectParserASTType.BEGIN,
+        showKeyword: showKeyword);
+    seen(data);
   }
 
   void endShow(Token showKeyword) {
-    seen("Show", DirectParserASTType.END, {"showKeyword": showKeyword});
+    DirectParserASTContentShowEnd data = new DirectParserASTContentShowEnd(
+        DirectParserASTType.END,
+        showKeyword: showKeyword);
+    seen(data);
   }
 
   void beginSwitchStatement(Token token) {
-    seen("SwitchStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentSwitchStatementBegin data =
+        new DirectParserASTContentSwitchStatementBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endSwitchStatement(Token switchKeyword, Token endToken) {
-    seen("SwitchStatement", DirectParserASTType.END,
-        {"switchKeyword": switchKeyword, "endToken": endToken});
+    DirectParserASTContentSwitchStatementEnd data =
+        new DirectParserASTContentSwitchStatementEnd(DirectParserASTType.END,
+            switchKeyword: switchKeyword, endToken: endToken);
+    seen(data);
   }
 
   void beginSwitchBlock(Token token) {
-    seen("SwitchBlock", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentSwitchBlockBegin data =
+        new DirectParserASTContentSwitchBlockBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
-    seen("SwitchBlock", DirectParserASTType.END, {
-      "caseCount": caseCount,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentSwitchBlockEnd data =
+        new DirectParserASTContentSwitchBlockEnd(DirectParserASTType.END,
+            caseCount: caseCount, beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void beginLiteralSymbol(Token token) {
-    seen("LiteralSymbol", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentLiteralSymbolBegin data =
+        new DirectParserASTContentLiteralSymbolBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endLiteralSymbol(Token hashToken, int identifierCount) {
-    seen("LiteralSymbol", DirectParserASTType.END,
-        {"hashToken": hashToken, "identifierCount": identifierCount});
+    DirectParserASTContentLiteralSymbolEnd data =
+        new DirectParserASTContentLiteralSymbolEnd(DirectParserASTType.END,
+            hashToken: hashToken, identifierCount: identifierCount);
+    seen(data);
   }
 
   void handleThrowExpression(Token throwToken, Token endToken) {
-    seen("ThrowExpression", DirectParserASTType.HANDLE,
-        {"throwToken": throwToken, "endToken": endToken});
+    DirectParserASTContentThrowExpressionHandle data =
+        new DirectParserASTContentThrowExpressionHandle(
+            DirectParserASTType.HANDLE,
+            throwToken: throwToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginRethrowStatement(Token token) {
-    seen("RethrowStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentRethrowStatementBegin data =
+        new DirectParserASTContentRethrowStatementBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endRethrowStatement(Token rethrowToken, Token endToken) {
-    seen("RethrowStatement", DirectParserASTType.END,
-        {"rethrowToken": rethrowToken, "endToken": endToken});
+    DirectParserASTContentRethrowStatementEnd data =
+        new DirectParserASTContentRethrowStatementEnd(DirectParserASTType.END,
+            rethrowToken: rethrowToken, endToken: endToken);
+    seen(data);
   }
 
   void endTopLevelDeclaration(Token nextToken) {
-    seen("TopLevelDeclaration", DirectParserASTType.END,
-        {"nextToken": nextToken});
+    DirectParserASTContentTopLevelDeclarationEnd data =
+        new DirectParserASTContentTopLevelDeclarationEnd(
+            DirectParserASTType.END,
+            nextToken: nextToken);
+    seen(data);
   }
 
   void handleInvalidTopLevelDeclaration(Token endToken) {
-    seen("InvalidTopLevelDeclaration", DirectParserASTType.HANDLE,
-        {"endToken": endToken});
+    DirectParserASTContentInvalidTopLevelDeclarationHandle data =
+        new DirectParserASTContentInvalidTopLevelDeclarationHandle(
+            DirectParserASTType.HANDLE,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginTopLevelMember(Token token) {
-    seen("TopLevelMember", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentTopLevelMemberBegin data =
+        new DirectParserASTContentTopLevelMemberBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void beginFields(Token lastConsumed) {
-    seen("Fields", DirectParserASTType.BEGIN, {"lastConsumed": lastConsumed});
+    DirectParserASTContentFieldsBegin data =
+        new DirectParserASTContentFieldsBegin(DirectParserASTType.BEGIN,
+            lastConsumed: lastConsumed);
+    seen(data);
   }
 
   void endTopLevelFields(
@@ -1115,348 +1643,533 @@
       int count,
       Token beginToken,
       Token endToken) {
-    seen("TopLevelFields", DirectParserASTType.END, {
-      "externalToken": externalToken,
-      "staticToken": staticToken,
-      "covariantToken": covariantToken,
-      "lateToken": lateToken,
-      "varFinalOrConst": varFinalOrConst,
-      "count": count,
-      "beginToken": beginToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentTopLevelFieldsEnd data =
+        new DirectParserASTContentTopLevelFieldsEnd(DirectParserASTType.END,
+            externalToken: externalToken,
+            staticToken: staticToken,
+            covariantToken: covariantToken,
+            lateToken: lateToken,
+            varFinalOrConst: varFinalOrConst,
+            count: count,
+            beginToken: beginToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
-    seen("TopLevelMethod", DirectParserASTType.BEGIN,
-        {"lastConsumed": lastConsumed, "externalToken": externalToken});
+    DirectParserASTContentTopLevelMethodBegin data =
+        new DirectParserASTContentTopLevelMethodBegin(DirectParserASTType.BEGIN,
+            lastConsumed: lastConsumed, externalToken: externalToken);
+    seen(data);
   }
 
   void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
-    seen("TopLevelMethod", DirectParserASTType.END,
-        {"beginToken": beginToken, "getOrSet": getOrSet, "endToken": endToken});
+    DirectParserASTContentTopLevelMethodEnd data =
+        new DirectParserASTContentTopLevelMethodEnd(DirectParserASTType.END,
+            beginToken: beginToken, getOrSet: getOrSet, endToken: endToken);
+    seen(data);
   }
 
   void beginTryStatement(Token token) {
-    seen("TryStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentTryStatementBegin data =
+        new DirectParserASTContentTryStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void handleCaseMatch(Token caseKeyword, Token colon) {
-    seen("CaseMatch", DirectParserASTType.HANDLE,
-        {"caseKeyword": caseKeyword, "colon": colon});
+    DirectParserASTContentCaseMatchHandle data =
+        new DirectParserASTContentCaseMatchHandle(DirectParserASTType.HANDLE,
+            caseKeyword: caseKeyword, colon: colon);
+    seen(data);
   }
 
   void beginCatchClause(Token token) {
-    seen("CatchClause", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentCatchClauseBegin data =
+        new DirectParserASTContentCatchClauseBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endCatchClause(Token token) {
-    seen("CatchClause", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentCatchClauseEnd data =
+        new DirectParserASTContentCatchClauseEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
-    seen("CatchBlock", DirectParserASTType.HANDLE,
-        {"onKeyword": onKeyword, "catchKeyword": catchKeyword, "comma": comma});
+    DirectParserASTContentCatchBlockHandle data =
+        new DirectParserASTContentCatchBlockHandle(DirectParserASTType.HANDLE,
+            onKeyword: onKeyword, catchKeyword: catchKeyword, comma: comma);
+    seen(data);
   }
 
   void handleFinallyBlock(Token finallyKeyword) {
-    seen("FinallyBlock", DirectParserASTType.HANDLE,
-        {"finallyKeyword": finallyKeyword});
+    DirectParserASTContentFinallyBlockHandle data =
+        new DirectParserASTContentFinallyBlockHandle(DirectParserASTType.HANDLE,
+            finallyKeyword: finallyKeyword);
+    seen(data);
   }
 
   void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
-    seen("TryStatement", DirectParserASTType.END, {
-      "catchCount": catchCount,
-      "tryKeyword": tryKeyword,
-      "finallyKeyword": finallyKeyword
-    });
+    DirectParserASTContentTryStatementEnd data =
+        new DirectParserASTContentTryStatementEnd(DirectParserASTType.END,
+            catchCount: catchCount,
+            tryKeyword: tryKeyword,
+            finallyKeyword: finallyKeyword);
+    seen(data);
   }
 
   void handleType(Token beginToken, Token questionMark) {
-    seen("Type", DirectParserASTType.HANDLE,
-        {"beginToken": beginToken, "questionMark": questionMark});
+    DirectParserASTContentTypeHandle data =
+        new DirectParserASTContentTypeHandle(DirectParserASTType.HANDLE,
+            beginToken: beginToken, questionMark: questionMark);
+    seen(data);
   }
 
   void handleNonNullAssertExpression(Token bang) {
-    seen("NonNullAssertExpression", DirectParserASTType.HANDLE, {"bang": bang});
+    DirectParserASTContentNonNullAssertExpressionHandle data =
+        new DirectParserASTContentNonNullAssertExpressionHandle(
+            DirectParserASTType.HANDLE,
+            bang: bang);
+    seen(data);
   }
 
   void handleNoName(Token token) {
-    seen("NoName", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoNameHandle data =
+        new DirectParserASTContentNoNameHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginFunctionType(Token beginToken) {
-    seen("FunctionType", DirectParserASTType.BEGIN, {"beginToken": beginToken});
+    DirectParserASTContentFunctionTypeBegin data =
+        new DirectParserASTContentFunctionTypeBegin(DirectParserASTType.BEGIN,
+            beginToken: beginToken);
+    seen(data);
   }
 
   void endFunctionType(Token functionToken, Token questionMark) {
-    seen("FunctionType", DirectParserASTType.END,
-        {"functionToken": functionToken, "questionMark": questionMark});
+    DirectParserASTContentFunctionTypeEnd data =
+        new DirectParserASTContentFunctionTypeEnd(DirectParserASTType.END,
+            functionToken: functionToken, questionMark: questionMark);
+    seen(data);
   }
 
   void beginTypeArguments(Token token) {
-    seen("TypeArguments", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentTypeArgumentsBegin data =
+        new DirectParserASTContentTypeArgumentsBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endTypeArguments(int count, Token beginToken, Token endToken) {
-    seen("TypeArguments", DirectParserASTType.END,
-        {"count": count, "beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentTypeArgumentsEnd data =
+        new DirectParserASTContentTypeArgumentsEnd(DirectParserASTType.END,
+            count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void handleInvalidTypeArguments(Token token) {
-    seen("InvalidTypeArguments", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentInvalidTypeArgumentsHandle data =
+        new DirectParserASTContentInvalidTypeArgumentsHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleNoTypeArguments(Token token) {
-    seen("NoTypeArguments", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoTypeArgumentsHandle data =
+        new DirectParserASTContentNoTypeArgumentsHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginTypeVariable(Token token) {
-    seen("TypeVariable", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentTypeVariableBegin data =
+        new DirectParserASTContentTypeVariableBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void handleTypeVariablesDefined(Token token, int count) {
-    seen("TypeVariablesDefined", DirectParserASTType.HANDLE,
-        {"token": token, "count": count});
+    DirectParserASTContentTypeVariablesDefinedHandle data =
+        new DirectParserASTContentTypeVariablesDefinedHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            count: count);
+    seen(data);
   }
 
   void endTypeVariable(
       Token token, int index, Token extendsOrSuper, Token variance) {
-    seen("TypeVariable", DirectParserASTType.END, {
-      "token": token,
-      "index": index,
-      "extendsOrSuper": extendsOrSuper,
-      "variance": variance
-    });
+    DirectParserASTContentTypeVariableEnd data =
+        new DirectParserASTContentTypeVariableEnd(DirectParserASTType.END,
+            token: token,
+            index: index,
+            extendsOrSuper: extendsOrSuper,
+            variance: variance);
+    seen(data);
   }
 
   void beginTypeVariables(Token token) {
-    seen("TypeVariables", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentTypeVariablesBegin data =
+        new DirectParserASTContentTypeVariablesBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endTypeVariables(Token beginToken, Token endToken) {
-    seen("TypeVariables", DirectParserASTType.END,
-        {"beginToken": beginToken, "endToken": endToken});
+    DirectParserASTContentTypeVariablesEnd data =
+        new DirectParserASTContentTypeVariablesEnd(DirectParserASTType.END,
+            beginToken: beginToken, endToken: endToken);
+    seen(data);
   }
 
   void beginFunctionExpression(Token token) {
-    seen("FunctionExpression", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentFunctionExpressionBegin data =
+        new DirectParserASTContentFunctionExpressionBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endFunctionExpression(Token beginToken, Token token) {
-    seen("FunctionExpression", DirectParserASTType.END,
-        {"beginToken": beginToken, "token": token});
+    DirectParserASTContentFunctionExpressionEnd data =
+        new DirectParserASTContentFunctionExpressionEnd(DirectParserASTType.END,
+            beginToken: beginToken, token: token);
+    seen(data);
   }
 
   void beginVariablesDeclaration(
       Token token, Token lateToken, Token varFinalOrConst) {
-    seen("VariablesDeclaration", DirectParserASTType.BEGIN, {
-      "token": token,
-      "lateToken": lateToken,
-      "varFinalOrConst": varFinalOrConst
-    });
+    DirectParserASTContentVariablesDeclarationBegin data =
+        new DirectParserASTContentVariablesDeclarationBegin(
+            DirectParserASTType.BEGIN,
+            token: token,
+            lateToken: lateToken,
+            varFinalOrConst: varFinalOrConst);
+    seen(data);
   }
 
   void endVariablesDeclaration(int count, Token endToken) {
-    seen("VariablesDeclaration", DirectParserASTType.END,
-        {"count": count, "endToken": endToken});
+    DirectParserASTContentVariablesDeclarationEnd data =
+        new DirectParserASTContentVariablesDeclarationEnd(
+            DirectParserASTType.END,
+            count: count,
+            endToken: endToken);
+    seen(data);
   }
 
   void beginWhileStatement(Token token) {
-    seen("WhileStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentWhileStatementBegin data =
+        new DirectParserASTContentWhileStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endWhileStatement(Token whileKeyword, Token endToken) {
-    seen("WhileStatement", DirectParserASTType.END,
-        {"whileKeyword": whileKeyword, "endToken": endToken});
+    DirectParserASTContentWhileStatementEnd data =
+        new DirectParserASTContentWhileStatementEnd(DirectParserASTType.END,
+            whileKeyword: whileKeyword, endToken: endToken);
+    seen(data);
   }
 
   void beginAsOperatorType(Token operator) {
-    seen("AsOperatorType", DirectParserASTType.BEGIN, {"operator": operator});
+    DirectParserASTContentAsOperatorTypeBegin data =
+        new DirectParserASTContentAsOperatorTypeBegin(DirectParserASTType.BEGIN,
+            operator: operator);
+    seen(data);
   }
 
   void endAsOperatorType(Token operator) {
-    seen("AsOperatorType", DirectParserASTType.END, {"operator": operator});
+    DirectParserASTContentAsOperatorTypeEnd data =
+        new DirectParserASTContentAsOperatorTypeEnd(DirectParserASTType.END,
+            operator: operator);
+    seen(data);
   }
 
   void handleAsOperator(Token operator) {
-    seen("AsOperator", DirectParserASTType.HANDLE, {"operator": operator});
+    DirectParserASTContentAsOperatorHandle data =
+        new DirectParserASTContentAsOperatorHandle(DirectParserASTType.HANDLE,
+            operator: operator);
+    seen(data);
   }
 
   void handleAssignmentExpression(Token token) {
-    seen("AssignmentExpression", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentAssignmentExpressionHandle data =
+        new DirectParserASTContentAssignmentExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginBinaryExpression(Token token) {
-    seen("BinaryExpression", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentBinaryExpressionBegin data =
+        new DirectParserASTContentBinaryExpressionBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endBinaryExpression(Token token) {
-    seen("BinaryExpression", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentBinaryExpressionEnd data =
+        new DirectParserASTContentBinaryExpressionEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void handleEndingBinaryExpression(Token token) {
-    seen(
-        "EndingBinaryExpression", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentEndingBinaryExpressionHandle data =
+        new DirectParserASTContentEndingBinaryExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginConditionalExpression(Token question) {
-    seen("ConditionalExpression", DirectParserASTType.BEGIN,
-        {"question": question});
+    DirectParserASTContentConditionalExpressionBegin data =
+        new DirectParserASTContentConditionalExpressionBegin(
+            DirectParserASTType.BEGIN,
+            question: question);
+    seen(data);
   }
 
   void handleConditionalExpressionColon() {
-    seen("ConditionalExpressionColon", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentConditionalExpressionColonHandle data =
+        new DirectParserASTContentConditionalExpressionColonHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 
   void endConditionalExpression(Token question, Token colon) {
-    seen("ConditionalExpression", DirectParserASTType.END,
-        {"question": question, "colon": colon});
+    DirectParserASTContentConditionalExpressionEnd data =
+        new DirectParserASTContentConditionalExpressionEnd(
+            DirectParserASTType.END,
+            question: question,
+            colon: colon);
+    seen(data);
   }
 
   void beginConstExpression(Token constKeyword) {
-    seen("ConstExpression", DirectParserASTType.BEGIN,
-        {"constKeyword": constKeyword});
+    DirectParserASTContentConstExpressionBegin data =
+        new DirectParserASTContentConstExpressionBegin(
+            DirectParserASTType.BEGIN,
+            constKeyword: constKeyword);
+    seen(data);
   }
 
   void endConstExpression(Token token) {
-    seen("ConstExpression", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentConstExpressionEnd data =
+        new DirectParserASTContentConstExpressionEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginForControlFlow(Token awaitToken, Token forToken) {
-    seen("ForControlFlow", DirectParserASTType.BEGIN,
-        {"awaitToken": awaitToken, "forToken": forToken});
+    DirectParserASTContentForControlFlowBegin data =
+        new DirectParserASTContentForControlFlowBegin(DirectParserASTType.BEGIN,
+            awaitToken: awaitToken, forToken: forToken);
+    seen(data);
   }
 
   void endForControlFlow(Token token) {
-    seen("ForControlFlow", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentForControlFlowEnd data =
+        new DirectParserASTContentForControlFlowEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void endForInControlFlow(Token token) {
-    seen("ForInControlFlow", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentForInControlFlowEnd data =
+        new DirectParserASTContentForInControlFlowEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void beginIfControlFlow(Token ifToken) {
-    seen("IfControlFlow", DirectParserASTType.BEGIN, {"ifToken": ifToken});
+    DirectParserASTContentIfControlFlowBegin data =
+        new DirectParserASTContentIfControlFlowBegin(DirectParserASTType.BEGIN,
+            ifToken: ifToken);
+    seen(data);
   }
 
   void handleThenControlFlow(Token token) {
-    seen("ThenControlFlow", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentThenControlFlowHandle data =
+        new DirectParserASTContentThenControlFlowHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleElseControlFlow(Token elseToken) {
-    seen("ElseControlFlow", DirectParserASTType.HANDLE,
-        {"elseToken": elseToken});
+    DirectParserASTContentElseControlFlowHandle data =
+        new DirectParserASTContentElseControlFlowHandle(
+            DirectParserASTType.HANDLE,
+            elseToken: elseToken);
+    seen(data);
   }
 
   void endIfControlFlow(Token token) {
-    seen("IfControlFlow", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentIfControlFlowEnd data =
+        new DirectParserASTContentIfControlFlowEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void endIfElseControlFlow(Token token) {
-    seen("IfElseControlFlow", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentIfElseControlFlowEnd data =
+        new DirectParserASTContentIfElseControlFlowEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void handleSpreadExpression(Token spreadToken) {
-    seen("SpreadExpression", DirectParserASTType.HANDLE,
-        {"spreadToken": spreadToken});
+    DirectParserASTContentSpreadExpressionHandle data =
+        new DirectParserASTContentSpreadExpressionHandle(
+            DirectParserASTType.HANDLE,
+            spreadToken: spreadToken);
+    seen(data);
   }
 
   void beginFunctionTypedFormalParameter(Token token) {
-    seen("FunctionTypedFormalParameter", DirectParserASTType.BEGIN,
-        {"token": token});
+    DirectParserASTContentFunctionTypedFormalParameterBegin data =
+        new DirectParserASTContentFunctionTypedFormalParameterBegin(
+            DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endFunctionTypedFormalParameter(Token nameToken, Token question) {
-    seen("FunctionTypedFormalParameter", DirectParserASTType.END,
-        {"nameToken": nameToken, "question": question});
+    DirectParserASTContentFunctionTypedFormalParameterEnd data =
+        new DirectParserASTContentFunctionTypedFormalParameterEnd(
+            DirectParserASTType.END,
+            nameToken: nameToken,
+            question: question);
+    seen(data);
   }
 
   void handleIdentifier(Token token, IdentifierContext context) {
-    seen("Identifier", DirectParserASTType.HANDLE,
-        {"token": token, "context": context});
+    DirectParserASTContentIdentifierHandle data =
+        new DirectParserASTContentIdentifierHandle(DirectParserASTType.HANDLE,
+            token: token, context: context);
+    seen(data);
   }
 
   void handleIndexedExpression(
       Token question, Token openSquareBracket, Token closeSquareBracket) {
-    seen("IndexedExpression", DirectParserASTType.HANDLE, {
-      "question": question,
-      "openSquareBracket": openSquareBracket,
-      "closeSquareBracket": closeSquareBracket
-    });
+    DirectParserASTContentIndexedExpressionHandle data =
+        new DirectParserASTContentIndexedExpressionHandle(
+            DirectParserASTType.HANDLE,
+            question: question,
+            openSquareBracket: openSquareBracket,
+            closeSquareBracket: closeSquareBracket);
+    seen(data);
   }
 
   void beginIsOperatorType(Token operator) {
-    seen("IsOperatorType", DirectParserASTType.BEGIN, {"operator": operator});
+    DirectParserASTContentIsOperatorTypeBegin data =
+        new DirectParserASTContentIsOperatorTypeBegin(DirectParserASTType.BEGIN,
+            operator: operator);
+    seen(data);
   }
 
   void endIsOperatorType(Token operator) {
-    seen("IsOperatorType", DirectParserASTType.END, {"operator": operator});
+    DirectParserASTContentIsOperatorTypeEnd data =
+        new DirectParserASTContentIsOperatorTypeEnd(DirectParserASTType.END,
+            operator: operator);
+    seen(data);
   }
 
   void handleIsOperator(Token isOperator, Token not) {
-    seen("IsOperator", DirectParserASTType.HANDLE,
-        {"isOperator": isOperator, "not": not});
+    DirectParserASTContentIsOperatorHandle data =
+        new DirectParserASTContentIsOperatorHandle(DirectParserASTType.HANDLE,
+            isOperator: isOperator, not: not);
+    seen(data);
   }
 
   void handleLiteralBool(Token token) {
-    seen("LiteralBool", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentLiteralBoolHandle data =
+        new DirectParserASTContentLiteralBoolHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleBreakStatement(
       bool hasTarget, Token breakKeyword, Token endToken) {
-    seen("BreakStatement", DirectParserASTType.HANDLE, {
-      "hasTarget": hasTarget,
-      "breakKeyword": breakKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentBreakStatementHandle data =
+        new DirectParserASTContentBreakStatementHandle(
+            DirectParserASTType.HANDLE,
+            hasTarget: hasTarget,
+            breakKeyword: breakKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void handleContinueStatement(
       bool hasTarget, Token continueKeyword, Token endToken) {
-    seen("ContinueStatement", DirectParserASTType.HANDLE, {
-      "hasTarget": hasTarget,
-      "continueKeyword": continueKeyword,
-      "endToken": endToken
-    });
+    DirectParserASTContentContinueStatementHandle data =
+        new DirectParserASTContentContinueStatementHandle(
+            DirectParserASTType.HANDLE,
+            hasTarget: hasTarget,
+            continueKeyword: continueKeyword,
+            endToken: endToken);
+    seen(data);
   }
 
   void handleEmptyStatement(Token token) {
-    seen("EmptyStatement", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentEmptyStatementHandle data =
+        new DirectParserASTContentEmptyStatementHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginAssert(Token assertKeyword, Assert kind) {
-    seen("Assert", DirectParserASTType.BEGIN,
-        {"assertKeyword": assertKeyword, "kind": kind});
+    DirectParserASTContentAssertBegin data =
+        new DirectParserASTContentAssertBegin(DirectParserASTType.BEGIN,
+            assertKeyword: assertKeyword, kind: kind);
+    seen(data);
   }
 
   void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
       Token commaToken, Token semicolonToken) {
-    seen("Assert", DirectParserASTType.END, {
-      "assertKeyword": assertKeyword,
-      "kind": kind,
-      "leftParenthesis": leftParenthesis,
-      "commaToken": commaToken,
-      "semicolonToken": semicolonToken
-    });
+    DirectParserASTContentAssertEnd data = new DirectParserASTContentAssertEnd(
+        DirectParserASTType.END,
+        assertKeyword: assertKeyword,
+        kind: kind,
+        leftParenthesis: leftParenthesis,
+        commaToken: commaToken,
+        semicolonToken: semicolonToken);
+    seen(data);
   }
 
   void handleLiteralDouble(Token token) {
-    seen("LiteralDouble", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentLiteralDoubleHandle data =
+        new DirectParserASTContentLiteralDoubleHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleLiteralInt(Token token) {
-    seen("LiteralInt", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentLiteralIntHandle data =
+        new DirectParserASTContentLiteralIntHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleLiteralList(
       int count, Token leftBracket, Token constKeyword, Token rightBracket) {
-    seen("LiteralList", DirectParserASTType.HANDLE, {
-      "count": count,
-      "leftBracket": leftBracket,
-      "constKeyword": constKeyword,
-      "rightBracket": rightBracket
-    });
+    DirectParserASTContentLiteralListHandle data =
+        new DirectParserASTContentLiteralListHandle(DirectParserASTType.HANDLE,
+            count: count,
+            leftBracket: leftBracket,
+            constKeyword: constKeyword,
+            rightBracket: rightBracket);
+    seen(data);
   }
 
   void handleLiteralSetOrMap(
@@ -1466,100 +2179,160 @@
     Token rightBrace,
     bool hasSetEntry,
   ) {
-    seen("LiteralSetOrMap", DirectParserASTType.HANDLE, {
-      "count": count,
-      "leftBrace": leftBrace,
-      "constKeyword": constKeyword,
-      "rightBrace": rightBrace,
-      "hasSetEntry": hasSetEntry
-    });
+    DirectParserASTContentLiteralSetOrMapHandle data =
+        new DirectParserASTContentLiteralSetOrMapHandle(
+            DirectParserASTType.HANDLE,
+            count: count,
+            leftBrace: leftBrace,
+            constKeyword: constKeyword,
+            rightBrace: rightBrace,
+            hasSetEntry: hasSetEntry);
+    seen(data);
   }
 
   void handleLiteralNull(Token token) {
-    seen("LiteralNull", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentLiteralNullHandle data =
+        new DirectParserASTContentLiteralNullHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleNativeClause(Token nativeToken, bool hasName) {
-    seen("NativeClause", DirectParserASTType.HANDLE,
-        {"nativeToken": nativeToken, "hasName": hasName});
+    DirectParserASTContentNativeClauseHandle data =
+        new DirectParserASTContentNativeClauseHandle(DirectParserASTType.HANDLE,
+            nativeToken: nativeToken, hasName: hasName);
+    seen(data);
   }
 
   void handleNamedArgument(Token colon) {
-    seen("NamedArgument", DirectParserASTType.HANDLE, {"colon": colon});
+    DirectParserASTContentNamedArgumentHandle data =
+        new DirectParserASTContentNamedArgumentHandle(
+            DirectParserASTType.HANDLE,
+            colon: colon);
+    seen(data);
   }
 
   void beginNewExpression(Token token) {
-    seen("NewExpression", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentNewExpressionBegin data =
+        new DirectParserASTContentNewExpressionBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endNewExpression(Token token) {
-    seen("NewExpression", DirectParserASTType.END, {"token": token});
+    DirectParserASTContentNewExpressionEnd data =
+        new DirectParserASTContentNewExpressionEnd(DirectParserASTType.END,
+            token: token);
+    seen(data);
   }
 
   void handleNoArguments(Token token) {
-    seen("NoArguments", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoArgumentsHandle data =
+        new DirectParserASTContentNoArgumentsHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
-    seen("NoConstructorReferenceContinuationAfterTypeArguments",
-        DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle
+        data =
+        new DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleNoType(Token lastConsumed) {
-    seen("NoType", DirectParserASTType.HANDLE, {"lastConsumed": lastConsumed});
+    DirectParserASTContentNoTypeHandle data =
+        new DirectParserASTContentNoTypeHandle(DirectParserASTType.HANDLE,
+            lastConsumed: lastConsumed);
+    seen(data);
   }
 
   void handleNoTypeVariables(Token token) {
-    seen("NoTypeVariables", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentNoTypeVariablesHandle data =
+        new DirectParserASTContentNoTypeVariablesHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleOperator(Token token) {
-    seen("Operator", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentOperatorHandle data =
+        new DirectParserASTContentOperatorHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleSymbolVoid(Token token) {
-    seen("SymbolVoid", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentSymbolVoidHandle data =
+        new DirectParserASTContentSymbolVoidHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleOperatorName(Token operatorKeyword, Token token) {
-    seen("OperatorName", DirectParserASTType.HANDLE,
-        {"operatorKeyword": operatorKeyword, "token": token});
+    DirectParserASTContentOperatorNameHandle data =
+        new DirectParserASTContentOperatorNameHandle(DirectParserASTType.HANDLE,
+            operatorKeyword: operatorKeyword, token: token);
+    seen(data);
   }
 
   void handleInvalidOperatorName(Token operatorKeyword, Token token) {
-    seen("InvalidOperatorName", DirectParserASTType.HANDLE,
-        {"operatorKeyword": operatorKeyword, "token": token});
+    DirectParserASTContentInvalidOperatorNameHandle data =
+        new DirectParserASTContentInvalidOperatorNameHandle(
+            DirectParserASTType.HANDLE,
+            operatorKeyword: operatorKeyword,
+            token: token);
+    seen(data);
   }
 
   void handleParenthesizedCondition(Token token) {
-    seen(
-        "ParenthesizedCondition", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentParenthesizedConditionHandle data =
+        new DirectParserASTContentParenthesizedConditionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleParenthesizedExpression(Token token) {
-    seen("ParenthesizedExpression", DirectParserASTType.HANDLE,
-        {"token": token});
+    DirectParserASTContentParenthesizedExpressionHandle data =
+        new DirectParserASTContentParenthesizedExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleQualified(Token period) {
-    seen("Qualified", DirectParserASTType.HANDLE, {"period": period});
+    DirectParserASTContentQualifiedHandle data =
+        new DirectParserASTContentQualifiedHandle(DirectParserASTType.HANDLE,
+            period: period);
+    seen(data);
   }
 
   void handleStringPart(Token token) {
-    seen("StringPart", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentStringPartHandle data =
+        new DirectParserASTContentStringPartHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleSuperExpression(Token token, IdentifierContext context) {
-    seen("SuperExpression", DirectParserASTType.HANDLE,
-        {"token": token, "context": context});
+    DirectParserASTContentSuperExpressionHandle data =
+        new DirectParserASTContentSuperExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            context: context);
+    seen(data);
   }
 
   void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
-    seen("SwitchCase", DirectParserASTType.BEGIN, {
-      "labelCount": labelCount,
-      "expressionCount": expressionCount,
-      "firstToken": firstToken
-    });
+    DirectParserASTContentSwitchCaseBegin data =
+        new DirectParserASTContentSwitchCaseBegin(DirectParserASTType.BEGIN,
+            labelCount: labelCount,
+            expressionCount: expressionCount,
+            firstToken: firstToken);
+    seen(data);
   }
 
   void endSwitchCase(
@@ -1570,133 +2343,4409 @@
       int statementCount,
       Token firstToken,
       Token endToken) {
-    seen("SwitchCase", DirectParserASTType.END, {
-      "labelCount": labelCount,
-      "expressionCount": expressionCount,
-      "defaultKeyword": defaultKeyword,
-      "colonAfterDefault": colonAfterDefault,
-      "statementCount": statementCount,
-      "firstToken": firstToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentSwitchCaseEnd data =
+        new DirectParserASTContentSwitchCaseEnd(DirectParserASTType.END,
+            labelCount: labelCount,
+            expressionCount: expressionCount,
+            defaultKeyword: defaultKeyword,
+            colonAfterDefault: colonAfterDefault,
+            statementCount: statementCount,
+            firstToken: firstToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void handleThisExpression(Token token, IdentifierContext context) {
-    seen("ThisExpression", DirectParserASTType.HANDLE,
-        {"token": token, "context": context});
+    DirectParserASTContentThisExpressionHandle data =
+        new DirectParserASTContentThisExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            context: context);
+    seen(data);
   }
 
   void handleUnaryPostfixAssignmentExpression(Token token) {
-    seen("UnaryPostfixAssignmentExpression", DirectParserASTType.HANDLE,
-        {"token": token});
+    DirectParserASTContentUnaryPostfixAssignmentExpressionHandle data =
+        new DirectParserASTContentUnaryPostfixAssignmentExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleUnaryPrefixExpression(Token token) {
-    seen("UnaryPrefixExpression", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentUnaryPrefixExpressionHandle data =
+        new DirectParserASTContentUnaryPrefixExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleUnaryPrefixAssignmentExpression(Token token) {
-    seen("UnaryPrefixAssignmentExpression", DirectParserASTType.HANDLE,
-        {"token": token});
+    DirectParserASTContentUnaryPrefixAssignmentExpressionHandle data =
+        new DirectParserASTContentUnaryPrefixAssignmentExpressionHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginFormalParameterDefaultValueExpression() {
-    seen(
-        "FormalParameterDefaultValueExpression", DirectParserASTType.BEGIN, {});
+    DirectParserASTContentFormalParameterDefaultValueExpressionBegin data =
+        new DirectParserASTContentFormalParameterDefaultValueExpressionBegin(
+            DirectParserASTType.BEGIN);
+    seen(data);
   }
 
   void endFormalParameterDefaultValueExpression() {
-    seen("FormalParameterDefaultValueExpression", DirectParserASTType.END, {});
+    DirectParserASTContentFormalParameterDefaultValueExpressionEnd data =
+        new DirectParserASTContentFormalParameterDefaultValueExpressionEnd(
+            DirectParserASTType.END);
+    seen(data);
   }
 
   void handleValuedFormalParameter(Token equals, Token token) {
-    seen("ValuedFormalParameter", DirectParserASTType.HANDLE,
-        {"equals": equals, "token": token});
+    DirectParserASTContentValuedFormalParameterHandle data =
+        new DirectParserASTContentValuedFormalParameterHandle(
+            DirectParserASTType.HANDLE,
+            equals: equals,
+            token: token);
+    seen(data);
   }
 
   void handleFormalParameterWithoutValue(Token token) {
-    seen("FormalParameterWithoutValue", DirectParserASTType.HANDLE,
-        {"token": token});
+    DirectParserASTContentFormalParameterWithoutValueHandle data =
+        new DirectParserASTContentFormalParameterWithoutValueHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleVoidKeyword(Token token) {
-    seen("VoidKeyword", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentVoidKeywordHandle data =
+        new DirectParserASTContentVoidKeywordHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleVoidKeywordWithTypeArguments(Token token) {
-    seen("VoidKeywordWithTypeArguments", DirectParserASTType.HANDLE,
-        {"token": token});
+    DirectParserASTContentVoidKeywordWithTypeArgumentsHandle data =
+        new DirectParserASTContentVoidKeywordWithTypeArgumentsHandle(
+            DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void beginYieldStatement(Token token) {
-    seen("YieldStatement", DirectParserASTType.BEGIN, {"token": token});
+    DirectParserASTContentYieldStatementBegin data =
+        new DirectParserASTContentYieldStatementBegin(DirectParserASTType.BEGIN,
+            token: token);
+    seen(data);
   }
 
   void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
-    seen("YieldStatement", DirectParserASTType.END, {
-      "yieldToken": yieldToken,
-      "starToken": starToken,
-      "endToken": endToken
-    });
+    DirectParserASTContentYieldStatementEnd data =
+        new DirectParserASTContentYieldStatementEnd(DirectParserASTType.END,
+            yieldToken: yieldToken, starToken: starToken, endToken: endToken);
+    seen(data);
   }
 
   void endInvalidYieldStatement(Token beginToken, Token starToken,
       Token endToken, MessageCode errorCode) {
-    seen("InvalidYieldStatement", DirectParserASTType.END, {
-      "beginToken": beginToken,
-      "starToken": starToken,
-      "endToken": endToken,
-      "errorCode": errorCode
-    });
+    DirectParserASTContentInvalidYieldStatementEnd data =
+        new DirectParserASTContentInvalidYieldStatementEnd(
+            DirectParserASTType.END,
+            beginToken: beginToken,
+            starToken: starToken,
+            endToken: endToken,
+            errorCode: errorCode);
+    seen(data);
   }
 
   void handleRecoverableError(
       Message message, Token startToken, Token endToken) {
-    seen("RecoverableError", DirectParserASTType.HANDLE,
-        {"message": message, "startToken": startToken, "endToken": endToken});
+    DirectParserASTContentRecoverableErrorHandle data =
+        new DirectParserASTContentRecoverableErrorHandle(
+            DirectParserASTType.HANDLE,
+            message: message,
+            startToken: startToken,
+            endToken: endToken);
+    seen(data);
   }
 
   void handleErrorToken(ErrorToken token) {
-    seen("ErrorToken", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentErrorTokenHandle data =
+        new DirectParserASTContentErrorTokenHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleUnescapeError(
       Message message, Token location, int stringOffset, int length) {
-    seen("UnescapeError", DirectParserASTType.HANDLE, {
-      "message": message,
-      "location": location,
-      "stringOffset": stringOffset,
-      "length": length
-    });
+    DirectParserASTContentUnescapeErrorHandle data =
+        new DirectParserASTContentUnescapeErrorHandle(
+            DirectParserASTType.HANDLE,
+            message: message,
+            location: location,
+            stringOffset: stringOffset,
+            length: length);
+    seen(data);
   }
 
   void handleInvalidStatement(Token token, Message message) {
-    seen("InvalidStatement", DirectParserASTType.HANDLE,
-        {"token": token, "message": message});
+    DirectParserASTContentInvalidStatementHandle data =
+        new DirectParserASTContentInvalidStatementHandle(
+            DirectParserASTType.HANDLE,
+            token: token,
+            message: message);
+    seen(data);
   }
 
   void handleScript(Token token) {
-    seen("Script", DirectParserASTType.HANDLE, {"token": token});
+    DirectParserASTContentScriptHandle data =
+        new DirectParserASTContentScriptHandle(DirectParserASTType.HANDLE,
+            token: token);
+    seen(data);
   }
 
   void handleCommentReferenceText(String referenceSource, int referenceOffset) {
-    seen("CommentReferenceText", DirectParserASTType.HANDLE, {
-      "referenceSource": referenceSource,
-      "referenceOffset": referenceOffset
-    });
+    DirectParserASTContentCommentReferenceTextHandle data =
+        new DirectParserASTContentCommentReferenceTextHandle(
+            DirectParserASTType.HANDLE,
+            referenceSource: referenceSource,
+            referenceOffset: referenceOffset);
+    seen(data);
   }
 
   void handleCommentReference(
       Token newKeyword, Token prefix, Token period, Token token) {
-    seen("CommentReference", DirectParserASTType.HANDLE, {
-      "newKeyword": newKeyword,
-      "prefix": prefix,
-      "period": period,
-      "token": token
-    });
+    DirectParserASTContentCommentReferenceHandle data =
+        new DirectParserASTContentCommentReferenceHandle(
+            DirectParserASTType.HANDLE,
+            newKeyword: newKeyword,
+            prefix: prefix,
+            period: period,
+            token: token);
+    seen(data);
   }
 
   void handleNoCommentReference() {
-    seen("NoCommentReference", DirectParserASTType.HANDLE, {});
+    DirectParserASTContentNoCommentReferenceHandle data =
+        new DirectParserASTContentNoCommentReferenceHandle(
+            DirectParserASTType.HANDLE);
+    seen(data);
   }
 }
+
+class DirectParserASTContentArgumentsBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentArgumentsBegin(DirectParserASTType type, {this.token})
+      : super("Arguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentArgumentsEnd extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentArgumentsEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken})
+      : super("Arguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentAsyncModifierHandle extends DirectParserASTContent {
+  final Token asyncToken;
+  final Token starToken;
+
+  DirectParserASTContentAsyncModifierHandle(DirectParserASTType type,
+      {this.asyncToken, this.starToken})
+      : super("AsyncModifier", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "asyncToken": asyncToken,
+        "starToken": starToken,
+      };
+}
+
+class DirectParserASTContentAwaitExpressionBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentAwaitExpressionBegin(DirectParserASTType type,
+      {this.token})
+      : super("AwaitExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentAwaitExpressionEnd extends DirectParserASTContent {
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentAwaitExpressionEnd(DirectParserASTType type,
+      {this.beginToken, this.endToken})
+      : super("AwaitExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentInvalidAwaitExpressionEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token endToken;
+  final MessageCode errorCode;
+
+  DirectParserASTContentInvalidAwaitExpressionEnd(DirectParserASTType type,
+      {this.beginToken, this.endToken, this.errorCode})
+      : super("InvalidAwaitExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+        "errorCode": errorCode,
+      };
+}
+
+class DirectParserASTContentBlockBegin extends DirectParserASTContent {
+  final Token token;
+  final BlockKind blockKind;
+
+  DirectParserASTContentBlockBegin(DirectParserASTType type,
+      {this.token, this.blockKind})
+      : super("Block", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "blockKind": blockKind,
+      };
+}
+
+class DirectParserASTContentBlockEnd extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+  final BlockKind blockKind;
+
+  DirectParserASTContentBlockEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken, this.blockKind})
+      : super("Block", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+        "blockKind": blockKind,
+      };
+}
+
+class DirectParserASTContentInvalidTopLevelBlockHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInvalidTopLevelBlockHandle(DirectParserASTType type,
+      {this.token})
+      : super("InvalidTopLevelBlock", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCascadeBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentCascadeBegin(DirectParserASTType type, {this.token})
+      : super("Cascade", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCascadeEnd extends DirectParserASTContent {
+  DirectParserASTContentCascadeEnd(DirectParserASTType type)
+      : super("Cascade", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentCaseExpressionBegin extends DirectParserASTContent {
+  final Token caseKeyword;
+
+  DirectParserASTContentCaseExpressionBegin(DirectParserASTType type,
+      {this.caseKeyword})
+      : super("CaseExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "caseKeyword": caseKeyword,
+      };
+}
+
+class DirectParserASTContentCaseExpressionEnd extends DirectParserASTContent {
+  final Token colon;
+
+  DirectParserASTContentCaseExpressionEnd(DirectParserASTType type,
+      {this.colon})
+      : super("CaseExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "colon": colon,
+      };
+}
+
+class DirectParserASTContentClassOrMixinBodyBegin
+    extends DirectParserASTContent {
+  final DeclarationKind kind;
+  final Token token;
+
+  DirectParserASTContentClassOrMixinBodyBegin(DirectParserASTType type,
+      {this.kind, this.token})
+      : super("ClassOrMixinBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "kind": kind,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentClassOrMixinBodyEnd extends DirectParserASTContent {
+  final DeclarationKind kind;
+  final int memberCount;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentClassOrMixinBodyEnd(DirectParserASTType type,
+      {this.kind, this.memberCount, this.beginToken, this.endToken})
+      : super("ClassOrMixinBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "kind": kind,
+        "memberCount": memberCount,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin(
+      DirectParserASTType type,
+      {this.token})
+      : super("ClassOrNamedMixinApplicationPrelude", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentClassDeclarationBegin
+    extends DirectParserASTContent {
+  final Token begin;
+  final Token abstractToken;
+  final Token name;
+
+  DirectParserASTContentClassDeclarationBegin(DirectParserASTType type,
+      {this.begin, this.abstractToken, this.name})
+      : super("ClassDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "begin": begin,
+        "abstractToken": abstractToken,
+        "name": name,
+      };
+}
+
+class DirectParserASTContentClassExtendsHandle extends DirectParserASTContent {
+  final Token extendsKeyword;
+  final int typeCount;
+
+  DirectParserASTContentClassExtendsHandle(DirectParserASTType type,
+      {this.extendsKeyword, this.typeCount})
+      : super("ClassExtends", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "extendsKeyword": extendsKeyword,
+        "typeCount": typeCount,
+      };
+}
+
+class DirectParserASTContentClassOrMixinImplementsHandle
+    extends DirectParserASTContent {
+  final Token implementsKeyword;
+  final int interfacesCount;
+
+  DirectParserASTContentClassOrMixinImplementsHandle(DirectParserASTType type,
+      {this.implementsKeyword, this.interfacesCount})
+      : super("ClassOrMixinImplements", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "implementsKeyword": implementsKeyword,
+        "interfacesCount": interfacesCount,
+      };
+}
+
+class DirectParserASTContentClassHeaderHandle extends DirectParserASTContent {
+  final Token begin;
+  final Token classKeyword;
+  final Token nativeToken;
+
+  DirectParserASTContentClassHeaderHandle(DirectParserASTType type,
+      {this.begin, this.classKeyword, this.nativeToken})
+      : super("ClassHeader", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "begin": begin,
+        "classKeyword": classKeyword,
+        "nativeToken": nativeToken,
+      };
+}
+
+class DirectParserASTContentRecoverClassHeaderHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentRecoverClassHeaderHandle(DirectParserASTType type)
+      : super("RecoverClassHeader", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentClassDeclarationEnd extends DirectParserASTContent {
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentClassDeclarationEnd(DirectParserASTType type,
+      {this.beginToken, this.endToken})
+      : super("ClassDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMixinDeclarationBegin
+    extends DirectParserASTContent {
+  final Token mixinKeyword;
+  final Token name;
+
+  DirectParserASTContentMixinDeclarationBegin(DirectParserASTType type,
+      {this.mixinKeyword, this.name})
+      : super("MixinDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "mixinKeyword": mixinKeyword,
+        "name": name,
+      };
+}
+
+class DirectParserASTContentMixinOnHandle extends DirectParserASTContent {
+  final Token onKeyword;
+  final int typeCount;
+
+  DirectParserASTContentMixinOnHandle(DirectParserASTType type,
+      {this.onKeyword, this.typeCount})
+      : super("MixinOn", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "onKeyword": onKeyword,
+        "typeCount": typeCount,
+      };
+}
+
+class DirectParserASTContentMixinHeaderHandle extends DirectParserASTContent {
+  final Token mixinKeyword;
+
+  DirectParserASTContentMixinHeaderHandle(DirectParserASTType type,
+      {this.mixinKeyword})
+      : super("MixinHeader", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "mixinKeyword": mixinKeyword,
+      };
+}
+
+class DirectParserASTContentRecoverMixinHeaderHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentRecoverMixinHeaderHandle(DirectParserASTType type)
+      : super("RecoverMixinHeader", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentMixinDeclarationEnd extends DirectParserASTContent {
+  final Token mixinKeyword;
+  final Token endToken;
+
+  DirectParserASTContentMixinDeclarationEnd(DirectParserASTType type,
+      {this.mixinKeyword, this.endToken})
+      : super("MixinDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "mixinKeyword": mixinKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentUncategorizedTopLevelDeclarationBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentUncategorizedTopLevelDeclarationBegin(
+      DirectParserASTType type,
+      {this.token})
+      : super("UncategorizedTopLevelDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentExtensionDeclarationPreludeBegin
+    extends DirectParserASTContent {
+  final Token extensionKeyword;
+
+  DirectParserASTContentExtensionDeclarationPreludeBegin(
+      DirectParserASTType type,
+      {this.extensionKeyword})
+      : super("ExtensionDeclarationPrelude", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "extensionKeyword": extensionKeyword,
+      };
+}
+
+class DirectParserASTContentExtensionDeclarationBegin
+    extends DirectParserASTContent {
+  final Token extensionKeyword;
+  final Token name;
+
+  DirectParserASTContentExtensionDeclarationBegin(DirectParserASTType type,
+      {this.extensionKeyword, this.name})
+      : super("ExtensionDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "extensionKeyword": extensionKeyword,
+        "name": name,
+      };
+}
+
+class DirectParserASTContentExtensionDeclarationEnd
+    extends DirectParserASTContent {
+  final Token extensionKeyword;
+  final Token onKeyword;
+  final Token endToken;
+
+  DirectParserASTContentExtensionDeclarationEnd(DirectParserASTType type,
+      {this.extensionKeyword, this.onKeyword, this.endToken})
+      : super("ExtensionDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "extensionKeyword": extensionKeyword,
+        "onKeyword": onKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentCombinatorsBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentCombinatorsBegin(DirectParserASTType type, {this.token})
+      : super("Combinators", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCombinatorsEnd extends DirectParserASTContent {
+  final int count;
+
+  DirectParserASTContentCombinatorsEnd(DirectParserASTType type, {this.count})
+      : super("Combinators", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class DirectParserASTContentCompilationUnitBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentCompilationUnitBegin(DirectParserASTType type,
+      {this.token})
+      : super("CompilationUnit", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentDirectivesOnlyHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentDirectivesOnlyHandle(DirectParserASTType type)
+      : super("DirectivesOnly", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentCompilationUnitEnd extends DirectParserASTContent {
+  final int count;
+  final Token token;
+
+  DirectParserASTContentCompilationUnitEnd(DirectParserASTType type,
+      {this.count, this.token})
+      : super("CompilationUnit", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentConstLiteralBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentConstLiteralBegin(DirectParserASTType type,
+      {this.token})
+      : super("ConstLiteral", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentConstLiteralEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentConstLiteralEnd(DirectParserASTType type, {this.token})
+      : super("ConstLiteral", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentConstructorReferenceBegin
+    extends DirectParserASTContent {
+  final Token start;
+
+  DirectParserASTContentConstructorReferenceBegin(DirectParserASTType type,
+      {this.start})
+      : super("ConstructorReference", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "start": start,
+      };
+}
+
+class DirectParserASTContentConstructorReferenceEnd
+    extends DirectParserASTContent {
+  final Token start;
+  final Token periodBeforeName;
+  final Token endToken;
+
+  DirectParserASTContentConstructorReferenceEnd(DirectParserASTType type,
+      {this.start, this.periodBeforeName, this.endToken})
+      : super("ConstructorReference", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "start": start,
+        "periodBeforeName": periodBeforeName,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentDoWhileStatementBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentDoWhileStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("DoWhileStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentDoWhileStatementEnd extends DirectParserASTContent {
+  final Token doKeyword;
+  final Token whileKeyword;
+  final Token endToken;
+
+  DirectParserASTContentDoWhileStatementEnd(DirectParserASTType type,
+      {this.doKeyword, this.whileKeyword, this.endToken})
+      : super("DoWhileStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "doKeyword": doKeyword,
+        "whileKeyword": whileKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentDoWhileStatementBodyBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentDoWhileStatementBodyBegin(DirectParserASTType type,
+      {this.token})
+      : super("DoWhileStatementBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentDoWhileStatementBodyEnd
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentDoWhileStatementBodyEnd(DirectParserASTType type,
+      {this.token})
+      : super("DoWhileStatementBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentWhileStatementBodyBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentWhileStatementBodyBegin(DirectParserASTType type,
+      {this.token})
+      : super("WhileStatementBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentWhileStatementBodyEnd
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentWhileStatementBodyEnd(DirectParserASTType type,
+      {this.token})
+      : super("WhileStatementBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentEnumBegin extends DirectParserASTContent {
+  final Token enumKeyword;
+
+  DirectParserASTContentEnumBegin(DirectParserASTType type, {this.enumKeyword})
+      : super("Enum", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "enumKeyword": enumKeyword,
+      };
+}
+
+class DirectParserASTContentEnumEnd extends DirectParserASTContent {
+  final Token enumKeyword;
+  final Token leftBrace;
+  final int count;
+
+  DirectParserASTContentEnumEnd(DirectParserASTType type,
+      {this.enumKeyword, this.leftBrace, this.count})
+      : super("Enum", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "enumKeyword": enumKeyword,
+        "leftBrace": leftBrace,
+        "count": count,
+      };
+}
+
+class DirectParserASTContentExportBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentExportBegin(DirectParserASTType type, {this.token})
+      : super("Export", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentExportEnd extends DirectParserASTContent {
+  final Token exportKeyword;
+  final Token semicolon;
+
+  DirectParserASTContentExportEnd(DirectParserASTType type,
+      {this.exportKeyword, this.semicolon})
+      : super("Export", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "exportKeyword": exportKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentExtraneousExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final Message message;
+
+  DirectParserASTContentExtraneousExpressionHandle(DirectParserASTType type,
+      {this.token, this.message})
+      : super("ExtraneousExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "message": message,
+      };
+}
+
+class DirectParserASTContentExpressionStatementHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentExpressionStatementHandle(DirectParserASTType type,
+      {this.token})
+      : super("ExpressionStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFactoryMethodBegin extends DirectParserASTContent {
+  final Token lastConsumed;
+  final Token externalToken;
+  final Token constToken;
+
+  DirectParserASTContentFactoryMethodBegin(DirectParserASTType type,
+      {this.lastConsumed, this.externalToken, this.constToken})
+      : super("FactoryMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "lastConsumed": lastConsumed,
+        "externalToken": externalToken,
+        "constToken": constToken,
+      };
+}
+
+class DirectParserASTContentClassFactoryMethodEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  DirectParserASTContentClassFactoryMethodEnd(DirectParserASTType type,
+      {this.beginToken, this.factoryKeyword, this.endToken})
+      : super("ClassFactoryMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMixinFactoryMethodEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  DirectParserASTContentMixinFactoryMethodEnd(DirectParserASTType type,
+      {this.beginToken, this.factoryKeyword, this.endToken})
+      : super("MixinFactoryMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentExtensionFactoryMethodEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  DirectParserASTContentExtensionFactoryMethodEnd(DirectParserASTType type,
+      {this.beginToken, this.factoryKeyword, this.endToken})
+      : super("ExtensionFactoryMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentFormalParameterBegin
+    extends DirectParserASTContent {
+  final Token token;
+  final MemberKind kind;
+  final Token requiredToken;
+  final Token covariantToken;
+  final Token varFinalOrConst;
+
+  DirectParserASTContentFormalParameterBegin(DirectParserASTType type,
+      {this.token,
+      this.kind,
+      this.requiredToken,
+      this.covariantToken,
+      this.varFinalOrConst})
+      : super("FormalParameter", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "kind": kind,
+        "requiredToken": requiredToken,
+        "covariantToken": covariantToken,
+        "varFinalOrConst": varFinalOrConst,
+      };
+}
+
+class DirectParserASTContentFormalParameterEnd extends DirectParserASTContent {
+  final Token thisKeyword;
+  final Token periodAfterThis;
+  final Token nameToken;
+  final Token initializerStart;
+  final Token initializerEnd;
+  final FormalParameterKind kind;
+  final MemberKind memberKind;
+
+  DirectParserASTContentFormalParameterEnd(DirectParserASTType type,
+      {this.thisKeyword,
+      this.periodAfterThis,
+      this.nameToken,
+      this.initializerStart,
+      this.initializerEnd,
+      this.kind,
+      this.memberKind})
+      : super("FormalParameter", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "thisKeyword": thisKeyword,
+        "periodAfterThis": periodAfterThis,
+        "nameToken": nameToken,
+        "initializerStart": initializerStart,
+        "initializerEnd": initializerEnd,
+        "kind": kind,
+        "memberKind": memberKind,
+      };
+}
+
+class DirectParserASTContentNoFormalParametersHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final MemberKind kind;
+
+  DirectParserASTContentNoFormalParametersHandle(DirectParserASTType type,
+      {this.token, this.kind})
+      : super("NoFormalParameters", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "kind": kind,
+      };
+}
+
+class DirectParserASTContentFormalParametersBegin
+    extends DirectParserASTContent {
+  final Token token;
+  final MemberKind kind;
+
+  DirectParserASTContentFormalParametersBegin(DirectParserASTType type,
+      {this.token, this.kind})
+      : super("FormalParameters", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "kind": kind,
+      };
+}
+
+class DirectParserASTContentFormalParametersEnd extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+  final MemberKind kind;
+
+  DirectParserASTContentFormalParametersEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken, this.kind})
+      : super("FormalParameters", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+        "kind": kind,
+      };
+}
+
+class DirectParserASTContentClassFieldsEnd extends DirectParserASTContent {
+  final Token abstractToken;
+  final Token externalToken;
+  final Token staticToken;
+  final Token covariantToken;
+  final Token lateToken;
+  final Token varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentClassFieldsEnd(DirectParserASTType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      this.count,
+      this.beginToken,
+      this.endToken})
+      : super("ClassFields", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMixinFieldsEnd extends DirectParserASTContent {
+  final Token abstractToken;
+  final Token externalToken;
+  final Token staticToken;
+  final Token covariantToken;
+  final Token lateToken;
+  final Token varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentMixinFieldsEnd(DirectParserASTType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      this.count,
+      this.beginToken,
+      this.endToken})
+      : super("MixinFields", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentExtensionFieldsEnd extends DirectParserASTContent {
+  final Token abstractToken;
+  final Token externalToken;
+  final Token staticToken;
+  final Token covariantToken;
+  final Token lateToken;
+  final Token varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentExtensionFieldsEnd(DirectParserASTType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      this.count,
+      this.beginToken,
+      this.endToken})
+      : super("ExtensionFields", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentForInitializerEmptyStatementHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForInitializerEmptyStatementHandle(
+      DirectParserASTType type,
+      {this.token})
+      : super("ForInitializerEmptyStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForInitializerExpressionStatementHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final bool forIn;
+
+  DirectParserASTContentForInitializerExpressionStatementHandle(
+      DirectParserASTType type,
+      {this.token,
+      this.forIn})
+      : super("ForInitializerExpressionStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "forIn": forIn,
+      };
+}
+
+class DirectParserASTContentForInitializerLocalVariableDeclarationHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final bool forIn;
+
+  DirectParserASTContentForInitializerLocalVariableDeclarationHandle(
+      DirectParserASTType type,
+      {this.token,
+      this.forIn})
+      : super("ForInitializerLocalVariableDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "forIn": forIn,
+      };
+}
+
+class DirectParserASTContentForStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("ForStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForLoopPartsHandle extends DirectParserASTContent {
+  final Token forKeyword;
+  final Token leftParen;
+  final Token leftSeparator;
+  final int updateExpressionCount;
+
+  DirectParserASTContentForLoopPartsHandle(DirectParserASTType type,
+      {this.forKeyword,
+      this.leftParen,
+      this.leftSeparator,
+      this.updateExpressionCount})
+      : super("ForLoopParts", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "forKeyword": forKeyword,
+        "leftParen": leftParen,
+        "leftSeparator": leftSeparator,
+        "updateExpressionCount": updateExpressionCount,
+      };
+}
+
+class DirectParserASTContentForStatementEnd extends DirectParserASTContent {
+  final Token endToken;
+
+  DirectParserASTContentForStatementEnd(DirectParserASTType type,
+      {this.endToken})
+      : super("ForStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentForStatementBodyBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForStatementBodyBegin(DirectParserASTType type,
+      {this.token})
+      : super("ForStatementBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForStatementBodyEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForStatementBodyEnd(DirectParserASTType type,
+      {this.token})
+      : super("ForStatementBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForInLoopPartsHandle
+    extends DirectParserASTContent {
+  final Token awaitToken;
+  final Token forToken;
+  final Token leftParenthesis;
+  final Token inKeyword;
+
+  DirectParserASTContentForInLoopPartsHandle(DirectParserASTType type,
+      {this.awaitToken, this.forToken, this.leftParenthesis, this.inKeyword})
+      : super("ForInLoopParts", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "awaitToken": awaitToken,
+        "forToken": forToken,
+        "leftParenthesis": leftParenthesis,
+        "inKeyword": inKeyword,
+      };
+}
+
+class DirectParserASTContentForInEnd extends DirectParserASTContent {
+  final Token endToken;
+
+  DirectParserASTContentForInEnd(DirectParserASTType type, {this.endToken})
+      : super("ForIn", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentForInExpressionBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForInExpressionBegin(DirectParserASTType type,
+      {this.token})
+      : super("ForInExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForInExpressionEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForInExpressionEnd(DirectParserASTType type,
+      {this.token})
+      : super("ForInExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForInBodyBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForInBodyBegin(DirectParserASTType type, {this.token})
+      : super("ForInBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForInBodyEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForInBodyEnd(DirectParserASTType type, {this.token})
+      : super("ForInBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNamedFunctionExpressionBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNamedFunctionExpressionBegin(DirectParserASTType type,
+      {this.token})
+      : super("NamedFunctionExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNamedFunctionExpressionEnd
+    extends DirectParserASTContent {
+  final Token endToken;
+
+  DirectParserASTContentNamedFunctionExpressionEnd(DirectParserASTType type,
+      {this.endToken})
+      : super("NamedFunctionExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentLocalFunctionDeclarationBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLocalFunctionDeclarationBegin(DirectParserASTType type,
+      {this.token})
+      : super("LocalFunctionDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLocalFunctionDeclarationEnd
+    extends DirectParserASTContent {
+  final Token endToken;
+
+  DirectParserASTContentLocalFunctionDeclarationEnd(DirectParserASTType type,
+      {this.endToken})
+      : super("LocalFunctionDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentBlockFunctionBodyBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentBlockFunctionBodyBegin(DirectParserASTType type,
+      {this.token})
+      : super("BlockFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentBlockFunctionBodyEnd
+    extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentBlockFunctionBodyEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken})
+      : super("BlockFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentNoFunctionBodyHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoFunctionBodyHandle(DirectParserASTType type,
+      {this.token})
+      : super("NoFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionBodySkippedHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final bool isExpressionBody;
+
+  DirectParserASTContentFunctionBodySkippedHandle(DirectParserASTType type,
+      {this.token, this.isExpressionBody})
+      : super("FunctionBodySkipped", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "isExpressionBody": isExpressionBody,
+      };
+}
+
+class DirectParserASTContentFunctionNameBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentFunctionNameBegin(DirectParserASTType type,
+      {this.token})
+      : super("FunctionName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionNameEnd extends DirectParserASTContent {
+  final Token beginToken;
+  final Token token;
+
+  DirectParserASTContentFunctionNameEnd(DirectParserASTType type,
+      {this.beginToken, this.token})
+      : super("FunctionName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionTypeAliasBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentFunctionTypeAliasBegin(DirectParserASTType type,
+      {this.token})
+      : super("FunctionTypeAlias", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionTypeAliasEnd
+    extends DirectParserASTContent {
+  final Token typedefKeyword;
+  final Token equals;
+  final Token endToken;
+
+  DirectParserASTContentFunctionTypeAliasEnd(DirectParserASTType type,
+      {this.typedefKeyword, this.equals, this.endToken})
+      : super("FunctionTypeAlias", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "typedefKeyword": typedefKeyword,
+        "equals": equals,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentClassWithClauseHandle
+    extends DirectParserASTContent {
+  final Token withKeyword;
+
+  DirectParserASTContentClassWithClauseHandle(DirectParserASTType type,
+      {this.withKeyword})
+      : super("ClassWithClause", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "withKeyword": withKeyword,
+      };
+}
+
+class DirectParserASTContentClassNoWithClauseHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentClassNoWithClauseHandle(DirectParserASTType type)
+      : super("ClassNoWithClause", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentNamedMixinApplicationBegin
+    extends DirectParserASTContent {
+  final Token begin;
+  final Token abstractToken;
+  final Token name;
+
+  DirectParserASTContentNamedMixinApplicationBegin(DirectParserASTType type,
+      {this.begin, this.abstractToken, this.name})
+      : super("NamedMixinApplication", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "begin": begin,
+        "abstractToken": abstractToken,
+        "name": name,
+      };
+}
+
+class DirectParserASTContentNamedMixinApplicationWithClauseHandle
+    extends DirectParserASTContent {
+  final Token withKeyword;
+
+  DirectParserASTContentNamedMixinApplicationWithClauseHandle(
+      DirectParserASTType type,
+      {this.withKeyword})
+      : super("NamedMixinApplicationWithClause", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "withKeyword": withKeyword,
+      };
+}
+
+class DirectParserASTContentNamedMixinApplicationEnd
+    extends DirectParserASTContent {
+  final Token begin;
+  final Token classKeyword;
+  final Token equals;
+  final Token implementsKeyword;
+  final Token endToken;
+
+  DirectParserASTContentNamedMixinApplicationEnd(DirectParserASTType type,
+      {this.begin,
+      this.classKeyword,
+      this.equals,
+      this.implementsKeyword,
+      this.endToken})
+      : super("NamedMixinApplication", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "begin": begin,
+        "classKeyword": classKeyword,
+        "equals": equals,
+        "implementsKeyword": implementsKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentHideBegin extends DirectParserASTContent {
+  final Token hideKeyword;
+
+  DirectParserASTContentHideBegin(DirectParserASTType type, {this.hideKeyword})
+      : super("Hide", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "hideKeyword": hideKeyword,
+      };
+}
+
+class DirectParserASTContentHideEnd extends DirectParserASTContent {
+  final Token hideKeyword;
+
+  DirectParserASTContentHideEnd(DirectParserASTType type, {this.hideKeyword})
+      : super("Hide", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "hideKeyword": hideKeyword,
+      };
+}
+
+class DirectParserASTContentIdentifierListHandle
+    extends DirectParserASTContent {
+  final int count;
+
+  DirectParserASTContentIdentifierListHandle(DirectParserASTType type,
+      {this.count})
+      : super("IdentifierList", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class DirectParserASTContentTypeListBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentTypeListBegin(DirectParserASTType type, {this.token})
+      : super("TypeList", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentTypeListEnd extends DirectParserASTContent {
+  final int count;
+
+  DirectParserASTContentTypeListEnd(DirectParserASTType type, {this.count})
+      : super("TypeList", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class DirectParserASTContentIfStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentIfStatementBegin(DirectParserASTType type, {this.token})
+      : super("IfStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentIfStatementEnd extends DirectParserASTContent {
+  final Token ifToken;
+  final Token elseToken;
+
+  DirectParserASTContentIfStatementEnd(DirectParserASTType type,
+      {this.ifToken, this.elseToken})
+      : super("IfStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "ifToken": ifToken,
+        "elseToken": elseToken,
+      };
+}
+
+class DirectParserASTContentThenStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentThenStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("ThenStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentThenStatementEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentThenStatementEnd(DirectParserASTType type, {this.token})
+      : super("ThenStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentElseStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentElseStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("ElseStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentElseStatementEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentElseStatementEnd(DirectParserASTType type, {this.token})
+      : super("ElseStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentImportBegin extends DirectParserASTContent {
+  final Token importKeyword;
+
+  DirectParserASTContentImportBegin(DirectParserASTType type,
+      {this.importKeyword})
+      : super("Import", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "importKeyword": importKeyword,
+      };
+}
+
+class DirectParserASTContentImportPrefixHandle extends DirectParserASTContent {
+  final Token deferredKeyword;
+  final Token asKeyword;
+
+  DirectParserASTContentImportPrefixHandle(DirectParserASTType type,
+      {this.deferredKeyword, this.asKeyword})
+      : super("ImportPrefix", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "deferredKeyword": deferredKeyword,
+        "asKeyword": asKeyword,
+      };
+}
+
+class DirectParserASTContentImportEnd extends DirectParserASTContent {
+  final Token importKeyword;
+  final Token semicolon;
+
+  DirectParserASTContentImportEnd(DirectParserASTType type,
+      {this.importKeyword, this.semicolon})
+      : super("Import", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "importKeyword": importKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentRecoverImportHandle extends DirectParserASTContent {
+  final Token semicolon;
+
+  DirectParserASTContentRecoverImportHandle(DirectParserASTType type,
+      {this.semicolon})
+      : super("RecoverImport", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentConditionalUrisBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentConditionalUrisBegin(DirectParserASTType type,
+      {this.token})
+      : super("ConditionalUris", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentConditionalUrisEnd extends DirectParserASTContent {
+  final int count;
+
+  DirectParserASTContentConditionalUrisEnd(DirectParserASTType type,
+      {this.count})
+      : super("ConditionalUris", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class DirectParserASTContentConditionalUriBegin extends DirectParserASTContent {
+  final Token ifKeyword;
+
+  DirectParserASTContentConditionalUriBegin(DirectParserASTType type,
+      {this.ifKeyword})
+      : super("ConditionalUri", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "ifKeyword": ifKeyword,
+      };
+}
+
+class DirectParserASTContentConditionalUriEnd extends DirectParserASTContent {
+  final Token ifKeyword;
+  final Token leftParen;
+  final Token equalSign;
+
+  DirectParserASTContentConditionalUriEnd(DirectParserASTType type,
+      {this.ifKeyword, this.leftParen, this.equalSign})
+      : super("ConditionalUri", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "ifKeyword": ifKeyword,
+        "leftParen": leftParen,
+        "equalSign": equalSign,
+      };
+}
+
+class DirectParserASTContentDottedNameHandle extends DirectParserASTContent {
+  final int count;
+  final Token firstIdentifier;
+
+  DirectParserASTContentDottedNameHandle(DirectParserASTType type,
+      {this.count, this.firstIdentifier})
+      : super("DottedName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "firstIdentifier": firstIdentifier,
+      };
+}
+
+class DirectParserASTContentImplicitCreationExpressionBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentImplicitCreationExpressionBegin(
+      DirectParserASTType type,
+      {this.token})
+      : super("ImplicitCreationExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentImplicitCreationExpressionEnd
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentImplicitCreationExpressionEnd(DirectParserASTType type,
+      {this.token})
+      : super("ImplicitCreationExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInitializedIdentifierBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInitializedIdentifierBegin(DirectParserASTType type,
+      {this.token})
+      : super("InitializedIdentifier", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInitializedIdentifierEnd
+    extends DirectParserASTContent {
+  final Token nameToken;
+
+  DirectParserASTContentInitializedIdentifierEnd(DirectParserASTType type,
+      {this.nameToken})
+      : super("InitializedIdentifier", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nameToken": nameToken,
+      };
+}
+
+class DirectParserASTContentFieldInitializerBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentFieldInitializerBegin(DirectParserASTType type,
+      {this.token})
+      : super("FieldInitializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFieldInitializerEnd extends DirectParserASTContent {
+  final Token assignment;
+  final Token token;
+
+  DirectParserASTContentFieldInitializerEnd(DirectParserASTType type,
+      {this.assignment, this.token})
+      : super("FieldInitializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "assignment": assignment,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNoFieldInitializerHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoFieldInitializerHandle(DirectParserASTType type,
+      {this.token})
+      : super("NoFieldInitializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentVariableInitializerBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentVariableInitializerBegin(DirectParserASTType type,
+      {this.token})
+      : super("VariableInitializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentVariableInitializerEnd
+    extends DirectParserASTContent {
+  final Token assignmentOperator;
+
+  DirectParserASTContentVariableInitializerEnd(DirectParserASTType type,
+      {this.assignmentOperator})
+      : super("VariableInitializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "assignmentOperator": assignmentOperator,
+      };
+}
+
+class DirectParserASTContentNoVariableInitializerHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoVariableInitializerHandle(DirectParserASTType type,
+      {this.token})
+      : super("NoVariableInitializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInitializerBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInitializerBegin(DirectParserASTType type, {this.token})
+      : super("Initializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInitializerEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInitializerEnd(DirectParserASTType type, {this.token})
+      : super("Initializer", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInitializersBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInitializersBegin(DirectParserASTType type,
+      {this.token})
+      : super("Initializers", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInitializersEnd extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentInitializersEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken})
+      : super("Initializers", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentNoInitializersHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentNoInitializersHandle(DirectParserASTType type)
+      : super("NoInitializers", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentInvalidExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInvalidExpressionHandle(DirectParserASTType type,
+      {this.token})
+      : super("InvalidExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInvalidFunctionBodyHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInvalidFunctionBodyHandle(DirectParserASTType type,
+      {this.token})
+      : super("InvalidFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInvalidTypeReferenceHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInvalidTypeReferenceHandle(DirectParserASTType type,
+      {this.token})
+      : super("InvalidTypeReference", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLabelHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLabelHandle(DirectParserASTType type, {this.token})
+      : super("Label", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLabeledStatementBegin
+    extends DirectParserASTContent {
+  final Token token;
+  final int labelCount;
+
+  DirectParserASTContentLabeledStatementBegin(DirectParserASTType type,
+      {this.token, this.labelCount})
+      : super("LabeledStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "labelCount": labelCount,
+      };
+}
+
+class DirectParserASTContentLabeledStatementEnd extends DirectParserASTContent {
+  final int labelCount;
+
+  DirectParserASTContentLabeledStatementEnd(DirectParserASTType type,
+      {this.labelCount})
+      : super("LabeledStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "labelCount": labelCount,
+      };
+}
+
+class DirectParserASTContentLibraryNameBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLibraryNameBegin(DirectParserASTType type, {this.token})
+      : super("LibraryName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLibraryNameEnd extends DirectParserASTContent {
+  final Token libraryKeyword;
+  final Token semicolon;
+
+  DirectParserASTContentLibraryNameEnd(DirectParserASTType type,
+      {this.libraryKeyword, this.semicolon})
+      : super("LibraryName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "libraryKeyword": libraryKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentLiteralMapEntryHandle
+    extends DirectParserASTContent {
+  final Token colon;
+  final Token endToken;
+
+  DirectParserASTContentLiteralMapEntryHandle(DirectParserASTType type,
+      {this.colon, this.endToken})
+      : super("LiteralMapEntry", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "colon": colon,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentLiteralStringBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLiteralStringBegin(DirectParserASTType type,
+      {this.token})
+      : super("LiteralString", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInterpolationExpressionHandle
+    extends DirectParserASTContent {
+  final Token leftBracket;
+  final Token rightBracket;
+
+  DirectParserASTContentInterpolationExpressionHandle(DirectParserASTType type,
+      {this.leftBracket, this.rightBracket})
+      : super("InterpolationExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "leftBracket": leftBracket,
+        "rightBracket": rightBracket,
+      };
+}
+
+class DirectParserASTContentLiteralStringEnd extends DirectParserASTContent {
+  final int interpolationCount;
+  final Token endToken;
+
+  DirectParserASTContentLiteralStringEnd(DirectParserASTType type,
+      {this.interpolationCount, this.endToken})
+      : super("LiteralString", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "interpolationCount": interpolationCount,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentStringJuxtapositionHandle
+    extends DirectParserASTContent {
+  final Token startToken;
+  final int literalCount;
+
+  DirectParserASTContentStringJuxtapositionHandle(DirectParserASTType type,
+      {this.startToken, this.literalCount})
+      : super("StringJuxtaposition", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "startToken": startToken,
+        "literalCount": literalCount,
+      };
+}
+
+class DirectParserASTContentMemberBegin extends DirectParserASTContent {
+  DirectParserASTContentMemberBegin(DirectParserASTType type)
+      : super("Member", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentInvalidMemberHandle extends DirectParserASTContent {
+  final Token endToken;
+
+  DirectParserASTContentInvalidMemberHandle(DirectParserASTType type,
+      {this.endToken})
+      : super("InvalidMember", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMemberEnd extends DirectParserASTContent {
+  DirectParserASTContentMemberEnd(DirectParserASTType type)
+      : super("Member", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentMethodBegin extends DirectParserASTContent {
+  final Token externalToken;
+  final Token staticToken;
+  final Token covariantToken;
+  final Token varFinalOrConst;
+  final Token getOrSet;
+  final Token name;
+
+  DirectParserASTContentMethodBegin(DirectParserASTType type,
+      {this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.varFinalOrConst,
+      this.getOrSet,
+      this.name})
+      : super("Method", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "varFinalOrConst": varFinalOrConst,
+        "getOrSet": getOrSet,
+        "name": name,
+      };
+}
+
+class DirectParserASTContentClassMethodEnd extends DirectParserASTContent {
+  final Token getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token beginInitializers;
+  final Token endToken;
+
+  DirectParserASTContentClassMethodEnd(DirectParserASTType type,
+      {this.getOrSet,
+      this.beginToken,
+      this.beginParam,
+      this.beginInitializers,
+      this.endToken})
+      : super("ClassMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMixinMethodEnd extends DirectParserASTContent {
+  final Token getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token beginInitializers;
+  final Token endToken;
+
+  DirectParserASTContentMixinMethodEnd(DirectParserASTType type,
+      {this.getOrSet,
+      this.beginToken,
+      this.beginParam,
+      this.beginInitializers,
+      this.endToken})
+      : super("MixinMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentExtensionMethodEnd extends DirectParserASTContent {
+  final Token getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token beginInitializers;
+  final Token endToken;
+
+  DirectParserASTContentExtensionMethodEnd(DirectParserASTType type,
+      {this.getOrSet,
+      this.beginToken,
+      this.beginParam,
+      this.beginInitializers,
+      this.endToken})
+      : super("ExtensionMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentClassConstructorEnd extends DirectParserASTContent {
+  final Token getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token beginInitializers;
+  final Token endToken;
+
+  DirectParserASTContentClassConstructorEnd(DirectParserASTType type,
+      {this.getOrSet,
+      this.beginToken,
+      this.beginParam,
+      this.beginInitializers,
+      this.endToken})
+      : super("ClassConstructor", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMixinConstructorEnd extends DirectParserASTContent {
+  final Token getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token beginInitializers;
+  final Token endToken;
+
+  DirectParserASTContentMixinConstructorEnd(DirectParserASTType type,
+      {this.getOrSet,
+      this.beginToken,
+      this.beginParam,
+      this.beginInitializers,
+      this.endToken})
+      : super("MixinConstructor", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentExtensionConstructorEnd
+    extends DirectParserASTContent {
+  final Token getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token beginInitializers;
+  final Token endToken;
+
+  DirectParserASTContentExtensionConstructorEnd(DirectParserASTType type,
+      {this.getOrSet,
+      this.beginToken,
+      this.beginParam,
+      this.beginInitializers,
+      this.endToken})
+      : super("ExtensionConstructor", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentMetadataStarBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentMetadataStarBegin(DirectParserASTType type,
+      {this.token})
+      : super("MetadataStar", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentMetadataStarEnd extends DirectParserASTContent {
+  final int count;
+
+  DirectParserASTContentMetadataStarEnd(DirectParserASTType type, {this.count})
+      : super("MetadataStar", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class DirectParserASTContentMetadataBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentMetadataBegin(DirectParserASTType type, {this.token})
+      : super("Metadata", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentMetadataEnd extends DirectParserASTContent {
+  final Token beginToken;
+  final Token periodBeforeName;
+  final Token endToken;
+
+  DirectParserASTContentMetadataEnd(DirectParserASTType type,
+      {this.beginToken, this.periodBeforeName, this.endToken})
+      : super("Metadata", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "periodBeforeName": periodBeforeName,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentOptionalFormalParametersBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentOptionalFormalParametersBegin(DirectParserASTType type,
+      {this.token})
+      : super("OptionalFormalParameters", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentOptionalFormalParametersEnd
+    extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentOptionalFormalParametersEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken})
+      : super("OptionalFormalParameters", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentPartBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentPartBegin(DirectParserASTType type, {this.token})
+      : super("Part", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentPartEnd extends DirectParserASTContent {
+  final Token partKeyword;
+  final Token semicolon;
+
+  DirectParserASTContentPartEnd(DirectParserASTType type,
+      {this.partKeyword, this.semicolon})
+      : super("Part", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "partKeyword": partKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentPartOfBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentPartOfBegin(DirectParserASTType type, {this.token})
+      : super("PartOf", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentPartOfEnd extends DirectParserASTContent {
+  final Token partKeyword;
+  final Token ofKeyword;
+  final Token semicolon;
+  final bool hasName;
+
+  DirectParserASTContentPartOfEnd(DirectParserASTType type,
+      {this.partKeyword, this.ofKeyword, this.semicolon, this.hasName})
+      : super("PartOf", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "partKeyword": partKeyword,
+        "ofKeyword": ofKeyword,
+        "semicolon": semicolon,
+        "hasName": hasName,
+      };
+}
+
+class DirectParserASTContentRedirectingFactoryBodyBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentRedirectingFactoryBodyBegin(DirectParserASTType type,
+      {this.token})
+      : super("RedirectingFactoryBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentRedirectingFactoryBodyEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentRedirectingFactoryBodyEnd(DirectParserASTType type,
+      {this.beginToken, this.endToken})
+      : super("RedirectingFactoryBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentReturnStatementBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentReturnStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("ReturnStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNativeFunctionBodyHandle
+    extends DirectParserASTContent {
+  final Token nativeToken;
+  final Token semicolon;
+
+  DirectParserASTContentNativeFunctionBodyHandle(DirectParserASTType type,
+      {this.nativeToken, this.semicolon})
+      : super("NativeFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentNativeFunctionBodyIgnoredHandle
+    extends DirectParserASTContent {
+  final Token nativeToken;
+  final Token semicolon;
+
+  DirectParserASTContentNativeFunctionBodyIgnoredHandle(
+      DirectParserASTType type,
+      {this.nativeToken,
+      this.semicolon})
+      : super("NativeFunctionBodyIgnored", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentNativeFunctionBodySkippedHandle
+    extends DirectParserASTContent {
+  final Token nativeToken;
+  final Token semicolon;
+
+  DirectParserASTContentNativeFunctionBodySkippedHandle(
+      DirectParserASTType type,
+      {this.nativeToken,
+      this.semicolon})
+      : super("NativeFunctionBodySkipped", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentEmptyFunctionBodyHandle
+    extends DirectParserASTContent {
+  final Token semicolon;
+
+  DirectParserASTContentEmptyFunctionBodyHandle(DirectParserASTType type,
+      {this.semicolon})
+      : super("EmptyFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "semicolon": semicolon,
+      };
+}
+
+class DirectParserASTContentExpressionFunctionBodyHandle
+    extends DirectParserASTContent {
+  final Token arrowToken;
+  final Token endToken;
+
+  DirectParserASTContentExpressionFunctionBodyHandle(DirectParserASTType type,
+      {this.arrowToken, this.endToken})
+      : super("ExpressionFunctionBody", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "arrowToken": arrowToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentReturnStatementEnd extends DirectParserASTContent {
+  final bool hasExpression;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentReturnStatementEnd(DirectParserASTType type,
+      {this.hasExpression, this.beginToken, this.endToken})
+      : super("ReturnStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "hasExpression": hasExpression,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentSendHandle extends DirectParserASTContent {
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentSendHandle(DirectParserASTType type,
+      {this.beginToken, this.endToken})
+      : super("Send", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentShowBegin extends DirectParserASTContent {
+  final Token showKeyword;
+
+  DirectParserASTContentShowBegin(DirectParserASTType type, {this.showKeyword})
+      : super("Show", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "showKeyword": showKeyword,
+      };
+}
+
+class DirectParserASTContentShowEnd extends DirectParserASTContent {
+  final Token showKeyword;
+
+  DirectParserASTContentShowEnd(DirectParserASTType type, {this.showKeyword})
+      : super("Show", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "showKeyword": showKeyword,
+      };
+}
+
+class DirectParserASTContentSwitchStatementBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentSwitchStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("SwitchStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentSwitchStatementEnd extends DirectParserASTContent {
+  final Token switchKeyword;
+  final Token endToken;
+
+  DirectParserASTContentSwitchStatementEnd(DirectParserASTType type,
+      {this.switchKeyword, this.endToken})
+      : super("SwitchStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "switchKeyword": switchKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentSwitchBlockBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentSwitchBlockBegin(DirectParserASTType type, {this.token})
+      : super("SwitchBlock", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentSwitchBlockEnd extends DirectParserASTContent {
+  final int caseCount;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentSwitchBlockEnd(DirectParserASTType type,
+      {this.caseCount, this.beginToken, this.endToken})
+      : super("SwitchBlock", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "caseCount": caseCount,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentLiteralSymbolBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLiteralSymbolBegin(DirectParserASTType type,
+      {this.token})
+      : super("LiteralSymbol", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLiteralSymbolEnd extends DirectParserASTContent {
+  final Token hashToken;
+  final int identifierCount;
+
+  DirectParserASTContentLiteralSymbolEnd(DirectParserASTType type,
+      {this.hashToken, this.identifierCount})
+      : super("LiteralSymbol", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "hashToken": hashToken,
+        "identifierCount": identifierCount,
+      };
+}
+
+class DirectParserASTContentThrowExpressionHandle
+    extends DirectParserASTContent {
+  final Token throwToken;
+  final Token endToken;
+
+  DirectParserASTContentThrowExpressionHandle(DirectParserASTType type,
+      {this.throwToken, this.endToken})
+      : super("ThrowExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "throwToken": throwToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentRethrowStatementBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentRethrowStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("RethrowStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentRethrowStatementEnd extends DirectParserASTContent {
+  final Token rethrowToken;
+  final Token endToken;
+
+  DirectParserASTContentRethrowStatementEnd(DirectParserASTType type,
+      {this.rethrowToken, this.endToken})
+      : super("RethrowStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "rethrowToken": rethrowToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentTopLevelDeclarationEnd
+    extends DirectParserASTContent {
+  final Token nextToken;
+
+  DirectParserASTContentTopLevelDeclarationEnd(DirectParserASTType type,
+      {this.nextToken})
+      : super("TopLevelDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nextToken": nextToken,
+      };
+}
+
+class DirectParserASTContentInvalidTopLevelDeclarationHandle
+    extends DirectParserASTContent {
+  final Token endToken;
+
+  DirectParserASTContentInvalidTopLevelDeclarationHandle(
+      DirectParserASTType type,
+      {this.endToken})
+      : super("InvalidTopLevelDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentTopLevelMemberBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentTopLevelMemberBegin(DirectParserASTType type,
+      {this.token})
+      : super("TopLevelMember", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFieldsBegin extends DirectParserASTContent {
+  final Token lastConsumed;
+
+  DirectParserASTContentFieldsBegin(DirectParserASTType type,
+      {this.lastConsumed})
+      : super("Fields", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "lastConsumed": lastConsumed,
+      };
+}
+
+class DirectParserASTContentTopLevelFieldsEnd extends DirectParserASTContent {
+  final Token externalToken;
+  final Token staticToken;
+  final Token covariantToken;
+  final Token lateToken;
+  final Token varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentTopLevelFieldsEnd(DirectParserASTType type,
+      {this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      this.count,
+      this.beginToken,
+      this.endToken})
+      : super("TopLevelFields", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentTopLevelMethodBegin extends DirectParserASTContent {
+  final Token lastConsumed;
+  final Token externalToken;
+
+  DirectParserASTContentTopLevelMethodBegin(DirectParserASTType type,
+      {this.lastConsumed, this.externalToken})
+      : super("TopLevelMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "lastConsumed": lastConsumed,
+        "externalToken": externalToken,
+      };
+}
+
+class DirectParserASTContentTopLevelMethodEnd extends DirectParserASTContent {
+  final Token beginToken;
+  final Token getOrSet;
+  final Token endToken;
+
+  DirectParserASTContentTopLevelMethodEnd(DirectParserASTType type,
+      {this.beginToken, this.getOrSet, this.endToken})
+      : super("TopLevelMethod", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "getOrSet": getOrSet,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentTryStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentTryStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("TryStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCaseMatchHandle extends DirectParserASTContent {
+  final Token caseKeyword;
+  final Token colon;
+
+  DirectParserASTContentCaseMatchHandle(DirectParserASTType type,
+      {this.caseKeyword, this.colon})
+      : super("CaseMatch", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "caseKeyword": caseKeyword,
+        "colon": colon,
+      };
+}
+
+class DirectParserASTContentCatchClauseBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentCatchClauseBegin(DirectParserASTType type, {this.token})
+      : super("CatchClause", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCatchClauseEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentCatchClauseEnd(DirectParserASTType type, {this.token})
+      : super("CatchClause", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCatchBlockHandle extends DirectParserASTContent {
+  final Token onKeyword;
+  final Token catchKeyword;
+  final Token comma;
+
+  DirectParserASTContentCatchBlockHandle(DirectParserASTType type,
+      {this.onKeyword, this.catchKeyword, this.comma})
+      : super("CatchBlock", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "onKeyword": onKeyword,
+        "catchKeyword": catchKeyword,
+        "comma": comma,
+      };
+}
+
+class DirectParserASTContentFinallyBlockHandle extends DirectParserASTContent {
+  final Token finallyKeyword;
+
+  DirectParserASTContentFinallyBlockHandle(DirectParserASTType type,
+      {this.finallyKeyword})
+      : super("FinallyBlock", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "finallyKeyword": finallyKeyword,
+      };
+}
+
+class DirectParserASTContentTryStatementEnd extends DirectParserASTContent {
+  final int catchCount;
+  final Token tryKeyword;
+  final Token finallyKeyword;
+
+  DirectParserASTContentTryStatementEnd(DirectParserASTType type,
+      {this.catchCount, this.tryKeyword, this.finallyKeyword})
+      : super("TryStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "catchCount": catchCount,
+        "tryKeyword": tryKeyword,
+        "finallyKeyword": finallyKeyword,
+      };
+}
+
+class DirectParserASTContentTypeHandle extends DirectParserASTContent {
+  final Token beginToken;
+  final Token questionMark;
+
+  DirectParserASTContentTypeHandle(DirectParserASTType type,
+      {this.beginToken, this.questionMark})
+      : super("Type", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "questionMark": questionMark,
+      };
+}
+
+class DirectParserASTContentNonNullAssertExpressionHandle
+    extends DirectParserASTContent {
+  final Token bang;
+
+  DirectParserASTContentNonNullAssertExpressionHandle(DirectParserASTType type,
+      {this.bang})
+      : super("NonNullAssertExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "bang": bang,
+      };
+}
+
+class DirectParserASTContentNoNameHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoNameHandle(DirectParserASTType type, {this.token})
+      : super("NoName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionTypeBegin extends DirectParserASTContent {
+  final Token beginToken;
+
+  DirectParserASTContentFunctionTypeBegin(DirectParserASTType type,
+      {this.beginToken})
+      : super("FunctionType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+      };
+}
+
+class DirectParserASTContentFunctionTypeEnd extends DirectParserASTContent {
+  final Token functionToken;
+  final Token questionMark;
+
+  DirectParserASTContentFunctionTypeEnd(DirectParserASTType type,
+      {this.functionToken, this.questionMark})
+      : super("FunctionType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "functionToken": functionToken,
+        "questionMark": questionMark,
+      };
+}
+
+class DirectParserASTContentTypeArgumentsBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentTypeArgumentsBegin(DirectParserASTType type,
+      {this.token})
+      : super("TypeArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentTypeArgumentsEnd extends DirectParserASTContent {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentTypeArgumentsEnd(DirectParserASTType type,
+      {this.count, this.beginToken, this.endToken})
+      : super("TypeArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentInvalidTypeArgumentsHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentInvalidTypeArgumentsHandle(DirectParserASTType type,
+      {this.token})
+      : super("InvalidTypeArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNoTypeArgumentsHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoTypeArgumentsHandle(DirectParserASTType type,
+      {this.token})
+      : super("NoTypeArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentTypeVariableBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentTypeVariableBegin(DirectParserASTType type,
+      {this.token})
+      : super("TypeVariable", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentTypeVariablesDefinedHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final int count;
+
+  DirectParserASTContentTypeVariablesDefinedHandle(DirectParserASTType type,
+      {this.token, this.count})
+      : super("TypeVariablesDefined", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "count": count,
+      };
+}
+
+class DirectParserASTContentTypeVariableEnd extends DirectParserASTContent {
+  final Token token;
+  final int index;
+  final Token extendsOrSuper;
+  final Token variance;
+
+  DirectParserASTContentTypeVariableEnd(DirectParserASTType type,
+      {this.token, this.index, this.extendsOrSuper, this.variance})
+      : super("TypeVariable", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "index": index,
+        "extendsOrSuper": extendsOrSuper,
+        "variance": variance,
+      };
+}
+
+class DirectParserASTContentTypeVariablesBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentTypeVariablesBegin(DirectParserASTType type,
+      {this.token})
+      : super("TypeVariables", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentTypeVariablesEnd extends DirectParserASTContent {
+  final Token beginToken;
+  final Token endToken;
+
+  DirectParserASTContentTypeVariablesEnd(DirectParserASTType type,
+      {this.beginToken, this.endToken})
+      : super("TypeVariables", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentFunctionExpressionBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentFunctionExpressionBegin(DirectParserASTType type,
+      {this.token})
+      : super("FunctionExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionExpressionEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token token;
+
+  DirectParserASTContentFunctionExpressionEnd(DirectParserASTType type,
+      {this.beginToken, this.token})
+      : super("FunctionExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentVariablesDeclarationBegin
+    extends DirectParserASTContent {
+  final Token token;
+  final Token lateToken;
+  final Token varFinalOrConst;
+
+  DirectParserASTContentVariablesDeclarationBegin(DirectParserASTType type,
+      {this.token, this.lateToken, this.varFinalOrConst})
+      : super("VariablesDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+      };
+}
+
+class DirectParserASTContentVariablesDeclarationEnd
+    extends DirectParserASTContent {
+  final int count;
+  final Token endToken;
+
+  DirectParserASTContentVariablesDeclarationEnd(DirectParserASTType type,
+      {this.count, this.endToken})
+      : super("VariablesDeclaration", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentWhileStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentWhileStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("WhileStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentWhileStatementEnd extends DirectParserASTContent {
+  final Token whileKeyword;
+  final Token endToken;
+
+  DirectParserASTContentWhileStatementEnd(DirectParserASTType type,
+      {this.whileKeyword, this.endToken})
+      : super("WhileStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "whileKeyword": whileKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentAsOperatorTypeBegin extends DirectParserASTContent {
+  final Token operator;
+
+  DirectParserASTContentAsOperatorTypeBegin(DirectParserASTType type,
+      {this.operator})
+      : super("AsOperatorType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class DirectParserASTContentAsOperatorTypeEnd extends DirectParserASTContent {
+  final Token operator;
+
+  DirectParserASTContentAsOperatorTypeEnd(DirectParserASTType type,
+      {this.operator})
+      : super("AsOperatorType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class DirectParserASTContentAsOperatorHandle extends DirectParserASTContent {
+  final Token operator;
+
+  DirectParserASTContentAsOperatorHandle(DirectParserASTType type,
+      {this.operator})
+      : super("AsOperator", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class DirectParserASTContentAssignmentExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentAssignmentExpressionHandle(DirectParserASTType type,
+      {this.token})
+      : super("AssignmentExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentBinaryExpressionBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentBinaryExpressionBegin(DirectParserASTType type,
+      {this.token})
+      : super("BinaryExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentBinaryExpressionEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentBinaryExpressionEnd(DirectParserASTType type,
+      {this.token})
+      : super("BinaryExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentEndingBinaryExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentEndingBinaryExpressionHandle(DirectParserASTType type,
+      {this.token})
+      : super("EndingBinaryExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentConditionalExpressionBegin
+    extends DirectParserASTContent {
+  final Token question;
+
+  DirectParserASTContentConditionalExpressionBegin(DirectParserASTType type,
+      {this.question})
+      : super("ConditionalExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "question": question,
+      };
+}
+
+class DirectParserASTContentConditionalExpressionColonHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentConditionalExpressionColonHandle(
+      DirectParserASTType type)
+      : super("ConditionalExpressionColon", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentConditionalExpressionEnd
+    extends DirectParserASTContent {
+  final Token question;
+  final Token colon;
+
+  DirectParserASTContentConditionalExpressionEnd(DirectParserASTType type,
+      {this.question, this.colon})
+      : super("ConditionalExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "question": question,
+        "colon": colon,
+      };
+}
+
+class DirectParserASTContentConstExpressionBegin
+    extends DirectParserASTContent {
+  final Token constKeyword;
+
+  DirectParserASTContentConstExpressionBegin(DirectParserASTType type,
+      {this.constKeyword})
+      : super("ConstExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "constKeyword": constKeyword,
+      };
+}
+
+class DirectParserASTContentConstExpressionEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentConstExpressionEnd(DirectParserASTType type,
+      {this.token})
+      : super("ConstExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForControlFlowBegin extends DirectParserASTContent {
+  final Token awaitToken;
+  final Token forToken;
+
+  DirectParserASTContentForControlFlowBegin(DirectParserASTType type,
+      {this.awaitToken, this.forToken})
+      : super("ForControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "awaitToken": awaitToken,
+        "forToken": forToken,
+      };
+}
+
+class DirectParserASTContentForControlFlowEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForControlFlowEnd(DirectParserASTType type,
+      {this.token})
+      : super("ForControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentForInControlFlowEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentForInControlFlowEnd(DirectParserASTType type,
+      {this.token})
+      : super("ForInControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentIfControlFlowBegin extends DirectParserASTContent {
+  final Token ifToken;
+
+  DirectParserASTContentIfControlFlowBegin(DirectParserASTType type,
+      {this.ifToken})
+      : super("IfControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "ifToken": ifToken,
+      };
+}
+
+class DirectParserASTContentThenControlFlowHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentThenControlFlowHandle(DirectParserASTType type,
+      {this.token})
+      : super("ThenControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentElseControlFlowHandle
+    extends DirectParserASTContent {
+  final Token elseToken;
+
+  DirectParserASTContentElseControlFlowHandle(DirectParserASTType type,
+      {this.elseToken})
+      : super("ElseControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "elseToken": elseToken,
+      };
+}
+
+class DirectParserASTContentIfControlFlowEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentIfControlFlowEnd(DirectParserASTType type, {this.token})
+      : super("IfControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentIfElseControlFlowEnd
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentIfElseControlFlowEnd(DirectParserASTType type,
+      {this.token})
+      : super("IfElseControlFlow", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentSpreadExpressionHandle
+    extends DirectParserASTContent {
+  final Token spreadToken;
+
+  DirectParserASTContentSpreadExpressionHandle(DirectParserASTType type,
+      {this.spreadToken})
+      : super("SpreadExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "spreadToken": spreadToken,
+      };
+}
+
+class DirectParserASTContentFunctionTypedFormalParameterBegin
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentFunctionTypedFormalParameterBegin(
+      DirectParserASTType type,
+      {this.token})
+      : super("FunctionTypedFormalParameter", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFunctionTypedFormalParameterEnd
+    extends DirectParserASTContent {
+  final Token nameToken;
+  final Token question;
+
+  DirectParserASTContentFunctionTypedFormalParameterEnd(
+      DirectParserASTType type,
+      {this.nameToken,
+      this.question})
+      : super("FunctionTypedFormalParameter", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nameToken": nameToken,
+        "question": question,
+      };
+}
+
+class DirectParserASTContentIdentifierHandle extends DirectParserASTContent {
+  final Token token;
+  final IdentifierContext context;
+
+  DirectParserASTContentIdentifierHandle(DirectParserASTType type,
+      {this.token, this.context})
+      : super("Identifier", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "context": context,
+      };
+}
+
+class DirectParserASTContentIndexedExpressionHandle
+    extends DirectParserASTContent {
+  final Token question;
+  final Token openSquareBracket;
+  final Token closeSquareBracket;
+
+  DirectParserASTContentIndexedExpressionHandle(DirectParserASTType type,
+      {this.question, this.openSquareBracket, this.closeSquareBracket})
+      : super("IndexedExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "question": question,
+        "openSquareBracket": openSquareBracket,
+        "closeSquareBracket": closeSquareBracket,
+      };
+}
+
+class DirectParserASTContentIsOperatorTypeBegin extends DirectParserASTContent {
+  final Token operator;
+
+  DirectParserASTContentIsOperatorTypeBegin(DirectParserASTType type,
+      {this.operator})
+      : super("IsOperatorType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class DirectParserASTContentIsOperatorTypeEnd extends DirectParserASTContent {
+  final Token operator;
+
+  DirectParserASTContentIsOperatorTypeEnd(DirectParserASTType type,
+      {this.operator})
+      : super("IsOperatorType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class DirectParserASTContentIsOperatorHandle extends DirectParserASTContent {
+  final Token isOperator;
+  final Token not;
+
+  DirectParserASTContentIsOperatorHandle(DirectParserASTType type,
+      {this.isOperator, this.not})
+      : super("IsOperator", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "isOperator": isOperator,
+        "not": not,
+      };
+}
+
+class DirectParserASTContentLiteralBoolHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLiteralBoolHandle(DirectParserASTType type,
+      {this.token})
+      : super("LiteralBool", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentBreakStatementHandle
+    extends DirectParserASTContent {
+  final bool hasTarget;
+  final Token breakKeyword;
+  final Token endToken;
+
+  DirectParserASTContentBreakStatementHandle(DirectParserASTType type,
+      {this.hasTarget, this.breakKeyword, this.endToken})
+      : super("BreakStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "hasTarget": hasTarget,
+        "breakKeyword": breakKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentContinueStatementHandle
+    extends DirectParserASTContent {
+  final bool hasTarget;
+  final Token continueKeyword;
+  final Token endToken;
+
+  DirectParserASTContentContinueStatementHandle(DirectParserASTType type,
+      {this.hasTarget, this.continueKeyword, this.endToken})
+      : super("ContinueStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "hasTarget": hasTarget,
+        "continueKeyword": continueKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentEmptyStatementHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentEmptyStatementHandle(DirectParserASTType type,
+      {this.token})
+      : super("EmptyStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentAssertBegin extends DirectParserASTContent {
+  final Token assertKeyword;
+  final Assert kind;
+
+  DirectParserASTContentAssertBegin(DirectParserASTType type,
+      {this.assertKeyword, this.kind})
+      : super("Assert", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "assertKeyword": assertKeyword,
+        "kind": kind,
+      };
+}
+
+class DirectParserASTContentAssertEnd extends DirectParserASTContent {
+  final Token assertKeyword;
+  final Assert kind;
+  final Token leftParenthesis;
+  final Token commaToken;
+  final Token semicolonToken;
+
+  DirectParserASTContentAssertEnd(DirectParserASTType type,
+      {this.assertKeyword,
+      this.kind,
+      this.leftParenthesis,
+      this.commaToken,
+      this.semicolonToken})
+      : super("Assert", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "assertKeyword": assertKeyword,
+        "kind": kind,
+        "leftParenthesis": leftParenthesis,
+        "commaToken": commaToken,
+        "semicolonToken": semicolonToken,
+      };
+}
+
+class DirectParserASTContentLiteralDoubleHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLiteralDoubleHandle(DirectParserASTType type,
+      {this.token})
+      : super("LiteralDouble", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLiteralIntHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLiteralIntHandle(DirectParserASTType type, {this.token})
+      : super("LiteralInt", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentLiteralListHandle extends DirectParserASTContent {
+  final int count;
+  final Token leftBracket;
+  final Token constKeyword;
+  final Token rightBracket;
+
+  DirectParserASTContentLiteralListHandle(DirectParserASTType type,
+      {this.count, this.leftBracket, this.constKeyword, this.rightBracket})
+      : super("LiteralList", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "leftBracket": leftBracket,
+        "constKeyword": constKeyword,
+        "rightBracket": rightBracket,
+      };
+}
+
+class DirectParserASTContentLiteralSetOrMapHandle
+    extends DirectParserASTContent {
+  final int count;
+  final Token leftBrace;
+  final Token constKeyword;
+  final Token rightBrace;
+  final bool hasSetEntry;
+
+  DirectParserASTContentLiteralSetOrMapHandle(DirectParserASTType type,
+      {this.count,
+      this.leftBrace,
+      this.constKeyword,
+      this.rightBrace,
+      this.hasSetEntry})
+      : super("LiteralSetOrMap", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "count": count,
+        "leftBrace": leftBrace,
+        "constKeyword": constKeyword,
+        "rightBrace": rightBrace,
+        "hasSetEntry": hasSetEntry,
+      };
+}
+
+class DirectParserASTContentLiteralNullHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentLiteralNullHandle(DirectParserASTType type,
+      {this.token})
+      : super("LiteralNull", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNativeClauseHandle extends DirectParserASTContent {
+  final Token nativeToken;
+  final bool hasName;
+
+  DirectParserASTContentNativeClauseHandle(DirectParserASTType type,
+      {this.nativeToken, this.hasName})
+      : super("NativeClause", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "hasName": hasName,
+      };
+}
+
+class DirectParserASTContentNamedArgumentHandle extends DirectParserASTContent {
+  final Token colon;
+
+  DirectParserASTContentNamedArgumentHandle(DirectParserASTType type,
+      {this.colon})
+      : super("NamedArgument", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "colon": colon,
+      };
+}
+
+class DirectParserASTContentNewExpressionBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNewExpressionBegin(DirectParserASTType type,
+      {this.token})
+      : super("NewExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNewExpressionEnd extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNewExpressionEnd(DirectParserASTType type, {this.token})
+      : super("NewExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNoArgumentsHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoArgumentsHandle(DirectParserASTType type,
+      {this.token})
+      : super("NoArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle(
+      DirectParserASTType type,
+      {this.token})
+      : super("NoConstructorReferenceContinuationAfterTypeArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNoTypeHandle extends DirectParserASTContent {
+  final Token lastConsumed;
+
+  DirectParserASTContentNoTypeHandle(DirectParserASTType type,
+      {this.lastConsumed})
+      : super("NoType", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "lastConsumed": lastConsumed,
+      };
+}
+
+class DirectParserASTContentNoTypeVariablesHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentNoTypeVariablesHandle(DirectParserASTType type,
+      {this.token})
+      : super("NoTypeVariables", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentOperatorHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentOperatorHandle(DirectParserASTType type, {this.token})
+      : super("Operator", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentSymbolVoidHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentSymbolVoidHandle(DirectParserASTType type, {this.token})
+      : super("SymbolVoid", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentOperatorNameHandle extends DirectParserASTContent {
+  final Token operatorKeyword;
+  final Token token;
+
+  DirectParserASTContentOperatorNameHandle(DirectParserASTType type,
+      {this.operatorKeyword, this.token})
+      : super("OperatorName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operatorKeyword": operatorKeyword,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentInvalidOperatorNameHandle
+    extends DirectParserASTContent {
+  final Token operatorKeyword;
+  final Token token;
+
+  DirectParserASTContentInvalidOperatorNameHandle(DirectParserASTType type,
+      {this.operatorKeyword, this.token})
+      : super("InvalidOperatorName", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "operatorKeyword": operatorKeyword,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentParenthesizedConditionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentParenthesizedConditionHandle(DirectParserASTType type,
+      {this.token})
+      : super("ParenthesizedCondition", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentParenthesizedExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentParenthesizedExpressionHandle(DirectParserASTType type,
+      {this.token})
+      : super("ParenthesizedExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentQualifiedHandle extends DirectParserASTContent {
+  final Token period;
+
+  DirectParserASTContentQualifiedHandle(DirectParserASTType type, {this.period})
+      : super("Qualified", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "period": period,
+      };
+}
+
+class DirectParserASTContentStringPartHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentStringPartHandle(DirectParserASTType type, {this.token})
+      : super("StringPart", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentSuperExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final IdentifierContext context;
+
+  DirectParserASTContentSuperExpressionHandle(DirectParserASTType type,
+      {this.token, this.context})
+      : super("SuperExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "context": context,
+      };
+}
+
+class DirectParserASTContentSwitchCaseBegin extends DirectParserASTContent {
+  final int labelCount;
+  final int expressionCount;
+  final Token firstToken;
+
+  DirectParserASTContentSwitchCaseBegin(DirectParserASTType type,
+      {this.labelCount, this.expressionCount, this.firstToken})
+      : super("SwitchCase", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "labelCount": labelCount,
+        "expressionCount": expressionCount,
+        "firstToken": firstToken,
+      };
+}
+
+class DirectParserASTContentSwitchCaseEnd extends DirectParserASTContent {
+  final int labelCount;
+  final int expressionCount;
+  final Token defaultKeyword;
+  final Token colonAfterDefault;
+  final int statementCount;
+  final Token firstToken;
+  final Token endToken;
+
+  DirectParserASTContentSwitchCaseEnd(DirectParserASTType type,
+      {this.labelCount,
+      this.expressionCount,
+      this.defaultKeyword,
+      this.colonAfterDefault,
+      this.statementCount,
+      this.firstToken,
+      this.endToken})
+      : super("SwitchCase", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "labelCount": labelCount,
+        "expressionCount": expressionCount,
+        "defaultKeyword": defaultKeyword,
+        "colonAfterDefault": colonAfterDefault,
+        "statementCount": statementCount,
+        "firstToken": firstToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentThisExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final IdentifierContext context;
+
+  DirectParserASTContentThisExpressionHandle(DirectParserASTType type,
+      {this.token, this.context})
+      : super("ThisExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "context": context,
+      };
+}
+
+class DirectParserASTContentUnaryPostfixAssignmentExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentUnaryPostfixAssignmentExpressionHandle(
+      DirectParserASTType type,
+      {this.token})
+      : super("UnaryPostfixAssignmentExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentUnaryPrefixExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentUnaryPrefixExpressionHandle(DirectParserASTType type,
+      {this.token})
+      : super("UnaryPrefixExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentUnaryPrefixAssignmentExpressionHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentUnaryPrefixAssignmentExpressionHandle(
+      DirectParserASTType type,
+      {this.token})
+      : super("UnaryPrefixAssignmentExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFormalParameterDefaultValueExpressionBegin
+    extends DirectParserASTContent {
+  DirectParserASTContentFormalParameterDefaultValueExpressionBegin(
+      DirectParserASTType type)
+      : super("FormalParameterDefaultValueExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentFormalParameterDefaultValueExpressionEnd
+    extends DirectParserASTContent {
+  DirectParserASTContentFormalParameterDefaultValueExpressionEnd(
+      DirectParserASTType type)
+      : super("FormalParameterDefaultValueExpression", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
+
+class DirectParserASTContentValuedFormalParameterHandle
+    extends DirectParserASTContent {
+  final Token equals;
+  final Token token;
+
+  DirectParserASTContentValuedFormalParameterHandle(DirectParserASTType type,
+      {this.equals, this.token})
+      : super("ValuedFormalParameter", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "equals": equals,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentFormalParameterWithoutValueHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentFormalParameterWithoutValueHandle(
+      DirectParserASTType type,
+      {this.token})
+      : super("FormalParameterWithoutValue", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentVoidKeywordHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentVoidKeywordHandle(DirectParserASTType type,
+      {this.token})
+      : super("VoidKeyword", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentVoidKeywordWithTypeArgumentsHandle
+    extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentVoidKeywordWithTypeArgumentsHandle(
+      DirectParserASTType type,
+      {this.token})
+      : super("VoidKeywordWithTypeArguments", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentYieldStatementBegin extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentYieldStatementBegin(DirectParserASTType type,
+      {this.token})
+      : super("YieldStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentYieldStatementEnd extends DirectParserASTContent {
+  final Token yieldToken;
+  final Token starToken;
+  final Token endToken;
+
+  DirectParserASTContentYieldStatementEnd(DirectParserASTType type,
+      {this.yieldToken, this.starToken, this.endToken})
+      : super("YieldStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "yieldToken": yieldToken,
+        "starToken": starToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentInvalidYieldStatementEnd
+    extends DirectParserASTContent {
+  final Token beginToken;
+  final Token starToken;
+  final Token endToken;
+  final MessageCode errorCode;
+
+  DirectParserASTContentInvalidYieldStatementEnd(DirectParserASTType type,
+      {this.beginToken, this.starToken, this.endToken, this.errorCode})
+      : super("InvalidYieldStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "starToken": starToken,
+        "endToken": endToken,
+        "errorCode": errorCode,
+      };
+}
+
+class DirectParserASTContentRecoverableErrorHandle
+    extends DirectParserASTContent {
+  final Message message;
+  final Token startToken;
+  final Token endToken;
+
+  DirectParserASTContentRecoverableErrorHandle(DirectParserASTType type,
+      {this.message, this.startToken, this.endToken})
+      : super("RecoverableError", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "message": message,
+        "startToken": startToken,
+        "endToken": endToken,
+      };
+}
+
+class DirectParserASTContentErrorTokenHandle extends DirectParserASTContent {
+  final ErrorToken token;
+
+  DirectParserASTContentErrorTokenHandle(DirectParserASTType type, {this.token})
+      : super("ErrorToken", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentUnescapeErrorHandle extends DirectParserASTContent {
+  final Message message;
+  final Token location;
+  final int stringOffset;
+  final int length;
+
+  DirectParserASTContentUnescapeErrorHandle(DirectParserASTType type,
+      {this.message, this.location, this.stringOffset, this.length})
+      : super("UnescapeError", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "message": message,
+        "location": location,
+        "stringOffset": stringOffset,
+        "length": length,
+      };
+}
+
+class DirectParserASTContentInvalidStatementHandle
+    extends DirectParserASTContent {
+  final Token token;
+  final Message message;
+
+  DirectParserASTContentInvalidStatementHandle(DirectParserASTType type,
+      {this.token, this.message})
+      : super("InvalidStatement", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+        "message": message,
+      };
+}
+
+class DirectParserASTContentScriptHandle extends DirectParserASTContent {
+  final Token token;
+
+  DirectParserASTContentScriptHandle(DirectParserASTType type, {this.token})
+      : super("Script", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectParserASTContentCommentReferenceTextHandle
+    extends DirectParserASTContent {
+  final String referenceSource;
+  final int referenceOffset;
+
+  DirectParserASTContentCommentReferenceTextHandle(DirectParserASTType type,
+      {this.referenceSource, this.referenceOffset})
+      : super("CommentReferenceText", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "referenceSource": referenceSource,
+        "referenceOffset": referenceOffset,
+      };
+}
+
+class DirectParserASTContentCommentReferenceHandle
+    extends DirectParserASTContent {
+  final Token newKeyword;
+  final Token prefix;
+  final Token period;
+  final Token token;
+
+  DirectParserASTContentCommentReferenceHandle(DirectParserASTType type,
+      {this.newKeyword, this.prefix, this.period, this.token})
+      : super("CommentReference", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "newKeyword": newKeyword,
+        "prefix": prefix,
+        "period": period,
+        "token": token,
+      };
+}
+
+class DirectParserASTContentNoCommentReferenceHandle
+    extends DirectParserASTContent {
+  DirectParserASTContentNoCommentReferenceHandle(DirectParserASTType type)
+      : super("NoCommentReference", type);
+
+  Map<String, Object> get deprecatedArguments => {};
+}
diff --git a/pkg/front_end/lib/src/fasta/util/textual_outline.dart b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
index 4b1f8cc..676582d 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -270,7 +270,7 @@
 }
 
 abstract class _ClassChunk extends _SortableChunk {
-  List<_Chunk> content = new List<_Chunk>();
+  List<_Chunk> content = <_Chunk>[];
   Token headerEnd;
   Token footerStart;
 
@@ -424,7 +424,7 @@
   Uint8List bytes = new Uint8List(rawBytes.length + 1);
   bytes.setRange(0, rawBytes.length, rawBytes);
 
-  List<_Chunk> parsedChunks = new List<_Chunk>();
+  List<_Chunk> parsedChunks = <_Chunk>[];
 
   BoxedInt originalPosition = new BoxedInt(0);
 
@@ -482,7 +482,7 @@
   StringBuffer sb = new StringBuffer();
   for (_Chunk chunk in chunks) {
     if (chunk is _MetadataChunk) {
-      metadataChunks ??= new List<_MetadataChunk>();
+      metadataChunks ??= <_MetadataChunk>[];
       metadataChunks.add(chunk);
     } else {
       chunk.metadata = metadataChunks;
@@ -491,7 +491,7 @@
       sb.clear();
 
       if (chunk is _SingleImportExportChunk) {
-        importExportChunks ??= new List<_SingleImportExportChunk>();
+        importExportChunks ??= <_SingleImportExportChunk>[];
         importExportChunks.add(chunk);
       } else {
         if (importExportChunks != null) {
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 24b5b55..ae668cb 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -74,7 +74,7 @@
     DillTarget dillTarget =
         new DillTarget(options.ticker, uriTranslator, options.target);
 
-    List<Component> loadedComponents = new List<Component>();
+    List<Component> loadedComponents = <Component>[];
 
     Component sdkSummary = await options.loadSdkSummary(null);
     // By using the nameRoot of the the summary, we enable sharing the
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index d63f675..f9fcbd3 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -4,6 +4,7 @@
 
 import 'package:_fe_analyzer_shared/src/testing/id.dart';
 import 'package:kernel/ast.dart';
+import '../api_prototype/lowering_predicates.dart';
 
 /// Compute a canonical [Id] for kernel-based nodes.
 Id computeMemberId(Member node) {
@@ -246,7 +247,12 @@
 
   @override
   visitFunctionDeclaration(FunctionDeclaration node) {
-    computeForNode(node, computeDefaultNodeId(node));
+    computeForNode(
+        node,
+        computeDefaultNodeId(node,
+            // TODO(johnniwinther): Remove this when late lowered setter
+            //  functions can have an offset.
+            skipNodeWithNoOffset: isLateLoweredLocalSetter(node.variable)));
     super.visitFunctionDeclaration(node);
   }
 
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 2fe29ec..2350d4d 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -629,8 +629,6 @@
 OperatorParameterMismatch2/example: Fail
 OperatorWithOptionalFormals/analyzerCode: Fail
 OperatorWithOptionalFormals/example: Fail
-OptionalNonNullableWithoutInitializerError/analyzerCode: Fail
-OptionalNonNullableWithoutInitializerWarning/analyzerCode: Fail
 OverrideFewerNamedArguments/example: Fail
 OverrideFewerPositionalArguments/example: Fail
 OverrideMismatchNamedParameter/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index ae4a9e7..96f20a7 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -4585,7 +4585,9 @@
   template: "Required named parameter '#name' must be provided."
 
 OptionalNonNullableWithoutInitializerError:
-  template: "Optional parameter '#name' should have a default value because its type '#type' doesn't allow null."
+  template: "The parameter '#name' can't have a value of 'null' because of its type '#type', but the implicit default value is 'null'."
+  tip: "Try adding either an explicit non-'null' default value or the 'required' modifier."
+  analyzerCode: MISSING_DEFAULT_VALUE_FOR_PARAMETER
   configuration: nnbd-strong
   script:
     - method1({int a}) {}
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 3f3905b..20a36d8 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -6,15 +6,19 @@
 publish_to: none
 
 environment:
-  sdk: '>=2.2.2 <3.0.0'
+  sdk: '>=2.6.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: any
-  kernel: any
-  package_config: any
+  _fe_analyzer_shared:
+    path: ../_fe_analyzer_shared
+  kernel:
+    path: ../kernel
+  package_config:
+    path: ../../third_party/pkg_tested/package_config
 
 dev_dependencies:
-  analyzer: any
+  analyzer:
+    path: ../analyzer
   args: '>=0.13.0 <2.0.0'
   async_helper:
     path: ../async_helper
@@ -38,14 +42,4 @@
   vm_service:
     path: ../vm_service
   web_socket_channel: ^1.0.4
-  yaml: '^2.1.12'
-
-dependency_overrides:
-  _fe_analyzer_shared:
-    path: ../_fe_analyzer_shared/
-  analyzer:
-    path: ../analyzer
-  kernel:
-    path: ../kernel/
-  package_config:
-    path: ../../third_party/pkg_tested/package_config/
+  yaml: any
diff --git a/pkg/front_end/test/ast_nodes_has_to_string_test.dart b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
index 13d7120..9b0dc9f 100644
--- a/pkg/front_end/test/ast_nodes_has_to_string_test.dart
+++ b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
@@ -56,13 +56,13 @@
               .toList();
           if (toStringList.length > 1) throw "What?";
           if (toStringList.length == 1) {
-            classMapWithOne[c.fileUri] ??= new List<Class>();
+            classMapWithOne[c.fileUri] ??= <Class>[];
             classMapWithOne[c.fileUri].add(c);
             continue;
           }
           toGo++;
 
-          classMap[c.fileUri] ??= new List<Class>();
+          classMap[c.fileUri] ??= <Class>[];
           classMap[c.fileUri].add(c);
         }
       }
diff --git a/pkg/front_end/test/binary_md_dill_reader.dart b/pkg/front_end/test/binary_md_dill_reader.dart
index c0a4b5b..271ffd8 100644
--- a/pkg/front_end/test/binary_md_dill_reader.dart
+++ b/pkg/front_end/test/binary_md_dill_reader.dart
@@ -517,7 +517,7 @@
 
         if (intCount >= 0) {
           readNothingIsOk = intCount == 0;
-          List<dynamic> value = new List(intCount);
+          List<dynamic> value = new List.filled(intCount, null);
           for (int i = 0; i < intCount; ++i) {
             int oldOffset2 = _binaryOffset;
             value[i] = _readBinary(type);
diff --git a/pkg/front_end/test/constant_evaluator_benchmark.dart b/pkg/front_end/test/constant_evaluator_benchmark.dart
new file mode 100644
index 0000000..f0e722c
--- /dev/null
+++ b/pkg/front_end/test/constant_evaluator_benchmark.dart
@@ -0,0 +1,304 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' show File;
+import 'dart:typed_data' show Uint8List;
+
+import 'package:_fe_analyzer_shared/src/messages/codes.dart';
+import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, DiagnosticMessage;
+
+import 'package:front_end/src/api_prototype/experimental_flags.dart'
+    show ExperimentalFlag;
+
+import 'package:front_end/src/base/processed_options.dart'
+    show ProcessedOptions;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+    show IncrementalCompiler;
+import 'package:front_end/src/fasta/kernel/constant_evaluator.dart' as constants
+    show EvaluationMode, transformLibraries, ErrorReporter;
+import 'package:front_end/src/fasta/kernel/kernel_api.dart';
+
+import 'package:front_end/src/fasta/kernel/kernel_target.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/binary/ast_from_binary.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/target/changed_structure_notifier.dart';
+
+import 'package:kernel/target/targets.dart'
+    show ConstantsBackend, DiagnosticReporter, Target, TargetFlags;
+import 'package:kernel/type_environment.dart';
+
+import "package:vm/target/flutter.dart" show FlutterTarget;
+
+import "package:vm/target/vm.dart" show VmTarget;
+
+import 'incremental_load_from_dill_suite.dart' show getOptions;
+
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
+
+bool tryWithNoEnvironment;
+bool verbose = false;
+bool skipNonNullEnvironment = false;
+bool skipNullEnvironment = false;
+
+void benchmark(Component component, List<Library> libraries) {
+  if (tryWithNoEnvironment == null) throw "tryWithNoEnvironment not set";
+  KernelTarget target = incrementalCompiler.userCode;
+  constants.EvaluationMode evaluationMode =
+      target.getConstantEvaluationModeForTesting();
+
+  Uint8List serializedComponent = serializeComponent(component);
+
+  for (int k = 0; k < 3; k++) {
+    Map<String, String> environmentDefines = null;
+    String environmentDefinesDescription = "null environment";
+
+    for (int j = 0; j < 2; j++) {
+      Stopwatch stopwatch = new Stopwatch()..start();
+      int iterations = 0;
+      int sum = 0;
+      for (int i = 0; i < 5; i++) {
+        if (!tryWithNoEnvironment && environmentDefines == null) continue;
+        if (skipNullEnvironment && environmentDefines == null) continue;
+        if (skipNonNullEnvironment && environmentDefines != null) continue;
+        stopwatch.reset();
+        Component component = new Component();
+        BinaryBuilder binaryBuilder = new BinaryBuilder(serializedComponent,
+            disableLazyClassReading: true, disableLazyReading: true);
+        binaryBuilder.readComponent(component);
+        if (verbose) {
+          print("Loaded component in ${stopwatch.elapsedMilliseconds} ms");
+        }
+
+        stopwatch.reset();
+        CoreTypes coreTypes = new CoreTypes(component);
+        ConstantsBackend constantsBackend =
+            target.backendTarget.constantsBackend(coreTypes);
+        ClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes);
+        TypeEnvironment environment = new TypeEnvironment(coreTypes, hierarchy);
+        if (verbose) {
+          print("Created core types and class hierarchy"
+              " in ${stopwatch.elapsedMilliseconds} ms");
+        }
+
+        stopwatch.reset();
+        constants.transformLibraries(
+            component.libraries,
+            constantsBackend,
+            environmentDefines,
+            environment,
+            new SilentErrorReporter(),
+            evaluationMode,
+            evaluateAnnotations: true,
+            enableTripleShift: target
+                .isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
+            errorOnUnevaluatedConstant:
+                incrementalCompiler.context.options.errorOnUnevaluatedConstant);
+        print("Transformed constants with $environmentDefinesDescription"
+            " in ${stopwatch.elapsedMilliseconds} ms");
+        sum += stopwatch.elapsedMilliseconds;
+        iterations++;
+      }
+      if (verbose) {
+        print("With $environmentDefinesDescription: "
+            "Did constant evaluation $iterations iterations in $sum ms,"
+            " i.e. an average of ${sum / iterations} ms per iteration.");
+      }
+      environmentDefines = {};
+      environmentDefinesDescription = "empty environment";
+    }
+  }
+}
+
+class SilentErrorReporter implements constants.ErrorReporter {
+  @override
+  void report(LocatedMessage message, List<LocatedMessage> context) {
+    // ignore
+  }
+
+  @override
+  void reportInvalidExpression(InvalidExpression node) {
+    // ignore
+  }
+}
+
+IncrementalCompiler incrementalCompiler;
+
+main(List<String> arguments) async {
+  Uri platformUri;
+  Uri mainUri;
+  bool nnbd = false;
+  String targetString = "VM";
+
+  String filename;
+  for (String arg in arguments) {
+    if (arg.startsWith("--")) {
+      if (arg == "--nnbd") {
+        nnbd = true;
+      } else if (arg.startsWith("--platform=")) {
+        String platform = arg.substring("--platform=".length);
+        platformUri = Uri.base.resolve(platform);
+      } else if (arg == "--target=VM") {
+        targetString = "VM";
+      } else if (arg == "--target=flutter") {
+        targetString = "flutter";
+      } else if (arg == "--target=ddc") {
+        targetString = "ddc";
+      } else if (arg == "--target=dart2js") {
+        targetString = "dart2js";
+      } else if (arg == "-v") {
+        verbose = true;
+      } else if (arg == "--skip-null-environment") {
+        skipNullEnvironment = true;
+      } else if (arg == "--skip-non-null-environment") {
+        skipNonNullEnvironment = true;
+      } else {
+        throw "Unknown option $arg";
+      }
+    } else if (filename != null) {
+      throw "Already got '$filename', '$arg' is also a filename; "
+          "can only get one";
+    } else {
+      filename = arg;
+    }
+  }
+
+  if (platformUri == null) {
+    throw "No platform given. Use --platform=/path/to/platform.dill";
+  }
+  if (!new File.fromUri(platformUri).existsSync()) {
+    throw "The platform file '$platformUri' doesn't exist";
+  }
+  if (filename == null) {
+    throw "Need file to operate on";
+  }
+  File file = new File(filename);
+  if (!file.existsSync()) throw "File $filename doesn't exist.";
+  mainUri = file.absolute.uri;
+
+  incrementalCompiler = new IncrementalCompiler(
+      setupCompilerContext(nnbd, targetString, false, platformUri, mainUri));
+  await incrementalCompiler.computeDelta();
+}
+
+CompilerContext setupCompilerContext(bool nnbd, String targetString,
+    bool widgetTransformation, Uri platformUri, Uri mainUri) {
+  CompilerOptions options = getOptions();
+
+  if (nnbd) {
+    options.explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
+  }
+
+  TargetFlags targetFlags = new TargetFlags(
+      enableNullSafety: nnbd, trackWidgetCreation: widgetTransformation);
+  Target target;
+  switch (targetString) {
+    case "VM":
+      target = new HookInVmTarget(targetFlags);
+      tryWithNoEnvironment = false;
+      break;
+    case "flutter":
+      target = new HookInFlutterTarget(targetFlags);
+      tryWithNoEnvironment = false;
+      break;
+    case "ddc":
+      target = new HookInDevCompilerTarget(targetFlags);
+      tryWithNoEnvironment = false;
+      break;
+    case "dart2js":
+      target = new HookInDart2jsTarget("dart2js", targetFlags);
+      tryWithNoEnvironment = true;
+      break;
+    default:
+      throw "Unknown target '$targetString'";
+  }
+  options.target = target;
+  options.sdkRoot = null;
+  options.sdkSummary = platformUri;
+  options.omitPlatform = false;
+  options.onDiagnostic = (DiagnosticMessage message) {
+    // don't care.
+  };
+
+  ProcessedOptions processedOptions =
+      new ProcessedOptions(options: options, inputs: [mainUri]);
+  CompilerContext compilerContext = new CompilerContext(processedOptions);
+  return compilerContext;
+}
+
+class HookInVmTarget extends VmTarget {
+  HookInVmTarget(TargetFlags flags) : super(flags);
+
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg),
+      ChangedStructureNotifier changedStructureNotifier}) {
+    super.performPreConstantEvaluationTransformations(
+        component, coreTypes, libraries, diagnosticReporter,
+        logger: logger, changedStructureNotifier: changedStructureNotifier);
+    benchmark(component, libraries);
+  }
+}
+
+class HookInDart2jsTarget extends Dart2jsTarget {
+  HookInDart2jsTarget(String name, TargetFlags flags) : super(name, flags);
+
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg),
+      ChangedStructureNotifier changedStructureNotifier}) {
+    super.performPreConstantEvaluationTransformations(
+        component, coreTypes, libraries, diagnosticReporter,
+        logger: logger, changedStructureNotifier: changedStructureNotifier);
+    benchmark(component, libraries);
+  }
+}
+
+class HookInDevCompilerTarget extends DevCompilerTarget {
+  HookInDevCompilerTarget(TargetFlags flags) : super(flags);
+
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg),
+      ChangedStructureNotifier changedStructureNotifier}) {
+    super.performPreConstantEvaluationTransformations(
+        component, coreTypes, libraries, diagnosticReporter,
+        logger: logger, changedStructureNotifier: changedStructureNotifier);
+    benchmark(component, libraries);
+  }
+}
+
+class HookInFlutterTarget extends FlutterTarget {
+  HookInFlutterTarget(TargetFlags flags) : super(flags);
+
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg),
+      ChangedStructureNotifier changedStructureNotifier}) {
+    super.performPreConstantEvaluationTransformations(
+        component, coreTypes, libraries, diagnosticReporter,
+        logger: logger, changedStructureNotifier: changedStructureNotifier);
+    benchmark(component, libraries);
+  }
+}
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
index 4f043ed..ea8ac64 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -2,667 +2,106 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert' show utf8;
+import 'dart:convert' show jsonDecode;
 
-import 'dart:io' show BytesBuilder, File, stdin;
+import 'dart:io' show File;
 
-import 'dart:typed_data' show Uint8List;
+import 'crashing_test_case_minimizer_impl.dart';
 
-import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
+// TODO(jensj): Option to automatically find and search for _all_ crashes that
+// it uncovers --- i.e. it currently has an option to ask if we want to search
+// for the other crash instead --- add an option so it does that automatically
+// for everything it sees. One can possibly just make a copy of the state of
+// the file system and save that for later...
 
-import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
-    show ScannerConfiguration, Token;
-
-import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
-import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
-
-import 'package:front_end/src/api_prototype/compiler_options.dart'
-    show CompilerOptions, DiagnosticMessage;
-
-import 'package:front_end/src/api_prototype/experimental_flags.dart'
-    show ExperimentalFlag;
-
-import 'package:front_end/src/api_prototype/file_system.dart'
-    show FileSystem, FileSystemEntity, FileSystemException;
-
-import 'package:front_end/src/base/processed_options.dart'
-    show ProcessedOptions;
-
-import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
-
-import 'package:front_end/src/fasta/incremental_compiler.dart'
-    show IncrementalCompiler;
-
-import 'package:kernel/ast.dart' show Component;
-
-import 'package:kernel/target/targets.dart' show Target, TargetFlags;
-
-import "package:vm/target/flutter.dart" show FlutterTarget;
-
-import "package:vm/target/vm.dart" show VmTarget;
-
-import 'incremental_load_from_dill_suite.dart' show getOptions;
-
-import 'parser_test_listener.dart' show ParserTestListener;
-
-import 'parser_suite.dart' as parser_suite;
-
-final FakeFileSystem fs = new FakeFileSystem();
-Uri mainUri;
-Uri platformUri;
-bool noPlatform = false;
-bool nnbd = false;
-bool widgetTransformation = false;
-List<Uri> invalidate = [];
-String targetString = "VM";
-String expectedCrashLine;
-bool byteDelete = false;
-bool askAboutRedirectCrashTarget = false;
-int stackTraceMatches = 1;
-Set<String> askedAboutRedirect = {};
+// TODO(jensj): Add asserts or similar where - after each rewrite - we run the
+// parser on it and verifies that no syntax errors have been introduced.
 
 main(List<String> arguments) async {
   String filename;
+  Uri loadJson;
   for (String arg in arguments) {
-    if (arg.startsWith("--")) {
-      if (arg == "--nnbd") {
-        nnbd = true;
-      } else if (arg.startsWith("--platform=")) {
-        String platform = arg.substring("--platform=".length);
-        platformUri = Uri.base.resolve(platform);
-      } else if (arg == "--no-platform") {
-        noPlatform = true;
-      } else if (arg.startsWith("--invalidate=")) {
-        for (String s in arg.substring("--invalidate=".length).split(",")) {
-          invalidate.add(Uri.base.resolve(s));
-        }
-      } else if (arg.startsWith("--widgetTransformation")) {
-        widgetTransformation = true;
-      } else if (arg.startsWith("--target=VM")) {
-        targetString = "VM";
-      } else if (arg.startsWith("--target=flutter")) {
-        targetString = "flutter";
-      } else if (arg.startsWith("--target=ddc")) {
-        targetString = "ddc";
-      } else if (arg == "--byteDelete") {
-        byteDelete = true;
-      } else if (arg == "--ask-redirect-target") {
-        askAboutRedirectCrashTarget = true;
-      } else if (arg.startsWith("--stack-matches=")) {
-        String stackMatches = arg.substring("--stack-matches=".length);
-        stackTraceMatches = int.parse(stackMatches);
-      } else {
-        throw "Unknown option $arg";
-      }
-    } else if (filename != null) {
-      throw "Already got '$filename', '$arg' is also a filename; "
-          "can only get one";
-    } else {
-      filename = arg;
+    if (arg.startsWith("--json=")) {
+      String json = arg.substring("--json=".length);
+      loadJson = Uri.base.resolve(json);
+      break;
     }
   }
-  if (noPlatform) {
-    int i = 0;
-    while (platformUri == null || new File.fromUri(platformUri).existsSync()) {
-      platformUri = Uri.base.resolve("nonexisting_$i");
-      i++;
-    }
+  TestMinimizerSettings settings = new TestMinimizerSettings();
+
+  if (loadJson != null) {
+    File f = new File.fromUri(loadJson);
+    settings.initializeFromJson((jsonDecode(f.readAsStringSync())));
   } else {
-    if (platformUri == null) {
-      throw "No platform given. Use --platform=/path/to/platform.dill";
-    }
-    if (!new File.fromUri(platformUri).existsSync()) {
-      throw "The platform file '$platformUri' doesn't exist";
-    }
-  }
-  if (filename == null) {
-    throw "Need file to operate on";
-  }
-  File file = new File(filename);
-  if (!file.existsSync()) throw "File $filename doesn't exist.";
-  mainUri = file.absolute.uri;
-
-  await tryToMinimize();
-}
-
-Future tryToMinimize() async {
-  // Set main to be basically empty up front.
-  fs.data[mainUri] = utf8.encode("main() {}");
-  Component initialComponent = await getInitialComponent();
-  print("Compiled initially (without data)");
-  // Remove fake cache.
-  fs.data.remove(mainUri);
-
-  // First assure it actually crash on the input.
-  if (!await crashesOnCompile(initialComponent)) {
-    throw "Input doesn't crash the compiler.";
-  }
-  print("Step #1: We did crash on the input!");
-
-  // All file should now be cached.
-  fs._redirectAndRecord = false;
-
-  // For all dart files: Parse them as set their source as the parsed source
-  // to "get around" any encoding issues when printing later.
-  Map<Uri, Uint8List> copy = new Map.from(fs.data);
-  for (Uri uri in fs.data.keys) {
-    String uriString = uri.toString();
-    if (uriString.endsWith(".json") ||
-        uriString.endsWith(".json") ||
-        uriString.endsWith(".packages") ||
-        uriString.endsWith(".dill") ||
-        fs.data[uri] == null ||
-        fs.data[uri].isEmpty) {
-      // skip
-    } else {
-      try {
-        String parsedString = getFileAsStringContent(fs.data[uri], nnbd);
-        fs.data[uri] = utf8.encode(parsedString);
-      } catch (e) {
-        // crash in scanner/parser --- keep original file. This crash might
-        // be what we're looking for!
-      }
-    }
-  }
-  if (!await crashesOnCompile(initialComponent)) {
-    // Now - for whatever reason - we didn't crash. Restore.
-    fs.data.clear();
-    fs.data.addAll(copy);
-  }
-
-  // Operate on one file at a time: Try to delete all content in file.
-  List<Uri> uris = new List<Uri>.from(fs.data.keys);
-
-  bool removedSome = true;
-  while (removedSome) {
-    while (removedSome) {
-      removedSome = false;
-      for (int i = 0; i < uris.length; i++) {
-        Uri uri = uris[i];
-        if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-        print("About to work on file $i of ${uris.length}");
-        await deleteContent(uris, i, false, initialComponent);
-        if (fs.data[uri] == null || fs.data[uri].isEmpty) removedSome = true;
-      }
-    }
-    int left = 0;
-    for (Uri uri in uris) {
-      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-      left++;
-    }
-    print("There's now $left files of ${fs.data.length} files left");
-
-    // Operate on one file at a time.
-    for (Uri uri in fs.data.keys) {
-      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-
-      print("Now working on $uri");
-
-      // Try to delete lines.
-      int prevLength = fs.data[uri].length;
-      await deleteLines(uri, initialComponent);
-      print("We're now at ${fs.data[uri].length} bytes for $uri.");
-      if (prevLength != fs.data[uri].length) removedSome = true;
-      if (fs.data[uri].isEmpty) continue;
-
-      if (byteDelete) {
-        // Now try to delete 'arbitrarily' (for any given start offset do an
-        // exponential binary search).
-        int prevLength = fs.data[uri].length;
-        while (true) {
-          await binarySearchDeleteData(uri, initialComponent);
-
-          if (fs.data[uri].length == prevLength) {
-            // No progress.
-            break;
-          } else {
-            print("We're now at ${fs.data[uri].length} bytes");
-            prevLength = fs.data[uri].length;
-            removedSome = true;
+    for (String arg in arguments) {
+      if (arg.startsWith("--")) {
+        if (arg == "--experimental-invalidation") {
+          settings.experimentalInvalidation = true;
+        } else if (arg == "--serialize") {
+          settings.serialize = true;
+        } else if (arg.startsWith("--platform=")) {
+          String platform = arg.substring("--platform=".length);
+          settings.platformUri = Uri.base.resolve(platform);
+        } else if (arg == "--no-platform") {
+          settings.noPlatform = true;
+        } else if (arg.startsWith("--invalidate=")) {
+          for (String s in arg.substring("--invalidate=".length).split(",")) {
+            settings.invalidate.add(Uri.base.resolve(s));
           }
+        } else if (arg.startsWith("--widgetTransformation")) {
+          settings.widgetTransformation = true;
+        } else if (arg.startsWith("--target=VM")) {
+          settings.targetString = "VM";
+        } else if (arg.startsWith("--target=flutter")) {
+          settings.targetString = "flutter";
+        } else if (arg.startsWith("--target=ddc")) {
+          settings.targetString = "ddc";
+        } else if (arg == "--oldBlockDelete") {
+          settings.oldBlockDelete = true;
+        } else if (arg == "--lineDelete") {
+          settings.lineDelete = true;
+        } else if (arg == "--byteDelete") {
+          settings.byteDelete = true;
+        } else if (arg == "--ask-redirect-target") {
+          settings.askAboutRedirectCrashTarget = true;
+        } else if (arg == "--auto-uncover-all-crashes") {
+          settings.autoUncoverAllCrashes = true;
+        } else if (arg.startsWith("--stack-matches=")) {
+          String stackMatches = arg.substring("--stack-matches=".length);
+          settings.stackTraceMatches = int.parse(stackMatches);
+        } else {
+          throw "Unknown option $arg";
         }
-      }
-    }
-  }
-
-  print("\n\nDONE\n\n");
-
-  for (Uri uri in uris) {
-    if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-    print("Uri $uri has this content:");
-
-    try {
-      String utfDecoded = utf8.decode(fs.data[uri], allowMalformed: true);
-      print(utfDecoded);
-    } catch (e) {
-      print(fs.data[uri]);
-      print("(which crashes when trying to decode as utf8)");
-    }
-    print("\n\n====================\n\n");
-  }
-}
-
-Uint8List sublist(Uint8List data, int start, int end) {
-  Uint8List result = new Uint8List(end - start);
-  result.setRange(0, result.length, data, start);
-  return result;
-}
-
-String dataToText(Uint8List data) {
-  StringBuffer sb = new StringBuffer();
-  String comma = "[";
-  for (int i = 0; i < data.length; i++) {
-    sb.write(comma);
-    sb.write(data[i]);
-    comma = ", ";
-    if (i > 100) break;
-  }
-  if (data.length > 100) {
-    sb.write("...");
-  }
-  sb.write("]");
-  return sb.toString();
-}
-
-void binarySearchDeleteData(Uri uri, Component initialComponent) async {
-  Uint8List latestCrashData = fs.data[uri];
-  int offset = 0;
-  while (offset < latestCrashData.length) {
-    print("Working at offset $offset of ${latestCrashData.length}");
-    BytesBuilder builder = new BytesBuilder();
-    builder.add(sublist(latestCrashData, 0, offset));
-    builder.add(sublist(latestCrashData, offset + 1, latestCrashData.length));
-    Uint8List candidate = builder.takeBytes();
-    fs.data[uri] = candidate;
-    if (!await crashesOnCompile(initialComponent)) {
-      // Deleting 1 char didn't crash; don't try to delete anymore starting
-      // here.
-      offset++;
-      continue;
-    }
-
-    // Find how long we can go.
-    int crashingAt = 1;
-    int noLongerCrashingAt;
-    while (true) {
-      int deleteChars = 2 * crashingAt;
-      if (offset + deleteChars > latestCrashData.length) {
-        deleteChars = latestCrashData.length - offset;
-      }
-      builder = new BytesBuilder();
-      builder.add(sublist(latestCrashData, 0, offset));
-      builder.add(sublist(
-          latestCrashData, offset + deleteChars, latestCrashData.length));
-      candidate = builder.takeBytes();
-      fs.data[uri] = candidate;
-      if (!await crashesOnCompile(initialComponent)) {
-        noLongerCrashingAt = deleteChars;
-        break;
-      }
-      crashingAt = deleteChars;
-      if (crashingAt + offset == latestCrashData.length) break;
-    }
-
-    if (noLongerCrashingAt == null) {
-      // We can delete the rest.
-      latestCrashData = candidate;
-      continue;
-    }
-
-    // Binary search between [crashingAt] and [noLongerCrashingAt].
-    while (crashingAt < noLongerCrashingAt) {
-      int mid = noLongerCrashingAt -
-          ((noLongerCrashingAt - crashingAt) >> 1); // Get middle, rounding up.
-      builder = new BytesBuilder();
-      builder.add(sublist(latestCrashData, 0, offset));
-      builder
-          .add(sublist(latestCrashData, offset + mid, latestCrashData.length));
-      candidate = builder.takeBytes();
-      fs.data[uri] = candidate;
-      if (await crashesOnCompile(initialComponent)) {
-        crashingAt = mid;
+      } else if (filename != null) {
+        throw "Already got '$filename', '$arg' is also a filename; "
+            "can only get one";
       } else {
-        // [noLongerCrashingAt] might actually crash now.
-        noLongerCrashingAt = mid - 1;
+        filename = arg;
       }
     }
-
-    // This is basically an assert.
-    builder = new BytesBuilder();
-    builder.add(sublist(latestCrashData, 0, offset));
-    builder.add(
-        sublist(latestCrashData, offset + crashingAt, latestCrashData.length));
-    candidate = builder.takeBytes();
-    fs.data[uri] = candidate;
-    if (!await crashesOnCompile(initialComponent)) {
-      throw "Error in binary search.";
-    }
-    latestCrashData = candidate;
-  }
-
-  fs.data[uri] = latestCrashData;
-}
-
-void _tryToRemoveUnreferencedFileContent(Component initialComponent) async {
-  // Check if there now are any unused files.
-  if (_latestComponent == null) return;
-  Set<Uri> neededUris = _latestComponent.uriToSource.keys.toSet();
-  Map<Uri, Uint8List> copy = new Map.from(fs.data);
-  bool removedSome = false;
-  for (MapEntry<Uri, Uint8List> entry in fs.data.entries) {
-    if (entry.value == null || entry.value.isEmpty) continue;
-    if (!entry.key.toString().endsWith(".dart")) continue;
-    if (!neededUris.contains(entry.key) && fs.data[entry.key].length != 0) {
-      fs.data[entry.key] = new Uint8List(0);
-      print(" => Can probably also delete ${entry.key}");
-      removedSome = true;
-    }
-  }
-  if (removedSome) {
-    if (await crashesOnCompile(initialComponent)) {
-      print(" => Yes; Could remove those too!");
-    } else {
-      print(" => No; Couldn't remove those too!");
-      fs.data.clear();
-      fs.data.addAll(copy);
-    }
-  }
-}
-
-void deleteContent(List<Uri> uris, int uriIndex, bool limitTo1,
-    Component initialComponent) async {
-  if (!limitTo1) {
-    Map<Uri, Uint8List> copy = new Map.from(fs.data);
-    // Try to remove content of i and the next 9 (10 files in total).
-    for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
-      Uri uri = uris[j];
-      fs.data[uri] = new Uint8List(0);
-    }
-    if (!await crashesOnCompile(initialComponent)) {
-      // Couldn't delete all 10 files. Restore and try the single one.
-      fs.data.clear();
-      fs.data.addAll(copy);
-    } else {
-      for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
-        Uri uri = uris[j];
-        print("Can delete all content of file $uri");
-      }
-      await _tryToRemoveUnreferencedFileContent(initialComponent);
-      return;
-    }
-  }
-
-  Uri uri = uris[uriIndex];
-  Uint8List data = fs.data[uri];
-  fs.data[uri] = new Uint8List(0);
-  if (!await crashesOnCompile(initialComponent)) {
-    print("Can't delete all content of file $uri -- keeping it (for now)");
-    fs.data[uri] = data;
-  } else {
-    print("Can delete all content of file $uri");
-    await _tryToRemoveUnreferencedFileContent(initialComponent);
-  }
-}
-
-void deleteLines(Uri uri, Component initialComponent) async {
-  // Try to delete "lines".
-  Uint8List data = fs.data[uri];
-  const int $LF = 10;
-  List<Uint8List> lines = [];
-  int start = 0;
-  for (int i = 0; i < data.length; i++) {
-    if (data[i] == $LF) {
-      lines.add(sublist(data, start, i));
-      start = i + 1;
-    }
-  }
-  lines.add(sublist(data, start, data.length));
-  List<bool> include = new List.filled(lines.length, true);
-  Uint8List latestCrashData = data;
-  int length = 1;
-  int i = 0;
-  while (i < lines.length) {
-    if (i + length > lines.length) {
-      length = lines.length - i;
-    }
-    for (int j = i; j < i + length; j++) {
-      include[j] = false;
-    }
-    final BytesBuilder builder = new BytesBuilder();
-    for (int j = 0; j < lines.length; j++) {
-      if (include[j]) {
-        builder.add(lines[j]);
-        if (j + 1 < lines.length) {
-          builder.addByte($LF);
-        }
-      }
-    }
-    Uint8List candidate = builder.takeBytes();
-    fs.data[uri] = candidate;
-    if (!await crashesOnCompile(initialComponent)) {
-      // Didn't crash => Can't remove line i-j.
-      for (int j = i; j < i + length; j++) {
-        include[j] = true;
-      }
-      if (length > 2) {
-        // Retry with length 2 at same i.
-        // The idea here is that for instance formatted json might have lines
-        // looking like
-        // {
-        // }
-        // where deleting just one line makes it invalid.
-        length = 2;
-      } else if (length > 1) {
-        // Retry with length 1 at same i.
-        length = 1;
-      } else {
-        // Couldn't with length 1 either.
+    if (settings.noPlatform) {
+      int i = 0;
+      while (settings.platformUri == null ||
+          new File.fromUri(settings.platformUri).existsSync()) {
+        settings.platformUri = Uri.base.resolve("nonexisting_$i");
         i++;
       }
     } else {
-      print("Can delete line $i (inclusive) - ${i + length} (exclusive) "
-          "(of ${lines.length})");
-      latestCrashData = candidate;
-      i += length;
-      length *= 2;
-    }
-  }
-  fs.data[uri] = latestCrashData;
-}
-
-Component _latestComponent;
-
-Future<bool> crashesOnCompile(Component initialComponent) async {
-  IncrementalCompiler incrementalCompiler;
-  if (noPlatform) {
-    incrementalCompiler = new IncrementalCompiler(setupCompilerContext());
-  } else {
-    incrementalCompiler = new IncrementalCompiler.fromComponent(
-        setupCompilerContext(), initialComponent);
-  }
-  incrementalCompiler.invalidate(mainUri);
-  try {
-    _latestComponent = await incrementalCompiler.computeDelta();
-    for (Uri uri in invalidate) {
-      incrementalCompiler.invalidate(uri);
-      await incrementalCompiler.computeDelta();
-    }
-    _latestComponent = null; // if it didn't crash this isn't relevant.
-    return false;
-  } catch (e, st) {
-    // Find line with #0 in it.
-    String eWithSt = "$e\n\n$st";
-    List<String> lines = eWithSt.split("\n");
-    String foundLine = "";
-    int lookFor = 0;
-    for (String line in lines) {
-      if (line.startsWith("#$lookFor")) {
-        foundLine += line;
-        lookFor++;
-        if (lookFor >= stackTraceMatches) {
-          break;
-        } else {
-          foundLine += "\n";
-        }
+      if (settings.platformUri == null) {
+        throw "No platform given. Use --platform=/path/to/platform.dill";
+      }
+      if (!new File.fromUri(settings.platformUri).existsSync()) {
+        throw "The platform file '${settings.platformUri}' doesn't exist";
       }
     }
-    if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
-    if (expectedCrashLine == null) {
-      print("Got '$foundLine'");
-      expectedCrashLine = foundLine;
-      return true;
-    } else if (foundLine == expectedCrashLine) {
-      return true;
-    } else {
-      print("Crashed, but another place: $foundLine");
-      if (askAboutRedirectCrashTarget &&
-          !askedAboutRedirect.contains(foundLine)) {
-        while (true) {
-          askedAboutRedirect.add(foundLine);
-          print(eWithSt);
-          print("Should we redirect to searching for that? (y/n)");
-          String answer = stdin.readLineSync();
-          if (answer == "yes" || answer == "y") {
-            expectedCrashLine = foundLine;
-            return true;
-          } else if (answer == "no" || answer == "n") {
-            break;
-          } else {
-            print("Didn't get that answer. "
-                "Please answer 'yes, 'y', 'no' or 'n'");
-          }
-        }
-      }
-      return false;
+    if (filename == null) {
+      throw "Need file to operate on";
     }
-  }
-}
-
-Future<Component> getInitialComponent() async {
-  IncrementalCompiler incrementalCompiler =
-      new IncrementalCompiler(setupCompilerContext());
-  Component originalComponent = await incrementalCompiler.computeDelta();
-  return originalComponent;
-}
-
-CompilerContext setupCompilerContext() {
-  CompilerOptions options = getOptions();
-
-  if (nnbd) {
-    options.explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
+    File file = new File(filename);
+    if (!file.existsSync()) throw "File $filename doesn't exist.";
+    settings.mainUri = file.absolute.uri;
   }
 
-  TargetFlags targetFlags = new TargetFlags(
-      enableNullSafety: nnbd, trackWidgetCreation: widgetTransformation);
-  Target target;
-  switch (targetString) {
-    case "VM":
-      target = new VmTarget(targetFlags);
-      break;
-    case "flutter":
-      target = new FlutterTarget(targetFlags);
-      break;
-    case "ddc":
-      target = new DevCompilerTarget(targetFlags);
-      break;
-    default:
-      throw "Unknown target '$target'";
-  }
-  options.target = target;
-  options.fileSystem = fs;
-  options.sdkRoot = null;
-  options.sdkSummary = platformUri;
-  options.omitPlatform = false;
-  options.onDiagnostic = (DiagnosticMessage message) {
-    // don't care.
-  };
-  if (noPlatform) {
-    options.librariesSpecificationUri = null;
-  }
-
-  CompilerContext compilerContext = new CompilerContext(
-      new ProcessedOptions(options: options, inputs: [mainUri]));
-  return compilerContext;
-}
-
-String getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
-  List<int> lineStarts = new List<int>();
-
-  Token firstToken = parser_suite.scanRawBytes(rawBytes,
-      nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
-
-  if (firstToken == null) {
-    throw "Got null token from scanner";
-  }
-
-  ParserTestListener parserTestListener = new ParserTestListener(false);
-  Parser parser = new Parser(parserTestListener);
-  parser.parseUnit(firstToken);
-  String parsedString =
-      parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
-  return parsedString;
-}
-
-ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
-    enableTripleShift: true,
-    enableExtensionMethods: true,
-    enableNonNullable: true);
-
-ScannerConfiguration scannerConfigurationNonNNBD = new ScannerConfiguration(
-    enableTripleShift: true,
-    enableExtensionMethods: true,
-    enableNonNullable: false);
-
-class FakeFileSystem extends FileSystem {
-  bool _redirectAndRecord = true;
-  final Map<Uri, Uint8List> data = {};
-
-  @override
-  FileSystemEntity entityForUri(Uri uri) {
-    return new FakeFileSystemEntity(this, uri);
-  }
-}
-
-class FakeFileSystemEntity extends FileSystemEntity {
-  final FakeFileSystem fs;
-  final Uri uri;
-  FakeFileSystemEntity(this.fs, this.uri);
-
-  void _ensureCachedIfOk() {
-    if (fs.data.containsKey(uri)) return;
-    if (!fs._redirectAndRecord) {
-      throw "Asked for file in non-recording mode that wasn't known";
-    }
-    File f = new File.fromUri(uri);
-    if (!f.existsSync()) {
-      fs.data[uri] = null;
-      return;
-    }
-    fs.data[uri] = f.readAsBytesSync();
-  }
-
-  @override
-  Future<bool> exists() {
-    _ensureCachedIfOk();
-    Uint8List data = fs.data[uri];
-    if (data == null) return Future.value(false);
-    return Future.value(true);
-  }
-
-  @override
-  Future<List<int>> readAsBytes() {
-    _ensureCachedIfOk();
-    Uint8List data = fs.data[uri];
-    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
-    return Future.value(data);
-  }
-
-  @override
-  Future<String> readAsString() {
-    _ensureCachedIfOk();
-    Uint8List data = fs.data[uri];
-    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
-    return Future.value(utf8.decode(data));
-  }
+  TestMinimizer testMinimizer = new TestMinimizer(settings);
+  await testMinimizer.tryToMinimize();
 }
diff --git a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
new file mode 100644
index 0000000..8bda7f4
--- /dev/null
+++ b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
@@ -0,0 +1,2102 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async' show Future, StreamSubscription;
+
+import 'dart:convert' show JsonEncoder, jsonDecode, utf8;
+
+import 'dart:io' show BytesBuilder, File, stdin, stdout;
+
+import 'dart:math' show max;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:_fe_analyzer_shared/src/util/relativize.dart'
+    show relativizeUri, isWindows;
+
+import 'package:_fe_analyzer_shared/src/parser/parser.dart'
+    show Listener, Parser;
+
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ErrorToken, ScannerConfiguration, Token;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, DiagnosticMessage;
+
+import 'package:front_end/src/api_prototype/experimental_flags.dart'
+    show ExperimentalFlag;
+
+import 'package:front_end/src/api_prototype/file_system.dart'
+    show FileSystem, FileSystemEntity, FileSystemException;
+
+import 'package:front_end/src/base/processed_options.dart'
+    show ProcessedOptions;
+import 'package:front_end/src/fasta/builder/library_builder.dart';
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+    show IncrementalCompiler;
+
+import 'package:front_end/src/fasta/kernel/utils.dart' show ByteSink;
+import 'package:front_end/src/fasta/messages.dart' show Message;
+import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
+
+import 'package:front_end/src/fasta/util/textual_outline.dart'
+    show textualOutline;
+
+import 'package:kernel/ast.dart' show Component;
+
+import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
+
+import 'package:kernel/target/targets.dart' show Target, TargetFlags;
+import 'package:package_config/package_config.dart';
+
+import "package:vm/target/flutter.dart" show FlutterTarget;
+
+import "package:vm/target/vm.dart" show VmTarget;
+
+import 'incremental_load_from_dill_suite.dart' show getOptions;
+
+import 'parser_test_listener.dart' show ParserTestListener;
+
+import 'parser_suite.dart' as parser_suite;
+
+class TestMinimizerSettings {
+  final _FakeFileSystem _fsInitial = new _FakeFileSystem();
+  final _FakeFileSystem _fsNotInitial = new _FakeFileSystem();
+  _FakeFileSystem get _fs {
+    if (_useInitialFs) return _fsInitial;
+    return _fsNotInitial;
+  }
+
+  bool _useInitialFs = true;
+  Uri mainUri;
+  Uri platformUri;
+  bool noPlatform = false;
+  bool experimentalInvalidation = false;
+  bool serialize = false;
+  bool widgetTransformation = false;
+  final List<Uri> invalidate = [];
+  String targetString = "VM";
+  bool oldBlockDelete = false;
+  bool lineDelete = false;
+  bool byteDelete = false;
+  bool askAboutRedirectCrashTarget = false;
+  bool autoUncoverAllCrashes = false;
+  int stackTraceMatches = 1;
+  final Set<String> askedAboutRedirect = {};
+  final List<Map<String, dynamic>> fileSystems = [];
+  final Set<String> allAutoRedirects = {};
+
+  void goToFileSystem(int i) {
+    Map<String, dynamic> fileSystem = fileSystems[i];
+    fileSystems[i] = _fsNotInitial.toJson();
+    _fsNotInitial.initializeFromJson(fileSystem);
+  }
+
+  Map<String, dynamic> toJson() {
+    List<Map<String, dynamic>> fileSystems =
+        new List<Map<String, dynamic>>.from(this.fileSystems);
+    fileSystems.add(_fsNotInitial.toJson());
+    return {
+      'mainUri': mainUri.toString(),
+      'platformUri': platformUri.toString(),
+      'noPlatform': noPlatform,
+      'experimentalInvalidation': experimentalInvalidation,
+      'serialize': serialize,
+      'widgetTransformation': widgetTransformation,
+      'invalidate': invalidate.map((uri) => uri.toString()).toList(),
+      'targetString': targetString,
+      'oldBlockDelete': oldBlockDelete,
+      'lineDelete': lineDelete,
+      'byteDelete': byteDelete,
+      'askAboutRedirectCrashTarget': askAboutRedirectCrashTarget,
+      'autoUncoverAllCrashes': autoUncoverAllCrashes,
+      'stackTraceMatches': stackTraceMatches,
+      'askedAboutRedirect': askedAboutRedirect.toList(),
+      'fileSystems': fileSystems,
+      'allAutoRedirects': allAutoRedirects.toList(),
+    };
+  }
+
+  initializeFromJson(Map<String, dynamic> json) {
+    mainUri = Uri.parse(json["mainUri"]);
+    platformUri = Uri.parse(json["platformUri"]);
+    noPlatform = json["noPlatform"];
+    experimentalInvalidation = json["experimentalInvalidation"];
+    serialize = json["serialize"];
+    widgetTransformation = json["widgetTransformation"];
+    invalidate.clear();
+    invalidate.addAll(
+        (json["invalidate"] as List).map((uriString) => Uri.parse(uriString)));
+    targetString = json["targetString"];
+    oldBlockDelete = json["oldBlockDelete"];
+    lineDelete = json["lineDelete"];
+    byteDelete = json["byteDelete"];
+    askAboutRedirectCrashTarget = json["askAboutRedirectCrashTarget"];
+    autoUncoverAllCrashes = json["autoUncoverAllCrashes"];
+    stackTraceMatches = json["stackTraceMatches"];
+    askedAboutRedirect.clear();
+    askedAboutRedirect.addAll((json["askedAboutRedirect"] as List).cast());
+    fileSystems.clear();
+    fileSystems.addAll((json["fileSystems"] as List).cast());
+    allAutoRedirects.clear();
+    allAutoRedirects.addAll((json["allAutoRedirects"] as List).cast());
+
+    _fsNotInitial.initializeFromJson(fileSystems.removeLast());
+  }
+}
+
+class TestMinimizer {
+  final TestMinimizerSettings _settings;
+  _FakeFileSystem get _fs => _settings._fs;
+  Uri get _mainUri => _settings.mainUri;
+  String _expectedCrashLine;
+  bool _quit = false;
+  bool _skip = false;
+  bool _check = false;
+  int _currentFsNum = -1;
+
+  Component _latestComponent;
+  IncrementalCompiler _latestCrashingIncrementalCompiler;
+  StreamSubscription<List<int>> _stdinSubscription;
+
+  static const int _$LF = 10;
+
+  TestMinimizer(this._settings);
+
+  void _setupStdin() {
+    try {
+      stdin.echoMode = false;
+      stdin.lineMode = false;
+    } catch (e) {
+      print("error setting settings on stdin");
+    }
+    _stdinSubscription = stdin.listen((List<int> event) {
+      if (event.length == 1 && event.single == "q".codeUnits.single) {
+        print("\n\nGot told to quit!\n\n");
+        _quit = true;
+      } else if (event.length == 1 && event.single == "s".codeUnits.single) {
+        print("\n\nGot told to skip!\n\n");
+        _skip = true;
+      } else if (event.length == 1 && event.single == "c".codeUnits.single) {
+        print("\n\nGot told to check!\n\n");
+        _check = true;
+      } else if (event.length == 1 && event.single == "i".codeUnits.single) {
+        print("\n\n--- STATUS INFORMATION START ---\n\n");
+        print("Currently looking for this crash: $_expectedCrashLine\n\n");
+        print("Currently on filesystem #$_currentFsNum out of "
+            "${_settings.fileSystems.length}\n\n");
+
+        int totalFiles = 0;
+        int emptyFiles = 0;
+        int combinedSize = 0;
+        for (Uri uri in _fs.data.keys) {
+          final Uint8List originalBytes = _fs.data[uri];
+          if (originalBytes == null) continue;
+          totalFiles++;
+          if (originalBytes.isEmpty) emptyFiles++;
+          combinedSize += originalBytes.length;
+        }
+        print("Total files left: $totalFiles.");
+        print("Of which empty: $emptyFiles.");
+        print("Combined size left: $combinedSize bytes.");
+        print("\n\n--- STATUS INFORMATION END ---\n\n");
+      } else {
+        print("\n\nGot stdin input: $event\n\n");
+      }
+    });
+  }
+
+  Future tryToMinimize() async {
+    _setupStdin();
+    while (_currentFsNum < _settings.fileSystems.length) {
+      try {
+        if (_currentFsNum >= 0) {
+          print("Replacing filesystem!");
+          _settings.goToFileSystem(_currentFsNum);
+          _expectedCrashLine = null;
+          _latestComponent = null;
+          _latestCrashingIncrementalCompiler = null;
+        }
+        await _tryToMinimizeImpl();
+        if (_currentFsNum + 1 < _settings.fileSystems.length) {
+          // We have more to do --- but we just printed something the user might
+          // want to read. So wait a little before continuing.
+          print("Waiting for 5 seconds before continuing.");
+          await Future.delayed(new Duration(seconds: 5));
+        }
+      } catch (e) {
+        if (e is _DoesntCrashOnInput) {
+          print("Currently doesn't crash (or no longer crashes) the compiler.");
+        } else {
+          print("About to crash. Dumping settings including the filesystem so "
+              "we can (hopefully) continue later.");
+          _dumpToJson();
+          rethrow;
+        }
+      }
+      _currentFsNum++;
+    }
+
+    await _stdinSubscription.cancel();
+  }
+
+  Future _tryToMinimizeImpl() async {
+    // Set main to be basically empty up front.
+    _settings._useInitialFs = true;
+    _fs.data[_mainUri] = utf8.encode("main() {}");
+    Component initialComponent = await _getInitialComponent();
+    print("Compiled initially (without data)");
+    // Remove fake cache.
+    _fs.data.remove(_mainUri);
+    _settings._useInitialFs = false;
+
+    // First assure it actually crash on the input.
+    if (!await _crashesOnCompile(initialComponent)) {
+      throw new _DoesntCrashOnInput();
+    }
+    print("Step #1: We did crash on the input!");
+
+    // All file should now be cached.
+    _fs._redirectAndRecord = false;
+
+    // For all dart files: Parse them as set their source as the parsed source
+    // to "get around" any encoding issues when printing later.
+    Map<Uri, Uint8List> copy = new Map.from(_fs.data);
+    for (Uri uri in _fs.data.keys) {
+      if (await _shouldQuit()) break;
+      String uriString = uri.toString();
+      if (uriString.endsWith(".json") ||
+          uriString.endsWith(".packages") ||
+          uriString.endsWith(".dill") ||
+          _fs.data[uri] == null ||
+          _fs.data[uri].isEmpty) {
+        // skip
+      } else {
+        try {
+          if (_knownByCompiler(uri)) {
+            String parsedString =
+                _getFileAsStringContent(_fs.data[uri], _isUriNnbd(uri));
+            _fs.data[uri] = utf8.encode(parsedString);
+          }
+        } catch (e) {
+          // crash in scanner/parser --- keep original file. This crash might
+          // be what we're looking for!
+        }
+      }
+    }
+    if (!await _crashesOnCompile(initialComponent)) {
+      // Now - for whatever reason - we didn't crash. Restore.
+      _fs.data.clear();
+      _fs.data.addAll(copy);
+    }
+
+    // Operate on one file at a time: Try to delete all content in file.
+    List<Uri> uris = new List<Uri>.from(_fs.data.keys);
+
+    // TODO(jensj): Can we "thread" this?
+    bool changedSome = true;
+    while (changedSome) {
+      if (await _shouldQuit()) break;
+      while (changedSome) {
+        if (await _shouldQuit()) break;
+        changedSome = false;
+        for (int i = 0; i < uris.length; i++) {
+          if (await _shouldQuit()) break;
+          Uri uri = uris[i];
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+          print("About to work on file $i of ${uris.length}");
+          await _deleteContent(uris, i, false, initialComponent);
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) {
+            changedSome = true;
+          }
+        }
+      }
+
+      // Try to delete empty files.
+      bool changedSome2 = true;
+      while (changedSome2) {
+        if (await _shouldQuit()) break;
+        changedSome2 = false;
+        for (int i = 0; i < uris.length; i++) {
+          if (await _shouldQuit()) break;
+          Uri uri = uris[i];
+          if (_fs.data[uri] == null || _fs.data[uri].isNotEmpty) continue;
+          print("About to work on file $i of ${uris.length}");
+          await _deleteContent(uris, i, false, initialComponent,
+              deleteFile: true);
+          if (_fs.data[uri] == null) {
+            changedSome = true;
+            changedSome2 = true;
+          }
+        }
+      }
+
+      int left = 0;
+      for (Uri uri in uris) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        left++;
+      }
+      print("There's now $left files of ${_fs.data.length} files left");
+
+      // Operate on one file at a time.
+      for (Uri uri in _fs.data.keys) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        if (await _shouldQuit()) break;
+
+        if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+          if (await _shouldQuit()) break;
+        }
+
+        if (_check) {
+          _check = false;
+          if (!await _crashesOnCompile(initialComponent)) {
+            throw "Check revealed that the current file system doesn't crash.";
+          } else {
+            print("Check OK!");
+          }
+        }
+
+        print("Now working on $uri");
+
+        int prevLength = _fs.data[uri].length;
+
+        await _deleteBlocks(uri, initialComponent);
+        await _deleteEmptyLines(uri, initialComponent);
+
+        if (_settings.oldBlockDelete) {
+          // Try to delete blocks.
+          await _deleteBlocksOld(uri, initialComponent);
+        }
+
+        if (_settings.lineDelete) {
+          // Try to delete lines.
+          await _deleteLines(uri, initialComponent);
+        }
+
+        print("We're now at ${_fs.data[uri].length} bytes for $uri "
+            "(was $prevLength).");
+        if (prevLength != _fs.data[uri].length) changedSome = true;
+        if (_fs.data[uri].isEmpty) continue;
+
+        if (_settings.byteDelete) {
+          // Now try to delete 'arbitrarily' (for any given start offset do an
+          // exponential binary search).
+          int prevLength = _fs.data[uri].length;
+          while (true) {
+            if (await _shouldQuit()) break;
+            await _binarySearchDeleteData(uri, initialComponent);
+
+            if (_fs.data[uri].length == prevLength) {
+              // No progress.
+              break;
+            } else {
+              print("We're now at ${_fs.data[uri].length} bytes");
+              prevLength = _fs.data[uri].length;
+              changedSome = true;
+            }
+          }
+        }
+      }
+      for (Uri uri in _fs.data.keys) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        if (await _shouldQuit()) break;
+
+        if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+          if (await _shouldQuit()) break;
+        }
+
+        if (await _attemptInline(uri, initialComponent)) {
+          changedSome = true;
+
+          if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
+            if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+            if (await _shouldQuit()) break;
+          }
+        }
+      }
+    }
+
+    if (await _shouldQuit()) {
+      print("\n\nASKED TO QUIT\n\n");
+    } else {
+      print("\n\nDONE\n\n");
+    }
+
+    Uri jsonOut = _dumpToJson();
+
+    if (!await _shouldQuit()) {
+      // Test converting to incremental compiler yaml test.
+      _outputIncrementalCompilerYamlTest();
+      print("\n\n\n");
+
+      for (Uri uri in uris) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        print("Uri $uri has this content:");
+
+        try {
+          String utfDecoded = utf8.decode(_fs.data[uri], allowMalformed: true);
+          print(utfDecoded);
+        } catch (e) {
+          print(_fs.data[uri]);
+          print("(which crashes when trying to decode as utf8)");
+        }
+        print("\n\n====================\n\n");
+      }
+
+      print("Wrote json dump to $jsonOut");
+    }
+  }
+
+  Future<bool> _shouldQuit() async {
+    // allow some time for stdin.listen to process data.
+    await new Future.delayed(new Duration(milliseconds: 5));
+    return _quit;
+  }
+
+  Uri _dumpToJson() {
+    JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
+    String json = jsonEncoder.convert(_settings);
+    int i = 0;
+    Uri jsonOut;
+    while (jsonOut == null || new File.fromUri(jsonOut).existsSync()) {
+      jsonOut = Uri.base.resolve("crash_minimizer_result_$i");
+      i++;
+    }
+    new File.fromUri(jsonOut).writeAsStringSync(json);
+    print("Wrote json dump to $jsonOut");
+    return jsonOut;
+  }
+
+  /// Attempts to inline small files in other files.
+  /// Returns true if anything was changed, i.e. if at least one inlining was a
+  /// success.
+  Future<bool> _attemptInline(Uri uri, Component initialComponent) async {
+    // Don't attempt to inline the main uri --- that's our entry!
+    if (uri == _mainUri) return false;
+
+    Uint8List inlineData = _fs.data[uri];
+    bool hasMultipleLines = false;
+    for (int i = 0; i < inlineData.length; i++) {
+      if (inlineData[i] == _$LF) {
+        hasMultipleLines = true;
+        break;
+      }
+    }
+    // TODO(jensj): Maybe inline slightly bigger files too?
+    if (hasMultipleLines) {
+      return false;
+    }
+
+    Uri inlinableUri = uri;
+
+    int compileTry = 0;
+    bool changed = false;
+
+    for (Uri uri in _fs.data.keys) {
+      if (!uri.toString().endsWith(".dart")) continue;
+      if (inlinableUri == uri) continue;
+      final Uint8List originalBytes = _fs.data[uri];
+      if (originalBytes == null || originalBytes.isEmpty) continue;
+      DirectParserASTContentCompilationUnitEnd ast = getAST(originalBytes,
+          includeBody: false,
+          includeComments: false,
+          enableExtensionMethods: true,
+          enableNonNullable: _isUriNnbd(uri));
+      // Find all imports/exports of this file (if any).
+      // If finding any:
+      // * remove all of them, then
+      // * find the end of the last import/export, and
+      // * insert the content of the file there.
+      // * if that *doesn't* work and we've inserted an export,
+      //   try converting that to an import instead.
+      List<_Replacement> replacements = [];
+      for (DirectParserASTContentImportEnd import in ast.getImports()) {
+        Token importUriToken = import.importKeyword.next;
+        Uri importUri = _getUri(importUriToken, uri);
+        if (inlinableUri == importUri) {
+          replacements.add(new _Replacement(
+              import.importKeyword.offset - 1, import.semicolon.offset + 1));
+        }
+      }
+      for (DirectParserASTContentExportEnd export in ast.getExports()) {
+        Token exportUriToken = export.exportKeyword.next;
+        Uri exportUri = _getUri(exportUriToken, uri);
+        if (inlinableUri == exportUri) {
+          replacements.add(new _Replacement(
+              export.exportKeyword.offset - 1, export.semicolon.offset + 1));
+        }
+      }
+      if (replacements.isEmpty) continue;
+
+      // Step 1: Remove all imports/exports *of* this file (the inlinable file).
+      final Uint8List withoutInlineable =
+          _replaceRange(replacements, originalBytes);
+
+      // Step 2: Find the last import/export.
+      int offsetOfLast = 0;
+      ast = getAST(withoutInlineable,
+          includeBody: false,
+          includeComments: false,
+          enableExtensionMethods: true,
+          enableNonNullable: _isUriNnbd(uri));
+      for (DirectParserASTContentImportEnd import in ast.getImports()) {
+        offsetOfLast = max(offsetOfLast, import.semicolon.offset + 1);
+      }
+      for (DirectParserASTContentExportEnd export in ast.getExports()) {
+        offsetOfLast = max(offsetOfLast, export.semicolon.offset + 1);
+      }
+
+      // Step 3: Insert the content of the file there. Note, though,
+      // that any imports/exports in _that_ file should be changed to be valid
+      // in regards to the new placement.
+      final String withoutInlineableString = utf8.decode(withoutInlineable);
+      StringBuffer builder = new StringBuffer();
+      for (int i = 0; i < offsetOfLast; i++) {
+        builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+      }
+      builder.write("\n");
+      builder.write(utf8.decode(_rewriteImportsExportsToUri(
+          inlineData, uri, inlinableUri, _isUriNnbd(inlinableUri))));
+      builder.write("\n");
+      for (int i = offsetOfLast; i < withoutInlineableString.length; i++) {
+        builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+      }
+      final Uint8List inlinedWithoutChange = utf8.encode(builder.toString());
+
+      if (!_parsesWithoutError(inlinedWithoutChange, _isUriNnbd(uri))) {
+        print("WARNING: Parser error after stuff at ${StackTrace.current}");
+      }
+
+      // Step 4: Try it out.
+      if (await _shouldQuit()) break;
+      if (_skip) {
+        _skip = false;
+        break;
+      }
+      stdout.write(".");
+      compileTry++;
+      if (compileTry % 50 == 0) {
+        stdout.write("(at $compileTry)\n");
+      }
+      _fs.data[uri] = inlinedWithoutChange;
+      if (await _crashesOnCompile(initialComponent)) {
+        print("Could inline $inlinableUri into $uri.");
+        changed = true;
+        // File was already updated.
+      } else {
+        // Couldn't replace that.
+        // Insert the original again.
+        _fs.data[uri] = originalBytes;
+
+        // If we've inlined an export, try changing that to an import.
+        builder = new StringBuffer();
+        for (int i = 0; i < offsetOfLast; i++) {
+          builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+        }
+        builder.write("\n");
+        builder.write(utf8.decode(_rewriteImportsExportsToUri(
+            inlineData, uri, inlinableUri, _isUriNnbd(inlinableUri),
+            convertExportToImport: true)));
+        builder.write("\n");
+        for (int i = offsetOfLast; i < withoutInlineableString.length; i++) {
+          builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+        }
+        Uint8List inlinedWithChange = utf8.encode(builder.toString());
+
+        if (!_parsesWithoutError(inlinedWithChange, _isUriNnbd(uri))) {
+          print("WARNING: Parser error after stuff at ${StackTrace.current}");
+        }
+
+        // Step 4: Try it out.
+        if (await _shouldQuit()) break;
+        if (_skip) {
+          _skip = false;
+          break;
+        }
+        stdout.write(".");
+        compileTry++;
+        if (compileTry % 50 == 0) {
+          stdout.write("(at $compileTry)\n");
+        }
+        _fs.data[uri] = inlinedWithChange;
+        if (await _crashesOnCompile(initialComponent)) {
+          print("Could inline $inlinableUri into $uri "
+              "(by converting export to import).");
+          changed = true;
+          // File was already updated.
+        } else {
+          // Couldn't replace that.
+          // Insert the original again.
+          _fs.data[uri] = originalBytes;
+        }
+      }
+    }
+
+    return changed;
+  }
+
+  Uint8List _rewriteImportsExportsToUri(
+      Uint8List oldData, Uri newUri, Uri oldUri, bool nnbd,
+      {bool convertExportToImport: false}) {
+    DirectParserASTContentCompilationUnitEnd ast = getAST(oldData,
+        includeBody: false,
+        includeComments: false,
+        enableExtensionMethods: true,
+        enableNonNullable: nnbd);
+    List<_Replacement> replacements = [];
+    for (DirectParserASTContentImportEnd import in ast.getImports()) {
+      _rewriteImportsExportsToUriInternal(
+          import.importKeyword.next, oldUri, replacements, newUri);
+    }
+    for (DirectParserASTContentExportEnd export in ast.getExports()) {
+      if (convertExportToImport) {
+        replacements.add(new _Replacement(
+          export.exportKeyword.offset - 1,
+          export.exportKeyword.offset + export.exportKeyword.length,
+          nullOrReplacement: "import",
+        ));
+      }
+      _rewriteImportsExportsToUriInternal(
+          export.exportKeyword.next, oldUri, replacements, newUri);
+    }
+    if (replacements.isNotEmpty) {
+      Uint8List candidate = _replaceRange(replacements, oldData);
+      return candidate;
+    }
+    return oldData;
+  }
+
+  void _outputIncrementalCompilerYamlTest() {
+    int dartFiles = 0;
+    for (MapEntry<Uri, Uint8List> entry in _fs.data.entries) {
+      if (entry.key.pathSegments.last.endsWith(".dart")) {
+        if (entry.value != null) dartFiles++;
+      }
+    }
+
+    print("------ Reproduction as semi-done incremental yaml test file ------");
+
+    // TODO(jensj): don't use full uris.
+    print("""
+        # Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+        # for details. All rights reserved. Use of this source code is governed by a
+        # BSD-style license that can be found in the LICENSE.md file.
+        
+        # Reproduce a crash.
+        
+        type: newworld""");
+    if (_settings.widgetTransformation) {
+      print("trackWidgetCreation: true");
+      print("target: DDC # basically needed for widget creation to be run");
+    }
+    print("""
+        worlds:
+          - entry: $_mainUri""");
+    if (_settings.experimentalInvalidation) {
+      print("    experiments: alternative-invalidation-strategy");
+    }
+    print("    sources:");
+    for (MapEntry<Uri, Uint8List> entry in _fs.data.entries) {
+      if (entry.value == null) continue;
+      print("      ${entry.key}: |");
+      String string = utf8.decode(entry.value);
+      List<String> lines = string.split("\n");
+      for (String line in lines) {
+        print("        $line");
+      }
+    }
+    print("    expectedLibraryCount: $dartFiles "
+        "# with parts this is not right");
+    print("");
+
+    for (Uri uri in _settings.invalidate) {
+      print("  - entry: $_mainUri");
+      if (_settings.experimentalInvalidation) {
+        print("    experiments: alternative-invalidation-strategy");
+      }
+      print("    worldType: updated");
+      print("    expectInitializeFromDill: false # or true?");
+      print("    invalidate:");
+      print("      - $uri");
+      print("    expectedLibraryCount: $dartFiles "
+          "# with parts this is not right");
+      print("    expectsRebuildBodiesOnly: true # or false?");
+      print("");
+    }
+
+    print("------------------------------------------------------------------");
+  }
+
+  void _rewriteImportsExportsToUriInternal(
+      Token uriToken, Uri oldUri, List<_Replacement> replacements, Uri newUri) {
+    Uri tokenUri = _getUri(uriToken, oldUri, resolvePackage: false);
+    if (tokenUri.scheme == "package" || tokenUri.scheme == "dart") return;
+    Uri asPackageUri = _getImportUri(tokenUri);
+    if (asPackageUri.scheme == "package") {
+      // Just replace with this package uri.
+      replacements.add(new _Replacement(
+        uriToken.offset - 1,
+        uriToken.offset + uriToken.length,
+        nullOrReplacement: '"${asPackageUri.toString()}"',
+      ));
+    } else {
+      String relative = relativizeUri(newUri, tokenUri, isWindows);
+      // TODO(jensj): Maybe if the relative uri becomes too long or has to many
+      // "../../" etc we should just use the absolute uri instead.
+      replacements.add(new _Replacement(
+        uriToken.offset - 1,
+        uriToken.offset + uriToken.length,
+        nullOrReplacement: '"${relative}"',
+      ));
+    }
+  }
+
+  Uri _getUri(Token uriToken, Uri uri, {bool resolvePackage: true}) {
+    String uriString = uriToken.lexeme;
+    uriString = uriString.substring(1, uriString.length - 1);
+    Uri uriTokenUri = uri.resolve(uriString);
+    if (resolvePackage && uriTokenUri.scheme == "package") {
+      Package package = _latestCrashingIncrementalCompiler
+          .currentPackagesMap[uriTokenUri.pathSegments.first];
+      uriTokenUri = package.packageUriRoot
+          .resolve(uriTokenUri.pathSegments.skip(1).join("/"));
+    }
+    return uriTokenUri;
+  }
+
+  Uri _getImportUri(Uri uri) {
+    return _latestCrashingIncrementalCompiler.userCode
+        .getEntryPointUri(uri, issueProblem: false);
+  }
+
+  Uint8List _sublist(Uint8List data, int start, int end) {
+    Uint8List result = new Uint8List(end - start);
+    result.setRange(0, result.length, data, start);
+    return result;
+  }
+
+  void _binarySearchDeleteData(Uri uri, Component initialComponent) async {
+    Uint8List latestCrashData = _fs.data[uri];
+    int offset = 0;
+    while (offset < latestCrashData.length) {
+      print("Working at offset $offset of ${latestCrashData.length}");
+      BytesBuilder builder = new BytesBuilder();
+      builder.add(_sublist(latestCrashData, 0, offset));
+      builder
+          .add(_sublist(latestCrashData, offset + 1, latestCrashData.length));
+      Uint8List candidate = builder.takeBytes();
+      _fs.data[uri] = candidate;
+      if (!await _crashesOnCompile(initialComponent)) {
+        // Deleting 1 char didn't crash; don't try to delete anymore starting
+        // here.
+        offset++;
+        continue;
+      }
+
+      // Find how long we can go.
+      int crashingAt = 1;
+      int noLongerCrashingAt;
+      while (true) {
+        int deleteChars = 2 * crashingAt;
+        if (offset + deleteChars > latestCrashData.length) {
+          deleteChars = latestCrashData.length - offset;
+        }
+        builder = new BytesBuilder();
+        builder.add(_sublist(latestCrashData, 0, offset));
+        builder.add(_sublist(
+            latestCrashData, offset + deleteChars, latestCrashData.length));
+        candidate = builder.takeBytes();
+        _fs.data[uri] = candidate;
+        if (!await _crashesOnCompile(initialComponent)) {
+          noLongerCrashingAt = deleteChars;
+          break;
+        }
+        crashingAt = deleteChars;
+        if (crashingAt + offset == latestCrashData.length) break;
+      }
+
+      if (noLongerCrashingAt == null) {
+        // We can delete the rest.
+        latestCrashData = candidate;
+        continue;
+      }
+
+      // Binary search between [crashingAt] and [noLongerCrashingAt].
+      while (crashingAt < noLongerCrashingAt) {
+        int mid = noLongerCrashingAt -
+            ((noLongerCrashingAt - crashingAt) >>
+                1); // Get middle, rounding up.
+        builder = new BytesBuilder();
+        builder.add(_sublist(latestCrashData, 0, offset));
+        builder.add(
+            _sublist(latestCrashData, offset + mid, latestCrashData.length));
+        candidate = builder.takeBytes();
+        _fs.data[uri] = candidate;
+        if (await _crashesOnCompile(initialComponent)) {
+          crashingAt = mid;
+        } else {
+          // [noLongerCrashingAt] might actually crash now.
+          noLongerCrashingAt = mid - 1;
+        }
+      }
+
+      // This is basically an assert.
+      builder = new BytesBuilder();
+      builder.add(_sublist(latestCrashData, 0, offset));
+      builder.add(_sublist(
+          latestCrashData, offset + crashingAt, latestCrashData.length));
+      candidate = builder.takeBytes();
+      _fs.data[uri] = candidate;
+      if (!await _crashesOnCompile(initialComponent)) {
+        throw "Error in binary search.";
+      }
+      latestCrashData = candidate;
+    }
+
+    _fs.data[uri] = latestCrashData;
+  }
+
+  void _tryToRemoveUnreferencedFileContent(Component initialComponent,
+      {bool deleteFile: false}) async {
+    // Check if there now are any unused files.
+    if (_latestComponent == null) return;
+    Set<Uri> neededUris = _latestComponent.uriToSource.keys.toSet();
+    Map<Uri, Uint8List> copy = new Map.from(_fs.data);
+    bool removedSome = false;
+    if (await _shouldQuit()) return;
+    for (MapEntry<Uri, Uint8List> entry in _fs.data.entries) {
+      if (entry.value == null || entry.value.isEmpty) continue;
+      if (!entry.key.toString().endsWith(".dart")) continue;
+      if (!neededUris.contains(entry.key) && _fs.data[entry.key].length != 0) {
+        if (deleteFile) {
+          _fs.data[entry.key] = null;
+        } else {
+          _fs.data[entry.key] = new Uint8List(0);
+        }
+        print(" => Can probably also delete ${entry.key}");
+        removedSome = true;
+      }
+    }
+    if (removedSome) {
+      if (await _crashesOnCompile(initialComponent)) {
+        print(" => Yes; Could remove those too!");
+      } else {
+        print(" => No; Couldn't remove those too!");
+        _fs.data.clear();
+        _fs.data.addAll(copy);
+      }
+    }
+  }
+
+  void _deleteContent(
+      List<Uri> uris, int uriIndex, bool limitTo1, Component initialComponent,
+      {bool deleteFile: false}) async {
+    String extraMessageText = "all content of ";
+    if (deleteFile) extraMessageText = "";
+
+    if (!limitTo1) {
+      if (await _shouldQuit()) return;
+      Map<Uri, Uint8List> copy = new Map.from(_fs.data);
+      // Try to remove content of i and the next 9 (10 files in total).
+      for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+        Uri uri = uris[j];
+        if (deleteFile) {
+          _fs.data[uri] = null;
+        } else {
+          _fs.data[uri] = new Uint8List(0);
+        }
+      }
+      if (!await _crashesOnCompile(initialComponent)) {
+        // Couldn't delete all 10 files. Restore and try the single one.
+        _fs.data.clear();
+        _fs.data.addAll(copy);
+      } else {
+        for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+          Uri uri = uris[j];
+          print("Can delete ${extraMessageText}file $uri");
+        }
+        await _tryToRemoveUnreferencedFileContent(initialComponent,
+            deleteFile: deleteFile);
+        return;
+      }
+    }
+
+    if (await _shouldQuit()) return;
+    Uri uri = uris[uriIndex];
+    Uint8List data = _fs.data[uri];
+    if (deleteFile) {
+      _fs.data[uri] = null;
+    } else {
+      _fs.data[uri] = new Uint8List(0);
+    }
+    if (!await _crashesOnCompile(initialComponent)) {
+      print(
+          "Can't delete ${extraMessageText}file $uri -- keeping it (for now)");
+      _fs.data[uri] = data;
+
+      // For dart files we can't truncate completely try to "outline" them
+      // instead.
+      if (uri.toString().endsWith(".dart")) {
+        String textualOutlined =
+            textualOutline(data)?.replaceAll(RegExp(r'\n+'), "\n");
+
+        bool outlined = false;
+        if (textualOutlined != null) {
+          Uint8List candidate = utf8.encode(textualOutlined);
+          // Because textual outline doesn't do the right thing for nnbd, only
+          // replace if it's syntactically valid.
+          if (candidate.length != _fs.data[uri].length &&
+              _parsesWithoutError(candidate, _isUriNnbd(uri))) {
+            if (await _shouldQuit()) return;
+            _fs.data[uri] = candidate;
+            if (!await _crashesOnCompile(initialComponent)) {
+              print("Can't outline the file $uri -- keeping it (for now)");
+              _fs.data[uri] = data;
+            } else {
+              outlined = true;
+              print("Can outline the file $uri "
+                  "(now ${_fs.data[uri].length} bytes)");
+            }
+          }
+        }
+        if (!outlined) {
+          // We can probably at least remove all comments then...
+          try {
+            List<String> strings = utf8.decode(_fs.data[uri]).split("\n");
+            List<String> stringsLeft = [];
+            for (String string in strings) {
+              if (!string.trim().startsWith("//")) stringsLeft.add(string);
+            }
+
+            Uint8List candidate = utf8.encode(stringsLeft.join("\n"));
+            if (candidate.length != _fs.data[uri].length) {
+              if (await _shouldQuit()) return;
+              _fs.data[uri] = candidate;
+              if (!await _crashesOnCompile(initialComponent)) {
+                print("Can't remove comments for file $uri -- "
+                    "keeping it (for now)");
+                _fs.data[uri] = data;
+              } else {
+                print("Removed comments for the file $uri");
+              }
+            }
+          } catch (e) {
+            // crash in scanner/parser --- keep original file. This crash might
+            // be what we're looking for!
+          }
+        }
+      }
+    } else {
+      print("Can delete ${extraMessageText}file $uri");
+      await _tryToRemoveUnreferencedFileContent(initialComponent);
+    }
+  }
+
+  void _deleteBlocksOld(Uri uri, Component initialComponent) async {
+    if (uri.toString().endsWith(".json")) {
+      // Try to find annoying
+      //
+      //    },
+      //    {
+      //    }
+      //
+      // part of json and remove it.
+      Uint8List data = _fs.data[uri];
+      String string = utf8.decode(data);
+      List<String> lines = string.split("\n");
+      for (int i = 0; i < lines.length - 2; i++) {
+        if (lines[i].trim() == "}," &&
+            lines[i + 1].trim() == "{" &&
+            lines[i + 2].trim() == "}") {
+          // This is the pattern we wanted to find. Remove it.
+          lines.removeRange(i, i + 2);
+          i--;
+        }
+      }
+      string = lines.join("\n");
+      _fs.data[uri] = utf8.encode(string);
+      if (!await _crashesOnCompile(initialComponent)) {
+        // For some reason that didn't work.
+        _fs.data[uri] = data;
+      }
+    }
+    if (!uri.toString().endsWith(".dart")) return;
+
+    Uint8List data = _fs.data[uri];
+    Uint8List latestCrashData = data;
+
+    List<int> lineStarts = [];
+
+    Token firstToken = parser_suite.scanRawBytes(
+        data,
+        _isUriNnbd(uri) ? _scannerConfiguration : _scannerConfigurationNonNNBD,
+        lineStarts);
+
+    if (firstToken == null) {
+      print("Got null token from scanner for $uri");
+      return;
+    }
+
+    int compileTry = 0;
+    Token token = firstToken;
+    while (token is ErrorToken) {
+      token = token.next;
+    }
+    List<_Replacement> replacements = [];
+    while (token != null && !token.isEof) {
+      bool tryCompile = false;
+      Token skipToToken = token;
+      // Skip very small blocks (e.g. "{}" or "{\n}");
+      if (token.endGroup != null && token.offset + 3 < token.endGroup.offset) {
+        replacements.add(new _Replacement(token.offset, token.endGroup.offset));
+        tryCompile = true;
+        skipToToken = token.endGroup;
+      } else if (token.lexeme == "@") {
+        if (token.next.next.endGroup != null) {
+          int end = token.next.next.endGroup.offset;
+          skipToToken = token.next.next.endGroup;
+          replacements.add(new _Replacement(token.offset - 1, end + 1));
+          tryCompile = true;
+        }
+      } else if (token.lexeme == "assert") {
+        if (token.next.endGroup != null) {
+          int end = token.next.endGroup.offset;
+          skipToToken = token.next.endGroup;
+          if (token.next.endGroup.next.lexeme == ",") {
+            end = token.next.endGroup.next.offset;
+            skipToToken = token.next.endGroup.next;
+          }
+          // +/- 1 to not include the start and the end character.
+          replacements.add(new _Replacement(token.offset - 1, end + 1));
+          tryCompile = true;
+        }
+      } else if ((token.lexeme == "abstract" && token.next.lexeme == "class") ||
+          token.lexeme == "class" ||
+          token.lexeme == "enum" ||
+          token.lexeme == "mixin" ||
+          token.lexeme == "static" ||
+          token.next.lexeme == "get" ||
+          token.next.lexeme == "set" ||
+          token.next.next.lexeme == "(" ||
+          (token.next.lexeme == "<" &&
+              token.next.endGroup != null &&
+              token.next.endGroup.next.next.lexeme == "(")) {
+        // Try to find and remove the entire class/enum/mixin/
+        // static procedure/getter/setter/simple procedure.
+        Token bracket = token;
+        for (int i = 0; i < 20; i++) {
+          // Find "{", but only go a maximum of 20 tokens to do that.
+          bracket = bracket.next;
+          if (bracket.lexeme == "{" && bracket.endGroup != null) {
+            break;
+          } else if ((bracket.lexeme == "(" || bracket.lexeme == "<") &&
+              bracket.endGroup != null) {
+            bracket = bracket.endGroup;
+          }
+        }
+        if (bracket.lexeme == "{" && bracket.endGroup != null) {
+          int end = bracket.endGroup.offset;
+          skipToToken = bracket.endGroup;
+          // +/- 1 to not include the start and the end character.
+          replacements.add(new _Replacement(token.offset - 1, end + 1));
+          tryCompile = true;
+        }
+      }
+
+      if (tryCompile) {
+        if (await _shouldQuit()) break;
+        if (_skip) {
+          _skip = false;
+          break;
+        }
+        stdout.write(".");
+        compileTry++;
+        if (compileTry % 50 == 0) {
+          stdout.write("(at $compileTry)\n");
+        }
+        Uint8List candidate = _replaceRange(replacements, data);
+        _fs.data[uri] = candidate;
+        if (await _crashesOnCompile(initialComponent)) {
+          print("Found block from "
+              "${replacements.last.from} to "
+              "${replacements.last.to} "
+              "that can be removed.");
+          latestCrashData = candidate;
+          token = skipToToken;
+        } else {
+          // Couldn't delete that.
+          replacements.removeLast();
+        }
+      }
+      token = token.next;
+    }
+    _fs.data[uri] = latestCrashData;
+  }
+
+  void _deleteBlocks(final Uri uri, Component initialComponent) async {
+    if (uri.toString().endsWith(".json")) {
+      // Try to find annoying
+      //
+      //    },
+      //    {
+      //    }
+      //
+      // part of json and remove it.
+      Uint8List data = _fs.data[uri];
+      String string = utf8.decode(data);
+      List<String> lines = string.split("\n");
+      for (int i = 0; i < lines.length - 2; i++) {
+        if (lines[i].trim() == "}," &&
+            lines[i + 1].trim() == "{" &&
+            lines[i + 2].trim() == "}") {
+          // This is the pattern we wanted to find. Remove it.
+          lines.removeRange(i, i + 2);
+          i--;
+        }
+      }
+      string = lines.join("\n");
+      Uint8List candidate = utf8.encode(string);
+      if (candidate.length != data.length) {
+        _fs.data[uri] = candidate;
+        if (!await _crashesOnCompile(initialComponent)) {
+          // For some reason that didn't work.
+          _fs.data[uri] = data;
+        }
+      }
+
+      // Try to load json and remove blocks.
+      try {
+        Map json = jsonDecode(utf8.decode(data));
+        Map jsonModified = new Map.from(json);
+        List packages = json["packages"];
+        List packagesModified = new List.from(packages);
+        jsonModified["packages"] = packagesModified;
+        int i = 0;
+        print("Note there's ${packagesModified.length} packages in .json");
+        JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
+        while (i < packagesModified.length) {
+          var oldEntry = packagesModified.removeAt(i);
+          String jsonString = jsonEncoder.convert(jsonModified);
+          candidate = utf8.encode(jsonString);
+          Uint8List previous = _fs.data[uri];
+          _fs.data[uri] = candidate;
+          if (!await _crashesOnCompile(initialComponent)) {
+            // Couldn't remove that part.
+            _fs.data[uri] = previous;
+            packagesModified.insert(i, oldEntry);
+            i++;
+          } else {
+            print("Removed package from .json "
+                "(${packagesModified.length} left).");
+          }
+        }
+      } catch (e) {
+        // Couldn't decode it, so don't try to do anything.
+      }
+      return;
+    }
+    if (!uri.toString().endsWith(".dart")) return;
+
+    Uint8List data = _fs.data[uri];
+    DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+        includeBody: true,
+        includeComments: false,
+        enableExtensionMethods: true,
+        enableNonNullable: _isUriNnbd(uri));
+
+    _CompilationHelperClass helper = new _CompilationHelperClass(data);
+
+    // Try to remove top level things one at a time.
+    for (DirectParserASTContent child in ast.children) {
+      bool shouldCompile = false;
+      String what = "";
+      if (child.isClass()) {
+        DirectParserASTContentClassDeclarationEnd cls = child.asClass();
+        helper.replacements.add(new _Replacement(
+            cls.beginToken.offset - 1, cls.endToken.offset + 1));
+        shouldCompile = true;
+        what = "class";
+      } else if (child.isMixinDeclaration()) {
+        DirectParserASTContentMixinDeclarationEnd decl =
+            child.asMixinDeclaration();
+        helper.replacements.add(new _Replacement(
+            decl.mixinKeyword.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "mixin";
+      } else if (child.isNamedMixinDeclaration()) {
+        DirectParserASTContentNamedMixinApplicationEnd decl =
+            child.asNamedMixinDeclaration();
+        helper.replacements.add(
+            new _Replacement(decl.begin.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "named mixin";
+      } else if (child.isExtension()) {
+        DirectParserASTContentExtensionDeclarationEnd decl =
+            child.asExtension();
+        helper.replacements.add(new _Replacement(
+            decl.extensionKeyword.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "extension";
+      } else if (child.isTopLevelFields()) {
+        DirectParserASTContentTopLevelFieldsEnd decl = child.asTopLevelFields();
+        helper.replacements.add(new _Replacement(
+            decl.beginToken.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "toplevel fields";
+      } else if (child.isTopLevelMethod()) {
+        DirectParserASTContentTopLevelMethodEnd decl = child.asTopLevelMethod();
+        helper.replacements.add(new _Replacement(
+            decl.beginToken.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "toplevel method";
+      } else if (child.isEnum()) {
+        DirectParserASTContentEnumEnd decl = child.asEnum();
+        helper.replacements.add(new _Replacement(
+            decl.enumKeyword.offset - 1, decl.leftBrace.endGroup.offset + 1));
+        shouldCompile = true;
+        what = "enum";
+      } else if (child.isTypedef()) {
+        DirectParserASTContentFunctionTypeAliasEnd decl = child.asTypedef();
+        helper.replacements.add(new _Replacement(
+            decl.typedefKeyword.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "typedef";
+      } else if (child.isMetadata()) {
+        DirectParserASTContentMetadataStarEnd decl = child.asMetadata();
+        List<DirectParserASTContentMetadataEnd> metadata =
+            decl.getMetadataEntries();
+        if (metadata.isNotEmpty) {
+          helper.replacements.add(new _Replacement(
+              metadata.first.beginToken.offset - 1,
+              metadata.last.endToken.offset));
+          shouldCompile = true;
+        }
+        what = "metadata";
+      } else if (child.isImport()) {
+        DirectParserASTContentImportEnd decl = child.asImport();
+        helper.replacements.add(new _Replacement(
+            decl.importKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "import";
+      } else if (child.isExport()) {
+        DirectParserASTContentExportEnd decl = child.asExport();
+        helper.replacements.add(new _Replacement(
+            decl.exportKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "export";
+      } else if (child.isLibraryName()) {
+        DirectParserASTContentLibraryNameEnd decl = child.asLibraryName();
+        helper.replacements.add(new _Replacement(
+            decl.libraryKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "library name";
+      } else if (child.isPart()) {
+        DirectParserASTContentPartEnd decl = child.asPart();
+        helper.replacements.add(new _Replacement(
+            decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "part";
+      } else if (child.isPartOf()) {
+        DirectParserASTContentPartOfEnd decl = child.asPartOf();
+        helper.replacements.add(new _Replacement(
+            decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "part of";
+      } else if (child.isScript()) {
+        var decl = child.asScript();
+        helper.replacements.add(new _Replacement(
+            decl.token.offset - 1, decl.token.offset + decl.token.length));
+        shouldCompile = true;
+        what = "script";
+      }
+
+      if (shouldCompile) {
+        bool success =
+            await _tryReplaceAndCompile(helper, uri, initialComponent, what);
+        if (helper.shouldQuit) return;
+        if (!success) {
+          if (child.isClass()) {
+            // Also try to remove all content of the class.
+            DirectParserASTContentClassDeclarationEnd decl = child.asClass();
+            DirectParserASTContentClassOrMixinBodyEnd body =
+                decl.getClassOrMixinBody();
+            if (body.beginToken.offset + 2 < body.endToken.offset) {
+              helper.replacements.add(new _Replacement(
+                  body.beginToken.offset, body.endToken.offset));
+              what = "class body";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+
+            if (!success) {
+              // Also try to remove members one at a time.
+              for (DirectParserASTContent child in body.children) {
+                shouldCompile = false;
+                if (child is DirectParserASTContentMemberEnd) {
+                  if (child.isClassConstructor()) {
+                    DirectParserASTContentClassConstructorEnd memberDecl =
+                        child.getClassConstructor();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class constructor";
+                    shouldCompile = true;
+                  } else if (child.isClassFields()) {
+                    DirectParserASTContentClassFieldsEnd memberDecl =
+                        child.getClassFields();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class fields";
+                    shouldCompile = true;
+                  } else if (child.isClassMethod()) {
+                    DirectParserASTContentClassMethodEnd memberDecl =
+                        child.getClassMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class method";
+                    shouldCompile = true;
+                  } else if (child.isClassFactoryMethod()) {
+                    DirectParserASTContentClassFactoryMethodEnd memberDecl =
+                        child.getClassFactoryMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class factory method";
+                    shouldCompile = true;
+                  } else {
+                    // throw "$child --- ${child.children}";
+                    continue;
+                  }
+                } else if (child.isMetadata()) {
+                  DirectParserASTContentMetadataStarEnd decl =
+                      child.asMetadata();
+                  List<DirectParserASTContentMetadataEnd> metadata =
+                      decl.getMetadataEntries();
+                  if (metadata.isNotEmpty) {
+                    helper.replacements.add(new _Replacement(
+                        metadata.first.beginToken.offset - 1,
+                        metadata.last.endToken.offset));
+                    shouldCompile = true;
+                  }
+                  what = "metadata";
+                }
+                if (shouldCompile) {
+                  success = await _tryReplaceAndCompile(
+                      helper, uri, initialComponent, what);
+                  if (helper.shouldQuit) return;
+                  if (!success) {
+                    DirectParserASTContentBlockFunctionBodyEnd decl;
+                    if (child is DirectParserASTContentMemberEnd) {
+                      if (child.isClassMethod()) {
+                        decl = child.getClassMethod().getBlockFunctionBody();
+                      } else if (child.isClassConstructor()) {
+                        decl =
+                            child.getClassConstructor().getBlockFunctionBody();
+                      }
+                    }
+                    if (decl != null &&
+                        decl.beginToken.offset + 2 < decl.endToken.offset) {
+                      helper.replacements.add(new _Replacement(
+                          decl.beginToken.offset, decl.endToken.offset));
+                      what = "class member content";
+                      await _tryReplaceAndCompile(
+                          helper, uri, initialComponent, what);
+                      if (helper.shouldQuit) return;
+                    }
+                  }
+                }
+              }
+            }
+
+            // Try to remove "extends", "implements" etc.
+            if (decl.getClassExtends().extendsKeyword != null) {
+              helper.replacements.add(new _Replacement(
+                  decl.getClassExtends().extendsKeyword.offset - 1,
+                  body.beginToken.offset));
+              what = "class extends";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+            if (decl.getClassImplements().implementsKeyword != null) {
+              helper.replacements.add(new _Replacement(
+                  decl.getClassImplements().implementsKeyword.offset - 1,
+                  body.beginToken.offset));
+              what = "class implements";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+            if (decl.getClassWithClause() != null) {
+              helper.replacements.add(new _Replacement(
+                  decl.getClassWithClause().withKeyword.offset - 1,
+                  body.beginToken.offset));
+              what = "class with clause";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+          } else if (child.isMixinDeclaration()) {
+            // Also try to remove all content of the mixin.
+            DirectParserASTContentMixinDeclarationEnd decl =
+                child.asMixinDeclaration();
+            DirectParserASTContentClassOrMixinBodyEnd body =
+                decl.getClassOrMixinBody();
+            if (body.beginToken.offset + 2 < body.endToken.offset) {
+              helper.replacements.add(new _Replacement(
+                  body.beginToken.offset, body.endToken.offset));
+              what = "mixin body";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+
+            if (!success) {
+              // Also try to remove members one at a time.
+              for (DirectParserASTContent child in body.children) {
+                shouldCompile = false;
+                if (child is DirectParserASTContentMemberEnd) {
+                  if (child.isMixinConstructor()) {
+                    DirectParserASTContentMixinConstructorEnd memberDecl =
+                        child.getMixinConstructor();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin constructor";
+                    shouldCompile = true;
+                  } else if (child.isMixinFields()) {
+                    DirectParserASTContentMixinFieldsEnd memberDecl =
+                        child.getMixinFields();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin fields";
+                    shouldCompile = true;
+                  } else if (child.isMixinMethod()) {
+                    DirectParserASTContentMixinMethodEnd memberDecl =
+                        child.getMixinMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin method";
+                    shouldCompile = true;
+                  } else if (child.isMixinFactoryMethod()) {
+                    DirectParserASTContentMixinFactoryMethodEnd memberDecl =
+                        child.getMixinFactoryMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin factory method";
+                    shouldCompile = true;
+                  } else {
+                    // throw "$child --- ${child.children}";
+                    continue;
+                  }
+                } else if (child.isMetadata()) {
+                  DirectParserASTContentMetadataStarEnd decl =
+                      child.asMetadata();
+                  List<DirectParserASTContentMetadataEnd> metadata =
+                      decl.getMetadataEntries();
+                  if (metadata.isNotEmpty) {
+                    helper.replacements.add(new _Replacement(
+                        metadata.first.beginToken.offset - 1,
+                        metadata.last.endToken.offset));
+                    shouldCompile = true;
+                  }
+                  what = "metadata";
+                }
+                if (shouldCompile) {
+                  success = await _tryReplaceAndCompile(
+                      helper, uri, initialComponent, what);
+                  if (helper.shouldQuit) return;
+                  if (!success) {
+                    DirectParserASTContentBlockFunctionBodyEnd decl;
+                    if (child is DirectParserASTContentMemberEnd) {
+                      if (child.isClassMethod()) {
+                        decl = child.getClassMethod().getBlockFunctionBody();
+                      } else if (child.isClassConstructor()) {
+                        decl =
+                            child.getClassConstructor().getBlockFunctionBody();
+                      }
+                    }
+                    if (decl != null &&
+                        decl.beginToken.offset + 2 < decl.endToken.offset) {
+                      helper.replacements.add(new _Replacement(
+                          decl.beginToken.offset, decl.endToken.offset));
+                      what = "class member content";
+                      await _tryReplaceAndCompile(
+                          helper, uri, initialComponent, what);
+                      if (helper.shouldQuit) return;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  Future<bool> _tryReplaceAndCompile(_CompilationHelperClass data, Uri uri,
+      Component initialComponent, String what) async {
+    if (await _shouldQuit()) {
+      data.shouldQuit = true;
+      return false;
+    }
+    stdout.write(".");
+    data.compileTry++;
+    if (data.compileTry % 50 == 0) {
+      stdout.write("(at ${data.compileTry})\n");
+    }
+    Uint8List candidate = _replaceRange(data.replacements, data.originalData);
+
+    if (!_parsesWithoutError(candidate, _isUriNnbd(uri))) {
+      print("WARNING: Parser error after stuff at ${StackTrace.current}");
+      _parsesWithoutError(candidate, _isUriNnbd(uri));
+      _parsesWithoutError(data.originalData, _isUriNnbd(uri));
+    }
+
+    _fs.data[uri] = candidate;
+    if (await _crashesOnCompile(initialComponent)) {
+      print("Found $what from "
+          "${data.replacements.last.from} to "
+          "${data.replacements.last.to} "
+          "that can be removed.");
+      data.latestCrashData = candidate;
+      return true;
+    } else {
+      // Couldn't delete that.
+      data.replacements.removeLast();
+      _fs.data[uri] = data.latestCrashData;
+      return false;
+    }
+  }
+
+  void _deleteEmptyLines(Uri uri, Component initialComponent) async {
+    Uint8List data = _fs.data[uri];
+    List<Uint8List> lines = [];
+    int start = 0;
+    for (int i = 0; i < data.length; i++) {
+      if (data[i] == _$LF) {
+        if (i - start > 0) {
+          lines.add(_sublist(data, start, i));
+        }
+        start = i + 1;
+      }
+    }
+    if (data.length - start > 0) {
+      lines.add(_sublist(data, start, data.length));
+    }
+
+    final BytesBuilder builder = new BytesBuilder();
+    for (int j = 0; j < lines.length; j++) {
+      if (builder.isNotEmpty) {
+        builder.addByte(_$LF);
+      }
+      builder.add(lines[j]);
+    }
+    Uint8List candidate = builder.takeBytes();
+    if (candidate.length == data.length) return;
+
+    if (!_parsesWithoutError(candidate, _isUriNnbd(uri))) {
+      print("WARNING: Parser error after stuff at ${StackTrace.current}");
+    }
+
+    if (await _shouldQuit()) return;
+    _fs.data[uri] = candidate;
+    if (!await _crashesOnCompile(initialComponent)) {
+      // For some reason the empty lines are important.
+      _fs.data[uri] = data;
+    } else {
+      print("\nDeleted empty lines.");
+    }
+  }
+
+  void _deleteLines(Uri uri, Component initialComponent) async {
+    // Try to delete "lines".
+    Uint8List data = _fs.data[uri];
+    List<Uint8List> lines = [];
+    int start = 0;
+    for (int i = 0; i < data.length; i++) {
+      if (data[i] == _$LF) {
+        lines.add(_sublist(data, start, i));
+        start = i + 1;
+      }
+    }
+    lines.add(_sublist(data, start, data.length));
+    List<bool> include = new List.filled(lines.length, true);
+    Uint8List latestCrashData = data;
+    int length = 1;
+    int i = 0;
+    while (i < lines.length) {
+      if (await _shouldQuit()) break;
+      if (_skip) {
+        _skip = false;
+        break;
+      }
+      stdout.write(".");
+      if (i % 50 == 0) {
+        stdout.write("(at $i of ${lines.length})\n");
+      }
+      if (i + length > lines.length) {
+        length = lines.length - i;
+      }
+      for (int j = i; j < i + length; j++) {
+        include[j] = false;
+      }
+      final BytesBuilder builder = new BytesBuilder();
+      for (int j = 0; j < lines.length; j++) {
+        if (include[j]) {
+          if (builder.isNotEmpty) {
+            builder.addByte(_$LF);
+          }
+          builder.add(lines[j]);
+        }
+      }
+      Uint8List candidate = builder.takeBytes();
+      _fs.data[uri] = candidate;
+      if (!await _crashesOnCompile(initialComponent)) {
+        // Didn't crash => Can't remove line i-j.
+        for (int j = i; j < i + length; j++) {
+          include[j] = true;
+        }
+        if (length > 2) {
+          // Retry with length 2 at same i.
+          // The idea here is that for instance formatted json might have lines
+          // looking like
+          // {
+          // }
+          // where deleting just one line makes it invalid.
+          length = 2;
+        } else if (length > 1) {
+          // Retry with length 1 at same i.
+          length = 1;
+        } else {
+          // Couldn't with length 1 either.
+          i++;
+        }
+      } else {
+        print("\nCan delete line $i (inclusive) - ${i + length} (exclusive) "
+            "(of ${lines.length})");
+        latestCrashData = candidate;
+        i += length;
+        length *= 2;
+      }
+    }
+    _fs.data[uri] = latestCrashData;
+  }
+
+  Future<bool> _tryRemoveIfNotKnownByCompiler(Uri uri, initialComponent) async {
+    if (_fs.data[uri] == null || _fs.data[uri].isEmpty) return false;
+    if (!uri.toString().endsWith(".dart")) return false;
+
+    if (_knownByCompiler(uri)) return false;
+
+    // Compiler might not know this. Can we delete it?
+    await _deleteContent([uri], 0, true, initialComponent);
+    if (_fs.data[uri] == null || _fs.data[uri].isEmpty) {
+      await _deleteContent([uri], 0, true, initialComponent, deleteFile: true);
+      return true;
+    }
+
+    return false;
+  }
+
+  bool _knownByCompiler(Uri uri) {
+    LibraryBuilder libraryBuilder = _latestCrashingIncrementalCompiler
+        .userCode.loader.builders[_getImportUri(uri)];
+    if (libraryBuilder != null) {
+      return true;
+    }
+    // TODO(jensj): Parts.
+    return false;
+  }
+
+  bool _isUriNnbd(Uri uri) {
+    LibraryBuilder libraryBuilder = _latestCrashingIncrementalCompiler
+        .userCode.loader.builders[_getImportUri(uri)];
+    if (libraryBuilder != null) {
+      return libraryBuilder.isNonNullableByDefault;
+    }
+    print("Couldn't lookup $uri");
+    for (LibraryBuilder libraryBuilder
+        in _latestCrashingIncrementalCompiler.userCode.loader.builders.values) {
+      if (libraryBuilder.importUri == uri) {
+        print("Found $uri as ${libraryBuilder.importUri} "
+            "(!= ${_getImportUri(uri)})");
+        return libraryBuilder.isNonNullableByDefault;
+      }
+    }
+    // This might be parts?
+    throw "Couldn't lookup $uri at all!";
+  }
+
+  Future<bool> _crashesOnCompile(Component initialComponent) async {
+    IncrementalCompiler incrementalCompiler;
+    if (_settings.noPlatform) {
+      incrementalCompiler = new IncrementalCompiler(_setupCompilerContext());
+    } else {
+      incrementalCompiler = new IncrementalCompiler.fromComponent(
+          _setupCompilerContext(), initialComponent);
+    }
+    incrementalCompiler.invalidate(_mainUri);
+    try {
+      _latestComponent = await incrementalCompiler.computeDelta();
+      if (_settings.serialize) {
+        ByteSink sink = new ByteSink();
+        BinaryPrinter printer = new BinaryPrinter(sink);
+        printer.writeComponentFile(_latestComponent);
+        sink.builder.takeBytes();
+      }
+      for (Uri uri in _settings.invalidate) {
+        incrementalCompiler.invalidate(uri);
+        Component delta = await incrementalCompiler.computeDelta();
+        if (_settings.serialize) {
+          ByteSink sink = new ByteSink();
+          BinaryPrinter printer = new BinaryPrinter(sink);
+          printer.writeComponentFile(delta);
+          sink.builder.takeBytes();
+        }
+      }
+      _latestComponent = null; // if it didn't crash this isn't relevant.
+      return false;
+    } catch (e, st) {
+      // Find line with #0 in it.
+      String eWithSt = "$e\n\n$st";
+      List<String> lines = eWithSt.split("\n");
+      String foundLine = "";
+      int lookFor = 0;
+      for (String line in lines) {
+        if (line.startsWith("#$lookFor")) {
+          foundLine += line;
+          lookFor++;
+          if (lookFor >= _settings.stackTraceMatches) {
+            break;
+          } else {
+            foundLine += "\n";
+          }
+        }
+      }
+      if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
+      if (_expectedCrashLine == null) {
+        print("Got '$foundLine'");
+        _expectedCrashLine = foundLine;
+        _latestCrashingIncrementalCompiler = incrementalCompiler;
+        return true;
+      } else if (foundLine == _expectedCrashLine) {
+        _latestCrashingIncrementalCompiler = incrementalCompiler;
+        return true;
+      } else {
+        if (_settings.autoUncoverAllCrashes &&
+            !_settings.allAutoRedirects.contains(foundLine)) {
+          print("Crashed, but another place: $foundLine");
+          print(" ==> Adding to auto redirects!");
+          // Add the current one too, so we don't rediscover that one once we
+          // try minimizing the new ones.
+          _settings.allAutoRedirects.add(_expectedCrashLine);
+          _settings.allAutoRedirects.add(foundLine);
+          _settings.fileSystems.add(_fs.toJson());
+        } else if (_settings.askAboutRedirectCrashTarget &&
+            !_settings.askedAboutRedirect.contains(foundLine)) {
+          print("Crashed, but another place: $foundLine");
+          while (true) {
+            // Add the current one too, so we don't rediscover that again
+            // and asks about going back to it.
+            _settings.askedAboutRedirect.add(_expectedCrashLine);
+            _settings.askedAboutRedirect.add(foundLine);
+            print(eWithSt);
+            print("Should we redirect to searching for that? (y/n)");
+            String answer = stdin.readLineSync();
+            if (answer == "yes" || answer == "y") {
+              _expectedCrashLine = foundLine;
+              _latestCrashingIncrementalCompiler = incrementalCompiler;
+              return true;
+            } else if (answer == "no" || answer == "n") {
+              break;
+            } else {
+              print("Didn't get that answer. "
+                  "Please answer 'yes, 'y', 'no' or 'n'");
+            }
+          }
+        }
+        return false;
+      }
+    }
+  }
+
+  Future<Component> _getInitialComponent() async {
+    IncrementalCompiler incrementalCompiler =
+        new IncrementalCompiler(_setupCompilerContext());
+    Component originalComponent = await incrementalCompiler.computeDelta();
+    return originalComponent;
+  }
+
+  CompilerContext _setupCompilerContext() {
+    CompilerOptions options = getOptions();
+
+    if (_settings.experimentalInvalidation) {
+      options.explicitExperimentalFlags ??= {};
+      options.explicitExperimentalFlags[
+          ExperimentalFlag.alternativeInvalidationStrategy] = true;
+    }
+
+    TargetFlags targetFlags = new TargetFlags(
+        enableNullSafety: false,
+        trackWidgetCreation: _settings.widgetTransformation);
+    Target target;
+    switch (_settings.targetString) {
+      case "VM":
+        target = new VmTarget(targetFlags);
+        break;
+      case "flutter":
+        target = new FlutterTarget(targetFlags);
+        break;
+      case "ddc":
+        target = new DevCompilerTarget(targetFlags);
+        break;
+      default:
+        throw "Unknown target '$target'";
+    }
+    options.target = target;
+    options.fileSystem = _fs;
+    options.sdkRoot = null;
+    options.sdkSummary = _settings.platformUri;
+    options.omitPlatform = false;
+    options.onDiagnostic = (DiagnosticMessage message) {
+      // don't care.
+    };
+    if (_settings.noPlatform) {
+      options.librariesSpecificationUri = null;
+    }
+
+    CompilerContext compilerContext = new CompilerContext(
+        new ProcessedOptions(options: options, inputs: [_mainUri]));
+    return compilerContext;
+  }
+
+  String _getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
+    List<int> lineStarts = [];
+
+    Token firstToken = parser_suite.scanRawBytes(
+        rawBytes,
+        nnbd ? _scannerConfiguration : _scannerConfigurationNonNNBD,
+        lineStarts);
+
+    if (firstToken == null) {
+      throw "Got null token from scanner";
+    }
+
+    ParserTestListener parserTestListener = new ParserTestListener(false);
+    Parser parser = new Parser(parserTestListener);
+    parser.parseUnit(firstToken);
+    String parsedString =
+        parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
+    return parsedString;
+  }
+
+  bool _parsesWithoutError(Uint8List rawBytes, bool nnbd) {
+    Token firstToken = parser_suite.scanRawBytes(rawBytes,
+        nnbd ? _scannerConfiguration : _scannerConfigurationNonNNBD, null);
+
+    if (firstToken == null) {
+      return false;
+    }
+
+    ParserErrorListener parserErrorListener = new ParserErrorListener();
+    Parser parser = new Parser(parserErrorListener);
+    parser.parseUnit(firstToken);
+    return !parserErrorListener.gotError;
+  }
+
+  ScannerConfiguration _scannerConfiguration = new ScannerConfiguration(
+      enableTripleShift: true,
+      enableExtensionMethods: true,
+      enableNonNullable: true);
+
+  ScannerConfiguration _scannerConfigurationNonNNBD = new ScannerConfiguration(
+      enableTripleShift: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+
+  List<int> _dataCache;
+  String _dataCacheString;
+  Uint8List _replaceRange(
+      List<_Replacement> unsortedReplacements, Uint8List rawData) {
+    // The offsets are character offsets, not byte offsets, so for non-ascii
+    // they are not the same so we need to work on the string, not the bytes.
+    if (identical(rawData, _dataCache)) {
+      // cache up to date.
+    } else {
+      _dataCache = rawData;
+      _dataCacheString = utf8.decode(rawData);
+    }
+
+    // The below assumes these are sorted.
+    List<_Replacement> sortedReplacements =
+        new List<_Replacement>.from(unsortedReplacements)..sort();
+    final StringBuffer builder = new StringBuffer();
+    int prev = 0;
+    for (int i = 0; i < sortedReplacements.length; i++) {
+      _Replacement replacement = sortedReplacements[i];
+      for (int j = prev; j <= replacement.from; j++) {
+        builder.writeCharCode(_dataCacheString.codeUnitAt(j));
+      }
+      if (replacement.nullOrReplacement != null) {
+        builder.write(replacement.nullOrReplacement);
+      }
+      prev = replacement.to;
+    }
+    for (int j = prev; j < _dataCacheString.length; j++) {
+      builder.writeCharCode(_dataCacheString.codeUnitAt(j));
+    }
+
+    Uint8List candidate = utf8.encode(builder.toString());
+    return candidate;
+  }
+}
+
+class ParserErrorListener extends Listener {
+  bool gotError = false;
+  List<Message> messages = [];
+  void handleRecoverableError(
+      Message message, Token startToken, Token endToken) {
+    gotError = true;
+    messages.add(message);
+  }
+}
+
+class _CompilationHelperClass {
+  int compileTry = 0;
+  bool shouldQuit = false;
+  List<_Replacement> replacements = [];
+  Uint8List latestCrashData;
+  final Uint8List originalData;
+
+  _CompilationHelperClass(this.originalData) : latestCrashData = originalData;
+}
+
+class _Replacement implements Comparable<_Replacement> {
+  final int from;
+  final int to;
+  final String nullOrReplacement;
+
+  _Replacement(this.from, this.to, {this.nullOrReplacement});
+
+  @override
+  int compareTo(_Replacement other) {
+    return from - other.from;
+  }
+}
+
+class _FakeFileSystem extends FileSystem {
+  bool _redirectAndRecord = true;
+  bool _initialized = false;
+  final Map<Uri, Uint8List> data = {};
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    return new _FakeFileSystemEntity(this, uri);
+  }
+
+  initializeFromJson(Map<String, dynamic> json) {
+    _initialized = true;
+    _redirectAndRecord = json['_redirectAndRecord'];
+    data.clear();
+    List tmp = json['data'];
+    for (int i = 0; i < tmp.length; i += 2) {
+      Uri key = tmp[i] == null ? null : Uri.parse(tmp[i]);
+      if (tmp[i + 1] == null) {
+        data[key] = null;
+      } else if (tmp[i + 1] is String) {
+        data[key] = utf8.encode(tmp[i + 1]);
+      } else {
+        data[key] = Uint8List.fromList(new List<int>.from(tmp[i + 1]));
+      }
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    List tmp = [];
+    for (var entry in data.entries) {
+      if (entry.value == null) continue;
+      tmp.add(entry.key == null ? null : entry.key.toString());
+      dynamic out = entry.value;
+      if (entry.value != null && entry.value.isNotEmpty) {
+        try {
+          String string = utf8.decode(entry.value);
+          out = string;
+        } catch (e) {
+          // not a string...
+        }
+      }
+      tmp.add(out);
+    }
+    return {
+      '_redirectAndRecord': _redirectAndRecord,
+      'data': tmp,
+    };
+  }
+}
+
+class _FakeFileSystemEntity extends FileSystemEntity {
+  final _FakeFileSystem fs;
+  final Uri uri;
+  _FakeFileSystemEntity(this.fs, this.uri);
+
+  void _ensureCachedIfOk() {
+    if (fs.data.containsKey(uri)) return;
+    if (fs._initialized) return;
+    if (!fs._redirectAndRecord) {
+      throw "Asked for file in non-recording mode that wasn't known";
+    }
+    File f = new File.fromUri(uri);
+    if (!f.existsSync()) {
+      fs.data[uri] = null;
+      return;
+    }
+    fs.data[uri] = f.readAsBytesSync();
+  }
+
+  @override
+  Future<bool> exists() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) return Future.value(false);
+    return Future.value(true);
+  }
+
+  @override
+  Future<List<int>> readAsBytes() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+    return Future.value(data);
+  }
+
+  @override
+  Future<String> readAsString() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+    return Future.value(utf8.decode(data));
+  }
+}
+
+class _DoesntCrashOnInput {
+  _DoesntCrashOnInput();
+}
diff --git a/pkg/front_end/test/dijkstras_sssp_algorithm.dart b/pkg/front_end/test/dijkstras_sssp_algorithm.dart
index c3079e9..b8f9789 100644
--- a/pkg/front_end/test/dijkstras_sssp_algorithm.dart
+++ b/pkg/front_end/test/dijkstras_sssp_algorithm.dart
@@ -79,7 +79,7 @@
   }
 
   List<E> getPathFromTarget(GraphNode<E> source, GraphNode<E> target) {
-    List<E> path = new List<E>();
+    List<E> path = <E>[];
     GraphNode<E> u = target;
     while (u == source || prev[u] != null) {
       path.add(u.node);
diff --git a/pkg/front_end/test/fasta/bootstrap_test.dart b/pkg/front_end/test/fasta/bootstrap_test.dart
index f7ea1bd..f48318a 100644
--- a/pkg/front_end/test/fasta/bootstrap_test.dart
+++ b/pkg/front_end/test/fasta/bootstrap_test.dart
@@ -46,16 +46,17 @@
 
 Future runCompiler(Uri compiler, Uri input, Uri output) async {
   Uri dartVm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
-  StdioProcess result = await StdioProcess.run(
-      dartVm.toFilePath(),
-      <String>[
-        compiler.toFilePath(),
-        "${Flags.compileSdk}=sdk/",
-        "${Flags.output}=${output.toFilePath()}",
-        Flags.verify,
-        input.toFilePath(),
-      ],
-      suppressOutput: false);
+  String executable = dartVm.toFilePath();
+  List<String> arguments = <String>[
+    compiler.toFilePath(),
+    "${Flags.compileSdk}=sdk/",
+    "${Flags.output}=${output.toFilePath()}",
+    Flags.verify,
+    input.toFilePath(),
+  ];
+  print('Running: $executable ${arguments.join(' ')}');
+  StdioProcess result =
+      await StdioProcess.run(executable, arguments, suppressOutput: false);
   if (result.exitCode != 0) {
     throw "Compilation failed:\n${result.output}";
   }
diff --git a/pkg/front_end/test/fasta/incremental_source_files.dart b/pkg/front_end/test/fasta/incremental_source_files.dart
index f830639..c6d6931 100644
--- a/pkg/front_end/test/fasta/incremental_source_files.dart
+++ b/pkg/front_end/test/fasta/incremental_source_files.dart
@@ -55,7 +55,7 @@
 ///   ["head v1 tail", "head v2 tail"]
 List<String> expandUpdates(List updates) {
   int outputCount = updates.firstWhere((e) => e is Iterable).length;
-  List<StringBuffer> result = new List<StringBuffer>(outputCount);
+  List<StringBuffer> result = new List<StringBuffer>.filled(outputCount, null);
   for (int i = 0; i < outputCount; i++) {
     result[i] = new StringBuffer();
   }
diff --git a/pkg/front_end/test/fasta/messages_suite.dart b/pkg/front_end/test/fasta/messages_suite.dart
index aa7aa4870..9a370f4 100644
--- a/pkg/front_end/test/fasta/messages_suite.dart
+++ b/pkg/front_end/test/fasta/messages_suite.dart
@@ -170,7 +170,7 @@
           int offset, String message, String messageForDenyListed) {
         if (source == null) {
           List<int> bytes = file.readAsBytesSync();
-          List<int> lineStarts = new List<int>();
+          List<int> lineStarts = <int>[];
           int indexOf = 0;
           while (indexOf >= 0) {
             lineStarts.add(indexOf);
@@ -179,7 +179,7 @@
           lineStarts.add(bytes.length);
           source = new Source(lineStarts, bytes, uri, uri);
         }
-        List<String> result = new List<String>();
+        List<String> result = <String>[];
         for (int i = 0; i < spellResult.misspelledWords.length; i++) {
           Location location = source.getLocation(
               uri, offset + spellResult.misspelledWordsOffset[i]);
@@ -217,7 +217,7 @@
                   spell.Dictionaries.cfeMessages
                 ]);
             if (spellingResult.misspelledWords != null) {
-              spellingMessages ??= new List<String>();
+              spellingMessages ??= <String>[];
               spellingMessages.addAll(formatSpellingMistakes(
                   spellingResult,
                   node.span.start.offset,
@@ -236,7 +236,7 @@
                   spell.Dictionaries.cfeMessages
                 ]);
             if (spellingResult.misspelledWords != null) {
-              spellingMessages ??= new List<String>();
+              spellingMessages ??= <String>[];
               spellingMessages.addAll(formatSpellingMistakes(
                   spellingResult,
                   node.span.start.offset,
@@ -741,7 +741,7 @@
 
     List<DiagnosticMessage> unexpectedMessages = <DiagnosticMessage>[];
     if (example.allowMoreCodes) {
-      List<DiagnosticMessage> messagesFiltered = new List<DiagnosticMessage>();
+      List<DiagnosticMessage> messagesFiltered = <DiagnosticMessage>[];
       for (DiagnosticMessage message in messages) {
         if (getMessageCodeObject(message).name == example.expectedCode) {
           messagesFiltered.add(message);
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index c9d68e8..44c9145 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -105,6 +105,7 @@
         DiagnosticReporter,
         NoneConstantsBackend,
         NoneTarget,
+        LateLowering,
         Target,
         TargetFlags;
 
@@ -205,7 +206,7 @@
 /// test folders.
 class FolderOptions {
   final Map<ExperimentalFlag, bool> _explicitExperimentalFlags;
-  final bool forceLateLowering;
+  final int forceLateLowerings;
   final bool forceLateLoweringSentinel;
   final bool forceStaticFieldLowering;
   final bool forceNoExplicitGetterCalls;
@@ -216,7 +217,7 @@
   final String overwriteCurrentSdkVersion;
 
   FolderOptions(this._explicitExperimentalFlags,
-      {this.forceLateLowering: false,
+      {this.forceLateLowerings: LateLowering.none,
       this.forceLateLoweringSentinel: false,
       this.forceStaticFieldLowering: false,
       this.forceNoExplicitGetterCalls: false,
@@ -226,7 +227,7 @@
       this.target: "vm",
       // can be null
       this.overwriteCurrentSdkVersion})
-      : assert(forceLateLowering != null),
+      : assert(forceLateLowerings != null),
         assert(forceLateLoweringSentinel != null),
         assert(forceStaticFieldLowering != null),
         assert(forceNoExplicitGetterCalls != null),
@@ -376,7 +377,7 @@
   FolderOptions _computeFolderOptions(Directory directory) {
     FolderOptions folderOptions = _folderOptions[directory.uri];
     if (folderOptions == null) {
-      bool forceLateLowering = false;
+      int forceLateLowering = LateLowering.none;
       bool forceLateLoweringSentinel = false;
       bool forceStaticFieldLowering = false;
       bool forceNoExplicitGetterCalls = false;
@@ -386,7 +387,7 @@
       String target = "vm";
       if (directory.uri == baseUri) {
         folderOptions = new FolderOptions({},
-            forceLateLowering: forceLateLowering,
+            forceLateLowerings: forceLateLowering,
             forceLateLoweringSentinel: forceLateLoweringSentinel,
             forceStaticFieldLowering: forceStaticFieldLowering,
             forceNoExplicitGetterCalls: forceNoExplicitGetterCalls,
@@ -410,8 +411,12 @@
                   line.substring(overwriteCurrentSdkVersion.length);
             } else if (line.startsWith(Flags.forceLateLoweringSentinel)) {
               forceLateLoweringSentinel = true;
+            } else if (line.startsWith('${Flags.forceLateLowering}=')) {
+              int mask = int.parse(
+                  line.substring('${Flags.forceLateLowering}='.length));
+              forceLateLowering = mask;
             } else if (line.startsWith(Flags.forceLateLowering)) {
-              forceLateLowering = true;
+              forceLateLowering = LateLowering.all;
             } else if (line.startsWith(Flags.forceStaticFieldLowering)) {
               forceStaticFieldLowering = true;
             } else if (line.startsWith(Flags.forceNoExplicitGetterCalls)) {
@@ -466,7 +471,7 @@
                   onError: (String message) => throw new ArgumentError(message),
                   onWarning: (String message) =>
                       throw new ArgumentError(message)),
-              forceLateLowering: forceLateLowering,
+              forceLateLowerings: forceLateLowering,
               forceLateLoweringSentinel: forceLateLoweringSentinel,
               forceStaticFieldLowering: forceStaticFieldLowering,
               forceNoExplicitGetterCalls: forceNoExplicitGetterCalls,
@@ -743,7 +748,7 @@
         StdioProcess process;
         try {
           var args = <String>[];
-          if (experimentalFlags[ExperimentalFlag.nonNullable]) {
+          if (experimentalFlags[ExperimentalFlag.nonNullable] == true) {
             args.add("--enable-experiment=non-nullable");
             if (!context.weak) {
               args.add("--sound-null-safety");
@@ -833,13 +838,11 @@
       EvaluationMode evaluationMode) {
     constantEvaluator = new ConstantEvaluator(
         backend, environmentDefines, typeEnvironment, this,
-        desugarSets: desugarSets,
         enableTripleShift: enableTripleShift,
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
         evaluationMode: evaluationMode);
     constantEvaluatorWithEmptyEnvironment = new ConstantEvaluator(
         backend, {}, typeEnvironment, this,
-        desugarSets: desugarSets,
         enableTripleShift: enableTripleShift,
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
         evaluationMode: evaluationMode);
@@ -1060,7 +1063,7 @@
         }
 
         testOptions.component = p;
-        List<Library> keepLibraries = new List<Library>();
+        List<Library> keepLibraries = <Library>[];
         for (Library lib in p.libraries) {
           if (testOptions.linkDependencies.contains(lib.importUri)) {
             keepLibraries.add(lib);
@@ -1110,16 +1113,16 @@
             await instrumentation.fixSource(description.uri, false);
           } else {
             return new Result<ComponentResult>(
-                new ComponentResult(
-                    description, p, userLibraries, options, sourceTarget),
+                new ComponentResult(description, p, userLibraries, options,
+                    sourceTarget, sourceTarget.constantCoverageForTesting),
                 context.expectationSet["InstrumentationMismatch"],
                 instrumentation.problemsAsString,
                 autoFixCommand: '${UPDATE_COMMENTS}=true');
           }
         }
       }
-      return pass(new ComponentResult(
-          description, p, userLibraries, options, sourceTarget));
+      return pass(new ComponentResult(description, p, userLibraries, options,
+          sourceTarget, sourceTarget.constantCoverageForTesting));
     });
   }
 
@@ -1134,7 +1137,7 @@
     UriTranslator uriTranslator =
         await context.computeUriTranslator(description);
     TargetFlags targetFlags = new TargetFlags(
-      forceLateLoweringForTesting: testOptions.forceLateLowering,
+      forceLateLoweringsForTesting: testOptions.forceLateLowerings,
       forceLateLoweringSentinelForTesting:
           testOptions.forceLateLoweringSentinel,
       forceStaticFieldLoweringForTesting: testOptions.forceStaticFieldLowering,
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
index d070369..9bc5b5d 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
@@ -8,7 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,352 +20,365 @@
 
 @reflectiveTest
 class TypeConstraintGathererTest {
-  static const UnknownType unknownType = const UnknownType();
+  Env env;
 
-  static const DynamicType dynamicType = const DynamicType();
+  final Map<String, DartType Function()> additionalTypes = {
+    'UNKNOWN': () => new UnknownType()
+  };
 
-  static const VoidType voidType = const VoidType();
+  Library _coreLibrary;
 
-  final testLib =
-      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib')
-        ..isNonNullableByDefault = true;
+  Library _testLibrary;
 
-  Component component;
+  TypeConstraintGathererTest();
 
-  CoreTypes coreTypes;
+  Component get component => env.component;
 
-  TypeParameterType T1;
-  TypeParameterType T2;
-  TypeParameterType S1;
-  TypeParameterType S2;
-  TypeParameterType R1;
-  TypeParameterType R2;
+  CoreTypes get coreTypes => env.coreTypes;
 
-  Class classP;
+  Library get coreLibrary => _coreLibrary;
 
-  Class classQ;
+  Library get testLibrary => _testLibrary;
 
-  TypeConstraintGathererTest() {
-    component = createMockSdkComponent();
-    component.libraries.add(testLib..parent = component);
-    coreTypes = new CoreTypes(component);
-    T1 = new TypeParameterType(
-        new TypeParameter('T1', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
-    T2 = new TypeParameterType(
-        new TypeParameter('T2', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
-    S1 = new TypeParameterType(
-        new TypeParameter('S1', coreTypes.objectNullableRawType),
-        Nullability.undetermined);
-    S2 = new TypeParameterType(
-        new TypeParameter('S2', coreTypes.objectNullableRawType),
-        Nullability.undetermined);
-    R1 = new TypeParameterType(
-        new TypeParameter('R1', coreTypes.objectNonNullableRawType),
-        Nullability.nonNullable);
-    R2 = new TypeParameterType(
-        new TypeParameter('R2', coreTypes.objectNonNullableRawType),
-        Nullability.nonNullable);
-    classP = _addClass(_class('P'));
-    classQ = _addClass(_class('Q'));
+  void parseTestLibrary(String testLibraryText) {
+    env = new Env(testLibraryText, isNonNullableByDefault: true);
+    assert(
+        env.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = env.component.libraries.first;
+    Library secondLibrary = env.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
-  Class get functionClass => coreTypes.functionClass;
-
-  InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get P => coreTypes.legacyRawType(classP);
-
-  InterfaceType get Q => coreTypes.legacyRawType(classQ);
-
   void test_any_subtype_parameter() {
-    DartType nullableQ = Q.withDeclaredNullability(Nullability.nullable);
-    DartType nonNullableQ = Q.withDeclaredNullability(Nullability.nonNullable);
+    parseTestLibrary('class P; class Q;');
 
-    _checkConstraintsLower(T1, nullableQ, testLib, ['lib::Q? <: T1']);
-    _checkConstraintsLower(T1, nonNullableQ, testLib, ['lib::Q <: T1']);
-    _checkConstraintsUpper(T1, nullableQ, testLib, ['T1 <: lib::Q?']);
-    _checkConstraintsUpper(T1, nonNullableQ, testLib, ['T1 <: lib::Q']);
+    checkConstraintsLower('T1*', 'Q?', ['lib::Q? <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsLower('T1*', 'Q', ['lib::Q <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('T1*', 'Q?', ['T1 <: lib::Q?'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('T1*', 'Q', ['T1 <: lib::Q'],
+        typeParameters: 'T1 extends Object*');
 
-    DartType nullableS1 = S1.withDeclaredNullability(Nullability.nullable);
-    _checkConstraintsLower(S1, nonNullableQ, testLib, ['lib::Q <: S1']);
-    _checkConstraintsLower(S1, nullableQ, testLib, ['lib::Q? <: S1']);
-    _checkConstraintsLower(nullableS1, nonNullableQ, testLib, ['lib::Q <: S1']);
-    _checkConstraintsLower(nullableS1, nullableQ, testLib, ['lib::Q <: S1']);
-    _checkConstraintsUpper(S1, nonNullableQ, testLib, ['S1 <: lib::Q']);
-    _checkConstraintsUpper(S1, nullableQ, testLib, ['S1 <: lib::Q?']);
-    _checkConstraintsUpper(nullableS1, nonNullableQ, testLib, null);
-    _checkConstraintsUpper(nullableS1, nullableQ, testLib, ['S1 <: lib::Q']);
+    checkConstraintsLower('S1', 'Q', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1', 'Q?', ['lib::Q? <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1?', 'Q', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1?', 'Q?', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1', 'Q', ['S1 <: lib::Q'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1', 'Q?', ['S1 <: lib::Q?'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1?', 'Q', null,
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1?', 'Q?', ['S1 <: lib::Q'],
+        typeParameters: 'S1 extends Object?');
   }
 
   void test_any_subtype_top() {
-    _checkConstraintsUpper(P, dynamicType, testLib, []);
-    _checkConstraintsUpper(P, coreTypes.objectLegacyRawType, testLib, []);
-    _checkConstraintsUpper(P, voidType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'dynamic', []);
+    checkConstraintsUpper('P*', 'Object*', []);
+    checkConstraintsUpper('P*', 'void', []);
   }
 
   void test_any_subtype_unknown() {
-    _checkConstraintsUpper(P, unknownType, testLib, []);
-    _checkConstraintsUpper(T1, unknownType, testLib, []);
-    _checkConstraintsUpper(S1, unknownType, testLib, []);
-    _checkConstraintsUpper(R1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'UNKNOWN', []);
+    checkConstraintsUpper('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('S1', 'UNKNOWN', [],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('R1', 'UNKNOWN', [],
+        typeParameters: 'R1 extends Object');
   }
 
   void test_different_classes() {
-    _checkConstraintsUpper(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(T1), _list(Q), testLib, null);
-    _checkConstraintsUpper(_list(S1), _iterable(Q), testLib, ['S1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(S1), _list(Q), testLib, null);
-    _checkConstraintsUpper(_list(R1), _iterable(Q), testLib, ['R1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(R1), _list(Q), testLib, null);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'Iterable<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Iterable<T1*>*', 'List<Q*>*', null,
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('List<S1>*', 'Iterable<Q*>*', ['S1 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('Iterable<S1>*', 'List<Q*>*', null,
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('List<R1>*', 'Iterable<Q*>*', ['R1 <: lib::Q*'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsUpper('Iterable<R1>*', 'List<Q*>*', null,
+        typeParameters: 'R1 extends Object');
   }
 
   void test_equal_types() {
-    _checkConstraintsUpper(P, P, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'P*', []);
   }
 
   void test_function_generic() {
-    var T = new TypeParameterType(
-        new TypeParameter('T', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
-    var U = new TypeParameterType(
-        new TypeParameter('U', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
+    parseTestLibrary('');
+
     // <T>() -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '<T extends Object*>() ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: <T>() -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '() ->* dynamic', '<T extends Object*>() ->* dynamic', null);
     // <T>(T) -> T <: <U>(U) -> U, always
-    _checkConstraintsUpper(
-        new FunctionType([T], T, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([U], U, Nullability.legacy,
-            typeParameters: [U.parameter]),
-        testLib,
-        []);
+    checkConstraintsUpper(
+        '<T extends Object*>(T*) ->* T*', '<U extends Object*>(U*) ->* U*', []);
   }
 
   void test_function_parameter_mismatch() {
+    parseTestLibrary('class P; class Q;');
+
     // (P) -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('(P*) ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: (P) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '(P*) ->* dynamic', null);
     // ([P]) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('([P*]) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic <: ([P]) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '([P*]) ->* dynamic', null);
     // ({x: P}) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('({P* x}) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic !<: ({x: P}) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '({P* x}) ->* dynamic', null);
   }
 
   void test_function_parameter_types() {
+    parseTestLibrary('class P; class Q;');
+
     // (T1) -> dynamic <: (Q) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([T1], dynamicType, Nullability.legacy),
-        new FunctionType([Q], dynamicType, Nullability.legacy),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '(T1*) ->* dynamic', '(Q*) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
     // ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', T1)]),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', Q)]),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '({T1* x}) ->* dynamic', '({Q* x}) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
     // (S1) -> S1? <: (P) -> P?
-    _checkConstraintsUpper(
-        new FunctionType([S1], S1.withDeclaredNullability(Nullability.nullable),
-            Nullability.nonNullable),
-        new FunctionType(
-            [P.withDeclaredNullability(Nullability.nonNullable)],
-            P.withDeclaredNullability(Nullability.nullable),
-            Nullability.nonNullable),
-        testLib,
-        ['lib::P <: S1 <: lib::P']);
+    checkConstraintsUpper(
+        '(S1) -> S1?', '(P) -> P?', ['lib::P <: S1 <: lib::P'],
+        typeParameters: 'S1 extends Object?');
     // (S1, List<S1?>) -> void <: (P, List<P?>) -> void
-    _checkConstraintsUpper(
-        new FunctionType(
-            [S1, _list(S1.withDeclaredNullability(Nullability.nullable))],
-            voidType,
-            Nullability.nonNullable),
-        new FunctionType([
-          P.withDeclaredNullability(Nullability.nonNullable),
-          _list(P.withDeclaredNullability(Nullability.nullable))
-        ], voidType, Nullability.nonNullable),
-        testLib,
-        ['lib::P <: S1']);
+    checkConstraintsUpper(
+        '(S1, List<S1?>*) -> void', '(P, List<P?>*) -> void', ['lib::P <: S1'],
+        typeParameters: 'S1 extends Object?');
   }
 
   void test_function_return_type() {
+    parseTestLibrary('class P; class Q;');
+
     // () -> T1 <: () -> Q, under constraint T1 <: Q
-    _checkConstraintsUpper(
-        new FunctionType([], T1, Nullability.legacy),
-        new FunctionType([], Q, Nullability.legacy),
-        testLib,
-        ['T1 <: lib::Q*']);
+    checkConstraintsUpper('() ->* T1', '() ->* Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
     // () -> P <: () -> void, always
-    _checkConstraintsUpper(new FunctionType([], P, Nullability.legacy),
-        new FunctionType([], voidType, Nullability.legacy), testLib, []);
+    checkConstraintsUpper('() ->* P*', '() ->* void', []);
     // () -> void <: () -> P, never
-    _checkConstraintsUpper(new FunctionType([], voidType, Nullability.legacy),
-        new FunctionType([], P, Nullability.legacy), testLib, null);
+    checkConstraintsUpper('() ->* void', '() ->* P*', null);
   }
 
   void test_function_trivial_cases() {
-    var F = new FunctionType([], dynamicType, Nullability.legacy);
+    parseTestLibrary('');
+
     // () -> dynamic <: dynamic, always
-    _checkConstraintsUpper(F, dynamicType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'dynamic', []);
     // () -> dynamic <: Function, always
-    _checkConstraintsUpper(F, functionType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'Function*', []);
     // () -> dynamic <: Object, always
-    _checkConstraintsUpper(F, coreTypes.objectLegacyRawType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'Object*', []);
   }
 
   void test_nonInferredParameter_subtype_any() {
-    var U = new TypeParameterType(
-        new TypeParameter('U', _list(P)), Nullability.legacy);
-    _checkConstraintsLower(_list(T1), U, testLib, ['lib::P* <: T1']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('List<T1*>*', 'U*', ['lib::P* <: T1'],
+        typeParameters: 'T1 extends Object*, U extends List<P*>*',
+        typeParametersToConstrain: 'T1');
   }
 
   void test_null_subtype_any() {
-    _checkConstraintsLower(T1, new NullType(), testLib, ['Null <: T1']);
-    _checkConstraintsUpper(new NullType(), Q, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('T1*', 'Null', ['Null <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Null', 'Q*', []);
   }
 
   void test_parameter_subtype_any() {
-    _checkConstraintsUpper(T1, Q, testLib, ['T1 <: lib::Q*']);
-    _checkConstraintsLower(T1, Q, testLib, ['lib::Q* <: T1']);
+    parseTestLibrary('class P; class Q;');
 
-    _checkConstraintsUpper(S1, Q, testLib, ['S1 <: lib::Q*']);
-    _checkConstraintsLower(S1, Q, testLib, ['lib::Q* <: S1']);
-    _checkConstraintsUpper(S1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['S1 <: lib::Q*']);
-    _checkConstraintsLower(S1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['lib::Q <: S1']);
+    checkConstraintsUpper('T1*', 'Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsLower('T1*', 'Q*', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
 
-    _checkConstraintsUpper(R1, Q, testLib, ['R1 <: lib::Q*']);
-    _checkConstraintsLower(R1, Q, testLib, ['lib::Q* <: R1']);
-    _checkConstraintsUpper(R1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['R1 <: lib::Q*']);
-    _checkConstraintsLower(R1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['lib::Q <: R1']);
+    checkConstraintsUpper('S1', 'Q*', ['S1 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1', 'Q*', ['lib::Q* <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1*', 'Q*', ['S1 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1*', 'Q*', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+
+    checkConstraintsUpper('R1', 'Q*', ['R1 <: lib::Q*'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsLower('R1', 'Q*', ['lib::Q* <: R1'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsUpper('R1*', 'Q*', ['R1 <: lib::Q*'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsLower('R1*', 'Q*', ['lib::Q <: R1'],
+        typeParameters: 'R1 extends Object');
   }
 
   void test_same_classes() {
-    _checkConstraintsUpper(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'List<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_typeParameters() {
-    _checkConstraintsUpper(
-        _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(T1, T2), _map(P, Q), testLib, ['lib::P* <: T1', 'lib::Q* <: T2']);
+    parseTestLibrary('class P; class Q; class Map<X, Y>;');
 
-    _checkConstraintsUpper(
-        _map(S1, S2), _map(P, Q), testLib, ['S1 <: lib::P*', 'S2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(S1, S2), _map(P, Q), testLib, ['lib::P* <: S1', 'lib::Q* <: S2']);
-    _checkConstraintsUpper(
-        _map(S1.withDeclaredNullability(Nullability.legacy),
-            S2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['S1 <: lib::P*', 'S2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(S1.withDeclaredNullability(Nullability.legacy),
-            S2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['lib::P <: S1', 'lib::Q <: S2']);
+    checkConstraintsUpper(
+        'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['T1 <: lib::P*', 'T2 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*, T2 extends Object*');
+    checkConstraintsLower(
+        'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['lib::P* <: T1', 'lib::Q* <: T2'],
+        typeParameters: 'T1 extends Object*, T2 extends Object*');
 
-    _checkConstraintsUpper(
-        _map(R1, R2), _map(P, Q), testLib, ['R1 <: lib::P*', 'R2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(R1, R2), _map(P, Q), testLib, ['lib::P* <: R1', 'lib::Q* <: R2']);
-    _checkConstraintsUpper(
-        _map(R1.withDeclaredNullability(Nullability.legacy),
-            R2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['R1 <: lib::P*', 'R2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(R1.withDeclaredNullability(Nullability.legacy),
-            R2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['lib::P <: R1', 'lib::Q <: R2']);
+    checkConstraintsUpper(
+        'Map<S1, S2>*', 'Map<P*, Q*>*', ['S1 <: lib::P*', 'S2 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+    checkConstraintsLower(
+        'Map<S1, S2>*', 'Map<P*, Q*>*', ['lib::P* <: S1', 'lib::Q* <: S2'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+    checkConstraintsUpper(
+        'Map<S1*, S2*>*', 'Map<P*, Q*>*', ['S1 <: lib::P*', 'S2 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+    checkConstraintsLower(
+        'Map<S1*, S2*>*', 'Map<P*, Q*>*', ['lib::P <: S1', 'lib::Q <: S2'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+
+    checkConstraintsUpper(
+        'Map<R1, R2>*', 'Map<P*, Q*>*', ['R1 <: lib::P*', 'R2 <: lib::Q*'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
+    checkConstraintsLower(
+        'Map<R1, R2>*', 'Map<P*, Q*>*', ['lib::P* <: R1', 'lib::Q* <: R2'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
+    checkConstraintsUpper(
+        'Map<R1*, R2*>*', 'Map<P*, Q*>*', ['R1 <: lib::P*', 'R2 <: lib::Q*'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
+    checkConstraintsLower(
+        'Map<R1*, R2*>*', 'Map<P*, Q*>*', ['lib::P <: R1', 'lib::Q <: R2'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
   }
 
   void test_unknown_subtype_any() {
-    _checkConstraintsLower(Q, unknownType, testLib, []);
-    _checkConstraintsLower(T1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('Q*', 'UNKNOWN', []);
+    checkConstraintsLower('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
   }
 
-  Class _addClass(Class c) {
-    testLib.addClass(c);
-    return c;
+  void checkConstraintsLower(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsLowerTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
   }
 
-  void _checkConstraintsLower(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound));
+  void _checkConstraintsLowerTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound),
+        typeParameterNodesToConstrain);
   }
 
-  void _checkConstraintsUpper(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound));
+  void checkConstraintsUpper(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsUpperTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
+  }
+
+  void _checkConstraintsUpperTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound),
+        typeParameterNodesToConstrain);
   }
 
   void _checkConstraintsHelper(
@@ -373,20 +386,12 @@
       DartType b,
       Library clientLibrary,
       List<String> expectedConstraints,
-      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain) {
+      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain,
+      List<TypeParameter> typeParameterNodesToConstrain) {
     var typeSchemaEnvironment = new TypeSchemaEnvironment(
         coreTypes, new ClassHierarchy(component, coreTypes));
     var typeConstraintGatherer = new TypeConstraintGatherer(
-        typeSchemaEnvironment,
-        [
-          T1.parameter,
-          T2.parameter,
-          S1.parameter,
-          S2.parameter,
-          R1.parameter,
-          R2.parameter
-        ],
-        testLib);
+        typeSchemaEnvironment, typeParameterNodesToConstrain, testLibrary);
     var constraints = tryConstrain(typeConstraintGatherer, a, b)
         ? typeConstraintGatherer.computeConstraints(clientLibrary)
         : null;
@@ -411,24 +416,4 @@
     });
     expect(constraintStrings, unorderedEquals(expectedConstraints));
   }
-
-  Class _class(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
-  }
-
-  DartType _iterable(DartType element) =>
-      new InterfaceType(iterableClass, Nullability.legacy, [element]);
-
-  DartType _list(DartType element) =>
-      new InterfaceType(listClass, Nullability.legacy, [element]);
-
-  DartType _map(DartType key, DartType value) =>
-      new InterfaceType(mapClass, Nullability.legacy, [key, value]);
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
index ebdb227..d690cba 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
@@ -8,7 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,239 +20,273 @@
 
 @reflectiveTest
 class TypeConstraintGathererTest {
-  static const UnknownType unknownType = const UnknownType();
+  Env env;
 
-  static const DynamicType dynamicType = const DynamicType();
+  final Map<String, DartType Function()> additionalTypes = {
+    'UNKNOWN': () => UnknownType()
+  };
 
-  static const VoidType voidType = const VoidType();
+  Library _coreLibrary;
 
-  final testLib =
-      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
+  Library _testLibrary;
 
-  Component component;
+  TypeConstraintGathererTest();
 
-  CoreTypes coreTypes;
+  Component get component => env.component;
 
-  TypeParameterType T1;
+  CoreTypes get coreTypes => env.coreTypes;
 
-  TypeParameterType T2;
+  Library get coreLibrary => _coreLibrary;
 
-  Class classP;
+  Library get testLibrary => _testLibrary;
 
-  Class classQ;
-
-  TypeConstraintGathererTest() {
-    component = createMockSdkComponent();
-    component.libraries.add(testLib..parent = component);
-    coreTypes = new CoreTypes(component);
-    T1 = new TypeParameterType(
-        new TypeParameter('T1', objectType), Nullability.legacy);
-    T2 = new TypeParameterType(
-        new TypeParameter('T2', objectType), Nullability.legacy);
-    classP = _addClass(_class('P'));
-    classQ = _addClass(_class('Q'));
+  void parseTestLibrary(String testLibraryText) {
+    env = new Env(testLibraryText, isNonNullableByDefault: false);
+    assert(
+        env.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = env.component.libraries.first;
+    Library secondLibrary = env.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
-  Class get functionClass => coreTypes.functionClass;
-
-  InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get objectType => coreTypes.objectLegacyRawType;
-
-  InterfaceType get P => coreTypes.legacyRawType(classP);
-
-  InterfaceType get Q => coreTypes.legacyRawType(classQ);
-
   void test_any_subtype_parameter() {
-    _checkConstraintsLower(T1, Q, testLib, ['lib::Q* <: T1']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('T1*', 'Q*', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_any_subtype_top() {
-    _checkConstraintsUpper(P, dynamicType, testLib, []);
-    _checkConstraintsUpper(P, objectType, testLib, []);
-    _checkConstraintsUpper(P, voidType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'dynamic', []);
+    checkConstraintsUpper('P*', 'Object*', []);
+    checkConstraintsUpper('P*', 'void', []);
   }
 
   void test_any_subtype_unknown() {
-    _checkConstraintsUpper(P, unknownType, testLib, []);
-    _checkConstraintsUpper(T1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'UNKNOWN', []);
+    checkConstraintsUpper('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_different_classes() {
-    _checkConstraintsUpper(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(T1), _list(Q), testLib, null);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'Iterable<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Iterable<T1*>*', 'List<Q*>*', null,
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_equal_types() {
-    _checkConstraintsUpper(P, P, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'P*', []);
   }
 
   void test_function_generic() {
-    var T = new TypeParameterType(
-        new TypeParameter('T', objectType), Nullability.legacy);
-    var U = new TypeParameterType(
-        new TypeParameter('U', objectType), Nullability.legacy);
+    parseTestLibrary('');
+
     // <T>() -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '<T extends Object*>() ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: <T>() -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '() ->* dynamic', '<T extends Object*>() ->* dynamic', null);
     // <T>(T) -> T <: <U>(U) -> U, always
-    _checkConstraintsUpper(
-        new FunctionType([T], T, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([U], U, Nullability.legacy,
-            typeParameters: [U.parameter]),
-        testLib,
-        []);
+    checkConstraintsUpper(
+        '<T extends Object*>(T*) ->* T*', '<U extends Object*>(U*) ->* U*', []);
   }
 
   void test_function_parameter_mismatch() {
+    parseTestLibrary('class P; class Q;');
+
     // (P) -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('(P*) ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: (P) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '(P*) ->* dynamic', null);
     // ([P]) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('([P*]) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic <: ([P]) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '([P*]) ->* dynamic', null);
     // ({x: P}) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('({P* x}) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic !<: ({x: P}) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '({P* x}) ->* dynamic', null);
   }
 
   void test_function_parameter_types() {
+    parseTestLibrary('class P; class Q;');
+
     // (T1) -> dynamic <: (Q) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([T1], dynamicType, Nullability.legacy),
-        new FunctionType([Q], dynamicType, Nullability.legacy),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '(T1*) ->* dynamic', '(Q*) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
     // ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', T1)]),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', Q)]),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '({T1* x}) ->* dynamic', '({Q* x}) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_function_return_type() {
+    parseTestLibrary('class P; class Q;');
+
     // () -> T1 <: () -> Q, under constraint T1 <: Q
-    _checkConstraintsUpper(
-        new FunctionType([], T1, Nullability.legacy),
-        new FunctionType([], Q, Nullability.legacy),
-        testLib,
-        ['T1 <: lib::Q*']);
+    checkConstraintsUpper('() ->* T1*', '() ->* Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
     // () -> P <: () -> void, always
-    _checkConstraintsUpper(new FunctionType([], P, Nullability.legacy),
-        new FunctionType([], voidType, Nullability.legacy), testLib, []);
+    checkConstraintsUpper('() ->* P*', '() ->* void', []);
     // () -> void <: () -> P, never
-    _checkConstraintsUpper(new FunctionType([], voidType, Nullability.legacy),
-        new FunctionType([], P, Nullability.legacy), testLib, null);
+    checkConstraintsUpper('() ->* void', '() ->* P*', null);
   }
 
   void test_function_trivial_cases() {
-    var F = new FunctionType([], dynamicType, Nullability.legacy);
+    parseTestLibrary('');
+
     // () -> dynamic <: dynamic, always
-    _checkConstraintsUpper(F, dynamicType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'dynamic', []);
     // () -> dynamic <: Function, always
-    _checkConstraintsUpper(F, functionType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', "Function*", []);
     // () -> dynamic <: Object, always
-    _checkConstraintsUpper(F, objectType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'Object*', []);
   }
 
   void test_nonInferredParameter_subtype_any() {
-    var U = new TypeParameterType(
-        new TypeParameter('U', _list(P)), Nullability.legacy);
-    _checkConstraintsLower(_list(T1), U, testLib, ['lib::P* <: T1']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('List<T1*>*', 'U*', ['lib::P* <: T1'],
+        typeParameters: 'T1 extends Object*, U extends List<P*>*',
+        typeParametersToConstrain: 'T1');
   }
 
   void test_null_subtype_any() {
-    _checkConstraintsLower(T1, new NullType(), testLib, ['Null <: T1']);
-    _checkConstraintsUpper(new NullType(), Q, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('T1*', 'Null', ['Null <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Null', 'Q*', []);
   }
 
   void test_parameter_subtype_any() {
-    _checkConstraintsUpper(T1, Q, testLib, ['T1 <: lib::Q*']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('T1*', 'Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_same_classes() {
-    _checkConstraintsUpper(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'List<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_typeParameters() {
-    _checkConstraintsUpper(
-        _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']);
+    parseTestLibrary('class P; class Q; class Map<X, Y>;');
+
+    checkConstraintsUpper(
+        'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['T1 <: lib::P*', 'T2 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*, T2 extends Object*');
   }
 
   void test_unknown_subtype_any() {
-    _checkConstraintsUpper(Q, unknownType, testLib, []);
-    _checkConstraintsUpper(T1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('Q*', 'UNKNOWN', []);
+    checkConstraintsUpper('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
   }
 
-  Class _addClass(Class c) {
-    testLib.addClass(c);
-    return c;
+  void checkConstraintsLower(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsLowerTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
   }
 
-  void _checkConstraintsLower(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound));
+  void _checkConstraintsLowerTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound),
+        typeParameterNodesToConstrain);
   }
 
-  void _checkConstraintsUpper(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound));
+  void checkConstraintsUpper(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsUpperTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
+  }
+
+  void _checkConstraintsUpperTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound),
+        typeParameterNodesToConstrain);
   }
 
   void _checkConstraintsHelper(
@@ -260,11 +294,12 @@
       DartType b,
       Library clientLibrary,
       List<String> expectedConstraints,
-      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain) {
+      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain,
+      List<TypeParameter> typeParameterNodesToConstrain) {
     var typeSchemaEnvironment = new TypeSchemaEnvironment(
         coreTypes, new ClassHierarchy(component, coreTypes));
     var typeConstraintGatherer = new TypeConstraintGatherer(
-        typeSchemaEnvironment, [T1.parameter, T2.parameter], testLib);
+        typeSchemaEnvironment, typeParameterNodesToConstrain, testLibrary);
     var constraints = tryConstrain(typeConstraintGatherer, a, b)
         ? typeConstraintGatherer.computeConstraints(clientLibrary)
         : null;
@@ -289,24 +324,4 @@
     });
     expect(constraintStrings, unorderedEquals(expectedConstraints));
   }
-
-  Class _class(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
-  }
-
-  DartType _iterable(DartType element) =>
-      new InterfaceType(iterableClass, Nullability.legacy, [element]);
-
-  DartType _list(DartType element) =>
-      new InterfaceType(listClass, Nullability.legacy, [element]);
-
-  DartType _map(DartType key, DartType value) =>
-      new InterfaceType(mapClass, Nullability.legacy, [key, value]);
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
index dcad472..aa491cc 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
@@ -6,7 +6,7 @@
 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
     as typeSchemaElimination;
 import 'package:kernel/ast.dart';
-import 'package:kernel/core_types.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -18,13 +18,10 @@
 
 @reflectiveTest
 class TypeSchemaEliminationTest {
-  static const DartType unknownType = const UnknownType();
-
-  CoreTypes coreTypes = new _MockCoreTypes();
-
-  DartType get dynamicType => const DynamicType();
-
-  DartType get nullType => new NullType();
+  final Env env = new Env("", isNonNullableByDefault: true);
+  final Map<String, DartType Function()> additionalTypes = {
+    "UNKNOWN": () => new UnknownType()
+  };
 
   DartType greatestClosure(DartType schema) {
     return typeSchemaElimination.greatestClosure(
@@ -36,116 +33,62 @@
         schema, const DynamicType(), const NeverType(Nullability.nonNullable));
   }
 
+  void testGreatest(String type, String expectedClosure) {
+    expect(
+        greatestClosure(env.parseType(type, additionalTypes: additionalTypes)),
+        env.parseType(expectedClosure, additionalTypes: additionalTypes));
+  }
+
+  void testLeast(String type, String expectedClosure) {
+    expect(leastClosure(env.parseType(type, additionalTypes: additionalTypes)),
+        env.parseType(expectedClosure, additionalTypes: additionalTypes));
+  }
+
   void test_greatestClosure_contravariant() {
-    expect(
-        greatestClosure(new FunctionType(
-                [unknownType], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '(Never) →* dynamic');
-    expect(
-        greatestClosure(new FunctionType([], dynamicType, Nullability.legacy,
-                namedParameters: [new NamedType('foo', unknownType)]))
-            .leakingDebugToString(),
-        '({foo: Never}) →* dynamic');
+    testGreatest("(UNKNOWN) ->* dynamic", "(Never) ->* dynamic");
+    testGreatest("({UNKNOWN foo}) ->* dynamic", "({Never foo}) ->* dynamic");
   }
 
   void test_greatestClosure_contravariant_contravariant() {
-    expect(
-        greatestClosure(new FunctionType([
-          new FunctionType([unknownType], dynamicType, Nullability.legacy)
-        ], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '((dynamic) →* dynamic) →* dynamic');
+    testGreatest("((UNKNOWN) ->* dynamic) ->* dynamic",
+        "((dynamic) ->* dynamic) ->* dynamic");
   }
 
   void test_greatestClosure_covariant() {
-    expect(
-        greatestClosure(new FunctionType([], unknownType, Nullability.legacy))
-            .leakingDebugToString(),
-        '() →* dynamic');
-    expect(
-        greatestClosure(new InterfaceType(
-                coreTypes.listClass, Nullability.legacy, [unknownType]))
-            .leakingDebugToString(),
-        'dart.core::List<dynamic>*');
+    testGreatest("() ->* UNKNOWN", "() ->* dynamic");
+    testGreatest("List<UNKNOWN>*", "List<dynamic>*");
   }
 
   void test_greatestClosure_function_multipleUnknown() {
-    expect(
-        greatestClosure(new FunctionType(
-            [unknownType, unknownType], unknownType, Nullability.legacy,
-            namedParameters: [
-              new NamedType('a', unknownType),
-              new NamedType('b', unknownType)
-            ])).leakingDebugToString(),
-        '(Never, Never, {a: Never, b: Never}) →* dynamic');
+    testGreatest("(UNKNOWN, UNKNOWN, {UNKNOWN a, UNKNOWN b}) ->* UNKNOWN",
+        "(Never, Never, {Never a, Never b}) ->* dynamic");
   }
 
   void test_greatestClosure_simple() {
-    expect(greatestClosure(unknownType).leakingDebugToString(), 'dynamic');
+    testGreatest("UNKNOWN", "dynamic");
   }
 
   void test_leastClosure_contravariant() {
-    expect(
-        leastClosure(new FunctionType(
-                [unknownType], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '(dynamic) →* dynamic');
-    expect(
-        leastClosure(new FunctionType([], dynamicType, Nullability.legacy,
-                namedParameters: [new NamedType('foo', unknownType)]))
-            .leakingDebugToString(),
-        '({foo: dynamic}) →* dynamic');
+    testLeast("(UNKNOWN) ->* dynamic", "(dynamic) ->* dynamic");
+    testLeast("({UNKNOWN foo}) ->* dynamic", "({dynamic foo}) ->* dynamic");
   }
 
   void test_leastClosure_contravariant_contravariant() {
-    expect(
-        leastClosure(new FunctionType([
-          new FunctionType([unknownType], dynamicType, Nullability.legacy)
-        ], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '((Never) →* dynamic) →* dynamic');
+    testLeast("((UNKNOWN) ->* dynamic) ->* dynamic",
+        "((Never) ->* dynamic) ->* dynamic");
   }
 
   void test_leastClosure_covariant() {
-    expect(
-        leastClosure(new FunctionType([], unknownType, Nullability.legacy))
-            .leakingDebugToString(),
-        '() →* Never');
-    expect(
-        leastClosure(new InterfaceType(
-                coreTypes.listClass, Nullability.legacy, [unknownType]))
-            .leakingDebugToString(),
-        'dart.core::List<Never>*');
+    testLeast("() ->* UNKNOWN", "() ->* Never");
+    testLeast("List<UNKNOWN>*", "List<Never>*");
   }
 
   void test_leastClosure_function_multipleUnknown() {
-    expect(
-        leastClosure(new FunctionType(
-            [unknownType, unknownType], unknownType, Nullability.legacy,
-            namedParameters: [
-              new NamedType('a', unknownType),
-              new NamedType('b', unknownType)
-            ])).leakingDebugToString(),
-        '(dynamic, dynamic, {a: dynamic, b: dynamic}) →* Never');
+    testLeast("(UNKNOWN, UNKNOWN, {UNKNOWN a, UNKNOWN b}) ->* UNKNOWN",
+        "(dynamic, dynamic, {dynamic a, dynamic b}) ->* Never");
   }
 
   void test_leastClosure_simple() {
-    expect(leastClosure(unknownType).leakingDebugToString(), 'Never');
+    testLeast("UNKNOWN", "Never");
   }
 }
-
-class _MockCoreTypes implements CoreTypes {
-  @override
-  final Class listClass = new Class(name: 'List');
-
-  @override
-  final Class objectClass = new Class(name: 'Object');
-
-  _MockCoreTypes() {
-    new Library(Uri.parse('dart:core'),
-        name: 'dart.core', classes: [listClass, objectClass]);
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index a4c8ee3..3d30f92 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -6,7 +6,7 @@
 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
     as typeSchemaElimination;
 import 'package:kernel/ast.dart';
-import 'package:kernel/core_types.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -18,134 +18,77 @@
 
 @reflectiveTest
 class TypeSchemaEliminationTest {
-  static const DartType unknownType = const UnknownType();
-
-  CoreTypes coreTypes = new _MockCoreTypes();
-
-  DartType get dynamicType => const DynamicType();
-
-  DartType get objectType => coreTypes.objectLegacyRawType;
+  final Env env = new Env("", isNonNullableByDefault: false);
+  final Map<String, DartType Function()> additionalTypes = {
+    "UNKNOWN": () => new UnknownType()
+  };
 
   DartType greatestClosure(DartType schema) {
     return typeSchemaElimination.greatestClosure(
-        schema, dynamicType, const NullType());
+        schema, new DynamicType(), new NullType());
   }
 
   DartType leastClosure(DartType schema) {
     return typeSchemaElimination.leastClosure(
-        schema, dynamicType, const NullType());
+        schema, new DynamicType(), new NullType());
+  }
+
+  void testGreatest(String type, String expectedClosure) {
+    expect(
+        greatestClosure(env.parseType(type, additionalTypes: additionalTypes)),
+        env.parseType(expectedClosure, additionalTypes: additionalTypes));
+  }
+
+  void testLeast(String type, String expectedClosure) {
+    expect(leastClosure(env.parseType(type, additionalTypes: additionalTypes)),
+        env.parseType(expectedClosure, additionalTypes: additionalTypes));
   }
 
   void test_greatestClosure_contravariant() {
-    expect(
-        greatestClosure(new FunctionType(
-                [unknownType], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '(Null) →* dynamic');
-    expect(
-        greatestClosure(new FunctionType([], dynamicType, Nullability.legacy,
-                namedParameters: [new NamedType('foo', unknownType)]))
-            .leakingDebugToString(),
-        '({foo: Null}) →* dynamic');
+    testGreatest("(UNKNOWN) ->* dynamic", "(Null) ->* dynamic");
+    testGreatest("({UNKNOWN foo}) ->* dynamic", "({Null foo}) ->* dynamic");
   }
 
   void test_greatestClosure_contravariant_contravariant() {
-    expect(
-        greatestClosure(new FunctionType([
-          new FunctionType([unknownType], dynamicType, Nullability.legacy)
-        ], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '((dynamic) →* dynamic) →* dynamic');
+    testGreatest("((UNKNOWN) ->* dynamic) ->* dynamic",
+        "((dynamic) ->* dynamic) ->* dynamic");
   }
 
   void test_greatestClosure_covariant() {
-    expect(
-        greatestClosure(new FunctionType([], unknownType, Nullability.legacy))
-            .leakingDebugToString(),
-        '() →* dynamic');
-    expect(
-        greatestClosure(new InterfaceType(
-                coreTypes.listClass, Nullability.legacy, [unknownType]))
-            .leakingDebugToString(),
-        'dart.core::List<dynamic>*');
+    testGreatest("() ->* UNKNOWN", "() ->* dynamic");
+    testGreatest("List<UNKNOWN>*", "List<dynamic>*");
   }
 
   void test_greatestClosure_function_multipleUnknown() {
-    expect(
-        greatestClosure(new FunctionType(
-            [unknownType, unknownType], unknownType, Nullability.legacy,
-            namedParameters: [
-              new NamedType('a', unknownType),
-              new NamedType('b', unknownType)
-            ])).leakingDebugToString(),
-        '(Null, Null, {a: Null, b: Null}) →* dynamic');
+    testGreatest("(UNKNOWN, UNKNOWN, {UNKNOWN a, UNKNOWN b}) ->* UNKNOWN",
+        "(Null, Null, {Null a, Null b}) ->* dynamic");
   }
 
   void test_greatestClosure_simple() {
-    expect(greatestClosure(unknownType).leakingDebugToString(), 'dynamic');
+    testGreatest("UNKNOWN", "dynamic");
   }
 
   void test_leastClosure_contravariant() {
-    expect(
-        leastClosure(new FunctionType(
-                [unknownType], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '(dynamic) →* dynamic');
-    expect(
-        leastClosure(new FunctionType([], dynamicType, Nullability.legacy,
-                namedParameters: [new NamedType('foo', unknownType)]))
-            .leakingDebugToString(),
-        '({foo: dynamic}) →* dynamic');
+    testLeast("(UNKNOWN) ->* dynamic", "(dynamic) ->* dynamic");
+    testLeast("({UNKNOWN foo}) ->* dynamic", "({dynamic foo}) ->* dynamic");
   }
 
   void test_leastClosure_contravariant_contravariant() {
-    expect(
-        leastClosure(new FunctionType([
-          new FunctionType([unknownType], dynamicType, Nullability.legacy)
-        ], dynamicType, Nullability.legacy))
-            .leakingDebugToString(),
-        '((Null) →* dynamic) →* dynamic');
+    testLeast("((UNKNOWN) ->* UNKNOWN) ->* dynamic",
+        "((Null) ->* dynamic) ->* dynamic");
   }
 
   void test_leastClosure_covariant() {
-    expect(
-        leastClosure(new FunctionType([], unknownType, Nullability.legacy))
-            .leakingDebugToString(),
-        '() →* Null');
-    expect(
-        leastClosure(new InterfaceType(
-                coreTypes.listClass, Nullability.legacy, [unknownType]))
-            .leakingDebugToString(),
-        'dart.core::List<Null>*');
+    testLeast("() ->* UNKNOWN", "() ->* Null");
+    testLeast("List<UNKNOWN>*", "List<Null>*");
   }
 
   void test_leastClosure_function_multipleUnknown() {
-    expect(
-        leastClosure(new FunctionType(
-            [unknownType, unknownType], unknownType, Nullability.legacy,
-            namedParameters: [
-              new NamedType('a', unknownType),
-              new NamedType('b', unknownType)
-            ])).leakingDebugToString(),
-        '(dynamic, dynamic, {a: dynamic, b: dynamic}) →* Null');
+    testLeast("(UNKNOWN, UNKNOWN, {UNKNOWN a, UNKNOWN b}) ->* UNKNOWN",
+        "(dynamic, dynamic, {dynamic a, dynamic b}) ->* Null");
   }
 
   void test_leastClosure_simple() {
-    expect(leastClosure(unknownType).leakingDebugToString(), 'Null');
+    testLeast("UNKNOWN", "Null");
   }
 }
-
-class _MockCoreTypes implements CoreTypes {
-  @override
-  final Class listClass = new Class(name: 'List');
-
-  @override
-  final Class objectClass = new Class(name: 'Object');
-
-  _MockCoreTypes() {
-    new Library(Uri.parse('dart:core'),
-        name: 'dart.core', classes: [listClass, objectClass]);
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
index 9e5df47..5818a50 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
@@ -8,8 +8,6 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/testing/type_parser_environment.dart';
-import 'package:kernel/testing/mock_sdk.dart';
-import 'package:kernel/type_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -21,97 +19,90 @@
 
 @reflectiveTest
 class TypeSchemaEnvironmentTest {
-  Component component;
+  Env typeParserEnvironment;
+  TypeSchemaEnvironment typeSchemaEnvironment;
 
-  CoreTypes coreTypes;
+  final Map<String, DartType Function()> additionalTypes = {
+    "UNKNOWN": () => new UnknownType(),
+    "BOTTOM": () => new BottomType(),
+  };
 
-  TypeSchemaEnvironment env;
+  Library _coreLibrary;
+  Library _testLibrary;
 
-  TypeParserEnvironment typeParserEnvironment;
+  Library get coreLibrary => _coreLibrary;
+  Library get testLibrary => _testLibrary;
 
-  Library get testLib => component.libraries.single;
+  Component get component => typeParserEnvironment.component;
+  CoreTypes get coreTypes => typeParserEnvironment.coreTypes;
 
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  DartType get bottomType => const NeverType(Nullability.nonNullable);
-
-  DartType get topType => coreTypes.objectNullableRawType;
-
-  /// Converts the [text] representation of a type into a type.
-  ///
-  /// If [environment] is passed it's used to resolve the type terms in [text].
-  /// If [typeParameters] are passed, they are used to extend
-  /// [typeParserEnvironment] to resolve the type terms in [text].  Not more
-  /// than one of [environment] or [typeParameters] should be passed in.
-  DartType toType(String text,
-      {TypeParserEnvironment environment, String typeParameters}) {
-    assert(environment == null || typeParameters == null);
-    environment ??= extend(typeParameters);
-    return environment.parseType(text);
-  }
-
-  TypeParserEnvironment extend(String typeParameters) {
-    return typeParserEnvironment.extendWithTypeParameters(typeParameters);
+  void parseTestLibrary(String testLibraryText) {
+    typeParserEnvironment =
+        new Env(testLibraryText, isNonNullableByDefault: true);
+    typeSchemaEnvironment = new TypeSchemaEnvironment(
+        coreTypes, new ClassHierarchy(component, coreTypes));
+    assert(
+        typeParserEnvironment.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = typeParserEnvironment.component.libraries.first;
+    Library secondLibrary = typeParserEnvironment.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
   void test_addLowerBound() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class C extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    TypeConstraint typeConstraint = new TypeConstraint();
 
     // typeConstraint: EMPTY <: TYPE <: EMPTY
-    expect(typeConstraint.lower, new UnknownType());
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
 
     // typeConstraint: B* <: TYPE <: EMPTY
-    env.addLowerBound(typeConstraint, toType("B*"), testLib);
-    testConstraint(typeConstraint, lowerExpected: toType("B*"));
+    checkConstraintLowerBound(constraint: ":> B*", bound: "B*");
 
     // typeConstraint: UP(B*, C*) <: TYPE <: EMPTY,
     //     where UP(B*, C*) = A*
-    env.addLowerBound(typeConstraint, toType("C*"), testLib);
-    testConstraint(typeConstraint, lowerExpected: toType("A*"));
+    checkConstraintLowerBound(constraint: ":> B* :> C*", bound: "A*");
   }
 
   void test_addUpperBound() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class C extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    TypeConstraint typeConstraint = new TypeConstraint();
 
     // typeConstraint: EMPTY <: TYPE <: EMPTY
-    expect(typeConstraint.upper, new UnknownType());
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
 
     // typeConstraint: EMPTY <: TYPE <: A*
-    env.addUpperBound(typeConstraint, toType("A*"), testLib);
-    testConstraint(typeConstraint, upperExpected: toType("A*"));
+    checkConstraintUpperBound(constraint: "<: A*", bound: "A*");
 
     // typeConstraint: EMPTY <: TYPE <: DOWN(A*, B*),
     //     where DOWN(A*, B*) = B*
-    env.addUpperBound(typeConstraint, toType("B*"), testLib);
-    testConstraint(typeConstraint, upperExpected: toType("B*"));
+    checkConstraintUpperBound(constraint: "<: A* <: B*", bound: "B*");
 
     // typeConstraint: EMPTY <: TYPE <: DOWN(B*, C*),
     //     where DOWN(B*, C*) = Never*
-    env.addUpperBound(typeConstraint, toType("C*"), testLib);
-    testConstraint(typeConstraint,
-        upperExpected: new NeverType(Nullability.legacy));
+    checkConstraintUpperBound(constraint: "<:A* <: B* <: C*", bound: "Never*");
   }
 
   /// Some of the types satisfying the TOP predicate.
@@ -272,53 +263,12 @@
     return "$typeParameters1, $typeParameters2";
   }
 
-  void testLower(String first, String second, String expected,
-      {String typeParameters}) {
-    TypeParserEnvironment environment = extend(typeParameters);
-    DartType firstType = toType(first, environment: environment);
-    DartType secondType = toType(second, environment: environment);
-    DartType expectedType = toType(expected, environment: environment);
-    DartType producedType =
-        env.getStandardLowerBound(firstType, secondType, testLib);
-    expect(producedType, expectedType,
-        reason: "DOWN(${firstType}, ${secondType}) produced '${producedType}', "
-            "but expected '${expectedType}'.");
-  }
-
-  void testUpper(String first, String second, String expected,
-      {String typeParameters}) {
-    TypeParserEnvironment environment = extend(typeParameters);
-    DartType firstType = toType(first, environment: environment);
-    DartType secondType = toType(second, environment: environment);
-    DartType expectedType = toType(expected, environment: environment);
-    DartType producedType =
-        env.getStandardUpperBound(firstType, secondType, testLib);
-    expect(producedType, expectedType,
-        reason: "UP(${firstType}, ${secondType}) produced '${producedType}', "
-            "but expected '${expectedType}'.");
-  }
-
-  void testConstraint(TypeConstraint typeConstraint,
-      {DartType lowerExpected, DartType upperExpected}) {
-    assert(lowerExpected != null || upperExpected != null);
-    if (lowerExpected != null) {
-      expect(typeConstraint.lower, lowerExpected,
-          reason: "Expected the lower bound to be '${lowerExpected}' "
-              "for the following type constraint: ${typeConstraint}");
-    }
-    if (upperExpected != null) {
-      expect(typeConstraint.upper, upperExpected,
-          reason: "Expected the upper bound to be '${upperExpected}' "
-              "for the following type constraint: ${typeConstraint}");
-    }
-  }
-
   void test_lower_bound_bottom() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     for (String type in ["A*", "A?", "A"]) {
-      testLower("bottom", type, "bottom");
-      testLower(type, "bottom", "bottom");
+      checkLowerBound(type1: "bottom", type2: type, lowerBound: "bottom");
+      checkLowerBound(type1: type, type2: "bottom", lowerBound: "bottom");
     }
 
     // DOWN(T1, T2) where BOTTOM(T1) and BOTTOM(T2) =
@@ -328,26 +278,39 @@
       for (String t2 in bottomPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             bottomPredicateEnumeration[t1], bottomPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testLower(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkLowerBound(
+              type1: t1,
+              type2: t2,
+              lowerBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // DOWN(T1, T2) = T2 if BOTTOM(T2)
     for (String type in ["A*", "A?", "A"]) {
       for (String t2 in bottomPredicateEnumeration.keys) {
-        testLower(type, t2, t2, typeParameters: bottomPredicateEnumeration[t2]);
+        checkLowerBound(
+            type1: type,
+            type2: t2,
+            lowerBound: t2,
+            typeParameters: bottomPredicateEnumeration[t2]);
       }
     }
 
     // DOWN(T1, T2) = T1 if BOTTOM(T1)
     for (String t1 in bottomPredicateEnumeration.keys) {
       for (String type in ["A*", "A?", "A"]) {
-        testLower(t1, type, t1, typeParameters: bottomPredicateEnumeration[t1]);
+        checkLowerBound(
+            type1: t1,
+            type2: type,
+            lowerBound: t1,
+            typeParameters: bottomPredicateEnumeration[t1]);
       }
     }
 
@@ -358,12 +321,17 @@
       for (String t2 in nullPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             nullPredicateEnumeration[t1], nullPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testLower(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkLowerBound(
+              type1: t1,
+              type2: t2,
+              lowerBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
@@ -371,167 +339,264 @@
     //   Null if Null <: T2
     //   Never otherwise
     for (String t1 in nullPredicateEnumeration.keys) {
-      testLower(t1, "A*", t1, typeParameters: nullPredicateEnumeration[t1]);
-      testLower(t1, "A?", t1, typeParameters: nullPredicateEnumeration[t1]);
-      testLower(t1, "A", "Never", typeParameters: nullPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A*",
+          lowerBound: t1,
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A?",
+          lowerBound: t1,
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A",
+          lowerBound: "Never",
+          typeParameters: nullPredicateEnumeration[t1]);
     }
 
     // DOWN(T1, Null) =
     //   Null if Null <: T1
     //   Never otherwise
     for (String t2 in nullPredicateEnumeration.keys) {
-      testLower("A*", t2, t2, typeParameters: nullPredicateEnumeration[t2]);
-      testLower("A?", t2, t2, typeParameters: nullPredicateEnumeration[t2]);
-      testLower("A", t2, "Never", typeParameters: nullPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A*",
+          type2: t2,
+          lowerBound: t2,
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A?",
+          type2: t2,
+          lowerBound: t2,
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A",
+          type2: t2,
+          lowerBound: "Never",
+          typeParameters: nullPredicateEnumeration[t2]);
     }
   }
 
   void test_lower_bound_object() {
-    _initialize("");
+    parseTestLibrary("");
 
-    testLower("Object", "FutureOr<Null>", "FutureOr<Never>");
-    testLower("FutureOr<Null>", "Object", "FutureOr<Never>");
+    checkLowerBound(
+        type1: "Object",
+        type2: "FutureOr<Null>",
+        lowerBound: "FutureOr<Never>");
+    checkLowerBound(
+        type1: "FutureOr<Null>",
+        type2: "Object",
+        lowerBound: "FutureOr<Never>");
 
     // FutureOr<dynamic> is top.
-    testLower("Object", "FutureOr<dynamic>", "Object");
-    testLower("FutureOr<dynamic>", "Object", "Object");
+    checkLowerBound(
+        type1: "Object", type2: "FutureOr<dynamic>", lowerBound: "Object");
+    checkLowerBound(
+        type1: "FutureOr<dynamic>", type2: "Object", lowerBound: "Object");
 
     // FutureOr<X> is not top and cannot be made non-nullable.
-    testLower("Object", "FutureOr<X>", "Never",
+    checkLowerBound(
+        type1: "Object",
+        type2: "FutureOr<X>",
+        lowerBound: "Never",
         typeParameters: 'X extends dynamic');
-    testLower("FutureOr<X>", "Object", "Never",
+    checkLowerBound(
+        type1: "FutureOr<X>",
+        type2: "Object",
+        lowerBound: "Never",
         typeParameters: 'X extends dynamic');
 
     // FutureOr<void> is top.
-    testLower("Object", "FutureOr<void>", "Object");
-    testLower("FutureOr<void>", "Object", "Object");
+    checkLowerBound(
+        type1: "Object", type2: "FutureOr<void>", lowerBound: "Object");
+    checkLowerBound(
+        type1: "FutureOr<void>", type2: "Object", lowerBound: "Object");
   }
 
   void test_lower_bound_function() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    testLower("() ->* A*", "() ->* B*", "() ->* B*");
-    testLower("() ->* void", "(A*, B*) ->* void", "([A*, B*]) ->* void");
-    testLower("(A*, B*) ->* void", "() ->* void", "([A*, B*]) ->* void");
-    testLower("(A*) ->* void", "(B*) ->* void", "(A*) ->* void");
-    testLower("(B*) ->* void", "(A*) ->* void", "(A*) ->* void");
-    testLower(
-        "({A* a}) ->* void", "({B* b}) ->* void", "({A* a, B* b}) ->* void");
-    testLower(
-        "({B* b}) ->* void", "({A* a}) ->* void", "({A* a, B* b}) ->* void");
-    testLower("({A* a, A* c}) ->* void", "({B* b, B* d}) ->* void",
-        "({A* a, B* b, A* c, B* d}) ->* void");
-    testLower("({A* a, B* b}) ->* void", "({B* a, A* b}) ->* void",
-        "({A* a, A* b}) ->* void");
-    testLower("({B* a, A* b}) ->* void", "({A* a, B* b}) ->* void",
-        "({A* a, A* b}) ->* void");
-    testLower(
-        "(B*, {A* a}) ->* void", "(B*) ->* void", "(B*, {A* a}) ->* void");
-    testLower("({A* a}) -> void", "(B*) -> void", "Never");
-    testLower("({A* a}) -> void", "([B*]) ->* void", "Never");
-    testLower("<X>() -> void", "<Y>() -> void", "<Z>() -> void");
-    testLower("<X>(X) -> List<X>", "<Y>(Y) -> List<Y>", "<Z>(Z) -> List<Z>");
-    testLower(
-        "<X1, X2 extends List<X1>>(X1) -> X2",
-        "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
-        "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
-    testLower(
-        "<X extends int>(X) -> void", "<Y extends double>(Y) -> void", "Never");
+    checkLowerBound(
+        type1: "() ->* A*", type2: "() ->* B*", lowerBound: "() ->* B*");
+    checkLowerBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+    checkLowerBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+    checkLowerBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(A*) ->* void");
+    checkLowerBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        lowerBound: "(A*) ->* void");
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+    checkLowerBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        lowerBound: "({A* a, B* b, A* c, B* d}) ->* void");
+    checkLowerBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+    checkLowerBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(B*, {A* a}) ->* void");
+    checkLowerBound(
+        type1: "({A* a}) -> void", type2: "(B*) -> void", lowerBound: "Never");
+    checkLowerBound(
+        type1: "({A* a}) -> void",
+        type2: "([B*]) ->* void",
+        lowerBound: "Never");
+    checkLowerBound(
+        type1: "<X>() -> void",
+        type2: "<Y>() -> void",
+        lowerBound: "<Z>() -> void");
+    checkLowerBound(
+        type1: "<X>(X) -> List<X>",
+        type2: "<Y>(Y) -> List<Y>",
+        lowerBound: "<Z>(Z) -> List<Z>");
+    checkLowerBound(
+        type1: "<X1, X2 extends List<X1>>(X1) -> X2",
+        type2: "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
+        lowerBound: "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
+    checkLowerBound(
+        type1: "<X extends int>(X) -> void",
+        type2: "<Y extends double>(Y) -> void",
+        lowerBound: "Never");
 
-    testLower(
-        "({required A a, A b, required A c, A d, required A e}) -> A",
-        "({required B a, required B b, B c, B f, required B g}) -> B",
-        "({required A a, A b, A c, A d, A e, B f, B g}) -> B");
+    checkLowerBound(
+        type1: "({required A a, A b, required A c, A d, required A e}) -> A",
+        type2: "({required B a, required B b, B c, B f, required B g}) -> B",
+        lowerBound: "({required A a, A b, A c, A d, A e, B f, B g}) -> B");
 
-    testLower("<X extends dynamic>() -> void", "<Y extends Object?>() -> void",
-        "<Z extends dynamic>() -> void");
-    testLower("<X extends Null>() -> void", "<Y extends Never?>() -> void",
-        "<Z extends Null>() -> void");
-    testLower(
-        "<X extends FutureOr<dynamic>?>() -> void",
-        "<Y extends FutureOr<Object?>>() -> void",
-        "<Z extends FutureOr<dynamic>?>() -> void");
+    checkLowerBound(
+        type1: "<X extends dynamic>() -> void",
+        type2: "<Y extends Object?>() -> void",
+        lowerBound: "<Z extends dynamic>() -> void");
+    checkLowerBound(
+        type1: "<X extends Null>() -> void",
+        type2: "<Y extends Never?>() -> void",
+        lowerBound: "<Z extends Null>() -> void");
+    checkLowerBound(
+        type1: "<X extends FutureOr<dynamic>?>() -> void",
+        type2: "<Y extends FutureOr<Object?>>() -> void",
+        lowerBound: "<Z extends FutureOr<dynamic>?>() -> void");
   }
 
   void test_lower_bound_identical() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testLower("A*", "A*", "A*");
-    testLower("A?", "A?", "A?");
-    testLower("A", "A", "A");
+    checkLowerBound(type1: "A*", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A?", type2: "A?", lowerBound: "A?");
+    checkLowerBound(type1: "A", type2: "A", lowerBound: "A");
   }
 
   void test_lower_bound_subtype() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testLower("A*", "B*", "B*");
-    testLower("A*", "B?", "B*");
-    testLower("A*", "B", "B");
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "B*");
+    checkLowerBound(type1: "A*", type2: "B?", lowerBound: "B*");
+    checkLowerBound(type1: "A*", type2: "B", lowerBound: "B");
 
-    testLower("A?", "B*", "B*");
-    testLower("A?", "B?", "B?");
-    testLower("A?", "B", "B");
+    checkLowerBound(type1: "A?", type2: "B*", lowerBound: "B*");
+    checkLowerBound(type1: "A?", type2: "B?", lowerBound: "B?");
+    checkLowerBound(type1: "A?", type2: "B", lowerBound: "B");
 
-    testLower("A", "B*", "B");
-    testLower("A", "B?", "B");
-    testLower("A", "B", "B");
+    checkLowerBound(type1: "A", type2: "B*", lowerBound: "B");
+    checkLowerBound(type1: "A", type2: "B?", lowerBound: "B");
+    checkLowerBound(type1: "A", type2: "B", lowerBound: "B");
 
-    testLower("B*", "A*", "B*");
-    testLower("B?", "A*", "B*");
-    testLower("B", "A*", "B");
+    checkLowerBound(type1: "B*", type2: "A*", lowerBound: "B*");
+    checkLowerBound(type1: "B?", type2: "A*", lowerBound: "B*");
+    checkLowerBound(type1: "B", type2: "A*", lowerBound: "B");
 
-    testLower("B*", "A?", "B*");
-    testLower("B?", "A?", "B?");
-    testLower("B", "A?", "B");
+    checkLowerBound(type1: "B*", type2: "A?", lowerBound: "B*");
+    checkLowerBound(type1: "B?", type2: "A?", lowerBound: "B?");
+    checkLowerBound(type1: "B", type2: "A?", lowerBound: "B");
 
-    testLower("B*", "A", "B");
-    testLower("B?", "A", "B");
-    testLower("B", "A", "B");
+    checkLowerBound(type1: "B*", type2: "A", lowerBound: "B");
+    checkLowerBound(type1: "B?", type2: "A", lowerBound: "B");
+    checkLowerBound(type1: "B", type2: "A", lowerBound: "B");
 
-    testLower("Iterable<A>*", "List<B>*", "List<B>*");
-    testLower("Iterable<A>*", "List<B>?", "List<B>*");
-    testLower("Iterable<A>*", "List<B>", "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>*", type2: "List<B>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "Iterable<A>*", type2: "List<B>?", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "Iterable<A>*", type2: "List<B>", lowerBound: "List<B>");
 
-    testLower("Iterable<A>?", "List<B>*", "List<B>*");
-    testLower("Iterable<A>?", "List<B>?", "List<B>?");
-    testLower("Iterable<A>?", "List<B>", "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>?", type2: "List<B>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "Iterable<A>?", type2: "List<B>?", lowerBound: "List<B>?");
+    checkLowerBound(
+        type1: "Iterable<A>?", type2: "List<B>", lowerBound: "List<B>");
 
-    testLower("Iterable<A>", "List<B>*", "List<B>");
-    testLower("Iterable<A>", "List<B>?", "List<B>");
-    testLower("Iterable<A>", "List<B>", "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>", type2: "List<B>*", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>", type2: "List<B>?", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>", type2: "List<B>", lowerBound: "List<B>");
 
-    testLower("List<B>*", "Iterable<A>*", "List<B>*");
-    testLower("List<B>?", "Iterable<A>*", "List<B>*");
-    testLower("List<B>", "Iterable<A>*", "List<B>");
+    checkLowerBound(
+        type1: "List<B>*", type2: "Iterable<A>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "List<B>?", type2: "Iterable<A>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "List<B>", type2: "Iterable<A>*", lowerBound: "List<B>");
 
-    testLower("List<B>*", "Iterable<A>?", "List<B>*");
-    testLower("List<B>?", "Iterable<A>?", "List<B>?");
-    testLower("List<B>", "Iterable<A>?", "List<B>");
+    checkLowerBound(
+        type1: "List<B>*", type2: "Iterable<A>?", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "List<B>?", type2: "Iterable<A>?", lowerBound: "List<B>?");
+    checkLowerBound(
+        type1: "List<B>", type2: "Iterable<A>?", lowerBound: "List<B>");
 
-    testLower("List<B>*", "Iterable<A>", "List<B>");
-    testLower("List<B>?", "Iterable<A>", "List<B>");
-    testLower("List<B>", "Iterable<A>", "List<B>");
+    checkLowerBound(
+        type1: "List<B>*", type2: "Iterable<A>", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "List<B>?", type2: "Iterable<A>", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "List<B>", type2: "Iterable<A>", lowerBound: "List<B>");
   }
 
   void test_lower_bound_top() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // TODO(dmitryas): Test for various nullabilities.
-    testLower("dynamic", "A*", "A*");
-    testLower("A*", "dynamic", "A*");
-    testLower("Object?", "A*", "A*");
-    testLower("A*", "Object?", "A*");
-    testLower("void", "A*", "A*");
-    testLower("A*", "void", "A*");
+    checkLowerBound(type1: "dynamic", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "dynamic", lowerBound: "A*");
+    checkLowerBound(type1: "Object?", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "Object?", lowerBound: "A*");
+    checkLowerBound(type1: "void", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "void", lowerBound: "A*");
 
     // DOWN(T1, T2) where TOP(T1) and TOP(T2) =
     //   T1 if MORETOP(T2, T1)
@@ -540,225 +605,208 @@
       for (String t2 in topPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             topPredicateEnumeration[t1], topPredicateEnumeration[t2]);
-        String expected = env.moretop(
-                toType(t2, typeParameters: typeParameters),
-                toType(t1, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testLower(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.moretop(parseType(t2), parseType(t1))
+                  ? t1
+                  : t2;
+          checkLowerBound(
+              type1: t1,
+              type2: t2,
+              lowerBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // DOWN(T1, T2) = T2 if TOP(T1)
     for (String t1 in topPredicateEnumeration.keys) {
-      testLower(t1, "A*", "A*", typeParameters: topPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A*",
+          lowerBound: "A*",
+          typeParameters: topPredicateEnumeration[t1]);
     }
 
     // DOWN(T1, T2) = T1 if TOP(T2)
     for (String t2 in topPredicateEnumeration.keys) {
-      testLower("A*", t2, "A*", typeParameters: topPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A*",
+          type2: t2,
+          lowerBound: "A*",
+          typeParameters: topPredicateEnumeration[t2]);
     }
   }
 
   void test_lower_bound_unknown() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testLower("A*", "unknown", "A*");
-    testLower("A?", "unknown", "A?");
-    testLower("A", "unknown", "A");
+    checkLowerBound(type1: "A*", type2: "UNKNOWN", lowerBound: "A*");
+    checkLowerBound(type1: "A?", type2: "UNKNOWN", lowerBound: "A?");
+    checkLowerBound(type1: "A", type2: "UNKNOWN", lowerBound: "A");
 
-    testLower("unknown", "A*", "A*");
-    testLower("unknown", "A?", "A?");
-    testLower("unknown", "A", "A");
+    checkLowerBound(type1: "UNKNOWN", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "UNKNOWN", type2: "A?", lowerBound: "A?");
+    checkLowerBound(type1: "UNKNOWN", type2: "A", lowerBound: "A");
   }
 
   void test_lower_bound_unrelated() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testLower("A*", "B*", "Never*");
-    testLower("A*", "B?", "Never*");
-    testLower("A*", "B", "Never");
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "Never*");
+    checkLowerBound(type1: "A*", type2: "B?", lowerBound: "Never*");
+    checkLowerBound(type1: "A*", type2: "B", lowerBound: "Never");
 
-    testLower("A?", "B*", "Never*");
-    testLower("A?", "B?", "Never?");
-    testLower("A?", "B", "Never");
+    checkLowerBound(type1: "A?", type2: "B*", lowerBound: "Never*");
+    checkLowerBound(type1: "A?", type2: "B?", lowerBound: "Never?");
+    checkLowerBound(type1: "A?", type2: "B", lowerBound: "Never");
 
-    testLower("A", "B*", "Never");
-    testLower("A", "B?", "Never");
-    testLower("A", "B", "Never");
+    checkLowerBound(type1: "A", type2: "B*", lowerBound: "Never");
+    checkLowerBound(type1: "A", type2: "B?", lowerBound: "Never");
+    checkLowerBound(type1: "A", type2: "B", lowerBound: "Never");
   }
 
   void test_inferGenericFunctionOrType() {
-    _initialize("");
+    parseTestLibrary("");
 
     // TODO(dmitryas): Test for various nullabilities.
-    InterfaceType listClassThisType =
-        coreTypes.thisInterfaceType(listClass, testLib.nonNullable);
-    {
-      // Test an instantiation of [1, 2.0] with no context.  This should infer
-      // as List<?> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], new UnknownType());
-      // And upwards inference should refine it to List<num>.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T],
-          [coreTypes.intNonNullableRawType, coreTypes.doubleNonNullableRawType],
-          null,
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.numNonNullableRawType);
-    }
-    {
-      // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
-      // should infer as List<Object> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          null,
-          null,
-          _list(coreTypes.objectNonNullableRawType),
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.objectNonNullableRawType);
-      // And upwards inference should preserve the type.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T],
-          [coreTypes.intNonNullableRawType, coreTypes.doubleNonNullableRawType],
-          _list(coreTypes.objectNonNullableRawType),
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.objectNonNullableRawType);
-    }
-    {
-      // Test an instantiation of [1, 2.0, null] with no context.  This should
-      // infer as List<?> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], new UnknownType());
-      // And upwards inference should refine it to List<num?>.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T, T],
-          [
-            coreTypes.intNonNullableRawType,
-            coreTypes.doubleNonNullableRawType,
-            const NullType()
-          ],
-          null,
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.numNullableRawType);
-    }
-    {
-      // Test an instantiation of legacy [1, 2.0] with no context.
-      // This should infer as List<?> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], new UnknownType());
-      // And upwards inference should refine it to List<num!>.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T],
-          [coreTypes.intLegacyRawType, coreTypes.doubleLegacyRawType],
-          null,
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-    }
+
+    // Test an instantiation of [1, 2.0] with no context.  This should infer
+    // as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    // And upwards inference should refine it to List<num>.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: "int, double",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num");
+
+    // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
+    // should infer as List<Object> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: "List<Object>",
+        expectedTypes: "Object");
+    // And upwards inference should preserve the type.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: "int, double",
+        returnContextType: "List<Object>",
+        inferredTypesFromDownwardPhase: "Object",
+        expectedTypes: "Object");
+
+    // Test an instantiation of [1, 2.0, null] with no context.  This should
+    // infer as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    // And upwards inference should refine it to List<num?>.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T, T) -> List<T>",
+        actualParameterTypes: "int, double, Null",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num?");
+
+    // Test an instantiation of legacy [1, 2.0] with no context.
+    // This should infer as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: "int*, double*",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num");
   }
 
   void test_inferTypeFromConstraints_applyBound() {
-    _initialize("");
+    parseTestLibrary("");
 
-    // class A<T extends num*> {}
-    TypeParameter T = new TypeParameter("T", coreTypes.numLegacyRawType);
+    // Assuming: class A<T extends num*> {}
 
     // TODO(dmitryas): Test for various nullabilities.
-    {
-      // With no constraints:
-      Map<TypeParameter, TypeConstraint> constraints = {
-        T: new TypeConstraint()
-      };
 
-      // Downward inference should infer A<?>
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], new UnknownType());
+    // With no constraints:
+    // Downward inference should infer A<?>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: true,
+        expected: "UNKNOWN");
+    // Upward inference should infer A<num*>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "UNKNOWN",
+        expected: "num*");
 
-      // Upward inference should infer A<num*>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-    }
-    {
-      // With an upper bound of Object*:
-      Map<TypeParameter, TypeConstraint> constraints = {
-        T: _makeConstraint(upper: coreTypes.objectLegacyRawType)
-      };
-
-      // Downward inference should infer A<num*>
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-
-      // Upward inference should infer A<num*>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-
-      // Upward inference should still infer A<num*> even if there are more
-      // constraints now, because num was finalized during downward inference.
-      constraints = {
-        T: _makeConstraint(
-            lower: coreTypes.intLegacyRawType,
-            upper: coreTypes.intLegacyRawType)
-      };
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-    }
+    // With an upper bound of Object*:
+    // Downward inference should infer A<num*>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: true,
+        expected: "num*");
+    // Upward inference should infer A<num*>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
+    // Upward inference should still infer A<num*> even if there are more
+    // constraints now, because num was finalized during downward inference.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: ":> int* <: int*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
   }
 
   void test_inferTypeFromConstraints_simple() {
-    _initialize("");
-
-    TypeParameter T = listClass.typeParameters[0];
+    parseTestLibrary("");
 
     // TODO(dmitryas): Test for various nullabilities.
 
     // With an upper bound of List<?>*:
-    Map<TypeParameter, TypeConstraint> constraints = {
-      T: _makeConstraint(upper: _list(new UnknownType()))
-    };
-
     // Downwards inference should infer List<List<?>*>*
-    List<DartType> inferredTypes = <DartType>[new UnknownType()];
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-        downwardsInferPhase: true);
-    expect(inferredTypes[0], _list(new UnknownType()));
-
-    // Upwards inference should refine that to List<List<dynamic>*>*
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-    expect(inferredTypes[0],
-        _list(new InterfaceType(objectClass, Nullability.nullable)));
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object?",
+        constraints: "<: List<UNKNOWN>",
+        downwardsInferPhase: true,
+        expected: "List<UNKNOWN>");
+    // Upwards inference should refine that to List<List<Object?>*>*
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object?",
+        constraints: "<: List<UNKNOWN>",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "List<UNKNOWN>",
+        expected: "List<Object?>");
   }
 
   void test_upper_bound_classic() {
@@ -771,7 +819,7 @@
     // B C K
     // |X| |
     // D E L
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B implements A;
       class C implements A;
@@ -779,180 +827,276 @@
       class D implements B, C;
       class E implements B, C;
       class L implements K;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    testUpper("B*", "E*", "B*");
-    testUpper("D*", "C*", "C*");
-    testUpper("D*", "E*", "A*");
-    testUpper("D*", "A*", "A*");
-    testUpper("B*", "K*", "A*");
-    testUpper("B*", "L*", "A*");
+    checkUpperBound(type1: "B*", type2: "E*", upperBound: "B*");
+    checkUpperBound(type1: "D*", type2: "C*", upperBound: "C*");
+    checkUpperBound(type1: "D*", type2: "E*", upperBound: "A*");
+    checkUpperBound(type1: "D*", type2: "A*", upperBound: "A*");
+    checkUpperBound(type1: "B*", type2: "K*", upperBound: "A*");
+    checkUpperBound(type1: "B*", type2: "L*", upperBound: "A*");
   }
 
   void test_upper_bound_commonClass() {
-    _initialize("");
+    parseTestLibrary("");
 
-    testUpper("List<int*>", "List<double*>", "List<num*>");
-    testUpper("List<int?>", "List<double>", "List<num?>");
+    checkUpperBound(
+        type1: "List<int*>", type2: "List<double*>", upperBound: "List<num*>");
+    checkUpperBound(
+        type1: "List<int?>", type2: "List<double>", upperBound: "List<num?>");
   }
 
   void test_upper_bound_object() {
-    _initialize("");
+    parseTestLibrary("");
 
-    testUpper("Object", "FutureOr<Function?>", "Object?");
-    testUpper("FutureOr<Function?>", "Object", "Object?");
+    checkUpperBound(
+        type1: "Object", type2: "FutureOr<Function?>", upperBound: "Object?");
+    checkUpperBound(
+        type1: "FutureOr<Function?>", type2: "Object", upperBound: "Object?");
   }
 
   void test_upper_bound_function() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testUpper("() ->? A", "() -> B?", "() ->? A?");
-    testUpper("([A*]) ->* void", "(A*) ->* void", "Function*");
-    testUpper("() ->* void", "(A*, B*) ->* void", "Function*");
-    testUpper("(A*, B*) ->* void", "() ->* void", "Function*");
-    testUpper("(A*) ->* void", "(B*) ->* void", "(B*) ->* void");
-    testUpper("(B*) ->* void", "(A*) ->* void", "(B*) ->* void");
-    testUpper("({A* a}) ->* void", "({B* b}) ->* void", "() ->* void");
-    testUpper("({B* b}) ->* void", "({A* a}) ->* void", "() ->* void");
-    testUpper(
-        "({A* a, A* c}) ->* void", "({B* b, B* d}) ->* void", "() ->* void");
-    testUpper("({A* a, B* b}) ->* void", "({B* a, A* b}) ->* void",
-        "({B* a, B* b}) ->* void");
-    testUpper("({B* a, A* b}) ->* void", "({A* a, B* b}) ->* void",
-        "({B* a, B* b}) ->* void");
-    testUpper("(B*, {A* a}) ->* void", "(B*) ->* void", "(B*) ->* void");
-    testUpper("({A* a}) ->* void", "(B*) ->* void", "Function*");
-    testUpper("() ->* void", "([B*]) ->* void", "() ->* void");
-    testUpper("<X>() -> void", "<Y>() -> void", "<Z>() -> void");
-    testUpper("<X>(X) -> List<X>", "<Y>(Y) -> List<Y>", "<Z>(Z) -> List<Z>");
-    testUpper(
-        "<X1, X2 extends List<X1>>(X1) -> X2",
-        "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
-        "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
-    testUpper("<X extends int>() -> void", "<Y extends double>() -> void",
-        "Function");
+    checkUpperBound(
+        type1: "() ->? A", type2: "() -> B?", upperBound: "() ->? A?");
+    checkUpperBound(
+        type1: "([A*]) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+    checkUpperBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+    checkUpperBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "() ->* void",
+        type2: "([B*]) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "<X>() -> void",
+        type2: "<Y>() -> void",
+        upperBound: "<Z>() -> void");
+    checkUpperBound(
+        type1: "<X>(X) -> List<X>",
+        type2: "<Y>(Y) -> List<Y>",
+        upperBound: "<Z>(Z) -> List<Z>");
+    checkUpperBound(
+        type1: "<X1, X2 extends List<X1>>(X1) -> X2",
+        type2: "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
+        upperBound: "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
+    checkUpperBound(
+        type1: "<X extends int>() -> void",
+        type2: "<Y extends double>() -> void",
+        upperBound: "Function");
 
-    testUpper("({required A a, B b}) -> A", "({B a, required A b}) -> B",
-        "({required B a, required B b}) -> A");
+    checkUpperBound(
+        type1: "({required A a, B b}) -> A",
+        type2: "({B a, required A b}) -> B",
+        upperBound: "({required B a, required B b}) -> A");
 
-    testUpper("<X extends dynamic>() -> void", "<Y extends Object?>() -> void",
-        "<Z extends dynamic>() -> void");
-    testUpper("<X extends Null>() -> void", "<Y extends Never?>() -> void",
-        "<Z extends Null>() -> void");
-    testUpper(
-        "<X extends FutureOr<dynamic>?>() -> void",
-        "<Y extends FutureOr<Object?>>() -> void",
-        "<Z extends FutureOr<dynamic>?>() -> void");
+    checkUpperBound(
+        type1: "<X extends dynamic>() -> void",
+        type2: "<Y extends Object?>() -> void",
+        upperBound: "<Z extends dynamic>() -> void");
+    checkUpperBound(
+        type1: "<X extends Null>() -> void",
+        type2: "<Y extends Never?>() -> void",
+        upperBound: "<Z extends Null>() -> void");
+    checkUpperBound(
+        type1: "<X extends FutureOr<dynamic>?>() -> void",
+        type2: "<Y extends FutureOr<Object?>>() -> void",
+        upperBound: "<Z extends FutureOr<dynamic>?>() -> void");
 
-    testUpper("([dynamic]) -> dynamic", "([dynamic]) -> dynamic",
-        "([dynamic]) -> dynamic");
+    checkUpperBound(
+        type1: "([dynamic]) -> dynamic",
+        type2: "([dynamic]) -> dynamic",
+        upperBound: "([dynamic]) -> dynamic");
   }
 
   void test_upper_bound_identical() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testUpper("A*", "A*", "A*");
-    testUpper("A*", "A?", "A?");
-    testUpper("A*", "A", "A*");
+    checkUpperBound(type1: "A*", type2: "A*", upperBound: "A*");
+    checkUpperBound(type1: "A*", type2: "A?", upperBound: "A?");
+    checkUpperBound(type1: "A*", type2: "A", upperBound: "A*");
 
-    testUpper("A?", "A*", "A?");
-    testUpper("A?", "A?", "A?");
-    testUpper("A?", "A", "A?");
+    checkUpperBound(type1: "A?", type2: "A*", upperBound: "A?");
+    checkUpperBound(type1: "A?", type2: "A?", upperBound: "A?");
+    checkUpperBound(type1: "A?", type2: "A", upperBound: "A?");
 
-    testUpper("A", "A*", "A*");
-    testUpper("A", "A?", "A?");
-    testUpper("A", "A", "A");
+    checkUpperBound(type1: "A", type2: "A*", upperBound: "A*");
+    checkUpperBound(type1: "A", type2: "A?", upperBound: "A?");
+    checkUpperBound(type1: "A", type2: "A", upperBound: "A");
   }
 
   void test_upper_bound_sameClass() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class Pair<X, Y>;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testUpper("Pair<A*, B*>", "Pair<B*, A*>", "Pair<A*, A*>");
-    testUpper("Pair<A*, B*>", "Pair<B?, A>", "Pair<A?, A*>");
-    testUpper("Pair<A?, B?>", "Pair<B, A>", "Pair<A?, A?>");
+    checkUpperBound(
+        type1: "Pair<A*, B*>",
+        type2: "Pair<B*, A*>",
+        upperBound: "Pair<A*, A*>");
+    checkUpperBound(
+        type1: "Pair<A*, B*>",
+        type2: "Pair<B?, A>",
+        upperBound: "Pair<A?, A*>");
+    checkUpperBound(
+        type1: "Pair<A?, B?>", type2: "Pair<B, A>", upperBound: "Pair<A?, A?>");
   }
 
   void test_upper_bound_subtype() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
-    testUpper("List<B*>", "Iterable<A*>", "Iterable<A*>");
-    testUpper("List<B*>", "Iterable<A?>", "Iterable<A?>");
-    testUpper("List<B*>", "Iterable<A>", "Iterable<A>");
-    testUpper("List<B>*", "Iterable<A>*", "Iterable<A>*");
-    testUpper("List<B>*", "Iterable<A>?", "Iterable<A>?");
-    testUpper("List<B>*", "Iterable<A>", "Iterable<A>*");
-    testUpper("List<B>?", "Iterable<A>*", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>?", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>", "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B*>", type2: "Iterable<A*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "List<B*>", type2: "Iterable<A?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "List<B*>", type2: "Iterable<A>", upperBound: "Iterable<A>");
+    checkUpperBound(
+        type1: "List<B>*", type2: "Iterable<A>*", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "List<B>*", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>*", type2: "Iterable<A>", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>*", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>", upperBound: "Iterable<A>?");
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
-    testUpper("List<B?>", "Iterable<A*>", "Iterable<A*>");
-    testUpper("List<B?>", "Iterable<A?>", "Iterable<A?>");
-    testUpper("List<B>?", "Iterable<A>*", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>?", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>", "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B?>", type2: "Iterable<A*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "List<B?>", type2: "Iterable<A?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>*", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>", upperBound: "Iterable<A>?");
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //     = least upper bound of two interfaces as in Dart 1.
-    testUpper("List<B?>", "Iterable<A>", "Object");
+    checkUpperBound(
+        type1: "List<B?>", type2: "Iterable<A>", upperBound: "Object");
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
-    testUpper("List<B>", "Iterable<A*>", "Iterable<A*>");
-    testUpper("List<B>", "Iterable<A?>", "Iterable<A?>");
-    testUpper("List<B>", "Iterable<A>", "Iterable<A>");
-    testUpper("List<B>", "Iterable<A>*", "Iterable<A>*");
-    testUpper("List<B>", "Iterable<A>?", "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A>", upperBound: "Iterable<A>");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A>*", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A*>", "List<B*>", "Iterable<A*>");
-    testUpper("Iterable<A*>", "List<B?>", "Iterable<A*>");
-    testUpper("Iterable<A*>", "List<B>", "Iterable<A*>");
-    testUpper("Iterable<A>*", "List<B>*", "Iterable<A>*");
-    testUpper("Iterable<A>*", "List<B>?", "Iterable<A>?");
-    testUpper("Iterable<A>*", "List<B>", "Iterable<A>*");
+    checkUpperBound(
+        type1: "Iterable<A*>", type2: "List<B*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "Iterable<A*>", type2: "List<B?>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "Iterable<A*>", type2: "List<B>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "Iterable<A>*", type2: "List<B>*", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "Iterable<A>*", type2: "List<B>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A>*", type2: "List<B>", upperBound: "Iterable<A>*");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A?>", "List<B*>", "Iterable<A?>");
-    testUpper("Iterable<A?>", "List<B?>", "Iterable<A?>");
-    testUpper("Iterable<A?>", "List<B>", "Iterable<A?>");
-    testUpper("Iterable<A>?", "List<B>*", "Iterable<A>?");
-    testUpper("Iterable<A>?", "List<B>?", "Iterable<A>?");
-    testUpper("Iterable<A>?", "List<B>", "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A?>", type2: "List<B*>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "Iterable<A?>", type2: "List<B?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "Iterable<A?>", type2: "List<B>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "Iterable<A>?", type2: "List<B>*", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A>?", type2: "List<B>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A>?", type2: "List<B>", upperBound: "Iterable<A>?");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A>", "List<B*>", "Iterable<A>");
-    testUpper("Iterable<A>", "List<B>*", "Iterable<A>*");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B*>", upperBound: "Iterable<A>");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B>*", upperBound: "Iterable<A>*");
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //     = least upper bound of two interfaces as in Dart 1.
-    testUpper("Iterable<A>", "List<B?>", "Object");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B?>", upperBound: "Object");
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A>", "List<B>", "Iterable<A>");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B>", upperBound: "Iterable<A>");
   }
 
   void test_upper_bound_top() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // UP(T1, T2) where TOP(T1) and TOP(T2) =
     //   T1 if MORETOP(T1, T2)
@@ -961,26 +1105,39 @@
       for (String t2 in topPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             topPredicateEnumeration[t1], topPredicateEnumeration[t2]);
-        String expected = env.moretop(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.moretop(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // UP(T1, T2) = T1 if TOP(T1)
     for (String t1 in topPredicateEnumeration.keys) {
       for (String t2 in ["A*", "A?", "A"]) {
-        testUpper(t1, t2, t1, typeParameters: topPredicateEnumeration[t1]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t1,
+            typeParameters: topPredicateEnumeration[t1]);
       }
     }
 
     // UP(T1, T2) = T2 if TOP(T2)
     for (String t1 in ["A*", "A?", "A"]) {
       for (String t2 in topPredicateEnumeration.keys) {
-        testUpper(t1, t2, t2, typeParameters: topPredicateEnumeration[t2]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t2,
+            typeParameters: topPredicateEnumeration[t2]);
       }
     }
 
@@ -991,12 +1148,17 @@
       for (String t2 in objectPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             objectPredicateEnumeration[t1], objectPredicateEnumeration[t2]);
-        String expected = env.moretop(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.moretop(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
@@ -1004,25 +1166,31 @@
     //   T1 if T2 is non-nullable
     //   T1? otherwise
     for (String t1 in objectPredicateEnumeration.keys) {
-      testUpper(t1, "A*", "${t1}?",
+      checkUpperBound(
+          type1: t1,
+          type2: "A*",
+          upperBound: "${t1}?",
           typeParameters: objectPredicateEnumeration[t1]);
-      testUpper(t1, "A?", "${t1}?",
+      checkUpperBound(
+          type1: t1,
+          type2: "A?",
+          upperBound: "${t1}?",
           typeParameters: objectPredicateEnumeration[t1]);
-      testUpper(t1, "A", t1);
+      checkUpperBound(type1: t1, type2: "A", upperBound: t1);
     }
 
     // UP(T1, T2) where OBJECT(T2) =
     //   T2 if T1 is non-nullable
     //   T2? otherwise
     for (String t2 in objectPredicateEnumeration.keys) {
-      testUpper("A*", t2, "${t2}?");
-      testUpper("A?", t2, "${t2}?");
-      testUpper("A", t2, t2);
+      checkUpperBound(type1: "A*", type2: t2, upperBound: "${t2}?");
+      checkUpperBound(type1: "A?", type2: t2, upperBound: "${t2}?");
+      checkUpperBound(type1: "A", type2: t2, upperBound: t2);
     }
   }
 
   void test_upper_bound_bottom() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // UP(T1, T2) where BOTTOM(T1) and BOTTOM(T2) =
     //   T2 if MOREBOTTOM(T1, T2)
@@ -1031,26 +1199,39 @@
       for (String t2 in bottomPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             bottomPredicateEnumeration[t1], bottomPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t2
-            : t1;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t2
+                  : t1;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // UP(T1, T2) = T2 if BOTTOM(T1)
     for (String t1 in bottomPredicateEnumeration.keys) {
       for (String t2 in ["A*", "A?", "A"]) {
-        testUpper(t1, t2, t2, typeParameters: bottomPredicateEnumeration[t1]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t2,
+            typeParameters: bottomPredicateEnumeration[t1]);
       }
     }
 
     // UP(T1, T2) = T1 if BOTTOM(T2)
     for (String t1 in ["A*", "A?", "A"]) {
       for (String t2 in bottomPredicateEnumeration.keys) {
-        testUpper(t1, t2, t1, typeParameters: bottomPredicateEnumeration[t2]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t1,
+            typeParameters: bottomPredicateEnumeration[t2]);
       }
     }
 
@@ -1061,12 +1242,17 @@
       for (String t2 in nullPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             nullPredicateEnumeration[t1], nullPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t2
-            : t1;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t2
+                  : t1;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
@@ -1074,286 +1260,426 @@
     //   T2 if T2 is nullable
     //   T2? otherwise
     for (String t1 in nullPredicateEnumeration.keys) {
-      testUpper(t1, "A*", "A?", typeParameters: nullPredicateEnumeration[t1]);
-      testUpper(t1, "A?", "A?", typeParameters: nullPredicateEnumeration[t1]);
-      testUpper(t1, "A", "A?", typeParameters: nullPredicateEnumeration[t1]);
+      checkUpperBound(
+          type1: t1,
+          type2: "A*",
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkUpperBound(
+          type1: t1,
+          type2: "A?",
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkUpperBound(
+          type1: t1,
+          type2: "A",
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t1]);
     }
 
     // UP(T1, T2) where NULL(T2) =
     //   T1 if T1 is nullable
     //   T1? otherwise
     for (String t2 in nullPredicateEnumeration.keys) {
-      testUpper("A*", t2, "A?", typeParameters: nullPredicateEnumeration[t2]);
-      testUpper("A?", t2, "A?", typeParameters: nullPredicateEnumeration[t2]);
-      testUpper("A", t2, "A?", typeParameters: nullPredicateEnumeration[t2]);
+      checkUpperBound(
+          type1: "A*",
+          type2: t2,
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkUpperBound(
+          type1: "A?",
+          type2: t2,
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkUpperBound(
+          type1: "A",
+          type2: t2,
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t2]);
     }
   }
 
   void test_upper_bound_typeParameter() {
-    _initialize("");
+    parseTestLibrary("");
 
     // TODO(dmitryas): Test for various nullabilities.
-    testUpper("T", "T", "T", typeParameters: "T extends Object");
-    testUpper("T", "List<Never>", "List<Object?>",
+    checkUpperBound(
+        type1: "T",
+        type2: "T",
+        upperBound: "T",
+        typeParameters: "T extends Object");
+    checkUpperBound(
+        type1: "T",
+        type2: "List<Never>",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>");
-    testUpper("List<Never>", "T", "List<Object?>",
+    checkUpperBound(
+        type1: "List<Never>",
+        type2: "T",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>");
-    testUpper("T", "U", "List<Object?>",
+    checkUpperBound(
+        type1: "T",
+        type2: "U",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>, U extends List<Never>");
-    testUpper("U", "T", "List<Object?>",
+    checkUpperBound(
+        type1: "U",
+        type2: "T",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>, U extends List<Never>");
   }
 
   void test_upper_bound_unknown() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testLower("A*", "unknown", "A*");
-    testLower("A?", "unknown", "A?");
-    testLower("A", "unknown", "A");
+    checkLowerBound(type1: "A*", type2: "UNKNOWN", lowerBound: "A*");
+    checkLowerBound(type1: "A?", type2: "UNKNOWN", lowerBound: "A?");
+    checkLowerBound(type1: "A", type2: "UNKNOWN", lowerBound: "A");
 
-    testLower("unknown", "A*", "A*");
-    testLower("unknown", "A?", "A?");
-    testLower("unknown", "A", "A");
+    checkLowerBound(type1: "UNKNOWN", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "UNKNOWN", type2: "A?", lowerBound: "A?");
+    checkLowerBound(type1: "UNKNOWN", type2: "A", lowerBound: "A");
   }
 
   void test_solveTypeConstraint() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A<X>;
       class B<Y> extends A<Y>;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
 
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint(), topType, bottomType),
-        new UnknownType());
+    checkConstraintSolving("", "UNKNOWN", grounded: false);
 
     // Solve(? <: T <: ?, grounded) => dynamic
-    expect(
-        env.solveTypeConstraint(_makeConstraint(), topType, bottomType,
-            grounded: true),
-        new DynamicType());
+    checkConstraintSolving("", "dynamic", grounded: true);
 
     // Solve(A <: T <: ?) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<dynamic>*")), topType, bottomType),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> A<dynamic>*", "A<dynamic>*", grounded: false);
 
     // Solve(A <: T <: ?, grounded) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<dynamic>*")), topType, bottomType,
-            grounded: true),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> A<dynamic>*", "A<dynamic>*", grounded: true);
 
     // Solve(A<?>* <: T <: ?) => A<?>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<unknown>*")), topType, bottomType),
-        toType("A<unknown>*"));
+    checkConstraintSolving(":> A<UNKNOWN>*", "A<UNKNOWN>*", grounded: false);
 
     // Solve(A<?>* <: T <: ?, grounded) => A<Never>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<unknown>*")), topType, bottomType,
-            grounded: true),
-        toType("A<Never>*"));
+    checkConstraintSolving(":> A<UNKNOWN>*", "A<Never>*", grounded: true);
 
     // Solve(? <: T <: A*) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<dynamic>*")), topType, bottomType),
-        toType("A<dynamic>*"));
+    checkConstraintSolving("<: A<dynamic>*", "A<dynamic>*", grounded: false);
 
     // Solve(? <: T <: A*, grounded) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<dynamic>*")), topType, bottomType,
-            grounded: true),
-        toType("A<dynamic>*"));
+    checkConstraintSolving("<: A<dynamic>*", "A<dynamic>*", grounded: true);
 
     // Solve(? <: T <: A<?>*) => A<?>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<unknown>*")), topType, bottomType),
-        toType("A<unknown>*"));
+    checkConstraintSolving("<: A<UNKNOWN>*", "A<UNKNOWN>*", grounded: false);
 
     // Solve(? <: T <: A<?>*, grounded) => A<dynamic>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<unknown>*")), topType, bottomType,
-            grounded: true),
-        toType("A<Object?>*"));
+    checkConstraintSolving("<: A<UNKNOWN>*", "A<Object?>*", grounded: true);
 
     // Solve(B* <: T <: A*) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<dynamic>*", "B<dynamic>*",
+        grounded: false);
 
     // Solve(B* <: T <: A*, grounded) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<dynamic>*", "B<dynamic>*",
+        grounded: true);
 
     // Solve(B<?>* <: T <: A*) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<dynamic>*", "A<dynamic>*",
+        grounded: false);
 
     // Solve(B<?>* <: T <: A*, grounded) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<dynamic>*", "A<dynamic>*",
+        grounded: true);
 
     // Solve(B* <: T <: A<?>*) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<UNKNOWN>*", "B<dynamic>*",
+        grounded: false);
 
     // Solve(B* <: T <: A<?>*, grounded) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<UNKNOWN>*", "B<dynamic>*",
+        grounded: true);
 
     // Solve(B<?>* <: T <: A<?>*) => B<?>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType),
-        toType("B<unknown>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<UNKNOWN>*", "B<UNKNOWN>*",
+        grounded: false);
 
     // Solve(B<?>* <: T <: A<?>*, grounded) => B<Never>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("B<Never>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<UNKNOWN>*", "B<Never>*",
+        grounded: true);
   }
 
   void test_typeConstraint_default() {
-    TypeConstraint typeConstraint = new TypeConstraint();
-    expect(typeConstraint.lower, new UnknownType());
-    expect(typeConstraint.upper, new UnknownType());
+    parseTestLibrary("");
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
   }
 
   void test_typeSatisfiesConstraint() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class C extends B;
       class D extends C;
       class E extends D;
-    """;
-    _initialize(testSdk);
+    """);
 
-    // TODO(dmitryas): Test for various nullabilities.
-    TypeConstraint typeConstraint =
-        _makeConstraint(upper: toType("B*"), lower: toType("D*"));
-
-    expect(env.typeSatisfiesConstraint(toType("A*"), typeConstraint), isFalse);
-    expect(env.typeSatisfiesConstraint(toType("B*"), typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(toType("C*"), typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(toType("D*"), typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(toType("E*"), typeConstraint), isFalse);
+    checkTypeDoesntSatisfyConstraint("A*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("B*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("C*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("D*", ":> D* <: B*");
+    checkTypeDoesntSatisfyConstraint("E*", ":> D* <: B*");
   }
 
   void test_unknown_at_bottom() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // TODO(dmitryas): Test for various nullabilities.
-    expect(
-        env.isSubtypeOf(new UnknownType(), toType("A*"),
-            SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+    checkIsLegacySubtype("UNKNOWN", "A*");
   }
 
   void test_unknown_at_top() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class Pair<X, Y>;
-    """;
-    _initialize(testSdk);
+    """);
 
+    checkIsLegacySubtype("A*", "UNKNOWN");
+    checkIsSubtype("Pair<A*, Null>*", "Pair<UNKNOWN, UNKNOWN>*");
+  }
+
+  void checkConstraintSolving(String constraint, String expected,
+      {bool grounded}) {
+    assert(grounded != null);
     expect(
-        env.isSubtypeOf(toType("A*"), new UnknownType(),
-            SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+        typeSchemaEnvironment.solveTypeConstraint(
+            parseConstraint(constraint),
+            coreTypes.objectNullableRawType,
+            new NeverType(Nullability.nonNullable),
+            grounded: grounded),
+        parseType(expected));
+  }
+
+  void checkConstraintUpperBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).upper, parseType(bound));
+  }
+
+  void checkConstraintLowerBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).lower, parseType(bound));
+  }
+
+  void checkTypeSatisfiesConstraint(String type, String constraint) {
     expect(
-        env.isSubtypeOf(
-            toType("Pair<A*, Null>*"),
-            toType("Pair<unknown, unknown>*"),
-            SubtypeCheckMode.withNullabilities),
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
         isTrue);
   }
 
-  DartType _list(DartType elementType) {
-    return new InterfaceType(listClass, Nullability.nonNullable, [elementType]);
+  void checkTypeDoesntSatisfyConstraint(String type, String constraint) {
+    expect(
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
+        isFalse);
   }
 
-  TypeConstraint _makeConstraint({DartType lower, DartType upper}) {
-    lower ??= new UnknownType();
-    upper ??= new UnknownType();
-    return new TypeConstraint()
-      ..lower = lower
-      ..upper = upper;
+  void checkIsSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenUsingNullabilities(),
+        isTrue);
   }
 
-  void _initialize(String testSdk) {
-    Uri uri = Uri.parse("dart:core");
-    typeParserEnvironment = new TypeSchemaTypeParserEnvironment(uri);
-    Library library =
-        parseLibrary(uri, mockSdk + testSdk, environment: typeParserEnvironment)
-          ..isNonNullableByDefault = true;
-    component = new Component(libraries: <Library>[library]);
-    coreTypes = new CoreTypes(component);
-    env = new TypeSchemaEnvironment(
-        coreTypes, new ClassHierarchy(component, coreTypes));
+  void checkIsLegacySubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isTrue);
   }
-}
 
-class TypeSchemaTypeParserEnvironment extends TypeParserEnvironment {
-  TypeSchemaTypeParserEnvironment(Uri uri) : super(uri, uri);
+  void checkIsNotSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isFalse);
+  }
 
-  DartType getPredefinedNamedType(String name) {
-    if (name == "unknown") {
-      // Don't return a const object to ensure we test implementations that use
-      // identical.
-      return new UnknownType();
+  void checkUpperBound(
+      {String type1, String type2, String upperBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(upperBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardUpperBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(upperBound));
+    });
+  }
+
+  void checkLowerBound(
+      {String type1, String type2, String lowerBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(lowerBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardLowerBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(lowerBound));
+    });
+  }
+
+  void checkInference(
+      {String typeParametersToInfer,
+      String functionType,
+      String actualParameterTypes,
+      String returnContextType,
+      String inferredTypesFromDownwardPhase,
+      String expectedTypes}) {
+    assert(typeParametersToInfer != null);
+    assert(functionType != null);
+    assert(expectedTypes != null);
+
+    typeParserEnvironment.withTypeParameters(typeParametersToInfer,
+        (List<TypeParameter> typeParameterNodesToInfer) {
+      FunctionType functionTypeNode = parseType(functionType);
+      DartType returnContextTypeNode =
+          returnContextType == null ? null : parseType(returnContextType);
+      List<DartType> actualTypeNodes = actualParameterTypes == null
+          ? null
+          : parseTypes(actualParameterTypes);
+      List<DartType> expectedTypeNodes =
+          expectedTypes == null ? null : parseTypes(expectedTypes);
+      DartType declaredReturnTypeNode = functionTypeNode.returnType;
+      List<DartType> formalTypeNodes = actualParameterTypes == null
+          ? null
+          : functionTypeNode.positionalParameters;
+
+      List<DartType> inferredTypeNodes;
+      if (inferredTypesFromDownwardPhase == null) {
+        inferredTypeNodes = new List<DartType>.generate(
+            typeParameterNodesToInfer.length, (_) => new UnknownType());
+      } else {
+        inferredTypeNodes = parseTypes(inferredTypesFromDownwardPhase);
+      }
+
+      typeSchemaEnvironment.inferGenericFunctionOrType(
+          declaredReturnTypeNode,
+          typeParameterNodesToInfer,
+          formalTypeNodes,
+          actualTypeNodes,
+          returnContextTypeNode,
+          inferredTypeNodes,
+          testLibrary);
+
+      assert(
+          inferredTypeNodes.length == expectedTypeNodes.length,
+          "The numbers of expected types and type parameters to infer "
+          "mismatch.");
+      for (int i = 0; i < inferredTypeNodes.length; ++i) {
+        expect(inferredTypeNodes[i], expectedTypeNodes[i]);
+      }
+    });
+  }
+
+  void checkInferenceFromConstraints(
+      {String typeParameter,
+      String constraints,
+      String inferredTypeFromDownwardPhase,
+      bool downwardsInferPhase,
+      String expected}) {
+    assert(typeParameter != null);
+    assert(expected != null);
+    assert(downwardsInferPhase != null);
+    assert(inferredTypeFromDownwardPhase == null || !downwardsInferPhase);
+
+    typeParserEnvironment.withTypeParameters(typeParameter,
+        (List<TypeParameter> typeParameterNodes) {
+      assert(typeParameterNodes.length == 1);
+
+      TypeConstraint typeConstraint = parseConstraint(constraints);
+      DartType expectedTypeNode = parseType(expected);
+      TypeParameter typeParameterNode = typeParameterNodes.single;
+      List<DartType> inferredTypeNodes = <DartType>[
+        inferredTypeFromDownwardPhase == null
+            ? new UnknownType()
+            : parseType(inferredTypeFromDownwardPhase)
+      ];
+
+      typeSchemaEnvironment.inferTypeFromConstraints(
+          {typeParameterNode: typeConstraint},
+          [typeParameterNode],
+          inferredTypeNodes,
+          testLibrary,
+          downwardsInferPhase: downwardsInferPhase);
+
+      expect(inferredTypeNodes.single, expectedTypeNode);
+    });
+  }
+
+  /// Parses a string like "<: T <: S >: R" into a [TypeConstraint].
+  ///
+  /// The [constraint] string is assumed to be a sequence of bounds added to the
+  /// constraint.  Each element of the sequence is either "<: T" or ":> T",
+  /// where the former adds an upper bound and the latter adds a lower bound.
+  /// The bounds are added to the constraint in the order they are mentioned in
+  /// the [constraint] string, from left to right.
+  TypeConstraint parseConstraint(String constraint) {
+    TypeConstraint result = new TypeConstraint();
+    List<String> upperBoundSegments = constraint.split("<:");
+    bool firstUpperBoundSegment = true;
+    for (String upperBoundSegment in upperBoundSegments) {
+      if (firstUpperBoundSegment) {
+        firstUpperBoundSegment = false;
+        if (upperBoundSegment.isEmpty) {
+          continue;
+        }
+      }
+      List<String> lowerBoundSegments = upperBoundSegment.split(":>");
+      bool firstLowerBoundSegment = true;
+      for (String segment in lowerBoundSegments) {
+        if (firstLowerBoundSegment) {
+          firstLowerBoundSegment = false;
+          if (segment.isNotEmpty) {
+            typeSchemaEnvironment.addUpperBound(
+                result, parseType(segment), testLibrary);
+          }
+        } else {
+          typeSchemaEnvironment.addLowerBound(
+              result, parseType(segment), testLibrary);
+        }
+      }
     }
-    return null;
+    return result;
+  }
+
+  DartType parseType(String type) {
+    return typeParserEnvironment.parseType(type,
+        additionalTypes: additionalTypes);
+  }
+
+  List<DartType> parseTypes(String types) {
+    return typeParserEnvironment.parseTypes(types,
+        additionalTypes: additionalTypes);
   }
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 24ef0a4..e57d799 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -7,8 +7,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
-import 'package:kernel/type_environment.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,356 +19,273 @@
 
 @reflectiveTest
 class TypeSchemaEnvironmentTest {
-  static const UnknownType unknownType = const UnknownType();
+  Env typeParserEnvironment;
+  TypeSchemaEnvironment typeSchemaEnvironment;
 
-  static const DynamicType dynamicType = const DynamicType();
+  final Map<String, DartType Function()> additionalTypes = {
+    "UNKNOWN": () => new UnknownType(),
+    "BOTTOM": () => new BottomType(),
+  };
 
-  static const VoidType voidType = const VoidType();
+  Library _coreLibrary;
+  Library _testLibrary;
 
-  final testLib = new Library(Uri.parse('org-dartlang:///test.dart'));
+  Library get coreLibrary => _coreLibrary;
+  Library get testLibrary => _testLibrary;
 
-  Component component;
+  Component get component => typeParserEnvironment.component;
+  CoreTypes get coreTypes => typeParserEnvironment.coreTypes;
 
-  CoreTypes coreTypes;
-
-  TypeSchemaEnvironmentTest() {
-    component = createMockSdkComponent();
-    component.libraries.add(testLib..parent = component);
-    coreTypes = new CoreTypes(component);
+  void parseTestLibrary(String testLibraryText) {
+    typeParserEnvironment =
+        new Env(testLibraryText, isNonNullableByDefault: false);
+    typeSchemaEnvironment = new TypeSchemaEnvironment(
+        coreTypes, new ClassHierarchy(component, coreTypes));
+    assert(
+        typeParserEnvironment.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = typeParserEnvironment.component.libraries.first;
+    Library secondLibrary = typeParserEnvironment.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
-  InterfaceType get doubleType => coreTypes.doubleLegacyRawType;
-
-  InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
-  InterfaceType get intType => coreTypes.intLegacyRawType;
-
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  InterfaceType get numType => coreTypes.numLegacyRawType;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get objectType => coreTypes.objectLegacyRawType;
-
-  DartType get bottomType => const NullType();
-
-  DartType get topType => const DynamicType();
-
   void test_addLowerBound() {
-    var A = coreTypes.legacyRawType(_addClass(_class('A')));
-    var B = coreTypes.legacyRawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)));
-    var C = coreTypes.legacyRawType(
-        _addClass(_class('C', supertype: A.classNode.asThisSupertype)));
-    var env = _makeEnv();
-    var typeConstraint = new TypeConstraint();
-    expect(typeConstraint.lower, same(unknownType));
-    env.addLowerBound(typeConstraint, B, testLib);
-    expect(typeConstraint.lower, same(B));
-    env.addLowerBound(typeConstraint, C, testLib);
-    expect(typeConstraint.lower, same(A));
+    parseTestLibrary("class A; class B extends A; class C extends A;");
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintLowerBound(constraint: ":> B*", bound: "B*");
+    checkConstraintLowerBound(constraint: ":> B* :> C*", bound: "A*");
   }
 
   void test_addUpperBound() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var C = coreTypes.rawType(
-        _addClass(_class('C', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    var typeConstraint = new TypeConstraint();
-    expect(typeConstraint.upper, same(unknownType));
-    env.addUpperBound(typeConstraint, A, testLib);
-    expect(typeConstraint.upper, same(A));
-    env.addUpperBound(typeConstraint, B, testLib);
-    expect(typeConstraint.upper, same(B));
-    env.addUpperBound(typeConstraint, C, testLib);
-    expect(typeConstraint.upper, new BottomType());
+    parseTestLibrary("class A; class B extends A; class C extends A;");
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintUpperBound(constraint: "<: A*", bound: "A*");
+    checkConstraintUpperBound(constraint: "<: A* <: B*", bound: "B*");
+    checkConstraintUpperBound(constraint: "<: A* <: B* <: C*", bound: "BOTTOM");
   }
 
   void test_glb_bottom() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(new BottomType(), A, testLib),
-        new BottomType());
-    expect(env.getStandardLowerBound(A, new BottomType(), testLib),
-        new BottomType());
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "Null", type2: "A*", lowerBound: "Null");
+    checkLowerBound(type1: "A*", type2: "Null", lowerBound: "Null");
   }
 
   void test_glb_function() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("class A; class B extends A;");
+
     // GLB(() -> A, () -> B) = () -> B
-    expect(
-        env.getStandardLowerBound(new FunctionType([], A, Nullability.legacy),
-            new FunctionType([], B, Nullability.legacy), testLib),
-        new FunctionType([], B, Nullability.legacy));
+    checkLowerBound(
+        type1: "() ->* A*", type2: "() ->* B*", lowerBound: "() ->* B*");
+
     // GLB(() -> void, (A, B) -> void) = ([A, B]) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy),
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A, B], voidType, Nullability.legacy,
-            requiredParameterCount: 0));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            new FunctionType([], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A, B], voidType, Nullability.legacy,
-            requiredParameterCount: 0));
+    checkLowerBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+    checkLowerBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+
     // GLB((A) -> void, (B) -> void) = (A) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([A], voidType, Nullability.legacy),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A], voidType, Nullability.legacy));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([B], voidType, Nullability.legacy),
-            new FunctionType([A], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A], voidType, Nullability.legacy));
+    checkLowerBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(A*) ->* void");
+    checkLowerBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        lowerBound: "(A*) ->* void");
+
     // GLB(({a: A}) -> void, ({b: B}) -> void) = ({a: A, b: B}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', B)]));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', B)]));
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+
     // GLB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void)
     //     = ({a: A, b: B, c: A, d: B}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('c', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('b', B),
-                  new NamedType('d', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [
-              new NamedType('a', A),
-              new NamedType('b', B),
-              new NamedType('c', A),
-              new NamedType('d', B)
-            ]));
+    checkLowerBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        lowerBound: "({A* a, B* b, A* c, B* d}) ->* void");
+
     // GLB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void)
     //     = ({a: A, b: A}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', A)]));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', A)]));
+    checkLowerBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+
     // GLB((B, {a: A}) -> void, (B) -> void) = (B, {a: A}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([B], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A)]));
+    checkLowerBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(B*, {A* a}) ->* void");
+
     // GLB(({a: A}) -> void, (B) -> void) = bottom
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new BottomType());
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "BOTTOM");
+
     // GLB(({a: A}) -> void, ([B]) -> void) = bottom
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy,
-                requiredParameterCount: 0),
-            testLib),
-        new BottomType());
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "([B*]) ->* void",
+        lowerBound: "BOTTOM");
   }
 
   void test_glb_identical() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, A, testLib), same(A));
-    expect(
-        env.getStandardLowerBound(
-            new InterfaceType(A.classNode, Nullability.legacy), A, testLib),
-        A);
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "A*", type2: "A*", lowerBound: "A*");
   }
 
   void test_glb_subtype() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, B, testLib), same(B));
-    expect(env.getStandardLowerBound(B, A, testLib), same(B));
+    parseTestLibrary("class A; class B extends A;");
+
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "B*");
+    checkLowerBound(type1: "B*", type2: "A*", lowerBound: "B*");
   }
 
   void test_glb_top() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(dynamicType, A, testLib), same(A));
-    expect(env.getStandardLowerBound(A, dynamicType, testLib), same(A));
-    expect(env.getStandardLowerBound(objectType, A, testLib), same(A));
-    expect(env.getStandardLowerBound(A, objectType, testLib), same(A));
-    expect(env.getStandardLowerBound(voidType, A, testLib), same(A));
-    expect(env.getStandardLowerBound(A, voidType, testLib), same(A));
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "dynamic", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "dynamic", lowerBound: "A*");
+    checkLowerBound(type1: "Object*", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "Object*", lowerBound: "A*");
+    checkLowerBound(type1: "void", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "void", lowerBound: "A*");
   }
 
   void test_glb_unknown() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, unknownType, testLib), same(A));
-    expect(env.getStandardLowerBound(unknownType, A, testLib), same(A));
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "A*", type2: "UNKNOWN", lowerBound: "A*");
+    checkLowerBound(type1: "UNKNOWN", type2: "A*", lowerBound: "A*");
   }
 
   void test_glb_unrelated() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(_addClass(_class('B')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, B, testLib), new BottomType());
+    parseTestLibrary("class A; class B;");
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "BOTTOM");
   }
 
   void test_inferGenericFunctionOrType() {
-    var env = _makeEnv();
-    InterfaceType listClassThisType =
-        coreTypes.thisInterfaceType(listClass, testLib.nonNullable);
-    {
-      // Test an instantiation of [1, 2.0] with no context.  This should infer
-      // as List<?> during downwards inference.
-      var inferredTypes = <DartType>[unknownType];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], unknownType);
-      // And upwards inference should refine it to List<num>.
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], [T, T],
-          [intType, doubleType], null, inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-    }
-    {
-      // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
-      // should infer as List<Object> during downwards inference.
-      var inferredTypes = <DartType>[unknownType];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, _list(objectType), inferredTypes, testLib);
-      expect(inferredTypes[0], objectType);
-      // And upwards inference should preserve the type.
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], [T, T],
-          [intType, doubleType], _list(objectType), inferredTypes, testLib);
-      expect(inferredTypes[0], objectType);
-    }
+    parseTestLibrary("");
+
+    // Test an instantiation of [1, 2.0] with no context.  This should infer
+    // as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "() ->* List<T*>*",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    // And upwards inference should refine it to List<num>.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "(T*, T*) ->* List<T*>*",
+        actualParameterTypes: "int*, double*",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num*");
+
+    // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
+    // should infer as List<Object> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "() ->* List<T*>*",
+        actualParameterTypes: null,
+        returnContextType: "List<Object*>*",
+        expectedTypes: "Object*");
+    // And upwards inference should preserve the type.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "(T*, T*) ->* List<T>",
+        actualParameterTypes: "int*, double*",
+        returnContextType: "List<Object*>*",
+        inferredTypesFromDownwardPhase: "Object*",
+        expectedTypes: "Object*");
   }
 
   void test_inferTypeFromConstraints_applyBound() {
-    // class A<T extends num> {}
-    var T = new TypeParameter('T', numType);
-    coreTypes.thisInterfaceType(
-        _addClass(_class('A', typeParameters: [T])), testLib.nonNullable);
-    var env = _makeEnv();
-    {
-      // With no constraints:
-      var constraints = {T: new TypeConstraint()};
-      // Downward inference should infer A<?>
-      var inferredTypes = <DartType>[unknownType];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], unknownType);
-      // Upward inference should infer A<num>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-    }
-    {
-      // With an upper bound of Object:
-      var constraints = {T: _makeConstraint(upper: objectType)};
-      // Downward inference should infer A<num>
-      var inferredTypes = <DartType>[unknownType];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], numType);
-      // Upward inference should infer A<num>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-      // Upward inference should still infer A<num> even if there are more
-      // constraints now, because num was finalized during downward inference.
-      constraints = {T: _makeConstraint(lower: intType, upper: intType)};
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-    }
+    parseTestLibrary("");
+
+    // With no constraints:
+    // Downward inference should infer '?'
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: true,
+        expected: "UNKNOWN");
+    // Upward inference should infer num
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "UNKNOWN",
+        expected: "num*");
+
+    // With an upper bound of Object:
+    // Downward inference should infer num.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: true,
+        expected: "num*");
+    // Upward inference should infer num.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
+    // Upward inference should still infer num even if there are more
+    // constraints now, because num was finalized during downward inference.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: ":> int* <: int*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
   }
 
   void test_inferTypeFromConstraints_simple() {
-    var env = _makeEnv();
-    var T = listClass.typeParameters[0];
+    parseTestLibrary("");
+
     // With an upper bound of List<?>:
-    var constraints = {T: _makeConstraint(upper: _list(unknownType))};
     // Downwards inference should infer List<List<?>>
-    var inferredTypes = <DartType>[unknownType];
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-        downwardsInferPhase: true);
-    expect(inferredTypes[0], _list(unknownType));
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object*",
+        constraints: "<: List<UNKNOWN>*",
+        downwardsInferPhase: true,
+        expected: "List<UNKNOWN>*");
     // Upwards inference should refine that to List<List<dynamic>>
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-    expect(inferredTypes[0], _list(dynamicType));
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object*",
+        constraints: "<: List<UNKNOWN>*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "List<UNKNOWN>*",
+        expected: "List<dynamic>*");
   }
 
   void test_lub_classic() {
@@ -382,485 +298,517 @@
     // B C
     // |X|
     // D E
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var C = coreTypes.rawType(
-        _addClass(_class('C', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var D = coreTypes.rawType(
-        _addClass(_class('D', implementedTypes: [
-          B.classNode.asThisSupertype,
-          C.classNode.asThisSupertype
-        ])),
-        Nullability.legacy);
-    var E = coreTypes.rawType(
-        _addClass(_class('E', implementedTypes: [
-          B.classNode.asThisSupertype,
-          C.classNode.asThisSupertype
-        ])),
-        Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardUpperBound(D, E, testLib), A);
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+      class C extends A;
+      class D implements B, C;
+      class E implements B, C;
+    """);
+
+    checkUpperBound(type1: "D*", type2: "E*", upperBound: "A*");
   }
 
   void test_lub_commonClass() {
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(_list(intType), _list(doubleType), testLib),
-        _list(numType));
+    parseTestLibrary("");
+    checkUpperBound(
+        type1: "List<int*>*",
+        type2: "List<double*>*",
+        upperBound: "List<num*>*");
   }
 
   void test_lub_function() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("class A; class B extends A;");
+
     // LUB(() -> A, () -> B) = () -> A
-    expect(
-        env.getStandardUpperBound(new FunctionType([], A, Nullability.legacy),
-            new FunctionType([], B, Nullability.legacy), testLib),
-        new FunctionType([], A, Nullability.legacy));
+    checkUpperBound(
+        type1: "() ->* A*", type2: "() ->* B*", upperBound: "() ->* A*");
+
     // LUB(([A]) -> void, (A) -> void) = Function
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([A], voidType, Nullability.legacy,
-                requiredParameterCount: 0),
-            new FunctionType([A], voidType, Nullability.legacy),
-            testLib),
-        functionType);
+    checkUpperBound(
+        type1: "([A*]) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "Function*");
+
     // LUB(() -> void, (A, B) -> void) = Function
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy),
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            testLib),
-        functionType);
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            new FunctionType([], voidType, Nullability.legacy),
-            testLib),
-        functionType);
+    checkUpperBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        upperBound: "Function*");
+
     // LUB((A) -> void, (B) -> void) = (B) -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([A], voidType, Nullability.legacy),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy));
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([B], voidType, Nullability.legacy),
-            new FunctionType([A], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "(B*) ->* void");
+
     // LUB(({a: A}) -> void, ({b: B}) -> void) = () -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        upperBound: "() ->* void");
+
     // LUB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void) = () -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('c', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('b', B),
-                  new NamedType('d', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        upperBound: "() ->* void");
+
     // LUB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void)
     //     = ({a: B, b: B}) -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', B), new NamedType('b', B)]));
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', B), new NamedType('b', B)]));
+    checkUpperBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+    checkUpperBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+
     // LUB((B, {a: A}) -> void, (B) -> void) = (B) -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([B], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+
     // LUB(({a: A}) -> void, (B) -> void) = Function
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        functionType);
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "Function*");
+
     // GLB(({a: A}) -> void, ([B]) -> void) = () -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy,
-                requiredParameterCount: 0),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "([B*]) ->* void",
+        upperBound: "() ->* void");
   }
 
   void test_lub_identical() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardUpperBound(A, A, testLib), same(A));
-    expect(
-        env.getStandardUpperBound(
-            new InterfaceType(A.classNode, Nullability.legacy), A, testLib),
-        A);
+    parseTestLibrary("class A;");
+    checkUpperBound(type1: "A*", type2: "A*", upperBound: "A*");
   }
 
   void test_lub_sameClass() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(_map(A, B), _map(B, A), testLib), _map(A, A));
+    parseTestLibrary("class A; class B extends A; class Map<X, Y>;");
+    checkUpperBound(
+        type1: "Map<A*, B*>*",
+        type2: "Map<B*, A*>*",
+        upperBound: "Map<A*, A*>*");
   }
 
   void test_lub_subtype() {
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(_list(intType), _iterable(numType), testLib),
-        _iterable(numType));
-    expect(
-        env.getStandardUpperBound(_iterable(numType), _list(intType), testLib),
-        _iterable(numType));
+    parseTestLibrary("");
+    checkUpperBound(
+        type1: "List<int*>*",
+        type2: "Iterable<num*>*",
+        upperBound: "Iterable<num*>*");
+    checkUpperBound(
+        type1: "Iterable<num*>*",
+        type2: "List<int*>*",
+        upperBound: "Iterable<num*>*");
   }
 
   void test_lub_top() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(dynamicType, A, testLib), same(dynamicType));
-    expect(
-        env.getStandardUpperBound(A, dynamicType, testLib), same(dynamicType));
-    expect(env.getStandardUpperBound(objectType, A, testLib), same(objectType));
-    expect(env.getStandardUpperBound(A, objectType, testLib), same(objectType));
-    expect(env.getStandardUpperBound(voidType, A, testLib), same(voidType));
-    expect(env.getStandardUpperBound(A, voidType, testLib), same(voidType));
-    expect(env.getStandardUpperBound(dynamicType, objectType, testLib),
-        same(dynamicType));
-    expect(env.getStandardUpperBound(objectType, dynamicType, testLib),
-        same(dynamicType));
-    expect(env.getStandardUpperBound(dynamicType, voidType, testLib),
-        same(voidType));
-    expect(env.getStandardUpperBound(voidType, dynamicType, testLib),
-        same(voidType));
-    expect(env.getStandardUpperBound(objectType, voidType, testLib),
-        same(voidType));
-    expect(env.getStandardUpperBound(voidType, objectType, testLib),
-        same(voidType));
+    parseTestLibrary("class A;");
+
+    checkUpperBound(type1: "dynamic", type2: "A*", upperBound: "dynamic");
+    checkUpperBound(type1: "A*", type2: "dynamic", upperBound: "dynamic");
+    checkUpperBound(type1: "Object*", type2: "A*", upperBound: "Object*");
+    checkUpperBound(type1: "A*", type2: "Object*", upperBound: "Object*");
+    checkUpperBound(type1: "void", type2: "A*", upperBound: "void");
+    checkUpperBound(type1: "A*", type2: "void", upperBound: "void");
+    checkUpperBound(type1: "dynamic", type2: "Object*", upperBound: "dynamic");
+    checkUpperBound(type1: "Object*", type2: "dynamic", upperBound: "dynamic");
+    checkUpperBound(type1: "dynamic", type2: "void", upperBound: "void");
+    checkUpperBound(type1: "void", type2: "dynamic", upperBound: "void");
+    checkUpperBound(type1: "Object*", type2: "void", upperBound: "void");
+    checkUpperBound(type1: "void", type2: "Object*", upperBound: "void");
   }
 
   void test_lub_typeParameter() {
-    var T = new TypeParameterType(new TypeParameter('T'), Nullability.legacy);
-    T.parameter.bound = _list(T);
-    var U = new TypeParameterType(new TypeParameter('U'), Nullability.legacy);
-    U.parameter.bound = _list(new BottomType());
-    var env = _makeEnv();
+    parseTestLibrary("");
+
     // LUB(T, T) = T
-    expect(env.getStandardUpperBound(T, T, testLib), same(T));
+    checkUpperBound(
+        type1: "T*",
+        type2: "T*",
+        upperBound: "T*",
+        typeParameters: "T extends List<T*>*");
+
     // LUB(T, List<Bottom>) = LUB(List<Object>, List<Bottom>) = List<Object>
-    expect(env.getStandardUpperBound(T, _list(new BottomType()), testLib),
-        _list(objectType));
-    expect(env.getStandardUpperBound(_list(new BottomType()), T, testLib),
-        _list(objectType));
+    checkUpperBound(
+        type1: "T*",
+        type2: "List<Null>*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*");
+    checkUpperBound(
+        type1: "List<Null>*",
+        type2: "T*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*");
+
     // LUB(T, U) = LUB(List<Object>, U) = LUB(List<Object>, List<Bottom>)
     // = List<Object>
-    expect(env.getStandardUpperBound(T, U, testLib), _list(objectType));
-    expect(env.getStandardUpperBound(U, T, testLib), _list(objectType));
+    checkUpperBound(
+        type1: "T*",
+        type2: "U*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*, U extends List<Null>*");
+    checkUpperBound(
+        type1: "U*",
+        type2: "T*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*, U extends List<Null>*");
   }
 
   void test_lub_unknown() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, unknownType, testLib), same(A));
-    expect(env.getStandardLowerBound(unknownType, A, testLib), same(A));
+    parseTestLibrary("class A;");
+    checkUpperBound(type1: "A*", type2: "UNKNOWN", upperBound: "A*");
+    checkUpperBound(type1: "UNKNOWN", type2: "A*", upperBound: "A*");
   }
 
   void test_solveTypeConstraint() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+      
+      class C<T extends Object*>;
+      class D<T extends Object*> extends C<T*>;
+    """);
+
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint(), topType, bottomType),
-        same(unknownType));
+    checkConstraintSolving("", "UNKNOWN", grounded: false);
+
     // Solve(? <: T <: ?, grounded) => dynamic
-    expect(
-        env.solveTypeConstraint(_makeConstraint(), topType, bottomType,
-            grounded: true),
-        dynamicType);
+    checkConstraintSolving("", "dynamic", grounded: true);
+
     // Solve(A <: T <: ?) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(lower: A), topType, bottomType),
-        A);
+    checkConstraintSolving(":> A*", "A*", grounded: false);
+
     // Solve(A <: T <: ?, grounded) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(lower: A), topType, bottomType,
-            grounded: true),
-        A);
+    checkConstraintSolving(":> A*", "A*", grounded: true);
+
     // Solve(A<?> <: T <: ?) => A<?>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
+    checkConstraintSolving(":> C<UNKNOWN>*", "C<UNKNOWN>*", grounded: false);
+
     // Solve(A<?> <: T <: ?, grounded) => A<Null>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        new InterfaceType(A.classNode, Nullability.legacy, [const NullType()]));
+    checkConstraintSolving(":> C<UNKNOWN>*", "C<Null>*", grounded: true);
+
     // Solve(? <: T <: A) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(upper: A), topType, bottomType),
-        A);
+    checkConstraintSolving("<: A*", "A*", grounded: false);
+
     // Solve(? <: T <: A, grounded) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(upper: A), topType, bottomType,
-            grounded: true),
-        A);
+    checkConstraintSolving("<: A*", "A*", grounded: true);
+
     // Solve(? <: T <: A<?>) => A<?>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
+    checkConstraintSolving("<: C<UNKNOWN>*", "C<UNKNOWN>*", grounded: false);
+
     // Solve(? <: T <: A<?>, grounded) => A<dynamic>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        new InterfaceType(A.classNode, Nullability.legacy, [dynamicType]));
+    checkConstraintSolving("<: C<UNKNOWN>*", "C<dynamic>*", grounded: true);
+
     // Solve(B <: T <: A) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: B, upper: A), topType, bottomType),
-        B);
+    checkConstraintSolving(":> B* <: A*", "B*", grounded: false);
+
     // Solve(B <: T <: A, grounded) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: B, upper: A), topType, bottomType,
-            grounded: true),
-        B);
+    checkConstraintSolving(":> B* <: A*", "B*", grounded: true);
+
     // Solve(B<?> <: T <: A) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: A),
-            topType,
-            bottomType),
-        A);
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<dynamic>*", "C<dynamic>*",
+        grounded: false);
+
     // Solve(B<?> <: T <: A, grounded) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: A),
-            topType,
-            bottomType,
-            grounded: true),
-        A);
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<dynamic>*", "C<dynamic>*",
+        grounded: true);
+
     // Solve(B <: T <: A<?>) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: B,
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        B);
+    checkConstraintSolving(":> D<Null>* <: C<UNKNOWN>*", "D<Null>*",
+        grounded: false);
+
     // Solve(B <: T <: A<?>, grounded) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: B,
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        B);
+    checkConstraintSolving(":> D<Null>* <: C<UNKNOWN>*", "D<Null>*",
+        grounded: true);
+
     // Solve(B<?> <: T <: A<?>) => B<?>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        new InterfaceType(B.classNode, Nullability.legacy, [unknownType]));
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<UNKNOWN>*", "D<UNKNOWN>*",
+        grounded: false);
+
     // Solve(B<?> <: T <: A<?>) => B<Null>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        new InterfaceType(B.classNode, Nullability.legacy, [const NullType()]));
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<UNKNOWN>*", "D<Null>*",
+        grounded: true);
   }
 
   void test_typeConstraint_default() {
-    var typeConstraint = new TypeConstraint();
-    expect(typeConstraint.lower, same(unknownType));
-    expect(typeConstraint.upper, same(unknownType));
+    parseTestLibrary("");
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
   }
 
   void test_typeSatisfiesConstraint() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var C = coreTypes.rawType(
-        _addClass(_class('C', supertype: B.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var D = coreTypes.rawType(
-        _addClass(_class('D', supertype: C.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var E = coreTypes.rawType(
-        _addClass(_class('E', supertype: D.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    var typeConstraint = _makeConstraint(upper: B, lower: D);
-    expect(env.typeSatisfiesConstraint(A, typeConstraint), isFalse);
-    expect(env.typeSatisfiesConstraint(B, typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(C, typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(D, typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(E, typeConstraint), isFalse);
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+      class C extends B;
+      class D extends C;
+      class E extends D;
+    """);
+
+    checkTypeDoesntSatisfyConstraint("A*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("B*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("C*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("D*", ":> D* <: B*");
+    checkTypeDoesntSatisfyConstraint("E*", ":> D* <: B*");
   }
 
   void test_unknown_at_bottom() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(
-        env.isSubtypeOf(unknownType, A, SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+    parseTestLibrary("class A;");
+    checkIsLegacySubtype("UNKNOWN", "A*");
   }
 
   void test_unknown_at_top() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("class A; class Map<X, Y>;");
+    checkIsLegacySubtype("A*", "UNKNOWN");
+    checkIsLegacySubtype("Map<A*, A*>*", "Map<UNKNOWN, UNKNOWN>*");
+  }
+
+  void checkConstraintSolving(String constraint, String expected,
+      {bool grounded}) {
+    assert(grounded != null);
     expect(
-        env.isSubtypeOf(A, unknownType, SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+        typeSchemaEnvironment.solveTypeConstraint(
+            parseConstraint(constraint), new DynamicType(), new NullType(),
+            grounded: grounded),
+        parseType(expected));
+  }
+
+  void checkConstraintUpperBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).upper, parseType(bound));
+  }
+
+  void checkConstraintLowerBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).lower, parseType(bound));
+  }
+
+  void checkTypeSatisfiesConstraint(String type, String constraint) {
     expect(
-        env.isSubtypeOf(_map(A, A), _map(unknownType, unknownType),
-            SubtypeCheckMode.ignoringNullabilities),
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
         isTrue);
   }
 
-  Class _addClass(Class c) {
-    testLib.addClass(c);
-    return c;
+  void checkTypeDoesntSatisfyConstraint(String type, String constraint) {
+    expect(
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
+        isFalse);
   }
 
-  Class _class(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
+  void checkIsSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenUsingNullabilities(),
+        isTrue);
   }
 
-  DartType _iterable(DartType elementType) =>
-      new InterfaceType(iterableClass, Nullability.legacy, [elementType]);
-
-  DartType _list(DartType elementType) =>
-      new InterfaceType(listClass, Nullability.legacy, [elementType]);
-
-  TypeConstraint _makeConstraint(
-      {DartType lower: const UnknownType(),
-      DartType upper: const UnknownType()}) {
-    return new TypeConstraint()
-      ..lower = lower
-      ..upper = upper;
+  void checkIsLegacySubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isTrue);
   }
 
-  TypeSchemaEnvironment _makeEnv() {
-    return new TypeSchemaEnvironment(
-        coreTypes, new ClassHierarchy(component, coreTypes));
+  void checkIsNotSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isFalse);
   }
 
-  DartType _map(DartType key, DartType value) =>
-      new InterfaceType(mapClass, Nullability.legacy, [key, value]);
+  void checkUpperBound(
+      {String type1, String type2, String upperBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(upperBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardUpperBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(upperBound));
+    });
+  }
+
+  void checkLowerBound(
+      {String type1, String type2, String lowerBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(lowerBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardLowerBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(lowerBound));
+    });
+  }
+
+  void checkInference(
+      {String typeParametersToInfer,
+      String functionType,
+      String actualParameterTypes,
+      String returnContextType,
+      String inferredTypesFromDownwardPhase,
+      String expectedTypes}) {
+    assert(typeParametersToInfer != null);
+    assert(functionType != null);
+    assert(expectedTypes != null);
+
+    typeParserEnvironment.withTypeParameters(typeParametersToInfer,
+        (List<TypeParameter> typeParameterNodesToInfer) {
+      FunctionType functionTypeNode = parseType(functionType);
+      DartType returnContextTypeNode =
+          returnContextType == null ? null : parseType(returnContextType);
+      List<DartType> actualTypeNodes = actualParameterTypes == null
+          ? null
+          : parseTypes(actualParameterTypes);
+      List<DartType> expectedTypeNodes =
+          expectedTypes == null ? null : parseTypes(expectedTypes);
+      DartType declaredReturnTypeNode = functionTypeNode.returnType;
+      List<DartType> formalTypeNodes = actualParameterTypes == null
+          ? null
+          : functionTypeNode.positionalParameters;
+
+      List<DartType> inferredTypeNodes;
+      if (inferredTypesFromDownwardPhase == null) {
+        inferredTypeNodes = new List<DartType>.generate(
+            typeParameterNodesToInfer.length, (_) => new UnknownType());
+      } else {
+        inferredTypeNodes = parseTypes(inferredTypesFromDownwardPhase);
+      }
+
+      typeSchemaEnvironment.inferGenericFunctionOrType(
+          declaredReturnTypeNode,
+          typeParameterNodesToInfer,
+          formalTypeNodes,
+          actualTypeNodes,
+          returnContextTypeNode,
+          inferredTypeNodes,
+          testLibrary);
+
+      assert(
+          inferredTypeNodes.length == expectedTypeNodes.length,
+          "The numbers of expected types and type parameters to infer "
+          "mismatch.");
+      for (int i = 0; i < inferredTypeNodes.length; ++i) {
+        expect(inferredTypeNodes[i], expectedTypeNodes[i]);
+      }
+    });
+  }
+
+  void checkInferenceFromConstraints(
+      {String typeParameter,
+      String constraints,
+      String inferredTypeFromDownwardPhase,
+      bool downwardsInferPhase,
+      String expected}) {
+    assert(typeParameter != null);
+    assert(expected != null);
+    assert(downwardsInferPhase != null);
+    assert(inferredTypeFromDownwardPhase == null || !downwardsInferPhase);
+
+    typeParserEnvironment.withTypeParameters(typeParameter,
+        (List<TypeParameter> typeParameterNodes) {
+      assert(typeParameterNodes.length == 1);
+
+      TypeConstraint typeConstraint = parseConstraint(constraints);
+      DartType expectedTypeNode = parseType(expected);
+      TypeParameter typeParameterNode = typeParameterNodes.single;
+      List<DartType> inferredTypeNodes = <DartType>[
+        inferredTypeFromDownwardPhase == null
+            ? new UnknownType()
+            : parseType(inferredTypeFromDownwardPhase)
+      ];
+
+      typeSchemaEnvironment.inferTypeFromConstraints(
+          {typeParameterNode: typeConstraint},
+          [typeParameterNode],
+          inferredTypeNodes,
+          testLibrary,
+          downwardsInferPhase: downwardsInferPhase);
+
+      expect(inferredTypeNodes.single, expectedTypeNode);
+    });
+  }
+
+  /// Parses a string like "<: T <: S >: R" into a [TypeConstraint].
+  ///
+  /// The [constraint] string is assumed to be a sequence of bounds added to the
+  /// constraint.  Each element of the sequence is either "<: T" or ":> T",
+  /// where the former adds an upper bound and the latter adds a lower bound.
+  /// The bounds are added to the constraint in the order they are mentioned in
+  /// the [constraint] string, from left to right.
+  TypeConstraint parseConstraint(String constraint) {
+    TypeConstraint result = new TypeConstraint();
+    List<String> upperBoundSegments = constraint.split("<:");
+    bool firstUpperBoundSegment = true;
+    for (String upperBoundSegment in upperBoundSegments) {
+      if (firstUpperBoundSegment) {
+        firstUpperBoundSegment = false;
+        if (upperBoundSegment.isEmpty) {
+          continue;
+        }
+      }
+      List<String> lowerBoundSegments = upperBoundSegment.split(":>");
+      bool firstLowerBoundSegment = true;
+      for (String segment in lowerBoundSegments) {
+        if (firstLowerBoundSegment) {
+          firstLowerBoundSegment = false;
+          if (segment.isNotEmpty) {
+            typeSchemaEnvironment.addUpperBound(
+                result, parseType(segment), testLibrary);
+          }
+        } else {
+          typeSchemaEnvironment.addLowerBound(
+              result, parseType(segment), testLibrary);
+        }
+      }
+    }
+    return result;
+  }
+
+  DartType parseType(String type) {
+    return typeParserEnvironment.parseType(type,
+        additionalTypes: additionalTypes);
+  }
+
+  List<DartType> parseTypes(String types) {
+    return typeParserEnvironment.parseTypes(types,
+        additionalTypes: additionalTypes);
+  }
 }
diff --git a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
index cf9cfa5..b1ac139 100644
--- a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
@@ -36,6 +36,9 @@
   FastaLegacyUpperBoundTest(this.ticker, this.context);
 
   @override
+  bool get isNonNullableByDefault => false;
+
+  @override
   Future<void> parseComponent(String source) async {
     await super.parseComponent(source);
 
diff --git a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
index 0409fcb..e353327 100644
--- a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
@@ -12,6 +12,9 @@
   ClassHierarchy hierarchy;
 
   @override
+  bool get isNonNullableByDefault => true;
+
+  @override
   Future<void> parseComponent(String source) {
     super.parseComponent(source);
     hierarchy = new ClassHierarchy(env.component, env.coreTypes);
diff --git a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
index f55fe0a..5a50c9e 100644
--- a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
+++ b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
@@ -17,8 +17,11 @@
   Library coreLibrary;
   Library testLibrary;
 
+  bool get isNonNullableByDefault;
+
   void parseComponent(String source) {
-    env = new parser.Env(source);
+    env =
+        new parser.Env(source, isNonNullableByDefault: isNonNullableByDefault);
     assert(
         env.component.libraries.length == 2,
         "The test component is expected to have exactly two libraries: "
@@ -30,6 +33,10 @@
       coreLibrary = firstLibrary;
       testLibrary = secondLibrary;
     } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
       coreLibrary = secondLibrary;
       testLibrary = firstLibrary;
     }
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart b/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart
new file mode 100644
index 0000000..4f2c82f
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart
@@ -0,0 +1,472 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
+
+Uri base;
+
+main(List<String> args) {
+  File script = new File.fromUri(Platform.script);
+  base = script.parent.uri;
+
+  testTopLevelStuff();
+  testClassStuff();
+  testMixinStuff();
+
+  if (!args.contains("--fast")) {
+    canParseTopLevelIshOfAllFrontendFiles();
+  }
+}
+
+void canParseTopLevelIshOfAllFrontendFiles() {
+  Directory directory = new Directory.fromUri(base.resolve("../../../"));
+  int processed = 0;
+  int errors = 0;
+  for (FileSystemEntity entry in directory.listSync(recursive: true)) {
+    if (entry is File) {
+      if (!entry.path.endsWith(".dart")) continue;
+      try {
+        processed++;
+        List<int> data = entry.readAsBytesSync();
+        DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+            includeBody: true,
+            includeComments: true,
+            enableExtensionMethods: true,
+            enableNonNullable: false);
+        splitIntoChunks(ast, data);
+        for (DirectParserASTContent child in ast.children) {
+          if (child.isClass()) {
+            splitIntoChunks(child.asClass().getClassOrMixinBody(), data);
+          } else if (child.isMixinDeclaration()) {
+            splitIntoChunks(
+                child.asMixinDeclaration().getClassOrMixinBody(), data);
+          }
+        }
+      } catch (e, st) {
+        print("Failure on $entry:\n$e\n\n$st\n\n--------------\n\n");
+        errors++;
+      }
+    }
+  }
+  print("Processed $processed files in $directory. "
+      "Encountered $errors errors.");
+}
+
+void testTopLevelStuff() {
+  File file = new File.fromUri(
+      base.resolve("direct_parser_ast_test_data/top_level_stuff.txt"));
+  List<int> data = file.readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  expect(2, ast.getImports().length);
+  expect(2, ast.getExports().length);
+
+  List<String> foundChunks = splitIntoChunks(ast, data);
+  expect(22, foundChunks.length);
+  expect("library top_level_stuff;", foundChunks[0]);
+  expect('import "top_level_stuff_helper.dart";', foundChunks[1]);
+  expect('export "top_level_stuff_helper.dart";', foundChunks[2]);
+  expect(
+      'import "top_level_stuff_helper.dart" show a, b, '
+      'c hide d, e, f show foo;',
+      foundChunks[3]);
+  expect(
+      'export "top_level_stuff_helper.dart" show a, b, '
+      'c hide d, e, f show foo;',
+      foundChunks[4]);
+  expect("part 'top_level_stuff_helper.dart';", foundChunks[5]);
+  expect('@metadataOneOnThisOne("bla")\n', foundChunks[6]);
+  expect("@metadataTwoOnThisOne\n", foundChunks[7]);
+  expect("""void toplevelMethod() {
+  // no content
+}""", foundChunks[8]);
+  expect("""List<E> anotherTopLevelMethod<E>() {
+  return null;
+}""", foundChunks[9]);
+  expect("enum FooEnum { A, B, Bla }", foundChunks[10]);
+  expect("""class FooClass {
+  // no content.
+}""", foundChunks[11]);
+  expect("""mixin FooMixin {
+  // no content.
+}""", foundChunks[12]);
+  expect("""class A<T> {
+  // no content.
+}""", foundChunks[13]);
+  expect("typedef B = Function();", foundChunks[14]);
+  expect("""mixin C<T> on A<T> {
+  // no content.
+}""", foundChunks[15]);
+  expect("""extension D<T> on A<T> {
+  // no content.
+}""", foundChunks[16]);
+  expect("class E = A with FooClass;", foundChunks[17]);
+  expect("int field1;", foundChunks[18]);
+  expect("int field2, field3;", foundChunks[19]);
+  expect("int field4 = 42;", foundChunks[20]);
+  expect("@AnnotationAtEOF", foundChunks[21]);
+
+  file = new File.fromUri(
+      base.resolve("direct_parser_ast_test_data/top_level_stuff_helper.txt"));
+  data = file.readAsBytesSync();
+  ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  foundChunks = splitIntoChunks(ast, data);
+  expect(1, foundChunks.length);
+  expect("part of 'top_level_stuff.txt';", foundChunks[0]);
+
+  file = new File.fromUri(
+      base.resolve("direct_parser_ast_test_data/script_handle.txt"));
+  data = file.readAsBytesSync();
+  ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  foundChunks = splitIntoChunks(ast, data);
+  expect(1, foundChunks.length);
+  expect("#!/usr/bin/env dart -c", foundChunks[0]);
+}
+
+void testClassStuff() {
+  File file =
+      new File.fromUri(base.resolve("direct_parser_ast_test_data/class.txt"));
+  List<int> data = file.readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  List<DirectParserASTContentTopLevelDeclarationEnd> classes = ast.getClasses();
+  expect(2, classes.length);
+
+  DirectParserASTContentTopLevelDeclarationEnd decl = classes[0];
+  DirectParserASTContentClassDeclarationEnd cls = decl.asClass();
+  expect("Foo", decl.getIdentifier().token.lexeme);
+  DirectParserASTContentClassExtendsHandle extendsDecl = cls.getClassExtends();
+  expect("extends", extendsDecl.extendsKeyword?.lexeme);
+  DirectParserASTContentClassOrMixinImplementsHandle implementsDecl =
+      cls.getClassImplements();
+  expect("implements", implementsDecl.implementsKeyword?.lexeme);
+  DirectParserASTContentClassWithClauseHandle withClauseDecl =
+      cls.getClassWithClause();
+  expect(null, withClauseDecl);
+  List<DirectParserASTContentMemberEnd> members =
+      cls.getClassOrMixinBody().getMembers();
+  expect(5, members.length);
+  expect(members[0].isClassConstructor(), true);
+  expect(members[1].isClassFactoryMethod(), true);
+  expect(members[2].isClassMethod(), true);
+  expect(members[3].isClassMethod(), true);
+  expect(members[4].isClassFields(), true);
+
+  List<String> chunks = splitIntoChunks(cls.getClassOrMixinBody(), data);
+  expect(5, chunks.length);
+  expect("""Foo() {
+    // Constructor
+  }""", chunks[0]);
+  expect("factory Foo.factory() => Foo();", chunks[1]);
+  expect("""void method() {
+    // instance method.
+  }""", chunks[2]);
+  expect("""static void staticMethod() {
+    // static method.
+  }""", chunks[3]);
+  expect("int field1, field2 = 42;", chunks[4]);
+
+  chunks = processItem(
+      members[0].getClassConstructor().getBlockFunctionBody(), data);
+  expect(1, chunks.length);
+  expect("""{
+    // Constructor
+  }""", chunks[0]);
+  chunks =
+      processItem(members[2].getClassMethod().getBlockFunctionBody(), data);
+  expect(1, chunks.length);
+  expect("""{
+    // instance method.
+  }""", chunks[0]);
+  chunks =
+      processItem(members[3].getClassMethod().getBlockFunctionBody(), data);
+  expect(1, chunks.length);
+  expect("""{
+    // static method.
+  }""", chunks[0]);
+
+  // TODO: Move (something like) this into the check-all-files-thing.
+  for (DirectParserASTContentMemberEnd member
+      in cls.getClassOrMixinBody().getMembers()) {
+    if (member.isClassConstructor()) continue;
+    if (member.isClassFactoryMethod()) continue;
+    if (member.isClassFields()) continue;
+    if (member.isClassMethod()) continue;
+    throw "$member --- ${member.children}";
+  }
+
+  decl = classes[1];
+  cls = decl.asClass();
+  expect("Foo2", decl.getIdentifier().token.lexeme);
+  extendsDecl = cls.getClassExtends();
+  expect(null, extendsDecl.extendsKeyword?.lexeme);
+  implementsDecl = cls.getClassImplements();
+  expect(null, implementsDecl.implementsKeyword?.lexeme);
+  withClauseDecl = cls.getClassWithClause();
+  expect("with", withClauseDecl.withKeyword.lexeme);
+  members = cls.getClassOrMixinBody().getMembers();
+  expect(0, members.length);
+}
+
+void testMixinStuff() {
+  File file =
+      new File.fromUri(base.resolve("direct_parser_ast_test_data/mixin.txt"));
+  List<int> data = file.readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+      includeBody: true,
+      includeComments: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+  List<DirectParserASTContentTopLevelDeclarationEnd> mixins =
+      ast.getMixinDeclarations();
+  expect(mixins.length, 1);
+
+  DirectParserASTContentTopLevelDeclarationEnd decl = mixins[0];
+  DirectParserASTContentMixinDeclarationEnd mxn = decl.asMixinDeclaration();
+  expect("B", decl.getIdentifier().token.lexeme);
+
+  List<DirectParserASTContentMemberEnd> members =
+      mxn.getClassOrMixinBody().getMembers();
+  expect(4, members.length);
+  expect(members[0].isMixinFields(), true);
+  expect(members[1].isMixinMethod(), true);
+  expect(members[2].isMixinFactoryMethod(), true);
+  expect(members[3].isMixinConstructor(), true);
+
+  List<String> chunks = splitIntoChunks(mxn.getClassOrMixinBody(), data);
+  expect(4, chunks.length);
+  expect("static int staticField = 0;", chunks[0]);
+  expect("""void foo() {
+    // empty
+  }""", chunks[1]);
+  expect("""factory B() {
+    // empty
+  }""", chunks[2]);
+  expect("""B.foo() {
+    // empty
+  }""", chunks[3]);
+}
+
+void expect<E>(E expect, E actual) {
+  if (expect != actual) throw "Expected '$expect' but got '$actual'";
+}
+
+List<String> splitIntoChunks(DirectParserASTContent ast, List<int> data) {
+  List<String> foundChunks = [];
+  for (DirectParserASTContent child in ast.children) {
+    foundChunks.addAll(processItem(child, data));
+  }
+  return foundChunks;
+}
+
+List<String> processItem(DirectParserASTContent item, List<int> data) {
+  if (item.isClass()) {
+    DirectParserASTContentClassDeclarationEnd cls = item.asClass();
+    return [
+      getCutContent(data, cls.beginToken.offset,
+          cls.endToken.offset + cls.endToken.length)
+    ];
+  } else if (item.isMetadata()) {
+    DirectParserASTContentMetadataStarEnd metadataStar = item.asMetadata();
+    List<DirectParserASTContentMetadataEnd> entries =
+        metadataStar.getMetadataEntries();
+    if (entries.isNotEmpty) {
+      List<String> chunks = [];
+      for (DirectParserASTContentMetadataEnd metadata in entries) {
+        chunks.add(getCutContent(
+            data, metadata.beginToken.offset, metadata.endToken.offset));
+      }
+      return chunks;
+    }
+    return const [];
+  } else if (item.isImport()) {
+    DirectParserASTContentImportEnd import = item.asImport();
+    return [
+      getCutContent(data, import.importKeyword.offset,
+          import.semicolon.offset + import.semicolon.length)
+    ];
+  } else if (item.isExport()) {
+    DirectParserASTContentExportEnd export = item.asExport();
+    return [
+      getCutContent(data, export.exportKeyword.offset,
+          export.semicolon.offset + export.semicolon.length)
+    ];
+  } else if (item.isLibraryName()) {
+    DirectParserASTContentLibraryNameEnd name = item.asLibraryName();
+    return [
+      getCutContent(data, name.libraryKeyword.offset,
+          name.semicolon.offset + name.semicolon.length)
+    ];
+  } else if (item.isPart()) {
+    DirectParserASTContentPartEnd part = item.asPart();
+    return [
+      getCutContent(data, part.partKeyword.offset,
+          part.semicolon.offset + part.semicolon.length)
+    ];
+  } else if (item.isPartOf()) {
+    DirectParserASTContentPartOfEnd partOf = item.asPartOf();
+    return [
+      getCutContent(data, partOf.partKeyword.offset,
+          partOf.semicolon.offset + partOf.semicolon.length)
+    ];
+  } else if (item.isTopLevelMethod()) {
+    DirectParserASTContentTopLevelMethodEnd method = item.asTopLevelMethod();
+    return [
+      getCutContent(data, method.beginToken.offset,
+          method.endToken.offset + method.endToken.length)
+    ];
+  } else if (item.isTopLevelFields()) {
+    DirectParserASTContentTopLevelFieldsEnd fields = item.asTopLevelFields();
+    return [
+      getCutContent(data, fields.beginToken.offset,
+          fields.endToken.offset + fields.endToken.length)
+    ];
+  } else if (item.isEnum()) {
+    DirectParserASTContentEnumEnd enm = item.asEnum();
+    return [
+      getCutContent(data, enm.enumKeyword.offset,
+          enm.leftBrace.endGroup.offset + enm.leftBrace.endGroup.length)
+    ];
+  } else if (item.isMixinDeclaration()) {
+    DirectParserASTContentMixinDeclarationEnd mixinDecl =
+        item.asMixinDeclaration();
+    return [
+      getCutContent(data, mixinDecl.mixinKeyword.offset,
+          mixinDecl.endToken.offset + mixinDecl.endToken.length)
+    ];
+  } else if (item.isNamedMixinDeclaration()) {
+    DirectParserASTContentNamedMixinApplicationEnd namedMixinDecl =
+        item.asNamedMixinDeclaration();
+    return [
+      getCutContent(data, namedMixinDecl.begin.offset,
+          namedMixinDecl.endToken.offset + namedMixinDecl.endToken.length)
+    ];
+  } else if (item.isTypedef()) {
+    DirectParserASTContentFunctionTypeAliasEnd typedefDecl = item.asTypedef();
+    return [
+      getCutContent(data, typedefDecl.typedefKeyword.offset,
+          typedefDecl.endToken.offset + typedefDecl.endToken.length)
+    ];
+  } else if (item.isExtension()) {
+    DirectParserASTContentExtensionDeclarationEnd extensionDecl =
+        item.asExtension();
+    return [
+      getCutContent(data, extensionDecl.extensionKeyword.offset,
+          extensionDecl.endToken.offset + extensionDecl.endToken.length)
+    ];
+  } else if (item.isScript()) {
+    DirectParserASTContentScriptHandle script = item.asScript();
+    return [
+      getCutContent(
+          data, script.token.offset, script.token.offset + script.token.length)
+    ];
+  } else if (item is DirectParserASTContentMemberEnd) {
+    if (item.isClassConstructor()) {
+      DirectParserASTContentClassConstructorEnd decl =
+          item.getClassConstructor();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassFactoryMethod()) {
+      DirectParserASTContentClassFactoryMethodEnd decl =
+          item.getClassFactoryMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassMethod()) {
+      DirectParserASTContentClassMethodEnd decl = item.getClassMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassFields()) {
+      DirectParserASTContentClassFieldsEnd decl = item.getClassFields();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isClassFields()) {
+      DirectParserASTContentClassFieldsEnd decl = item.getClassFields();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinFields()) {
+      DirectParserASTContentMixinFieldsEnd decl = item.getMixinFields();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinMethod()) {
+      DirectParserASTContentMixinMethodEnd decl = item.getMixinMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinFactoryMethod()) {
+      DirectParserASTContentMixinFactoryMethodEnd decl =
+          item.getMixinFactoryMethod();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else if (item.isMixinConstructor()) {
+      DirectParserASTContentMixinConstructorEnd decl =
+          item.getMixinConstructor();
+      return [
+        getCutContent(data, decl.beginToken.offset,
+            decl.endToken.offset + decl.endToken.length)
+      ];
+    } else {
+      if (item.type == DirectParserASTType.BEGIN) return const [];
+      if (item.type == DirectParserASTType.HANDLE) return const [];
+      if (item.isClassRecoverableError()) return const [];
+      if (item.isRecoverableError()) return const [];
+      if (item.isRecoverImport()) return const [];
+      throw "Unknown: $item --- ${item.children}";
+    }
+  } else if (item.isFunctionBody()) {
+    DirectParserASTContentBlockFunctionBodyEnd decl = item.asFunctionBody();
+    return [
+      getCutContent(data, decl.beginToken.offset,
+          decl.endToken.offset + decl.endToken.length)
+    ];
+  } else {
+    if (item.type == DirectParserASTType.BEGIN) return const [];
+    if (item.type == DirectParserASTType.HANDLE) return const [];
+    if (item.isInvalidTopLevelDeclaration()) return const [];
+    if (item.isRecoverableError()) return const [];
+    if (item.isRecoverImport()) return const [];
+
+    throw "Unknown: $item --- ${item.children}";
+  }
+}
+
+List<int> _contentCache;
+String _contentCacheString;
+String getCutContent(List<int> content, int from, int to) {
+  if (identical(content, _contentCache)) {
+    // cache up to date.
+  } else {
+    _contentCache = content;
+    _contentCacheString = utf8.decode(content);
+  }
+  return _contentCacheString.substring(from, to);
+}
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt
new file mode 100644
index 0000000..a6784da
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt
@@ -0,0 +1,21 @@
+class Foo extends Bar implements Baz {
+  Foo() {
+    // Constructor
+  }
+
+  factory Foo.factory() => Foo();
+
+  void method() {
+    // instance method.
+  }
+
+  static void staticMethod() {
+    // static method.
+  }
+
+  int field1, field2 = 42;
+}
+
+class Foo2 with Bar2 {
+  // empty
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt
new file mode 100644
index 0000000..031ace0
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt
@@ -0,0 +1,15 @@
+mixin B {
+  static int staticField = 0;
+  void foo() {
+    // empty
+  }
+
+  // Mixins cannot have constructors (or members with same name as mixin).
+  factory B() {
+    // empty
+  }
+
+  B.foo() {
+    // empty
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt
new file mode 100644
index 0000000..8e731aa
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt
@@ -0,0 +1 @@
+#!/usr/bin/env dart -c
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt
new file mode 100644
index 0000000..3cd024b
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt
@@ -0,0 +1,53 @@
+// Top level comment of sorts. With utf8 stuff → in it so offsets aren't byte
+// offset!
+
+library top_level_stuff;
+
+import "top_level_stuff_helper.dart";
+export "top_level_stuff_helper.dart";
+import "top_level_stuff_helper.dart" show a, b, c hide d, e, f show foo;
+export "top_level_stuff_helper.dart" show a, b, c hide d, e, f show foo;
+
+part 'top_level_stuff_helper.dart';
+
+@metadataOneOnThisOne("bla")
+@metadataTwoOnThisOne
+void toplevelMethod() {
+  // no content
+}
+
+List<E> anotherTopLevelMethod<E>() {
+  return null;
+}
+
+enum FooEnum { A, B, Bla }
+
+class FooClass {
+  // no content.
+}
+
+mixin FooMixin {
+  // no content.
+}
+
+class A<T> {
+  // no content.
+}
+
+typedef B = Function();
+
+mixin C<T> on A<T> {
+  // no content.
+}
+
+extension D<T> on A<T> {
+  // no content.
+}
+
+class E = A with FooClass;
+
+int field1;
+int field2, field3;
+int field4 = 42;
+
+@AnnotationAtEOF
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt
new file mode 100644
index 0000000..b2c46c8
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt
@@ -0,0 +1 @@
+part of 'top_level_stuff.txt';
\ No newline at end of file
diff --git a/pkg/front_end/test/flutter_gallery_leak_tester.dart b/pkg/front_end/test/flutter_gallery_leak_tester.dart
index 033b59a..fa3a949 100644
--- a/pkg/front_end/test/flutter_gallery_leak_tester.dart
+++ b/pkg/front_end/test/flutter_gallery_leak_tester.dart
@@ -151,7 +151,7 @@
     throw "Didn't find $galleryDotPackages";
   }
 
-  List<helper.Interest> interests = new List<helper.Interest>();
+  List<helper.Interest> interests = <helper.Interest>[];
   interests.add(new helper.Interest(
       Uri.parse("package:kernel/ast.dart"), "Library", ["fileUri"]));
   helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper =
@@ -179,7 +179,6 @@
     "--incremental",
     "--target=flutter",
     "--debugger-module-names",
-    "-Ddart.developer.causal_async_stacks=true",
     "--output-dill",
     "$rootPath/flutter_server_tmp.dill",
     "--packages",
diff --git a/pkg/front_end/test/incremental_compiler_leak_test.dart b/pkg/front_end/test/incremental_compiler_leak_test.dart
index 7d3fcd7..9cefae5 100644
--- a/pkg/front_end/test/incremental_compiler_leak_test.dart
+++ b/pkg/front_end/test/incremental_compiler_leak_test.dart
@@ -143,8 +143,7 @@
           }
           List<int> listOfInstanceCounts = instanceCounts[member.classRef];
           if (listOfInstanceCounts == null) {
-            listOfInstanceCounts =
-                instanceCounts[member.classRef] = new List<int>();
+            listOfInstanceCounts = instanceCounts[member.classRef] = <int>[];
           }
           while (listOfInstanceCounts.length < iterationNumber - 2) {
             listOfInstanceCounts.add(0);
diff --git a/pkg/front_end/test/incremental_dart2js_tester.dart b/pkg/front_end/test/incremental_dart2js_tester.dart
index 59c95ee..05b5538 100644
--- a/pkg/front_end/test/incremental_dart2js_tester.dart
+++ b/pkg/front_end/test/incremental_dart2js_tester.dart
@@ -51,7 +51,7 @@
   Map<Uri, List<int>> libToData;
   List<Uri> uris;
 
-  List<Uri> diffs = new List<Uri>();
+  List<Uri> diffs = <Uri>[];
   Set<Uri> componentUris = new Set<Uri>();
 
   Dart2jsTester(this.useExperimentalInvalidation, this.fast,
@@ -63,7 +63,7 @@
       debugger();
     }
 
-    diffs = new List<Uri>();
+    diffs = <Uri>[];
     componentUris = new Set<Uri>();
 
     Stopwatch localStopwatch = new Stopwatch()..start();
diff --git a/pkg/front_end/test/incremental_flutter_tester.dart b/pkg/front_end/test/incremental_flutter_tester.dart
index ac3be91..4d2aa12 100644
--- a/pkg/front_end/test/incremental_flutter_tester.dart
+++ b/pkg/front_end/test/incremental_flutter_tester.dart
@@ -122,7 +122,7 @@
 
   c = null;
 
-  List<Uri> diffs = new List<Uri>();
+  List<Uri> diffs = <Uri>[];
   Set<Uri> componentUris = new Set<Uri>();
 
   Stopwatch localStopwatch = new Stopwatch()..start();
diff --git a/pkg/front_end/test/incremental_load_from_dill_suite.dart b/pkg/front_end/test/incremental_load_from_dill_suite.dart
index a6237db..3a00d7e 100644
--- a/pkg/front_end/test/incremental_load_from_dill_suite.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_suite.dart
@@ -68,7 +68,7 @@
         Version;
 
 import 'package:kernel/target/targets.dart'
-    show NoneTarget, Target, TargetFlags;
+    show NoneTarget, LateLowering, Target, TargetFlags;
 
 import 'package:kernel/text/ast_to_text.dart' show Printer, componentToString;
 
@@ -316,7 +316,7 @@
   Map<String, List<int>> moduleResult = new Map<String, List<int>>();
 
   for (String moduleName in module.keys) {
-    List<Uri> moduleSources = new List<Uri>();
+    List<Uri> moduleSources = <Uri>[];
     Uri packagesUri;
     for (String filename in module[moduleName].keys) {
       Uri uri = base.resolve(filename);
@@ -343,7 +343,7 @@
         new TestIncrementalCompiler(options, moduleSources.first, null);
     Component c = await compiler.computeDelta(entryPoints: moduleSources);
     c.computeCanonicalNames();
-    List<Library> wantedLibs = new List<Library>();
+    List<Library> wantedLibs = <Library>[];
     for (Library lib in c.libraries) {
       if (moduleSources.contains(lib.importUri) ||
           moduleSources.contains(lib.fileUri)) {
@@ -392,7 +392,8 @@
     final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
 
     TargetFlags targetFlags = new TargetFlags(
-        forceLateLoweringForTesting: forceLateLoweringForTesting,
+        forceLateLoweringsForTesting:
+            forceLateLoweringForTesting ? LateLowering.all : LateLowering.none,
         trackWidgetCreation: trackWidgetCreation);
     Target target = new VmTarget(targetFlags);
     String sdkSummary = "vm_platform_strong.dill";
@@ -450,7 +451,7 @@
           c.adoptChildren();
         }
 
-        modulesToUse = new List<Component>();
+        modulesToUse = <Component>[];
         for (String moduleName in world["modules"]) {
           Component moduleComponent = moduleComponents[moduleName];
           if (moduleComponent != null) {
@@ -593,7 +594,7 @@
       if (world["entry"] is String) {
         entries = [base.resolve(world["entry"])];
       } else {
-        entries = new List<Uri>();
+        entries = <Uri>[];
         List<dynamic> entryList = world["entry"];
         for (String entry in entryList) {
           entries.add(base.resolve(entry));
@@ -623,7 +624,7 @@
         }
       }
 
-      List<Uri> invalidated = new List<Uri>();
+      List<Uri> invalidated = <Uri>[];
       if (world["invalidate"] != null) {
         for (String filename in world["invalidate"]) {
           Uri uri = base.resolve(filename);
@@ -1534,13 +1535,13 @@
 Result<TestData> checkNeededDillLibraries(
     YamlMap world, TestData data, Set<Library> neededDillLibraries, Uri base) {
   if (world["neededDillLibraries"] != null) {
-    List<Uri> actualContent = new List<Uri>();
+    List<Uri> actualContent = <Uri>[];
     for (Library lib in neededDillLibraries) {
       if (lib.importUri.scheme == "dart") continue;
       actualContent.add(lib.importUri);
     }
 
-    List<Uri> expectedContent = new List<Uri>();
+    List<Uri> expectedContent = <Uri>[];
     for (String entry in world["neededDillLibraries"]) {
       expectedContent.add(base.resolve(entry));
     }
@@ -1579,7 +1580,7 @@
 
 String componentToStringSdkFiltered(Component component) {
   Component c = new Component();
-  List<Uri> dartUris = new List<Uri>();
+  List<Uri> dartUris = <Uri>[];
   for (Library lib in component.libraries) {
     if (lib.importUri.scheme == "dart") {
       dartUris.add(lib.importUri);
diff --git a/pkg/front_end/test/lint_suite.dart b/pkg/front_end/test/lint_suite.dart
index 938c1bf..8547196 100644
--- a/pkg/front_end/test/lint_suite.dart
+++ b/pkg/front_end/test/lint_suite.dart
@@ -194,7 +194,7 @@
 }
 
 class LintListener extends Listener {
-  List<String> problems = new List<String>();
+  List<String> problems = <String>[];
   LintTestDescription description;
   Uri uri;
 
@@ -204,7 +204,7 @@
 }
 
 class ExplicitTypeLintListener extends LintListener {
-  List<LatestType> _latestTypes = new List<LatestType>();
+  List<LatestType> _latestTypes = <LatestType>[];
 
   @override
   void beginVariablesDeclaration(
diff --git a/pkg/front_end/test/lint_test.status b/pkg/front_end/test/lint_test.status
index 10f7b68..2728954 100644
--- a/pkg/front_end/test/lint_test.status
+++ b/pkg/front_end/test/lint_test.status
@@ -39,3 +39,8 @@
 front_end/lib/src/fasta/type_inference/type_constraint_gatherer/ImportsTwice: Fail
 front_end/lib/src/fasta/type_inference/type_inferrer/ImportsTwice: Fail
 front_end/lib/src/testing/id_testing_helper/Exports: Fail
+kernel/lib/ast/ImportsTwice: Fail
+kernel/lib/ast/Exports: Fail
+kernel/lib/kernel/Exports: Fail
+kernel/lib/testing/type_parser_environment/ImportsTwice: Fail
+kernel/lib/text/ast_to_text/ImportsTwice: Fail
diff --git a/pkg/front_end/test/parser_suite.dart b/pkg/front_end/test/parser_suite.dart
index da464ac..8ef6ae8 100644
--- a/pkg/front_end/test/parser_suite.dart
+++ b/pkg/front_end/test/parser_suite.dart
@@ -171,7 +171,7 @@
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) {
-    List<int> lineStarts = new List<int>();
+    List<int> lineStarts = <int>[];
 
     Token firstToken =
         scanUri(description.uri, description.shortName, lineStarts: lineStarts);
@@ -215,7 +215,7 @@
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) {
-    List<int> lineStarts = new List<int>();
+    List<int> lineStarts = <int>[];
     Token firstToken =
         scanUri(description.uri, description.shortName, lineStarts: lineStarts);
 
@@ -251,7 +251,7 @@
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) {
-    List<int> lineStarts = new List<int>();
+    List<int> lineStarts = <int>[];
     Token firstToken =
         scanUri(description.uri, description.shortName, lineStarts: lineStarts);
 
@@ -412,7 +412,7 @@
   final bool annotateLines;
   final Source source;
   final String shortName;
-  final List<String> errors = new List<String>();
+  final List<String> errors = <String>[];
   Location latestSeenLocation;
 
   ParserTestListenerWithMessageFormatting(
diff --git a/pkg/front_end/test/predicates/data/extension.dart b/pkg/front_end/test/predicates/data/extension.dart
new file mode 100644
index 0000000..ac1dd00
--- /dev/null
+++ b/pkg/front_end/test/predicates/data/extension.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension Extension on int {
+  int /*extensionThis*/ instanceMethod() => this;
+
+  int get /*extensionThis*/ instanceGetter => this;
+
+  void set /*extensionThis*/ instanceSetter(int value) {}
+
+  static int staticMethod() => 42;
+
+  static int get staticGetter => 42;
+
+  static void set staticSetter(int value) {}
+}
diff --git a/pkg/front_end/test/predicates/data/late.dart b/pkg/front_end/test/predicates/data/late.dart
index 3218974..55cfbb6 100644
--- a/pkg/front_end/test/predicates/data/late.dart
+++ b/pkg/front_end/test/predicates/data/late.dart
@@ -120,3 +120,66 @@
   /*member: Class.finalStaticNullableWithInitializer:lateFieldGetter*/
   static late final int? finalStaticNullableWithInitializer = 0;
 }
+
+method() {
+  late int
+      /*
+   lateIsSetLocal,
+   lateLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNonNullableWithoutInitializer;
+  late final int
+      /*
+       lateIsSetLocal,
+       lateLocal,
+       lateLocalGetter,
+       lateLocalSetter
+      */
+      finalLocalNonNullableWithoutInitializer;
+  late int?
+      /*
+   lateIsSetLocal,
+   lateLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNullableWithoutInitializer;
+  late final int?
+      /*
+       lateIsSetLocal,
+       lateLocal,
+       lateLocalGetter,
+       lateLocalSetter
+      */
+      finalLocalNullableWithoutInitializer;
+  late int
+      /*
+   lateIsSetLocal,
+   lateLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNonNullableWithInitializer = 0;
+  late final int /*
+   lateIsSetLocal,
+   lateLocal,
+   lateLocalGetter
+  */
+      finalLocalNonNullableWithInitializer = 0;
+  late int?
+      /*
+   lateIsSetLocal,
+   lateLocal,
+   lateLocalGetter,
+   lateLocalSetter
+  */
+      localNullableWithInitializer = 0;
+  late final int? /*
+   lateIsSetLocal,
+   lateLocal,
+   lateLocalGetter
+  */
+      finalLocalNullableWithInitializer = 0;
+}
diff --git a/pkg/front_end/test/predicates/predicate_test.dart b/pkg/front_end/test/predicates/predicate_test.dart
index 89ddb9f..f62f803 100644
--- a/pkg/front_end/test/predicates/predicate_test.dart
+++ b/pkg/front_end/test/predicates/predicate_test.dart
@@ -9,6 +9,7 @@
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:_fe_analyzer_shared/src/testing/features.dart';
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/testing/id_extractor.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/api_prototype/lowering_predicates.dart';
 import 'package:kernel/ast.dart';
@@ -25,7 +26,8 @@
             explicitExperimentalFlags: const {
               ExperimentalFlag.nonNullable: true
             },
-            targetFlags: const TargetFlags(forceLateLoweringForTesting: true))
+            targetFlags: const TargetFlags(
+                forceLateLoweringsForTesting: LateLowering.all))
       ]));
 }
 
@@ -39,6 +41,8 @@
   static const String lateIsSetLocal = 'lateIsSetLocal';
   static const String lateLocalGetter = 'lateLocalGetter';
   static const String lateLocalSetter = 'lateLocalSetter';
+
+  static const String extensionThis = 'extensionThis';
 }
 
 class PredicateDataComputer extends DataComputer<Features> {
@@ -73,6 +77,9 @@
 }
 
 class PredicateDataExtractor extends CfeDataExtractor<Features> {
+  Map<String, Features> featureMap = {};
+  Map<String, NodeId> nodeIdMap = {};
+
   PredicateDataExtractor(InternalCompilerResult compilerResult,
       Map<Id, ActualData<Features>> actualMap)
       : super(compilerResult, actualMap);
@@ -106,4 +113,63 @@
     }
     return null;
   }
+
+  void visitProcedure(Procedure node) {
+    super.visitProcedure(node);
+    nodeIdMap.forEach((String name, NodeId id) {
+      Features features = featureMap[name];
+      if (features != null) {
+        TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+        registerValue(
+            nodeWithOffset.location.file, id.value, id, features, name);
+      }
+    });
+    nodeIdMap.clear();
+    featureMap.clear();
+  }
+
+  void visitVariableDeclaration(VariableDeclaration node) {
+    String name;
+    String tag;
+    if (isLateLoweredLocal(node)) {
+      name = extractLocalNameFromLateLoweredLocal(node.name);
+      tag = Tags.lateLocal;
+    } else if (isLateLoweredIsSetLocal(node)) {
+      name = extractLocalNameFromLateLoweredIsSet(node.name);
+      tag = Tags.lateIsSetLocal;
+    } else if (isLateLoweredLocalGetter(node)) {
+      name = extractLocalNameFromLateLoweredGetter(node.name);
+      tag = Tags.lateLocalGetter;
+    } else if (isLateLoweredLocalSetter(node)) {
+      name = extractLocalNameFromLateLoweredSetter(node.name);
+      tag = Tags.lateLocalSetter;
+    } else if (isExtensionThis(node)) {
+      name = extractLocalNameForExtensionThis(node.name);
+      tag = Tags.extensionThis;
+    } else if (node.name != null) {
+      name = node.name;
+    }
+    if (name != null) {
+      if (node.fileOffset != TreeNode.noOffset) {
+        nodeIdMap[name] ??= new NodeId(node.fileOffset, IdKind.node);
+      }
+      if (tag != null) {
+        Features features = featureMap[name] ??= new Features();
+        features.add(tag);
+      }
+    }
+    super.visitVariableDeclaration(node);
+  }
+
+  @override
+  ActualData<Features> mergeData(
+      ActualData<Features> value1, ActualData<Features> value2) {
+    if ('${value1.value}' == '${value2.value}') {
+      // The extension this parameter is seen twice in the extension method
+      // and the corresponding tearoff. The features are identical, though, so
+      // we just use the first.
+      return value1;
+    }
+    return null;
+  }
 }
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index ea17792..08f0bc6 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -8,11 +8,8 @@
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
     as usedForFuzzTesting;
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
-import 'package:_fe_analyzer_shared/src/scanner/string_scanner.dart' as fasta;
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' as fasta;
 import 'package:_fe_analyzer_shared/src/scanner/token_constants.dart' as fasta;
-import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
-    as fasta;
 import 'package:_fe_analyzer_shared/src/scanner/errors.dart';
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:front_end/src/fasta/fasta_codes.dart';
diff --git a/pkg/front_end/test/spell_checking_cleanup_lists.dart b/pkg/front_end/test/spell_checking_cleanup_lists.dart
index 3cca7cb..af7d5bd 100644
--- a/pkg/front_end/test/spell_checking_cleanup_lists.dart
+++ b/pkg/front_end/test/spell_checking_cleanup_lists.dart
@@ -14,7 +14,7 @@
     for (spell.Dictionaries dictionary in spell.Dictionaries.values) {
       if (dictionary == spell.Dictionaries.common) continue;
       Uri uri = spell.dictionaryToUri(dictionary);
-      List<String> keep = new List<String>();
+      List<String> keep = <String>[];
       for (String line in new File.fromUri(uri).readAsLinesSync()) {
         if (!commonWords.contains(line)) {
           keep.add(line);
@@ -30,7 +30,7 @@
     Set<String> codeWords =
         spell.loadedDictionaries[spell.Dictionaries.cfeCode];
     Uri uri = spell.dictionaryToUri(spell.Dictionaries.cfeTests);
-    List<String> keep = new List<String>();
+    List<String> keep = <String>[];
     for (String line in new File.fromUri(uri).readAsLinesSync()) {
       if (!codeWords.contains(line)) {
         keep.add(line);
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 5fd534d..6c4e50f 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -113,6 +113,7 @@
 bit2
 bj
 bk
+blindly
 blob
 blocking
 bmp
@@ -244,6 +245,7 @@
 cosmetic
 counters
 covariances
+coverage
 cr
 creator
 criterion
@@ -546,6 +548,7 @@
 inst
 instanceof
 instantiator
+integrate
 intentionally
 interim
 interior
@@ -830,6 +833,7 @@
 pragma
 pre
 prebuilt
+preexisted
 preexisting
 preorder
 prev
@@ -1062,6 +1066,7 @@
 stdout
 sticky
 stmt
+stopped
 str
 strategies
 streak
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 5255e56..7806bde 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1784,6 +1784,7 @@
 maintains
 major
 make
+makers
 makes
 making
 malformed
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index d50f907..49cac17 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -25,6 +25,7 @@
 amortized
 analyses
 animal
+annoying
 anon
 aoo
 approval
@@ -55,6 +56,7 @@
 besides
 beta
 bigger
+bitmask
 bkonyi
 bla
 blah
@@ -125,6 +127,7 @@
 compiler's
 complement
 completers
+complicated
 confidence
 confident
 confirm
@@ -221,6 +224,7 @@
 edits
 elapse
 ell
+enm
 entrypoint
 entrypoints
 eoo
@@ -290,6 +294,7 @@
 forty
 foundation
 fox
+frozen
 fulfill
 func
 futures
@@ -319,6 +324,7 @@
 hits
 home
 hoo
+hook
 hosted
 hosting
 hot
@@ -342,6 +348,8 @@
 increments
 indents
 initializer2
+inlinable
+inlineable
 instance2
 insufficient
 intdiv
@@ -368,6 +376,7 @@
 invocation7d
 invocation7e
 ioo
+ish
 isolate
 isolates
 issue41210b
@@ -399,6 +408,7 @@
 lints
 linux
 listening
+listing
 literal2
 ln
 local1a
@@ -441,6 +451,8 @@
 mf
 micro
 minimize
+minimizer
+minimizing
 mintty
 minutes
 mismatched
@@ -456,12 +468,15 @@
 moo
 mul
 mx
+mxn
 mysdk
+naively
 naturally
 negatable
 newworld
 nil
 ninja
+noisy
 nondefault
 nonexisting
 noo
@@ -481,6 +496,7 @@
 out1
 out2
 outbound
+outlined
 overlay
 ox
 pack
@@ -545,10 +561,12 @@
 recompiles
 redir
 redirections
+rediscover
 reducer
 referring
 reflectee
 refusing
+regards
 regenerate
 regressions
 reify
@@ -558,6 +576,8 @@
 rendition
 repaint
 repro
+reproduce
+reproduction
 response
 result1
 result2
@@ -566,6 +586,7 @@
 retainingpath
 retains
 rev
+revealed
 risky
 rk
 row
@@ -656,11 +677,13 @@
 test3b
 theoretically
 thereof
+thread
 timed
 timeout
 timer
 timings
 tinv
+told
 tpt
 transitively
 translators
@@ -683,6 +706,8 @@
 unawaited
 unbreak
 unconverted
+uncover
+uncovers
 underline
 unpacked
 unpatched
@@ -694,6 +719,7 @@
 unversioned
 upload
 upward
+usages
 uses8
 uuid
 v1
diff --git a/pkg/front_end/test/spell_checking_utils.dart b/pkg/front_end/test/spell_checking_utils.dart
index 948ea88..b0f33a3 100644
--- a/pkg/front_end/test/spell_checking_utils.dart
+++ b/pkg/front_end/test/spell_checking_utils.dart
@@ -28,7 +28,7 @@
   List<List<String>> wrongWordsAlternatives;
   List<int> wrongWordsOffset;
   List<bool> wrongWordDenylisted;
-  List<int> wordOffsets = new List<int>();
+  List<int> wordOffsets = <int>[];
   List<String> words =
       splitStringIntoWords(s, wordOffsets, splitAsCode: splitAsCode);
   List<Set<String>> dictionariesUnpacked = [];
@@ -51,13 +51,13 @@
       }
     }
     if (!found) {
-      wrongWords ??= new List<String>();
+      wrongWords ??= <String>[];
       wrongWords.add(word);
-      wrongWordsAlternatives ??= new List<List<String>>();
+      wrongWordsAlternatives ??= <List<String>>[];
       wrongWordsAlternatives.add(findAlternatives(word, dictionariesUnpacked));
-      wrongWordsOffset ??= new List<int>();
+      wrongWordsOffset ??= <int>[];
       wrongWordsOffset.add(offset);
-      wrongWordDenylisted ??= new List<bool>();
+      wrongWordDenylisted ??= <bool>[];
       wrongWordDenylisted
           .add(loadedDictionaries[Dictionaries.denylist].contains(word));
     }
@@ -79,7 +79,7 @@
   }
 
   void ok(String w) {
-    result ??= new List<String>();
+    result ??= <String>[];
     result.add(w);
   }
 
@@ -185,7 +185,7 @@
 
 List<String> splitStringIntoWords(String s, List<int> splitOffsets,
     {bool splitAsCode: false}) {
-  List<String> result = new List<String>();
+  List<String> result = <String>[];
   // Match whitespace and the characters "-", "=", "|", "/", ",".
   String regExpStringInner = r"\s-=\|\/,";
   if (splitAsCode) {
@@ -204,8 +204,8 @@
   Iterator<RegExpMatch> matchesIterator =
       new RegExp(regExp).allMatches(s).iterator;
   int latestMatch = 0;
-  List<String> split = new List<String>();
-  List<int> splitOffset = new List<int>();
+  List<String> split = <String>[];
+  List<int> splitOffset = <int>[];
   while (matchesIterator.moveNext()) {
     RegExpMatch match = matchesIterator.current;
     if (match.start > latestMatch) {
@@ -385,7 +385,7 @@
     }
 
     if (interactive && dictionaryToUse != null) {
-      List<String> addedWords = new List<String>();
+      List<String> addedWords = <String>[];
       for (String s in reportedWords) {
         print("- $s");
         String answer;
@@ -420,8 +420,8 @@
         File dictionaryFile =
             new File.fromUri(dictionaryToUri(dictionaryToUse));
         List<String> lines = dictionaryFile.readAsLinesSync();
-        List<String> header = new List<String>();
-        List<String> sortThis = new List<String>();
+        List<String> header = <String>[];
+        List<String> sortThis = <String>[];
         for (String line in lines) {
           if (line.startsWith("#")) {
             header.add(line);
@@ -433,7 +433,7 @@
         }
         sortThis.addAll(addedWords);
         sortThis.sort();
-        lines = new List<String>();
+        lines = <String>[];
         lines.addAll(header);
         if (header.isEmpty || header.last.isNotEmpty) {
           lines.add("");
diff --git a/pkg/front_end/test/spell_checking_utils_test.dart b/pkg/front_end/test/spell_checking_utils_test.dart
index 3b5616e..658c88e 100644
--- a/pkg/front_end/test/spell_checking_utils_test.dart
+++ b/pkg/front_end/test/spell_checking_utils_test.dart
@@ -89,7 +89,7 @@
 
 void expectSplit(String s, bool splitAsCode, List<String> expectedWords,
     List<int> expectedOffsets) {
-  List<int> actualOffsets = new List<int>();
+  List<int> actualOffsets = <int>[];
   List<String> actualWords =
       splitStringIntoWords(s, actualOffsets, splitAsCode: splitAsCode);
   compareLists(actualWords, expectedWords);
diff --git a/pkg/front_end/test/spelling_test_base.dart b/pkg/front_end/test/spelling_test_base.dart
index 23d64a5..bd0ea9f 100644
--- a/pkg/front_end/test/spelling_test_base.dart
+++ b/pkg/front_end/test/spelling_test_base.dart
@@ -102,7 +102,7 @@
         scanner.lineStarts, rawBytes, description.uri, description.uri);
     void addErrorMessage(
         int offset, String word, bool denylisted, List<String> alternatives) {
-      errors ??= new List<String>();
+      errors ??= <String>[];
       String message;
       if (denylisted) {
         message = "Misspelled word: '$word' has explicitly been denylisted.";
diff --git a/pkg/front_end/test/split_dill_test.dart b/pkg/front_end/test/split_dill_test.dart
index 55f52ba..0ed6a0f 100644
--- a/pkg/front_end/test/split_dill_test.dart
+++ b/pkg/front_end/test/split_dill_test.dart
@@ -33,7 +33,7 @@
   component.computeCanonicalNames();
 
   stopwatch.reset();
-  List<List<int>> libComponents = new List<List<int>>();
+  List<List<int>> libComponents = <List<int>>[];
   for (Library lib in component.libraries) {
     Component libComponent = new Component(nameRoot: component.root);
     libComponent.libraries.add(lib);
diff --git a/pkg/front_end/test/static_types/analysis_helper.dart b/pkg/front_end/test/static_types/analysis_helper.dart
new file mode 100644
index 0000000..f6c6981
--- /dev/null
+++ b/pkg/front_end/test/static_types/analysis_helper.dart
@@ -0,0 +1,342 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' as json;
+import 'dart:io';
+
+import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart';
+import 'package:expect/expect.dart';
+import 'package:front_end/src/api_prototype/front_end.dart';
+import 'package:front_end/src/api_prototype/kernel_generator.dart';
+import 'package:front_end/src/api_prototype/terminal_color_support.dart';
+import 'package:front_end/src/api_unstable/ddc.dart';
+import 'package:front_end/src/compute_platform_binaries_location.dart';
+import 'package:front_end/src/fasta/command_line_reporting.dart';
+import 'package:front_end/src/fasta/fasta_codes.dart';
+import 'package:front_end/src/fasta/kernel/redirecting_factory_body.dart';
+import 'package:front_end/src/kernel_generator_impl.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
+
+run(Uri entryPoint, String allowedListPath,
+    {bool verbose = false,
+    bool generate = false,
+    bool analyzedUrisFilter(Uri uri)}) async {
+  CompilerOptions options = new CompilerOptions();
+  options.sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
+
+  options.onDiagnostic = (DiagnosticMessage message) {
+    printDiagnosticMessage(message, print);
+  };
+  InternalCompilerResult compilerResult = await kernelForProgramInternal(
+      entryPoint, options,
+      retainDataForTesting: true, requireMain: false);
+
+  new DynamicVisitor(options.onDiagnostic, compilerResult.component,
+          allowedListPath, analyzedUrisFilter)
+      .run(verbose: verbose, generate: generate);
+}
+
+class StaticTypeVisitorBase extends RecursiveVisitor<void> {
+  final TypeEnvironment typeEnvironment;
+
+  StaticTypeContext staticTypeContext;
+
+  StaticTypeVisitorBase(Component component, ClassHierarchy classHierarchy)
+      : typeEnvironment =
+            new TypeEnvironment(new CoreTypes(component), classHierarchy);
+
+  @override
+  void visitProcedure(Procedure node) {
+    if (node.kind == ProcedureKind.Factory && isRedirectingFactory(node)) {
+      // Don't visit redirecting factories.
+      return;
+    }
+    staticTypeContext = new StaticTypeContext(node, typeEnvironment);
+    super.visitProcedure(node);
+    staticTypeContext = null;
+  }
+
+  @override
+  void visitField(Field node) {
+    if (isRedirectingFactoryField(node)) {
+      // Skip synthetic .dill members.
+      return;
+    }
+    staticTypeContext = new StaticTypeContext(node, typeEnvironment);
+    super.visitField(node);
+    staticTypeContext = null;
+  }
+
+  @override
+  void visitConstructor(Constructor node) {
+    staticTypeContext = new StaticTypeContext(node, typeEnvironment);
+    super.visitConstructor(node);
+    staticTypeContext = null;
+  }
+}
+
+class DynamicVisitor extends StaticTypeVisitorBase {
+  // TODO(johnniwinther): Enable this when it is less noisy.
+  static const bool checkReturnTypes = false;
+
+  final DiagnosticMessageHandler onDiagnostic;
+  final Component component;
+  final String _allowedListPath;
+  final bool Function(Uri uri) analyzedUrisFilter;
+
+  Map _expectedJson = {};
+  Map<String, Map<String, List<FormattedMessage>>> _actualMessages = {};
+
+  DynamicVisitor(this.onDiagnostic, this.component, this._allowedListPath,
+      this.analyzedUrisFilter)
+      : super(
+            component, new ClassHierarchy(component, new CoreTypes(component)));
+
+  void run({bool verbose = false, bool generate = false}) {
+    if (!generate && _allowedListPath != null) {
+      File file = new File(_allowedListPath);
+      if (file.existsSync()) {
+        try {
+          _expectedJson = json.jsonDecode(file.readAsStringSync());
+        } catch (e) {
+          Expect.fail('Error reading allowed list from $_allowedListPath: $e');
+        }
+      }
+    }
+    component.accept(this);
+    if (generate && _allowedListPath != null) {
+      Map<String, Map<String, int>> actualJson = {};
+      _actualMessages.forEach(
+          (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
+        Map<String, int> map = {};
+        actualMessagesMap
+            .forEach((String message, List<FormattedMessage> actualMessages) {
+          map[message] = actualMessages.length;
+        });
+        actualJson[uri] = map;
+      });
+
+      new File(_allowedListPath).writeAsStringSync(
+          new json.JsonEncoder.withIndent('  ').convert(actualJson));
+      return;
+    }
+
+    int errorCount = 0;
+    _expectedJson.forEach((uri, expectedMessages) {
+      Map<String, List<FormattedMessage>> actualMessagesMap =
+          _actualMessages[uri];
+      if (actualMessagesMap == null) {
+        print("Error: Allowed-listing of uri '$uri' isn't used. "
+            "Remove it from the allowed-list.");
+        errorCount++;
+      } else {
+        expectedMessages.forEach((expectedMessage, expectedCount) {
+          List<FormattedMessage> actualMessages =
+              actualMessagesMap[expectedMessage];
+          if (actualMessages == null) {
+            print("Error: Allowed-listing of message '$expectedMessage' "
+                "in uri '$uri' isn't used. Remove it from the allowed-list.");
+            errorCount++;
+          } else {
+            int actualCount = actualMessages.length;
+            if (actualCount != expectedCount) {
+              print("Error: Unexpected count of allowed message "
+                  "'$expectedMessage' in uri '$uri'. "
+                  "Expected $expectedCount, actual $actualCount:");
+              print(
+                  '----------------------------------------------------------');
+              for (FormattedMessage message in actualMessages) {
+                onDiagnostic(message);
+              }
+              print(
+                  '----------------------------------------------------------');
+              errorCount++;
+            }
+          }
+        });
+        actualMessagesMap
+            .forEach((String message, List<FormattedMessage> actualMessages) {
+          if (!expectedMessages.containsKey(message)) {
+            for (FormattedMessage message in actualMessages) {
+              onDiagnostic(message);
+              errorCount++;
+            }
+          }
+        });
+      }
+    });
+    _actualMessages.forEach(
+        (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
+      if (!_expectedJson.containsKey(uri)) {
+        actualMessagesMap
+            .forEach((String message, List<FormattedMessage> actualMessages) {
+          for (FormattedMessage message in actualMessages) {
+            onDiagnostic(message);
+            errorCount++;
+          }
+        });
+      }
+    });
+    if (errorCount != 0) {
+      print('$errorCount error(s) found.');
+      print("""
+
+********************************************************************************
+*  Unexpected dynamic invocations found by test:
+*
+*    ${relativizeUri(Platform.script)}
+*
+*  Please address the reported errors, or, if the errors are as expected, run
+*
+*    dart ${relativizeUri(Platform.script)} -g
+*
+*  to update the expectation file.
+********************************************************************************
+""");
+      exit(-1);
+    }
+    if (verbose) {
+      _actualMessages.forEach(
+          (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
+        actualMessagesMap
+            .forEach((String message, List<FormattedMessage> actualMessages) {
+          for (FormattedMessage message in actualMessages) {
+            // TODO(johnniwinther): It is unnecessarily complicated to just
+            // add ' (allowed)' to an existing message!
+            LocatedMessage locatedMessage = message.locatedMessage;
+            String newMessageText =
+                '${locatedMessage.messageObject.message} (allowed)';
+            message = locatedMessage.withFormatting(
+                format(
+                    new LocatedMessage(
+                        locatedMessage.uri,
+                        locatedMessage.charOffset,
+                        locatedMessage.length,
+                        new Message(locatedMessage.messageObject.code,
+                            message: newMessageText,
+                            tip: locatedMessage.messageObject.tip,
+                            arguments: locatedMessage.messageObject.arguments)),
+                    Severity.warning,
+                    location:
+                        new Location(message.uri, message.line, message.column),
+                    uriToSource: component.uriToSource),
+                message.line,
+                message.column,
+                Severity.warning,
+                []);
+            onDiagnostic(message);
+          }
+        });
+      });
+    } else {
+      int total = 0;
+      _actualMessages.forEach(
+          (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
+        int count = 0;
+        actualMessagesMap
+            .forEach((String message, List<FormattedMessage> actualMessages) {
+          count += actualMessages.length;
+        });
+
+        print('${count} error(s) allowed in $uri');
+        total += count;
+      });
+      if (total > 0) {
+        print('${total} error(s) allowed in total.');
+      }
+    }
+  }
+
+  @override
+  void visitLibrary(Library node) {
+    if (analyzedUrisFilter != null) {
+      if (analyzedUrisFilter(node.importUri)) {
+        super.visitLibrary(node);
+      }
+    } else {
+      super.visitLibrary(node);
+    }
+  }
+
+  @override
+  void visitPropertyGet(PropertyGet node) {
+    DartType receiverType = node.receiver.getStaticType(staticTypeContext);
+    if (receiverType is DynamicType && node.interfaceTarget == null) {
+      registerError(node, "Dynamic access of '${node.name}'.");
+    }
+    super.visitPropertyGet(node);
+  }
+
+  @override
+  void visitPropertySet(PropertySet node) {
+    DartType receiverType = node.receiver.getStaticType(staticTypeContext);
+    if (receiverType is DynamicType) {
+      registerError(node, "Dynamic update to '${node.name}'.");
+    }
+    super.visitPropertySet(node);
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    DartType receiverType = node.receiver.getStaticType(staticTypeContext);
+    if (receiverType is DynamicType && node.interfaceTarget == null) {
+      registerError(node, "Dynamic invocation of '${node.name}'.");
+    }
+    super.visitMethodInvocation(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    if (checkReturnTypes && node.function.returnType is DynamicType) {
+      registerError(node, "Dynamic return type");
+    }
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    if (checkReturnTypes && node.function.returnType is DynamicType) {
+      registerError(node, "Dynamic return type");
+    }
+    super.visitFunctionExpression(node);
+  }
+
+  @override
+  void visitProcedure(Procedure node) {
+    if (checkReturnTypes &&
+        node.function.returnType is DynamicType &&
+        node.name.text != 'noSuchMethod') {
+      registerError(node, "Dynamic return type on $node");
+    }
+    super.visitProcedure(node);
+  }
+
+  void registerError(TreeNode node, String message) {
+    Location location = node.location;
+    Uri uri = location.file;
+    String uriString = relativizeUri(uri);
+    Map<String, List<FormattedMessage>> actualMap = _actualMessages.putIfAbsent(
+        uriString, () => <String, List<FormattedMessage>>{});
+    if (uri.scheme == 'org-dartlang-sdk') {
+      location = new Location(Uri.base.resolve(uri.path.substring(1)),
+          location.line, location.column);
+    }
+    LocatedMessage locatedMessage = templateUnspecified
+        .withArguments(message)
+        .withLocation(uri, node.fileOffset, noLength);
+    FormattedMessage diagnosticMessage = locatedMessage.withFormatting(
+        format(locatedMessage, Severity.warning,
+            location: location, uriToSource: component.uriToSource),
+        location.line,
+        location.column,
+        Severity.warning,
+        []);
+    actualMap
+        .putIfAbsent(message, () => <FormattedMessage>[])
+        .add(diagnosticMessage);
+  }
+}
diff --git a/pkg/front_end/test/static_types/cfe_allowed.json b/pkg/front_end/test/static_types/cfe_allowed.json
new file mode 100644
index 0000000..9dd0b5b
--- /dev/null
+++ b/pkg/front_end/test/static_types/cfe_allowed.json
@@ -0,0 +1,52 @@
+{
+  "pkg/front_end/lib/src/api_prototype/terminal_color_support.dart": {
+    "Dynamic invocation of 'split'.": 1
+  },
+  "pkg/front_end/lib/src/base/libraries_specification.dart": {
+    "Dynamic invocation of 'containsKey'.": 1,
+    "Dynamic invocation of '[]'.": 8,
+    "Dynamic invocation of 'forEach'.": 1,
+    "Dynamic invocation of 'toList'.": 1,
+    "Dynamic invocation of 'map'.": 1,
+    "Dynamic invocation of '[]='.": 1
+  },
+  "pkg/_fe_analyzer_shared/lib/src/util/colors.dart": {
+    "Dynamic access of 'supportsAnsiEscapes'.": 1,
+    "Dynamic invocation of 'split'.": 1
+  },
+  "pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart": {
+    "Dynamic access of 'data'.": 1,
+    "Dynamic access of 'start'.": 1,
+    "Dynamic access of 'length'.": 1,
+    "Dynamic access of 'boolValue'.": 2
+  },
+  "pkg/kernel/lib/transformations/value_class.dart": {
+    "Dynamic access of 'text'.": 2,
+    "Dynamic access of 'name'.": 2,
+    "Dynamic access of 'type'.": 1
+  },
+  "pkg/front_end/lib/src/fasta/crash.dart": {
+    "Dynamic access of 'trace'.": 1,
+    "Dynamic access of 'uri'.": 1,
+    "Dynamic access of 'charOffset'.": 1,
+    "Dynamic access of 'error'.": 1
+  },
+  "pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart": {
+    "Dynamic access of 'fileUri'.": 1
+  },
+  "pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart": {
+    "Dynamic invocation of '[]'.": 2
+  },
+  "pkg/front_end/lib/src/fasta/kernel/body_builder.dart": {
+    "Dynamic invocation of 'buildForEffect'.": 1
+  },
+  "pkg/_fe_analyzer_shared/lib/src/util/link.dart": {
+    "Dynamic access of 'isEmpty'.": 1
+  },
+  "pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart": {
+    "Dynamic access of 'isNotEmpty'.": 1,
+    "Dynamic access of 'head'.": 1,
+    "Dynamic access of 'tail'.": 1,
+    "Dynamic access of 'isEmpty'.": 1
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/static_types/cfe_dynamic_test.dart b/pkg/front_end/test/static_types/cfe_dynamic_test.dart
new file mode 100644
index 0000000..306dc85
--- /dev/null
+++ b/pkg/front_end/test/static_types/cfe_dynamic_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'analysis_helper.dart';
+
+/// Filter function used to only analysis cfe source code.
+bool cfeOnly(Uri uri) {
+  String text = '$uri';
+  for (String path in [
+    'package:_fe_analyzer_shared/',
+    'package:kernel/',
+    'package:front_end/',
+  ]) {
+    if (text.startsWith(path)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+main(List<String> args) async {
+  await run(Uri.base.resolve('pkg/front_end/tool/_fasta/compile.dart'),
+      'pkg/front_end/test/static_types/cfe_allowed.json',
+      analyzedUrisFilter: cfeOnly,
+      verbose: args.contains('-v'),
+      generate: args.contains('-g'));
+}
diff --git a/pkg/front_end/test/static_types/data/null_aware_spread.dart b/pkg/front_end/test/static_types/data/null_aware_spread.dart
index 43cf405..0eec790 100644
--- a/pkg/front_end/test/static_types/data/null_aware_spread.dart
+++ b/pkg/front_end/test/static_types/data/null_aware_spread.dart
@@ -12,17 +12,13 @@
       /*cfe.List<String>*/
       /*cfe:nnbd.List<String!>!*/
       [
-    /*invoke: void*/
     /*cfe.String*/
     /*cfe:nnbd.String!*/
     'foo',
-    /*invoke: void*/
-    /*cfe.current: String*/
-    /*cfe:nnbd.current: String!*/
     ...?
     /*cfe.List<String>*/
     /*cfe:nnbd.List<String!>!*/
-    list
+    /*invoke: void*/ list
   ];
 }
 
@@ -30,22 +26,16 @@
   /*cfe.update: Set<String>*/
   /*cfe:nnbd.update: Set<String!>!*/
   set =
-      /*cfe.invoke: LinkedHashSet<String>!*/
-      /*cfe:nnbd.invoke: LinkedHashSet<String!>!*/
-      /*cfe.<String>*/
-      /*cfe:nnbd.<String!>*/
+      /*cfe.Set<String>*/
+      /*cfe:nnbd.Set<String!>!*/
       {
-    /*invoke: bool!*/
     /*cfe.String*/
     /*cfe:nnbd.String!*/
     'foo',
-    /*invoke: bool!*/
-    /*cfe.current: String*/
-    /*cfe:nnbd.current: String!*/
     ...?
     /*cfe.Set<String>*/
     /*cfe:nnbd.Set<String!>!*/
-    set
+    /*invoke: void*/ set
   };
 }
 
diff --git a/pkg/front_end/test/test_generator_test.dart b/pkg/front_end/test/test_generator_test.dart
index a701999..2ad6f36 100644
--- a/pkg/front_end/test/test_generator_test.dart
+++ b/pkg/front_end/test/test_generator_test.dart
@@ -139,8 +139,8 @@
 
     final Set<String> formattedErrors = new Set<String>();
     final Set<String> formattedWarnings = new Set<String>();
-    final List<Code> formattedErrorsCodes = new List<Code>();
-    final List<Code> formattedWarningsCodes = new List<Code>();
+    final List<Code> formattedErrorsCodes = <Code>[];
+    final List<Code> formattedWarningsCodes = <Code>[];
 
     options.onDiagnostic = (DiagnosticMessage message) {
       String stringId = message.ansiFormatted.join("\n");
diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
index 17e9ba5..6c6582b 100644
--- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
+++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
@@ -581,7 +581,18 @@
 
 void _testCompoundExtensionSet() {}
 
-void _testCompoundPropertySet() {}
+void _testCompoundPropertySet() {
+  testExpression(
+      new CompoundPropertySet(
+          new IntLiteral(0), new Name('foo'), new Name('+'), new IntLiteral(1),
+          readOffset: TreeNode.noOffset,
+          binaryOffset: TreeNode.noOffset,
+          writeOffset: TreeNode.noOffset,
+          readOnlyReceiver: false,
+          forEffect: false),
+      '''
+0.foo += 1''');
+}
 
 void _testPropertyPostIncDec() {}
 
@@ -607,9 +618,40 @@
 
 void _testCompoundIndexSet() {}
 
-void _testNullAwareCompoundSet() {}
+void _testNullAwareCompoundSet() {
+  testExpression(
+      new NullAwareCompoundSet(
+          new IntLiteral(0), new Name('foo'), new Name('+'), new IntLiteral(1),
+          readOffset: TreeNode.noOffset,
+          binaryOffset: TreeNode.noOffset,
+          writeOffset: TreeNode.noOffset,
+          forPostIncDec: false,
+          forEffect: false),
+      '''
+0?.foo += 1''');
+  testExpression(
+      new NullAwareCompoundSet(
+          new IntLiteral(0), new Name('foo'), new Name('+'), new IntLiteral(1),
+          readOffset: TreeNode.noOffset,
+          binaryOffset: TreeNode.noOffset,
+          writeOffset: TreeNode.noOffset,
+          forPostIncDec: true,
+          forEffect: false),
+      '''
+0?.foo++''');
+}
 
-void _testNullAwareIfNullSet() {}
+void _testNullAwareIfNullSet() {
+  testExpression(
+      new NullAwareIfNullSet(
+          new IntLiteral(0), new Name('foo'), new IntLiteral(1),
+          readOffset: TreeNode.noOffset,
+          testOffset: TreeNode.noOffset,
+          writeOffset: TreeNode.noOffset,
+          forEffect: false),
+      '''
+0?.foo ??= 1''');
+}
 
 void _testCompoundSuperIndexSet() {}
 
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 81b5e42..f5f4ba8 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -23,6 +23,8 @@
 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
 
 import 'package:front_end/src/fasta/fasta_codes.dart' show templateUnspecified;
+import 'package:front_end/src/fasta/kernel/constant_evaluator.dart'
+    show ConstantCoverage;
 
 import 'package:front_end/src/fasta/kernel/kernel_target.dart'
     show KernelTarget;
@@ -293,6 +295,24 @@
         buffer.writeln(extraConstantString);
       }
     }
+    // TODO(jensj): Don't comment this out. Will be done in a follow-up-CL.
+    // if (result.constantCoverage != null) {
+    //   ConstantCoverage constantCoverage = result.constantCoverage;
+    //   if (constantCoverage.constructorCoverage.isNotEmpty) {
+    //     buffer.writeln("");
+    //     buffer.writeln("");
+    //     buffer.writeln("Constructor coverage from constants:");
+    //     for (MapEntry<Uri, Set<Reference>> entry
+    //         in constantCoverage.constructorCoverage.entries) {
+    //       buffer.writeln("${entry.key}:");
+    //       for (Reference reference in entry.value) {
+    //         buffer.writeln(
+    //             "- ${reference.node} (from ${reference.node.location})");
+    //       }
+    //       buffer.writeln("");
+    //     }
+    //   }
+    // }
 
     String actual = "$buffer";
     String binariesPath =
@@ -393,8 +413,14 @@
     Uri uri = tmp.uri.resolve("generated.dill");
     File generated = new File.fromUri(uri);
     IOSink sink = generated.openWrite();
-    result = new ComponentResult(result.description, result.component,
-        result.userLibraries, result.options, result.sourceTarget, uri);
+    result = new ComponentResult(
+        result.description,
+        result.component,
+        result.userLibraries,
+        result.options,
+        result.sourceTarget,
+        result.constantCoverage,
+        uri);
     try {
       new BinaryPrinter(sink).writeComponentFile(component);
     } catch (e, s) {
@@ -493,9 +519,10 @@
   final ProcessedOptions options;
   final KernelTarget sourceTarget;
   final List<String> extraConstantStrings = [];
+  final ConstantCoverage constantCoverage;
 
   ComponentResult(this.description, this.component, this.userLibraries,
-      this.options, this.sourceTarget,
+      this.options, this.sourceTarget, this.constantCoverage,
       [this.outputUri]);
 
   bool isUserLibrary(Library library) {
diff --git a/pkg/front_end/test/vm_service_coverage.dart b/pkg/front_end/test/vm_service_coverage.dart
index b144e3d..7c69754 100644
--- a/pkg/front_end/test/vm_service_coverage.dart
+++ b/pkg/front_end/test/vm_service_coverage.dart
@@ -5,7 +5,7 @@
 main(List<String> args) async {
   CoverageHelper coverageHelper = new CoverageHelper();
 
-  List<String> allArgs = new List<String>();
+  List<String> allArgs = <String>[];
   allArgs.addAll([
     "--disable-dart-dev",
     "--enable-asserts",
diff --git a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
index 4cab31b..d042077 100644
--- a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
+++ b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
@@ -3,7 +3,7 @@
 main(List<String> args) async {
   CoverageHelper coverageHelper = new CoverageHelper();
 
-  List<String> allArgs = new List<String>();
+  List<String> allArgs = <String>[];
   allArgs.addAll([
     "--disable-dart-dev",
     "--enable-asserts",
diff --git a/pkg/front_end/test/vm_service_for_leak_detection.dart b/pkg/front_end/test/vm_service_for_leak_detection.dart
index 9879b9c..748756e 100644
--- a/pkg/front_end/test/vm_service_for_leak_detection.dart
+++ b/pkg/front_end/test/vm_service_for_leak_detection.dart
@@ -3,7 +3,7 @@
 import "vm_service_heap_helper.dart" as helper;
 
 main(List<String> args) async {
-  List<helper.Interest> interests = new List<helper.Interest>();
+  List<helper.Interest> interests = <helper.Interest>[];
   interests.add(new helper.Interest(
       Uri.parse(
           "package:front_end/src/fasta/source/source_library_builder.dart"),
diff --git a/pkg/front_end/test/vm_service_heap_helper.dart b/pkg/front_end/test/vm_service_heap_helper.dart
index 497c0b3..f4841d0 100644
--- a/pkg/front_end/test/vm_service_heap_helper.dart
+++ b/pkg/front_end/test/vm_service_heap_helper.dart
@@ -28,7 +28,7 @@
       }
       List<String> fields = classToFields[interest.className];
       if (fields == null) {
-        fields = new List<String>();
+        fields = <String>[];
         classToFields[interest.className] = fields;
       }
       fields.addAll(interest.fieldNames);
@@ -41,7 +41,7 @@
       }
       List<String> fields = classToFields[interest.className];
       if (fields == null) {
-        fields = new List<String>();
+        fields = <String>[];
         classToFields[interest.className] = fields;
       }
       fields.addAll(interest.fieldNames);
@@ -421,7 +421,7 @@
 HeapGraph convertHeapGraph(vmService.HeapSnapshotGraph graph) {
   HeapGraphClassSentinel classSentinel = new HeapGraphClassSentinel();
   List<HeapGraphClassActual> classes =
-      new List<HeapGraphClassActual>(graph.classes.length);
+      new List<HeapGraphClassActual>.filled(graph.classes.length, null);
   for (int i = 0; i < graph.classes.length; i++) {
     vmService.HeapSnapshotClass c = graph.classes[i];
     classes[i] = new HeapGraphClassActual(c);
@@ -429,7 +429,7 @@
 
   HeapGraphElementSentinel elementSentinel = new HeapGraphElementSentinel();
   List<HeapGraphElementActual> elements =
-      new List<HeapGraphElementActual>(graph.objects.length);
+      new List<HeapGraphElementActual>.filled(graph.objects.length, null);
   for (int i = 0; i < graph.objects.length; i++) {
     vmService.HeapSnapshotObject o = graph.objects[i];
     elements[i] = new HeapGraphElementActual(o);
@@ -474,7 +474,7 @@
   void Function() referencesFiller;
   List<HeapGraphElement> get references {
     if (_references == null && referencesFiller != null) {
-      _references = new List<HeapGraphElement>();
+      _references = <HeapGraphElement>[];
       referencesFiller();
     }
     return _references;
@@ -552,7 +552,7 @@
   List<HeapGraphElement> _instances;
   List<HeapGraphElement> getInstances(HeapGraph graph) {
     if (_instances == null) {
-      _instances = new List<HeapGraphElement>();
+      _instances = <HeapGraphElement>[];
       for (int i = 0; i < graph.elements.length; i++) {
         HeapGraphElementActual converted = graph.elements[i];
         if (converted.class_ == this) {
diff --git a/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
index 02ef4d6..5167c83 100644
--- a/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
@@ -1,4 +1,4 @@
 Errors: {
 }
-method /*isNullableByDefault, from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+method /*isLegacy, from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
   return dart.core::identical(1, 1);
diff --git a/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
index c4ded9a..72b7d9d 100644
--- a/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
@@ -1,4 +1,4 @@
 Errors: {
 }
-method /*isNullableByDefault, from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+method /*isLegacy, from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
   return null is dart.collection::Queue<dynamic>*;
diff --git a/pkg/front_end/testcases/expression/from_vm_cc_linked_hash_map.expression.yaml.expect b/pkg/front_end/testcases/expression/from_vm_cc_linked_hash_map.expression.yaml.expect
index 2643d93..15bc127 100644
--- a/pkg/front_end/testcases/expression/from_vm_cc_linked_hash_map.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/from_vm_cc_linked_hash_map.expression.yaml.expect
@@ -1,6 +1,6 @@
 Errors: {
 }
-method /*isNullableByDefault, from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic a, dynamic b) → dynamic
+method /*isLegacy, from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic a, dynamic b) → dynamic
   return ((dynamic a, dynamic b) → dart.core::bool* {
     if(!a._usedData.{dart.core::Object::==}(b._usedData) || !a._deletedKeys.{dart.core::Object::==}(b._deletedKeys) || !a._hashMask.{dart.core::Object::==}(b._hashMask) || !a._index.length.{dart.core::Object::==}(b._index.length) || !a._data.length.{dart.core::Object::==}(b._data.length)) {
       return false;
diff --git a/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect b/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect
index 8c2b235..fd35ac2 100644
--- a/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect
@@ -1,4 +1,4 @@
 Errors: {
 }
-method /*isNullableByDefault, from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+method /*isLegacy, from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
   return this.{dart.core::Object::toString}();
diff --git a/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect b/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect
index e34676b..6c8b355 100644
--- a/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/spread_element.expression.yaml.expect
@@ -2,12 +2,5 @@
 }
 method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
   return block {
-    final dart.core::List<dart.core::String*>* #t1 = <dart.core::String*>[];
-    {
-      dart.core::Iterator<dart.core::String*>* :sync-for-iterator = main::listOfStrings.{dart.core::Iterable::iterator};
-      for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
-        final dart.core::String* #t2 = :sync-for-iterator.{dart.core::Iterator::current};
-        #t1.{dart.core::List::add}{Invariant}(#t2);
-      }
-    }
+    final dart.core::List<dart.core::String*>* #t1 = dart.core::List::of<dart.core::String*>(main::listOfStrings);
   } =>#t1;
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.outline.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.outline.expect
index 5ee4ba9..8ac03b2 100644
--- a/pkg/front_end/testcases/extensions/ambiguous.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.outline.expect
@@ -36,37 +36,37 @@
   set setter = self::B|set#setter;
   set property = self::B|set#property;
 }
-static method A|method(final self::C* #this) → void
+static method A|method(lowered final self::C* #this) → void
   ;
-static method A|get#method(final self::C* #this) → () →* void
+static method A|get#method(lowered final self::C* #this) → () →* void
   return () → void => self::A|method(#this);
-static method A|get#getter(final self::C* #this) → core::int*
+static method A|get#getter(lowered final self::C* #this) → core::int*
   ;
-static method A|set#setter(final self::C* #this, core::int* value) → void
+static method A|set#setter(lowered final self::C* #this, core::int* value) → void
   ;
-static method A|get#property(final self::C* #this) → core::int*
+static method A|get#property(lowered final self::C* #this) → core::int*
   ;
-static method A|+(final self::C* #this, core::int* i) → core::int*
+static method A|+(lowered final self::C* #this, core::int* i) → core::int*
   ;
-static method A|unary-(final self::C* #this) → core::int*
+static method A|unary-(lowered final self::C* #this) → core::int*
   ;
-static method A|[](final self::C* #this, core::int* i) → core::int*
+static method A|[](lowered final self::C* #this, core::int* i) → core::int*
   ;
-static method B|method(final self::C* #this) → void
+static method B|method(lowered final self::C* #this) → void
   ;
-static method B|get#method(final self::C* #this) → () →* void
+static method B|get#method(lowered final self::C* #this) → () →* void
   return () → void => self::B|method(#this);
-static method B|get#getter(final self::C* #this) → core::int*
+static method B|get#getter(lowered final self::C* #this) → core::int*
   ;
-static method B|set#setter(final self::C* #this, core::int* value) → void
+static method B|set#setter(lowered final self::C* #this, core::int* value) → void
   ;
-static method B|set#property(final self::C* #this, core::int* value) → void
+static method B|set#property(lowered final self::C* #this, core::int* value) → void
   ;
-static method B|+(final self::C* #this, core::int* i) → core::int*
+static method B|+(lowered final self::C* #this, core::int* i) → core::int*
   ;
-static method B|unary-(final self::C* #this) → core::int*
+static method B|unary-(lowered final self::C* #this) → core::int*
   ;
-static method B|[]=(final self::C* #this, core::int* i, core::int* j) → void
+static method B|[]=(lowered final self::C* #this, core::int* i, core::int* j) → void
   ;
 static method errors(self::C* c) → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.strong.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.strong.expect
index a54a55b..3797b04 100644
--- a/pkg/front_end/testcases/extensions/ambiguous.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.strong.expect
@@ -184,32 +184,32 @@
   set setter = self::B|set#setter;
   set property = self::B|set#property;
 }
-static method A|method(final self::C* #this) → void {}
-static method A|get#method(final self::C* #this) → () →* void
+static method A|method(lowered final self::C* #this) → void {}
+static method A|get#method(lowered final self::C* #this) → () →* void
   return () → void => self::A|method(#this);
-static method A|get#getter(final self::C* #this) → core::int*
+static method A|get#getter(lowered final self::C* #this) → core::int*
   return 42;
-static method A|set#setter(final self::C* #this, core::int* value) → void {}
-static method A|get#property(final self::C* #this) → core::int*
+static method A|set#setter(lowered final self::C* #this, core::int* value) → void {}
+static method A|get#property(lowered final self::C* #this) → core::int*
   return 42;
-static method A|+(final self::C* #this, core::int* i) → core::int*
+static method A|+(lowered final self::C* #this, core::int* i) → core::int*
   return i;
-static method A|unary-(final self::C* #this) → core::int*
+static method A|unary-(lowered final self::C* #this) → core::int*
   return 0;
-static method A|[](final self::C* #this, core::int* i) → core::int*
+static method A|[](lowered final self::C* #this, core::int* i) → core::int*
   return i;
-static method B|method(final self::C* #this) → void {}
-static method B|get#method(final self::C* #this) → () →* void
+static method B|method(lowered final self::C* #this) → void {}
+static method B|get#method(lowered final self::C* #this) → () →* void
   return () → void => self::B|method(#this);
-static method B|get#getter(final self::C* #this) → core::int*
+static method B|get#getter(lowered final self::C* #this) → core::int*
   return 42;
-static method B|set#setter(final self::C* #this, core::int* value) → void {}
-static method B|set#property(final self::C* #this, core::int* value) → void {}
-static method B|+(final self::C* #this, core::int* i) → core::int*
+static method B|set#setter(lowered final self::C* #this, core::int* value) → void {}
+static method B|set#property(lowered final self::C* #this, core::int* value) → void {}
+static method B|+(lowered final self::C* #this, core::int* i) → core::int*
   return i;
-static method B|unary-(final self::C* #this) → core::int*
+static method B|unary-(lowered final self::C* #this) → core::int*
   return 0;
-static method B|[]=(final self::C* #this, core::int* i, core::int* j) → void {}
+static method B|[]=(lowered final self::C* #this, core::int* i, core::int* j) → void {}
 static method errors(self::C* c) → dynamic {
   invalid-expression "pkg/front_end/testcases/extensions/ambiguous.dart:28:5: Error: The method 'method' is defined in multiple extensions for 'C' and neither is more specific.
  - 'C' is from 'pkg/front_end/testcases/extensions/ambiguous.dart'.
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.strong.transformed.expect
index a54a55b..3797b04 100644
--- a/pkg/front_end/testcases/extensions/ambiguous.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.strong.transformed.expect
@@ -184,32 +184,32 @@
   set setter = self::B|set#setter;
   set property = self::B|set#property;
 }
-static method A|method(final self::C* #this) → void {}
-static method A|get#method(final self::C* #this) → () →* void
+static method A|method(lowered final self::C* #this) → void {}
+static method A|get#method(lowered final self::C* #this) → () →* void
   return () → void => self::A|method(#this);
-static method A|get#getter(final self::C* #this) → core::int*
+static method A|get#getter(lowered final self::C* #this) → core::int*
   return 42;
-static method A|set#setter(final self::C* #this, core::int* value) → void {}
-static method A|get#property(final self::C* #this) → core::int*
+static method A|set#setter(lowered final self::C* #this, core::int* value) → void {}
+static method A|get#property(lowered final self::C* #this) → core::int*
   return 42;
-static method A|+(final self::C* #this, core::int* i) → core::int*
+static method A|+(lowered final self::C* #this, core::int* i) → core::int*
   return i;
-static method A|unary-(final self::C* #this) → core::int*
+static method A|unary-(lowered final self::C* #this) → core::int*
   return 0;
-static method A|[](final self::C* #this, core::int* i) → core::int*
+static method A|[](lowered final self::C* #this, core::int* i) → core::int*
   return i;
-static method B|method(final self::C* #this) → void {}
-static method B|get#method(final self::C* #this) → () →* void
+static method B|method(lowered final self::C* #this) → void {}
+static method B|get#method(lowered final self::C* #this) → () →* void
   return () → void => self::B|method(#this);
-static method B|get#getter(final self::C* #this) → core::int*
+static method B|get#getter(lowered final self::C* #this) → core::int*
   return 42;
-static method B|set#setter(final self::C* #this, core::int* value) → void {}
-static method B|set#property(final self::C* #this, core::int* value) → void {}
-static method B|+(final self::C* #this, core::int* i) → core::int*
+static method B|set#setter(lowered final self::C* #this, core::int* value) → void {}
+static method B|set#property(lowered final self::C* #this, core::int* value) → void {}
+static method B|+(lowered final self::C* #this, core::int* i) → core::int*
   return i;
-static method B|unary-(final self::C* #this) → core::int*
+static method B|unary-(lowered final self::C* #this) → core::int*
   return 0;
-static method B|[]=(final self::C* #this, core::int* i, core::int* j) → void {}
+static method B|[]=(lowered final self::C* #this, core::int* i, core::int* j) → void {}
 static method errors(self::C* c) → dynamic {
   invalid-expression "pkg/front_end/testcases/extensions/ambiguous.dart:28:5: Error: The method 'method' is defined in multiple extensions for 'C' and neither is more specific.
  - 'C' is from 'pkg/front_end/testcases/extensions/ambiguous.dart'.
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.outline.expect b/pkg/front_end/testcases/extensions/annotations.dart.outline.expect
index ff75d1b..8a6129e 100644
--- a/pkg/front_end/testcases/extensions/annotations.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/annotations.dart.outline.expect
@@ -28,9 +28,9 @@
   static method extensionStaticMethod = self::Extension|extensionStaticMethod;
 }
 @core::pragma::_("dart2js:noInline")
-static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic
+static method Extension|extensionInstanceMethod(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|get#extensionInstanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|extensionInstanceMethod(#this);
 @core::pragma::_("dart2js:noInline")
 static method Extension|extensionStaticMethod() → dynamic
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.strong.expect b/pkg/front_end/testcases/extensions/annotations.dart.strong.expect
index 44c7c8a..441d5bd 100644
--- a/pkg/front_end/testcases/extensions/annotations.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/annotations.dart.strong.expect
@@ -27,8 +27,8 @@
   static method extensionStaticMethod = self::Extension|extensionStaticMethod;
 }
 @#C3
-static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic {}
-static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|extensionInstanceMethod(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#extensionInstanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|extensionInstanceMethod(#this);
 @#C3
 static method Extension|extensionStaticMethod() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect
index 44c7c8a..441d5bd 100644
--- a/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect
@@ -27,8 +27,8 @@
   static method extensionStaticMethod = self::Extension|extensionStaticMethod;
 }
 @#C3
-static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic {}
-static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|extensionInstanceMethod(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#extensionInstanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|extensionInstanceMethod(#this);
 @#C3
 static method Extension|extensionStaticMethod() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.outline.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.outline.expect
index 18fc103..cc28afd 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.outline.expect
@@ -10,17 +10,17 @@
   method asyncStarMethod = self::Extension|asyncStarMethod;
   tearoff asyncStarMethod = self::Extension|get#asyncStarMethod;
 }
-static method Extension|syncStarMethod(final core::int* #this) → dynamic sync* 
+static method Extension|syncStarMethod(lowered final core::int* #this) → dynamic sync* 
   ;
-static method Extension|get#syncStarMethod(final core::int* #this) → () →* dynamic
+static method Extension|get#syncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
-static method Extension|asyncMethod(final core::int* #this) → dynamic async 
+static method Extension|asyncMethod(lowered final core::int* #this) → dynamic async 
   ;
-static method Extension|get#asyncMethod(final core::int* #this) → () →* dynamic
+static method Extension|get#asyncMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncMethod(#this);
-static method Extension|asyncStarMethod(final core::int* #this) → dynamic async* 
+static method Extension|asyncStarMethod(lowered final core::int* #this) → dynamic async* 
   ;
-static method Extension|get#asyncStarMethod(final core::int* #this) → () →* dynamic
+static method Extension|get#asyncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncStarMethod(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.expect
index fd5e869..f053e58 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.expect
@@ -10,14 +10,14 @@
   method asyncStarMethod = self::Extension|asyncStarMethod;
   tearoff asyncStarMethod = self::Extension|get#asyncStarMethod;
 }
-static method Extension|syncStarMethod(final core::int* #this) → dynamic sync* {}
-static method Extension|get#syncStarMethod(final core::int* #this) → () →* dynamic
+static method Extension|syncStarMethod(lowered final core::int* #this) → dynamic sync* {}
+static method Extension|get#syncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
-static method Extension|asyncMethod(final core::int* #this) → dynamic async {}
-static method Extension|get#asyncMethod(final core::int* #this) → () →* dynamic
+static method Extension|asyncMethod(lowered final core::int* #this) → dynamic async {}
+static method Extension|get#asyncMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncMethod(#this);
-static method Extension|asyncStarMethod(final core::int* #this) → dynamic async* {}
-static method Extension|get#asyncStarMethod(final core::int* #this) → () →* dynamic
+static method Extension|asyncStarMethod(lowered final core::int* #this) → dynamic async* {}
+static method Extension|get#asyncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncStarMethod(#this);
 static method main() → dynamic {
   self::Extension|syncStarMethod(0);
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
index 36fe6ad..769d43f 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
   method asyncStarMethod = self::Extension|asyncStarMethod;
   tearoff asyncStarMethod = self::Extension|get#asyncStarMethod;
 }
-static method Extension|syncStarMethod(final core::int* #this) → dynamic /* originally sync* */ {
+static method Extension|syncStarMethod(lowered final core::int* #this) → dynamic /* originally sync* */ {
   function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
     core::int* :await_jump_var = 0;
     dynamic :await_ctx_var;
@@ -23,13 +23,12 @@
   }
   return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
 }
-static method Extension|get#syncStarMethod(final core::int* #this) → () →* dynamic
+static method Extension|get#syncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
-static method Extension|asyncMethod(final core::int* #this) → dynamic /* originally async */ {
+static method Extension|asyncMethod(lowered final core::int* #this) → dynamic /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -44,19 +43,17 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
   :is_sync = true;
   return :async_future;
 }
-static method Extension|get#asyncMethod(final core::int* #this) → () →* dynamic
+static method Extension|get#asyncMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncMethod(#this);
-static method Extension|asyncStarMethod(final core::int* #this) → dynamic /* originally async* */ {
+static method Extension|asyncStarMethod(lowered final core::int* #this) → dynamic /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -74,14 +71,13 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
   return :controller_stream;
 }
-static method Extension|get#asyncStarMethod(final core::int* #this) → () →* dynamic
+static method Extension|get#asyncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncStarMethod(#this);
 static method main() → dynamic {
   self::Extension|syncStarMethod(0);
diff --git a/pkg/front_end/testcases/extensions/bounds.dart.outline.expect b/pkg/front_end/testcases/extensions/bounds.dart.outline.expect
index 6c07498..460599a 100644
--- a/pkg/front_end/testcases/extensions/bounds.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/bounds.dart.outline.expect
@@ -42,69 +42,69 @@
   method method4 = self::Extension4|method4;
   tearoff method4 = self::Extension4|get#method4;
 }
-static method Extension1|method1<T extends core::Object* = core::Object*, S extends core::Object* = core::Object*>(final self::Extension1|method1::T* #this) → dynamic
+static method Extension1|method1<T extends core::Object* = core::Object*, S extends core::Object* = core::Object*>(lowered final self::Extension1|method1::T* #this) → dynamic
   ;
-static method Extension1|get#method1<T extends core::Object* = core::Object*>(final self::Extension1|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension1|get#method1<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T*, S*>(#this);
-static method Extension1|method2<T extends core::Object* = core::Object*, S extends core::String* = core::String*>(final self::Extension1|method2::T* #this) → dynamic
+static method Extension1|method2<T extends core::Object* = core::Object*, S extends core::String* = core::String*>(lowered final self::Extension1|method2::T* #this) → dynamic
   ;
-static method Extension1|get#method2<T extends core::Object* = core::Object*>(final self::Extension1|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension1|get#method2<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T*, S*>(#this);
-static method Extension1|method3<T extends core::Object* = core::Object*, S extends dynamic = dynamic>(final self::Extension1|method3::T* #this) → dynamic
+static method Extension1|method3<T extends core::Object* = core::Object*, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T* #this) → dynamic
   ;
-static method Extension1|get#method3<T extends core::Object* = core::Object*>(final self::Extension1|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension1|get#method3<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T*, S%>(#this);
-static method Extension1|method4<T extends core::Object* = core::Object*, S extends core::Object* = dynamic>(final self::Extension1|method4::T* #this) → dynamic
+static method Extension1|method4<T extends core::Object* = core::Object*, S extends core::Object* = dynamic>(lowered final self::Extension1|method4::T* #this) → dynamic
   ;
-static method Extension1|get#method4<T extends core::Object* = core::Object*>(final self::Extension1|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension1|get#method4<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T*, S*>(#this);
-static method Extension2|method1<T extends core::String* = core::String*, S extends core::Object* = core::Object*>(final self::Extension2|method1::T* #this) → dynamic
+static method Extension2|method1<T extends core::String* = core::String*, S extends core::Object* = core::Object*>(lowered final self::Extension2|method1::T* #this) → dynamic
   ;
-static method Extension2|get#method1<T extends core::String* = core::String*>(final self::Extension2|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension2|get#method1<T extends core::String* = core::String*>(lowered final self::Extension2|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T*, S*>(#this);
-static method Extension2|method2<T extends core::String* = core::String*, S extends core::String* = core::String*>(final self::Extension2|method2::T* #this) → dynamic
+static method Extension2|method2<T extends core::String* = core::String*, S extends core::String* = core::String*>(lowered final self::Extension2|method2::T* #this) → dynamic
   ;
-static method Extension2|get#method2<T extends core::String* = core::String*>(final self::Extension2|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension2|get#method2<T extends core::String* = core::String*>(lowered final self::Extension2|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T*, S*>(#this);
-static method Extension2|method3<T extends core::String* = core::String*, S extends dynamic = dynamic>(final self::Extension2|method3::T* #this) → dynamic
+static method Extension2|method3<T extends core::String* = core::String*, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T* #this) → dynamic
   ;
-static method Extension2|get#method3<T extends core::String* = core::String*>(final self::Extension2|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension2|get#method3<T extends core::String* = core::String*>(lowered final self::Extension2|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T*, S%>(#this);
-static method Extension2|method4<T extends core::String* = core::String*, S extends core::Object* = dynamic>(final self::Extension2|method4::T* #this) → dynamic
+static method Extension2|method4<T extends core::String* = core::String*, S extends core::Object* = dynamic>(lowered final self::Extension2|method4::T* #this) → dynamic
   ;
-static method Extension2|get#method4<T extends core::String* = core::String*>(final self::Extension2|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension2|get#method4<T extends core::String* = core::String*>(lowered final self::Extension2|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T*, S*>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object* = core::Object*>(final self::Extension3|method1::T* #this) → dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object* = core::Object*>(lowered final self::Extension3|method1::T* #this) → dynamic
   ;
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S*>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String* = core::String*>(final self::Extension3|method2::T* #this) → dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String* = core::String*>(lowered final self::Extension3|method2::T* #this) → dynamic
   ;
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S*>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T* #this) → dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T* #this) → dynamic
   ;
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object* = dynamic>(final self::Extension3|method4::T* #this) → dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object* = dynamic>(lowered final self::Extension3|method4::T* #this) → dynamic
   ;
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S*>(#this);
-static method Extension4|method1<T extends core::Object* = dynamic, S extends core::Object* = core::Object*>(final self::Extension4|method1::T* #this) → dynamic
+static method Extension4|method1<T extends core::Object* = dynamic, S extends core::Object* = core::Object*>(lowered final self::Extension4|method1::T* #this) → dynamic
   ;
-static method Extension4|get#method1<T extends core::Object* = dynamic>(final self::Extension4|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension4|get#method1<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T*, S*>(#this);
-static method Extension4|method2<T extends core::Object* = dynamic, S extends core::String* = core::String*>(final self::Extension4|method2::T* #this) → dynamic
+static method Extension4|method2<T extends core::Object* = dynamic, S extends core::String* = core::String*>(lowered final self::Extension4|method2::T* #this) → dynamic
   ;
-static method Extension4|get#method2<T extends core::Object* = dynamic>(final self::Extension4|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension4|get#method2<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T*, S*>(#this);
-static method Extension4|method3<T extends core::Object* = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T* #this) → dynamic
+static method Extension4|method3<T extends core::Object* = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T* #this) → dynamic
   ;
-static method Extension4|get#method3<T extends core::Object* = dynamic>(final self::Extension4|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension4|get#method3<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T*, S%>(#this);
-static method Extension4|method4<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::Extension4|method4::T* #this) → dynamic
+static method Extension4|method4<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::Extension4|method4::T* #this) → dynamic
   ;
-static method Extension4|get#method4<T extends core::Object* = dynamic>(final self::Extension4|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension4|get#method4<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T*, S*>(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/bounds.dart.strong.expect b/pkg/front_end/testcases/extensions/bounds.dart.strong.expect
index 46c68c7..b7ca556 100644
--- a/pkg/front_end/testcases/extensions/bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/bounds.dart.strong.expect
@@ -42,52 +42,52 @@
   method method4 = self::Extension4|method4;
   tearoff method4 = self::Extension4|get#method4;
 }
-static method Extension1|method1<T extends core::Object* = core::Object*, S extends core::Object* = core::Object*>(final self::Extension1|method1::T* #this) → dynamic {}
-static method Extension1|get#method1<T extends core::Object* = core::Object*>(final self::Extension1|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension1|method1<T extends core::Object* = core::Object*, S extends core::Object* = core::Object*>(lowered final self::Extension1|method1::T* #this) → dynamic {}
+static method Extension1|get#method1<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T*, S*>(#this);
-static method Extension1|method2<T extends core::Object* = core::Object*, S extends core::String* = core::String*>(final self::Extension1|method2::T* #this) → dynamic {}
-static method Extension1|get#method2<T extends core::Object* = core::Object*>(final self::Extension1|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension1|method2<T extends core::Object* = core::Object*, S extends core::String* = core::String*>(lowered final self::Extension1|method2::T* #this) → dynamic {}
+static method Extension1|get#method2<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T*, S*>(#this);
-static method Extension1|method3<T extends core::Object* = core::Object*, S extends dynamic = dynamic>(final self::Extension1|method3::T* #this) → dynamic {}
-static method Extension1|get#method3<T extends core::Object* = core::Object*>(final self::Extension1|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension1|method3<T extends core::Object* = core::Object*, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T* #this) → dynamic {}
+static method Extension1|get#method3<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T*, S%>(#this);
-static method Extension1|method4<T extends core::Object* = core::Object*, S extends core::Object* = dynamic>(final self::Extension1|method4::T* #this) → dynamic {}
-static method Extension1|get#method4<T extends core::Object* = core::Object*>(final self::Extension1|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension1|method4<T extends core::Object* = core::Object*, S extends core::Object* = dynamic>(lowered final self::Extension1|method4::T* #this) → dynamic {}
+static method Extension1|get#method4<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T*, S*>(#this);
-static method Extension2|method1<T extends core::String* = core::String*, S extends core::Object* = core::Object*>(final self::Extension2|method1::T* #this) → dynamic {}
-static method Extension2|get#method1<T extends core::String* = core::String*>(final self::Extension2|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension2|method1<T extends core::String* = core::String*, S extends core::Object* = core::Object*>(lowered final self::Extension2|method1::T* #this) → dynamic {}
+static method Extension2|get#method1<T extends core::String* = core::String*>(lowered final self::Extension2|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T*, S*>(#this);
-static method Extension2|method2<T extends core::String* = core::String*, S extends core::String* = core::String*>(final self::Extension2|method2::T* #this) → dynamic {}
-static method Extension2|get#method2<T extends core::String* = core::String*>(final self::Extension2|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension2|method2<T extends core::String* = core::String*, S extends core::String* = core::String*>(lowered final self::Extension2|method2::T* #this) → dynamic {}
+static method Extension2|get#method2<T extends core::String* = core::String*>(lowered final self::Extension2|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T*, S*>(#this);
-static method Extension2|method3<T extends core::String* = core::String*, S extends dynamic = dynamic>(final self::Extension2|method3::T* #this) → dynamic {}
-static method Extension2|get#method3<T extends core::String* = core::String*>(final self::Extension2|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension2|method3<T extends core::String* = core::String*, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T* #this) → dynamic {}
+static method Extension2|get#method3<T extends core::String* = core::String*>(lowered final self::Extension2|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T*, S%>(#this);
-static method Extension2|method4<T extends core::String* = core::String*, S extends core::Object* = dynamic>(final self::Extension2|method4::T* #this) → dynamic {}
-static method Extension2|get#method4<T extends core::String* = core::String*>(final self::Extension2|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension2|method4<T extends core::String* = core::String*, S extends core::Object* = dynamic>(lowered final self::Extension2|method4::T* #this) → dynamic {}
+static method Extension2|get#method4<T extends core::String* = core::String*>(lowered final self::Extension2|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T*, S*>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object* = core::Object*>(final self::Extension3|method1::T* #this) → dynamic {}
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object* = core::Object*>(lowered final self::Extension3|method1::T* #this) → dynamic {}
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S*>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String* = core::String*>(final self::Extension3|method2::T* #this) → dynamic {}
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String* = core::String*>(lowered final self::Extension3|method2::T* #this) → dynamic {}
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S*>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T* #this) → dynamic {}
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T* #this) → dynamic {}
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object* = dynamic>(final self::Extension3|method4::T* #this) → dynamic {}
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object* = dynamic>(lowered final self::Extension3|method4::T* #this) → dynamic {}
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S*>(#this);
-static method Extension4|method1<T extends core::Object* = dynamic, S extends core::Object* = core::Object*>(final self::Extension4|method1::T* #this) → dynamic {}
-static method Extension4|get#method1<T extends core::Object* = dynamic>(final self::Extension4|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension4|method1<T extends core::Object* = dynamic, S extends core::Object* = core::Object*>(lowered final self::Extension4|method1::T* #this) → dynamic {}
+static method Extension4|get#method1<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T*, S*>(#this);
-static method Extension4|method2<T extends core::Object* = dynamic, S extends core::String* = core::String*>(final self::Extension4|method2::T* #this) → dynamic {}
-static method Extension4|get#method2<T extends core::Object* = dynamic>(final self::Extension4|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension4|method2<T extends core::Object* = dynamic, S extends core::String* = core::String*>(lowered final self::Extension4|method2::T* #this) → dynamic {}
+static method Extension4|get#method2<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T*, S*>(#this);
-static method Extension4|method3<T extends core::Object* = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T* #this) → dynamic {}
-static method Extension4|get#method3<T extends core::Object* = dynamic>(final self::Extension4|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension4|method3<T extends core::Object* = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T* #this) → dynamic {}
+static method Extension4|get#method3<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T*, S%>(#this);
-static method Extension4|method4<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::Extension4|method4::T* #this) → dynamic {}
-static method Extension4|get#method4<T extends core::Object* = dynamic>(final self::Extension4|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension4|method4<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::Extension4|method4::T* #this) → dynamic {}
+static method Extension4|get#method4<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T*, S*>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/bounds.dart.strong.transformed.expect
index 46c68c7..b7ca556 100644
--- a/pkg/front_end/testcases/extensions/bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/bounds.dart.strong.transformed.expect
@@ -42,52 +42,52 @@
   method method4 = self::Extension4|method4;
   tearoff method4 = self::Extension4|get#method4;
 }
-static method Extension1|method1<T extends core::Object* = core::Object*, S extends core::Object* = core::Object*>(final self::Extension1|method1::T* #this) → dynamic {}
-static method Extension1|get#method1<T extends core::Object* = core::Object*>(final self::Extension1|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension1|method1<T extends core::Object* = core::Object*, S extends core::Object* = core::Object*>(lowered final self::Extension1|method1::T* #this) → dynamic {}
+static method Extension1|get#method1<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T*, S*>(#this);
-static method Extension1|method2<T extends core::Object* = core::Object*, S extends core::String* = core::String*>(final self::Extension1|method2::T* #this) → dynamic {}
-static method Extension1|get#method2<T extends core::Object* = core::Object*>(final self::Extension1|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension1|method2<T extends core::Object* = core::Object*, S extends core::String* = core::String*>(lowered final self::Extension1|method2::T* #this) → dynamic {}
+static method Extension1|get#method2<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T*, S*>(#this);
-static method Extension1|method3<T extends core::Object* = core::Object*, S extends dynamic = dynamic>(final self::Extension1|method3::T* #this) → dynamic {}
-static method Extension1|get#method3<T extends core::Object* = core::Object*>(final self::Extension1|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension1|method3<T extends core::Object* = core::Object*, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T* #this) → dynamic {}
+static method Extension1|get#method3<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T*, S%>(#this);
-static method Extension1|method4<T extends core::Object* = core::Object*, S extends core::Object* = dynamic>(final self::Extension1|method4::T* #this) → dynamic {}
-static method Extension1|get#method4<T extends core::Object* = core::Object*>(final self::Extension1|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension1|method4<T extends core::Object* = core::Object*, S extends core::Object* = dynamic>(lowered final self::Extension1|method4::T* #this) → dynamic {}
+static method Extension1|get#method4<T extends core::Object* = core::Object*>(lowered final self::Extension1|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T*, S*>(#this);
-static method Extension2|method1<T extends core::String* = core::String*, S extends core::Object* = core::Object*>(final self::Extension2|method1::T* #this) → dynamic {}
-static method Extension2|get#method1<T extends core::String* = core::String*>(final self::Extension2|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension2|method1<T extends core::String* = core::String*, S extends core::Object* = core::Object*>(lowered final self::Extension2|method1::T* #this) → dynamic {}
+static method Extension2|get#method1<T extends core::String* = core::String*>(lowered final self::Extension2|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T*, S*>(#this);
-static method Extension2|method2<T extends core::String* = core::String*, S extends core::String* = core::String*>(final self::Extension2|method2::T* #this) → dynamic {}
-static method Extension2|get#method2<T extends core::String* = core::String*>(final self::Extension2|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension2|method2<T extends core::String* = core::String*, S extends core::String* = core::String*>(lowered final self::Extension2|method2::T* #this) → dynamic {}
+static method Extension2|get#method2<T extends core::String* = core::String*>(lowered final self::Extension2|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T*, S*>(#this);
-static method Extension2|method3<T extends core::String* = core::String*, S extends dynamic = dynamic>(final self::Extension2|method3::T* #this) → dynamic {}
-static method Extension2|get#method3<T extends core::String* = core::String*>(final self::Extension2|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension2|method3<T extends core::String* = core::String*, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T* #this) → dynamic {}
+static method Extension2|get#method3<T extends core::String* = core::String*>(lowered final self::Extension2|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T*, S%>(#this);
-static method Extension2|method4<T extends core::String* = core::String*, S extends core::Object* = dynamic>(final self::Extension2|method4::T* #this) → dynamic {}
-static method Extension2|get#method4<T extends core::String* = core::String*>(final self::Extension2|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension2|method4<T extends core::String* = core::String*, S extends core::Object* = dynamic>(lowered final self::Extension2|method4::T* #this) → dynamic {}
+static method Extension2|get#method4<T extends core::String* = core::String*>(lowered final self::Extension2|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T*, S*>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object* = core::Object*>(final self::Extension3|method1::T* #this) → dynamic {}
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object* = core::Object*>(lowered final self::Extension3|method1::T* #this) → dynamic {}
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S*>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String* = core::String*>(final self::Extension3|method2::T* #this) → dynamic {}
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String* = core::String*>(lowered final self::Extension3|method2::T* #this) → dynamic {}
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S*>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T* #this) → dynamic {}
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T* #this) → dynamic {}
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object* = dynamic>(final self::Extension3|method4::T* #this) → dynamic {}
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object* = dynamic>(lowered final self::Extension3|method4::T* #this) → dynamic {}
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S*>(#this);
-static method Extension4|method1<T extends core::Object* = dynamic, S extends core::Object* = core::Object*>(final self::Extension4|method1::T* #this) → dynamic {}
-static method Extension4|get#method1<T extends core::Object* = dynamic>(final self::Extension4|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
+static method Extension4|method1<T extends core::Object* = dynamic, S extends core::Object* = core::Object*>(lowered final self::Extension4|method1::T* #this) → dynamic {}
+static method Extension4|get#method1<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method1::T* #this) → <S extends core::Object* = core::Object*>() →* dynamic
   return <S extends core::Object* = core::Object*>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T*, S*>(#this);
-static method Extension4|method2<T extends core::Object* = dynamic, S extends core::String* = core::String*>(final self::Extension4|method2::T* #this) → dynamic {}
-static method Extension4|get#method2<T extends core::Object* = dynamic>(final self::Extension4|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
+static method Extension4|method2<T extends core::Object* = dynamic, S extends core::String* = core::String*>(lowered final self::Extension4|method2::T* #this) → dynamic {}
+static method Extension4|get#method2<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method2::T* #this) → <S extends core::String* = core::String*>() →* dynamic
   return <S extends core::String* = core::String*>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T*, S*>(#this);
-static method Extension4|method3<T extends core::Object* = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T* #this) → dynamic {}
-static method Extension4|get#method3<T extends core::Object* = dynamic>(final self::Extension4|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
+static method Extension4|method3<T extends core::Object* = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T* #this) → dynamic {}
+static method Extension4|get#method3<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method3::T* #this) → <S extends dynamic = dynamic>() →* dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T*, S%>(#this);
-static method Extension4|method4<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::Extension4|method4::T* #this) → dynamic {}
-static method Extension4|get#method4<T extends core::Object* = dynamic>(final self::Extension4|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
+static method Extension4|method4<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::Extension4|method4::T* #this) → dynamic {}
+static method Extension4|get#method4<T extends core::Object* = dynamic>(lowered final self::Extension4|get#method4::T* #this) → <S extends core::Object* = dynamic>() →* dynamic
   return <S extends core::Object* = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T*, S*>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
index f5610f5..173e1a4 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.outline.expect
@@ -51,11 +51,11 @@
 static field core::String* topLevel5;
 static field self::B* b;
 static field core::String* topLevel6;
-static method _extension#0|get#call(final core::int* #this) → core::String*
+static method _extension#0|get#call(lowered final core::int* #this) → core::String*
   ;
-static method _extension#1|get#call(final core::num* #this) → core::String*
+static method _extension#1|get#call(lowered final core::num* #this) → core::String*
   ;
-static method _extension#2|get#call(final core::String* #this) → () →* core::String*
+static method _extension#2|get#call(lowered final core::String* #this) → () →* core::String*
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect b/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
index 6ad9135..e207c34 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.strong.expect
@@ -166,11 +166,11 @@
 Try changing 'call' to a method or explicitly invoke 'call'.
 var topLevel6 = a(2, \"3\");
                  ^" as{TypeError,ForDynamic} core::String*;
-static method _extension#0|get#call(final core::int* #this) → core::String*
+static method _extension#0|get#call(lowered final core::int* #this) → core::String*
   return "My name is int";
-static method _extension#1|get#call(final core::num* #this) → core::String*
+static method _extension#1|get#call(lowered final core::num* #this) → core::String*
   return "My name is num";
-static method _extension#2|get#call(final core::String* #this) → () →* core::String*
+static method _extension#2|get#call(lowered final core::String* #this) → () →* core::String*
   return () → core::String* => "My name is String";
 static method main() → dynamic {
   self::_extension#2|get#call("").call();
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect
index 1a72e8b..b599220 100644
--- a/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect
@@ -73,13 +73,13 @@
 static final field dynamic field27;
 static final field dynamic field28;
 static final field dynamic field29;
-static method Extension|method<T extends self::B* = self::B*>(final self::Class<self::Extension|method::T*>* #this) → dynamic
+static method Extension|method<T extends self::B* = self::B*>(lowered final self::Class<self::Extension|method::T*>* #this) → dynamic
   ;
-static method Extension|get#method<T extends self::B* = self::B*>(final self::Class<self::Extension|get#method::T*>* #this) → () →* dynamic
+static method Extension|get#method<T extends self::B* = self::B*>(lowered 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* = self::B*, S extends self::B* = self::B*>(final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic
+static method Extension|genericMethod<T extends self::B* = self::B*, S extends self::B* = self::B*>(lowered final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic
   ;
-static method Extension|get#genericMethod<T extends self::B* = self::B*>(final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = self::B*>(S*) →* dynamic
+static method Extension|get#genericMethod<T extends self::B* = self::B*>(lowered final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = self::B*>(S*) →* dynamic
   return <S extends self::B* = self::B*>(S* s) → dynamic => self::Extension|genericMethod<self::Extension|get#genericMethod::T*, S*>(#this, s);
 static method main() → 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
index 1d88a8a..635468b 100644
--- a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
@@ -885,11 +885,11 @@
 static final field dynamic field27 = self::Extension|genericMethod<self::B*, self::A*>(self::classB, self::a);
 static final field dynamic field28 = self::Extension|genericMethod<self::B*, self::A*>(self::classB, self::a);
 static final field dynamic field29 = self::Extension|genericMethod<self::B*, self::B*>(self::classB, self::a as{TypeError} self::B*);
-static method Extension|method<T extends self::B* = self::B*>(final self::Class<self::Extension|method::T*>* #this) → dynamic {}
-static method Extension|get#method<T extends self::B* = self::B*>(final self::Class<self::Extension|get#method::T*>* #this) → () →* dynamic
+static method Extension|method<T extends self::B* = self::B*>(lowered final self::Class<self::Extension|method::T*>* #this) → dynamic {}
+static method Extension|get#method<T extends self::B* = self::B*>(lowered 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* = self::B*, S extends self::B* = self::B*>(final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic {}
-static method Extension|get#genericMethod<T extends self::B* = self::B*>(final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = self::B*>(S*) →* dynamic
+static method Extension|genericMethod<T extends self::B* = self::B*, S extends self::B* = self::B*>(lowered final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic {}
+static method Extension|get#genericMethod<T extends self::B* = self::B*>(lowered final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = self::B*>(S*) →* dynamic
   return <S extends self::B* = self::B*>(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.transformed.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
index 1d88a8a..635468b 100644
--- a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
@@ -885,11 +885,11 @@
 static final field dynamic field27 = self::Extension|genericMethod<self::B*, self::A*>(self::classB, self::a);
 static final field dynamic field28 = self::Extension|genericMethod<self::B*, self::A*>(self::classB, self::a);
 static final field dynamic field29 = self::Extension|genericMethod<self::B*, self::B*>(self::classB, self::a as{TypeError} self::B*);
-static method Extension|method<T extends self::B* = self::B*>(final self::Class<self::Extension|method::T*>* #this) → dynamic {}
-static method Extension|get#method<T extends self::B* = self::B*>(final self::Class<self::Extension|get#method::T*>* #this) → () →* dynamic
+static method Extension|method<T extends self::B* = self::B*>(lowered final self::Class<self::Extension|method::T*>* #this) → dynamic {}
+static method Extension|get#method<T extends self::B* = self::B*>(lowered 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* = self::B*, S extends self::B* = self::B*>(final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic {}
-static method Extension|get#genericMethod<T extends self::B* = self::B*>(final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = self::B*>(S*) →* dynamic
+static method Extension|genericMethod<T extends self::B* = self::B*, S extends self::B* = self::B*>(lowered final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic {}
+static method Extension|get#genericMethod<T extends self::B* = self::B*>(lowered final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = self::B*>(S*) →* dynamic
   return <S extends self::B* = self::B*>(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/compounds.dart.outline.expect b/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
index a4408ae..3bfb031 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
@@ -66,25 +66,25 @@
   tearoff testImplicitProperties = self::IntClassExtension|get#testImplicitProperties;
   set property = self::IntClassExtension|set#property;
 }
-static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number*
+static method NumberExtension|+(lowered final self::Number* #this, core::Object* other) → self::Number*
   ;
-static method NumberExtension|-(final self::Number* #this, core::Object* other) → self::Number*
+static method NumberExtension|-(lowered final self::Number* #this, core::Object* other) → self::Number*
   ;
-static method ClassExtension|get#property(final self::Class* #this) → self::Number*
+static method ClassExtension|get#property(lowered final self::Class* #this) → self::Number*
   ;
-static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void
+static method ClassExtension|set#property(lowered final self::Class* #this, self::Number* value) → void
   ;
-static method ClassExtension|testImplicitProperties(final self::Class* #this) → dynamic
+static method ClassExtension|testImplicitProperties(lowered final self::Class* #this) → dynamic
   ;
-static method ClassExtension|get#testImplicitProperties(final self::Class* #this) → () →* dynamic
+static method ClassExtension|get#testImplicitProperties(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
-static method IntClassExtension|get#property(final self::IntClass* #this) → core::int*
+static method IntClassExtension|get#property(lowered final self::IntClass* #this) → core::int*
   ;
-static method IntClassExtension|set#property(final self::IntClass* #this, core::int* value) → void
+static method IntClassExtension|set#property(lowered final self::IntClass* #this, core::int* value) → void
   ;
-static method IntClassExtension|testImplicitProperties(final self::IntClass* #this) → dynamic
+static method IntClassExtension|testImplicitProperties(lowered final self::IntClass* #this) → dynamic
   ;
-static method IntClassExtension|get#testImplicitProperties(final self::IntClass* #this) → () →* dynamic
+static method IntClassExtension|get#testImplicitProperties(lowered final self::IntClass* #this) → () →* dynamic
   return () → dynamic => self::IntClassExtension|testImplicitProperties(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.strong.expect b/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
index b69e531..5174cae 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
@@ -69,7 +69,7 @@
   tearoff testImplicitProperties = self::IntClassExtension|get#testImplicitProperties;
   set property = self::IntClassExtension|set#property;
 }
-static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number* {
+static method NumberExtension|+(lowered final self::Number* #this, core::Object* other) → self::Number* {
   if(other is core::int*) {
     return new self::Number::•(#this.{self::Number::value}.{core::num::+}(other{core::int*}));
   }
@@ -81,7 +81,7 @@
       throw new core::ArgumentError::•("${other}");
     }
 }
-static method NumberExtension|-(final self::Number* #this, core::Object* other) → self::Number* {
+static method NumberExtension|-(lowered final self::Number* #this, core::Object* other) → self::Number* {
   if(other is core::int*) {
     return new self::Number::•(#this.{self::Number::value}.{core::num::-}(other{core::int*}));
   }
@@ -93,12 +93,12 @@
       throw new core::ArgumentError::•("${other}");
     }
 }
-static method ClassExtension|get#property(final self::Class* #this) → self::Number*
+static method ClassExtension|get#property(lowered final self::Class* #this) → self::Number*
   return #this.{self::Class::field};
-static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void {
+static method ClassExtension|set#property(lowered final self::Class* #this, self::Number* value) → void {
   #this.{self::Class::field} = value;
 }
-static method ClassExtension|testImplicitProperties(final self::Class* #this) → dynamic {
+static method ClassExtension|testImplicitProperties(lowered final self::Class* #this) → dynamic {
   self::Number* n0 = new self::Number::•(0);
   self::Number* n1 = new self::Number::•(1);
   self::Number* n2 = new self::Number::•(2);
@@ -133,14 +133,14 @@
   self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), 1));
   self::expect(n0, self::ClassExtension|get#property(#this));
 }
-static method ClassExtension|get#testImplicitProperties(final self::Class* #this) → () →* dynamic
+static method ClassExtension|get#testImplicitProperties(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
-static method IntClassExtension|get#property(final self::IntClass* #this) → core::int*
+static method IntClassExtension|get#property(lowered final self::IntClass* #this) → core::int*
   return #this.{self::IntClass::field};
-static method IntClassExtension|set#property(final self::IntClass* #this, core::int* value) → void {
+static method IntClassExtension|set#property(lowered final self::IntClass* #this, core::int* value) → void {
   #this.{self::IntClass::field} = value;
 }
-static method IntClassExtension|testImplicitProperties(final self::IntClass* #this) → dynamic {
+static method IntClassExtension|testImplicitProperties(lowered final self::IntClass* #this) → dynamic {
   core::int* n0 = 0;
   core::int* n1 = 1;
   core::int* n2 = 2;
@@ -175,7 +175,7 @@
   self::IntClassExtension|set#property(#this, self::IntClassExtension|get#property(#this).{core::num::-}(1));
   self::expect(n0, self::IntClassExtension|get#property(#this));
 }
-static method IntClassExtension|get#testImplicitProperties(final self::IntClass* #this) → () →* dynamic
+static method IntClassExtension|get#testImplicitProperties(lowered final self::IntClass* #this) → () →* dynamic
   return () → dynamic => self::IntClassExtension|testImplicitProperties(#this);
 static method main() → dynamic {
   self::testLocals();
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
index b69e531..5174cae 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
@@ -69,7 +69,7 @@
   tearoff testImplicitProperties = self::IntClassExtension|get#testImplicitProperties;
   set property = self::IntClassExtension|set#property;
 }
-static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number* {
+static method NumberExtension|+(lowered final self::Number* #this, core::Object* other) → self::Number* {
   if(other is core::int*) {
     return new self::Number::•(#this.{self::Number::value}.{core::num::+}(other{core::int*}));
   }
@@ -81,7 +81,7 @@
       throw new core::ArgumentError::•("${other}");
     }
 }
-static method NumberExtension|-(final self::Number* #this, core::Object* other) → self::Number* {
+static method NumberExtension|-(lowered final self::Number* #this, core::Object* other) → self::Number* {
   if(other is core::int*) {
     return new self::Number::•(#this.{self::Number::value}.{core::num::-}(other{core::int*}));
   }
@@ -93,12 +93,12 @@
       throw new core::ArgumentError::•("${other}");
     }
 }
-static method ClassExtension|get#property(final self::Class* #this) → self::Number*
+static method ClassExtension|get#property(lowered final self::Class* #this) → self::Number*
   return #this.{self::Class::field};
-static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void {
+static method ClassExtension|set#property(lowered final self::Class* #this, self::Number* value) → void {
   #this.{self::Class::field} = value;
 }
-static method ClassExtension|testImplicitProperties(final self::Class* #this) → dynamic {
+static method ClassExtension|testImplicitProperties(lowered final self::Class* #this) → dynamic {
   self::Number* n0 = new self::Number::•(0);
   self::Number* n1 = new self::Number::•(1);
   self::Number* n2 = new self::Number::•(2);
@@ -133,14 +133,14 @@
   self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), 1));
   self::expect(n0, self::ClassExtension|get#property(#this));
 }
-static method ClassExtension|get#testImplicitProperties(final self::Class* #this) → () →* dynamic
+static method ClassExtension|get#testImplicitProperties(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
-static method IntClassExtension|get#property(final self::IntClass* #this) → core::int*
+static method IntClassExtension|get#property(lowered final self::IntClass* #this) → core::int*
   return #this.{self::IntClass::field};
-static method IntClassExtension|set#property(final self::IntClass* #this, core::int* value) → void {
+static method IntClassExtension|set#property(lowered final self::IntClass* #this, core::int* value) → void {
   #this.{self::IntClass::field} = value;
 }
-static method IntClassExtension|testImplicitProperties(final self::IntClass* #this) → dynamic {
+static method IntClassExtension|testImplicitProperties(lowered final self::IntClass* #this) → dynamic {
   core::int* n0 = 0;
   core::int* n1 = 1;
   core::int* n2 = 2;
@@ -175,7 +175,7 @@
   self::IntClassExtension|set#property(#this, self::IntClassExtension|get#property(#this).{core::num::-}(1));
   self::expect(n0, self::IntClassExtension|get#property(#this));
 }
-static method IntClassExtension|get#testImplicitProperties(final self::IntClass* #this) → () →* dynamic
+static method IntClassExtension|get#testImplicitProperties(lowered final self::IntClass* #this) → () →* dynamic
   return () → dynamic => self::IntClassExtension|testImplicitProperties(#this);
 static method main() → dynamic {
   self::testLocals();
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect
index 4d46ff2..500096d 100644
--- a/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect
@@ -33,15 +33,15 @@
   static method toString = self::Extension|toString;
   set hashCode = self::Extension|set#hashCode;
 }
-static method Extension|get#noSuchMethod(final core::String* #this) → core::int*
+static method Extension|get#noSuchMethod(lowered final core::String* #this) → core::int*
   ;
-static method Extension|set#hashCode(final core::String* #this, core::int* value) → void
+static method Extension|set#hashCode(lowered final core::String* #this, core::int* value) → void
   ;
-static method Extension|runtimeType(final core::String* #this) → core::int*
+static method Extension|runtimeType(lowered final core::String* #this) → core::int*
   ;
-static method Extension|get#runtimeType(final core::String* #this) → () →* core::int*
+static method Extension|get#runtimeType(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self::Extension|runtimeType(#this);
-static method Extension|==(final core::String* #this, dynamic other) → dynamic
+static method Extension|==(lowered final core::String* #this, dynamic other) → dynamic
   ;
 static method Extension|toString() → core::String*
   ;
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect
index 891feb9..f363804 100644
--- a/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect
@@ -48,13 +48,13 @@
   static method toString = self::Extension|toString;
   set hashCode = self::Extension|set#hashCode;
 }
-static method Extension|get#noSuchMethod(final core::String* #this) → core::int*
+static method Extension|get#noSuchMethod(lowered final core::String* #this) → core::int*
   return 42;
-static method Extension|set#hashCode(final core::String* #this, core::int* value) → void {}
-static method Extension|runtimeType(final core::String* #this) → core::int* {}
-static method Extension|get#runtimeType(final core::String* #this) → () →* core::int*
+static method Extension|set#hashCode(lowered final core::String* #this, core::int* value) → void {}
+static method Extension|runtimeType(lowered final core::String* #this) → core::int* {}
+static method Extension|get#runtimeType(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self::Extension|runtimeType(#this);
-static method Extension|==(final core::String* #this, dynamic other) → dynamic
+static method Extension|==(lowered final core::String* #this, dynamic other) → dynamic
   return false;
 static method Extension|toString() → core::String*
   return "Foo";
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect
index 55715f8..b53449f 100644
--- a/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect
@@ -48,13 +48,13 @@
   static method toString = self::Extension|toString;
   set hashCode = self::Extension|set#hashCode;
 }
-static method Extension|get#noSuchMethod(final core::String* #this) → core::int*
+static method Extension|get#noSuchMethod(lowered final core::String* #this) → core::int*
   return 42;
-static method Extension|set#hashCode(final core::String* #this, core::int* value) → void {}
-static method Extension|runtimeType(final core::String* #this) → core::int* {}
-static method Extension|get#runtimeType(final core::String* #this) → () →* core::int*
+static method Extension|set#hashCode(lowered final core::String* #this, core::int* value) → void {}
+static method Extension|runtimeType(lowered final core::String* #this) → core::int* {}
+static method Extension|get#runtimeType(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self::Extension|runtimeType(#this);
-static method Extension|==(final core::String* #this, dynamic other) → dynamic
+static method Extension|==(lowered final core::String* #this, dynamic other) → dynamic
   return false;
 static method Extension|toString() → core::String*
   return "Foo";
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect b/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect
index 6fb3b5f..4e95f3b 100644
--- a/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect
@@ -57,17 +57,17 @@
   method duplicateMethodName1 = self::UniqueExtensionName|duplicateMethodName1;
   tearoff duplicateMethodName1 = self::UniqueExtensionName|get#duplicateMethodName1;
 }
-static method DuplicateExtensionName|uniqueMethod1(final self::Class1* #this) → dynamic
+static method DuplicateExtensionName|uniqueMethod1(lowered final self::Class1* #this) → dynamic
   ;
-static method DuplicateExtensionName|get#uniqueMethod1(final self::Class1* #this) → () →* dynamic
+static method DuplicateExtensionName|get#uniqueMethod1(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::DuplicateExtensionName|uniqueMethod1(#this);
-static method DuplicateExtensionName|duplicateMethodName2(final self::Class1* #this) → dynamic
+static method DuplicateExtensionName|duplicateMethodName2(lowered final self::Class1* #this) → dynamic
   ;
-static method DuplicateExtensionName|get#duplicateMethodName2(final self::Class1* #this) → () →* dynamic
+static method DuplicateExtensionName|get#duplicateMethodName2(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::DuplicateExtensionName|duplicateMethodName2(#this);
-static method UniqueExtensionName|duplicateMethodName1(final self::Class1* #this) → dynamic
+static method UniqueExtensionName|duplicateMethodName1(lowered final self::Class1* #this) → dynamic
   ;
-static method UniqueExtensionName|get#duplicateMethodName1(final self::Class1* #this) → () →* dynamic
+static method UniqueExtensionName|get#duplicateMethodName1(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::UniqueExtensionName|duplicateMethodName1(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect b/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect
index 9764dae..a6fe24f 100644
--- a/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect
@@ -65,16 +65,16 @@
   method duplicateMethodName1 = self::UniqueExtensionName|duplicateMethodName1;
   tearoff duplicateMethodName1 = self::UniqueExtensionName|get#duplicateMethodName1;
 }
-static method DuplicateExtensionName|uniqueMethod1(final self::Class1* #this) → dynamic {}
-static method DuplicateExtensionName|get#uniqueMethod1(final self::Class1* #this) → () →* dynamic
+static method DuplicateExtensionName|uniqueMethod1(lowered final self::Class1* #this) → dynamic {}
+static method DuplicateExtensionName|get#uniqueMethod1(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::DuplicateExtensionName|uniqueMethod1(#this);
-static method DuplicateExtensionName|duplicateMethodName2(final self::Class1* #this) → dynamic
+static method DuplicateExtensionName|duplicateMethodName2(lowered final self::Class1* #this) → dynamic
   return 1;
-static method DuplicateExtensionName|get#duplicateMethodName2(final self::Class1* #this) → () →* dynamic
+static method DuplicateExtensionName|get#duplicateMethodName2(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::DuplicateExtensionName|duplicateMethodName2(#this);
-static method UniqueExtensionName|duplicateMethodName1(final self::Class1* #this) → dynamic
+static method UniqueExtensionName|duplicateMethodName1(lowered final self::Class1* #this) → dynamic
   return 1;
-static method UniqueExtensionName|get#duplicateMethodName1(final self::Class1* #this) → () →* dynamic
+static method UniqueExtensionName|get#duplicateMethodName1(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::UniqueExtensionName|duplicateMethodName1(#this);
 static method main() → dynamic {
   self::Class1* c1 = new self::Class1::•();
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect
index 9764dae..a6fe24f 100644
--- a/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect
@@ -65,16 +65,16 @@
   method duplicateMethodName1 = self::UniqueExtensionName|duplicateMethodName1;
   tearoff duplicateMethodName1 = self::UniqueExtensionName|get#duplicateMethodName1;
 }
-static method DuplicateExtensionName|uniqueMethod1(final self::Class1* #this) → dynamic {}
-static method DuplicateExtensionName|get#uniqueMethod1(final self::Class1* #this) → () →* dynamic
+static method DuplicateExtensionName|uniqueMethod1(lowered final self::Class1* #this) → dynamic {}
+static method DuplicateExtensionName|get#uniqueMethod1(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::DuplicateExtensionName|uniqueMethod1(#this);
-static method DuplicateExtensionName|duplicateMethodName2(final self::Class1* #this) → dynamic
+static method DuplicateExtensionName|duplicateMethodName2(lowered final self::Class1* #this) → dynamic
   return 1;
-static method DuplicateExtensionName|get#duplicateMethodName2(final self::Class1* #this) → () →* dynamic
+static method DuplicateExtensionName|get#duplicateMethodName2(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::DuplicateExtensionName|duplicateMethodName2(#this);
-static method UniqueExtensionName|duplicateMethodName1(final self::Class1* #this) → dynamic
+static method UniqueExtensionName|duplicateMethodName1(lowered final self::Class1* #this) → dynamic
   return 1;
-static method UniqueExtensionName|get#duplicateMethodName1(final self::Class1* #this) → () →* dynamic
+static method UniqueExtensionName|get#duplicateMethodName1(lowered final self::Class1* #this) → () →* dynamic
   return () → dynamic => self::UniqueExtensionName|duplicateMethodName1(#this);
 static method main() → dynamic {
   self::Class1* c1 = new self::Class1::•();
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.outline.expect b/pkg/front_end/testcases/extensions/default_values.dart.outline.expect
index 04ed817..9469573 100644
--- a/pkg/front_end/testcases/extensions/default_values.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/default_values.dart.outline.expect
@@ -27,21 +27,21 @@
   tearoff method3 = self::Extension|get#method3;
   static method staticMethod = self::Extension|staticMethod;
 }
-static method Extension|method0(final self::Class* #this, [dynamic a]) → dynamic
+static method Extension|method0(lowered final self::Class* #this, [dynamic a]) → dynamic
   ;
-static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#method0(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic a]) → dynamic => self::Extension|method0(#this, a);
-static method Extension|method1(final self::Class* #this, [dynamic a]) → dynamic
+static method Extension|method1(lowered final self::Class* #this, [dynamic a]) → dynamic
   ;
-static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#method1(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic a]) → dynamic => self::Extension|method1(#this, a);
-static method Extension|method2(final self::Class* #this, {dynamic b}) → dynamic
+static method Extension|method2(lowered final self::Class* #this, {dynamic b}) → dynamic
   ;
-static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
+static method Extension|get#method2(lowered final self::Class* #this) → ({b: dynamic}) →* dynamic
   return ({dynamic b}) → dynamic => self::Extension|method2(#this, b: b);
-static method Extension|method3(final self::Class* #this, {dynamic c}) → dynamic
+static method Extension|method3(lowered final self::Class* #this, {dynamic c}) → dynamic
   ;
-static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
+static method Extension|get#method3(lowered final self::Class* #this) → ({c: dynamic}) →* dynamic
   return ({dynamic c}) → dynamic => self::Extension|method3(#this, c: c);
 static method Extension|staticMethod() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.strong.expect b/pkg/front_end/testcases/extensions/default_values.dart.strong.expect
index c31a720..3c37068 100644
--- a/pkg/front_end/testcases/extensions/default_values.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/default_values.dart.strong.expect
@@ -28,21 +28,21 @@
   tearoff method3 = self::Extension|get#method3;
   static method staticMethod = self::Extension|staticMethod;
 }
-static method Extension|method0(final self::Class* #this, [dynamic a = #C1]) → dynamic
+static method Extension|method0(lowered final self::Class* #this, [dynamic a = #C1]) → dynamic
   return a;
-static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#method0(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic a = #C1]) → dynamic => self::Extension|method0(#this, a);
-static method Extension|method1(final self::Class* #this, [dynamic a = #C2]) → dynamic
+static method Extension|method1(lowered final self::Class* #this, [dynamic a = #C2]) → dynamic
   return a;
-static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#method1(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic a = #C2]) → dynamic => self::Extension|method1(#this, a);
-static method Extension|method2(final self::Class* #this, {dynamic b = #C3}) → dynamic
+static method Extension|method2(lowered final self::Class* #this, {dynamic b = #C3}) → dynamic
   return b;
-static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
+static method Extension|get#method2(lowered final self::Class* #this) → ({b: dynamic}) →* dynamic
   return ({dynamic b = #C3}) → dynamic => self::Extension|method2(#this, b: b);
-static method Extension|method3(final self::Class* #this, {dynamic c = #C4}) → dynamic
+static method Extension|method3(lowered final self::Class* #this, {dynamic c = #C4}) → dynamic
   return c.call();
-static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
+static method Extension|get#method3(lowered final self::Class* #this) → ({c: dynamic}) →* dynamic
   return ({dynamic c = #C4}) → dynamic => self::Extension|method3(#this, c: c);
 static method Extension|staticMethod() → dynamic
   return 123;
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect
index c31a720..3c37068 100644
--- a/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect
@@ -28,21 +28,21 @@
   tearoff method3 = self::Extension|get#method3;
   static method staticMethod = self::Extension|staticMethod;
 }
-static method Extension|method0(final self::Class* #this, [dynamic a = #C1]) → dynamic
+static method Extension|method0(lowered final self::Class* #this, [dynamic a = #C1]) → dynamic
   return a;
-static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#method0(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic a = #C1]) → dynamic => self::Extension|method0(#this, a);
-static method Extension|method1(final self::Class* #this, [dynamic a = #C2]) → dynamic
+static method Extension|method1(lowered final self::Class* #this, [dynamic a = #C2]) → dynamic
   return a;
-static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#method1(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic a = #C2]) → dynamic => self::Extension|method1(#this, a);
-static method Extension|method2(final self::Class* #this, {dynamic b = #C3}) → dynamic
+static method Extension|method2(lowered final self::Class* #this, {dynamic b = #C3}) → dynamic
   return b;
-static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
+static method Extension|get#method2(lowered final self::Class* #this) → ({b: dynamic}) →* dynamic
   return ({dynamic b = #C3}) → dynamic => self::Extension|method2(#this, b: b);
-static method Extension|method3(final self::Class* #this, {dynamic c = #C4}) → dynamic
+static method Extension|method3(lowered final self::Class* #this, {dynamic c = #C4}) → dynamic
   return c.call();
-static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
+static method Extension|get#method3(lowered final self::Class* #this) → ({c: dynamic}) →* dynamic
   return ({dynamic c = #C4}) → dynamic => self::Extension|method3(#this, c: c);
 static method Extension|staticMethod() → dynamic
   return 123;
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.outline.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.outline.expect
index bd4405e..b5db0d7 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.outline.expect
@@ -38,13 +38,13 @@
   ;
 static method Extension|staticMethod() → core::int*
   ;
-static method Extension|get#property(final core::int* #this) → core::int*
+static method Extension|get#property(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#property(final core::int* #this, core::int* value) → void
+static method Extension|set#property(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|method(final core::int* #this) → core::int*
+static method Extension|method(lowered final core::int* #this) → core::int*
   ;
-static method Extension|get#method(final core::int* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
   return () → core::int* => self2::Extension|method(#this);
 static get topLevelProperty() → core::int*
   ;
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.expect
index e9e8aad..eb88dad 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.expect
@@ -52,14 +52,14 @@
 }
 static method Extension|staticMethod() → core::int*
   return def::Extension|staticField;
-static method Extension|get#property(final core::int* #this) → core::int*
+static method Extension|get#property(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|set#property(final core::int* #this, core::int* value) → void {
+static method Extension|set#property(lowered final core::int* #this, core::int* value) → void {
   def::Extension|staticField = value;
 }
-static method Extension|method(final core::int* #this) → core::int*
+static method Extension|method(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|get#method(final core::int* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
   return () → core::int* => def::Extension|method(#this);
 static get topLevelProperty() → core::int*
   return def::Extension|staticField;
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
index 580ca3c..9a7758f 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
@@ -18,7 +18,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -45,7 +44,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -80,14 +78,14 @@
 }
 static method Extension|staticMethod() → core::int*
   return def::Extension|staticField;
-static method Extension|get#property(final core::int* #this) → core::int*
+static method Extension|get#property(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|set#property(final core::int* #this, core::int* value) → void {
+static method Extension|set#property(lowered final core::int* #this, core::int* value) → void {
   def::Extension|staticField = value;
 }
-static method Extension|method(final core::int* #this) → core::int*
+static method Extension|method(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|get#method(final core::int* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
   return () → core::int* => def::Extension|method(#this);
 static get topLevelProperty() → core::int*
   return def::Extension|staticField;
@@ -102,4 +100,4 @@
 Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:31 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:45 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:45 -> IntConstant(42)
-Extra constant evaluation: evaluated: 96, effectively constant: 3
+Extra constant evaluation: evaluated: 93, effectively constant: 3
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.outline.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.outline.expect
index 92e7dbc..a0ceed4 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.outline.expect
@@ -30,13 +30,13 @@
   ;
 static method Extension|staticMethod() → core::int*
   ;
-static method Extension|get#property(final core::int* #this) → core::int*
+static method Extension|get#property(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#property(final core::int* #this, core::int* value) → void
+static method Extension|set#property(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|method(final core::int* #this) → core::int*
+static method Extension|method(lowered final core::int* #this) → core::int*
   ;
-static method Extension|get#method(final core::int* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
   return () → core::int* => self2::Extension|method(#this);
 static get topLevelProperty() → core::int*
   ;
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.expect
index 310c8c4..614cb6f 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.expect
@@ -43,14 +43,14 @@
 }
 static method Extension|staticMethod() → core::int*
   return def::Extension|staticField;
-static method Extension|get#property(final core::int* #this) → core::int*
+static method Extension|get#property(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|set#property(final core::int* #this, core::int* value) → void {
+static method Extension|set#property(lowered final core::int* #this, core::int* value) → void {
   def::Extension|staticField = value;
 }
-static method Extension|method(final core::int* #this) → core::int*
+static method Extension|method(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|get#method(final core::int* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
   return () → core::int* => def::Extension|method(#this);
 static get topLevelProperty() → core::int*
   return def::Extension|staticField;
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
index 187e9da..41815d4 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -36,7 +35,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -71,14 +69,14 @@
 }
 static method Extension|staticMethod() → core::int*
   return def::Extension|staticField;
-static method Extension|get#property(final core::int* #this) → core::int*
+static method Extension|get#property(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|set#property(final core::int* #this, core::int* value) → void {
+static method Extension|set#property(lowered final core::int* #this, core::int* value) → void {
   def::Extension|staticField = value;
 }
-static method Extension|method(final core::int* #this) → core::int*
+static method Extension|method(lowered final core::int* #this) → core::int*
   return #this.{core::num::+}(def::Extension|staticField);
-static method Extension|get#method(final core::int* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
   return () → core::int* => def::Extension|method(#this);
 static get topLevelProperty() → core::int*
   return def::Extension|staticField;
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
index 2d17121..55a6232 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
@@ -85,103 +85,103 @@
   tearoff getterCalls = self::GenericExtension|get#getterCalls;
   set property = self::GenericExtension|set#property;
 }
-static method Extension|get#readGetter(final self::Class* #this) → () →* dynamic
+static method Extension|get#readGetter(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|readGetter(#this);
-static method Extension|readGetter(final self::Class* #this) → dynamic
+static method Extension|readGetter(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|writeSetterRequired(final self::Class* #this, dynamic value) → dynamic
+static method Extension|writeSetterRequired(lowered final self::Class* #this, dynamic value) → dynamic
   ;
-static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#writeSetterRequired(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
-static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value]) → dynamic
+static method Extension|writeSetterOptional(lowered final self::Class* #this, [dynamic value]) → dynamic
   ;
-static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#writeSetterOptional(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic value]) → dynamic => self::Extension|writeSetterOptional(#this, value);
-static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value}) → dynamic
+static method Extension|writeSetterNamed(lowered final self::Class* #this, {dynamic value}) → dynamic
   ;
-static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
+static method Extension|get#writeSetterNamed(lowered final self::Class* #this) → ({value: dynamic}) →* dynamic
   return ({dynamic value}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
-static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterNoArgs(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterRequired(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#tearOffGetterOptional(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterOptional(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#tearOffGetterNamed(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterNamed(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#property(final self::Class* #this) → dynamic
+static method Extension|get#property(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|set#property(final self::Class* #this, dynamic value) → void
+static method Extension|set#property(lowered final self::Class* #this, dynamic value) → void
   ;
-static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic
+static method Extension|invocations(lowered final self::Class* #this, dynamic value) → dynamic
   ;
-static method Extension|get#invocations(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#invocations(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|invocations(#this, value);
-static method Extension|get#tearOffs(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#tearOffs(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|tearOffs(#this, value);
-static method Extension|tearOffs(final self::Class* #this, dynamic value) → dynamic
+static method Extension|tearOffs(lowered final self::Class* #this, dynamic value) → dynamic
   ;
-static method Extension|getterCalls(final self::Class* #this, dynamic value) → dynamic
+static method Extension|getterCalls(lowered final self::Class* #this, dynamic value) → dynamic
   ;
-static method Extension|get#getterCalls(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#getterCalls(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|getterCalls(#this, value);
-static method GenericExtension|readGetter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|readGetter::T*>* #this) → self::GenericExtension|readGetter::T*
+static method GenericExtension|readGetter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|readGetter::T*>* #this) → self::GenericExtension|readGetter::T*
   ;
-static method GenericExtension|get#readGetter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#readGetter::T*>* #this) → () →* self::GenericExtension|get#readGetter::T*
+static method GenericExtension|get#readGetter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#readGetter::T*>* #this) → () →* self::GenericExtension|get#readGetter::T*
   return () → self::GenericExtension|get#readGetter::T* => self::GenericExtension|readGetter<self::GenericExtension|get#readGetter::T*>(#this);
-static method GenericExtension|writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterRequired::T*>* #this, self::GenericExtension|writeSetterRequired::T* value) → dynamic
+static method GenericExtension|writeSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterRequired::T*>* #this, self::GenericExtension|writeSetterRequired::T* value) → dynamic
   ;
-static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
+static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
   return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
-static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value]) → dynamic
+static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value]) → dynamic
   ;
-static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
+static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
   return ([self::GenericExtension|get#writeSetterOptional::T* value]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
-static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value}) → dynamic
+static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value}) → dynamic
   ;
-static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
+static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
   return ({self::GenericExtension|get#writeSetterNamed::T* value}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
-static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic
+static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic
   ;
-static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
-static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value]) → dynamic
+static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value]) → dynamic
   ;
-static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
+static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
-static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
+static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
-static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value}) → dynamic
+static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value}) → dynamic
   ;
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   ;
-static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void
+static method GenericExtension|set#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void
   ;
-static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#tearOffGetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#tearOffGetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#tearOffGetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#tearOffGetterGenericRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#tearOffGetterGenericOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#tearOffGetterGenericNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::T*>* #this) → dynamic
   ;
-static method GenericExtension|invocations<T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::T* = dynamic>(final self::GenericClass<self::GenericExtension|invocations::T*>* #this, self::GenericExtension|invocations::S* value) → dynamic
+static method GenericExtension|invocations<T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|invocations::T*>* #this, self::GenericExtension|invocations::S* value) → dynamic
   ;
-static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#invocations::T* = dynamic>(S* value) → dynamic => self::GenericExtension|invocations<self::GenericExtension|get#invocations::T*, S*>(#this, value);
-static method GenericExtension|tearOffs<T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::T* = dynamic>(final self::GenericClass<self::GenericExtension|tearOffs::T*>* #this, self::GenericExtension|tearOffs::S* value) → dynamic
+static method GenericExtension|tearOffs<T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|tearOffs::T*>* #this, self::GenericExtension|tearOffs::S* value) → dynamic
   ;
-static method GenericExtension|get#tearOffs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffs::T*>* #this) → <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#tearOffs<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffs::T*>* #this) → <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S* value) → dynamic => self::GenericExtension|tearOffs<self::GenericExtension|get#tearOffs::T*, S*>(#this, value);
-static method GenericExtension|getterCalls<T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::T* = dynamic>(final self::GenericClass<self::GenericExtension|getterCalls::T*>* #this, self::GenericExtension|getterCalls::S* value) → dynamic
+static method GenericExtension|getterCalls<T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|getterCalls::T*>* #this, self::GenericExtension|getterCalls::S* value) → dynamic
   ;
-static method GenericExtension|get#getterCalls<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#getterCalls::T*>* #this) → <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#getterCalls<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#getterCalls::T*>* #this) → <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S* value) → dynamic => self::GenericExtension|getterCalls<self::GenericExtension|get#getterCalls::T*, S*>(#this, value);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
index 17dadac..394a69b3 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
@@ -87,40 +87,40 @@
   tearoff getterCalls = self::GenericExtension|get#getterCalls;
   set property = self::GenericExtension|set#property;
 }
-static method Extension|get#readGetter(final self::Class* #this) → () →* dynamic
+static method Extension|get#readGetter(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|readGetter(#this);
-static method Extension|readGetter(final self::Class* #this) → dynamic {
+static method Extension|readGetter(lowered final self::Class* #this) → dynamic {
   return self::Extension|get#property(#this);
 }
-static method Extension|writeSetterRequired(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|writeSetterRequired(lowered final self::Class* #this, dynamic value) → dynamic {
   self::Extension|set#property(#this, value);
 }
-static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#writeSetterRequired(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
-static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value = #C1]) → dynamic {
+static method Extension|writeSetterOptional(lowered final self::Class* #this, [dynamic value = #C1]) → dynamic {
   self::Extension|set#property(#this, value);
 }
-static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#writeSetterOptional(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
-static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value = #C1}) → dynamic {
+static method Extension|writeSetterNamed(lowered final self::Class* #this, {dynamic value = #C1}) → dynamic {
   self::Extension|set#property(#this, value);
 }
-static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
+static method Extension|get#writeSetterNamed(lowered final self::Class* #this) → ({value: dynamic}) →* dynamic
   return ({dynamic value = #C1}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
-static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterNoArgs(lowered final self::Class* #this) → dynamic
   return self::Extension|get#readGetter(#this);
-static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterRequired(lowered final self::Class* #this) → dynamic
   return self::Extension|get#writeSetterRequired(#this);
-static method Extension|get#tearOffGetterOptional(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterOptional(lowered final self::Class* #this) → dynamic
   return self::Extension|get#writeSetterOptional(#this);
-static method Extension|get#tearOffGetterNamed(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterNamed(lowered final self::Class* #this) → dynamic
   return self::Extension|get#writeSetterNamed(#this);
-static method Extension|get#property(final self::Class* #this) → dynamic
+static method Extension|get#property(lowered final self::Class* #this) → dynamic
   return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, dynamic value) → void {
+static method Extension|set#property(lowered final self::Class* #this, dynamic value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|invocations(lowered final self::Class* #this, dynamic value) → dynamic {
   self::Extension|readGetter(#this);
   self::Extension|writeSetterRequired(#this, value);
   self::Extension|writeSetterOptional(#this);
@@ -128,11 +128,11 @@
   self::Extension|writeSetterNamed(#this);
   self::Extension|writeSetterNamed(#this, value: value);
 }
-static method Extension|get#invocations(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#invocations(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|invocations(#this, value);
-static method Extension|get#tearOffs(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#tearOffs(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|tearOffs(#this, value);
-static method Extension|tearOffs(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|tearOffs(lowered final self::Class* #this, dynamic value) → dynamic {
   () →* dynamic tearOffNoArgs = self::Extension|get#readGetter(#this);
   tearOffNoArgs.call();
   (dynamic) →* dynamic tearOffRequired = self::Extension|get#writeSetterRequired(#this);
@@ -144,7 +144,7 @@
   tearOffNamed.call();
   tearOffNamed.call(value: value);
 }
-static method Extension|getterCalls(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|getterCalls(lowered final self::Class* #this, dynamic value) → dynamic {
   self::Extension|get#tearOffGetterNoArgs(#this).call();
   self::Extension|get#tearOffGetterRequired(#this).call(value);
   self::Extension|get#tearOffGetterOptional(#this).call();
@@ -152,63 +152,63 @@
   self::Extension|get#tearOffGetterNamed(#this).call();
   self::Extension|get#tearOffGetterNamed(#this).call(value: value);
 }
-static method Extension|get#getterCalls(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#getterCalls(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|getterCalls(#this, value);
-static method GenericExtension|readGetter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|readGetter::T*>* #this) → self::GenericExtension|readGetter::T* {
+static method GenericExtension|readGetter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|readGetter::T*>* #this) → self::GenericExtension|readGetter::T* {
   return self::GenericExtension|get#property<self::GenericExtension|readGetter::T*>(#this);
 }
-static method GenericExtension|get#readGetter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#readGetter::T*>* #this) → () →* self::GenericExtension|get#readGetter::T*
+static method GenericExtension|get#readGetter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#readGetter::T*>* #this) → () →* self::GenericExtension|get#readGetter::T*
   return () → self::GenericExtension|get#readGetter::T* => self::GenericExtension|readGetter<self::GenericExtension|get#readGetter::T*>(#this);
-static method GenericExtension|writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterRequired::T*>* #this, self::GenericExtension|writeSetterRequired::T* value) → dynamic {
+static method GenericExtension|writeSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterRequired::T*>* #this, self::GenericExtension|writeSetterRequired::T* value) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|writeSetterRequired::T*>(#this, value);
 }
-static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
+static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
   return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
-static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
+static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::T*>(#this, value);
 }
-static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
+static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
   return ([self::GenericExtension|get#writeSetterOptional::T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
-static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
+static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::T*>(#this, value);
 }
-static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
+static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
   return ({self::GenericExtension|get#writeSetterNamed::T* value = #C1}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
-static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic {
+static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterRequired::T*>(#this, value);
 }
-static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
-static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
+static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::T*>(#this, value);
 }
-static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
+static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
-static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
+static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
-static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
+static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::T*>(#this, value);
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   return #this.{self::GenericClass::field};
-static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void {
+static method GenericExtension|set#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void {
   #this.{self::GenericClass::field} = value;
 }
-static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
   return self::GenericExtension|get#readGetter<self::GenericExtension|get#tearOffGetterNoArgs::T*>(#this);
-static method GenericExtension|get#tearOffGetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::T*>* #this) → dynamic
   return self::GenericExtension|get#writeSetterRequired<self::GenericExtension|get#tearOffGetterRequired::T*>(#this);
-static method GenericExtension|get#tearOffGetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::T*>* #this) → dynamic
   return self::GenericExtension|get#writeSetterOptional<self::GenericExtension|get#tearOffGetterOptional::T*>(#this);
-static method GenericExtension|get#tearOffGetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::T*>* #this) → dynamic
   return self::GenericExtension|get#writeSetterNamed<self::GenericExtension|get#tearOffGetterNamed::T*>(#this);
-static method GenericExtension|get#tearOffGetterGenericRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::T*>* #this) → dynamic
   return self::GenericExtension|get#genericWriteSetterRequired<self::GenericExtension|get#tearOffGetterGenericRequired::T*>(#this);
-static method GenericExtension|get#tearOffGetterGenericOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::T*>* #this) → dynamic
   return self::GenericExtension|get#genericWriteSetterOptional<self::GenericExtension|get#tearOffGetterGenericOptional::T*>(#this);
-static method GenericExtension|get#tearOffGetterGenericNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::T*>* #this) → dynamic
   return self::GenericExtension|get#genericWriteSetterNamed<self::GenericExtension|get#tearOffGetterGenericNamed::T*>(#this);
-static method GenericExtension|invocations<T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::T* = dynamic>(final self::GenericClass<self::GenericExtension|invocations::T*>* #this, self::GenericExtension|invocations::S* value) → dynamic {
+static method GenericExtension|invocations<T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|invocations::T*>* #this, self::GenericExtension|invocations::S* value) → dynamic {
   self::GenericExtension|readGetter<self::GenericExtension|invocations::T*>(#this);
   self::GenericExtension|writeSetterRequired<self::GenericExtension|invocations::T*>(#this, value);
   self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::T*>(#this);
@@ -231,9 +231,9 @@
   self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value: value);
   self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value: value);
 }
-static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#invocations::T* = dynamic>(S* value) → dynamic => self::GenericExtension|invocations<self::GenericExtension|get#invocations::T*, S*>(#this, value);
-static method GenericExtension|tearOffs<T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::T* = dynamic>(final self::GenericClass<self::GenericExtension|tearOffs::T*>* #this, self::GenericExtension|tearOffs::S* value) → dynamic {
+static method GenericExtension|tearOffs<T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|tearOffs::T*>* #this, self::GenericExtension|tearOffs::S* value) → dynamic {
   () →* self::GenericExtension|tearOffs::T* tearOffNoArgs = self::GenericExtension|get#readGetter<self::GenericExtension|tearOffs::T*>(#this);
   tearOffNoArgs.call();
   (self::GenericExtension|tearOffs::T*) →* dynamic tearOffRequired = self::GenericExtension|get#writeSetterRequired<self::GenericExtension|tearOffs::T*>(#this);
@@ -263,9 +263,9 @@
   genericTearOffNamed.call<self::GenericExtension|tearOffs::T*>(value: value);
   genericTearOffNamed.call<self::GenericExtension|tearOffs::S*>(value: value);
 }
-static method GenericExtension|get#tearOffs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffs::T*>* #this) → <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#tearOffs<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffs::T*>* #this) → <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S* value) → dynamic => self::GenericExtension|tearOffs<self::GenericExtension|get#tearOffs::T*, S*>(#this, value);
-static method GenericExtension|getterCalls<T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::T* = dynamic>(final self::GenericClass<self::GenericExtension|getterCalls::T*>* #this, self::GenericExtension|getterCalls::S* value) → dynamic {
+static method GenericExtension|getterCalls<T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|getterCalls::T*>* #this, self::GenericExtension|getterCalls::S* value) → dynamic {
   self::GenericExtension|get#tearOffGetterNoArgs<self::GenericExtension|getterCalls::T*>(#this).call();
   self::GenericExtension|get#tearOffGetterRequired<self::GenericExtension|getterCalls::T*>(#this).call(value);
   self::GenericExtension|get#tearOffGetterOptional<self::GenericExtension|getterCalls::T*>(#this).call();
@@ -288,7 +288,7 @@
   self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::T*>(#this).call<self::GenericExtension|getterCalls::T*>(value: value);
   self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::T*>(#this).call<self::GenericExtension|getterCalls::S*>(value: value);
 }
-static method GenericExtension|get#getterCalls<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#getterCalls::T*>* #this) → <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#getterCalls<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#getterCalls::T*>* #this) → <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S* value) → dynamic => self::GenericExtension|getterCalls<self::GenericExtension|get#getterCalls::T*, S*>(#this, value);
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
index 17dadac..394a69b3 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
@@ -87,40 +87,40 @@
   tearoff getterCalls = self::GenericExtension|get#getterCalls;
   set property = self::GenericExtension|set#property;
 }
-static method Extension|get#readGetter(final self::Class* #this) → () →* dynamic
+static method Extension|get#readGetter(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|readGetter(#this);
-static method Extension|readGetter(final self::Class* #this) → dynamic {
+static method Extension|readGetter(lowered final self::Class* #this) → dynamic {
   return self::Extension|get#property(#this);
 }
-static method Extension|writeSetterRequired(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|writeSetterRequired(lowered final self::Class* #this, dynamic value) → dynamic {
   self::Extension|set#property(#this, value);
 }
-static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#writeSetterRequired(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
-static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value = #C1]) → dynamic {
+static method Extension|writeSetterOptional(lowered final self::Class* #this, [dynamic value = #C1]) → dynamic {
   self::Extension|set#property(#this, value);
 }
-static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
+static method Extension|get#writeSetterOptional(lowered final self::Class* #this) → ([dynamic]) →* dynamic
   return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
-static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value = #C1}) → dynamic {
+static method Extension|writeSetterNamed(lowered final self::Class* #this, {dynamic value = #C1}) → dynamic {
   self::Extension|set#property(#this, value);
 }
-static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
+static method Extension|get#writeSetterNamed(lowered final self::Class* #this) → ({value: dynamic}) →* dynamic
   return ({dynamic value = #C1}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
-static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterNoArgs(lowered final self::Class* #this) → dynamic
   return self::Extension|get#readGetter(#this);
-static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterRequired(lowered final self::Class* #this) → dynamic
   return self::Extension|get#writeSetterRequired(#this);
-static method Extension|get#tearOffGetterOptional(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterOptional(lowered final self::Class* #this) → dynamic
   return self::Extension|get#writeSetterOptional(#this);
-static method Extension|get#tearOffGetterNamed(final self::Class* #this) → dynamic
+static method Extension|get#tearOffGetterNamed(lowered final self::Class* #this) → dynamic
   return self::Extension|get#writeSetterNamed(#this);
-static method Extension|get#property(final self::Class* #this) → dynamic
+static method Extension|get#property(lowered final self::Class* #this) → dynamic
   return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, dynamic value) → void {
+static method Extension|set#property(lowered final self::Class* #this, dynamic value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|invocations(lowered final self::Class* #this, dynamic value) → dynamic {
   self::Extension|readGetter(#this);
   self::Extension|writeSetterRequired(#this, value);
   self::Extension|writeSetterOptional(#this);
@@ -128,11 +128,11 @@
   self::Extension|writeSetterNamed(#this);
   self::Extension|writeSetterNamed(#this, value: value);
 }
-static method Extension|get#invocations(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#invocations(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|invocations(#this, value);
-static method Extension|get#tearOffs(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#tearOffs(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|tearOffs(#this, value);
-static method Extension|tearOffs(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|tearOffs(lowered final self::Class* #this, dynamic value) → dynamic {
   () →* dynamic tearOffNoArgs = self::Extension|get#readGetter(#this);
   tearOffNoArgs.call();
   (dynamic) →* dynamic tearOffRequired = self::Extension|get#writeSetterRequired(#this);
@@ -144,7 +144,7 @@
   tearOffNamed.call();
   tearOffNamed.call(value: value);
 }
-static method Extension|getterCalls(final self::Class* #this, dynamic value) → dynamic {
+static method Extension|getterCalls(lowered final self::Class* #this, dynamic value) → dynamic {
   self::Extension|get#tearOffGetterNoArgs(#this).call();
   self::Extension|get#tearOffGetterRequired(#this).call(value);
   self::Extension|get#tearOffGetterOptional(#this).call();
@@ -152,63 +152,63 @@
   self::Extension|get#tearOffGetterNamed(#this).call();
   self::Extension|get#tearOffGetterNamed(#this).call(value: value);
 }
-static method Extension|get#getterCalls(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#getterCalls(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic value) → dynamic => self::Extension|getterCalls(#this, value);
-static method GenericExtension|readGetter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|readGetter::T*>* #this) → self::GenericExtension|readGetter::T* {
+static method GenericExtension|readGetter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|readGetter::T*>* #this) → self::GenericExtension|readGetter::T* {
   return self::GenericExtension|get#property<self::GenericExtension|readGetter::T*>(#this);
 }
-static method GenericExtension|get#readGetter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#readGetter::T*>* #this) → () →* self::GenericExtension|get#readGetter::T*
+static method GenericExtension|get#readGetter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#readGetter::T*>* #this) → () →* self::GenericExtension|get#readGetter::T*
   return () → self::GenericExtension|get#readGetter::T* => self::GenericExtension|readGetter<self::GenericExtension|get#readGetter::T*>(#this);
-static method GenericExtension|writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterRequired::T*>* #this, self::GenericExtension|writeSetterRequired::T* value) → dynamic {
+static method GenericExtension|writeSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterRequired::T*>* #this, self::GenericExtension|writeSetterRequired::T* value) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|writeSetterRequired::T*>(#this, value);
 }
-static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
+static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
   return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
-static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
+static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::T*>(#this, value);
 }
-static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
+static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
   return ([self::GenericExtension|get#writeSetterOptional::T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
-static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
+static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::T*>(#this, value);
 }
-static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
+static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
   return ({self::GenericExtension|get#writeSetterNamed::T* value = #C1}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
-static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic {
+static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterRequired::T*>(#this, value);
 }
-static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
-static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
+static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::T*>(#this, value);
 }
-static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
+static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
-static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
+static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
   return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
-static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
+static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
   self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::T*>(#this, value);
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   return #this.{self::GenericClass::field};
-static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void {
+static method GenericExtension|set#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void {
   #this.{self::GenericClass::field} = value;
 }
-static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
   return self::GenericExtension|get#readGetter<self::GenericExtension|get#tearOffGetterNoArgs::T*>(#this);
-static method GenericExtension|get#tearOffGetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterRequired::T*>* #this) → dynamic
   return self::GenericExtension|get#writeSetterRequired<self::GenericExtension|get#tearOffGetterRequired::T*>(#this);
-static method GenericExtension|get#tearOffGetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterOptional::T*>* #this) → dynamic
   return self::GenericExtension|get#writeSetterOptional<self::GenericExtension|get#tearOffGetterOptional::T*>(#this);
-static method GenericExtension|get#tearOffGetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterNamed::T*>* #this) → dynamic
   return self::GenericExtension|get#writeSetterNamed<self::GenericExtension|get#tearOffGetterNamed::T*>(#this);
-static method GenericExtension|get#tearOffGetterGenericRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericRequired<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericRequired::T*>* #this) → dynamic
   return self::GenericExtension|get#genericWriteSetterRequired<self::GenericExtension|get#tearOffGetterGenericRequired::T*>(#this);
-static method GenericExtension|get#tearOffGetterGenericOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericOptional<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericOptional::T*>* #this) → dynamic
   return self::GenericExtension|get#genericWriteSetterOptional<self::GenericExtension|get#tearOffGetterGenericOptional::T*>(#this);
-static method GenericExtension|get#tearOffGetterGenericNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::T*>* #this) → dynamic
+static method GenericExtension|get#tearOffGetterGenericNamed<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffGetterGenericNamed::T*>* #this) → dynamic
   return self::GenericExtension|get#genericWriteSetterNamed<self::GenericExtension|get#tearOffGetterGenericNamed::T*>(#this);
-static method GenericExtension|invocations<T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::T* = dynamic>(final self::GenericClass<self::GenericExtension|invocations::T*>* #this, self::GenericExtension|invocations::S* value) → dynamic {
+static method GenericExtension|invocations<T extends core::Object* = dynamic, S extends self::GenericExtension|invocations::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|invocations::T*>* #this, self::GenericExtension|invocations::S* value) → dynamic {
   self::GenericExtension|readGetter<self::GenericExtension|invocations::T*>(#this);
   self::GenericExtension|writeSetterRequired<self::GenericExtension|invocations::T*>(#this, value);
   self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::T*>(#this);
@@ -231,9 +231,9 @@
   self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value: value);
   self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value: value);
 }
-static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#invocations::T* = dynamic>(S* value) → dynamic => self::GenericExtension|invocations<self::GenericExtension|get#invocations::T*, S*>(#this, value);
-static method GenericExtension|tearOffs<T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::T* = dynamic>(final self::GenericClass<self::GenericExtension|tearOffs::T*>* #this, self::GenericExtension|tearOffs::S* value) → dynamic {
+static method GenericExtension|tearOffs<T extends core::Object* = dynamic, S extends self::GenericExtension|tearOffs::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|tearOffs::T*>* #this, self::GenericExtension|tearOffs::S* value) → dynamic {
   () →* self::GenericExtension|tearOffs::T* tearOffNoArgs = self::GenericExtension|get#readGetter<self::GenericExtension|tearOffs::T*>(#this);
   tearOffNoArgs.call();
   (self::GenericExtension|tearOffs::T*) →* dynamic tearOffRequired = self::GenericExtension|get#writeSetterRequired<self::GenericExtension|tearOffs::T*>(#this);
@@ -263,9 +263,9 @@
   genericTearOffNamed.call<self::GenericExtension|tearOffs::T*>(value: value);
   genericTearOffNamed.call<self::GenericExtension|tearOffs::S*>(value: value);
 }
-static method GenericExtension|get#tearOffs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffs::T*>* #this) → <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#tearOffs<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#tearOffs::T*>* #this) → <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#tearOffs::T* = dynamic>(S* value) → dynamic => self::GenericExtension|tearOffs<self::GenericExtension|get#tearOffs::T*, S*>(#this, value);
-static method GenericExtension|getterCalls<T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::T* = dynamic>(final self::GenericClass<self::GenericExtension|getterCalls::T*>* #this, self::GenericExtension|getterCalls::S* value) → dynamic {
+static method GenericExtension|getterCalls<T extends core::Object* = dynamic, S extends self::GenericExtension|getterCalls::T* = dynamic>(lowered final self::GenericClass<self::GenericExtension|getterCalls::T*>* #this, self::GenericExtension|getterCalls::S* value) → dynamic {
   self::GenericExtension|get#tearOffGetterNoArgs<self::GenericExtension|getterCalls::T*>(#this).call();
   self::GenericExtension|get#tearOffGetterRequired<self::GenericExtension|getterCalls::T*>(#this).call(value);
   self::GenericExtension|get#tearOffGetterOptional<self::GenericExtension|getterCalls::T*>(#this).call();
@@ -288,7 +288,7 @@
   self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::T*>(#this).call<self::GenericExtension|getterCalls::T*>(value: value);
   self::GenericExtension|get#tearOffGetterGenericNamed<self::GenericExtension|getterCalls::T*>(#this).call<self::GenericExtension|getterCalls::S*>(value: value);
 }
-static method GenericExtension|get#getterCalls<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#getterCalls::T*>* #this) → <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S*) →* dynamic
+static method GenericExtension|get#getterCalls<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#getterCalls::T*>* #this) → <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S*) →* dynamic
   return <S extends self::GenericExtension|get#getterCalls::T* = dynamic>(S* value) → dynamic => self::GenericExtension|getterCalls<self::GenericExtension|get#getterCalls::T*, S*>(#this, value);
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect
index 7dd4ee1..4453608 100644
--- a/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.outline.expect
@@ -89,21 +89,21 @@
   ;
 static method Extension|getterCallsFromStaticContext(core::int* value) → dynamic
   ;
-static method Extension|invocationsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|invocationsFromInstanceContext::T*>* #this, self::Extension|invocationsFromInstanceContext::T* value) → dynamic
+static method Extension|invocationsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|invocationsFromInstanceContext::T*>* #this, self::Extension|invocationsFromInstanceContext::T* value) → dynamic
   ;
-static method Extension|get#invocationsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#invocationsFromInstanceContext::T*>* #this) → (self::Extension|get#invocationsFromInstanceContext::T*) →* dynamic
+static method Extension|get#invocationsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#invocationsFromInstanceContext::T*>* #this) → (self::Extension|get#invocationsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#invocationsFromInstanceContext::T* value) → dynamic => self::Extension|invocationsFromInstanceContext<self::Extension|get#invocationsFromInstanceContext::T*>(#this, value);
-static method Extension|tearOffsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|tearOffsFromInstanceContext::T*>* #this, self::Extension|tearOffsFromInstanceContext::T* value) → dynamic
+static method Extension|tearOffsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|tearOffsFromInstanceContext::T*>* #this, self::Extension|tearOffsFromInstanceContext::T* value) → dynamic
   ;
-static method Extension|get#tearOffsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#tearOffsFromInstanceContext::T*>* #this) → (self::Extension|get#tearOffsFromInstanceContext::T*) →* dynamic
+static method Extension|get#tearOffsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#tearOffsFromInstanceContext::T*>* #this) → (self::Extension|get#tearOffsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#tearOffsFromInstanceContext::T* value) → dynamic => self::Extension|tearOffsFromInstanceContext<self::Extension|get#tearOffsFromInstanceContext::T*>(#this, value);
-static method Extension|fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|fieldAccessFromInstanceContext::T*>* #this) → dynamic
+static method Extension|fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|fieldAccessFromInstanceContext::T*>* #this) → dynamic
   ;
-static method Extension|get#fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#fieldAccessFromInstanceContext::T*>* #this) → () →* dynamic
+static method Extension|get#fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#fieldAccessFromInstanceContext::T*>* #this) → () →* dynamic
   return () → dynamic => self::Extension|fieldAccessFromInstanceContext<self::Extension|get#fieldAccessFromInstanceContext::T*>(#this);
-static method Extension|getterCallsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|getterCallsFromInstanceContext::T*>* #this, self::Extension|getterCallsFromInstanceContext::T* value) → dynamic
+static method Extension|getterCallsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|getterCallsFromInstanceContext::T*>* #this, self::Extension|getterCallsFromInstanceContext::T* value) → dynamic
   ;
-static method Extension|get#getterCallsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#getterCallsFromInstanceContext::T*>* #this) → (self::Extension|get#getterCallsFromInstanceContext::T*) →* dynamic
+static method Extension|get#getterCallsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#getterCallsFromInstanceContext::T*>* #this) → (self::Extension|get#getterCallsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#getterCallsFromInstanceContext::T* value) → dynamic => self::Extension|getterCallsFromInstanceContext<self::Extension|get#getterCallsFromInstanceContext::T*>(#this, value);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
index 1a55006..f9c2886 100644
--- a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
@@ -155,7 +155,7 @@
   self::Extension|tearOffGetterGenericNamed.call(value: value);
   self::Extension|tearOffGetterGenericNamed.call<core::int*>(value: value);
 }
-static method Extension|invocationsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|invocationsFromInstanceContext::T*>* #this, self::Extension|invocationsFromInstanceContext::T* value) → dynamic {
+static method Extension|invocationsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|invocationsFromInstanceContext::T*>* #this, self::Extension|invocationsFromInstanceContext::T* value) → dynamic {
   self::Extension|readGetter();
   self::Extension|writeSetterRequired(value);
   self::Extension|writeSetterOptional();
@@ -173,9 +173,9 @@
   self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::T*>(value: value);
   self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::T*>(value: value);
 }
-static method Extension|get#invocationsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#invocationsFromInstanceContext::T*>* #this) → (self::Extension|get#invocationsFromInstanceContext::T*) →* dynamic
+static method Extension|get#invocationsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#invocationsFromInstanceContext::T*>* #this) → (self::Extension|get#invocationsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#invocationsFromInstanceContext::T* value) → dynamic => self::Extension|invocationsFromInstanceContext<self::Extension|get#invocationsFromInstanceContext::T*>(#this, value);
-static method Extension|tearOffsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|tearOffsFromInstanceContext::T*>* #this, self::Extension|tearOffsFromInstanceContext::T* value) → dynamic {
+static method Extension|tearOffsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|tearOffsFromInstanceContext::T*>* #this, self::Extension|tearOffsFromInstanceContext::T* value) → dynamic {
   () →* dynamic tearOffNoArgs = #C2;
   tearOffNoArgs.call();
   (dynamic) →* dynamic tearOffRequired = #C3;
@@ -200,15 +200,15 @@
   tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>(value: value);
   tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>(value: value);
 }
-static method Extension|get#tearOffsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#tearOffsFromInstanceContext::T*>* #this) → (self::Extension|get#tearOffsFromInstanceContext::T*) →* dynamic
+static method Extension|get#tearOffsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#tearOffsFromInstanceContext::T*>* #this) → (self::Extension|get#tearOffsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#tearOffsFromInstanceContext::T* value) → dynamic => self::Extension|tearOffsFromInstanceContext<self::Extension|get#tearOffsFromInstanceContext::T*>(#this, value);
-static method Extension|fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|fieldAccessFromInstanceContext::T*>* #this) → dynamic {
+static method Extension|fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|fieldAccessFromInstanceContext::T*>* #this) → dynamic {
   self::Extension|field = self::Extension|property;
   self::Extension|property = self::Extension|field;
 }
-static method Extension|get#fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#fieldAccessFromInstanceContext::T*>* #this) → () →* dynamic
+static method Extension|get#fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#fieldAccessFromInstanceContext::T*>* #this) → () →* dynamic
   return () → dynamic => self::Extension|fieldAccessFromInstanceContext<self::Extension|get#fieldAccessFromInstanceContext::T*>(#this);
-static method Extension|getterCallsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|getterCallsFromInstanceContext::T*>* #this, self::Extension|getterCallsFromInstanceContext::T* value) → dynamic {
+static method Extension|getterCallsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|getterCallsFromInstanceContext::T*>* #this, self::Extension|getterCallsFromInstanceContext::T* value) → dynamic {
   self::Extension|tearOffGetterNoArgs.call();
   self::Extension|tearOffGetterRequired.call(value);
   self::Extension|tearOffGetterOptional.call();
@@ -226,7 +226,7 @@
   self::Extension|tearOffGetterGenericNamed.call(value: value);
   self::Extension|tearOffGetterGenericNamed.call<self::Extension|getterCallsFromInstanceContext::T*>(value: value);
 }
-static method Extension|get#getterCallsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#getterCallsFromInstanceContext::T*>* #this) → (self::Extension|get#getterCallsFromInstanceContext::T*) →* dynamic
+static method Extension|get#getterCallsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#getterCallsFromInstanceContext::T*>* #this) → (self::Extension|get#getterCallsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#getterCallsFromInstanceContext::T* value) → dynamic => self::Extension|getterCallsFromInstanceContext<self::Extension|get#getterCallsFromInstanceContext::T*>(#this, value);
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
index 1a55006..f9c2886 100644
--- a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
@@ -155,7 +155,7 @@
   self::Extension|tearOffGetterGenericNamed.call(value: value);
   self::Extension|tearOffGetterGenericNamed.call<core::int*>(value: value);
 }
-static method Extension|invocationsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|invocationsFromInstanceContext::T*>* #this, self::Extension|invocationsFromInstanceContext::T* value) → dynamic {
+static method Extension|invocationsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|invocationsFromInstanceContext::T*>* #this, self::Extension|invocationsFromInstanceContext::T* value) → dynamic {
   self::Extension|readGetter();
   self::Extension|writeSetterRequired(value);
   self::Extension|writeSetterOptional();
@@ -173,9 +173,9 @@
   self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::T*>(value: value);
   self::Extension|genericWriteSetterNamed<self::Extension|invocationsFromInstanceContext::T*>(value: value);
 }
-static method Extension|get#invocationsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#invocationsFromInstanceContext::T*>* #this) → (self::Extension|get#invocationsFromInstanceContext::T*) →* dynamic
+static method Extension|get#invocationsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#invocationsFromInstanceContext::T*>* #this) → (self::Extension|get#invocationsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#invocationsFromInstanceContext::T* value) → dynamic => self::Extension|invocationsFromInstanceContext<self::Extension|get#invocationsFromInstanceContext::T*>(#this, value);
-static method Extension|tearOffsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|tearOffsFromInstanceContext::T*>* #this, self::Extension|tearOffsFromInstanceContext::T* value) → dynamic {
+static method Extension|tearOffsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|tearOffsFromInstanceContext::T*>* #this, self::Extension|tearOffsFromInstanceContext::T* value) → dynamic {
   () →* dynamic tearOffNoArgs = #C2;
   tearOffNoArgs.call();
   (dynamic) →* dynamic tearOffRequired = #C3;
@@ -200,15 +200,15 @@
   tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>(value: value);
   tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>(value: value);
 }
-static method Extension|get#tearOffsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#tearOffsFromInstanceContext::T*>* #this) → (self::Extension|get#tearOffsFromInstanceContext::T*) →* dynamic
+static method Extension|get#tearOffsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#tearOffsFromInstanceContext::T*>* #this) → (self::Extension|get#tearOffsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#tearOffsFromInstanceContext::T* value) → dynamic => self::Extension|tearOffsFromInstanceContext<self::Extension|get#tearOffsFromInstanceContext::T*>(#this, value);
-static method Extension|fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|fieldAccessFromInstanceContext::T*>* #this) → dynamic {
+static method Extension|fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|fieldAccessFromInstanceContext::T*>* #this) → dynamic {
   self::Extension|field = self::Extension|property;
   self::Extension|property = self::Extension|field;
 }
-static method Extension|get#fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#fieldAccessFromInstanceContext::T*>* #this) → () →* dynamic
+static method Extension|get#fieldAccessFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#fieldAccessFromInstanceContext::T*>* #this) → () →* dynamic
   return () → dynamic => self::Extension|fieldAccessFromInstanceContext<self::Extension|get#fieldAccessFromInstanceContext::T*>(#this);
-static method Extension|getterCallsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|getterCallsFromInstanceContext::T*>* #this, self::Extension|getterCallsFromInstanceContext::T* value) → dynamic {
+static method Extension|getterCallsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|getterCallsFromInstanceContext::T*>* #this, self::Extension|getterCallsFromInstanceContext::T* value) → dynamic {
   self::Extension|tearOffGetterNoArgs.call();
   self::Extension|tearOffGetterRequired.call(value);
   self::Extension|tearOffGetterOptional.call();
@@ -226,7 +226,7 @@
   self::Extension|tearOffGetterGenericNamed.call(value: value);
   self::Extension|tearOffGetterGenericNamed.call<self::Extension|getterCallsFromInstanceContext::T*>(value: value);
 }
-static method Extension|get#getterCallsFromInstanceContext<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#getterCallsFromInstanceContext::T*>* #this) → (self::Extension|get#getterCallsFromInstanceContext::T*) →* dynamic
+static method Extension|get#getterCallsFromInstanceContext<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#getterCallsFromInstanceContext::T*>* #this) → (self::Extension|get#getterCallsFromInstanceContext::T*) →* dynamic
   return (self::Extension|get#getterCallsFromInstanceContext::T* value) → dynamic => self::Extension|getterCallsFromInstanceContext<self::Extension|get#getterCallsFromInstanceContext::T*>(#this, value);
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect
index a2ea0ee..1f8c07d 100644
--- a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect
@@ -25,13 +25,13 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method ClassExtension|method(final self::Class* #this) → core::int*
+static method ClassExtension|method(lowered final self::Class* #this) → core::int*
   ;
-static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
+static method ClassExtension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::ClassExtension|method(#this);
-static method Extension|method(final dynamic #this) → core::int*
+static method Extension|method(lowered final dynamic #this) → core::int*
   ;
-static method Extension|get#method(final dynamic #this) → () →* core::int*
+static method Extension|get#method(lowered final dynamic #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect
index 627b139..3f2a400 100644
--- a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect
@@ -26,13 +26,13 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method ClassExtension|method(final self::Class* #this) → core::int*
+static method ClassExtension|method(lowered final self::Class* #this) → core::int*
   return 42;
-static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
+static method ClassExtension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::ClassExtension|method(#this);
-static method Extension|method(final dynamic #this) → core::int*
+static method Extension|method(lowered final dynamic #this) → core::int*
   return 87;
-static method Extension|get#method(final dynamic #this) → () →* core::int*
+static method Extension|get#method(lowered final dynamic #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
 static method main() → dynamic {
   dynamic c0 = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect
index 627b139..3f2a400 100644
--- a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect
@@ -26,13 +26,13 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method ClassExtension|method(final self::Class* #this) → core::int*
+static method ClassExtension|method(lowered final self::Class* #this) → core::int*
   return 42;
-static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
+static method ClassExtension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::ClassExtension|method(#this);
-static method Extension|method(final dynamic #this) → core::int*
+static method Extension|method(lowered final dynamic #this) → core::int*
   return 87;
-static method Extension|get#method(final dynamic #this) → () →* core::int*
+static method Extension|get#method(lowered final dynamic #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
 static method main() → dynamic {
   dynamic c0 = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.outline.expect
index 293f3df..c567e2c 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.outline.expect
@@ -34,29 +34,29 @@
   tearoff genericMethod = self::Extension2|get#genericMethod;
   set field = self::Extension2|set#field;
 }
-static method Extension1|get#field(final self::Class* #this) → core::int*
+static method Extension1|get#field(lowered final self::Class* #this) → core::int*
   ;
-static method Extension1|set#field(final self::Class* #this, core::int* value) → void
+static method Extension1|set#field(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension1|method(final self::Class* #this) → core::int*
+static method Extension1|method(lowered final self::Class* #this) → core::int*
   ;
-static method Extension1|get#method(final self::Class* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class* #this, self::Extension1|genericMethod::T* t) → core::int*
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class* #this, self::Extension1|genericMethod::T* t) → core::int*
   ;
-static method Extension1|get#genericMethod(final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension2|get#field(final self::Class* #this) → core::int*
+static method Extension2|get#field(lowered final self::Class* #this) → core::int*
   ;
-static method Extension2|set#field(final self::Class* #this, core::int* value) → void
+static method Extension2|set#field(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension2|method(final self::Class* #this) → core::int*
+static method Extension2|method(lowered final self::Class* #this) → core::int*
   ;
-static method Extension2|get#method(final self::Class* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class* #this, self::Extension2|genericMethod::T* t) → core::int*
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class* #this, self::Extension2|genericMethod::T* t) → core::int*
   ;
-static method Extension2|get#genericMethod(final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect
index 1de117d..c216317 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect
@@ -35,31 +35,31 @@
   tearoff genericMethod = self::Extension2|get#genericMethod;
   set field = self::Extension2|set#field;
 }
-static method Extension1|get#field(final self::Class* #this) → core::int*
+static method Extension1|get#field(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field1};
-static method Extension1|set#field(final self::Class* #this, core::int* value) → void {
+static method Extension1|set#field(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field1} = value;
 }
-static method Extension1|method(final self::Class* #this) → core::int*
+static method Extension1|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field1};
-static method Extension1|get#method(final self::Class* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class* #this, self::Extension1|genericMethod::T* t) → core::int*
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class* #this, self::Extension1|genericMethod::T* t) → core::int*
   return #this.{self::Class::field1}.{core::num::+}(t) as{TypeError} core::int*;
-static method Extension1|get#genericMethod(final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension2|get#field(final self::Class* #this) → core::int*
+static method Extension2|get#field(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field2};
-static method Extension2|set#field(final self::Class* #this, core::int* value) → void {
+static method Extension2|set#field(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field2} = value;
 }
-static method Extension2|method(final self::Class* #this) → core::int*
+static method Extension2|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field2};
-static method Extension2|get#method(final self::Class* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class* #this, self::Extension2|genericMethod::T* t) → core::int*
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class* #this, self::Extension2|genericMethod::T* t) → core::int*
   return #this.{self::Class::field2}.{core::num::+}(t) as{TypeError} core::int*;
-static method Extension2|get#genericMethod(final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect
index 47097a2..e1fd4f1 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect
@@ -35,31 +35,31 @@
   tearoff genericMethod = self::Extension2|get#genericMethod;
   set field = self::Extension2|set#field;
 }
-static method Extension1|get#field(final self::Class* #this) → core::int*
+static method Extension1|get#field(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field1};
-static method Extension1|set#field(final self::Class* #this, core::int* value) → void {
+static method Extension1|set#field(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field1} = value;
 }
-static method Extension1|method(final self::Class* #this) → core::int*
+static method Extension1|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field1};
-static method Extension1|get#method(final self::Class* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class* #this, self::Extension1|genericMethod::T* t) → core::int*
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class* #this, self::Extension1|genericMethod::T* t) → core::int*
   return #this.{self::Class::field1}.{core::num::+}(t) as{TypeError} core::int*;
-static method Extension1|get#genericMethod(final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension2|get#field(final self::Class* #this) → core::int*
+static method Extension2|get#field(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field2};
-static method Extension2|set#field(final self::Class* #this, core::int* value) → void {
+static method Extension2|set#field(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field2} = value;
 }
-static method Extension2|method(final self::Class* #this) → core::int*
+static method Extension2|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field2};
-static method Extension2|get#method(final self::Class* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class* #this, self::Extension2|genericMethod::T* t) → core::int*
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class* #this, self::Extension2|genericMethod::T* t) → core::int*
   return #this.{self::Class::field2}.{core::num::+}(t) as{TypeError} core::int*;
-static method Extension2|get#genericMethod(final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.outline.expect
index 21fc22e..eb41182 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.outline.expect
@@ -45,15 +45,15 @@
   method genericMethod1 = self::GenericExtension|genericMethod1;
   tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   ;
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
   ;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
   return (self::GenericExtension|get#method::T* t) → self::GenericExtension|get#method::T* => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this, t);
-static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
+static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
   ;
-static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
+static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
   return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::T*, S*>(#this, s);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.expect
index 3d6532f..429ac83 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.expect
@@ -49,15 +49,15 @@
   method genericMethod1 = self::GenericExtension|genericMethod1;
   tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   return null;
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
   return null;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
   return (self::GenericExtension|get#method::T* t) → self::GenericExtension|get#method::T* => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this, t);
-static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
+static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
   return null;
-static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
+static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
   return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::T*, S*>(#this, s);
 static method main() → dynamic {
   self::A* aVariable;
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.transformed.expect
index 3d6532f..429ac83 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.strong.transformed.expect
@@ -49,15 +49,15 @@
   method genericMethod1 = self::GenericExtension|genericMethod1;
   tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   return null;
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
   return null;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
   return (self::GenericExtension|get#method::T* t) → self::GenericExtension|get#method::T* => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this, t);
-static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
+static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
   return null;
-static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
+static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
   return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::T*, S*>(#this, s);
 static method main() → dynamic {
   self::A* aVariable;
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.outline.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.outline.expect
index c63ea7d..633ea25 100644
--- a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.outline.expect
@@ -36,29 +36,29 @@
   set field = self::Extension2|set#field;
 }
 static field core::String* Extension1|latestType;
-static method Extension1|get#field<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#field::T*>* #this) → self::Extension1|get#field::T*
+static method Extension1|get#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#field::T*>* #this) → self::Extension1|get#field::T*
   ;
-static method Extension1|set#field<T extends core::num* = core::num*>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void
+static method Extension1|set#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void
   ;
-static method Extension1|method<T extends core::num* = core::num*>(final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T*
+static method Extension1|method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T*
   ;
-static method Extension1|get#method<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#method::T*>* #this) → () →* self::Extension1|get#method::T*
+static method Extension1|get#method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#method::T*>* #this) → () →* self::Extension1|get#method::T*
   return () → self::Extension1|get#method::T* => self::Extension1|method<self::Extension1|get#method::T*>(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(final self::Class<self::Extension1|genericMethod::T*>* #this, self::Extension1|genericMethod::S* t) → self::Extension1|genericMethod::T*
+static method Extension1|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(lowered final self::Class<self::Extension1|genericMethod::T*>* #this, self::Extension1|genericMethod::S* t) → self::Extension1|genericMethod::T*
   ;
-static method Extension1|get#genericMethod<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension1|get#genericMethod::T*
+static method Extension1|get#genericMethod<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension1|get#genericMethod::T*
   return <S extends core::num* = core::num*>(S* t) → self::Extension1|get#genericMethod::T* => self::Extension1|genericMethod<self::Extension1|get#genericMethod::T*, S*>(#this, t);
-static method Extension2|get#field<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
+static method Extension2|get#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
   ;
-static method Extension2|set#field<T extends core::num* = core::num*>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void
+static method Extension2|set#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void
   ;
-static method Extension2|method<T extends core::num* = core::num*>(final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
+static method Extension2|method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
   ;
-static method Extension2|get#method<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#method::T*>* #this) → () →* self::Extension2|get#method::T*
+static method Extension2|get#method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#method::T*>* #this) → () →* self::Extension2|get#method::T*
   return () → self::Extension2|get#method::T* => self::Extension2|method<self::Extension2|get#method::T*>(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(final self::Class<self::Extension2|genericMethod::T*>* #this, self::Extension2|genericMethod::S* t) → self::Extension2|genericMethod::T*
+static method Extension2|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(lowered final self::Class<self::Extension2|genericMethod::T*>* #this, self::Extension2|genericMethod::S* t) → self::Extension2|genericMethod::T*
   ;
-static method Extension2|get#genericMethod<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension2|get#genericMethod::T*
+static method Extension2|get#genericMethod<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension2|get#genericMethod::T*
   return <S extends core::num* = core::num*>(S* t) → self::Extension2|get#genericMethod::T* => self::Extension2|genericMethod<self::Extension2|get#genericMethod::T*, S*>(#this, t);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect
index adc49e4..1934541 100644
--- a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect
@@ -37,38 +37,38 @@
   set field = self::Extension2|set#field;
 }
 static field core::String* Extension1|latestType;
-static method Extension1|get#field<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#field::T*>* #this) → self::Extension1|get#field::T* {
+static method Extension1|get#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#field::T*>* #this) → self::Extension1|get#field::T* {
   self::Extension1|latestType = "${self::Extension1|get#field::T*}";
   return #this.{self::Class::field1};
 }
-static method Extension1|set#field<T extends core::num* = core::num*>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void {
+static method Extension1|set#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void {
   self::Extension1|latestType = "${self::Extension1|set#field::T*}";
   #this.{self::Class::field1} = value;
 }
-static method Extension1|method<T extends core::num* = core::num*>(final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T* {
+static method Extension1|method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T* {
   self::Extension1|latestType = "${self::Extension1|method::T*}";
   return #this.{self::Class::field1};
 }
-static method Extension1|get#method<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#method::T*>* #this) → () →* self::Extension1|get#method::T*
+static method Extension1|get#method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#method::T*>* #this) → () →* self::Extension1|get#method::T*
   return () → self::Extension1|get#method::T* => self::Extension1|method<self::Extension1|get#method::T*>(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(final self::Class<self::Extension1|genericMethod::T*>* #this, self::Extension1|genericMethod::S* t) → self::Extension1|genericMethod::T* {
+static method Extension1|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(lowered final self::Class<self::Extension1|genericMethod::T*>* #this, self::Extension1|genericMethod::S* t) → self::Extension1|genericMethod::T* {
   self::Extension1|latestType = "${self::Extension1|genericMethod::T*}:${self::Extension1|genericMethod::S*}";
   return #this.{self::Class::field1}.{core::num::+}(t) as{TypeError} self::Extension1|genericMethod::T*;
 }
-static method Extension1|get#genericMethod<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension1|get#genericMethod::T*
+static method Extension1|get#genericMethod<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension1|get#genericMethod::T*
   return <S extends core::num* = core::num*>(S* t) → self::Extension1|get#genericMethod::T* => self::Extension1|genericMethod<self::Extension1|get#genericMethod::T*, S*>(#this, t);
-static method Extension2|get#field<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
+static method Extension2|get#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
   return #this.{self::Class::field2};
-static method Extension2|set#field<T extends core::num* = core::num*>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void {
+static method Extension2|set#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void {
   #this.{self::Class::field2} = value;
 }
-static method Extension2|method<T extends core::num* = core::num*>(final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
+static method Extension2|method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
   return #this.{self::Class::field2};
-static method Extension2|get#method<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#method::T*>* #this) → () →* self::Extension2|get#method::T*
+static method Extension2|get#method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#method::T*>* #this) → () →* self::Extension2|get#method::T*
   return () → self::Extension2|get#method::T* => self::Extension2|method<self::Extension2|get#method::T*>(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(final self::Class<self::Extension2|genericMethod::T*>* #this, self::Extension2|genericMethod::S* t) → self::Extension2|genericMethod::T*
+static method Extension2|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(lowered final self::Class<self::Extension2|genericMethod::T*>* #this, self::Extension2|genericMethod::S* t) → self::Extension2|genericMethod::T*
   return #this.{self::Class::field2}.{core::num::+}(t) as{TypeError} self::Extension2|genericMethod::T*;
-static method Extension2|get#genericMethod<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension2|get#genericMethod::T*
+static method Extension2|get#genericMethod<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension2|get#genericMethod::T*
   return <S extends core::num* = core::num*>(S* t) → self::Extension2|get#genericMethod::T* => self::Extension2|genericMethod<self::Extension2|get#genericMethod::T*, S*>(#this, t);
 static method main() → dynamic {
   self::Class<core::int*>* c = new self::Class::•<core::int*>(42, 87);
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect
index 7239cba..c99297a 100644
--- a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect
@@ -37,38 +37,38 @@
   set field = self::Extension2|set#field;
 }
 static field core::String* Extension1|latestType;
-static method Extension1|get#field<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#field::T*>* #this) → self::Extension1|get#field::T* {
+static method Extension1|get#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#field::T*>* #this) → self::Extension1|get#field::T* {
   self::Extension1|latestType = "${self::Extension1|get#field::T*}";
   return #this.{self::Class::field1};
 }
-static method Extension1|set#field<T extends core::num* = core::num*>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void {
+static method Extension1|set#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void {
   self::Extension1|latestType = "${self::Extension1|set#field::T*}";
   #this.{self::Class::field1} = value;
 }
-static method Extension1|method<T extends core::num* = core::num*>(final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T* {
+static method Extension1|method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T* {
   self::Extension1|latestType = "${self::Extension1|method::T*}";
   return #this.{self::Class::field1};
 }
-static method Extension1|get#method<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#method::T*>* #this) → () →* self::Extension1|get#method::T*
+static method Extension1|get#method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#method::T*>* #this) → () →* self::Extension1|get#method::T*
   return () → self::Extension1|get#method::T* => self::Extension1|method<self::Extension1|get#method::T*>(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(final self::Class<self::Extension1|genericMethod::T*>* #this, self::Extension1|genericMethod::S* t) → self::Extension1|genericMethod::T* {
+static method Extension1|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(lowered final self::Class<self::Extension1|genericMethod::T*>* #this, self::Extension1|genericMethod::S* t) → self::Extension1|genericMethod::T* {
   self::Extension1|latestType = "${self::Extension1|genericMethod::T*}:${self::Extension1|genericMethod::S*}";
   return #this.{self::Class::field1}.{core::num::+}(t) as{TypeError} self::Extension1|genericMethod::T*;
 }
-static method Extension1|get#genericMethod<T extends core::num* = core::num*>(final self::Class<self::Extension1|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension1|get#genericMethod::T*
+static method Extension1|get#genericMethod<T extends core::num* = core::num*>(lowered final self::Class<self::Extension1|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension1|get#genericMethod::T*
   return <S extends core::num* = core::num*>(S* t) → self::Extension1|get#genericMethod::T* => self::Extension1|genericMethod<self::Extension1|get#genericMethod::T*, S*>(#this, t);
-static method Extension2|get#field<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
+static method Extension2|get#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
   return #this.{self::Class::field2};
-static method Extension2|set#field<T extends core::num* = core::num*>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void {
+static method Extension2|set#field<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void {
   #this.{self::Class::field2} = value;
 }
-static method Extension2|method<T extends core::num* = core::num*>(final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
+static method Extension2|method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
   return #this.{self::Class::field2};
-static method Extension2|get#method<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#method::T*>* #this) → () →* self::Extension2|get#method::T*
+static method Extension2|get#method<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#method::T*>* #this) → () →* self::Extension2|get#method::T*
   return () → self::Extension2|get#method::T* => self::Extension2|method<self::Extension2|get#method::T*>(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(final self::Class<self::Extension2|genericMethod::T*>* #this, self::Extension2|genericMethod::S* t) → self::Extension2|genericMethod::T*
+static method Extension2|genericMethod<T extends core::num* = core::num*, S extends core::num* = core::num*>(lowered final self::Class<self::Extension2|genericMethod::T*>* #this, self::Extension2|genericMethod::S* t) → self::Extension2|genericMethod::T*
   return #this.{self::Class::field2}.{core::num::+}(t) as{TypeError} self::Extension2|genericMethod::T*;
-static method Extension2|get#genericMethod<T extends core::num* = core::num*>(final self::Class<self::Extension2|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension2|get#genericMethod::T*
+static method Extension2|get#genericMethod<T extends core::num* = core::num*>(lowered final self::Class<self::Extension2|get#genericMethod::T*>* #this) → <S extends core::num* = core::num*>(S*) →* self::Extension2|get#genericMethod::T*
   return <S extends core::num* = core::num*>(S* t) → self::Extension2|get#genericMethod::T* => self::Extension2|genericMethod<self::Extension2|get#genericMethod::T*, S*>(#this, t);
 static method main() → dynamic {
   self::Class<core::int*>* c = new self::Class::•<core::int*>(42, 87);
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.outline.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.outline.expect
index fee8d56..21fa5c7 100644
--- a/pkg/front_end/testcases/extensions/explicit_this.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.outline.expect
@@ -27,17 +27,17 @@
   method method4 = self::A2|method4;
   tearoff method4 = self::A2|get#method4;
 }
-static method A2|method2(final self::A1* #this) → void
+static method A2|method2(lowered final self::A1* #this) → void
   ;
-static method A2|get#method2(final self::A1* #this) → () →* void
+static method A2|get#method2(lowered final self::A1* #this) → () →* void
   return () → void => self::A2|method2(#this);
-static method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(lowered final self::A1* #this) → core::Object*
   ;
-static method A2|get#method3(final self::A1* #this) → () →* core::Object*
+static method A2|get#method3(lowered final self::A1* #this) → () →* core::Object*
   return () → core::Object* => self::A2|method3(#this);
-static method A2|method4(final self::A1* #this, core::Object* o) → void
+static method A2|method4(lowered final self::A1* #this, core::Object* o) → void
   ;
-static method A2|get#method4(final self::A1* #this) → (core::Object*) →* void
+static method A2|get#method4(lowered final self::A1* #this) → (core::Object*) →* void
   return (core::Object* o) → void => self::A2|method4(#this, o);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect
index ef5a89a..f13b8bd 100644
--- a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.expect
@@ -27,17 +27,17 @@
   method method4 = self::A2|method4;
   tearoff method4 = self::A2|get#method4;
 }
-static method A2|method2(final self::A1* #this) → void
+static method A2|method2(lowered final self::A1* #this) → void
   return #this.{self::A1::method1}();
-static method A2|get#method2(final self::A1* #this) → () →* void
+static method A2|get#method2(lowered final self::A1* #this) → () →* void
   return () → void => self::A2|method2(#this);
-static method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(lowered final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-static method A2|get#method3(final self::A1* #this) → () →* core::Object*
+static method A2|get#method3(lowered final self::A1* #this) → () →* core::Object*
   return () → core::Object* => self::A2|method3(#this);
-static method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(lowered final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
-static method A2|get#method4(final self::A1* #this) → (core::Object*) →* void
+static method A2|get#method4(lowered final self::A1* #this) → (core::Object*) →* void
   return (core::Object* o) → void => self::A2|method4(#this, o);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect
index ef5a89a..f13b8bd 100644
--- a/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.strong.transformed.expect
@@ -27,17 +27,17 @@
   method method4 = self::A2|method4;
   tearoff method4 = self::A2|get#method4;
 }
-static method A2|method2(final self::A1* #this) → void
+static method A2|method2(lowered final self::A1* #this) → void
   return #this.{self::A1::method1}();
-static method A2|get#method2(final self::A1* #this) → () →* void
+static method A2|get#method2(lowered final self::A1* #this) → () →* void
   return () → void => self::A2|method2(#this);
-static method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(lowered final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-static method A2|get#method3(final self::A1* #this) → () →* core::Object*
+static method A2|get#method3(lowered final self::A1* #this) → () →* core::Object*
   return () → core::Object* => self::A2|method3(#this);
-static method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(lowered final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
-static method A2|get#method4(final self::A1* #this) → (core::Object*) →* void
+static method A2|get#method4(lowered final self::A1* #this) → (core::Object*) →* void
   return (core::Object* o) → void => self::A2|method4(#this, o);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/export_from_dill/main.dart.outline.expect b/pkg/front_end/testcases/extensions/export_from_dill/main.dart.outline.expect
index e4074ca..70bd997 100644
--- a/pkg/front_end/testcases/extensions/export_from_dill/main.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/export_from_dill/main.dart.outline.expect
@@ -33,13 +33,13 @@
 static field core::int* Extension|staticField;
 static final field core::int* Extension|staticFinalField;
 static const field core::int* Extension|staticConstField = #C1;
-static method Extension|get#instanceProperty(final core::int* #this) → core::int*
+static method Extension|get#instanceProperty(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#instanceProperty(final core::int* #this, core::int* value) → void
+static method Extension|set#instanceProperty(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|instanceMethod(final core::int* #this) → void
+static method Extension|instanceMethod(lowered final core::int* #this) → void
   ;
-static method Extension|get#instanceMethod(final core::int* #this) → () →* void
+static method Extension|get#instanceMethod(lowered final core::int* #this) → () →* void
   return () → void => mai::Extension|instanceMethod(#this);
 static get Extension|staticProperty() → core::int*
   ;
diff --git a/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.expect b/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.expect
index 93ed84b..d7c5320 100644
--- a/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.expect
@@ -43,11 +43,11 @@
 static field core::int* Extension|staticField = 42;
 static final field core::int* Extension|staticFinalField = 42;
 static const field core::int* Extension|staticConstField = #C1;
-static method Extension|get#instanceProperty(final core::int* #this) → core::int*
+static method Extension|get#instanceProperty(lowered final core::int* #this) → core::int*
   return 42;
-static method Extension|set#instanceProperty(final core::int* #this, core::int* value) → void {}
-static method Extension|instanceMethod(final core::int* #this) → void {}
-static method Extension|get#instanceMethod(final core::int* #this) → () →* void
+static method Extension|set#instanceProperty(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|instanceMethod(lowered final core::int* #this) → void {}
+static method Extension|get#instanceMethod(lowered final core::int* #this) → () →* void
   return () → void => mai::Extension|instanceMethod(#this);
 static get Extension|staticProperty() → core::int*
   return 42;
diff --git a/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.transformed.expect
index 93ed84b..d7c5320 100644
--- a/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/export_from_dill/main.dart.strong.transformed.expect
@@ -43,11 +43,11 @@
 static field core::int* Extension|staticField = 42;
 static final field core::int* Extension|staticFinalField = 42;
 static const field core::int* Extension|staticConstField = #C1;
-static method Extension|get#instanceProperty(final core::int* #this) → core::int*
+static method Extension|get#instanceProperty(lowered final core::int* #this) → core::int*
   return 42;
-static method Extension|set#instanceProperty(final core::int* #this, core::int* value) → void {}
-static method Extension|instanceMethod(final core::int* #this) → void {}
-static method Extension|get#instanceMethod(final core::int* #this) → () →* void
+static method Extension|set#instanceProperty(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|instanceMethod(lowered final core::int* #this) → void {}
+static method Extension|get#instanceMethod(lowered final core::int* #this) → () →* void
   return () → void => mai::Extension|instanceMethod(#this);
 static get Extension|staticProperty() → core::int*
   return 42;
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.outline.expect b/pkg/front_end/testcases/extensions/export_twice.dart.outline.expect
index 1ee21db..a7b9b7e 100644
--- a/pkg/front_end/testcases/extensions/export_twice.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.outline.expect
@@ -29,9 +29,9 @@
   method method = self2::Extension|method;
   tearoff method = self2::Extension|get#method;
 }
-static method Extension|method(final self2::Class* #this) → dynamic
+static method Extension|method(lowered final self2::Class* #this) → dynamic
   ;
-static method Extension|get#method(final self2::Class* #this) → () →* dynamic
+static method Extension|get#method(lowered final self2::Class* #this) → () →* dynamic
   return () → dynamic => self2::Extension|method(#this);
 
 library;
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.strong.expect b/pkg/front_end/testcases/extensions/export_twice.dart.strong.expect
index bc0e513..d7eef99 100644
--- a/pkg/front_end/testcases/extensions/export_twice.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.strong.expect
@@ -32,8 +32,8 @@
   method method = exp::Extension|method;
   tearoff method = exp::Extension|get#method;
 }
-static method Extension|method(final exp::Class* #this) → dynamic {}
-static method Extension|get#method(final exp::Class* #this) → () →* dynamic
+static method Extension|method(lowered final exp::Class* #this) → dynamic {}
+static method Extension|get#method(lowered final exp::Class* #this) → () →* dynamic
   return () → dynamic => exp::Extension|method(#this);
 
 library;
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/export_twice.dart.strong.transformed.expect
index bc0e513..d7eef99 100644
--- a/pkg/front_end/testcases/extensions/export_twice.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.strong.transformed.expect
@@ -32,8 +32,8 @@
   method method = exp::Extension|method;
   tearoff method = exp::Extension|get#method;
 }
-static method Extension|method(final exp::Class* #this) → dynamic {}
-static method Extension|get#method(final exp::Class* #this) → () →* dynamic
+static method Extension|method(lowered final exp::Class* #this) → dynamic {}
+static method Extension|get#method(lowered final exp::Class* #this) → () →* dynamic
   return () → dynamic => exp::Extension|method(#this);
 
 library;
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect
index b95b9c6..bb8bde3 100644
--- a/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect
@@ -22,9 +22,9 @@
   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|call<T extends core::Object* = dynamic>(lowered 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*
+static method Extension|get#call<T extends core::Object* = dynamic>(lowered 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
   ;
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect
index 946cf57..12c9cd8 100644
--- a/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect
@@ -23,9 +23,9 @@
   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|call<T extends core::Object* = dynamic>(lowered 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*
+static method Extension|get#call<T extends core::Object* = dynamic>(lowered 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*>();
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
index 946cf57..12c9cd8 100644
--- a/pkg/front_end/testcases/extensions/extension_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.strong.transformed.expect
@@ -23,9 +23,9 @@
   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|call<T extends core::Object* = dynamic>(lowered 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*
+static method Extension|get#call<T extends core::Object* = dynamic>(lowered 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*>();
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect
index 85085ee..5bcfb3c 100644
--- a/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect
@@ -57,9 +57,9 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method Extension|method(final self::Class* #this) → dynamic
+static method Extension|method(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#method(final self::Class* #this) → () →* dynamic
+static method Extension|get#method(lowered 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
index d5d8cb2..e059431 100644
--- a/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.expect
@@ -58,7 +58,7 @@
   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
+static method Extension|method(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#method(lowered 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
index d5d8cb2..e059431 100644
--- a/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.transformed.expect
@@ -58,7 +58,7 @@
   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
+static method Extension|method(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#method(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|method(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect
index 78e8afc..4010730 100644
--- a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect
@@ -169,13 +169,13 @@
   set instanceSetterAndStaticField = self::Extension|set#instanceSetterAndStaticField;
 }
 static field core::int* Extension|duplicateStaticField;
-static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → void
+static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(lowered final core::int* #this) → void
   ;
-static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → () →* void
+static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(lowered final core::int* #this) → () →* void
   return () → void => self::Extension|duplicateInstanceMethod<self::Extension|get#duplicateInstanceMethod::T*>(#this);
 static get Extension|duplicateStaticGetter() → core::int*
   ;
@@ -183,17 +183,17 @@
   ;
 static method Extension|duplicateStaticMethod() → void
   ;
-static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void
   ;
 static get Extension|duplicateStaticGetterPlusSetter() → core::int*
   ;
@@ -207,17 +207,17 @@
   ;
 static set Extension|duplicateStaticGetterAndSetter(core::int* value) → void
   ;
-static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   ;
 static set Extension|instanceGetterAndStaticSetter(core::int* value) → void
   ;
 static get Extension|instanceSetterAndStaticGetter() → core::int*
   ;
-static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect
index 52aa6f4..fd72cf1 100644
--- a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect
@@ -169,25 +169,25 @@
   set instanceSetterAndStaticField = self::Extension|set#instanceSetterAndStaticField;
 }
 static field core::int* Extension|duplicateStaticField;
-static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → void {}
-static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → () →* void
+static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(lowered final core::int* #this) → void {}
+static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(lowered final core::int* #this) → () →* void
   return () → void => self::Extension|duplicateInstanceMethod<self::Extension|get#duplicateInstanceMethod::T*>(#this);
 static get Extension|duplicateStaticGetter() → core::int*
   return 0;
 static set Extension|duplicateStaticSetter(core::int* value) → void {}
 static method Extension|duplicateStaticMethod() → void {}
-static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
 static get Extension|duplicateStaticGetterPlusSetter() → core::int*
   return 0;
 static set Extension|duplicateStaticGetterPlusSetter(core::int* value) → void {}
@@ -197,13 +197,13 @@
 static get Extension|duplicateStaticGetterAndSetter() → core::int*
   return 0;
 static set Extension|duplicateStaticGetterAndSetter(core::int* value) → void {}
-static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
 static set Extension|instanceGetterAndStaticSetter(core::int* value) → void {}
 static get Extension|instanceSetterAndStaticGetter() → core::int*
   return 0;
-static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect
index 52aa6f4..fd72cf1 100644
--- a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect
@@ -169,25 +169,25 @@
   set instanceSetterAndStaticField = self::Extension|set#instanceSetterAndStaticField;
 }
 static field core::int* Extension|duplicateStaticField;
-static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → void {}
-static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → () →* void
+static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(lowered final core::int* #this) → void {}
+static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(lowered final core::int* #this) → () →* void
   return () → void => self::Extension|duplicateInstanceMethod<self::Extension|get#duplicateInstanceMethod::T*>(#this);
 static get Extension|duplicateStaticGetter() → core::int*
   return 0;
 static set Extension|duplicateStaticSetter(core::int* value) → void {}
 static method Extension|duplicateStaticMethod() → void {}
-static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
 static get Extension|duplicateStaticGetterPlusSetter() → core::int*
   return 0;
 static set Extension|duplicateStaticGetterPlusSetter(core::int* value) → void {}
@@ -197,13 +197,13 @@
 static get Extension|duplicateStaticGetterAndSetter() → core::int*
   return 0;
 static set Extension|duplicateStaticGetterAndSetter(core::int* value) → void {}
-static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
 static set Extension|instanceGetterAndStaticSetter(core::int* value) → void {}
 static get Extension|instanceSetterAndStaticGetter() → core::int*
   return 0;
-static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
-static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(lowered final core::int* #this, core::int* value) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.outline.expect
index f327887..20fb805 100644
--- a/pkg/front_end/testcases/extensions/extension_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.outline.expect
@@ -23,7 +23,7 @@
 extension E on self::C* {
   get two = self::E|get#two;
 }
-static method E|get#two(final self::C* #this) → core::int*
+static method E|get#two(lowered final self::C* #this) → core::int*
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.strong.expect
index b6a1193..fd6fddd 100644
--- a/pkg/front_end/testcases/extensions/extension_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.strong.expect
@@ -25,7 +25,7 @@
 extension E on self::C* {
   get two = self::E|get#two;
 }
-static method E|get#two(final self::C* #this) → core::int*
+static method E|get#two(lowered final self::C* #this) → core::int*
   return 2;
 static method main() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.strong.transformed.expect
index b6a1193..fd6fddd 100644
--- a/pkg/front_end/testcases/extensions/extension_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.strong.transformed.expect
@@ -25,7 +25,7 @@
 extension E on self::C* {
   get two = self::E|get#two;
 }
-static method E|get#two(final self::C* #this) → core::int*
+static method E|get#two(lowered final self::C* #this) → core::int*
   return 2;
 static method main() → dynamic {
   self::C* c = new self::C::•();
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 a46d986..f2ff9b4 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
@@ -46,27 +46,27 @@
 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|get#simpleSetter(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void
+static method Extension|set#simpleSetter(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension|get#mutatingSetter(final self::Class* #this) → core::int*
+static method Extension|get#mutatingSetter(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|set#mutatingSetter(final self::Class* #this, core::int* value) → void
+static method Extension|set#mutatingSetter(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension|get#setterWithReturn(final self::Class* #this) → core::int*
+static method Extension|get#setterWithReturn(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|set#setterWithReturn(final self::Class* #this, core::int* value) → void
+static method Extension|set#setterWithReturn(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension|get#setterWithClosure(final self::Class* #this) → core::int*
+static method Extension|get#setterWithClosure(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|set#setterWithClosure(final self::Class* #this, core::int* value) → void
+static method Extension|set#setterWithClosure(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension|testInternal(final self::Class* #this) → dynamic
+static method Extension|testInternal(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
+static method Extension|get#testInternal(lowered 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 GenericExtension|set#setter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void
   ;
 static method main() → 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 dbe9bc2..ce8e8ef 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
@@ -48,35 +48,35 @@
 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|get#simpleSetter(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void {
+static method Extension|set#simpleSetter(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|get#mutatingSetter(final self::Class* #this) → core::int*
+static method Extension|get#mutatingSetter(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#mutatingSetter(final self::Class* #this, core::int* value) → void {
+static method Extension|set#mutatingSetter(lowered final self::Class* #this, core::int* value) → void {
   value = value.{core::num::+}(1);
   #this.{self::Class::field} = value;
 }
-static method Extension|get#setterWithReturn(final self::Class* #this) → core::int*
+static method Extension|get#setterWithReturn(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#setterWithReturn(final self::Class* #this, core::int* value) → void {
+static method Extension|set#setterWithReturn(lowered final self::Class* #this, core::int* value) → void {
   if(value.{core::num::<}(0)) {
     #this.{self::Class::field} = value.{core::int::unary-}();
     return;
   }
   #this.{self::Class::field} = value;
 }
-static method Extension|get#setterWithClosure(final self::Class* #this) → core::int*
+static method Extension|get#setterWithClosure(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#setterWithClosure(final self::Class* #this, core::int* value) → void {
+static method Extension|set#setterWithClosure(lowered final self::Class* #this, core::int* value) → void {
   function abs(dynamic value) → dynamic {
     return value.<(0) as{TypeError,ForDynamic} core::bool* ?{dynamic} value.unary-() : value;
   }
   #this.{self::Class::field} = abs.call(value) as{TypeError,ForDynamic} core::int*;
 }
-static method Extension|testInternal(final self::Class* #this) → dynamic {
+static method Extension|testInternal(lowered final self::Class* #this) → dynamic {
   self::expect(null, #this.{self::Class::field});
   self::Extension|set#simpleSetter(#this, 0);
   self::expect(0, #this.{self::Class::field});
@@ -102,9 +102,9 @@
   self::expect(4.{core::int::unary-}(), let final core::int* #t11 = 4.{core::int::unary-}() in let final void #t12 = self::Extension|set#setterWithClosure(#this, #t11) in #t11);
   self::expect(4, #this.{self::Class::field});
 }
-static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
+static method Extension|get#testInternal(lowered 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 GenericExtension|set#setter<T extends core::Object* = dynamic>(lowered 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});
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 cb01579..37d083c 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
@@ -48,35 +48,35 @@
 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|get#simpleSetter(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void {
+static method Extension|set#simpleSetter(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|get#mutatingSetter(final self::Class* #this) → core::int*
+static method Extension|get#mutatingSetter(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#mutatingSetter(final self::Class* #this, core::int* value) → void {
+static method Extension|set#mutatingSetter(lowered final self::Class* #this, core::int* value) → void {
   value = value.{core::num::+}(1);
   #this.{self::Class::field} = value;
 }
-static method Extension|get#setterWithReturn(final self::Class* #this) → core::int*
+static method Extension|get#setterWithReturn(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#setterWithReturn(final self::Class* #this, core::int* value) → void {
+static method Extension|set#setterWithReturn(lowered final self::Class* #this, core::int* value) → void {
   if(value.{core::num::<}(0)) {
     #this.{self::Class::field} = value.{core::int::unary-}();
     return;
   }
   #this.{self::Class::field} = value;
 }
-static method Extension|get#setterWithClosure(final self::Class* #this) → core::int*
+static method Extension|get#setterWithClosure(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#setterWithClosure(final self::Class* #this, core::int* value) → void {
+static method Extension|set#setterWithClosure(lowered final self::Class* #this, core::int* value) → void {
   function abs(dynamic value) → dynamic {
     return value.<(0) as{TypeError,ForDynamic} core::bool* ?{dynamic} value.unary-() : value;
   }
   #this.{self::Class::field} = abs.call(value) as{TypeError,ForDynamic} core::int*;
 }
-static method Extension|testInternal(final self::Class* #this) → dynamic {
+static method Extension|testInternal(lowered final self::Class* #this) → dynamic {
   self::expect(null, #this.{self::Class::field});
   self::Extension|set#simpleSetter(#this, 0);
   self::expect(0, #this.{self::Class::field});
@@ -102,9 +102,9 @@
   self::expect(4.{core::int::unary-}(), let final core::int* #t11 = 4.{core::int::unary-}() in let final void #t12 = self::Extension|set#setterWithClosure(#this, #t11) in #t11);
   self::expect(4, #this.{self::Class::field});
 }
-static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
+static method Extension|get#testInternal(lowered 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 GenericExtension|set#setter<T extends core::Object* = dynamic>(lowered 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});
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
index 4044e84..2b0f430 100644
--- a/pkg/front_end/testcases/extensions/extension_setter_error.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.outline.expect
@@ -19,7 +19,7 @@
 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 GenericExtension|set#setter<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void
   ;
 static method error() → 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
index f0d0e30..b053b1b 100644
--- a/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
@@ -28,7 +28,7 @@
 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 GenericExtension|set#setter<T extends core::Object* = dynamic>(lowered 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>'.
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect
index 6155609..de2e8df 100644
--- a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect
@@ -20,9 +20,9 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
+static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(lowered final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
   ;
-static method Extension|get#method<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
+static method Extension|get#method<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
   return <R extends core::Object* = dynamic>(self::Extension|get#method::T* t) → R* => self::Extension|method<self::Extension|get#method::T*, R*>(#this, t);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect
index f7c38aa..e351a9e 100644
--- a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect
@@ -21,9 +21,9 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
+static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(lowered final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
   return null;
-static method Extension|get#method<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
+static method Extension|get#method<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
   return <R extends core::Object* = dynamic>(self::Extension|get#method::T* t) → R* => self::Extension|method<self::Extension|get#method::T*, R*>(#this, t);
 static method main() → dynamic {
   let final dynamic #t1 = self::Extension|method<core::int*, dynamic>(new self::Class::•<core::int*>(), 0) in #t1.{core::Object::==}(null) ?{core::String*} null : #t1.{core::Object::toString}();
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect
index f7c38aa..e351a9e 100644
--- a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect
@@ -21,9 +21,9 @@
   method method = self::Extension|method;
   tearoff method = self::Extension|get#method;
 }
-static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
+static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(lowered final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
   return null;
-static method Extension|get#method<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
+static method Extension|get#method<T extends core::Object* = dynamic>(lowered final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
   return <R extends core::Object* = dynamic>(self::Extension|get#method::T* t) → R* => self::Extension|method<self::Extension|get#method::T*, R*>(#this, t);
 static method main() → dynamic {
   let final dynamic #t1 = self::Extension|method<core::int*, dynamic>(new self::Class::•<core::int*>(), 0) in #t1.{core::Object::==}(null) ?{core::String*} null : #t1.{core::Object::toString}();
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect
index 9d49790..c1bc20e 100644
--- a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect
@@ -30,17 +30,17 @@
   get m3 = self::Extension1|get#m3;
   set m4 = self::Extension1|set#m4;
 }
-static method Extension0|set#m1(final self::Class* #this, core::int* x) → void
+static method Extension0|set#m1(lowered final self::Class* #this, core::int* x) → void
   ;
-static method Extension0|get#m2(final self::Class* #this) → core::int*
+static method Extension0|get#m2(lowered final self::Class* #this) → core::int*
   ;
-static method Extension0|set#m3(final self::Class* #this, core::int* x) → void
+static method Extension0|set#m3(lowered final self::Class* #this, core::int* x) → void
   ;
-static method Extension0|get#m4(final self::Class* #this) → core::int*
+static method Extension0|get#m4(lowered final self::Class* #this) → core::int*
   ;
-static method Extension1|get#m3(final self::Class* #this) → core::int*
+static method Extension1|get#m3(lowered final self::Class* #this) → core::int*
   ;
-static method Extension1|set#m4(final self::Class* #this, core::int* x) → void
+static method Extension1|set#m4(lowered final self::Class* #this, core::int* x) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect
index 966e6eb..4c0c516 100644
--- a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect
@@ -93,15 +93,15 @@
   get m3 = self::Extension1|get#m3;
   set m4 = self::Extension1|set#m4;
 }
-static method Extension0|set#m1(final self::Class* #this, core::int* x) → void {}
-static method Extension0|get#m2(final self::Class* #this) → core::int*
+static method Extension0|set#m1(lowered final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m2(lowered final self::Class* #this) → core::int*
   return 0;
-static method Extension0|set#m3(final self::Class* #this, core::int* x) → void {}
-static method Extension0|get#m4(final self::Class* #this) → core::int*
+static method Extension0|set#m3(lowered final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m4(lowered final self::Class* #this) → core::int*
   return 0;
-static method Extension1|get#m3(final self::Class* #this) → core::int*
+static method Extension1|get#m3(lowered final self::Class* #this) → core::int*
   return 0;
-static method Extension1|set#m4(final self::Class* #this, core::int* x) → void {}
+static method Extension1|set#m4(lowered final self::Class* #this, core::int* x) → void {}
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
   self::expect(0, c.{self::Class::m1});
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect
index 966e6eb..4c0c516 100644
--- a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect
@@ -93,15 +93,15 @@
   get m3 = self::Extension1|get#m3;
   set m4 = self::Extension1|set#m4;
 }
-static method Extension0|set#m1(final self::Class* #this, core::int* x) → void {}
-static method Extension0|get#m2(final self::Class* #this) → core::int*
+static method Extension0|set#m1(lowered final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m2(lowered final self::Class* #this) → core::int*
   return 0;
-static method Extension0|set#m3(final self::Class* #this, core::int* x) → void {}
-static method Extension0|get#m4(final self::Class* #this) → core::int*
+static method Extension0|set#m3(lowered final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m4(lowered final self::Class* #this) → core::int*
   return 0;
-static method Extension1|get#m3(final self::Class* #this) → core::int*
+static method Extension1|get#m3(lowered final self::Class* #this) → core::int*
   return 0;
-static method Extension1|set#m4(final self::Class* #this, core::int* x) → void {}
+static method Extension1|set#m4(lowered final self::Class* #this, core::int* x) → void {}
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
   self::expect(0, c.{self::Class::m1});
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.outline.expect b/pkg/front_end/testcases/extensions/if_null.dart.outline.expect
index 3d3aea8..1ce7da8 100644
--- a/pkg/front_end/testcases/extensions/if_null.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/if_null.dart.outline.expect
@@ -23,13 +23,13 @@
   tearoff method = self::Extension|get#method;
   set property = self::Extension|set#property;
 }
-static method Extension|get#property(final self::Class* #this) → core::int*
+static method Extension|get#property(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|set#property(final self::Class* #this, core::int* value) → void
+static method Extension|set#property(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension|method(final self::Class* #this) → core::int*
+static method Extension|method(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|get#method(final self::Class* #this) → () →* core::int*
+static method Extension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.strong.expect b/pkg/front_end/testcases/extensions/if_null.dart.strong.expect
index 4a04ad0..e4d6312 100644
--- a/pkg/front_end/testcases/extensions/if_null.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/if_null.dart.strong.expect
@@ -24,14 +24,14 @@
   tearoff method = self::Extension|get#method;
   set property = self::Extension|set#property;
 }
-static method Extension|get#property(final self::Class* #this) → core::int*
+static method Extension|get#property(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, core::int* value) → void {
+static method Extension|set#property(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|method(final self::Class* #this) → core::int*
+static method Extension|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|get#method(final self::Class* #this) → () →* core::int*
+static method Extension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
 static method main() → dynamic {
   self::Class* c;
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect
index cd0b1b3..f3e6b96 100644
--- a/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect
@@ -24,14 +24,14 @@
   tearoff method = self::Extension|get#method;
   set property = self::Extension|set#property;
 }
-static method Extension|get#property(final self::Class* #this) → core::int*
+static method Extension|get#property(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, core::int* value) → void {
+static method Extension|set#property(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|method(final self::Class* #this) → core::int*
+static method Extension|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|get#method(final self::Class* #this) → () →* core::int*
+static method Extension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
 static method main() → dynamic {
   self::Class* c;
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.outline.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.outline.expect
index 21fc22e..eb41182 100644
--- a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.outline.expect
@@ -45,15 +45,15 @@
   method genericMethod1 = self::GenericExtension|genericMethod1;
   tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   ;
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
   ;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
   return (self::GenericExtension|get#method::T* t) → self::GenericExtension|get#method::T* => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this, t);
-static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
+static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
   ;
-static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
+static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
   return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::T*, S*>(#this, s);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.expect
index e9f7f82..68819f0 100644
--- a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.expect
@@ -49,15 +49,15 @@
   method genericMethod1 = self::GenericExtension|genericMethod1;
   tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   return null;
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
   return null;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
   return (self::GenericExtension|get#method::T* t) → self::GenericExtension|get#method::T* => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this, t);
-static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
+static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
   return null;
-static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
+static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
   return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::T*, S*>(#this, s);
 static method main() → dynamic {
   self::A* aVariable;
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.transformed.expect
index e9f7f82..68819f0 100644
--- a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.strong.transformed.expect
@@ -49,15 +49,15 @@
   method genericMethod1 = self::GenericExtension|genericMethod1;
   tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
 }
-static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
+static method GenericExtension|get#property<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
   return null;
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this, self::GenericExtension|method::T* t) → self::GenericExtension|method::T*
   return null;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → (self::GenericExtension|get#method::T*) →* self::GenericExtension|get#method::T*
   return (self::GenericExtension|get#method::T* t) → self::GenericExtension|get#method::T* => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this, t);
-static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
+static method GenericExtension|genericMethod1<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|genericMethod1::T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
   return null;
-static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
+static method GenericExtension|get#genericMethod1<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#genericMethod1::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
   return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::T*, S*>(#this, s);
 static method main() → dynamic {
   self::A* aVariable;
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.outline.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.outline.expect
index fee8d56..21fa5c7 100644
--- a/pkg/front_end/testcases/extensions/implicit_this.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.outline.expect
@@ -27,17 +27,17 @@
   method method4 = self::A2|method4;
   tearoff method4 = self::A2|get#method4;
 }
-static method A2|method2(final self::A1* #this) → void
+static method A2|method2(lowered final self::A1* #this) → void
   ;
-static method A2|get#method2(final self::A1* #this) → () →* void
+static method A2|get#method2(lowered final self::A1* #this) → () →* void
   return () → void => self::A2|method2(#this);
-static method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(lowered final self::A1* #this) → core::Object*
   ;
-static method A2|get#method3(final self::A1* #this) → () →* core::Object*
+static method A2|get#method3(lowered final self::A1* #this) → () →* core::Object*
   return () → core::Object* => self::A2|method3(#this);
-static method A2|method4(final self::A1* #this, core::Object* o) → void
+static method A2|method4(lowered final self::A1* #this, core::Object* o) → void
   ;
-static method A2|get#method4(final self::A1* #this) → (core::Object*) →* void
+static method A2|get#method4(lowered final self::A1* #this) → (core::Object*) →* void
   return (core::Object* o) → void => self::A2|method4(#this, o);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect
index ef5a89a..f13b8bd 100644
--- a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.expect
@@ -27,17 +27,17 @@
   method method4 = self::A2|method4;
   tearoff method4 = self::A2|get#method4;
 }
-static method A2|method2(final self::A1* #this) → void
+static method A2|method2(lowered final self::A1* #this) → void
   return #this.{self::A1::method1}();
-static method A2|get#method2(final self::A1* #this) → () →* void
+static method A2|get#method2(lowered final self::A1* #this) → () →* void
   return () → void => self::A2|method2(#this);
-static method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(lowered final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-static method A2|get#method3(final self::A1* #this) → () →* core::Object*
+static method A2|get#method3(lowered final self::A1* #this) → () →* core::Object*
   return () → core::Object* => self::A2|method3(#this);
-static method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(lowered final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
-static method A2|get#method4(final self::A1* #this) → (core::Object*) →* void
+static method A2|get#method4(lowered final self::A1* #this) → (core::Object*) →* void
   return (core::Object* o) → void => self::A2|method4(#this, o);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect
index ef5a89a..f13b8bd 100644
--- a/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.strong.transformed.expect
@@ -27,17 +27,17 @@
   method method4 = self::A2|method4;
   tearoff method4 = self::A2|get#method4;
 }
-static method A2|method2(final self::A1* #this) → void
+static method A2|method2(lowered final self::A1* #this) → void
   return #this.{self::A1::method1}();
-static method A2|get#method2(final self::A1* #this) → () →* void
+static method A2|get#method2(lowered final self::A1* #this) → () →* void
   return () → void => self::A2|method2(#this);
-static method A2|method3(final self::A1* #this) → core::Object*
+static method A2|method3(lowered final self::A1* #this) → core::Object*
   return #this.{self::A1::field};
-static method A2|get#method3(final self::A1* #this) → () →* core::Object*
+static method A2|get#method3(lowered final self::A1* #this) → () →* core::Object*
   return () → core::Object* => self::A2|method3(#this);
-static method A2|method4(final self::A1* #this, core::Object* o) → void {
+static method A2|method4(lowered final self::A1* #this, core::Object* o) → void {
   #this.{self::A1::field} = o;
 }
-static method A2|get#method4(final self::A1* #this) → (core::Object*) →* void
+static method A2|get#method4(lowered final self::A1* #this) → (core::Object*) →* void
   return (core::Object* o) → void => self::A2|method4(#this, o);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/import_from_dill/main.dart.outline.expect b/pkg/front_end/testcases/extensions/import_from_dill/main.dart.outline.expect
index ccc1535..71c7348 100644
--- a/pkg/front_end/testcases/extensions/import_from_dill/main.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/import_from_dill/main.dart.outline.expect
@@ -25,13 +25,13 @@
 static field core::int* Extension|staticField;
 static final field core::int* Extension|staticFinalField;
 static const field core::int* Extension|staticConstField = #C1;
-static method Extension|get#instanceProperty(final core::int* #this) → core::int*
+static method Extension|get#instanceProperty(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#instanceProperty(final core::int* #this, core::int* value) → void
+static method Extension|set#instanceProperty(lowered final core::int* #this, core::int* value) → void
   ;
-static method Extension|instanceMethod(final core::int* #this) → void
+static method Extension|instanceMethod(lowered final core::int* #this) → void
   ;
-static method Extension|get#instanceMethod(final core::int* #this) → () →* void
+static method Extension|get#instanceMethod(lowered final core::int* #this) → () →* void
   return () → void => self2::Extension|instanceMethod(#this);
 static get Extension|staticProperty() → core::int*
   ;
diff --git a/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.expect b/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.expect
index 1672c049..dda54b1 100644
--- a/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.expect
@@ -35,11 +35,11 @@
 static field core::int* Extension|staticField = 42;
 static final field core::int* Extension|staticFinalField = 42;
 static const field core::int* Extension|staticConstField = #C1;
-static method Extension|get#instanceProperty(final core::int* #this) → core::int*
+static method Extension|get#instanceProperty(lowered final core::int* #this) → core::int*
   return 42;
-static method Extension|set#instanceProperty(final core::int* #this, core::int* value) → void {}
-static method Extension|instanceMethod(final core::int* #this) → void {}
-static method Extension|get#instanceMethod(final core::int* #this) → () →* void
+static method Extension|set#instanceProperty(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|instanceMethod(lowered final core::int* #this) → void {}
+static method Extension|get#instanceMethod(lowered final core::int* #this) → () →* void
   return () → void => mai::Extension|instanceMethod(#this);
 static get Extension|staticProperty() → core::int*
   return 42;
diff --git a/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.transformed.expect
index 1672c049..dda54b1 100644
--- a/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/import_from_dill/main.dart.strong.transformed.expect
@@ -35,11 +35,11 @@
 static field core::int* Extension|staticField = 42;
 static final field core::int* Extension|staticFinalField = 42;
 static const field core::int* Extension|staticConstField = #C1;
-static method Extension|get#instanceProperty(final core::int* #this) → core::int*
+static method Extension|get#instanceProperty(lowered final core::int* #this) → core::int*
   return 42;
-static method Extension|set#instanceProperty(final core::int* #this, core::int* value) → void {}
-static method Extension|instanceMethod(final core::int* #this) → void {}
-static method Extension|get#instanceMethod(final core::int* #this) → () →* void
+static method Extension|set#instanceProperty(lowered final core::int* #this, core::int* value) → void {}
+static method Extension|instanceMethod(lowered final core::int* #this) → void {}
+static method Extension|get#instanceMethod(lowered final core::int* #this) → () →* void
   return () → void => mai::Extension|instanceMethod(#this);
 static get Extension|staticProperty() → core::int*
   return 42;
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.outline.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.outline.expect
index 4b7b4b9..920ce9c 100644
--- a/pkg/front_end/testcases/extensions/import_via_prefix.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.outline.expect
@@ -16,7 +16,7 @@
   method method = self2::Extension|method;
   tearoff method = self2::Extension|get#method;
 }
-static method Extension|method(final core::String* #this) → core::int*
+static method Extension|method(lowered final core::String* #this) → core::int*
   ;
-static method Extension|get#method(final core::String* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::Extension|method(#this);
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.expect
index 7030c4a..6ffdbd7 100644
--- a/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.expect
@@ -21,7 +21,7 @@
   method method = imp::Extension|method;
   tearoff method = imp::Extension|get#method;
 }
-static method Extension|method(final core::String* #this) → core::int*
+static method Extension|method(lowered final core::String* #this) → core::int*
   return #this.{core::String::length};
-static method Extension|get#method(final core::String* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => imp::Extension|method(#this);
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.transformed.expect
index 7030c4a..6ffdbd7 100644
--- a/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
   method method = imp::Extension|method;
   tearoff method = imp::Extension|get#method;
 }
-static method Extension|method(final core::String* #this) → core::int*
+static method Extension|method(lowered final core::String* #this) → core::int*
   return #this.{core::String::length};
-static method Extension|get#method(final core::String* #this) → () →* core::int*
+static method Extension|get#method(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => imp::Extension|method(#this);
diff --git a/pkg/front_end/testcases/extensions/index.dart.outline.expect b/pkg/front_end/testcases/extensions/index.dart.outline.expect
index da0ddd9..8b0b1ca 100644
--- a/pkg/front_end/testcases/extensions/index.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.outline.expect
@@ -25,9 +25,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[]<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(final self::MapLike<self::Extension|[]::K*, self::Extension|[]::V*>* #this, core::Object* key) → self::Extension|[]::V*
+static method Extension|[]<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(lowered final self::MapLike<self::Extension|[]::K*, self::Extension|[]::V*>* #this, core::Object* key) → self::Extension|[]::V*
   ;
-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
+static method Extension|[]=<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(lowered final self::MapLike<self::Extension|[]=::K*, self::Extension|[]=::V*>* #this, self::Extension|[]=::K* key, self::Extension|[]=::V* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.expect b/pkg/front_end/testcases/extensions/index.dart.strong.expect
index 67d8909..f9f0d76 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.expect
@@ -26,9 +26,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[]<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(final self::MapLike<self::Extension|[]::K*, self::Extension|[]::V*>* #this, core::Object* key) → self::Extension|[]::V*
+static method Extension|[]<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(lowered final self::MapLike<self::Extension|[]::K*, self::Extension|[]::V*>* #this, core::Object* key) → self::Extension|[]::V*
   return #this.{self::MapLike::get}(key);
-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
+static method Extension|[]=<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(lowered 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();
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 f406204..771f107 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
@@ -26,9 +26,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[]<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(final self::MapLike<self::Extension|[]::K*, self::Extension|[]::V*>* #this, core::Object* key) → self::Extension|[]::V*
+static method Extension|[]<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(lowered final self::MapLike<self::Extension|[]::K*, self::Extension|[]::V*>* #this, core::Object* key) → self::Extension|[]::V*
   return #this.{self::MapLike::get}(key);
-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
+static method Extension|[]=<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(lowered 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();
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.outline.expect b/pkg/front_end/testcases/extensions/instance_access.dart.outline.expect
index 7bdfef2..36f5cf9 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.outline.expect
@@ -50,29 +50,29 @@
   get property = self::Extension2|get#property;
   set property = self::Extension2|set#property;
 }
-static method Extension1|method(final self::Class1* #this) → core::int*
+static method Extension1|method(lowered final self::Class1* #this) → core::int*
   ;
-static method Extension1|get#method(final self::Class1* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int*
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int*
   ;
-static method Extension1|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension1|get#property(final self::Class1* #this) → core::int*
+static method Extension1|get#property(lowered final self::Class1* #this) → core::int*
   ;
-static method Extension1|set#property(final self::Class1* #this, core::int* value) → void
+static method Extension1|set#property(lowered final self::Class1* #this, core::int* value) → void
   ;
-static method Extension2|method(final self::Class2* #this) → core::int*
+static method Extension2|method(lowered final self::Class2* #this) → core::int*
   ;
-static method Extension2|get#method(final self::Class2* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int*
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int*
   ;
-static method Extension2|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
-static method Extension2|get#property(final self::Class2* #this) → core::int*
+static method Extension2|get#property(lowered final self::Class2* #this) → core::int*
   ;
-static method Extension2|set#property(final self::Class2* #this, core::int* value) → void
+static method Extension2|set#property(lowered final self::Class2* #this, core::int* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
index ca462d0..4fd4d22 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
@@ -52,44 +52,44 @@
   get property = self::Extension2|get#property;
   set property = self::Extension2|set#property;
 }
-static method Extension1|method(final self::Class1* #this) → core::int* {
+static method Extension1|method(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.method on ${#this}");
   return #this.{self::Class1::field};
 }
-static method Extension1|get#method(final self::Class1* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
   core::print("Extension1.genericMethod<${self::Extension1|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
 }
-static method Extension1|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension1|get#property(final self::Class1* #this) → core::int* {
+static method Extension1|get#property(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.property get on ${#this}");
   return #this.{self::Class1::field};
 }
-static method Extension1|set#property(final self::Class1* #this, core::int* value) → void {
+static method Extension1|set#property(lowered final self::Class1* #this, core::int* value) → void {
   #this.{self::Class1::field} = value;
   core::print("Extension1.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
 }
-static method Extension2|method(final self::Class2* #this) → core::int* {
+static method Extension2|method(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.method on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(3);
 }
-static method Extension2|get#method(final self::Class2* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
   core::print("Extension2.genericMethod<${self::Extension2|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(4) as{TypeError} core::int*;
 }
-static method Extension2|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
-static method Extension2|get#property(final self::Class2* #this) → core::int* {
+static method Extension2|get#property(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.property get on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(5);
 }
-static method Extension2|set#property(final self::Class2* #this, core::int* value) → void {
+static method Extension2|set#property(lowered final self::Class2* #this, core::int* value) → void {
   core::print("Extension2.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
   #this.{self::Class2::field} = value;
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
index b117363..9d2558b 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
@@ -52,44 +52,44 @@
   get property = self::Extension2|get#property;
   set property = self::Extension2|set#property;
 }
-static method Extension1|method(final self::Class1* #this) → core::int* {
+static method Extension1|method(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.method on ${#this}");
   return #this.{self::Class1::field};
 }
-static method Extension1|get#method(final self::Class1* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
   core::print("Extension1.genericMethod<${self::Extension1|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
 }
-static method Extension1|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension1|get#property(final self::Class1* #this) → core::int* {
+static method Extension1|get#property(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.property get on ${#this}");
   return #this.{self::Class1::field};
 }
-static method Extension1|set#property(final self::Class1* #this, core::int* value) → void {
+static method Extension1|set#property(lowered final self::Class1* #this, core::int* value) → void {
   #this.{self::Class1::field} = value;
   core::print("Extension1.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
 }
-static method Extension2|method(final self::Class2* #this) → core::int* {
+static method Extension2|method(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.method on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(3);
 }
-static method Extension2|get#method(final self::Class2* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
   core::print("Extension2.genericMethod<${self::Extension2|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(4) as{TypeError} core::int*;
 }
-static method Extension2|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
-static method Extension2|get#property(final self::Class2* #this) → core::int* {
+static method Extension2|get#property(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.property get on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(5);
 }
-static method Extension2|set#property(final self::Class2* #this, core::int* value) → void {
+static method Extension2|set#property(lowered final self::Class2* #this, core::int* value) → void {
   core::print("Extension2.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
   #this.{self::Class2::field} = value;
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect b/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect
index 04be94e..63e9fce 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect
@@ -46,29 +46,29 @@
   method method2 = self::B2|method2;
   tearoff method2 = self::B2|get#method2;
 }
-static method A2|method1(final self::A1* #this) → self::A1*
+static method A2|method1(lowered final self::A1* #this) → self::A1*
   ;
-static method A2|get#method1(final self::A1* #this) → () →* self::A1*
+static method A2|get#method1(lowered final self::A1* #this) → () →* self::A1*
   return () → self::A1* => self::A2|method1(#this);
-static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1*
+static method A2|method2<T extends core::Object* = dynamic>(lowered final self::A1* #this, self::A2|method2::T* o) → self::A1*
   ;
-static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
+static method A2|get#method2(lowered final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
   return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o]) → self::A1*
+static method A2|method3<T extends core::Object* = dynamic>(lowered final self::A1* #this, [self::A2|method3::T* o]) → self::A1*
   ;
-static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
+static method A2|get#method3(lowered final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
   return <T extends core::Object* = dynamic>([T* o]) → self::A1* => self::A2|method3<T*>(#this, o);
-static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o}) → self::A1*
+static method A2|method4<T extends core::Object* = dynamic>(lowered final self::A1* #this, {self::A2|method4::T* o}) → self::A1*
   ;
-static method A2|get#method4(final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
+static method A2|get#method4(lowered final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
   return <T extends core::Object* = dynamic>({T* o}) → self::A1* => self::A2|method4<T*>(#this, o: o);
-static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>*
+static method B2|method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>*
   ;
-static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
+static method B2|get#method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
   return () → self::B1<self::B2|get#method1::T*>* => self::B2|method1<self::B2|get#method1::T*>(#this);
-static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>*
+static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>*
   ;
-static method B2|get#method2<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
+static method B2|get#method2<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
   return <S extends core::Object* = dynamic>(S* o) → self::B1<self::B2|get#method2::T*>* => self::B2|method2<self::B2|get#method2::T*, S*>(#this, o);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
index 72cb315d..d189b6d 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
@@ -48,39 +48,39 @@
   method method2 = self::B2|method2;
   tearoff method2 = self::B2|get#method2;
 }
-static method A2|method1(final self::A1* #this) → self::A1* {
+static method A2|method1(lowered final self::A1* #this) → self::A1* {
   return #this;
 }
-static method A2|get#method1(final self::A1* #this) → () →* self::A1*
+static method A2|get#method1(lowered final self::A1* #this) → () →* self::A1*
   return () → self::A1* => self::A2|method1(#this);
-static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(lowered final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
+static method A2|get#method2(lowered final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
   return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
+static method A2|method3<T extends core::Object* = dynamic>(lowered final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
+static method A2|get#method3(lowered final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
   return <T extends core::Object* = dynamic>([T* o = #C1]) → self::A1* => self::A2|method3<T*>(#this, o);
-static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
+static method A2|method4<T extends core::Object* = dynamic>(lowered final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method4(final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
+static method A2|get#method4(lowered final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
   return <T extends core::Object* = dynamic>({T* o = #C1}) → self::A1* => self::A2|method4<T*>(#this, o: o);
-static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
+static method B2|method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
   return #this;
 }
-static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
+static method B2|get#method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
   return () → self::B1<self::B2|get#method1::T*>* => self::B2|method1<self::B2|get#method1::T*>(#this);
-static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
+static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
   core::print(o);
   return #this;
 }
-static method B2|get#method2<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
+static method B2|get#method2<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
   return <S extends core::Object* = dynamic>(S* o) → self::B1<self::B2|get#method2::T*>* => self::B2|method2<self::B2|get#method2::T*, S*>(#this, o);
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
index 72cb315d..d189b6d 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
@@ -48,39 +48,39 @@
   method method2 = self::B2|method2;
   tearoff method2 = self::B2|get#method2;
 }
-static method A2|method1(final self::A1* #this) → self::A1* {
+static method A2|method1(lowered final self::A1* #this) → self::A1* {
   return #this;
 }
-static method A2|get#method1(final self::A1* #this) → () →* self::A1*
+static method A2|get#method1(lowered final self::A1* #this) → () →* self::A1*
   return () → self::A1* => self::A2|method1(#this);
-static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(lowered final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
+static method A2|get#method2(lowered final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
   return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
+static method A2|method3<T extends core::Object* = dynamic>(lowered final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
+static method A2|get#method3(lowered final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
   return <T extends core::Object* = dynamic>([T* o = #C1]) → self::A1* => self::A2|method3<T*>(#this, o);
-static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
+static method A2|method4<T extends core::Object* = dynamic>(lowered final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method4(final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
+static method A2|get#method4(lowered final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
   return <T extends core::Object* = dynamic>({T* o = #C1}) → self::A1* => self::A2|method4<T*>(#this, o: o);
-static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
+static method B2|method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
   return #this;
 }
-static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
+static method B2|get#method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
   return () → self::B1<self::B2|get#method1::T*>* => self::B2|method1<self::B2|get#method1::T*>(#this);
-static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
+static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
   core::print(o);
   return #this;
 }
-static method B2|get#method2<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
+static method B2|get#method2<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
   return <S extends core::Object* = dynamic>(S* o) → self::B1<self::B2|get#method2::T*>* => self::B2|method2<self::B2|get#method2::T*, S*>(#this, o);
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.outline.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.outline.expect
index 08380b2..03756cc 100644
--- a/pkg/front_end/testcases/extensions/instance_tearoff.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.outline.expect
@@ -46,21 +46,21 @@
   method genericMethod = self::Extension2|genericMethod;
   tearoff genericMethod = self::Extension2|get#genericMethod;
 }
-static method Extension1|method(final self::Class1* #this) → core::int*
+static method Extension1|method(lowered final self::Class1* #this) → core::int*
   ;
-static method Extension1|get#method(final self::Class1* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int*
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int*
   ;
-static method Extension1|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension2|method(final self::Class2* #this) → core::int*
+static method Extension2|method(lowered final self::Class2* #this) → core::int*
   ;
-static method Extension2|get#method(final self::Class2* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int*
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int*
   ;
-static method Extension2|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect
index 9508bad..3e30930 100644
--- a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect
@@ -48,29 +48,29 @@
   method genericMethod = self::Extension2|genericMethod;
   tearoff genericMethod = self::Extension2|get#genericMethod;
 }
-static method Extension1|method(final self::Class1* #this) → core::int* {
+static method Extension1|method(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.method on ${#this}");
   return #this.{self::Class1::field};
 }
-static method Extension1|get#method(final self::Class1* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
   core::print("Extension1.genericMethod<${self::Extension1|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
 }
-static method Extension1|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension2|method(final self::Class2* #this) → core::int* {
+static method Extension2|method(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.method on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(2);
 }
-static method Extension2|get#method(final self::Class2* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
   core::print("Extension2.genericMethod<${self::Extension2|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(3) as{TypeError} core::int*;
 }
-static method Extension2|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
 static method main() → dynamic {
   self::testExtension1();
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect
index aabacb2..70b8f9f 100644
--- a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect
@@ -48,29 +48,29 @@
   method genericMethod = self::Extension2|genericMethod;
   tearoff genericMethod = self::Extension2|get#genericMethod;
 }
-static method Extension1|method(final self::Class1* #this) → core::int* {
+static method Extension1|method(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.method on ${#this}");
   return #this.{self::Class1::field};
 }
-static method Extension1|get#method(final self::Class1* #this) → () →* core::int*
+static method Extension1|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::Extension1|method(#this);
-static method Extension1|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
+static method Extension1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::Extension1|genericMethod::T* t) → core::int* {
   core::print("Extension1.genericMethod<${self::Extension1|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
 }
-static method Extension1|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension1|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
-static method Extension2|method(final self::Class2* #this) → core::int* {
+static method Extension2|method(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.method on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(2);
 }
-static method Extension2|get#method(final self::Class2* #this) → () →* core::int*
+static method Extension2|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::Extension2|method(#this);
-static method Extension2|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
+static method Extension2|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::Extension2|genericMethod::T* t) → core::int* {
   core::print("Extension2.genericMethod<${self::Extension2|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(3) as{TypeError} core::int*;
 }
-static method Extension2|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method Extension2|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::Extension2|genericMethod<T*>(#this, t);
 static method main() → dynamic {
   self::testExtension1();
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect
index 1c64152..24d15c6 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect
@@ -25,13 +25,13 @@
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
-static method _extension#0|get#property1(final self::Class* #this) → core::int*
+static method _extension#0|get#property1(lowered final self::Class* #this) → core::int*
   ;
-static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
+static method _extension#0|set#property1(lowered final self::Class* #this, core::int* value) → void
   ;
-static method _extension#1|get#property2(final self::Class* #this) → core::int*
+static method _extension#1|get#property2(lowered final self::Class* #this) → core::int*
   ;
-static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
+static method _extension#1|set#property2(lowered final self::Class* #this, core::int* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect
index dadb2db..810c73b 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect
@@ -26,13 +26,13 @@
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
-static method _extension#0|get#property1(final self::Class* #this) → core::int*
+static method _extension#0|get#property1(lowered final self::Class* #this) → core::int*
   return self::_extension#1|get#property2(#this);
-static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
+static method _extension#0|set#property1(lowered final self::Class* #this, core::int* value) → void
   return #this.{self::Class::field} = value;
-static method _extension#1|get#property2(final self::Class* #this) → core::int*
+static method _extension#1|get#property2(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
+static method _extension#1|set#property2(lowered final self::Class* #this, core::int* value) → void
   return let final core::int* #t1 = value in let final void #t2 = self::_extension#0|set#property1(#this, #t1) in #t1;
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect
index d9024f1..ee08d45 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect
@@ -26,13 +26,13 @@
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
-static method _extension#0|get#property1(final self::Class* #this) → core::int*
+static method _extension#0|get#property1(lowered final self::Class* #this) → core::int*
   return self::_extension#1|get#property2(#this);
-static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
+static method _extension#0|set#property1(lowered final self::Class* #this, core::int* value) → void
   return #this.{self::Class::field} = value;
-static method _extension#1|get#property2(final self::Class* #this) → core::int*
+static method _extension#1|get#property2(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
+static method _extension#1|set#property2(lowered final self::Class* #this, core::int* value) → void
   return let final core::int* #t1 = value in let final void #t2 = self::_extension#0|set#property1(#this, #t1) in #t1;
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.outline.expect
index 0b7201a..064d285 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.outline.expect
@@ -38,13 +38,13 @@
   method method = self::GenericExtension|method;
   tearoff method = self::GenericExtension|get#method;
 }
-static method Extension|method(final self::Class* #this, dynamic a) → dynamic
+static method Extension|method(lowered final self::Class* #this, dynamic a) → dynamic
   ;
-static method Extension|get#method(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|get#method(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic a) → dynamic => self::Extension|method(#this, a);
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this) → dynamic
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this) → dynamic
   ;
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → () →* dynamic
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → () →* dynamic
   return () → dynamic => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this);
 static method main() → dynamic
   ;
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 431609f..3fb95ef 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
@@ -162,11 +162,11 @@
   method method = self::GenericExtension|method;
   tearoff method = self::GenericExtension|get#method;
 }
-static method Extension|method(final self::Class* #this, dynamic a) → dynamic {}
-static method Extension|get#method(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|method(lowered final self::Class* #this, dynamic a) → dynamic {}
+static method Extension|get#method(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic a) → dynamic => self::Extension|method(#this, a);
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this) → dynamic {}
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → () →* dynamic
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this) → dynamic {}
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → () →* dynamic
   return () → dynamic => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this);
 static method main() → dynamic {
   core::String* s = "";
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 431609f..3fb95ef 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
@@ -162,11 +162,11 @@
   method method = self::GenericExtension|method;
   tearoff method = self::GenericExtension|get#method;
 }
-static method Extension|method(final self::Class* #this, dynamic a) → dynamic {}
-static method Extension|get#method(final self::Class* #this) → (dynamic) →* dynamic
+static method Extension|method(lowered final self::Class* #this, dynamic a) → dynamic {}
+static method Extension|get#method(lowered final self::Class* #this) → (dynamic) →* dynamic
   return (dynamic a) → dynamic => self::Extension|method(#this, a);
-static method GenericExtension|method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::T*>* #this) → dynamic {}
-static method GenericExtension|get#method<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → () →* dynamic
+static method GenericExtension|method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|method::T*>* #this) → dynamic {}
+static method GenericExtension|get#method<T extends core::Object* = dynamic>(lowered final self::GenericClass<self::GenericExtension|get#method::T*>* #this) → () →* dynamic
   return () → dynamic => self::GenericExtension|method<self::GenericExtension|get#method::T*>(#this);
 static method main() → dynamic {
   core::String* s = "";
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.outline.expect b/pkg/front_end/testcases/extensions/issue38713.dart.outline.expect
index b1e807a..ca41f17 100644
--- a/pkg/front_end/testcases/extensions/issue38713.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.outline.expect
@@ -32,7 +32,7 @@
   ;
 static set C|property3(core::int* x) → void
   ;
-static method C|get#property3(final core::int* #this) → core::int*
+static method C|get#property3(lowered final core::int* #this) → core::int*
   ;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.strong.expect b/pkg/front_end/testcases/extensions/issue38713.dart.strong.expect
index 3f56d65..9108ed9 100644
--- a/pkg/front_end/testcases/extensions/issue38713.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.strong.expect
@@ -30,7 +30,7 @@
 static field core::int* C|property2;
 static set C|property2(core::int* x) → void {}
 static set C|property3(core::int* x) → void {}
-static method C|get#property3(final core::int* #this) → core::int*
+static method C|get#property3(lowered final core::int* #this) → core::int*
   return 1;
 static method main() → void {
   self::C|property2;
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue38713.dart.strong.transformed.expect
index 3f56d65..9108ed9 100644
--- a/pkg/front_end/testcases/extensions/issue38713.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.strong.transformed.expect
@@ -30,7 +30,7 @@
 static field core::int* C|property2;
 static set C|property2(core::int* x) → void {}
 static set C|property3(core::int* x) → void {}
-static method C|get#property3(final core::int* #this) → core::int*
+static method C|get#property3(lowered final core::int* #this) → core::int*
   return 1;
 static method main() → void {
   self::C|property2;
diff --git a/pkg/front_end/testcases/extensions/issue38745.dart.outline.expect b/pkg/front_end/testcases/extensions/issue38745.dart.outline.expect
index 166ad22..8777198 100644
--- a/pkg/front_end/testcases/extensions/issue38745.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38745.dart.outline.expect
@@ -54,13 +54,13 @@
 static field core::int* ext|field;
 static final field core::int* ext|property;
 static final field core::int* ext|property2;
-static method ext|set#property<T extends core::Object* = dynamic>(final self::C<self::ext|set#property::T*>* #this, core::int* value) → void
+static method ext|set#property<T extends core::Object* = dynamic>(lowered final self::C<self::ext|set#property::T*>* #this, core::int* value) → void
   ;
 static set ext|property2(core::int* value) → void
   ;
-static method ext|method<T extends core::Object* = dynamic>(final self::C<self::ext|method::T*>* #this) → dynamic
+static method ext|method<T extends core::Object* = dynamic>(lowered final self::C<self::ext|method::T*>* #this) → dynamic
   ;
-static method ext|get#method<T extends core::Object* = dynamic>(final self::C<self::ext|get#method::T*>* #this) → () →* dynamic
+static method ext|get#method<T extends core::Object* = dynamic>(lowered final self::C<self::ext|get#method::T*>* #this) → () →* dynamic
   return () → dynamic => self::ext|method<self::ext|get#method::T*>(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue38745.dart.strong.expect b/pkg/front_end/testcases/extensions/issue38745.dart.strong.expect
index 40c2392..13017ea 100644
--- a/pkg/front_end/testcases/extensions/issue38745.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue38745.dart.strong.expect
@@ -125,9 +125,9 @@
 static field core::int* ext|field;
 static final field core::int* ext|property = 42;
 static final field core::int* ext|property2 = 42;
-static method ext|set#property<T extends core::Object* = dynamic>(final self::C<self::ext|set#property::T*>* #this, core::int* value) → void {}
+static method ext|set#property<T extends core::Object* = dynamic>(lowered final self::C<self::ext|set#property::T*>* #this, core::int* value) → void {}
 static set ext|property2(core::int* value) → void {}
-static method ext|method<T extends core::Object* = dynamic>(final self::C<self::ext|method::T*>* #this) → dynamic {
+static method ext|method<T extends core::Object* = dynamic>(lowered final self::C<self::ext|method::T*>* #this) → dynamic {
   invalid-expression "pkg/front_end/testcases/extensions/issue38745.dart:20:5: Error: Getter not found: 'field'.
     field;
     ^^^^^";
@@ -145,7 +145,7 @@
     property2 = 23;
     ^^^^^^^^^";
 }
-static method ext|get#method<T extends core::Object* = dynamic>(final self::C<self::ext|get#method::T*>* #this) → () →* dynamic
+static method ext|get#method<T extends core::Object* = dynamic>(lowered final self::C<self::ext|get#method::T*>* #this) → () →* dynamic
   return () → dynamic => self::ext|method<self::ext|get#method::T*>(#this);
 static method main() → dynamic {}
 static method errors() → dynamic {
diff --git a/pkg/front_end/testcases/extensions/issue38745.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue38745.dart.strong.transformed.expect
index 40c2392..13017ea 100644
--- a/pkg/front_end/testcases/extensions/issue38745.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue38745.dart.strong.transformed.expect
@@ -125,9 +125,9 @@
 static field core::int* ext|field;
 static final field core::int* ext|property = 42;
 static final field core::int* ext|property2 = 42;
-static method ext|set#property<T extends core::Object* = dynamic>(final self::C<self::ext|set#property::T*>* #this, core::int* value) → void {}
+static method ext|set#property<T extends core::Object* = dynamic>(lowered final self::C<self::ext|set#property::T*>* #this, core::int* value) → void {}
 static set ext|property2(core::int* value) → void {}
-static method ext|method<T extends core::Object* = dynamic>(final self::C<self::ext|method::T*>* #this) → dynamic {
+static method ext|method<T extends core::Object* = dynamic>(lowered final self::C<self::ext|method::T*>* #this) → dynamic {
   invalid-expression "pkg/front_end/testcases/extensions/issue38745.dart:20:5: Error: Getter not found: 'field'.
     field;
     ^^^^^";
@@ -145,7 +145,7 @@
     property2 = 23;
     ^^^^^^^^^";
 }
-static method ext|get#method<T extends core::Object* = dynamic>(final self::C<self::ext|get#method::T*>* #this) → () →* dynamic
+static method ext|get#method<T extends core::Object* = dynamic>(lowered final self::C<self::ext|get#method::T*>* #this) → () →* dynamic
   return () → dynamic => self::ext|method<self::ext|get#method::T*>(#this);
 static method main() → dynamic {}
 static method errors() → dynamic {
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.outline.expect b/pkg/front_end/testcases/extensions/issue38750.dart.outline.expect
index 30d8538..68e7bae 100644
--- a/pkg/front_end/testcases/extensions/issue38750.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.outline.expect
@@ -39,9 +39,9 @@
   method _bar = self2::ext|_bar;
   tearoff _bar = self2::ext|get#_bar;
 }
-static method ext|_bar(final self2::C* #this) → dynamic
+static method ext|_bar(lowered final self2::C* #this) → dynamic
   ;
-static method ext|get#_bar(final self2::C* #this) → () →* dynamic
+static method ext|get#_bar(lowered final self2::C* #this) → () →* dynamic
   return () → dynamic => self2::ext|_bar(#this);
 
 library;
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.strong.expect b/pkg/front_end/testcases/extensions/issue38750.dart.strong.expect
index ed20ca4..3935f4db 100644
--- a/pkg/front_end/testcases/extensions/issue38750.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.strong.expect
@@ -82,7 +82,7 @@
   method _bar = iss::ext|_bar;
   tearoff _bar = iss::ext|get#_bar;
 }
-static method ext|_bar(final iss::C* #this) → dynamic {
+static method ext|_bar(lowered final iss::C* #this) → dynamic {
   try {
     throw "producing a stack trace";
   }
@@ -90,7 +90,7 @@
     core::print(s);
   }
 }
-static method ext|get#_bar(final iss::C* #this) → () →* dynamic
+static method ext|get#_bar(lowered final iss::C* #this) → () →* dynamic
   return () → dynamic => iss::ext|_bar(#this);
 
 library;
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue38750.dart.strong.transformed.expect
index ed20ca4..3935f4db 100644
--- a/pkg/front_end/testcases/extensions/issue38750.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.strong.transformed.expect
@@ -82,7 +82,7 @@
   method _bar = iss::ext|_bar;
   tearoff _bar = iss::ext|get#_bar;
 }
-static method ext|_bar(final iss::C* #this) → dynamic {
+static method ext|_bar(lowered final iss::C* #this) → dynamic {
   try {
     throw "producing a stack trace";
   }
@@ -90,7 +90,7 @@
     core::print(s);
   }
 }
-static method ext|get#_bar(final iss::C* #this) → () →* dynamic
+static method ext|get#_bar(lowered final iss::C* #this) → () →* dynamic
   return () → dynamic => iss::ext|_bar(#this);
 
 library;
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.outline.expect b/pkg/front_end/testcases/extensions/issue38755.dart.outline.expect
index f901d42..13c7102 100644
--- a/pkg/front_end/testcases/extensions/issue38755.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.outline.expect
@@ -7,9 +7,9 @@
   tearoff myMap = self::A|get#myMap;
 }
 static final field core::List<core::String*>* list;
-static method A|myMap<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final core::List<self::A|myMap::T*>* #this, (self::A|myMap::T*) →* self::A|myMap::R* block) → core::List<self::A|myMap::R*>*
+static method A|myMap<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(lowered final core::List<self::A|myMap::T*>* #this, (self::A|myMap::T*) →* self::A|myMap::R* block) → core::List<self::A|myMap::R*>*
   ;
-static method A|get#myMap<T extends core::Object* = dynamic>(final core::List<self::A|get#myMap::T*>* #this) → <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R*) →* core::List<R*>*
+static method A|get#myMap<T extends core::Object* = dynamic>(lowered final core::List<self::A|get#myMap::T*>* #this) → <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R*) →* core::List<R*>*
   return <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R* block) → core::List<R*>* => self::A|myMap<self::A|get#myMap::T*, R*>(#this, block);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.strong.expect b/pkg/front_end/testcases/extensions/issue38755.dart.strong.expect
index 31b4214..724ef26 100644
--- a/pkg/front_end/testcases/extensions/issue38755.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.strong.expect
@@ -7,10 +7,10 @@
   tearoff myMap = self::A|get#myMap;
 }
 static final field core::List<core::String*>* list = self::A|myMap<core::String*, core::String*>(<core::String*>["a", "b", "c"], (core::String* it) → core::String* => it);
-static method A|myMap<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final core::List<self::A|myMap::T*>* #this, (self::A|myMap::T*) →* self::A|myMap::R* block) → core::List<self::A|myMap::R*>* {
+static method A|myMap<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(lowered final core::List<self::A|myMap::T*>* #this, (self::A|myMap::T*) →* self::A|myMap::R* block) → core::List<self::A|myMap::R*>* {
   return #this.{core::Iterable::map}<self::A|myMap::R*>(block).{core::Iterable::toList}();
 }
-static method A|get#myMap<T extends core::Object* = dynamic>(final core::List<self::A|get#myMap::T*>* #this) → <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R*) →* core::List<R*>*
+static method A|get#myMap<T extends core::Object* = dynamic>(lowered final core::List<self::A|get#myMap::T*>* #this) → <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R*) →* core::List<R*>*
   return <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R* block) → core::List<R*>* => self::A|myMap<self::A|get#myMap::T*, R*>(#this, block);
 static method main() → dynamic {
   core::print(self::list);
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue38755.dart.strong.transformed.expect
index 31b4214..724ef26 100644
--- a/pkg/front_end/testcases/extensions/issue38755.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.strong.transformed.expect
@@ -7,10 +7,10 @@
   tearoff myMap = self::A|get#myMap;
 }
 static final field core::List<core::String*>* list = self::A|myMap<core::String*, core::String*>(<core::String*>["a", "b", "c"], (core::String* it) → core::String* => it);
-static method A|myMap<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final core::List<self::A|myMap::T*>* #this, (self::A|myMap::T*) →* self::A|myMap::R* block) → core::List<self::A|myMap::R*>* {
+static method A|myMap<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(lowered final core::List<self::A|myMap::T*>* #this, (self::A|myMap::T*) →* self::A|myMap::R* block) → core::List<self::A|myMap::R*>* {
   return #this.{core::Iterable::map}<self::A|myMap::R*>(block).{core::Iterable::toList}();
 }
-static method A|get#myMap<T extends core::Object* = dynamic>(final core::List<self::A|get#myMap::T*>* #this) → <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R*) →* core::List<R*>*
+static method A|get#myMap<T extends core::Object* = dynamic>(lowered final core::List<self::A|get#myMap::T*>* #this) → <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R*) →* core::List<R*>*
   return <R extends core::Object* = dynamic>((self::A|get#myMap::T*) →* R* block) → core::List<R*>* => self::A|myMap<self::A|get#myMap::T*, R*>(#this, block);
 static method main() → dynamic {
   core::print(self::list);
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.outline.expect b/pkg/front_end/testcases/extensions/issue38915.dart.outline.expect
index 6231a80..0d8feca 100644
--- a/pkg/front_end/testcases/extensions/issue38915.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.outline.expect
@@ -26,21 +26,21 @@
   method method4 = self::Extension|method4;
   tearoff method4 = self::Extension|get#method4;
 }
-static method Extension|method1(final self::Class* #this, {core::bool* b, core::String* s}) → void
+static method Extension|method1(lowered final self::Class* #this, {core::bool* b, core::String* s}) → void
   ;
-static method Extension|get#method1(final self::Class* #this) → ({b: core::bool*, s: core::String*}) →* void
+static method Extension|get#method1(lowered final self::Class* #this) → ({b: core::bool*, s: core::String*}) →* void
   return ({core::bool* b, core::String* s}) → void => self::Extension|method1(#this, b: b, s: s);
-static method Extension|method2(final self::Class* #this, [core::bool* b, core::String* s]) → void
+static method Extension|method2(lowered final self::Class* #this, [core::bool* b, core::String* s]) → void
   ;
-static method Extension|get#method2(final self::Class* #this) → ([core::bool*, core::String*]) →* void
+static method Extension|get#method2(lowered final self::Class* #this) → ([core::bool*, core::String*]) →* void
   return ([core::bool* b, core::String* s]) → void => self::Extension|method2(#this, b, s);
-static method Extension|method3(final self::Class* #this, core::int* i, {core::bool* b, core::String* s}) → void
+static method Extension|method3(lowered final self::Class* #this, core::int* i, {core::bool* b, core::String* s}) → void
   ;
-static method Extension|get#method3(final self::Class* #this) → (core::int*, {b: core::bool*, s: core::String*}) →* void
+static method Extension|get#method3(lowered final self::Class* #this) → (core::int*, {b: core::bool*, s: core::String*}) →* void
   return (core::int* i, {core::bool* b, core::String* s}) → void => self::Extension|method3(#this, i, b: b, s: s);
-static method Extension|method4(final self::Class* #this, core::int* i, [core::bool* b, core::String* s]) → void
+static method Extension|method4(lowered final self::Class* #this, core::int* i, [core::bool* b, core::String* s]) → void
   ;
-static method Extension|get#method4(final self::Class* #this) → (core::int*, [core::bool*, core::String*]) →* void
+static method Extension|get#method4(lowered final self::Class* #this) → (core::int*, [core::bool*, core::String*]) →* void
   return (core::int* i, [core::bool* b, core::String* s]) → void => self::Extension|method4(#this, i, b, s);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.strong.expect b/pkg/front_end/testcases/extensions/issue38915.dart.strong.expect
index 59a9add..ab76811 100644
--- a/pkg/front_end/testcases/extensions/issue38915.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.strong.expect
@@ -27,19 +27,19 @@
   method method4 = self::Extension|method4;
   tearoff method4 = self::Extension|get#method4;
 }
-static method Extension|method1(final self::Class* #this, {core::bool* b = #C1, core::String* s = #C2}) → void
+static method Extension|method1(lowered final self::Class* #this, {core::bool* b = #C1, core::String* s = #C2}) → void
   return null;
-static method Extension|get#method1(final self::Class* #this) → ({b: core::bool*, s: core::String*}) →* void
+static method Extension|get#method1(lowered final self::Class* #this) → ({b: core::bool*, s: core::String*}) →* void
   return ({core::bool* b = #C1, core::String* s = #C2}) → void => self::Extension|method1(#this, b: b, s: s);
-static method Extension|method2(final self::Class* #this, [core::bool* b = #C1, core::String* s = #C2]) → void
+static method Extension|method2(lowered final self::Class* #this, [core::bool* b = #C1, core::String* s = #C2]) → void
   return null;
-static method Extension|get#method2(final self::Class* #this) → ([core::bool*, core::String*]) →* void
+static method Extension|get#method2(lowered final self::Class* #this) → ([core::bool*, core::String*]) →* void
   return ([core::bool* b = #C1, core::String* s = #C2]) → void => self::Extension|method2(#this, b, s);
-static method Extension|method3(final self::Class* #this, core::int* i, {core::bool* b = #C1, core::String* s = #C2}) → void {}
-static method Extension|get#method3(final self::Class* #this) → (core::int*, {b: core::bool*, s: core::String*}) →* void
+static method Extension|method3(lowered final self::Class* #this, core::int* i, {core::bool* b = #C1, core::String* s = #C2}) → void {}
+static method Extension|get#method3(lowered final self::Class* #this) → (core::int*, {b: core::bool*, s: core::String*}) →* void
   return (core::int* i, {core::bool* b = #C1, core::String* s = #C2}) → void => self::Extension|method3(#this, i, b: b, s: s);
-static method Extension|method4(final self::Class* #this, core::int* i, [core::bool* b = #C1, core::String* s = #C2]) → void {}
-static method Extension|get#method4(final self::Class* #this) → (core::int*, [core::bool*, core::String*]) →* void
+static method Extension|method4(lowered final self::Class* #this, core::int* i, [core::bool* b = #C1, core::String* s = #C2]) → void {}
+static method Extension|get#method4(lowered final self::Class* #this) → (core::int*, [core::bool*, core::String*]) →* void
   return (core::int* i, [core::bool* b = #C1, core::String* s = #C2]) → void => self::Extension|method4(#this, i, b, s);
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue38915.dart.strong.transformed.expect
index 59a9add..ab76811 100644
--- a/pkg/front_end/testcases/extensions/issue38915.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.strong.transformed.expect
@@ -27,19 +27,19 @@
   method method4 = self::Extension|method4;
   tearoff method4 = self::Extension|get#method4;
 }
-static method Extension|method1(final self::Class* #this, {core::bool* b = #C1, core::String* s = #C2}) → void
+static method Extension|method1(lowered final self::Class* #this, {core::bool* b = #C1, core::String* s = #C2}) → void
   return null;
-static method Extension|get#method1(final self::Class* #this) → ({b: core::bool*, s: core::String*}) →* void
+static method Extension|get#method1(lowered final self::Class* #this) → ({b: core::bool*, s: core::String*}) →* void
   return ({core::bool* b = #C1, core::String* s = #C2}) → void => self::Extension|method1(#this, b: b, s: s);
-static method Extension|method2(final self::Class* #this, [core::bool* b = #C1, core::String* s = #C2]) → void
+static method Extension|method2(lowered final self::Class* #this, [core::bool* b = #C1, core::String* s = #C2]) → void
   return null;
-static method Extension|get#method2(final self::Class* #this) → ([core::bool*, core::String*]) →* void
+static method Extension|get#method2(lowered final self::Class* #this) → ([core::bool*, core::String*]) →* void
   return ([core::bool* b = #C1, core::String* s = #C2]) → void => self::Extension|method2(#this, b, s);
-static method Extension|method3(final self::Class* #this, core::int* i, {core::bool* b = #C1, core::String* s = #C2}) → void {}
-static method Extension|get#method3(final self::Class* #this) → (core::int*, {b: core::bool*, s: core::String*}) →* void
+static method Extension|method3(lowered final self::Class* #this, core::int* i, {core::bool* b = #C1, core::String* s = #C2}) → void {}
+static method Extension|get#method3(lowered final self::Class* #this) → (core::int*, {b: core::bool*, s: core::String*}) →* void
   return (core::int* i, {core::bool* b = #C1, core::String* s = #C2}) → void => self::Extension|method3(#this, i, b: b, s: s);
-static method Extension|method4(final self::Class* #this, core::int* i, [core::bool* b = #C1, core::String* s = #C2]) → void {}
-static method Extension|get#method4(final self::Class* #this) → (core::int*, [core::bool*, core::String*]) →* void
+static method Extension|method4(lowered final self::Class* #this, core::int* i, [core::bool* b = #C1, core::String* s = #C2]) → void {}
+static method Extension|get#method4(lowered final self::Class* #this) → (core::int*, [core::bool*, core::String*]) →* void
   return (core::int* i, [core::bool* b = #C1, core::String* s = #C2]) → void => self::Extension|method4(#this, i, b, s);
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.outline.expect b/pkg/front_end/testcases/extensions/issue39527.dart.outline.expect
index 1055553..32185bf 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.outline.expect
@@ -22,11 +22,11 @@
   operator []= = self::Extension1|[]=;
   operator - = self::Extension1|-;
 }
-static method Extension1|[](final self::C* #this, core::int* index) → self::C*
+static method Extension1|[](lowered final self::C* #this, core::int* index) → self::C*
   ;
-static method Extension1|[]=(final self::C* #this, core::int* index, self::C* other) → void
+static method Extension1|[]=(lowered final self::C* #this, core::int* index, self::C* other) → void
   ;
-static method Extension1|-(final self::C* #this, core::int* val) → self::C*
+static method Extension1|-(lowered final self::C* #this, core::int* val) → self::C*
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect b/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
index 32a70a4..8131831 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
@@ -23,13 +23,13 @@
   operator []= = self::Extension1|[]=;
   operator - = self::Extension1|-;
 }
-static method Extension1|[](final self::C* #this, core::int* index) → self::C*
+static method Extension1|[](lowered final self::C* #this, core::int* index) → self::C*
   return let final self::C* #t1 = #this in block {
     let final self::C* #t2 = #t1 in #t2.{self::C::value} = #t2.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
   } =>#t1;
-static method Extension1|[]=(final self::C* #this, core::int* index, self::C* other) → void
+static method Extension1|[]=(lowered final self::C* #this, core::int* index, self::C* other) → void
   return let final self::C* #t3 = #this in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
-static method Extension1|-(final self::C* #this, core::int* val) → self::C*
+static method Extension1|-(lowered final self::C* #this, core::int* val) → self::C*
   return #this;
 static method main() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
index a4adb78..85bc50b 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
@@ -23,13 +23,13 @@
   operator []= = self::Extension1|[]=;
   operator - = self::Extension1|-;
 }
-static method Extension1|[](final self::C* #this, core::int* index) → self::C*
+static method Extension1|[](lowered final self::C* #this, core::int* index) → self::C*
   return let final self::C* #t1 = #this in block {
     let final self::C* #t2 = #t1 in #t2.{self::C::value} = #t2.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
   } =>#t1;
-static method Extension1|[]=(final self::C* #this, core::int* index, self::C* other) → void
+static method Extension1|[]=(lowered final self::C* #this, core::int* index, self::C* other) → void
   return let final self::C* #t3 = #this in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
-static method Extension1|-(final self::C* #this, core::int* val) → self::C*
+static method Extension1|-(lowered final self::C* #this, core::int* val) → self::C*
   return #this;
 static method main() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.outline.expect b/pkg/front_end/testcases/extensions/issue39889.dart.outline.expect
index 1c18ba8..0569c0a 100644
--- a/pkg/front_end/testcases/extensions/issue39889.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.outline.expect
@@ -20,9 +20,9 @@
   method f = self::E|f;
   tearoff f = self::E|get#f;
 }
-static method E|f(final self::C* #this, core::String* b) → void
+static method E|f(lowered final self::C* #this, core::String* b) → void
   ;
-static method E|get#f(final self::C* #this) → (core::String*) →* void
+static method E|get#f(lowered final self::C* #this) → (core::String*) →* void
   return (core::String* b) → void => self::E|f(#this, b);
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.strong.expect b/pkg/front_end/testcases/extensions/issue39889.dart.strong.expect
index 8d52ecb..3d65b0f 100644
--- a/pkg/front_end/testcases/extensions/issue39889.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.strong.expect
@@ -21,8 +21,8 @@
   method f = self::E|f;
   tearoff f = self::E|get#f;
 }
-static method E|f(final self::C* #this, core::String* b) → void {}
-static method E|get#f(final self::C* #this) → (core::String*) →* void
+static method E|f(lowered final self::C* #this, core::String* b) → void {}
+static method E|get#f(lowered final self::C* #this) → (core::String*) →* void
   return (core::String* b) → void => self::E|f(#this, b);
 static method main() → void {
   dynamic b = "456";
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue39889.dart.strong.transformed.expect
index 8d52ecb..3d65b0f 100644
--- a/pkg/front_end/testcases/extensions/issue39889.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.strong.transformed.expect
@@ -21,8 +21,8 @@
   method f = self::E|f;
   tearoff f = self::E|get#f;
 }
-static method E|f(final self::C* #this, core::String* b) → void {}
-static method E|get#f(final self::C* #this) → (core::String*) →* void
+static method E|f(lowered final self::C* #this, core::String* b) → void {}
+static method E|get#f(lowered final self::C* #this) → (core::String*) →* void
   return (core::String* b) → void => self::E|f(#this, b);
 static method main() → void {
   dynamic b = "456";
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.outline.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.outline.expect
index b84871b..975b7b2 100644
--- a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.outline.expect
@@ -15,5 +15,5 @@
 extension Extension on core::bool* {
   operator + = self2::Extension|+;
 }
-static method Extension|+(final core::bool* #this, core::bool* other) → core::bool*
+static method Extension|+(lowered final core::bool* #this, core::bool* other) → core::bool*
   ;
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.expect
index e321b2b..687f686 100644
--- a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.expect
@@ -27,5 +27,5 @@
 extension Extension on core::bool* {
   operator + = iss::Extension|+;
 }
-static method Extension|+(final core::bool* #this, core::bool* other) → core::bool*
+static method Extension|+(lowered final core::bool* #this, core::bool* other) → core::bool*
   return #this.{core::bool::|}(other);
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.transformed.expect
index e321b2b..687f686 100644
--- a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.strong.transformed.expect
@@ -27,5 +27,5 @@
 extension Extension on core::bool* {
   operator + = iss::Extension|+;
 }
-static method Extension|+(final core::bool* #this, core::bool* other) → core::bool*
+static method Extension|+(lowered final core::bool* #this, core::bool* other) → core::bool*
   return #this.{core::bool::|}(other);
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.outline.expect b/pkg/front_end/testcases/extensions/issue40596.dart.outline.expect
index 026a6f7..8be7c09 100644
--- a/pkg/front_end/testcases/extensions/issue40596.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.outline.expect
@@ -11,7 +11,7 @@
 }
 static method main() → void
   ;
-static method Extension|call<T extends core::Object* = dynamic>(final asy::Stream<self::Extension|call::T*>* #this, core::Function* onData) → asy::StreamSubscription<self::Extension|call::T*>*
+static method Extension|call<T extends core::Object* = dynamic>(lowered final asy::Stream<self::Extension|call::T*>* #this, core::Function* onData) → asy::StreamSubscription<self::Extension|call::T*>*
   ;
-static method Extension|get#call<T extends core::Object* = dynamic>(final asy::Stream<self::Extension|get#call::T*>* #this) → (core::Function*) →* asy::StreamSubscription<self::Extension|get#call::T*>*
+static method Extension|get#call<T extends core::Object* = dynamic>(lowered final asy::Stream<self::Extension|get#call::T*>* #this) → (core::Function*) →* asy::StreamSubscription<self::Extension|get#call::T*>*
   return (core::Function* onData) → asy::StreamSubscription<self::Extension|get#call::T*>* => self::Extension|call<self::Extension|get#call::T*>(#this, onData);
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.strong.expect b/pkg/front_end/testcases/extensions/issue40596.dart.strong.expect
index 1511135..7a2fd83 100644
--- a/pkg/front_end/testcases/extensions/issue40596.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.strong.expect
@@ -15,10 +15,10 @@
     core::print(s);
   } in self::Extension|call<core::String*>(#t1.{asy::StreamController::stream}, #t2);
 }
-static method Extension|call<T extends core::Object* = dynamic>(final asy::Stream<self::Extension|call::T*>* #this, core::Function* onData) → asy::StreamSubscription<self::Extension|call::T*>* {
+static method Extension|call<T extends core::Object* = dynamic>(lowered final asy::Stream<self::Extension|call::T*>* #this, core::Function* onData) → asy::StreamSubscription<self::Extension|call::T*>* {
   return #this.{asy::Stream::listen}((self::Extension|call::T* d) → Null {
     onData.call(d);
   });
 }
-static method Extension|get#call<T extends core::Object* = dynamic>(final asy::Stream<self::Extension|get#call::T*>* #this) → (core::Function*) →* asy::StreamSubscription<self::Extension|get#call::T*>*
+static method Extension|get#call<T extends core::Object* = dynamic>(lowered final asy::Stream<self::Extension|get#call::T*>* #this) → (core::Function*) →* asy::StreamSubscription<self::Extension|get#call::T*>*
   return (core::Function* onData) → asy::StreamSubscription<self::Extension|get#call::T*>* => self::Extension|call<self::Extension|get#call::T*>(#this, onData);
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue40596.dart.strong.transformed.expect
index 1511135..7a2fd83 100644
--- a/pkg/front_end/testcases/extensions/issue40596.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.strong.transformed.expect
@@ -15,10 +15,10 @@
     core::print(s);
   } in self::Extension|call<core::String*>(#t1.{asy::StreamController::stream}, #t2);
 }
-static method Extension|call<T extends core::Object* = dynamic>(final asy::Stream<self::Extension|call::T*>* #this, core::Function* onData) → asy::StreamSubscription<self::Extension|call::T*>* {
+static method Extension|call<T extends core::Object* = dynamic>(lowered final asy::Stream<self::Extension|call::T*>* #this, core::Function* onData) → asy::StreamSubscription<self::Extension|call::T*>* {
   return #this.{asy::Stream::listen}((self::Extension|call::T* d) → Null {
     onData.call(d);
   });
 }
-static method Extension|get#call<T extends core::Object* = dynamic>(final asy::Stream<self::Extension|get#call::T*>* #this) → (core::Function*) →* asy::StreamSubscription<self::Extension|get#call::T*>*
+static method Extension|get#call<T extends core::Object* = dynamic>(lowered final asy::Stream<self::Extension|get#call::T*>* #this) → (core::Function*) →* asy::StreamSubscription<self::Extension|get#call::T*>*
   return (core::Function* onData) → asy::StreamSubscription<self::Extension|get#call::T*>* => self::Extension|call<self::Extension|get#call::T*>(#this, onData);
diff --git a/pkg/front_end/testcases/extensions/issue40713.dart.outline.expect b/pkg/front_end/testcases/extensions/issue40713.dart.outline.expect
index 9afde88..a5d8dfc 100644
--- a/pkg/front_end/testcases/extensions/issue40713.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40713.dart.outline.expect
@@ -5,7 +5,7 @@
 extension SafeAccess<T extends core::Object* = dynamic> on core::Iterable<T*>* {
   get safeFirst = self::SafeAccess|get#safeFirst;
 }
-static method SafeAccess|get#safeFirst<T extends core::Object* = dynamic>(final core::Iterable<self::SafeAccess|get#safeFirst::T*>* #this) → self::SafeAccess|get#safeFirst::T*
+static method SafeAccess|get#safeFirst<T extends core::Object* = dynamic>(lowered final core::Iterable<self::SafeAccess|get#safeFirst::T*>* #this) → self::SafeAccess|get#safeFirst::T*
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue40713.dart.strong.expect b/pkg/front_end/testcases/extensions/issue40713.dart.strong.expect
index 13b8a9d..ef2e7dc 100644
--- a/pkg/front_end/testcases/extensions/issue40713.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue40713.dart.strong.expect
@@ -16,7 +16,7 @@
 extension SafeAccess<T extends core::Object* = dynamic> on core::Iterable<T*>* {
   get safeFirst = self::SafeAccess|get#safeFirst;
 }
-static method SafeAccess|get#safeFirst<T extends core::Object* = dynamic>(final core::Iterable<self::SafeAccess|get#safeFirst::T*>* #this) → self::SafeAccess|get#safeFirst::T* {
+static method SafeAccess|get#safeFirst<T extends core::Object* = dynamic>(lowered final core::Iterable<self::SafeAccess|get#safeFirst::T*>* #this) → self::SafeAccess|get#safeFirst::T* {
   return #this.{core::Iterable::isNotEmpty} ?{self::SafeAccess|get#safeFirst::T*} #this.{core::Iterable::first} : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect b/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect
index 6e864bd..6bf9120 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect
@@ -34,9 +34,9 @@
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
-static method _extension#0|foo(final self::A* #this, self::A* a, self::B* b) → void
+static method _extension#0|foo(lowered final self::A* #this, self::A* a, self::B* b) → void
   ;
-static method _extension#0|get#foo(final self::A* #this) → (self::A*, self::B*) →* void
+static method _extension#0|get#foo(lowered final self::A* #this) → (self::A*, self::B*) →* void
   return (self::A* a, self::B* b) → void => self::_extension#0|foo(#this, a, b);
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect b/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect
index cc59049..70c933c 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect
@@ -36,8 +36,8 @@
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
-static method _extension#0|foo(final self::A* #this, self::A* a, self::B* b) → void {}
-static method _extension#0|get#foo(final self::A* #this) → (self::A*, self::B*) →* void
+static method _extension#0|foo(lowered final self::A* #this, self::A* a, self::B* b) → void {}
+static method _extension#0|get#foo(lowered final self::A* #this) → (self::A*, self::B*) →* void
   return (self::A* a, self::B* b) → void => self::_extension#0|foo(#this, a, b);
 static method main() → void {
   dynamic a = new self::A::•();
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect
index cc59049..70c933c 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect
@@ -36,8 +36,8 @@
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
-static method _extension#0|foo(final self::A* #this, self::A* a, self::B* b) → void {}
-static method _extension#0|get#foo(final self::A* #this) → (self::A*, self::B*) →* void
+static method _extension#0|foo(lowered final self::A* #this, self::A* a, self::B* b) → void {}
+static method _extension#0|get#foo(lowered final self::A* #this) → (self::A*, self::B*) →* void
   return (self::A* a, self::B* b) → void => self::_extension#0|foo(#this, a, b);
 static method main() → void {
   dynamic a = new self::A::•();
diff --git a/pkg/front_end/testcases/extensions/issue43218.dart.outline.expect b/pkg/front_end/testcases/extensions/issue43218.dart.outline.expect
index 193d91e..5ca5e4a 100644
--- a/pkg/front_end/testcases/extensions/issue43218.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue43218.dart.outline.expect
@@ -26,7 +26,7 @@
 extension Ext on self::C* {
   get id = self::Ext|get#id;
 }
-static method Ext|get#id(final self::C* #this) → core::int*
+static method Ext|get#id(lowered final self::C* #this) → core::int*
   ;
 static method test() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue43218.dart.strong.expect b/pkg/front_end/testcases/extensions/issue43218.dart.strong.expect
index c6208d5..fd80b29 100644
--- a/pkg/front_end/testcases/extensions/issue43218.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue43218.dart.strong.expect
@@ -36,7 +36,7 @@
 extension Ext on self::C* {
   get id = self::Ext|get#id;
 }
-static method Ext|get#id(final self::C* #this) → core::int*
+static method Ext|get#id(lowered final self::C* #this) → core::int*
   return #this.{self::C::value}.{core::num::+}(1);
 static method test() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/extensions/issue43218.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue43218.dart.strong.transformed.expect
index c6208d5..fd80b29 100644
--- a/pkg/front_end/testcases/extensions/issue43218.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue43218.dart.strong.transformed.expect
@@ -36,7 +36,7 @@
 extension Ext on self::C* {
   get id = self::Ext|get#id;
 }
-static method Ext|get#id(final self::C* #this) → core::int*
+static method Ext|get#id(lowered final self::C* #this) → core::int*
   return #this.{self::C::value}.{core::num::+}(1);
 static method test() → dynamic {
   self::C* c = new self::C::•();
diff --git a/pkg/front_end/testcases/extensions/language_issue1182.dart.outline.expect b/pkg/front_end/testcases/extensions/language_issue1182.dart.outline.expect
index c989ba2..44bd9dc 100644
--- a/pkg/front_end/testcases/extensions/language_issue1182.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/language_issue1182.dart.outline.expect
@@ -21,7 +21,7 @@
 extension Test<T extends core::Object* = dynamic> on T* {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object* = dynamic>(final self::Test|get#test::T* #this) → (self::Test|get#test::T*) →* self::Test|get#test::T*
+static method Test|get#test<T extends core::Object* = dynamic>(lowered final self::Test|get#test::T* #this) → (self::Test|get#test::T*) →* self::Test|get#test::T*
   ;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.expect b/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.expect
index 17bdb9d..6f515b5 100644
--- a/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.expect
@@ -32,6 +32,6 @@
 extension Test<T extends core::Object* = dynamic> on T* {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object* = dynamic>(final self::Test|get#test::T* #this) → (self::Test|get#test::T*) →* self::Test|get#test::T*
+static method Test|get#test<T extends core::Object* = dynamic>(lowered final self::Test|get#test::T* #this) → (self::Test|get#test::T*) →* self::Test|get#test::T*
   return (self::Test|get#test::T* a) → self::Test|get#test::T* => #this;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.transformed.expect
index 17bdb9d..6f515b5 100644
--- a/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/language_issue1182.dart.strong.transformed.expect
@@ -32,6 +32,6 @@
 extension Test<T extends core::Object* = dynamic> on T* {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object* = dynamic>(final self::Test|get#test::T* #this) → (self::Test|get#test::T*) →* self::Test|get#test::T*
+static method Test|get#test<T extends core::Object* = dynamic>(lowered final self::Test|get#test::T* #this) → (self::Test|get#test::T*) →* self::Test|get#test::T*
   return (self::Test|get#test::T* a) → self::Test|get#test::T* => #this;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.outline.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.outline.expect
index f116af6..5cbfe17 100644
--- a/pkg/front_end/testcases/extensions/missing_toplevel.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.outline.expect
@@ -21,7 +21,7 @@
 }
 static field self::Class* c;
 static field dynamic missingGetter;
-static method Extension|set#setter(final self::Class* #this, core::int* value) → void
+static method Extension|set#setter(lowered final self::Class* #this, core::int* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.expect
index f17f432..c79acde 100644
--- a/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.expect
@@ -35,5 +35,5 @@
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'setter'.
 var missingGetter = c.setter += 42;
                       ^^^^^^".+(42) as{TypeError,ForDynamic} core::int* in let final void #t3 = self::Extension|set#setter(#t1, #t2) in #t2;
-static method Extension|set#setter(final self::Class* #this, core::int* value) → void {}
+static method Extension|set#setter(lowered final self::Class* #this, core::int* value) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.transformed.expect
index bae62c7..0a31620 100644
--- a/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.strong.transformed.expect
@@ -35,5 +35,5 @@
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'setter'.
 var missingGetter = c.setter += 42;
                       ^^^^^^".+(42) as{TypeError,ForDynamic} core::int* in let final void #t3 = self::Extension|set#setter(#t1, #t2) in #t2;
-static method Extension|set#setter(final self::Class* #this, core::int* value) → void {}
+static method Extension|set#setter(lowered final self::Class* #this, core::int* value) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.outline.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.outline.expect
index e6d42c5..b5fda8d 100644
--- a/pkg/front_end/testcases/extensions/nested_on_types.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.outline.expect
@@ -22,13 +22,13 @@
   method method2 = self::Extension|method2;
   tearoff method2 = self::Extension|get#method2;
 }
-static method Extension|method1<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|method1::T*>*>* #this) → dynamic
+static method Extension|method1<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|method1::T*>*>* #this) → dynamic
   ;
-static method Extension|get#method1<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|get#method1::T*>*>* #this) → () →* dynamic
+static method Extension|get#method1<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|get#method1::T*>*>* #this) → () →* dynamic
   return () → dynamic => self::Extension|method1<self::Extension|get#method1::T*>(#this);
-static method Extension|method2<T extends core::Object* = dynamic, A extends core::Object* = dynamic>(final self::A<self::A<self::Extension|method2::T*>*>* #this, self::Extension|method2::A* a) → dynamic
+static method Extension|method2<T extends core::Object* = dynamic, A extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|method2::T*>*>* #this, self::Extension|method2::A* a) → dynamic
   ;
-static method Extension|get#method2<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|get#method2::T*>*>* #this) → <A extends core::Object* = dynamic>(A*) →* dynamic
+static method Extension|get#method2<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|get#method2::T*>*>* #this) → <A extends core::Object* = dynamic>(A*) →* dynamic
   return <A extends core::Object* = dynamic>(A* a) → dynamic => self::Extension|method2<self::Extension|get#method2::T*, A*>(#this, a);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.expect
index 271fc66..001a0b6 100644
--- a/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.expect
@@ -23,10 +23,10 @@
   method method2 = self::Extension|method2;
   tearoff method2 = self::Extension|get#method2;
 }
-static method Extension|method1<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|method1::T*>*>* #this) → dynamic {}
-static method Extension|get#method1<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|get#method1::T*>*>* #this) → () →* dynamic
+static method Extension|method1<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|method1::T*>*>* #this) → dynamic {}
+static method Extension|get#method1<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|get#method1::T*>*>* #this) → () →* dynamic
   return () → dynamic => self::Extension|method1<self::Extension|get#method1::T*>(#this);
-static method Extension|method2<T extends core::Object* = dynamic, A extends core::Object* = dynamic>(final self::A<self::A<self::Extension|method2::T*>*>* #this, self::Extension|method2::A* a) → dynamic {}
-static method Extension|get#method2<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|get#method2::T*>*>* #this) → <A extends core::Object* = dynamic>(A*) →* dynamic
+static method Extension|method2<T extends core::Object* = dynamic, A extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|method2::T*>*>* #this, self::Extension|method2::A* a) → dynamic {}
+static method Extension|get#method2<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|get#method2::T*>*>* #this) → <A extends core::Object* = dynamic>(A*) →* dynamic
   return <A extends core::Object* = dynamic>(A* a) → dynamic => self::Extension|method2<self::Extension|get#method2::T*, A*>(#this, a);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.transformed.expect
index 271fc66..001a0b6 100644
--- a/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.strong.transformed.expect
@@ -23,10 +23,10 @@
   method method2 = self::Extension|method2;
   tearoff method2 = self::Extension|get#method2;
 }
-static method Extension|method1<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|method1::T*>*>* #this) → dynamic {}
-static method Extension|get#method1<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|get#method1::T*>*>* #this) → () →* dynamic
+static method Extension|method1<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|method1::T*>*>* #this) → dynamic {}
+static method Extension|get#method1<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|get#method1::T*>*>* #this) → () →* dynamic
   return () → dynamic => self::Extension|method1<self::Extension|get#method1::T*>(#this);
-static method Extension|method2<T extends core::Object* = dynamic, A extends core::Object* = dynamic>(final self::A<self::A<self::Extension|method2::T*>*>* #this, self::Extension|method2::A* a) → dynamic {}
-static method Extension|get#method2<T extends core::Object* = dynamic>(final self::A<self::A<self::Extension|get#method2::T*>*>* #this) → <A extends core::Object* = dynamic>(A*) →* dynamic
+static method Extension|method2<T extends core::Object* = dynamic, A extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|method2::T*>*>* #this, self::Extension|method2::A* a) → dynamic {}
+static method Extension|get#method2<T extends core::Object* = dynamic>(lowered final self::A<self::A<self::Extension|get#method2::T*>*>* #this) → <A extends core::Object* = dynamic>(A*) →* dynamic
   return <A extends core::Object* = dynamic>(A* a) → dynamic => self::Extension|method2<self::Extension|get#method2::T*, A*>(#this, a);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect b/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
index ec1bb35..c3b7817 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
@@ -25,17 +25,17 @@
   tearoff testImplicitThis = self::Extension|get#testImplicitThis;
   set property = self::Extension|set#property;
 }
-static method Extension|get#property(final self::Class* #this) → core::int*
+static method Extension|get#property(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|set#property(final self::Class* #this, core::int* value) → void
+static method Extension|set#property(lowered final self::Class* #this, core::int* value) → void
   ;
-static method Extension|method(final self::Class* #this) → core::int*
+static method Extension|method(lowered final self::Class* #this) → core::int*
   ;
-static method Extension|get#method(final self::Class* #this) → () →* core::int*
+static method Extension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
-static method Extension|testImplicitThis(final self::Class* #this) → dynamic
+static method Extension|testImplicitThis(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
+static method Extension|get#testImplicitThis(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|testImplicitThis(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect b/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
index fb975d6..9cff1f1 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
@@ -26,21 +26,21 @@
   tearoff testImplicitThis = self::Extension|get#testImplicitThis;
   set property = self::Extension|set#property;
 }
-static method Extension|get#property(final self::Class* #this) → core::int*
+static method Extension|get#property(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, core::int* value) → void {
+static method Extension|set#property(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|method(final self::Class* #this) → core::int*
+static method Extension|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|get#method(final self::Class* #this) → () →* core::int*
+static method Extension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
-static method Extension|testImplicitThis(final self::Class* #this) → dynamic {
+static method Extension|testImplicitThis(lowered final self::Class* #this) → dynamic {
   self::expect(null, self::Extension|get#property(#this));
   self::expect(42, let final core::int* #t1 = self::Extension|get#property(#this) in #t1.{core::num::==}(null) ?{core::int*} let final core::int* #t2 = 42 in let final void #t3 = self::Extension|set#property(#this, #t2) in #t2 : #t1);
   self::expect(42, let final core::int* #t4 = self::Extension|get#property(#this) in #t4.{core::num::==}(null) ?{core::int*} let final core::int* #t5 = 87 in let final void #t6 = self::Extension|set#property(#this, #t5) in #t5 : #t4);
 }
-static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
+static method Extension|get#testImplicitThis(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|testImplicitThis(#this);
 static method main() → dynamic {
   self::Class* c;
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
index 4697d39..afe8026 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
@@ -26,21 +26,21 @@
   tearoff testImplicitThis = self::Extension|get#testImplicitThis;
   set property = self::Extension|set#property;
 }
-static method Extension|get#property(final self::Class* #this) → core::int*
+static method Extension|get#property(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, core::int* value) → void {
+static method Extension|set#property(lowered final self::Class* #this, core::int* value) → void {
   #this.{self::Class::field} = value;
 }
-static method Extension|method(final self::Class* #this) → core::int*
+static method Extension|method(lowered final self::Class* #this) → core::int*
   return #this.{self::Class::field};
-static method Extension|get#method(final self::Class* #this) → () →* core::int*
+static method Extension|get#method(lowered final self::Class* #this) → () →* core::int*
   return () → core::int* => self::Extension|method(#this);
-static method Extension|testImplicitThis(final self::Class* #this) → dynamic {
+static method Extension|testImplicitThis(lowered final self::Class* #this) → dynamic {
   self::expect(null, self::Extension|get#property(#this));
   self::expect(42, let final core::int* #t1 = self::Extension|get#property(#this) in #t1.{core::num::==}(null) ?{core::int*} let final core::int* #t2 = 42 in let final void #t3 = self::Extension|set#property(#this, #t2) in #t2 : #t1);
   self::expect(42, let final core::int* #t4 = self::Extension|get#property(#this) in #t4.{core::num::==}(null) ?{core::int*} let final core::int* #t5 = 87 in let final void #t6 = self::Extension|set#property(#this, #t5) in #t5 : #t4);
 }
-static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
+static method Extension|get#testImplicitThis(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|testImplicitThis(#this);
 static method main() → dynamic {
   self::Class* c;
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect
index 6e6c978..3447999 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect
@@ -27,11 +27,11 @@
 extension _extension#1<T extends self::Class<T*>* = self::Class<dynamic>*> on <S extends T* = dynamic>(T*, S*) →* dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
-static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
+static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
   ;
-static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
+static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
   ;
-static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = self::Class<dynamic>*>(final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
+static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = self::Class<dynamic>*>(lowered final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect
index 59a3ec8..9c1f826 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect
@@ -29,11 +29,11 @@
 extension _extension#1<T extends self::Class<T*>* = self::Class<dynamic>*> on <S extends T* = dynamic>(T*, S*) →* dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
-static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
+static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
   return self::_extension#0|get#returnType::R*;
-static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
+static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
   return self::_extension#0|get#parameterType::T*;
-static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = self::Class<dynamic>*>(final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
+static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = self::Class<dynamic>*>(lowered final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
   return self::_extension#1|get#parameterType::T*;
 static method main() → dynamic {
   function local1(core::int* i) → core::int*
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect
index 59a3ec8..9c1f826 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect
@@ -29,11 +29,11 @@
 extension _extension#1<T extends self::Class<T*>* = self::Class<dynamic>*> on <S extends T* = dynamic>(T*, S*) →* dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
-static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
+static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
   return self::_extension#0|get#returnType::R*;
-static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
+static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
   return self::_extension#0|get#parameterType::T*;
-static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = self::Class<dynamic>*>(final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
+static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = self::Class<dynamic>*>(lowered final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
   return self::_extension#1|get#parameterType::T*;
 static method main() → dynamic {
   function local1(core::int* i) → core::int*
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.outline.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.outline.expect
index 2753b81..f2746bb 100644
--- a/pkg/front_end/testcases/extensions/on_type_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.outline.expect
@@ -14,17 +14,17 @@
   method best = self::BestSpec|best;
   tearoff best = self::BestSpec|get#best;
 }
-static method BestCom|best<T extends core::num* = core::num*>(final core::Iterable<self::BestCom|best::T*>* #this) → self::BestCom|best::T*
+static method BestCom|best<T extends core::num* = core::num*>(lowered final core::Iterable<self::BestCom|best::T*>* #this) → self::BestCom|best::T*
   ;
-static method BestCom|get#best<T extends core::num* = core::num*>(final core::Iterable<self::BestCom|get#best::T*>* #this) → () →* self::BestCom|get#best::T*
+static method BestCom|get#best<T extends core::num* = core::num*>(lowered final core::Iterable<self::BestCom|get#best::T*>* #this) → () →* self::BestCom|get#best::T*
   return () → self::BestCom|get#best::T* => self::BestCom|best<self::BestCom|get#best::T*>(#this);
-static method BestList|best<T extends core::Object* = dynamic>(final core::List<self::BestList|best::T*>* #this) → self::BestList|best::T*
+static method BestList|best<T extends core::Object* = dynamic>(lowered final core::List<self::BestList|best::T*>* #this) → self::BestList|best::T*
   ;
-static method BestList|get#best<T extends core::Object* = dynamic>(final core::List<self::BestList|get#best::T*>* #this) → () →* self::BestList|get#best::T*
+static method BestList|get#best<T extends core::Object* = dynamic>(lowered final core::List<self::BestList|get#best::T*>* #this) → () →* self::BestList|get#best::T*
   return () → self::BestList|get#best::T* => self::BestList|best<self::BestList|get#best::T*>(#this);
-static method BestSpec|best(final core::List<core::num*>* #this) → core::num*
+static method BestSpec|best(lowered final core::List<core::num*>* #this) → core::num*
   ;
-static method BestSpec|get#best(final core::List<core::num*>* #this) → () →* core::num*
+static method BestSpec|get#best(lowered final core::List<core::num*>* #this) → () →* core::num*
   return () → core::num* => self::BestSpec|best(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.expect
index b0990ec..75adac2 100644
--- a/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.expect
@@ -14,17 +14,17 @@
   method best = self::BestSpec|best;
   tearoff best = self::BestSpec|get#best;
 }
-static method BestCom|best<T extends core::num* = core::num*>(final core::Iterable<self::BestCom|best::T*>* #this) → self::BestCom|best::T*
+static method BestCom|best<T extends core::num* = core::num*>(lowered final core::Iterable<self::BestCom|best::T*>* #this) → self::BestCom|best::T*
   return null;
-static method BestCom|get#best<T extends core::num* = core::num*>(final core::Iterable<self::BestCom|get#best::T*>* #this) → () →* self::BestCom|get#best::T*
+static method BestCom|get#best<T extends core::num* = core::num*>(lowered final core::Iterable<self::BestCom|get#best::T*>* #this) → () →* self::BestCom|get#best::T*
   return () → self::BestCom|get#best::T* => self::BestCom|best<self::BestCom|get#best::T*>(#this);
-static method BestList|best<T extends core::Object* = dynamic>(final core::List<self::BestList|best::T*>* #this) → self::BestList|best::T*
+static method BestList|best<T extends core::Object* = dynamic>(lowered final core::List<self::BestList|best::T*>* #this) → self::BestList|best::T*
   return null;
-static method BestList|get#best<T extends core::Object* = dynamic>(final core::List<self::BestList|get#best::T*>* #this) → () →* self::BestList|get#best::T*
+static method BestList|get#best<T extends core::Object* = dynamic>(lowered final core::List<self::BestList|get#best::T*>* #this) → () →* self::BestList|get#best::T*
   return () → self::BestList|get#best::T* => self::BestList|best<self::BestList|get#best::T*>(#this);
-static method BestSpec|best(final core::List<core::num*>* #this) → core::num*
+static method BestSpec|best(lowered final core::List<core::num*>* #this) → core::num*
   return null;
-static method BestSpec|get#best(final core::List<core::num*>* #this) → () →* core::num*
+static method BestSpec|get#best(lowered final core::List<core::num*>* #this) → () →* core::num*
   return () → core::num* => self::BestSpec|best(#this);
 static method main() → dynamic {
   core::List<core::int*>* x;
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.transformed.expect
index b0990ec..75adac2 100644
--- a/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.strong.transformed.expect
@@ -14,17 +14,17 @@
   method best = self::BestSpec|best;
   tearoff best = self::BestSpec|get#best;
 }
-static method BestCom|best<T extends core::num* = core::num*>(final core::Iterable<self::BestCom|best::T*>* #this) → self::BestCom|best::T*
+static method BestCom|best<T extends core::num* = core::num*>(lowered final core::Iterable<self::BestCom|best::T*>* #this) → self::BestCom|best::T*
   return null;
-static method BestCom|get#best<T extends core::num* = core::num*>(final core::Iterable<self::BestCom|get#best::T*>* #this) → () →* self::BestCom|get#best::T*
+static method BestCom|get#best<T extends core::num* = core::num*>(lowered final core::Iterable<self::BestCom|get#best::T*>* #this) → () →* self::BestCom|get#best::T*
   return () → self::BestCom|get#best::T* => self::BestCom|best<self::BestCom|get#best::T*>(#this);
-static method BestList|best<T extends core::Object* = dynamic>(final core::List<self::BestList|best::T*>* #this) → self::BestList|best::T*
+static method BestList|best<T extends core::Object* = dynamic>(lowered final core::List<self::BestList|best::T*>* #this) → self::BestList|best::T*
   return null;
-static method BestList|get#best<T extends core::Object* = dynamic>(final core::List<self::BestList|get#best::T*>* #this) → () →* self::BestList|get#best::T*
+static method BestList|get#best<T extends core::Object* = dynamic>(lowered final core::List<self::BestList|get#best::T*>* #this) → () →* self::BestList|get#best::T*
   return () → self::BestList|get#best::T* => self::BestList|best<self::BestList|get#best::T*>(#this);
-static method BestSpec|best(final core::List<core::num*>* #this) → core::num*
+static method BestSpec|best(lowered final core::List<core::num*>* #this) → core::num*
   return null;
-static method BestSpec|get#best(final core::List<core::num*>* #this) → () →* core::num*
+static method BestSpec|get#best(lowered final core::List<core::num*>* #this) → () →* core::num*
   return () → core::num* => self::BestSpec|best(#this);
 static method main() → dynamic {
   core::List<core::int*>* x;
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.outline.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.outline.expect
index 2681a86..3dd1c35 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.outline.expect
@@ -44,13 +44,13 @@
   get property = self::Extension|get#property;
   set property = self::Extension|set#property;
 }
-static method Extension|method<T extends self::Struct* = self::Struct*>(final self::Extension|method::T* #this) → self::Extension|method::T*
+static method Extension|method<T extends self::Struct* = self::Struct*>(lowered final self::Extension|method::T* #this) → self::Extension|method::T*
   ;
-static method Extension|get#method<T extends self::Struct* = self::Struct*>(final self::Extension|get#method::T* #this) → () →* self::Extension|get#method::T*
+static method Extension|get#method<T extends self::Struct* = self::Struct*>(lowered final self::Extension|get#method::T* #this) → () →* self::Extension|get#method::T*
   return () → self::Extension|get#method::T* => self::Extension|method<self::Extension|get#method::T*>(#this);
-static method Extension|get#property<T extends self::Struct* = self::Struct*>(final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
+static method Extension|get#property<T extends self::Struct* = self::Struct*>(lowered final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
   ;
-static method Extension|set#property<T extends self::Struct* = self::Struct*>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void
+static method Extension|set#property<T extends self::Struct* = self::Struct*>(lowered final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
index 0558246..21907d2 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
@@ -87,13 +87,13 @@
   get property = self::Extension|get#property;
   set property = self::Extension|set#property;
 }
-static method Extension|method<T extends self::Struct* = self::Struct*>(final self::Extension|method::T* #this) → self::Extension|method::T*
+static method Extension|method<T extends self::Struct* = self::Struct*>(lowered final self::Extension|method::T* #this) → self::Extension|method::T*
   return #this;
-static method Extension|get#method<T extends self::Struct* = self::Struct*>(final self::Extension|get#method::T* #this) → () →* self::Extension|get#method::T*
+static method Extension|get#method<T extends self::Struct* = self::Struct*>(lowered final self::Extension|get#method::T* #this) → () →* self::Extension|get#method::T*
   return () → self::Extension|get#method::T* => self::Extension|method<self::Extension|get#method::T*>(#this);
-static method Extension|get#property<T extends self::Struct* = self::Struct*>(final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
+static method Extension|get#property<T extends self::Struct* = self::Struct*>(lowered final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
   return #this;
-static method Extension|set#property<T extends self::Struct* = self::Struct*>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void {}
+static method Extension|set#property<T extends self::Struct* = self::Struct*>(lowered final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void {}
 static method main() → dynamic {
   self::Struct* struct;
   self::StructA* structA;
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
index 0558246..21907d2 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
@@ -87,13 +87,13 @@
   get property = self::Extension|get#property;
   set property = self::Extension|set#property;
 }
-static method Extension|method<T extends self::Struct* = self::Struct*>(final self::Extension|method::T* #this) → self::Extension|method::T*
+static method Extension|method<T extends self::Struct* = self::Struct*>(lowered final self::Extension|method::T* #this) → self::Extension|method::T*
   return #this;
-static method Extension|get#method<T extends self::Struct* = self::Struct*>(final self::Extension|get#method::T* #this) → () →* self::Extension|get#method::T*
+static method Extension|get#method<T extends self::Struct* = self::Struct*>(lowered final self::Extension|get#method::T* #this) → () →* self::Extension|get#method::T*
   return () → self::Extension|get#method::T* => self::Extension|method<self::Extension|get#method::T*>(#this);
-static method Extension|get#property<T extends self::Struct* = self::Struct*>(final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
+static method Extension|get#property<T extends self::Struct* = self::Struct*>(lowered final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
   return #this;
-static method Extension|set#property<T extends self::Struct* = self::Struct*>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void {}
+static method Extension|set#property<T extends self::Struct* = self::Struct*>(lowered final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void {}
 static method main() → dynamic {
   self::Struct* struct;
   self::StructA* structA;
diff --git a/pkg/front_end/testcases/extensions/operators.dart.outline.expect b/pkg/front_end/testcases/extensions/operators.dart.outline.expect
index eeac9a5..479c1d6 100644
--- a/pkg/front_end/testcases/extensions/operators.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/operators.dart.outline.expect
@@ -33,11 +33,11 @@
   operator - = self::Operators|-;
   operator unary- = self::Operators|unary-;
 }
-static method Operators|+(final self::Complex* #this, self::Complex* other) → self::Complex*
+static method Operators|+(lowered final self::Complex* #this, self::Complex* other) → self::Complex*
   ;
-static method Operators|-(final self::Complex* #this, self::Complex* other) → self::Complex*
+static method Operators|-(lowered final self::Complex* #this, self::Complex* other) → self::Complex*
   ;
-static method Operators|unary-(final self::Complex* #this) → self::Complex*
+static method Operators|unary-(lowered final self::Complex* #this) → self::Complex*
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/operators.dart.strong.expect b/pkg/front_end/testcases/extensions/operators.dart.strong.expect
index 62682da..271cbb1 100644
--- a/pkg/front_end/testcases/extensions/operators.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/operators.dart.strong.expect
@@ -50,11 +50,11 @@
   operator - = self::Operators|-;
   operator unary- = self::Operators|unary-;
 }
-static method Operators|+(final self::Complex* #this, self::Complex* other) → self::Complex*
+static method Operators|+(lowered final self::Complex* #this, self::Complex* other) → self::Complex*
   return #this.{self::Complex::add}(other);
-static method Operators|-(final self::Complex* #this, self::Complex* other) → self::Complex*
+static method Operators|-(lowered final self::Complex* #this, self::Complex* other) → self::Complex*
   return #this.{self::Complex::sub}(other);
-static method Operators|unary-(final self::Complex* #this) → self::Complex*
+static method Operators|unary-(lowered final self::Complex* #this) → self::Complex*
   return #this.{self::Complex::negate}();
 static method main() → dynamic {
   self::implicit();
diff --git a/pkg/front_end/testcases/extensions/operators.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/operators.dart.strong.transformed.expect
index 62682da..271cbb1 100644
--- a/pkg/front_end/testcases/extensions/operators.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/operators.dart.strong.transformed.expect
@@ -50,11 +50,11 @@
   operator - = self::Operators|-;
   operator unary- = self::Operators|unary-;
 }
-static method Operators|+(final self::Complex* #this, self::Complex* other) → self::Complex*
+static method Operators|+(lowered final self::Complex* #this, self::Complex* other) → self::Complex*
   return #this.{self::Complex::add}(other);
-static method Operators|-(final self::Complex* #this, self::Complex* other) → self::Complex*
+static method Operators|-(lowered final self::Complex* #this, self::Complex* other) → self::Complex*
   return #this.{self::Complex::sub}(other);
-static method Operators|unary-(final self::Complex* #this) → self::Complex*
+static method Operators|unary-(lowered final self::Complex* #this) → self::Complex*
   return #this.{self::Complex::negate}();
 static method main() → dynamic {
   self::implicit();
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
index cfd012a..e2dcbf5 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
@@ -37,15 +37,15 @@
   static set staticProperty = set self::A2|staticProperty;
 }
 static field core::int* A2|staticField;
-static method A2|get#instanceProperty(final self::A1* #this) → core::int*
+static method A2|get#instanceProperty(lowered final self::A1* #this) → core::int*
   ;
-static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void
+static method A2|set#instanceProperty(lowered final self::A1* #this, core::int* value) → void
   ;
-static method A2|+(final self::A1* #this, core::int* value) → core::int*
+static method A2|+(lowered final self::A1* #this, core::int* value) → core::int*
   ;
-static method A2|-(final self::A1* #this, core::int* value) → core::int*
+static method A2|-(lowered final self::A1* #this, core::int* value) → core::int*
   ;
-static method A2|unary-(final self::A1* #this) → core::int*
+static method A2|unary-(lowered final self::A1* #this) → core::int*
   ;
 static get A2|staticProperty() → core::int*
   ;
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
index a2cf3e1..c83a5d1 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
@@ -40,18 +40,18 @@
   static set staticProperty = set self::A2|staticProperty;
 }
 static field core::int* A2|staticField = self::A1::getStaticField();
-static method A2|get#instanceProperty(final self::A1* #this) → core::int*
+static method A2|get#instanceProperty(lowered final self::A1* #this) → core::int*
   return #this.{self::A1::getInstanceField}();
-static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void {
+static method A2|set#instanceProperty(lowered final self::A1* #this, core::int* value) → void {
   #this.{self::A1::setInstanceField}(value);
 }
-static method A2|+(final self::A1* #this, core::int* value) → core::int* {
+static method A2|+(lowered final self::A1* #this, core::int* value) → core::int* {
   return #this.{self::A1::getInstanceField}().{core::num::+}(value);
 }
-static method A2|-(final self::A1* #this, core::int* value) → core::int* {
+static method A2|-(lowered final self::A1* #this, core::int* value) → core::int* {
   return #this.{self::A1::getInstanceField}().{core::num::-}(value);
 }
-static method A2|unary-(final self::A1* #this) → core::int* {
+static method A2|unary-(lowered final self::A1* #this) → core::int* {
   return #this.{self::A1::getInstanceField}().{core::int::unary-}();
 }
 static get A2|staticProperty() → core::int*
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
index a2cf3e1..c83a5d1 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
@@ -40,18 +40,18 @@
   static set staticProperty = set self::A2|staticProperty;
 }
 static field core::int* A2|staticField = self::A1::getStaticField();
-static method A2|get#instanceProperty(final self::A1* #this) → core::int*
+static method A2|get#instanceProperty(lowered final self::A1* #this) → core::int*
   return #this.{self::A1::getInstanceField}();
-static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void {
+static method A2|set#instanceProperty(lowered final self::A1* #this, core::int* value) → void {
   #this.{self::A1::setInstanceField}(value);
 }
-static method A2|+(final self::A1* #this, core::int* value) → core::int* {
+static method A2|+(lowered final self::A1* #this, core::int* value) → core::int* {
   return #this.{self::A1::getInstanceField}().{core::num::+}(value);
 }
-static method A2|-(final self::A1* #this, core::int* value) → core::int* {
+static method A2|-(lowered final self::A1* #this, core::int* value) → core::int* {
   return #this.{self::A1::getInstanceField}().{core::num::-}(value);
 }
-static method A2|unary-(final self::A1* #this) → core::int* {
+static method A2|unary-(lowered final self::A1* #this) → core::int* {
   return #this.{self::A1::getInstanceField}().{core::int::unary-}();
 }
 static get A2|staticProperty() → core::int*
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.outline.expect b/pkg/front_end/testcases/extensions/private_members.dart.outline.expect
index adc6463..5f25ddb 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.outline.expect
@@ -42,53 +42,53 @@
   method test3 = self2::_extension#0|test3;
   tearoff test3 = self2::_extension#0|get#test3;
 }
-static method _PrivateExtension|publicMethod1(final core::String* #this) → core::int*
+static method _PrivateExtension|publicMethod1(lowered final core::String* #this) → core::int*
   ;
-static method _PrivateExtension|get#publicMethod1(final core::String* #this) → () →* core::int*
+static method _PrivateExtension|get#publicMethod1(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::_PrivateExtension|publicMethod1(#this);
-static method _PrivateExtension|_privateMethod1(final core::String* #this) → core::int*
+static method _PrivateExtension|_privateMethod1(lowered final core::String* #this) → core::int*
   ;
-static method _PrivateExtension|get#_privateMethod1(final core::String* #this) → () →* core::int*
+static method _PrivateExtension|get#_privateMethod1(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::_PrivateExtension|_privateMethod1(#this);
 static method _PrivateExtension|publicStaticMethod1() → core::int*
   ;
 static method _PrivateExtension|_privateStaticMethod1() → core::int*
   ;
-static method _PrivateExtension|test1(final core::String* #this) → dynamic
+static method _PrivateExtension|test1(lowered final core::String* #this) → dynamic
   ;
-static method _PrivateExtension|get#test1(final core::String* #this) → () →* dynamic
+static method _PrivateExtension|get#test1(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => self2::_PrivateExtension|test1(#this);
-static method PublicExtension|publicMethod2(final core::String* #this) → core::int*
+static method PublicExtension|publicMethod2(lowered final core::String* #this) → core::int*
   ;
-static method PublicExtension|get#publicMethod2(final core::String* #this) → () →* core::int*
+static method PublicExtension|get#publicMethod2(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::PublicExtension|publicMethod2(#this);
-static method PublicExtension|_privateMethod2(final core::String* #this) → core::int*
+static method PublicExtension|_privateMethod2(lowered final core::String* #this) → core::int*
   ;
-static method PublicExtension|get#_privateMethod2(final core::String* #this) → () →* core::int*
+static method PublicExtension|get#_privateMethod2(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::PublicExtension|_privateMethod2(#this);
 static method PublicExtension|publicStaticMethod2() → core::int*
   ;
 static method PublicExtension|_privateStaticMethod2() → core::int*
   ;
-static method PublicExtension|test2(final core::String* #this) → dynamic
+static method PublicExtension|test2(lowered final core::String* #this) → dynamic
   ;
-static method PublicExtension|get#test2(final core::String* #this) → () →* dynamic
+static method PublicExtension|get#test2(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => self2::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(final core::String* #this) → core::int*
+static method _extension#0|publicMethod3(lowered final core::String* #this) → core::int*
   ;
-static method _extension#0|get#publicMethod3(final core::String* #this) → () →* core::int*
+static method _extension#0|get#publicMethod3(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(final core::String* #this) → core::int*
+static method _extension#0|_privateMethod3(lowered final core::String* #this) → core::int*
   ;
-static method _extension#0|get#_privateMethod3(final core::String* #this) → () →* core::int*
+static method _extension#0|get#_privateMethod3(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => self2::_extension#0|_privateMethod3(#this);
 static method _extension#0|publicStaticMethod3() → core::int*
   ;
 static method _extension#0|_privateStaticMethod3() → core::int*
   ;
-static method _extension#0|test3(final core::String* #this) → dynamic
+static method _extension#0|test3(lowered final core::String* #this) → dynamic
   ;
-static method _extension#0|get#test3(final core::String* #this) → () →* dynamic
+static method _extension#0|get#test3(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => self2::_extension#0|test3(#this);
 static method test() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.strong.expect b/pkg/front_end/testcases/extensions/private_members.dart.strong.expect
index 79b67f0..344b0e7 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.strong.expect
@@ -137,65 +137,65 @@
   method test3 = pri::_extension#0|test3;
   tearoff test3 = pri::_extension#0|get#test3;
 }
-static method _PrivateExtension|publicMethod1(final core::String* #this) → core::int*
+static method _PrivateExtension|publicMethod1(lowered final core::String* #this) → core::int*
   return 42;
-static method _PrivateExtension|get#publicMethod1(final core::String* #this) → () →* core::int*
+static method _PrivateExtension|get#publicMethod1(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_PrivateExtension|publicMethod1(#this);
-static method _PrivateExtension|_privateMethod1(final core::String* #this) → core::int*
+static method _PrivateExtension|_privateMethod1(lowered final core::String* #this) → core::int*
   return 87;
-static method _PrivateExtension|get#_privateMethod1(final core::String* #this) → () →* core::int*
+static method _PrivateExtension|get#_privateMethod1(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_PrivateExtension|_privateMethod1(#this);
 static method _PrivateExtension|publicStaticMethod1() → core::int*
   return 24;
 static method _PrivateExtension|_privateStaticMethod1() → core::int*
   return 78;
-static method _PrivateExtension|test1(final core::String* #this) → dynamic {
+static method _PrivateExtension|test1(lowered final core::String* #this) → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(#this));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(#this));
   pri::expect(24, pri::_PrivateExtension|publicStaticMethod1());
   pri::expect(78, pri::_PrivateExtension|_privateStaticMethod1());
 }
-static method _PrivateExtension|get#test1(final core::String* #this) → () →* dynamic
+static method _PrivateExtension|get#test1(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => pri::_PrivateExtension|test1(#this);
-static method PublicExtension|publicMethod2(final core::String* #this) → core::int*
+static method PublicExtension|publicMethod2(lowered final core::String* #this) → core::int*
   return 123;
-static method PublicExtension|get#publicMethod2(final core::String* #this) → () →* core::int*
+static method PublicExtension|get#publicMethod2(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::PublicExtension|publicMethod2(#this);
-static method PublicExtension|_privateMethod2(final core::String* #this) → core::int*
+static method PublicExtension|_privateMethod2(lowered final core::String* #this) → core::int*
   return 237;
-static method PublicExtension|get#_privateMethod2(final core::String* #this) → () →* core::int*
+static method PublicExtension|get#_privateMethod2(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::PublicExtension|_privateMethod2(#this);
 static method PublicExtension|publicStaticMethod2() → core::int*
   return 321;
 static method PublicExtension|_privateStaticMethod2() → core::int*
   return 732;
-static method PublicExtension|test2(final core::String* #this) → dynamic {
+static method PublicExtension|test2(lowered final core::String* #this) → dynamic {
   pri::expect(123, pri::PublicExtension|publicMethod2(#this));
   pri::expect(237, pri::PublicExtension|_privateMethod2(#this));
   pri::expect(321, pri::PublicExtension|publicStaticMethod2());
   pri::expect(732, pri::PublicExtension|_privateStaticMethod2());
 }
-static method PublicExtension|get#test2(final core::String* #this) → () →* dynamic
+static method PublicExtension|get#test2(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => pri::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(final core::String* #this) → core::int*
+static method _extension#0|publicMethod3(lowered final core::String* #this) → core::int*
   return 473;
-static method _extension#0|get#publicMethod3(final core::String* #this) → () →* core::int*
+static method _extension#0|get#publicMethod3(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(final core::String* #this) → core::int*
+static method _extension#0|_privateMethod3(lowered final core::String* #this) → core::int*
   return 586;
-static method _extension#0|get#_privateMethod3(final core::String* #this) → () →* core::int*
+static method _extension#0|get#_privateMethod3(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_extension#0|_privateMethod3(#this);
 static method _extension#0|publicStaticMethod3() → core::int*
   return 374;
 static method _extension#0|_privateStaticMethod3() → core::int*
   return 685;
-static method _extension#0|test3(final core::String* #this) → dynamic {
+static method _extension#0|test3(lowered final core::String* #this) → dynamic {
   pri::expect(473, pri::_extension#0|publicMethod3(#this));
   pri::expect(586, pri::_extension#0|_privateMethod3(#this));
   pri::expect(374, pri::_extension#0|publicStaticMethod3());
   pri::expect(685, pri::_extension#0|_privateStaticMethod3());
 }
-static method _extension#0|get#test3(final core::String* #this) → () →* dynamic
+static method _extension#0|get#test3(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => pri::_extension#0|test3(#this);
 static method test() → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/private_members.dart.strong.transformed.expect
index 79b67f0..344b0e7 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.strong.transformed.expect
@@ -137,65 +137,65 @@
   method test3 = pri::_extension#0|test3;
   tearoff test3 = pri::_extension#0|get#test3;
 }
-static method _PrivateExtension|publicMethod1(final core::String* #this) → core::int*
+static method _PrivateExtension|publicMethod1(lowered final core::String* #this) → core::int*
   return 42;
-static method _PrivateExtension|get#publicMethod1(final core::String* #this) → () →* core::int*
+static method _PrivateExtension|get#publicMethod1(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_PrivateExtension|publicMethod1(#this);
-static method _PrivateExtension|_privateMethod1(final core::String* #this) → core::int*
+static method _PrivateExtension|_privateMethod1(lowered final core::String* #this) → core::int*
   return 87;
-static method _PrivateExtension|get#_privateMethod1(final core::String* #this) → () →* core::int*
+static method _PrivateExtension|get#_privateMethod1(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_PrivateExtension|_privateMethod1(#this);
 static method _PrivateExtension|publicStaticMethod1() → core::int*
   return 24;
 static method _PrivateExtension|_privateStaticMethod1() → core::int*
   return 78;
-static method _PrivateExtension|test1(final core::String* #this) → dynamic {
+static method _PrivateExtension|test1(lowered final core::String* #this) → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(#this));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(#this));
   pri::expect(24, pri::_PrivateExtension|publicStaticMethod1());
   pri::expect(78, pri::_PrivateExtension|_privateStaticMethod1());
 }
-static method _PrivateExtension|get#test1(final core::String* #this) → () →* dynamic
+static method _PrivateExtension|get#test1(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => pri::_PrivateExtension|test1(#this);
-static method PublicExtension|publicMethod2(final core::String* #this) → core::int*
+static method PublicExtension|publicMethod2(lowered final core::String* #this) → core::int*
   return 123;
-static method PublicExtension|get#publicMethod2(final core::String* #this) → () →* core::int*
+static method PublicExtension|get#publicMethod2(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::PublicExtension|publicMethod2(#this);
-static method PublicExtension|_privateMethod2(final core::String* #this) → core::int*
+static method PublicExtension|_privateMethod2(lowered final core::String* #this) → core::int*
   return 237;
-static method PublicExtension|get#_privateMethod2(final core::String* #this) → () →* core::int*
+static method PublicExtension|get#_privateMethod2(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::PublicExtension|_privateMethod2(#this);
 static method PublicExtension|publicStaticMethod2() → core::int*
   return 321;
 static method PublicExtension|_privateStaticMethod2() → core::int*
   return 732;
-static method PublicExtension|test2(final core::String* #this) → dynamic {
+static method PublicExtension|test2(lowered final core::String* #this) → dynamic {
   pri::expect(123, pri::PublicExtension|publicMethod2(#this));
   pri::expect(237, pri::PublicExtension|_privateMethod2(#this));
   pri::expect(321, pri::PublicExtension|publicStaticMethod2());
   pri::expect(732, pri::PublicExtension|_privateStaticMethod2());
 }
-static method PublicExtension|get#test2(final core::String* #this) → () →* dynamic
+static method PublicExtension|get#test2(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => pri::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(final core::String* #this) → core::int*
+static method _extension#0|publicMethod3(lowered final core::String* #this) → core::int*
   return 473;
-static method _extension#0|get#publicMethod3(final core::String* #this) → () →* core::int*
+static method _extension#0|get#publicMethod3(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(final core::String* #this) → core::int*
+static method _extension#0|_privateMethod3(lowered final core::String* #this) → core::int*
   return 586;
-static method _extension#0|get#_privateMethod3(final core::String* #this) → () →* core::int*
+static method _extension#0|get#_privateMethod3(lowered final core::String* #this) → () →* core::int*
   return () → core::int* => pri::_extension#0|_privateMethod3(#this);
 static method _extension#0|publicStaticMethod3() → core::int*
   return 374;
 static method _extension#0|_privateStaticMethod3() → core::int*
   return 685;
-static method _extension#0|test3(final core::String* #this) → dynamic {
+static method _extension#0|test3(lowered final core::String* #this) → dynamic {
   pri::expect(473, pri::_extension#0|publicMethod3(#this));
   pri::expect(586, pri::_extension#0|_privateMethod3(#this));
   pri::expect(374, pri::_extension#0|publicStaticMethod3());
   pri::expect(685, pri::_extension#0|_privateStaticMethod3());
 }
-static method _extension#0|get#test3(final core::String* #this) → () →* dynamic
+static method _extension#0|get#test3(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => pri::_extension#0|test3(#this);
 static method test() → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.outline.expect b/pkg/front_end/testcases/extensions/static_access.dart.outline.expect
index 9eda9c7..362a61f 100644
--- a/pkg/front_end/testcases/extensions/static_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/static_access.dart.outline.expect
@@ -36,13 +36,13 @@
   ;
 static set Extension|property(dynamic value) → void
   ;
-static method Extension|instanceMethod(final self::Class* #this) → dynamic
+static method Extension|instanceMethod(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#instanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|get#instanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|instanceMethod(#this);
-static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
+static method Extension|get#instanceProperty(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void
+static method Extension|set#instanceProperty(lowered final self::Class* #this, dynamic value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
index a6390b5..5cc472a 100644
--- a/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
@@ -34,12 +34,12 @@
 static get Extension|property() → dynamic
   return 42;
 static set Extension|property(dynamic value) → void {}
-static method Extension|instanceMethod(final self::Class* #this) → dynamic {}
-static method Extension|get#instanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|instanceMethod(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#instanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|instanceMethod(#this);
-static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
+static method Extension|get#instanceProperty(lowered final self::Class* #this) → dynamic
   return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
+static method Extension|set#instanceProperty(lowered final self::Class* #this, dynamic value) → void {}
 static method main() → dynamic {
   self::Extension|method();
   self::Extension|genericMethod<core::int*>(42);
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
index a6390b5..5cc472a 100644
--- a/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
@@ -34,12 +34,12 @@
 static get Extension|property() → dynamic
   return 42;
 static set Extension|property(dynamic value) → void {}
-static method Extension|instanceMethod(final self::Class* #this) → dynamic {}
-static method Extension|get#instanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|instanceMethod(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#instanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|instanceMethod(#this);
-static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
+static method Extension|get#instanceProperty(lowered final self::Class* #this) → dynamic
   return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
+static method Extension|set#instanceProperty(lowered final self::Class* #this, dynamic value) → void {}
 static method main() → dynamic {
   self::Extension|method();
   self::Extension|genericMethod<core::int*>(42);
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.outline.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.outline.expect
index b403165..a401139 100644
--- a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.outline.expect
@@ -22,13 +22,13 @@
   get instanceProperty = self::Extension|get#instanceProperty;
   set instanceProperty = self::Extension|set#instanceProperty;
 }
-static method Extension|instanceMethod(final self::Class* #this) → dynamic
+static method Extension|instanceMethod(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#instanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|get#instanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|instanceMethod(#this);
-static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
+static method Extension|get#instanceProperty(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void
+static method Extension|set#instanceProperty(lowered final self::Class* #this, dynamic value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect
index fd0a648..09b420f 100644
--- a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect
@@ -42,12 +42,12 @@
   get instanceProperty = self::Extension|get#instanceProperty;
   set instanceProperty = self::Extension|set#instanceProperty;
 }
-static method Extension|instanceMethod(final self::Class* #this) → dynamic {}
-static method Extension|get#instanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|instanceMethod(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#instanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|instanceMethod(#this);
-static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
+static method Extension|get#instanceProperty(lowered final self::Class* #this) → dynamic
   return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
+static method Extension|set#instanceProperty(lowered final self::Class* #this, dynamic value) → void {}
 static method main() → dynamic {
   invalid-expression "pkg/front_end/testcases/extensions/static_access_of_instance.dart:14:13: Error: Method not found: 'Extension.instanceMethod'.
   Extension.instanceMethod();
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect
index fd0a648..09b420f 100644
--- a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect
@@ -42,12 +42,12 @@
   get instanceProperty = self::Extension|get#instanceProperty;
   set instanceProperty = self::Extension|set#instanceProperty;
 }
-static method Extension|instanceMethod(final self::Class* #this) → dynamic {}
-static method Extension|get#instanceMethod(final self::Class* #this) → () →* dynamic
+static method Extension|instanceMethod(lowered final self::Class* #this) → dynamic {}
+static method Extension|get#instanceMethod(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|instanceMethod(#this);
-static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
+static method Extension|get#instanceProperty(lowered final self::Class* #this) → dynamic
   return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
+static method Extension|set#instanceProperty(lowered final self::Class* #this, dynamic value) → void {}
 static method main() → dynamic {
   invalid-expression "pkg/front_end/testcases/extensions/static_access_of_instance.dart:14:13: Error: Method not found: 'Extension.instanceMethod'.
   Extension.instanceMethod();
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect
index 250f13d..da9b31b 100644
--- a/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect
@@ -25,19 +25,19 @@
   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|id<T extends core::Object* = dynamic>(lowered 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*
+static method Extension|get#id(lowered 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|get#getter(lowered final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
   ;
-static method Extension|method(final self::Class* #this) → dynamic
+static method Extension|method(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#method(final self::Class* #this) → () →* dynamic
+static method Extension|get#method(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|method(#this);
-static method Extension|errors(final self::Class* #this) → dynamic
+static method Extension|errors(lowered final self::Class* #this) → dynamic
   ;
-static method Extension|get#errors(final self::Class* #this) → () →* dynamic
+static method Extension|get#errors(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|errors(#this);
 static method main() → 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
index 6b6aaf0..d3c534e 100644
--- a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
@@ -41,23 +41,23 @@
   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|id<T extends core::Object* = dynamic>(lowered 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*
+static method Extension|get#id(lowered 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|get#getter(lowered 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 {
+static method Extension|method(lowered 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
+static method Extension|get#method(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|method(#this);
-static method Extension|errors(final self::Class* #this) → dynamic {
+static method Extension|errors(lowered 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)'.
     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
+static method Extension|get#errors(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|errors(#this);
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
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
index 6b6aaf0..d3c534e 100644
--- a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
@@ -41,23 +41,23 @@
   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|id<T extends core::Object* = dynamic>(lowered 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*
+static method Extension|get#id(lowered 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|get#getter(lowered 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 {
+static method Extension|method(lowered 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
+static method Extension|get#method(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|method(#this);
-static method Extension|errors(final self::Class* #this) → dynamic {
+static method Extension|errors(lowered 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)'.
     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
+static method Extension|get#errors(lowered final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|errors(#this);
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
diff --git a/pkg/front_end/testcases/extensions/type_variable_bound.dart.outline.expect b/pkg/front_end/testcases/extensions/type_variable_bound.dart.outline.expect
index 6574fb9..6efbb7d 100644
--- a/pkg/front_end/testcases/extensions/type_variable_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/type_variable_bound.dart.outline.expect
@@ -28,13 +28,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object* = dynamic>(final self::Extension|method1::T* #this) → self::Extension|method1::T*
+static method Extension|method1<T extends core::Object* = dynamic>(lowered final self::Extension|method1::T* #this) → self::Extension|method1::T*
   ;
-static method Extension|get#method1<T extends core::Object* = dynamic>(final self::Extension|get#method1::T* #this) → () →* self::Extension|get#method1::T*
+static method Extension|get#method1<T extends core::Object* = dynamic>(lowered final self::Extension|get#method1::T* #this) → () →* self::Extension|get#method1::T*
   return () → self::Extension|get#method1::T* => self::Extension|method1<self::Extension|get#method1::T*>(#this);
-static method BoundExtension|method2<T extends self::Class* = self::Class*>(final self::BoundExtension|method2::T* #this) → self::BoundExtension|method2::T*
+static method BoundExtension|method2<T extends self::Class* = self::Class*>(lowered final self::BoundExtension|method2::T* #this) → self::BoundExtension|method2::T*
   ;
-static method BoundExtension|get#method2<T extends self::Class* = self::Class*>(final self::BoundExtension|get#method2::T* #this) → () →* self::BoundExtension|get#method2::T*
+static method BoundExtension|get#method2<T extends self::Class* = self::Class*>(lowered final self::BoundExtension|get#method2::T* #this) → () →* self::BoundExtension|get#method2::T*
   return () → self::BoundExtension|get#method2::T* => self::BoundExtension|method2<self::BoundExtension|get#method2::T*>(#this);
 static method test1<T extends core::Object* = dynamic>(self::test1::T* t1) → self::Class*
   ;
diff --git a/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.expect b/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.expect
index 14cb1a6..3dfb6be 100644
--- a/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.expect
@@ -30,13 +30,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object* = dynamic>(final self::Extension|method1::T* #this) → self::Extension|method1::T*
+static method Extension|method1<T extends core::Object* = dynamic>(lowered final self::Extension|method1::T* #this) → self::Extension|method1::T*
   return #this;
-static method Extension|get#method1<T extends core::Object* = dynamic>(final self::Extension|get#method1::T* #this) → () →* self::Extension|get#method1::T*
+static method Extension|get#method1<T extends core::Object* = dynamic>(lowered final self::Extension|get#method1::T* #this) → () →* self::Extension|get#method1::T*
   return () → self::Extension|get#method1::T* => self::Extension|method1<self::Extension|get#method1::T*>(#this);
-static method BoundExtension|method2<T extends self::Class* = self::Class*>(final self::BoundExtension|method2::T* #this) → self::BoundExtension|method2::T*
+static method BoundExtension|method2<T extends self::Class* = self::Class*>(lowered final self::BoundExtension|method2::T* #this) → self::BoundExtension|method2::T*
   return #this;
-static method BoundExtension|get#method2<T extends self::Class* = self::Class*>(final self::BoundExtension|get#method2::T* #this) → () →* self::BoundExtension|get#method2::T*
+static method BoundExtension|get#method2<T extends self::Class* = self::Class*>(lowered final self::BoundExtension|get#method2::T* #this) → () →* self::BoundExtension|get#method2::T*
   return () → self::BoundExtension|get#method2::T* => self::BoundExtension|method2<self::BoundExtension|get#method2::T*>(#this);
 static method test1<T extends core::Object* = dynamic>(self::test1::T* t1) → self::Class* {
   if(t1 is self::SubClass*) {
diff --git a/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.transformed.expect
index 0bc41be..79b6d8f 100644
--- a/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/type_variable_bound.dart.strong.transformed.expect
@@ -30,13 +30,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object* = dynamic>(final self::Extension|method1::T* #this) → self::Extension|method1::T*
+static method Extension|method1<T extends core::Object* = dynamic>(lowered final self::Extension|method1::T* #this) → self::Extension|method1::T*
   return #this;
-static method Extension|get#method1<T extends core::Object* = dynamic>(final self::Extension|get#method1::T* #this) → () →* self::Extension|get#method1::T*
+static method Extension|get#method1<T extends core::Object* = dynamic>(lowered final self::Extension|get#method1::T* #this) → () →* self::Extension|get#method1::T*
   return () → self::Extension|get#method1::T* => self::Extension|method1<self::Extension|get#method1::T*>(#this);
-static method BoundExtension|method2<T extends self::Class* = self::Class*>(final self::BoundExtension|method2::T* #this) → self::BoundExtension|method2::T*
+static method BoundExtension|method2<T extends self::Class* = self::Class*>(lowered final self::BoundExtension|method2::T* #this) → self::BoundExtension|method2::T*
   return #this;
-static method BoundExtension|get#method2<T extends self::Class* = self::Class*>(final self::BoundExtension|get#method2::T* #this) → () →* self::BoundExtension|get#method2::T*
+static method BoundExtension|get#method2<T extends self::Class* = self::Class*>(lowered final self::BoundExtension|get#method2::T* #this) → () →* self::BoundExtension|get#method2::T*
   return () → self::BoundExtension|get#method2::T* => self::BoundExtension|method2<self::BoundExtension|get#method2::T*>(#this);
 static method test1<T extends core::Object* = dynamic>(self::test1::T* t1) → self::Class* {
   if(t1 is self::SubClass*) {
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.outline.expect b/pkg/front_end/testcases/extensions/type_variables.dart.outline.expect
index f786bf3..38ec5af 100644
--- a/pkg/front_end/testcases/extensions/type_variables.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.outline.expect
@@ -28,17 +28,17 @@
   method method = self::A4|method;
   tearoff method = self::A4|get#method;
 }
-static method A2|method1<T extends core::Object* = dynamic, S extends self::A2|method1::T* = dynamic>(final self::A1<self::A2|method1::T*>* #this) → self::A1<self::A2|method1::T*>*
+static method A2|method1<T extends core::Object* = dynamic, S extends self::A2|method1::T* = dynamic>(lowered final self::A1<self::A2|method1::T*>* #this) → self::A1<self::A2|method1::T*>*
   ;
-static method A2|get#method1<T extends core::Object* = dynamic>(final self::A1<self::A2|get#method1::T*>* #this) → <S extends self::A2|get#method1::T* = dynamic>() →* self::A1<self::A2|get#method1::T*>*
+static method A2|get#method1<T extends core::Object* = dynamic>(lowered final self::A1<self::A2|get#method1::T*>* #this) → <S extends self::A2|get#method1::T* = dynamic>() →* self::A1<self::A2|get#method1::T*>*
   return <S extends self::A2|get#method1::T* = dynamic>() → self::A1<self::A2|get#method1::T*>* => self::A2|method1<self::A2|get#method1::T*, S*>(#this);
-static method A2|method2<T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::T*>* = self::A1<dynamic>*>(final self::A1<self::A2|method2::T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::T*>*
+static method A2|method2<T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::T*>* = self::A1<dynamic>*>(lowered final self::A1<self::A2|method2::T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::T*>*
   ;
-static method A2|get#method2<T extends core::Object* = dynamic>(final self::A1<self::A2|get#method2::T*>* #this) → <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S*) →* self::A1<self::A2|get#method2::T*>*
+static method A2|get#method2<T extends core::Object* = dynamic>(lowered final self::A1<self::A2|get#method2::T*>* #this) → <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S*) →* self::A1<self::A2|get#method2::T*>*
   return <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S* o) → self::A1<self::A2|get#method2::T*>* => self::A2|method2<self::A2|get#method2::T*, S*>(#this, o);
-static method A4|method<#T extends core::Object* = dynamic, T extends core::Object* = dynamic>(final self::A1<self::A4|method::#T*>* #this) → dynamic
+static method A4|method<#T extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final self::A1<self::A4|method::#T*>* #this) → dynamic
   ;
-static method A4|get#method<#T extends core::Object* = dynamic>(final self::A1<self::A4|get#method::#T*>* #this) → <T extends core::Object* = dynamic>() →* dynamic
+static method A4|get#method<#T extends core::Object* = dynamic>(lowered final self::A1<self::A4|get#method::#T*>* #this) → <T extends core::Object* = dynamic>() →* dynamic
   return <T extends core::Object* = dynamic>() → dynamic => self::A4|method<self::A4|get#method::#T*, T*>(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect b/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect
index e2c6597..aeae0f7 100644
--- a/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.strong.expect
@@ -29,20 +29,20 @@
   method method = self::A4|method;
   tearoff method = self::A4|get#method;
 }
-static method A2|method1<T extends core::Object* = dynamic, S extends self::A2|method1::T* = dynamic>(final self::A1<self::A2|method1::T*>* #this) → self::A1<self::A2|method1::T*>* {
+static method A2|method1<T extends core::Object* = dynamic, S extends self::A2|method1::T* = dynamic>(lowered final self::A1<self::A2|method1::T*>* #this) → self::A1<self::A2|method1::T*>* {
   return #this;
 }
-static method A2|get#method1<T extends core::Object* = dynamic>(final self::A1<self::A2|get#method1::T*>* #this) → <S extends self::A2|get#method1::T* = dynamic>() →* self::A1<self::A2|get#method1::T*>*
+static method A2|get#method1<T extends core::Object* = dynamic>(lowered final self::A1<self::A2|get#method1::T*>* #this) → <S extends self::A2|get#method1::T* = dynamic>() →* self::A1<self::A2|get#method1::T*>*
   return <S extends self::A2|get#method1::T* = dynamic>() → self::A1<self::A2|get#method1::T*>* => self::A2|method1<self::A2|get#method1::T*, S*>(#this);
-static method A2|method2<T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::T*>* = self::A1<dynamic>*>(final self::A1<self::A2|method2::T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::T*>* {
+static method A2|method2<T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::T*>* = self::A1<dynamic>*>(lowered final self::A1<self::A2|method2::T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::T*>* {
   core::print(o);
   core::print(self::A2|method2::T*);
   core::print(self::A2|method2::S*);
   return #this;
 }
-static method A2|get#method2<T extends core::Object* = dynamic>(final self::A1<self::A2|get#method2::T*>* #this) → <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S*) →* self::A1<self::A2|get#method2::T*>*
+static method A2|get#method2<T extends core::Object* = dynamic>(lowered final self::A1<self::A2|get#method2::T*>* #this) → <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S*) →* self::A1<self::A2|get#method2::T*>*
   return <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S* o) → self::A1<self::A2|get#method2::T*>* => self::A2|method2<self::A2|get#method2::T*, S*>(#this, o);
-static method A4|method<#T extends core::Object* = dynamic, T extends core::Object* = dynamic>(final self::A1<self::A4|method::#T*>* #this) → dynamic {}
-static method A4|get#method<#T extends core::Object* = dynamic>(final self::A1<self::A4|get#method::#T*>* #this) → <T extends core::Object* = dynamic>() →* dynamic
+static method A4|method<#T extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final self::A1<self::A4|method::#T*>* #this) → dynamic {}
+static method A4|get#method<#T extends core::Object* = dynamic>(lowered final self::A1<self::A4|get#method::#T*>* #this) → <T extends core::Object* = dynamic>() →* dynamic
   return <T extends core::Object* = dynamic>() → dynamic => self::A4|method<self::A4|get#method::#T*, T*>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect
index e2c6597..aeae0f7 100644
--- a/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.strong.transformed.expect
@@ -29,20 +29,20 @@
   method method = self::A4|method;
   tearoff method = self::A4|get#method;
 }
-static method A2|method1<T extends core::Object* = dynamic, S extends self::A2|method1::T* = dynamic>(final self::A1<self::A2|method1::T*>* #this) → self::A1<self::A2|method1::T*>* {
+static method A2|method1<T extends core::Object* = dynamic, S extends self::A2|method1::T* = dynamic>(lowered final self::A1<self::A2|method1::T*>* #this) → self::A1<self::A2|method1::T*>* {
   return #this;
 }
-static method A2|get#method1<T extends core::Object* = dynamic>(final self::A1<self::A2|get#method1::T*>* #this) → <S extends self::A2|get#method1::T* = dynamic>() →* self::A1<self::A2|get#method1::T*>*
+static method A2|get#method1<T extends core::Object* = dynamic>(lowered final self::A1<self::A2|get#method1::T*>* #this) → <S extends self::A2|get#method1::T* = dynamic>() →* self::A1<self::A2|get#method1::T*>*
   return <S extends self::A2|get#method1::T* = dynamic>() → self::A1<self::A2|get#method1::T*>* => self::A2|method1<self::A2|get#method1::T*, S*>(#this);
-static method A2|method2<T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::T*>* = self::A1<dynamic>*>(final self::A1<self::A2|method2::T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::T*>* {
+static method A2|method2<T extends core::Object* = dynamic, S extends self::A1<self::A2|method2::T*>* = self::A1<dynamic>*>(lowered final self::A1<self::A2|method2::T*>* #this, self::A2|method2::S* o) → self::A1<self::A2|method2::T*>* {
   core::print(o);
   core::print(self::A2|method2::T*);
   core::print(self::A2|method2::S*);
   return #this;
 }
-static method A2|get#method2<T extends core::Object* = dynamic>(final self::A1<self::A2|get#method2::T*>* #this) → <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S*) →* self::A1<self::A2|get#method2::T*>*
+static method A2|get#method2<T extends core::Object* = dynamic>(lowered final self::A1<self::A2|get#method2::T*>* #this) → <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S*) →* self::A1<self::A2|get#method2::T*>*
   return <S extends self::A1<self::A2|get#method2::T*>* = self::A1<dynamic>*>(S* o) → self::A1<self::A2|get#method2::T*>* => self::A2|method2<self::A2|get#method2::T*, S*>(#this, o);
-static method A4|method<#T extends core::Object* = dynamic, T extends core::Object* = dynamic>(final self::A1<self::A4|method::#T*>* #this) → dynamic {}
-static method A4|get#method<#T extends core::Object* = dynamic>(final self::A1<self::A4|get#method::#T*>* #this) → <T extends core::Object* = dynamic>() →* dynamic
+static method A4|method<#T extends core::Object* = dynamic, T extends core::Object* = dynamic>(lowered final self::A1<self::A4|method::#T*>* #this) → dynamic {}
+static method A4|get#method<#T extends core::Object* = dynamic>(lowered final self::A1<self::A4|get#method::#T*>* #this) → <T extends core::Object* = dynamic>() →* dynamic
   return <T extends core::Object* = dynamic>() → dynamic => self::A4|method<self::A4|get#method::#T*, T*>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect
index c671d48..bca6081 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect
@@ -50,29 +50,29 @@
   get property = self::_extension#1|get#property;
   set property = self::_extension#1|set#property;
 }
-static method _extension#0|method(final self::Class1* #this) → core::int*
+static method _extension#0|method(lowered final self::Class1* #this) → core::int*
   ;
-static method _extension#0|get#method(final self::Class1* #this) → () →* core::int*
+static method _extension#0|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::_extension#0|method(#this);
-static method _extension#0|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int*
+static method _extension#0|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int*
   ;
-static method _extension#0|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method _extension#0|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::_extension#0|genericMethod<T*>(#this, t);
-static method _extension#0|get#property(final self::Class1* #this) → core::int*
+static method _extension#0|get#property(lowered final self::Class1* #this) → core::int*
   ;
-static method _extension#0|set#property(final self::Class1* #this, core::int* value) → void
+static method _extension#0|set#property(lowered final self::Class1* #this, core::int* value) → void
   ;
-static method _extension#1|method(final self::Class2* #this) → core::int*
+static method _extension#1|method(lowered final self::Class2* #this) → core::int*
   ;
-static method _extension#1|get#method(final self::Class2* #this) → () →* core::int*
+static method _extension#1|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::_extension#1|method(#this);
-static method _extension#1|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int*
+static method _extension#1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int*
   ;
-static method _extension#1|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method _extension#1|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::_extension#1|genericMethod<T*>(#this, t);
-static method _extension#1|get#property(final self::Class2* #this) → core::int*
+static method _extension#1|get#property(lowered final self::Class2* #this) → core::int*
   ;
-static method _extension#1|set#property(final self::Class2* #this, core::int* value) → void
+static method _extension#1|set#property(lowered final self::Class2* #this, core::int* value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
index aa753cc..1786045 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
@@ -52,44 +52,44 @@
   get property = self::_extension#1|get#property;
   set property = self::_extension#1|set#property;
 }
-static method _extension#0|method(final self::Class1* #this) → core::int* {
+static method _extension#0|method(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.method on ${#this}");
   return #this.{self::Class1::field};
 }
-static method _extension#0|get#method(final self::Class1* #this) → () →* core::int*
+static method _extension#0|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::_extension#0|method(#this);
-static method _extension#0|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int* {
+static method _extension#0|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int* {
   core::print("Extension1.genericMethod<${self::_extension#0|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
 }
-static method _extension#0|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method _extension#0|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::_extension#0|genericMethod<T*>(#this, t);
-static method _extension#0|get#property(final self::Class1* #this) → core::int* {
+static method _extension#0|get#property(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.property get on ${#this}");
   return #this.{self::Class1::field};
 }
-static method _extension#0|set#property(final self::Class1* #this, core::int* value) → void {
+static method _extension#0|set#property(lowered final self::Class1* #this, core::int* value) → void {
   #this.{self::Class1::field} = value;
   core::print("Extension1.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
 }
-static method _extension#1|method(final self::Class2* #this) → core::int* {
+static method _extension#1|method(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.method on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(3);
 }
-static method _extension#1|get#method(final self::Class2* #this) → () →* core::int*
+static method _extension#1|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::_extension#1|method(#this);
-static method _extension#1|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int* {
+static method _extension#1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int* {
   core::print("Extension2.genericMethod<${self::_extension#1|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(4) as{TypeError} core::int*;
 }
-static method _extension#1|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method _extension#1|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::_extension#1|genericMethod<T*>(#this, t);
-static method _extension#1|get#property(final self::Class2* #this) → core::int* {
+static method _extension#1|get#property(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.property get on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(5);
 }
-static method _extension#1|set#property(final self::Class2* #this, core::int* value) → void {
+static method _extension#1|set#property(lowered final self::Class2* #this, core::int* value) → void {
   core::print("Extension2.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
   #this.{self::Class2::field} = value;
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
index 6d78eba..4e7371c 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
@@ -52,44 +52,44 @@
   get property = self::_extension#1|get#property;
   set property = self::_extension#1|set#property;
 }
-static method _extension#0|method(final self::Class1* #this) → core::int* {
+static method _extension#0|method(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.method on ${#this}");
   return #this.{self::Class1::field};
 }
-static method _extension#0|get#method(final self::Class1* #this) → () →* core::int*
+static method _extension#0|get#method(lowered final self::Class1* #this) → () →* core::int*
   return () → core::int* => self::_extension#0|method(#this);
-static method _extension#0|genericMethod<T extends core::num* = core::num*>(final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int* {
+static method _extension#0|genericMethod<T extends core::num* = core::num*>(lowered final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int* {
   core::print("Extension1.genericMethod<${self::_extension#0|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
 }
-static method _extension#0|get#genericMethod(final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method _extension#0|get#genericMethod(lowered final self::Class1* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::_extension#0|genericMethod<T*>(#this, t);
-static method _extension#0|get#property(final self::Class1* #this) → core::int* {
+static method _extension#0|get#property(lowered final self::Class1* #this) → core::int* {
   core::print("Extension1.property get on ${#this}");
   return #this.{self::Class1::field};
 }
-static method _extension#0|set#property(final self::Class1* #this, core::int* value) → void {
+static method _extension#0|set#property(lowered final self::Class1* #this, core::int* value) → void {
   #this.{self::Class1::field} = value;
   core::print("Extension1.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
 }
-static method _extension#1|method(final self::Class2* #this) → core::int* {
+static method _extension#1|method(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.method on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(3);
 }
-static method _extension#1|get#method(final self::Class2* #this) → () →* core::int*
+static method _extension#1|get#method(lowered final self::Class2* #this) → () →* core::int*
   return () → core::int* => self::_extension#1|method(#this);
-static method _extension#1|genericMethod<T extends core::num* = core::num*>(final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int* {
+static method _extension#1|genericMethod<T extends core::num* = core::num*>(lowered final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int* {
   core::print("Extension2.genericMethod<${self::_extension#1|genericMethod::T*}>(${t}) on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(4) as{TypeError} core::int*;
 }
-static method _extension#1|get#genericMethod(final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
+static method _extension#1|get#genericMethod(lowered final self::Class2* #this) → <T extends core::num* = core::num*>(T*) →* core::int*
   return <T extends core::num* = core::num*>(T* t) → core::int* => self::_extension#1|genericMethod<T*>(#this, t);
-static method _extension#1|get#property(final self::Class2* #this) → core::int* {
+static method _extension#1|get#property(lowered final self::Class2* #this) → core::int* {
   core::print("Extension2.property get on ${#this}");
   return #this.{self::Class2::field}.{core::num::+}(5);
 }
-static method _extension#1|set#property(final self::Class2* #this, core::int* value) → void {
+static method _extension#1|set#property(lowered final self::Class2* #this, core::int* value) → void {
   core::print("Extension2.property set(${value}) on ${#this}");
   value = value.{core::num::+}(1);
   #this.{self::Class2::field} = value;
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.outline.expect b/pkg/front_end/testcases/extensions/use_this.dart.outline.expect
index 70ab4eb..f40c736 100644
--- a/pkg/front_end/testcases/extensions/use_this.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/use_this.dart.outline.expect
@@ -42,21 +42,21 @@
   method method2 = self::B2|method2;
   tearoff method2 = self::B2|get#method2;
 }
-static method A2|method1(final self::A1* #this) → self::A1*
+static method A2|method1(lowered final self::A1* #this) → self::A1*
   ;
-static method A2|get#method1(final self::A1* #this) → () →* self::A1*
+static method A2|get#method1(lowered final self::A1* #this) → () →* self::A1*
   return () → self::A1* => self::A2|method1(#this);
-static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1*
+static method A2|method2<T extends core::Object* = dynamic>(lowered final self::A1* #this, self::A2|method2::T* o) → self::A1*
   ;
-static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
+static method A2|get#method2(lowered final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
   return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>*
+static method B2|method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>*
   ;
-static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
+static method B2|get#method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
   return () → self::B1<self::B2|get#method1::T*>* => self::B2|method1<self::B2|get#method1::T*>(#this);
-static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>*
+static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>*
   ;
-static method B2|get#method2<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
+static method B2|get#method2<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
   return <S extends core::Object* = dynamic>(S* o) → self::B1<self::B2|get#method2::T*>* => self::B2|method2<self::B2|get#method2::T*, S*>(#this, o);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.strong.expect b/pkg/front_end/testcases/extensions/use_this.dart.strong.expect
index f66aba6..f7ce7a4 100644
--- a/pkg/front_end/testcases/extensions/use_this.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/use_this.dart.strong.expect
@@ -44,26 +44,26 @@
   method method2 = self::B2|method2;
   tearoff method2 = self::B2|get#method2;
 }
-static method A2|method1(final self::A1* #this) → self::A1* {
+static method A2|method1(lowered final self::A1* #this) → self::A1* {
   return #this;
 }
-static method A2|get#method1(final self::A1* #this) → () →* self::A1*
+static method A2|get#method1(lowered final self::A1* #this) → () →* self::A1*
   return () → self::A1* => self::A2|method1(#this);
-static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(lowered final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
+static method A2|get#method2(lowered final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
   return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
+static method B2|method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
   return #this;
 }
-static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
+static method B2|get#method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
   return () → self::B1<self::B2|get#method1::T*>* => self::B2|method1<self::B2|get#method1::T*>(#this);
-static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
+static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
   core::print(o);
   return #this;
 }
-static method B2|get#method2<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
+static method B2|get#method2<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
   return <S extends core::Object* = dynamic>(S* o) → self::B1<self::B2|get#method2::T*>* => self::B2|method2<self::B2|get#method2::T*, S*>(#this, o);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect
index f66aba6..f7ce7a4 100644
--- a/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/use_this.dart.strong.transformed.expect
@@ -44,26 +44,26 @@
   method method2 = self::B2|method2;
   tearoff method2 = self::B2|get#method2;
 }
-static method A2|method1(final self::A1* #this) → self::A1* {
+static method A2|method1(lowered final self::A1* #this) → self::A1* {
   return #this;
 }
-static method A2|get#method1(final self::A1* #this) → () →* self::A1*
+static method A2|get#method1(lowered final self::A1* #this) → () →* self::A1*
   return () → self::A1* => self::A2|method1(#this);
-static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #this, self::A2|method2::T* o) → self::A1* {
+static method A2|method2<T extends core::Object* = dynamic>(lowered final self::A1* #this, self::A2|method2::T* o) → self::A1* {
   core::print(o);
   return #this;
 }
-static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
+static method A2|get#method2(lowered final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
   return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
+static method B2|method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>* {
   return #this;
 }
-static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
+static method B2|get#method1<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
   return () → self::B1<self::B2|get#method1::T*>* => self::B2|method1<self::B2|get#method1::T*>(#this);
-static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
+static method B2|method2<T extends core::Object* = dynamic, S extends core::Object* = dynamic>(lowered final self::B1<self::B2|method2::T*>* #this, self::B2|method2::S* o) → self::B1<self::B2|method2::T*>* {
   core::print(o);
   return #this;
 }
-static method B2|get#method2<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
+static method B2|get#method2<T extends core::Object* = dynamic>(lowered final self::B1<self::B2|get#method2::T*>* #this) → <S extends core::Object* = dynamic>(S*) →* self::B1<self::B2|get#method2::T*>*
   return <S extends core::Object* = dynamic>(S* o) → self::B1<self::B2|get#method2::T*>* => self::B2|method2<self::B2|get#method2::T*, S*>(#this, o);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
index 3382485..33ab33f 100644
--- a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
@@ -11,7 +11,6 @@
   final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
   core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -29,7 +28,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -40,7 +38,6 @@
   final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
   core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -58,7 +55,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -110,7 +106,6 @@
 static method asyncStarString() → asy::Stream<core::String*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -144,7 +139,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::String*>(:async_op);
@@ -154,7 +148,6 @@
 static method asyncStarString2() → asy::Stream<core::String*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -179,7 +172,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::String*>(:async_op);
@@ -190,7 +182,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -209,7 +200,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
index 772b468..78818d9 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
@@ -31,7 +31,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -69,7 +68,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/await.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
index 9bac1f2..04a6af0 100644
--- a/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
@@ -8,7 +8,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -27,7 +26,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
index d6a8b95..8b69c50 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
@@ -60,7 +60,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -107,7 +106,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -118,7 +116,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -160,7 +157,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -171,7 +167,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -214,7 +209,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -225,7 +219,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -268,7 +261,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -279,7 +271,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -342,7 +333,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -353,7 +343,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -417,7 +406,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -428,7 +416,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -562,7 +549,6 @@
                 final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
                 core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -582,7 +568,6 @@
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
                     asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :async_op.call();
@@ -594,7 +579,6 @@
                 final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
                 core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -612,7 +596,6 @@
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
                     asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :async_op.call();
@@ -623,7 +606,6 @@
               function testStream1() → asy::Stream<core::int*>* /* originally async* */ {
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -649,7 +631,6 @@
                   finally {
                     :controller.{asy::_AsyncStarStreamController::close}();
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
@@ -662,7 +643,6 @@
               function testStream2() → asy::Stream<core::int*>* /* originally async* */ {
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -688,7 +668,6 @@
                   finally {
                     :controller.{asy::_AsyncStarStreamController::close}();
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
@@ -708,7 +687,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -719,7 +697,6 @@
   final asy::_Future<self::future::T*>* :async_future = new asy::_Future::•<self::future::T*>();
   core::bool* :is_sync = false;
   FutureOr<self::future::T*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -737,7 +714,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -749,7 +725,6 @@
 static method intStream() → asy::Stream<core::int*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::int*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -774,7 +749,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
@@ -785,7 +759,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -818,7 +791,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
index fe03b1d..e178bdf 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
@@ -14,7 +14,6 @@
     final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
     core::bool* :is_sync = false;
     FutureOr<core::List<core::int*>*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -36,7 +35,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -47,7 +45,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -65,7 +62,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -87,7 +83,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -106,7 +101,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
index fe416ab..ea1347a 100644
--- a/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
@@ -13,7 +13,6 @@
   final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
   core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -31,7 +30,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
index 389811c..b800d2a 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
@@ -44,7 +44,6 @@
   final asy::_Future<core::List<core::Object*>*>* :async_future = new asy::_Future::•<core::List<core::Object*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::Object*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -62,7 +61,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -75,7 +73,6 @@
   final asy::_Future<core::Object*>* :async_future = new asy::_Future::•<core::Object*>();
   core::bool* :is_sync = false;
   FutureOr<core::Object*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -93,7 +90,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -104,7 +100,6 @@
   final asy::_Future<self::X*>* :async_future = new asy::_Future::•<self::X*>();
   core::bool* :is_sync = false;
   FutureOr<self::X*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -131,7 +126,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -142,7 +136,6 @@
   final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -161,7 +154,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
index ad4521b..fd3b4a6 100644
--- a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
@@ -11,7 +11,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -31,7 +30,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/constants/const_collections.dart.strong.expect b/pkg/front_end/testcases/general/constants/const_collections.dart.strong.expect
index b9b41ea..43efaee 100644
--- a/pkg/front_end/testcases/general/constants/const_collections.dart.strong.expect
+++ b/pkg/front_end/testcases/general/constants/const_collections.dart.strong.expect
@@ -405,9 +405,7 @@
 static const field core::List<core::String*>* foo = #C8;
 static const field core::List<core::String*>* bar = #C10;
 static field core::List<core::String*>* barAsVar = block {
-  final core::List<core::String*>* #t1 = <core::String*>[];
-  for (final core::String* #t2 in #C8)
-    #t1.{core::List::add}{Invariant}(#t2);
+  final core::List<core::String*>* #t1 = core::List::of<core::String*>(#C8);
   #t1.{core::List::add}{Invariant}("!");
 } =>#t1;
 static const field core::List<core::String*>* barWithNullSpread = invalid-expression "Null value during constant evaluation.";
@@ -481,9 +479,9 @@
   core::print(#C17);
   core::print(#C22);
   core::print( block {
-    final core::Set<core::String*>* #t3 = col::LinkedHashSet::•<core::String*>();
-    #t3.{core::Set::add}{Invariant}("hello");
-  } =>#t3);
+    final core::Set<core::String*>* #t2 = col::LinkedHashSet::•<core::String*>();
+    #t2.{core::Set::add}{Invariant}("hello");
+  } =>#t2);
   core::print(#C26);
 }
 
diff --git a/pkg/front_end/testcases/general/constants/const_collections.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constants/const_collections.dart.strong.transformed.expect
index 168f850..9b88a94 100644
--- a/pkg/front_end/testcases/general/constants/const_collections.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/const_collections.dart.strong.transformed.expect
@@ -405,14 +405,7 @@
 static const field core::List<core::String*>* foo = #C8;
 static const field core::List<core::String*>* bar = #C10;
 static field core::List<core::String*>* barAsVar = block {
-  final core::List<core::String*>* #t1 = <core::String*>[];
-  {
-    core::Iterator<core::String*>* :sync-for-iterator = (#C8).{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final core::String* #t2 = :sync-for-iterator.{core::Iterator::current};
-      #t1.{core::List::add}{Invariant}(#t2);
-    }
-  }
+  final core::List<core::String*>* #t1 = core::List::of<core::String*>(#C8);
   #t1.{core::List::add}{Invariant}("!");
 } =>#t1;
 static const field core::List<core::String*>* barWithNullSpread = invalid-expression "Null value during constant evaluation.";
@@ -486,9 +479,9 @@
   core::print(#C17);
   core::print(#C22);
   core::print( block {
-    final core::Set<core::String*>* #t3 = new col::_CompactLinkedHashSet::•<core::String*>();
-    #t3.{core::Set::add}{Invariant}("hello");
-  } =>#t3);
+    final core::Set<core::String*>* #t2 = new col::_CompactLinkedHashSet::•<core::String*>();
+    #t2.{core::Set::add}{Invariant}("hello");
+  } =>#t2);
   core::print(#C26);
 }
 
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart
new file mode 100644
index 0000000..952eff9
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "const_constructor_coverage_lib1.dart";
+import "const_constructor_coverage_lib2.dart";
+
+const Foo foo1 = const Foo();
+const Foo foo2 = const Foo.named1();
+const Foo foo3 = const Foo.named2();
+const Foo foo4 = const Foo.named3();
+
+main() {
+  print(foo1);
+}
+
+// This file in itself should mark the following as const-constructor-covered:
+// * "Foo", "Foo.named1", "Foo.named2" and "Foo.named3" from constant-evaluating
+//   the const fields.
+
+// Notice, that combined these 3 files should have coverage for:
+// * "Foo", "Foo.named1", "Foo.named2", "Foo.named3",
+// * "Bar", "Bar.named1", "Bar.named2", "Bar.named3",
+// * "Baz", "Baz.named1", "Baz.named4", "Baz.named5", "Baz.named6"
+// but NOT have any coverage for
+// * "Bar.named4",
+// * "Baz.named2" and "Baz.named3".
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.outline.expect b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.outline.expect
new file mode 100644
index 0000000..ea2f79f
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.outline.expect
@@ -0,0 +1,143 @@
+library;
+import self as self;
+import "const_constructor_coverage_lib1.dart" as con;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib1.dart";
+import "org-dartlang-testcase:///const_constructor_coverage_lib2.dart";
+
+static const field con::Foo* foo1 = const con::Foo::•();
+static const field con::Foo* foo2 = const con::Foo::named1();
+static const field con::Foo* foo3 = const con::Foo::named2();
+static const field con::Foo* foo4 = const con::Foo::named3();
+static method main() → dynamic
+  ;
+
+library;
+import self as con;
+import "dart:core" as core;
+import "const_constructor_coverage_lib2.dart" as con2;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib2.dart";
+
+class Foo extends core::Object /*hasConstConstructor*/  {
+  final field con::Bar* bar;
+  const constructor •() → con::Foo*
+    : con::Foo::bar = const con::Bar::•(), super core::Object::•()
+    ;
+  const constructor named1() → con::Foo*
+    : con::Foo::bar = const con::Bar::named1(), super core::Object::•()
+    ;
+  const constructor named2() → con::Foo*
+    : con::Foo::bar = const con::Bar::named1(), super core::Object::•()
+    ;
+  const constructor named3() → con::Foo*
+    : con::Foo::bar = const con::Bar::named1(), super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Bar extends core::Object /*hasConstConstructor*/  {
+  final field con2::Baz* baz;
+  const constructor •() → con::Bar*
+    : con::Bar::baz = const con2::Baz::•(), super core::Object::•()
+    ;
+  const constructor named1() → con::Bar*
+    : con::Bar::baz = const con2::Baz::named1(), super core::Object::•()
+    ;
+  const constructor named2() → con::Bar*
+    : con::Bar::baz = const con2::Baz::named1(), super core::Object::•()
+    ;
+  const constructor named3() → con::Bar*
+    : con::Bar::baz = const con2::Baz::named1(), super core::Object::•()
+    ;
+  const constructor named4(core::int* i) → con::Bar*
+    : con::Bar::baz = i.{core::num::>}(0) ?{con2::Baz*} const con2::Baz::named5() : const con2::Baz::named6(), super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static const field con::Foo* foo = const con::Foo::named3();
+
+library;
+import self as con2;
+import "dart:core" as core;
+import "const_constructor_coverage_lib1.dart" as con;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib1.dart";
+
+class Baz extends core::Object /*hasConstConstructor*/  {
+  final field con::Bar* bar;
+  const constructor •() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named1() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named2() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named3() → con2::Baz*
+    : con2::Baz::bar = const con::Bar::named3(), super core::Object::•()
+    ;
+  const constructor named4() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named5() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named6() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static const field con2::Baz* baz = const con2::Baz::named4();
+static const field con::Foo* foo = const con::Foo::named2();
+static const field con::Bar* bar = const con::Bar::named2();
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage.dart:8:24 -> InstanceConstant(const Foo{Foo.bar: const Bar{Bar.baz: const Baz{Baz.bar: null}}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage.dart:9:24 -> InstanceConstant(const Foo{Foo.bar: const Bar{Bar.baz: const Baz{Baz.bar: null}}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage.dart:10:24 -> InstanceConstant(const Foo{Foo.bar: const Bar{Bar.baz: const Baz{Baz.bar: null}}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage.dart:11:24 -> InstanceConstant(const Foo{Foo.bar: const Bar{Bar.baz: const Baz{Baz.bar: null}}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:9:35 -> InstanceConstant(const Bar{Bar.baz: const Baz{Baz.bar: null}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:10:42 -> InstanceConstant(const Bar{Bar.baz: const Baz{Baz.bar: null}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:11:42 -> InstanceConstant(const Bar{Bar.baz: const Baz{Baz.bar: null}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:12:42 -> InstanceConstant(const Bar{Bar.baz: const Baz{Baz.bar: null}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:17:35 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:18:42 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:19:42 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:20:42 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:22:29 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:22:50 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib1.dart:25:23 -> InstanceConstant(const Foo{Foo.bar: const Bar{Bar.baz: const Baz{Baz.bar: null}}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib2.dart:12:36 -> InstanceConstant(const Bar{Bar.baz: const Baz{Baz.bar: null}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib2.dart:18:23 -> InstanceConstant(const Baz{Baz.bar: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib2.dart:19:23 -> InstanceConstant(const Foo{Foo.bar: const Bar{Bar.baz: const Baz{Baz.bar: null}}})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_constructor_coverage_lib2.dart:20:23 -> InstanceConstant(const Bar{Bar.baz: const Baz{Baz.bar: null}})
+Extra constant evaluation: evaluated: 22, effectively constant: 19
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.strong.expect b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.strong.expect
new file mode 100644
index 0000000..19a070b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.strong.expect
@@ -0,0 +1,129 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "const_constructor_coverage_lib1.dart" as con;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib1.dart";
+import "org-dartlang-testcase:///const_constructor_coverage_lib2.dart";
+
+static const field con::Foo* foo1 = #C4;
+static const field con::Foo* foo2 = #C4;
+static const field con::Foo* foo3 = #C4;
+static const field con::Foo* foo4 = #C4;
+static method main() → dynamic {
+  core::print(#C4);
+}
+
+library;
+import self as con;
+import "dart:core" as core;
+import "const_constructor_coverage_lib2.dart" as con2;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib2.dart";
+
+class Foo extends core::Object /*hasConstConstructor*/  {
+  final field con::Bar* bar;
+  const constructor •() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  const constructor named1() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  const constructor named2() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  const constructor named3() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Bar extends core::Object /*hasConstConstructor*/  {
+  final field con2::Baz* baz;
+  const constructor •() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named1() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named2() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named3() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named4(core::int* i) → con::Bar*
+    : con::Bar::baz = i.{core::num::>}(0) ?{con2::Baz*} #C2 : #C2, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static const field con::Foo* foo = #C4;
+
+library;
+import self as con2;
+import "dart:core" as core;
+import "const_constructor_coverage_lib1.dart" as con;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib1.dart";
+
+class Baz extends core::Object /*hasConstConstructor*/  {
+  final field con::Bar* bar;
+  const constructor •() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named1() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named2() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named3() → con2::Baz*
+    : con2::Baz::bar = #C3, super core::Object::•()
+    ;
+  const constructor named4() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named5() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named6() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static const field con2::Baz* baz = #C2;
+static const field con::Foo* foo = #C4;
+static const field con::Bar* bar = #C3;
+
+constants  {
+  #C1 = null
+  #C2 = con2::Baz {bar:#C1}
+  #C3 = con::Bar {baz:#C2}
+  #C4 = con::Foo {bar:#C3}
+}
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.strong.transformed.expect
new file mode 100644
index 0000000..19a070b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.strong.transformed.expect
@@ -0,0 +1,129 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "const_constructor_coverage_lib1.dart" as con;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib1.dart";
+import "org-dartlang-testcase:///const_constructor_coverage_lib2.dart";
+
+static const field con::Foo* foo1 = #C4;
+static const field con::Foo* foo2 = #C4;
+static const field con::Foo* foo3 = #C4;
+static const field con::Foo* foo4 = #C4;
+static method main() → dynamic {
+  core::print(#C4);
+}
+
+library;
+import self as con;
+import "dart:core" as core;
+import "const_constructor_coverage_lib2.dart" as con2;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib2.dart";
+
+class Foo extends core::Object /*hasConstConstructor*/  {
+  final field con::Bar* bar;
+  const constructor •() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  const constructor named1() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  const constructor named2() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  const constructor named3() → con::Foo*
+    : con::Foo::bar = #C3, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Bar extends core::Object /*hasConstConstructor*/  {
+  final field con2::Baz* baz;
+  const constructor •() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named1() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named2() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named3() → con::Bar*
+    : con::Bar::baz = #C2, super core::Object::•()
+    ;
+  const constructor named4(core::int* i) → con::Bar*
+    : con::Bar::baz = i.{core::num::>}(0) ?{con2::Baz*} #C2 : #C2, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static const field con::Foo* foo = #C4;
+
+library;
+import self as con2;
+import "dart:core" as core;
+import "const_constructor_coverage_lib1.dart" as con;
+
+import "org-dartlang-testcase:///const_constructor_coverage_lib1.dart";
+
+class Baz extends core::Object /*hasConstConstructor*/  {
+  final field con::Bar* bar;
+  const constructor •() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named1() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named2() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named3() → con2::Baz*
+    : con2::Baz::bar = #C3, super core::Object::•()
+    ;
+  const constructor named4() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named5() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  const constructor named6() → con2::Baz*
+    : con2::Baz::bar = null, super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static const field con2::Baz* baz = #C2;
+static const field con::Foo* foo = #C4;
+static const field con::Bar* bar = #C3;
+
+constants  {
+  #C1 = null
+  #C2 = con2::Baz {bar:#C1}
+  #C3 = con::Bar {baz:#C2}
+  #C4 = con::Foo {bar:#C3}
+}
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.textual_outline.expect
new file mode 100644
index 0000000..a7b8a8a
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+import "const_constructor_coverage_lib1.dart";
+import "const_constructor_coverage_lib2.dart";
+
+const Foo foo1 = const Foo();
+const Foo foo2 = const Foo.named1();
+const Foo foo3 = const Foo.named2();
+const Foo foo4 = const Foo.named3();
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a7b8a8a
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import "const_constructor_coverage_lib1.dart";
+import "const_constructor_coverage_lib2.dart";
+
+const Foo foo1 = const Foo();
+const Foo foo2 = const Foo.named1();
+const Foo foo3 = const Foo.named2();
+const Foo foo4 = const Foo.named3();
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage_lib1.dart b/pkg/front_end/testcases/general/constants/const_constructor_coverage_lib1.dart
new file mode 100644
index 0000000..e7d6647
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage_lib1.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "const_constructor_coverage_lib2.dart";
+
+class Foo {
+  final Bar bar;
+  const /*x*/ Foo() : bar = const Bar();
+  const /*x*/ Foo.named1() : bar = const Bar.named1();
+  const /*x*/ Foo.named2() : bar = const Bar.named1();
+  const /*x*/ Foo.named3() : bar = const Bar.named1();
+}
+
+class Bar {
+  final Baz baz;
+  const /*x*/ Bar() : baz = const Baz();
+  const /*x*/ Bar.named1() : baz = const Baz.named1();
+  const /*x*/ Bar.named2() : baz = const Baz.named1();
+  const /*x*/ Bar.named3() : baz = const Baz.named1();
+  const Bar.named4(int i)
+      : baz = i > 0 ? const Baz.named5() : const Baz.named6();
+}
+
+const Foo foo = const Foo.named3();
+
+// This file in itself should mark the following as const-constructor-covered:
+// * "Bar", "Bar.named1", "Baz", "Baz.named1", "Baz.named5" and "Baz.named6"
+//   from evaluating field initializers (done unconditionally).
+// * "Foo.named3" from constant-evaluating the const field.
diff --git a/pkg/front_end/testcases/general/constants/const_constructor_coverage_lib2.dart b/pkg/front_end/testcases/general/constants/const_constructor_coverage_lib2.dart
new file mode 100644
index 0000000..88e63b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/const_constructor_coverage_lib2.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "const_constructor_coverage_lib1.dart";
+
+class Baz {
+  final Bar bar;
+  const /*x*/ Baz() : bar = null;
+  const /*x*/ Baz.named1() : bar = null;
+  const Baz.named2() : bar = null;
+  const Baz.named3() : bar = const Bar.named3();
+  const /*x*/ Baz.named4() : bar = null;
+  const /*x*/ Baz.named5() : bar = null;
+  const /*x*/ Baz.named6() : bar = null;
+}
+
+const Baz baz = const Baz.named4();
+const Foo foo = const Foo.named2();
+const Bar bar = const Bar.named2();
+
+// This file in itself should mark the following as const-constructor-covered:
+// * "Bar.named3" from evaluating field initializers (done unconditionally).
+// * "Baz.named4", "Foo.named2" and "Bar.named2" from constant-evaluating the
+//   const fields.
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart b/pkg/front_end/testcases/general/constants/from_lib/main.dart
new file mode 100644
index 0000000..b301857
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'main_lib.dart' as a;
+
+const map = <int, String>{
+  ...a.map,
+};
+
+const set = <int>{
+  ...a.set,
+  ...a.list,
+};
+
+const list = <int>[
+  ...a.list,
+  ...a.set,
+];
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.outline.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.outline.expect
new file mode 100644
index 0000000..280c0fe
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.outline.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart" as a;
+
+static const field core::Map<core::int*, core::String*>* map = mai::map;
+static const field core::Set<core::int*>* set = mai::set + mai::list;
+static const field core::List<core::int*>* list = mai::list + mai::set;
+static method main() → dynamic
+  ;
+
+library;
+import self as mai;
+import "dart:core" as core;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C9;
+static const field core::List<core::int*>* list = #C11;
+
+constants  {
+  #C1 = 1
+  #C2 = "a"
+  #C3 = <dynamic>[#C1, #C2]
+  #C4 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C3}
+  #C5 = 2
+  #C6 = null
+  #C7 = <dynamic>[#C5, #C6]
+  #C8 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C7}
+  #C9 = col::_UnmodifiableSet<core::int*> {_map:#C8}
+  #C10 = 3
+  #C11 = <core::int*>[#C10]
+}
+
+Extra constant evaluation status:
+Evaluated: MapConcatenation @ org-dartlang-testcase:///main.dart:7:7 -> InstanceConstant(const _ImmutableMap<int*, String*>{_ImmutableMap._kvPairs: const <dynamic>[1, "a"]})
+Evaluated: SetConcatenation @ org-dartlang-testcase:///main.dart:11:18 -> InstanceConstant(const _UnmodifiableSet<int*>{_UnmodifiableSet._map: const _ImmutableMap<int*, Null>{_ImmutableMap._kvPairs: const <dynamic>[2, null, 3, null]}})
+Evaluated: ListConcatenation @ org-dartlang-testcase:///main.dart:16:19 -> ListConstant(const <int*>[3, 2])
+Extra constant evaluation: evaluated: 3, effectively constant: 3
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.expect
new file mode 100644
index 0000000..c76837e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart" as a;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C10;
+static const field core::List<core::int*>* list = #C11;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C14;
+static const field core::List<core::int*>* list = #C15;
+
+constants  {
+  #C1 = 1
+  #C2 = "a"
+  #C3 = <dynamic>[#C1, #C2]
+  #C4 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C3}
+  #C5 = 2
+  #C6 = null
+  #C7 = 3
+  #C8 = <dynamic>[#C5, #C6, #C7, #C6]
+  #C9 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C8}
+  #C10 = col::_UnmodifiableSet<core::int*> {_map:#C9}
+  #C11 = <core::int*>[#C7, #C5]
+  #C12 = <dynamic>[#C5, #C6]
+  #C13 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C12}
+  #C14 = col::_UnmodifiableSet<core::int*> {_map:#C13}
+  #C15 = <core::int*>[#C7]
+}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..c76837e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart" as a;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C10;
+static const field core::List<core::int*>* list = #C11;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C14;
+static const field core::List<core::int*>* list = #C15;
+
+constants  {
+  #C1 = 1
+  #C2 = "a"
+  #C3 = <dynamic>[#C1, #C2]
+  #C4 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C3}
+  #C5 = 2
+  #C6 = null
+  #C7 = 3
+  #C8 = <dynamic>[#C5, #C6, #C7, #C6]
+  #C9 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C8}
+  #C10 = col::_UnmodifiableSet<core::int*> {_map:#C9}
+  #C11 = <core::int*>[#C7, #C5]
+  #C12 = <dynamic>[#C5, #C6]
+  #C13 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C12}
+  #C14 = col::_UnmodifiableSet<core::int*> {_map:#C13}
+  #C15 = <core::int*>[#C7]
+}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline.expect
new file mode 100644
index 0000000..ecc271e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import 'main_lib.dart' as a;
+
+const map = <int, String>{
+  ...a.map,
+};
+const set = <int>{
+  ...a.set,
+  ...a.list,
+};
+const list = <int>[
+  ...a.list,
+  ...a.set,
+];
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b817c1c
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import 'main_lib.dart' as a;
+
+const list = <int>[
+  ...a.list,
+  ...a.set,
+];
+const map = <int, String>{
+  ...a.map,
+};
+const set = <int>{
+  ...a.set,
+  ...a.list,
+};
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main_lib.dart b/pkg/front_end/testcases/general/constants/from_lib/main_lib.dart
new file mode 100644
index 0000000..eccfc0b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const map = <int, String>{
+  1: 'a',
+};
+
+const set = <int>{
+  2,
+};
+
+const list = <int>[
+  3,
+];
diff --git a/pkg/front_end/testcases/general/constants/from_lib/test.options b/pkg/front_end/testcases/general/constants/from_lib/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.outline.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.outline.expect
index 7171bac..e60e513 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.outline.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.outline.expect
@@ -22,7 +22,8 @@
 //   const Class.method(T t) : this(-t);
 //                                  ^
 //
-// pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart:123:27: Error: Optional parameter 'named' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart:123:27: Error: The parameter 'named' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // int procedure(int i, {int named}) => i;
 //                           ^^^^^
 //
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.expect
index aa1a131..8f2590a 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.expect
@@ -22,7 +22,8 @@
 //   const Class.method(T t) : this(-t);
 //                                  ^
 //
-// pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart:123:27: Error: Optional parameter 'named' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart:123:27: Error: The parameter 'named' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // int procedure(int i, {int named}) => i;
 //                           ^^^^^
 //
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.transformed.expect
index 9d5946b..858bb47 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart.strong.transformed.expect
@@ -22,7 +22,8 @@
 //   const Class.method(T t) : this(-t);
 //                                  ^
 //
-// pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart:123:27: Error: Optional parameter 'named' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various.dart:123:27: Error: The parameter 'named' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // int procedure(int i, {int named}) => i;
 //                           ^^^^^
 //
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.strong.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.strong.expect
index dffdbc4..bc26325 100644
--- a/pkg/front_end/testcases/general/control_flow_collection.dart.strong.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.strong.expect
@@ -5,8 +5,7 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
+    final core::List<core::int*>* #t1 = <core::int*>[1];
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
       #t1.{core::List::add}{Invariant}(2);
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect
index 6041ee9..17ab5b6 100644
--- a/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.strong.transformed.expect
@@ -5,8 +5,7 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
+    final core::List<core::int*>* #t1 = <core::int*>[1];
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
       #t1.{core::List::add}{Invariant}(2);
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -107,4 +106,4 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///control_flow_collection.dart:18:26 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///control_flow_collection.dart:27:29 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///control_flow_collection.dart:27:33 -> IntConstant(-1)
-Extra constant evaluation: evaluated: 160, effectively constant: 4
+Extra constant evaluation: evaluated: 158, effectively constant: 4
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
index 4065ab1..6f6e59d 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
@@ -505,553 +505,512 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t11 in <core::int*>[42])
-        #t10.{core::List::add}{Invariant}(#t11);
+      #t10.{core::List::addAll}{Invariant}(<core::int*>[42]);
   } =>#t10;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t12 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t13 in <core::int*>[42])
-        #t12.{core::Set::add}{Invariant}(#t13);
-    #t12.{core::Set::add}{Invariant}(null);
-  } =>#t12;
+      #t11.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t11.{core::Set::add}{Invariant}(null);
+  } =>#t11;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::int*>* #t15 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
-        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
-    #t14.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t14;
+      for (final core::MapEntry<core::String*, core::int*>* #t13 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
+    #t12.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t12;
   core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t16 = <dynamic>[];
+    final core::List<dynamic>* #t14 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t17 in <dynamic>[dynVar])
-        #t16.{core::List::add}{Invariant}(#t17);
-  } =>#t16;
+      #t14.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t14;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t18 = col::LinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t15 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t19 in <dynamic>[dynVar])
-        #t18.{core::Set::add}{Invariant}(#t19);
-    #t18.{core::Set::add}{Invariant}(null);
-  } =>#t18;
+      #t15.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t15.{core::Set::add}{Invariant}(null);
+  } =>#t15;
   core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t16 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, dynamic>* #t21 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+      for (final core::MapEntry<core::String*, dynamic>* #t17 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+    #t16.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t16;
+  core::List<core::List<core::int*>*>* list22 = block {
+    final core::List<core::List<core::int*>*>* #t18 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t18.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t18;
+  core::Set<core::List<core::int*>*>* set22 = block {
+    final core::Set<core::List<core::int*>*>* #t19 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t19.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t19.{core::Set::add}{Invariant}(null);
+  } =>#t19;
+  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t20 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t21 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
         #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
     #t20.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t20;
-  core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t23 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t22.{core::List::add}{Invariant}(#t23);
-  } =>#t22;
-  core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t24 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t25 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t24.{core::Set::add}{Invariant}(#t25);
-    #t24.{core::Set::add}{Invariant}(null);
-  } =>#t24;
-  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
-        #t26.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
-    #t26.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t26;
   core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t28 = <core::int*>[];
+    final core::List<core::int*>* #t22 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t29 in <core::int*>[42])
-          #t28.{core::List::add}{Invariant}(#t29);
-  } =>#t28;
+        #t22.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t22;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t23 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t31 in <core::int*>[42])
-          #t30.{core::Set::add}{Invariant}(#t31);
-    #t30.{core::Set::add}{Invariant}(null);
-  } =>#t30;
+        #t23.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t23.{core::Set::add}{Invariant}(null);
+  } =>#t23;
   core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t24 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::int*>* #t33 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+        for (final core::MapEntry<core::String*, core::int*>* #t25 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+          #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
+    #t24.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t24;
+  core::List<dynamic>* list31 = block {
+    final core::List<dynamic>* #t26 = <dynamic>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t26.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t26;
+  core::Set<dynamic>* set31 = block {
+    final core::Set<dynamic>* #t27 = col::LinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t27.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t27.{core::Set::add}{Invariant}(null);
+  } =>#t27;
+  core::Map<core::String*, dynamic>* map31 = block {
+    final core::Map<core::String*, dynamic>* #t28 = <core::String*, dynamic>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, dynamic>* #t29 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+          #t28.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
+    #t28.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t28;
+  core::List<core::List<core::int*>*>* list33 = block {
+    final core::List<core::List<core::int*>*>* #t30 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t30.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t30;
+  core::Set<core::List<core::int*>*>* set33 = block {
+    final core::Set<core::List<core::int*>*>* #t31 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t31.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t31.{core::Set::add}{Invariant}(null);
+  } =>#t31;
+  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
           #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
     #t32.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t32;
-  core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t34 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t35 in <dynamic>[dynVar])
-          #t34.{core::List::add}{Invariant}(#t35);
-  } =>#t34;
-  core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t36 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t37 in <dynamic>[dynVar])
-          #t36.{core::Set::add}{Invariant}(#t37);
-    #t36.{core::Set::add}{Invariant}(null);
-  } =>#t36;
-  core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, dynamic>* #t39 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
-          #t38.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
-    #t38.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t38;
-  core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t41 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t40.{core::List::add}{Invariant}(#t41);
-  } =>#t40;
-  core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t42 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t43 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t42.{core::Set::add}{Invariant}(#t43);
-    #t42.{core::Set::add}{Invariant}(null);
-  } =>#t42;
-  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
-          #t44.{core::Map::[]=}{Invariant}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
-    #t44.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t44;
   core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t34 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t47 in <core::List<core::int*>*>[<core::int*>[]])
-        #t46.{core::List::add}{Invariant}(#t47);
-  } =>#t46;
+      #t34.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t34;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t48 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t35 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t49 in <core::List<core::int*>*>[<core::int*>[]])
-        #t48.{core::Set::add}{Invariant}(#t49);
-    #t48.{core::Set::add}{Invariant}(null);
-  } =>#t48;
+      #t35.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t35.{core::Set::add}{Invariant}(null);
+  } =>#t35;
   core::Map<core::String*, core::List<core::int*>*>* map40 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:39:34: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
   Map<String, List<int>> map40 = {if (oracle(\"foo\")) ...{\"bar\", []}, \"baz\": null};
                                  ^";
   core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t36 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t51 in block {
-        final core::Set<core::List<core::int*>*>* #t52 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t52.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t52)
-        #t50.{core::List::add}{Invariant}(#t51);
-  } =>#t50;
+      #t36.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t37.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t37);
+  } =>#t36;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t53 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t38 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t54 in block {
-        final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t55.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t55)
-        #t53.{core::Set::add}{Invariant}(#t54);
+      #t38.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t39.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t39);
+    #t38.{core::Set::add}{Invariant}(null);
+  } =>#t38;
+  core::List<core::List<core::int*>*>* list42 = block {
+    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t40.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t40;
+  core::Set<core::List<core::int*>*>* set42 = block {
+    final core::Set<core::List<core::int*>*>* #t41 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t41.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t41.{core::Set::add}{Invariant}(null);
+  } =>#t41;
+  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
+    #t42.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t42;
+  core::List<core::int*>* list50 = block {
+    final core::List<core::int*>* #t44 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t44.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t44;
+  core::Set<core::int*>* set50 = block {
+    final core::Set<core::int*>* #t45 = col::LinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t45.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t45.{core::Set::add}{Invariant}(null);
+  } =>#t45;
+  core::Map<core::String*, core::int*>* map50 = block {
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      for (final core::MapEntry<core::String*, core::int*>* #t47 in <core::String*, core::int*>{}.{core::Map::entries})
+        #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
+    #t46.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t46;
+  core::List<core::int*>* list51 = block {
+    final core::List<core::int*>* #t48 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t48.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t49 = col::LinkedHashSet::•<core::int*>();
+      } =>#t49);
+  } =>#t48;
+  core::Set<core::int*>* set51 = block {
+    final core::Set<core::int*>* #t50 = col::LinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t50.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
+      } =>#t51);
+    #t50.{core::Set::add}{Invariant}(null);
+  } =>#t50;
+  core::List<core::int*>* list52 = block {
+    final core::List<core::int*>* #t52 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t52.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t52;
+  core::Set<core::int*>* set52 = block {
+    final core::Set<core::int*>* #t53 = col::LinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t53.{core::Set::addAll}{Invariant}(<core::int*>[]);
     #t53.{core::Set::add}{Invariant}(null);
   } =>#t53;
-  core::List<core::List<core::int*>*>* list42 = block {
+  core::Map<core::String*, core::int*>* map52 = block {
+    final core::Map<core::String*, core::int*>* #t54 = <core::String*, core::int*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::int*>* #t55 in <core::String*, core::int*>{}.{core::Map::entries})
+          #t54.{core::Map::[]=}{Invariant}(#t55.{core::MapEntry::key}, #t55.{core::MapEntry::value});
+    #t54.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t54;
+  core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t56 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t57 in <core::List<core::int*>*>[<core::int*>[]])
-          #t56.{core::List::add}{Invariant}(#t57);
+      #t56.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
   } =>#t56;
-  core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t58 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t59 in <core::List<core::int*>*>[<core::int*>[]])
-          #t58.{core::Set::add}{Invariant}(#t59);
-    #t58.{core::Set::add}{Invariant}(null);
-  } =>#t58;
-  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t60 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t61 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t60.{core::Map::[]=}{Invariant}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value});
-    #t60.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t60;
-  core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t62 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t63 in <core::int*>[])
-        #t62.{core::List::add}{Invariant}(#t63);
-  } =>#t62;
-  core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t64 = col::LinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t65 in <core::int*>[])
-        #t64.{core::Set::add}{Invariant}(#t65);
-    #t64.{core::Set::add}{Invariant}(null);
-  } =>#t64;
-  core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t66 = <core::String*, core::int*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::int*>* #t67 in <core::String*, core::int*>{}.{core::Map::entries})
-        #t66.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
-    #t66.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t66;
-  core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t68 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t69 in block {
-        final core::Set<core::int*>* #t70 = col::LinkedHashSet::•<core::int*>();
-      } =>#t70)
-        #t68.{core::List::add}{Invariant}(#t69);
-  } =>#t68;
-  core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t72 in block {
-        final core::Set<core::int*>* #t73 = col::LinkedHashSet::•<core::int*>();
-      } =>#t73)
-        #t71.{core::Set::add}{Invariant}(#t72);
-    #t71.{core::Set::add}{Invariant}(null);
-  } =>#t71;
-  core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t74 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t75 in <core::int*>[])
-          #t74.{core::List::add}{Invariant}(#t75);
-  } =>#t74;
-  core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t76 = col::LinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t77 in <core::int*>[])
-          #t76.{core::Set::add}{Invariant}(#t77);
-    #t76.{core::Set::add}{Invariant}(null);
-  } =>#t76;
-  core::Map<core::String*, core::int*>* map52 = block {
-    final core::Map<core::String*, core::int*>* #t78 = <core::String*, core::int*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::int*>* #t79 in <core::String*, core::int*>{}.{core::Map::entries})
-          #t78.{core::Map::[]=}{Invariant}(#t79.{core::MapEntry::key}, #t79.{core::MapEntry::value});
-    #t78.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t78;
-  core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t80 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t81 in <core::List<core::int*>*>[<core::int*>[]])
-        #t80.{core::List::add}{Invariant}(#t81);
-  } =>#t80;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t82 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t57 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t83 in <core::List<core::int*>*>[<core::int*>[]])
-        #t82.{core::Set::add}{Invariant}(#t83);
-    #t82.{core::Set::add}{Invariant}(null);
-  } =>#t82;
+      #t57.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t57.{core::Set::add}{Invariant}(null);
+  } =>#t57;
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t84 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t58 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t85 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-        #t84.{core::Map::[]=}{Invariant}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
-    #t84.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t84;
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t59 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+        #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
+    #t58.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t58;
   core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t86 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t60 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t87 in <core::List<core::int*>*>[<core::int*>[]])
-          #t86.{core::List::add}{Invariant}(#t87);
-  } =>#t86;
+        #t60.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t60;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t88 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t61 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t89 in <core::List<core::int*>*>[<core::int*>[]])
-          #t88.{core::Set::add}{Invariant}(#t89);
-    #t88.{core::Set::add}{Invariant}(null);
-  } =>#t88;
+        #t61.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t61.{core::Set::add}{Invariant}(null);
+  } =>#t61;
   core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t90 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t91 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t90.{core::Map::[]=}{Invariant}(#t91.{core::MapEntry::key}, #t91.{core::MapEntry::value});
-    #t90.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t90;
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t62.{core::Map::[]=}{Invariant}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
+    #t62.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t62;
   core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t92 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t64 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t92.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t92;
+      #t64.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t64;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t93 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t65 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t93.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t93.{core::Set::add}{Invariant}(null);
-  } =>#t93;
+      #t65.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t65.{core::Set::add}{Invariant}(null);
+  } =>#t65;
   core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t94 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t66 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t94.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t94;
+        #t66.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t66;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t95 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t67 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t95.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t95.{core::Set::add}{Invariant}(null);
-  } =>#t95;
+        #t67.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t67.{core::Set::add}{Invariant}(null);
+  } =>#t67;
   core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t96 = <core::num*>[];
+    final core::List<core::num*>* #t68 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t96.{core::List::add}{Invariant}(42);
+      #t68.{core::List::add}{Invariant}(42);
     else
-      #t96.{core::List::add}{Invariant}(3.14);
-  } =>#t96;
+      #t68.{core::List::add}{Invariant}(3.14);
+  } =>#t68;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t97 = col::LinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t69 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t97.{core::Set::add}{Invariant}(42);
+      #t69.{core::Set::add}{Invariant}(42);
     else
-      #t97.{core::Set::add}{Invariant}(3.14);
-    #t97.{core::Set::add}{Invariant}(null);
-  } =>#t97;
+      #t69.{core::Set::add}{Invariant}(3.14);
+    #t69.{core::Set::add}{Invariant}(null);
+  } =>#t69;
   core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t98 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t70 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t98.{core::Map::[]=}{Invariant}("bar", 42);
+      #t70.{core::Map::[]=}{Invariant}("bar", 42);
     else
-      #t98.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t98.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t98;
+      #t70.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t70.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t70;
   core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t99 = <core::num*>[];
+    final core::List<core::num*>* #t71 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::num* #t100 in listInt)
-        #t99.{core::List::add}{Invariant}(#t100);
+      #t71.{core::List::addAll}{Invariant}(listInt);
     else
-      for (final core::num* #t101 in listDouble)
-        #t99.{core::List::add}{Invariant}(#t101);
-  } =>#t99;
+      #t71.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t71;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t102 = col::LinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t72 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::num* #t103 in listInt)
-        #t102.{core::Set::add}{Invariant}(#t103);
+      #t72.{core::Set::addAll}{Invariant}(listInt);
     else
-      for (final core::num* #t104 in listDouble)
-        #t102.{core::Set::add}{Invariant}(#t104);
-    #t102.{core::Set::add}{Invariant}(null);
-  } =>#t102;
+      #t72.{core::Set::addAll}{Invariant}(listDouble);
+    #t72.{core::Set::add}{Invariant}(null);
+  } =>#t72;
   core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t105 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t73 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::num*>* #t106 in mapToInt.{core::Map::entries})
-        #t105.{core::Map::[]=}{Invariant}(#t106.{core::MapEntry::key}, #t106.{core::MapEntry::value});
+      for (final core::MapEntry<core::String*, core::num*>* #t74 in mapToInt.{core::Map::entries})
+        #t73.{core::Map::[]=}{Invariant}(#t74.{core::MapEntry::key}, #t74.{core::MapEntry::value});
     else
-      for (final core::MapEntry<core::String*, core::num*>* #t107 in mapToDouble.{core::Map::entries})
-        #t105.{core::Map::[]=}{Invariant}(#t107.{core::MapEntry::key}, #t107.{core::MapEntry::value});
-    #t105.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t105;
+      for (final core::MapEntry<core::String*, core::num*>* #t75 in mapToDouble.{core::Map::entries})
+        #t73.{core::Map::[]=}{Invariant}(#t75.{core::MapEntry::key}, #t75.{core::MapEntry::value});
+    #t73.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t73;
   core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t108 = <dynamic>[];
+    final core::List<dynamic>* #t76 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t109 in listInt)
-        #t108.{core::List::add}{Invariant}(#t109);
+      #t76.{core::List::addAll}{Invariant}(listInt);
     else
-      for (final dynamic #t110 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-        #t108.{core::List::add}{Invariant}(#t110);
-  } =>#t108;
+      #t76.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t76;
   core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t111 = col::LinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t77 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t112 in listInt)
-        #t111.{core::Set::add}{Invariant}(#t112);
+      #t77.{core::Set::addAll}{Invariant}(listInt);
     else
-      for (final dynamic #t113 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-        #t111.{core::Set::add}{Invariant}(#t113);
-    #t111.{core::Set::add}{Invariant}(null);
-  } =>#t111;
+      #t77.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t77.{core::Set::add}{Invariant}(null);
+  } =>#t77;
   core::Set<dynamic>* map82 = block {
-    final core::Set<dynamic>* #t114 = col::LinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t78 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t114.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t78.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
     else
-      for (final dynamic #t115 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-        #t114.{core::Set::add}{Invariant}(#t115);
-    #t114.{core::Set::add}{Invariant}(null);
-  } =>#t114;
+      #t78.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t78.{core::Set::add}{Invariant}(null);
+  } =>#t78;
   core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t116 = <core::num*>[];
+    final core::List<core::num*>* #t79 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t116.{core::List::add}{Invariant}(42);
+      #t79.{core::List::add}{Invariant}(42);
     else
-      for (final core::num* #t117 in listDouble)
-        #t116.{core::List::add}{Invariant}(#t117);
-  } =>#t116;
+      #t79.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t79;
   core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t118 = col::LinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t80 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::num* #t119 in listInt)
-        #t118.{core::Set::add}{Invariant}(#t119);
+      #t80.{core::Set::addAll}{Invariant}(listInt);
     else
-      #t118.{core::Set::add}{Invariant}(3.14);
-    #t118.{core::Set::add}{Invariant}(null);
-  } =>#t118;
+      #t80.{core::Set::add}{Invariant}(3.14);
+    #t80.{core::Set::add}{Invariant}(null);
+  } =>#t80;
   core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t120 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t81 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::num*>* #t121 in mapToInt.{core::Map::entries})
-        #t120.{core::Map::[]=}{Invariant}(#t121.{core::MapEntry::key}, #t121.{core::MapEntry::value});
+      for (final core::MapEntry<core::String*, core::num*>* #t82 in mapToInt.{core::Map::entries})
+        #t81.{core::Map::[]=}{Invariant}(#t82.{core::MapEntry::key}, #t82.{core::MapEntry::value});
     else
-      #t120.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t120.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t120;
+      #t81.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t81.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t81;
   core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t122 = <core::int*>[];
+    final core::List<core::int*>* #t83 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t122.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t122;
+      #t83.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+  } =>#t83;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t123 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t84 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t123.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t123.{core::Set::add}{Invariant}(null);
-  } =>#t123;
+      #t84.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t84.{core::Set::add}{Invariant}(null);
+  } =>#t84;
   core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t124 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t85 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t124.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t124.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t124;
+      #t85.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t85.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t85;
   core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t125 = <core::int*>[];
+    final core::List<core::int*>* #t86 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t126 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t127 = #t126 as{TypeError} core::int*;
-        #t125.{core::List::add}{Invariant}(#t127);
+      for (final dynamic #t87 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t88 = #t87 as{TypeError} core::int*;
+        #t86.{core::List::add}{Invariant}(#t88);
       }
-  } =>#t125;
+  } =>#t86;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t128 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t89 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t129 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t130 = #t129 as{TypeError} core::int*;
-        #t128.{core::Set::add}{Invariant}(#t130);
+      for (final dynamic #t90 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t91 = #t90 as{TypeError} core::int*;
+        #t89.{core::Set::add}{Invariant}(#t91);
       }
-    #t128.{core::Set::add}{Invariant}(null);
-  } =>#t128;
+    #t89.{core::Set::add}{Invariant}(null);
+  } =>#t89;
   core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t131 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t92 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<dynamic, dynamic>* #t132 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-        final core::String* #t133 = #t132.{core::MapEntry::key} as{TypeError} core::String*;
-        final core::int* #t134 = #t132.{core::MapEntry::value} as{TypeError} core::int*;
-        #t131.{core::Map::[]=}{Invariant}(#t133, #t134);
+      for (final core::MapEntry<dynamic, dynamic>* #t93 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+        final core::String* #t94 = #t93.{core::MapEntry::key} as{TypeError} core::String*;
+        final core::int* #t95 = #t93.{core::MapEntry::value} as{TypeError} core::int*;
+        #t92.{core::Map::[]=}{Invariant}(#t94, #t95);
       }
-    #t131.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t131;
+    #t92.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t92;
   core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t135 = <core::int*>[];
+    final core::List<core::int*>* #t96 = <core::int*>[];
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t135.{core::List::add}{Invariant}(42);
-  } =>#t135;
+      #t96.{core::List::add}{Invariant}(42);
+  } =>#t96;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t136 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t97 = col::LinkedHashSet::•<core::int*>();
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t136.{core::Set::add}{Invariant}(42);
-  } =>#t136;
+      #t97.{core::Set::add}{Invariant}(42);
+  } =>#t97;
   core::Map<core::int*, core::int*>* map100 = block {
-    final core::Map<core::int*, core::int*>* #t137 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t98 = <core::int*, core::int*>{};
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t137.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t137;
+      #t98.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t98;
 }
 static method testIfElementErrors(core::Map<core::int*, core::int*>* map) → dynamic {
   block {
-    final core::List<core::int*>* #t138 = <core::int*>[];
+    final core::List<core::int*>* #t99 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t138.{core::List::add}{Invariant}(let final<BottomType> #t139 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t99.{core::List::add}{Invariant}(let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) \"bar\"];
                            ^" in "bar" as{TypeError} core::int*);
-  } =>#t138;
+  } =>#t99;
   block {
-    final core::Set<core::int*>* #t140 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t101 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t140.{core::Set::add}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t101.{core::Set::add}{Invariant}(let final<BottomType> #t102 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
                            ^" in "bar" as{TypeError} core::int*);
-    #t140.{core::Set::add}{Invariant}(null);
-  } =>#t140;
+    #t101.{core::Set::add}{Invariant}(null);
+  } =>#t101;
   block {
-    final core::Map<core::String*, core::int*>* #t142 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t103 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t142.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t103.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
                                           ^" in "bar" as{TypeError} core::int*);
-    #t142.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t142;
+    #t103.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t103;
   block {
-    final core::List<core::int*>* #t144 = <core::int*>[];
+    final core::List<core::int*>* #t105 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t145 in <core::int*>[let final<BottomType> #t146 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t105.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*])
-        #t144.{core::List::add}{Invariant}(#t145);
-  } =>#t144;
+                               ^" in "bar" as{TypeError} core::int*]);
+  } =>#t105;
   block {
-    final core::Set<core::int*>* #t147 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t107 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t148 in <core::int*>[let final<BottomType> #t149 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t107.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*])
-        #t147.{core::Set::add}{Invariant}(#t148);
-    #t147.{core::Set::add}{Invariant}(null);
-  } =>#t147;
+                               ^" in "bar" as{TypeError} core::int*]);
+    #t107.{core::Set::add}{Invariant}(null);
+  } =>#t107;
   block {
-    final core::Map<core::String*, core::int*>* #t150 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t109 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::int*>* #t151 in <core::String*, core::int*>{"bar": let final<BottomType> #t152 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      for (final core::MapEntry<core::String*, core::int*>* #t110 in <core::String*, core::int*>{"bar": let final<BottomType> #t111 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
-        #t150.{core::Map::[]=}{Invariant}(#t151.{core::MapEntry::key}, #t151.{core::MapEntry::value});
-    #t150.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t150;
+        #t109.{core::Map::[]=}{Invariant}(#t110.{core::MapEntry::key}, #t110.{core::MapEntry::value});
+    #t109.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t109;
   block {
-    final core::List<core::int*>* #t153 = <core::int*>[];
+    final core::List<core::int*>* #t112 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t153.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t112.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map];
                               ^");
-  } =>#t153;
+  } =>#t112;
   block {
-    final core::Set<core::int*>* #t154 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t113 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t154.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t113.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map, null};
                               ^");
-    #t154.{core::Set::add}{Invariant}(null);
-  } =>#t154;
+    #t113.{core::Set::add}{Invariant}(null);
+  } =>#t113;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
@@ -1060,61 +1019,61 @@
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::String*>* #t155 = <core::String*>[];
+    final core::List<core::String*>* #t114 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t156 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t115 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t157 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                                       ^" in 3.14 as{TypeError} core::String*);
-  } =>#t155;
+  } =>#t114;
   block {
-    final core::Set<core::String*>* #t158 = col::LinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t117 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t160 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                                       ^" in 3.14 as{TypeError} core::String*);
-    #t158.{core::Set::add}{Invariant}(null);
-  } =>#t158;
+    #t117.{core::Set::add}{Invariant}(null);
+  } =>#t117;
   block {
-    final core::Map<core::String*, core::String*>* #t161 = <core::String*, core::String*>{};
+    final core::Map<core::String*, core::String*>* #t120 = <core::String*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t161.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                              ^" in 42 as{TypeError} core::String*);
     else
-      #t161.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t163 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                                             ^" in 3.14 as{TypeError} core::String*);
-    #t161.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t161;
+    #t120.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t120;
   block {
-    final core::List<core::int*>* #t164 = <core::int*>[];
+    final core::List<core::int*>* #t123 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t164.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t123.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map else 42];
                               ^");
     else
-      #t164.{core::List::add}{Invariant}(42);
-  } =>#t164;
+      #t123.{core::List::add}{Invariant}(42);
+  } =>#t123;
   block {
-    final core::Set<core::int*>* #t165 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t124 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t165.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t124.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t165.{core::Set::add}{Invariant}(42);
-    #t165.{core::Set::add}{Invariant}(null);
-  } =>#t165;
+      #t124.{core::Set::add}{Invariant}(42);
+    #t124.{core::Set::add}{Invariant}(null);
+  } =>#t124;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
@@ -1123,26 +1082,26 @@
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::int*>* #t166 = <core::int*>[];
+    final core::List<core::int*>* #t125 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t166.{core::List::add}{Invariant}(42);
+      #t125.{core::List::add}{Invariant}(42);
     else
-      #t166.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t125.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) 42 else ...map];
                                       ^");
-  } =>#t166;
+  } =>#t125;
   block {
-    final core::Set<core::int*>* #t167 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t126 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t167.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t126.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t167.{core::Set::add}{Invariant}(42);
-    #t167.{core::Set::add}{Invariant}(null);
-  } =>#t167;
+      #t126.{core::Set::add}{Invariant}(42);
+    #t126.{core::Set::add}{Invariant}(null);
+  } =>#t126;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
@@ -1169,749 +1128,709 @@
   var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
                                                    ^": null};
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t168 = <core::int*>[];
-    if(let final<BottomType> #t169 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int*>* #t127 = <core::int*>[];
+    if(let final<BottomType> #t128 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   List<int> list20 = [if (42) 42];
                           ^" in 42 as{TypeError} core::bool*)
-      #t168.{core::List::add}{Invariant}(42);
-  } =>#t168;
+      #t127.{core::List::add}{Invariant}(42);
+  } =>#t127;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t170 = col::LinkedHashSet::•<core::int*>();
-    if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int*>* #t129 = col::LinkedHashSet::•<core::int*>();
+    if(let final<BottomType> #t130 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
-      #t170.{core::Set::add}{Invariant}(42);
-  } =>#t170;
+      #t129.{core::Set::add}{Invariant}(42);
+  } =>#t129;
   core::Map<core::int*, core::int*>* map30 = block {
-    final core::Map<core::int*, core::int*>* #t172 = <core::int*, core::int*>{};
-    if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::int*, core::int*>* #t131 = <core::int*, core::int*>{};
+    if(let final<BottomType> #t132 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Map<int, int> map30 = {if (42) 42: 42};
                              ^" in 42 as{TypeError} core::bool*)
-      #t172.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t172;
+      #t131.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t131;
   core::List<core::String*>* list40 = block {
-    final core::List<core::String*>* #t174 = <core::String*>[];
+    final core::List<core::String*>* #t133 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t134 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                     ^" in true as{TypeError} core::String*);
     else
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t176 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t135 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t174;
+  } =>#t133;
   core::Set<core::String*>* set40 = block {
-    final core::Set<core::String*>* #t177 = col::LinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t136 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t137 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                   ^" in true as{TypeError} core::String*);
     else
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t179 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t138 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                             ^" in 42 as{TypeError} core::String*);
-  } =>#t177;
+  } =>#t136;
   core::Map<core::String*, core::int*>* map40 = block {
-    final core::Map<core::String*, core::int*>* #t180 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t139 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t140 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                             ^" in true as{TypeError} core::String*, 42);
     else
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t182 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                                           ^" in 42 as{TypeError} core::String*, 42);
-  } =>#t180;
+  } =>#t139;
   core::Map<core::int*, core::String*>* map41 = block {
-    final core::Map<core::int*, core::String*>* #t183 = <core::int*, core::String*>{};
+    final core::Map<core::int*, core::String*>* #t142 = <core::int*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                 ^" in true as{TypeError} core::String*);
     else
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t185 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t144 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t183;
+  } =>#t142;
 }
 static method testForElement(dynamic dynVar, core::List<core::int*>* listInt, core::List<core::double*>* listDouble, core::int* index, core::Map<core::String*, core::int*>* mapStringInt, core::Map<core::String*, core::double*>* mapStringDouble) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t186 = <core::int*>[];
+    final core::List<core::int*>* #t145 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t186.{core::List::add}{Invariant}(42);
-  } =>#t186;
+      #t145.{core::List::add}{Invariant}(42);
+  } =>#t145;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t187 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t146 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t187.{core::Set::add}{Invariant}(42);
+      #t146.{core::Set::add}{Invariant}(42);
+    #t146.{core::Set::add}{Invariant}(null);
+  } =>#t146;
+  core::Map<core::String*, core::int*>* map10 = block {
+    final core::Map<core::String*, core::int*>* #t147 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t147.{core::Map::[]=}{Invariant}("bar", 42);
+    #t147.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t147;
+  core::List<dynamic>* list11 = block {
+    final core::List<dynamic>* #t148 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t148.{core::List::add}{Invariant}(dynVar);
+  } =>#t148;
+  core::Set<dynamic>* set11 = block {
+    final core::Set<dynamic>* #t149 = col::LinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t149.{core::Set::add}{Invariant}(dynVar);
+    #t149.{core::Set::add}{Invariant}(null);
+  } =>#t149;
+  core::Map<core::String*, dynamic>* map11 = block {
+    final core::Map<core::String*, dynamic>* #t150 = <core::String*, dynamic>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t150.{core::Map::[]=}{Invariant}("bar", dynVar);
+    #t150.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t150;
+  core::List<core::List<core::int*>*>* list12 = block {
+    final core::List<core::List<core::int*>*>* #t151 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t151.{core::List::add}{Invariant}(<core::int*>[42]);
+  } =>#t151;
+  core::Set<core::List<core::int*>*>* set12 = block {
+    final core::Set<core::List<core::int*>*>* #t152 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t152.{core::Set::add}{Invariant}(<core::int*>[42]);
+    #t152.{core::Set::add}{Invariant}(null);
+  } =>#t152;
+  core::Map<core::String*, core::List<core::int*>*>* map12 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t153 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t153.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
+    #t153.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t153;
+  core::List<core::int*>* list20 = block {
+    final core::List<core::int*>* #t154 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t154.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t154;
+  core::Set<core::int*>* set20 = block {
+    final core::Set<core::int*>* #t155 = col::LinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t155.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t155.{core::Set::add}{Invariant}(null);
+  } =>#t155;
+  core::Map<core::String*, core::int*>* map20 = block {
+    final core::Map<core::String*, core::int*>* #t156 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, core::int*>* #t157 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+        #t156.{core::Map::[]=}{Invariant}(#t157.{core::MapEntry::key}, #t157.{core::MapEntry::value});
+    #t156.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t156;
+  core::List<dynamic>* list21 = block {
+    final core::List<dynamic>* #t158 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t158.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t158;
+  core::Set<dynamic>* set21 = block {
+    final core::Set<dynamic>* #t159 = col::LinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t159.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t159.{core::Set::add}{Invariant}(null);
+  } =>#t159;
+  core::Map<core::String*, dynamic>* map21 = block {
+    final core::Map<core::String*, dynamic>* #t160 = <core::String*, dynamic>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, dynamic>* #t161 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+        #t160.{core::Map::[]=}{Invariant}(#t161.{core::MapEntry::key}, #t161.{core::MapEntry::value});
+    #t160.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t160;
+  core::List<core::List<core::int*>*>* list22 = block {
+    final core::List<core::List<core::int*>*>* #t162 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t162.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t162;
+  core::Set<core::List<core::int*>*>* set22 = block {
+    final core::Set<core::List<core::int*>*>* #t163 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t163.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t163.{core::Set::add}{Invariant}(null);
+  } =>#t163;
+  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t164 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t165 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
+        #t164.{core::Map::[]=}{Invariant}(#t165.{core::MapEntry::key}, #t165.{core::MapEntry::value});
+    #t164.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t164;
+  core::List<core::int*>* list30 = block {
+    final core::List<core::int*>* #t166 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t166.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t166;
+  core::Set<core::int*>* set30 = block {
+    final core::Set<core::int*>* #t167 = col::LinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t167.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t167.{core::Set::add}{Invariant}(null);
+  } =>#t167;
+  core::Map<core::String*, core::int*>* map30 = block {
+    final core::Map<core::String*, core::int*>* #t168 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::int*>* #t169 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+          #t168.{core::Map::[]=}{Invariant}(#t169.{core::MapEntry::key}, #t169.{core::MapEntry::value});
+    #t168.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t168;
+  core::List<dynamic>* list31 = block {
+    final core::List<dynamic>* #t170 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t170.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t170;
+  core::Set<dynamic>* set31 = block {
+    final core::Set<dynamic>* #t171 = col::LinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t171.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t171.{core::Set::add}{Invariant}(null);
+  } =>#t171;
+  core::Map<core::String*, dynamic>* map31 = block {
+    final core::Map<core::String*, dynamic>* #t172 = <core::String*, dynamic>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, dynamic>* #t173 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+          #t172.{core::Map::[]=}{Invariant}(#t173.{core::MapEntry::key}, #t173.{core::MapEntry::value});
+    #t172.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t172;
+  core::List<core::List<core::int*>*>* list33 = block {
+    final core::List<core::List<core::int*>*>* #t174 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t174.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t174;
+  core::Set<core::List<core::int*>*>* set33 = block {
+    final core::Set<core::List<core::int*>*>* #t175 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t175.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t175.{core::Set::add}{Invariant}(null);
+  } =>#t175;
+  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t176 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t177 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
+          #t176.{core::Map::[]=}{Invariant}(#t177.{core::MapEntry::key}, #t177.{core::MapEntry::value});
+    #t176.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t176;
+  core::List<core::List<core::int*>*>* list40 = block {
+    final core::List<core::List<core::int*>*>* #t178 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t178.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t178;
+  core::Set<core::List<core::int*>*>* set40 = block {
+    final core::Set<core::List<core::int*>*>* #t179 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t179.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t179.{core::Set::add}{Invariant}(null);
+  } =>#t179;
+  core::Map<core::String*, core::List<core::int*>*>* map40 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t180 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t181 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+        #t180.{core::Map::[]=}{Invariant}(#t181.{core::MapEntry::key}, #t181.{core::MapEntry::value});
+    #t180.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t180;
+  core::List<core::List<core::int*>*>* list41 = block {
+    final core::List<core::List<core::int*>*>* #t182 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t182.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t183 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t183.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t183);
+  } =>#t182;
+  core::Set<core::List<core::int*>*>* set41 = block {
+    final core::Set<core::List<core::int*>*>* #t184 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t184.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t185 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t185.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t185);
+    #t184.{core::Set::add}{Invariant}(null);
+  } =>#t184;
+  core::List<core::List<core::int*>*>* list42 = block {
+    final core::List<core::List<core::int*>*>* #t186 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t186.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t186;
+  core::Set<core::List<core::int*>*>* set42 = block {
+    final core::Set<core::List<core::int*>*>* #t187 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t187.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
     #t187.{core::Set::add}{Invariant}(null);
   } =>#t187;
-  core::Map<core::String*, core::int*>* map10 = block {
-    final core::Map<core::String*, core::int*>* #t188 = <core::String*, core::int*>{};
+  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t188 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t188.{core::Map::[]=}{Invariant}("bar", 42);
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t189 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t188.{core::Map::[]=}{Invariant}(#t189.{core::MapEntry::key}, #t189.{core::MapEntry::value});
     #t188.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t188;
-  core::List<dynamic>* list11 = block {
-    final core::List<dynamic>* #t189 = <dynamic>[];
+  core::List<core::int*>* list50 = block {
+    final core::List<core::int*>* #t190 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t189.{core::List::add}{Invariant}(dynVar);
-  } =>#t189;
-  core::Set<dynamic>* set11 = block {
-    final core::Set<dynamic>* #t190 = col::LinkedHashSet::•<dynamic>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t190.{core::Set::add}{Invariant}(dynVar);
-    #t190.{core::Set::add}{Invariant}(null);
+      #t190.{core::List::addAll}{Invariant}(<core::int*>[]);
   } =>#t190;
-  core::Map<core::String*, dynamic>* map11 = block {
-    final core::Map<core::String*, dynamic>* #t191 = <core::String*, dynamic>{};
+  core::Set<core::int*>* set50 = block {
+    final core::Set<core::int*>* #t191 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t191.{core::Map::[]=}{Invariant}("bar", dynVar);
-    #t191.{core::Map::[]=}{Invariant}("baz", null);
+      #t191.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t191.{core::Set::add}{Invariant}(null);
   } =>#t191;
-  core::List<core::List<core::int*>*>* list12 = block {
-    final core::List<core::List<core::int*>*>* #t192 = <core::List<core::int*>*>[];
+  core::Map<core::String*, core::int*>* map50 = block {
+    final core::Map<core::String*, core::int*>* #t192 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t192.{core::List::add}{Invariant}(<core::int*>[42]);
+      for (final core::MapEntry<core::String*, core::int*>* #t193 in <core::String*, core::int*>{}.{core::Map::entries})
+        #t192.{core::Map::[]=}{Invariant}(#t193.{core::MapEntry::key}, #t193.{core::MapEntry::value});
+    #t192.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t192;
-  core::Set<core::List<core::int*>*>* set12 = block {
-    final core::Set<core::List<core::int*>*>* #t193 = col::LinkedHashSet::•<core::List<core::int*>*>();
+  core::List<core::int*>* list51 = block {
+    final core::List<core::int*>* #t194 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t193.{core::Set::add}{Invariant}(<core::int*>[42]);
-    #t193.{core::Set::add}{Invariant}(null);
-  } =>#t193;
-  core::Map<core::String*, core::List<core::int*>*>* map12 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t194 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t194.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
-    #t194.{core::Map::[]=}{Invariant}("baz", null);
+      #t194.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t195 = col::LinkedHashSet::•<core::int*>();
+      } =>#t195);
   } =>#t194;
-  core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t195 = <core::int*>[];
+  core::Set<core::int*>* set51 = block {
+    final core::Set<core::int*>* #t196 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t196 in <core::int*>[42])
-        #t195.{core::List::add}{Invariant}(#t196);
-  } =>#t195;
-  core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t197 = col::LinkedHashSet::•<core::int*>();
+      #t196.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t197 = col::LinkedHashSet::•<core::int*>();
+      } =>#t197);
+    #t196.{core::Set::add}{Invariant}(null);
+  } =>#t196;
+  core::List<core::int*>* list52 = block {
+    final core::List<core::int*>* #t198 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t198 in <core::int*>[42])
-        #t197.{core::Set::add}{Invariant}(#t198);
-    #t197.{core::Set::add}{Invariant}(null);
-  } =>#t197;
-  core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t199 = <core::String*, core::int*>{};
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t198.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t198;
+  core::Set<core::int*>* set52 = block {
+    final core::Set<core::int*>* #t199 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::int*>* #t200 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
-        #t199.{core::Map::[]=}{Invariant}(#t200.{core::MapEntry::key}, #t200.{core::MapEntry::value});
-    #t199.{core::Map::[]=}{Invariant}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t199.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t199.{core::Set::add}{Invariant}(null);
   } =>#t199;
-  core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t201 = <dynamic>[];
+  core::List<core::List<core::int*>*>* list60 = block {
+    final core::List<core::List<core::int*>*>* #t200 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t202 in <dynamic>[dynVar])
-        #t201.{core::List::add}{Invariant}(#t202);
+      #t200.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t200;
+  core::Set<core::List<core::int*>*>* set60 = block {
+    final core::Set<core::List<core::int*>*>* #t201 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t201.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t201.{core::Set::add}{Invariant}(null);
   } =>#t201;
-  core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t203 = col::LinkedHashSet::•<dynamic>();
+  core::Map<core::String*, core::List<core::int*>*>* map60 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t202 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t204 in <dynamic>[dynVar])
-        #t203.{core::Set::add}{Invariant}(#t204);
-    #t203.{core::Set::add}{Invariant}(null);
-  } =>#t203;
-  core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t205 = <core::String*, dynamic>{};
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t203 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+        #t202.{core::Map::[]=}{Invariant}(#t203.{core::MapEntry::key}, #t203.{core::MapEntry::value});
+    #t202.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t202;
+  core::List<core::List<core::int*>*>* list61 = block {
+    final core::List<core::List<core::int*>*>* #t204 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, dynamic>* #t206 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
-        #t205.{core::Map::[]=}{Invariant}(#t206.{core::MapEntry::key}, #t206.{core::MapEntry::value});
-    #t205.{core::Map::[]=}{Invariant}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t204.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t204;
+  core::Set<core::List<core::int*>*>* set61 = block {
+    final core::Set<core::List<core::int*>*>* #t205 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t205.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t205.{core::Set::add}{Invariant}(null);
   } =>#t205;
-  core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t207 = <core::List<core::int*>*>[];
+  core::Map<core::String*, core::List<core::int*>*>* map61 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t206 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t208 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t207.{core::List::add}{Invariant}(#t208);
-  } =>#t207;
-  core::Set<core::List<core::int*>*>* set22 = block {
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t207 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t206.{core::Map::[]=}{Invariant}(#t207.{core::MapEntry::key}, #t207.{core::MapEntry::value});
+    #t206.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t206;
+  core::List<core::List<core::int*>*>* list70 = block {
+    final core::List<core::List<core::int*>*>* #t208 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t208.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t208;
+  core::Set<core::List<core::int*>*>* set70 = block {
     final core::Set<core::List<core::int*>*>* #t209 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t210 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t209.{core::Set::add}{Invariant}(#t210);
+      #t209.{core::Set::add}{Invariant}(<core::int*>[]);
     #t209.{core::Set::add}{Invariant}(null);
   } =>#t209;
-  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t211 = <core::String*, core::List<core::int*>*>{};
+  core::Map<core::String*, core::List<core::int*>*>* map70 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t210 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t212 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
-        #t211.{core::Map::[]=}{Invariant}(#t212.{core::MapEntry::key}, #t212.{core::MapEntry::value});
-    #t211.{core::Map::[]=}{Invariant}("baz", null);
+      #t210.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t210.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t210;
+  core::List<core::List<core::int*>*>* list71 = block {
+    final core::List<core::List<core::int*>*>* #t211 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t211.{core::List::add}{Invariant}(<core::int*>[]);
   } =>#t211;
-  core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t213 = <core::int*>[];
+  core::Set<core::List<core::int*>*>* set71 = block {
+    final core::Set<core::List<core::int*>*>* #t212 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t214 in <core::int*>[42])
-          #t213.{core::List::add}{Invariant}(#t214);
+        #t212.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t212.{core::Set::add}{Invariant}(null);
+  } =>#t212;
+  core::Map<core::String*, core::List<core::int*>*>* map71 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t213.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t213.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t213;
-  core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t215 = col::LinkedHashSet::•<core::int*>();
+  core::List<core::num*>* list80 = block {
+    final core::List<core::num*>* #t214 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t216 in <core::int*>[42])
-          #t215.{core::Set::add}{Invariant}(#t216);
+        #t214.{core::List::add}{Invariant}(42);
+      else
+        #t214.{core::List::add}{Invariant}(3.14);
+  } =>#t214;
+  core::Set<core::num*>* set80 = block {
+    final core::Set<core::num*>* #t215 = col::LinkedHashSet::•<core::num*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t215.{core::Set::add}{Invariant}(42);
+      else
+        #t215.{core::Set::add}{Invariant}(3.14);
     #t215.{core::Set::add}{Invariant}(null);
   } =>#t215;
-  core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t217 = <core::String*, core::int*>{};
+  core::Map<core::String*, core::num*>* map80 = block {
+    final core::Map<core::String*, core::num*>* #t216 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::int*>* #t218 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
-          #t217.{core::Map::[]=}{Invariant}(#t218.{core::MapEntry::key}, #t218.{core::MapEntry::value});
-    #t217.{core::Map::[]=}{Invariant}("baz", null);
+        #t216.{core::Map::[]=}{Invariant}("bar", 42);
+      else
+        #t216.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t216.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t216;
+  core::List<core::num*>* list81 = block {
+    final core::List<core::num*>* #t217 = <core::num*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t217.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t217.{core::List::addAll}{Invariant}(listDouble);
   } =>#t217;
-  core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t219 = <dynamic>[];
+  core::Set<core::num*>* set81 = block {
+    final core::Set<core::num*>* #t218 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t220 in <dynamic>[dynVar])
-          #t219.{core::List::add}{Invariant}(#t220);
+        #t218.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t218.{core::Set::addAll}{Invariant}(listDouble);
+    #t218.{core::Set::add}{Invariant}(null);
+  } =>#t218;
+  core::Map<core::String*, core::num*>* map81 = block {
+    final core::Map<core::String*, core::num*>* #t219 = <core::String*, core::num*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::num*>* #t220 in mapStringInt.{core::Map::entries})
+          #t219.{core::Map::[]=}{Invariant}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<core::String*, core::num*>* #t221 in mapStringDouble.{core::Map::entries})
+          #t219.{core::Map::[]=}{Invariant}(#t221.{core::MapEntry::key}, #t221.{core::MapEntry::value});
+    #t219.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t219;
-  core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t221 = col::LinkedHashSet::•<dynamic>();
+  core::List<dynamic>* list82 = block {
+    final core::List<dynamic>* #t222 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t222 in <dynamic>[dynVar])
-          #t221.{core::Set::add}{Invariant}(#t222);
-    #t221.{core::Set::add}{Invariant}(null);
-  } =>#t221;
-  core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t223 = <core::String*, dynamic>{};
+        #t222.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t222.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t222;
+  core::Set<dynamic>* set82 = block {
+    final core::Set<dynamic>* #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, dynamic>* #t224 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
-          #t223.{core::Map::[]=}{Invariant}(#t224.{core::MapEntry::key}, #t224.{core::MapEntry::value});
-    #t223.{core::Map::[]=}{Invariant}("baz", null);
+        #t223.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t223.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t223.{core::Set::add}{Invariant}(null);
   } =>#t223;
-  core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t225 = <core::List<core::int*>*>[];
+  core::Map<dynamic, dynamic>* map82 = block {
+    final core::Map<dynamic, dynamic>* #t224 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t226 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t225.{core::List::add}{Invariant}(#t226);
-  } =>#t225;
-  core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t227 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        for (final core::MapEntry<dynamic, dynamic>* #t225 in mapStringInt.{core::Map::entries})
+          #t224.{core::Map::[]=}{Invariant}(#t225.{core::MapEntry::key}, #t225.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<dynamic, dynamic>* #t226 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
+          #t224.{core::Map::[]=}{Invariant}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
+    #t224.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t224;
+  core::List<core::num*>* list83 = block {
+    final core::List<core::num*>* #t227 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t228 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t227.{core::Set::add}{Invariant}(#t228);
-    #t227.{core::Set::add}{Invariant}(null);
+        #t227.{core::List::add}{Invariant}(42);
+      else
+        #t227.{core::List::addAll}{Invariant}(listDouble);
   } =>#t227;
-  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t229 = <core::String*, core::List<core::int*>*>{};
+  core::Set<core::num*>* set83 = block {
+    final core::Set<core::num*>* #t228 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t230 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
+        #t228.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t228.{core::Set::add}{Invariant}(3.14);
+    #t228.{core::Set::add}{Invariant}(null);
+  } =>#t228;
+  core::Map<core::String*, core::num*>* map83 = block {
+    final core::Map<core::String*, core::num*>* #t229 = <core::String*, core::num*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::num*>* #t230 in mapStringInt.{core::Map::entries})
           #t229.{core::Map::[]=}{Invariant}(#t230.{core::MapEntry::key}, #t230.{core::MapEntry::value});
+      else
+        #t229.{core::Map::[]=}{Invariant}("bar", 3.14);
     #t229.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t229;
-  core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t231 = <core::List<core::int*>*>[];
+  core::List<core::int*>* list90 = block {
+    final core::List<core::int*>* #t231 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t232 in <core::List<core::int*>*>[<core::int*>[]])
-        #t231.{core::List::add}{Invariant}(#t232);
+      #t231.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
   } =>#t231;
-  core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t233 = col::LinkedHashSet::•<core::List<core::int*>*>();
+  core::Set<core::int*>* set90 = block {
+    final core::Set<core::int*>* #t232 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t234 in <core::List<core::int*>*>[<core::int*>[]])
-        #t233.{core::Set::add}{Invariant}(#t234);
-    #t233.{core::Set::add}{Invariant}(null);
+      #t232.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t232.{core::Set::add}{Invariant}(null);
+  } =>#t232;
+  core::Map<core::String*, core::int*>* map90 = block {
+    final core::Map<core::String*, core::int*>* #t233 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t233.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t233.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t233;
-  core::Map<core::String*, core::List<core::int*>*>* map40 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t235 = <core::String*, core::List<core::int*>*>{};
+  core::List<core::int*>* list91 = block {
+    final core::List<core::int*>* #t234 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t236 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-        #t235.{core::Map::[]=}{Invariant}(#t236.{core::MapEntry::key}, #t236.{core::MapEntry::value});
-    #t235.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t235;
-  core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t237 = <core::List<core::int*>*>[];
+      for (final dynamic #t235 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t236 = #t235 as{TypeError} core::int*;
+        #t234.{core::List::add}{Invariant}(#t236);
+      }
+  } =>#t234;
+  core::Set<core::int*>* set91 = block {
+    final core::Set<core::int*>* #t237 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t238 in block {
-        final core::Set<core::List<core::int*>*>* #t239 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t239.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t239)
-        #t237.{core::List::add}{Invariant}(#t238);
+      for (final dynamic #t238 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t239 = #t238 as{TypeError} core::int*;
+        #t237.{core::Set::add}{Invariant}(#t239);
+      }
+    #t237.{core::Set::add}{Invariant}(null);
   } =>#t237;
-  core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>();
+  core::Map<core::String*, core::int*>* map91 = block {
+    final core::Map<core::String*, core::int*>* #t240 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t241 in block {
-        final core::Set<core::List<core::int*>*>* #t242 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t242.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t242)
-        #t240.{core::Set::add}{Invariant}(#t241);
-    #t240.{core::Set::add}{Invariant}(null);
+      for (final core::MapEntry<dynamic, dynamic>* #t241 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+        final core::String* #t242 = #t241.{core::MapEntry::key} as{TypeError} core::String*;
+        final core::int* #t243 = #t241.{core::MapEntry::value} as{TypeError} core::int*;
+        #t240.{core::Map::[]=}{Invariant}(#t242, #t243);
+      }
+    #t240.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t240;
-  core::List<core::List<core::int*>*>* list42 = block {
-    final core::List<core::List<core::int*>*>* #t243 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t244 in <core::List<core::int*>*>[<core::int*>[]])
-          #t243.{core::List::add}{Invariant}(#t244);
-  } =>#t243;
-  core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t245 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t246 in <core::List<core::int*>*>[<core::int*>[]])
-          #t245.{core::Set::add}{Invariant}(#t246);
-    #t245.{core::Set::add}{Invariant}(null);
-  } =>#t245;
-  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t247 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t248 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t247.{core::Map::[]=}{Invariant}(#t248.{core::MapEntry::key}, #t248.{core::MapEntry::value});
-    #t247.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t247;
-  core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t249 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t250 in <core::int*>[])
-        #t249.{core::List::add}{Invariant}(#t250);
-  } =>#t249;
-  core::Set<core::int*>* set50 = block {
+  core::List<core::int*>* list100 = block {
+    final core::List<core::int*>* #t244 = <core::int*>[];
+    for (final core::int* #t245 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t244.{core::List::add}{Invariant}(42);
+  } =>#t244;
+  core::Set<core::int*>* set100 = block {
+    final core::Set<core::int*>* #t246 = col::LinkedHashSet::•<core::int*>();
+    for (final core::int* #t247 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t246.{core::Set::add}{Invariant}(42);
+  } =>#t246;
+  core::Map<core::String*, core::int*>* map100 = block {
+    final core::Map<core::String*, core::int*>* #t248 = <core::String*, core::int*>{};
+    for (final core::int* #t249 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t248.{core::Map::[]=}{Invariant}("bar", 42);
+  } =>#t248;
+  core::List<core::int*>* list110 = block {
+    final core::List<core::int*>* #t250 = <core::int*>[];
+    for (core::int* i in <core::int*>[1, 2, 3])
+      #t250.{core::List::add}{Invariant}(i);
+  } =>#t250;
+  core::Set<core::int*>* set110 = block {
     final core::Set<core::int*>* #t251 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t252 in <core::int*>[])
-        #t251.{core::Set::add}{Invariant}(#t252);
+    for (core::int* i in <core::int*>[1, 2, 3])
+      #t251.{core::Set::add}{Invariant}(i);
     #t251.{core::Set::add}{Invariant}(null);
   } =>#t251;
-  core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t253 = <core::String*, core::int*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::int*>* #t254 in <core::String*, core::int*>{}.{core::Map::entries})
-        #t253.{core::Map::[]=}{Invariant}(#t254.{core::MapEntry::key}, #t254.{core::MapEntry::value});
-    #t253.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t253;
-  core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t255 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t256 in block {
-        final core::Set<core::int*>* #t257 = col::LinkedHashSet::•<core::int*>();
-      } =>#t257)
-        #t255.{core::List::add}{Invariant}(#t256);
-  } =>#t255;
-  core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t258 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t259 in block {
-        final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>();
-      } =>#t260)
-        #t258.{core::Set::add}{Invariant}(#t259);
-    #t258.{core::Set::add}{Invariant}(null);
-  } =>#t258;
-  core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t261 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t262 in <core::int*>[])
-          #t261.{core::List::add}{Invariant}(#t262);
-  } =>#t261;
-  core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t264 in <core::int*>[])
-          #t263.{core::Set::add}{Invariant}(#t264);
-    #t263.{core::Set::add}{Invariant}(null);
-  } =>#t263;
-  core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t265 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t266 in <core::List<core::int*>*>[<core::int*>[]])
-        #t265.{core::List::add}{Invariant}(#t266);
-  } =>#t265;
-  core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t267 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t268 in <core::List<core::int*>*>[<core::int*>[]])
-        #t267.{core::Set::add}{Invariant}(#t268);
-    #t267.{core::Set::add}{Invariant}(null);
-  } =>#t267;
-  core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t269 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t270 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-        #t269.{core::Map::[]=}{Invariant}(#t270.{core::MapEntry::key}, #t270.{core::MapEntry::value});
-    #t269.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t269;
-  core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t271 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t272 in <core::List<core::int*>*>[<core::int*>[]])
-          #t271.{core::List::add}{Invariant}(#t272);
-  } =>#t271;
-  core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t273 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t274 in <core::List<core::int*>*>[<core::int*>[]])
-          #t273.{core::Set::add}{Invariant}(#t274);
-    #t273.{core::Set::add}{Invariant}(null);
-  } =>#t273;
-  core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t275 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t276 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t275.{core::Map::[]=}{Invariant}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value});
-    #t275.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t275;
-  core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t277 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t277.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t277;
-  core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t278 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t278.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t278.{core::Set::add}{Invariant}(null);
-  } =>#t278;
-  core::Map<core::String*, core::List<core::int*>*>* map70 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t279.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t279.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t279;
-  core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t280 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t280.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t280;
-  core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t281 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t281.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t281.{core::Set::add}{Invariant}(null);
-  } =>#t281;
-  core::Map<core::String*, core::List<core::int*>*>* map71 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t282 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t282.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t282.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t282;
-  core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t283 = <core::num*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t283.{core::List::add}{Invariant}(42);
-      else
-        #t283.{core::List::add}{Invariant}(3.14);
-  } =>#t283;
-  core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t284 = col::LinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t284.{core::Set::add}{Invariant}(42);
-      else
-        #t284.{core::Set::add}{Invariant}(3.14);
-    #t284.{core::Set::add}{Invariant}(null);
-  } =>#t284;
-  core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t285 = <core::String*, core::num*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t285.{core::Map::[]=}{Invariant}("bar", 42);
-      else
-        #t285.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t285.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t285;
-  core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t286 = <core::num*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::num* #t287 in listInt)
-          #t286.{core::List::add}{Invariant}(#t287);
-      else
-        for (final core::num* #t288 in listDouble)
-          #t286.{core::List::add}{Invariant}(#t288);
-  } =>#t286;
-  core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t289 = col::LinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::num* #t290 in listInt)
-          #t289.{core::Set::add}{Invariant}(#t290);
-      else
-        for (final core::num* #t291 in listDouble)
-          #t289.{core::Set::add}{Invariant}(#t291);
-    #t289.{core::Set::add}{Invariant}(null);
-  } =>#t289;
-  core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t292 = <core::String*, core::num*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::num*>* #t293 in mapStringInt.{core::Map::entries})
-          #t292.{core::Map::[]=}{Invariant}(#t293.{core::MapEntry::key}, #t293.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<core::String*, core::num*>* #t294 in mapStringDouble.{core::Map::entries})
-          #t292.{core::Map::[]=}{Invariant}(#t294.{core::MapEntry::key}, #t294.{core::MapEntry::value});
-    #t292.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t292;
-  core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t295 = <dynamic>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t296 in listInt)
-          #t295.{core::List::add}{Invariant}(#t296);
-      else
-        for (final dynamic #t297 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-          #t295.{core::List::add}{Invariant}(#t297);
-  } =>#t295;
-  core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t298 = col::LinkedHashSet::•<dynamic>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t299 in listInt)
-          #t298.{core::Set::add}{Invariant}(#t299);
-      else
-        for (final dynamic #t300 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-          #t298.{core::Set::add}{Invariant}(#t300);
-    #t298.{core::Set::add}{Invariant}(null);
-  } =>#t298;
-  core::Map<dynamic, dynamic>* map82 = block {
-    final core::Map<dynamic, dynamic>* #t301 = <dynamic, dynamic>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<dynamic, dynamic>* #t302 in mapStringInt.{core::Map::entries})
-          #t301.{core::Map::[]=}{Invariant}(#t302.{core::MapEntry::key}, #t302.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<dynamic, dynamic>* #t303 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
-          #t301.{core::Map::[]=}{Invariant}(#t303.{core::MapEntry::key}, #t303.{core::MapEntry::value});
-    #t301.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t301;
-  core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t304 = <core::num*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t304.{core::List::add}{Invariant}(42);
-      else
-        for (final core::num* #t305 in listDouble)
-          #t304.{core::List::add}{Invariant}(#t305);
-  } =>#t304;
-  core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t306 = col::LinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::num* #t307 in listInt)
-          #t306.{core::Set::add}{Invariant}(#t307);
-      else
-        #t306.{core::Set::add}{Invariant}(3.14);
-    #t306.{core::Set::add}{Invariant}(null);
-  } =>#t306;
-  core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t308 = <core::String*, core::num*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::num*>* #t309 in mapStringInt.{core::Map::entries})
-          #t308.{core::Map::[]=}{Invariant}(#t309.{core::MapEntry::key}, #t309.{core::MapEntry::value});
-      else
-        #t308.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t308.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t308;
-  core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t310 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t310.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t310;
-  core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t311 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t311.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t311.{core::Set::add}{Invariant}(null);
-  } =>#t311;
-  core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t312 = <core::String*, core::int*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t312.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t312.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t312;
-  core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t313 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t314 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t315 = #t314 as{TypeError} core::int*;
-        #t313.{core::List::add}{Invariant}(#t315);
-      }
-  } =>#t313;
-  core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t316 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t317 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t318 = #t317 as{TypeError} core::int*;
-        #t316.{core::Set::add}{Invariant}(#t318);
-      }
-    #t316.{core::Set::add}{Invariant}(null);
-  } =>#t316;
-  core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t319 = <core::String*, core::int*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<dynamic, dynamic>* #t320 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-        final core::String* #t321 = #t320.{core::MapEntry::key} as{TypeError} core::String*;
-        final core::int* #t322 = #t320.{core::MapEntry::value} as{TypeError} core::int*;
-        #t319.{core::Map::[]=}{Invariant}(#t321, #t322);
-      }
-    #t319.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t319;
-  core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t323 = <core::int*>[];
-    for (final core::int* #t324 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t323.{core::List::add}{Invariant}(42);
-  } =>#t323;
-  core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t325 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t326 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t325.{core::Set::add}{Invariant}(42);
-  } =>#t325;
-  core::Map<core::String*, core::int*>* map100 = block {
-    final core::Map<core::String*, core::int*>* #t327 = <core::String*, core::int*>{};
-    for (final core::int* #t328 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t327.{core::Map::[]=}{Invariant}("bar", 42);
-  } =>#t327;
-  core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t329 = <core::int*>[];
-    for (core::int* i in <core::int*>[1, 2, 3])
-      #t329.{core::List::add}{Invariant}(i);
-  } =>#t329;
-  core::Set<core::int*>* set110 = block {
-    final core::Set<core::int*>* #t330 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i in <core::int*>[1, 2, 3])
-      #t330.{core::Set::add}{Invariant}(i);
-    #t330.{core::Set::add}{Invariant}(null);
-  } =>#t330;
   core::Map<core::String*, core::int*>* map110 = block {
-    final core::Map<core::String*, core::int*>* #t331 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t252 = <core::String*, core::int*>{};
     for (core::int* i in <core::int*>[1, 2, 3])
-      #t331.{core::Map::[]=}{Invariant}("bar", i);
-    #t331.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t331;
+      #t252.{core::Map::[]=}{Invariant}("bar", i);
+    #t252.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t252;
   core::List<core::int*>* list120 = block {
-    final core::List<core::int*>* #t332 = <core::int*>[];
+    final core::List<core::int*>* #t253 = <core::int*>[];
     for (dynamic i in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t332.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
-  } =>#t332;
+      #t253.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+  } =>#t253;
   core::Set<core::int*>* set120 = block {
-    final core::Set<core::int*>* #t333 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t254 = col::LinkedHashSet::•<core::int*>();
     for (dynamic i in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t333.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
-    #t333.{core::Set::add}{Invariant}(null);
-  } =>#t333;
+      #t254.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+    #t254.{core::Set::add}{Invariant}(null);
+  } =>#t254;
   core::Map<core::String*, core::int*>* map120 = block {
-    final core::Map<core::String*, core::int*>* #t334 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t255 = <core::String*, core::int*>{};
     for (dynamic i in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t334.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
-    #t334.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t334;
+      #t255.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
+    #t255.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t255;
   core::List<core::int*>* list130 = block {
-    final core::List<core::int*>* #t335 = <core::int*>[];
+    final core::List<core::int*>* #t256 = <core::int*>[];
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t335.{core::List::add}{Invariant}(i);
-  } =>#t335;
+      #t256.{core::List::add}{Invariant}(i);
+  } =>#t256;
   core::Set<core::int*>* set130 = block {
-    final core::Set<core::int*>* #t336 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t257 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t336.{core::Set::add}{Invariant}(i);
-  } =>#t336;
+      #t257.{core::Set::add}{Invariant}(i);
+  } =>#t257;
   core::Map<core::int*, core::int*>* map130 = block {
-    final core::Map<core::int*, core::int*>* #t337 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t258 = <core::int*, core::int*>{};
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t337.{core::Map::[]=}{Invariant}(i, i);
-  } =>#t337;
+      #t258.{core::Map::[]=}{Invariant}(i, i);
+  } =>#t258;
 }
 static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic async {
   block {
-    final core::List<core::int*>* #t338 = <core::int*>[];
+    final core::List<core::int*>* #t259 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t338.{core::List::add}{Invariant}(let final<BottomType> #t339 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t259.{core::List::add}{Invariant}(let final<BottomType> #t260 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
                                             ^" in "bar" as{TypeError} core::int*);
-  } =>#t338;
+  } =>#t259;
   block {
-    final core::Set<core::int*>* #t340 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t261 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t340.{core::Set::add}{Invariant}(let final<BottomType> #t341 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t261.{core::Set::add}{Invariant}(let final<BottomType> #t262 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
                                             ^" in "bar" as{TypeError} core::int*);
-    #t340.{core::Set::add}{Invariant}(null);
-  } =>#t340;
+    #t261.{core::Set::add}{Invariant}(null);
+  } =>#t261;
   block {
-    final core::Map<core::int*, core::int*>* #t342 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t263 = <core::int*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t264 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t265 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                         ^" in "bar" as{TypeError} core::int*);
-    #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t266 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                                ^" in "baz" as{TypeError} core::int*, null);
-  } =>#t342;
+  } =>#t263;
   block {
-    final core::List<core::int*>* #t346 = <core::int*>[];
+    final core::List<core::int*>* #t267 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t347 in <core::int*>[let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t267.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*])
-        #t346.{core::List::add}{Invariant}(#t347);
-  } =>#t346;
+                                                ^" in "bar" as{TypeError} core::int*]);
+  } =>#t267;
   block {
-    final core::Set<core::int*>* #t349 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t269 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t350 in <core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t269.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t270 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*])
-        #t349.{core::Set::add}{Invariant}(#t350);
-    #t349.{core::Set::add}{Invariant}(null);
-  } =>#t349;
+                                                ^" in "bar" as{TypeError} core::int*]);
+    #t269.{core::Set::add}{Invariant}(null);
+  } =>#t269;
   block {
-    final core::Map<core::int*, core::int*>* #t352 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t271 = <core::int*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::int*, core::int*>* #t353 in <core::int*, core::int*>{let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      for (final core::MapEntry<core::int*, core::int*>* #t272 in <core::int*, core::int*>{let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t274 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
-        #t352.{core::Map::[]=}{Invariant}(#t353.{core::MapEntry::key}, #t353.{core::MapEntry::value});
-    #t352.{core::Map::[]=}{Invariant}(let final<BottomType> #t356 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+        #t271.{core::Map::[]=}{Invariant}(#t272.{core::MapEntry::key}, #t272.{core::MapEntry::value});
+    #t271.{core::Map::[]=}{Invariant}(let final<BottomType> #t275 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int*, null);
-  } =>#t352;
+  } =>#t271;
   block {
-    final core::List<core::int*>* #t357 = <core::int*>[];
+    final core::List<core::int*>* #t276 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t357.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t276.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...map];
                                                ^");
-  } =>#t357;
+  } =>#t276;
   block {
-    final core::Set<core::int*>* #t358 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t277 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t358.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t277.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null};
                                                ^");
-    #t358.{core::Set::add}{Invariant}(null);
-  } =>#t358;
+    #t277.{core::Set::add}{Invariant}(null);
+  } =>#t277;
   <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
@@ -1920,66 +1839,66 @@
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
                                                     ^": null};
   block {
-    final core::List<core::String*>* #t359 = <core::String*>[];
+    final core::List<core::String*>* #t278 = <core::String*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t359.{core::List::add}{Invariant}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+        #t278.{core::List::add}{Invariant}(let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                              ^" in 42 as{TypeError} core::String*);
       else
-        #t359.{core::List::add}{Invariant}(let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+        #t278.{core::List::add}{Invariant}(let final<BottomType> #t280 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                                      ^" in 3.14 as{TypeError} core::String*);
-  } =>#t359;
+  } =>#t278;
   block {
-    final core::Set<core::String*>* #t362 = col::LinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t281 = col::LinkedHashSet::•<core::String*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t362.{core::Set::add}{Invariant}(let final<BottomType> #t363 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+        #t281.{core::Set::add}{Invariant}(let final<BottomType> #t282 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                              ^" in 42 as{TypeError} core::String*);
       else
-        #t362.{core::Set::add}{Invariant}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+        #t281.{core::Set::add}{Invariant}(let final<BottomType> #t283 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                                      ^" in 3.14 as{TypeError} core::String*);
-    #t362.{core::Set::add}{Invariant}(null);
-  } =>#t362;
+    #t281.{core::Set::add}{Invariant}(null);
+  } =>#t281;
   block {
-    final core::Map<core::String*, core::String*>* #t365 = <core::String*, core::String*>{};
+    final core::Map<core::String*, core::String*>* #t284 = <core::String*, core::String*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t366 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+        #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t285 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                             ^" in 42 as{TypeError} core::String*);
       else
-        #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+        #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t286 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                                            ^" in 3.14 as{TypeError} core::String*);
-    #t365.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t365;
+    #t284.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t284;
   block {
-    final core::List<core::int*>* #t368 = <core::int*>[];
+    final core::List<core::int*>* #t287 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t368.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t287.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42];
                                                              ^");
       else
-        #t368.{core::List::add}{Invariant}(42);
-  } =>#t368;
+        #t287.{core::List::add}{Invariant}(42);
+  } =>#t287;
   block {
-    final core::Set<core::int*>* #t369 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t288 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t369.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t288.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null};
                                                              ^");
       else
-        #t369.{core::Set::add}{Invariant}(42);
-    #t369.{core::Set::add}{Invariant}(null);
-  } =>#t369;
+        #t288.{core::Set::add}{Invariant}(42);
+    #t288.{core::Set::add}{Invariant}(null);
+  } =>#t288;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
@@ -1988,28 +1907,28 @@
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
                                                                      ^": null};
   block {
-    final core::List<core::int*>* #t370 = <core::int*>[];
+    final core::List<core::int*>* #t289 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t370.{core::List::add}{Invariant}(42);
+        #t289.{core::List::add}{Invariant}(42);
       else
-        #t370.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t289.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map];
                                                                      ^");
-  } =>#t370;
+  } =>#t289;
   block {
-    final core::Set<core::int*>* #t371 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t290 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t371.{core::Set::add}{Invariant}(42);
+        #t290.{core::Set::add}{Invariant}(42);
       else
-        #t371.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t290.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null};
                                                                      ^");
-    #t371.{core::Set::add}{Invariant}(null);
-  } =>#t371;
+    #t290.{core::Set::add}{Invariant}(null);
+  } =>#t290;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
@@ -2019,218 +1938,218 @@
                                                                                     ^": null};
   final core::int* i = 0;
   block {
-    final core::List<core::int*>* #t372 = <core::int*>[];
-    for (final core::int* #t373 in <core::int*>[1]) {
+    final core::List<core::int*>* #t291 = <core::int*>[];
+    for (final core::int* #t292 in <core::int*>[1]) {
       invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
-      #t372.{core::List::add}{Invariant}(i);
+      #t291.{core::List::add}{Invariant}(i);
     }
-  } =>#t372;
+  } =>#t291;
   block {
-    final core::Set<core::int*>* #t374 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t375 in <core::int*>[1]) {
+    final core::Set<core::int*>* #t293 = col::LinkedHashSet::•<core::int*>();
+    for (final core::int* #t294 in <core::int*>[1]) {
       invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
-      #t374.{core::Set::add}{Invariant}(i);
+      #t293.{core::Set::add}{Invariant}(i);
     }
-    #t374.{core::Set::add}{Invariant}(null);
-  } =>#t374;
+    #t293.{core::Set::add}{Invariant}(null);
+  } =>#t293;
   block {
-    final core::Map<core::String*, core::int*>* #t376 = <core::String*, core::int*>{};
-    for (final core::int* #t377 in <core::int*>[1]) {
+    final core::Map<core::String*, core::int*>* #t295 = <core::String*, core::int*>{};
+    for (final core::int* #t296 in <core::int*>[1]) {
       invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
-      #t376.{core::Map::[]=}{Invariant}("bar", i);
+      #t295.{core::Map::[]=}{Invariant}("bar", i);
     }
-    #t376.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t376;
+    #t295.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t295;
   core::List<dynamic>* list10 = block {
-    final core::List<dynamic>* #t378 = <dynamic>[];
-    for (dynamic i in let final<BottomType> #t379 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::List<dynamic>* #t297 = <dynamic>[];
+    for (dynamic i in let final<BottomType> #t298 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*)
-      #t378.{core::List::add}{Invariant}(i);
-  } =>#t378;
+      #t297.{core::List::add}{Invariant}(i);
+  } =>#t297;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t380 = col::LinkedHashSet::•<dynamic>();
-    for (dynamic i in let final<BottomType> #t381 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::Set<dynamic>* #t299 = col::LinkedHashSet::•<dynamic>();
+    for (dynamic i in let final<BottomType> #t300 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*)
-      #t380.{core::Set::add}{Invariant}(i);
-    #t380.{core::Set::add}{Invariant}(null);
-  } =>#t380;
+      #t299.{core::Set::add}{Invariant}(i);
+    #t299.{core::Set::add}{Invariant}(null);
+  } =>#t299;
   core::Map<core::String*, dynamic>* map10 = block {
-    final core::Map<core::String*, dynamic>* #t382 = <core::String*, dynamic>{};
-    for (dynamic i in let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::Map<core::String*, dynamic>* #t301 = <core::String*, dynamic>{};
+    for (dynamic i in let final<BottomType> #t302 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*)
-      #t382.{core::Map::[]=}{Invariant}("bar", i);
-    #t382.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t382;
+      #t301.{core::Map::[]=}{Invariant}("bar", i);
+    #t301.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t301;
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t384 = <core::int*>[];
-    for (core::int* i in <core::int*>[let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t303 = <core::int*>[];
+    for (core::int* i in <core::int*>[let final<BottomType> #t304 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t386 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t305 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int*])
-      #t384.{core::List::add}{Invariant}(i);
-  } =>#t384;
+      #t303.{core::List::add}{Invariant}(i);
+  } =>#t303;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t387 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i in <core::int*>[let final<BottomType> #t388 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t306 = col::LinkedHashSet::•<core::int*>();
+    for (core::int* i in <core::int*>[let final<BottomType> #t307 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t308 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int*])
-      #t387.{core::Set::add}{Invariant}(i);
-    #t387.{core::Set::add}{Invariant}(null);
-  } =>#t387;
+      #t306.{core::Set::add}{Invariant}(i);
+    #t306.{core::Set::add}{Invariant}(null);
+  } =>#t306;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t390 = <core::String*, core::int*>{};
-    for (core::int* i in <core::int*>[let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String*, core::int*>* #t309 = <core::String*, core::int*>{};
+    for (core::int* i in <core::int*>[let final<BottomType> #t310 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t311 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int*])
-      #t390.{core::Map::[]=}{Invariant}("bar", i);
-    #t390.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t390;
+      #t309.{core::Map::[]=}{Invariant}("bar", i);
+    #t309.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t309;
   core::List<dynamic>* list30 = block {
-    final core::List<dynamic>* #t393 = <dynamic>[];
-    await for (dynamic i in let final<BottomType> #t394 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::List<dynamic>* #t312 = <dynamic>[];
+    await for (dynamic i in let final<BottomType> #t313 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*)
-      #t393.{core::List::add}{Invariant}(i);
-  } =>#t393;
+      #t312.{core::List::add}{Invariant}(i);
+  } =>#t312;
   core::Set<dynamic>* set30 = block {
-    final core::Set<dynamic>* #t395 = col::LinkedHashSet::•<dynamic>();
-    await for (dynamic i in let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::Set<dynamic>* #t314 = col::LinkedHashSet::•<dynamic>();
+    await for (dynamic i in let final<BottomType> #t315 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*)
-      #t395.{core::Set::add}{Invariant}(i);
-    #t395.{core::Set::add}{Invariant}(null);
-  } =>#t395;
+      #t314.{core::Set::add}{Invariant}(i);
+    #t314.{core::Set::add}{Invariant}(null);
+  } =>#t314;
   core::Map<core::String*, dynamic>* map30 = block {
-    final core::Map<core::String*, dynamic>* #t397 = <core::String*, dynamic>{};
-    await for (dynamic i in let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::Map<core::String*, dynamic>* #t316 = <core::String*, dynamic>{};
+    await for (dynamic i in let final<BottomType> #t317 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*)
-      #t397.{core::Map::[]=}{Invariant}("bar", i);
-    #t397.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t397;
+      #t316.{core::Map::[]=}{Invariant}("bar", i);
+    #t316.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t316;
   core::List<core::int*>* list40 = block {
-    final core::List<core::int*>* #t399 = <core::int*>[];
-    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t400 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t318 = <core::int*>[];
+    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t319 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t401 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t320 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int*]))
-      #t399.{core::List::add}{Invariant}(i);
-  } =>#t399;
+      #t318.{core::List::add}{Invariant}(i);
+  } =>#t318;
   core::Set<core::int*>* set40 = block {
-    final core::Set<core::int*>* #t402 = col::LinkedHashSet::•<core::int*>();
-    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t321 = col::LinkedHashSet::•<core::int*>();
+    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t322 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int*]))
-      #t402.{core::Set::add}{Invariant}(i);
-    #t402.{core::Set::add}{Invariant}(null);
-  } =>#t402;
+      #t321.{core::Set::add}{Invariant}(i);
+    #t321.{core::Set::add}{Invariant}(null);
+  } =>#t321;
   core::Map<core::String*, core::int*>* map40 = block {
-    final core::Map<core::String*, core::int*>* #t405 = <core::String*, core::int*>{};
-    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t406 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String*, core::int*>* #t324 = <core::String*, core::int*>{};
+    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t325 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t407 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t326 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int*]))
-      #t405.{core::Map::[]=}{Invariant}("bar", i);
-    #t405.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t405;
+      #t324.{core::Map::[]=}{Invariant}("bar", i);
+    #t324.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t324;
   core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t408 = <core::int*>[];
+    final core::List<core::int*>* #t327 = <core::int*>[];
     for (; ; )
-      #t408.{core::List::add}{Invariant}(42);
-  } =>#t408;
+      #t327.{core::List::add}{Invariant}(42);
+  } =>#t327;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t409 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t328 = col::LinkedHashSet::•<core::int*>();
     for (; ; )
-      #t409.{core::Set::add}{Invariant}(42);
-    #t409.{core::Set::add}{Invariant}(null);
-  } =>#t409;
+      #t328.{core::Set::add}{Invariant}(42);
+    #t328.{core::Set::add}{Invariant}(null);
+  } =>#t328;
   core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t410 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t329 = <core::String*, core::int*>{};
     for (; ; )
-      #t410.{core::Map::[]=}{Invariant}("bar", 42);
-    #t410.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t410;
+      #t329.{core::Map::[]=}{Invariant}("bar", 42);
+    #t329.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t329;
   core::List<core::int*>* list60 = block {
-    final core::List<core::int*>* #t411 = <core::int*>[];
-    for (; let final<BottomType> #t412 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int*>* #t330 = <core::int*>[];
+    for (; let final<BottomType> #t331 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool*; )
-      #t411.{core::List::add}{Invariant}(42);
-  } =>#t411;
+      #t330.{core::List::add}{Invariant}(42);
+  } =>#t330;
   core::Set<core::int*>* set60 = block {
-    final core::Set<core::int*>* #t413 = col::LinkedHashSet::•<core::int*>();
-    for (; let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int*>* #t332 = col::LinkedHashSet::•<core::int*>();
+    for (; let final<BottomType> #t333 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-      #t413.{core::Set::add}{Invariant}(42);
-    #t413.{core::Set::add}{Invariant}(null);
-  } =>#t413;
+      #t332.{core::Set::add}{Invariant}(42);
+    #t332.{core::Set::add}{Invariant}(null);
+  } =>#t332;
   core::Map<core::String*, core::int*>* map60 = block {
-    final core::Map<core::String*, core::int*>* #t415 = <core::String*, core::int*>{};
-    for (; let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::String*, core::int*>* #t334 = <core::String*, core::int*>{};
+    for (; let final<BottomType> #t335 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-      #t415.{core::Map::[]=}{Invariant}("bar", 42);
-    #t415.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t415;
+      #t334.{core::Map::[]=}{Invariant}("bar", 42);
+    #t334.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t334;
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
   block {
-    final core::List<core::int*>* #t417 = <core::int*>[];
+    final core::List<core::int*>* #t336 = <core::int*>[];
     await for (core::int* i in stream)
-      #t417.{core::List::add}{Invariant}(i);
-  } =>#t417;
+      #t336.{core::List::add}{Invariant}(i);
+  } =>#t336;
   block {
-    final core::Set<core::int*>* #t418 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t337 = col::LinkedHashSet::•<core::int*>();
     await for (core::int* i in stream)
-      #t418.{core::Set::add}{Invariant}(i);
-  } =>#t418;
+      #t337.{core::Set::add}{Invariant}(i);
+  } =>#t337;
   block {
-    final core::Map<core::String*, core::int*>* #t419 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t338 = <core::String*, core::int*>{};
     await for (core::int* i in stream)
-      #t419.{core::Map::[]=}{Invariant}("bar", i);
-  } =>#t419;
+      #t338.{core::Map::[]=}{Invariant}("bar", i);
+  } =>#t338;
 }
 static method testPromotion(self::A* a) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t420 = <core::int*>[];
+    final core::List<core::int*>* #t339 = <core::int*>[];
     if(a is self::B*)
-      #t420.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t420;
+      #t339.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t339;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t421 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t340 = col::LinkedHashSet::•<core::int*>();
     if(a is self::B*)
-      #t421.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t421;
+      #t340.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t340;
   core::Map<core::int*, core::int*>* map10 = block {
-    final core::Map<core::int*, core::int*>* #t422 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t341 = <core::int*, core::int*>{};
     if(a is self::B*)
-      #t422.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
-  } =>#t422;
+      #t341.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
+  } =>#t341;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index 898ae52..da6a4b7 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -505,793 +505,588 @@
   } =>#t9;
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::List::add}{Invariant}(#t11);
-      }
-    }
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t10.{core::List::addAll}{Invariant}(<core::int*>[42]);
   } =>#t10;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t12 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t13 = :sync-for-iterator.{core::Iterator::current};
-        #t12.{core::Set::add}{Invariant}(#t13);
-      }
-    }
-    #t12.{core::Set::add}{Invariant}(null);
-  } =>#t12;
+    final core::Set<core::int*>* #t11 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t11.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t11.{core::Set::add}{Invariant}(null);
+  } =>#t11;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
-        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
       }
     }
-    #t14.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t14;
+    #t12.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t12;
   core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t16 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::List::add}{Invariant}(#t17);
-      }
-    }
-  } =>#t16;
+    final core::List<dynamic>* #t14 = <dynamic>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t14.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t14;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t18 = new col::_CompactLinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Set::add}{Invariant}(#t19);
-      }
-    }
-    #t18.{core::Set::add}{Invariant}(null);
-  } =>#t18;
+    final core::Set<dynamic>* #t15 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t15.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t15.{core::Set::add}{Invariant}(null);
+  } =>#t15;
   core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t16 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, dynamic>* #t21 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<core::String*, dynamic>* #t17 = :sync-for-iterator.{core::Iterator::current};
+        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+      }
+    }
+    #t16.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t16;
+  core::List<core::List<core::int*>*>* list22 = block {
+    final core::List<core::List<core::int*>*>* #t18 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t18.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t18;
+  core::Set<core::List<core::int*>*>* set22 = block {
+    final core::Set<core::List<core::int*>*>* #t19 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t19.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t19.{core::Set::add}{Invariant}(null);
+  } =>#t19;
+  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t20 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
       }
     }
     #t20.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t20;
-  core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t23 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::List::add}{Invariant}(#t23);
-      }
-    }
-  } =>#t22;
-  core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t24 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
-        #t24.{core::Set::add}{Invariant}(#t25);
-      }
-    }
-    #t24.{core::Set::add}{Invariant}(null);
-  } =>#t24;
-  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 = :sync-for-iterator.{core::Iterator::current};
-        #t26.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
-      }
-    }
-    #t26.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t26;
   core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t28 = <core::int*>[];
+    final core::List<core::int*>* #t22 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
-          #t28.{core::List::add}{Invariant}(#t29);
-        }
-      }
-  } =>#t28;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t22.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t22;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t30 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t23 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t31 = :sync-for-iterator.{core::Iterator::current};
-          #t30.{core::Set::add}{Invariant}(#t31);
-        }
-      }
-    #t30.{core::Set::add}{Invariant}(null);
-  } =>#t30;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t23.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t23.{core::Set::add}{Invariant}(null);
+  } =>#t23;
   core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t24 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::int*>* #t33 = :sync-for-iterator.{core::Iterator::current};
+          final core::MapEntry<core::String*, core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
+          #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
+        }
+      }
+    #t24.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t24;
+  core::List<dynamic>* list31 = block {
+    final core::List<dynamic>* #t26 = <dynamic>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t26.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t26;
+  core::Set<dynamic>* set31 = block {
+    final core::Set<dynamic>* #t27 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t27.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t27.{core::Set::add}{Invariant}(null);
+  } =>#t27;
+  core::Map<core::String*, dynamic>* map31 = block {
+    final core::Map<core::String*, dynamic>* #t28 = <core::String*, dynamic>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
+        core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
+        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+          final core::MapEntry<core::String*, dynamic>* #t29 = :sync-for-iterator.{core::Iterator::current};
+          #t28.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
+        }
+      }
+    #t28.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t28;
+  core::List<core::List<core::int*>*>* list33 = block {
+    final core::List<core::List<core::int*>*>* #t30 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t30.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t30;
+  core::Set<core::List<core::int*>*>* set33 = block {
+    final core::Set<core::List<core::int*>*>* #t31 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t31.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t31.{core::Set::add}{Invariant}(null);
+  } =>#t31;
+  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
+        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 = :sync-for-iterator.{core::Iterator::current};
           #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
         }
       }
     #t32.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t32;
-  core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t34 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
-          #t34.{core::List::add}{Invariant}(#t35);
-        }
-      }
-  } =>#t34;
-  core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t36 = new col::_CompactLinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t37 = :sync-for-iterator.{core::Iterator::current};
-          #t36.{core::Set::add}{Invariant}(#t37);
-        }
-      }
-    #t36.{core::Set::add}{Invariant}(null);
-  } =>#t36;
-  core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, dynamic>* #t39 = :sync-for-iterator.{core::Iterator::current};
-          #t38.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
-        }
-      }
-    #t38.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t38;
-  core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t41 = :sync-for-iterator.{core::Iterator::current};
-          #t40.{core::List::add}{Invariant}(#t41);
-        }
-      }
-  } =>#t40;
-  core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t42 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t43 = :sync-for-iterator.{core::Iterator::current};
-          #t42.{core::Set::add}{Invariant}(#t43);
-        }
-      }
-    #t42.{core::Set::add}{Invariant}(null);
-  } =>#t42;
-  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 = :sync-for-iterator.{core::Iterator::current};
-          #t44.{core::Map::[]=}{Invariant}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
-        }
-      }
-    #t44.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t44;
   core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
-        #t46.{core::List::add}{Invariant}(#t47);
-      }
-    }
-  } =>#t46;
+    final core::List<core::List<core::int*>*>* #t34 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t34.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t34;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t48 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t49 = :sync-for-iterator.{core::Iterator::current};
-        #t48.{core::Set::add}{Invariant}(#t49);
-      }
-    }
-    #t48.{core::Set::add}{Invariant}(null);
-  } =>#t48;
+    final core::Set<core::List<core::int*>*>* #t35 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t35.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t35.{core::Set::add}{Invariant}(null);
+  } =>#t35;
   core::Map<core::String*, core::List<core::int*>*>* map40 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:39:34: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
   Map<String, List<int>> map40 = {if (oracle(\"foo\")) ...{\"bar\", []}, \"baz\": null};
                                  ^";
   core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t51 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t51.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t51).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t52 = :sync-for-iterator.{core::Iterator::current};
-        #t50.{core::List::add}{Invariant}(#t52);
-      }
-    }
-  } =>#t50;
+    final core::List<core::List<core::int*>*>* #t36 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t36.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t37 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t37.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t37);
+  } =>#t36;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t53 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t54 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t54.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t54).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t55 = :sync-for-iterator.{core::Iterator::current};
-        #t53.{core::Set::add}{Invariant}(#t55);
-      }
-    }
-    #t53.{core::Set::add}{Invariant}(null);
-  } =>#t53;
+    final core::Set<core::List<core::int*>*>* #t38 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t38.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t39 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t39.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t39);
+    #t38.{core::Set::add}{Invariant}(null);
+  } =>#t38;
   core::List<core::List<core::int*>*>* list42 = block {
-    final core::List<core::List<core::int*>*>* #t56 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t57 = :sync-for-iterator.{core::Iterator::current};
-          #t56.{core::List::add}{Invariant}(#t57);
-        }
-      }
-  } =>#t56;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t40.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t40;
   core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t58 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t41 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
-          #t58.{core::Set::add}{Invariant}(#t59);
-        }
-      }
-    #t58.{core::Set::add}{Invariant}(null);
-  } =>#t58;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t41.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t41.{core::Set::add}{Invariant}(null);
+  } =>#t41;
   core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t60 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t61 = :sync-for-iterator.{core::Iterator::current};
-          #t60.{core::Map::[]=}{Invariant}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
+          #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
         }
       }
-    #t60.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t60;
+    #t42.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t42;
   core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t62 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t63 = :sync-for-iterator.{core::Iterator::current};
-        #t62.{core::List::add}{Invariant}(#t63);
-      }
-    }
-  } =>#t62;
+    final core::List<core::int*>* #t44 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t44.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t44;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t64 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t65 = :sync-for-iterator.{core::Iterator::current};
-        #t64.{core::Set::add}{Invariant}(#t65);
-      }
-    }
-    #t64.{core::Set::add}{Invariant}(null);
-  } =>#t64;
+    final core::Set<core::int*>* #t45 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t45.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t45.{core::Set::add}{Invariant}(null);
+  } =>#t45;
   core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t66 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t67 = :sync-for-iterator.{core::Iterator::current};
-        #t66.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
+        #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
       }
     }
-    #t66.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t66;
+    #t46.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t46;
   core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t68 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t69 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t69).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t70 = :sync-for-iterator.{core::Iterator::current};
-        #t68.{core::List::add}{Invariant}(#t70);
-      }
-    }
-  } =>#t68;
+    final core::List<core::int*>* #t48 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t48.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t49 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t49);
+  } =>#t48;
   core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t71 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t72 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t72).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t73 = :sync-for-iterator.{core::Iterator::current};
-        #t71.{core::Set::add}{Invariant}(#t73);
-      }
-    }
-    #t71.{core::Set::add}{Invariant}(null);
-  } =>#t71;
+    final core::Set<core::int*>* #t50 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t50.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t51 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t51);
+    #t50.{core::Set::add}{Invariant}(null);
+  } =>#t50;
   core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t74 = <core::int*>[];
+    final core::List<core::int*>* #t52 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t75 = :sync-for-iterator.{core::Iterator::current};
-          #t74.{core::List::add}{Invariant}(#t75);
-        }
-      }
-  } =>#t74;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t52.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t52;
   core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t76 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t53 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t77 = :sync-for-iterator.{core::Iterator::current};
-          #t76.{core::Set::add}{Invariant}(#t77);
-        }
-      }
-    #t76.{core::Set::add}{Invariant}(null);
-  } =>#t76;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t53.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t53.{core::Set::add}{Invariant}(null);
+  } =>#t53;
   core::Map<core::String*, core::int*>* map52 = block {
-    final core::Map<core::String*, core::int*>* #t78 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t54 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::int*>* #t79 = :sync-for-iterator.{core::Iterator::current};
-          #t78.{core::Map::[]=}{Invariant}(#t79.{core::MapEntry::key}, #t79.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::int*>* #t55 = :sync-for-iterator.{core::Iterator::current};
+          #t54.{core::Map::[]=}{Invariant}(#t55.{core::MapEntry::key}, #t55.{core::MapEntry::value});
         }
       }
-    #t78.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t78;
+    #t54.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t54;
   core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t80 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
-        #t80.{core::List::add}{Invariant}(#t81);
-      }
-    }
-  } =>#t80;
+    final core::List<core::List<core::int*>*>* #t56 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t56.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t56;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t82 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
-        #t82.{core::Set::add}{Invariant}(#t83);
-      }
-    }
-    #t82.{core::Set::add}{Invariant}(null);
-  } =>#t82;
+    final core::Set<core::List<core::int*>*>* #t57 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t57.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t57.{core::Set::add}{Invariant}(null);
+  } =>#t57;
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t84 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t58 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t85 = :sync-for-iterator.{core::Iterator::current};
-        #t84.{core::Map::[]=}{Invariant}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t59 = :sync-for-iterator.{core::Iterator::current};
+        #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
       }
     }
-    #t84.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t84;
+    #t58.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t58;
   core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t86 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t60 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t87 = :sync-for-iterator.{core::Iterator::current};
-          #t86.{core::List::add}{Invariant}(#t87);
-        }
-      }
-  } =>#t86;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t60.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t60;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t88 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t61 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t89 = :sync-for-iterator.{core::Iterator::current};
-          #t88.{core::Set::add}{Invariant}(#t89);
-        }
-      }
-    #t88.{core::Set::add}{Invariant}(null);
-  } =>#t88;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t61.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t61.{core::Set::add}{Invariant}(null);
+  } =>#t61;
   core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t90 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t91 = :sync-for-iterator.{core::Iterator::current};
-          #t90.{core::Map::[]=}{Invariant}(#t91.{core::MapEntry::key}, #t91.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 = :sync-for-iterator.{core::Iterator::current};
+          #t62.{core::Map::[]=}{Invariant}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
         }
       }
-    #t90.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t90;
+    #t62.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t62;
   core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t92 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t64 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t92.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t92;
+      #t64.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t64;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t93 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t65 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t93.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t93.{core::Set::add}{Invariant}(null);
-  } =>#t93;
+      #t65.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t65.{core::Set::add}{Invariant}(null);
+  } =>#t65;
   core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t94 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t66 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t94.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t94;
+        #t66.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t66;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t95 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t67 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t95.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t95.{core::Set::add}{Invariant}(null);
-  } =>#t95;
+        #t67.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t67.{core::Set::add}{Invariant}(null);
+  } =>#t67;
   core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t96 = <core::num*>[];
+    final core::List<core::num*>* #t68 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t96.{core::List::add}{Invariant}(42);
+      #t68.{core::List::add}{Invariant}(42);
     else
-      #t96.{core::List::add}{Invariant}(3.14);
-  } =>#t96;
+      #t68.{core::List::add}{Invariant}(3.14);
+  } =>#t68;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t97 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t69 = new col::_CompactLinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t97.{core::Set::add}{Invariant}(42);
+      #t69.{core::Set::add}{Invariant}(42);
     else
-      #t97.{core::Set::add}{Invariant}(3.14);
-    #t97.{core::Set::add}{Invariant}(null);
-  } =>#t97;
+      #t69.{core::Set::add}{Invariant}(3.14);
+    #t69.{core::Set::add}{Invariant}(null);
+  } =>#t69;
   core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t98 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t70 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t98.{core::Map::[]=}{Invariant}("bar", 42);
+      #t70.{core::Map::[]=}{Invariant}("bar", 42);
     else
-      #t98.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t98.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t98;
+      #t70.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t70.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t70;
   core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t99 = <core::num*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t100 = :sync-for-iterator.{core::Iterator::current};
-        #t99.{core::List::add}{Invariant}(#t100);
-      }
-    }
-    else {
-      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t101 = :sync-for-iterator.{core::Iterator::current};
-        #t99.{core::List::add}{Invariant}(#t101);
-      }
-    }
-  } =>#t99;
+    final core::List<core::num*>* #t71 = <core::num*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t71.{core::List::addAll}{Invariant}(listInt);
+    else
+      #t71.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t71;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t102 = new col::_CompactLinkedHashSet::•<core::num*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t103 = :sync-for-iterator.{core::Iterator::current};
-        #t102.{core::Set::add}{Invariant}(#t103);
-      }
-    }
-    else {
-      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t104 = :sync-for-iterator.{core::Iterator::current};
-        #t102.{core::Set::add}{Invariant}(#t104);
-      }
-    }
-    #t102.{core::Set::add}{Invariant}(null);
-  } =>#t102;
+    final core::Set<core::num*>* #t72 = new col::_CompactLinkedHashSet::•<core::num*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t72.{core::Set::addAll}{Invariant}(listInt);
+    else
+      #t72.{core::Set::addAll}{Invariant}(listDouble);
+    #t72.{core::Set::add}{Invariant}(null);
+  } =>#t72;
   core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t105 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t73 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::num*>* #t106 = :sync-for-iterator.{core::Iterator::current};
-        #t105.{core::Map::[]=}{Invariant}(#t106.{core::MapEntry::key}, #t106.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::num*>* #t74 = :sync-for-iterator.{core::Iterator::current};
+        #t73.{core::Map::[]=}{Invariant}(#t74.{core::MapEntry::key}, #t74.{core::MapEntry::value});
       }
     }
     else {
       core::Iterator<core::MapEntry<core::String*, core::double*>>* :sync-for-iterator = mapToDouble.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::num*>* #t107 = :sync-for-iterator.{core::Iterator::current};
-        #t105.{core::Map::[]=}{Invariant}(#t107.{core::MapEntry::key}, #t107.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::num*>* #t75 = :sync-for-iterator.{core::Iterator::current};
+        #t73.{core::Map::[]=}{Invariant}(#t75.{core::MapEntry::key}, #t75.{core::MapEntry::value});
       }
     }
-    #t105.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t105;
+    #t73.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t73;
   core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t108 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t109 = :sync-for-iterator.{core::Iterator::current};
-        #t108.{core::List::add}{Invariant}(#t109);
-      }
-    }
-    else {
-      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t110 = :sync-for-iterator.{core::Iterator::current};
-        #t108.{core::List::add}{Invariant}(#t110);
-      }
-    }
-  } =>#t108;
-  core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t111 = new col::_CompactLinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t112 = :sync-for-iterator.{core::Iterator::current};
-        #t111.{core::Set::add}{Invariant}(#t112);
-      }
-    }
-    else {
-      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t113 = :sync-for-iterator.{core::Iterator::current};
-        #t111.{core::Set::add}{Invariant}(#t113);
-      }
-    }
-    #t111.{core::Set::add}{Invariant}(null);
-  } =>#t111;
-  core::Set<dynamic>* map82 = block {
-    final core::Set<dynamic>* #t114 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::List<dynamic>* #t76 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t114.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t76.{core::List::addAll}{Invariant}(listInt);
+    else
+      #t76.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t76;
+  core::Set<dynamic>* set82 = block {
+    final core::Set<dynamic>* #t77 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t77.{core::Set::addAll}{Invariant}(listInt);
+    else
+      #t77.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t77.{core::Set::add}{Invariant}(null);
+  } =>#t77;
+  core::Set<dynamic>* map82 = block {
+    final core::Set<dynamic>* #t78 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t78.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
-    else {
-      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t115 = :sync-for-iterator.{core::Iterator::current};
-        #t114.{core::Set::add}{Invariant}(#t115);
-      }
-    }
-    #t114.{core::Set::add}{Invariant}(null);
-  } =>#t114;
-  core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t116 = <core::num*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t116.{core::List::add}{Invariant}(42);
-    else {
-      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t117 = :sync-for-iterator.{core::Iterator::current};
-        #t116.{core::List::add}{Invariant}(#t117);
-      }
-    }
-  } =>#t116;
-  core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t118 = new col::_CompactLinkedHashSet::•<core::num*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t119 = :sync-for-iterator.{core::Iterator::current};
-        #t118.{core::Set::add}{Invariant}(#t119);
-      }
-    }
     else
-      #t118.{core::Set::add}{Invariant}(3.14);
-    #t118.{core::Set::add}{Invariant}(null);
-  } =>#t118;
+      #t78.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t78.{core::Set::add}{Invariant}(null);
+  } =>#t78;
+  core::List<core::num*>* list83 = block {
+    final core::List<core::num*>* #t79 = <core::num*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t79.{core::List::add}{Invariant}(42);
+    else
+      #t79.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t79;
+  core::Set<core::num*>* set83 = block {
+    final core::Set<core::num*>* #t80 = new col::_CompactLinkedHashSet::•<core::num*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t80.{core::Set::addAll}{Invariant}(listInt);
+    else
+      #t80.{core::Set::add}{Invariant}(3.14);
+    #t80.{core::Set::add}{Invariant}(null);
+  } =>#t80;
   core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t120 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t81 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::num*>* #t121 = :sync-for-iterator.{core::Iterator::current};
-        #t120.{core::Map::[]=}{Invariant}(#t121.{core::MapEntry::key}, #t121.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::num*>* #t82 = :sync-for-iterator.{core::Iterator::current};
+        #t81.{core::Map::[]=}{Invariant}(#t82.{core::MapEntry::key}, #t82.{core::MapEntry::value});
       }
     }
     else
-      #t120.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t120.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t120;
+      #t81.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t81.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t81;
   core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t122 = <core::int*>[];
+    final core::List<core::int*>* #t83 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t122.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t122;
+      #t83.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+  } =>#t83;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t123 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t84 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t123.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t123.{core::Set::add}{Invariant}(null);
-  } =>#t123;
+      #t84.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t84.{core::Set::add}{Invariant}(null);
+  } =>#t84;
   core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t124 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t85 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t124.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t124.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t124;
+      #t85.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t85.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t85;
   core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t125 = <core::int*>[];
+    final core::List<core::int*>* #t86 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t126 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t87 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t127 = #t126 as{TypeError} core::int*;
-          #t125.{core::List::add}{Invariant}(#t127);
+          final core::int* #t88 = #t87 as{TypeError} core::int*;
+          #t86.{core::List::add}{Invariant}(#t88);
         }
       }
     }
-  } =>#t125;
+  } =>#t86;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t128 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t89 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t129 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t90 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t130 = #t129 as{TypeError} core::int*;
-          #t128.{core::Set::add}{Invariant}(#t130);
+          final core::int* #t91 = #t90 as{TypeError} core::int*;
+          #t89.{core::Set::add}{Invariant}(#t91);
         }
       }
     }
-    #t128.{core::Set::add}{Invariant}(null);
-  } =>#t128;
+    #t89.{core::Set::add}{Invariant}(null);
+  } =>#t89;
   core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t131 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t92 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t132 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<dynamic, dynamic>* #t93 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::String* #t133 = #t132.{core::MapEntry::key} as{TypeError} core::String*;
-          final core::int* #t134 = #t132.{core::MapEntry::value} as{TypeError} core::int*;
-          #t131.{core::Map::[]=}{Invariant}(#t133, #t134);
+          final core::String* #t94 = #t93.{core::MapEntry::key} as{TypeError} core::String*;
+          final core::int* #t95 = #t93.{core::MapEntry::value} as{TypeError} core::int*;
+          #t92.{core::Map::[]=}{Invariant}(#t94, #t95);
         }
       }
     }
-    #t131.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t131;
+    #t92.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t92;
   core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t135 = <core::int*>[];
+    final core::List<core::int*>* #t96 = <core::int*>[];
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t135.{core::List::add}{Invariant}(42);
-  } =>#t135;
+      #t96.{core::List::add}{Invariant}(42);
+  } =>#t96;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t136 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t97 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t136.{core::Set::add}{Invariant}(42);
-  } =>#t136;
+      #t97.{core::Set::add}{Invariant}(42);
+  } =>#t97;
   core::Map<core::int*, core::int*>* map100 = block {
-    final core::Map<core::int*, core::int*>* #t137 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t98 = <core::int*, core::int*>{};
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t137.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t137;
+      #t98.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t98;
 }
 static method testIfElementErrors(core::Map<core::int*, core::int*>* map) → dynamic {
   block {
-    final core::List<core::int*>* #t138 = <core::int*>[];
+    final core::List<core::int*>* #t99 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t138.{core::List::add}{Invariant}(let final<BottomType> #t139 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t99.{core::List::add}{Invariant}(let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) \"bar\"];
                            ^" in "bar" as{TypeError} core::int*);
-  } =>#t138;
+  } =>#t99;
   block {
-    final core::Set<core::int*>* #t140 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t101 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t140.{core::Set::add}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t101.{core::Set::add}{Invariant}(let final<BottomType> #t102 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
                            ^" in "bar" as{TypeError} core::int*);
-    #t140.{core::Set::add}{Invariant}(null);
-  } =>#t140;
+    #t101.{core::Set::add}{Invariant}(null);
+  } =>#t101;
   block {
-    final core::Map<core::String*, core::int*>* #t142 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t103 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t142.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t103.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
                                           ^" in "bar" as{TypeError} core::int*);
-    #t142.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t142;
+    #t103.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t103;
   block {
-    final core::List<core::int*>* #t144 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t105 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t105.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t146 = :sync-for-iterator.{core::Iterator::current};
-        #t144.{core::List::add}{Invariant}(#t146);
-      }
-    }
-  } =>#t144;
+                               ^" in "bar" as{TypeError} core::int*]);
+  } =>#t105;
   block {
-    final core::Set<core::int*>* #t147 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t107 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t107.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t149 = :sync-for-iterator.{core::Iterator::current};
-        #t147.{core::Set::add}{Invariant}(#t149);
-      }
-    }
-    #t147.{core::Set::add}{Invariant}(null);
-  } =>#t147;
+                               ^" in "bar" as{TypeError} core::int*]);
+    #t107.{core::Set::add}{Invariant}(null);
+  } =>#t107;
   block {
-    final core::Map<core::String*, core::int*>* #t150 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t109 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t110 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t152 = :sync-for-iterator.{core::Iterator::current};
-        #t150.{core::Map::[]=}{Invariant}(#t152.{core::MapEntry::key}, #t152.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t111 = :sync-for-iterator.{core::Iterator::current};
+        #t109.{core::Map::[]=}{Invariant}(#t111.{core::MapEntry::key}, #t111.{core::MapEntry::value});
       }
     }
-    #t150.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t150;
+    #t109.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t109;
   block {
-    final core::List<core::int*>* #t153 = <core::int*>[];
+    final core::List<core::int*>* #t112 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t153.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t112.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map];
                               ^");
-  } =>#t153;
+  } =>#t112;
   block {
-    final core::Set<core::int*>* #t154 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t113 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t154.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t113.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map, null};
                               ^");
-    #t154.{core::Set::add}{Invariant}(null);
-  } =>#t154;
+    #t113.{core::Set::add}{Invariant}(null);
+  } =>#t113;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
@@ -1300,61 +1095,61 @@
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::String*>* #t155 = <core::String*>[];
+    final core::List<core::String*>* #t114 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t156 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t115 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t157 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                                       ^" in 3.14 as{TypeError} core::String*);
-  } =>#t155;
+  } =>#t114;
   block {
-    final core::Set<core::String*>* #t158 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t117 = new col::_CompactLinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t160 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                                       ^" in 3.14 as{TypeError} core::String*);
-    #t158.{core::Set::add}{Invariant}(null);
-  } =>#t158;
+    #t117.{core::Set::add}{Invariant}(null);
+  } =>#t117;
   block {
-    final core::Map<core::String*, core::String*>* #t161 = <core::String*, core::String*>{};
+    final core::Map<core::String*, core::String*>* #t120 = <core::String*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t161.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                              ^" in 42 as{TypeError} core::String*);
     else
-      #t161.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t163 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                                             ^" in 3.14 as{TypeError} core::String*);
-    #t161.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t161;
+    #t120.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t120;
   block {
-    final core::List<core::int*>* #t164 = <core::int*>[];
+    final core::List<core::int*>* #t123 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t164.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t123.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map else 42];
                               ^");
     else
-      #t164.{core::List::add}{Invariant}(42);
-  } =>#t164;
+      #t123.{core::List::add}{Invariant}(42);
+  } =>#t123;
   block {
-    final core::Set<core::int*>* #t165 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t124 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t165.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t124.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t165.{core::Set::add}{Invariant}(42);
-    #t165.{core::Set::add}{Invariant}(null);
-  } =>#t165;
+      #t124.{core::Set::add}{Invariant}(42);
+    #t124.{core::Set::add}{Invariant}(null);
+  } =>#t124;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
@@ -1363,26 +1158,26 @@
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::int*>* #t166 = <core::int*>[];
+    final core::List<core::int*>* #t125 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t166.{core::List::add}{Invariant}(42);
+      #t125.{core::List::add}{Invariant}(42);
     else
-      #t166.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t125.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) 42 else ...map];
                                       ^");
-  } =>#t166;
+  } =>#t125;
   block {
-    final core::Set<core::int*>* #t167 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t126 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t167.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t126.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t167.{core::Set::add}{Invariant}(42);
-    #t167.{core::Set::add}{Invariant}(null);
-  } =>#t167;
+      #t126.{core::Set::add}{Invariant}(42);
+    #t126.{core::Set::add}{Invariant}(null);
+  } =>#t126;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
@@ -1409,940 +1204,749 @@
   var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
                                                    ^": null};
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t168 = <core::int*>[];
-    if(let final<BottomType> #t169 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int*>* #t127 = <core::int*>[];
+    if(let final<BottomType> #t128 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   List<int> list20 = [if (42) 42];
                           ^" in 42 as{TypeError} core::bool*)
-      #t168.{core::List::add}{Invariant}(42);
-  } =>#t168;
+      #t127.{core::List::add}{Invariant}(42);
+  } =>#t127;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t170 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int*>* #t129 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(let final<BottomType> #t130 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
-      #t170.{core::Set::add}{Invariant}(42);
-  } =>#t170;
+      #t129.{core::Set::add}{Invariant}(42);
+  } =>#t129;
   core::Map<core::int*, core::int*>* map30 = block {
-    final core::Map<core::int*, core::int*>* #t172 = <core::int*, core::int*>{};
-    if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::int*, core::int*>* #t131 = <core::int*, core::int*>{};
+    if(let final<BottomType> #t132 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Map<int, int> map30 = {if (42) 42: 42};
                              ^" in 42 as{TypeError} core::bool*)
-      #t172.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t172;
+      #t131.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t131;
   core::List<core::String*>* list40 = block {
-    final core::List<core::String*>* #t174 = <core::String*>[];
+    final core::List<core::String*>* #t133 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t134 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                     ^" in true as{TypeError} core::String*);
     else
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t176 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t135 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t174;
+  } =>#t133;
   core::Set<core::String*>* set40 = block {
-    final core::Set<core::String*>* #t177 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t136 = new col::_CompactLinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t137 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                   ^" in true as{TypeError} core::String*);
     else
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t179 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t138 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                             ^" in 42 as{TypeError} core::String*);
-  } =>#t177;
+  } =>#t136;
   core::Map<core::String*, core::int*>* map40 = block {
-    final core::Map<core::String*, core::int*>* #t180 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t139 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t140 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                             ^" in true as{TypeError} core::String*, 42);
     else
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t182 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                                           ^" in 42 as{TypeError} core::String*, 42);
-  } =>#t180;
+  } =>#t139;
   core::Map<core::int*, core::String*>* map41 = block {
-    final core::Map<core::int*, core::String*>* #t183 = <core::int*, core::String*>{};
+    final core::Map<core::int*, core::String*>* #t142 = <core::int*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                 ^" in true as{TypeError} core::String*);
     else
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t185 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t144 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t183;
+  } =>#t142;
 }
 static method testForElement(dynamic dynVar, core::List<core::int*>* listInt, core::List<core::double*>* listDouble, core::int* index, core::Map<core::String*, core::int*>* mapStringInt, core::Map<core::String*, core::double*>* mapStringDouble) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t186 = <core::int*>[];
+    final core::List<core::int*>* #t145 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t186.{core::List::add}{Invariant}(42);
-  } =>#t186;
+      #t145.{core::List::add}{Invariant}(42);
+  } =>#t145;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t187 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t146 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t187.{core::Set::add}{Invariant}(42);
-    #t187.{core::Set::add}{Invariant}(null);
-  } =>#t187;
+      #t146.{core::Set::add}{Invariant}(42);
+    #t146.{core::Set::add}{Invariant}(null);
+  } =>#t146;
   core::Map<core::String*, core::int*>* map10 = block {
-    final core::Map<core::String*, core::int*>* #t188 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t147 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t188.{core::Map::[]=}{Invariant}("bar", 42);
-    #t188.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t188;
+      #t147.{core::Map::[]=}{Invariant}("bar", 42);
+    #t147.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t147;
   core::List<dynamic>* list11 = block {
-    final core::List<dynamic>* #t189 = <dynamic>[];
+    final core::List<dynamic>* #t148 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t189.{core::List::add}{Invariant}(dynVar);
-  } =>#t189;
+      #t148.{core::List::add}{Invariant}(dynVar);
+  } =>#t148;
   core::Set<dynamic>* set11 = block {
-    final core::Set<dynamic>* #t190 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t149 = new col::_CompactLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t190.{core::Set::add}{Invariant}(dynVar);
-    #t190.{core::Set::add}{Invariant}(null);
-  } =>#t190;
+      #t149.{core::Set::add}{Invariant}(dynVar);
+    #t149.{core::Set::add}{Invariant}(null);
+  } =>#t149;
   core::Map<core::String*, dynamic>* map11 = block {
-    final core::Map<core::String*, dynamic>* #t191 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t150 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t191.{core::Map::[]=}{Invariant}("bar", dynVar);
-    #t191.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t191;
+      #t150.{core::Map::[]=}{Invariant}("bar", dynVar);
+    #t150.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t150;
   core::List<core::List<core::int*>*>* list12 = block {
-    final core::List<core::List<core::int*>*>* #t192 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t151 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t192.{core::List::add}{Invariant}(<core::int*>[42]);
-  } =>#t192;
+      #t151.{core::List::add}{Invariant}(<core::int*>[42]);
+  } =>#t151;
   core::Set<core::List<core::int*>*>* set12 = block {
-    final core::Set<core::List<core::int*>*>* #t193 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t152 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t193.{core::Set::add}{Invariant}(<core::int*>[42]);
-    #t193.{core::Set::add}{Invariant}(null);
-  } =>#t193;
+      #t152.{core::Set::add}{Invariant}(<core::int*>[42]);
+    #t152.{core::Set::add}{Invariant}(null);
+  } =>#t152;
   core::Map<core::String*, core::List<core::int*>*>* map12 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t194 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t153 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t194.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
-    #t194.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t194;
+      #t153.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
+    #t153.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t153;
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t195 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t196 = :sync-for-iterator.{core::Iterator::current};
-        #t195.{core::List::add}{Invariant}(#t196);
-      }
-    }
-  } =>#t195;
+    final core::List<core::int*>* #t154 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t154.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t154;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t197 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t198 = :sync-for-iterator.{core::Iterator::current};
-        #t197.{core::Set::add}{Invariant}(#t198);
-      }
-    }
-    #t197.{core::Set::add}{Invariant}(null);
-  } =>#t197;
+    final core::Set<core::int*>* #t155 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t155.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t155.{core::Set::add}{Invariant}(null);
+  } =>#t155;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t199 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t156 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t200 = :sync-for-iterator.{core::Iterator::current};
-        #t199.{core::Map::[]=}{Invariant}(#t200.{core::MapEntry::key}, #t200.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t157 = :sync-for-iterator.{core::Iterator::current};
+        #t156.{core::Map::[]=}{Invariant}(#t157.{core::MapEntry::key}, #t157.{core::MapEntry::value});
       }
     }
-    #t199.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t199;
+    #t156.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t156;
   core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t201 = <dynamic>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t202 = :sync-for-iterator.{core::Iterator::current};
-        #t201.{core::List::add}{Invariant}(#t202);
-      }
-    }
-  } =>#t201;
+    final core::List<dynamic>* #t158 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t158.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t158;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t203 = new col::_CompactLinkedHashSet::•<dynamic>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t204 = :sync-for-iterator.{core::Iterator::current};
-        #t203.{core::Set::add}{Invariant}(#t204);
-      }
-    }
-    #t203.{core::Set::add}{Invariant}(null);
-  } =>#t203;
+    final core::Set<dynamic>* #t159 = new col::_CompactLinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t159.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t159.{core::Set::add}{Invariant}(null);
+  } =>#t159;
   core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t205 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t160 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, dynamic>* #t206 = :sync-for-iterator.{core::Iterator::current};
-        #t205.{core::Map::[]=}{Invariant}(#t206.{core::MapEntry::key}, #t206.{core::MapEntry::value});
+        final core::MapEntry<core::String*, dynamic>* #t161 = :sync-for-iterator.{core::Iterator::current};
+        #t160.{core::Map::[]=}{Invariant}(#t161.{core::MapEntry::key}, #t161.{core::MapEntry::value});
       }
     }
-    #t205.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t205;
+    #t160.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t160;
   core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t207 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t208 = :sync-for-iterator.{core::Iterator::current};
-        #t207.{core::List::add}{Invariant}(#t208);
-      }
-    }
-  } =>#t207;
+    final core::List<core::List<core::int*>*>* #t162 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t162.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t162;
   core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t209 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t210 = :sync-for-iterator.{core::Iterator::current};
-        #t209.{core::Set::add}{Invariant}(#t210);
-      }
-    }
-    #t209.{core::Set::add}{Invariant}(null);
-  } =>#t209;
+    final core::Set<core::List<core::int*>*>* #t163 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t163.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t163.{core::Set::add}{Invariant}(null);
+  } =>#t163;
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t211 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t164 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t212 = :sync-for-iterator.{core::Iterator::current};
-        #t211.{core::Map::[]=}{Invariant}(#t212.{core::MapEntry::key}, #t212.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t165 = :sync-for-iterator.{core::Iterator::current};
+        #t164.{core::Map::[]=}{Invariant}(#t165.{core::MapEntry::key}, #t165.{core::MapEntry::value});
       }
     }
-    #t211.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t211;
+    #t164.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t164;
   core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t213 = <core::int*>[];
+    final core::List<core::int*>* #t166 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t214 = :sync-for-iterator.{core::Iterator::current};
-          #t213.{core::List::add}{Invariant}(#t214);
-        }
-      }
-  } =>#t213;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t166.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t166;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t215 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t167 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t216 = :sync-for-iterator.{core::Iterator::current};
-          #t215.{core::Set::add}{Invariant}(#t216);
-        }
-      }
-    #t215.{core::Set::add}{Invariant}(null);
-  } =>#t215;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t167.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t167.{core::Set::add}{Invariant}(null);
+  } =>#t167;
   core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t217 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t168 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::int*>* #t218 = :sync-for-iterator.{core::Iterator::current};
-          #t217.{core::Map::[]=}{Invariant}(#t218.{core::MapEntry::key}, #t218.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::int*>* #t169 = :sync-for-iterator.{core::Iterator::current};
+          #t168.{core::Map::[]=}{Invariant}(#t169.{core::MapEntry::key}, #t169.{core::MapEntry::value});
         }
       }
-    #t217.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t217;
+    #t168.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t168;
   core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t219 = <dynamic>[];
+    final core::List<dynamic>* #t170 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t220 = :sync-for-iterator.{core::Iterator::current};
-          #t219.{core::List::add}{Invariant}(#t220);
-        }
-      }
-  } =>#t219;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t170.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t170;
   core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t221 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t171 = new col::_CompactLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t222 = :sync-for-iterator.{core::Iterator::current};
-          #t221.{core::Set::add}{Invariant}(#t222);
-        }
-      }
-    #t221.{core::Set::add}{Invariant}(null);
-  } =>#t221;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t171.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t171.{core::Set::add}{Invariant}(null);
+  } =>#t171;
   core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t223 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t172 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, dynamic>* #t224 = :sync-for-iterator.{core::Iterator::current};
-          #t223.{core::Map::[]=}{Invariant}(#t224.{core::MapEntry::key}, #t224.{core::MapEntry::value});
+          final core::MapEntry<core::String*, dynamic>* #t173 = :sync-for-iterator.{core::Iterator::current};
+          #t172.{core::Map::[]=}{Invariant}(#t173.{core::MapEntry::key}, #t173.{core::MapEntry::value});
         }
       }
-    #t223.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t223;
+    #t172.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t172;
   core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t225 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t174 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t226 = :sync-for-iterator.{core::Iterator::current};
-          #t225.{core::List::add}{Invariant}(#t226);
-        }
-      }
-  } =>#t225;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t174.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t174;
   core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t227 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t175 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t228 = :sync-for-iterator.{core::Iterator::current};
-          #t227.{core::Set::add}{Invariant}(#t228);
-        }
-      }
-    #t227.{core::Set::add}{Invariant}(null);
-  } =>#t227;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t175.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t175.{core::Set::add}{Invariant}(null);
+  } =>#t175;
   core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t229 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t176 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t230 = :sync-for-iterator.{core::Iterator::current};
-          #t229.{core::Map::[]=}{Invariant}(#t230.{core::MapEntry::key}, #t230.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t177 = :sync-for-iterator.{core::Iterator::current};
+          #t176.{core::Map::[]=}{Invariant}(#t177.{core::MapEntry::key}, #t177.{core::MapEntry::value});
         }
       }
-    #t229.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t229;
+    #t176.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t176;
   core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t231 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t232 = :sync-for-iterator.{core::Iterator::current};
-        #t231.{core::List::add}{Invariant}(#t232);
-      }
-    }
-  } =>#t231;
+    final core::List<core::List<core::int*>*>* #t178 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t178.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t178;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t233 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t234 = :sync-for-iterator.{core::Iterator::current};
-        #t233.{core::Set::add}{Invariant}(#t234);
-      }
-    }
-    #t233.{core::Set::add}{Invariant}(null);
-  } =>#t233;
+    final core::Set<core::List<core::int*>*>* #t179 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t179.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t179.{core::Set::add}{Invariant}(null);
+  } =>#t179;
   core::Map<core::String*, core::List<core::int*>*>* map40 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t235 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t180 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t236 = :sync-for-iterator.{core::Iterator::current};
-        #t235.{core::Map::[]=}{Invariant}(#t236.{core::MapEntry::key}, #t236.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t181 = :sync-for-iterator.{core::Iterator::current};
+        #t180.{core::Map::[]=}{Invariant}(#t181.{core::MapEntry::key}, #t181.{core::MapEntry::value});
       }
     }
-    #t235.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t235;
+    #t180.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t180;
   core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t237 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t238 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t238.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t238).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t239 = :sync-for-iterator.{core::Iterator::current};
-        #t237.{core::List::add}{Invariant}(#t239);
-      }
-    }
-  } =>#t237;
+    final core::List<core::List<core::int*>*>* #t182 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t182.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t183 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t183.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t183);
+  } =>#t182;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t240 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t241 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t241.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t241).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t242 = :sync-for-iterator.{core::Iterator::current};
-        #t240.{core::Set::add}{Invariant}(#t242);
-      }
-    }
-    #t240.{core::Set::add}{Invariant}(null);
-  } =>#t240;
+    final core::Set<core::List<core::int*>*>* #t184 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t184.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t185 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t185.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t185);
+    #t184.{core::Set::add}{Invariant}(null);
+  } =>#t184;
   core::List<core::List<core::int*>*>* list42 = block {
-    final core::List<core::List<core::int*>*>* #t243 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t186 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t244 = :sync-for-iterator.{core::Iterator::current};
-          #t243.{core::List::add}{Invariant}(#t244);
-        }
-      }
-  } =>#t243;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t186.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t186;
   core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t245 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t187 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t246 = :sync-for-iterator.{core::Iterator::current};
-          #t245.{core::Set::add}{Invariant}(#t246);
-        }
-      }
-    #t245.{core::Set::add}{Invariant}(null);
-  } =>#t245;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t187.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t187.{core::Set::add}{Invariant}(null);
+  } =>#t187;
   core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t247 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t188 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t248 = :sync-for-iterator.{core::Iterator::current};
-          #t247.{core::Map::[]=}{Invariant}(#t248.{core::MapEntry::key}, #t248.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t189 = :sync-for-iterator.{core::Iterator::current};
+          #t188.{core::Map::[]=}{Invariant}(#t189.{core::MapEntry::key}, #t189.{core::MapEntry::value});
         }
       }
-    #t247.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t247;
+    #t188.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t188;
   core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t249 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t250 = :sync-for-iterator.{core::Iterator::current};
-        #t249.{core::List::add}{Invariant}(#t250);
-      }
-    }
-  } =>#t249;
+    final core::List<core::int*>* #t190 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t190.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t190;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t251 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t252 = :sync-for-iterator.{core::Iterator::current};
-        #t251.{core::Set::add}{Invariant}(#t252);
-      }
-    }
-    #t251.{core::Set::add}{Invariant}(null);
-  } =>#t251;
+    final core::Set<core::int*>* #t191 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t191.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t191.{core::Set::add}{Invariant}(null);
+  } =>#t191;
   core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t253 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t192 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t254 = :sync-for-iterator.{core::Iterator::current};
-        #t253.{core::Map::[]=}{Invariant}(#t254.{core::MapEntry::key}, #t254.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t193 = :sync-for-iterator.{core::Iterator::current};
+        #t192.{core::Map::[]=}{Invariant}(#t193.{core::MapEntry::key}, #t193.{core::MapEntry::value});
       }
     }
-    #t253.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t253;
+    #t192.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t192;
   core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t255 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t256 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t256).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t257 = :sync-for-iterator.{core::Iterator::current};
-        #t255.{core::List::add}{Invariant}(#t257);
-      }
-    }
-  } =>#t255;
+    final core::List<core::int*>* #t194 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t194.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t195 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t195);
+  } =>#t194;
   core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t258 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t259 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t259).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t260 = :sync-for-iterator.{core::Iterator::current};
-        #t258.{core::Set::add}{Invariant}(#t260);
-      }
-    }
-    #t258.{core::Set::add}{Invariant}(null);
-  } =>#t258;
+    final core::Set<core::int*>* #t196 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t196.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t197 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t197);
+    #t196.{core::Set::add}{Invariant}(null);
+  } =>#t196;
   core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t261 = <core::int*>[];
+    final core::List<core::int*>* #t198 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t262 = :sync-for-iterator.{core::Iterator::current};
-          #t261.{core::List::add}{Invariant}(#t262);
-        }
-      }
-  } =>#t261;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t198.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t198;
   core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t263 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t199 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t264 = :sync-for-iterator.{core::Iterator::current};
-          #t263.{core::Set::add}{Invariant}(#t264);
-        }
-      }
-    #t263.{core::Set::add}{Invariant}(null);
-  } =>#t263;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t199.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t199.{core::Set::add}{Invariant}(null);
+  } =>#t199;
   core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t265 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t266 = :sync-for-iterator.{core::Iterator::current};
-        #t265.{core::List::add}{Invariant}(#t266);
-      }
-    }
-  } =>#t265;
+    final core::List<core::List<core::int*>*>* #t200 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t200.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t200;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t267 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t268 = :sync-for-iterator.{core::Iterator::current};
-        #t267.{core::Set::add}{Invariant}(#t268);
-      }
-    }
-    #t267.{core::Set::add}{Invariant}(null);
-  } =>#t267;
+    final core::Set<core::List<core::int*>*>* #t201 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t201.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t201.{core::Set::add}{Invariant}(null);
+  } =>#t201;
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t269 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t202 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t270 = :sync-for-iterator.{core::Iterator::current};
-        #t269.{core::Map::[]=}{Invariant}(#t270.{core::MapEntry::key}, #t270.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t203 = :sync-for-iterator.{core::Iterator::current};
+        #t202.{core::Map::[]=}{Invariant}(#t203.{core::MapEntry::key}, #t203.{core::MapEntry::value});
       }
     }
-    #t269.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t269;
+    #t202.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t202;
   core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t271 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t204 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t272 = :sync-for-iterator.{core::Iterator::current};
-          #t271.{core::List::add}{Invariant}(#t272);
-        }
-      }
-  } =>#t271;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t204.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t204;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t273 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t205 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t274 = :sync-for-iterator.{core::Iterator::current};
-          #t273.{core::Set::add}{Invariant}(#t274);
-        }
-      }
-    #t273.{core::Set::add}{Invariant}(null);
-  } =>#t273;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t205.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t205.{core::Set::add}{Invariant}(null);
+  } =>#t205;
   core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t275 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t206 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t276 = :sync-for-iterator.{core::Iterator::current};
-          #t275.{core::Map::[]=}{Invariant}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t207 = :sync-for-iterator.{core::Iterator::current};
+          #t206.{core::Map::[]=}{Invariant}(#t207.{core::MapEntry::key}, #t207.{core::MapEntry::value});
         }
       }
-    #t275.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t275;
+    #t206.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t206;
   core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t277 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t208 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t277.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t277;
+      #t208.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t208;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t278 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t209 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t278.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t278.{core::Set::add}{Invariant}(null);
-  } =>#t278;
+      #t209.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t209.{core::Set::add}{Invariant}(null);
+  } =>#t209;
   core::Map<core::String*, core::List<core::int*>*>* map70 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t210 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t279.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t279.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t279;
+      #t210.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t210.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t210;
   core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t280 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t211 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t280.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t280;
+        #t211.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t211;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t281 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t212 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t281.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t281.{core::Set::add}{Invariant}(null);
-  } =>#t281;
+        #t212.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t212.{core::Set::add}{Invariant}(null);
+  } =>#t212;
   core::Map<core::String*, core::List<core::int*>*>* map71 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t282 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t282.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t282.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t282;
+        #t213.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t213.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t213;
   core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t283 = <core::num*>[];
+    final core::List<core::num*>* #t214 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t283.{core::List::add}{Invariant}(42);
+        #t214.{core::List::add}{Invariant}(42);
       else
-        #t283.{core::List::add}{Invariant}(3.14);
-  } =>#t283;
+        #t214.{core::List::add}{Invariant}(3.14);
+  } =>#t214;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t284 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t215 = new col::_CompactLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t284.{core::Set::add}{Invariant}(42);
+        #t215.{core::Set::add}{Invariant}(42);
       else
-        #t284.{core::Set::add}{Invariant}(3.14);
-    #t284.{core::Set::add}{Invariant}(null);
-  } =>#t284;
+        #t215.{core::Set::add}{Invariant}(3.14);
+    #t215.{core::Set::add}{Invariant}(null);
+  } =>#t215;
   core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t285 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t216 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t285.{core::Map::[]=}{Invariant}("bar", 42);
+        #t216.{core::Map::[]=}{Invariant}("bar", 42);
       else
-        #t285.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t285.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t285;
+        #t216.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t216.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t216;
   core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t286 = <core::num*>[];
+    final core::List<core::num*>* #t217 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t287 = :sync-for-iterator.{core::Iterator::current};
-          #t286.{core::List::add}{Invariant}(#t287);
-        }
-      }
-      else {
-        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t288 = :sync-for-iterator.{core::Iterator::current};
-          #t286.{core::List::add}{Invariant}(#t288);
-        }
-      }
-  } =>#t286;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t217.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t217.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t217;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t289 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t218 = new col::_CompactLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t290 = :sync-for-iterator.{core::Iterator::current};
-          #t289.{core::Set::add}{Invariant}(#t290);
-        }
-      }
-      else {
-        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t291 = :sync-for-iterator.{core::Iterator::current};
-          #t289.{core::Set::add}{Invariant}(#t291);
-        }
-      }
-    #t289.{core::Set::add}{Invariant}(null);
-  } =>#t289;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t218.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t218.{core::Set::addAll}{Invariant}(listDouble);
+    #t218.{core::Set::add}{Invariant}(null);
+  } =>#t218;
   core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t292 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t219 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::num*>* #t293 = :sync-for-iterator.{core::Iterator::current};
-          #t292.{core::Map::[]=}{Invariant}(#t293.{core::MapEntry::key}, #t293.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::num*>* #t220 = :sync-for-iterator.{core::Iterator::current};
+          #t219.{core::Map::[]=}{Invariant}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
         }
       }
       else {
         core::Iterator<core::MapEntry<core::String*, core::double*>>* :sync-for-iterator = mapStringDouble.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::num*>* #t294 = :sync-for-iterator.{core::Iterator::current};
-          #t292.{core::Map::[]=}{Invariant}(#t294.{core::MapEntry::key}, #t294.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::num*>* #t221 = :sync-for-iterator.{core::Iterator::current};
+          #t219.{core::Map::[]=}{Invariant}(#t221.{core::MapEntry::key}, #t221.{core::MapEntry::value});
         }
       }
-    #t292.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t292;
+    #t219.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t219;
   core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t295 = <dynamic>[];
+    final core::List<dynamic>* #t222 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t296 = :sync-for-iterator.{core::Iterator::current};
-          #t295.{core::List::add}{Invariant}(#t296);
-        }
-      }
-      else {
-        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t297 = :sync-for-iterator.{core::Iterator::current};
-          #t295.{core::List::add}{Invariant}(#t297);
-        }
-      }
-  } =>#t295;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t222.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t222.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t222;
   core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t298 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t223 = new col::_CompactLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t299 = :sync-for-iterator.{core::Iterator::current};
-          #t298.{core::Set::add}{Invariant}(#t299);
-        }
-      }
-      else {
-        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t300 = :sync-for-iterator.{core::Iterator::current};
-          #t298.{core::Set::add}{Invariant}(#t300);
-        }
-      }
-    #t298.{core::Set::add}{Invariant}(null);
-  } =>#t298;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t223.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t223.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t223.{core::Set::add}{Invariant}(null);
+  } =>#t223;
   core::Map<dynamic, dynamic>* map82 = block {
-    final core::Map<dynamic, dynamic>* #t301 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic>* #t224 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<dynamic, dynamic>* #t302 = :sync-for-iterator.{core::Iterator::current};
-          #t301.{core::Map::[]=}{Invariant}(#t302.{core::MapEntry::key}, #t302.{core::MapEntry::value});
+          final core::MapEntry<dynamic, dynamic>* #t225 = :sync-for-iterator.{core::Iterator::current};
+          #t224.{core::Map::[]=}{Invariant}(#t225.{core::MapEntry::key}, #t225.{core::MapEntry::value});
         }
       }
       else {
         core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<dynamic, dynamic>* #t303 = :sync-for-iterator.{core::Iterator::current};
-          #t301.{core::Map::[]=}{Invariant}(#t303.{core::MapEntry::key}, #t303.{core::MapEntry::value});
+          final core::MapEntry<dynamic, dynamic>* #t226 = :sync-for-iterator.{core::Iterator::current};
+          #t224.{core::Map::[]=}{Invariant}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
         }
       }
-    #t301.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t301;
+    #t224.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t224;
   core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t304 = <core::num*>[];
+    final core::List<core::num*>* #t227 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t304.{core::List::add}{Invariant}(42);
-      else {
-        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t305 = :sync-for-iterator.{core::Iterator::current};
-          #t304.{core::List::add}{Invariant}(#t305);
-        }
-      }
-  } =>#t304;
-  core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t306 = new col::_CompactLinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t307 = :sync-for-iterator.{core::Iterator::current};
-          #t306.{core::Set::add}{Invariant}(#t307);
-        }
-      }
+        #t227.{core::List::add}{Invariant}(42);
       else
-        #t306.{core::Set::add}{Invariant}(3.14);
-    #t306.{core::Set::add}{Invariant}(null);
-  } =>#t306;
+        #t227.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t227;
+  core::Set<core::num*>* set83 = block {
+    final core::Set<core::num*>* #t228 = new col::_CompactLinkedHashSet::•<core::num*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t228.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t228.{core::Set::add}{Invariant}(3.14);
+    #t228.{core::Set::add}{Invariant}(null);
+  } =>#t228;
   core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t308 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t229 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::num*>* #t309 = :sync-for-iterator.{core::Iterator::current};
-          #t308.{core::Map::[]=}{Invariant}(#t309.{core::MapEntry::key}, #t309.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::num*>* #t230 = :sync-for-iterator.{core::Iterator::current};
+          #t229.{core::Map::[]=}{Invariant}(#t230.{core::MapEntry::key}, #t230.{core::MapEntry::value});
         }
       }
       else
-        #t308.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t308.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t308;
+        #t229.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t229.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t229;
   core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t310 = <core::int*>[];
+    final core::List<core::int*>* #t231 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t310.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t310;
+      #t231.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+  } =>#t231;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t311 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t232 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t311.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t311.{core::Set::add}{Invariant}(null);
-  } =>#t311;
+      #t232.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t232.{core::Set::add}{Invariant}(null);
+  } =>#t232;
   core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t312 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t233 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t312.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t312.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t312;
+      #t233.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t233.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t233;
   core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t313 = <core::int*>[];
+    final core::List<core::int*>* #t234 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t314 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t235 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t315 = #t314 as{TypeError} core::int*;
-          #t313.{core::List::add}{Invariant}(#t315);
+          final core::int* #t236 = #t235 as{TypeError} core::int*;
+          #t234.{core::List::add}{Invariant}(#t236);
         }
       }
     }
-  } =>#t313;
+  } =>#t234;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t316 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t237 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t317 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t238 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t318 = #t317 as{TypeError} core::int*;
-          #t316.{core::Set::add}{Invariant}(#t318);
+          final core::int* #t239 = #t238 as{TypeError} core::int*;
+          #t237.{core::Set::add}{Invariant}(#t239);
         }
       }
     }
-    #t316.{core::Set::add}{Invariant}(null);
-  } =>#t316;
+    #t237.{core::Set::add}{Invariant}(null);
+  } =>#t237;
   core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t319 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t240 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t320 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<dynamic, dynamic>* #t241 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::String* #t321 = #t320.{core::MapEntry::key} as{TypeError} core::String*;
-          final core::int* #t322 = #t320.{core::MapEntry::value} as{TypeError} core::int*;
-          #t319.{core::Map::[]=}{Invariant}(#t321, #t322);
+          final core::String* #t242 = #t241.{core::MapEntry::key} as{TypeError} core::String*;
+          final core::int* #t243 = #t241.{core::MapEntry::value} as{TypeError} core::int*;
+          #t240.{core::Map::[]=}{Invariant}(#t242, #t243);
         }
       }
     }
-    #t319.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t319;
+    #t240.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t240;
   core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t323 = <core::int*>[];
-    for (final core::int* #t324 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t323.{core::List::add}{Invariant}(42);
-  } =>#t323;
+    final core::List<core::int*>* #t244 = <core::int*>[];
+    for (final core::int* #t245 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t244.{core::List::add}{Invariant}(42);
+  } =>#t244;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t325 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (final core::int* #t326 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t325.{core::Set::add}{Invariant}(42);
-  } =>#t325;
+    final core::Set<core::int*>* #t246 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (final core::int* #t247 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t246.{core::Set::add}{Invariant}(42);
+  } =>#t246;
   core::Map<core::String*, core::int*>* map100 = block {
-    final core::Map<core::String*, core::int*>* #t327 = <core::String*, core::int*>{};
-    for (final core::int* #t328 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t327.{core::Map::[]=}{Invariant}("bar", 42);
-  } =>#t327;
+    final core::Map<core::String*, core::int*>* #t248 = <core::String*, core::int*>{};
+    for (final core::int* #t249 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t248.{core::Map::[]=}{Invariant}("bar", 42);
+  } =>#t248;
   core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t329 = <core::int*>[];
+    final core::List<core::int*>* #t250 = <core::int*>[];
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
-        #t329.{core::List::add}{Invariant}(i);
+        #t250.{core::List::add}{Invariant}(i);
       }
     }
-  } =>#t329;
+  } =>#t250;
   core::Set<core::int*>* set110 = block {
-    final core::Set<core::int*>* #t330 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t251 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
-        #t330.{core::Set::add}{Invariant}(i);
+        #t251.{core::Set::add}{Invariant}(i);
       }
     }
-    #t330.{core::Set::add}{Invariant}(null);
-  } =>#t330;
+    #t251.{core::Set::add}{Invariant}(null);
+  } =>#t251;
   core::Map<core::String*, core::int*>* map110 = block {
-    final core::Map<core::String*, core::int*>* #t331 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t252 = <core::String*, core::int*>{};
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
-        #t331.{core::Map::[]=}{Invariant}("bar", i);
+        #t252.{core::Map::[]=}{Invariant}("bar", i);
       }
     }
-    #t331.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t331;
+    #t252.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t252;
   core::List<core::int*>* list120 = block {
-    final core::List<core::int*>* #t332 = <core::int*>[];
+    final core::List<core::int*>* #t253 = <core::int*>[];
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
-        #t332.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+        #t253.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
       }
     }
-  } =>#t332;
+  } =>#t253;
   core::Set<core::int*>* set120 = block {
-    final core::Set<core::int*>* #t333 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t254 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
-        #t333.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+        #t254.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
       }
     }
-    #t333.{core::Set::add}{Invariant}(null);
-  } =>#t333;
+    #t254.{core::Set::add}{Invariant}(null);
+  } =>#t254;
   core::Map<core::String*, core::int*>* map120 = block {
-    final core::Map<core::String*, core::int*>* #t334 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t255 = <core::String*, core::int*>{};
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
-        #t334.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
+        #t255.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
       }
     }
-    #t334.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t334;
+    #t255.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t255;
   core::List<core::int*>* list130 = block {
-    final core::List<core::int*>* #t335 = <core::int*>[];
+    final core::List<core::int*>* #t256 = <core::int*>[];
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t335.{core::List::add}{Invariant}(i);
-  } =>#t335;
+      #t256.{core::List::add}{Invariant}(i);
+  } =>#t256;
   core::Set<core::int*>* set130 = block {
-    final core::Set<core::int*>* #t336 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t257 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t336.{core::Set::add}{Invariant}(i);
-  } =>#t336;
+      #t257.{core::Set::add}{Invariant}(i);
+  } =>#t257;
   core::Map<core::int*, core::int*>* map130 = block {
-    final core::Map<core::int*, core::int*>* #t337 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t258 = <core::int*, core::int*>{};
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t337.{core::Map::[]=}{Invariant}(i, i);
-  } =>#t337;
+      #t258.{core::Map::[]=}{Invariant}(i, i);
+  } =>#t258;
 }
 static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -2356,91 +1960,81 @@
       #L1:
       {
         block {
-          final core::List<core::int*>* #t338 = <core::int*>[];
+          final core::List<core::int*>* #t259 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t338.{core::List::add}{Invariant}(let final<BottomType> #t339 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t259.{core::List::add}{Invariant}(let final<BottomType> #t260 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
                                             ^" in "bar" as{TypeError} core::int*);
-        } =>#t338;
+        } =>#t259;
         block {
-          final core::Set<core::int*>* #t340 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t261 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t340.{core::Set::add}{Invariant}(let final<BottomType> #t341 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t261.{core::Set::add}{Invariant}(let final<BottomType> #t262 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
                                             ^" in "bar" as{TypeError} core::int*);
-          #t340.{core::Set::add}{Invariant}(null);
-        } =>#t340;
+          #t261.{core::Set::add}{Invariant}(null);
+        } =>#t261;
         block {
-          final core::Map<core::int*, core::int*>* #t342 = <core::int*, core::int*>{};
+          final core::Map<core::int*, core::int*>* #t263 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t264 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t265 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                         ^" in "bar" as{TypeError} core::int*);
-          #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t266 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                                ^" in "baz" as{TypeError} core::int*, null);
-        } =>#t342;
+        } =>#t263;
         block {
-          final core::List<core::int*>* #t346 = <core::int*>[];
-          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::List<core::int*>* #t267 = <core::int*>[];
+          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+            #t267.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-            for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t348 = :sync-for-iterator.{core::Iterator::current};
-              #t346.{core::List::add}{Invariant}(#t348);
-            }
-          }
-        } =>#t346;
+                                                ^" in "bar" as{TypeError} core::int*]);
+        } =>#t267;
         block {
-          final core::Set<core::int*>* #t349 = new col::_CompactLinkedHashSet::•<core::int*>();
-          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t350 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::Set<core::int*>* #t269 = new col::_CompactLinkedHashSet::•<core::int*>();
+          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+            #t269.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t270 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-            for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t351 = :sync-for-iterator.{core::Iterator::current};
-              #t349.{core::Set::add}{Invariant}(#t351);
-            }
-          }
-          #t349.{core::Set::add}{Invariant}(null);
-        } =>#t349;
+                                                ^" in "bar" as{TypeError} core::int*]);
+          #t269.{core::Set::add}{Invariant}(null);
+        } =>#t269;
         block {
-          final core::Map<core::int*, core::int*>* #t352 = <core::int*, core::int*>{};
+          final core::Map<core::int*, core::int*>* #t271 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t272 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::MapEntry<core::int*, core::int*>* #t355 = :sync-for-iterator.{core::Iterator::current};
-              #t352.{core::Map::[]=}{Invariant}(#t355.{core::MapEntry::key}, #t355.{core::MapEntry::value});
+              final core::MapEntry<core::int*, core::int*>* #t274 = :sync-for-iterator.{core::Iterator::current};
+              #t271.{core::Map::[]=}{Invariant}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
             }
           }
-          #t352.{core::Map::[]=}{Invariant}(let final<BottomType> #t356 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          #t271.{core::Map::[]=}{Invariant}(let final<BottomType> #t275 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int*, null);
-        } =>#t352;
+        } =>#t271;
         block {
-          final core::List<core::int*>* #t357 = <core::int*>[];
+          final core::List<core::int*>* #t276 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t357.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            #t276.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...map];
                                                ^");
-        } =>#t357;
+        } =>#t276;
         block {
-          final core::Set<core::int*>* #t358 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t277 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t358.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            #t277.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null};
                                                ^");
-          #t358.{core::Set::add}{Invariant}(null);
-        } =>#t358;
+          #t277.{core::Set::add}{Invariant}(null);
+        } =>#t277;
         <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
@@ -2449,66 +2043,66 @@
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
                                                     ^": null};
         block {
-          final core::List<core::String*>* #t359 = <core::String*>[];
+          final core::List<core::String*>* #t278 = <core::String*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t359.{core::List::add}{Invariant}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+              #t278.{core::List::add}{Invariant}(let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                              ^" in 42 as{TypeError} core::String*);
             else
-              #t359.{core::List::add}{Invariant}(let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+              #t278.{core::List::add}{Invariant}(let final<BottomType> #t280 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                                      ^" in 3.14 as{TypeError} core::String*);
-        } =>#t359;
+        } =>#t278;
         block {
-          final core::Set<core::String*>* #t362 = new col::_CompactLinkedHashSet::•<core::String*>();
+          final core::Set<core::String*>* #t281 = new col::_CompactLinkedHashSet::•<core::String*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t362.{core::Set::add}{Invariant}(let final<BottomType> #t363 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+              #t281.{core::Set::add}{Invariant}(let final<BottomType> #t282 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                              ^" in 42 as{TypeError} core::String*);
             else
-              #t362.{core::Set::add}{Invariant}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+              #t281.{core::Set::add}{Invariant}(let final<BottomType> #t283 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                                      ^" in 3.14 as{TypeError} core::String*);
-          #t362.{core::Set::add}{Invariant}(null);
-        } =>#t362;
+          #t281.{core::Set::add}{Invariant}(null);
+        } =>#t281;
         block {
-          final core::Map<core::String*, core::String*>* #t365 = <core::String*, core::String*>{};
+          final core::Map<core::String*, core::String*>* #t284 = <core::String*, core::String*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t366 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+              #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t285 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                             ^" in 42 as{TypeError} core::String*);
             else
-              #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+              #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t286 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                                            ^" in 3.14 as{TypeError} core::String*);
-          #t365.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t365;
+          #t284.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t284;
         block {
-          final core::List<core::int*>* #t368 = <core::int*>[];
+          final core::List<core::int*>* #t287 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t368.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t287.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42];
                                                              ^");
             else
-              #t368.{core::List::add}{Invariant}(42);
-        } =>#t368;
+              #t287.{core::List::add}{Invariant}(42);
+        } =>#t287;
         block {
-          final core::Set<core::int*>* #t369 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t288 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t369.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t288.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null};
                                                              ^");
             else
-              #t369.{core::Set::add}{Invariant}(42);
-          #t369.{core::Set::add}{Invariant}(null);
-        } =>#t369;
+              #t288.{core::Set::add}{Invariant}(42);
+          #t288.{core::Set::add}{Invariant}(null);
+        } =>#t288;
         <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
@@ -2517,28 +2111,28 @@
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
                                                                      ^": null};
         block {
-          final core::List<core::int*>* #t370 = <core::int*>[];
+          final core::List<core::int*>* #t289 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t370.{core::List::add}{Invariant}(42);
+              #t289.{core::List::add}{Invariant}(42);
             else
-              #t370.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t289.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map];
                                                                      ^");
-        } =>#t370;
+        } =>#t289;
         block {
-          final core::Set<core::int*>* #t371 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t290 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t371.{core::Set::add}{Invariant}(42);
+              #t290.{core::Set::add}{Invariant}(42);
             else
-              #t371.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t290.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null};
                                                                      ^");
-          #t371.{core::Set::add}{Invariant}(null);
-        } =>#t371;
+          #t290.{core::Set::add}{Invariant}(null);
+        } =>#t290;
         <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
@@ -2548,140 +2142,140 @@
                                                                                     ^": null};
         final core::int* i = 0;
         block {
-          final core::List<core::int*>* #t372 = <core::int*>[];
+          final core::List<core::int*>* #t291 = <core::int*>[];
           {
             core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t373 = :sync-for-iterator.{core::Iterator::current};
+              final core::int* #t292 = :sync-for-iterator.{core::Iterator::current};
               {
                 invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
-                #t372.{core::List::add}{Invariant}(i);
+                #t291.{core::List::add}{Invariant}(i);
               }
             }
           }
-        } =>#t372;
+        } =>#t291;
         block {
-          final core::Set<core::int*>* #t374 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t293 = new col::_CompactLinkedHashSet::•<core::int*>();
           {
             core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t375 = :sync-for-iterator.{core::Iterator::current};
+              final core::int* #t294 = :sync-for-iterator.{core::Iterator::current};
               {
                 invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
-                #t374.{core::Set::add}{Invariant}(i);
+                #t293.{core::Set::add}{Invariant}(i);
               }
             }
           }
-          #t374.{core::Set::add}{Invariant}(null);
-        } =>#t374;
+          #t293.{core::Set::add}{Invariant}(null);
+        } =>#t293;
         block {
-          final core::Map<core::String*, core::int*>* #t376 = <core::String*, core::int*>{};
+          final core::Map<core::String*, core::int*>* #t295 = <core::String*, core::int*>{};
           {
             core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
+              final core::int* #t296 = :sync-for-iterator.{core::Iterator::current};
               {
                 invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
-                #t376.{core::Map::[]=}{Invariant}("bar", i);
+                #t295.{core::Map::[]=}{Invariant}("bar", i);
               }
             }
           }
-          #t376.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t376;
+          #t295.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t295;
         core::List<dynamic>* list10 = block {
-          final core::List<dynamic>* #t378 = <dynamic>[];
+          final core::List<dynamic>* #t297 = <dynamic>[];
           {
-            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t379 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t298 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               dynamic i = :sync-for-iterator.{core::Iterator::current};
-              #t378.{core::List::add}{Invariant}(i);
+              #t297.{core::List::add}{Invariant}(i);
             }
           }
-        } =>#t378;
+        } =>#t297;
         core::Set<dynamic>* set10 = block {
-          final core::Set<dynamic>* #t380 = new col::_CompactLinkedHashSet::•<dynamic>();
+          final core::Set<dynamic>* #t299 = new col::_CompactLinkedHashSet::•<dynamic>();
           {
-            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t381 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t300 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               dynamic i = :sync-for-iterator.{core::Iterator::current};
-              #t380.{core::Set::add}{Invariant}(i);
+              #t299.{core::Set::add}{Invariant}(i);
             }
           }
-          #t380.{core::Set::add}{Invariant}(null);
-        } =>#t380;
+          #t299.{core::Set::add}{Invariant}(null);
+        } =>#t299;
         core::Map<core::String*, dynamic>* map10 = block {
-          final core::Map<core::String*, dynamic>* #t382 = <core::String*, dynamic>{};
+          final core::Map<core::String*, dynamic>* #t301 = <core::String*, dynamic>{};
           {
-            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t302 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               dynamic i = :sync-for-iterator.{core::Iterator::current};
-              #t382.{core::Map::[]=}{Invariant}("bar", i);
+              #t301.{core::Map::[]=}{Invariant}("bar", i);
             }
           }
-          #t382.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t382;
+          #t301.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t301;
         core::List<core::int*>* list20 = block {
-          final core::List<core::int*>* #t384 = <core::int*>[];
+          final core::List<core::int*>* #t303 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t304 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t386 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t305 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
-              #t384.{core::List::add}{Invariant}(i);
+              #t303.{core::List::add}{Invariant}(i);
             }
           }
-        } =>#t384;
+        } =>#t303;
         core::Set<core::int*>* set20 = block {
-          final core::Set<core::int*>* #t387 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t306 = new col::_CompactLinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t388 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t307 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t308 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
-              #t387.{core::Set::add}{Invariant}(i);
+              #t306.{core::Set::add}{Invariant}(i);
             }
           }
-          #t387.{core::Set::add}{Invariant}(null);
-        } =>#t387;
+          #t306.{core::Set::add}{Invariant}(null);
+        } =>#t306;
         core::Map<core::String*, core::int*>* map20 = block {
-          final core::Map<core::String*, core::int*>* #t390 = <core::String*, core::int*>{};
+          final core::Map<core::String*, core::int*>* #t309 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t310 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t311 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
-              #t390.{core::Map::[]=}{Invariant}("bar", i);
+              #t309.{core::Map::[]=}{Invariant}("bar", i);
             }
           }
-          #t390.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t390;
-        final core::List<dynamic>* #t393 = <dynamic>[];
+          #t309.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t309;
+        final core::List<dynamic>* #t312 = <dynamic>[];
         {
-          asy::Stream<dynamic>* :stream = let final<BottomType> #t394 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t313 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2689,25 +2283,25 @@
           try
             #L2:
             while (true) {
-              dynamic #t395 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t396 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t314 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t315 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t393.{core::List::add}{Invariant}(i);
+                #t312.{core::List::add}{Invariant}(i);
               }
               else
                 break #L2;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t397 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t316 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
-        core::List<dynamic>* list30 = block {} =>#t393;
-        final core::Set<dynamic>* #t398 = new col::_CompactLinkedHashSet::•<dynamic>();
+        core::List<dynamic>* list30 = block {} =>#t312;
+        final core::Set<dynamic>* #t317 = new col::_CompactLinkedHashSet::•<dynamic>();
         {
-          asy::Stream<dynamic>* :stream = let final<BottomType> #t399 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t318 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2715,27 +2309,27 @@
           try
             #L3:
             while (true) {
-              dynamic #t400 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t401 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t319 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t320 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t398.{core::Set::add}{Invariant}(i);
+                #t317.{core::Set::add}{Invariant}(i);
               }
               else
                 break #L3;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t402 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t321 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Set<dynamic>* set30 = block {
-          #t398.{core::Set::add}{Invariant}(null);
-        } =>#t398;
-        final core::Map<core::String*, dynamic>* #t403 = <core::String*, dynamic>{};
+          #t317.{core::Set::add}{Invariant}(null);
+        } =>#t317;
+        final core::Map<core::String*, dynamic>* #t322 = <core::String*, dynamic>{};
         {
-          asy::Stream<dynamic>* :stream = let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2743,149 +2337,149 @@
           try
             #L4:
             while (true) {
-              dynamic #t405 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t406 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t324 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t325 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t403.{core::Map::[]=}{Invariant}("bar", i);
+                #t322.{core::Map::[]=}{Invariant}("bar", i);
               }
               else
                 break #L4;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t407 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t326 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Map<core::String*, dynamic>* map30 = block {
-          #t403.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t403;
-        final core::List<core::int*>* #t408 = <core::int*>[];
+          #t322.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t322;
+        final core::List<core::int*>* #t327 = <core::int*>[];
         {
-          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t409 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t328 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t410 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t329 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int*]);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
             #L5:
             while (true) {
-              dynamic #t411 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t412 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t330 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t331 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 core::int* i = :for-iterator.{asy::_StreamIterator::current};
-                #t408.{core::List::add}{Invariant}(i);
+                #t327.{core::List::add}{Invariant}(i);
               }
               else
                 break #L5;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t413 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t332 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
-        core::List<core::int*>* list40 = block {} =>#t408;
-        final core::Set<core::int*>* #t414 = new col::_CompactLinkedHashSet::•<core::int*>();
+        core::List<core::int*>* list40 = block {} =>#t327;
+        final core::Set<core::int*>* #t333 = new col::_CompactLinkedHashSet::•<core::int*>();
         {
-          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t415 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t334 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t335 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int*]);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
             #L6:
             while (true) {
-              dynamic #t417 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t418 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t336 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t337 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 core::int* i = :for-iterator.{asy::_StreamIterator::current};
-                #t414.{core::Set::add}{Invariant}(i);
+                #t333.{core::Set::add}{Invariant}(i);
               }
               else
                 break #L6;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t419 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t338 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Set<core::int*>* set40 = block {
-          #t414.{core::Set::add}{Invariant}(null);
-        } =>#t414;
-        final core::Map<core::String*, core::int*>* #t420 = <core::String*, core::int*>{};
+          #t333.{core::Set::add}{Invariant}(null);
+        } =>#t333;
+        final core::Map<core::String*, core::int*>* #t339 = <core::String*, core::int*>{};
         {
-          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t421 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t340 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t422 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t341 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int*]);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
             #L7:
             while (true) {
-              dynamic #t423 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t424 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t342 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t343 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 core::int* i = :for-iterator.{asy::_StreamIterator::current};
-                #t420.{core::Map::[]=}{Invariant}("bar", i);
+                #t339.{core::Map::[]=}{Invariant}("bar", i);
               }
               else
                 break #L7;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t425 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t344 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Map<core::String*, core::int*>* map40 = block {
-          #t420.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t420;
+          #t339.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t339;
         core::List<core::int*>* list50 = block {
-          final core::List<core::int*>* #t426 = <core::int*>[];
+          final core::List<core::int*>* #t345 = <core::int*>[];
           for (; ; )
-            #t426.{core::List::add}{Invariant}(42);
-        } =>#t426;
+            #t345.{core::List::add}{Invariant}(42);
+        } =>#t345;
         core::Set<core::int*>* set50 = block {
-          final core::Set<core::int*>* #t427 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t346 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (; ; )
-            #t427.{core::Set::add}{Invariant}(42);
-          #t427.{core::Set::add}{Invariant}(null);
-        } =>#t427;
+            #t346.{core::Set::add}{Invariant}(42);
+          #t346.{core::Set::add}{Invariant}(null);
+        } =>#t346;
         core::Map<core::String*, core::int*>* map50 = block {
-          final core::Map<core::String*, core::int*>* #t428 = <core::String*, core::int*>{};
+          final core::Map<core::String*, core::int*>* #t347 = <core::String*, core::int*>{};
           for (; ; )
-            #t428.{core::Map::[]=}{Invariant}("bar", 42);
-          #t428.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t428;
+            #t347.{core::Map::[]=}{Invariant}("bar", 42);
+          #t347.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t347;
         core::List<core::int*>* list60 = block {
-          final core::List<core::int*>* #t429 = <core::int*>[];
-          for (; let final<BottomType> #t430 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::List<core::int*>* #t348 = <core::int*>[];
+          for (; let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool*; )
-            #t429.{core::List::add}{Invariant}(42);
-        } =>#t429;
+            #t348.{core::List::add}{Invariant}(42);
+        } =>#t348;
         core::Set<core::int*>* set60 = block {
-          final core::Set<core::int*>* #t431 = new col::_CompactLinkedHashSet::•<core::int*>();
-          for (; let final<BottomType> #t432 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Set<core::int*>* #t350 = new col::_CompactLinkedHashSet::•<core::int*>();
+          for (; let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-            #t431.{core::Set::add}{Invariant}(42);
-          #t431.{core::Set::add}{Invariant}(null);
-        } =>#t431;
+            #t350.{core::Set::add}{Invariant}(42);
+          #t350.{core::Set::add}{Invariant}(null);
+        } =>#t350;
         core::Map<core::String*, core::int*>* map60 = block {
-          final core::Map<core::String*, core::int*>* #t433 = <core::String*, core::int*>{};
-          for (; let final<BottomType> #t434 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Map<core::String*, core::int*>* #t352 = <core::String*, core::int*>{};
+          for (; let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-            #t433.{core::Map::[]=}{Invariant}("bar", 42);
-          #t433.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t433;
+            #t352.{core::Map::[]=}{Invariant}("bar", 42);
+          #t352.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t352;
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
@@ -2893,7 +2487,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -2902,37 +2495,37 @@
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
   block {
-    final core::List<core::int*>* #t435 = <core::int*>[];
+    final core::List<core::int*>* #t354 = <core::int*>[];
     await for (core::int* i in stream)
-      #t435.{core::List::add}{Invariant}(i);
-  } =>#t435;
+      #t354.{core::List::add}{Invariant}(i);
+  } =>#t354;
   block {
-    final core::Set<core::int*>* #t436 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t355 = new col::_CompactLinkedHashSet::•<core::int*>();
     await for (core::int* i in stream)
-      #t436.{core::Set::add}{Invariant}(i);
-  } =>#t436;
+      #t355.{core::Set::add}{Invariant}(i);
+  } =>#t355;
   block {
-    final core::Map<core::String*, core::int*>* #t437 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t356 = <core::String*, core::int*>{};
     await for (core::int* i in stream)
-      #t437.{core::Map::[]=}{Invariant}("bar", i);
-  } =>#t437;
+      #t356.{core::Map::[]=}{Invariant}("bar", i);
+  } =>#t356;
 }
 static method testPromotion(self::A* a) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t438 = <core::int*>[];
+    final core::List<core::int*>* #t357 = <core::int*>[];
     if(a is self::B*)
-      #t438.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t438;
+      #t357.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t357;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t439 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t358 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(a is self::B*)
-      #t439.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t439;
+      #t358.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t358;
   core::Map<core::int*, core::int*>* map10 = block {
-    final core::Map<core::int*, core::int*>* #t440 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t359 = <core::int*, core::int*>{};
     if(a is self::B*)
-      #t440.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
-  } =>#t440;
+      #t359.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
+  } =>#t359;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect
index 02fa4fc..92572f2 100644
--- a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* a) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
   A(this.a);
-         ^", super core::Object::•()
+         ^"
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect
index 02fa4fc..92572f2 100644
--- a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* a) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
   A(this.a);
-         ^", super core::Object::•()
+         ^"
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
index caf60f4..8ab3f4c 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
@@ -20,7 +20,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -67,7 +66,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/expressions.dart b/pkg/front_end/testcases/general/expressions.dart
index 2cfc539..6cef03b 100644
--- a/pkg/front_end/testcases/general/expressions.dart
+++ b/pkg/front_end/testcases/general/expressions.dart
@@ -41,7 +41,7 @@
   print(i++);
   print(new Object());
   print(const Object());
-  print((new List<String>(2)).runtimeType);
+  print((new List<String>.filled(2, null)).runtimeType);
   foo(fisk: "Blorp gulp");
   f() {
     print("f was called");
diff --git a/pkg/front_end/testcases/general/expressions.dart.strong.expect b/pkg/front_end/testcases/general/expressions.dart.strong.expect
index 1c9f07b..90c7dca 100644
--- a/pkg/front_end/testcases/general/expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/general/expressions.dart.strong.expect
@@ -49,7 +49,7 @@
   core::print(let final core::int* #t3 = i in let final core::int* #t4 = i = #t3.{core::num::+}(1) in #t3);
   core::print(new core::Object::•());
   core::print(#C2);
-  core::print(core::List::•<core::String*>(2).{core::Object::runtimeType});
+  core::print(core::List::filled<core::String*>(2, null).{core::Object::runtimeType});
   self::foo(fisk: "Blorp gulp");
   function f() → Null {
     core::print("f was called");
diff --git a/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect b/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect
index 23d120e..97f034a 100644
--- a/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect
@@ -9,7 +9,6 @@
     final asy::_Future<self::TestMixin::T*>* :async_future = new asy::_Future::•<self::TestMixin::T*>();
     core::bool* :is_sync = false;
     FutureOr<self::TestMixin::T*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -45,7 +44,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -129,7 +127,6 @@
     final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
     core::bool* :is_sync = false;
     FutureOr<core::String*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -165,7 +162,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -200,7 +196,6 @@
     final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
     core::bool* :is_sync = false;
     FutureOr<core::String*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -236,7 +231,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect b/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
index a4ac3f4..f62a5eb 100644
--- a/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
@@ -31,7 +31,6 @@
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -49,7 +48,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -76,7 +74,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -94,7 +91,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect b/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect
index 6f96292..059106c 100644
--- a/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect
@@ -46,7 +46,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -64,7 +63,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -75,7 +73,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -93,7 +90,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -104,7 +100,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -122,7 +117,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -133,7 +127,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -151,7 +144,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -162,7 +154,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -180,7 +171,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -191,7 +181,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -209,7 +198,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -220,7 +208,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -238,7 +225,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -249,7 +235,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -267,7 +252,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -278,7 +262,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -296,7 +279,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -307,7 +289,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -325,7 +306,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -336,7 +316,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -354,7 +333,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -365,7 +343,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -383,7 +360,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -394,7 +370,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -435,7 +410,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect
index f255528..587242a 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect
@@ -361,37 +361,37 @@
   static set property8b = set self::Extension|property8b;
   static set property9 = set self::Extension|property9;
 }
-static method Extension|get#property1<T extends core::num* = core::num*, S extends self::Extension|get#property1::T* = core::num*>(final core::int* #this) → core::int*
+static method Extension|get#property1<T extends core::num* = core::num*, S extends self::Extension|get#property1::T* = core::num*>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#property1<T extends core::num* = core::num*, S extends self::Extension|set#property1::T* = core::num*>(final core::int* #this, core::int* i) → void
+static method Extension|set#property1<T extends core::num* = core::num*, S extends self::Extension|set#property1::T* = core::num*>(lowered final core::int* #this, core::int* i) → void
   ;
-static method Extension|get#property2a<T extends core::num* = core::num*, S extends self::Extension|get#property2a::T* = core::num*>(final core::int* #this) → core::num*
+static method Extension|get#property2a<T extends core::num* = core::num*, S extends self::Extension|get#property2a::T* = core::num*>(lowered final core::int* #this) → core::num*
   ;
-static method Extension|set#property2a<T extends core::num* = core::num*, S extends self::Extension|set#property2a::T* = core::num*>(final core::int* #this, core::int* i) → void
+static method Extension|set#property2a<T extends core::num* = core::num*, S extends self::Extension|set#property2a::T* = core::num*>(lowered final core::int* #this, core::int* i) → void
   ;
-static method Extension|get#property2b<T extends core::num* = core::num*, S extends self::Extension|get#property2b::T* = core::num*>(final core::int* #this) → core::int*
+static method Extension|get#property2b<T extends core::num* = core::num*, S extends self::Extension|get#property2b::T* = core::num*>(lowered final core::int* #this) → core::int*
   ;
-static method Extension|set#property2b<T extends core::num* = core::num*, S extends self::Extension|set#property2b::T* = core::num*>(final core::int* #this, core::num* i) → void
+static method Extension|set#property2b<T extends core::num* = core::num*, S extends self::Extension|set#property2b::T* = core::num*>(lowered final core::int* #this, core::num* i) → void
   ;
-static method Extension|get#property3<T extends core::num* = core::num*, S extends self::Extension|get#property3::T* = core::num*>(final core::int* #this) → core::String*
+static method Extension|get#property3<T extends core::num* = core::num*, S extends self::Extension|get#property3::T* = core::num*>(lowered final core::int* #this) → core::String*
   ;
-static method Extension|set#property3<T extends core::num* = core::num*, S extends self::Extension|set#property3::T* = core::num*>(final core::int* #this, core::int* i) → void
+static method Extension|set#property3<T extends core::num* = core::num*, S extends self::Extension|set#property3::T* = core::num*>(lowered final core::int* #this, core::int* i) → void
   ;
-static method Extension|get#property4<T extends core::num* = core::num*, S extends self::Extension|get#property4::T* = core::num*>(final core::int* #this) → self::Extension|get#property4::S*
+static method Extension|get#property4<T extends core::num* = core::num*, S extends self::Extension|get#property4::T* = core::num*>(lowered final core::int* #this) → self::Extension|get#property4::S*
   ;
-static method Extension|set#property4<T extends core::num* = core::num*, S extends self::Extension|set#property4::T* = core::num*>(final core::int* #this, self::Extension|set#property4::S* i) → void
+static method Extension|set#property4<T extends core::num* = core::num*, S extends self::Extension|set#property4::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property4::S* i) → void
   ;
-static method Extension|get#property5a<T extends core::num* = core::num*, S extends self::Extension|get#property5a::T* = core::num*>(final core::int* #this) → self::Extension|get#property5a::S*
+static method Extension|get#property5a<T extends core::num* = core::num*, S extends self::Extension|get#property5a::T* = core::num*>(lowered final core::int* #this) → self::Extension|get#property5a::S*
   ;
-static method Extension|set#property5a<T extends core::num* = core::num*, S extends self::Extension|set#property5a::T* = core::num*>(final core::int* #this, self::Extension|set#property5a::T* i) → void
+static method Extension|set#property5a<T extends core::num* = core::num*, S extends self::Extension|set#property5a::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property5a::T* i) → void
   ;
-static method Extension|get#property5b<T extends core::num* = core::num*, S extends self::Extension|get#property5b::T* = core::num*>(final core::int* #this) → self::Extension|get#property5b::T*
+static method Extension|get#property5b<T extends core::num* = core::num*, S extends self::Extension|get#property5b::T* = core::num*>(lowered final core::int* #this) → self::Extension|get#property5b::T*
   ;
-static method Extension|set#property5b<T extends core::num* = core::num*, S extends self::Extension|set#property5b::T* = core::num*>(final core::int* #this, self::Extension|set#property5b::S* i) → void
+static method Extension|set#property5b<T extends core::num* = core::num*, S extends self::Extension|set#property5b::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property5b::S* i) → void
   ;
-static method Extension|get#property6<T extends core::num* = core::num*, S extends self::Extension|get#property6::T* = core::num*>(final core::int* #this) → core::String*
+static method Extension|get#property6<T extends core::num* = core::num*, S extends self::Extension|get#property6::T* = core::num*>(lowered final core::int* #this) → core::String*
   ;
-static method Extension|set#property6<T extends core::num* = core::num*, S extends self::Extension|set#property6::T* = core::num*>(final core::int* #this, self::Extension|set#property6::S* i) → void
+static method Extension|set#property6<T extends core::num* = core::num*, S extends self::Extension|set#property6::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property6::S* i) → void
   ;
 static get Extension|property7() → core::int*
   ;
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect
index 0ab82ac..1515fe4 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect
@@ -378,36 +378,36 @@
   static set property8b = set self::Extension|property8b;
   static set property9 = set self::Extension|property9;
 }
-static method Extension|get#property1<T extends core::num* = core::num*, S extends self::Extension|get#property1::T* = core::num*>(final core::int* #this) → core::int*
+static method Extension|get#property1<T extends core::num* = core::num*, S extends self::Extension|get#property1::T* = core::num*>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#property1<T extends core::num* = core::num*, S extends self::Extension|set#property1::T* = core::num*>(final core::int* #this, core::int* i) → void {}
-static method Extension|get#property2a<T extends core::num* = core::num*, S extends self::Extension|get#property2a::T* = core::num*>(final core::int* #this) → core::num*
+static method Extension|set#property1<T extends core::num* = core::num*, S extends self::Extension|set#property1::T* = core::num*>(lowered final core::int* #this, core::int* i) → void {}
+static method Extension|get#property2a<T extends core::num* = core::num*, S extends self::Extension|get#property2a::T* = core::num*>(lowered final core::int* #this) → core::num*
   return 0;
-static method Extension|set#property2a<T extends core::num* = core::num*, S extends self::Extension|set#property2a::T* = core::num*>(final core::int* #this, core::int* i) → void {}
-static method Extension|get#property2b<T extends core::num* = core::num*, S extends self::Extension|get#property2b::T* = core::num*>(final core::int* #this) → core::int*
+static method Extension|set#property2a<T extends core::num* = core::num*, S extends self::Extension|set#property2a::T* = core::num*>(lowered final core::int* #this, core::int* i) → void {}
+static method Extension|get#property2b<T extends core::num* = core::num*, S extends self::Extension|get#property2b::T* = core::num*>(lowered final core::int* #this) → core::int*
   return 0;
-static method Extension|set#property2b<T extends core::num* = core::num*, S extends self::Extension|set#property2b::T* = core::num*>(final core::int* #this, core::num* i) → void {}
-static method Extension|get#property3<T extends core::num* = core::num*, S extends self::Extension|get#property3::T* = core::num*>(final core::int* #this) → core::String*
+static method Extension|set#property2b<T extends core::num* = core::num*, S extends self::Extension|set#property2b::T* = core::num*>(lowered final core::int* #this, core::num* i) → void {}
+static method Extension|get#property3<T extends core::num* = core::num*, S extends self::Extension|get#property3::T* = core::num*>(lowered final core::int* #this) → core::String*
   return "";
-static method Extension|set#property3<T extends core::num* = core::num*, S extends self::Extension|set#property3::T* = core::num*>(final core::int* #this, core::int* i) → void {}
-static method Extension|get#property4<T extends core::num* = core::num*, S extends self::Extension|get#property4::T* = core::num*>(final core::int* #this) → self::Extension|get#property4::S*
+static method Extension|set#property3<T extends core::num* = core::num*, S extends self::Extension|set#property3::T* = core::num*>(lowered final core::int* #this, core::int* i) → void {}
+static method Extension|get#property4<T extends core::num* = core::num*, S extends self::Extension|get#property4::T* = core::num*>(lowered final core::int* #this) → self::Extension|get#property4::S*
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be assigned to a variable of type 'S'.
   S get property4 => 0; // ok
                      ^" in 0 as{TypeError} <BottomType>;
-static method Extension|set#property4<T extends core::num* = core::num*, S extends self::Extension|set#property4::T* = core::num*>(final core::int* #this, self::Extension|set#property4::S* i) → void {}
-static method Extension|get#property5a<T extends core::num* = core::num*, S extends self::Extension|get#property5a::T* = core::num*>(final core::int* #this) → self::Extension|get#property5a::S*
+static method Extension|set#property4<T extends core::num* = core::num*, S extends self::Extension|set#property4::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property4::S* i) → void {}
+static method Extension|get#property5a<T extends core::num* = core::num*, S extends self::Extension|get#property5a::T* = core::num*>(lowered final core::int* #this) → self::Extension|get#property5a::S*
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/getter_vs_setter_type.dart:136:23: Error: A value of type 'int' can't be assigned to a variable of type 'S'.
   S get property5a => 0; // ok
                       ^" in 0 as{TypeError} <BottomType>;
-static method Extension|set#property5a<T extends core::num* = core::num*, S extends self::Extension|set#property5a::T* = core::num*>(final core::int* #this, self::Extension|set#property5a::T* i) → void {}
-static method Extension|get#property5b<T extends core::num* = core::num*, S extends self::Extension|get#property5b::T* = core::num*>(final core::int* #this) → self::Extension|get#property5b::T*
+static method Extension|set#property5a<T extends core::num* = core::num*, S extends self::Extension|set#property5a::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property5a::T* i) → void {}
+static method Extension|get#property5b<T extends core::num* = core::num*, S extends self::Extension|get#property5b::T* = core::num*>(lowered final core::int* #this) → self::Extension|get#property5b::T*
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/getter_vs_setter_type.dart:139:23: Error: A value of type 'int' can't be assigned to a variable of type 'T'.
   T get property5b => 0; // ok
                       ^" in 0 as{TypeError} <BottomType>;
-static method Extension|set#property5b<T extends core::num* = core::num*, S extends self::Extension|set#property5b::T* = core::num*>(final core::int* #this, self::Extension|set#property5b::S* i) → void {}
-static method Extension|get#property6<T extends core::num* = core::num*, S extends self::Extension|get#property6::T* = core::num*>(final core::int* #this) → core::String*
+static method Extension|set#property5b<T extends core::num* = core::num*, S extends self::Extension|set#property5b::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property5b::S* i) → void {}
+static method Extension|get#property6<T extends core::num* = core::num*, S extends self::Extension|get#property6::T* = core::num*>(lowered final core::int* #this) → core::String*
   return "";
-static method Extension|set#property6<T extends core::num* = core::num*, S extends self::Extension|set#property6::T* = core::num*>(final core::int* #this, self::Extension|set#property6::S* i) → void {}
+static method Extension|set#property6<T extends core::num* = core::num*, S extends self::Extension|set#property6::T* = core::num*>(lowered final core::int* #this, self::Extension|set#property6::S* i) → void {}
 static get Extension|property7() → core::int*
   return 0;
 static set Extension|property7(core::int* value) → void {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart b/pkg/front_end/testcases/general/infer_equals.dart
new file mode 100644
index 0000000..5ef9b93
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+class Class {
+  var field;
+
+  operator ==(o) {
+    if (o is! Class) return false;
+    return field == o.field;
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.outline.expect b/pkg/front_end/testcases/general/infer_equals.dart.outline.expect
new file mode 100644
index 0000000..1e4df77
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.outline.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field;
+  synthetic constructor •() → self::Class*
+    ;
+  operator ==(dynamic o) → core::bool*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.strong.expect b/pkg/front_end/testcases/general/infer_equals.dart.strong.expect
new file mode 100644
index 0000000..f1fea95
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.strong.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  operator ==(dynamic o) → core::bool* {
+    if(!(o is self::Class*))
+      return false;
+    return this.{self::Class::field}.{core::Object::==}(o.field);
+  }
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/general/infer_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..f1fea95
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  operator ==(dynamic o) → core::bool* {
+    if(!(o is self::Class*))
+      return false;
+    return this.{self::Class::field}.{core::Object::==}(o.field);
+  }
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..f3b19e7
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class {
+  var field;
+  operator ==(o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..00f7d50
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class {
+  operator ==(o) {}
+  var field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.outline.expect b/pkg/front_end/testcases/general/invalid_operator.dart.outline.expect
index 7cd9550..9ee095c 100644
--- a/pkg/front_end/testcases/general/invalid_operator.dart.outline.expect
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.outline.expect
@@ -563,28 +563,28 @@
 // pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   operator ==() => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
 // pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
 //   operator ==(a, b) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
 // pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   operator ==({a}) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
 // pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
 //   operator ==<T>(a) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
@@ -592,7 +592,7 @@
 // Change to a subtype of 'bool'.
 //   operator ==<T>(a) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.strong.expect b/pkg/front_end/testcases/general/invalid_operator.dart.strong.expect
index 6e9b140..1c0ff49 100644
--- a/pkg/front_end/testcases/general/invalid_operator.dart.strong.expect
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.strong.expect
@@ -563,28 +563,28 @@
 // pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   operator ==() => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
 // pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
 //   operator ==(a, b) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
 // pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   operator ==({a}) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
 // pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
 //   operator ==<T>(a) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
@@ -592,7 +592,7 @@
 // Change to a subtype of 'bool'.
 //   operator ==<T>(a) => true;
 //            ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
diff --git a/pkg/front_end/testcases/general/issue38938.dart.strong.expect b/pkg/front_end/testcases/general/issue38938.dart.strong.expect
index ffb21f8..2ed9c3f 100644
--- a/pkg/front_end/testcases/general/issue38938.dart.strong.expect
+++ b/pkg/front_end/testcases/general/issue38938.dart.strong.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* v) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue38938.dart:8:10: Error: Can't use 'v' because it is declared more than once.
   A(this.v);
-         ^", super core::Object::•()
+         ^"
     ;
   constructor second() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect
index ffb21f8..2ed9c3f 100644
--- a/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* v) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue38938.dart:8:10: Error: Can't use 'v' because it is declared more than once.
   A(this.v);
-         ^", super core::Object::•()
+         ^"
     ;
   constructor second() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/general/issue40242.dart.outline.expect b/pkg/front_end/testcases/general/issue40242.dart.outline.expect
index e0984be..09336b0 100644
--- a/pkg/front_end/testcases/general/issue40242.dart.outline.expect
+++ b/pkg/front_end/testcases/general/issue40242.dart.outline.expect
@@ -20,9 +20,9 @@
   method errors = self::E|errors;
   tearoff errors = self::E|get#errors;
 }
-static method E|errors(final self::C* #this) → dynamic
+static method E|errors(lowered final self::C* #this) → dynamic
   ;
-static method E|get#errors(final self::C* #this) → () →* dynamic
+static method E|get#errors(lowered final self::C* #this) → () →* dynamic
   return () → dynamic => self::E|errors(#this);
 static method errors() → dynamic
   ;
diff --git a/pkg/front_end/testcases/general/issue40242.dart.strong.expect b/pkg/front_end/testcases/general/issue40242.dart.strong.expect
index 69fa368..69ece96a 100644
--- a/pkg/front_end/testcases/general/issue40242.dart.strong.expect
+++ b/pkg/front_end/testcases/general/issue40242.dart.strong.expect
@@ -44,12 +44,12 @@
   method errors = self::E|errors;
   tearoff errors = self::E|get#errors;
 }
-static method E|errors(final self::C* #this) → dynamic {
+static method E|errors(lowered final self::C* #this) → dynamic {
   invalid-expression "pkg/front_end/testcases/general/issue40242.dart:9:5: Error: Can't assign to 'this'.
     this = new C();
     ^^^^";
 }
-static method E|get#errors(final self::C* #this) → () →* dynamic
+static method E|get#errors(lowered final self::C* #this) → () →* dynamic
   return () → dynamic => self::E|errors(#this);
 static method errors() → dynamic {
   final self::C* c1 = new self::C::•();
diff --git a/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect
index 69fa368..69ece96a 100644
--- a/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect
@@ -44,12 +44,12 @@
   method errors = self::E|errors;
   tearoff errors = self::E|get#errors;
 }
-static method E|errors(final self::C* #this) → dynamic {
+static method E|errors(lowered final self::C* #this) → dynamic {
   invalid-expression "pkg/front_end/testcases/general/issue40242.dart:9:5: Error: Can't assign to 'this'.
     this = new C();
     ^^^^";
 }
-static method E|get#errors(final self::C* #this) → () →* dynamic
+static method E|get#errors(lowered final self::C* #this) → () →* dynamic
   return () → dynamic => self::E|errors(#this);
 static method errors() → dynamic {
   final self::C* c1 = new self::C::•();
diff --git a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
index d7e7eca..58436b7 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -45,7 +44,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -56,7 +54,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -76,7 +73,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -92,4 +88,4 @@
 Extra constant evaluation status:
 Evaluated: MethodInvocation @ org-dartlang-testcase:///issue40662.dart:8:10 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///issue40662.dart:9:10 -> IntConstant(-1)
-Extra constant evaluation: evaluated: 101, effectively constant: 2
+Extra constant evaluation: evaluated: 95, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/issue40982.dart b/pkg/front_end/testcases/general/issue40982.dart
new file mode 100644
index 0000000..ed06fc3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  const A();
+}
+
+mixin B {
+  static const int value = 1;
+}
+
+class C1 extends A with B {
+  const C1();
+}
+
+class C2 = A with B;
+
+class C3 extends C2 {
+  const C3();
+}
+
+mixin D {
+  int value = 1;
+}
+
+class E1 extends A with D {
+  const E1();
+}
+
+class E2 = A with D;
+
+class E3 extends E2 {
+  const E3();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.outline.expect b/pkg/front_end/testcases/general/issue40982.dart.outline.expect
new file mode 100644
index 0000000..642ab52
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.outline.expect
@@ -0,0 +1,98 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40982.dart:28:9: Error: A constant constructor can't call a non-constant super constructor.
+//   const E1();
+//         ^
+//
+// pkg/front_end/testcases/general/issue40982.dart:34:9: Error: A constant constructor can't call a non-constant super constructor.
+//   const E3();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class B extends core::Object /*isMixinDeclaration*/  {
+  static const field core::int* value = 1;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _C1&A&B = self::A with self::B /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C1&A&B*
+    : super self::A::•()
+    ;
+}
+class C1 extends self::_C1&A&B /*hasConstConstructor*/  {
+  const constructor •() → self::C1*
+    : super self::_C1&A&B::•()
+    ;
+}
+class C2 = self::A with self::B /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::C2*
+    : super self::A::•()
+    ;
+}
+class C3 extends self::C2 /*hasConstConstructor*/  {
+  const constructor •() → self::C3*
+    : super self::C2::•()
+    ;
+}
+abstract class D extends core::Object /*isMixinDeclaration*/  {
+  field core::int* value;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _E1&A&D = self::A with self::D /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_E1&A&D*
+    : super self::A::•()
+    ;
+}
+class E1 extends self::_E1&A&D /*hasConstConstructor*/  {
+  const constructor •() → self::E1*
+    : super self::_E1&A&D::•()
+    ;
+}
+class E2 = self::A with self::D {
+  synthetic constructor •() → self::E2*
+    : super self::A::•()
+    ;
+}
+class E3 extends self::E2 /*hasConstConstructor*/  {
+  const constructor •() → self::E3*
+    : super self::E2::•()
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue40982.dart.strong.expect b/pkg/front_end/testcases/general/issue40982.dart.strong.expect
new file mode 100644
index 0000000..d5bdf49
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.strong.expect
@@ -0,0 +1,101 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40982.dart:28:9: Error: A constant constructor can't call a non-constant super constructor.
+//   const E1();
+//         ^
+//
+// pkg/front_end/testcases/general/issue40982.dart:34:9: Error: A constant constructor can't call a non-constant super constructor.
+//   const E3();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class B extends core::Object /*isMixinDeclaration*/  {
+  static const field core::int* value = #C1;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _C1&A&B = self::A with self::B /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_C1&A&B*
+    : super self::A::•()
+    ;
+}
+class C1 extends self::_C1&A&B /*hasConstConstructor*/  {
+  const constructor •() → self::C1*
+    : super self::_C1&A&B::•()
+    ;
+}
+class C2 = self::A with self::B /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::C2*
+    : super self::A::•()
+    ;
+}
+class C3 extends self::C2 /*hasConstConstructor*/  {
+  const constructor •() → self::C3*
+    : super self::C2::•()
+    ;
+}
+abstract class D extends core::Object /*isMixinDeclaration*/  {
+  field core::int* value = 1;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _E1&A&D = self::A with self::D /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_E1&A&D*
+    : super self::A::•()
+    ;
+}
+class E1 extends self::_E1&A&D /*hasConstConstructor*/  {
+  const constructor •() → self::E1*
+    : super self::_E1&A&D::•()
+    ;
+}
+class E2 = self::A with self::D {
+  synthetic constructor •() → self::E2*
+    : super self::A::•()
+    ;
+}
+class E3 extends self::E2 /*hasConstConstructor*/  {
+  const constructor •() → self::E3*
+    : super self::E2::•()
+    ;
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = 1
+}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40982.dart.strong.transformed.expect
new file mode 100644
index 0000000..a903a15
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.strong.transformed.expect
@@ -0,0 +1,145 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40982.dart:28:9: Error: A constant constructor can't call a non-constant super constructor.
+//   const E1();
+//         ^
+//
+// pkg/front_end/testcases/general/issue40982.dart:34:9: Error: A constant constructor can't call a non-constant super constructor.
+//   const E3();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class B extends core::Object /*isMixinDeclaration*/  {
+  static const field core::int* value = #C1;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _C1&A&B extends self::A implements self::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  static const field core::int* value = #C1;
+  const synthetic constructor •() → self::_C1&A&B*
+    : super self::A::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class C1 extends self::_C1&A&B /*hasConstConstructor*/  {
+  const constructor •() → self::C1*
+    : super self::_C1&A&B::•()
+    ;
+}
+class C2 extends self::A implements self::B /*isEliminatedMixin,hasConstConstructor*/  {
+  static const field core::int* value = #C1;
+  const synthetic constructor •() → self::C2*
+    : super self::A::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class C3 extends self::C2 /*hasConstConstructor*/  {
+  const constructor •() → self::C3*
+    : super self::C2::•()
+    ;
+}
+abstract class D extends core::Object /*isMixinDeclaration*/  {
+  field core::int* value = 1;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _E1&A&D extends self::A implements self::D /*isAnonymousMixin,isEliminatedMixin*/  {
+  field core::int* value = 1;
+  synthetic constructor •() → self::_E1&A&D*
+    : super self::A::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class E1 extends self::_E1&A&D /*hasConstConstructor*/  {
+  const constructor •() → self::E1*
+    : super self::_E1&A&D::•()
+    ;
+}
+class E2 extends self::A implements self::D /*isEliminatedMixin*/  {
+  field core::int* value = 1;
+  synthetic constructor •() → self::E2*
+    : super self::A::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class E3 extends self::E2 /*hasConstConstructor*/  {
+  const constructor •() → self::E3*
+    : super self::E2::•()
+    ;
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = 1
+}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40982.dart.textual_outline.expect
new file mode 100644
index 0000000..d0c04bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.textual_outline.expect
@@ -0,0 +1,33 @@
+class A {
+  const A();
+}
+
+mixin B {
+  static const int value = 1;
+}
+
+class C1 extends A with B {
+  const C1();
+}
+
+class C2 = A with B;
+
+class C3 extends C2 {
+  const C3();
+}
+
+mixin D {
+  int value = 1;
+}
+
+class E1 extends A with D {
+  const E1();
+}
+
+class E2 = A with D;
+
+class E3 extends E2 {
+  const E3();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40982.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eeaccee
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+class A {
+  const A();
+}
+
+class C1 extends A with B {
+  const C1();
+}
+
+class C2 = A with B;
+
+class C3 extends C2 {
+  const C3();
+}
+
+class E1 extends A with D {
+  const E1();
+}
+
+class E2 = A with D;
+
+class E3 extends E2 {
+  const E3();
+}
+
+main() {}
+mixin B {
+  static const int value = 1;
+}
+mixin D {
+  int value = 1;
+}
diff --git a/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect
index 5550a8f..3144af6 100644
--- a/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect
@@ -27,7 +27,6 @@
     final asy::_Future<core::List<dynamic>*>* :async_future = new asy::_Future::•<core::List<dynamic>*>();
     core::bool* :is_sync = false;
     FutureOr<core::List<dynamic>*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -45,7 +44,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/general/issue43290.dart b/pkg/front_end/testcases/general/issue43290.dart
index bdd22fa..14acc31 100644
--- a/pkg/front_end/testcases/general/issue43290.dart
+++ b/pkg/front_end/testcases/general/issue43290.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 class Class {
   final int length;
 
diff --git a/pkg/front_end/testcases/general/issue43290.dart.strong.expect b/pkg/front_end/testcases/general/issue43290.dart.strong.expect
index 053b66cc..436e5dd 100644
--- a/pkg/front_end/testcases/general/issue43290.dart.strong.expect
+++ b/pkg/front_end/testcases/general/issue43290.dart.strong.expect
@@ -2,45 +2,45 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/issue43290.dart:11:25: Error: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:15:25: Error: Not a constant expression.
 //     const Class(length: length);
 //                         ^^^^^^
 //
-// pkg/front_end/testcases/general/issue43290.dart:19:15: Error: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:23:15: Error: Not a constant expression.
 //     const a = length;
 //               ^^^^^^
 //
-// pkg/front_end/testcases/general/issue43290.dart:7:11: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:11:11: Error: Constant evaluation error:
 //     const Class(length: this.length);
 //           ^
-// pkg/front_end/testcases/general/issue43290.dart:7:30: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:11:30: Context: Not a constant expression.
 //     const Class(length: this.length);
 //                              ^
 //
-// pkg/front_end/testcases/general/issue43290.dart:11:11: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:15:11: Error: Constant evaluation error:
 //     const Class(length: length);
 //           ^
-// pkg/front_end/testcases/general/issue43290.dart:11:25: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:15:25: Context: Not a constant expression.
 //     const Class(length: length);
 //                         ^
 //
-// pkg/front_end/testcases/general/issue43290.dart:15:20: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:19:20: Error: Constant evaluation error:
 //     const a = this.length;
 //                    ^
-// pkg/front_end/testcases/general/issue43290.dart:15:20: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:19:20: Context: Not a constant expression.
 //     const a = this.length;
 //                    ^
-// pkg/front_end/testcases/general/issue43290.dart:15:11: Context: While analyzing:
+// pkg/front_end/testcases/general/issue43290.dart:19:11: Context: While analyzing:
 //     const a = this.length;
 //           ^
 //
-// pkg/front_end/testcases/general/issue43290.dart:19:15: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:23:15: Error: Constant evaluation error:
 //     const a = length;
 //               ^
-// pkg/front_end/testcases/general/issue43290.dart:19:15: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:23:15: Context: Not a constant expression.
 //     const a = length;
 //               ^
-// pkg/front_end/testcases/general/issue43290.dart:19:11: Context: While analyzing:
+// pkg/front_end/testcases/general/issue43290.dart:23:11: Context: While analyzing:
 //     const a = length;
 //           ^
 //
diff --git a/pkg/front_end/testcases/general/issue43290.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue43290.dart.strong.transformed.expect
index 053b66cc..436e5dd 100644
--- a/pkg/front_end/testcases/general/issue43290.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue43290.dart.strong.transformed.expect
@@ -2,45 +2,45 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/issue43290.dart:11:25: Error: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:15:25: Error: Not a constant expression.
 //     const Class(length: length);
 //                         ^^^^^^
 //
-// pkg/front_end/testcases/general/issue43290.dart:19:15: Error: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:23:15: Error: Not a constant expression.
 //     const a = length;
 //               ^^^^^^
 //
-// pkg/front_end/testcases/general/issue43290.dart:7:11: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:11:11: Error: Constant evaluation error:
 //     const Class(length: this.length);
 //           ^
-// pkg/front_end/testcases/general/issue43290.dart:7:30: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:11:30: Context: Not a constant expression.
 //     const Class(length: this.length);
 //                              ^
 //
-// pkg/front_end/testcases/general/issue43290.dart:11:11: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:15:11: Error: Constant evaluation error:
 //     const Class(length: length);
 //           ^
-// pkg/front_end/testcases/general/issue43290.dart:11:25: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:15:25: Context: Not a constant expression.
 //     const Class(length: length);
 //                         ^
 //
-// pkg/front_end/testcases/general/issue43290.dart:15:20: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:19:20: Error: Constant evaluation error:
 //     const a = this.length;
 //                    ^
-// pkg/front_end/testcases/general/issue43290.dart:15:20: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:19:20: Context: Not a constant expression.
 //     const a = this.length;
 //                    ^
-// pkg/front_end/testcases/general/issue43290.dart:15:11: Context: While analyzing:
+// pkg/front_end/testcases/general/issue43290.dart:19:11: Context: While analyzing:
 //     const a = this.length;
 //           ^
 //
-// pkg/front_end/testcases/general/issue43290.dart:19:15: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/issue43290.dart:23:15: Error: Constant evaluation error:
 //     const a = length;
 //               ^
-// pkg/front_end/testcases/general/issue43290.dart:19:15: Context: Not a constant expression.
+// pkg/front_end/testcases/general/issue43290.dart:23:15: Context: Not a constant expression.
 //     const a = length;
 //               ^
-// pkg/front_end/testcases/general/issue43290.dart:19:11: Context: While analyzing:
+// pkg/front_end/testcases/general/issue43290.dart:23:11: Context: While analyzing:
 //     const a = length;
 //           ^
 //
diff --git a/pkg/front_end/testcases/general/issue43363.dart b/pkg/front_end/testcases/general/issue43363.dart
new file mode 100644
index 0000000..86d91ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class E {
+  final int x;
+  final int y;
+  E() : this.named(),
+        this.x = 1;
+        this.y = 2;
+
+  E.named() : this.x = 5,
+              this.y = 6;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue43363.dart.outline.expect b/pkg/front_end/testcases/general/issue43363.dart.outline.expect
new file mode 100644
index 0000000..e44f548
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.outline.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:9: Error: Expected a class member, but got 'this'.
+//         this.y = 2;
+//         ^^^^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:13: Error: Expected a class member, but got '.'.
+//         this.y = 2;
+//             ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//         this.y = 2;
+//              ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: 'y' is already declared in this scope.
+//         this.y = 2;
+//              ^
+// pkg/front_end/testcases/general/issue43363.dart:7:13: Context: Previous declaration of 'y'.
+//   final int y;
+//             ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int* x;
+  final field core::int* y;
+  constructor •() → self::E*
+    ;
+  constructor named() → self::E*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue43363.dart.strong.expect b/pkg/front_end/testcases/general/issue43363.dart.strong.expect
new file mode 100644
index 0000000..b4cfb49
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.strong.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:9: Error: Expected a class member, but got 'this'.
+//         this.y = 2;
+//         ^^^^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:13: Error: Expected a class member, but got '.'.
+//         this.y = 2;
+//             ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//         this.y = 2;
+//              ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: 'y' is already declared in this scope.
+//         this.y = 2;
+//              ^
+// pkg/front_end/testcases/general/issue43363.dart:7:13: Context: Previous declaration of 'y'.
+//   final int y;
+//             ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+//         this.x = 1;
+//                ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+//               this.y = 6;
+//                    ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int* x;
+  final field core::int* y = null;
+  constructor •() → self::E*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+        this.x = 1;
+               ^", this self::E::named()
+    ;
+  constructor named() → self::E*
+    : self::E::x = 5, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+              this.y = 6;
+                   ^"
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue43363.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue43363.dart.strong.transformed.expect
new file mode 100644
index 0000000..b4cfb49
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.strong.transformed.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:9: Error: Expected a class member, but got 'this'.
+//         this.y = 2;
+//         ^^^^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:13: Error: Expected a class member, but got '.'.
+//         this.y = 2;
+//             ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+//         this.y = 2;
+//              ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: 'y' is already declared in this scope.
+//         this.y = 2;
+//              ^
+// pkg/front_end/testcases/general/issue43363.dart:7:13: Context: Previous declaration of 'y'.
+//   final int y;
+//             ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+//         this.x = 1;
+//                ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+//               this.y = 6;
+//                    ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int* x;
+  final field core::int* y = null;
+  constructor •() → self::E*
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+        this.x = 1;
+               ^", this self::E::named()
+    ;
+  constructor named() → self::E*
+    : self::E::x = 5, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+              this.y = 6;
+                   ^"
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue43363.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue43363.dart.textual_outline.expect
new file mode 100644
index 0000000..f2bf39e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class E {
+  final int x;
+  final int y;
+  E() : this.named(), this.x = 1;
+  this.
+  y = 2;
+  E.named() : this.x = 5, this.y = 6;
+}
+main() {}
diff --git a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect
index bb66d2f..72d4454 100644
--- a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -32,7 +31,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.strong.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.strong.expect
index bd5bf0d..807a6b5 100644
--- a/pkg/front_end/testcases/general/null_aware_spread.dart.strong.expect
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.strong.expect
@@ -5,33 +5,30 @@
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
   list = block {
-    final core::List<core::String*>* #t1 = <core::String*>[];
-    #t1.{core::List::add}{Invariant}("foo");
+    final core::List<core::String*>* #t1 = <core::String*>["foo"];
     final core::Iterable<core::String*>* #t2 = list;
     if(!#t2.{core::Object::==}(null))
-      for (final core::String* #t3 in #t2)
-        #t1.{core::List::add}{Invariant}(#t3);
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
 }
 static method nullAwareSetSpread(core::Set<core::String*>* set) → dynamic {
   set = block {
-    final core::Set<core::String*>* #t4 = col::LinkedHashSet::•<core::String*>();
-    #t4.{core::Set::add}{Invariant}("foo");
-    final core::Iterable<core::String*>* #t5 = set;
-    if(!#t5.{core::Object::==}(null))
-      for (final core::String* #t6 in #t5)
-        #t4.{core::Set::add}{Invariant}(#t6);
-  } =>#t4;
+    final core::Set<core::String*>* #t3 = col::LinkedHashSet::•<core::String*>();
+    #t3.{core::Set::add}{Invariant}("foo");
+    final core::Iterable<core::String*>* #t4 = set;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::Set::addAll}{Invariant}(#t4);
+  } =>#t3;
 }
 static method nullAwareMapSpread(core::Map<core::int*, core::String*>* map) → dynamic {
   map = block {
-    final core::Map<core::int*, core::String*>* #t7 = <core::int*, core::String*>{};
-    #t7.{core::Map::[]=}{Invariant}(0, "foo");
-    final core::Map<core::int*, core::String*>* #t8 = map;
-    if(!#t8.{core::Object::==}(null))
-      for (final core::MapEntry<core::int*, core::String*>* #t9 in #t8.{core::Map::entries})
-        #t7.{core::Map::[]=}{Invariant}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
-  } =>#t7;
+    final core::Map<core::int*, core::String*>* #t5 = <core::int*, core::String*>{};
+    #t5.{core::Map::[]=}{Invariant}(0, "foo");
+    final core::Map<core::int*, core::String*>* #t6 = map;
+    if(!#t6.{core::Object::==}(null))
+      for (final core::MapEntry<core::int*, core::String*>* #t7 in #t6.{core::Map::entries})
+        #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
+  } =>#t5;
 }
 static method main() → dynamic {
   self::nullAwareListSpread(null);
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect
index 67a6d44..e5e1b00 100644
--- a/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.strong.transformed.expect
@@ -5,45 +5,34 @@
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
   list = block {
-    final core::List<core::String*>* #t1 = <core::String*>[];
-    #t1.{core::List::add}{Invariant}("foo");
+    final core::List<core::String*>* #t1 = <core::String*>["foo"];
     final core::Iterable<core::String*>* #t2 = list;
-    if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String* #t3 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t3);
-      }
-    }
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
 }
 static method nullAwareSetSpread(core::Set<core::String*>* set) → dynamic {
   set = block {
-    final core::Set<core::String*>* #t4 = new col::_CompactLinkedHashSet::•<core::String*>();
-    #t4.{core::Set::add}{Invariant}("foo");
-    final core::Iterable<core::String*>* #t5 = set;
-    if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = #t5.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String* #t6 = :sync-for-iterator.{core::Iterator::current};
-        #t4.{core::Set::add}{Invariant}(#t6);
-      }
-    }
-  } =>#t4;
+    final core::Set<core::String*>* #t3 = new col::_CompactLinkedHashSet::•<core::String*>();
+    #t3.{core::Set::add}{Invariant}("foo");
+    final core::Iterable<core::String*>* #t4 = set;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::Set::addAll}{Invariant}(#t4);
+  } =>#t3;
 }
 static method nullAwareMapSpread(core::Map<core::int*, core::String*>* map) → dynamic {
   map = block {
-    final core::Map<core::int*, core::String*>* #t7 = <core::int*, core::String*>{};
-    #t7.{core::Map::[]=}{Invariant}(0, "foo");
-    final core::Map<core::int*, core::String*>* #t8 = map;
-    if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::String*>>* :sync-for-iterator = #t8.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int*, core::String*>* #t5 = <core::int*, core::String*>{};
+    #t5.{core::Map::[]=}{Invariant}(0, "foo");
+    final core::Map<core::int*, core::String*>* #t6 = map;
+    if(!#t6.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int*, core::String*>>* :sync-for-iterator = #t6.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int*, core::String*>* #t9 = :sync-for-iterator.{core::Iterator::current};
-        #t7.{core::Map::[]=}{Invariant}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
+        final core::MapEntry<core::int*, core::String*>* #t7 = :sync-for-iterator.{core::Iterator::current};
+        #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
       }
     }
-  } =>#t7;
+  } =>#t5;
 }
 static method main() → dynamic {
   self::nullAwareListSpread(null);
diff --git a/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect b/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect
index 30085d7..442d3ae 100644
--- a/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
     final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
     core::bool* :is_sync = false;
     FutureOr<void>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -27,7 +26,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -53,7 +51,6 @@
     final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
     core::bool* :is_sync = false;
     FutureOr<void>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -68,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -90,7 +86,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -116,7 +111,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.strong.expect b/pkg/front_end/testcases/general/spread_collection.dart.strong.expect
index 45566e9..049bc9f 100644
--- a/pkg/front_end/testcases/general/spread_collection.dart.strong.expect
+++ b/pkg/front_end/testcases/general/spread_collection.dart.strong.expect
@@ -13,35 +13,30 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
-    for (final core::int* #t2 in <core::int*>[2])
-      #t1.{core::List::add}{Invariant}(#t2);
-    final core::Iterable<core::int*>* #t3 = <core::int*>[3];
-    if(!#t3.{core::Object::==}(null))
-      for (final core::int* #t4 in #t3)
-        #t1.{core::List::add}{Invariant}(#t4);
+    final core::List<core::int*>* #t1 = <core::int*>[1];
+    #t1.{core::List::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t2 = <core::int*>[3];
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
   final core::Map<core::int*, core::int*>* aMap = block {
-    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
-    #t5.{core::Map::[]=}{Invariant}(1, 1);
-    for (final core::MapEntry<core::int*, core::int*>* #t6 in <core::int*, core::int*>{2: 2}.{core::Map::entries})
-      #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
-    final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
-    if(!#t7.{core::Object::==}(null))
-      for (final core::MapEntry<core::int*, core::int*>* #t8 in #t7.{core::Map::entries})
-        #t5.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-  } =>#t5;
+    final core::Map<core::int*, core::int*>* #t3 = <core::int*, core::int*>{};
+    #t3.{core::Map::[]=}{Invariant}(1, 1);
+    for (final core::MapEntry<core::int*, core::int*>* #t4 in <core::int*, core::int*>{2: 2}.{core::Map::entries})
+      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{3: 3};
+    if(!#t5.{core::Object::==}(null))
+      for (final core::MapEntry<core::int*, core::int*>* #t6 in #t5.{core::Map::entries})
+        #t3.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
+  } =>#t3;
   final core::Set<core::int*>* aSet = block {
-    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
-    #t9.{core::Set::add}{Invariant}(1);
-    for (final core::int* #t10 in <core::int*>[2])
-      #t9.{core::Set::add}{Invariant}(#t10);
-    final core::Iterable<core::int*>* #t11 = <core::int*>[3];
-    if(!#t11.{core::Object::==}(null))
-      for (final core::int* #t12 in #t11)
-        #t9.{core::Set::add}{Invariant}(#t12);
-  } =>#t9;
+    final core::Set<core::int*>* #t7 = col::LinkedHashSet::•<core::int*>();
+    #t7.{core::Set::add}{Invariant}(1);
+    #t7.{core::Set::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t8 = <core::int*>[3];
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::Set::addAll}{Invariant}(#t8);
+  } =>#t7;
   final dynamic aSetOrMap = invalid-expression "pkg/front_end/testcases/general/spread_collection.dart:21:21: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   final aSetOrMap = {...foo()};
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect
index d6d75a5..ff4b46b 100644
--- a/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection.dart.strong.transformed.expect
@@ -13,62 +13,39 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t2 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t2);
-      }
-    }
-    final core::Iterable<core::int*>* #t3 = <core::int*>[3];
-    if(!#t3.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t3.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t4 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t4);
-      }
-    }
+    final core::List<core::int*>* #t1 = <core::int*>[1];
+    #t1.{core::List::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t2 = <core::int*>[3];
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
   final core::Map<core::int*, core::int*>* aMap = block {
-    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
-    #t5.{core::Map::[]=}{Invariant}(1, 1);
+    final core::Map<core::int*, core::int*>* #t3 = <core::int*, core::int*>{};
+    #t3.{core::Map::[]=}{Invariant}(1, 1);
     {
       core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{2: 2}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::int*, core::int*>* #t4 = :sync-for-iterator.{core::Iterator::current};
+        #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+      }
+    }
+    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{3: 3};
+    if(!#t5.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = #t5.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t6 = :sync-for-iterator.{core::Iterator::current};
-        #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
+        #t3.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
       }
     }
-    final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
-    if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = #t7.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int*, core::int*>* #t8 = :sync-for-iterator.{core::Iterator::current};
-        #t5.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-      }
-    }
-  } =>#t5;
+  } =>#t3;
   final core::Set<core::int*>* aSet = block {
-    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t9.{core::Set::add}{Invariant}(1);
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::Set::add}{Invariant}(#t10);
-      }
-    }
-    final core::Iterable<core::int*>* #t11 = <core::int*>[3];
-    if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t11.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::Set::add}{Invariant}(#t12);
-      }
-    }
-  } =>#t9;
+    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t7.{core::Set::add}{Invariant}(1);
+    #t7.{core::Set::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t8 = <core::int*>[3];
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::Set::addAll}{Invariant}(#t8);
+  } =>#t7;
   final dynamic aSetOrMap = invalid-expression "pkg/front_end/testcases/general/spread_collection.dart:21:21: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   final aSetOrMap = {...foo()};
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect
index e2acef4..65bf53e 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect
@@ -110,177 +110,153 @@
   core::Map<core::int*, core::num*>* mapIntNum = <core::int*, core::num*>{42: 42};
   core::List<core::num*>* listNum = <core::num*>[42];
   core::List<dynamic>* lhs10 = block {
-    final core::List<dynamic>* #t1 = <dynamic>[];
-    for (final dynamic #t2 in <dynamic>[])
-      #t1.{core::List::add}{Invariant}(#t2);
+    final core::List<dynamic>* #t1 = core::List::of<dynamic>(<dynamic>[]);
   } =>#t1;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t3 = col::LinkedHashSet::•<dynamic>();
-    for (final dynamic #t4 in <dynamic>[])
-      #t3.{core::Set::add}{Invariant}(#t4);
-  } =>#t3;
+    final core::Set<dynamic>* #t2 = col::LinkedHashSet::of<dynamic>(<dynamic>[]);
+  } =>#t2;
   core::Map<dynamic, dynamic>* map10 = block {
+    final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t4 in <dynamic, dynamic>{}.{core::Map::entries})
+      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+  } =>#t3;
+  core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     for (final core::MapEntry<dynamic, dynamic>* #t6 in <dynamic, dynamic>{}.{core::Map::entries})
       #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
   } =>#t5;
-  core::Map<dynamic, dynamic>* map10ambiguous = block {
-    final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t8 in <dynamic, dynamic>{}.{core::Map::entries})
-      #t7.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-  } =>#t7;
   core::List<core::int*>* lhs20 = block {
-    final core::List<core::int*>* #t9 = <core::int*>[];
-    for (final core::int* #t10 in spread)
-      #t9.{core::List::add}{Invariant}(#t10);
-  } =>#t9;
+    final core::List<core::int*>* #t7 = core::List::of<core::int*>(spread);
+  } =>#t7;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t12 in spread)
-      #t11.{core::Set::add}{Invariant}(#t12);
-    #t11.{core::Set::add}{Invariant}(42);
-  } =>#t11;
+    final core::Set<core::int*>* #t8 = col::LinkedHashSet::of<core::int*>(spread);
+    #t8.{core::Set::add}{Invariant}(42);
+  } =>#t8;
   core::Set<core::int*>* set20ambiguous = block {
-    final core::Set<core::int*>* #t13 = col::LinkedHashSet::•<core::int*>();
-    for (final dynamic #t14 in spread) {
-      final core::int* #t15 = #t14 as{TypeError} core::int*;
-      #t13.{core::Set::add}{Invariant}(#t15);
+    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t10 in spread) {
+      final core::int* #t11 = #t10 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t11);
     }
-  } =>#t13;
+  } =>#t9;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t17 in mapSpread.{core::Map::entries})
-      #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-    #t16.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t16;
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t13 in mapSpread.{core::Map::entries})
+      #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
+    #t12.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t12;
   core::Map<core::String*, core::int*>* map20ambiguous = block {
-    final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t19 in mapSpread.{core::Map::entries})
-      #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
-  } =>#t18;
+    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t15 in mapSpread.{core::Map::entries})
+      #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+  } =>#t14;
   core::List<dynamic>* lhs21 = block {
-    final core::List<dynamic>* #t20 = <dynamic>[];
-    for (final dynamic #t21 in (spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t20.{core::List::add}{Invariant}(#t21);
-  } =>#t20;
+    final core::List<dynamic>* #t16 = core::List::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t16;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t22 = col::LinkedHashSet::•<dynamic>();
-    for (final dynamic #t23 in (spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t22.{core::Set::add}{Invariant}(#t23);
-    #t22.{core::Set::add}{Invariant}(42);
-  } =>#t22;
+    final core::Set<dynamic>* #t17 = col::LinkedHashSet::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t17.{core::Set::add}{Invariant}(42);
+  } =>#t17;
   core::Map<dynamic, dynamic>* map21 = block {
-    final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t25 in ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
-      #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
-    #t24.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t24;
+    final core::Map<dynamic, dynamic>* #t18 = <dynamic, dynamic>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t19 in ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
+      #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
+    #t18.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t18;
   dynamic map21ambiguous = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:64:28: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   dynamic map21ambiguous = {...(mapSpread as dynamic)};
                            ^";
   core::List<core::int*>* lhs22 = block {
-    final core::List<core::int*>* #t26 = <core::int*>[];
-    for (final core::int* #t27 in <core::int*>[])
-      #t26.{core::List::add}{Invariant}(#t27);
-  } =>#t26;
+    final core::List<core::int*>* #t20 = core::List::of<core::int*>(<core::int*>[]);
+  } =>#t20;
   core::Set<core::int*>* set22 = block {
-    final core::Set<core::int*>* #t28 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t29 in <core::int*>[])
-      #t28.{core::Set::add}{Invariant}(#t29);
-    #t28.{core::Set::add}{Invariant}(42);
-  } =>#t28;
+    final core::Set<core::int*>* #t21 = col::LinkedHashSet::of<core::int*>(<core::int*>[]);
+    #t21.{core::Set::add}{Invariant}(42);
+  } =>#t21;
   core::Set<core::int*>* set22ambiguous = block {
-    final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
-    for (final dynamic #t31 in <core::int*>[]) {
-      final core::int* #t32 = #t31 as{TypeError} core::int*;
-      #t30.{core::Set::add}{Invariant}(#t32);
+    final core::Set<core::int*>* #t22 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t23 in <core::int*>[]) {
+      final core::int* #t24 = #t23 as{TypeError} core::int*;
+      #t22.{core::Set::add}{Invariant}(#t24);
     }
-  } =>#t30;
+  } =>#t22;
   core::Map<core::String*, core::int*>* map22 = block {
-    final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t34 in <core::String*, core::int*>{}.{core::Map::entries})
-      #t33.{core::Map::[]=}{Invariant}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
-  } =>#t33;
+    final core::Map<core::String*, core::int*>* #t25 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t26 in <core::String*, core::int*>{}.{core::Map::entries})
+      #t25.{core::Map::[]=}{Invariant}(#t26.{core::MapEntry::key}, #t26.{core::MapEntry::value});
+  } =>#t25;
   core::List<core::List<core::int*>*>* lhs23 = block {
-    final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
-    for (final core::List<core::int*>* #t36 in <core::List<core::int*>*>[<core::int*>[]])
-      #t35.{core::List::add}{Invariant}(#t36);
-  } =>#t35;
+    final core::List<core::List<core::int*>*>* #t27 = core::List::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t27;
   core::Set<core::List<core::int*>*>* set23 = block {
-    final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (final core::List<core::int*>* #t38 in <core::List<core::int*>*>[<core::int*>[]])
-      #t37.{core::Set::add}{Invariant}(#t38);
-    #t37.{core::Set::add}{Invariant}(<core::int*>[42]);
-  } =>#t37;
+    final core::Set<core::List<core::int*>*>* #t28 = col::LinkedHashSet::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+    #t28.{core::Set::add}{Invariant}(<core::int*>[42]);
+  } =>#t28;
   core::Set<core::List<core::int*>*>* set23ambiguous = block {
-    final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (final dynamic #t40 in <core::List<core::int*>*>[<core::int*>[]]) {
-      final core::List<core::int*>* #t41 = #t40 as{TypeError} core::List<core::int*>*;
-      #t39.{core::Set::add}{Invariant}(#t41);
+    final core::Set<core::List<core::int*>*>* #t29 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (final dynamic #t30 in <core::List<core::int*>*>[<core::int*>[]]) {
+      final core::List<core::int*>* #t31 = #t30 as{TypeError} core::List<core::int*>*;
+      #t29.{core::Set::add}{Invariant}(#t31);
     }
-  } =>#t39;
+  } =>#t29;
   core::Map<core::String*, core::List<core::int*>*>* map23 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
-    for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 in <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries})
-      #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-  } =>#t42;
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
+    for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 in <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries})
+      #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
+  } =>#t32;
   dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:96:28: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
   dynamic map24ambiguous = {...spread, ...mapSpread};
                            ^";
-  core::int* lhs30 = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+  core::int* lhs30 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
  - 'List' is from 'dart:core'.
   int lhs30 = /*@ typeArgs=int* */ [...spread];
                                    ^" in ( block {
-    final core::List<core::int*>* #t45 = <core::int*>[];
-    for (final core::int* #t46 in spread)
-      #t45.{core::List::add}{Invariant}(#t46);
-  } =>#t45) as{TypeError} core::int*;
-  core::int* set30 = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t35 = core::List::of<core::int*>(spread);
+  } =>#t35) as{TypeError} core::int*;
+  core::int* set30 = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
   int set30 = /*@ typeArgs=int* */ {...spread, 42};
                                    ^" in ( block {
-    final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t49 in spread)
-      #t48.{core::Set::add}{Invariant}(#t49);
-    #t48.{core::Set::add}{Invariant}(42);
-  } =>#t48) as{TypeError} core::int*;
-  core::int* set30ambiguous = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t37 = col::LinkedHashSet::of<core::int*>(spread);
+    #t37.{core::Set::add}{Invariant}(42);
+  } =>#t37) as{TypeError} core::int*;
+  core::int* set30ambiguous = let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
       {...spread};
       ^" in ( block {
-    final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
-    for (final dynamic #t52 in spread) {
-      final core::int* #t53 = #t52 as{TypeError} core::int*;
-      #t51.{core::Set::add}{Invariant}(#t53);
+    final core::Set<core::int*>* #t39 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t40 in spread) {
+      final core::int* #t41 = #t40 as{TypeError} core::int*;
+      #t39.{core::Set::add}{Invariant}(#t41);
     }
-  } =>#t51) as{TypeError} core::int*;
-  core::int* map30 = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+  } =>#t39) as{TypeError} core::int*;
+  core::int* map30 = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread, \"baz\": 42};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t56 in mapSpread.{core::Map::entries})
-      #t55.{core::Map::[]=}{Invariant}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
-    #t55.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t55) as{TypeError} core::int*;
-  core::int* map30ambiguous = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String*, core::int*>* #t43 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t44 in mapSpread.{core::Map::entries})
+      #t43.{core::Map::[]=}{Invariant}(#t44.{core::MapEntry::key}, #t44.{core::MapEntry::value});
+    #t43.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t43) as{TypeError} core::int*;
+  core::int* map30ambiguous = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t59 in mapSpread.{core::Map::entries})
-      #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
-  } =>#t58) as{TypeError} core::int*;
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t47 in mapSpread.{core::Map::entries})
+      #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
+  } =>#t46) as{TypeError} core::int*;
   core::List<dynamic>* lhs40 = <dynamic>[invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:111:38: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   List<dynamic> lhs40 = <dynamic>[...notSpreadInt];
                                      ^"];
   core::Set<dynamic>* set40 = block {
-    final core::Set<dynamic>* #t60 = col::LinkedHashSet::•<dynamic>();
-    #t60.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:113:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t48 = col::LinkedHashSet::•<dynamic>();
+    #t48.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:113:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set40 = <dynamic>{...notSpreadInt};
                                     ^");
-  } =>#t60;
+  } =>#t48;
   core::Map<dynamic, dynamic>* map40 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:115:55: Error: Unexpected type 'int' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map40 = <dynamic, dynamic>{...notSpreadInt};
                                                       ^": null};
@@ -288,11 +264,11 @@
   List<dynamic> lhs50 = <dynamic>[...notSpreadFunction];
                                      ^"];
   core::Set<dynamic>* set50 = block {
-    final core::Set<dynamic>* #t61 = col::LinkedHashSet::•<dynamic>();
-    #t61.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:119:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t49 = col::LinkedHashSet::•<dynamic>();
+    #t49.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:119:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set50 = <dynamic>{...notSpreadFunction};
                                     ^");
-  } =>#t61;
+  } =>#t49;
   core::Map<dynamic, dynamic>* map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:121:55: Error: Unexpected type 'int Function()' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map50 = <dynamic, dynamic>{...notSpreadFunction};
                                                       ^": null};
@@ -300,11 +276,11 @@
   List<String> lhs60 = <String>[...spread];
                                    ^"];
   core::Set<core::String*>* set60 = block {
-    final core::Set<core::String*>* #t62 = col::LinkedHashSet::•<core::String*>();
-    #t62.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:125:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
+    final core::Set<core::String*>* #t50 = col::LinkedHashSet::•<core::String*>();
+    #t50.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:125:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{...spread};
                                   ^");
-  } =>#t62;
+  } =>#t50;
   core::Map<core::int*, core::int*>* map60 = <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:127:39: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
   Map<int, int> map60 = <int, int>{...mapSpread};
                                       ^": null};
@@ -315,92 +291,90 @@
   List<int> lhs70 = <int>[...null];
                              ^"];
   core::Set<core::int*>* set70 = block {
-    final core::Set<core::int*>* #t63 = col::LinkedHashSet::•<core::int*>();
-    #t63.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:133:29: Error: Can't spread a value with static type 'Null'.
+    final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
+    #t51.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:133:29: Error: Can't spread a value with static type 'Null'.
   Set<int> set70 = <int>{...null};
                             ^");
-  } =>#t63;
+  } =>#t51;
   core::Set<dynamic>* set71ambiguous = block {
-    final core::Set<dynamic>* #t64 = col::LinkedHashSet::•<dynamic>();
-    #t64.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:137:8: Error: Expected ',' before this.
+    final core::Set<dynamic>* #t52 = col::LinkedHashSet::•<dynamic>();
+    #t52.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:137:8: Error: Expected ',' before this.
     ...null,
        ^");
-    for (final dynamic #t65 in <dynamic>[]) {
-      final dynamic #t66 = #t65 as{TypeError} dynamic;
-      #t64.{core::Set::add}{Invariant}(#t66);
+    for (final dynamic #t53 in <dynamic>[]) {
+      final dynamic #t54 = #t53 as{TypeError} dynamic;
+      #t52.{core::Set::add}{Invariant}(#t54);
     }
-  } =>#t64;
+  } =>#t52;
   core::Map<core::String*, core::int*>* map70 = <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:142:45: Error: Can't spread a value with static type 'Null'.
   Map<String, int> map70 = <String, int>{...null};
                                             ^": null};
   core::List<core::int*>* lhs80 = block {
-    final core::List<core::int*>* #t67 = <core::int*>[];
-    final core::Iterable<core::int*>* #t68 = null;
-    if(!#t68.{core::Object::==}(null))
-      for (final core::int* #t69 in #t68)
-        #t67.{core::List::add}{Invariant}(#t69);
-  } =>#t67;
+    final core::List<core::int*>* #t55 = <core::int*>[];
+    final core::Iterable<core::int*>* #t56 = null;
+    if(!#t56.{core::Object::==}(null))
+      #t55.{core::List::addAll}{Invariant}(#t56);
+  } =>#t55;
   core::Set<core::int*>* set80 = block {
-    final core::Set<core::int*>* #t70 = col::LinkedHashSet::•<core::int*>();
-    final core::Iterable<core::int*>* #t71 = null;
-    if(!#t71.{core::Object::==}(null))
-      for (final core::int* #t72 in #t71)
-        #t70.{core::Set::add}{Invariant}(#t72);
-  } =>#t70;
+    final core::Set<core::int*>* #t57 = col::LinkedHashSet::•<core::int*>();
+    final core::Iterable<core::int*>* #t58 = null;
+    if(!#t58.{core::Object::==}(null))
+      #t57.{core::Set::addAll}{Invariant}(#t58);
+  } =>#t57;
   core::Set<dynamic>* set81ambiguous = block {
-    final core::Set<dynamic>* #t73 = col::LinkedHashSet::•<dynamic>();
-    final core::Iterable<dynamic>* #t74 = null;
-    if(!#t74.{core::Object::==}(null))
-      for (final dynamic #t75 in #t74) {
-        final dynamic #t76 = #t75 as{TypeError} dynamic;
-        #t73.{core::Set::add}{Invariant}(#t76);
+    final core::Set<dynamic>* #t59 = col::LinkedHashSet::•<dynamic>();
+    final core::Iterable<dynamic>* #t60 = null;
+    if(!#t60.{core::Object::==}(null))
+      for (final dynamic #t61 in #t60) {
+        final dynamic #t62 = #t61 as{TypeError} dynamic;
+        #t59.{core::Set::add}{Invariant}(#t62);
       }
-    for (final dynamic #t77 in <dynamic>[]) {
-      final dynamic #t78 = #t77 as{TypeError} dynamic;
-      #t73.{core::Set::add}{Invariant}(#t78);
+    for (final dynamic #t63 in <dynamic>[]) {
+      final dynamic #t64 = #t63 as{TypeError} dynamic;
+      #t59.{core::Set::add}{Invariant}(#t64);
+    }
+  } =>#t59;
+  core::Map<core::String*, core::int*>* map80 = block {
+    final core::Map<core::String*, core::int*>* #t65 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t66 = null;
+    if(!#t66.{core::Object::==}(null))
+      for (final core::MapEntry<core::String*, core::int*>* #t67 in #t66.{core::Map::entries})
+        #t65.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+  } =>#t65;
+  core::Map<core::String*, core::int*>* map90 = block {
+    final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t69 in self::bar<core::String*, core::int*>().{core::Map::entries})
+      #t68.{core::Map::[]=}{Invariant}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
+  } =>#t68;
+  core::List<core::int*>* list100 = block {
+    final core::List<core::int*>* #t70 = <core::int*>[];
+    for (final dynamic #t71 in listNum) {
+      final core::int* #t72 = #t71 as{TypeError} core::int*;
+      #t70.{core::List::add}{Invariant}(#t72);
+    }
+  } =>#t70;
+  core::Map<core::num*, core::int*>* map100 = block {
+    final core::Map<core::num*, core::int*>* #t73 = <core::num*, core::int*>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t74 in mapIntNum.{core::Map::entries}) {
+      final core::num* #t75 = #t74.{core::MapEntry::key} as{TypeError} core::num*;
+      final core::int* #t76 = #t74.{core::MapEntry::value} as{TypeError} core::int*;
+      #t73.{core::Map::[]=}{Invariant}(#t75, #t76);
     }
   } =>#t73;
-  core::Map<core::String*, core::int*>* map80 = block {
-    final core::Map<core::String*, core::int*>* #t79 = <core::String*, core::int*>{};
-    final core::Map<core::String*, core::int*>* #t80 = null;
-    if(!#t80.{core::Object::==}(null))
-      for (final core::MapEntry<core::String*, core::int*>* #t81 in #t80.{core::Map::entries})
-        #t79.{core::Map::[]=}{Invariant}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
-  } =>#t79;
-  core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t82 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t83 in self::bar<core::String*, core::int*>().{core::Map::entries})
-      #t82.{core::Map::[]=}{Invariant}(#t83.{core::MapEntry::key}, #t83.{core::MapEntry::value});
-  } =>#t82;
-  core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t84 = <core::int*>[];
-    for (final dynamic #t85 in listNum) {
-      final core::int* #t86 = #t85 as{TypeError} core::int*;
-      #t84.{core::List::add}{Invariant}(#t86);
-    }
-  } =>#t84;
-  core::Map<core::num*, core::int*>* map100 = block {
-    final core::Map<core::num*, core::int*>* #t87 = <core::num*, core::int*>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t88 in mapIntNum.{core::Map::entries}) {
-      final core::num* #t89 = #t88.{core::MapEntry::key} as{TypeError} core::num*;
-      final core::int* #t90 = #t88.{core::MapEntry::value} as{TypeError} core::int*;
-      #t87.{core::Map::[]=}{Invariant}(#t89, #t90);
-    }
-  } =>#t87;
   core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t91 = <core::int*>[];
-    for (final dynamic #t92 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-      final core::int* #t93 = #t92 as{TypeError} core::int*;
-      #t91.{core::List::add}{Invariant}(#t93);
+    final core::List<core::int*>* #t77 = <core::int*>[];
+    for (final dynamic #t78 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t79 = #t78 as{TypeError} core::int*;
+      #t77.{core::List::add}{Invariant}(#t79);
     }
-  } =>#t91;
+  } =>#t77;
   core::Map<core::num*, core::int*>* map110 = block {
-    final core::Map<core::num*, core::int*>* #t94 = <core::num*, core::int*>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t95 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-      final core::num* #t96 = #t95.{core::MapEntry::key} as{TypeError} core::num*;
-      final core::int* #t97 = #t95.{core::MapEntry::value} as{TypeError} core::int*;
-      #t94.{core::Map::[]=}{Invariant}(#t96, #t97);
+    final core::Map<core::num*, core::int*>* #t80 = <core::num*, core::int*>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t81 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+      final core::num* #t82 = #t81.{core::MapEntry::key} as{TypeError} core::num*;
+      final core::int* #t83 = #t81.{core::MapEntry::value} as{TypeError} core::int*;
+      #t80.{core::Map::[]=}{Invariant}(#t82, #t83);
     }
-  } =>#t94;
+  } =>#t80;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
index 6ecdd84..8638624 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
@@ -110,26 +110,22 @@
   core::Map<core::int*, core::num*>* mapIntNum = <core::int*, core::num*>{42: 42};
   core::List<core::num*>* listNum = <core::num*>[42];
   core::List<dynamic>* lhs10 = block {
-    final core::List<dynamic>* #t1 = <dynamic>[];
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t2);
-      }
-    }
+    final core::List<dynamic>* #t1 = core::List::of<dynamic>(<dynamic>[]);
   } =>#t1;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t3 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t2 = col::LinkedHashSet::of<dynamic>(<dynamic>[]);
+  } =>#t2;
+  core::Map<dynamic, dynamic>* map10 = block {
+    final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
     {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
-        #t3.{core::Set::add}{Invariant}(#t4);
+        final core::MapEntry<dynamic, dynamic>* #t4 = :sync-for-iterator.{core::Iterator::current};
+        #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
       }
     }
   } =>#t3;
-  core::Map<dynamic, dynamic>* map10 = block {
+  core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
@@ -139,277 +135,197 @@
       }
     }
   } =>#t5;
-  core::Map<dynamic, dynamic>* map10ambiguous = block {
-    final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
-    {
-      core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t8 = :sync-for-iterator.{core::Iterator::current};
-        #t7.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-      }
-    }
-  } =>#t7;
   core::List<core::int*>* lhs20 = block {
-    final core::List<core::int*>* #t9 = <core::int*>[];
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::List::add}{Invariant}(#t10);
-      }
-    }
-  } =>#t9;
+    final core::List<core::int*>* #t7 = core::List::of<core::int*>(spread);
+  } =>#t7;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t11 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t11.{core::Set::add}{Invariant}(#t12);
-      }
-    }
-    #t11.{core::Set::add}{Invariant}(42);
-  } =>#t11;
+    final core::Set<core::int*>* #t8 = col::LinkedHashSet::of<core::int*>(spread);
+    #t8.{core::Set::add}{Invariant}(42);
+  } =>#t8;
   core::Set<core::int*>* set20ambiguous = block {
-    final core::Set<core::int*>* #t13 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t15 = #t14 as{TypeError} core::int*;
-          #t13.{core::Set::add}{Invariant}(#t15);
+          final core::int* #t11 = #t10 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t11);
         }
       }
     }
-  } =>#t13;
+  } =>#t9;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
       }
     }
-    #t16.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t16;
+    #t12.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t12;
   core::Map<core::String*, core::int*>* map20ambiguous = block {
-    final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
+        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
       }
     }
-  } =>#t18;
+  } =>#t14;
   core::List<dynamic>* lhs21 = block {
-    final core::List<dynamic>* #t20 = <dynamic>[];
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
-        #t20.{core::List::add}{Invariant}(#t21);
-      }
-    }
-  } =>#t20;
+    final core::List<dynamic>* #t16 = core::List::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t16;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t22 = new col::_CompactLinkedHashSet::•<dynamic>();
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::Set::add}{Invariant}(#t23);
-      }
-    }
-    #t22.{core::Set::add}{Invariant}(42);
-  } =>#t22;
+    final core::Set<dynamic>* #t17 = col::LinkedHashSet::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t17.{core::Set::add}{Invariant}(42);
+  } =>#t17;
   core::Map<dynamic, dynamic>* map21 = block {
-    final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic>* #t18 = <dynamic, dynamic>{};
     {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t25 = :sync-for-iterator.{core::Iterator::current};
-        #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
+        final core::MapEntry<dynamic, dynamic>* #t19 = :sync-for-iterator.{core::Iterator::current};
+        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
       }
     }
-    #t24.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t24;
+    #t18.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t18;
   dynamic map21ambiguous = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:64:28: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   dynamic map21ambiguous = {...(mapSpread as dynamic)};
                            ^";
   core::List<core::int*>* lhs22 = block {
-    final core::List<core::int*>* #t26 = <core::int*>[];
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t27 = :sync-for-iterator.{core::Iterator::current};
-        #t26.{core::List::add}{Invariant}(#t27);
-      }
-    }
-  } =>#t26;
+    final core::List<core::int*>* #t20 = core::List::of<core::int*>(<core::int*>[]);
+  } =>#t20;
   core::Set<core::int*>* set22 = block {
-    final core::Set<core::int*>* #t28 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
-        #t28.{core::Set::add}{Invariant}(#t29);
-      }
-    }
-    #t28.{core::Set::add}{Invariant}(42);
-  } =>#t28;
+    final core::Set<core::int*>* #t21 = col::LinkedHashSet::of<core::int*>(<core::int*>[]);
+    #t21.{core::Set::add}{Invariant}(42);
+  } =>#t21;
   core::Set<core::int*>* set22ambiguous = block {
-    final core::Set<core::int*>* #t30 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t22 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t31 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t32 = #t31 as{TypeError} core::int*;
-          #t30.{core::Set::add}{Invariant}(#t32);
+          final core::int* #t24 = #t23 as{TypeError} core::int*;
+          #t22.{core::Set::add}{Invariant}(#t24);
         }
       }
     }
-  } =>#t30;
+  } =>#t22;
   core::Map<core::String*, core::int*>* map22 = block {
-    final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t25 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t34 = :sync-for-iterator.{core::Iterator::current};
-        #t33.{core::Map::[]=}{Invariant}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t26 = :sync-for-iterator.{core::Iterator::current};
+        #t25.{core::Map::[]=}{Invariant}(#t26.{core::MapEntry::key}, #t26.{core::MapEntry::value});
       }
     }
-  } =>#t33;
+  } =>#t25;
   core::List<core::List<core::int*>*>* lhs23 = block {
-    final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
-    {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t36 = :sync-for-iterator.{core::Iterator::current};
-        #t35.{core::List::add}{Invariant}(#t36);
-      }
-    }
-  } =>#t35;
+    final core::List<core::List<core::int*>*>* #t27 = core::List::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t27;
   core::Set<core::List<core::int*>*>* set23 = block {
-    final core::Set<core::List<core::int*>*>* #t37 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t28 = col::LinkedHashSet::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+    #t28.{core::Set::add}{Invariant}(<core::int*>[42]);
+  } =>#t28;
+  core::Set<core::List<core::int*>*>* set23ambiguous = block {
+    final core::Set<core::List<core::int*>*>* #t29 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     {
       core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t38 = :sync-for-iterator.{core::Iterator::current};
-        #t37.{core::Set::add}{Invariant}(#t38);
+        final dynamic #t30 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::List<core::int*>* #t31 = #t30 as{TypeError} core::List<core::int*>*;
+          #t29.{core::Set::add}{Invariant}(#t31);
+        }
       }
     }
-    #t37.{core::Set::add}{Invariant}(<core::int*>[42]);
-  } =>#t37;
-  core::Set<core::List<core::int*>*>* set23ambiguous = block {
-    final core::Set<core::List<core::int*>*>* #t39 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+  } =>#t29;
+  core::Map<core::String*, core::List<core::int*>*>* map23 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 = :sync-for-iterator.{core::Iterator::current};
+        #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
+      }
+    }
+  } =>#t32;
+  dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:96:28: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+  dynamic map24ambiguous = {...spread, ...mapSpread};
+                           ^";
+  core::int* lhs30 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+  int lhs30 = /*@ typeArgs=int* */ [...spread];
+                                   ^" in ( block {
+    final core::List<core::int*>* #t35 = core::List::of<core::int*>(spread);
+  } =>#t35) as{TypeError} core::int*;
+  core::int* set30 = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+ - 'Set' is from 'dart:core'.
+  int set30 = /*@ typeArgs=int* */ {...spread, 42};
+                                   ^" in ( block {
+    final core::Set<core::int*>* #t37 = col::LinkedHashSet::of<core::int*>(spread);
+    #t37.{core::Set::add}{Invariant}(42);
+  } =>#t37) as{TypeError} core::int*;
+  core::int* set30ambiguous = let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+ - 'Set' is from 'dart:core'.
+      {...spread};
+      ^" in ( block {
+    final core::Set<core::int*>* #t39 = new col::_CompactLinkedHashSet::•<core::int*>();
+    {
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t40 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::List<core::int*>* #t41 = #t40 as{TypeError} core::List<core::int*>*;
+          final core::int* #t41 = #t40 as{TypeError} core::int*;
           #t39.{core::Set::add}{Invariant}(#t41);
         }
       }
     }
-  } =>#t39;
-  core::Map<core::String*, core::List<core::int*>*>* map23 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
-    {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
-        #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-      }
-    }
-  } =>#t42;
-  dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:96:28: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-  dynamic map24ambiguous = {...spread, ...mapSpread};
-                           ^";
-  core::int* lhs30 = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
- - 'List' is from 'dart:core'.
-  int lhs30 = /*@ typeArgs=int* */ [...spread];
-                                   ^" in ( block {
-    final core::List<core::int*>* #t45 = <core::int*>[];
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t46 = :sync-for-iterator.{core::Iterator::current};
-        #t45.{core::List::add}{Invariant}(#t46);
-      }
-    }
-  } =>#t45) as{TypeError} core::int*;
-  core::int* set30 = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
- - 'Set' is from 'dart:core'.
-  int set30 = /*@ typeArgs=int* */ {...spread, 42};
-                                   ^" in ( block {
-    final core::Set<core::int*>* #t48 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t49 = :sync-for-iterator.{core::Iterator::current};
-        #t48.{core::Set::add}{Invariant}(#t49);
-      }
-    }
-    #t48.{core::Set::add}{Invariant}(42);
-  } =>#t48) as{TypeError} core::int*;
-  core::int* set30ambiguous = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
- - 'Set' is from 'dart:core'.
-      {...spread};
-      ^" in ( block {
-    final core::Set<core::int*>* #t51 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t52 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t53 = #t52 as{TypeError} core::int*;
-          #t51.{core::Set::add}{Invariant}(#t53);
-        }
-      }
-    }
-  } =>#t51) as{TypeError} core::int*;
-  core::int* map30 = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+  } =>#t39) as{TypeError} core::int*;
+  core::int* map30 = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread, \"baz\": 42};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t43 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t56 = :sync-for-iterator.{core::Iterator::current};
-        #t55.{core::Map::[]=}{Invariant}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t44 = :sync-for-iterator.{core::Iterator::current};
+        #t43.{core::Map::[]=}{Invariant}(#t44.{core::MapEntry::key}, #t44.{core::MapEntry::value});
       }
     }
-    #t55.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t55) as{TypeError} core::int*;
-  core::int* map30ambiguous = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+    #t43.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t43) as{TypeError} core::int*;
+  core::int* map30ambiguous = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
-        #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
+        #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
       }
     }
-  } =>#t58) as{TypeError} core::int*;
+  } =>#t46) as{TypeError} core::int*;
   core::List<dynamic>* lhs40 = <dynamic>[invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:111:38: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   List<dynamic> lhs40 = <dynamic>[...notSpreadInt];
                                      ^"];
   core::Set<dynamic>* set40 = block {
-    final core::Set<dynamic>* #t60 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t60.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:113:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t48 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t48.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:113:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set40 = <dynamic>{...notSpreadInt};
                                     ^");
-  } =>#t60;
+  } =>#t48;
   core::Map<dynamic, dynamic>* map40 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:115:55: Error: Unexpected type 'int' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map40 = <dynamic, dynamic>{...notSpreadInt};
                                                       ^": null};
@@ -417,11 +333,11 @@
   List<dynamic> lhs50 = <dynamic>[...notSpreadFunction];
                                      ^"];
   core::Set<dynamic>* set50 = block {
-    final core::Set<dynamic>* #t61 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t61.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:119:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t49 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t49.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:119:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set50 = <dynamic>{...notSpreadFunction};
                                     ^");
-  } =>#t61;
+  } =>#t49;
   core::Map<dynamic, dynamic>* map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:121:55: Error: Unexpected type 'int Function()' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map50 = <dynamic, dynamic>{...notSpreadFunction};
                                                       ^": null};
@@ -429,11 +345,11 @@
   List<String> lhs60 = <String>[...spread];
                                    ^"];
   core::Set<core::String*>* set60 = block {
-    final core::Set<core::String*>* #t62 = new col::_CompactLinkedHashSet::•<core::String*>();
-    #t62.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:125:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
+    final core::Set<core::String*>* #t50 = new col::_CompactLinkedHashSet::•<core::String*>();
+    #t50.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:125:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{...spread};
                                   ^");
-  } =>#t62;
+  } =>#t50;
   core::Map<core::int*, core::int*>* map60 = <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:127:39: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
   Map<int, int> map60 = <int, int>{...mapSpread};
                                       ^": null};
@@ -444,150 +360,140 @@
   List<int> lhs70 = <int>[...null];
                              ^"];
   core::Set<core::int*>* set70 = block {
-    final core::Set<core::int*>* #t63 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t63.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:133:29: Error: Can't spread a value with static type 'Null'.
+    final core::Set<core::int*>* #t51 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t51.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:133:29: Error: Can't spread a value with static type 'Null'.
   Set<int> set70 = <int>{...null};
                             ^");
-  } =>#t63;
+  } =>#t51;
   core::Set<dynamic>* set71ambiguous = block {
-    final core::Set<dynamic>* #t64 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t64.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:137:8: Error: Expected ',' before this.
+    final core::Set<dynamic>* #t52 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t52.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:137:8: Error: Expected ',' before this.
     ...null,
        ^");
     {
       core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t65 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t53 = :sync-for-iterator.{core::Iterator::current};
         {
-          final dynamic #t66 = #t65 as{TypeError} dynamic;
-          #t64.{core::Set::add}{Invariant}(#t66);
+          final dynamic #t54 = #t53 as{TypeError} dynamic;
+          #t52.{core::Set::add}{Invariant}(#t54);
         }
       }
     }
-  } =>#t64;
+  } =>#t52;
   core::Map<core::String*, core::int*>* map70 = <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:142:45: Error: Can't spread a value with static type 'Null'.
   Map<String, int> map70 = <String, int>{...null};
                                             ^": null};
   core::List<core::int*>* lhs80 = block {
-    final core::List<core::int*>* #t67 = <core::int*>[];
-    final core::Iterable<core::int*>* #t68 = null;
-    if(!#t68.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t68.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t69 = :sync-for-iterator.{core::Iterator::current};
-        #t67.{core::List::add}{Invariant}(#t69);
-      }
-    }
-  } =>#t67;
+    final core::List<core::int*>* #t55 = <core::int*>[];
+    final core::Iterable<core::int*>* #t56 = null;
+    if(!#t56.{core::Object::==}(null))
+      #t55.{core::List::addAll}{Invariant}(#t56);
+  } =>#t55;
   core::Set<core::int*>* set80 = block {
-    final core::Set<core::int*>* #t70 = new col::_CompactLinkedHashSet::•<core::int*>();
-    final core::Iterable<core::int*>* #t71 = null;
-    if(!#t71.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t71.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t72 = :sync-for-iterator.{core::Iterator::current};
-        #t70.{core::Set::add}{Invariant}(#t72);
-      }
-    }
-  } =>#t70;
+    final core::Set<core::int*>* #t57 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Iterable<core::int*>* #t58 = null;
+    if(!#t58.{core::Object::==}(null))
+      #t57.{core::Set::addAll}{Invariant}(#t58);
+  } =>#t57;
   core::Set<dynamic>* set81ambiguous = block {
-    final core::Set<dynamic>* #t73 = new col::_CompactLinkedHashSet::•<dynamic>();
-    final core::Iterable<dynamic>* #t74 = null;
-    if(!#t74.{core::Object::==}(null)) {
-      core::Iterator<dynamic>* :sync-for-iterator = #t74.{core::Iterable::iterator};
+    final core::Set<dynamic>* #t59 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Iterable<dynamic>* #t60 = null;
+    if(!#t60.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t60.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t75 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t61 = :sync-for-iterator.{core::Iterator::current};
         {
-          final dynamic #t76 = #t75 as{TypeError} dynamic;
-          #t73.{core::Set::add}{Invariant}(#t76);
+          final dynamic #t62 = #t61 as{TypeError} dynamic;
+          #t59.{core::Set::add}{Invariant}(#t62);
         }
       }
     }
     {
       core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t77 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t63 = :sync-for-iterator.{core::Iterator::current};
         {
-          final dynamic #t78 = #t77 as{TypeError} dynamic;
-          #t73.{core::Set::add}{Invariant}(#t78);
+          final dynamic #t64 = #t63 as{TypeError} dynamic;
+          #t59.{core::Set::add}{Invariant}(#t64);
+        }
+      }
+    }
+  } =>#t59;
+  core::Map<core::String*, core::int*>* map80 = block {
+    final core::Map<core::String*, core::int*>* #t65 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t66 = null;
+    if(!#t66.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = #t66.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::int*>* #t67 = :sync-for-iterator.{core::Iterator::current};
+        #t65.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+      }
+    }
+  } =>#t65;
+  core::Map<core::String*, core::int*>* map90 = block {
+    final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
+    {
+      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::int*>* #t69 = :sync-for-iterator.{core::Iterator::current};
+        #t68.{core::Map::[]=}{Invariant}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
+      }
+    }
+  } =>#t68;
+  core::List<core::int*>* list100 = block {
+    final core::List<core::int*>* #t70 = <core::int*>[];
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t71 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t72 = #t71 as{TypeError} core::int*;
+          #t70.{core::List::add}{Invariant}(#t72);
+        }
+      }
+    }
+  } =>#t70;
+  core::Map<core::num*, core::int*>* map100 = block {
+    final core::Map<core::num*, core::int*>* #t73 = <core::num*, core::int*>{};
+    {
+      core::Iterator<core::MapEntry<core::int*, core::num*>>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<dynamic, dynamic>* #t74 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t75 = #t74.{core::MapEntry::key} as{TypeError} core::num*;
+          final core::int* #t76 = #t74.{core::MapEntry::value} as{TypeError} core::int*;
+          #t73.{core::Map::[]=}{Invariant}(#t75, #t76);
         }
       }
     }
   } =>#t73;
-  core::Map<core::String*, core::int*>* map80 = block {
-    final core::Map<core::String*, core::int*>* #t79 = <core::String*, core::int*>{};
-    final core::Map<core::String*, core::int*>* #t80 = null;
-    if(!#t80.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = #t80.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
-        #t79.{core::Map::[]=}{Invariant}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
-      }
-    }
-  } =>#t79;
-  core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t82 = <core::String*, core::int*>{};
-    {
-      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
-        #t82.{core::Map::[]=}{Invariant}(#t83.{core::MapEntry::key}, #t83.{core::MapEntry::value});
-      }
-    }
-  } =>#t82;
-  core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t84 = <core::int*>[];
-    {
-      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t85 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t86 = #t85 as{TypeError} core::int*;
-          #t84.{core::List::add}{Invariant}(#t86);
-        }
-      }
-    }
-  } =>#t84;
-  core::Map<core::num*, core::int*>* map100 = block {
-    final core::Map<core::num*, core::int*>* #t87 = <core::num*, core::int*>{};
-    {
-      core::Iterator<core::MapEntry<core::int*, core::num*>>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t88 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::num* #t89 = #t88.{core::MapEntry::key} as{TypeError} core::num*;
-          final core::int* #t90 = #t88.{core::MapEntry::value} as{TypeError} core::int*;
-          #t87.{core::Map::[]=}{Invariant}(#t89, #t90);
-        }
-      }
-    }
-  } =>#t87;
   core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t91 = <core::int*>[];
+    final core::List<core::int*>* #t77 = <core::int*>[];
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t92 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t78 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t93 = #t92 as{TypeError} core::int*;
-          #t91.{core::List::add}{Invariant}(#t93);
+          final core::int* #t79 = #t78 as{TypeError} core::int*;
+          #t77.{core::List::add}{Invariant}(#t79);
         }
       }
     }
-  } =>#t91;
+  } =>#t77;
   core::Map<core::num*, core::int*>* map110 = block {
-    final core::Map<core::num*, core::int*>* #t94 = <core::num*, core::int*>{};
+    final core::Map<core::num*, core::int*>* #t80 = <core::num*, core::int*>{};
     {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t95 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<dynamic, dynamic>* #t81 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::num* #t96 = #t95.{core::MapEntry::key} as{TypeError} core::num*;
-          final core::int* #t97 = #t95.{core::MapEntry::value} as{TypeError} core::int*;
-          #t94.{core::Map::[]=}{Invariant}(#t96, #t97);
+          final core::num* #t82 = #t81.{core::MapEntry::key} as{TypeError} core::num*;
+          final core::int* #t83 = #t81.{core::MapEntry::value} as{TypeError} core::int*;
+          #t80.{core::Map::[]=}{Invariant}(#t82, #t83);
         }
       }
     }
-  } =>#t94;
+  } =>#t80;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/statements.dart.strong.transformed.expect b/pkg/front_end/testcases/general/statements.dart.strong.transformed.expect
index a02506d..91dfee3 100644
--- a/pkg/front_end/testcases/general/statements.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/statements.dart.strong.transformed.expect
@@ -15,7 +15,6 @@
 static method bar(dynamic d) → dynamic /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -69,7 +68,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
diff --git a/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect b/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect
index 97bf589..f768444 100644
--- a/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect
@@ -38,7 +38,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -56,7 +55,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -67,7 +65,6 @@
   final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
   core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -85,7 +82,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -95,7 +91,6 @@
 static method error() → asy::Stream<FutureOr<self::Class*>*>* /* originally async* */ {
   asy::_AsyncStarStreamController<FutureOr<self::Class*>*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -124,7 +119,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<FutureOr<self::Class*>*>(:async_op);
@@ -134,7 +128,6 @@
 static method stream() → asy::Stream<FutureOr<self::Class*>*>* /* originally async* */ {
   asy::_AsyncStarStreamController<FutureOr<self::Class*>*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -167,7 +160,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<FutureOr<self::Class*>*>(:async_op);
@@ -178,7 +170,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -221,7 +212,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.outline.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.outline.expect
index bc603fc..82ff41e 100644
--- a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.outline.expect
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.outline.expect
@@ -101,17 +101,17 @@
   tearoff bazOfE = self::E|get#bazOfE;
 }
 static field self::A<core::num*>* E|fieldOfE;
-static method E|fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → self::A<core::num*>*
+static method E|fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → self::A<core::num*>*
   ;
-static method E|get#fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → () →* self::A<core::num*>*
+static method E|get#fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → () →* self::A<core::num*>*
   return () → self::A<core::num*>* => self::E|fooOfE<self::E|get#fooOfE::X*>(#this);
-static method E|barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this, self::A<core::num*>* a) → void
+static method E|barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this, self::A<core::num*>* a) → void
   ;
-static method E|get#barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → (self::A<core::num*>*) →* void
+static method E|get#barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → (self::A<core::num*>*) →* void
   return (self::A<core::num*>* a) → void => self::E|barOfE<self::E|get#barOfE::X*>(#this, a);
-static method E|bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*, Y extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → void
+static method E|bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*, Y extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → void
   ;
-static method E|get#bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → <Y extends self::A<core::num*>* = self::A<core::num*>*>() →* void
+static method E|get#bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → <Y extends self::A<core::num*>* = self::A<core::num*>*>() →* void
   return <Y extends self::A<core::num*>* = self::A<core::num*>*>() → void => self::E|bazOfE<self::E|get#bazOfE::X*, Y*>(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.expect
index fa633e1b..56d2323 100644
--- a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.expect
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.expect
@@ -103,14 +103,14 @@
   tearoff bazOfE = self::E|get#bazOfE;
 }
 static field self::A<core::num*>* E|fieldOfE;
-static method E|fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → self::A<core::num*>*
+static method E|fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → self::A<core::num*>*
   return null;
-static method E|get#fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → () →* self::A<core::num*>*
+static method E|get#fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → () →* self::A<core::num*>*
   return () → self::A<core::num*>* => self::E|fooOfE<self::E|get#fooOfE::X*>(#this);
-static method E|barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this, self::A<core::num*>* a) → void {}
-static method E|get#barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → (self::A<core::num*>*) →* void
+static method E|barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this, self::A<core::num*>* a) → void {}
+static method E|get#barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → (self::A<core::num*>*) →* void
   return (self::A<core::num*>* a) → void => self::E|barOfE<self::E|get#barOfE::X*>(#this, a);
-static method E|bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*, Y extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → void {}
-static method E|get#bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → <Y extends self::A<core::num*>* = self::A<core::num*>*>() →* void
+static method E|bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*, Y extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → void {}
+static method E|get#bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → <Y extends self::A<core::num*>* = self::A<core::num*>*>() →* void
   return <Y extends self::A<core::num*>* = self::A<core::num*>*>() → void => self::E|bazOfE<self::E|get#bazOfE::X*, Y*>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.transformed.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.transformed.expect
index fa633e1b..56d2323 100644
--- a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.strong.transformed.expect
@@ -103,14 +103,14 @@
   tearoff bazOfE = self::E|get#bazOfE;
 }
 static field self::A<core::num*>* E|fieldOfE;
-static method E|fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → self::A<core::num*>*
+static method E|fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → self::A<core::num*>*
   return null;
-static method E|get#fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → () →* self::A<core::num*>*
+static method E|get#fooOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → () →* self::A<core::num*>*
   return () → self::A<core::num*>* => self::E|fooOfE<self::E|get#fooOfE::X*>(#this);
-static method E|barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this, self::A<core::num*>* a) → void {}
-static method E|get#barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → (self::A<core::num*>*) →* void
+static method E|barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this, self::A<core::num*>* a) → void {}
+static method E|get#barOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → (self::A<core::num*>*) →* void
   return (self::A<core::num*>* a) → void => self::E|barOfE<self::E|get#barOfE::X*>(#this, a);
-static method E|bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*, Y extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → void {}
-static method E|get#bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(final self::A<core::int*>* #this) → <Y extends self::A<core::num*>* = self::A<core::num*>*>() →* void
+static method E|bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*, Y extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → void {}
+static method E|get#bazOfE<X extends self::A<core::num*>* = self::A<core::num*>*>(lowered final self::A<core::int*>* #this) → <Y extends self::A<core::num*>* = self::A<core::num*>*>() →* void
   return <Y extends self::A<core::num*>* = self::A<core::num*>*>() → void => self::E|bazOfE<self::E|get#bazOfE::X*, Y*>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.outline.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.outline.expect
index f307bb3..3c9cb35 100644
--- a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.outline.expect
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.outline.expect
@@ -22,7 +22,7 @@
   method foo = ext::Extension|foo;
   tearoff foo = ext::Extension|get#foo;
 }
-static method Extension|foo(final core::String* #this) → dynamic
+static method Extension|foo(lowered final core::String* #this) → dynamic
   ;
-static method Extension|get#foo(final core::String* #this) → () →* dynamic
+static method Extension|get#foo(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => ext::Extension|foo(#this);
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.expect
index 01e6ac2..aa7decf 100644
--- a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.expect
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.expect
@@ -24,7 +24,7 @@
   method foo = ext::Extension|foo;
   tearoff foo = ext::Extension|get#foo;
 }
-static method Extension|foo(final core::String* #this) → dynamic
+static method Extension|foo(lowered final core::String* #this) → dynamic
   return 42;
-static method Extension|get#foo(final core::String* #this) → () →* dynamic
+static method Extension|get#foo(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => ext::Extension|foo(#this);
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.transformed.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.transformed.expect
index 01e6ac2..aa7decf 100644
--- a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.strong.transformed.expect
@@ -24,7 +24,7 @@
   method foo = ext::Extension|foo;
   tearoff foo = ext::Extension|get#foo;
 }
-static method Extension|foo(final core::String* #this) → dynamic
+static method Extension|foo(lowered final core::String* #this) → dynamic
   return 42;
-static method Extension|get#foo(final core::String* #this) → () →* dynamic
+static method Extension|get#foo(lowered final core::String* #this) → () →* dynamic
   return () → dynamic => ext::Extension|foo(#this);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
index 3382485..33ab33f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
@@ -11,7 +11,6 @@
   final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
   core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -29,7 +28,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -40,7 +38,6 @@
   final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
   core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -58,7 +55,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -110,7 +106,6 @@
 static method asyncStarString() → asy::Stream<core::String*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -144,7 +139,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::String*>(:async_op);
@@ -154,7 +148,6 @@
 static method asyncStarString2() → asy::Stream<core::String*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::String*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -179,7 +172,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::String*>(:async_op);
@@ -190,7 +182,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -209,7 +200,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
index 772b468..78818d9 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
@@ -31,7 +31,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -69,7 +68,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
index 9bac1f2..04a6af0 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
@@ -8,7 +8,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -27,7 +26,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
index d6a8b95..8b69c50 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
@@ -60,7 +60,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -107,7 +106,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -118,7 +116,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -160,7 +157,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -171,7 +167,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -214,7 +209,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -225,7 +219,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -268,7 +261,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -279,7 +271,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -342,7 +333,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -353,7 +343,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -417,7 +406,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -428,7 +416,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -562,7 +549,6 @@
                 final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
                 core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -582,7 +568,6 @@
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
                     asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :async_op.call();
@@ -594,7 +579,6 @@
                 final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
                 core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -612,7 +596,6 @@
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
                     asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :async_op.call();
@@ -623,7 +606,6 @@
               function testStream1() → asy::Stream<core::int*>* /* originally async* */ {
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -649,7 +631,6 @@
                   finally {
                     :controller.{asy::_AsyncStarStreamController::close}();
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
@@ -662,7 +643,6 @@
               function testStream2() → asy::Stream<core::int*>* /* originally async* */ {
                 asy::_AsyncStarStreamController<core::int*>* :controller;
                 dynamic :controller_stream;
-                dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
                 (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
                 core::int* :await_jump_var = 0;
@@ -688,7 +668,6 @@
                   finally {
                     :controller.{asy::_AsyncStarStreamController::close}();
                   }
-                :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
                 :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
@@ -708,7 +687,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -719,7 +697,6 @@
   final asy::_Future<self::future::T*>* :async_future = new asy::_Future::•<self::future::T*>();
   core::bool* :is_sync = false;
   FutureOr<self::future::T*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -737,7 +714,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -749,7 +725,6 @@
 static method intStream() → asy::Stream<core::int*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::int*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -774,7 +749,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
@@ -785,7 +759,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -818,7 +791,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
index fe03b1d..e178bdf 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
@@ -14,7 +14,6 @@
     final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
     core::bool* :is_sync = false;
     FutureOr<core::List<core::int*>*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -36,7 +35,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -47,7 +45,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -65,7 +62,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -87,7 +83,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -106,7 +101,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
index fe416ab..ea1347a 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
@@ -13,7 +13,6 @@
   final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
   core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -31,7 +30,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
index 389811c..b800d2a 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
@@ -44,7 +44,6 @@
   final asy::_Future<core::List<core::Object*>*>* :async_future = new asy::_Future::•<core::List<core::Object*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::Object*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -62,7 +61,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -75,7 +73,6 @@
   final asy::_Future<core::Object*>* :async_future = new asy::_Future::•<core::Object*>();
   core::bool* :is_sync = false;
   FutureOr<core::Object*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -93,7 +90,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -104,7 +100,6 @@
   final asy::_Future<self::X*>* :async_future = new asy::_Future::•<self::X*>();
   core::bool* :is_sync = false;
   FutureOr<self::X*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -131,7 +126,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -142,7 +136,6 @@
   final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -161,7 +154,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
index ad4521b..fd3b4a6 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
@@ -11,7 +11,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -31,7 +30,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.expect
index dffdbc4..bc26325 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.expect
@@ -5,8 +5,7 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
+    final core::List<core::int*>* #t1 = <core::int*>[1];
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
       #t1.{core::List::add}{Invariant}(2);
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect
index c62af95..09e88b5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.weak.transformed.expect
@@ -5,8 +5,7 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
+    final core::List<core::int*>* #t1 = <core::int*>[1];
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
       #t1.{core::List::add}{Invariant}(2);
     if(self::oracle() as{TypeError,ForDynamic} core::bool*)
@@ -107,4 +106,4 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///control_flow_collection.dart:20:26 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///control_flow_collection.dart:29:29 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///control_flow_collection.dart:29:33 -> IntConstant(-1)
-Extra constant evaluation: evaluated: 160, effectively constant: 4
+Extra constant evaluation: evaluated: 158, effectively constant: 4
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect
index 9301e7e..c3d3cee 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect
@@ -505,553 +505,512 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t11 in <core::int*>[42])
-        #t10.{core::List::add}{Invariant}(#t11);
+      #t10.{core::List::addAll}{Invariant}(<core::int*>[42]);
   } =>#t10;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t12 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t13 in <core::int*>[42])
-        #t12.{core::Set::add}{Invariant}(#t13);
-    #t12.{core::Set::add}{Invariant}(null);
-  } =>#t12;
+      #t11.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t11.{core::Set::add}{Invariant}(null);
+  } =>#t11;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::int*>* #t15 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
-        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
-    #t14.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t14;
+      for (final core::MapEntry<core::String*, core::int*>* #t13 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
+    #t12.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t12;
   core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t16 = <dynamic>[];
+    final core::List<dynamic>* #t14 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t17 in <dynamic>[dynVar])
-        #t16.{core::List::add}{Invariant}(#t17);
-  } =>#t16;
+      #t14.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t14;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t18 = col::LinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t15 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t19 in <dynamic>[dynVar])
-        #t18.{core::Set::add}{Invariant}(#t19);
-    #t18.{core::Set::add}{Invariant}(null);
-  } =>#t18;
+      #t15.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t15.{core::Set::add}{Invariant}(null);
+  } =>#t15;
   core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t16 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, dynamic>* #t21 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+      for (final core::MapEntry<core::String*, dynamic>* #t17 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+    #t16.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t16;
+  core::List<core::List<core::int*>*>* list22 = block {
+    final core::List<core::List<core::int*>*>* #t18 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t18.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t18;
+  core::Set<core::List<core::int*>*>* set22 = block {
+    final core::Set<core::List<core::int*>*>* #t19 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t19.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t19.{core::Set::add}{Invariant}(null);
+  } =>#t19;
+  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t20 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t21 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
         #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
     #t20.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t20;
-  core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t23 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t22.{core::List::add}{Invariant}(#t23);
-  } =>#t22;
-  core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t24 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t25 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t24.{core::Set::add}{Invariant}(#t25);
-    #t24.{core::Set::add}{Invariant}(null);
-  } =>#t24;
-  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
-        #t26.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
-    #t26.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t26;
   core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t28 = <core::int*>[];
+    final core::List<core::int*>* #t22 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t29 in <core::int*>[42])
-          #t28.{core::List::add}{Invariant}(#t29);
-  } =>#t28;
+        #t22.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t22;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t23 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t31 in <core::int*>[42])
-          #t30.{core::Set::add}{Invariant}(#t31);
-    #t30.{core::Set::add}{Invariant}(null);
-  } =>#t30;
+        #t23.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t23.{core::Set::add}{Invariant}(null);
+  } =>#t23;
   core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t24 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::int*>* #t33 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+        for (final core::MapEntry<core::String*, core::int*>* #t25 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+          #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
+    #t24.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t24;
+  core::List<dynamic>* list31 = block {
+    final core::List<dynamic>* #t26 = <dynamic>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t26.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t26;
+  core::Set<dynamic>* set31 = block {
+    final core::Set<dynamic>* #t27 = col::LinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t27.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t27.{core::Set::add}{Invariant}(null);
+  } =>#t27;
+  core::Map<core::String*, dynamic>* map31 = block {
+    final core::Map<core::String*, dynamic>* #t28 = <core::String*, dynamic>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, dynamic>* #t29 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+          #t28.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
+    #t28.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t28;
+  core::List<core::List<core::int*>*>* list33 = block {
+    final core::List<core::List<core::int*>*>* #t30 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t30.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t30;
+  core::Set<core::List<core::int*>*>* set33 = block {
+    final core::Set<core::List<core::int*>*>* #t31 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t31.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t31.{core::Set::add}{Invariant}(null);
+  } =>#t31;
+  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
           #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
     #t32.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t32;
-  core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t34 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t35 in <dynamic>[dynVar])
-          #t34.{core::List::add}{Invariant}(#t35);
-  } =>#t34;
-  core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t36 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t37 in <dynamic>[dynVar])
-          #t36.{core::Set::add}{Invariant}(#t37);
-    #t36.{core::Set::add}{Invariant}(null);
-  } =>#t36;
-  core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, dynamic>* #t39 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
-          #t38.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
-    #t38.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t38;
-  core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t41 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t40.{core::List::add}{Invariant}(#t41);
-  } =>#t40;
-  core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t42 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t43 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t42.{core::Set::add}{Invariant}(#t43);
-    #t42.{core::Set::add}{Invariant}(null);
-  } =>#t42;
-  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
-          #t44.{core::Map::[]=}{Invariant}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
-    #t44.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t44;
   core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t34 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t47 in <core::List<core::int*>*>[<core::int*>[]])
-        #t46.{core::List::add}{Invariant}(#t47);
-  } =>#t46;
+      #t34.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t34;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t48 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t35 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t49 in <core::List<core::int*>*>[<core::int*>[]])
-        #t48.{core::Set::add}{Invariant}(#t49);
-    #t48.{core::Set::add}{Invariant}(null);
-  } =>#t48;
+      #t35.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t35.{core::Set::add}{Invariant}(null);
+  } =>#t35;
   core::Map<core::String*, core::List<core::int*>*>* map40 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:41:34: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
   Map<String, List<int>> map40 = {if (oracle(\"foo\")) ...{\"bar\", []}, \"baz\": null};
                                  ^";
   core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t36 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t51 in block {
-        final core::Set<core::List<core::int*>*>* #t52 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t52.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t52)
-        #t50.{core::List::add}{Invariant}(#t51);
-  } =>#t50;
+      #t36.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t37.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t37);
+  } =>#t36;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t53 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t38 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t54 in block {
-        final core::Set<core::List<core::int*>*>* #t55 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t55.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t55)
-        #t53.{core::Set::add}{Invariant}(#t54);
+      #t38.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t39.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t39);
+    #t38.{core::Set::add}{Invariant}(null);
+  } =>#t38;
+  core::List<core::List<core::int*>*>* list42 = block {
+    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t40.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t40;
+  core::Set<core::List<core::int*>*>* set42 = block {
+    final core::Set<core::List<core::int*>*>* #t41 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t41.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t41.{core::Set::add}{Invariant}(null);
+  } =>#t41;
+  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
+    #t42.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t42;
+  core::List<core::int*>* list50 = block {
+    final core::List<core::int*>* #t44 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t44.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t44;
+  core::Set<core::int*>* set50 = block {
+    final core::Set<core::int*>* #t45 = col::LinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t45.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t45.{core::Set::add}{Invariant}(null);
+  } =>#t45;
+  core::Map<core::String*, core::int*>* map50 = block {
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      for (final core::MapEntry<core::String*, core::int*>* #t47 in <core::String*, core::int*>{}.{core::Map::entries})
+        #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
+    #t46.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t46;
+  core::List<core::int*>* list51 = block {
+    final core::List<core::int*>* #t48 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t48.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t49 = col::LinkedHashSet::•<core::int*>();
+      } =>#t49);
+  } =>#t48;
+  core::Set<core::int*>* set51 = block {
+    final core::Set<core::int*>* #t50 = col::LinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t50.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
+      } =>#t51);
+    #t50.{core::Set::add}{Invariant}(null);
+  } =>#t50;
+  core::List<core::int*>* list52 = block {
+    final core::List<core::int*>* #t52 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t52.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t52;
+  core::Set<core::int*>* set52 = block {
+    final core::Set<core::int*>* #t53 = col::LinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t53.{core::Set::addAll}{Invariant}(<core::int*>[]);
     #t53.{core::Set::add}{Invariant}(null);
   } =>#t53;
-  core::List<core::List<core::int*>*>* list42 = block {
+  core::Map<core::String*, core::int*>* map52 = block {
+    final core::Map<core::String*, core::int*>* #t54 = <core::String*, core::int*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::int*>* #t55 in <core::String*, core::int*>{}.{core::Map::entries})
+          #t54.{core::Map::[]=}{Invariant}(#t55.{core::MapEntry::key}, #t55.{core::MapEntry::value});
+    #t54.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t54;
+  core::List<core::List<core::int*>*>* list60 = block {
     final core::List<core::List<core::int*>*>* #t56 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t57 in <core::List<core::int*>*>[<core::int*>[]])
-          #t56.{core::List::add}{Invariant}(#t57);
+      #t56.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
   } =>#t56;
-  core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t58 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t59 in <core::List<core::int*>*>[<core::int*>[]])
-          #t58.{core::Set::add}{Invariant}(#t59);
-    #t58.{core::Set::add}{Invariant}(null);
-  } =>#t58;
-  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t60 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t61 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t60.{core::Map::[]=}{Invariant}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value});
-    #t60.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t60;
-  core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t62 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t63 in <core::int*>[])
-        #t62.{core::List::add}{Invariant}(#t63);
-  } =>#t62;
-  core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t64 = col::LinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t65 in <core::int*>[])
-        #t64.{core::Set::add}{Invariant}(#t65);
-    #t64.{core::Set::add}{Invariant}(null);
-  } =>#t64;
-  core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t66 = <core::String*, core::int*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::int*>* #t67 in <core::String*, core::int*>{}.{core::Map::entries})
-        #t66.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
-    #t66.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t66;
-  core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t68 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t69 in block {
-        final core::Set<core::int*>* #t70 = col::LinkedHashSet::•<core::int*>();
-      } =>#t70)
-        #t68.{core::List::add}{Invariant}(#t69);
-  } =>#t68;
-  core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t71 = col::LinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t72 in block {
-        final core::Set<core::int*>* #t73 = col::LinkedHashSet::•<core::int*>();
-      } =>#t73)
-        #t71.{core::Set::add}{Invariant}(#t72);
-    #t71.{core::Set::add}{Invariant}(null);
-  } =>#t71;
-  core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t74 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t75 in <core::int*>[])
-          #t74.{core::List::add}{Invariant}(#t75);
-  } =>#t74;
-  core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t76 = col::LinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t77 in <core::int*>[])
-          #t76.{core::Set::add}{Invariant}(#t77);
-    #t76.{core::Set::add}{Invariant}(null);
-  } =>#t76;
-  core::Map<core::String*, core::int*>* map52 = block {
-    final core::Map<core::String*, core::int*>* #t78 = <core::String*, core::int*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::int*>* #t79 in <core::String*, core::int*>{}.{core::Map::entries})
-          #t78.{core::Map::[]=}{Invariant}(#t79.{core::MapEntry::key}, #t79.{core::MapEntry::value});
-    #t78.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t78;
-  core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t80 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t81 in <core::List<core::int*>*>[<core::int*>[]])
-        #t80.{core::List::add}{Invariant}(#t81);
-  } =>#t80;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t82 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t57 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::List<core::int*>* #t83 in <core::List<core::int*>*>[<core::int*>[]])
-        #t82.{core::Set::add}{Invariant}(#t83);
-    #t82.{core::Set::add}{Invariant}(null);
-  } =>#t82;
+      #t57.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t57.{core::Set::add}{Invariant}(null);
+  } =>#t57;
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t84 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t58 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t85 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-        #t84.{core::Map::[]=}{Invariant}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
-    #t84.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t84;
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t59 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+        #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
+    #t58.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t58;
   core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t86 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t60 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t87 in <core::List<core::int*>*>[<core::int*>[]])
-          #t86.{core::List::add}{Invariant}(#t87);
-  } =>#t86;
+        #t60.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t60;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t88 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t61 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t89 in <core::List<core::int*>*>[<core::int*>[]])
-          #t88.{core::Set::add}{Invariant}(#t89);
-    #t88.{core::Set::add}{Invariant}(null);
-  } =>#t88;
+        #t61.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t61.{core::Set::add}{Invariant}(null);
+  } =>#t61;
   core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t90 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t91 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t90.{core::Map::[]=}{Invariant}(#t91.{core::MapEntry::key}, #t91.{core::MapEntry::value});
-    #t90.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t90;
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t62.{core::Map::[]=}{Invariant}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
+    #t62.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t62;
   core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t92 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t64 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t92.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t92;
+      #t64.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t64;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t93 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t65 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t93.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t93.{core::Set::add}{Invariant}(null);
-  } =>#t93;
+      #t65.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t65.{core::Set::add}{Invariant}(null);
+  } =>#t65;
   core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t94 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t66 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t94.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t94;
+        #t66.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t66;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t95 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t67 = col::LinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t95.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t95.{core::Set::add}{Invariant}(null);
-  } =>#t95;
+        #t67.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t67.{core::Set::add}{Invariant}(null);
+  } =>#t67;
   core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t96 = <core::num*>[];
+    final core::List<core::num*>* #t68 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t96.{core::List::add}{Invariant}(42);
+      #t68.{core::List::add}{Invariant}(42);
     else
-      #t96.{core::List::add}{Invariant}(3.14);
-  } =>#t96;
+      #t68.{core::List::add}{Invariant}(3.14);
+  } =>#t68;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t97 = col::LinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t69 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t97.{core::Set::add}{Invariant}(42);
+      #t69.{core::Set::add}{Invariant}(42);
     else
-      #t97.{core::Set::add}{Invariant}(3.14);
-    #t97.{core::Set::add}{Invariant}(null);
-  } =>#t97;
+      #t69.{core::Set::add}{Invariant}(3.14);
+    #t69.{core::Set::add}{Invariant}(null);
+  } =>#t69;
   core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t98 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t70 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t98.{core::Map::[]=}{Invariant}("bar", 42);
+      #t70.{core::Map::[]=}{Invariant}("bar", 42);
     else
-      #t98.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t98.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t98;
+      #t70.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t70.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t70;
   core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t99 = <core::num*>[];
+    final core::List<core::num*>* #t71 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::num* #t100 in listInt)
-        #t99.{core::List::add}{Invariant}(#t100);
+      #t71.{core::List::addAll}{Invariant}(listInt);
     else
-      for (final core::num* #t101 in listDouble)
-        #t99.{core::List::add}{Invariant}(#t101);
-  } =>#t99;
+      #t71.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t71;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t102 = col::LinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t72 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::num* #t103 in listInt)
-        #t102.{core::Set::add}{Invariant}(#t103);
+      #t72.{core::Set::addAll}{Invariant}(listInt);
     else
-      for (final core::num* #t104 in listDouble)
-        #t102.{core::Set::add}{Invariant}(#t104);
-    #t102.{core::Set::add}{Invariant}(null);
-  } =>#t102;
+      #t72.{core::Set::addAll}{Invariant}(listDouble);
+    #t72.{core::Set::add}{Invariant}(null);
+  } =>#t72;
   core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t105 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t73 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::num*>* #t106 in mapToInt.{core::Map::entries})
-        #t105.{core::Map::[]=}{Invariant}(#t106.{core::MapEntry::key}, #t106.{core::MapEntry::value});
+      for (final core::MapEntry<core::String*, core::num*>* #t74 in mapToInt.{core::Map::entries})
+        #t73.{core::Map::[]=}{Invariant}(#t74.{core::MapEntry::key}, #t74.{core::MapEntry::value});
     else
-      for (final core::MapEntry<core::String*, core::num*>* #t107 in mapToDouble.{core::Map::entries})
-        #t105.{core::Map::[]=}{Invariant}(#t107.{core::MapEntry::key}, #t107.{core::MapEntry::value});
-    #t105.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t105;
+      for (final core::MapEntry<core::String*, core::num*>* #t75 in mapToDouble.{core::Map::entries})
+        #t73.{core::Map::[]=}{Invariant}(#t75.{core::MapEntry::key}, #t75.{core::MapEntry::value});
+    #t73.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t73;
   core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t108 = <dynamic>[];
+    final core::List<dynamic>* #t76 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t109 in listInt)
-        #t108.{core::List::add}{Invariant}(#t109);
+      #t76.{core::List::addAll}{Invariant}(listInt);
     else
-      for (final dynamic #t110 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-        #t108.{core::List::add}{Invariant}(#t110);
-  } =>#t108;
+      #t76.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t76;
   core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t111 = col::LinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t77 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t112 in listInt)
-        #t111.{core::Set::add}{Invariant}(#t112);
+      #t77.{core::Set::addAll}{Invariant}(listInt);
     else
-      for (final dynamic #t113 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-        #t111.{core::Set::add}{Invariant}(#t113);
-    #t111.{core::Set::add}{Invariant}(null);
-  } =>#t111;
+      #t77.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t77.{core::Set::add}{Invariant}(null);
+  } =>#t77;
   core::Set<dynamic>* map82 = block {
-    final core::Set<dynamic>* #t114 = col::LinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t78 = col::LinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t114.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:73:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t78.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:73:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
     else
-      for (final dynamic #t115 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-        #t114.{core::Set::add}{Invariant}(#t115);
-    #t114.{core::Set::add}{Invariant}(null);
-  } =>#t114;
+      #t78.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t78.{core::Set::add}{Invariant}(null);
+  } =>#t78;
   core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t116 = <core::num*>[];
+    final core::List<core::num*>* #t79 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t116.{core::List::add}{Invariant}(42);
+      #t79.{core::List::add}{Invariant}(42);
     else
-      for (final core::num* #t117 in listDouble)
-        #t116.{core::List::add}{Invariant}(#t117);
-  } =>#t116;
+      #t79.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t79;
   core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t118 = col::LinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t80 = col::LinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::num* #t119 in listInt)
-        #t118.{core::Set::add}{Invariant}(#t119);
+      #t80.{core::Set::addAll}{Invariant}(listInt);
     else
-      #t118.{core::Set::add}{Invariant}(3.14);
-    #t118.{core::Set::add}{Invariant}(null);
-  } =>#t118;
+      #t80.{core::Set::add}{Invariant}(3.14);
+    #t80.{core::Set::add}{Invariant}(null);
+  } =>#t80;
   core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t120 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t81 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::num*>* #t121 in mapToInt.{core::Map::entries})
-        #t120.{core::Map::[]=}{Invariant}(#t121.{core::MapEntry::key}, #t121.{core::MapEntry::value});
+      for (final core::MapEntry<core::String*, core::num*>* #t82 in mapToInt.{core::Map::entries})
+        #t81.{core::Map::[]=}{Invariant}(#t82.{core::MapEntry::key}, #t82.{core::MapEntry::value});
     else
-      #t120.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t120.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t120;
+      #t81.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t81.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t81;
   core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t122 = <core::int*>[];
+    final core::List<core::int*>* #t83 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t122.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t122;
+      #t83.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+  } =>#t83;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t123 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t84 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t123.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t123.{core::Set::add}{Invariant}(null);
-  } =>#t123;
+      #t84.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t84.{core::Set::add}{Invariant}(null);
+  } =>#t84;
   core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t124 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t85 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t124.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t124.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t124;
+      #t85.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t85.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t85;
   core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t125 = <core::int*>[];
+    final core::List<core::int*>* #t86 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t126 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t127 = #t126 as{TypeError} core::int*;
-        #t125.{core::List::add}{Invariant}(#t127);
+      for (final dynamic #t87 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t88 = #t87 as{TypeError} core::int*;
+        #t86.{core::List::add}{Invariant}(#t88);
       }
-  } =>#t125;
+  } =>#t86;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t128 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t89 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final dynamic #t129 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t130 = #t129 as{TypeError} core::int*;
-        #t128.{core::Set::add}{Invariant}(#t130);
+      for (final dynamic #t90 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t91 = #t90 as{TypeError} core::int*;
+        #t89.{core::Set::add}{Invariant}(#t91);
       }
-    #t128.{core::Set::add}{Invariant}(null);
-  } =>#t128;
+    #t89.{core::Set::add}{Invariant}(null);
+  } =>#t89;
   core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t131 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t92 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<dynamic, dynamic>* #t132 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-        final core::String* #t133 = #t132.{core::MapEntry::key} as{TypeError} core::String*;
-        final core::int* #t134 = #t132.{core::MapEntry::value} as{TypeError} core::int*;
-        #t131.{core::Map::[]=}{Invariant}(#t133, #t134);
+      for (final core::MapEntry<dynamic, dynamic>* #t93 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+        final core::String* #t94 = #t93.{core::MapEntry::key} as{TypeError} core::String*;
+        final core::int* #t95 = #t93.{core::MapEntry::value} as{TypeError} core::int*;
+        #t92.{core::Map::[]=}{Invariant}(#t94, #t95);
       }
-    #t131.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t131;
+    #t92.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t92;
   core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t135 = <core::int*>[];
+    final core::List<core::int*>* #t96 = <core::int*>[];
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t135.{core::List::add}{Invariant}(42);
-  } =>#t135;
+      #t96.{core::List::add}{Invariant}(42);
+  } =>#t96;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t136 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t97 = col::LinkedHashSet::•<core::int*>();
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t136.{core::Set::add}{Invariant}(42);
-  } =>#t136;
+      #t97.{core::Set::add}{Invariant}(42);
+  } =>#t97;
   core::Map<core::int*, core::int*>* map100 = block {
-    final core::Map<core::int*, core::int*>* #t137 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t98 = <core::int*, core::int*>{};
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t137.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t137;
+      #t98.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t98;
 }
 static method testIfElementErrors(core::Map<core::int*, core::int*>* map) → dynamic {
   block {
-    final core::List<core::int*>* #t138 = <core::int*>[];
+    final core::List<core::int*>* #t99 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t138.{core::List::add}{Invariant}(let final<BottomType> #t139 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:89:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t99.{core::List::add}{Invariant}(let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:89:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) \"bar\"];
                            ^" in "bar" as{TypeError} core::int*);
-  } =>#t138;
+  } =>#t99;
   block {
-    final core::Set<core::int*>* #t140 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t101 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t140.{core::Set::add}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:90:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t101.{core::Set::add}{Invariant}(let final<BottomType> #t102 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:90:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
                            ^" in "bar" as{TypeError} core::int*);
-    #t140.{core::Set::add}{Invariant}(null);
-  } =>#t140;
+    #t101.{core::Set::add}{Invariant}(null);
+  } =>#t101;
   block {
-    final core::Map<core::String*, core::int*>* #t142 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t103 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t142.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:91:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t103.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:91:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
                                           ^" in "bar" as{TypeError} core::int*);
-    #t142.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t142;
+    #t103.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t103;
   block {
-    final core::List<core::int*>* #t144 = <core::int*>[];
+    final core::List<core::int*>* #t105 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t145 in <core::int*>[let final<BottomType> #t146 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t105.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*])
-        #t144.{core::List::add}{Invariant}(#t145);
-  } =>#t144;
+                               ^" in "bar" as{TypeError} core::int*]);
+  } =>#t105;
   block {
-    final core::Set<core::int*>* #t147 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t107 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::int* #t148 in <core::int*>[let final<BottomType> #t149 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t107.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*])
-        #t147.{core::Set::add}{Invariant}(#t148);
-    #t147.{core::Set::add}{Invariant}(null);
-  } =>#t147;
+                               ^" in "bar" as{TypeError} core::int*]);
+    #t107.{core::Set::add}{Invariant}(null);
+  } =>#t107;
   block {
-    final core::Map<core::String*, core::int*>* #t150 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t109 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      for (final core::MapEntry<core::String*, core::int*>* #t151 in <core::String*, core::int*>{"bar": let final<BottomType> #t152 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      for (final core::MapEntry<core::String*, core::int*>* #t110 in <core::String*, core::int*>{"bar": let final<BottomType> #t111 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
-        #t150.{core::Map::[]=}{Invariant}(#t151.{core::MapEntry::key}, #t151.{core::MapEntry::value});
-    #t150.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t150;
+        #t109.{core::Map::[]=}{Invariant}(#t110.{core::MapEntry::key}, #t110.{core::MapEntry::value});
+    #t109.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t109;
   block {
-    final core::List<core::int*>* #t153 = <core::int*>[];
+    final core::List<core::int*>* #t112 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t153.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:95:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t112.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:95:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map];
                               ^");
-  } =>#t153;
+  } =>#t112;
   block {
-    final core::Set<core::int*>* #t154 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t113 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t154.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t113.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map, null};
                               ^");
-    #t154.{core::Set::add}{Invariant}(null);
-  } =>#t154;
+    #t113.{core::Set::add}{Invariant}(null);
+  } =>#t113;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:97:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
@@ -1060,61 +1019,61 @@
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::String*>* #t155 = <core::String*>[];
+    final core::List<core::String*>* #t114 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t156 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t115 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t157 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                                       ^" in 3.14 as{TypeError} core::String*);
-  } =>#t155;
+  } =>#t114;
   block {
-    final core::Set<core::String*>* #t158 = col::LinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t117 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t160 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                                       ^" in 3.14 as{TypeError} core::String*);
-    #t158.{core::Set::add}{Invariant}(null);
-  } =>#t158;
+    #t117.{core::Set::add}{Invariant}(null);
+  } =>#t117;
   block {
-    final core::Map<core::String*, core::String*>* #t161 = <core::String*, core::String*>{};
+    final core::Map<core::String*, core::String*>* #t120 = <core::String*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t161.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                              ^" in 42 as{TypeError} core::String*);
     else
-      #t161.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t163 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                                             ^" in 3.14 as{TypeError} core::String*);
-    #t161.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t161;
+    #t120.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t120;
   block {
-    final core::List<core::int*>* #t164 = <core::int*>[];
+    final core::List<core::int*>* #t123 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t164.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:101:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t123.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:101:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map else 42];
                               ^");
     else
-      #t164.{core::List::add}{Invariant}(42);
-  } =>#t164;
+      #t123.{core::List::add}{Invariant}(42);
+  } =>#t123;
   block {
-    final core::Set<core::int*>* #t165 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t124 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t165.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:102:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t124.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:102:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t165.{core::Set::add}{Invariant}(42);
-    #t165.{core::Set::add}{Invariant}(null);
-  } =>#t165;
+      #t124.{core::Set::add}{Invariant}(42);
+    #t124.{core::Set::add}{Invariant}(null);
+  } =>#t124;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:103:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
@@ -1123,26 +1082,26 @@
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::int*>* #t166 = <core::int*>[];
+    final core::List<core::int*>* #t125 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t166.{core::List::add}{Invariant}(42);
+      #t125.{core::List::add}{Invariant}(42);
     else
-      #t166.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:104:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t125.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:104:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) 42 else ...map];
                                       ^");
-  } =>#t166;
+  } =>#t125;
   block {
-    final core::Set<core::int*>* #t167 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t126 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t167.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:105:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t126.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:105:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t167.{core::Set::add}{Invariant}(42);
-    #t167.{core::Set::add}{Invariant}(null);
-  } =>#t167;
+      #t126.{core::Set::add}{Invariant}(42);
+    #t126.{core::Set::add}{Invariant}(null);
+  } =>#t126;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:106:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
@@ -1169,749 +1128,709 @@
   var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
                                                    ^": null};
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t168 = <core::int*>[];
-    if(let final<BottomType> #t169 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:114:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int*>* #t127 = <core::int*>[];
+    if(let final<BottomType> #t128 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:114:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   List<int> list20 = [if (42) 42];
                           ^" in 42 as{TypeError} core::bool*)
-      #t168.{core::List::add}{Invariant}(42);
-  } =>#t168;
+      #t127.{core::List::add}{Invariant}(42);
+  } =>#t127;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t170 = col::LinkedHashSet::•<core::int*>();
-    if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:115:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int*>* #t129 = col::LinkedHashSet::•<core::int*>();
+    if(let final<BottomType> #t130 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:115:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
-      #t170.{core::Set::add}{Invariant}(42);
-  } =>#t170;
+      #t129.{core::Set::add}{Invariant}(42);
+  } =>#t129;
   core::Map<core::int*, core::int*>* map30 = block {
-    final core::Map<core::int*, core::int*>* #t172 = <core::int*, core::int*>{};
-    if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:116:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::int*, core::int*>* #t131 = <core::int*, core::int*>{};
+    if(let final<BottomType> #t132 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:116:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Map<int, int> map30 = {if (42) 42: 42};
                              ^" in 42 as{TypeError} core::bool*)
-      #t172.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t172;
+      #t131.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t131;
   core::List<core::String*>* list40 = block {
-    final core::List<core::String*>* #t174 = <core::String*>[];
+    final core::List<core::String*>* #t133 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t134 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                     ^" in true as{TypeError} core::String*);
     else
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t176 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t135 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t174;
+  } =>#t133;
   core::Set<core::String*>* set40 = block {
-    final core::Set<core::String*>* #t177 = col::LinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t136 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t137 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                   ^" in true as{TypeError} core::String*);
     else
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t179 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t138 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                             ^" in 42 as{TypeError} core::String*);
-  } =>#t177;
+  } =>#t136;
   core::Map<core::String*, core::int*>* map40 = block {
-    final core::Map<core::String*, core::int*>* #t180 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t139 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t140 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                             ^" in true as{TypeError} core::String*, 42);
     else
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t182 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                                           ^" in 42 as{TypeError} core::String*, 42);
-  } =>#t180;
+  } =>#t139;
   core::Map<core::int*, core::String*>* map41 = block {
-    final core::Map<core::int*, core::String*>* #t183 = <core::int*, core::String*>{};
+    final core::Map<core::int*, core::String*>* #t142 = <core::int*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                 ^" in true as{TypeError} core::String*);
     else
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t185 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t144 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t183;
+  } =>#t142;
 }
 static method testForElement(dynamic dynVar, core::List<core::int*>* listInt, core::List<core::double*>* listDouble, core::int* index, core::Map<core::String*, core::int*>* mapStringInt, core::Map<core::String*, core::double*>* mapStringDouble) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t186 = <core::int*>[];
+    final core::List<core::int*>* #t145 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t186.{core::List::add}{Invariant}(42);
-  } =>#t186;
+      #t145.{core::List::add}{Invariant}(42);
+  } =>#t145;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t187 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t146 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t187.{core::Set::add}{Invariant}(42);
+      #t146.{core::Set::add}{Invariant}(42);
+    #t146.{core::Set::add}{Invariant}(null);
+  } =>#t146;
+  core::Map<core::String*, core::int*>* map10 = block {
+    final core::Map<core::String*, core::int*>* #t147 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t147.{core::Map::[]=}{Invariant}("bar", 42);
+    #t147.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t147;
+  core::List<dynamic>* list11 = block {
+    final core::List<dynamic>* #t148 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t148.{core::List::add}{Invariant}(dynVar);
+  } =>#t148;
+  core::Set<dynamic>* set11 = block {
+    final core::Set<dynamic>* #t149 = col::LinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t149.{core::Set::add}{Invariant}(dynVar);
+    #t149.{core::Set::add}{Invariant}(null);
+  } =>#t149;
+  core::Map<core::String*, dynamic>* map11 = block {
+    final core::Map<core::String*, dynamic>* #t150 = <core::String*, dynamic>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t150.{core::Map::[]=}{Invariant}("bar", dynVar);
+    #t150.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t150;
+  core::List<core::List<core::int*>*>* list12 = block {
+    final core::List<core::List<core::int*>*>* #t151 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t151.{core::List::add}{Invariant}(<core::int*>[42]);
+  } =>#t151;
+  core::Set<core::List<core::int*>*>* set12 = block {
+    final core::Set<core::List<core::int*>*>* #t152 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t152.{core::Set::add}{Invariant}(<core::int*>[42]);
+    #t152.{core::Set::add}{Invariant}(null);
+  } =>#t152;
+  core::Map<core::String*, core::List<core::int*>*>* map12 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t153 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t153.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
+    #t153.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t153;
+  core::List<core::int*>* list20 = block {
+    final core::List<core::int*>* #t154 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t154.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t154;
+  core::Set<core::int*>* set20 = block {
+    final core::Set<core::int*>* #t155 = col::LinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t155.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t155.{core::Set::add}{Invariant}(null);
+  } =>#t155;
+  core::Map<core::String*, core::int*>* map20 = block {
+    final core::Map<core::String*, core::int*>* #t156 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, core::int*>* #t157 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+        #t156.{core::Map::[]=}{Invariant}(#t157.{core::MapEntry::key}, #t157.{core::MapEntry::value});
+    #t156.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t156;
+  core::List<dynamic>* list21 = block {
+    final core::List<dynamic>* #t158 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t158.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t158;
+  core::Set<dynamic>* set21 = block {
+    final core::Set<dynamic>* #t159 = col::LinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t159.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t159.{core::Set::add}{Invariant}(null);
+  } =>#t159;
+  core::Map<core::String*, dynamic>* map21 = block {
+    final core::Map<core::String*, dynamic>* #t160 = <core::String*, dynamic>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, dynamic>* #t161 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+        #t160.{core::Map::[]=}{Invariant}(#t161.{core::MapEntry::key}, #t161.{core::MapEntry::value});
+    #t160.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t160;
+  core::List<core::List<core::int*>*>* list22 = block {
+    final core::List<core::List<core::int*>*>* #t162 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t162.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t162;
+  core::Set<core::List<core::int*>*>* set22 = block {
+    final core::Set<core::List<core::int*>*>* #t163 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t163.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t163.{core::Set::add}{Invariant}(null);
+  } =>#t163;
+  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t164 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t165 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
+        #t164.{core::Map::[]=}{Invariant}(#t165.{core::MapEntry::key}, #t165.{core::MapEntry::value});
+    #t164.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t164;
+  core::List<core::int*>* list30 = block {
+    final core::List<core::int*>* #t166 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t166.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t166;
+  core::Set<core::int*>* set30 = block {
+    final core::Set<core::int*>* #t167 = col::LinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t167.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t167.{core::Set::add}{Invariant}(null);
+  } =>#t167;
+  core::Map<core::String*, core::int*>* map30 = block {
+    final core::Map<core::String*, core::int*>* #t168 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::int*>* #t169 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
+          #t168.{core::Map::[]=}{Invariant}(#t169.{core::MapEntry::key}, #t169.{core::MapEntry::value});
+    #t168.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t168;
+  core::List<dynamic>* list31 = block {
+    final core::List<dynamic>* #t170 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t170.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t170;
+  core::Set<dynamic>* set31 = block {
+    final core::Set<dynamic>* #t171 = col::LinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t171.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t171.{core::Set::add}{Invariant}(null);
+  } =>#t171;
+  core::Map<core::String*, dynamic>* map31 = block {
+    final core::Map<core::String*, dynamic>* #t172 = <core::String*, dynamic>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, dynamic>* #t173 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
+          #t172.{core::Map::[]=}{Invariant}(#t173.{core::MapEntry::key}, #t173.{core::MapEntry::value});
+    #t172.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t172;
+  core::List<core::List<core::int*>*>* list33 = block {
+    final core::List<core::List<core::int*>*>* #t174 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t174.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t174;
+  core::Set<core::List<core::int*>*>* set33 = block {
+    final core::Set<core::List<core::int*>*>* #t175 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t175.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t175.{core::Set::add}{Invariant}(null);
+  } =>#t175;
+  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t176 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t177 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
+          #t176.{core::Map::[]=}{Invariant}(#t177.{core::MapEntry::key}, #t177.{core::MapEntry::value});
+    #t176.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t176;
+  core::List<core::List<core::int*>*>* list40 = block {
+    final core::List<core::List<core::int*>*>* #t178 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t178.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t178;
+  core::Set<core::List<core::int*>*>* set40 = block {
+    final core::Set<core::List<core::int*>*>* #t179 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t179.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t179.{core::Set::add}{Invariant}(null);
+  } =>#t179;
+  core::Map<core::String*, core::List<core::int*>*>* map40 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t180 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t181 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+        #t180.{core::Map::[]=}{Invariant}(#t181.{core::MapEntry::key}, #t181.{core::MapEntry::value});
+    #t180.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t180;
+  core::List<core::List<core::int*>*>* list41 = block {
+    final core::List<core::List<core::int*>*>* #t182 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t182.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t183 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t183.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t183);
+  } =>#t182;
+  core::Set<core::List<core::int*>*>* set41 = block {
+    final core::Set<core::List<core::int*>*>* #t184 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t184.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t185 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        #t185.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t185);
+    #t184.{core::Set::add}{Invariant}(null);
+  } =>#t184;
+  core::List<core::List<core::int*>*>* list42 = block {
+    final core::List<core::List<core::int*>*>* #t186 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t186.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t186;
+  core::Set<core::List<core::int*>*>* set42 = block {
+    final core::Set<core::List<core::int*>*>* #t187 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t187.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
     #t187.{core::Set::add}{Invariant}(null);
   } =>#t187;
-  core::Map<core::String*, core::int*>* map10 = block {
-    final core::Map<core::String*, core::int*>* #t188 = <core::String*, core::int*>{};
+  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t188 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t188.{core::Map::[]=}{Invariant}("bar", 42);
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t189 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t188.{core::Map::[]=}{Invariant}(#t189.{core::MapEntry::key}, #t189.{core::MapEntry::value});
     #t188.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t188;
-  core::List<dynamic>* list11 = block {
-    final core::List<dynamic>* #t189 = <dynamic>[];
+  core::List<core::int*>* list50 = block {
+    final core::List<core::int*>* #t190 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t189.{core::List::add}{Invariant}(dynVar);
-  } =>#t189;
-  core::Set<dynamic>* set11 = block {
-    final core::Set<dynamic>* #t190 = col::LinkedHashSet::•<dynamic>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t190.{core::Set::add}{Invariant}(dynVar);
-    #t190.{core::Set::add}{Invariant}(null);
+      #t190.{core::List::addAll}{Invariant}(<core::int*>[]);
   } =>#t190;
-  core::Map<core::String*, dynamic>* map11 = block {
-    final core::Map<core::String*, dynamic>* #t191 = <core::String*, dynamic>{};
+  core::Set<core::int*>* set50 = block {
+    final core::Set<core::int*>* #t191 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t191.{core::Map::[]=}{Invariant}("bar", dynVar);
-    #t191.{core::Map::[]=}{Invariant}("baz", null);
+      #t191.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t191.{core::Set::add}{Invariant}(null);
   } =>#t191;
-  core::List<core::List<core::int*>*>* list12 = block {
-    final core::List<core::List<core::int*>*>* #t192 = <core::List<core::int*>*>[];
+  core::Map<core::String*, core::int*>* map50 = block {
+    final core::Map<core::String*, core::int*>* #t192 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t192.{core::List::add}{Invariant}(<core::int*>[42]);
+      for (final core::MapEntry<core::String*, core::int*>* #t193 in <core::String*, core::int*>{}.{core::Map::entries})
+        #t192.{core::Map::[]=}{Invariant}(#t193.{core::MapEntry::key}, #t193.{core::MapEntry::value});
+    #t192.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t192;
-  core::Set<core::List<core::int*>*>* set12 = block {
-    final core::Set<core::List<core::int*>*>* #t193 = col::LinkedHashSet::•<core::List<core::int*>*>();
+  core::List<core::int*>* list51 = block {
+    final core::List<core::int*>* #t194 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t193.{core::Set::add}{Invariant}(<core::int*>[42]);
-    #t193.{core::Set::add}{Invariant}(null);
-  } =>#t193;
-  core::Map<core::String*, core::List<core::int*>*>* map12 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t194 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t194.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
-    #t194.{core::Map::[]=}{Invariant}("baz", null);
+      #t194.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t195 = col::LinkedHashSet::•<core::int*>();
+      } =>#t195);
   } =>#t194;
-  core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t195 = <core::int*>[];
+  core::Set<core::int*>* set51 = block {
+    final core::Set<core::int*>* #t196 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t196 in <core::int*>[42])
-        #t195.{core::List::add}{Invariant}(#t196);
-  } =>#t195;
-  core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t197 = col::LinkedHashSet::•<core::int*>();
+      #t196.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t197 = col::LinkedHashSet::•<core::int*>();
+      } =>#t197);
+    #t196.{core::Set::add}{Invariant}(null);
+  } =>#t196;
+  core::List<core::int*>* list52 = block {
+    final core::List<core::int*>* #t198 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t198 in <core::int*>[42])
-        #t197.{core::Set::add}{Invariant}(#t198);
-    #t197.{core::Set::add}{Invariant}(null);
-  } =>#t197;
-  core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t199 = <core::String*, core::int*>{};
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t198.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t198;
+  core::Set<core::int*>* set52 = block {
+    final core::Set<core::int*>* #t199 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::int*>* #t200 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
-        #t199.{core::Map::[]=}{Invariant}(#t200.{core::MapEntry::key}, #t200.{core::MapEntry::value});
-    #t199.{core::Map::[]=}{Invariant}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t199.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t199.{core::Set::add}{Invariant}(null);
   } =>#t199;
-  core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t201 = <dynamic>[];
+  core::List<core::List<core::int*>*>* list60 = block {
+    final core::List<core::List<core::int*>*>* #t200 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t202 in <dynamic>[dynVar])
-        #t201.{core::List::add}{Invariant}(#t202);
+      #t200.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t200;
+  core::Set<core::List<core::int*>*>* set60 = block {
+    final core::Set<core::List<core::int*>*>* #t201 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t201.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t201.{core::Set::add}{Invariant}(null);
   } =>#t201;
-  core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t203 = col::LinkedHashSet::•<dynamic>();
+  core::Map<core::String*, core::List<core::int*>*>* map60 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t202 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t204 in <dynamic>[dynVar])
-        #t203.{core::Set::add}{Invariant}(#t204);
-    #t203.{core::Set::add}{Invariant}(null);
-  } =>#t203;
-  core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t205 = <core::String*, dynamic>{};
+      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t203 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+        #t202.{core::Map::[]=}{Invariant}(#t203.{core::MapEntry::key}, #t203.{core::MapEntry::value});
+    #t202.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t202;
+  core::List<core::List<core::int*>*>* list61 = block {
+    final core::List<core::List<core::int*>*>* #t204 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, dynamic>* #t206 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
-        #t205.{core::Map::[]=}{Invariant}(#t206.{core::MapEntry::key}, #t206.{core::MapEntry::value});
-    #t205.{core::Map::[]=}{Invariant}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t204.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t204;
+  core::Set<core::List<core::int*>*>* set61 = block {
+    final core::Set<core::List<core::int*>*>* #t205 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t205.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t205.{core::Set::add}{Invariant}(null);
   } =>#t205;
-  core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t207 = <core::List<core::int*>*>[];
+  core::Map<core::String*, core::List<core::int*>*>* map61 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t206 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t208 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t207.{core::List::add}{Invariant}(#t208);
-  } =>#t207;
-  core::Set<core::List<core::int*>*>* set22 = block {
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t207 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
+          #t206.{core::Map::[]=}{Invariant}(#t207.{core::MapEntry::key}, #t207.{core::MapEntry::value});
+    #t206.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t206;
+  core::List<core::List<core::int*>*>* list70 = block {
+    final core::List<core::List<core::int*>*>* #t208 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t208.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t208;
+  core::Set<core::List<core::int*>*>* set70 = block {
     final core::Set<core::List<core::int*>*>* #t209 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t210 in <core::List<core::int*>*>[<core::int*>[42]])
-        #t209.{core::Set::add}{Invariant}(#t210);
+      #t209.{core::Set::add}{Invariant}(<core::int*>[]);
     #t209.{core::Set::add}{Invariant}(null);
   } =>#t209;
-  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t211 = <core::String*, core::List<core::int*>*>{};
+  core::Map<core::String*, core::List<core::int*>*>* map70 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t210 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t212 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
-        #t211.{core::Map::[]=}{Invariant}(#t212.{core::MapEntry::key}, #t212.{core::MapEntry::value});
-    #t211.{core::Map::[]=}{Invariant}("baz", null);
+      #t210.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t210.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t210;
+  core::List<core::List<core::int*>*>* list71 = block {
+    final core::List<core::List<core::int*>*>* #t211 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t211.{core::List::add}{Invariant}(<core::int*>[]);
   } =>#t211;
-  core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t213 = <core::int*>[];
+  core::Set<core::List<core::int*>*>* set71 = block {
+    final core::Set<core::List<core::int*>*>* #t212 = col::LinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t214 in <core::int*>[42])
-          #t213.{core::List::add}{Invariant}(#t214);
+        #t212.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t212.{core::Set::add}{Invariant}(null);
+  } =>#t212;
+  core::Map<core::String*, core::List<core::int*>*>* map71 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t213.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t213.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t213;
-  core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t215 = col::LinkedHashSet::•<core::int*>();
+  core::List<core::num*>* list80 = block {
+    final core::List<core::num*>* #t214 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t216 in <core::int*>[42])
-          #t215.{core::Set::add}{Invariant}(#t216);
+        #t214.{core::List::add}{Invariant}(42);
+      else
+        #t214.{core::List::add}{Invariant}(3.14);
+  } =>#t214;
+  core::Set<core::num*>* set80 = block {
+    final core::Set<core::num*>* #t215 = col::LinkedHashSet::•<core::num*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t215.{core::Set::add}{Invariant}(42);
+      else
+        #t215.{core::Set::add}{Invariant}(3.14);
     #t215.{core::Set::add}{Invariant}(null);
   } =>#t215;
-  core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t217 = <core::String*, core::int*>{};
+  core::Map<core::String*, core::num*>* map80 = block {
+    final core::Map<core::String*, core::num*>* #t216 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::int*>* #t218 in <core::String*, core::int*>{"bar": 42}.{core::Map::entries})
-          #t217.{core::Map::[]=}{Invariant}(#t218.{core::MapEntry::key}, #t218.{core::MapEntry::value});
-    #t217.{core::Map::[]=}{Invariant}("baz", null);
+        #t216.{core::Map::[]=}{Invariant}("bar", 42);
+      else
+        #t216.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t216.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t216;
+  core::List<core::num*>* list81 = block {
+    final core::List<core::num*>* #t217 = <core::num*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t217.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t217.{core::List::addAll}{Invariant}(listDouble);
   } =>#t217;
-  core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t219 = <dynamic>[];
+  core::Set<core::num*>* set81 = block {
+    final core::Set<core::num*>* #t218 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t220 in <dynamic>[dynVar])
-          #t219.{core::List::add}{Invariant}(#t220);
+        #t218.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t218.{core::Set::addAll}{Invariant}(listDouble);
+    #t218.{core::Set::add}{Invariant}(null);
+  } =>#t218;
+  core::Map<core::String*, core::num*>* map81 = block {
+    final core::Map<core::String*, core::num*>* #t219 = <core::String*, core::num*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::num*>* #t220 in mapStringInt.{core::Map::entries})
+          #t219.{core::Map::[]=}{Invariant}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<core::String*, core::num*>* #t221 in mapStringDouble.{core::Map::entries})
+          #t219.{core::Map::[]=}{Invariant}(#t221.{core::MapEntry::key}, #t221.{core::MapEntry::value});
+    #t219.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t219;
-  core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t221 = col::LinkedHashSet::•<dynamic>();
+  core::List<dynamic>* list82 = block {
+    final core::List<dynamic>* #t222 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t222 in <dynamic>[dynVar])
-          #t221.{core::Set::add}{Invariant}(#t222);
-    #t221.{core::Set::add}{Invariant}(null);
-  } =>#t221;
-  core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t223 = <core::String*, dynamic>{};
+        #t222.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t222.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t222;
+  core::Set<dynamic>* set82 = block {
+    final core::Set<dynamic>* #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, dynamic>* #t224 in <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries})
-          #t223.{core::Map::[]=}{Invariant}(#t224.{core::MapEntry::key}, #t224.{core::MapEntry::value});
-    #t223.{core::Map::[]=}{Invariant}("baz", null);
+        #t223.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t223.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t223.{core::Set::add}{Invariant}(null);
   } =>#t223;
-  core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t225 = <core::List<core::int*>*>[];
+  core::Map<dynamic, dynamic>* map82 = block {
+    final core::Map<dynamic, dynamic>* #t224 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t226 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t225.{core::List::add}{Invariant}(#t226);
-  } =>#t225;
-  core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t227 = col::LinkedHashSet::•<core::List<core::int*>*>();
+        for (final core::MapEntry<dynamic, dynamic>* #t225 in mapStringInt.{core::Map::entries})
+          #t224.{core::Map::[]=}{Invariant}(#t225.{core::MapEntry::key}, #t225.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<dynamic, dynamic>* #t226 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
+          #t224.{core::Map::[]=}{Invariant}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
+    #t224.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t224;
+  core::List<core::num*>* list83 = block {
+    final core::List<core::num*>* #t227 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t228 in <core::List<core::int*>*>[<core::int*>[42]])
-          #t227.{core::Set::add}{Invariant}(#t228);
-    #t227.{core::Set::add}{Invariant}(null);
+        #t227.{core::List::add}{Invariant}(42);
+      else
+        #t227.{core::List::addAll}{Invariant}(listDouble);
   } =>#t227;
-  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t229 = <core::String*, core::List<core::int*>*>{};
+  core::Set<core::num*>* set83 = block {
+    final core::Set<core::num*>* #t228 = col::LinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t230 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries})
+        #t228.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t228.{core::Set::add}{Invariant}(3.14);
+    #t228.{core::Set::add}{Invariant}(null);
+  } =>#t228;
+  core::Map<core::String*, core::num*>* map83 = block {
+    final core::Map<core::String*, core::num*>* #t229 = <core::String*, core::num*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        for (final core::MapEntry<core::String*, core::num*>* #t230 in mapStringInt.{core::Map::entries})
           #t229.{core::Map::[]=}{Invariant}(#t230.{core::MapEntry::key}, #t230.{core::MapEntry::value});
+      else
+        #t229.{core::Map::[]=}{Invariant}("bar", 3.14);
     #t229.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t229;
-  core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t231 = <core::List<core::int*>*>[];
+  core::List<core::int*>* list90 = block {
+    final core::List<core::int*>* #t231 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t232 in <core::List<core::int*>*>[<core::int*>[]])
-        #t231.{core::List::add}{Invariant}(#t232);
+      #t231.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
   } =>#t231;
-  core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t233 = col::LinkedHashSet::•<core::List<core::int*>*>();
+  core::Set<core::int*>* set90 = block {
+    final core::Set<core::int*>* #t232 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t234 in <core::List<core::int*>*>[<core::int*>[]])
-        #t233.{core::Set::add}{Invariant}(#t234);
-    #t233.{core::Set::add}{Invariant}(null);
+      #t232.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t232.{core::Set::add}{Invariant}(null);
+  } =>#t232;
+  core::Map<core::String*, core::int*>* map90 = block {
+    final core::Map<core::String*, core::int*>* #t233 = <core::String*, core::int*>{};
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t233.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t233.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t233;
-  core::Map<core::String*, core::List<core::int*>*>* map40 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t235 = <core::String*, core::List<core::int*>*>{};
+  core::List<core::int*>* list91 = block {
+    final core::List<core::int*>* #t234 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t236 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-        #t235.{core::Map::[]=}{Invariant}(#t236.{core::MapEntry::key}, #t236.{core::MapEntry::value});
-    #t235.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t235;
-  core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t237 = <core::List<core::int*>*>[];
+      for (final dynamic #t235 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t236 = #t235 as{TypeError} core::int*;
+        #t234.{core::List::add}{Invariant}(#t236);
+      }
+  } =>#t234;
+  core::Set<core::int*>* set91 = block {
+    final core::Set<core::int*>* #t237 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t238 in block {
-        final core::Set<core::List<core::int*>*>* #t239 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t239.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t239)
-        #t237.{core::List::add}{Invariant}(#t238);
+      for (final dynamic #t238 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+        final core::int* #t239 = #t238 as{TypeError} core::int*;
+        #t237.{core::Set::add}{Invariant}(#t239);
+      }
+    #t237.{core::Set::add}{Invariant}(null);
   } =>#t237;
-  core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t240 = col::LinkedHashSet::•<core::List<core::int*>*>();
+  core::Map<core::String*, core::int*>* map91 = block {
+    final core::Map<core::String*, core::int*>* #t240 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t241 in block {
-        final core::Set<core::List<core::int*>*>* #t242 = col::LinkedHashSet::•<core::List<core::int*>*>();
-        #t242.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t242)
-        #t240.{core::Set::add}{Invariant}(#t241);
-    #t240.{core::Set::add}{Invariant}(null);
+      for (final core::MapEntry<dynamic, dynamic>* #t241 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+        final core::String* #t242 = #t241.{core::MapEntry::key} as{TypeError} core::String*;
+        final core::int* #t243 = #t241.{core::MapEntry::value} as{TypeError} core::int*;
+        #t240.{core::Map::[]=}{Invariant}(#t242, #t243);
+      }
+    #t240.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t240;
-  core::List<core::List<core::int*>*>* list42 = block {
-    final core::List<core::List<core::int*>*>* #t243 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t244 in <core::List<core::int*>*>[<core::int*>[]])
-          #t243.{core::List::add}{Invariant}(#t244);
-  } =>#t243;
-  core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t245 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t246 in <core::List<core::int*>*>[<core::int*>[]])
-          #t245.{core::Set::add}{Invariant}(#t246);
-    #t245.{core::Set::add}{Invariant}(null);
-  } =>#t245;
-  core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t247 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t248 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t247.{core::Map::[]=}{Invariant}(#t248.{core::MapEntry::key}, #t248.{core::MapEntry::value});
-    #t247.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t247;
-  core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t249 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t250 in <core::int*>[])
-        #t249.{core::List::add}{Invariant}(#t250);
-  } =>#t249;
-  core::Set<core::int*>* set50 = block {
+  core::List<core::int*>* list100 = block {
+    final core::List<core::int*>* #t244 = <core::int*>[];
+    for (final core::int* #t245 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t244.{core::List::add}{Invariant}(42);
+  } =>#t244;
+  core::Set<core::int*>* set100 = block {
+    final core::Set<core::int*>* #t246 = col::LinkedHashSet::•<core::int*>();
+    for (final core::int* #t247 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t246.{core::Set::add}{Invariant}(42);
+  } =>#t246;
+  core::Map<core::String*, core::int*>* map100 = block {
+    final core::Map<core::String*, core::int*>* #t248 = <core::String*, core::int*>{};
+    for (final core::int* #t249 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t248.{core::Map::[]=}{Invariant}("bar", 42);
+  } =>#t248;
+  core::List<core::int*>* list110 = block {
+    final core::List<core::int*>* #t250 = <core::int*>[];
+    for (core::int* i in <core::int*>[1, 2, 3])
+      #t250.{core::List::add}{Invariant}(i);
+  } =>#t250;
+  core::Set<core::int*>* set110 = block {
     final core::Set<core::int*>* #t251 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t252 in <core::int*>[])
-        #t251.{core::Set::add}{Invariant}(#t252);
+    for (core::int* i in <core::int*>[1, 2, 3])
+      #t251.{core::Set::add}{Invariant}(i);
     #t251.{core::Set::add}{Invariant}(null);
   } =>#t251;
-  core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t253 = <core::String*, core::int*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::int*>* #t254 in <core::String*, core::int*>{}.{core::Map::entries})
-        #t253.{core::Map::[]=}{Invariant}(#t254.{core::MapEntry::key}, #t254.{core::MapEntry::value});
-    #t253.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t253;
-  core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t255 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t256 in block {
-        final core::Set<core::int*>* #t257 = col::LinkedHashSet::•<core::int*>();
-      } =>#t257)
-        #t255.{core::List::add}{Invariant}(#t256);
-  } =>#t255;
-  core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t258 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t259 in block {
-        final core::Set<core::int*>* #t260 = col::LinkedHashSet::•<core::int*>();
-      } =>#t260)
-        #t258.{core::Set::add}{Invariant}(#t259);
-    #t258.{core::Set::add}{Invariant}(null);
-  } =>#t258;
-  core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t261 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t262 in <core::int*>[])
-          #t261.{core::List::add}{Invariant}(#t262);
-  } =>#t261;
-  core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t263 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::int* #t264 in <core::int*>[])
-          #t263.{core::Set::add}{Invariant}(#t264);
-    #t263.{core::Set::add}{Invariant}(null);
-  } =>#t263;
-  core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t265 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t266 in <core::List<core::int*>*>[<core::int*>[]])
-        #t265.{core::List::add}{Invariant}(#t266);
-  } =>#t265;
-  core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t267 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::List<core::int*>* #t268 in <core::List<core::int*>*>[<core::int*>[]])
-        #t267.{core::Set::add}{Invariant}(#t268);
-    #t267.{core::Set::add}{Invariant}(null);
-  } =>#t267;
-  core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t269 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t270 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-        #t269.{core::Map::[]=}{Invariant}(#t270.{core::MapEntry::key}, #t270.{core::MapEntry::value});
-    #t269.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t269;
-  core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t271 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t272 in <core::List<core::int*>*>[<core::int*>[]])
-          #t271.{core::List::add}{Invariant}(#t272);
-  } =>#t271;
-  core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t273 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::List<core::int*>* #t274 in <core::List<core::int*>*>[<core::int*>[]])
-          #t273.{core::Set::add}{Invariant}(#t274);
-    #t273.{core::Set::add}{Invariant}(null);
-  } =>#t273;
-  core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t275 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t276 in <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries})
-          #t275.{core::Map::[]=}{Invariant}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value});
-    #t275.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t275;
-  core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t277 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t277.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t277;
-  core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t278 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t278.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t278.{core::Set::add}{Invariant}(null);
-  } =>#t278;
-  core::Map<core::String*, core::List<core::int*>*>* map70 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t279.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t279.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t279;
-  core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t280 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t280.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t280;
-  core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t281 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t281.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t281.{core::Set::add}{Invariant}(null);
-  } =>#t281;
-  core::Map<core::String*, core::List<core::int*>*>* map71 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t282 = <core::String*, core::List<core::int*>*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t282.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t282.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t282;
-  core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t283 = <core::num*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t283.{core::List::add}{Invariant}(42);
-      else
-        #t283.{core::List::add}{Invariant}(3.14);
-  } =>#t283;
-  core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t284 = col::LinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t284.{core::Set::add}{Invariant}(42);
-      else
-        #t284.{core::Set::add}{Invariant}(3.14);
-    #t284.{core::Set::add}{Invariant}(null);
-  } =>#t284;
-  core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t285 = <core::String*, core::num*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t285.{core::Map::[]=}{Invariant}("bar", 42);
-      else
-        #t285.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t285.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t285;
-  core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t286 = <core::num*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::num* #t287 in listInt)
-          #t286.{core::List::add}{Invariant}(#t287);
-      else
-        for (final core::num* #t288 in listDouble)
-          #t286.{core::List::add}{Invariant}(#t288);
-  } =>#t286;
-  core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t289 = col::LinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::num* #t290 in listInt)
-          #t289.{core::Set::add}{Invariant}(#t290);
-      else
-        for (final core::num* #t291 in listDouble)
-          #t289.{core::Set::add}{Invariant}(#t291);
-    #t289.{core::Set::add}{Invariant}(null);
-  } =>#t289;
-  core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t292 = <core::String*, core::num*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::num*>* #t293 in mapStringInt.{core::Map::entries})
-          #t292.{core::Map::[]=}{Invariant}(#t293.{core::MapEntry::key}, #t293.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<core::String*, core::num*>* #t294 in mapStringDouble.{core::Map::entries})
-          #t292.{core::Map::[]=}{Invariant}(#t294.{core::MapEntry::key}, #t294.{core::MapEntry::value});
-    #t292.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t292;
-  core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t295 = <dynamic>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t296 in listInt)
-          #t295.{core::List::add}{Invariant}(#t296);
-      else
-        for (final dynamic #t297 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-          #t295.{core::List::add}{Invariant}(#t297);
-  } =>#t295;
-  core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t298 = col::LinkedHashSet::•<dynamic>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final dynamic #t299 in listInt)
-          #t298.{core::Set::add}{Invariant}(#t299);
-      else
-        for (final dynamic #t300 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-          #t298.{core::Set::add}{Invariant}(#t300);
-    #t298.{core::Set::add}{Invariant}(null);
-  } =>#t298;
-  core::Map<dynamic, dynamic>* map82 = block {
-    final core::Map<dynamic, dynamic>* #t301 = <dynamic, dynamic>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<dynamic, dynamic>* #t302 in mapStringInt.{core::Map::entries})
-          #t301.{core::Map::[]=}{Invariant}(#t302.{core::MapEntry::key}, #t302.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<dynamic, dynamic>* #t303 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
-          #t301.{core::Map::[]=}{Invariant}(#t303.{core::MapEntry::key}, #t303.{core::MapEntry::value});
-    #t301.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t301;
-  core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t304 = <core::num*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t304.{core::List::add}{Invariant}(42);
-      else
-        for (final core::num* #t305 in listDouble)
-          #t304.{core::List::add}{Invariant}(#t305);
-  } =>#t304;
-  core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t306 = col::LinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::num* #t307 in listInt)
-          #t306.{core::Set::add}{Invariant}(#t307);
-      else
-        #t306.{core::Set::add}{Invariant}(3.14);
-    #t306.{core::Set::add}{Invariant}(null);
-  } =>#t306;
-  core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t308 = <core::String*, core::num*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        for (final core::MapEntry<core::String*, core::num*>* #t309 in mapStringInt.{core::Map::entries})
-          #t308.{core::Map::[]=}{Invariant}(#t309.{core::MapEntry::key}, #t309.{core::MapEntry::value});
-      else
-        #t308.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t308.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t308;
-  core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t310 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t310.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t310;
-  core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t311 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t311.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t311.{core::Set::add}{Invariant}(null);
-  } =>#t311;
-  core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t312 = <core::String*, core::int*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t312.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t312.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t312;
-  core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t313 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t314 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t315 = #t314 as{TypeError} core::int*;
-        #t313.{core::List::add}{Invariant}(#t315);
-      }
-  } =>#t313;
-  core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t316 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final dynamic #t317 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-        final core::int* #t318 = #t317 as{TypeError} core::int*;
-        #t316.{core::Set::add}{Invariant}(#t318);
-      }
-    #t316.{core::Set::add}{Invariant}(null);
-  } =>#t316;
-  core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t319 = <core::String*, core::int*>{};
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<dynamic, dynamic>* #t320 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-        final core::String* #t321 = #t320.{core::MapEntry::key} as{TypeError} core::String*;
-        final core::int* #t322 = #t320.{core::MapEntry::value} as{TypeError} core::int*;
-        #t319.{core::Map::[]=}{Invariant}(#t321, #t322);
-      }
-    #t319.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t319;
-  core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t323 = <core::int*>[];
-    for (final core::int* #t324 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t323.{core::List::add}{Invariant}(42);
-  } =>#t323;
-  core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t325 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t326 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t325.{core::Set::add}{Invariant}(42);
-  } =>#t325;
-  core::Map<core::String*, core::int*>* map100 = block {
-    final core::Map<core::String*, core::int*>* #t327 = <core::String*, core::int*>{};
-    for (final core::int* #t328 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t327.{core::Map::[]=}{Invariant}("bar", 42);
-  } =>#t327;
-  core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t329 = <core::int*>[];
-    for (core::int* i in <core::int*>[1, 2, 3])
-      #t329.{core::List::add}{Invariant}(i);
-  } =>#t329;
-  core::Set<core::int*>* set110 = block {
-    final core::Set<core::int*>* #t330 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i in <core::int*>[1, 2, 3])
-      #t330.{core::Set::add}{Invariant}(i);
-    #t330.{core::Set::add}{Invariant}(null);
-  } =>#t330;
   core::Map<core::String*, core::int*>* map110 = block {
-    final core::Map<core::String*, core::int*>* #t331 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t252 = <core::String*, core::int*>{};
     for (core::int* i in <core::int*>[1, 2, 3])
-      #t331.{core::Map::[]=}{Invariant}("bar", i);
-    #t331.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t331;
+      #t252.{core::Map::[]=}{Invariant}("bar", i);
+    #t252.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t252;
   core::List<core::int*>* list120 = block {
-    final core::List<core::int*>* #t332 = <core::int*>[];
+    final core::List<core::int*>* #t253 = <core::int*>[];
     for (dynamic i in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t332.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
-  } =>#t332;
+      #t253.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+  } =>#t253;
   core::Set<core::int*>* set120 = block {
-    final core::Set<core::int*>* #t333 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t254 = col::LinkedHashSet::•<core::int*>();
     for (dynamic i in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t333.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
-    #t333.{core::Set::add}{Invariant}(null);
-  } =>#t333;
+      #t254.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+    #t254.{core::Set::add}{Invariant}(null);
+  } =>#t254;
   core::Map<core::String*, core::int*>* map120 = block {
-    final core::Map<core::String*, core::int*>* #t334 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t255 = <core::String*, core::int*>{};
     for (dynamic i in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t334.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
-    #t334.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t334;
+      #t255.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
+    #t255.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t255;
   core::List<core::int*>* list130 = block {
-    final core::List<core::int*>* #t335 = <core::int*>[];
+    final core::List<core::int*>* #t256 = <core::int*>[];
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t335.{core::List::add}{Invariant}(i);
-  } =>#t335;
+      #t256.{core::List::add}{Invariant}(i);
+  } =>#t256;
   core::Set<core::int*>* set130 = block {
-    final core::Set<core::int*>* #t336 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t257 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t336.{core::Set::add}{Invariant}(i);
-  } =>#t336;
+      #t257.{core::Set::add}{Invariant}(i);
+  } =>#t257;
   core::Map<core::int*, core::int*>* map130 = block {
-    final core::Map<core::int*, core::int*>* #t337 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t258 = <core::int*, core::int*>{};
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t337.{core::Map::[]=}{Invariant}(i, i);
-  } =>#t337;
+      #t258.{core::Map::[]=}{Invariant}(i, i);
+  } =>#t258;
 }
 static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic async {
   block {
-    final core::List<core::int*>* #t338 = <core::int*>[];
+    final core::List<core::int*>* #t259 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t338.{core::List::add}{Invariant}(let final<BottomType> #t339 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:212:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t259.{core::List::add}{Invariant}(let final<BottomType> #t260 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:212:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
                                             ^" in "bar" as{TypeError} core::int*);
-  } =>#t338;
+  } =>#t259;
   block {
-    final core::Set<core::int*>* #t340 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t261 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t340.{core::Set::add}{Invariant}(let final<BottomType> #t341 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:213:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t261.{core::Set::add}{Invariant}(let final<BottomType> #t262 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:213:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
                                             ^" in "bar" as{TypeError} core::int*);
-    #t340.{core::Set::add}{Invariant}(null);
-  } =>#t340;
+    #t261.{core::Set::add}{Invariant}(null);
+  } =>#t261;
   block {
-    final core::Map<core::int*, core::int*>* #t342 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t263 = <core::int*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t264 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t265 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                         ^" in "bar" as{TypeError} core::int*);
-    #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t266 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                                ^" in "baz" as{TypeError} core::int*, null);
-  } =>#t342;
+  } =>#t263;
   block {
-    final core::List<core::int*>* #t346 = <core::int*>[];
+    final core::List<core::int*>* #t267 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t347 in <core::int*>[let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t267.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*])
-        #t346.{core::List::add}{Invariant}(#t347);
-  } =>#t346;
+                                                ^" in "bar" as{TypeError} core::int*]);
+  } =>#t267;
   block {
-    final core::Set<core::int*>* #t349 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t269 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::int* #t350 in <core::int*>[let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t269.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t270 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*])
-        #t349.{core::Set::add}{Invariant}(#t350);
-    #t349.{core::Set::add}{Invariant}(null);
-  } =>#t349;
+                                                ^" in "bar" as{TypeError} core::int*]);
+    #t269.{core::Set::add}{Invariant}(null);
+  } =>#t269;
   block {
-    final core::Map<core::int*, core::int*>* #t352 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t271 = <core::int*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::int*, core::int*>* #t353 in <core::int*, core::int*>{let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      for (final core::MapEntry<core::int*, core::int*>* #t272 in <core::int*, core::int*>{let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t274 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
-        #t352.{core::Map::[]=}{Invariant}(#t353.{core::MapEntry::key}, #t353.{core::MapEntry::value});
-    #t352.{core::Map::[]=}{Invariant}(let final<BottomType> #t356 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+        #t271.{core::Map::[]=}{Invariant}(#t272.{core::MapEntry::key}, #t272.{core::MapEntry::value});
+    #t271.{core::Map::[]=}{Invariant}(let final<BottomType> #t275 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int*, null);
-  } =>#t352;
+  } =>#t271;
   block {
-    final core::List<core::int*>* #t357 = <core::int*>[];
+    final core::List<core::int*>* #t276 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t357.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:218:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t276.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:218:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...map];
                                                ^");
-  } =>#t357;
+  } =>#t276;
   block {
-    final core::Set<core::int*>* #t358 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t277 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t358.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:219:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t277.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:219:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null};
                                                ^");
-    #t358.{core::Set::add}{Invariant}(null);
-  } =>#t358;
+    #t277.{core::Set::add}{Invariant}(null);
+  } =>#t277;
   <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:220:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
@@ -1920,66 +1839,66 @@
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
                                                     ^": null};
   block {
-    final core::List<core::String*>* #t359 = <core::String*>[];
+    final core::List<core::String*>* #t278 = <core::String*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t359.{core::List::add}{Invariant}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+        #t278.{core::List::add}{Invariant}(let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                              ^" in 42 as{TypeError} core::String*);
       else
-        #t359.{core::List::add}{Invariant}(let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+        #t278.{core::List::add}{Invariant}(let final<BottomType> #t280 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                                      ^" in 3.14 as{TypeError} core::String*);
-  } =>#t359;
+  } =>#t278;
   block {
-    final core::Set<core::String*>* #t362 = col::LinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t281 = col::LinkedHashSet::•<core::String*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t362.{core::Set::add}{Invariant}(let final<BottomType> #t363 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+        #t281.{core::Set::add}{Invariant}(let final<BottomType> #t282 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                              ^" in 42 as{TypeError} core::String*);
       else
-        #t362.{core::Set::add}{Invariant}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+        #t281.{core::Set::add}{Invariant}(let final<BottomType> #t283 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                                      ^" in 3.14 as{TypeError} core::String*);
-    #t362.{core::Set::add}{Invariant}(null);
-  } =>#t362;
+    #t281.{core::Set::add}{Invariant}(null);
+  } =>#t281;
   block {
-    final core::Map<core::String*, core::String*>* #t365 = <core::String*, core::String*>{};
+    final core::Map<core::String*, core::String*>* #t284 = <core::String*, core::String*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t366 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+        #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t285 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                             ^" in 42 as{TypeError} core::String*);
       else
-        #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+        #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t286 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                                            ^" in 3.14 as{TypeError} core::String*);
-    #t365.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t365;
+    #t284.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t284;
   block {
-    final core::List<core::int*>* #t368 = <core::int*>[];
+    final core::List<core::int*>* #t287 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t368.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:224:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t287.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:224:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42];
                                                              ^");
       else
-        #t368.{core::List::add}{Invariant}(42);
-  } =>#t368;
+        #t287.{core::List::add}{Invariant}(42);
+  } =>#t287;
   block {
-    final core::Set<core::int*>* #t369 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t288 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t369.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:225:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t288.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:225:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null};
                                                              ^");
       else
-        #t369.{core::Set::add}{Invariant}(42);
-    #t369.{core::Set::add}{Invariant}(null);
-  } =>#t369;
+        #t288.{core::Set::add}{Invariant}(42);
+    #t288.{core::Set::add}{Invariant}(null);
+  } =>#t288;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
@@ -1988,28 +1907,28 @@
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
                                                                      ^": null};
   block {
-    final core::List<core::int*>* #t370 = <core::int*>[];
+    final core::List<core::int*>* #t289 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t370.{core::List::add}{Invariant}(42);
+        #t289.{core::List::add}{Invariant}(42);
       else
-        #t370.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:227:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t289.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:227:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map];
                                                                      ^");
-  } =>#t370;
+  } =>#t289;
   block {
-    final core::Set<core::int*>* #t371 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t290 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t371.{core::Set::add}{Invariant}(42);
+        #t290.{core::Set::add}{Invariant}(42);
       else
-        #t371.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:228:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t290.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:228:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null};
                                                                      ^");
-    #t371.{core::Set::add}{Invariant}(null);
-  } =>#t371;
+    #t290.{core::Set::add}{Invariant}(null);
+  } =>#t290;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:229:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
@@ -2019,218 +1938,218 @@
                                                                                     ^": null};
   final core::int* i = 0;
   block {
-    final core::List<core::int*>* #t372 = <core::int*>[];
-    for (final core::int* #t373 in <core::int*>[1]) {
+    final core::List<core::int*>* #t291 = <core::int*>[];
+    for (final core::int* #t292 in <core::int*>[1]) {
       invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
-      #t372.{core::List::add}{Invariant}(i);
+      #t291.{core::List::add}{Invariant}(i);
     }
-  } =>#t372;
+  } =>#t291;
   block {
-    final core::Set<core::int*>* #t374 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t375 in <core::int*>[1]) {
+    final core::Set<core::int*>* #t293 = col::LinkedHashSet::•<core::int*>();
+    for (final core::int* #t294 in <core::int*>[1]) {
       invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
-      #t374.{core::Set::add}{Invariant}(i);
+      #t293.{core::Set::add}{Invariant}(i);
     }
-    #t374.{core::Set::add}{Invariant}(null);
-  } =>#t374;
+    #t293.{core::Set::add}{Invariant}(null);
+  } =>#t293;
   block {
-    final core::Map<core::String*, core::int*>* #t376 = <core::String*, core::int*>{};
-    for (final core::int* #t377 in <core::int*>[1]) {
+    final core::Map<core::String*, core::int*>* #t295 = <core::String*, core::int*>{};
+    for (final core::int* #t296 in <core::int*>[1]) {
       invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
-      #t376.{core::Map::[]=}{Invariant}("bar", i);
+      #t295.{core::Map::[]=}{Invariant}("bar", i);
     }
-    #t376.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t376;
+    #t295.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t295;
   core::List<dynamic>* list10 = block {
-    final core::List<dynamic>* #t378 = <dynamic>[];
-    for (dynamic i in let final<BottomType> #t379 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::List<dynamic>* #t297 = <dynamic>[];
+    for (dynamic i in let final<BottomType> #t298 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*)
-      #t378.{core::List::add}{Invariant}(i);
-  } =>#t378;
+      #t297.{core::List::add}{Invariant}(i);
+  } =>#t297;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t380 = col::LinkedHashSet::•<dynamic>();
-    for (dynamic i in let final<BottomType> #t381 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::Set<dynamic>* #t299 = col::LinkedHashSet::•<dynamic>();
+    for (dynamic i in let final<BottomType> #t300 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*)
-      #t380.{core::Set::add}{Invariant}(i);
-    #t380.{core::Set::add}{Invariant}(null);
-  } =>#t380;
+      #t299.{core::Set::add}{Invariant}(i);
+    #t299.{core::Set::add}{Invariant}(null);
+  } =>#t299;
   core::Map<core::String*, dynamic>* map10 = block {
-    final core::Map<core::String*, dynamic>* #t382 = <core::String*, dynamic>{};
-    for (dynamic i in let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::Map<core::String*, dynamic>* #t301 = <core::String*, dynamic>{};
+    for (dynamic i in let final<BottomType> #t302 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*)
-      #t382.{core::Map::[]=}{Invariant}("bar", i);
-    #t382.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t382;
+      #t301.{core::Map::[]=}{Invariant}("bar", i);
+    #t301.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t301;
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t384 = <core::int*>[];
-    for (core::int* i in <core::int*>[let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t303 = <core::int*>[];
+    for (core::int* i in <core::int*>[let final<BottomType> #t304 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t386 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t305 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int*])
-      #t384.{core::List::add}{Invariant}(i);
-  } =>#t384;
+      #t303.{core::List::add}{Invariant}(i);
+  } =>#t303;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t387 = col::LinkedHashSet::•<core::int*>();
-    for (core::int* i in <core::int*>[let final<BottomType> #t388 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t306 = col::LinkedHashSet::•<core::int*>();
+    for (core::int* i in <core::int*>[let final<BottomType> #t307 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t308 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int*])
-      #t387.{core::Set::add}{Invariant}(i);
-    #t387.{core::Set::add}{Invariant}(null);
-  } =>#t387;
+      #t306.{core::Set::add}{Invariant}(i);
+    #t306.{core::Set::add}{Invariant}(null);
+  } =>#t306;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t390 = <core::String*, core::int*>{};
-    for (core::int* i in <core::int*>[let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String*, core::int*>* #t309 = <core::String*, core::int*>{};
+    for (core::int* i in <core::int*>[let final<BottomType> #t310 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t311 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int*])
-      #t390.{core::Map::[]=}{Invariant}("bar", i);
-    #t390.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t390;
+      #t309.{core::Map::[]=}{Invariant}("bar", i);
+    #t309.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t309;
   core::List<dynamic>* list30 = block {
-    final core::List<dynamic>* #t393 = <dynamic>[];
-    await for (dynamic i in let final<BottomType> #t394 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::List<dynamic>* #t312 = <dynamic>[];
+    await for (dynamic i in let final<BottomType> #t313 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*)
-      #t393.{core::List::add}{Invariant}(i);
-  } =>#t393;
+      #t312.{core::List::add}{Invariant}(i);
+  } =>#t312;
   core::Set<dynamic>* set30 = block {
-    final core::Set<dynamic>* #t395 = col::LinkedHashSet::•<dynamic>();
-    await for (dynamic i in let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::Set<dynamic>* #t314 = col::LinkedHashSet::•<dynamic>();
+    await for (dynamic i in let final<BottomType> #t315 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*)
-      #t395.{core::Set::add}{Invariant}(i);
-    #t395.{core::Set::add}{Invariant}(null);
-  } =>#t395;
+      #t314.{core::Set::add}{Invariant}(i);
+    #t314.{core::Set::add}{Invariant}(null);
+  } =>#t314;
   core::Map<core::String*, dynamic>* map30 = block {
-    final core::Map<core::String*, dynamic>* #t397 = <core::String*, dynamic>{};
-    await for (dynamic i in let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::Map<core::String*, dynamic>* #t316 = <core::String*, dynamic>{};
+    await for (dynamic i in let final<BottomType> #t317 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*)
-      #t397.{core::Map::[]=}{Invariant}("bar", i);
-    #t397.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t397;
+      #t316.{core::Map::[]=}{Invariant}("bar", i);
+    #t316.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t316;
   core::List<core::int*>* list40 = block {
-    final core::List<core::int*>* #t399 = <core::int*>[];
-    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t400 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t318 = <core::int*>[];
+    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t319 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t401 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t320 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int*]))
-      #t399.{core::List::add}{Invariant}(i);
-  } =>#t399;
+      #t318.{core::List::add}{Invariant}(i);
+  } =>#t318;
   core::Set<core::int*>* set40 = block {
-    final core::Set<core::int*>* #t402 = col::LinkedHashSet::•<core::int*>();
-    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t321 = col::LinkedHashSet::•<core::int*>();
+    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t322 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int*]))
-      #t402.{core::Set::add}{Invariant}(i);
-    #t402.{core::Set::add}{Invariant}(null);
-  } =>#t402;
+      #t321.{core::Set::add}{Invariant}(i);
+    #t321.{core::Set::add}{Invariant}(null);
+  } =>#t321;
   core::Map<core::String*, core::int*>* map40 = block {
-    final core::Map<core::String*, core::int*>* #t405 = <core::String*, core::int*>{};
-    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t406 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String*, core::int*>* #t324 = <core::String*, core::int*>{};
+    await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t325 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t407 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t326 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int*]))
-      #t405.{core::Map::[]=}{Invariant}("bar", i);
-    #t405.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t405;
+      #t324.{core::Map::[]=}{Invariant}("bar", i);
+    #t324.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t324;
   core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t408 = <core::int*>[];
+    final core::List<core::int*>* #t327 = <core::int*>[];
     for (; ; )
-      #t408.{core::List::add}{Invariant}(42);
-  } =>#t408;
+      #t327.{core::List::add}{Invariant}(42);
+  } =>#t327;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t409 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t328 = col::LinkedHashSet::•<core::int*>();
     for (; ; )
-      #t409.{core::Set::add}{Invariant}(42);
-    #t409.{core::Set::add}{Invariant}(null);
-  } =>#t409;
+      #t328.{core::Set::add}{Invariant}(42);
+    #t328.{core::Set::add}{Invariant}(null);
+  } =>#t328;
   core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t410 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t329 = <core::String*, core::int*>{};
     for (; ; )
-      #t410.{core::Map::[]=}{Invariant}("bar", 42);
-    #t410.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t410;
+      #t329.{core::Map::[]=}{Invariant}("bar", 42);
+    #t329.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t329;
   core::List<core::int*>* list60 = block {
-    final core::List<core::int*>* #t411 = <core::int*>[];
-    for (; let final<BottomType> #t412 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:251:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int*>* #t330 = <core::int*>[];
+    for (; let final<BottomType> #t331 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:251:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool*; )
-      #t411.{core::List::add}{Invariant}(42);
-  } =>#t411;
+      #t330.{core::List::add}{Invariant}(42);
+  } =>#t330;
   core::Set<core::int*>* set60 = block {
-    final core::Set<core::int*>* #t413 = col::LinkedHashSet::•<core::int*>();
-    for (; let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:252:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int*>* #t332 = col::LinkedHashSet::•<core::int*>();
+    for (; let final<BottomType> #t333 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:252:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-      #t413.{core::Set::add}{Invariant}(42);
-    #t413.{core::Set::add}{Invariant}(null);
-  } =>#t413;
+      #t332.{core::Set::add}{Invariant}(42);
+    #t332.{core::Set::add}{Invariant}(null);
+  } =>#t332;
   core::Map<core::String*, core::int*>* map60 = block {
-    final core::Map<core::String*, core::int*>* #t415 = <core::String*, core::int*>{};
-    for (; let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:253:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::String*, core::int*>* #t334 = <core::String*, core::int*>{};
+    for (; let final<BottomType> #t335 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:253:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-      #t415.{core::Map::[]=}{Invariant}("bar", 42);
-    #t415.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t415;
+      #t334.{core::Map::[]=}{Invariant}("bar", 42);
+    #t334.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t334;
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
   block {
-    final core::List<core::int*>* #t417 = <core::int*>[];
+    final core::List<core::int*>* #t336 = <core::int*>[];
     await for (core::int* i in stream)
-      #t417.{core::List::add}{Invariant}(i);
-  } =>#t417;
+      #t336.{core::List::add}{Invariant}(i);
+  } =>#t336;
   block {
-    final core::Set<core::int*>* #t418 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t337 = col::LinkedHashSet::•<core::int*>();
     await for (core::int* i in stream)
-      #t418.{core::Set::add}{Invariant}(i);
-  } =>#t418;
+      #t337.{core::Set::add}{Invariant}(i);
+  } =>#t337;
   block {
-    final core::Map<core::String*, core::int*>* #t419 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t338 = <core::String*, core::int*>{};
     await for (core::int* i in stream)
-      #t419.{core::Map::[]=}{Invariant}("bar", i);
-  } =>#t419;
+      #t338.{core::Map::[]=}{Invariant}("bar", i);
+  } =>#t338;
 }
 static method testPromotion(self::A* a) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t420 = <core::int*>[];
+    final core::List<core::int*>* #t339 = <core::int*>[];
     if(a is self::B*)
-      #t420.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t420;
+      #t339.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t339;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t421 = col::LinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t340 = col::LinkedHashSet::•<core::int*>();
     if(a is self::B*)
-      #t421.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t421;
+      #t340.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t340;
   core::Map<core::int*, core::int*>* map10 = block {
-    final core::Map<core::int*, core::int*>* #t422 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t341 = <core::int*, core::int*>{};
     if(a is self::B*)
-      #t422.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
-  } =>#t422;
+      #t341.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
+  } =>#t341;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
index b843b32..6adb0fe 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
@@ -505,793 +505,588 @@
   } =>#t9;
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t10 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::List::add}{Invariant}(#t11);
-      }
-    }
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t10.{core::List::addAll}{Invariant}(<core::int*>[42]);
   } =>#t10;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t12 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t13 = :sync-for-iterator.{core::Iterator::current};
-        #t12.{core::Set::add}{Invariant}(#t13);
-      }
-    }
-    #t12.{core::Set::add}{Invariant}(null);
-  } =>#t12;
+    final core::Set<core::int*>* #t11 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t11.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t11.{core::Set::add}{Invariant}(null);
+  } =>#t11;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
-        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
       }
     }
-    #t14.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t14;
+    #t12.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t12;
   core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t16 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::List::add}{Invariant}(#t17);
-      }
-    }
-  } =>#t16;
+    final core::List<dynamic>* #t14 = <dynamic>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t14.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t14;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t18 = new col::_CompactLinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Set::add}{Invariant}(#t19);
-      }
-    }
-    #t18.{core::Set::add}{Invariant}(null);
-  } =>#t18;
+    final core::Set<dynamic>* #t15 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t15.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t15.{core::Set::add}{Invariant}(null);
+  } =>#t15;
   core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t20 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t16 = <core::String*, dynamic>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, dynamic>* #t21 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<core::String*, dynamic>* #t17 = :sync-for-iterator.{core::Iterator::current};
+        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+      }
+    }
+    #t16.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t16;
+  core::List<core::List<core::int*>*>* list22 = block {
+    final core::List<core::List<core::int*>*>* #t18 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t18.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t18;
+  core::Set<core::List<core::int*>*>* set22 = block {
+    final core::Set<core::List<core::int*>*>* #t19 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t19.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t19.{core::Set::add}{Invariant}(null);
+  } =>#t19;
+  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t20 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t21 = :sync-for-iterator.{core::Iterator::current};
         #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
       }
     }
     #t20.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t20;
-  core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t22 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t23 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::List::add}{Invariant}(#t23);
-      }
-    }
-  } =>#t22;
-  core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t24 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
-        #t24.{core::Set::add}{Invariant}(#t25);
-      }
-    }
-    #t24.{core::Set::add}{Invariant}(null);
-  } =>#t24;
-  core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t26 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t27 = :sync-for-iterator.{core::Iterator::current};
-        #t26.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
-      }
-    }
-    #t26.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t26;
   core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t28 = <core::int*>[];
+    final core::List<core::int*>* #t22 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
-          #t28.{core::List::add}{Invariant}(#t29);
-        }
-      }
-  } =>#t28;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t22.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t22;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t30 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t23 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t31 = :sync-for-iterator.{core::Iterator::current};
-          #t30.{core::Set::add}{Invariant}(#t31);
-        }
-      }
-    #t30.{core::Set::add}{Invariant}(null);
-  } =>#t30;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t23.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t23.{core::Set::add}{Invariant}(null);
+  } =>#t23;
   core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t32 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t24 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::int*>* #t33 = :sync-for-iterator.{core::Iterator::current};
+          final core::MapEntry<core::String*, core::int*>* #t25 = :sync-for-iterator.{core::Iterator::current};
+          #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
+        }
+      }
+    #t24.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t24;
+  core::List<dynamic>* list31 = block {
+    final core::List<dynamic>* #t26 = <dynamic>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t26.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t26;
+  core::Set<dynamic>* set31 = block {
+    final core::Set<dynamic>* #t27 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t27.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t27.{core::Set::add}{Invariant}(null);
+  } =>#t27;
+  core::Map<core::String*, dynamic>* map31 = block {
+    final core::Map<core::String*, dynamic>* #t28 = <core::String*, dynamic>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
+        core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
+        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+          final core::MapEntry<core::String*, dynamic>* #t29 = :sync-for-iterator.{core::Iterator::current};
+          #t28.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
+        }
+      }
+    #t28.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t28;
+  core::List<core::List<core::int*>*>* list33 = block {
+    final core::List<core::List<core::int*>*>* #t30 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t30.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t30;
+  core::Set<core::List<core::int*>*>* set33 = block {
+    final core::Set<core::List<core::int*>*>* #t31 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t31.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t31.{core::Set::add}{Invariant}(null);
+  } =>#t31;
+  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
+        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
+        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 = :sync-for-iterator.{core::Iterator::current};
           #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
         }
       }
     #t32.{core::Map::[]=}{Invariant}("baz", null);
   } =>#t32;
-  core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t34 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
-          #t34.{core::List::add}{Invariant}(#t35);
-        }
-      }
-  } =>#t34;
-  core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t36 = new col::_CompactLinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t37 = :sync-for-iterator.{core::Iterator::current};
-          #t36.{core::Set::add}{Invariant}(#t37);
-        }
-      }
-    #t36.{core::Set::add}{Invariant}(null);
-  } =>#t36;
-  core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t38 = <core::String*, dynamic>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, dynamic>* #t39 = :sync-for-iterator.{core::Iterator::current};
-          #t38.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
-        }
-      }
-    #t38.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t38;
-  core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t41 = :sync-for-iterator.{core::Iterator::current};
-          #t40.{core::List::add}{Invariant}(#t41);
-        }
-      }
-  } =>#t40;
-  core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t42 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t43 = :sync-for-iterator.{core::Iterator::current};
-          #t42.{core::Set::add}{Invariant}(#t43);
-        }
-      }
-    #t42.{core::Set::add}{Invariant}(null);
-  } =>#t42;
-  core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t44 = <core::String*, core::List<core::int*>*>{};
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t45 = :sync-for-iterator.{core::Iterator::current};
-          #t44.{core::Map::[]=}{Invariant}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
-        }
-      }
-    #t44.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t44;
   core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t46 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
-        #t46.{core::List::add}{Invariant}(#t47);
-      }
-    }
-  } =>#t46;
+    final core::List<core::List<core::int*>*>* #t34 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t34.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t34;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t48 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t49 = :sync-for-iterator.{core::Iterator::current};
-        #t48.{core::Set::add}{Invariant}(#t49);
-      }
-    }
-    #t48.{core::Set::add}{Invariant}(null);
-  } =>#t48;
+    final core::Set<core::List<core::int*>*>* #t35 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t35.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t35.{core::Set::add}{Invariant}(null);
+  } =>#t35;
   core::Map<core::String*, core::List<core::int*>*>* map40 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:41:34: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
   Map<String, List<int>> map40 = {if (oracle(\"foo\")) ...{\"bar\", []}, \"baz\": null};
                                  ^";
   core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t50 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t51 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t51.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t51).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t52 = :sync-for-iterator.{core::Iterator::current};
-        #t50.{core::List::add}{Invariant}(#t52);
-      }
-    }
-  } =>#t50;
+    final core::List<core::List<core::int*>*>* #t36 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t36.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t37 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t37.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t37);
+  } =>#t36;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t53 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t54 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t54.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t54).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t55 = :sync-for-iterator.{core::Iterator::current};
-        #t53.{core::Set::add}{Invariant}(#t55);
-      }
-    }
-    #t53.{core::Set::add}{Invariant}(null);
-  } =>#t53;
+    final core::Set<core::List<core::int*>*>* #t38 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t38.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t39 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t39.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t39);
+    #t38.{core::Set::add}{Invariant}(null);
+  } =>#t38;
   core::List<core::List<core::int*>*>* list42 = block {
-    final core::List<core::List<core::int*>*>* #t56 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t40 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t57 = :sync-for-iterator.{core::Iterator::current};
-          #t56.{core::List::add}{Invariant}(#t57);
-        }
-      }
-  } =>#t56;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t40.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t40;
   core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t58 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t41 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
-          #t58.{core::Set::add}{Invariant}(#t59);
-        }
-      }
-    #t58.{core::Set::add}{Invariant}(null);
-  } =>#t58;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t41.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t41.{core::Set::add}{Invariant}(null);
+  } =>#t41;
   core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t60 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t61 = :sync-for-iterator.{core::Iterator::current};
-          #t60.{core::Map::[]=}{Invariant}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
+          #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
         }
       }
-    #t60.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t60;
+    #t42.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t42;
   core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t62 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t63 = :sync-for-iterator.{core::Iterator::current};
-        #t62.{core::List::add}{Invariant}(#t63);
-      }
-    }
-  } =>#t62;
+    final core::List<core::int*>* #t44 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t44.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t44;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t64 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t65 = :sync-for-iterator.{core::Iterator::current};
-        #t64.{core::Set::add}{Invariant}(#t65);
-      }
-    }
-    #t64.{core::Set::add}{Invariant}(null);
-  } =>#t64;
+    final core::Set<core::int*>* #t45 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t45.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t45.{core::Set::add}{Invariant}(null);
+  } =>#t45;
   core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t66 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t67 = :sync-for-iterator.{core::Iterator::current};
-        #t66.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
+        #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
       }
     }
-    #t66.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t66;
+    #t46.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t46;
   core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t68 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t69 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t69).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t70 = :sync-for-iterator.{core::Iterator::current};
-        #t68.{core::List::add}{Invariant}(#t70);
-      }
-    }
-  } =>#t68;
+    final core::List<core::int*>* #t48 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t48.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t49 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t49);
+  } =>#t48;
   core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t71 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t72 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t72).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t73 = :sync-for-iterator.{core::Iterator::current};
-        #t71.{core::Set::add}{Invariant}(#t73);
-      }
-    }
-    #t71.{core::Set::add}{Invariant}(null);
-  } =>#t71;
+    final core::Set<core::int*>* #t50 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t50.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t51 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t51);
+    #t50.{core::Set::add}{Invariant}(null);
+  } =>#t50;
   core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t74 = <core::int*>[];
+    final core::List<core::int*>* #t52 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t75 = :sync-for-iterator.{core::Iterator::current};
-          #t74.{core::List::add}{Invariant}(#t75);
-        }
-      }
-  } =>#t74;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t52.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t52;
   core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t76 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t53 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t77 = :sync-for-iterator.{core::Iterator::current};
-          #t76.{core::Set::add}{Invariant}(#t77);
-        }
-      }
-    #t76.{core::Set::add}{Invariant}(null);
-  } =>#t76;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t53.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t53.{core::Set::add}{Invariant}(null);
+  } =>#t53;
   core::Map<core::String*, core::int*>* map52 = block {
-    final core::Map<core::String*, core::int*>* #t78 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t54 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::int*>* #t79 = :sync-for-iterator.{core::Iterator::current};
-          #t78.{core::Map::[]=}{Invariant}(#t79.{core::MapEntry::key}, #t79.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::int*>* #t55 = :sync-for-iterator.{core::Iterator::current};
+          #t54.{core::Map::[]=}{Invariant}(#t55.{core::MapEntry::key}, #t55.{core::MapEntry::value});
         }
       }
-    #t78.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t78;
+    #t54.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t54;
   core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t80 = <core::List<core::int*>*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
-        #t80.{core::List::add}{Invariant}(#t81);
-      }
-    }
-  } =>#t80;
+    final core::List<core::List<core::int*>*>* #t56 = <core::List<core::int*>*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t56.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t56;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t82 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
-        #t82.{core::Set::add}{Invariant}(#t83);
-      }
-    }
-    #t82.{core::Set::add}{Invariant}(null);
-  } =>#t82;
+    final core::Set<core::List<core::int*>*>* #t57 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t57.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t57.{core::Set::add}{Invariant}(null);
+  } =>#t57;
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t84 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t58 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t85 = :sync-for-iterator.{core::Iterator::current};
-        #t84.{core::Map::[]=}{Invariant}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t59 = :sync-for-iterator.{core::Iterator::current};
+        #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
       }
     }
-    #t84.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t84;
+    #t58.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t58;
   core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t86 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t60 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t87 = :sync-for-iterator.{core::Iterator::current};
-          #t86.{core::List::add}{Invariant}(#t87);
-        }
-      }
-  } =>#t86;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t60.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t60;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t88 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t61 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t89 = :sync-for-iterator.{core::Iterator::current};
-          #t88.{core::Set::add}{Invariant}(#t89);
-        }
-      }
-    #t88.{core::Set::add}{Invariant}(null);
-  } =>#t88;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t61.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t61.{core::Set::add}{Invariant}(null);
+  } =>#t61;
   core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t90 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t62 = <core::String*, core::List<core::int*>*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t91 = :sync-for-iterator.{core::Iterator::current};
-          #t90.{core::Map::[]=}{Invariant}(#t91.{core::MapEntry::key}, #t91.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t63 = :sync-for-iterator.{core::Iterator::current};
+          #t62.{core::Map::[]=}{Invariant}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
         }
       }
-    #t90.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t90;
+    #t62.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t62;
   core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t92 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t64 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t92.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t92;
+      #t64.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t64;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t93 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t65 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t93.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t93.{core::Set::add}{Invariant}(null);
-  } =>#t93;
+      #t65.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t65.{core::Set::add}{Invariant}(null);
+  } =>#t65;
   core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t94 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t66 = <core::List<core::int*>*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t94.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t94;
+        #t66.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t66;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t95 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t67 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t95.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t95.{core::Set::add}{Invariant}(null);
-  } =>#t95;
+        #t67.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t67.{core::Set::add}{Invariant}(null);
+  } =>#t67;
   core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t96 = <core::num*>[];
+    final core::List<core::num*>* #t68 = <core::num*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t96.{core::List::add}{Invariant}(42);
+      #t68.{core::List::add}{Invariant}(42);
     else
-      #t96.{core::List::add}{Invariant}(3.14);
-  } =>#t96;
+      #t68.{core::List::add}{Invariant}(3.14);
+  } =>#t68;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t97 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t69 = new col::_CompactLinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t97.{core::Set::add}{Invariant}(42);
+      #t69.{core::Set::add}{Invariant}(42);
     else
-      #t97.{core::Set::add}{Invariant}(3.14);
-    #t97.{core::Set::add}{Invariant}(null);
-  } =>#t97;
+      #t69.{core::Set::add}{Invariant}(3.14);
+    #t69.{core::Set::add}{Invariant}(null);
+  } =>#t69;
   core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t98 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t70 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t98.{core::Map::[]=}{Invariant}("bar", 42);
+      #t70.{core::Map::[]=}{Invariant}("bar", 42);
     else
-      #t98.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t98.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t98;
+      #t70.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t70.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t70;
   core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t99 = <core::num*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t100 = :sync-for-iterator.{core::Iterator::current};
-        #t99.{core::List::add}{Invariant}(#t100);
-      }
-    }
-    else {
-      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t101 = :sync-for-iterator.{core::Iterator::current};
-        #t99.{core::List::add}{Invariant}(#t101);
-      }
-    }
-  } =>#t99;
+    final core::List<core::num*>* #t71 = <core::num*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t71.{core::List::addAll}{Invariant}(listInt);
+    else
+      #t71.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t71;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t102 = new col::_CompactLinkedHashSet::•<core::num*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t103 = :sync-for-iterator.{core::Iterator::current};
-        #t102.{core::Set::add}{Invariant}(#t103);
-      }
-    }
-    else {
-      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t104 = :sync-for-iterator.{core::Iterator::current};
-        #t102.{core::Set::add}{Invariant}(#t104);
-      }
-    }
-    #t102.{core::Set::add}{Invariant}(null);
-  } =>#t102;
+    final core::Set<core::num*>* #t72 = new col::_CompactLinkedHashSet::•<core::num*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t72.{core::Set::addAll}{Invariant}(listInt);
+    else
+      #t72.{core::Set::addAll}{Invariant}(listDouble);
+    #t72.{core::Set::add}{Invariant}(null);
+  } =>#t72;
   core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t105 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t73 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::num*>* #t106 = :sync-for-iterator.{core::Iterator::current};
-        #t105.{core::Map::[]=}{Invariant}(#t106.{core::MapEntry::key}, #t106.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::num*>* #t74 = :sync-for-iterator.{core::Iterator::current};
+        #t73.{core::Map::[]=}{Invariant}(#t74.{core::MapEntry::key}, #t74.{core::MapEntry::value});
       }
     }
     else {
       core::Iterator<core::MapEntry<core::String*, core::double*>>* :sync-for-iterator = mapToDouble.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::num*>* #t107 = :sync-for-iterator.{core::Iterator::current};
-        #t105.{core::Map::[]=}{Invariant}(#t107.{core::MapEntry::key}, #t107.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::num*>* #t75 = :sync-for-iterator.{core::Iterator::current};
+        #t73.{core::Map::[]=}{Invariant}(#t75.{core::MapEntry::key}, #t75.{core::MapEntry::value});
       }
     }
-    #t105.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t105;
+    #t73.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t73;
   core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t108 = <dynamic>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t109 = :sync-for-iterator.{core::Iterator::current};
-        #t108.{core::List::add}{Invariant}(#t109);
-      }
-    }
-    else {
-      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t110 = :sync-for-iterator.{core::Iterator::current};
-        #t108.{core::List::add}{Invariant}(#t110);
-      }
-    }
-  } =>#t108;
-  core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t111 = new col::_CompactLinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t112 = :sync-for-iterator.{core::Iterator::current};
-        #t111.{core::Set::add}{Invariant}(#t112);
-      }
-    }
-    else {
-      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t113 = :sync-for-iterator.{core::Iterator::current};
-        #t111.{core::Set::add}{Invariant}(#t113);
-      }
-    }
-    #t111.{core::Set::add}{Invariant}(null);
-  } =>#t111;
-  core::Set<dynamic>* map82 = block {
-    final core::Set<dynamic>* #t114 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::List<dynamic>* #t76 = <dynamic>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t114.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:73:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t76.{core::List::addAll}{Invariant}(listInt);
+    else
+      #t76.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t76;
+  core::Set<dynamic>* set82 = block {
+    final core::Set<dynamic>* #t77 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t77.{core::Set::addAll}{Invariant}(listInt);
+    else
+      #t77.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t77.{core::Set::add}{Invariant}(null);
+  } =>#t77;
+  core::Set<dynamic>* map82 = block {
+    final core::Set<dynamic>* #t78 = new col::_CompactLinkedHashSet::•<dynamic>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t78.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:73:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
                                      ^");
-    else {
-      core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t115 = :sync-for-iterator.{core::Iterator::current};
-        #t114.{core::Set::add}{Invariant}(#t115);
-      }
-    }
-    #t114.{core::Set::add}{Invariant}(null);
-  } =>#t114;
-  core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t116 = <core::num*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t116.{core::List::add}{Invariant}(42);
-    else {
-      core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t117 = :sync-for-iterator.{core::Iterator::current};
-        #t116.{core::List::add}{Invariant}(#t117);
-      }
-    }
-  } =>#t116;
-  core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t118 = new col::_CompactLinkedHashSet::•<core::num*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::num* #t119 = :sync-for-iterator.{core::Iterator::current};
-        #t118.{core::Set::add}{Invariant}(#t119);
-      }
-    }
     else
-      #t118.{core::Set::add}{Invariant}(3.14);
-    #t118.{core::Set::add}{Invariant}(null);
-  } =>#t118;
+      #t78.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t78.{core::Set::add}{Invariant}(null);
+  } =>#t78;
+  core::List<core::num*>* list83 = block {
+    final core::List<core::num*>* #t79 = <core::num*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t79.{core::List::add}{Invariant}(42);
+    else
+      #t79.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t79;
+  core::Set<core::num*>* set83 = block {
+    final core::Set<core::num*>* #t80 = new col::_CompactLinkedHashSet::•<core::num*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t80.{core::Set::addAll}{Invariant}(listInt);
+    else
+      #t80.{core::Set::add}{Invariant}(3.14);
+    #t80.{core::Set::add}{Invariant}(null);
+  } =>#t80;
   core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t120 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t81 = <core::String*, core::num*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapToInt.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::num*>* #t121 = :sync-for-iterator.{core::Iterator::current};
-        #t120.{core::Map::[]=}{Invariant}(#t121.{core::MapEntry::key}, #t121.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::num*>* #t82 = :sync-for-iterator.{core::Iterator::current};
+        #t81.{core::Map::[]=}{Invariant}(#t82.{core::MapEntry::key}, #t82.{core::MapEntry::value});
       }
     }
     else
-      #t120.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t120.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t120;
+      #t81.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t81.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t81;
   core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t122 = <core::int*>[];
+    final core::List<core::int*>* #t83 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t122.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t122;
+      #t83.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+  } =>#t83;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t123 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t84 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t123.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t123.{core::Set::add}{Invariant}(null);
-  } =>#t123;
+      #t84.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t84.{core::Set::add}{Invariant}(null);
+  } =>#t84;
   core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t124 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t85 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t124.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t124.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t124;
+      #t85.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t85.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t85;
   core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t125 = <core::int*>[];
+    final core::List<core::int*>* #t86 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t126 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t87 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t127 = #t126 as{TypeError} core::int*;
-          #t125.{core::List::add}{Invariant}(#t127);
+          final core::int* #t88 = #t87 as{TypeError} core::int*;
+          #t86.{core::List::add}{Invariant}(#t88);
         }
       }
     }
-  } =>#t125;
+  } =>#t86;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t128 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t89 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t129 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t90 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t130 = #t129 as{TypeError} core::int*;
-          #t128.{core::Set::add}{Invariant}(#t130);
+          final core::int* #t91 = #t90 as{TypeError} core::int*;
+          #t89.{core::Set::add}{Invariant}(#t91);
         }
       }
     }
-    #t128.{core::Set::add}{Invariant}(null);
-  } =>#t128;
+    #t89.{core::Set::add}{Invariant}(null);
+  } =>#t89;
   core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t131 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t92 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t132 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<dynamic, dynamic>* #t93 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::String* #t133 = #t132.{core::MapEntry::key} as{TypeError} core::String*;
-          final core::int* #t134 = #t132.{core::MapEntry::value} as{TypeError} core::int*;
-          #t131.{core::Map::[]=}{Invariant}(#t133, #t134);
+          final core::String* #t94 = #t93.{core::MapEntry::key} as{TypeError} core::String*;
+          final core::int* #t95 = #t93.{core::MapEntry::value} as{TypeError} core::int*;
+          #t92.{core::Map::[]=}{Invariant}(#t94, #t95);
         }
       }
     }
-    #t131.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t131;
+    #t92.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t92;
   core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t135 = <core::int*>[];
+    final core::List<core::int*>* #t96 = <core::int*>[];
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t135.{core::List::add}{Invariant}(42);
-  } =>#t135;
+      #t96.{core::List::add}{Invariant}(42);
+  } =>#t96;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t136 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t97 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t136.{core::Set::add}{Invariant}(42);
-  } =>#t136;
+      #t97.{core::Set::add}{Invariant}(42);
+  } =>#t97;
   core::Map<core::int*, core::int*>* map100 = block {
-    final core::Map<core::int*, core::int*>* #t137 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t98 = <core::int*, core::int*>{};
     if(dynVar as{TypeError,ForDynamic} core::bool*)
-      #t137.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t137;
+      #t98.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t98;
 }
 static method testIfElementErrors(core::Map<core::int*, core::int*>* map) → dynamic {
   block {
-    final core::List<core::int*>* #t138 = <core::int*>[];
+    final core::List<core::int*>* #t99 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t138.{core::List::add}{Invariant}(let final<BottomType> #t139 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:89:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t99.{core::List::add}{Invariant}(let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:89:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) \"bar\"];
                            ^" in "bar" as{TypeError} core::int*);
-  } =>#t138;
+  } =>#t99;
   block {
-    final core::Set<core::int*>* #t140 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t101 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t140.{core::Set::add}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:90:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t101.{core::Set::add}{Invariant}(let final<BottomType> #t102 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:90:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
                            ^" in "bar" as{TypeError} core::int*);
-    #t140.{core::Set::add}{Invariant}(null);
-  } =>#t140;
+    #t101.{core::Set::add}{Invariant}(null);
+  } =>#t101;
   block {
-    final core::Map<core::String*, core::int*>* #t142 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t103 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t142.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:91:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t103.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:91:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
                                           ^" in "bar" as{TypeError} core::int*);
-    #t142.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t142;
+    #t103.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t103;
   block {
-    final core::List<core::int*>* #t144 = <core::int*>[];
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t105 = <core::int*>[];
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t105.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:92:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
-                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t146 = :sync-for-iterator.{core::Iterator::current};
-        #t144.{core::List::add}{Invariant}(#t146);
-      }
-    }
-  } =>#t144;
+                               ^" in "bar" as{TypeError} core::int*]);
+  } =>#t105;
   block {
-    final core::Set<core::int*>* #t147 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t107 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
+      #t107.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
-                               ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t149 = :sync-for-iterator.{core::Iterator::current};
-        #t147.{core::Set::add}{Invariant}(#t149);
-      }
-    }
-    #t147.{core::Set::add}{Invariant}(null);
-  } =>#t147;
+                               ^" in "bar" as{TypeError} core::int*]);
+    #t107.{core::Set::add}{Invariant}(null);
+  } =>#t107;
   block {
-    final core::Map<core::String*, core::int*>* #t150 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t109 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": let final<BottomType> #t110 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:94:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t152 = :sync-for-iterator.{core::Iterator::current};
-        #t150.{core::Map::[]=}{Invariant}(#t152.{core::MapEntry::key}, #t152.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t111 = :sync-for-iterator.{core::Iterator::current};
+        #t109.{core::Map::[]=}{Invariant}(#t111.{core::MapEntry::key}, #t111.{core::MapEntry::value});
       }
     }
-    #t150.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t150;
+    #t109.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t109;
   block {
-    final core::List<core::int*>* #t153 = <core::int*>[];
+    final core::List<core::int*>* #t112 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t153.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:95:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t112.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:95:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map];
                               ^");
-  } =>#t153;
+  } =>#t112;
   block {
-    final core::Set<core::int*>* #t154 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t113 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t154.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t113.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map, null};
                               ^");
-    #t154.{core::Set::add}{Invariant}(null);
-  } =>#t154;
+    #t113.{core::Set::add}{Invariant}(null);
+  } =>#t113;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:97:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
@@ -1300,61 +1095,61 @@
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::String*>* #t155 = <core::String*>[];
+    final core::List<core::String*>* #t114 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t156 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t115 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t155.{core::List::add}{Invariant}(let final<BottomType> #t157 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t114.{core::List::add}{Invariant}(let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:98:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                                       ^" in 3.14 as{TypeError} core::String*);
-  } =>#t155;
+  } =>#t114;
   block {
-    final core::Set<core::String*>* #t158 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t117 = new col::_CompactLinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                               ^" in 42 as{TypeError} core::String*);
     else
-      #t158.{core::Set::add}{Invariant}(let final<BottomType> #t160 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t117.{core::Set::add}{Invariant}(let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:99:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                                       ^" in 3.14 as{TypeError} core::String*);
-    #t158.{core::Set::add}{Invariant}(null);
-  } =>#t158;
+    #t117.{core::Set::add}{Invariant}(null);
+  } =>#t117;
   block {
-    final core::Map<core::String*, core::String*>* #t161 = <core::String*, core::String*>{};
+    final core::Map<core::String*, core::String*>* #t120 = <core::String*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t161.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                              ^" in 42 as{TypeError} core::String*);
     else
-      #t161.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t163 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+      #t120.{core::Map::[]=}{Invariant}("baz", let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:100:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                                             ^" in 3.14 as{TypeError} core::String*);
-    #t161.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t161;
+    #t120.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t120;
   block {
-    final core::List<core::int*>* #t164 = <core::int*>[];
+    final core::List<core::int*>* #t123 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t164.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:101:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t123.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:101:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map else 42];
                               ^");
     else
-      #t164.{core::List::add}{Invariant}(42);
-  } =>#t164;
+      #t123.{core::List::add}{Invariant}(42);
+  } =>#t123;
   block {
-    final core::Set<core::int*>* #t165 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t124 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t165.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:102:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t124.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:102:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t165.{core::Set::add}{Invariant}(42);
-    #t165.{core::Set::add}{Invariant}(null);
-  } =>#t165;
+      #t124.{core::Set::add}{Invariant}(42);
+    #t124.{core::Set::add}{Invariant}(null);
+  } =>#t124;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:103:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
@@ -1363,26 +1158,26 @@
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::int*>* #t166 = <core::int*>[];
+    final core::List<core::int*>* #t125 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t166.{core::List::add}{Invariant}(42);
+      #t125.{core::List::add}{Invariant}(42);
     else
-      #t166.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:104:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t125.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:104:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) 42 else ...map];
                                       ^");
-  } =>#t166;
+  } =>#t125;
   block {
-    final core::Set<core::int*>* #t167 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t126 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t167.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:105:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t126.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:105:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
                               ^");
     else
-      #t167.{core::Set::add}{Invariant}(42);
-    #t167.{core::Set::add}{Invariant}(null);
-  } =>#t167;
+      #t126.{core::Set::add}{Invariant}(42);
+    #t126.{core::Set::add}{Invariant}(null);
+  } =>#t126;
   <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:106:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
@@ -1409,940 +1204,749 @@
   var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
                                                    ^": null};
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t168 = <core::int*>[];
-    if(let final<BottomType> #t169 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:114:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int*>* #t127 = <core::int*>[];
+    if(let final<BottomType> #t128 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:114:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   List<int> list20 = [if (42) 42];
                           ^" in 42 as{TypeError} core::bool*)
-      #t168.{core::List::add}{Invariant}(42);
-  } =>#t168;
+      #t127.{core::List::add}{Invariant}(42);
+  } =>#t127;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t170 = new col::_CompactLinkedHashSet::•<core::int*>();
-    if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:115:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int*>* #t129 = new col::_CompactLinkedHashSet::•<core::int*>();
+    if(let final<BottomType> #t130 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:115:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
-      #t170.{core::Set::add}{Invariant}(42);
-  } =>#t170;
+      #t129.{core::Set::add}{Invariant}(42);
+  } =>#t129;
   core::Map<core::int*, core::int*>* map30 = block {
-    final core::Map<core::int*, core::int*>* #t172 = <core::int*, core::int*>{};
-    if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:116:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::int*, core::int*>* #t131 = <core::int*, core::int*>{};
+    if(let final<BottomType> #t132 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:116:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Map<int, int> map30 = {if (42) 42: 42};
                              ^" in 42 as{TypeError} core::bool*)
-      #t172.{core::Map::[]=}{Invariant}(42, 42);
-  } =>#t172;
+      #t131.{core::Map::[]=}{Invariant}(42, 42);
+  } =>#t131;
   core::List<core::String*>* list40 = block {
-    final core::List<core::String*>* #t174 = <core::String*>[];
+    final core::List<core::String*>* #t133 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t134 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                     ^" in true as{TypeError} core::String*);
     else
-      #t174.{core::List::add}{Invariant}(let final<BottomType> #t176 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t133.{core::List::add}{Invariant}(let final<BottomType> #t135 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:117:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t174;
+  } =>#t133;
   core::Set<core::String*>* set40 = block {
-    final core::Set<core::String*>* #t177 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t136 = new col::_CompactLinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t137 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                   ^" in true as{TypeError} core::String*);
     else
-      #t177.{core::Set::add}{Invariant}(let final<BottomType> #t179 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t136.{core::Set::add}{Invariant}(let final<BottomType> #t138 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:118:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                             ^" in 42 as{TypeError} core::String*);
-  } =>#t177;
+  } =>#t136;
   core::Map<core::String*, core::int*>* map40 = block {
-    final core::Map<core::String*, core::int*>* #t180 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t139 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t140 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                             ^" in true as{TypeError} core::String*, 42);
     else
-      #t180.{core::Map::[]=}{Invariant}(let final<BottomType> #t182 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t139.{core::Map::[]=}{Invariant}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:119:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                                           ^" in 42 as{TypeError} core::String*, 42);
-  } =>#t180;
+  } =>#t139;
   core::Map<core::int*, core::String*>* map41 = block {
-    final core::Map<core::int*, core::String*>* #t183 = <core::int*, core::String*>{};
+    final core::Map<core::int*, core::String*>* #t142 = <core::int*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                 ^" in true as{TypeError} core::String*);
     else
-      #t183.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t185 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+      #t142.{core::Map::[]=}{Invariant}(42, let final<BottomType> #t144 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:120:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                               ^" in 42 as{TypeError} core::String*);
-  } =>#t183;
+  } =>#t142;
 }
 static method testForElement(dynamic dynVar, core::List<core::int*>* listInt, core::List<core::double*>* listDouble, core::int* index, core::Map<core::String*, core::int*>* mapStringInt, core::Map<core::String*, core::double*>* mapStringDouble) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t186 = <core::int*>[];
+    final core::List<core::int*>* #t145 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t186.{core::List::add}{Invariant}(42);
-  } =>#t186;
+      #t145.{core::List::add}{Invariant}(42);
+  } =>#t145;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t187 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t146 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t187.{core::Set::add}{Invariant}(42);
-    #t187.{core::Set::add}{Invariant}(null);
-  } =>#t187;
+      #t146.{core::Set::add}{Invariant}(42);
+    #t146.{core::Set::add}{Invariant}(null);
+  } =>#t146;
   core::Map<core::String*, core::int*>* map10 = block {
-    final core::Map<core::String*, core::int*>* #t188 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t147 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t188.{core::Map::[]=}{Invariant}("bar", 42);
-    #t188.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t188;
+      #t147.{core::Map::[]=}{Invariant}("bar", 42);
+    #t147.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t147;
   core::List<dynamic>* list11 = block {
-    final core::List<dynamic>* #t189 = <dynamic>[];
+    final core::List<dynamic>* #t148 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t189.{core::List::add}{Invariant}(dynVar);
-  } =>#t189;
+      #t148.{core::List::add}{Invariant}(dynVar);
+  } =>#t148;
   core::Set<dynamic>* set11 = block {
-    final core::Set<dynamic>* #t190 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t149 = new col::_CompactLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t190.{core::Set::add}{Invariant}(dynVar);
-    #t190.{core::Set::add}{Invariant}(null);
-  } =>#t190;
+      #t149.{core::Set::add}{Invariant}(dynVar);
+    #t149.{core::Set::add}{Invariant}(null);
+  } =>#t149;
   core::Map<core::String*, dynamic>* map11 = block {
-    final core::Map<core::String*, dynamic>* #t191 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t150 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t191.{core::Map::[]=}{Invariant}("bar", dynVar);
-    #t191.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t191;
+      #t150.{core::Map::[]=}{Invariant}("bar", dynVar);
+    #t150.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t150;
   core::List<core::List<core::int*>*>* list12 = block {
-    final core::List<core::List<core::int*>*>* #t192 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t151 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t192.{core::List::add}{Invariant}(<core::int*>[42]);
-  } =>#t192;
+      #t151.{core::List::add}{Invariant}(<core::int*>[42]);
+  } =>#t151;
   core::Set<core::List<core::int*>*>* set12 = block {
-    final core::Set<core::List<core::int*>*>* #t193 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t152 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t193.{core::Set::add}{Invariant}(<core::int*>[42]);
-    #t193.{core::Set::add}{Invariant}(null);
-  } =>#t193;
+      #t152.{core::Set::add}{Invariant}(<core::int*>[42]);
+    #t152.{core::Set::add}{Invariant}(null);
+  } =>#t152;
   core::Map<core::String*, core::List<core::int*>*>* map12 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t194 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t153 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t194.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
-    #t194.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t194;
+      #t153.{core::Map::[]=}{Invariant}("bar", <core::int*>[42]);
+    #t153.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t153;
   core::List<core::int*>* list20 = block {
-    final core::List<core::int*>* #t195 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t196 = :sync-for-iterator.{core::Iterator::current};
-        #t195.{core::List::add}{Invariant}(#t196);
-      }
-    }
-  } =>#t195;
+    final core::List<core::int*>* #t154 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t154.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t154;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t197 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t198 = :sync-for-iterator.{core::Iterator::current};
-        #t197.{core::Set::add}{Invariant}(#t198);
-      }
-    }
-    #t197.{core::Set::add}{Invariant}(null);
-  } =>#t197;
+    final core::Set<core::int*>* #t155 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t155.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t155.{core::Set::add}{Invariant}(null);
+  } =>#t155;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t199 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t156 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t200 = :sync-for-iterator.{core::Iterator::current};
-        #t199.{core::Map::[]=}{Invariant}(#t200.{core::MapEntry::key}, #t200.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t157 = :sync-for-iterator.{core::Iterator::current};
+        #t156.{core::Map::[]=}{Invariant}(#t157.{core::MapEntry::key}, #t157.{core::MapEntry::value});
       }
     }
-    #t199.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t199;
+    #t156.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t156;
   core::List<dynamic>* list21 = block {
-    final core::List<dynamic>* #t201 = <dynamic>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t202 = :sync-for-iterator.{core::Iterator::current};
-        #t201.{core::List::add}{Invariant}(#t202);
-      }
-    }
-  } =>#t201;
+    final core::List<dynamic>* #t158 = <dynamic>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t158.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t158;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t203 = new col::_CompactLinkedHashSet::•<dynamic>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t204 = :sync-for-iterator.{core::Iterator::current};
-        #t203.{core::Set::add}{Invariant}(#t204);
-      }
-    }
-    #t203.{core::Set::add}{Invariant}(null);
-  } =>#t203;
+    final core::Set<dynamic>* #t159 = new col::_CompactLinkedHashSet::•<dynamic>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t159.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t159.{core::Set::add}{Invariant}(null);
+  } =>#t159;
   core::Map<core::String*, dynamic>* map21 = block {
-    final core::Map<core::String*, dynamic>* #t205 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t160 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, dynamic>* #t206 = :sync-for-iterator.{core::Iterator::current};
-        #t205.{core::Map::[]=}{Invariant}(#t206.{core::MapEntry::key}, #t206.{core::MapEntry::value});
+        final core::MapEntry<core::String*, dynamic>* #t161 = :sync-for-iterator.{core::Iterator::current};
+        #t160.{core::Map::[]=}{Invariant}(#t161.{core::MapEntry::key}, #t161.{core::MapEntry::value});
       }
     }
-    #t205.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t205;
+    #t160.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t160;
   core::List<core::List<core::int*>*>* list22 = block {
-    final core::List<core::List<core::int*>*>* #t207 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t208 = :sync-for-iterator.{core::Iterator::current};
-        #t207.{core::List::add}{Invariant}(#t208);
-      }
-    }
-  } =>#t207;
+    final core::List<core::List<core::int*>*>* #t162 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t162.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t162;
   core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t209 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t210 = :sync-for-iterator.{core::Iterator::current};
-        #t209.{core::Set::add}{Invariant}(#t210);
-      }
-    }
-    #t209.{core::Set::add}{Invariant}(null);
-  } =>#t209;
+    final core::Set<core::List<core::int*>*>* #t163 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t163.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t163.{core::Set::add}{Invariant}(null);
+  } =>#t163;
   core::Map<core::String*, core::List<core::int*>*>* map22 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t211 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t164 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t212 = :sync-for-iterator.{core::Iterator::current};
-        #t211.{core::Map::[]=}{Invariant}(#t212.{core::MapEntry::key}, #t212.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t165 = :sync-for-iterator.{core::Iterator::current};
+        #t164.{core::Map::[]=}{Invariant}(#t165.{core::MapEntry::key}, #t165.{core::MapEntry::value});
       }
     }
-    #t211.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t211;
+    #t164.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t164;
   core::List<core::int*>* list30 = block {
-    final core::List<core::int*>* #t213 = <core::int*>[];
+    final core::List<core::int*>* #t166 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t214 = :sync-for-iterator.{core::Iterator::current};
-          #t213.{core::List::add}{Invariant}(#t214);
-        }
-      }
-  } =>#t213;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t166.{core::List::addAll}{Invariant}(<core::int*>[42]);
+  } =>#t166;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t215 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t167 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[42].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t216 = :sync-for-iterator.{core::Iterator::current};
-          #t215.{core::Set::add}{Invariant}(#t216);
-        }
-      }
-    #t215.{core::Set::add}{Invariant}(null);
-  } =>#t215;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t167.{core::Set::addAll}{Invariant}(<core::int*>[42]);
+    #t167.{core::Set::add}{Invariant}(null);
+  } =>#t167;
   core::Map<core::String*, core::int*>* map30 = block {
-    final core::Map<core::String*, core::int*>* #t217 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t168 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{"bar": 42}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::int*>* #t218 = :sync-for-iterator.{core::Iterator::current};
-          #t217.{core::Map::[]=}{Invariant}(#t218.{core::MapEntry::key}, #t218.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::int*>* #t169 = :sync-for-iterator.{core::Iterator::current};
+          #t168.{core::Map::[]=}{Invariant}(#t169.{core::MapEntry::key}, #t169.{core::MapEntry::value});
         }
       }
-    #t217.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t217;
+    #t168.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t168;
   core::List<dynamic>* list31 = block {
-    final core::List<dynamic>* #t219 = <dynamic>[];
+    final core::List<dynamic>* #t170 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t220 = :sync-for-iterator.{core::Iterator::current};
-          #t219.{core::List::add}{Invariant}(#t220);
-        }
-      }
-  } =>#t219;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t170.{core::List::addAll}{Invariant}(<dynamic>[dynVar]);
+  } =>#t170;
   core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t221 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t171 = new col::_CompactLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[dynVar].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t222 = :sync-for-iterator.{core::Iterator::current};
-          #t221.{core::Set::add}{Invariant}(#t222);
-        }
-      }
-    #t221.{core::Set::add}{Invariant}(null);
-  } =>#t221;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t171.{core::Set::addAll}{Invariant}(<dynamic>[dynVar]);
+    #t171.{core::Set::add}{Invariant}(null);
+  } =>#t171;
   core::Map<core::String*, dynamic>* map31 = block {
-    final core::Map<core::String*, dynamic>* #t223 = <core::String*, dynamic>{};
+    final core::Map<core::String*, dynamic>* #t172 = <core::String*, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, dynamic>>* :sync-for-iterator = <core::String*, dynamic>{"bar": dynVar}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, dynamic>* #t224 = :sync-for-iterator.{core::Iterator::current};
-          #t223.{core::Map::[]=}{Invariant}(#t224.{core::MapEntry::key}, #t224.{core::MapEntry::value});
+          final core::MapEntry<core::String*, dynamic>* #t173 = :sync-for-iterator.{core::Iterator::current};
+          #t172.{core::Map::[]=}{Invariant}(#t173.{core::MapEntry::key}, #t173.{core::MapEntry::value});
         }
       }
-    #t223.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t223;
+    #t172.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t172;
   core::List<core::List<core::int*>*>* list33 = block {
-    final core::List<core::List<core::int*>*>* #t225 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t174 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t226 = :sync-for-iterator.{core::Iterator::current};
-          #t225.{core::List::add}{Invariant}(#t226);
-        }
-      }
-  } =>#t225;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t174.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+  } =>#t174;
   core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t227 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t175 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[42]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t228 = :sync-for-iterator.{core::Iterator::current};
-          #t227.{core::Set::add}{Invariant}(#t228);
-        }
-      }
-    #t227.{core::Set::add}{Invariant}(null);
-  } =>#t227;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t175.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[42]]);
+    #t175.{core::Set::add}{Invariant}(null);
+  } =>#t175;
   core::Map<core::String*, core::List<core::int*>*>* map33 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t229 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t176 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[42]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t230 = :sync-for-iterator.{core::Iterator::current};
-          #t229.{core::Map::[]=}{Invariant}(#t230.{core::MapEntry::key}, #t230.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t177 = :sync-for-iterator.{core::Iterator::current};
+          #t176.{core::Map::[]=}{Invariant}(#t177.{core::MapEntry::key}, #t177.{core::MapEntry::value});
         }
       }
-    #t229.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t229;
+    #t176.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t176;
   core::List<core::List<core::int*>*>* list40 = block {
-    final core::List<core::List<core::int*>*>* #t231 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t232 = :sync-for-iterator.{core::Iterator::current};
-        #t231.{core::List::add}{Invariant}(#t232);
-      }
-    }
-  } =>#t231;
+    final core::List<core::List<core::int*>*>* #t178 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t178.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t178;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t233 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t234 = :sync-for-iterator.{core::Iterator::current};
-        #t233.{core::Set::add}{Invariant}(#t234);
-      }
-    }
-    #t233.{core::Set::add}{Invariant}(null);
-  } =>#t233;
+    final core::Set<core::List<core::int*>*>* #t179 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t179.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t179.{core::Set::add}{Invariant}(null);
+  } =>#t179;
   core::Map<core::String*, core::List<core::int*>*>* map40 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t235 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t180 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t236 = :sync-for-iterator.{core::Iterator::current};
-        #t235.{core::Map::[]=}{Invariant}(#t236.{core::MapEntry::key}, #t236.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t181 = :sync-for-iterator.{core::Iterator::current};
+        #t180.{core::Map::[]=}{Invariant}(#t181.{core::MapEntry::key}, #t181.{core::MapEntry::value});
       }
     }
-    #t235.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t235;
+    #t180.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t180;
   core::List<core::List<core::int*>*>* list41 = block {
-    final core::List<core::List<core::int*>*>* #t237 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t238 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t238.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t238).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t239 = :sync-for-iterator.{core::Iterator::current};
-        #t237.{core::List::add}{Invariant}(#t239);
-      }
-    }
-  } =>#t237;
+    final core::List<core::List<core::int*>*>* #t182 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t182.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t183 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t183.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t183);
+  } =>#t182;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t240 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = ( block {
-        final core::Set<core::List<core::int*>*>* #t241 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-        #t241.{core::Set::add}{Invariant}(<core::int*>[]);
-      } =>#t241).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t242 = :sync-for-iterator.{core::Iterator::current};
-        #t240.{core::Set::add}{Invariant}(#t242);
-      }
-    }
-    #t240.{core::Set::add}{Invariant}(null);
-  } =>#t240;
+    final core::Set<core::List<core::int*>*>* #t184 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t184.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::List<core::int*>*>* #t185 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        #t185.{core::Set::add}{Invariant}(<core::int*>[]);
+      } =>#t185);
+    #t184.{core::Set::add}{Invariant}(null);
+  } =>#t184;
   core::List<core::List<core::int*>*>* list42 = block {
-    final core::List<core::List<core::int*>*>* #t243 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t186 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t244 = :sync-for-iterator.{core::Iterator::current};
-          #t243.{core::List::add}{Invariant}(#t244);
-        }
-      }
-  } =>#t243;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t186.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t186;
   core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t245 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t187 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t246 = :sync-for-iterator.{core::Iterator::current};
-          #t245.{core::Set::add}{Invariant}(#t246);
-        }
-      }
-    #t245.{core::Set::add}{Invariant}(null);
-  } =>#t245;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t187.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t187.{core::Set::add}{Invariant}(null);
+  } =>#t187;
   core::Map<core::String*, core::List<core::int*>*>* map42 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t247 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t188 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t248 = :sync-for-iterator.{core::Iterator::current};
-          #t247.{core::Map::[]=}{Invariant}(#t248.{core::MapEntry::key}, #t248.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t189 = :sync-for-iterator.{core::Iterator::current};
+          #t188.{core::Map::[]=}{Invariant}(#t189.{core::MapEntry::key}, #t189.{core::MapEntry::value});
         }
       }
-    #t247.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t247;
+    #t188.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t188;
   core::List<core::int*>* list50 = block {
-    final core::List<core::int*>* #t249 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t250 = :sync-for-iterator.{core::Iterator::current};
-        #t249.{core::List::add}{Invariant}(#t250);
-      }
-    }
-  } =>#t249;
+    final core::List<core::int*>* #t190 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t190.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t190;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t251 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t252 = :sync-for-iterator.{core::Iterator::current};
-        #t251.{core::Set::add}{Invariant}(#t252);
-      }
-    }
-    #t251.{core::Set::add}{Invariant}(null);
-  } =>#t251;
+    final core::Set<core::int*>* #t191 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t191.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t191.{core::Set::add}{Invariant}(null);
+  } =>#t191;
   core::Map<core::String*, core::int*>* map50 = block {
-    final core::Map<core::String*, core::int*>* #t253 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t192 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t254 = :sync-for-iterator.{core::Iterator::current};
-        #t253.{core::Map::[]=}{Invariant}(#t254.{core::MapEntry::key}, #t254.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t193 = :sync-for-iterator.{core::Iterator::current};
+        #t192.{core::Map::[]=}{Invariant}(#t193.{core::MapEntry::key}, #t193.{core::MapEntry::value});
       }
     }
-    #t253.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t253;
+    #t192.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t192;
   core::List<core::int*>* list51 = block {
-    final core::List<core::int*>* #t255 = <core::int*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t256 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t256).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t257 = :sync-for-iterator.{core::Iterator::current};
-        #t255.{core::List::add}{Invariant}(#t257);
-      }
-    }
-  } =>#t255;
+    final core::List<core::int*>* #t194 = <core::int*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t194.{core::List::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t195 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t195);
+  } =>#t194;
   core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t258 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::int*>* :sync-for-iterator = ( block {
-        final core::Set<core::int*>* #t259 = new col::_CompactLinkedHashSet::•<core::int*>();
-      } =>#t259).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t260 = :sync-for-iterator.{core::Iterator::current};
-        #t258.{core::Set::add}{Invariant}(#t260);
-      }
-    }
-    #t258.{core::Set::add}{Invariant}(null);
-  } =>#t258;
+    final core::Set<core::int*>* #t196 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t196.{core::Set::addAll}{Invariant}( block {
+        final core::Set<core::int*>* #t197 = new col::_CompactLinkedHashSet::•<core::int*>();
+      } =>#t197);
+    #t196.{core::Set::add}{Invariant}(null);
+  } =>#t196;
   core::List<core::int*>* list52 = block {
-    final core::List<core::int*>* #t261 = <core::int*>[];
+    final core::List<core::int*>* #t198 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t262 = :sync-for-iterator.{core::Iterator::current};
-          #t261.{core::List::add}{Invariant}(#t262);
-        }
-      }
-  } =>#t261;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t198.{core::List::addAll}{Invariant}(<core::int*>[]);
+  } =>#t198;
   core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t263 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t199 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::int* #t264 = :sync-for-iterator.{core::Iterator::current};
-          #t263.{core::Set::add}{Invariant}(#t264);
-        }
-      }
-    #t263.{core::Set::add}{Invariant}(null);
-  } =>#t263;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t199.{core::Set::addAll}{Invariant}(<core::int*>[]);
+    #t199.{core::Set::add}{Invariant}(null);
+  } =>#t199;
   core::List<core::List<core::int*>*>* list60 = block {
-    final core::List<core::List<core::int*>*>* #t265 = <core::List<core::int*>*>[];
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t266 = :sync-for-iterator.{core::Iterator::current};
-        #t265.{core::List::add}{Invariant}(#t266);
-      }
-    }
-  } =>#t265;
+    final core::List<core::List<core::int*>*>* #t200 = <core::List<core::int*>*>[];
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t200.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t200;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t267 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t268 = :sync-for-iterator.{core::Iterator::current};
-        #t267.{core::Set::add}{Invariant}(#t268);
-      }
-    }
-    #t267.{core::Set::add}{Invariant}(null);
-  } =>#t267;
+    final core::Set<core::List<core::int*>*>* #t201 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      #t201.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t201.{core::Set::add}{Invariant}(null);
+  } =>#t201;
   core::Map<core::String*, core::List<core::int*>*>* map60 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t269 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t202 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t270 = :sync-for-iterator.{core::Iterator::current};
-        #t269.{core::Map::[]=}{Invariant}(#t270.{core::MapEntry::key}, #t270.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t203 = :sync-for-iterator.{core::Iterator::current};
+        #t202.{core::Map::[]=}{Invariant}(#t203.{core::MapEntry::key}, #t203.{core::MapEntry::value});
       }
     }
-    #t269.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t269;
+    #t202.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t202;
   core::List<core::List<core::int*>*>* list61 = block {
-    final core::List<core::List<core::int*>*>* #t271 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t204 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t272 = :sync-for-iterator.{core::Iterator::current};
-          #t271.{core::List::add}{Invariant}(#t272);
-        }
-      }
-  } =>#t271;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t204.{core::List::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t204;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t273 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t205 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::List<core::int*>* #t274 = :sync-for-iterator.{core::Iterator::current};
-          #t273.{core::Set::add}{Invariant}(#t274);
-        }
-      }
-    #t273.{core::Set::add}{Invariant}(null);
-  } =>#t273;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t205.{core::Set::addAll}{Invariant}(<core::List<core::int*>*>[<core::int*>[]]);
+    #t205.{core::Set::add}{Invariant}(null);
+  } =>#t205;
   core::Map<core::String*, core::List<core::int*>*>* map61 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t275 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t206 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"bar": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::List<core::int*>*>* #t276 = :sync-for-iterator.{core::Iterator::current};
-          #t275.{core::Map::[]=}{Invariant}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::List<core::int*>*>* #t207 = :sync-for-iterator.{core::Iterator::current};
+          #t206.{core::Map::[]=}{Invariant}(#t207.{core::MapEntry::key}, #t207.{core::MapEntry::value});
         }
       }
-    #t275.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t275;
+    #t206.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t206;
   core::List<core::List<core::int*>*>* list70 = block {
-    final core::List<core::List<core::int*>*>* #t277 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t208 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t277.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t277;
+      #t208.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t208;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t278 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t209 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t278.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t278.{core::Set::add}{Invariant}(null);
-  } =>#t278;
+      #t209.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t209.{core::Set::add}{Invariant}(null);
+  } =>#t209;
   core::Map<core::String*, core::List<core::int*>*>* map70 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t279 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t210 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t279.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t279.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t279;
+      #t210.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t210.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t210;
   core::List<core::List<core::int*>*>* list71 = block {
-    final core::List<core::List<core::int*>*>* #t280 = <core::List<core::int*>*>[];
+    final core::List<core::List<core::int*>*>* #t211 = <core::List<core::int*>*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t280.{core::List::add}{Invariant}(<core::int*>[]);
-  } =>#t280;
+        #t211.{core::List::add}{Invariant}(<core::int*>[]);
+  } =>#t211;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t281 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t212 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t281.{core::Set::add}{Invariant}(<core::int*>[]);
-    #t281.{core::Set::add}{Invariant}(null);
-  } =>#t281;
+        #t212.{core::Set::add}{Invariant}(<core::int*>[]);
+    #t212.{core::Set::add}{Invariant}(null);
+  } =>#t212;
   core::Map<core::String*, core::List<core::int*>*>* map71 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t282 = <core::String*, core::List<core::int*>*>{};
+    final core::Map<core::String*, core::List<core::int*>*>* #t213 = <core::String*, core::List<core::int*>*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t282.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
-    #t282.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t282;
+        #t213.{core::Map::[]=}{Invariant}("bar", <core::int*>[]);
+    #t213.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t213;
   core::List<core::num*>* list80 = block {
-    final core::List<core::num*>* #t283 = <core::num*>[];
+    final core::List<core::num*>* #t214 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t283.{core::List::add}{Invariant}(42);
+        #t214.{core::List::add}{Invariant}(42);
       else
-        #t283.{core::List::add}{Invariant}(3.14);
-  } =>#t283;
+        #t214.{core::List::add}{Invariant}(3.14);
+  } =>#t214;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t284 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t215 = new col::_CompactLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t284.{core::Set::add}{Invariant}(42);
+        #t215.{core::Set::add}{Invariant}(42);
       else
-        #t284.{core::Set::add}{Invariant}(3.14);
-    #t284.{core::Set::add}{Invariant}(null);
-  } =>#t284;
+        #t215.{core::Set::add}{Invariant}(3.14);
+    #t215.{core::Set::add}{Invariant}(null);
+  } =>#t215;
   core::Map<core::String*, core::num*>* map80 = block {
-    final core::Map<core::String*, core::num*>* #t285 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t216 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t285.{core::Map::[]=}{Invariant}("bar", 42);
+        #t216.{core::Map::[]=}{Invariant}("bar", 42);
       else
-        #t285.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t285.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t285;
+        #t216.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t216.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t216;
   core::List<core::num*>* list81 = block {
-    final core::List<core::num*>* #t286 = <core::num*>[];
+    final core::List<core::num*>* #t217 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t287 = :sync-for-iterator.{core::Iterator::current};
-          #t286.{core::List::add}{Invariant}(#t287);
-        }
-      }
-      else {
-        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t288 = :sync-for-iterator.{core::Iterator::current};
-          #t286.{core::List::add}{Invariant}(#t288);
-        }
-      }
-  } =>#t286;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t217.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t217.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t217;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t289 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t218 = new col::_CompactLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t290 = :sync-for-iterator.{core::Iterator::current};
-          #t289.{core::Set::add}{Invariant}(#t290);
-        }
-      }
-      else {
-        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t291 = :sync-for-iterator.{core::Iterator::current};
-          #t289.{core::Set::add}{Invariant}(#t291);
-        }
-      }
-    #t289.{core::Set::add}{Invariant}(null);
-  } =>#t289;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t218.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t218.{core::Set::addAll}{Invariant}(listDouble);
+    #t218.{core::Set::add}{Invariant}(null);
+  } =>#t218;
   core::Map<core::String*, core::num*>* map81 = block {
-    final core::Map<core::String*, core::num*>* #t292 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t219 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::num*>* #t293 = :sync-for-iterator.{core::Iterator::current};
-          #t292.{core::Map::[]=}{Invariant}(#t293.{core::MapEntry::key}, #t293.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::num*>* #t220 = :sync-for-iterator.{core::Iterator::current};
+          #t219.{core::Map::[]=}{Invariant}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
         }
       }
       else {
         core::Iterator<core::MapEntry<core::String*, core::double*>>* :sync-for-iterator = mapStringDouble.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::num*>* #t294 = :sync-for-iterator.{core::Iterator::current};
-          #t292.{core::Map::[]=}{Invariant}(#t294.{core::MapEntry::key}, #t294.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::num*>* #t221 = :sync-for-iterator.{core::Iterator::current};
+          #t219.{core::Map::[]=}{Invariant}(#t221.{core::MapEntry::key}, #t221.{core::MapEntry::value});
         }
       }
-    #t292.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t292;
+    #t219.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t219;
   core::List<dynamic>* list82 = block {
-    final core::List<dynamic>* #t295 = <dynamic>[];
+    final core::List<dynamic>* #t222 = <dynamic>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t296 = :sync-for-iterator.{core::Iterator::current};
-          #t295.{core::List::add}{Invariant}(#t296);
-        }
-      }
-      else {
-        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t297 = :sync-for-iterator.{core::Iterator::current};
-          #t295.{core::List::add}{Invariant}(#t297);
-        }
-      }
-  } =>#t295;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t222.{core::List::addAll}{Invariant}(listInt);
+      else
+        #t222.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t222;
   core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t298 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t223 = new col::_CompactLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t299 = :sync-for-iterator.{core::Iterator::current};
-          #t298.{core::Set::add}{Invariant}(#t299);
-        }
-      }
-      else {
-        core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final dynamic #t300 = :sync-for-iterator.{core::Iterator::current};
-          #t298.{core::Set::add}{Invariant}(#t300);
-        }
-      }
-    #t298.{core::Set::add}{Invariant}(null);
-  } =>#t298;
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t223.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t223.{core::Set::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t223.{core::Set::add}{Invariant}(null);
+  } =>#t223;
   core::Map<dynamic, dynamic>* map82 = block {
-    final core::Map<dynamic, dynamic>* #t301 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic>* #t224 = <dynamic, dynamic>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<dynamic, dynamic>* #t302 = :sync-for-iterator.{core::Iterator::current};
-          #t301.{core::Map::[]=}{Invariant}(#t302.{core::MapEntry::key}, #t302.{core::MapEntry::value});
+          final core::MapEntry<dynamic, dynamic>* #t225 = :sync-for-iterator.{core::Iterator::current};
+          #t224.{core::Map::[]=}{Invariant}(#t225.{core::MapEntry::key}, #t225.{core::MapEntry::value});
         }
       }
       else {
         core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<dynamic, dynamic>* #t303 = :sync-for-iterator.{core::Iterator::current};
-          #t301.{core::Map::[]=}{Invariant}(#t303.{core::MapEntry::key}, #t303.{core::MapEntry::value});
+          final core::MapEntry<dynamic, dynamic>* #t226 = :sync-for-iterator.{core::Iterator::current};
+          #t224.{core::Map::[]=}{Invariant}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
         }
       }
-    #t301.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t301;
+    #t224.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t224;
   core::List<core::num*>* list83 = block {
-    final core::List<core::num*>* #t304 = <core::num*>[];
+    final core::List<core::num*>* #t227 = <core::num*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-        #t304.{core::List::add}{Invariant}(42);
-      else {
-        core::Iterator<core::double*>* :sync-for-iterator = listDouble.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t305 = :sync-for-iterator.{core::Iterator::current};
-          #t304.{core::List::add}{Invariant}(#t305);
-        }
-      }
-  } =>#t304;
-  core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t306 = new col::_CompactLinkedHashSet::•<core::num*>();
-    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
-        core::Iterator<core::int*>* :sync-for-iterator = listInt.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::num* #t307 = :sync-for-iterator.{core::Iterator::current};
-          #t306.{core::Set::add}{Invariant}(#t307);
-        }
-      }
+        #t227.{core::List::add}{Invariant}(42);
       else
-        #t306.{core::Set::add}{Invariant}(3.14);
-    #t306.{core::Set::add}{Invariant}(null);
-  } =>#t306;
+        #t227.{core::List::addAll}{Invariant}(listDouble);
+  } =>#t227;
+  core::Set<core::num*>* set83 = block {
+    final core::Set<core::num*>* #t228 = new col::_CompactLinkedHashSet::•<core::num*>();
+    for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
+        #t228.{core::Set::addAll}{Invariant}(listInt);
+      else
+        #t228.{core::Set::add}{Invariant}(3.14);
+    #t228.{core::Set::add}{Invariant}(null);
+  } =>#t228;
   core::Map<core::String*, core::num*>* map83 = block {
-    final core::Map<core::String*, core::num*>* #t308 = <core::String*, core::num*>{};
+    final core::Map<core::String*, core::num*>* #t229 = <core::String*, core::num*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*) {
         core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapStringInt.{core::Map::entries}.{core::Iterable::iterator};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<core::String*, core::num*>* #t309 = :sync-for-iterator.{core::Iterator::current};
-          #t308.{core::Map::[]=}{Invariant}(#t309.{core::MapEntry::key}, #t309.{core::MapEntry::value});
+          final core::MapEntry<core::String*, core::num*>* #t230 = :sync-for-iterator.{core::Iterator::current};
+          #t229.{core::Map::[]=}{Invariant}(#t230.{core::MapEntry::key}, #t230.{core::MapEntry::value});
         }
       }
       else
-        #t308.{core::Map::[]=}{Invariant}("bar", 3.14);
-    #t308.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t308;
+        #t229.{core::Map::[]=}{Invariant}("bar", 3.14);
+    #t229.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t229;
   core::List<core::int*>* list90 = block {
-    final core::List<core::int*>* #t310 = <core::int*>[];
+    final core::List<core::int*>* #t231 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t310.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-  } =>#t310;
+      #t231.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+  } =>#t231;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t311 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t232 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t311.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
-    #t311.{core::Set::add}{Invariant}(null);
-  } =>#t311;
+      #t232.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*);
+    #t232.{core::Set::add}{Invariant}(null);
+  } =>#t232;
   core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t312 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t233 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-      #t312.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
-    #t312.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t312;
+      #t233.{core::Map::[]=}{Invariant}("bar", dynVar as{TypeError,ForDynamic} core::int*);
+    #t233.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t233;
   core::List<core::int*>* list91 = block {
-    final core::List<core::int*>* #t313 = <core::int*>[];
+    final core::List<core::int*>* #t234 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t314 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t235 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t315 = #t314 as{TypeError} core::int*;
-          #t313.{core::List::add}{Invariant}(#t315);
+          final core::int* #t236 = #t235 as{TypeError} core::int*;
+          #t234.{core::List::add}{Invariant}(#t236);
         }
       }
     }
-  } =>#t313;
+  } =>#t234;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t316 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t237 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t317 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t238 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t318 = #t317 as{TypeError} core::int*;
-          #t316.{core::Set::add}{Invariant}(#t318);
+          final core::int* #t239 = #t238 as{TypeError} core::int*;
+          #t237.{core::Set::add}{Invariant}(#t239);
         }
       }
     }
-    #t316.{core::Set::add}{Invariant}(null);
-  } =>#t316;
+    #t237.{core::Set::add}{Invariant}(null);
+  } =>#t237;
   core::Map<core::String*, core::int*>* map91 = block {
-    final core::Map<core::String*, core::int*>* #t319 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t240 = <core::String*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t320 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<dynamic, dynamic>* #t241 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::String* #t321 = #t320.{core::MapEntry::key} as{TypeError} core::String*;
-          final core::int* #t322 = #t320.{core::MapEntry::value} as{TypeError} core::int*;
-          #t319.{core::Map::[]=}{Invariant}(#t321, #t322);
+          final core::String* #t242 = #t241.{core::MapEntry::key} as{TypeError} core::String*;
+          final core::int* #t243 = #t241.{core::MapEntry::value} as{TypeError} core::int*;
+          #t240.{core::Map::[]=}{Invariant}(#t242, #t243);
         }
       }
     }
-    #t319.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t319;
+    #t240.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t240;
   core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t323 = <core::int*>[];
-    for (final core::int* #t324 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t323.{core::List::add}{Invariant}(42);
-  } =>#t323;
+    final core::List<core::int*>* #t244 = <core::int*>[];
+    for (final core::int* #t245 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t244.{core::List::add}{Invariant}(42);
+  } =>#t244;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t325 = new col::_CompactLinkedHashSet::•<core::int*>();
-    for (final core::int* #t326 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t325.{core::Set::add}{Invariant}(42);
-  } =>#t325;
+    final core::Set<core::int*>* #t246 = new col::_CompactLinkedHashSet::•<core::int*>();
+    for (final core::int* #t247 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t246.{core::Set::add}{Invariant}(42);
+  } =>#t246;
   core::Map<core::String*, core::int*>* map100 = block {
-    final core::Map<core::String*, core::int*>* #t327 = <core::String*, core::int*>{};
-    for (final core::int* #t328 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
-      #t327.{core::Map::[]=}{Invariant}("bar", 42);
-  } =>#t327;
+    final core::Map<core::String*, core::int*>* #t248 = <core::String*, core::int*>{};
+    for (final core::int* #t249 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1))
+      #t248.{core::Map::[]=}{Invariant}("bar", 42);
+  } =>#t248;
   core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t329 = <core::int*>[];
+    final core::List<core::int*>* #t250 = <core::int*>[];
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
-        #t329.{core::List::add}{Invariant}(i);
+        #t250.{core::List::add}{Invariant}(i);
       }
     }
-  } =>#t329;
+  } =>#t250;
   core::Set<core::int*>* set110 = block {
-    final core::Set<core::int*>* #t330 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t251 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
-        #t330.{core::Set::add}{Invariant}(i);
+        #t251.{core::Set::add}{Invariant}(i);
       }
     }
-    #t330.{core::Set::add}{Invariant}(null);
-  } =>#t330;
+    #t251.{core::Set::add}{Invariant}(null);
+  } =>#t251;
   core::Map<core::String*, core::int*>* map110 = block {
-    final core::Map<core::String*, core::int*>* #t331 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t252 = <core::String*, core::int*>{};
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         core::int* i = :sync-for-iterator.{core::Iterator::current};
-        #t331.{core::Map::[]=}{Invariant}("bar", i);
+        #t252.{core::Map::[]=}{Invariant}("bar", i);
       }
     }
-    #t331.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t331;
+    #t252.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t252;
   core::List<core::int*>* list120 = block {
-    final core::List<core::int*>* #t332 = <core::int*>[];
+    final core::List<core::int*>* #t253 = <core::int*>[];
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
-        #t332.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+        #t253.{core::List::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
       }
     }
-  } =>#t332;
+  } =>#t253;
   core::Set<core::int*>* set120 = block {
-    final core::Set<core::int*>* #t333 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t254 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
-        #t333.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
+        #t254.{core::Set::add}{Invariant}(i as{TypeError,ForDynamic} core::int*);
       }
     }
-    #t333.{core::Set::add}{Invariant}(null);
-  } =>#t333;
+    #t254.{core::Set::add}{Invariant}(null);
+  } =>#t254;
   core::Map<core::String*, core::int*>* map120 = block {
-    final core::Map<core::String*, core::int*>* #t334 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t255 = <core::String*, core::int*>{};
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         dynamic i = :sync-for-iterator.{core::Iterator::current};
-        #t334.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
+        #t255.{core::Map::[]=}{Invariant}("bar", i as{TypeError,ForDynamic} core::int*);
       }
     }
-    #t334.{core::Map::[]=}{Invariant}("baz", null);
-  } =>#t334;
+    #t255.{core::Map::[]=}{Invariant}("baz", null);
+  } =>#t255;
   core::List<core::int*>* list130 = block {
-    final core::List<core::int*>* #t335 = <core::int*>[];
+    final core::List<core::int*>* #t256 = <core::int*>[];
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t335.{core::List::add}{Invariant}(i);
-  } =>#t335;
+      #t256.{core::List::add}{Invariant}(i);
+  } =>#t256;
   core::Set<core::int*>* set130 = block {
-    final core::Set<core::int*>* #t336 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t257 = new col::_CompactLinkedHashSet::•<core::int*>();
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t336.{core::Set::add}{Invariant}(i);
-  } =>#t336;
+      #t257.{core::Set::add}{Invariant}(i);
+  } =>#t257;
   core::Map<core::int*, core::int*>* map130 = block {
-    final core::Map<core::int*, core::int*>* #t337 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t258 = <core::int*, core::int*>{};
     for (core::int* i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
-      #t337.{core::Map::[]=}{Invariant}(i, i);
-  } =>#t337;
+      #t258.{core::Map::[]=}{Invariant}(i, i);
+  } =>#t258;
 }
 static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -2356,91 +1960,81 @@
       #L1:
       {
         block {
-          final core::List<core::int*>* #t338 = <core::int*>[];
+          final core::List<core::int*>* #t259 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t338.{core::List::add}{Invariant}(let final<BottomType> #t339 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:212:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t259.{core::List::add}{Invariant}(let final<BottomType> #t260 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:212:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
                                             ^" in "bar" as{TypeError} core::int*);
-        } =>#t338;
+        } =>#t259;
         block {
-          final core::Set<core::int*>* #t340 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t261 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t340.{core::Set::add}{Invariant}(let final<BottomType> #t341 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:213:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t261.{core::Set::add}{Invariant}(let final<BottomType> #t262 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:213:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
                                             ^" in "bar" as{TypeError} core::int*);
-          #t340.{core::Set::add}{Invariant}(null);
-        } =>#t340;
+          #t261.{core::Set::add}{Invariant}(null);
+        } =>#t261;
         block {
-          final core::Map<core::int*, core::int*>* #t342 = <core::int*, core::int*>{};
+          final core::Map<core::int*, core::int*>* #t263 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t264 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                 ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t265 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                         ^" in "bar" as{TypeError} core::int*);
-          #t342.{core::Map::[]=}{Invariant}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          #t263.{core::Map::[]=}{Invariant}(let final<BottomType> #t266 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:214:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                                ^" in "baz" as{TypeError} core::int*, null);
-        } =>#t342;
+        } =>#t263;
         block {
-          final core::List<core::int*>* #t346 = <core::int*>[];
-          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::List<core::int*>* #t267 = <core::int*>[];
+          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+            #t267.{core::List::addAll}{Invariant}(<core::int*>[let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:215:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
-                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-            for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t348 = :sync-for-iterator.{core::Iterator::current};
-              #t346.{core::List::add}{Invariant}(#t348);
-            }
-          }
-        } =>#t346;
+                                                ^" in "bar" as{TypeError} core::int*]);
+        } =>#t267;
         block {
-          final core::Set<core::int*>* #t349 = new col::_CompactLinkedHashSet::•<core::int*>();
-          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t350 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::Set<core::int*>* #t269 = new col::_CompactLinkedHashSet::•<core::int*>();
+          for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
+            #t269.{core::Set::addAll}{Invariant}(<core::int*>[let final<BottomType> #t270 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
-                                                ^" in "bar" as{TypeError} core::int*].{core::Iterable::iterator};
-            for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t351 = :sync-for-iterator.{core::Iterator::current};
-              #t349.{core::Set::add}{Invariant}(#t351);
-            }
-          }
-          #t349.{core::Set::add}{Invariant}(null);
-        } =>#t349;
+                                                ^" in "bar" as{TypeError} core::int*]);
+          #t269.{core::Set::add}{Invariant}(null);
+        } =>#t269;
         block {
-          final core::Map<core::int*, core::int*>* #t352 = <core::int*, core::int*>{};
+          final core::Map<core::int*, core::int*>* #t271 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
-            core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{let final<BottomType> #t272 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t354 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                     ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int*}.{core::Map::entries}.{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::MapEntry<core::int*, core::int*>* #t355 = :sync-for-iterator.{core::Iterator::current};
-              #t352.{core::Map::[]=}{Invariant}(#t355.{core::MapEntry::key}, #t355.{core::MapEntry::value});
+              final core::MapEntry<core::int*, core::int*>* #t274 = :sync-for-iterator.{core::Iterator::current};
+              #t271.{core::Map::[]=}{Invariant}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
             }
           }
-          #t352.{core::Map::[]=}{Invariant}(let final<BottomType> #t356 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          #t271.{core::Map::[]=}{Invariant}(let final<BottomType> #t275 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:217:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int*, null);
-        } =>#t352;
+        } =>#t271;
         block {
-          final core::List<core::int*>* #t357 = <core::int*>[];
+          final core::List<core::int*>* #t276 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t357.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:218:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            #t276.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:218:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...map];
                                                ^");
-        } =>#t357;
+        } =>#t276;
         block {
-          final core::Set<core::int*>* #t358 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t277 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
-            #t358.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:219:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            #t277.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:219:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null};
                                                ^");
-          #t358.{core::Set::add}{Invariant}(null);
-        } =>#t358;
+          #t277.{core::Set::add}{Invariant}(null);
+        } =>#t277;
         <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:220:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
@@ -2449,66 +2043,66 @@
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
                                                     ^": null};
         block {
-          final core::List<core::String*>* #t359 = <core::String*>[];
+          final core::List<core::String*>* #t278 = <core::String*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t359.{core::List::add}{Invariant}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+              #t278.{core::List::add}{Invariant}(let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                              ^" in 42 as{TypeError} core::String*);
             else
-              #t359.{core::List::add}{Invariant}(let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+              #t278.{core::List::add}{Invariant}(let final<BottomType> #t280 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:221:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                                      ^" in 3.14 as{TypeError} core::String*);
-        } =>#t359;
+        } =>#t278;
         block {
-          final core::Set<core::String*>* #t362 = new col::_CompactLinkedHashSet::•<core::String*>();
+          final core::Set<core::String*>* #t281 = new col::_CompactLinkedHashSet::•<core::String*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t362.{core::Set::add}{Invariant}(let final<BottomType> #t363 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+              #t281.{core::Set::add}{Invariant}(let final<BottomType> #t282 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                              ^" in 42 as{TypeError} core::String*);
             else
-              #t362.{core::Set::add}{Invariant}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+              #t281.{core::Set::add}{Invariant}(let final<BottomType> #t283 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:222:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                                      ^" in 3.14 as{TypeError} core::String*);
-          #t362.{core::Set::add}{Invariant}(null);
-        } =>#t362;
+          #t281.{core::Set::add}{Invariant}(null);
+        } =>#t281;
         block {
-          final core::Map<core::String*, core::String*>* #t365 = <core::String*, core::String*>{};
+          final core::Map<core::String*, core::String*>* #t284 = <core::String*, core::String*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t366 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+              #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t285 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                             ^" in 42 as{TypeError} core::String*);
             else
-              #t365.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+              #t284.{core::Map::[]=}{Invariant}("bar", let final<BottomType> #t286 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:223:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                                            ^" in 3.14 as{TypeError} core::String*);
-          #t365.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t365;
+          #t284.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t284;
         block {
-          final core::List<core::int*>* #t368 = <core::int*>[];
+          final core::List<core::int*>* #t287 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t368.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:224:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t287.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:224:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42];
                                                              ^");
             else
-              #t368.{core::List::add}{Invariant}(42);
-        } =>#t368;
+              #t287.{core::List::add}{Invariant}(42);
+        } =>#t287;
         block {
-          final core::Set<core::int*>* #t369 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t288 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t369.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:225:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t288.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:225:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null};
                                                              ^");
             else
-              #t369.{core::Set::add}{Invariant}(42);
-          #t369.{core::Set::add}{Invariant}(null);
-        } =>#t369;
+              #t288.{core::Set::add}{Invariant}(42);
+          #t288.{core::Set::add}{Invariant}(null);
+        } =>#t288;
         <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
@@ -2517,28 +2111,28 @@
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
                                                                      ^": null};
         block {
-          final core::List<core::int*>* #t370 = <core::int*>[];
+          final core::List<core::int*>* #t289 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t370.{core::List::add}{Invariant}(42);
+              #t289.{core::List::add}{Invariant}(42);
             else
-              #t370.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:227:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t289.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:227:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map];
                                                                      ^");
-        } =>#t370;
+        } =>#t289;
         block {
-          final core::Set<core::int*>* #t371 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t290 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
-              #t371.{core::Set::add}{Invariant}(42);
+              #t290.{core::Set::add}{Invariant}(42);
             else
-              #t371.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:228:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t290.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:228:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null};
                                                                      ^");
-          #t371.{core::Set::add}{Invariant}(null);
-        } =>#t371;
+          #t290.{core::Set::add}{Invariant}(null);
+        } =>#t290;
         <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:229:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
@@ -2548,140 +2142,140 @@
                                                                                     ^": null};
         final core::int* i = 0;
         block {
-          final core::List<core::int*>* #t372 = <core::int*>[];
+          final core::List<core::int*>* #t291 = <core::int*>[];
           {
             core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t373 = :sync-for-iterator.{core::Iterator::current};
+              final core::int* #t292 = :sync-for-iterator.{core::Iterator::current};
               {
                 invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
-                #t372.{core::List::add}{Invariant}(i);
+                #t291.{core::List::add}{Invariant}(i);
               }
             }
           }
-        } =>#t372;
+        } =>#t291;
         block {
-          final core::Set<core::int*>* #t374 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t293 = new col::_CompactLinkedHashSet::•<core::int*>();
           {
             core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t375 = :sync-for-iterator.{core::Iterator::current};
+              final core::int* #t294 = :sync-for-iterator.{core::Iterator::current};
               {
                 invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
-                #t374.{core::Set::add}{Invariant}(i);
+                #t293.{core::Set::add}{Invariant}(i);
               }
             }
           }
-          #t374.{core::Set::add}{Invariant}(null);
-        } =>#t374;
+          #t293.{core::Set::add}{Invariant}(null);
+        } =>#t293;
         block {
-          final core::Map<core::String*, core::int*>* #t376 = <core::String*, core::int*>{};
+          final core::Map<core::String*, core::int*>* #t295 = <core::String*, core::int*>{};
           {
             core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-              final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
+              final core::int* #t296 = :sync-for-iterator.{core::Iterator::current};
               {
                 invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
-                #t376.{core::Map::[]=}{Invariant}("bar", i);
+                #t295.{core::Map::[]=}{Invariant}("bar", i);
               }
             }
           }
-          #t376.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t376;
+          #t295.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t295;
         core::List<dynamic>* list10 = block {
-          final core::List<dynamic>* #t378 = <dynamic>[];
+          final core::List<dynamic>* #t297 = <dynamic>[];
           {
-            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t379 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t298 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:236:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               dynamic i = :sync-for-iterator.{core::Iterator::current};
-              #t378.{core::List::add}{Invariant}(i);
+              #t297.{core::List::add}{Invariant}(i);
             }
           }
-        } =>#t378;
+        } =>#t297;
         core::Set<dynamic>* set10 = block {
-          final core::Set<dynamic>* #t380 = new col::_CompactLinkedHashSet::•<dynamic>();
+          final core::Set<dynamic>* #t299 = new col::_CompactLinkedHashSet::•<dynamic>();
           {
-            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t381 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t300 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               dynamic i = :sync-for-iterator.{core::Iterator::current};
-              #t380.{core::Set::add}{Invariant}(i);
+              #t299.{core::Set::add}{Invariant}(i);
             }
           }
-          #t380.{core::Set::add}{Invariant}(null);
-        } =>#t380;
+          #t299.{core::Set::add}{Invariant}(null);
+        } =>#t299;
         core::Map<core::String*, dynamic>* map10 = block {
-          final core::Map<core::String*, dynamic>* #t382 = <core::String*, dynamic>{};
+          final core::Map<core::String*, dynamic>* #t301 = <core::String*, dynamic>{};
           {
-            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+            core::Iterator<dynamic>* :sync-for-iterator = (let final<BottomType> #t302 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:238:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>*).{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               dynamic i = :sync-for-iterator.{core::Iterator::current};
-              #t382.{core::Map::[]=}{Invariant}("bar", i);
+              #t301.{core::Map::[]=}{Invariant}("bar", i);
             }
           }
-          #t382.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t382;
+          #t301.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t301;
         core::List<core::int*>* list20 = block {
-          final core::List<core::int*>* #t384 = <core::int*>[];
+          final core::List<core::int*>* #t303 = <core::int*>[];
           {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t304 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t386 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t305 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:239:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
-              #t384.{core::List::add}{Invariant}(i);
+              #t303.{core::List::add}{Invariant}(i);
             }
           }
-        } =>#t384;
+        } =>#t303;
         core::Set<core::int*>* set20 = block {
-          final core::Set<core::int*>* #t387 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t306 = new col::_CompactLinkedHashSet::•<core::int*>();
           {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t388 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t307 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t308 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:240:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
-              #t387.{core::Set::add}{Invariant}(i);
+              #t306.{core::Set::add}{Invariant}(i);
             }
           }
-          #t387.{core::Set::add}{Invariant}(null);
-        } =>#t387;
+          #t306.{core::Set::add}{Invariant}(null);
+        } =>#t306;
         core::Map<core::String*, core::int*>* map20 = block {
-          final core::Map<core::String*, core::int*>* #t390 = <core::String*, core::int*>{};
+          final core::Map<core::String*, core::int*>* #t309 = <core::String*, core::int*>{};
           {
-            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[let final<BottomType> #t310 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int*, let final<BottomType> #t311 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:241:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int*].{core::Iterable::iterator};
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               core::int* i = :sync-for-iterator.{core::Iterator::current};
-              #t390.{core::Map::[]=}{Invariant}("bar", i);
+              #t309.{core::Map::[]=}{Invariant}("bar", i);
             }
           }
-          #t390.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t390;
-        final core::List<dynamic>* #t393 = <dynamic>[];
+          #t309.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t309;
+        final core::List<dynamic>* #t312 = <dynamic>[];
         {
-          asy::Stream<dynamic>* :stream = let final<BottomType> #t394 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t313 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:242:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2689,25 +2283,25 @@
           try
             #L2:
             while (true) {
-              dynamic #t395 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t396 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t314 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t315 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t393.{core::List::add}{Invariant}(i);
+                #t312.{core::List::add}{Invariant}(i);
               }
               else
                 break #L2;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t397 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t316 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
-        core::List<dynamic>* list30 = block {} =>#t393;
-        final core::Set<dynamic>* #t398 = new col::_CompactLinkedHashSet::•<dynamic>();
+        core::List<dynamic>* list30 = block {} =>#t312;
+        final core::Set<dynamic>* #t317 = new col::_CompactLinkedHashSet::•<dynamic>();
         {
-          asy::Stream<dynamic>* :stream = let final<BottomType> #t399 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t318 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2715,27 +2309,27 @@
           try
             #L3:
             while (true) {
-              dynamic #t400 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t401 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t319 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t320 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t398.{core::Set::add}{Invariant}(i);
+                #t317.{core::Set::add}{Invariant}(i);
               }
               else
                 break #L3;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t402 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t321 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Set<dynamic>* set30 = block {
-          #t398.{core::Set::add}{Invariant}(null);
-        } =>#t398;
-        final core::Map<core::String*, dynamic>* #t403 = <core::String*, dynamic>{};
+          #t317.{core::Set::add}{Invariant}(null);
+        } =>#t317;
+        final core::Map<core::String*, dynamic>* #t322 = <core::String*, dynamic>{};
         {
-          asy::Stream<dynamic>* :stream = let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          asy::Stream<dynamic>* :stream = let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:244:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>*;
@@ -2743,149 +2337,149 @@
           try
             #L4:
             while (true) {
-              dynamic #t405 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t406 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t324 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t325 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t403.{core::Map::[]=}{Invariant}("bar", i);
+                #t322.{core::Map::[]=}{Invariant}("bar", i);
               }
               else
                 break #L4;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t407 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t326 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Map<core::String*, dynamic>* map30 = block {
-          #t403.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t403;
-        final core::List<core::int*>* #t408 = <core::int*>[];
+          #t322.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t322;
+        final core::List<core::int*>* #t327 = <core::int*>[];
         {
-          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t409 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t328 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t410 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t329 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:245:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int*]);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
             #L5:
             while (true) {
-              dynamic #t411 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t412 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t330 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t331 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 core::int* i = :for-iterator.{asy::_StreamIterator::current};
-                #t408.{core::List::add}{Invariant}(i);
+                #t327.{core::List::add}{Invariant}(i);
               }
               else
                 break #L5;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t413 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t332 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
-        core::List<core::int*>* list40 = block {} =>#t408;
-        final core::Set<core::int*>* #t414 = new col::_CompactLinkedHashSet::•<core::int*>();
+        core::List<core::int*>* list40 = block {} =>#t327;
+        final core::Set<core::int*>* #t333 = new col::_CompactLinkedHashSet::•<core::int*>();
         {
-          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t415 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t334 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t335 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:246:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int*]);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
             #L6:
             while (true) {
-              dynamic #t417 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t418 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t336 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t337 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 core::int* i = :for-iterator.{asy::_StreamIterator::current};
-                #t414.{core::Set::add}{Invariant}(i);
+                #t333.{core::Set::add}{Invariant}(i);
               }
               else
                 break #L6;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t419 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t338 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Set<core::int*>* set40 = block {
-          #t414.{core::Set::add}{Invariant}(null);
-        } =>#t414;
-        final core::Map<core::String*, core::int*>* #t420 = <core::String*, core::int*>{};
+          #t333.{core::Set::add}{Invariant}(null);
+        } =>#t333;
+        final core::Map<core::String*, core::int*>* #t339 = <core::String*, core::int*>{};
         {
-          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t421 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t340 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t422 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int*, let final<BottomType> #t341 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:247:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int*]);
           asy::_StreamIterator<core::int*>* :for-iterator = new asy::_StreamIterator::•<core::int*>(:stream);
           try
             #L7:
             while (true) {
-              dynamic #t423 = asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t424 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t342 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t343 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool>(:result)) {
                 core::int* i = :for-iterator.{asy::_StreamIterator::current};
-                #t420.{core::Map::[]=}{Invariant}("bar", i);
+                #t339.{core::Map::[]=}{Invariant}("bar", i);
               }
               else
                 break #L7;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t425 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t344 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Map<core::String*, core::int*>* map40 = block {
-          #t420.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t420;
+          #t339.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t339;
         core::List<core::int*>* list50 = block {
-          final core::List<core::int*>* #t426 = <core::int*>[];
+          final core::List<core::int*>* #t345 = <core::int*>[];
           for (; ; )
-            #t426.{core::List::add}{Invariant}(42);
-        } =>#t426;
+            #t345.{core::List::add}{Invariant}(42);
+        } =>#t345;
         core::Set<core::int*>* set50 = block {
-          final core::Set<core::int*>* #t427 = new col::_CompactLinkedHashSet::•<core::int*>();
+          final core::Set<core::int*>* #t346 = new col::_CompactLinkedHashSet::•<core::int*>();
           for (; ; )
-            #t427.{core::Set::add}{Invariant}(42);
-          #t427.{core::Set::add}{Invariant}(null);
-        } =>#t427;
+            #t346.{core::Set::add}{Invariant}(42);
+          #t346.{core::Set::add}{Invariant}(null);
+        } =>#t346;
         core::Map<core::String*, core::int*>* map50 = block {
-          final core::Map<core::String*, core::int*>* #t428 = <core::String*, core::int*>{};
+          final core::Map<core::String*, core::int*>* #t347 = <core::String*, core::int*>{};
           for (; ; )
-            #t428.{core::Map::[]=}{Invariant}("bar", 42);
-          #t428.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t428;
+            #t347.{core::Map::[]=}{Invariant}("bar", 42);
+          #t347.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t347;
         core::List<core::int*>* list60 = block {
-          final core::List<core::int*>* #t429 = <core::int*>[];
-          for (; let final<BottomType> #t430 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:251:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::List<core::int*>* #t348 = <core::int*>[];
+          for (; let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:251:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool*; )
-            #t429.{core::List::add}{Invariant}(42);
-        } =>#t429;
+            #t348.{core::List::add}{Invariant}(42);
+        } =>#t348;
         core::Set<core::int*>* set60 = block {
-          final core::Set<core::int*>* #t431 = new col::_CompactLinkedHashSet::•<core::int*>();
-          for (; let final<BottomType> #t432 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:252:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Set<core::int*>* #t350 = new col::_CompactLinkedHashSet::•<core::int*>();
+          for (; let final<BottomType> #t351 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:252:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-            #t431.{core::Set::add}{Invariant}(42);
-          #t431.{core::Set::add}{Invariant}(null);
-        } =>#t431;
+            #t350.{core::Set::add}{Invariant}(42);
+          #t350.{core::Set::add}{Invariant}(null);
+        } =>#t350;
         core::Map<core::String*, core::int*>* map60 = block {
-          final core::Map<core::String*, core::int*>* #t433 = <core::String*, core::int*>{};
-          for (; let final<BottomType> #t434 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:253:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Map<core::String*, core::int*>* #t352 = <core::String*, core::int*>{};
+          for (; let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:253:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool*; )
-            #t433.{core::Map::[]=}{Invariant}("bar", 42);
-          #t433.{core::Map::[]=}{Invariant}("baz", null);
-        } =>#t433;
+            #t352.{core::Map::[]=}{Invariant}("bar", 42);
+          #t352.{core::Map::[]=}{Invariant}("baz", null);
+        } =>#t352;
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
@@ -2893,7 +2487,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -2902,37 +2495,37 @@
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
   block {
-    final core::List<core::int*>* #t435 = <core::int*>[];
+    final core::List<core::int*>* #t354 = <core::int*>[];
     await for (core::int* i in stream)
-      #t435.{core::List::add}{Invariant}(i);
-  } =>#t435;
+      #t354.{core::List::add}{Invariant}(i);
+  } =>#t354;
   block {
-    final core::Set<core::int*>* #t436 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t355 = new col::_CompactLinkedHashSet::•<core::int*>();
     await for (core::int* i in stream)
-      #t436.{core::Set::add}{Invariant}(i);
-  } =>#t436;
+      #t355.{core::Set::add}{Invariant}(i);
+  } =>#t355;
   block {
-    final core::Map<core::String*, core::int*>* #t437 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t356 = <core::String*, core::int*>{};
     await for (core::int* i in stream)
-      #t437.{core::Map::[]=}{Invariant}("bar", i);
-  } =>#t437;
+      #t356.{core::Map::[]=}{Invariant}("bar", i);
+  } =>#t356;
 }
 static method testPromotion(self::A* a) → dynamic {
   core::List<core::int*>* list10 = block {
-    final core::List<core::int*>* #t438 = <core::int*>[];
+    final core::List<core::int*>* #t357 = <core::int*>[];
     if(a is self::B*)
-      #t438.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t438;
+      #t357.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t357;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t439 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t358 = new col::_CompactLinkedHashSet::•<core::int*>();
     if(a is self::B*)
-      #t439.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
-  } =>#t439;
+      #t358.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo});
+  } =>#t358;
   core::Map<core::int*, core::int*>* map10 = block {
-    final core::Map<core::int*, core::int*>* #t440 = <core::int*, core::int*>{};
+    final core::Map<core::int*, core::int*>* #t359 = <core::int*, core::int*>{};
     if(a is self::B*)
-      #t440.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
-  } =>#t440;
+      #t359.{core::Map::[]=}{Invariant}(a{self::B*}.{self::B::foo}, a{self::B*}.{self::B::foo});
+  } =>#t359;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect
index 02b4a69..64e0ad7 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* a) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart:10:10: Error: Can't use 'a' because it is declared more than once.
   A(this.a);
-         ^", super core::Object::•()
+         ^"
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect
index 02b4a69..64e0ad7 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* a) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart:10:10: Error: Can't use 'a' because it is declared more than once.
   A(this.a);
-         ^", super core::Object::•()
+         ^"
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
index a4ac3f4..f62a5eb 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
@@ -31,7 +31,6 @@
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -49,7 +48,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -76,7 +74,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -94,7 +91,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect
index c592b47..227ba25 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* v) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart:10:10: Error: Can't use 'v' because it is declared more than once.
   A(this.v);
-         ^", super core::Object::•()
+         ^"
     ;
   constructor second() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect
index c592b47..227ba25 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
   constructor •(core::int* v) → self::A*
     : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart:10:10: Error: Can't use 'v' because it is declared more than once.
   A(this.v);
-         ^", super core::Object::•()
+         ^"
     ;
   constructor second() → self::A*
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.expect
index bd5bf0d..807a6b5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.expect
@@ -5,33 +5,30 @@
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
   list = block {
-    final core::List<core::String*>* #t1 = <core::String*>[];
-    #t1.{core::List::add}{Invariant}("foo");
+    final core::List<core::String*>* #t1 = <core::String*>["foo"];
     final core::Iterable<core::String*>* #t2 = list;
     if(!#t2.{core::Object::==}(null))
-      for (final core::String* #t3 in #t2)
-        #t1.{core::List::add}{Invariant}(#t3);
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
 }
 static method nullAwareSetSpread(core::Set<core::String*>* set) → dynamic {
   set = block {
-    final core::Set<core::String*>* #t4 = col::LinkedHashSet::•<core::String*>();
-    #t4.{core::Set::add}{Invariant}("foo");
-    final core::Iterable<core::String*>* #t5 = set;
-    if(!#t5.{core::Object::==}(null))
-      for (final core::String* #t6 in #t5)
-        #t4.{core::Set::add}{Invariant}(#t6);
-  } =>#t4;
+    final core::Set<core::String*>* #t3 = col::LinkedHashSet::•<core::String*>();
+    #t3.{core::Set::add}{Invariant}("foo");
+    final core::Iterable<core::String*>* #t4 = set;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::Set::addAll}{Invariant}(#t4);
+  } =>#t3;
 }
 static method nullAwareMapSpread(core::Map<core::int*, core::String*>* map) → dynamic {
   map = block {
-    final core::Map<core::int*, core::String*>* #t7 = <core::int*, core::String*>{};
-    #t7.{core::Map::[]=}{Invariant}(0, "foo");
-    final core::Map<core::int*, core::String*>* #t8 = map;
-    if(!#t8.{core::Object::==}(null))
-      for (final core::MapEntry<core::int*, core::String*>* #t9 in #t8.{core::Map::entries})
-        #t7.{core::Map::[]=}{Invariant}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
-  } =>#t7;
+    final core::Map<core::int*, core::String*>* #t5 = <core::int*, core::String*>{};
+    #t5.{core::Map::[]=}{Invariant}(0, "foo");
+    final core::Map<core::int*, core::String*>* #t6 = map;
+    if(!#t6.{core::Object::==}(null))
+      for (final core::MapEntry<core::int*, core::String*>* #t7 in #t6.{core::Map::entries})
+        #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
+  } =>#t5;
 }
 static method main() → dynamic {
   self::nullAwareListSpread(null);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect
index 67a6d44..e5e1b00 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.weak.transformed.expect
@@ -5,45 +5,34 @@
 
 static method nullAwareListSpread(core::List<core::String*>* list) → dynamic {
   list = block {
-    final core::List<core::String*>* #t1 = <core::String*>[];
-    #t1.{core::List::add}{Invariant}("foo");
+    final core::List<core::String*>* #t1 = <core::String*>["foo"];
     final core::Iterable<core::String*>* #t2 = list;
-    if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String* #t3 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t3);
-      }
-    }
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
 }
 static method nullAwareSetSpread(core::Set<core::String*>* set) → dynamic {
   set = block {
-    final core::Set<core::String*>* #t4 = new col::_CompactLinkedHashSet::•<core::String*>();
-    #t4.{core::Set::add}{Invariant}("foo");
-    final core::Iterable<core::String*>* #t5 = set;
-    if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::String*>* :sync-for-iterator = #t5.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String* #t6 = :sync-for-iterator.{core::Iterator::current};
-        #t4.{core::Set::add}{Invariant}(#t6);
-      }
-    }
-  } =>#t4;
+    final core::Set<core::String*>* #t3 = new col::_CompactLinkedHashSet::•<core::String*>();
+    #t3.{core::Set::add}{Invariant}("foo");
+    final core::Iterable<core::String*>* #t4 = set;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::Set::addAll}{Invariant}(#t4);
+  } =>#t3;
 }
 static method nullAwareMapSpread(core::Map<core::int*, core::String*>* map) → dynamic {
   map = block {
-    final core::Map<core::int*, core::String*>* #t7 = <core::int*, core::String*>{};
-    #t7.{core::Map::[]=}{Invariant}(0, "foo");
-    final core::Map<core::int*, core::String*>* #t8 = map;
-    if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::String*>>* :sync-for-iterator = #t8.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int*, core::String*>* #t5 = <core::int*, core::String*>{};
+    #t5.{core::Map::[]=}{Invariant}(0, "foo");
+    final core::Map<core::int*, core::String*>* #t6 = map;
+    if(!#t6.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int*, core::String*>>* :sync-for-iterator = #t6.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int*, core::String*>* #t9 = :sync-for-iterator.{core::Iterator::current};
-        #t7.{core::Map::[]=}{Invariant}(#t9.{core::MapEntry::key}, #t9.{core::MapEntry::value});
+        final core::MapEntry<core::int*, core::String*>* #t7 = :sync-for-iterator.{core::Iterator::current};
+        #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
       }
     }
-  } =>#t7;
+  } =>#t5;
 }
 static method main() → dynamic {
   self::nullAwareListSpread(null);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.expect
index c862e55..3740a07 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.expect
@@ -13,35 +13,30 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
-    for (final core::int* #t2 in <core::int*>[2])
-      #t1.{core::List::add}{Invariant}(#t2);
-    final core::Iterable<core::int*>* #t3 = <core::int*>[3];
-    if(!#t3.{core::Object::==}(null))
-      for (final core::int* #t4 in #t3)
-        #t1.{core::List::add}{Invariant}(#t4);
+    final core::List<core::int*>* #t1 = <core::int*>[1];
+    #t1.{core::List::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t2 = <core::int*>[3];
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
   final core::Map<core::int*, core::int*>* aMap = block {
-    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
-    #t5.{core::Map::[]=}{Invariant}(1, 1);
-    for (final core::MapEntry<core::int*, core::int*>* #t6 in <core::int*, core::int*>{2: 2}.{core::Map::entries})
-      #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
-    final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
-    if(!#t7.{core::Object::==}(null))
-      for (final core::MapEntry<core::int*, core::int*>* #t8 in #t7.{core::Map::entries})
-        #t5.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-  } =>#t5;
+    final core::Map<core::int*, core::int*>* #t3 = <core::int*, core::int*>{};
+    #t3.{core::Map::[]=}{Invariant}(1, 1);
+    for (final core::MapEntry<core::int*, core::int*>* #t4 in <core::int*, core::int*>{2: 2}.{core::Map::entries})
+      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{3: 3};
+    if(!#t5.{core::Object::==}(null))
+      for (final core::MapEntry<core::int*, core::int*>* #t6 in #t5.{core::Map::entries})
+        #t3.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
+  } =>#t3;
   final core::Set<core::int*>* aSet = block {
-    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
-    #t9.{core::Set::add}{Invariant}(1);
-    for (final core::int* #t10 in <core::int*>[2])
-      #t9.{core::Set::add}{Invariant}(#t10);
-    final core::Iterable<core::int*>* #t11 = <core::int*>[3];
-    if(!#t11.{core::Object::==}(null))
-      for (final core::int* #t12 in #t11)
-        #t9.{core::Set::add}{Invariant}(#t12);
-  } =>#t9;
+    final core::Set<core::int*>* #t7 = col::LinkedHashSet::•<core::int*>();
+    #t7.{core::Set::add}{Invariant}(1);
+    #t7.{core::Set::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t8 = <core::int*>[3];
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::Set::addAll}{Invariant}(#t8);
+  } =>#t7;
   final dynamic aSetOrMap = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart:23:21: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   final aSetOrMap = {...foo()};
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect
index 791309b..2972e81 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.weak.transformed.expect
@@ -13,62 +13,39 @@
 
 static method main() → dynamic {
   final core::List<core::int*>* aList = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(1);
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t2 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t2);
-      }
-    }
-    final core::Iterable<core::int*>* #t3 = <core::int*>[3];
-    if(!#t3.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t3.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t4 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t4);
-      }
-    }
+    final core::List<core::int*>* #t1 = <core::int*>[1];
+    #t1.{core::List::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t2 = <core::int*>[3];
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2);
   } =>#t1;
   final core::Map<core::int*, core::int*>* aMap = block {
-    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{};
-    #t5.{core::Map::[]=}{Invariant}(1, 1);
+    final core::Map<core::int*, core::int*>* #t3 = <core::int*, core::int*>{};
+    #t3.{core::Map::[]=}{Invariant}(1, 1);
     {
       core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{2: 2}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::int*, core::int*>* #t4 = :sync-for-iterator.{core::Iterator::current};
+        #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+      }
+    }
+    final core::Map<core::int*, core::int*>* #t5 = <core::int*, core::int*>{3: 3};
+    if(!#t5.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = #t5.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final core::MapEntry<core::int*, core::int*>* #t6 = :sync-for-iterator.{core::Iterator::current};
-        #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
+        #t3.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
       }
     }
-    final core::Map<core::int*, core::int*>* #t7 = <core::int*, core::int*>{3: 3};
-    if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = #t7.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int*, core::int*>* #t8 = :sync-for-iterator.{core::Iterator::current};
-        #t5.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-      }
-    }
-  } =>#t5;
+  } =>#t3;
   final core::Set<core::int*>* aSet = block {
-    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t9.{core::Set::add}{Invariant}(1);
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[2].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::Set::add}{Invariant}(#t10);
-      }
-    }
-    final core::Iterable<core::int*>* #t11 = <core::int*>[3];
-    if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t11.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::Set::add}{Invariant}(#t12);
-      }
-    }
-  } =>#t9;
+    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t7.{core::Set::add}{Invariant}(1);
+    #t7.{core::Set::addAll}{Invariant}(<core::int*>[2]);
+    final core::Iterable<core::int*>* #t8 = <core::int*>[3];
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::Set::addAll}{Invariant}(#t8);
+  } =>#t7;
   final dynamic aSetOrMap = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart:23:21: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   final aSetOrMap = {...foo()};
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.expect
index 6d91849..dc07d28 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.expect
@@ -110,177 +110,153 @@
   core::Map<core::int*, core::num*>* mapIntNum = <core::int*, core::num*>{42: 42};
   core::List<core::num*>* listNum = <core::num*>[42];
   core::List<dynamic>* lhs10 = block {
-    final core::List<dynamic>* #t1 = <dynamic>[];
-    for (final dynamic #t2 in <dynamic>[])
-      #t1.{core::List::add}{Invariant}(#t2);
+    final core::List<dynamic>* #t1 = core::List::of<dynamic>(<dynamic>[]);
   } =>#t1;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t3 = col::LinkedHashSet::•<dynamic>();
-    for (final dynamic #t4 in <dynamic>[])
-      #t3.{core::Set::add}{Invariant}(#t4);
-  } =>#t3;
+    final core::Set<dynamic>* #t2 = col::LinkedHashSet::of<dynamic>(<dynamic>[]);
+  } =>#t2;
   core::Map<dynamic, dynamic>* map10 = block {
+    final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t4 in <dynamic, dynamic>{}.{core::Map::entries})
+      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+  } =>#t3;
+  core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     for (final core::MapEntry<dynamic, dynamic>* #t6 in <dynamic, dynamic>{}.{core::Map::entries})
       #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
   } =>#t5;
-  core::Map<dynamic, dynamic>* map10ambiguous = block {
-    final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t8 in <dynamic, dynamic>{}.{core::Map::entries})
-      #t7.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-  } =>#t7;
   core::List<core::int*>* lhs20 = block {
-    final core::List<core::int*>* #t9 = <core::int*>[];
-    for (final core::int* #t10 in spread)
-      #t9.{core::List::add}{Invariant}(#t10);
-  } =>#t9;
+    final core::List<core::int*>* #t7 = core::List::of<core::int*>(spread);
+  } =>#t7;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t11 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t12 in spread)
-      #t11.{core::Set::add}{Invariant}(#t12);
-    #t11.{core::Set::add}{Invariant}(42);
-  } =>#t11;
+    final core::Set<core::int*>* #t8 = col::LinkedHashSet::of<core::int*>(spread);
+    #t8.{core::Set::add}{Invariant}(42);
+  } =>#t8;
   core::Set<core::int*>* set20ambiguous = block {
-    final core::Set<core::int*>* #t13 = col::LinkedHashSet::•<core::int*>();
-    for (final dynamic #t14 in spread) {
-      final core::int* #t15 = #t14 as{TypeError} core::int*;
-      #t13.{core::Set::add}{Invariant}(#t15);
+    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t10 in spread) {
+      final core::int* #t11 = #t10 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t11);
     }
-  } =>#t13;
+  } =>#t9;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t17 in mapSpread.{core::Map::entries})
-      #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-    #t16.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t16;
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t13 in mapSpread.{core::Map::entries})
+      #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
+    #t12.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t12;
   core::Map<core::String*, core::int*>* map20ambiguous = block {
-    final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t19 in mapSpread.{core::Map::entries})
-      #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
-  } =>#t18;
+    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t15 in mapSpread.{core::Map::entries})
+      #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+  } =>#t14;
   core::List<dynamic>* lhs21 = block {
-    final core::List<dynamic>* #t20 = <dynamic>[];
-    for (final dynamic #t21 in (spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t20.{core::List::add}{Invariant}(#t21);
-  } =>#t20;
+    final core::List<dynamic>* #t16 = core::List::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t16;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t22 = col::LinkedHashSet::•<dynamic>();
-    for (final dynamic #t23 in (spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*)
-      #t22.{core::Set::add}{Invariant}(#t23);
-    #t22.{core::Set::add}{Invariant}(42);
-  } =>#t22;
+    final core::Set<dynamic>* #t17 = col::LinkedHashSet::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t17.{core::Set::add}{Invariant}(42);
+  } =>#t17;
   core::Map<dynamic, dynamic>* map21 = block {
-    final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t25 in ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
-      #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
-    #t24.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t24;
+    final core::Map<dynamic, dynamic>* #t18 = <dynamic, dynamic>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t19 in ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries})
+      #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
+    #t18.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t18;
   dynamic map21ambiguous = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:66:28: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   dynamic map21ambiguous = {...(mapSpread as dynamic)};
                            ^";
   core::List<core::int*>* lhs22 = block {
-    final core::List<core::int*>* #t26 = <core::int*>[];
-    for (final core::int* #t27 in <core::int*>[])
-      #t26.{core::List::add}{Invariant}(#t27);
-  } =>#t26;
+    final core::List<core::int*>* #t20 = core::List::of<core::int*>(<core::int*>[]);
+  } =>#t20;
   core::Set<core::int*>* set22 = block {
-    final core::Set<core::int*>* #t28 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t29 in <core::int*>[])
-      #t28.{core::Set::add}{Invariant}(#t29);
-    #t28.{core::Set::add}{Invariant}(42);
-  } =>#t28;
+    final core::Set<core::int*>* #t21 = col::LinkedHashSet::of<core::int*>(<core::int*>[]);
+    #t21.{core::Set::add}{Invariant}(42);
+  } =>#t21;
   core::Set<core::int*>* set22ambiguous = block {
-    final core::Set<core::int*>* #t30 = col::LinkedHashSet::•<core::int*>();
-    for (final dynamic #t31 in <core::int*>[]) {
-      final core::int* #t32 = #t31 as{TypeError} core::int*;
-      #t30.{core::Set::add}{Invariant}(#t32);
+    final core::Set<core::int*>* #t22 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t23 in <core::int*>[]) {
+      final core::int* #t24 = #t23 as{TypeError} core::int*;
+      #t22.{core::Set::add}{Invariant}(#t24);
     }
-  } =>#t30;
+  } =>#t22;
   core::Map<core::String*, core::int*>* map22 = block {
-    final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t34 in <core::String*, core::int*>{}.{core::Map::entries})
-      #t33.{core::Map::[]=}{Invariant}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
-  } =>#t33;
+    final core::Map<core::String*, core::int*>* #t25 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t26 in <core::String*, core::int*>{}.{core::Map::entries})
+      #t25.{core::Map::[]=}{Invariant}(#t26.{core::MapEntry::key}, #t26.{core::MapEntry::value});
+  } =>#t25;
   core::List<core::List<core::int*>*>* lhs23 = block {
-    final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
-    for (final core::List<core::int*>* #t36 in <core::List<core::int*>*>[<core::int*>[]])
-      #t35.{core::List::add}{Invariant}(#t36);
-  } =>#t35;
+    final core::List<core::List<core::int*>*>* #t27 = core::List::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t27;
   core::Set<core::List<core::int*>*>* set23 = block {
-    final core::Set<core::List<core::int*>*>* #t37 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (final core::List<core::int*>* #t38 in <core::List<core::int*>*>[<core::int*>[]])
-      #t37.{core::Set::add}{Invariant}(#t38);
-    #t37.{core::Set::add}{Invariant}(<core::int*>[42]);
-  } =>#t37;
+    final core::Set<core::List<core::int*>*>* #t28 = col::LinkedHashSet::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+    #t28.{core::Set::add}{Invariant}(<core::int*>[42]);
+  } =>#t28;
   core::Set<core::List<core::int*>*>* set23ambiguous = block {
-    final core::Set<core::List<core::int*>*>* #t39 = col::LinkedHashSet::•<core::List<core::int*>*>();
-    for (final dynamic #t40 in <core::List<core::int*>*>[<core::int*>[]]) {
-      final core::List<core::int*>* #t41 = #t40 as{TypeError} core::List<core::int*>*;
-      #t39.{core::Set::add}{Invariant}(#t41);
+    final core::Set<core::List<core::int*>*>* #t29 = col::LinkedHashSet::•<core::List<core::int*>*>();
+    for (final dynamic #t30 in <core::List<core::int*>*>[<core::int*>[]]) {
+      final core::List<core::int*>* #t31 = #t30 as{TypeError} core::List<core::int*>*;
+      #t29.{core::Set::add}{Invariant}(#t31);
     }
-  } =>#t39;
+  } =>#t29;
   core::Map<core::String*, core::List<core::int*>*>* map23 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
-    for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 in <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries})
-      #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-  } =>#t42;
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
+    for (final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 in <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries})
+      #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
+  } =>#t32;
   dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:98:28: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
   dynamic map24ambiguous = {...spread, ...mapSpread};
                            ^";
-  core::int* lhs30 = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:100:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+  core::int* lhs30 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:100:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
  - 'List' is from 'dart:core'.
   int lhs30 = /*@ typeArgs=int* */ [...spread];
                                    ^" in ( block {
-    final core::List<core::int*>* #t45 = <core::int*>[];
-    for (final core::int* #t46 in spread)
-      #t45.{core::List::add}{Invariant}(#t46);
-  } =>#t45) as{TypeError} core::int*;
-  core::int* set30 = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:102:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+    final core::List<core::int*>* #t35 = core::List::of<core::int*>(spread);
+  } =>#t35) as{TypeError} core::int*;
+  core::int* set30 = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:102:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
   int set30 = /*@ typeArgs=int* */ {...spread, 42};
                                    ^" in ( block {
-    final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
-    for (final core::int* #t49 in spread)
-      #t48.{core::Set::add}{Invariant}(#t49);
-    #t48.{core::Set::add}{Invariant}(42);
-  } =>#t48) as{TypeError} core::int*;
-  core::int* set30ambiguous = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:105:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int*>* #t37 = col::LinkedHashSet::of<core::int*>(spread);
+    #t37.{core::Set::add}{Invariant}(42);
+  } =>#t37) as{TypeError} core::int*;
+  core::int* set30ambiguous = let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:105:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
       {...spread};
       ^" in ( block {
-    final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
-    for (final dynamic #t52 in spread) {
-      final core::int* #t53 = #t52 as{TypeError} core::int*;
-      #t51.{core::Set::add}{Invariant}(#t53);
+    final core::Set<core::int*>* #t39 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t40 in spread) {
+      final core::int* #t41 = #t40 as{TypeError} core::int*;
+      #t39.{core::Set::add}{Invariant}(#t41);
     }
-  } =>#t51) as{TypeError} core::int*;
-  core::int* map30 = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:108:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+  } =>#t39) as{TypeError} core::int*;
+  core::int* map30 = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:108:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread, \"baz\": 42};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t56 in mapSpread.{core::Map::entries})
-      #t55.{core::Map::[]=}{Invariant}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
-    #t55.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t55) as{TypeError} core::int*;
-  core::int* map30ambiguous = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:111:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String*, core::int*>* #t43 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t44 in mapSpread.{core::Map::entries})
+      #t43.{core::Map::[]=}{Invariant}(#t44.{core::MapEntry::key}, #t44.{core::MapEntry::value});
+    #t43.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t43) as{TypeError} core::int*;
+  core::int* map30ambiguous = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:111:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t59 in mapSpread.{core::Map::entries})
-      #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
-  } =>#t58) as{TypeError} core::int*;
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t47 in mapSpread.{core::Map::entries})
+      #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
+  } =>#t46) as{TypeError} core::int*;
   core::List<dynamic>* lhs40 = <dynamic>[invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:113:38: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   List<dynamic> lhs40 = <dynamic>[...notSpreadInt];
                                      ^"];
   core::Set<dynamic>* set40 = block {
-    final core::Set<dynamic>* #t60 = col::LinkedHashSet::•<dynamic>();
-    #t60.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:115:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t48 = col::LinkedHashSet::•<dynamic>();
+    #t48.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:115:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set40 = <dynamic>{...notSpreadInt};
                                     ^");
-  } =>#t60;
+  } =>#t48;
   core::Map<dynamic, dynamic>* map40 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:117:55: Error: Unexpected type 'int' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map40 = <dynamic, dynamic>{...notSpreadInt};
                                                       ^": null};
@@ -288,11 +264,11 @@
   List<dynamic> lhs50 = <dynamic>[...notSpreadFunction];
                                      ^"];
   core::Set<dynamic>* set50 = block {
-    final core::Set<dynamic>* #t61 = col::LinkedHashSet::•<dynamic>();
-    #t61.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:121:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t49 = col::LinkedHashSet::•<dynamic>();
+    #t49.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:121:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set50 = <dynamic>{...notSpreadFunction};
                                     ^");
-  } =>#t61;
+  } =>#t49;
   core::Map<dynamic, dynamic>* map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:123:55: Error: Unexpected type 'int Function()' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map50 = <dynamic, dynamic>{...notSpreadFunction};
                                                       ^": null};
@@ -300,11 +276,11 @@
   List<String> lhs60 = <String>[...spread];
                                    ^"];
   core::Set<core::String*>* set60 = block {
-    final core::Set<core::String*>* #t62 = col::LinkedHashSet::•<core::String*>();
-    #t62.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:127:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
+    final core::Set<core::String*>* #t50 = col::LinkedHashSet::•<core::String*>();
+    #t50.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:127:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{...spread};
                                   ^");
-  } =>#t62;
+  } =>#t50;
   core::Map<core::int*, core::int*>* map60 = <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:129:39: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
   Map<int, int> map60 = <int, int>{...mapSpread};
                                       ^": null};
@@ -315,92 +291,90 @@
   List<int> lhs70 = <int>[...null];
                              ^"];
   core::Set<core::int*>* set70 = block {
-    final core::Set<core::int*>* #t63 = col::LinkedHashSet::•<core::int*>();
-    #t63.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:135:29: Error: Can't spread a value with static type 'Null'.
+    final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
+    #t51.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:135:29: Error: Can't spread a value with static type 'Null'.
   Set<int> set70 = <int>{...null};
                             ^");
-  } =>#t63;
+  } =>#t51;
   core::Set<dynamic>* set71ambiguous = block {
-    final core::Set<dynamic>* #t64 = col::LinkedHashSet::•<dynamic>();
-    #t64.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:139:8: Error: Expected ',' before this.
+    final core::Set<dynamic>* #t52 = col::LinkedHashSet::•<dynamic>();
+    #t52.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:139:8: Error: Expected ',' before this.
     ...null,
        ^");
-    for (final dynamic #t65 in <dynamic>[]) {
-      final dynamic #t66 = #t65 as{TypeError} dynamic;
-      #t64.{core::Set::add}{Invariant}(#t66);
+    for (final dynamic #t53 in <dynamic>[]) {
+      final dynamic #t54 = #t53 as{TypeError} dynamic;
+      #t52.{core::Set::add}{Invariant}(#t54);
     }
-  } =>#t64;
+  } =>#t52;
   core::Map<core::String*, core::int*>* map70 = <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:144:45: Error: Can't spread a value with static type 'Null'.
   Map<String, int> map70 = <String, int>{...null};
                                             ^": null};
   core::List<core::int*>* lhs80 = block {
-    final core::List<core::int*>* #t67 = <core::int*>[];
-    final core::Iterable<core::int*>* #t68 = null;
-    if(!#t68.{core::Object::==}(null))
-      for (final core::int* #t69 in #t68)
-        #t67.{core::List::add}{Invariant}(#t69);
-  } =>#t67;
+    final core::List<core::int*>* #t55 = <core::int*>[];
+    final core::Iterable<core::int*>* #t56 = null;
+    if(!#t56.{core::Object::==}(null))
+      #t55.{core::List::addAll}{Invariant}(#t56);
+  } =>#t55;
   core::Set<core::int*>* set80 = block {
-    final core::Set<core::int*>* #t70 = col::LinkedHashSet::•<core::int*>();
-    final core::Iterable<core::int*>* #t71 = null;
-    if(!#t71.{core::Object::==}(null))
-      for (final core::int* #t72 in #t71)
-        #t70.{core::Set::add}{Invariant}(#t72);
-  } =>#t70;
+    final core::Set<core::int*>* #t57 = col::LinkedHashSet::•<core::int*>();
+    final core::Iterable<core::int*>* #t58 = null;
+    if(!#t58.{core::Object::==}(null))
+      #t57.{core::Set::addAll}{Invariant}(#t58);
+  } =>#t57;
   core::Set<dynamic>* set81ambiguous = block {
-    final core::Set<dynamic>* #t73 = col::LinkedHashSet::•<dynamic>();
-    final core::Iterable<dynamic>* #t74 = null;
-    if(!#t74.{core::Object::==}(null))
-      for (final dynamic #t75 in #t74) {
-        final dynamic #t76 = #t75 as{TypeError} dynamic;
-        #t73.{core::Set::add}{Invariant}(#t76);
+    final core::Set<dynamic>* #t59 = col::LinkedHashSet::•<dynamic>();
+    final core::Iterable<dynamic>* #t60 = null;
+    if(!#t60.{core::Object::==}(null))
+      for (final dynamic #t61 in #t60) {
+        final dynamic #t62 = #t61 as{TypeError} dynamic;
+        #t59.{core::Set::add}{Invariant}(#t62);
       }
-    for (final dynamic #t77 in <dynamic>[]) {
-      final dynamic #t78 = #t77 as{TypeError} dynamic;
-      #t73.{core::Set::add}{Invariant}(#t78);
+    for (final dynamic #t63 in <dynamic>[]) {
+      final dynamic #t64 = #t63 as{TypeError} dynamic;
+      #t59.{core::Set::add}{Invariant}(#t64);
+    }
+  } =>#t59;
+  core::Map<core::String*, core::int*>* map80 = block {
+    final core::Map<core::String*, core::int*>* #t65 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t66 = null;
+    if(!#t66.{core::Object::==}(null))
+      for (final core::MapEntry<core::String*, core::int*>* #t67 in #t66.{core::Map::entries})
+        #t65.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+  } =>#t65;
+  core::Map<core::String*, core::int*>* map90 = block {
+    final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
+    for (final core::MapEntry<core::String*, core::int*>* #t69 in self::bar<core::String*, core::int*>().{core::Map::entries})
+      #t68.{core::Map::[]=}{Invariant}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
+  } =>#t68;
+  core::List<core::int*>* list100 = block {
+    final core::List<core::int*>* #t70 = <core::int*>[];
+    for (final dynamic #t71 in listNum) {
+      final core::int* #t72 = #t71 as{TypeError} core::int*;
+      #t70.{core::List::add}{Invariant}(#t72);
+    }
+  } =>#t70;
+  core::Map<core::num*, core::int*>* map100 = block {
+    final core::Map<core::num*, core::int*>* #t73 = <core::num*, core::int*>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t74 in mapIntNum.{core::Map::entries}) {
+      final core::num* #t75 = #t74.{core::MapEntry::key} as{TypeError} core::num*;
+      final core::int* #t76 = #t74.{core::MapEntry::value} as{TypeError} core::int*;
+      #t73.{core::Map::[]=}{Invariant}(#t75, #t76);
     }
   } =>#t73;
-  core::Map<core::String*, core::int*>* map80 = block {
-    final core::Map<core::String*, core::int*>* #t79 = <core::String*, core::int*>{};
-    final core::Map<core::String*, core::int*>* #t80 = null;
-    if(!#t80.{core::Object::==}(null))
-      for (final core::MapEntry<core::String*, core::int*>* #t81 in #t80.{core::Map::entries})
-        #t79.{core::Map::[]=}{Invariant}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
-  } =>#t79;
-  core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t82 = <core::String*, core::int*>{};
-    for (final core::MapEntry<core::String*, core::int*>* #t83 in self::bar<core::String*, core::int*>().{core::Map::entries})
-      #t82.{core::Map::[]=}{Invariant}(#t83.{core::MapEntry::key}, #t83.{core::MapEntry::value});
-  } =>#t82;
-  core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t84 = <core::int*>[];
-    for (final dynamic #t85 in listNum) {
-      final core::int* #t86 = #t85 as{TypeError} core::int*;
-      #t84.{core::List::add}{Invariant}(#t86);
-    }
-  } =>#t84;
-  core::Map<core::num*, core::int*>* map100 = block {
-    final core::Map<core::num*, core::int*>* #t87 = <core::num*, core::int*>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t88 in mapIntNum.{core::Map::entries}) {
-      final core::num* #t89 = #t88.{core::MapEntry::key} as{TypeError} core::num*;
-      final core::int* #t90 = #t88.{core::MapEntry::value} as{TypeError} core::int*;
-      #t87.{core::Map::[]=}{Invariant}(#t89, #t90);
-    }
-  } =>#t87;
   core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t91 = <core::int*>[];
-    for (final dynamic #t92 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-      final core::int* #t93 = #t92 as{TypeError} core::int*;
-      #t91.{core::List::add}{Invariant}(#t93);
+    final core::List<core::int*>* #t77 = <core::int*>[];
+    for (final dynamic #t78 in dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t79 = #t78 as{TypeError} core::int*;
+      #t77.{core::List::add}{Invariant}(#t79);
     }
-  } =>#t91;
+  } =>#t77;
   core::Map<core::num*, core::int*>* map110 = block {
-    final core::Map<core::num*, core::int*>* #t94 = <core::num*, core::int*>{};
-    for (final core::MapEntry<dynamic, dynamic>* #t95 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-      final core::num* #t96 = #t95.{core::MapEntry::key} as{TypeError} core::num*;
-      final core::int* #t97 = #t95.{core::MapEntry::value} as{TypeError} core::int*;
-      #t94.{core::Map::[]=}{Invariant}(#t96, #t97);
+    final core::Map<core::num*, core::int*>* #t80 = <core::num*, core::int*>{};
+    for (final core::MapEntry<dynamic, dynamic>* #t81 in (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+      final core::num* #t82 = #t81.{core::MapEntry::key} as{TypeError} core::num*;
+      final core::int* #t83 = #t81.{core::MapEntry::value} as{TypeError} core::int*;
+      #t80.{core::Map::[]=}{Invariant}(#t82, #t83);
     }
-  } =>#t94;
+  } =>#t80;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect
index 4cafcc2..d10c002 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.weak.transformed.expect
@@ -110,26 +110,22 @@
   core::Map<core::int*, core::num*>* mapIntNum = <core::int*, core::num*>{42: 42};
   core::List<core::num*>* listNum = <core::num*>[42];
   core::List<dynamic>* lhs10 = block {
-    final core::List<dynamic>* #t1 = <dynamic>[];
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t2);
-      }
-    }
+    final core::List<dynamic>* #t1 = core::List::of<dynamic>(<dynamic>[]);
   } =>#t1;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t3 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t2 = col::LinkedHashSet::of<dynamic>(<dynamic>[]);
+  } =>#t2;
+  core::Map<dynamic, dynamic>* map10 = block {
+    final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
     {
-      core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
-        #t3.{core::Set::add}{Invariant}(#t4);
+        final core::MapEntry<dynamic, dynamic>* #t4 = :sync-for-iterator.{core::Iterator::current};
+        #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
       }
     }
   } =>#t3;
-  core::Map<dynamic, dynamic>* map10 = block {
+  core::Map<dynamic, dynamic>* map10ambiguous = block {
     final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
     {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
@@ -139,277 +135,197 @@
       }
     }
   } =>#t5;
-  core::Map<dynamic, dynamic>* map10ambiguous = block {
-    final core::Map<dynamic, dynamic>* #t7 = <dynamic, dynamic>{};
-    {
-      core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = <dynamic, dynamic>{}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t8 = :sync-for-iterator.{core::Iterator::current};
-        #t7.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
-      }
-    }
-  } =>#t7;
   core::List<core::int*>* lhs20 = block {
-    final core::List<core::int*>* #t9 = <core::int*>[];
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t10 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::List::add}{Invariant}(#t10);
-      }
-    }
-  } =>#t9;
+    final core::List<core::int*>* #t7 = core::List::of<core::int*>(spread);
+  } =>#t7;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t11 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t11.{core::Set::add}{Invariant}(#t12);
-      }
-    }
-    #t11.{core::Set::add}{Invariant}(42);
-  } =>#t11;
+    final core::Set<core::int*>* #t8 = col::LinkedHashSet::of<core::int*>(spread);
+    #t8.{core::Set::add}{Invariant}(42);
+  } =>#t8;
   core::Set<core::int*>* set20ambiguous = block {
-    final core::Set<core::int*>* #t13 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t15 = #t14 as{TypeError} core::int*;
-          #t13.{core::Set::add}{Invariant}(#t15);
+          final core::int* #t11 = #t10 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t11);
         }
       }
     }
-  } =>#t13;
+  } =>#t9;
   core::Map<core::String*, core::int*>* map20 = block {
-    final core::Map<core::String*, core::int*>* #t16 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t12 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
       }
     }
-    #t16.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t16;
+    #t12.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t12;
   core::Map<core::String*, core::int*>* map20ambiguous = block {
-    final core::Map<core::String*, core::int*>* #t18 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t14 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t15 = :sync-for-iterator.{core::Iterator::current};
+        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
       }
     }
-  } =>#t18;
+  } =>#t14;
   core::List<dynamic>* lhs21 = block {
-    final core::List<dynamic>* #t20 = <dynamic>[];
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
-        #t20.{core::List::add}{Invariant}(#t21);
-      }
-    }
-  } =>#t20;
+    final core::List<dynamic>* #t16 = core::List::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+  } =>#t16;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t22 = new col::_CompactLinkedHashSet::•<dynamic>();
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = ((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::Set::add}{Invariant}(#t23);
-      }
-    }
-    #t22.{core::Set::add}{Invariant}(42);
-  } =>#t22;
+    final core::Set<dynamic>* #t17 = col::LinkedHashSet::of<dynamic>((spread as dynamic) as{TypeError,ForDynamic} core::Iterable<dynamic>*);
+    #t17.{core::Set::add}{Invariant}(42);
+  } =>#t17;
   core::Map<dynamic, dynamic>* map21 = block {
-    final core::Map<dynamic, dynamic>* #t24 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic>* #t18 = <dynamic, dynamic>{};
     {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = ((mapSpread as dynamic) as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t25 = :sync-for-iterator.{core::Iterator::current};
-        #t24.{core::Map::[]=}{Invariant}(#t25.{core::MapEntry::key}, #t25.{core::MapEntry::value});
+        final core::MapEntry<dynamic, dynamic>* #t19 = :sync-for-iterator.{core::Iterator::current};
+        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
       }
     }
-    #t24.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t24;
+    #t18.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t18;
   dynamic map21ambiguous = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:66:28: Error: Not enough type information to disambiguate between literal set and literal map.
 Try providing type arguments for the literal explicitly to disambiguate it.
   dynamic map21ambiguous = {...(mapSpread as dynamic)};
                            ^";
   core::List<core::int*>* lhs22 = block {
-    final core::List<core::int*>* #t26 = <core::int*>[];
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t27 = :sync-for-iterator.{core::Iterator::current};
-        #t26.{core::List::add}{Invariant}(#t27);
-      }
-    }
-  } =>#t26;
+    final core::List<core::int*>* #t20 = core::List::of<core::int*>(<core::int*>[]);
+  } =>#t20;
   core::Set<core::int*>* set22 = block {
-    final core::Set<core::int*>* #t28 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t29 = :sync-for-iterator.{core::Iterator::current};
-        #t28.{core::Set::add}{Invariant}(#t29);
-      }
-    }
-    #t28.{core::Set::add}{Invariant}(42);
-  } =>#t28;
+    final core::Set<core::int*>* #t21 = col::LinkedHashSet::of<core::int*>(<core::int*>[]);
+    #t21.{core::Set::add}{Invariant}(42);
+  } =>#t21;
   core::Set<core::int*>* set22ambiguous = block {
-    final core::Set<core::int*>* #t30 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t22 = new col::_CompactLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t31 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t32 = #t31 as{TypeError} core::int*;
-          #t30.{core::Set::add}{Invariant}(#t32);
+          final core::int* #t24 = #t23 as{TypeError} core::int*;
+          #t22.{core::Set::add}{Invariant}(#t24);
         }
       }
     }
-  } =>#t30;
+  } =>#t22;
   core::Map<core::String*, core::int*>* map22 = block {
-    final core::Map<core::String*, core::int*>* #t33 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t25 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = <core::String*, core::int*>{}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t34 = :sync-for-iterator.{core::Iterator::current};
-        #t33.{core::Map::[]=}{Invariant}(#t34.{core::MapEntry::key}, #t34.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t26 = :sync-for-iterator.{core::Iterator::current};
+        #t25.{core::Map::[]=}{Invariant}(#t26.{core::MapEntry::key}, #t26.{core::MapEntry::value});
       }
     }
-  } =>#t33;
+  } =>#t25;
   core::List<core::List<core::int*>*>* lhs23 = block {
-    final core::List<core::List<core::int*>*>* #t35 = <core::List<core::int*>*>[];
-    {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t36 = :sync-for-iterator.{core::Iterator::current};
-        #t35.{core::List::add}{Invariant}(#t36);
-      }
-    }
-  } =>#t35;
+    final core::List<core::List<core::int*>*>* #t27 = core::List::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+  } =>#t27;
   core::Set<core::List<core::int*>*>* set23 = block {
-    final core::Set<core::List<core::int*>*>* #t37 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t28 = col::LinkedHashSet::of<core::List<core::int*>*>(<core::List<core::int*>*>[<core::int*>[]]);
+    #t28.{core::Set::add}{Invariant}(<core::int*>[42]);
+  } =>#t28;
+  core::Set<core::List<core::int*>*>* set23ambiguous = block {
+    final core::Set<core::List<core::int*>*>* #t29 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
     {
       core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::List<core::int*>* #t38 = :sync-for-iterator.{core::Iterator::current};
-        #t37.{core::Set::add}{Invariant}(#t38);
+        final dynamic #t30 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::List<core::int*>* #t31 = #t30 as{TypeError} core::List<core::int*>*;
+          #t29.{core::Set::add}{Invariant}(#t31);
+        }
       }
     }
-    #t37.{core::Set::add}{Invariant}(<core::int*>[42]);
-  } =>#t37;
-  core::Set<core::List<core::int*>*>* set23ambiguous = block {
-    final core::Set<core::List<core::int*>*>* #t39 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+  } =>#t29;
+  core::Map<core::String*, core::List<core::int*>*>* map23 = block {
+    final core::Map<core::String*, core::List<core::int*>*>* #t32 = <core::String*, core::List<core::int*>*>{};
     {
-      core::Iterator<core::List<core::int*>*>* :sync-for-iterator = <core::List<core::int*>*>[<core::int*>[]].{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::List<core::int*>*>* #t33 = :sync-for-iterator.{core::Iterator::current};
+        #t32.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
+      }
+    }
+  } =>#t32;
+  dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:98:28: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+  dynamic map24ambiguous = {...spread, ...mapSpread};
+                           ^";
+  core::int* lhs30 = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:100:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+  int lhs30 = /*@ typeArgs=int* */ [...spread];
+                                   ^" in ( block {
+    final core::List<core::int*>* #t35 = core::List::of<core::int*>(spread);
+  } =>#t35) as{TypeError} core::int*;
+  core::int* set30 = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:102:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+ - 'Set' is from 'dart:core'.
+  int set30 = /*@ typeArgs=int* */ {...spread, 42};
+                                   ^" in ( block {
+    final core::Set<core::int*>* #t37 = col::LinkedHashSet::of<core::int*>(spread);
+    #t37.{core::Set::add}{Invariant}(42);
+  } =>#t37) as{TypeError} core::int*;
+  core::int* set30ambiguous = let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:105:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
+ - 'Set' is from 'dart:core'.
+      {...spread};
+      ^" in ( block {
+    final core::Set<core::int*>* #t39 = new col::_CompactLinkedHashSet::•<core::int*>();
+    {
+      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t40 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::List<core::int*>* #t41 = #t40 as{TypeError} core::List<core::int*>*;
+          final core::int* #t41 = #t40 as{TypeError} core::int*;
           #t39.{core::Set::add}{Invariant}(#t41);
         }
       }
     }
-  } =>#t39;
-  core::Map<core::String*, core::List<core::int*>*>* map23 = block {
-    final core::Map<core::String*, core::List<core::int*>*>* #t42 = <core::String*, core::List<core::int*>*>{};
-    {
-      core::Iterator<core::MapEntry<core::String*, core::List<core::int*>*>>* :sync-for-iterator = <core::String*, core::List<core::int*>*>{"baz": <core::int*>[]}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::List<core::int*>*>* #t43 = :sync-for-iterator.{core::Iterator::current};
-        #t42.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-      }
-    }
-  } =>#t42;
-  dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:98:28: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-  dynamic map24ambiguous = {...spread, ...mapSpread};
-                           ^";
-  core::int* lhs30 = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:100:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
- - 'List' is from 'dart:core'.
-  int lhs30 = /*@ typeArgs=int* */ [...spread];
-                                   ^" in ( block {
-    final core::List<core::int*>* #t45 = <core::int*>[];
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t46 = :sync-for-iterator.{core::Iterator::current};
-        #t45.{core::List::add}{Invariant}(#t46);
-      }
-    }
-  } =>#t45) as{TypeError} core::int*;
-  core::int* set30 = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:102:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
- - 'Set' is from 'dart:core'.
-  int set30 = /*@ typeArgs=int* */ {...spread, 42};
-                                   ^" in ( block {
-    final core::Set<core::int*>* #t48 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t49 = :sync-for-iterator.{core::Iterator::current};
-        #t48.{core::Set::add}{Invariant}(#t49);
-      }
-    }
-    #t48.{core::Set::add}{Invariant}(42);
-  } =>#t48) as{TypeError} core::int*;
-  core::int* set30ambiguous = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:105:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
- - 'Set' is from 'dart:core'.
-      {...spread};
-      ^" in ( block {
-    final core::Set<core::int*>* #t51 = new col::_CompactLinkedHashSet::•<core::int*>();
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = spread.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t52 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t53 = #t52 as{TypeError} core::int*;
-          #t51.{core::Set::add}{Invariant}(#t53);
-        }
-      }
-    }
-  } =>#t51) as{TypeError} core::int*;
-  core::int* map30 = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:108:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+  } =>#t39) as{TypeError} core::int*;
+  core::int* map30 = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:108:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread, \"baz\": 42};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t43 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t56 = :sync-for-iterator.{core::Iterator::current};
-        #t55.{core::Map::[]=}{Invariant}(#t56.{core::MapEntry::key}, #t56.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t44 = :sync-for-iterator.{core::Iterator::current};
+        #t43.{core::Map::[]=}{Invariant}(#t44.{core::MapEntry::key}, #t44.{core::MapEntry::value});
       }
     }
-    #t55.{core::Map::[]=}{Invariant}("baz", 42);
-  } =>#t55) as{TypeError} core::int*;
-  core::int* map30ambiguous = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:111:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
+    #t43.{core::Map::[]=}{Invariant}("baz", 42);
+  } =>#t43) as{TypeError} core::int*;
+  core::int* map30ambiguous = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:111:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
       {...mapSpread};
       ^" in ( block {
-    final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t46 = <core::String*, core::int*>{};
     {
       core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = mapSpread.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t59 = :sync-for-iterator.{core::Iterator::current};
-        #t58.{core::Map::[]=}{Invariant}(#t59.{core::MapEntry::key}, #t59.{core::MapEntry::value});
+        final core::MapEntry<core::String*, core::int*>* #t47 = :sync-for-iterator.{core::Iterator::current};
+        #t46.{core::Map::[]=}{Invariant}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value});
       }
     }
-  } =>#t58) as{TypeError} core::int*;
+  } =>#t46) as{TypeError} core::int*;
   core::List<dynamic>* lhs40 = <dynamic>[invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:113:38: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   List<dynamic> lhs40 = <dynamic>[...notSpreadInt];
                                      ^"];
   core::Set<dynamic>* set40 = block {
-    final core::Set<dynamic>* #t60 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t60.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:115:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t48 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t48.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:115:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set40 = <dynamic>{...notSpreadInt};
                                     ^");
-  } =>#t60;
+  } =>#t48;
   core::Map<dynamic, dynamic>* map40 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:117:55: Error: Unexpected type 'int' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map40 = <dynamic, dynamic>{...notSpreadInt};
                                                       ^": null};
@@ -417,11 +333,11 @@
   List<dynamic> lhs50 = <dynamic>[...notSpreadFunction];
                                      ^"];
   core::Set<dynamic>* set50 = block {
-    final core::Set<dynamic>* #t61 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t61.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:121:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<dynamic>* #t49 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t49.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:121:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set50 = <dynamic>{...notSpreadFunction};
                                     ^");
-  } =>#t61;
+  } =>#t49;
   core::Map<dynamic, dynamic>* map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:123:55: Error: Unexpected type 'int Function()' of a map spread entry.  Expected 'dynamic' or a Map.
   Map<dynamic, dynamic> map50 = <dynamic, dynamic>{...notSpreadFunction};
                                                       ^": null};
@@ -429,11 +345,11 @@
   List<String> lhs60 = <String>[...spread];
                                    ^"];
   core::Set<core::String*>* set60 = block {
-    final core::Set<core::String*>* #t62 = new col::_CompactLinkedHashSet::•<core::String*>();
-    #t62.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:127:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
+    final core::Set<core::String*>* #t50 = new col::_CompactLinkedHashSet::•<core::String*>();
+    #t50.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:127:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{...spread};
                                   ^");
-  } =>#t62;
+  } =>#t50;
   core::Map<core::int*, core::int*>* map60 = <core::int*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:129:39: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
   Map<int, int> map60 = <int, int>{...mapSpread};
                                       ^": null};
@@ -444,150 +360,140 @@
   List<int> lhs70 = <int>[...null];
                              ^"];
   core::Set<core::int*>* set70 = block {
-    final core::Set<core::int*>* #t63 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t63.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:135:29: Error: Can't spread a value with static type 'Null'.
+    final core::Set<core::int*>* #t51 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t51.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:135:29: Error: Can't spread a value with static type 'Null'.
   Set<int> set70 = <int>{...null};
                             ^");
-  } =>#t63;
+  } =>#t51;
   core::Set<dynamic>* set71ambiguous = block {
-    final core::Set<dynamic>* #t64 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t64.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:139:8: Error: Expected ',' before this.
+    final core::Set<dynamic>* #t52 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t52.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:139:8: Error: Expected ',' before this.
     ...null,
        ^");
     {
       core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t65 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t53 = :sync-for-iterator.{core::Iterator::current};
         {
-          final dynamic #t66 = #t65 as{TypeError} dynamic;
-          #t64.{core::Set::add}{Invariant}(#t66);
+          final dynamic #t54 = #t53 as{TypeError} dynamic;
+          #t52.{core::Set::add}{Invariant}(#t54);
         }
       }
     }
-  } =>#t64;
+  } =>#t52;
   core::Map<core::String*, core::int*>* map70 = <core::String*, core::int*>{invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart:144:45: Error: Can't spread a value with static type 'Null'.
   Map<String, int> map70 = <String, int>{...null};
                                             ^": null};
   core::List<core::int*>* lhs80 = block {
-    final core::List<core::int*>* #t67 = <core::int*>[];
-    final core::Iterable<core::int*>* #t68 = null;
-    if(!#t68.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t68.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t69 = :sync-for-iterator.{core::Iterator::current};
-        #t67.{core::List::add}{Invariant}(#t69);
-      }
-    }
-  } =>#t67;
+    final core::List<core::int*>* #t55 = <core::int*>[];
+    final core::Iterable<core::int*>* #t56 = null;
+    if(!#t56.{core::Object::==}(null))
+      #t55.{core::List::addAll}{Invariant}(#t56);
+  } =>#t55;
   core::Set<core::int*>* set80 = block {
-    final core::Set<core::int*>* #t70 = new col::_CompactLinkedHashSet::•<core::int*>();
-    final core::Iterable<core::int*>* #t71 = null;
-    if(!#t71.{core::Object::==}(null)) {
-      core::Iterator<core::int*>* :sync-for-iterator = #t71.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t72 = :sync-for-iterator.{core::Iterator::current};
-        #t70.{core::Set::add}{Invariant}(#t72);
-      }
-    }
-  } =>#t70;
+    final core::Set<core::int*>* #t57 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Iterable<core::int*>* #t58 = null;
+    if(!#t58.{core::Object::==}(null))
+      #t57.{core::Set::addAll}{Invariant}(#t58);
+  } =>#t57;
   core::Set<dynamic>* set81ambiguous = block {
-    final core::Set<dynamic>* #t73 = new col::_CompactLinkedHashSet::•<dynamic>();
-    final core::Iterable<dynamic>* #t74 = null;
-    if(!#t74.{core::Object::==}(null)) {
-      core::Iterator<dynamic>* :sync-for-iterator = #t74.{core::Iterable::iterator};
+    final core::Set<dynamic>* #t59 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Iterable<dynamic>* #t60 = null;
+    if(!#t60.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t60.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t75 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t61 = :sync-for-iterator.{core::Iterator::current};
         {
-          final dynamic #t76 = #t75 as{TypeError} dynamic;
-          #t73.{core::Set::add}{Invariant}(#t76);
+          final dynamic #t62 = #t61 as{TypeError} dynamic;
+          #t59.{core::Set::add}{Invariant}(#t62);
         }
       }
     }
     {
       core::Iterator<dynamic>* :sync-for-iterator = <dynamic>[].{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t77 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t63 = :sync-for-iterator.{core::Iterator::current};
         {
-          final dynamic #t78 = #t77 as{TypeError} dynamic;
-          #t73.{core::Set::add}{Invariant}(#t78);
+          final dynamic #t64 = #t63 as{TypeError} dynamic;
+          #t59.{core::Set::add}{Invariant}(#t64);
+        }
+      }
+    }
+  } =>#t59;
+  core::Map<core::String*, core::int*>* map80 = block {
+    final core::Map<core::String*, core::int*>* #t65 = <core::String*, core::int*>{};
+    final core::Map<core::String*, core::int*>* #t66 = null;
+    if(!#t66.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = #t66.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::int*>* #t67 = :sync-for-iterator.{core::Iterator::current};
+        #t65.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+      }
+    }
+  } =>#t65;
+  core::Map<core::String*, core::int*>* map90 = block {
+    final core::Map<core::String*, core::int*>* #t68 = <core::String*, core::int*>{};
+    {
+      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::String*, core::int*>* #t69 = :sync-for-iterator.{core::Iterator::current};
+        #t68.{core::Map::[]=}{Invariant}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
+      }
+    }
+  } =>#t68;
+  core::List<core::int*>* list100 = block {
+    final core::List<core::int*>* #t70 = <core::int*>[];
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t71 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t72 = #t71 as{TypeError} core::int*;
+          #t70.{core::List::add}{Invariant}(#t72);
+        }
+      }
+    }
+  } =>#t70;
+  core::Map<core::num*, core::int*>* map100 = block {
+    final core::Map<core::num*, core::int*>* #t73 = <core::num*, core::int*>{};
+    {
+      core::Iterator<core::MapEntry<core::int*, core::num*>>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<dynamic, dynamic>* #t74 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t75 = #t74.{core::MapEntry::key} as{TypeError} core::num*;
+          final core::int* #t76 = #t74.{core::MapEntry::value} as{TypeError} core::int*;
+          #t73.{core::Map::[]=}{Invariant}(#t75, #t76);
         }
       }
     }
   } =>#t73;
-  core::Map<core::String*, core::int*>* map80 = block {
-    final core::Map<core::String*, core::int*>* #t79 = <core::String*, core::int*>{};
-    final core::Map<core::String*, core::int*>* #t80 = null;
-    if(!#t80.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = #t80.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t81 = :sync-for-iterator.{core::Iterator::current};
-        #t79.{core::Map::[]=}{Invariant}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
-      }
-    }
-  } =>#t79;
-  core::Map<core::String*, core::int*>* map90 = block {
-    final core::Map<core::String*, core::int*>* #t82 = <core::String*, core::int*>{};
-    {
-      core::Iterator<core::MapEntry<core::String*, core::int*>>* :sync-for-iterator = self::bar<core::String*, core::int*>().{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String*, core::int*>* #t83 = :sync-for-iterator.{core::Iterator::current};
-        #t82.{core::Map::[]=}{Invariant}(#t83.{core::MapEntry::key}, #t83.{core::MapEntry::value});
-      }
-    }
-  } =>#t82;
-  core::List<core::int*>* list100 = block {
-    final core::List<core::int*>* #t84 = <core::int*>[];
-    {
-      core::Iterator<core::num*>* :sync-for-iterator = listNum.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t85 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t86 = #t85 as{TypeError} core::int*;
-          #t84.{core::List::add}{Invariant}(#t86);
-        }
-      }
-    }
-  } =>#t84;
-  core::Map<core::num*, core::int*>* map100 = block {
-    final core::Map<core::num*, core::int*>* #t87 = <core::num*, core::int*>{};
-    {
-      core::Iterator<core::MapEntry<core::int*, core::num*>>* :sync-for-iterator = mapIntNum.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t88 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::num* #t89 = #t88.{core::MapEntry::key} as{TypeError} core::num*;
-          final core::int* #t90 = #t88.{core::MapEntry::value} as{TypeError} core::int*;
-          #t87.{core::Map::[]=}{Invariant}(#t89, #t90);
-        }
-      }
-    }
-  } =>#t87;
   core::List<core::int*>* list110 = block {
-    final core::List<core::int*>* #t91 = <core::int*>[];
+    final core::List<core::int*>* #t77 = <core::int*>[];
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t92 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t78 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int* #t93 = #t92 as{TypeError} core::int*;
-          #t91.{core::List::add}{Invariant}(#t93);
+          final core::int* #t79 = #t78 as{TypeError} core::int*;
+          #t77.{core::List::add}{Invariant}(#t79);
         }
       }
     }
-  } =>#t91;
+  } =>#t77;
   core::Map<core::num*, core::int*>* map110 = block {
-    final core::Map<core::num*, core::int*>* #t94 = <core::num*, core::int*>{};
+    final core::Map<core::num*, core::int*>* #t80 = <core::num*, core::int*>{};
     {
       core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t95 = :sync-for-iterator.{core::Iterator::current};
+        final core::MapEntry<dynamic, dynamic>* #t81 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::num* #t96 = #t95.{core::MapEntry::key} as{TypeError} core::num*;
-          final core::int* #t97 = #t95.{core::MapEntry::value} as{TypeError} core::int*;
-          #t94.{core::Map::[]=}{Invariant}(#t96, #t97);
+          final core::num* #t82 = #t81.{core::MapEntry::key} as{TypeError} core::num*;
+          final core::int* #t83 = #t81.{core::MapEntry::value} as{TypeError} core::int*;
+          #t80.{core::Map::[]=}{Invariant}(#t82, #t83);
         }
       }
     }
-  } =>#t94;
+  } =>#t80;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.weak.transformed.expect
index a02506d..91dfee3 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.weak.transformed.expect
@@ -15,7 +15,6 @@
 static method bar(dynamic d) → dynamic /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -69,7 +68,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.1.expect
index a871263..8a0cc29 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.1.expect
@@ -7,7 +7,7 @@
   static method foo() → dynamic {}
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -26,4 +26,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.2.expect
index 42ee856..0e7c789 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml.world.2.expect
@@ -14,7 +14,7 @@
   static method foo() → dynamic {}
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -33,4 +33,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/bad_sdk_uri.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/bad_sdk_uri.yaml.world.3.expect
index 6480cc2..69312e6 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/bad_sdk_uri.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/bad_sdk_uri.yaml.world.3.expect
@@ -20,7 +20,7 @@
   }
 }
 
-And 18 platform libraries:
+And 17 platform libraries:
  - dart:_builtin
  - dart:_internal
  - dart:_vmservice
@@ -38,4 +38,3 @@
  - dart:nativewrappers
  - dart:typed_data
  - dart:vmservice_io
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/extension_expression_compilation_usage.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/extension_expression_compilation_usage.yaml.world.1.expect
index 73e7fda..361ccb3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/extension_expression_compilation_usage.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/extension_expression_compilation_usage.yaml.world.1.expect
@@ -5,9 +5,9 @@
     method parseInt = main::NumberParsing|parseInt;
     tearoff parseInt = main::NumberParsing|get#parseInt;
   }
-  static method NumberParsing|parseInt(final dart.core::String* #this) → dart.core::int* {
+  static method NumberParsing|parseInt(lowered final dart.core::String* #this) → dart.core::int* {
     return dart.core::int::parse(#this);
   }
-  static method NumberParsing|get#parseInt(final dart.core::String* #this) → () →* dart.core::int*
+  static method NumberParsing|get#parseInt(lowered final dart.core::String* #this) → () →* dart.core::int*
     return () → dart.core::int* => main::NumberParsing|parseInt(#this);
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.1.expect
index 58648d5..83ad3f0 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.1.expect
@@ -5,10 +5,10 @@
     method parseInt = lib1::NumberParsing|parseInt;
     tearoff parseInt = lib1::NumberParsing|get#parseInt;
   }
-  static method NumberParsing|parseInt(final dart.core::String* #this) → dart.core::int* {
+  static method NumberParsing|parseInt(lowered final dart.core::String* #this) → dart.core::int* {
     return dart.core::int::parse(#this);
   }
-  static method NumberParsing|get#parseInt(final dart.core::String* #this) → () →* dart.core::int*
+  static method NumberParsing|get#parseInt(lowered final dart.core::String* #this) → () →* dart.core::int*
     return () → dart.core::int* => lib1::NumberParsing|parseInt(#this);
 }
 library from "org-dartlang-test:///lib2.dart" as lib2 {
@@ -17,10 +17,10 @@
     method fooMe1 = lib2::DuplicateName|fooMe1;
     tearoff fooMe1 = lib2::DuplicateName|get#fooMe1;
   }
-  static method DuplicateName|fooMe1(final dart.core::String* #this) → dart.core::String* {
+  static method DuplicateName|fooMe1(lowered final dart.core::String* #this) → dart.core::String* {
     return "Foo1";
   }
-  static method DuplicateName|get#fooMe1(final dart.core::String* #this) → () →* dart.core::String*
+  static method DuplicateName|get#fooMe1(lowered final dart.core::String* #this) → () →* dart.core::String*
     return () → dart.core::String* => lib2::DuplicateName|fooMe1(#this);
 }
 library from "org-dartlang-test:///lib3.dart" as lib3 {
@@ -29,10 +29,10 @@
     method fooMe2 = lib3::DuplicateName|fooMe2;
     tearoff fooMe2 = lib3::DuplicateName|get#fooMe2;
   }
-  static method DuplicateName|fooMe2(final dart.core::String* #this) → dart.core::String* {
+  static method DuplicateName|fooMe2(lowered final dart.core::String* #this) → dart.core::String* {
     return "Foo2";
   }
-  static method DuplicateName|get#fooMe2(final dart.core::String* #this) → () →* dart.core::String*
+  static method DuplicateName|get#fooMe2(lowered final dart.core::String* #this) → () →* dart.core::String*
     return () → dart.core::String* => lib3::DuplicateName|fooMe2(#this);
 }
 library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.2.expect
index 58648d5..83ad3f0 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/extension_usage_from_dill.yaml.world.2.expect
@@ -5,10 +5,10 @@
     method parseInt = lib1::NumberParsing|parseInt;
     tearoff parseInt = lib1::NumberParsing|get#parseInt;
   }
-  static method NumberParsing|parseInt(final dart.core::String* #this) → dart.core::int* {
+  static method NumberParsing|parseInt(lowered final dart.core::String* #this) → dart.core::int* {
     return dart.core::int::parse(#this);
   }
-  static method NumberParsing|get#parseInt(final dart.core::String* #this) → () →* dart.core::int*
+  static method NumberParsing|get#parseInt(lowered final dart.core::String* #this) → () →* dart.core::int*
     return () → dart.core::int* => lib1::NumberParsing|parseInt(#this);
 }
 library from "org-dartlang-test:///lib2.dart" as lib2 {
@@ -17,10 +17,10 @@
     method fooMe1 = lib2::DuplicateName|fooMe1;
     tearoff fooMe1 = lib2::DuplicateName|get#fooMe1;
   }
-  static method DuplicateName|fooMe1(final dart.core::String* #this) → dart.core::String* {
+  static method DuplicateName|fooMe1(lowered final dart.core::String* #this) → dart.core::String* {
     return "Foo1";
   }
-  static method DuplicateName|get#fooMe1(final dart.core::String* #this) → () →* dart.core::String*
+  static method DuplicateName|get#fooMe1(lowered final dart.core::String* #this) → () →* dart.core::String*
     return () → dart.core::String* => lib2::DuplicateName|fooMe1(#this);
 }
 library from "org-dartlang-test:///lib3.dart" as lib3 {
@@ -29,10 +29,10 @@
     method fooMe2 = lib3::DuplicateName|fooMe2;
     tearoff fooMe2 = lib3::DuplicateName|get#fooMe2;
   }
-  static method DuplicateName|fooMe2(final dart.core::String* #this) → dart.core::String* {
+  static method DuplicateName|fooMe2(lowered final dart.core::String* #this) → dart.core::String* {
     return "Foo2";
   }
-  static method DuplicateName|get#fooMe2(final dart.core::String* #this) → () →* dart.core::String*
+  static method DuplicateName|get#fooMe2(lowered final dart.core::String* #this) → () →* dart.core::String*
     return () → dart.core::String* => lib3::DuplicateName|fooMe2(#this);
 }
 library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect
index a789fc9..d40aeb92 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
@@ -45,7 +45,7 @@
       return #C7;
   }
   class Bar extends fra::Widget /*hasConstConstructor*/  {
-    static field dynamic _redirecting# = <dynamic>[foo::Bar::•]/*isNullableByDefault*/;
+    static field dynamic _redirecting# = <dynamic>[foo::Bar::•]/*isLegacy*/;
     const constructor _({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Bar
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
@@ -53,7 +53,7 @@
       let dynamic #redirecting_factory = foo::Bar::_ in invalid-expression;
   }
   class Baz extends fra::Widget /*hasConstConstructor*/  {
-    static field dynamic _redirecting# = <dynamic>[foo::Baz::_]/*isNullableByDefault*/;
+    static field dynamic _redirecting# = <dynamic>[foo::Baz::_]/*isLegacy*/;
     const constructor __({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect
index 489ea3e..ec1cec8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
@@ -45,7 +45,7 @@
       return #C7;
   }
   class Bar extends fra::Widget /*hasConstConstructor*/  {
-    static field dynamic _redirecting# = <dynamic>[foo::Bar::•]/*isNullableByDefault*/;
+    static field dynamic _redirecting# = <dynamic>[foo::Bar::•]/*isLegacy*/;
     const constructor _({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Bar
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
@@ -53,7 +53,7 @@
       let dynamic #redirecting_factory = foo::Bar::_ in invalid-expression;
   }
   class Baz extends fra::Widget /*hasConstConstructor*/  {
-    static field dynamic _redirecting# = <dynamic>[foo::Baz::_]/*isNullableByDefault*/;
+    static field dynamic _redirecting# = <dynamic>[foo::Baz::_]/*isLegacy*/;
     const constructor __({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect
index a789fc9..d40aeb92 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
@@ -45,7 +45,7 @@
       return #C7;
   }
   class Bar extends fra::Widget /*hasConstConstructor*/  {
-    static field dynamic _redirecting# = <dynamic>[foo::Bar::•]/*isNullableByDefault*/;
+    static field dynamic _redirecting# = <dynamic>[foo::Bar::•]/*isLegacy*/;
     const constructor _({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Bar
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
@@ -53,7 +53,7 @@
       let dynamic #redirecting_factory = foo::Bar::_ in invalid-expression;
   }
   class Baz extends fra::Widget /*hasConstConstructor*/  {
-    static field dynamic _redirecting# = <dynamic>[foo::Baz::_]/*isNullableByDefault*/;
+    static field dynamic _redirecting# = <dynamic>[foo::Baz::_]/*isLegacy*/;
     const constructor __({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → foo::Baz
       : super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect
index aeb8651..c896f26 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect
index 871b5ac..23d9796 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect
index fc776ae..b666fa7 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect
@@ -8,7 +8,7 @@
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field dart.core::Object? key;
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({dart.core::Object? key = #C1, wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : fra::Widget::key = key, super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect
index 6a2fb38..6d4e387 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect
@@ -8,7 +8,7 @@
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field dart.core::Object? key;
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({dart.core::Object? key = #C1, wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : fra::Widget::key = key, super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect
index 89e94d3..506067f 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect
index a33902f..fda5bb6 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect
@@ -7,7 +7,7 @@
       ;
   }
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
-    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    final field wid::_Location? _location /*isLegacy, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
       : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.1.expect
index 5a49451..2360766 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.1.expect
@@ -16,7 +16,7 @@
   }
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -35,4 +35,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.2.expect
index 5a49451..2360766 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml.world.2.expect
@@ -16,7 +16,7 @@
   }
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -35,4 +35,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.1.expect
index 07336f4..c11a0be 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.1.expect
@@ -29,14 +29,14 @@
   }
   static field dart.core::int* A2|staticField = 42;
   static final field dart.core::int* A2|staticFinalField = 42;
-  static method A2|method1(final main::A1* #this) → main::A1* {
+  static method A2|method1(lowered final main::A1* #this) → main::A1* {
     return #this;
   }
-  static method A2|get#method1(final main::A1* #this) → () →* main::A1*
+  static method A2|get#method1(lowered final main::A1* #this) → () →* main::A1*
     return () → main::A1* => main::A2|method1(#this);
-  static method A2|get#getter1(final main::A1* #this) → dart.core::String*
+  static method A2|get#getter1(lowered final main::A1* #this) → dart.core::String*
     return "42!";
-  static method A2|set#setter1(final main::A1* #this, dart.core::String* s) → void {}
+  static method A2|set#setter1(lowered final main::A1* #this, dart.core::String* s) → void {}
   static method A2|method2() → main::A1* {
     return null;
   }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.2.expect
index 07336f4..c11a0be 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_19.yaml.world.2.expect
@@ -29,14 +29,14 @@
   }
   static field dart.core::int* A2|staticField = 42;
   static final field dart.core::int* A2|staticFinalField = 42;
-  static method A2|method1(final main::A1* #this) → main::A1* {
+  static method A2|method1(lowered final main::A1* #this) → main::A1* {
     return #this;
   }
-  static method A2|get#method1(final main::A1* #this) → () →* main::A1*
+  static method A2|get#method1(lowered final main::A1* #this) → () →* main::A1*
     return () → main::A1* => main::A2|method1(#this);
-  static method A2|get#getter1(final main::A1* #this) → dart.core::String*
+  static method A2|get#getter1(lowered final main::A1* #this) → dart.core::String*
     return "42!";
-  static method A2|set#setter1(final main::A1* #this, dart.core::String* s) → void {}
+  static method A2|set#setter1(lowered final main::A1* #this, dart.core::String* s) → void {}
   static method A2|method2() → main::A1* {
     return null;
   }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.1.expect
index a9ef23e..c5238dd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.1.expect
@@ -25,14 +25,14 @@
     set setter1 = main::_extension#0|set#setter1;
     static set setter2 = set main::_extension#0|setter2;
   }
-  static method _extension#0|method1(final main::A1* #this) → main::A1* {
+  static method _extension#0|method1(lowered final main::A1* #this) → main::A1* {
     return #this;
   }
-  static method _extension#0|get#method1(final main::A1* #this) → () →* main::A1*
+  static method _extension#0|get#method1(lowered final main::A1* #this) → () →* main::A1*
     return () → main::A1* => main::_extension#0|method1(#this);
-  static method _extension#0|get#getter1(final main::A1* #this) → dart.core::String*
+  static method _extension#0|get#getter1(lowered final main::A1* #this) → dart.core::String*
     return "42!";
-  static method _extension#0|set#setter1(final main::A1* #this, dart.core::String* s) → void {}
+  static method _extension#0|set#setter1(lowered final main::A1* #this, dart.core::String* s) → void {}
   static method _extension#0|method2() → main::A1* {
     return null;
   }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.2.expect
index a9ef23e..c5238dd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_20.yaml.world.2.expect
@@ -25,14 +25,14 @@
     set setter1 = main::_extension#0|set#setter1;
     static set setter2 = set main::_extension#0|setter2;
   }
-  static method _extension#0|method1(final main::A1* #this) → main::A1* {
+  static method _extension#0|method1(lowered final main::A1* #this) → main::A1* {
     return #this;
   }
-  static method _extension#0|get#method1(final main::A1* #this) → () →* main::A1*
+  static method _extension#0|get#method1(lowered final main::A1* #this) → () →* main::A1*
     return () → main::A1* => main::_extension#0|method1(#this);
-  static method _extension#0|get#getter1(final main::A1* #this) → dart.core::String*
+  static method _extension#0|get#getter1(lowered final main::A1* #this) → dart.core::String*
     return "42!";
-  static method _extension#0|set#setter1(final main::A1* #this, dart.core::String* s) → void {}
+  static method _extension#0|set#setter1(lowered final main::A1* #this, dart.core::String* s) → void {}
   static method _extension#0|method2() → main::A1* {
     return null;
   }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
index 994228a..4547b87 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
@@ -317,21 +317,8 @@
     }
     operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*>
       return block {
-        final dart.core::List<dart.core::int*> #t5 = <dart.core::int*>[];
-        {
-          dart.core::Iterator<dart.core::int*> :sync-for-iterator = this.{dart.core::Iterable::iterator};
-          for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
-            final dart.core::int* #t6 = :sync-for-iterator.{dart.core::Iterator::current};
-            #t5.{dart.core::List::add}{Invariant}(#t6);
-          }
-        }
-        {
-          dart.core::Iterator<dart.core::int*> :sync-for-iterator = other.{dart.core::Iterable::iterator};
-          for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
-            final dart.core::int* #t7 = :sync-for-iterator.{dart.core::Iterator::current};
-            #t5.{dart.core::List::add}{Invariant}(#t7);
-          }
-        }
+        final dart.core::List<dart.core::int*> #t5 = dart.core::List::of<dart.core::int*>(this);
+        #t5.{dart.core::List::addAll}{Invariant}(other);
       } =>#t5;
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> {
       dart.core::int listLength = this.{dart.core::List::length};
@@ -352,7 +339,7 @@
       }
     }
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
-      dart.core::int* value = let dart.core::int? #t8 = fill in #t8.==(null) ?{dart.core::int*} #t8 : #t8{dart.core::int*};
+      dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
       dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
       for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
         this.{dart.core::List::[]=}(i, value);
@@ -479,7 +466,7 @@
       return 1.{dart.core::int::unary-}();
     }
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void {
-      dart.core::ArgumentError::checkNotNull<dart.core::int>(index, "index");
+      dart._internal::checkNotNullable<dart.core::int>(index, "index");
       dart.core::int length = this.{dart.core::List::length};
       dart.core::RangeError::checkValueInInterval(index, 0, length, "index");
       this.{dart.collection::ListMixin::add}(element);
@@ -530,7 +517,7 @@
           for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
             dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
             {
-              this.{dart.core::List::[]=}(let final dart.core::int #t9 = index in let final dart.core::int #t10 = index = #t9.{dart.core::num::+}(1) in #t9, element);
+              this.{dart.core::List::[]=}(let final dart.core::int #t7 = index in let final dart.core::int #t8 = index = #t7.{dart.core::num::+}(1) in #t7, element);
             }
           }
         }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
index 994228a..4547b87 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
@@ -317,21 +317,8 @@
     }
     operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*>
       return block {
-        final dart.core::List<dart.core::int*> #t5 = <dart.core::int*>[];
-        {
-          dart.core::Iterator<dart.core::int*> :sync-for-iterator = this.{dart.core::Iterable::iterator};
-          for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
-            final dart.core::int* #t6 = :sync-for-iterator.{dart.core::Iterator::current};
-            #t5.{dart.core::List::add}{Invariant}(#t6);
-          }
-        }
-        {
-          dart.core::Iterator<dart.core::int*> :sync-for-iterator = other.{dart.core::Iterable::iterator};
-          for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
-            final dart.core::int* #t7 = :sync-for-iterator.{dart.core::Iterator::current};
-            #t5.{dart.core::List::add}{Invariant}(#t7);
-          }
-        }
+        final dart.core::List<dart.core::int*> #t5 = dart.core::List::of<dart.core::int*>(this);
+        #t5.{dart.core::List::addAll}{Invariant}(other);
       } =>#t5;
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> {
       dart.core::int listLength = this.{dart.core::List::length};
@@ -352,7 +339,7 @@
       }
     }
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
-      dart.core::int* value = let dart.core::int? #t8 = fill in #t8.==(null) ?{dart.core::int*} #t8 : #t8{dart.core::int*};
+      dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
       dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
       for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
         this.{dart.core::List::[]=}(i, value);
@@ -479,7 +466,7 @@
       return 1.{dart.core::int::unary-}();
     }
     method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void {
-      dart.core::ArgumentError::checkNotNull<dart.core::int>(index, "index");
+      dart._internal::checkNotNullable<dart.core::int>(index, "index");
       dart.core::int length = this.{dart.core::List::length};
       dart.core::RangeError::checkValueInInterval(index, 0, length, "index");
       this.{dart.collection::ListMixin::add}(element);
@@ -530,7 +517,7 @@
           for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
             dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
             {
-              this.{dart.core::List::[]=}(let final dart.core::int #t9 = index in let final dart.core::int #t10 = index = #t9.{dart.core::num::+}(1) in #t9, element);
+              this.{dart.core::List::[]=}(let final dart.core::int #t7 = index in let final dart.core::int #t8 = index = #t7.{dart.core::num::+}(1) in #t7, element);
             }
           }
         }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
index 32da763..e2cb288 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
@@ -5,7 +5,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -26,7 +25,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -59,7 +57,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -79,7 +76,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
index 0fabe89..6ef77a2 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
@@ -5,7 +5,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -26,7 +25,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -59,7 +57,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -80,7 +77,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.1.expect
index 6a509d9..c1889db 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.1.expect
@@ -12,8 +12,8 @@
     method method2 = lib1::Extension2|method2;
     tearoff method2 = lib1::Extension2|get#method2;
   }
-  static method Extension2|method2(final main::Class* #this) → void {}
-  static method Extension2|get#method2(final main::Class* #this) → () →* void
+  static method Extension2|method2(lowered final main::Class* #this) → void {}
+  static method Extension2|get#method2(lowered final main::Class* #this) → () →* void
     return () → void => lib1::Extension2|method2(#this);
   static method lib1() → dynamic {
     main::Class* a = new main::Class::•();
@@ -30,8 +30,8 @@
     method method3 = lib2::Extension3|method3;
     tearoff method3 = lib2::Extension3|get#method3;
   }
-  static method Extension3|method3(final main::Class* #this) → void {}
-  static method Extension3|get#method3(final main::Class* #this) → () →* void
+  static method Extension3|method3(lowered final main::Class* #this) → void {}
+  static method Extension3|get#method3(lowered final main::Class* #this) → () →* void
     return () → void => lib2::Extension3|method3(#this);
   static method lib2() → dynamic {
     main::Class* a = new main::Class::•();
@@ -65,8 +65,8 @@
     method method = main::Extension|method;
     tearoff method = main::Extension|get#method;
   }
-  static method Extension|method(final main::Class* #this) → void {}
-  static method Extension|get#method(final main::Class* #this) → () →* void
+  static method Extension|method(lowered final main::Class* #this) → void {}
+  static method Extension|get#method(lowered final main::Class* #this) → () →* void
     return () → void => main::Extension|method(#this);
   static method main() → dynamic {
     main::Class* a = new main::Class::•();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.2.expect
index 2ffd6f9..7d35940 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.2.expect
@@ -12,8 +12,8 @@
     method method2 = lib1::Extension2|method2;
     tearoff method2 = lib1::Extension2|get#method2;
   }
-  static method Extension2|method2(final main::Class* #this) → void {}
-  static method Extension2|get#method2(final main::Class* #this) → () →* void
+  static method Extension2|method2(lowered final main::Class* #this) → void {}
+  static method Extension2|get#method2(lowered final main::Class* #this) → () →* void
     return () → void => lib1::Extension2|method2(#this);
   static method lib1() → dynamic {
     main::Class* a = new main::Class::•();
@@ -30,8 +30,8 @@
     method method3 = lib2::Extension3|method3;
     tearoff method3 = lib2::Extension3|get#method3;
   }
-  static method Extension3|method3(final main::Class* #this) → void {}
-  static method Extension3|get#method3(final main::Class* #this) → () →* void
+  static method Extension3|method3(lowered final main::Class* #this) → void {}
+  static method Extension3|get#method3(lowered final main::Class* #this) → () →* void
     return () → void => lib2::Extension3|method3(#this);
   static method lib2() → dynamic {
     main::Class* a = new main::Class::•();
@@ -65,8 +65,8 @@
     method method = main::Extension|method;
     tearoff method = main::Extension|get#method;
   }
-  static method Extension|method(final main::Class* #this) → void {}
-  static method Extension|get#method(final main::Class* #this) → () →* void
+  static method Extension|method(lowered final main::Class* #this) → void {}
+  static method Extension|get#method(lowered final main::Class* #this) → () →* void
     return () → void => main::Extension|method(#this);
   static method main() → dynamic {
     main::Class* a = new main::Class::•();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.3.expect
index 9287c32..f07ce1c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.3.expect
@@ -12,8 +12,8 @@
     method method2 = lib1::Extension2|method2;
     tearoff method2 = lib1::Extension2|get#method2;
   }
-  static method Extension2|method2(final main::Class* #this) → void {}
-  static method Extension2|get#method2(final main::Class* #this) → () →* void
+  static method Extension2|method2(lowered final main::Class* #this) → void {}
+  static method Extension2|get#method2(lowered final main::Class* #this) → () →* void
     return () → void => lib1::Extension2|method2(#this);
   static method lib1() → dynamic {
     main::Class* a = new main::Class::•();
@@ -30,8 +30,8 @@
     method method3 = lib2::Extension3|method3;
     tearoff method3 = lib2::Extension3|get#method3;
   }
-  static method Extension3|method3(final main::Class* #this) → void {}
-  static method Extension3|get#method3(final main::Class* #this) → () →* void
+  static method Extension3|method3(lowered final main::Class* #this) → void {}
+  static method Extension3|get#method3(lowered final main::Class* #this) → () →* void
     return () → void => lib2::Extension3|method3(#this);
   static method lib2() → dynamic {
     main::Class* a = new main::Class::•();
@@ -66,8 +66,8 @@
     method method = main::Extension|method;
     tearoff method = main::Extension|get#method;
   }
-  static method Extension|method(final main::Class* #this) → void {}
-  static method Extension|get#method(final main::Class* #this) → () →* void
+  static method Extension|method(lowered final main::Class* #this) → void {}
+  static method Extension|get#method(lowered final main::Class* #this) → () →* void
     return () → void => main::Extension|method(#this);
   static method main() → dynamic {
     main::Class* a = new main::Class::•();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.4.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.4.expect
index 2e9599f..72bb927 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.4.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_34.yaml.world.4.expect
@@ -12,8 +12,8 @@
     method method2 = lib1::Extension2|method2;
     tearoff method2 = lib1::Extension2|get#method2;
   }
-  static method Extension2|method2(final main::Class* #this) → void {}
-  static method Extension2|get#method2(final main::Class* #this) → () →* void
+  static method Extension2|method2(lowered final main::Class* #this) → void {}
+  static method Extension2|get#method2(lowered final main::Class* #this) → () →* void
     return () → void => lib1::Extension2|method2(#this);
   static method lib1() → dynamic {
     main::Class* a = new main::Class::•();
@@ -31,8 +31,8 @@
     method method3 = lib2::Extension3|method3;
     tearoff method3 = lib2::Extension3|get#method3;
   }
-  static method Extension3|method3(final main::Class* #this) → void {}
-  static method Extension3|get#method3(final main::Class* #this) → () →* void
+  static method Extension3|method3(lowered final main::Class* #this) → void {}
+  static method Extension3|get#method3(lowered final main::Class* #this) → () →* void
     return () → void => lib2::Extension3|method3(#this);
   static method lib2() → dynamic {
     main::Class* a = new main::Class::•();
@@ -67,8 +67,8 @@
     method method = main::Extension|method;
     tearoff method = main::Extension|get#method;
   }
-  static method Extension|method(final main::Class* #this) → void {}
-  static method Extension|get#method(final main::Class* #this) → () →* void
+  static method Extension|method(lowered final main::Class* #this) → void {}
+  static method Extension|get#method(lowered final main::Class* #this) → () →* void
     return () → void => main::Extension|method(#this);
   static method main() → dynamic {
     main::Class* a = new main::Class::•();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.1.expect
index 7c7bff1..e0981f7 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.1.expect
@@ -7,9 +7,9 @@
     method baz = lib1::Extension1|baz;
     tearoff baz = lib1::Extension1|get#baz;
   }
-  static method Extension1|baz(final main::A* #this) → dynamic
+  static method Extension1|baz(lowered final main::A* #this) → dynamic
     return 42;
-  static method Extension1|get#baz(final main::A* #this) → () →* dynamic
+  static method Extension1|get#baz(lowered final main::A* #this) → () →* dynamic
     return () → dynamic => lib1::Extension1|baz(#this);
 }
 library from "org-dartlang-test:///lib2.dart" as lib2 {
@@ -56,8 +56,8 @@
   static method main() → dynamic {
     lib2::method(new main::A::•());
   }
-  static method Extension2|boz(final main::A* #this) → dynamic
+  static method Extension2|boz(lowered final main::A* #this) → dynamic
     return 87;
-  static method Extension2|get#boz(final main::A* #this) → () →* dynamic
+  static method Extension2|get#boz(lowered final main::A* #this) → () →* dynamic
     return () → dynamic => main::Extension2|boz(#this);
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.2.expect
index 3b56dcd..13f26e0 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.2.expect
@@ -7,9 +7,9 @@
     method baz = lib1::Extension1|baz;
     tearoff baz = lib1::Extension1|get#baz;
   }
-  static method Extension1|baz(final main::A* #this) → dynamic
+  static method Extension1|baz(lowered final main::A* #this) → dynamic
     return 42;
-  static method Extension1|get#baz(final main::A* #this) → () →* dynamic
+  static method Extension1|get#baz(lowered final main::A* #this) → () →* dynamic
     return () → dynamic => lib1::Extension1|baz(#this);
 }
 library from "org-dartlang-test:///lib2.dart" as lib2 {
@@ -57,8 +57,8 @@
   static method main() → dynamic {
     lib2::method(new main::A::•());
   }
-  static method Extension2|boz(final main::A* #this) → dynamic
+  static method Extension2|boz(lowered final main::A* #this) → dynamic
     return 87;
-  static method Extension2|get#boz(final main::A* #this) → () →* dynamic
+  static method Extension2|get#boz(lowered final main::A* #this) → () →* dynamic
     return () → dynamic => main::Extension2|boz(#this);
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.3.expect
index 0958b1c..562f9d8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_40.yaml.world.3.expect
@@ -7,9 +7,9 @@
     method baz = lib1::Extension1|baz;
     tearoff baz = lib1::Extension1|get#baz;
   }
-  static method Extension1|baz(final main::A* #this) → dynamic
+  static method Extension1|baz(lowered final main::A* #this) → dynamic
     return 42;
-  static method Extension1|get#baz(final main::A* #this) → () →* dynamic
+  static method Extension1|get#baz(lowered final main::A* #this) → () →* dynamic
     return () → dynamic => lib1::Extension1|baz(#this);
 }
 library from "org-dartlang-test:///lib2.dart" as lib2 {
@@ -57,8 +57,8 @@
   static method main() → dynamic {
     lib2::method(new main::A::•());
   }
-  static method Extension2|boz(final main::A* #this) → dynamic
+  static method Extension2|boz(lowered final main::A* #this) → dynamic
     return 123;
-  static method Extension2|get#boz(final main::A* #this) → () →* dynamic
+  static method Extension2|get#boz(lowered final main::A* #this) → () →* dynamic
     return () → dynamic => main::Extension2|boz(#this);
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml
new file mode 100644
index 0000000..6ace390
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml
@@ -0,0 +1,45 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Reproduce a crash.
+
+type: newworld
+trackWidgetCreation: true
+target: DDC # basically needed for widget creation to be run
+worlds:
+  - entry: flutter_gallery/lib/main.dart
+    experiments: alternative-invalidation-strategy
+    sources:
+      flutter_gallery/.dart_tool/package_config.json: |
+        {
+          "packages": [
+            {
+              "name": "flutter",
+              "rootUri": "../../flutter",
+              "packageUri": "lib/",
+              "languageVersion": "2.12"
+            }
+          ],
+          "configVersion": 2,
+          "generatorVersion": "2.12.0-50.0.dev"
+        }
+      flutter_gallery/lib/main.dart: |
+        import 'package:flutter/src/widgets/framework.dart';
+      flutter/lib/src/widgets/framework.dart: |
+        import 'widget_inspector.dart';
+        abstract class Widget {}
+      flutter/lib/src/widgets/widget_inspector.dart: |
+        abstract class _HasCreationLocation {}
+        class _Location {}
+    expectedLibraryCount: 3
+
+  - entry: flutter_gallery/lib/main.dart
+    experiments: alternative-invalidation-strategy
+    worldType: updated
+    expectInitializeFromDill: false
+    invalidate:
+      - package:flutter/src/widgets/framework.dart
+    expectedLibraryCount: 3
+    expectsRebuildBodiesOnly: true
+
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml.world.1.expect
new file mode 100644
index 0000000..1c83cc5
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml.world.1.expect
@@ -0,0 +1,33 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  import "package:flutter/src/widgets/widget_inspector.dart";
+
+  abstract class Widget extends dart.core::Object implements wid::_HasCreationLocation {
+    final field wid::_Location? _location /*isLegacy, from null */;
+    synthetic constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
+      : super dart.core::Object::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+      ;
+  }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+  abstract class _HasCreationLocation extends dart.core::Object {
+    synthetic constructor •() → wid::_HasCreationLocation
+      : super dart.core::Object::•()
+      ;
+  }
+  class _Location extends dart.core::Object {
+    synthetic constructor •() → wid::_Location
+      : super dart.core::Object::•()
+      ;
+  }
+}
+library from "org-dartlang-test:///flutter_gallery/lib/main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+
+}
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml.world.2.expect
new file mode 100644
index 0000000..1c83cc5
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_44_flutter.yaml.world.2.expect
@@ -0,0 +1,33 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  import "package:flutter/src/widgets/widget_inspector.dart";
+
+  abstract class Widget extends dart.core::Object implements wid::_HasCreationLocation {
+    final field wid::_Location? _location /*isLegacy, from null */;
+    synthetic constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4 = #C1}) → fra::Widget
+      : super dart.core::Object::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+      ;
+  }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+  abstract class _HasCreationLocation extends dart.core::Object {
+    synthetic constructor •() → wid::_HasCreationLocation
+      : super dart.core::Object::•()
+      ;
+  }
+  class _Location extends dart.core::Object {
+    synthetic constructor •() → wid::_Location
+      : super dart.core::Object::•()
+      ;
+  }
+}
+library from "org-dartlang-test:///flutter_gallery/lib/main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+
+}
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
index e8c7c9a..824f20e 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
@@ -23,7 +23,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -43,7 +42,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -54,7 +52,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -75,7 +72,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
index af9c5da..44652d1 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
@@ -23,7 +23,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -43,7 +42,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -54,7 +52,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -75,7 +72,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
index abf2025..99415d4 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
@@ -23,7 +23,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -44,7 +43,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -55,7 +53,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -76,7 +73,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.1.expect
index aa1db3e..4981234 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.1.expect
@@ -6,7 +6,7 @@
   }
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -25,4 +25,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.4.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.4.expect
index c0b1b18..b1013a0 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.4.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.4.expect
@@ -14,7 +14,7 @@
   }
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -33,4 +33,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.5.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.5.expect
index 6afed6a..a4d9f55 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.5.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml.world.5.expect
@@ -14,7 +14,7 @@
   }
 }
 
-And 19 platform libraries:
+And 18 platform libraries:
  - dart:_http
  - dart:_builtin
  - dart:vmservice_io
@@ -33,4 +33,3 @@
  - dart:mirrors
  - dart:typed_data
  - dart:_vmservice
- - dart:wasm
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
index 487e430..d56811d 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
@@ -30,7 +30,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -54,7 +53,6 @@
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -72,7 +70,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -83,7 +80,6 @@
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -101,7 +97,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -112,7 +107,6 @@
           final asy::_Future<asy::Future<core::int*>*>* :async_future = new asy::_Future::•<asy::Future<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<asy::Future<core::int*>*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -130,7 +124,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -141,7 +134,6 @@
           final asy::_Future<FutureOr<core::int*>*>* :async_future = new asy::_Future::•<FutureOr<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<FutureOr<core::int*>*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -159,7 +151,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -170,7 +161,6 @@
           final asy::_Future<self::MyFuture*>* :async_future = new asy::_Future::•<self::MyFuture*>();
           core::bool* :is_sync = false;
           FutureOr<self::MyFuture*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -188,7 +178,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -199,7 +188,6 @@
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -217,7 +205,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -228,7 +215,6 @@
           final asy::_Future<asy::Future<core::int*>*>* :async_future = new asy::_Future::•<asy::Future<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<asy::Future<core::int*>*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -246,7 +232,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -257,7 +242,6 @@
           final asy::_Future<FutureOr<core::int*>*>* :async_future = new asy::_Future::•<FutureOr<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<FutureOr<core::int*>*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -275,7 +259,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -286,7 +269,6 @@
           final asy::_Future<self::MyFuture*>* :async_future = new asy::_Future::•<self::MyFuture*>();
           core::bool* :is_sync = false;
           FutureOr<self::MyFuture*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -304,7 +286,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -315,7 +296,6 @@
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -333,7 +313,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -367,7 +346,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
index e19b6bd..3a8bfa5c7 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
@@ -11,7 +11,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -29,7 +28,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
index e7ca87d..8e77c75 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
@@ -7,7 +7,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -25,7 +24,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
index 191fffb..b678b0d 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
@@ -11,7 +11,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -29,7 +28,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
index 04cb4b4..5bac272 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
     final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
     core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -36,7 +35,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
index a7b9b3d..6d91810 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
     final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
     core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -36,7 +35,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
index 398dba4..5cd44bc 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
     final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
     core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -36,7 +35,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
index a13fe6a..adbe951 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
@@ -9,7 +9,6 @@
   () →* asy::Stream<core::num*>* f = () → asy::Stream<core::num*>* /* originally async* */ {
     asy::_AsyncStarStreamController<core::num*>* :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -39,7 +38,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<core::num*>(:async_op);
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
index 6215f3a..bd417fc 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -24,7 +23,6 @@
           final asy::_Future<Null>* :async_future = new asy::_Future::•<Null>();
           core::bool* :is_sync = false;
           FutureOr<Null>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -42,7 +40,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -60,7 +57,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
index a83d5ab..fa13ae6 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -23,7 +22,6 @@
         () →* asy::Stream<Null>* f = () → asy::Stream<Null>* /* originally async* */ {
           asy::_AsyncStarStreamController<Null>* :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -48,7 +46,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<Null>(:async_op);
@@ -66,7 +63,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
index c861eee..1d08476 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -32,7 +31,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
index 30e4086..313ed02 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
@@ -63,7 +63,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -233,7 +232,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -244,7 +242,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -327,7 +324,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart
index aaa7e1c..7ea3518 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart
@@ -12,17 +12,17 @@
 }
 
 Stream<List<int>> foo() async* {
-  yield new /*@ typeArgs=int* */ List();
+  yield /*@typeArgs=int**/ [];
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
-  yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
+  yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
   yield* new /*@ typeArgs=List<int*>* */ MyStream();
 }
 
 Iterable<Map<int, int>> bar() sync* {
   yield new /*@ typeArgs=int*, int* */ Map();
-  yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
+  yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
-  yield* new /*@ typeArgs=Map<int*, int*>* */ List();
+  yield* /*@typeArgs=Map<int*, int*>**/ [];
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
index 2514965..2420358 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
@@ -8,17 +8,17 @@
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
 //                                                                     ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Stream' is from 'dart:async'.
-//   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                      ^
+//   yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                                ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Map' is from 'dart:core'.
-//   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                     ^
+//   yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
 //  - 'Map' is from 'dart:core'.
@@ -84,32 +84,32 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method foo() → asy::Stream<core::List<core::int*>*>* async* {
-  yield core::List::•<core::int*>();
+  yield<core::int*>[];
   yield let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:69: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
  - 'List' is from 'dart:core'.
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
                                                                     ^" in self::MyStream::•<dynamic>() as{TypeError} core::List<core::int*>*;
-  yield* let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+  yield* let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
-  yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                     ^" in core::List::•<dynamic>() as{TypeError} asy::Stream<core::List<core::int*>*>*;
+  yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                               ^" in <dynamic>[] as{TypeError} asy::Stream<core::List<core::int*>*>*;
   yield* self::MyStream::•<core::List<core::int*>*>();
 }
 static method bar() → core::Iterable<core::Map<core::int*, core::int*>*>* sync* {
   yield core::Map::•<core::int*, core::int*>();
-  yield let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+  yield let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
  - 'List' is from 'dart:core'.
  - 'Map' is from 'dart:core'.
-  yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                    ^" in core::List::•<dynamic>() as{TypeError} core::Map<core::int*, core::int*>*;
+  yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                              ^" in <dynamic>[] as{TypeError} core::Map<core::int*, core::int*>*;
   yield* let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
  - 'Map' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
                                                                               ^" in core::Map::•<dynamic, dynamic>() as{TypeError} core::Iterable<core::Map<core::int*, core::int*>*>*;
-  yield* core::List::•<core::Map<core::int*, core::int*>*>();
+  yield*<core::Map<core::int*, core::int*>*>[];
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
index 91c8102..6772134 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
@@ -8,17 +8,17 @@
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
 //                                                                     ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Stream' is from 'dart:async'.
-//   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                      ^
+//   yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                                ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Map' is from 'dart:core'.
-//   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                     ^
+//   yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
 //  - 'Map' is from 'dart:core'.
@@ -86,7 +86,6 @@
 static method foo() → asy::Stream<core::List<core::int*>*>* /* originally async* */ {
   asy::_AsyncStarStreamController<core::List<core::int*>*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -98,7 +97,7 @@
       try {
         #L1:
         {
-          if(:controller.{asy::_AsyncStarStreamController::add}(core::_GrowableList::•<core::int*>(0)))
+          if(:controller.{asy::_AsyncStarStreamController::add}(<core::int*>[]))
             return null;
           else
             [yield] null;
@@ -110,11 +109,11 @@
             return null;
           else
             [yield] null;
-          if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
-  yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                     ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} asy::Stream<core::List<core::int*>*>*))
+  yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                               ^" in <dynamic>[] as{TypeError} asy::Stream<core::List<core::int*>*>*))
             return null;
           else
             [yield] null;
@@ -131,7 +130,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::List<core::int*>*>(:async_op);
@@ -149,11 +147,11 @@
           [yield] true;
         }
         {
-          :iterator.{core::_SyncIterator::_current} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+          :iterator.{core::_SyncIterator::_current} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
  - 'List' is from 'dart:core'.
  - 'Map' is from 'dart:core'.
-  yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                    ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} core::Map<core::int*, core::int*>*;
+  yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                              ^" in <dynamic>[] as{TypeError} core::Map<core::int*, core::int*>*;
           [yield] true;
         }
         {
@@ -165,7 +163,7 @@
           [yield] true;
         }
         {
-          :iterator.{core::_SyncIterator::_yieldEachIterable} = core::_GrowableList::•<core::Map<core::int*, core::int*>*>(0);
+          :iterator.{core::_SyncIterator::_yieldEachIterable} = <core::Map<core::int*, core::int*>*>[];
           [yield] true;
         }
       }
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
index 7e9c9e0..a832376 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
@@ -8,7 +8,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -90,7 +89,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index d5ab080..99706f8 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -59,7 +58,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -70,7 +68,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -90,7 +87,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -101,7 +97,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -119,7 +114,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +124,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -148,7 +141,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -163,7 +155,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -181,7 +172,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -192,7 +182,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -210,7 +199,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index 4e59f53..780ffb76 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -59,7 +58,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -70,7 +68,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -90,7 +87,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -101,7 +97,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -119,7 +114,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +124,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -148,7 +141,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -163,7 +155,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -181,7 +172,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -192,7 +182,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -210,7 +199,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
index d64e850..3b12a3e 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -59,7 +58,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -70,7 +68,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -90,7 +87,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -101,7 +97,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -119,7 +114,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +124,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -148,7 +141,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -163,7 +155,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -181,7 +172,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -192,7 +182,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -210,7 +199,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
index 656e9a7..f715984 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -59,7 +58,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -70,7 +68,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -90,7 +87,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -101,7 +97,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -119,7 +114,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +124,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -148,7 +141,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -163,7 +155,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -181,7 +172,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -192,7 +182,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -210,7 +199,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
index 5f08a16..8095cd9 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -59,7 +58,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -70,7 +68,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -90,7 +87,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -101,7 +97,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -119,7 +114,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +124,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -148,7 +141,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -163,7 +155,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -181,7 +172,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -192,7 +182,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -210,7 +199,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
index 6e05d10..2bb0e59 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -59,7 +58,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -70,7 +68,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -90,7 +87,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -101,7 +97,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -119,7 +114,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +124,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -148,7 +141,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -163,7 +155,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -181,7 +172,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -192,7 +182,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -210,7 +199,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
index 97390dc..1b90060 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -77,7 +75,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -97,7 +94,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
index 7e7583e..09ef601 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -77,7 +75,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -97,7 +94,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
index b8e8643..97bec60 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -77,7 +75,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -97,7 +94,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
index dbf053f..947f092 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -77,7 +75,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -97,7 +94,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
index f0ab4cd..1ea35fe 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -77,7 +75,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -97,7 +94,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
index 27e32cf..8acc631 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -77,7 +75,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -97,7 +94,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index 0ffe085..41975f17 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -67,7 +66,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -78,7 +76,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -98,7 +95,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
index cf08d88..2d0d430 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
@@ -36,7 +36,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -54,7 +53,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -65,7 +63,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -83,7 +80,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -94,7 +90,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -113,7 +108,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
index eae9737..e4ad380 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
@@ -36,7 +36,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -54,7 +53,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -65,7 +63,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -83,7 +80,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -94,7 +90,6 @@
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -113,7 +108,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
index b26d359..cdf55f7 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -48,7 +48,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -77,7 +75,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -95,7 +92,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
index 223a03e..3338e9b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -57,7 +56,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -68,7 +66,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -86,7 +83,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
index 083d7a2..d89cd97 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -48,7 +48,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -66,7 +65,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -77,7 +75,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -95,7 +92,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
index 31ccfda..b7ad80a 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
@@ -39,7 +39,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -57,7 +56,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -68,7 +66,6 @@
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -86,7 +83,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
index 9eb7030..a59d7c8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
@@ -25,7 +25,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -46,7 +45,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
index b214c57..611598b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -32,7 +31,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
index fee2dcd..448d38f 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
@@ -35,7 +35,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -61,7 +60,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
index b1d5d53..2f34a0b 100644
--- a/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
   self::foo(() → asy::Stream<core::int*>* /* originally async* */ {
     asy::_AsyncStarStreamController<core::int*>* :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -39,7 +38,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
index c1b45ec..eeeccd2 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -28,7 +27,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -42,7 +40,6 @@
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -60,7 +57,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -87,7 +83,6 @@
   function f5() → asy::Stream<core::int*>* /* originally async* */ {
     asy::_AsyncStarStreamController<core::int*>* :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -112,7 +107,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<core::int*>(:async_op);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
index 7ef736b..4aa6578 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
@@ -59,7 +59,6 @@
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -104,7 +103,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -130,7 +128,6 @@
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -176,7 +173,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -249,7 +245,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -451,7 +446,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
index 273bbbe..57169ca 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -22,7 +22,6 @@
     final asy::_Future<(core::int*) →* core::int*>* :async_future = new asy::_Future::•<(core::int*) →* core::int*>();
     core::bool* :is_sync = false;
     FutureOr<(core::int*) →* core::int*>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -43,7 +42,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -87,7 +85,6 @@
   function e() → asy::Stream<(core::int*) →* core::int*>* /* originally async* */ {
     asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -112,7 +109,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<(core::int*) →* core::int*>(:async_op);
@@ -122,7 +118,6 @@
   function f() → asy::Stream<(core::int*) →* core::int*>* /* originally async* */ {
     asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -147,7 +142,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<(core::int*) →* core::int*>(:async_op);
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
index 0028ef6..340170ef 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -21,7 +21,6 @@
   final asy::_Future<(core::int*) →* core::int*>* :async_future = new asy::_Future::•<(core::int*) →* core::int*>();
   core::bool* :is_sync = false;
   FutureOr<(core::int*) →* core::int*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -42,7 +41,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -86,7 +84,6 @@
 static method e() → asy::Stream<(core::int*) →* core::int*>* /* originally async* */ {
   asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -111,7 +108,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<(core::int*) →* core::int*>(:async_op);
@@ -121,7 +117,6 @@
 static method f() → asy::Stream<(core::int*) →* core::int*>* /* originally async* */ {
   asy::_AsyncStarStreamController<(core::int*) →* core::int*>* :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -146,7 +141,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<(core::int*) →* core::int*>(:async_op);
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
index 1af0a51..75740f5 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
@@ -31,7 +31,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -129,7 +128,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
index 0d9cdbd..c9f269d 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
@@ -47,7 +47,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -208,7 +207,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.strong.expect b/pkg/front_end/testcases/late_lowering/compound.dart.strong.expect
index 43cd6f1..39a246d 100644
--- a/pkg/front_end/testcases/late_lowering/compound.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.strong.expect
@@ -11,31 +11,31 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? local1;
+  lowered core::int? #local1;
   function #local1#get() → core::int
-    return let final core::int? #t1 = local1 in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local1") : #t1{core::int};
+    return let final core::int? #t1 = #local1 in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local1") : #t1{core::int};
   function #local1#set(core::int #t2) → dynamic
-    return local1 = #t2;
+    return #local1 = #t2;
   #local1#set.call(0);
   self::expect(0, #local1#get.call());
   #local1#set.call(#local1#get.call().{core::num::+}(2));
   self::expect(2, #local1#get.call());
-  core::int? local2;
+  lowered core::int? #local2;
   function #local2#get() → core::int
-    return let final core::int? #t3 = local2 in #t3.==(null) ?{core::int} local2 = 1 : #t3{core::int};
+    return let final core::int? #t3 = #local2 in #t3.==(null) ?{core::int} #local2 = 1 : #t3{core::int};
   function #local2#set(core::int #t4) → dynamic
-    return local2 = #t4;
+    return #local2 = #t4;
   self::expect(1, #local2#get.call());
   #local2#set.call(#local2#get.call().{core::num::+}(2));
   self::expect(3, #local2#get.call());
 }
 static method error() → dynamic {
-  final core::int? local;
+  lowered final core::int? #local;
   function #local#get() → core::int
-    return let final core::int? #t5 = local in #t5.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t5{core::int};
+    return let final core::int? #t5 = #local in #t5.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t5{core::int};
   function #local#set(core::int #t6) → dynamic
-    if(local.==(null))
-      return local = #t6;
+    if(#local.==(null))
+      return #local = #t6;
     else
       throw new _in::LateError::localAI("local");
   #local#set.call((let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/compound.dart:20:3: Error: Late variable 'local' without initializer is definitely unassigned.
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/compound.dart.strong.transformed.expect
index 43cd6f1..39a246d 100644
--- a/pkg/front_end/testcases/late_lowering/compound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.strong.transformed.expect
@@ -11,31 +11,31 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? local1;
+  lowered core::int? #local1;
   function #local1#get() → core::int
-    return let final core::int? #t1 = local1 in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local1") : #t1{core::int};
+    return let final core::int? #t1 = #local1 in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local1") : #t1{core::int};
   function #local1#set(core::int #t2) → dynamic
-    return local1 = #t2;
+    return #local1 = #t2;
   #local1#set.call(0);
   self::expect(0, #local1#get.call());
   #local1#set.call(#local1#get.call().{core::num::+}(2));
   self::expect(2, #local1#get.call());
-  core::int? local2;
+  lowered core::int? #local2;
   function #local2#get() → core::int
-    return let final core::int? #t3 = local2 in #t3.==(null) ?{core::int} local2 = 1 : #t3{core::int};
+    return let final core::int? #t3 = #local2 in #t3.==(null) ?{core::int} #local2 = 1 : #t3{core::int};
   function #local2#set(core::int #t4) → dynamic
-    return local2 = #t4;
+    return #local2 = #t4;
   self::expect(1, #local2#get.call());
   #local2#set.call(#local2#get.call().{core::num::+}(2));
   self::expect(3, #local2#get.call());
 }
 static method error() → dynamic {
-  final core::int? local;
+  lowered final core::int? #local;
   function #local#get() → core::int
-    return let final core::int? #t5 = local in #t5.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t5{core::int};
+    return let final core::int? #t5 = #local in #t5.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t5{core::int};
   function #local#set(core::int #t6) → dynamic
-    if(local.==(null))
-      return local = #t6;
+    if(#local.==(null))
+      return #local = #t6;
     else
       throw new _in::LateError::localAI("local");
   #local#set.call((let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/compound.dart:20:3: Error: Late variable 'local' without initializer is definitely unassigned.
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.weak.expect b/pkg/front_end/testcases/late_lowering/compound.dart.weak.expect
index 991bc7a..c56967b 100644
--- a/pkg/front_end/testcases/late_lowering/compound.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.weak.expect
@@ -11,46 +11,46 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? local1;
-  core::bool #local1#isSet = false;
+  lowered core::int? #local1;
+  lowered core::bool #local1#isSet = false;
   function #local1#get() → core::int
-    return #local1#isSet ?{core::int} local1{core::int} : throw new _in::LateError::localNI("local1");
+    return #local1#isSet ?{core::int} #local1{core::int} : throw new _in::LateError::localNI("local1");
   function #local1#set(core::int #t1) → dynamic {
     #local1#isSet = true;
-    return local1 = #t1;
+    return #local1 = #t1;
   }
   #local1#set.call(0);
   self::expect(0, #local1#get.call());
   #local1#set.call(#local1#get.call().{core::num::+}(2));
   self::expect(2, #local1#get.call());
-  core::int? local2;
-  core::bool #local2#isSet = false;
+  lowered core::int? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → core::int {
     if(!#local2#isSet) {
-      local2 = 1;
+      #local2 = 1;
       #local2#isSet = true;
     }
-    return local2{core::int};
+    return #local2{core::int};
   }
   function #local2#set(core::int #t2) → dynamic {
     #local2#isSet = true;
-    return local2 = #t2;
+    return #local2 = #t2;
   }
   self::expect(1, #local2#get.call());
   #local2#set.call(#local2#get.call().{core::num::+}(2));
   self::expect(3, #local2#get.call());
 }
 static method error() → dynamic {
-  final core::int? local;
-  core::bool #local#isSet = false;
+  lowered final core::int? #local;
+  lowered core::bool #local#isSet = false;
   function #local#get() → core::int
-    return #local#isSet ?{core::int} local{core::int} : throw new _in::LateError::localNI("local");
+    return #local#isSet ?{core::int} #local{core::int} : throw new _in::LateError::localNI("local");
   function #local#set(core::int #t3) → dynamic
     if(#local#isSet)
       throw new _in::LateError::localAI("local");
     else {
       #local#isSet = true;
-      return local = #t3;
+      return #local = #t3;
     }
   #local#set.call((let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/late_lowering/compound.dart:20:3: Error: Late variable 'local' without initializer is definitely unassigned.
   local += 0;
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/compound.dart.weak.transformed.expect
index 991bc7a..c56967b 100644
--- a/pkg/front_end/testcases/late_lowering/compound.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.weak.transformed.expect
@@ -11,46 +11,46 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? local1;
-  core::bool #local1#isSet = false;
+  lowered core::int? #local1;
+  lowered core::bool #local1#isSet = false;
   function #local1#get() → core::int
-    return #local1#isSet ?{core::int} local1{core::int} : throw new _in::LateError::localNI("local1");
+    return #local1#isSet ?{core::int} #local1{core::int} : throw new _in::LateError::localNI("local1");
   function #local1#set(core::int #t1) → dynamic {
     #local1#isSet = true;
-    return local1 = #t1;
+    return #local1 = #t1;
   }
   #local1#set.call(0);
   self::expect(0, #local1#get.call());
   #local1#set.call(#local1#get.call().{core::num::+}(2));
   self::expect(2, #local1#get.call());
-  core::int? local2;
-  core::bool #local2#isSet = false;
+  lowered core::int? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → core::int {
     if(!#local2#isSet) {
-      local2 = 1;
+      #local2 = 1;
       #local2#isSet = true;
     }
-    return local2{core::int};
+    return #local2{core::int};
   }
   function #local2#set(core::int #t2) → dynamic {
     #local2#isSet = true;
-    return local2 = #t2;
+    return #local2 = #t2;
   }
   self::expect(1, #local2#get.call());
   #local2#set.call(#local2#get.call().{core::num::+}(2));
   self::expect(3, #local2#get.call());
 }
 static method error() → dynamic {
-  final core::int? local;
-  core::bool #local#isSet = false;
+  lowered final core::int? #local;
+  lowered core::bool #local#isSet = false;
   function #local#get() → core::int
-    return #local#isSet ?{core::int} local{core::int} : throw new _in::LateError::localNI("local");
+    return #local#isSet ?{core::int} #local{core::int} : throw new _in::LateError::localNI("local");
   function #local#set(core::int #t3) → dynamic
     if(#local#isSet)
       throw new _in::LateError::localAI("local");
     else {
       #local#isSet = true;
-      return local = #t3;
+      return #local = #t3;
     }
   #local#set.call((let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/late_lowering/compound.dart:20:3: Error: Late variable 'local' without initializer is definitely unassigned.
   local += 0;
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.expect
index ec6a51e..32bd105 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.expect
@@ -2,61 +2,61 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -65,72 +65,72 @@
 import "dart:async";
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t1;
+      return #local2 = #t1;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t2 = local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
+    return let final core::int? #t2 = #local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
   function #local4#set(core::int #t3) → dynamic
-    if(local4.==(null))
-      return local4 = #t3;
+    if(#local4.==(null))
+      return #local4 = #t3;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t4 = local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t4 = #local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t5) → dynamic
-    if(local6.==(null))
-      return local6 = #t5;
+    if(#local6.==(null))
+      return #local6 = #t5;
     else
       throw new _in::LateError::localAI("local6");
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t9) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t9;
+      return #local2 = #t9;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t10 = local4 in #t10.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t10{core::int};
+    return let final core::int? #t10 = #local4 in #t10.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t10{core::int};
   function #local4#set(core::int #t11) → dynamic
-    if(local4.==(null))
-      return local4 = #t11;
+    if(#local4.==(null))
+      return #local4 = #t11;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t12 = local6 in #t12.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t12{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t12 = #local6 in #t12.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t12{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t13) → dynamic
-    if(local6.==(null))
-      return local6 = #t13;
+    if(#local6.==(null))
+      return #local6 = #t13;
     else
       throw new _in::LateError::localAI("local6");
   if(b) {
@@ -141,97 +141,97 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field () → Null fieldCompound = () → Null {
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t17 = local4 in #t17.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t17{core::int};
+    return let final core::int? #t17 = #local4 in #t17.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t17{core::int};
   function #local4#set(core::int #t18) → dynamic
-    if(local4.==(null))
-      return local4 = #t18;
+    if(#local4.==(null))
+      return #local4 = #t18;
     else
       throw new _in::LateError::localAI("local4");
   #local4#set.call(0);
-  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
-  final self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t20) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t20;
+      return #local2 = #t20;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t21 = local4 in #t21.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t21{core::int};
+    return let final core::int? #t21 = #local4 in #t21.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t21{core::int};
   function #local4#set(core::int #t22) → dynamic
-    if(local4.==(null))
-      return local4 = #t22;
+    if(#local4.==(null))
+      return #local4 = #t22;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t23 = local6 in #t23.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t23{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t23 = #local6 in #t23.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t23{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t24) → dynamic
-    if(local6.==(null))
-      return local6 = #t24;
+    if(#local6.==(null))
+      return #local6 = #t24;
     else
       throw new _in::LateError::localAI("local6");
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
-  final self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t28) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t28;
+      return #local2 = #t28;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t29 = local4 in #t29.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t29{core::int};
+    return let final core::int? #t29 = #local4 in #t29.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t29{core::int};
   function #local4#set(core::int #t30) → dynamic
-    if(local4.==(null))
-      return local4 = #t30;
+    if(#local4.==(null))
+      return #local4 = #t30;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t31 = local6 in #t31.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t31{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t31 = #local6 in #t31.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t31{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t32) → dynamic
-    if(local6.==(null))
-      return local6 = #t32;
+    if(#local6.==(null))
+      return #local6 = #t32;
     else
       throw new _in::LateError::localAI("local6");
   if(b) {
@@ -242,28 +242,28 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodCompound() → dynamic {
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t36 = local4 in #t36.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t36{core::int};
+    return let final core::int? #t36 = #local4 in #t36.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t36{core::int};
   function #local4#set(core::int #t37) → dynamic
-    if(local4.==(null))
-      return local4 = #t37;
+    if(#local4.==(null))
+      return #local4 = #t37;
     else
       throw new _in::LateError::localAI("local4");
   #local4#set.call(0);
-  let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.transformed.expect
index ec6a51e..32bd105 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.strong.transformed.expect
@@ -2,61 +2,61 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -65,72 +65,72 @@
 import "dart:async";
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t1;
+      return #local2 = #t1;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t2 = local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
+    return let final core::int? #t2 = #local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
   function #local4#set(core::int #t3) → dynamic
-    if(local4.==(null))
-      return local4 = #t3;
+    if(#local4.==(null))
+      return #local4 = #t3;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t4 = local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t4 = #local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t5) → dynamic
-    if(local6.==(null))
-      return local6 = #t5;
+    if(#local6.==(null))
+      return #local6 = #t5;
     else
       throw new _in::LateError::localAI("local6");
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t9) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t9;
+      return #local2 = #t9;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t10 = local4 in #t10.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t10{core::int};
+    return let final core::int? #t10 = #local4 in #t10.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t10{core::int};
   function #local4#set(core::int #t11) → dynamic
-    if(local4.==(null))
-      return local4 = #t11;
+    if(#local4.==(null))
+      return #local4 = #t11;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t12 = local6 in #t12.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t12{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t12 = #local6 in #t12.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t12{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t13) → dynamic
-    if(local6.==(null))
-      return local6 = #t13;
+    if(#local6.==(null))
+      return #local6 = #t13;
     else
       throw new _in::LateError::localAI("local6");
   if(b) {
@@ -141,97 +141,97 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field () → Null fieldCompound = () → Null {
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t17 = local4 in #t17.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t17{core::int};
+    return let final core::int? #t17 = #local4 in #t17.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t17{core::int};
   function #local4#set(core::int #t18) → dynamic
-    if(local4.==(null))
-      return local4 = #t18;
+    if(#local4.==(null))
+      return #local4 = #t18;
     else
       throw new _in::LateError::localAI("local4");
   #local4#set.call(0);
-  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
-  final self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t20) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t20;
+      return #local2 = #t20;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t21 = local4 in #t21.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t21{core::int};
+    return let final core::int? #t21 = #local4 in #t21.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t21{core::int};
   function #local4#set(core::int #t22) → dynamic
-    if(local4.==(null))
-      return local4 = #t22;
+    if(#local4.==(null))
+      return #local4 = #t22;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t23 = local6 in #t23.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t23{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t23 = #local6 in #t23.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t23{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t24) → dynamic
-    if(local6.==(null))
-      return local6 = #t24;
+    if(#local6.==(null))
+      return #local6 = #t24;
     else
       throw new _in::LateError::localAI("local6");
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
-  final self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t28) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t28;
+      return #local2 = #t28;
     }
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t29 = local4 in #t29.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t29{core::int};
+    return let final core::int? #t29 = #local4 in #t29.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t29{core::int};
   function #local4#set(core::int #t30) → dynamic
-    if(local4.==(null))
-      return local4 = #t30;
+    if(#local4.==(null))
+      return #local4 = #t30;
     else
       throw new _in::LateError::localAI("local4");
-  final FutureOr<core::int>? local6;
+  lowered final FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t31 = local6 in #t31.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t31{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t31 = #local6 in #t31.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t31{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t32) → dynamic
-    if(local6.==(null))
-      return local6 = #t32;
+    if(#local6.==(null))
+      return #local6 = #t32;
     else
       throw new _in::LateError::localAI("local6");
   if(b) {
@@ -242,28 +242,28 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodCompound() → dynamic {
-  final core::int? local4;
+  lowered final core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t36 = local4 in #t36.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t36{core::int};
+    return let final core::int? #t36 = #local4 in #t36.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t36{core::int};
   function #local4#set(core::int #t37) → dynamic
-    if(local4.==(null))
-      return local4 = #t37;
+    if(#local4.==(null))
+      return #local4 = #t37;
     else
       throw new _in::LateError::localAI("local4");
   #local4#set.call(0);
-  let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.expect
index 0b4576c..aa4b724 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.expect
@@ -2,61 +2,61 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -65,85 +65,85 @@
 import "dart:async";
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t1;
+      return #local2 = #t1;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t2) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t2;
+      return #local4 = #t2;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t3) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t3;
+      return #local6 = #t3;
     }
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t7) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t7;
+      return #local2 = #t7;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t8) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t8;
+      return #local4 = #t8;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t9) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t9;
+      return #local6 = #t9;
     }
   if(b) {
     #local2#set.call(value);
@@ -153,113 +153,113 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field () → Null fieldCompound = () → Null {
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t13) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t13;
+      return #local4 = #t13;
     }
   #local4#set.call(0);
-  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
-  final self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t15) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t15;
+      return #local2 = #t15;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t16) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t16;
+      return #local4 = #t16;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t17) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t17;
+      return #local6 = #t17;
     }
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
-  final self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t21) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t21;
+      return #local2 = #t21;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t22) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t22;
+      return #local4 = #t22;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t23) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t23;
+      return #local6 = #t23;
     }
   if(b) {
     #local2#set.call(value);
@@ -269,31 +269,31 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodCompound() → dynamic {
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t27) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t27;
+      return #local4 = #t27;
     }
   #local4#set.call(0);
-  let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.transformed.expect
index 0b4576c..aa4b724 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.weak.transformed.expect
@@ -2,61 +2,61 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
 //   local2 = value; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
 //   local6 = 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
-// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+// pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
 //   local4 += 0; // error
-//   ^^^^^^
+//   ^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -65,85 +65,85 @@
 import "dart:async";
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t1;
+      return #local2 = #t1;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t2) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t2;
+      return #local4 = #t2;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t3) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t3;
+      return #local6 = #t3;
     }
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:30:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:31:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:32:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
-  final T? local2;
-  core::bool #local2#isSet = false;
+  lowered final T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t7) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t7;
+      return #local2 = #t7;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t8) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t8;
+      return #local4 = #t8;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t9) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t9;
+      return #local6 = #t9;
     }
   if(b) {
     #local2#set.call(value);
@@ -153,113 +153,113 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:70:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:71:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:72:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 };
 static field () → Null fieldCompound = () → Null {
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t13) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t13;
+      return #local4 = #t13;
     }
   #local4#set.call(0);
-  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:88:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
-  final self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t15) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t15;
+      return #local2 = #t15;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t16) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t16;
+      return #local4 = #t16;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t17) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t17;
+      return #local6 = #t17;
     }
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:16:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:17:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:18:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
-  final self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered final self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t21) → dynamic
     if(#local2#isSet)
       throw new _in::LateError::localAI("local2");
     else {
       #local2#isSet = true;
-      return local2 = #t21;
+      return #local2 = #t21;
     }
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t22) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t22;
+      return #local4 = #t22;
     }
-  final FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered final FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t23) → dynamic
     if(#local6#isSet)
       throw new _in::LateError::localAI("local6");
     else {
       #local6#isSet = true;
-      return local6 = #t23;
+      return #local6 = #t23;
     }
   if(b) {
     #local2#set.call(value);
@@ -269,31 +269,31 @@
   #local2#set.call(value);
   #local4#set.call(0);
   #local6#set.call(0);
-  let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable 'local2' definitely assigned.
+  let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:50:3: Error: Late final variable '#local2' definitely assigned.
   local2 = value; // error
-  ^^^^^^" in #local2#set.call(value);
-  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable 'local4' definitely assigned.
+  ^^^^^^^" in #local2#set.call(value);
+  let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:51:3: Error: Late final variable '#local4' definitely assigned.
   local4 = 0; // error
-  ^^^^^^" in #local4#set.call(0);
-  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable 'local6' definitely assigned.
+  ^^^^^^^" in #local4#set.call(0);
+  let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:52:3: Error: Late final variable '#local6' definitely assigned.
   local6 = 0; // error
-  ^^^^^^" in #local6#set.call(0);
+  ^^^^^^^" in #local6#set.call(0);
 }
 static method methodCompound() → dynamic {
-  final core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered final core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t27) → dynamic
     if(#local4#isSet)
       throw new _in::LateError::localAI("local4");
     else {
       #local4#isSet = true;
-      return local4 = #t27;
+      return #local4 = #t27;
     }
   #local4#set.call(0);
-  let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable 'local4' definitely assigned.
+  let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_assigned.dart:80:3: Error: Late final variable '#local4' definitely assigned.
   local4 += 0; // error
-  ^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
+  ^^^^^^^" in #local4#set.call(#local4#get.call().{core::num::+}(0));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect
index 9fd2c07..a3ede2a 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect
@@ -98,38 +98,38 @@
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic {
     #local2#isSet = true;
-    return local2 = #t1;
+    return #local2 = #t1;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t2 = local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
+    return let final core::int? #t2 = #local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
   function #local4#set(core::int #t3) → dynamic
-    return local4 = #t3;
+    return #local4 = #t3;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t4 = local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t4 = #local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t5) → dynamic
-    return local6 = #t5;
-  T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t5;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t6) → dynamic {
     #local7#isSet = true;
-    return local7 = #t6;
+    return #local7 = #t6;
   }
   let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:34:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -153,38 +153,38 @@
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t13) → dynamic {
     #local2#isSet = true;
-    return local2 = #t13;
+    return #local2 = #t13;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t14 = local4 in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t14{core::int};
+    return let final core::int? #t14 = #local4 in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t14{core::int};
   function #local4#set(core::int #t15) → dynamic
-    return local4 = #t15;
+    return #local4 = #t15;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t16 = local6 in #t16.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t16{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t16 = #local6 in #t16.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t16{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t17) → dynamic
-    return local6 = #t17;
-  T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t17;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t18) → dynamic {
     #local7#isSet = true;
-    return local7 = #t18;
+    return #local7 = #t18;
   }
   if(b) {
     local1 = value;
@@ -211,11 +211,11 @@
 };
 static field () → Null fieldCompound = () → Null {
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t22 = local4 in #t22.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t22{core::int};
+    return let final core::int? #t22 = #local4 in #t22.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t22{core::int};
   function #local4#set(core::int #t23) → dynamic
-    return local4 = #t23;
+    return #local4 = #t23;
   local3 = (let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:111:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
   ^^^^^^" in local3).{core::num::+}(0);
@@ -225,38 +225,38 @@
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
   self::methodDirect::T% local1;
-  self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t26) → dynamic {
     #local2#isSet = true;
-    return local2 = #t26;
+    return #local2 = #t26;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t27 = local4 in #t27.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t27{core::int};
+    return let final core::int? #t27 = #local4 in #t27.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t27{core::int};
   function #local4#set(core::int #t28) → dynamic
-    return local4 = #t28;
+    return #local4 = #t28;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t29 = local6 in #t29.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t29{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t29 = #local6 in #t29.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t29{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t30) → dynamic
-    return local6 = #t30;
-  self::methodDirect::T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t30;
+  lowered self::methodDirect::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodDirect::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodDirect::T%};
+    return #local7{self::methodDirect::T%};
   }
   function #local7#set(self::methodDirect::T% #t31) → dynamic {
     #local7#isSet = true;
-    return local7 = #t31;
+    return #local7 = #t31;
   }
   let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:16:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -280,38 +280,38 @@
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
   self::methodConditional::T% local1;
-  self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t38) → dynamic {
     #local2#isSet = true;
-    return local2 = #t38;
+    return #local2 = #t38;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t39 = local4 in #t39.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t39{core::int};
+    return let final core::int? #t39 = #local4 in #t39.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t39{core::int};
   function #local4#set(core::int #t40) → dynamic
-    return local4 = #t40;
+    return #local4 = #t40;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t41 = local6 in #t41.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t41{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t41 = #local6 in #t41.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t41{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t42) → dynamic
-    return local6 = #t42;
-  self::methodConditional::T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t42;
+  lowered self::methodConditional::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodConditional::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodConditional::T%};
+    return #local7{self::methodConditional::T%};
   }
   function #local7#set(self::methodConditional::T% #t43) → dynamic {
     #local7#isSet = true;
-    return local7 = #t43;
+    return #local7 = #t43;
   }
   if(b) {
     local1 = value;
@@ -338,11 +338,11 @@
 }
 static method methodCompound() → dynamic {
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t47 = local4 in #t47.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t47{core::int};
+    return let final core::int? #t47 = #local4 in #t47.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t47{core::int};
   function #local4#set(core::int #t48) → dynamic
-    return local4 = #t48;
+    return #local4 = #t48;
   local3 = (let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:103:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
   ^^^^^^" in local3).{core::num::+}(0);
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect
index 9fd2c07..a3ede2a 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect
@@ -98,38 +98,38 @@
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic {
     #local2#isSet = true;
-    return local2 = #t1;
+    return #local2 = #t1;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t2 = local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
+    return let final core::int? #t2 = #local4 in #t2.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t2{core::int};
   function #local4#set(core::int #t3) → dynamic
-    return local4 = #t3;
+    return #local4 = #t3;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t4 = local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t4 = #local6 in #t4.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t4{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t5) → dynamic
-    return local6 = #t5;
-  T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t5;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t6) → dynamic {
     #local7#isSet = true;
-    return local7 = #t6;
+    return #local7 = #t6;
   }
   let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:34:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -153,38 +153,38 @@
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t13) → dynamic {
     #local2#isSet = true;
-    return local2 = #t13;
+    return #local2 = #t13;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t14 = local4 in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t14{core::int};
+    return let final core::int? #t14 = #local4 in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t14{core::int};
   function #local4#set(core::int #t15) → dynamic
-    return local4 = #t15;
+    return #local4 = #t15;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t16 = local6 in #t16.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t16{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t16 = #local6 in #t16.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t16{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t17) → dynamic
-    return local6 = #t17;
-  T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t17;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t18) → dynamic {
     #local7#isSet = true;
-    return local7 = #t18;
+    return #local7 = #t18;
   }
   if(b) {
     local1 = value;
@@ -211,11 +211,11 @@
 };
 static field () → Null fieldCompound = () → Null {
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t22 = local4 in #t22.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t22{core::int};
+    return let final core::int? #t22 = #local4 in #t22.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t22{core::int};
   function #local4#set(core::int #t23) → dynamic
-    return local4 = #t23;
+    return #local4 = #t23;
   local3 = (let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:111:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
   ^^^^^^" in local3).{core::num::+}(0);
@@ -225,38 +225,38 @@
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
   self::methodDirect::T% local1;
-  self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t26) → dynamic {
     #local2#isSet = true;
-    return local2 = #t26;
+    return #local2 = #t26;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t27 = local4 in #t27.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t27{core::int};
+    return let final core::int? #t27 = #local4 in #t27.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t27{core::int};
   function #local4#set(core::int #t28) → dynamic
-    return local4 = #t28;
+    return #local4 = #t28;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t29 = local6 in #t29.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t29{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t29 = #local6 in #t29.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t29{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t30) → dynamic
-    return local6 = #t30;
-  self::methodDirect::T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t30;
+  lowered self::methodDirect::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodDirect::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodDirect::T%};
+    return #local7{self::methodDirect::T%};
   }
   function #local7#set(self::methodDirect::T% #t31) → dynamic {
     #local7#isSet = true;
-    return local7 = #t31;
+    return #local7 = #t31;
   }
   let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:16:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -280,38 +280,38 @@
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
   self::methodConditional::T% local1;
-  self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t38) → dynamic {
     #local2#isSet = true;
-    return local2 = #t38;
+    return #local2 = #t38;
   }
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t39 = local4 in #t39.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t39{core::int};
+    return let final core::int? #t39 = #local4 in #t39.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t39{core::int};
   function #local4#set(core::int #t40) → dynamic
-    return local4 = #t40;
+    return #local4 = #t40;
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
+  lowered FutureOr<core::int>? #local6;
   function #local6#get() → FutureOr<core::int>
-    return let final FutureOr<core::int>? #t41 = local6 in #t41.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t41{FutureOr<core::int>};
+    return let final FutureOr<core::int>? #t41 = #local6 in #t41.==(null) ?{FutureOr<core::int>} throw new _in::LateError::localNI("local6") : #t41{FutureOr<core::int>};
   function #local6#set(FutureOr<core::int>#t42) → dynamic
-    return local6 = #t42;
-  self::methodConditional::T? local7;
-  core::bool #local7#isSet = false;
+    return #local6 = #t42;
+  lowered self::methodConditional::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodConditional::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodConditional::T%};
+    return #local7{self::methodConditional::T%};
   }
   function #local7#set(self::methodConditional::T% #t43) → dynamic {
     #local7#isSet = true;
-    return local7 = #t43;
+    return #local7 = #t43;
   }
   if(b) {
     local1 = value;
@@ -338,11 +338,11 @@
 }
 static method methodCompound() → dynamic {
   core::int local3;
-  core::int? local4;
+  lowered core::int? #local4;
   function #local4#get() → core::int
-    return let final core::int? #t47 = local4 in #t47.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t47{core::int};
+    return let final core::int? #t47 = #local4 in #t47.==(null) ?{core::int} throw new _in::LateError::localNI("local4") : #t47{core::int};
   function #local4#set(core::int #t48) → dynamic
-    return local4 = #t48;
+    return #local4 = #t48;
   local3 = (let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:103:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
   ^^^^^^" in local3).{core::num::+}(0);
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect
index be1e0a1..9372b12 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect
@@ -98,44 +98,44 @@
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic {
     #local2#isSet = true;
-    return local2 = #t1;
+    return #local2 = #t1;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t2) → dynamic {
     #local4#isSet = true;
-    return local4 = #t2;
+    return #local4 = #t2;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t3) → dynamic {
     #local6#isSet = true;
-    return local6 = #t3;
+    return #local6 = #t3;
   }
-  T? local7;
-  core::bool #local7#isSet = false;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t4) → dynamic {
     #local7#isSet = true;
-    return local7 = #t4;
+    return #local7 = #t4;
   }
   let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:34:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -159,44 +159,44 @@
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t11) → dynamic {
     #local2#isSet = true;
-    return local2 = #t11;
+    return #local2 = #t11;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t12) → dynamic {
     #local4#isSet = true;
-    return local4 = #t12;
+    return #local4 = #t12;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t13) → dynamic {
     #local6#isSet = true;
-    return local6 = #t13;
+    return #local6 = #t13;
   }
-  T? local7;
-  core::bool #local7#isSet = false;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t14) → dynamic {
     #local7#isSet = true;
-    return local7 = #t14;
+    return #local7 = #t14;
   }
   if(b) {
     local1 = value;
@@ -223,13 +223,13 @@
 };
 static field () → Null fieldCompound = () → Null {
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t18) → dynamic {
     #local4#isSet = true;
-    return local4 = #t18;
+    return #local4 = #t18;
   }
   local3 = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:111:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
@@ -240,44 +240,44 @@
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
   self::methodDirect::T% local1;
-  self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t21) → dynamic {
     #local2#isSet = true;
-    return local2 = #t21;
+    return #local2 = #t21;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t22) → dynamic {
     #local4#isSet = true;
-    return local4 = #t22;
+    return #local4 = #t22;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t23) → dynamic {
     #local6#isSet = true;
-    return local6 = #t23;
+    return #local6 = #t23;
   }
-  self::methodDirect::T? local7;
-  core::bool #local7#isSet = false;
+  lowered self::methodDirect::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodDirect::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodDirect::T%};
+    return #local7{self::methodDirect::T%};
   }
   function #local7#set(self::methodDirect::T% #t24) → dynamic {
     #local7#isSet = true;
-    return local7 = #t24;
+    return #local7 = #t24;
   }
   let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:16:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -301,44 +301,44 @@
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
   self::methodConditional::T% local1;
-  self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t31) → dynamic {
     #local2#isSet = true;
-    return local2 = #t31;
+    return #local2 = #t31;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t32) → dynamic {
     #local4#isSet = true;
-    return local4 = #t32;
+    return #local4 = #t32;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t33) → dynamic {
     #local6#isSet = true;
-    return local6 = #t33;
+    return #local6 = #t33;
   }
-  self::methodConditional::T? local7;
-  core::bool #local7#isSet = false;
+  lowered self::methodConditional::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodConditional::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodConditional::T%};
+    return #local7{self::methodConditional::T%};
   }
   function #local7#set(self::methodConditional::T% #t34) → dynamic {
     #local7#isSet = true;
-    return local7 = #t34;
+    return #local7 = #t34;
   }
   if(b) {
     local1 = value;
@@ -365,13 +365,13 @@
 }
 static method methodCompound() → dynamic {
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t38) → dynamic {
     #local4#isSet = true;
-    return local4 = #t38;
+    return #local4 = #t38;
   }
   local3 = (let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:103:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect
index be1e0a1..9372b12 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect
@@ -98,44 +98,44 @@
 
 static field <T extends core::Object? = dynamic>(T%) → Null fieldDirect = <T extends core::Object? = dynamic>(T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t1) → dynamic {
     #local2#isSet = true;
-    return local2 = #t1;
+    return #local2 = #t1;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t2) → dynamic {
     #local4#isSet = true;
-    return local4 = #t2;
+    return #local4 = #t2;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t3) → dynamic {
     #local6#isSet = true;
-    return local6 = #t3;
+    return #local6 = #t3;
   }
-  T? local7;
-  core::bool #local7#isSet = false;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t4) → dynamic {
     #local7#isSet = true;
-    return local7 = #t4;
+    return #local7 = #t4;
   }
   let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:34:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -159,44 +159,44 @@
 };
 static field <T extends core::Object? = dynamic>(core::bool, T%) → Null fieldConditional = <T extends core::Object? = dynamic>(core::bool b, T% value) → Null {
   T% local1;
-  T? local2;
-  core::bool #local2#isSet = false;
+  lowered T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → T%
-    return #local2#isSet ?{T%} local2{T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{T%} #local2{T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(T% #t11) → dynamic {
     #local2#isSet = true;
-    return local2 = #t11;
+    return #local2 = #t11;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t12) → dynamic {
     #local4#isSet = true;
-    return local4 = #t12;
+    return #local4 = #t12;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t13) → dynamic {
     #local6#isSet = true;
-    return local6 = #t13;
+    return #local6 = #t13;
   }
-  T? local7;
-  core::bool #local7#isSet = false;
+  lowered T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{T%};
+    return #local7{T%};
   }
   function #local7#set(T% #t14) → dynamic {
     #local7#isSet = true;
-    return local7 = #t14;
+    return #local7 = #t14;
   }
   if(b) {
     local1 = value;
@@ -223,13 +223,13 @@
 };
 static field () → Null fieldCompound = () → Null {
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t18) → dynamic {
     #local4#isSet = true;
-    return local4 = #t18;
+    return #local4 = #t18;
   }
   local3 = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:111:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
@@ -240,44 +240,44 @@
 };
 static method methodDirect<T extends core::Object? = dynamic>(self::methodDirect::T% value) → dynamic {
   self::methodDirect::T% local1;
-  self::methodDirect::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodDirect::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodDirect::T%
-    return #local2#isSet ?{self::methodDirect::T%} local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodDirect::T%} #local2{self::methodDirect::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodDirect::T% #t21) → dynamic {
     #local2#isSet = true;
-    return local2 = #t21;
+    return #local2 = #t21;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t22) → dynamic {
     #local4#isSet = true;
-    return local4 = #t22;
+    return #local4 = #t22;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t23) → dynamic {
     #local6#isSet = true;
-    return local6 = #t23;
+    return #local6 = #t23;
   }
-  self::methodDirect::T? local7;
-  core::bool #local7#isSet = false;
+  lowered self::methodDirect::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodDirect::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodDirect::T%};
+    return #local7{self::methodDirect::T%};
   }
   function #local7#set(self::methodDirect::T% #t24) → dynamic {
     #local7#isSet = true;
-    return local7 = #t24;
+    return #local7 = #t24;
   }
   let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:16:3: Error: Non-nullable variable 'local1' must be assigned before it can be used.
   local1; // error
@@ -301,44 +301,44 @@
 }
 static method methodConditional<T extends core::Object? = dynamic>(core::bool b, self::methodConditional::T% value) → dynamic {
   self::methodConditional::T% local1;
-  self::methodConditional::T? local2;
-  core::bool #local2#isSet = false;
+  lowered self::methodConditional::T? #local2;
+  lowered core::bool #local2#isSet = false;
   function #local2#get() → self::methodConditional::T%
-    return #local2#isSet ?{self::methodConditional::T%} local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
+    return #local2#isSet ?{self::methodConditional::T%} #local2{self::methodConditional::T%} : throw new _in::LateError::localNI("local2");
   function #local2#set(self::methodConditional::T% #t31) → dynamic {
     #local2#isSet = true;
-    return local2 = #t31;
+    return #local2 = #t31;
   }
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t32) → dynamic {
     #local4#isSet = true;
-    return local4 = #t32;
+    return #local4 = #t32;
   }
   FutureOr<core::int>local5;
-  FutureOr<core::int>? local6;
-  core::bool #local6#isSet = false;
+  lowered FutureOr<core::int>? #local6;
+  lowered core::bool #local6#isSet = false;
   function #local6#get() → FutureOr<core::int>
-    return #local6#isSet ?{FutureOr<core::int>} local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
+    return #local6#isSet ?{FutureOr<core::int>} #local6{FutureOr<core::int>} : throw new _in::LateError::localNI("local6");
   function #local6#set(FutureOr<core::int>#t33) → dynamic {
     #local6#isSet = true;
-    return local6 = #t33;
+    return #local6 = #t33;
   }
-  self::methodConditional::T? local7;
-  core::bool #local7#isSet = false;
+  lowered self::methodConditional::T? #local7;
+  lowered core::bool #local7#isSet = false;
   function #local7#get() → self::methodConditional::T% {
     if(!#local7#isSet) {
-      local7 = value;
+      #local7 = value;
       #local7#isSet = true;
     }
-    return local7{self::methodConditional::T%};
+    return #local7{self::methodConditional::T%};
   }
   function #local7#set(self::methodConditional::T% #t34) → dynamic {
     #local7#isSet = true;
-    return local7 = #t34;
+    return #local7 = #t34;
   }
   if(b) {
     local1 = value;
@@ -365,13 +365,13 @@
 }
 static method methodCompound() → dynamic {
   core::int local3;
-  core::int? local4;
-  core::bool #local4#isSet = false;
+  lowered core::int? #local4;
+  lowered core::bool #local4#isSet = false;
   function #local4#get() → core::int
-    return #local4#isSet ?{core::int} local4{core::int} : throw new _in::LateError::localNI("local4");
+    return #local4#isSet ?{core::int} #local4{core::int} : throw new _in::LateError::localNI("local4");
   function #local4#set(core::int #t38) → dynamic {
     #local4#isSet = true;
-    return local4 = #t38;
+    return #local4 = #t38;
   }
   local3 = (let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/late_lowering/definitely_unassigned.dart:103:3: Error: Non-nullable variable 'local3' must be assigned before it can be used.
   local3 += 0; // error
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.expect
index 18df179..b34786e 100644
--- a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.expect
@@ -6,10 +6,10 @@
 static method f<T extends core::Object? = dynamic>(self::f::T% t) → self::f::T%
   return t;
 static method main() → dynamic {
-  core::int? local;
+  lowered core::int? #local;
   function #local#get() → core::int
-    return let final core::int? #t1 = local in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t1{core::int};
+    return let final core::int? #t1 = #local in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t1{core::int};
   function #local#set(core::int #t2) → dynamic
-    return local = #t2;
+    return #local = #t2;
   #local#set.call(self::f<core::int>(0));
 }
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.transformed.expect
index 18df179..b34786e 100644
--- a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.strong.transformed.expect
@@ -6,10 +6,10 @@
 static method f<T extends core::Object? = dynamic>(self::f::T% t) → self::f::T%
   return t;
 static method main() → dynamic {
-  core::int? local;
+  lowered core::int? #local;
   function #local#get() → core::int
-    return let final core::int? #t1 = local in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t1{core::int};
+    return let final core::int? #t1 = #local in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t1{core::int};
   function #local#set(core::int #t2) → dynamic
-    return local = #t2;
+    return #local = #t2;
   #local#set.call(self::f<core::int>(0));
 }
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.expect
index a9eee6d..4a7ba84 100644
--- a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.expect
@@ -6,13 +6,13 @@
 static method f<T extends core::Object? = dynamic>(self::f::T% t) → self::f::T%
   return t;
 static method main() → dynamic {
-  core::int? local;
-  core::bool #local#isSet = false;
+  lowered core::int? #local;
+  lowered core::bool #local#isSet = false;
   function #local#get() → core::int
-    return #local#isSet ?{core::int} local{core::int} : throw new _in::LateError::localNI("local");
+    return #local#isSet ?{core::int} #local{core::int} : throw new _in::LateError::localNI("local");
   function #local#set(core::int #t1) → dynamic {
     #local#isSet = true;
-    return local = #t1;
+    return #local = #t1;
   }
   #local#set.call(self::f<core::int>(0));
 }
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.transformed.expect
index a9eee6d..4a7ba84 100644
--- a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.weak.transformed.expect
@@ -6,13 +6,13 @@
 static method f<T extends core::Object? = dynamic>(self::f::T% t) → self::f::T%
   return t;
 static method main() → dynamic {
-  core::int? local;
-  core::bool #local#isSet = false;
+  lowered core::int? #local;
+  lowered core::bool #local#isSet = false;
   function #local#get() → core::int
-    return #local#isSet ?{core::int} local{core::int} : throw new _in::LateError::localNI("local");
+    return #local#isSet ?{core::int} #local{core::int} : throw new _in::LateError::localNI("local");
   function #local#set(core::int #t1) → dynamic {
     #local#isSet = true;
-    return local = #t1;
+    return #local = #t1;
   }
   #local#set.call(self::f<core::int>(0));
 }
diff --git a/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.expect
index 8eb1418..b788f31 100644
--- a/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.expect
@@ -42,16 +42,16 @@
     self::_#g = #t3;
   }
 static method main() → dynamic {
-  final dynamic l;
-  core::bool #l#isSet = false;
+  lowered final dynamic #l;
+  lowered core::bool #l#isSet = false;
   function #l#get() → dynamic
-    return #l#isSet ?{dynamic} l : throw new _in::LateError::localNI("l");
+    return #l#isSet ?{dynamic} #l : throw new _in::LateError::localNI("l");
   function #l#set(dynamic #t4) → dynamic
     if(#l#isSet)
       throw new _in::LateError::localAI("l");
     else {
       #l#isSet = true;
-      return l = #t4;
+      return #l = #t4;
     }
   self::g = "Lily";
   self::C::s = "was";
diff --git a/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.transformed.expect
index 8eb1418..b788f31 100644
--- a/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40373b.dart.strong.transformed.expect
@@ -42,16 +42,16 @@
     self::_#g = #t3;
   }
 static method main() → dynamic {
-  final dynamic l;
-  core::bool #l#isSet = false;
+  lowered final dynamic #l;
+  lowered core::bool #l#isSet = false;
   function #l#get() → dynamic
-    return #l#isSet ?{dynamic} l : throw new _in::LateError::localNI("l");
+    return #l#isSet ?{dynamic} #l : throw new _in::LateError::localNI("l");
   function #l#set(dynamic #t4) → dynamic
     if(#l#isSet)
       throw new _in::LateError::localAI("l");
     else {
       #l#isSet = true;
-      return l = #t4;
+      return #l = #t4;
     }
   self::g = "Lily";
   self::C::s = "was";
diff --git a/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.expect
index 8eb1418..b788f31 100644
--- a/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.expect
@@ -42,16 +42,16 @@
     self::_#g = #t3;
   }
 static method main() → dynamic {
-  final dynamic l;
-  core::bool #l#isSet = false;
+  lowered final dynamic #l;
+  lowered core::bool #l#isSet = false;
   function #l#get() → dynamic
-    return #l#isSet ?{dynamic} l : throw new _in::LateError::localNI("l");
+    return #l#isSet ?{dynamic} #l : throw new _in::LateError::localNI("l");
   function #l#set(dynamic #t4) → dynamic
     if(#l#isSet)
       throw new _in::LateError::localAI("l");
     else {
       #l#isSet = true;
-      return l = #t4;
+      return #l = #t4;
     }
   self::g = "Lily";
   self::C::s = "was";
diff --git a/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.transformed.expect
index 8eb1418..b788f31 100644
--- a/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40373b.dart.weak.transformed.expect
@@ -42,16 +42,16 @@
     self::_#g = #t3;
   }
 static method main() → dynamic {
-  final dynamic l;
-  core::bool #l#isSet = false;
+  lowered final dynamic #l;
+  lowered core::bool #l#isSet = false;
   function #l#get() → dynamic
-    return #l#isSet ?{dynamic} l : throw new _in::LateError::localNI("l");
+    return #l#isSet ?{dynamic} #l : throw new _in::LateError::localNI("l");
   function #l#set(dynamic #t4) → dynamic
     if(#l#isSet)
       throw new _in::LateError::localAI("l");
     else {
       #l#isSet = true;
-      return l = #t4;
+      return #l = #t4;
     }
   self::g = "Lily";
   self::C::s = "was";
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.expect
index 7e000ad..6de62a5 100644
--- a/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.expect
@@ -10,13 +10,13 @@
   abstract method baz() → self::A::T%;
   method bar(generic-covariant-impl self::A::T% value) → dynamic {}
   method foo() → dynamic {
-    self::A::T? value;
-    core::bool #value#isSet = false;
+    lowered self::A::T? #value;
+    lowered core::bool #value#isSet = false;
     function #value#get() → self::A::T%
-      return #value#isSet ?{self::A::T%} value{self::A::T%} : throw new _in::LateError::localNI("value");
+      return #value#isSet ?{self::A::T%} #value{self::A::T%} : throw new _in::LateError::localNI("value");
     function #value#set(self::A::T% #t1) → dynamic {
       #value#isSet = true;
-      return value = #t1;
+      return #value = #t1;
     }
     () → dynamic result = () → dynamic => this.{self::A::bar}(#value#get.call());
     (() → Null {
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.transformed.expect
index 7e000ad..6de62a5 100644
--- a/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.strong.transformed.expect
@@ -10,13 +10,13 @@
   abstract method baz() → self::A::T%;
   method bar(generic-covariant-impl self::A::T% value) → dynamic {}
   method foo() → dynamic {
-    self::A::T? value;
-    core::bool #value#isSet = false;
+    lowered self::A::T? #value;
+    lowered core::bool #value#isSet = false;
     function #value#get() → self::A::T%
-      return #value#isSet ?{self::A::T%} value{self::A::T%} : throw new _in::LateError::localNI("value");
+      return #value#isSet ?{self::A::T%} #value{self::A::T%} : throw new _in::LateError::localNI("value");
     function #value#set(self::A::T% #t1) → dynamic {
       #value#isSet = true;
-      return value = #t1;
+      return #value = #t1;
     }
     () → dynamic result = () → dynamic => this.{self::A::bar}(#value#get.call());
     (() → Null {
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.expect
index 7e000ad..6de62a5 100644
--- a/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.expect
@@ -10,13 +10,13 @@
   abstract method baz() → self::A::T%;
   method bar(generic-covariant-impl self::A::T% value) → dynamic {}
   method foo() → dynamic {
-    self::A::T? value;
-    core::bool #value#isSet = false;
+    lowered self::A::T? #value;
+    lowered core::bool #value#isSet = false;
     function #value#get() → self::A::T%
-      return #value#isSet ?{self::A::T%} value{self::A::T%} : throw new _in::LateError::localNI("value");
+      return #value#isSet ?{self::A::T%} #value{self::A::T%} : throw new _in::LateError::localNI("value");
     function #value#set(self::A::T% #t1) → dynamic {
       #value#isSet = true;
-      return value = #t1;
+      return #value = #t1;
     }
     () → dynamic result = () → dynamic => this.{self::A::bar}(#value#get.call());
     (() → Null {
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.transformed.expect
index 7e000ad..6de62a5 100644
--- a/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.weak.transformed.expect
@@ -10,13 +10,13 @@
   abstract method baz() → self::A::T%;
   method bar(generic-covariant-impl self::A::T% value) → dynamic {}
   method foo() → dynamic {
-    self::A::T? value;
-    core::bool #value#isSet = false;
+    lowered self::A::T? #value;
+    lowered core::bool #value#isSet = false;
     function #value#get() → self::A::T%
-      return #value#isSet ?{self::A::T%} value{self::A::T%} : throw new _in::LateError::localNI("value");
+      return #value#isSet ?{self::A::T%} #value{self::A::T%} : throw new _in::LateError::localNI("value");
     function #value#set(self::A::T% #t1) → dynamic {
       #value#isSet = true;
-      return value = #t1;
+      return #value = #t1;
     }
     () → dynamic result = () → dynamic => this.{self::A::bar}(#value#get.call());
     (() → Null {
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart b/pkg/front_end/testcases/late_lowering/issue44372.dart
new file mode 100644
index 0000000..2550604
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main(List<String> args) {
+  late int Function() recursiveInitLocal;
+  late final int local = recursiveInitLocal();
+
+  bool doRecursiveInitLocal = true;
+  recursiveInitLocal = () {
+    print('Executing initializer');
+    if (doRecursiveInitLocal) {
+      doRecursiveInitLocal = false;
+      print('Trigger recursive initialization');
+      int val = local;
+      print('Final local has value $val');
+      print('Returning 4 from initializer');
+      return 4;
+    }
+    print('Returning 3 from initializer');
+    return 3;
+  };
+
+  throws(() {
+    int val = local;
+    print('Final local has value $val');
+  }, "Read local");
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(f(), String message) {
+  dynamic value;
+  try {
+    value = f();
+  } on LateInitializationError catch (e) {
+    print(e);
+    return;
+  }
+  throw '$message: $value';
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.outline.expect
new file mode 100644
index 0000000..cd8b66b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.outline.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main(core::List<core::String> args) → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+static method throws(() → dynamic f, core::String message) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.expect
new file mode 100644
index 0000000..2e8255b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+  lowered () →? core::int #recursiveInitLocal;
+  function #recursiveInitLocal#get() → () → core::int
+    return let final () →? core::int #t1 = #recursiveInitLocal in #t1.==(null) ?{() → core::int} throw new _in::LateError::localNI("recursiveInitLocal") : #t1{() → core::int};
+  function #recursiveInitLocal#set(() → core::int #t2) → dynamic
+    return #recursiveInitLocal = #t2;
+  lowered final core::int? #local;
+  function #local#get() → core::int
+    return let final core::int? #t3 = #local in #t3.==(null) ?{core::int} let final core::int #t4 = #recursiveInitLocal#get.call().call() in #local.==(null) ?{core::int} #local = #t4 : throw new _in::LateError::localADI("local") : #t3{core::int};
+  core::bool doRecursiveInitLocal = true;
+  #recursiveInitLocal#set.call(() → core::int {
+    core::print("Executing initializer");
+    if(doRecursiveInitLocal) {
+      doRecursiveInitLocal = false;
+      core::print("Trigger recursive initialization");
+      core::int val = #local#get.call();
+      core::print("Final local has value ${val}");
+      core::print("Returning 4 from initializer");
+      return 4;
+    }
+    core::print("Returning 3 from initializer");
+    return 3;
+  });
+  self::throws(() → Null {
+    core::int val = #local#get.call();
+    core::print("Final local has value ${val}");
+  }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+  dynamic value;
+  try {
+    value = f.call();
+  }
+  on core::LateInitializationError catch(final core::LateInitializationError e) {
+    core::print(e);
+    return;
+  }
+  throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.transformed.expect
new file mode 100644
index 0000000..2e8255b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+  lowered () →? core::int #recursiveInitLocal;
+  function #recursiveInitLocal#get() → () → core::int
+    return let final () →? core::int #t1 = #recursiveInitLocal in #t1.==(null) ?{() → core::int} throw new _in::LateError::localNI("recursiveInitLocal") : #t1{() → core::int};
+  function #recursiveInitLocal#set(() → core::int #t2) → dynamic
+    return #recursiveInitLocal = #t2;
+  lowered final core::int? #local;
+  function #local#get() → core::int
+    return let final core::int? #t3 = #local in #t3.==(null) ?{core::int} let final core::int #t4 = #recursiveInitLocal#get.call().call() in #local.==(null) ?{core::int} #local = #t4 : throw new _in::LateError::localADI("local") : #t3{core::int};
+  core::bool doRecursiveInitLocal = true;
+  #recursiveInitLocal#set.call(() → core::int {
+    core::print("Executing initializer");
+    if(doRecursiveInitLocal) {
+      doRecursiveInitLocal = false;
+      core::print("Trigger recursive initialization");
+      core::int val = #local#get.call();
+      core::print("Final local has value ${val}");
+      core::print("Returning 4 from initializer");
+      return 4;
+    }
+    core::print("Returning 3 from initializer");
+    return 3;
+  });
+  self::throws(() → Null {
+    core::int val = #local#get.call();
+    core::print("Final local has value ${val}");
+  }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+  dynamic value;
+  try {
+    value = f.call();
+  }
+  on core::LateInitializationError catch(final core::LateInitializationError e) {
+    core::print(e);
+    return;
+  }
+  throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline.expect
new file mode 100644
index 0000000..59d6aea
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main(List<String> args) {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52b9bda
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main(List<String> args) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.expect
new file mode 100644
index 0000000..16f8718
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.expect
@@ -0,0 +1,60 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+  lowered () →? core::int #recursiveInitLocal;
+  lowered core::bool #recursiveInitLocal#isSet = false;
+  function #recursiveInitLocal#get() → () → core::int
+    return #recursiveInitLocal#isSet ?{() → core::int} #recursiveInitLocal{() → core::int} : throw new _in::LateError::localNI("recursiveInitLocal");
+  function #recursiveInitLocal#set(() → core::int #t1) → dynamic {
+    #recursiveInitLocal#isSet = true;
+    return #recursiveInitLocal = #t1;
+  }
+  lowered final core::int? #local;
+  lowered core::bool #local#isSet = false;
+  function #local#get() → core::int {
+    if(!#local#isSet) {
+      final core::int #t2 = #recursiveInitLocal#get.call().call();
+      if(#local#isSet)
+        throw new _in::LateError::localADI("local");
+      #local = #t2;
+      #local#isSet = true;
+    }
+    return #local{core::int};
+  }
+  core::bool doRecursiveInitLocal = true;
+  #recursiveInitLocal#set.call(() → core::int {
+    core::print("Executing initializer");
+    if(doRecursiveInitLocal) {
+      doRecursiveInitLocal = false;
+      core::print("Trigger recursive initialization");
+      core::int val = #local#get.call();
+      core::print("Final local has value ${val}");
+      core::print("Returning 4 from initializer");
+      return 4;
+    }
+    core::print("Returning 3 from initializer");
+    return 3;
+  });
+  self::throws(() → Null {
+    core::int val = #local#get.call();
+    core::print("Final local has value ${val}");
+  }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+  dynamic value;
+  try {
+    value = f.call();
+  }
+  on core::LateInitializationError catch(final core::LateInitializationError e) {
+    core::print(e);
+    return;
+  }
+  throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.transformed.expect
new file mode 100644
index 0000000..16f8718
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.transformed.expect
@@ -0,0 +1,60 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+  lowered () →? core::int #recursiveInitLocal;
+  lowered core::bool #recursiveInitLocal#isSet = false;
+  function #recursiveInitLocal#get() → () → core::int
+    return #recursiveInitLocal#isSet ?{() → core::int} #recursiveInitLocal{() → core::int} : throw new _in::LateError::localNI("recursiveInitLocal");
+  function #recursiveInitLocal#set(() → core::int #t1) → dynamic {
+    #recursiveInitLocal#isSet = true;
+    return #recursiveInitLocal = #t1;
+  }
+  lowered final core::int? #local;
+  lowered core::bool #local#isSet = false;
+  function #local#get() → core::int {
+    if(!#local#isSet) {
+      final core::int #t2 = #recursiveInitLocal#get.call().call();
+      if(#local#isSet)
+        throw new _in::LateError::localADI("local");
+      #local = #t2;
+      #local#isSet = true;
+    }
+    return #local{core::int};
+  }
+  core::bool doRecursiveInitLocal = true;
+  #recursiveInitLocal#set.call(() → core::int {
+    core::print("Executing initializer");
+    if(doRecursiveInitLocal) {
+      doRecursiveInitLocal = false;
+      core::print("Trigger recursive initialization");
+      core::int val = #local#get.call();
+      core::print("Final local has value ${val}");
+      core::print("Returning 4 from initializer");
+      return 4;
+    }
+    core::print("Returning 3 from initializer");
+    return 3;
+  });
+  self::throws(() → Null {
+    core::int val = #local#get.call();
+    core::print("Final local has value ${val}");
+  }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+  dynamic value;
+  try {
+    value = f.call();
+  }
+  on core::LateInitializationError catch(final core::LateInitializationError e) {
+    core::print(e);
+    return;
+  }
+  throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
index 8a5dd62..b219a6f 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
@@ -1,15 +1,16 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int value) → core::int {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
+  lowered final core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} lateLocal = initLateLocal.call(123) : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} let final core::int #t2 = initLateLocal.call(123) in #lateLocal.==(null) ?{core::int} #lateLocal = #t2 : throw new _in::LateError::localADI("lateLocal") : #t1{core::int};
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
   self::expect(123, lateLocalInit);
@@ -18,14 +19,17 @@
     function initLateGenericLocal(T% value) → T% {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T% #t3 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t3;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
index 8a5dd62..b219a6f 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
@@ -1,15 +1,16 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int value) → core::int {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
+  lowered final core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} lateLocal = initLateLocal.call(123) : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} let final core::int #t2 = initLateLocal.call(123) in #lateLocal.==(null) ?{core::int} #lateLocal = #t2 : throw new _in::LateError::localADI("lateLocal") : #t1{core::int};
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
   self::expect(123, lateLocalInit);
@@ -18,14 +19,17 @@
     function initLateGenericLocal(T% value) → T% {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T% #t3 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t3;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
index 76adb10..fd2146f 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
@@ -1,20 +1,24 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int value) → core::int {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int {
     if(!#lateLocal#isSet) {
-      lateLocal = initLateLocal.call(123);
+      final core::int #t1 = initLateLocal.call(123);
+      if(#lateLocal#isSet)
+        throw new _in::LateError::localADI("lateLocal");
+      #lateLocal = #t1;
       #lateLocal#isSet = true;
     }
-    return lateLocal{core::int};
+    return #lateLocal{core::int};
   }
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
@@ -24,14 +28,17 @@
     function initLateGenericLocal(T% value) → T% {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T% #t2 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t2;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
index 76adb10..fd2146f 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
@@ -1,20 +1,24 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int value) → core::int {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int {
     if(!#lateLocal#isSet) {
-      lateLocal = initLateLocal.call(123);
+      final core::int #t1 = initLateLocal.call(123);
+      if(#lateLocal#isSet)
+        throw new _in::LateError::localADI("lateLocal");
+      #lateLocal = #t1;
       #lateLocal#isSet = true;
     }
-    return lateLocal{core::int};
+    return #lateLocal{core::int};
   }
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
@@ -24,14 +28,17 @@
     function initLateGenericLocal(T% value) → T% {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T% #t2 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t2;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect
index 5052aa475..2240a48 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect
@@ -5,12 +5,12 @@
 
 static method main() → dynamic {
   core::bool b = false;
-  final core::int? lateLocal;
+  lowered final core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
-    if(lateLocal.==(null))
-      return lateLocal = #t2;
+    if(#lateLocal.==(null))
+      return #lateLocal = #t2;
     else
       throw new _in::LateError::localAI("lateLocal");
   if(b) {
@@ -23,16 +23,16 @@
   }
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t3) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t3;
+        return #lateGenericLocal = #t3;
       }
     if(b) {
       #lateGenericLocal#set.call(value);
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect
index 5052aa475..2240a48 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect
@@ -5,12 +5,12 @@
 
 static method main() → dynamic {
   core::bool b = false;
-  final core::int? lateLocal;
+  lowered final core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
-    if(lateLocal.==(null))
-      return lateLocal = #t2;
+    if(#lateLocal.==(null))
+      return #lateLocal = #t2;
     else
       throw new _in::LateError::localAI("lateLocal");
   if(b) {
@@ -23,16 +23,16 @@
   }
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t3) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t3;
+        return #lateGenericLocal = #t3;
       }
     if(b) {
       #lateGenericLocal#set.call(value);
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect
index 4a3c1ef..8f08ee7 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect
@@ -5,16 +5,16 @@
 
 static method main() → dynamic {
   core::bool b = false;
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int
-    return #lateLocal#isSet ?{core::int} lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int} #lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int #t1) → dynamic
     if(#lateLocal#isSet)
       throw new _in::LateError::localAI("lateLocal");
     else {
       #lateLocal#isSet = true;
-      return lateLocal = #t1;
+      return #lateLocal = #t1;
     }
   if(b) {
     #lateLocal#set.call(123);
@@ -26,16 +26,16 @@
   }
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t2) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t2;
+        return #lateGenericLocal = #t2;
       }
     if(b) {
       #lateGenericLocal#set.call(value);
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect
index 4a3c1ef..8f08ee7 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect
@@ -5,16 +5,16 @@
 
 static method main() → dynamic {
   core::bool b = false;
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int
-    return #lateLocal#isSet ?{core::int} lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int} #lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int #t1) → dynamic
     if(#lateLocal#isSet)
       throw new _in::LateError::localAI("lateLocal");
     else {
       #lateLocal#isSet = true;
-      return lateLocal = #t1;
+      return #lateLocal = #t1;
     }
   if(b) {
     #lateLocal#set.call(123);
@@ -26,16 +26,16 @@
   }
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t2) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t2;
+        return #lateGenericLocal = #t2;
       }
     if(b) {
       #lateGenericLocal#set.call(value);
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
index ffb22f1..d2e95b9 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
@@ -1,20 +1,24 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int? value) → core::int? {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = initLateLocal.call(123);
+      final core::int? #t1 = initLateLocal.call(123);
+      if(#lateLocal#isSet)
+        throw new _in::LateError::localADI("lateLocal");
+      #lateLocal = #t1;
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
@@ -24,14 +28,17 @@
     function initLateGenericLocal(T? value) → T? {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T? #t2 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t2;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
index ffb22f1..d2e95b9 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
@@ -1,20 +1,24 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int? value) → core::int? {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = initLateLocal.call(123);
+      final core::int? #t1 = initLateLocal.call(123);
+      if(#lateLocal#isSet)
+        throw new _in::LateError::localADI("lateLocal");
+      #lateLocal = #t1;
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
@@ -24,14 +28,17 @@
     function initLateGenericLocal(T? value) → T? {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T? #t2 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t2;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
index ffb22f1..d2e95b9 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
@@ -1,20 +1,24 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int? value) → core::int? {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = initLateLocal.call(123);
+      final core::int? #t1 = initLateLocal.call(123);
+      if(#lateLocal#isSet)
+        throw new _in::LateError::localADI("lateLocal");
+      #lateLocal = #t1;
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
@@ -24,14 +28,17 @@
     function initLateGenericLocal(T? value) → T? {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T? #t2 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t2;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
index ffb22f1..d2e95b9 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
@@ -1,20 +1,24 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic {
   core::int? lateLocalInit;
   function initLateLocal(core::int? value) → core::int? {
     return lateLocalInit = value;
   }
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = initLateLocal.call(123);
+      final core::int? #t1 = initLateLocal.call(123);
+      if(#lateLocal#isSet)
+        throw new _in::LateError::localADI("lateLocal");
+      #lateLocal = #t1;
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   self::expect(null, lateLocalInit);
   self::expect(123, #lateLocal#get.call());
@@ -24,14 +28,17 @@
     function initLateGenericLocal(T? value) → T? {
       return lateGenericLocalInit = value;
     }
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = initLateGenericLocal.call(value);
+        final T? #t2 = initLateGenericLocal.call(value);
+        if(#lateGenericLocal#isSet)
+          throw new _in::LateError::localADI("lateGenericLocal");
+        #lateGenericLocal = #t2;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     self::expect(null, lateGenericLocalInit);
     self::expect(value, #lateGenericLocal#get.call());
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.expect
index 37fa15a..5d5693d 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.expect
@@ -4,16 +4,16 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic
     if(#lateLocal#isSet)
       throw new _in::LateError::localAI("lateLocal");
     else {
       #lateLocal#isSet = true;
-      return lateLocal = #t1;
+      return #lateLocal = #t1;
     }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   if(1.{core::num::==}(1)) {
@@ -22,16 +22,16 @@
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t2;
+        return #lateGenericLocal = #t2;
       }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     if(1.{core::num::==}(1)) {
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.transformed.expect
index 3dfd218..15d60ff 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.strong.transformed.expect
@@ -4,16 +4,16 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic
     if(#lateLocal#isSet)
       throw new _in::LateError::localAI("lateLocal");
     else {
       #lateLocal#isSet = true;
-      return lateLocal = #t1;
+      return #lateLocal = #t1;
     }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   if(1.{core::num::==}(1)) {
@@ -22,16 +22,16 @@
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t2;
+        return #lateGenericLocal = #t2;
       }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     if(1.{core::num::==}(1)) {
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.expect
index 37fa15a..5d5693d 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.expect
@@ -4,16 +4,16 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic
     if(#lateLocal#isSet)
       throw new _in::LateError::localAI("lateLocal");
     else {
       #lateLocal#isSet = true;
-      return lateLocal = #t1;
+      return #lateLocal = #t1;
     }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   if(1.{core::num::==}(1)) {
@@ -22,16 +22,16 @@
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t2;
+        return #lateGenericLocal = #t2;
       }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     if(1.{core::num::==}(1)) {
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.transformed.expect
index 3dfd218..15d60ff 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.weak.transformed.expect
@@ -4,16 +4,16 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  final core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered final core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic
     if(#lateLocal#isSet)
       throw new _in::LateError::localAI("lateLocal");
     else {
       #lateLocal#isSet = true;
-      return lateLocal = #t1;
+      return #lateLocal = #t1;
     }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   if(1.{core::num::==}(1)) {
@@ -22,16 +22,16 @@
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    final T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered final T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic
       if(#lateGenericLocal#isSet)
         throw new _in::LateError::localAI("lateGenericLocal");
       else {
         #lateGenericLocal#isSet = true;
-        return lateGenericLocal = #t2;
+        return #lateGenericLocal = #t2;
       }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     if(1.{core::num::==}(1)) {
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect
index f28f0a7..2a49ff2 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect
@@ -50,45 +50,45 @@
     this.{self::C::_#C#field5} = #t6;
   }
   method method() → dynamic {
-    FutureOr<dynamic>? local1;
-    core::bool #local1#isSet = false;
+    lowered FutureOr<dynamic>? #local1;
+    lowered core::bool #local1#isSet = false;
     function #local1#get() → FutureOr<dynamic>
-      return #local1#isSet ?{FutureOr<dynamic>} local1 : throw new _in::LateError::localNI("local1");
+      return #local1#isSet ?{FutureOr<dynamic>} #local1 : throw new _in::LateError::localNI("local1");
     function #local1#set(FutureOr<dynamic>#t7) → dynamic {
       #local1#isSet = true;
-      return local1 = #t7;
+      return #local1 = #t7;
     }
-    FutureOr<dynamic>? local2;
-    core::bool #local2#isSet = false;
+    lowered FutureOr<dynamic>? #local2;
+    lowered core::bool #local2#isSet = false;
     function #local2#get() → FutureOr<dynamic>?
-      return #local2#isSet ?{FutureOr<dynamic>?} local2 : throw new _in::LateError::localNI("local2");
+      return #local2#isSet ?{FutureOr<dynamic>?} #local2 : throw new _in::LateError::localNI("local2");
     function #local2#set(FutureOr<dynamic>? #t8) → dynamic {
       #local2#isSet = true;
-      return local2 = #t8;
+      return #local2 = #t8;
     }
-    FutureOr<self::C::T%>? local3;
-    core::bool #local3#isSet = false;
+    lowered FutureOr<self::C::T%>? #local3;
+    lowered core::bool #local3#isSet = false;
     function #local3#get() → FutureOr<self::C::T%>
-      return #local3#isSet ?{FutureOr<self::C::T%>} local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
+      return #local3#isSet ?{FutureOr<self::C::T%>} #local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
     function #local3#set(FutureOr<self::C::T%>#t9) → dynamic {
       #local3#isSet = true;
-      return local3 = #t9;
+      return #local3 = #t9;
     }
-    FutureOr<self::C::T?>? local4;
-    core::bool #local4#isSet = false;
+    lowered FutureOr<self::C::T?>? #local4;
+    lowered core::bool #local4#isSet = false;
     function #local4#get() → FutureOr<self::C::T?>
-      return #local4#isSet ?{FutureOr<self::C::T?>} local4 : throw new _in::LateError::localNI("local4");
+      return #local4#isSet ?{FutureOr<self::C::T?>} #local4 : throw new _in::LateError::localNI("local4");
     function #local4#set(FutureOr<self::C::T?>#t10) → dynamic {
       #local4#isSet = true;
-      return local4 = #t10;
+      return #local4 = #t10;
     }
-    FutureOr<self::C::T?>? local5;
-    core::bool #local5#isSet = false;
+    lowered FutureOr<self::C::T?>? #local5;
+    lowered core::bool #local5#isSet = false;
     function #local5#get() → FutureOr<self::C::T?>?
-      return #local5#isSet ?{FutureOr<self::C::T?>?} local5 : throw new _in::LateError::localNI("local5");
+      return #local5#isSet ?{FutureOr<self::C::T?>?} #local5 : throw new _in::LateError::localNI("local5");
     function #local5#set(FutureOr<self::C::T?>? #t11) → dynamic {
       #local5#isSet = true;
-      return local5 = #t11;
+      return #local5 = #t11;
     }
   }
 }
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect
index f28f0a7..2a49ff2 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect
@@ -50,45 +50,45 @@
     this.{self::C::_#C#field5} = #t6;
   }
   method method() → dynamic {
-    FutureOr<dynamic>? local1;
-    core::bool #local1#isSet = false;
+    lowered FutureOr<dynamic>? #local1;
+    lowered core::bool #local1#isSet = false;
     function #local1#get() → FutureOr<dynamic>
-      return #local1#isSet ?{FutureOr<dynamic>} local1 : throw new _in::LateError::localNI("local1");
+      return #local1#isSet ?{FutureOr<dynamic>} #local1 : throw new _in::LateError::localNI("local1");
     function #local1#set(FutureOr<dynamic>#t7) → dynamic {
       #local1#isSet = true;
-      return local1 = #t7;
+      return #local1 = #t7;
     }
-    FutureOr<dynamic>? local2;
-    core::bool #local2#isSet = false;
+    lowered FutureOr<dynamic>? #local2;
+    lowered core::bool #local2#isSet = false;
     function #local2#get() → FutureOr<dynamic>?
-      return #local2#isSet ?{FutureOr<dynamic>?} local2 : throw new _in::LateError::localNI("local2");
+      return #local2#isSet ?{FutureOr<dynamic>?} #local2 : throw new _in::LateError::localNI("local2");
     function #local2#set(FutureOr<dynamic>? #t8) → dynamic {
       #local2#isSet = true;
-      return local2 = #t8;
+      return #local2 = #t8;
     }
-    FutureOr<self::C::T%>? local3;
-    core::bool #local3#isSet = false;
+    lowered FutureOr<self::C::T%>? #local3;
+    lowered core::bool #local3#isSet = false;
     function #local3#get() → FutureOr<self::C::T%>
-      return #local3#isSet ?{FutureOr<self::C::T%>} local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
+      return #local3#isSet ?{FutureOr<self::C::T%>} #local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
     function #local3#set(FutureOr<self::C::T%>#t9) → dynamic {
       #local3#isSet = true;
-      return local3 = #t9;
+      return #local3 = #t9;
     }
-    FutureOr<self::C::T?>? local4;
-    core::bool #local4#isSet = false;
+    lowered FutureOr<self::C::T?>? #local4;
+    lowered core::bool #local4#isSet = false;
     function #local4#get() → FutureOr<self::C::T?>
-      return #local4#isSet ?{FutureOr<self::C::T?>} local4 : throw new _in::LateError::localNI("local4");
+      return #local4#isSet ?{FutureOr<self::C::T?>} #local4 : throw new _in::LateError::localNI("local4");
     function #local4#set(FutureOr<self::C::T?>#t10) → dynamic {
       #local4#isSet = true;
-      return local4 = #t10;
+      return #local4 = #t10;
     }
-    FutureOr<self::C::T?>? local5;
-    core::bool #local5#isSet = false;
+    lowered FutureOr<self::C::T?>? #local5;
+    lowered core::bool #local5#isSet = false;
     function #local5#get() → FutureOr<self::C::T?>?
-      return #local5#isSet ?{FutureOr<self::C::T?>?} local5 : throw new _in::LateError::localNI("local5");
+      return #local5#isSet ?{FutureOr<self::C::T?>?} #local5 : throw new _in::LateError::localNI("local5");
     function #local5#set(FutureOr<self::C::T?>? #t11) → dynamic {
       #local5#isSet = true;
-      return local5 = #t11;
+      return #local5 = #t11;
     }
   }
 }
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect
index 78cd9c9..0ac8dba 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect
@@ -50,45 +50,45 @@
     this.{self::C::_#C#field5} = #t6;
   }
   method method() → dynamic {
-    FutureOr<dynamic>? local1;
-    core::bool #local1#isSet = false;
+    lowered FutureOr<dynamic>? #local1;
+    lowered core::bool #local1#isSet = false;
     function #local1#get() → FutureOr<dynamic>
-      return #local1#isSet ?{FutureOr<dynamic>} local1 : throw new _in::LateError::localNI("local1");
+      return #local1#isSet ?{FutureOr<dynamic>} #local1 : throw new _in::LateError::localNI("local1");
     function #local1#set(FutureOr<dynamic>#t7) → dynamic {
       #local1#isSet = true;
-      return local1 = #t7;
+      return #local1 = #t7;
     }
-    FutureOr<dynamic>? local2;
-    core::bool #local2#isSet = false;
+    lowered FutureOr<dynamic>? #local2;
+    lowered core::bool #local2#isSet = false;
     function #local2#get() → FutureOr<dynamic>?
-      return #local2#isSet ?{FutureOr<dynamic>?} local2 : throw new _in::LateError::localNI("local2");
+      return #local2#isSet ?{FutureOr<dynamic>?} #local2 : throw new _in::LateError::localNI("local2");
     function #local2#set(FutureOr<dynamic>? #t8) → dynamic {
       #local2#isSet = true;
-      return local2 = #t8;
+      return #local2 = #t8;
     }
-    FutureOr<self::C::T%>? local3;
-    core::bool #local3#isSet = false;
+    lowered FutureOr<self::C::T%>? #local3;
+    lowered core::bool #local3#isSet = false;
     function #local3#get() → FutureOr<self::C::T%>
-      return #local3#isSet ?{FutureOr<self::C::T%>} local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
+      return #local3#isSet ?{FutureOr<self::C::T%>} #local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
     function #local3#set(FutureOr<self::C::T%>#t9) → dynamic {
       #local3#isSet = true;
-      return local3 = #t9;
+      return #local3 = #t9;
     }
-    FutureOr<self::C::T?>? local4;
-    core::bool #local4#isSet = false;
+    lowered FutureOr<self::C::T?>? #local4;
+    lowered core::bool #local4#isSet = false;
     function #local4#get() → FutureOr<self::C::T?>
-      return #local4#isSet ?{FutureOr<self::C::T?>} local4 : throw new _in::LateError::localNI("local4");
+      return #local4#isSet ?{FutureOr<self::C::T?>} #local4 : throw new _in::LateError::localNI("local4");
     function #local4#set(FutureOr<self::C::T?>#t10) → dynamic {
       #local4#isSet = true;
-      return local4 = #t10;
+      return #local4 = #t10;
     }
-    FutureOr<self::C::T?>? local5;
-    core::bool #local5#isSet = false;
+    lowered FutureOr<self::C::T?>? #local5;
+    lowered core::bool #local5#isSet = false;
     function #local5#get() → FutureOr<self::C::T?>?
-      return #local5#isSet ?{FutureOr<self::C::T?>?} local5 : throw new _in::LateError::localNI("local5");
+      return #local5#isSet ?{FutureOr<self::C::T?>?} #local5 : throw new _in::LateError::localNI("local5");
     function #local5#set(FutureOr<self::C::T?>? #t11) → dynamic {
       #local5#isSet = true;
-      return local5 = #t11;
+      return #local5 = #t11;
     }
   }
 }
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect
index 78cd9c9..0ac8dba 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect
@@ -50,45 +50,45 @@
     this.{self::C::_#C#field5} = #t6;
   }
   method method() → dynamic {
-    FutureOr<dynamic>? local1;
-    core::bool #local1#isSet = false;
+    lowered FutureOr<dynamic>? #local1;
+    lowered core::bool #local1#isSet = false;
     function #local1#get() → FutureOr<dynamic>
-      return #local1#isSet ?{FutureOr<dynamic>} local1 : throw new _in::LateError::localNI("local1");
+      return #local1#isSet ?{FutureOr<dynamic>} #local1 : throw new _in::LateError::localNI("local1");
     function #local1#set(FutureOr<dynamic>#t7) → dynamic {
       #local1#isSet = true;
-      return local1 = #t7;
+      return #local1 = #t7;
     }
-    FutureOr<dynamic>? local2;
-    core::bool #local2#isSet = false;
+    lowered FutureOr<dynamic>? #local2;
+    lowered core::bool #local2#isSet = false;
     function #local2#get() → FutureOr<dynamic>?
-      return #local2#isSet ?{FutureOr<dynamic>?} local2 : throw new _in::LateError::localNI("local2");
+      return #local2#isSet ?{FutureOr<dynamic>?} #local2 : throw new _in::LateError::localNI("local2");
     function #local2#set(FutureOr<dynamic>? #t8) → dynamic {
       #local2#isSet = true;
-      return local2 = #t8;
+      return #local2 = #t8;
     }
-    FutureOr<self::C::T%>? local3;
-    core::bool #local3#isSet = false;
+    lowered FutureOr<self::C::T%>? #local3;
+    lowered core::bool #local3#isSet = false;
     function #local3#get() → FutureOr<self::C::T%>
-      return #local3#isSet ?{FutureOr<self::C::T%>} local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
+      return #local3#isSet ?{FutureOr<self::C::T%>} #local3{FutureOr<self::C::T%>} : throw new _in::LateError::localNI("local3");
     function #local3#set(FutureOr<self::C::T%>#t9) → dynamic {
       #local3#isSet = true;
-      return local3 = #t9;
+      return #local3 = #t9;
     }
-    FutureOr<self::C::T?>? local4;
-    core::bool #local4#isSet = false;
+    lowered FutureOr<self::C::T?>? #local4;
+    lowered core::bool #local4#isSet = false;
     function #local4#get() → FutureOr<self::C::T?>
-      return #local4#isSet ?{FutureOr<self::C::T?>} local4 : throw new _in::LateError::localNI("local4");
+      return #local4#isSet ?{FutureOr<self::C::T?>} #local4 : throw new _in::LateError::localNI("local4");
     function #local4#set(FutureOr<self::C::T?>#t10) → dynamic {
       #local4#isSet = true;
-      return local4 = #t10;
+      return #local4 = #t10;
     }
-    FutureOr<self::C::T?>? local5;
-    core::bool #local5#isSet = false;
+    lowered FutureOr<self::C::T?>? #local5;
+    lowered core::bool #local5#isSet = false;
     function #local5#get() → FutureOr<self::C::T?>?
-      return #local5#isSet ?{FutureOr<self::C::T?>?} local5 : throw new _in::LateError::localNI("local5");
+      return #local5#isSet ?{FutureOr<self::C::T?>?} #local5 : throw new _in::LateError::localNI("local5");
     function #local5#set(FutureOr<self::C::T?>? #t11) → dynamic {
       #local5#isSet = true;
-      return local5 = #t11;
+      return #local5 = #t11;
     }
   }
 }
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect
index d08871e..77cb4ba 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect
@@ -3,27 +3,27 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  core::int? lateLocal;
+  lowered core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} lateLocal = 123 : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} #lateLocal = 123 : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
-    return lateLocal = #t2;
+    return #lateLocal = #t2;
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value1, T% value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     function #lateGenericLocal#set(T% #t3) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t3;
+      return #lateGenericLocal = #t3;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect
index d08871e..77cb4ba 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect
@@ -3,27 +3,27 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  core::int? lateLocal;
+  lowered core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} lateLocal = 123 : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} #lateLocal = 123 : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
-    return lateLocal = #t2;
+    return #lateLocal = #t2;
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value1, T% value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     function #lateGenericLocal#set(T% #t3) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t3;
+      return #lateGenericLocal = #t3;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect
index c681474..8942212 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect
@@ -3,35 +3,35 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int {
     if(!#lateLocal#isSet) {
-      lateLocal = 123;
+      #lateLocal = 123;
       #lateLocal#isSet = true;
     }
-    return lateLocal{core::int};
+    return #lateLocal{core::int};
   }
   function #lateLocal#set(core::int #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value1, T% value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     function #lateGenericLocal#set(T% #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect
index c681474..8942212 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect
@@ -3,35 +3,35 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int {
     if(!#lateLocal#isSet) {
-      lateLocal = 123;
+      #lateLocal = 123;
       #lateLocal#isSet = true;
     }
-    return lateLocal{core::int};
+    return #lateLocal{core::int};
   }
   function #lateLocal#set(core::int #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value1, T% value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T% {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal{T%};
+      return #lateGenericLocal{T%};
     }
     function #lateGenericLocal#set(T% #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect
index 0f888e9..a8ded51 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect
@@ -4,22 +4,22 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
+  lowered core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
-    return lateLocal = #t2;
+    return #lateLocal = #t2;
   self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t3) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t3;
+      return #lateGenericLocal = #t3;
     }
     self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect
index 0f888e9..a8ded51 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect
@@ -4,22 +4,22 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
+  lowered core::int? #lateLocal;
   function #lateLocal#get() → core::int
-    return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
+    return let final core::int? #t1 = #lateLocal in #t1.==(null) ?{core::int} throw new _in::LateError::localNI("lateLocal") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
-    return lateLocal = #t2;
+    return #lateLocal = #t2;
   self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t3) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t3;
+      return #lateGenericLocal = #t3;
     }
     self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect
index 49dc955..44d30d6 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect
@@ -4,25 +4,25 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int
-    return #lateLocal#isSet ?{core::int} lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int} #lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect
index 49dc955..44d30d6 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect
@@ -4,25 +4,25 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int
-    return #lateLocal#isSet ?{core::int} lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int} #lateLocal{core::int} : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T%
-      return #lateGenericLocal#isSet ?{T%} lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T%} #lateGenericLocal{T%} : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T% #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart
new file mode 100644
index 0000000..b5a6079
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A declaration for each kind of late field/local lowering enabled by
+// target bitmask.
+
+main() {}
+
+method() {
+  late int? nullableUninitializedNonFinalLocal;
+  late int nonNullableUninitializedNonFinalLocal;
+  late final int? nullableUninitializedFinalLocal;
+  late final int nonNullableUninitializedFinalLocal;
+  late int? nullableInitializedNonFinalLocal = 0;
+  late int nonNullableInitializedNonFinalLocal = 0;
+  late final int? nullableInitializedFinalLocal = 0;
+  late final int nonNullableInitializedFinalLocal = 0;
+}
+
+late int uninitializedNonFinalTopLevelField;
+late final int uninitializedFinalTopLevelField;
+late int initializedNonFinalTopLevelField = 0;
+late final int initializedFinalTopLevelField = 0;
+
+class Class {
+  static late int uninitializedNonFinalStaticField;
+  static late final int uninitializedFinalStaticField;
+  static late int initializedNonFinalStaticField = 0;
+  static late final int initializedFinalStaticField = 0;
+
+  late int uninitializedNonFinalInstanceField;
+  late final int uninitializedFinalInstanceField;
+  late int initializedNonFinalInstanceField = 0;
+  late final int initializedFinalInstanceField = 0;
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.outline.expect
new file mode 100644
index 0000000..9c49adf
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.outline.expect
@@ -0,0 +1,45 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField;
+  static field core::int? _#uninitializedFinalStaticField;
+  static field core::int? _#initializedNonFinalStaticField;
+  static field core::int? _#initializedFinalStaticField;
+  field core::int? _#Class#uninitializedNonFinalInstanceField;
+  field core::int? _#Class#uninitializedFinalInstanceField;
+  field core::int? _#Class#initializedNonFinalInstanceField;
+  field core::int? _#Class#initializedFinalInstanceField;
+  synthetic constructor •() → self::Class
+    ;
+  static get uninitializedNonFinalStaticField() → core::int;
+  static set uninitializedNonFinalStaticField(core::int #t1) → void;
+  static get uninitializedFinalStaticField() → core::int;
+  static set uninitializedFinalStaticField(core::int #t2) → void;
+  static get initializedNonFinalStaticField() → core::int;
+  static set initializedNonFinalStaticField(core::int #t3) → void;
+  static get initializedFinalStaticField() → core::int;
+  get uninitializedNonFinalInstanceField() → core::int;
+  set uninitializedNonFinalInstanceField(core::int #t4) → void;
+  get uninitializedFinalInstanceField() → core::int;
+  set uninitializedFinalInstanceField(core::int #t5) → void;
+  get initializedNonFinalInstanceField() → core::int;
+  set initializedNonFinalInstanceField(core::int #t6) → void;
+  get initializedFinalInstanceField() → core::int;
+}
+static field core::int? _#uninitializedNonFinalTopLevelField;
+static field core::int? _#uninitializedFinalTopLevelField;
+static field core::int? _#initializedNonFinalTopLevelField;
+static field core::int? _#initializedFinalTopLevelField;
+static method main() → dynamic
+  ;
+static method method() → dynamic
+  ;
+static get uninitializedNonFinalTopLevelField() → core::int;
+static set uninitializedNonFinalTopLevelField(core::int #t7) → void;
+static get uninitializedFinalTopLevelField() → core::int;
+static set uninitializedFinalTopLevelField(core::int #t8) → void;
+static get initializedNonFinalTopLevelField() → core::int;
+static set initializedNonFinalTopLevelField(core::int #t9) → void;
+static get initializedFinalTopLevelField() → core::int;
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect
new file mode 100644
index 0000000..b8d325b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect
@@ -0,0 +1,141 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::int? _#initializedFinalStaticField = null;
+  field core::int? _#Class#uninitializedNonFinalInstanceField = null;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField") : #t1{core::int};
+  static set uninitializedNonFinalStaticField(core::int #t2) → void
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  static get uninitializedFinalStaticField() → core::int
+    return let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalStaticField") : #t3{core::int};
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField.==(null))
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+  static get initializedNonFinalStaticField() → core::int
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5.==(null) ?{core::int} self::Class::_#initializedNonFinalStaticField = 0 : #t5{core::int};
+  static set initializedNonFinalStaticField(core::int #t6) → void
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  static get initializedFinalStaticField() → core::int
+    return let final core::int? #t7 = self::Class::_#initializedFinalStaticField in #t7.==(null) ?{core::int} let final core::int #t8 = 0 in self::Class::_#initializedFinalStaticField.==(null) ?{core::int} self::Class::_#initializedFinalStaticField = #t8 : throw new _in::LateError::fieldADI("initializedFinalStaticField") : #t7{core::int};
+  get uninitializedNonFinalInstanceField() → core::int
+    return let final core::int? #t9 = this.{self::Class::_#Class#uninitializedNonFinalInstanceField} in #t9.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalInstanceField") : #t9{core::int};
+  set uninitializedNonFinalInstanceField(core::int #t10) → void
+    this.{self::Class::_#Class#uninitializedNonFinalInstanceField} = #t10;
+  get uninitializedFinalInstanceField() → core::int
+    return let final core::int? #t11 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t11.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalInstanceField") : #t11{core::int};
+  set uninitializedFinalInstanceField(core::int #t12) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField}.==(null))
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t12;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+  get initializedNonFinalInstanceField() → core::int
+    return let final core::int? #t13 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t13.==(null) ?{core::int} this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0 : #t13{core::int};
+  set initializedNonFinalInstanceField(core::int #t14) → void
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t14;
+  get initializedFinalInstanceField() → core::int
+    return let final core::int? #t15 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in this.{self::Class::_#Class#initializedFinalInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#initializedFinalInstanceField} = #t16 : throw new _in::LateError::fieldADI("initializedFinalInstanceField") : #t15{core::int};
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::int? _#initializedFinalTopLevelField = null;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t17) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t17;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t18 = #nonNullableUninitializedNonFinalLocal in #t18.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal") : #t18{core::int};
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t19) → dynamic
+    return #nonNullableUninitializedNonFinalLocal = #t19;
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t20) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t20;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return let final core::int? #t21 = #nonNullableUninitializedFinalLocal in #t21.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal") : #t21{core::int};
+  function #nonNullableUninitializedFinalLocal#set(core::int #t22) → dynamic
+    if(#nonNullableUninitializedFinalLocal.==(null))
+      return #nonNullableUninitializedFinalLocal = #t22;
+    else
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t23) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t23;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t24 = #nonNullableInitializedNonFinalLocal in #t24.==(null) ?{core::int} #nonNullableInitializedNonFinalLocal = 0 : #t24{core::int};
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t25) → dynamic
+    return #nonNullableInitializedNonFinalLocal = #t25;
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t26 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t26;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  function #nonNullableInitializedFinalLocal#get() → core::int
+    return let final core::int? #t27 = #nonNullableInitializedFinalLocal in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in #nonNullableInitializedFinalLocal.==(null) ?{core::int} #nonNullableInitializedFinalLocal = #t28 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t27{core::int};
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t29 = self::_#uninitializedNonFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t29{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t30) → void
+  self::_#uninitializedNonFinalTopLevelField = #t30;
+static get uninitializedFinalTopLevelField() → core::int
+  return let final core::int? #t31 = self::_#uninitializedFinalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t31{core::int};
+static set uninitializedFinalTopLevelField(core::int #t32) → void
+  if(self::_#uninitializedFinalTopLevelField.==(null))
+    self::_#uninitializedFinalTopLevelField = #t32;
+  else
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+static get initializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t33 = self::_#initializedNonFinalTopLevelField in #t33.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t33{core::int};
+static set initializedNonFinalTopLevelField(core::int #t34) → void
+  self::_#initializedNonFinalTopLevelField = #t34;
+static get initializedFinalTopLevelField() → core::int
+  return let final core::int? #t35 = self::_#initializedFinalTopLevelField in #t35.==(null) ?{core::int} let final core::int #t36 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t36 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t35{core::int};
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect
new file mode 100644
index 0000000..dd059f5
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect
@@ -0,0 +1,149 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::int? _#initializedFinalStaticField = null;
+  field core::int? _#Class#uninitializedNonFinalInstanceField = null;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField") : #t1{core::int};
+  static set uninitializedNonFinalStaticField(core::int #t2) → void
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  static get uninitializedFinalStaticField() → core::int
+    return let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalStaticField") : #t3{core::int};
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField.==(null))
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+  static get initializedNonFinalStaticField() → core::int
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5.==(null) ?{core::int} self::Class::_#initializedNonFinalStaticField = 0 : #t5{core::int};
+  static set initializedNonFinalStaticField(core::int #t6) → void
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  static get initializedFinalStaticField() → core::int
+    return let final core::int? #t7 = self::Class::_#initializedFinalStaticField in #t7.==(null) ?{core::int} let final core::int #t8 = 0 in self::Class::_#initializedFinalStaticField.==(null) ?{core::int} self::Class::_#initializedFinalStaticField = #t8 : throw new _in::LateError::fieldADI("initializedFinalStaticField") : #t7{core::int};
+  get uninitializedNonFinalInstanceField() → core::int
+    return let final core::int? #t9 = this.{self::Class::_#Class#uninitializedNonFinalInstanceField} in #t9.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalInstanceField") : #t9{core::int};
+  set uninitializedNonFinalInstanceField(core::int #t10) → void
+    this.{self::Class::_#Class#uninitializedNonFinalInstanceField} = #t10;
+  get uninitializedFinalInstanceField() → core::int
+    return let final core::int? #t11 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t11.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalInstanceField") : #t11{core::int};
+  set uninitializedFinalInstanceField(core::int #t12) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField}.==(null))
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t12;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+  get initializedNonFinalInstanceField() → core::int
+    return let final core::int? #t13 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t13.==(null) ?{core::int} this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0 : #t13{core::int};
+  set initializedNonFinalInstanceField(core::int #t14) → void
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t14;
+  get initializedFinalInstanceField() → core::int
+    return let final core::int? #t15 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in this.{self::Class::_#Class#initializedFinalInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#initializedFinalInstanceField} = #t16 : throw new _in::LateError::fieldADI("initializedFinalInstanceField") : #t15{core::int};
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::int? _#initializedFinalTopLevelField = null;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t17) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t17;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t18 = #nonNullableUninitializedNonFinalLocal in #t18.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal") : #t18{core::int};
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t19) → dynamic
+    return #nonNullableUninitializedNonFinalLocal = #t19;
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t20) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t20;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return let final core::int? #t21 = #nonNullableUninitializedFinalLocal in #t21.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal") : #t21{core::int};
+  function #nonNullableUninitializedFinalLocal#set(core::int #t22) → dynamic
+    if(#nonNullableUninitializedFinalLocal.==(null))
+      return #nonNullableUninitializedFinalLocal = #t22;
+    else
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t23) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t23;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t24 = #nonNullableInitializedNonFinalLocal in #t24.==(null) ?{core::int} #nonNullableInitializedNonFinalLocal = 0 : #t24{core::int};
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t25) → dynamic
+    return #nonNullableInitializedNonFinalLocal = #t25;
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t26 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t26;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  function #nonNullableInitializedFinalLocal#get() → core::int
+    return let final core::int? #t27 = #nonNullableInitializedFinalLocal in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in #nonNullableInitializedFinalLocal.==(null) ?{core::int} #nonNullableInitializedFinalLocal = #t28 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t27{core::int};
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t29 = self::_#uninitializedNonFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t29{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t30) → void
+  self::_#uninitializedNonFinalTopLevelField = #t30;
+static get uninitializedFinalTopLevelField() → core::int
+  return let final core::int? #t31 = self::_#uninitializedFinalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t31{core::int};
+static set uninitializedFinalTopLevelField(core::int #t32) → void
+  if(self::_#uninitializedFinalTopLevelField.==(null))
+    self::_#uninitializedFinalTopLevelField = #t32;
+  else
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+static get initializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t33 = self::_#initializedNonFinalTopLevelField in #t33.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t33{core::int};
+static set initializedNonFinalTopLevelField(core::int #t34) → void
+  self::_#initializedNonFinalTopLevelField = #t34;
+static get initializedFinalTopLevelField() → core::int
+  return let final core::int? #t35 = self::_#initializedFinalTopLevelField in #t35.==(null) ?{core::int} let final core::int #t36 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t36 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t35{core::int};
+
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:30:25 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:35:18 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:18:18 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:24:16 -> IntConstant(0)
+Extra constant evaluation: evaluated: 235, effectively constant: 4
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.textual_outline.expect
new file mode 100644
index 0000000..83c95c1
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+main() {}
+method() {}
+late int ;
+uninitializedNonFinalTopLevelField;
+late ;
+final int uninitializedFinalTopLevelField;
+late int ;
+initializedNonFinalTopLevelField = 0;
+late ;
+final int initializedFinalTopLevelField = 0;
+class Class {
+  static late int ;
+  uninitializedNonFinalStaticField;
+  static late ;
+  final int uninitializedFinalStaticField;
+  static late int ;
+  initializedNonFinalStaticField = 0;
+  static late ;
+  final int initializedFinalStaticField = 0;
+  late int ;
+  uninitializedNonFinalInstanceField;
+  late ;
+  final int uninitializedFinalInstanceField;
+  late int ;
+  initializedNonFinalInstanceField = 0;
+  late ;
+  final int initializedFinalInstanceField = 0;
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect
new file mode 100644
index 0000000..46b8989
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect
@@ -0,0 +1,233 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::bool _#uninitializedNonFinalStaticField#isSet = false;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::bool _#uninitializedFinalStaticField#isSet = false;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::bool _#initializedNonFinalStaticField#isSet = false;
+  static field core::int? _#initializedFinalStaticField = null;
+  static field core::bool _#initializedFinalStaticField#isSet = false;
+  field core::int? _#Class#uninitializedNonFinalInstanceField = null;
+  field core::bool _#Class#uninitializedNonFinalInstanceField#isSet = false;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::bool _#Class#uninitializedFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::bool _#Class#initializedNonFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  field core::bool _#Class#initializedFinalInstanceField#isSet = false;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return self::Class::_#uninitializedNonFinalStaticField#isSet ?{core::int} let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField");
+  static set uninitializedNonFinalStaticField(core::int #t2) → void {
+    self::Class::_#uninitializedNonFinalStaticField#isSet = true;
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  }
+  static get uninitializedFinalStaticField() → core::int
+    return self::Class::_#uninitializedFinalStaticField#isSet ?{core::int} let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalStaticField");
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField#isSet)
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+    else {
+      self::Class::_#uninitializedFinalStaticField#isSet = true;
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    }
+  static get initializedNonFinalStaticField() → core::int {
+    if(!self::Class::_#initializedNonFinalStaticField#isSet) {
+      self::Class::_#initializedNonFinalStaticField = 0;
+      self::Class::_#initializedNonFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5{core::int};
+  }
+  static set initializedNonFinalStaticField(core::int #t6) → void {
+    self::Class::_#initializedNonFinalStaticField#isSet = true;
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  }
+  static get initializedFinalStaticField() → core::int {
+    if(!self::Class::_#initializedFinalStaticField#isSet) {
+      final core::int #t7 = 0;
+      if(self::Class::_#initializedFinalStaticField#isSet)
+        throw new _in::LateError::fieldADI("initializedFinalStaticField");
+      self::Class::_#initializedFinalStaticField = #t7;
+      self::Class::_#initializedFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t8 = self::Class::_#initializedFinalStaticField in #t8{core::int};
+  }
+  get uninitializedNonFinalInstanceField() → core::int
+    return this.{self::Class::_#Class#uninitializedNonFinalInstanceField#isSet} ?{core::int} let final core::int? #t9 = this.{self::Class::_#Class#uninitializedNonFinalInstanceField} in #t9{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalInstanceField");
+  set uninitializedNonFinalInstanceField(core::int #t10) → void {
+    this.{self::Class::_#Class#uninitializedNonFinalInstanceField#isSet} = true;
+    this.{self::Class::_#Class#uninitializedNonFinalInstanceField} = #t10;
+  }
+  get uninitializedFinalInstanceField() → core::int
+    return this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} ?{core::int} let final core::int? #t11 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t11{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalInstanceField");
+  set uninitializedFinalInstanceField(core::int #t12) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet})
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+    else {
+      this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} = true;
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t12;
+    }
+  get initializedNonFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet}) {
+      this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0;
+      this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t13 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t13{core::int};
+  }
+  set initializedNonFinalInstanceField(core::int #t14) → void {
+    this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t14;
+  }
+  get initializedFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedFinalInstanceField#isSet}) {
+      final core::int #t15 = 0;
+      if(this.{self::Class::_#Class#initializedFinalInstanceField#isSet})
+        throw new _in::LateError::fieldADI("initializedFinalInstanceField");
+      this.{self::Class::_#Class#initializedFinalInstanceField} = #t15;
+      this.{self::Class::_#Class#initializedFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t16 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t16{core::int};
+  }
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::bool _#uninitializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::bool _#uninitializedFinalTopLevelField#isSet = false;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::bool _#initializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#initializedFinalTopLevelField = null;
+static field core::bool _#initializedFinalTopLevelField#isSet = false;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t17) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t17;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  lowered core::bool #nonNullableUninitializedNonFinalLocal#isSet = false;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return #nonNullableUninitializedNonFinalLocal#isSet ?{core::int} #nonNullableUninitializedNonFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal");
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t18) → dynamic {
+    #nonNullableUninitializedNonFinalLocal#isSet = true;
+    return #nonNullableUninitializedNonFinalLocal = #t18;
+  }
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t19) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t19;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  lowered core::bool #nonNullableUninitializedFinalLocal#isSet = false;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return #nonNullableUninitializedFinalLocal#isSet ?{core::int} #nonNullableUninitializedFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal");
+  function #nonNullableUninitializedFinalLocal#set(core::int #t20) → dynamic
+    if(#nonNullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+    else {
+      #nonNullableUninitializedFinalLocal#isSet = true;
+      return #nonNullableUninitializedFinalLocal = #t20;
+    }
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t21) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t21;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  lowered core::bool #nonNullableInitializedNonFinalLocal#isSet = false;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedNonFinalLocal#isSet) {
+      #nonNullableInitializedNonFinalLocal = 0;
+      #nonNullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedNonFinalLocal{core::int};
+  }
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t22) → dynamic {
+    #nonNullableInitializedNonFinalLocal#isSet = true;
+    return #nonNullableInitializedNonFinalLocal = #t22;
+  }
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t23 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t23;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  lowered core::bool #nonNullableInitializedFinalLocal#isSet = false;
+  function #nonNullableInitializedFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedFinalLocal#isSet) {
+      final core::int #t24 = 0;
+      if(#nonNullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+      #nonNullableInitializedFinalLocal = #t24;
+      #nonNullableInitializedFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedFinalLocal{core::int};
+  }
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedNonFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t26) → void {
+  self::_#uninitializedNonFinalTopLevelField#isSet = true;
+  self::_#uninitializedNonFinalTopLevelField = #t26;
+}
+static get uninitializedFinalTopLevelField() → core::int
+  return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t27 = self::_#uninitializedFinalTopLevelField in #t27{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t28) → void
+  if(self::_#uninitializedFinalTopLevelField#isSet)
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+  else {
+    self::_#uninitializedFinalTopLevelField#isSet = true;
+    self::_#uninitializedFinalTopLevelField = #t28;
+  }
+static get initializedNonFinalTopLevelField() → core::int {
+  if(!self::_#initializedNonFinalTopLevelField#isSet) {
+    self::_#initializedNonFinalTopLevelField = 0;
+    self::_#initializedNonFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t29 = self::_#initializedNonFinalTopLevelField in #t29{core::int};
+}
+static set initializedNonFinalTopLevelField(core::int #t30) → void {
+  self::_#initializedNonFinalTopLevelField#isSet = true;
+  self::_#initializedNonFinalTopLevelField = #t30;
+}
+static get initializedFinalTopLevelField() → core::int {
+  if(!self::_#initializedFinalTopLevelField#isSet) {
+    final core::int #t31 = 0;
+    if(self::_#initializedFinalTopLevelField#isSet)
+      throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
+    self::_#initializedFinalTopLevelField = #t31;
+    self::_#initializedFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t32 = self::_#initializedFinalTopLevelField in #t32{core::int};
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect
new file mode 100644
index 0000000..46b8989
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect
@@ -0,0 +1,233 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::bool _#uninitializedNonFinalStaticField#isSet = false;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::bool _#uninitializedFinalStaticField#isSet = false;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::bool _#initializedNonFinalStaticField#isSet = false;
+  static field core::int? _#initializedFinalStaticField = null;
+  static field core::bool _#initializedFinalStaticField#isSet = false;
+  field core::int? _#Class#uninitializedNonFinalInstanceField = null;
+  field core::bool _#Class#uninitializedNonFinalInstanceField#isSet = false;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::bool _#Class#uninitializedFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::bool _#Class#initializedNonFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  field core::bool _#Class#initializedFinalInstanceField#isSet = false;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return self::Class::_#uninitializedNonFinalStaticField#isSet ?{core::int} let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField");
+  static set uninitializedNonFinalStaticField(core::int #t2) → void {
+    self::Class::_#uninitializedNonFinalStaticField#isSet = true;
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  }
+  static get uninitializedFinalStaticField() → core::int
+    return self::Class::_#uninitializedFinalStaticField#isSet ?{core::int} let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalStaticField");
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField#isSet)
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+    else {
+      self::Class::_#uninitializedFinalStaticField#isSet = true;
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    }
+  static get initializedNonFinalStaticField() → core::int {
+    if(!self::Class::_#initializedNonFinalStaticField#isSet) {
+      self::Class::_#initializedNonFinalStaticField = 0;
+      self::Class::_#initializedNonFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5{core::int};
+  }
+  static set initializedNonFinalStaticField(core::int #t6) → void {
+    self::Class::_#initializedNonFinalStaticField#isSet = true;
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  }
+  static get initializedFinalStaticField() → core::int {
+    if(!self::Class::_#initializedFinalStaticField#isSet) {
+      final core::int #t7 = 0;
+      if(self::Class::_#initializedFinalStaticField#isSet)
+        throw new _in::LateError::fieldADI("initializedFinalStaticField");
+      self::Class::_#initializedFinalStaticField = #t7;
+      self::Class::_#initializedFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t8 = self::Class::_#initializedFinalStaticField in #t8{core::int};
+  }
+  get uninitializedNonFinalInstanceField() → core::int
+    return this.{self::Class::_#Class#uninitializedNonFinalInstanceField#isSet} ?{core::int} let final core::int? #t9 = this.{self::Class::_#Class#uninitializedNonFinalInstanceField} in #t9{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalInstanceField");
+  set uninitializedNonFinalInstanceField(core::int #t10) → void {
+    this.{self::Class::_#Class#uninitializedNonFinalInstanceField#isSet} = true;
+    this.{self::Class::_#Class#uninitializedNonFinalInstanceField} = #t10;
+  }
+  get uninitializedFinalInstanceField() → core::int
+    return this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} ?{core::int} let final core::int? #t11 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t11{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalInstanceField");
+  set uninitializedFinalInstanceField(core::int #t12) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet})
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+    else {
+      this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} = true;
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t12;
+    }
+  get initializedNonFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet}) {
+      this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0;
+      this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t13 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t13{core::int};
+  }
+  set initializedNonFinalInstanceField(core::int #t14) → void {
+    this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t14;
+  }
+  get initializedFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedFinalInstanceField#isSet}) {
+      final core::int #t15 = 0;
+      if(this.{self::Class::_#Class#initializedFinalInstanceField#isSet})
+        throw new _in::LateError::fieldADI("initializedFinalInstanceField");
+      this.{self::Class::_#Class#initializedFinalInstanceField} = #t15;
+      this.{self::Class::_#Class#initializedFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t16 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t16{core::int};
+  }
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::bool _#uninitializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::bool _#uninitializedFinalTopLevelField#isSet = false;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::bool _#initializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#initializedFinalTopLevelField = null;
+static field core::bool _#initializedFinalTopLevelField#isSet = false;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t17) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t17;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  lowered core::bool #nonNullableUninitializedNonFinalLocal#isSet = false;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return #nonNullableUninitializedNonFinalLocal#isSet ?{core::int} #nonNullableUninitializedNonFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal");
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t18) → dynamic {
+    #nonNullableUninitializedNonFinalLocal#isSet = true;
+    return #nonNullableUninitializedNonFinalLocal = #t18;
+  }
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t19) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t19;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  lowered core::bool #nonNullableUninitializedFinalLocal#isSet = false;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return #nonNullableUninitializedFinalLocal#isSet ?{core::int} #nonNullableUninitializedFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal");
+  function #nonNullableUninitializedFinalLocal#set(core::int #t20) → dynamic
+    if(#nonNullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+    else {
+      #nonNullableUninitializedFinalLocal#isSet = true;
+      return #nonNullableUninitializedFinalLocal = #t20;
+    }
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t21) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t21;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  lowered core::bool #nonNullableInitializedNonFinalLocal#isSet = false;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedNonFinalLocal#isSet) {
+      #nonNullableInitializedNonFinalLocal = 0;
+      #nonNullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedNonFinalLocal{core::int};
+  }
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t22) → dynamic {
+    #nonNullableInitializedNonFinalLocal#isSet = true;
+    return #nonNullableInitializedNonFinalLocal = #t22;
+  }
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t23 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t23;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  lowered core::bool #nonNullableInitializedFinalLocal#isSet = false;
+  function #nonNullableInitializedFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedFinalLocal#isSet) {
+      final core::int #t24 = 0;
+      if(#nonNullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+      #nonNullableInitializedFinalLocal = #t24;
+      #nonNullableInitializedFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedFinalLocal{core::int};
+  }
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedNonFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t26) → void {
+  self::_#uninitializedNonFinalTopLevelField#isSet = true;
+  self::_#uninitializedNonFinalTopLevelField = #t26;
+}
+static get uninitializedFinalTopLevelField() → core::int
+  return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t27 = self::_#uninitializedFinalTopLevelField in #t27{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t28) → void
+  if(self::_#uninitializedFinalTopLevelField#isSet)
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+  else {
+    self::_#uninitializedFinalTopLevelField#isSet = true;
+    self::_#uninitializedFinalTopLevelField = #t28;
+  }
+static get initializedNonFinalTopLevelField() → core::int {
+  if(!self::_#initializedNonFinalTopLevelField#isSet) {
+    self::_#initializedNonFinalTopLevelField = 0;
+    self::_#initializedNonFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t29 = self::_#initializedNonFinalTopLevelField in #t29{core::int};
+}
+static set initializedNonFinalTopLevelField(core::int #t30) → void {
+  self::_#initializedNonFinalTopLevelField#isSet = true;
+  self::_#initializedNonFinalTopLevelField = #t30;
+}
+static get initializedFinalTopLevelField() → core::int {
+  if(!self::_#initializedFinalTopLevelField#isSet) {
+    final core::int #t31 = 0;
+    if(self::_#initializedFinalTopLevelField#isSet)
+      throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
+    self::_#initializedFinalTopLevelField = #t31;
+    self::_#initializedFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t32 = self::_#initializedFinalTopLevelField in #t32{core::int};
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect
index 44a6c7f..12dcc96 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect
@@ -5,35 +5,35 @@
 static method lateLocalInit() → core::int?
   return 123;
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = self::lateLocalInit();
+      #lateLocal = self::lateLocalInit();
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value1, T? value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect
index 44a6c7f..12dcc96 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect
@@ -5,35 +5,35 @@
 static method lateLocalInit() → core::int?
   return 123;
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = self::lateLocalInit();
+      #lateLocal = self::lateLocalInit();
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value1, T? value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect
index 44a6c7f..12dcc96 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect
@@ -5,35 +5,35 @@
 static method lateLocalInit() → core::int?
   return 123;
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = self::lateLocalInit();
+      #lateLocal = self::lateLocalInit();
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value1, T? value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect
index 44a6c7f..12dcc96 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect
@@ -5,35 +5,35 @@
 static method lateLocalInit() → core::int?
   return 123;
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int? {
     if(!#lateLocal#isSet) {
-      lateLocal = self::lateLocalInit();
+      #lateLocal = self::lateLocalInit();
       #lateLocal#isSet = true;
     }
-    return lateLocal;
+    return #lateLocal;
   }
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::expect(123, #lateLocal#get.call());
   self::expect(124, #lateLocal#set.call(124));
   self::expect(124, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value1, T? value2) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T? {
       if(!#lateGenericLocal#isSet) {
-        lateGenericLocal = value1;
+        #lateGenericLocal = value1;
         #lateGenericLocal#isSet = true;
       }
-      return lateGenericLocal;
+      return #lateGenericLocal;
     }
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::expect(value1, #lateGenericLocal#get.call());
     self::expect(value2, #lateGenericLocal#set.call(value2));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.expect
index d1c2417..a635204 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.expect
@@ -4,25 +4,25 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.transformed.expect
index d1c2417..a635204 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.strong.transformed.expect
@@ -4,25 +4,25 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.expect
index d1c2417..a635204 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.expect
@@ -4,25 +4,25 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.transformed.expect
index d1c2417..a635204 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.weak.transformed.expect
@@ -4,25 +4,25 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic {
-  core::int? lateLocal;
-  core::bool #lateLocal#isSet = false;
+  lowered core::int? #lateLocal;
+  lowered core::bool #lateLocal#isSet = false;
   function #lateLocal#get() → core::int?
-    return #lateLocal#isSet ?{core::int?} lateLocal : throw new _in::LateError::localNI("lateLocal");
+    return #lateLocal#isSet ?{core::int?} #lateLocal : throw new _in::LateError::localNI("lateLocal");
   function #lateLocal#set(core::int? #t1) → dynamic {
     #lateLocal#isSet = true;
-    return lateLocal = #t1;
+    return #lateLocal = #t1;
   }
   self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T? value) → Null {
-    T? lateGenericLocal;
-    core::bool #lateGenericLocal#isSet = false;
+    lowered T? #lateGenericLocal;
+    lowered core::bool #lateGenericLocal#isSet = false;
     function #lateGenericLocal#get() → T?
-      return #lateGenericLocal#isSet ?{T?} lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
+      return #lateGenericLocal#isSet ?{T?} #lateGenericLocal : throw new _in::LateError::localNI("lateGenericLocal");
     function #lateGenericLocal#set(T? #t2) → dynamic {
       #lateGenericLocal#isSet = true;
-      return lateGenericLocal = #t2;
+      return #lateGenericLocal = #t2;
     }
     self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
index 1876a7a..0b84933 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
@@ -137,25 +137,25 @@
   return "hest";
 }
 static method fisk() → dynamic async {
-  core::String? s1;
+  lowered core::String? #s1;
   function #s1#get() → core::String
-    return let final core::String? #t8 = s1 in #t8.==(null) ?{core::String} s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
+    return let final core::String? #t8 = #s1 in #t8.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest(); // Error.
                    ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t8{core::String};
   function #s1#set(core::String #t9) → dynamic
-    return s1 = #t9;
-  core::String? s2;
+    return #s1 = #t9;
+  lowered core::String? #s2;
   function #s2#get() → core::String
-    return let final core::String? #t10 = s2 in #t10.==(null) ?{core::String} s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
+    return let final core::String? #t10 = #s2 in #t10.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
                              ^^^^^"}${#C1}" : #t10{core::String};
   function #s2#set(core::String #t11) → dynamic
-    return s2 = #t11;
-  core::Function? f;
+    return #s2 = #t11;
+  lowered core::Function? #f;
   function #f#get() → core::Function
-    return let final core::Function? #t12 = f in #t12.==(null) ?{core::Function} f = () → asy::Future<dynamic> async => await self::hest() : #t12{core::Function};
+    return let final core::Function? #t12 = #f in #t12.==(null) ?{core::Function} #f = () → asy::Future<dynamic> async => await self::hest() : #t12{core::Function};
   function #f#set(core::Function #t13) → dynamic
-    return f = #t13;
+    return #f = #t13;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
index d9e572e..f251299 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
@@ -140,7 +140,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -185,7 +184,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -196,7 +194,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -205,27 +202,26 @@
     try {
       #L3:
       {
-        core::String? s1;
+        lowered core::String? #s1;
         function #s1#get() → core::String
-          return let final core::String? #t11 = s1 in #t11.==(null) ?{core::String} s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
+          return let final core::String? #t11 = #s1 in #t11.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest(); // Error.
                    ^^^^^" : #t11{core::String};
         function #s1#set(core::String #t12) → dynamic
-          return s1 = #t12;
-        core::String? s2;
+          return #s1 = #t12;
+        lowered core::String? #s2;
         function #s2#get() → core::String
-          return let final core::String? #t13 = s2 in #t13.==(null) ?{core::String} s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
+          return let final core::String? #t13 = #s2 in #t13.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
                              ^^^^^"}${#C1}" : #t13{core::String};
         function #s2#set(core::String #t14) → dynamic
-          return s2 = #t14;
-        core::Function? f;
+          return #s2 = #t14;
+        lowered core::Function? #f;
         function #f#get() → core::Function
-          return let final core::Function? #t15 = f in #t15.==(null) ?{core::Function} f = () → asy::Future<dynamic> /* originally async */ {
+          return let final core::Function? #t15 = #f in #t15.==(null) ?{core::Function} #f = () → asy::Future<dynamic> /* originally async */ {
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
             core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
-            dynamic :async_stack_trace;
             (dynamic) → dynamic :async_op_then;
             (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
@@ -245,7 +241,6 @@
               on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
                 asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
               }
-            :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
             :async_op.call();
@@ -253,7 +248,7 @@
             return :async_future;
           } : #t15{core::Function};
         function #f#set(core::Function #t17) → dynamic
-          return f = #t17;
+          return #f = #t17;
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
@@ -261,7 +256,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -276,4 +270,4 @@
 
 Extra constant evaluation status:
 Evaluated: VariableGet @ org-dartlang-testcase:///later.dart:46:18 -> IntConstant(42)
-Extra constant evaluation: evaluated: 216, effectively constant: 1
+Extra constant evaluation: evaluated: 207, effectively constant: 1
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
index 267e384..7123dd80 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
@@ -157,48 +157,48 @@
   return "hest";
 }
 static method fisk() → dynamic async {
-  core::String? s1;
-  core::bool #s1#isSet = false;
+  lowered core::String? #s1;
+  lowered core::bool #s1#isSet = false;
   function #s1#get() → core::String {
     if(!#s1#isSet) {
-      s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
+      #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest(); // Error.
                    ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
       #s1#isSet = true;
     }
-    return s1{core::String};
+    return #s1{core::String};
   }
   function #s1#set(core::String #t8) → dynamic {
     #s1#isSet = true;
-    return s1 = #t8;
+    return #s1 = #t8;
   }
-  core::String? s2;
-  core::bool #s2#isSet = false;
+  lowered core::String? #s2;
+  lowered core::bool #s2#isSet = false;
   function #s2#get() → core::String {
     if(!#s2#isSet) {
-      s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
+      #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
                              ^^^^^"}${#C1}";
       #s2#isSet = true;
     }
-    return s2{core::String};
+    return #s2{core::String};
   }
   function #s2#set(core::String #t9) → dynamic {
     #s2#isSet = true;
-    return s2 = #t9;
+    return #s2 = #t9;
   }
-  core::Function? f;
-  core::bool #f#isSet = false;
+  lowered core::Function? #f;
+  lowered core::bool #f#isSet = false;
   function #f#get() → core::Function {
     if(!#f#isSet) {
-      f = () → asy::Future<dynamic> async => await self::hest();
+      #f = () → asy::Future<dynamic> async => await self::hest();
       #f#isSet = true;
     }
-    return f{core::Function};
+    return #f{core::Function};
   }
   function #f#set(core::Function #t10) → dynamic {
     #f#isSet = true;
-    return f = #t10;
+    return #f = #t10;
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
index abfa48e..11b98b1 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
@@ -160,7 +160,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -205,7 +204,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -216,7 +214,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -225,45 +222,44 @@
     try {
       #L3:
       {
-        core::String? s1;
-        core::bool #s1#isSet = false;
+        lowered core::String? #s1;
+        lowered core::bool #s1#isSet = false;
         function #s1#get() → core::String {
           if(!#s1#isSet) {
-            s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
+            #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest(); // Error.
                    ^^^^^";
             #s1#isSet = true;
           }
-          return s1{core::String};
+          return #s1{core::String};
         }
         function #s1#set(core::String #t11) → dynamic {
           #s1#isSet = true;
-          return s1 = #t11;
+          return #s1 = #t11;
         }
-        core::String? s2;
-        core::bool #s2#isSet = false;
+        lowered core::String? #s2;
+        lowered core::bool #s2#isSet = false;
         function #s2#get() → core::String {
           if(!#s2#isSet) {
-            s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
+            #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
                              ^^^^^"}${#C1}";
             #s2#isSet = true;
           }
-          return s2{core::String};
+          return #s2{core::String};
         }
         function #s2#set(core::String #t12) → dynamic {
           #s2#isSet = true;
-          return s2 = #t12;
+          return #s2 = #t12;
         }
-        core::Function? f;
-        core::bool #f#isSet = false;
+        lowered core::Function? #f;
+        lowered core::bool #f#isSet = false;
         function #f#get() → core::Function {
           if(!#f#isSet) {
-            f = () → asy::Future<dynamic> /* originally async */ {
+            #f = () → asy::Future<dynamic> /* originally async */ {
               final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
               core::bool* :is_sync = false;
               FutureOr<dynamic>? :return_value;
-              dynamic :async_stack_trace;
               (dynamic) → dynamic :async_op_then;
               (core::Object, core::StackTrace) → dynamic :async_op_error;
               core::int :await_jump_var = 0;
@@ -283,7 +279,6 @@
                 on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
                   asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                 }
-              :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
               :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
               :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
               :async_op.call();
@@ -292,11 +287,11 @@
             };
             #f#isSet = true;
           }
-          return f{core::Function};
+          return #f{core::Function};
         }
         function #f#set(core::Function #t14) → dynamic {
           #f#isSet = true;
-          return f = #t14;
+          return #f = #t14;
         }
       }
       asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -305,7 +300,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.expect b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.expect
index 03ef078..184faaf 100644
--- a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.expect
@@ -109,33 +109,33 @@
     non::_#finalTopLevelField = #t13;
   }
 static method method<T extends core::Object = core::Object>(core::bool b, core::int i, non::method::T t) → dynamic {
-  core::int? local;
+  lowered core::int? #local;
   function #local#get() → core::int
-    return let final core::int? #t14 = local in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t14{core::int};
+    return let final core::int? #t14 = #local in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t14{core::int};
   function #local#set(core::int #t15) → dynamic
-    return local = #t15;
-  final dynamic finalLocal;
-  core::bool #finalLocal#isSet = false;
+    return #local = #t15;
+  lowered final dynamic #finalLocal;
+  lowered core::bool #finalLocal#isSet = false;
   function #finalLocal#get() → dynamic
-    return #finalLocal#isSet ?{dynamic} finalLocal : throw new _in::LateError::localNI("finalLocal");
+    return #finalLocal#isSet ?{dynamic} #finalLocal : throw new _in::LateError::localNI("finalLocal");
   function #finalLocal#set(dynamic #t16) → dynamic
     if(#finalLocal#isSet)
       throw new _in::LateError::localAI("finalLocal");
     else {
       #finalLocal#isSet = true;
-      return finalLocal = #t16;
+      return #finalLocal = #t16;
     }
-  non::method::T? localTypeVariable;
+  lowered non::method::T? #localTypeVariable;
   function #localTypeVariable#get() → non::method::T
-    return let final non::method::T? #t17 = localTypeVariable in #t17.==(null) ?{non::method::T} throw new _in::LateError::localNI("localTypeVariable") : #t17{non::method::T};
+    return let final non::method::T? #t17 = #localTypeVariable in #t17.==(null) ?{non::method::T} throw new _in::LateError::localNI("localTypeVariable") : #t17{non::method::T};
   function #localTypeVariable#set(non::method::T #t18) → dynamic
-    return localTypeVariable = #t18;
-  final non::method::T? finalLocalTypeVariable;
+    return #localTypeVariable = #t18;
+  lowered final non::method::T? #finalLocalTypeVariable;
   function #finalLocalTypeVariable#get() → non::method::T
-    return let final non::method::T? #t19 = finalLocalTypeVariable in #t19.==(null) ?{non::method::T} throw new _in::LateError::localNI("finalLocalTypeVariable") : #t19{non::method::T};
+    return let final non::method::T? #t19 = #finalLocalTypeVariable in #t19.==(null) ?{non::method::T} throw new _in::LateError::localNI("finalLocalTypeVariable") : #t19{non::method::T};
   function #finalLocalTypeVariable#set(non::method::T #t20) → dynamic
-    if(finalLocalTypeVariable.==(null))
-      return finalLocalTypeVariable = #t20;
+    if(#finalLocalTypeVariable.==(null))
+      return #finalLocalTypeVariable = #t20;
     else
       throw new _in::LateError::localAI("finalLocalTypeVariable");
   if(b) {
diff --git a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.transformed.expect
index 03ef078..184faaf 100644
--- a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.strong.transformed.expect
@@ -109,33 +109,33 @@
     non::_#finalTopLevelField = #t13;
   }
 static method method<T extends core::Object = core::Object>(core::bool b, core::int i, non::method::T t) → dynamic {
-  core::int? local;
+  lowered core::int? #local;
   function #local#get() → core::int
-    return let final core::int? #t14 = local in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t14{core::int};
+    return let final core::int? #t14 = #local in #t14.==(null) ?{core::int} throw new _in::LateError::localNI("local") : #t14{core::int};
   function #local#set(core::int #t15) → dynamic
-    return local = #t15;
-  final dynamic finalLocal;
-  core::bool #finalLocal#isSet = false;
+    return #local = #t15;
+  lowered final dynamic #finalLocal;
+  lowered core::bool #finalLocal#isSet = false;
   function #finalLocal#get() → dynamic
-    return #finalLocal#isSet ?{dynamic} finalLocal : throw new _in::LateError::localNI("finalLocal");
+    return #finalLocal#isSet ?{dynamic} #finalLocal : throw new _in::LateError::localNI("finalLocal");
   function #finalLocal#set(dynamic #t16) → dynamic
     if(#finalLocal#isSet)
       throw new _in::LateError::localAI("finalLocal");
     else {
       #finalLocal#isSet = true;
-      return finalLocal = #t16;
+      return #finalLocal = #t16;
     }
-  non::method::T? localTypeVariable;
+  lowered non::method::T? #localTypeVariable;
   function #localTypeVariable#get() → non::method::T
-    return let final non::method::T? #t17 = localTypeVariable in #t17.==(null) ?{non::method::T} throw new _in::LateError::localNI("localTypeVariable") : #t17{non::method::T};
+    return let final non::method::T? #t17 = #localTypeVariable in #t17.==(null) ?{non::method::T} throw new _in::LateError::localNI("localTypeVariable") : #t17{non::method::T};
   function #localTypeVariable#set(non::method::T #t18) → dynamic
-    return localTypeVariable = #t18;
-  final non::method::T? finalLocalTypeVariable;
+    return #localTypeVariable = #t18;
+  lowered final non::method::T? #finalLocalTypeVariable;
   function #finalLocalTypeVariable#get() → non::method::T
-    return let final non::method::T? #t19 = finalLocalTypeVariable in #t19.==(null) ?{non::method::T} throw new _in::LateError::localNI("finalLocalTypeVariable") : #t19{non::method::T};
+    return let final non::method::T? #t19 = #finalLocalTypeVariable in #t19.==(null) ?{non::method::T} throw new _in::LateError::localNI("finalLocalTypeVariable") : #t19{non::method::T};
   function #finalLocalTypeVariable#set(non::method::T #t20) → dynamic
-    if(finalLocalTypeVariable.==(null))
-      return finalLocalTypeVariable = #t20;
+    if(#finalLocalTypeVariable.==(null))
+      return #finalLocalTypeVariable = #t20;
     else
       throw new _in::LateError::localAI("finalLocalTypeVariable");
   if(b) {
diff --git a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.expect b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.expect
index 53ea9c9..7555788 100644
--- a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.expect
@@ -117,43 +117,43 @@
     non::_#finalTopLevelField = #t13;
   }
 static method method<T extends core::Object = core::Object>(core::bool b, core::int i, non::method::T t) → dynamic {
-  core::int? local;
-  core::bool #local#isSet = false;
+  lowered core::int? #local;
+  lowered core::bool #local#isSet = false;
   function #local#get() → core::int
-    return #local#isSet ?{core::int} local{core::int} : throw new _in::LateError::localNI("local");
+    return #local#isSet ?{core::int} #local{core::int} : throw new _in::LateError::localNI("local");
   function #local#set(core::int #t14) → dynamic {
     #local#isSet = true;
-    return local = #t14;
+    return #local = #t14;
   }
-  final dynamic finalLocal;
-  core::bool #finalLocal#isSet = false;
+  lowered final dynamic #finalLocal;
+  lowered core::bool #finalLocal#isSet = false;
   function #finalLocal#get() → dynamic
-    return #finalLocal#isSet ?{dynamic} finalLocal : throw new _in::LateError::localNI("finalLocal");
+    return #finalLocal#isSet ?{dynamic} #finalLocal : throw new _in::LateError::localNI("finalLocal");
   function #finalLocal#set(dynamic #t15) → dynamic
     if(#finalLocal#isSet)
       throw new _in::LateError::localAI("finalLocal");
     else {
       #finalLocal#isSet = true;
-      return finalLocal = #t15;
+      return #finalLocal = #t15;
     }
-  non::method::T? localTypeVariable;
-  core::bool #localTypeVariable#isSet = false;
+  lowered non::method::T? #localTypeVariable;
+  lowered core::bool #localTypeVariable#isSet = false;
   function #localTypeVariable#get() → non::method::T
-    return #localTypeVariable#isSet ?{non::method::T} localTypeVariable{non::method::T} : throw new _in::LateError::localNI("localTypeVariable");
+    return #localTypeVariable#isSet ?{non::method::T} #localTypeVariable{non::method::T} : throw new _in::LateError::localNI("localTypeVariable");
   function #localTypeVariable#set(non::method::T #t16) → dynamic {
     #localTypeVariable#isSet = true;
-    return localTypeVariable = #t16;
+    return #localTypeVariable = #t16;
   }
-  final non::method::T? finalLocalTypeVariable;
-  core::bool #finalLocalTypeVariable#isSet = false;
+  lowered final non::method::T? #finalLocalTypeVariable;
+  lowered core::bool #finalLocalTypeVariable#isSet = false;
   function #finalLocalTypeVariable#get() → non::method::T
-    return #finalLocalTypeVariable#isSet ?{non::method::T} finalLocalTypeVariable{non::method::T} : throw new _in::LateError::localNI("finalLocalTypeVariable");
+    return #finalLocalTypeVariable#isSet ?{non::method::T} #finalLocalTypeVariable{non::method::T} : throw new _in::LateError::localNI("finalLocalTypeVariable");
   function #finalLocalTypeVariable#set(non::method::T #t17) → dynamic
     if(#finalLocalTypeVariable#isSet)
       throw new _in::LateError::localAI("finalLocalTypeVariable");
     else {
       #finalLocalTypeVariable#isSet = true;
-      return finalLocalTypeVariable = #t17;
+      return #finalLocalTypeVariable = #t17;
     }
   if(b) {
     #local#set.call(i);
diff --git a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.transformed.expect
index 53ea9c9..7555788 100644
--- a/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/non_nullable_from_opt_out.dart.weak.transformed.expect
@@ -117,43 +117,43 @@
     non::_#finalTopLevelField = #t13;
   }
 static method method<T extends core::Object = core::Object>(core::bool b, core::int i, non::method::T t) → dynamic {
-  core::int? local;
-  core::bool #local#isSet = false;
+  lowered core::int? #local;
+  lowered core::bool #local#isSet = false;
   function #local#get() → core::int
-    return #local#isSet ?{core::int} local{core::int} : throw new _in::LateError::localNI("local");
+    return #local#isSet ?{core::int} #local{core::int} : throw new _in::LateError::localNI("local");
   function #local#set(core::int #t14) → dynamic {
     #local#isSet = true;
-    return local = #t14;
+    return #local = #t14;
   }
-  final dynamic finalLocal;
-  core::bool #finalLocal#isSet = false;
+  lowered final dynamic #finalLocal;
+  lowered core::bool #finalLocal#isSet = false;
   function #finalLocal#get() → dynamic
-    return #finalLocal#isSet ?{dynamic} finalLocal : throw new _in::LateError::localNI("finalLocal");
+    return #finalLocal#isSet ?{dynamic} #finalLocal : throw new _in::LateError::localNI("finalLocal");
   function #finalLocal#set(dynamic #t15) → dynamic
     if(#finalLocal#isSet)
       throw new _in::LateError::localAI("finalLocal");
     else {
       #finalLocal#isSet = true;
-      return finalLocal = #t15;
+      return #finalLocal = #t15;
     }
-  non::method::T? localTypeVariable;
-  core::bool #localTypeVariable#isSet = false;
+  lowered non::method::T? #localTypeVariable;
+  lowered core::bool #localTypeVariable#isSet = false;
   function #localTypeVariable#get() → non::method::T
-    return #localTypeVariable#isSet ?{non::method::T} localTypeVariable{non::method::T} : throw new _in::LateError::localNI("localTypeVariable");
+    return #localTypeVariable#isSet ?{non::method::T} #localTypeVariable{non::method::T} : throw new _in::LateError::localNI("localTypeVariable");
   function #localTypeVariable#set(non::method::T #t16) → dynamic {
     #localTypeVariable#isSet = true;
-    return localTypeVariable = #t16;
+    return #localTypeVariable = #t16;
   }
-  final non::method::T? finalLocalTypeVariable;
-  core::bool #finalLocalTypeVariable#isSet = false;
+  lowered final non::method::T? #finalLocalTypeVariable;
+  lowered core::bool #finalLocalTypeVariable#isSet = false;
   function #finalLocalTypeVariable#get() → non::method::T
-    return #finalLocalTypeVariable#isSet ?{non::method::T} finalLocalTypeVariable{non::method::T} : throw new _in::LateError::localNI("finalLocalTypeVariable");
+    return #finalLocalTypeVariable#isSet ?{non::method::T} #finalLocalTypeVariable{non::method::T} : throw new _in::LateError::localNI("finalLocalTypeVariable");
   function #finalLocalTypeVariable#set(non::method::T #t17) → dynamic
     if(#finalLocalTypeVariable#isSet)
       throw new _in::LateError::localAI("finalLocalTypeVariable");
     else {
       #finalLocalTypeVariable#isSet = true;
-      return finalLocalTypeVariable = #t17;
+      return #finalLocalTypeVariable = #t17;
     }
   if(b) {
     #local#set.call(i);
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
index 1cc4a59..2ad5eb6 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
@@ -8,43 +8,43 @@
     : self::Class::field = field, super core::Object::•()
     ;
   method returnTypeVariable() → self::Class::E% {
-    self::Class::E? result;
-    core::bool #result#isSet = false;
+    lowered self::Class::E? #result;
+    lowered core::bool #result#isSet = false;
     function #result#get() → self::Class::E% {
       if(!#result#isSet) {
-        result = this.{self::Class::field};
+        #result = this.{self::Class::field};
         #result#isSet = true;
       }
-      return result{self::Class::E%};
+      return #result{self::Class::E%};
     }
     function #result#set(self::Class::E% #t1) → dynamic {
       #result#isSet = true;
-      return result = #t1;
+      return #result = #t1;
     }
     return #result#get.call();
   }
 }
 static method returnNonNullable(core::int value) → core::int {
-  core::int? result;
+  lowered core::int? #result;
   function #result#get() → core::int
-    return let final core::int? #t2 = result in #t2.==(null) ?{core::int} result = value : #t2{core::int};
+    return let final core::int? #t2 = #result in #t2.==(null) ?{core::int} #result = value : #t2{core::int};
   function #result#set(core::int #t3) → dynamic
-    return result = #t3;
+    return #result = #t3;
   return #result#get.call();
 }
 static method returnNullable(core::int? value) → core::int? {
-  core::int? result;
-  core::bool #result#isSet = false;
+  lowered core::int? #result;
+  lowered core::bool #result#isSet = false;
   function #result#get() → core::int? {
     if(!#result#isSet) {
-      result = value;
+      #result = value;
       #result#isSet = true;
     }
-    return result;
+    return #result;
   }
   function #result#set(core::int? #t4) → dynamic {
     #result#isSet = true;
-    return result = #t4;
+    return #result = #t4;
   }
   return #result#get.call();
 }
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
index 1cc4a59..2ad5eb6 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
@@ -8,43 +8,43 @@
     : self::Class::field = field, super core::Object::•()
     ;
   method returnTypeVariable() → self::Class::E% {
-    self::Class::E? result;
-    core::bool #result#isSet = false;
+    lowered self::Class::E? #result;
+    lowered core::bool #result#isSet = false;
     function #result#get() → self::Class::E% {
       if(!#result#isSet) {
-        result = this.{self::Class::field};
+        #result = this.{self::Class::field};
         #result#isSet = true;
       }
-      return result{self::Class::E%};
+      return #result{self::Class::E%};
     }
     function #result#set(self::Class::E% #t1) → dynamic {
       #result#isSet = true;
-      return result = #t1;
+      return #result = #t1;
     }
     return #result#get.call();
   }
 }
 static method returnNonNullable(core::int value) → core::int {
-  core::int? result;
+  lowered core::int? #result;
   function #result#get() → core::int
-    return let final core::int? #t2 = result in #t2.==(null) ?{core::int} result = value : #t2{core::int};
+    return let final core::int? #t2 = #result in #t2.==(null) ?{core::int} #result = value : #t2{core::int};
   function #result#set(core::int #t3) → dynamic
-    return result = #t3;
+    return #result = #t3;
   return #result#get.call();
 }
 static method returnNullable(core::int? value) → core::int? {
-  core::int? result;
-  core::bool #result#isSet = false;
+  lowered core::int? #result;
+  lowered core::bool #result#isSet = false;
   function #result#get() → core::int? {
     if(!#result#isSet) {
-      result = value;
+      #result = value;
       #result#isSet = true;
     }
-    return result;
+    return #result;
   }
   function #result#set(core::int? #t4) → dynamic {
     #result#isSet = true;
-    return result = #t4;
+    return #result = #t4;
   }
   return #result#get.call();
 }
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
index 9db48a4..3270539 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
@@ -8,51 +8,51 @@
     : self::Class::field = field, super core::Object::•()
     ;
   method returnTypeVariable() → self::Class::E% {
-    self::Class::E? result;
-    core::bool #result#isSet = false;
+    lowered self::Class::E? #result;
+    lowered core::bool #result#isSet = false;
     function #result#get() → self::Class::E% {
       if(!#result#isSet) {
-        result = this.{self::Class::field};
+        #result = this.{self::Class::field};
         #result#isSet = true;
       }
-      return result{self::Class::E%};
+      return #result{self::Class::E%};
     }
     function #result#set(self::Class::E% #t1) → dynamic {
       #result#isSet = true;
-      return result = #t1;
+      return #result = #t1;
     }
     return #result#get.call();
   }
 }
 static method returnNonNullable(core::int value) → core::int {
-  core::int? result;
-  core::bool #result#isSet = false;
+  lowered core::int? #result;
+  lowered core::bool #result#isSet = false;
   function #result#get() → core::int {
     if(!#result#isSet) {
-      result = value;
+      #result = value;
       #result#isSet = true;
     }
-    return result{core::int};
+    return #result{core::int};
   }
   function #result#set(core::int #t2) → dynamic {
     #result#isSet = true;
-    return result = #t2;
+    return #result = #t2;
   }
   return #result#get.call();
 }
 static method returnNullable(core::int? value) → core::int? {
-  core::int? result;
-  core::bool #result#isSet = false;
+  lowered core::int? #result;
+  lowered core::bool #result#isSet = false;
   function #result#get() → core::int? {
     if(!#result#isSet) {
-      result = value;
+      #result = value;
       #result#isSet = true;
     }
-    return result;
+    return #result;
   }
   function #result#set(core::int? #t3) → dynamic {
     #result#isSet = true;
-    return result = #t3;
+    return #result = #t3;
   }
   return #result#get.call();
 }
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
index 9db48a4..3270539 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
@@ -8,51 +8,51 @@
     : self::Class::field = field, super core::Object::•()
     ;
   method returnTypeVariable() → self::Class::E% {
-    self::Class::E? result;
-    core::bool #result#isSet = false;
+    lowered self::Class::E? #result;
+    lowered core::bool #result#isSet = false;
     function #result#get() → self::Class::E% {
       if(!#result#isSet) {
-        result = this.{self::Class::field};
+        #result = this.{self::Class::field};
         #result#isSet = true;
       }
-      return result{self::Class::E%};
+      return #result{self::Class::E%};
     }
     function #result#set(self::Class::E% #t1) → dynamic {
       #result#isSet = true;
-      return result = #t1;
+      return #result = #t1;
     }
     return #result#get.call();
   }
 }
 static method returnNonNullable(core::int value) → core::int {
-  core::int? result;
-  core::bool #result#isSet = false;
+  lowered core::int? #result;
+  lowered core::bool #result#isSet = false;
   function #result#get() → core::int {
     if(!#result#isSet) {
-      result = value;
+      #result = value;
       #result#isSet = true;
     }
-    return result{core::int};
+    return #result{core::int};
   }
   function #result#set(core::int #t2) → dynamic {
     #result#isSet = true;
-    return result = #t2;
+    return #result = #t2;
   }
   return #result#get.call();
 }
 static method returnNullable(core::int? value) → core::int? {
-  core::int? result;
-  core::bool #result#isSet = false;
+  lowered core::int? #result;
+  lowered core::bool #result#isSet = false;
   function #result#get() → core::int? {
     if(!#result#isSet) {
-      result = value;
+      #result = value;
       #result#isSet = true;
     }
-    return result;
+    return #result;
   }
   function #result#set(core::int? #t3) → dynamic {
     #result#isSet = true;
-    return result = #t3;
+    return #result = #t3;
   }
   return #result#get.call();
 }
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/folder.options b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/folder.options
new file mode 100644
index 0000000..d9c5c2f
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/folder.options
@@ -0,0 +1 @@
+--force-late-lowering=0xEFFF
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart
new file mode 100644
index 0000000..b5a6079
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A declaration for each kind of late field/local lowering enabled by
+// target bitmask.
+
+main() {}
+
+method() {
+  late int? nullableUninitializedNonFinalLocal;
+  late int nonNullableUninitializedNonFinalLocal;
+  late final int? nullableUninitializedFinalLocal;
+  late final int nonNullableUninitializedFinalLocal;
+  late int? nullableInitializedNonFinalLocal = 0;
+  late int nonNullableInitializedNonFinalLocal = 0;
+  late final int? nullableInitializedFinalLocal = 0;
+  late final int nonNullableInitializedFinalLocal = 0;
+}
+
+late int uninitializedNonFinalTopLevelField;
+late final int uninitializedFinalTopLevelField;
+late int initializedNonFinalTopLevelField = 0;
+late final int initializedFinalTopLevelField = 0;
+
+class Class {
+  static late int uninitializedNonFinalStaticField;
+  static late final int uninitializedFinalStaticField;
+  static late int initializedNonFinalStaticField = 0;
+  static late final int initializedFinalStaticField = 0;
+
+  late int uninitializedNonFinalInstanceField;
+  late final int uninitializedFinalInstanceField;
+  late int initializedNonFinalInstanceField = 0;
+  late final int initializedFinalInstanceField = 0;
+}
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.outline.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.outline.expect
new file mode 100644
index 0000000..b65cd70
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.outline.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField;
+  static field core::int? _#uninitializedFinalStaticField;
+  static field core::int? _#initializedNonFinalStaticField;
+  static field core::int? _#initializedFinalStaticField;
+  late field core::int uninitializedNonFinalInstanceField;
+  field core::int? _#Class#uninitializedFinalInstanceField;
+  field core::int? _#Class#initializedNonFinalInstanceField;
+  field core::int? _#Class#initializedFinalInstanceField;
+  synthetic constructor •() → self::Class
+    ;
+  static get uninitializedNonFinalStaticField() → core::int;
+  static set uninitializedNonFinalStaticField(core::int #t1) → void;
+  static get uninitializedFinalStaticField() → core::int;
+  static set uninitializedFinalStaticField(core::int #t2) → void;
+  static get initializedNonFinalStaticField() → core::int;
+  static set initializedNonFinalStaticField(core::int #t3) → void;
+  static get initializedFinalStaticField() → core::int;
+  get uninitializedFinalInstanceField() → core::int;
+  set uninitializedFinalInstanceField(core::int #t4) → void;
+  get initializedNonFinalInstanceField() → core::int;
+  set initializedNonFinalInstanceField(core::int #t5) → void;
+  get initializedFinalInstanceField() → core::int;
+}
+static field core::int? _#uninitializedNonFinalTopLevelField;
+static field core::int? _#uninitializedFinalTopLevelField;
+static field core::int? _#initializedNonFinalTopLevelField;
+static field core::int? _#initializedFinalTopLevelField;
+static method main() → dynamic
+  ;
+static method method() → dynamic
+  ;
+static get uninitializedNonFinalTopLevelField() → core::int;
+static set uninitializedNonFinalTopLevelField(core::int #t6) → void;
+static get uninitializedFinalTopLevelField() → core::int;
+static set uninitializedFinalTopLevelField(core::int #t7) → void;
+static get initializedNonFinalTopLevelField() → core::int;
+static set initializedNonFinalTopLevelField(core::int #t8) → void;
+static get initializedFinalTopLevelField() → core::int;
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect
new file mode 100644
index 0000000..74bb4fc
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect
@@ -0,0 +1,137 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::int? _#initializedFinalStaticField = null;
+  late field core::int uninitializedNonFinalInstanceField;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField") : #t1{core::int};
+  static set uninitializedNonFinalStaticField(core::int #t2) → void
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  static get uninitializedFinalStaticField() → core::int
+    return let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalStaticField") : #t3{core::int};
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField.==(null))
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+  static get initializedNonFinalStaticField() → core::int
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5.==(null) ?{core::int} self::Class::_#initializedNonFinalStaticField = 0 : #t5{core::int};
+  static set initializedNonFinalStaticField(core::int #t6) → void
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  static get initializedFinalStaticField() → core::int
+    return let final core::int? #t7 = self::Class::_#initializedFinalStaticField in #t7.==(null) ?{core::int} let final core::int #t8 = 0 in self::Class::_#initializedFinalStaticField.==(null) ?{core::int} self::Class::_#initializedFinalStaticField = #t8 : throw new _in::LateError::fieldADI("initializedFinalStaticField") : #t7{core::int};
+  get uninitializedFinalInstanceField() → core::int
+    return let final core::int? #t9 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t9.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalInstanceField") : #t9{core::int};
+  set uninitializedFinalInstanceField(core::int #t10) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField}.==(null))
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t10;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+  get initializedNonFinalInstanceField() → core::int
+    return let final core::int? #t11 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t11.==(null) ?{core::int} this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0 : #t11{core::int};
+  set initializedNonFinalInstanceField(core::int #t12) → void
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t12;
+  get initializedFinalInstanceField() → core::int
+    return let final core::int? #t13 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t13.==(null) ?{core::int} let final core::int #t14 = 0 in this.{self::Class::_#Class#initializedFinalInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#initializedFinalInstanceField} = #t14 : throw new _in::LateError::fieldADI("initializedFinalInstanceField") : #t13{core::int};
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::int? _#initializedFinalTopLevelField = null;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t15) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t15;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t16 = #nonNullableUninitializedNonFinalLocal in #t16.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal") : #t16{core::int};
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t17) → dynamic
+    return #nonNullableUninitializedNonFinalLocal = #t17;
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t18) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t18;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return let final core::int? #t19 = #nonNullableUninitializedFinalLocal in #t19.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal") : #t19{core::int};
+  function #nonNullableUninitializedFinalLocal#set(core::int #t20) → dynamic
+    if(#nonNullableUninitializedFinalLocal.==(null))
+      return #nonNullableUninitializedFinalLocal = #t20;
+    else
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t21) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t21;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t22 = #nonNullableInitializedNonFinalLocal in #t22.==(null) ?{core::int} #nonNullableInitializedNonFinalLocal = 0 : #t22{core::int};
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t23) → dynamic
+    return #nonNullableInitializedNonFinalLocal = #t23;
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t24 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t24;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  function #nonNullableInitializedFinalLocal#get() → core::int
+    return let final core::int? #t25 = #nonNullableInitializedFinalLocal in #t25.==(null) ?{core::int} let final core::int #t26 = 0 in #nonNullableInitializedFinalLocal.==(null) ?{core::int} #nonNullableInitializedFinalLocal = #t26 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t25{core::int};
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t27 = self::_#uninitializedNonFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t27{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t28) → void
+  self::_#uninitializedNonFinalTopLevelField = #t28;
+static get uninitializedFinalTopLevelField() → core::int
+  return let final core::int? #t29 = self::_#uninitializedFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t29{core::int};
+static set uninitializedFinalTopLevelField(core::int #t30) → void
+  if(self::_#uninitializedFinalTopLevelField.==(null))
+    self::_#uninitializedFinalTopLevelField = #t30;
+  else
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+static get initializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t31 = self::_#initializedNonFinalTopLevelField in #t31.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t31{core::int};
+static set initializedNonFinalTopLevelField(core::int #t32) → void
+  self::_#initializedNonFinalTopLevelField = #t32;
+static get initializedFinalTopLevelField() → core::int
+  return let final core::int? #t33 = self::_#initializedFinalTopLevelField in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t34 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t33{core::int};
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..64e9c55
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect
@@ -0,0 +1,145 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::int? _#initializedFinalStaticField = null;
+  late field core::int uninitializedNonFinalInstanceField;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField") : #t1{core::int};
+  static set uninitializedNonFinalStaticField(core::int #t2) → void
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  static get uninitializedFinalStaticField() → core::int
+    return let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalStaticField") : #t3{core::int};
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField.==(null))
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+  static get initializedNonFinalStaticField() → core::int
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5.==(null) ?{core::int} self::Class::_#initializedNonFinalStaticField = 0 : #t5{core::int};
+  static set initializedNonFinalStaticField(core::int #t6) → void
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  static get initializedFinalStaticField() → core::int
+    return let final core::int? #t7 = self::Class::_#initializedFinalStaticField in #t7.==(null) ?{core::int} let final core::int #t8 = 0 in self::Class::_#initializedFinalStaticField.==(null) ?{core::int} self::Class::_#initializedFinalStaticField = #t8 : throw new _in::LateError::fieldADI("initializedFinalStaticField") : #t7{core::int};
+  get uninitializedFinalInstanceField() → core::int
+    return let final core::int? #t9 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t9.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalInstanceField") : #t9{core::int};
+  set uninitializedFinalInstanceField(core::int #t10) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField}.==(null))
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t10;
+    else
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+  get initializedNonFinalInstanceField() → core::int
+    return let final core::int? #t11 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t11.==(null) ?{core::int} this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0 : #t11{core::int};
+  set initializedNonFinalInstanceField(core::int #t12) → void
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t12;
+  get initializedFinalInstanceField() → core::int
+    return let final core::int? #t13 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t13.==(null) ?{core::int} let final core::int #t14 = 0 in this.{self::Class::_#Class#initializedFinalInstanceField}.==(null) ?{core::int} this.{self::Class::_#Class#initializedFinalInstanceField} = #t14 : throw new _in::LateError::fieldADI("initializedFinalInstanceField") : #t13{core::int};
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::int? _#initializedFinalTopLevelField = null;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t15) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t15;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t16 = #nonNullableUninitializedNonFinalLocal in #t16.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal") : #t16{core::int};
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t17) → dynamic
+    return #nonNullableUninitializedNonFinalLocal = #t17;
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t18) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t18;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return let final core::int? #t19 = #nonNullableUninitializedFinalLocal in #t19.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal") : #t19{core::int};
+  function #nonNullableUninitializedFinalLocal#set(core::int #t20) → dynamic
+    if(#nonNullableUninitializedFinalLocal.==(null))
+      return #nonNullableUninitializedFinalLocal = #t20;
+    else
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t21) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t21;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int
+    return let final core::int? #t22 = #nonNullableInitializedNonFinalLocal in #t22.==(null) ?{core::int} #nonNullableInitializedNonFinalLocal = 0 : #t22{core::int};
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t23) → dynamic
+    return #nonNullableInitializedNonFinalLocal = #t23;
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t24 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t24;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  function #nonNullableInitializedFinalLocal#get() → core::int
+    return let final core::int? #t25 = #nonNullableInitializedFinalLocal in #t25.==(null) ?{core::int} let final core::int #t26 = 0 in #nonNullableInitializedFinalLocal.==(null) ?{core::int} #nonNullableInitializedFinalLocal = #t26 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t25{core::int};
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t27 = self::_#uninitializedNonFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t27{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t28) → void
+  self::_#uninitializedNonFinalTopLevelField = #t28;
+static get uninitializedFinalTopLevelField() → core::int
+  return let final core::int? #t29 = self::_#uninitializedFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t29{core::int};
+static set uninitializedFinalTopLevelField(core::int #t30) → void
+  if(self::_#uninitializedFinalTopLevelField.==(null))
+    self::_#uninitializedFinalTopLevelField = #t30;
+  else
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+static get initializedNonFinalTopLevelField() → core::int
+  return let final core::int? #t31 = self::_#initializedNonFinalTopLevelField in #t31.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t31{core::int};
+static set initializedNonFinalTopLevelField(core::int #t32) → void
+  self::_#initializedNonFinalTopLevelField = #t32;
+static get initializedFinalTopLevelField() → core::int
+  return let final core::int? #t33 = self::_#initializedFinalTopLevelField in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t34 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t33{core::int};
+
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:30:25 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:35:18 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:18:18 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:24:16 -> IntConstant(0)
+Extra constant evaluation: evaluated: 223, effectively constant: 4
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.textual_outline.expect
new file mode 100644
index 0000000..83c95c1
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+main() {}
+method() {}
+late int ;
+uninitializedNonFinalTopLevelField;
+late ;
+final int uninitializedFinalTopLevelField;
+late int ;
+initializedNonFinalTopLevelField = 0;
+late ;
+final int initializedFinalTopLevelField = 0;
+class Class {
+  static late int ;
+  uninitializedNonFinalStaticField;
+  static late ;
+  final int uninitializedFinalStaticField;
+  static late int ;
+  initializedNonFinalStaticField = 0;
+  static late ;
+  final int initializedFinalStaticField = 0;
+  late int ;
+  uninitializedNonFinalInstanceField;
+  late ;
+  final int uninitializedFinalInstanceField;
+  late int ;
+  initializedNonFinalInstanceField = 0;
+  late ;
+  final int initializedFinalInstanceField = 0;
+}
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect
new file mode 100644
index 0000000..079c847
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect
@@ -0,0 +1,226 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::bool _#uninitializedNonFinalStaticField#isSet = false;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::bool _#uninitializedFinalStaticField#isSet = false;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::bool _#initializedNonFinalStaticField#isSet = false;
+  static field core::int? _#initializedFinalStaticField = null;
+  static field core::bool _#initializedFinalStaticField#isSet = false;
+  late field core::int uninitializedNonFinalInstanceField;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::bool _#Class#uninitializedFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::bool _#Class#initializedNonFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  field core::bool _#Class#initializedFinalInstanceField#isSet = false;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return self::Class::_#uninitializedNonFinalStaticField#isSet ?{core::int} let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField");
+  static set uninitializedNonFinalStaticField(core::int #t2) → void {
+    self::Class::_#uninitializedNonFinalStaticField#isSet = true;
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  }
+  static get uninitializedFinalStaticField() → core::int
+    return self::Class::_#uninitializedFinalStaticField#isSet ?{core::int} let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalStaticField");
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField#isSet)
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+    else {
+      self::Class::_#uninitializedFinalStaticField#isSet = true;
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    }
+  static get initializedNonFinalStaticField() → core::int {
+    if(!self::Class::_#initializedNonFinalStaticField#isSet) {
+      self::Class::_#initializedNonFinalStaticField = 0;
+      self::Class::_#initializedNonFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5{core::int};
+  }
+  static set initializedNonFinalStaticField(core::int #t6) → void {
+    self::Class::_#initializedNonFinalStaticField#isSet = true;
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  }
+  static get initializedFinalStaticField() → core::int {
+    if(!self::Class::_#initializedFinalStaticField#isSet) {
+      final core::int #t7 = 0;
+      if(self::Class::_#initializedFinalStaticField#isSet)
+        throw new _in::LateError::fieldADI("initializedFinalStaticField");
+      self::Class::_#initializedFinalStaticField = #t7;
+      self::Class::_#initializedFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t8 = self::Class::_#initializedFinalStaticField in #t8{core::int};
+  }
+  get uninitializedFinalInstanceField() → core::int
+    return this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} ?{core::int} let final core::int? #t9 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t9{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalInstanceField");
+  set uninitializedFinalInstanceField(core::int #t10) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet})
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+    else {
+      this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} = true;
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t10;
+    }
+  get initializedNonFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet}) {
+      this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0;
+      this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t11 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t11{core::int};
+  }
+  set initializedNonFinalInstanceField(core::int #t12) → void {
+    this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t12;
+  }
+  get initializedFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedFinalInstanceField#isSet}) {
+      final core::int #t13 = 0;
+      if(this.{self::Class::_#Class#initializedFinalInstanceField#isSet})
+        throw new _in::LateError::fieldADI("initializedFinalInstanceField");
+      this.{self::Class::_#Class#initializedFinalInstanceField} = #t13;
+      this.{self::Class::_#Class#initializedFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t14 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t14{core::int};
+  }
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::bool _#uninitializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::bool _#uninitializedFinalTopLevelField#isSet = false;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::bool _#initializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#initializedFinalTopLevelField = null;
+static field core::bool _#initializedFinalTopLevelField#isSet = false;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t15) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t15;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  lowered core::bool #nonNullableUninitializedNonFinalLocal#isSet = false;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return #nonNullableUninitializedNonFinalLocal#isSet ?{core::int} #nonNullableUninitializedNonFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal");
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t16) → dynamic {
+    #nonNullableUninitializedNonFinalLocal#isSet = true;
+    return #nonNullableUninitializedNonFinalLocal = #t16;
+  }
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t17) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t17;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  lowered core::bool #nonNullableUninitializedFinalLocal#isSet = false;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return #nonNullableUninitializedFinalLocal#isSet ?{core::int} #nonNullableUninitializedFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal");
+  function #nonNullableUninitializedFinalLocal#set(core::int #t18) → dynamic
+    if(#nonNullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+    else {
+      #nonNullableUninitializedFinalLocal#isSet = true;
+      return #nonNullableUninitializedFinalLocal = #t18;
+    }
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t19) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t19;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  lowered core::bool #nonNullableInitializedNonFinalLocal#isSet = false;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedNonFinalLocal#isSet) {
+      #nonNullableInitializedNonFinalLocal = 0;
+      #nonNullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedNonFinalLocal{core::int};
+  }
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t20) → dynamic {
+    #nonNullableInitializedNonFinalLocal#isSet = true;
+    return #nonNullableInitializedNonFinalLocal = #t20;
+  }
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t21 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t21;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  lowered core::bool #nonNullableInitializedFinalLocal#isSet = false;
+  function #nonNullableInitializedFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedFinalLocal#isSet) {
+      final core::int #t22 = 0;
+      if(#nonNullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+      #nonNullableInitializedFinalLocal = #t22;
+      #nonNullableInitializedFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedFinalLocal{core::int};
+  }
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedNonFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t24) → void {
+  self::_#uninitializedNonFinalTopLevelField#isSet = true;
+  self::_#uninitializedNonFinalTopLevelField = #t24;
+}
+static get uninitializedFinalTopLevelField() → core::int
+  return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t26) → void
+  if(self::_#uninitializedFinalTopLevelField#isSet)
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+  else {
+    self::_#uninitializedFinalTopLevelField#isSet = true;
+    self::_#uninitializedFinalTopLevelField = #t26;
+  }
+static get initializedNonFinalTopLevelField() → core::int {
+  if(!self::_#initializedNonFinalTopLevelField#isSet) {
+    self::_#initializedNonFinalTopLevelField = 0;
+    self::_#initializedNonFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t27 = self::_#initializedNonFinalTopLevelField in #t27{core::int};
+}
+static set initializedNonFinalTopLevelField(core::int #t28) → void {
+  self::_#initializedNonFinalTopLevelField#isSet = true;
+  self::_#initializedNonFinalTopLevelField = #t28;
+}
+static get initializedFinalTopLevelField() → core::int {
+  if(!self::_#initializedFinalTopLevelField#isSet) {
+    final core::int #t29 = 0;
+    if(self::_#initializedFinalTopLevelField#isSet)
+      throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
+    self::_#initializedFinalTopLevelField = #t29;
+    self::_#initializedFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t30 = self::_#initializedFinalTopLevelField in #t30{core::int};
+}
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..079c847
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect
@@ -0,0 +1,226 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Class extends core::Object {
+  static field core::int? _#uninitializedNonFinalStaticField = null;
+  static field core::bool _#uninitializedNonFinalStaticField#isSet = false;
+  static field core::int? _#uninitializedFinalStaticField = null;
+  static field core::bool _#uninitializedFinalStaticField#isSet = false;
+  static field core::int? _#initializedNonFinalStaticField = null;
+  static field core::bool _#initializedNonFinalStaticField#isSet = false;
+  static field core::int? _#initializedFinalStaticField = null;
+  static field core::bool _#initializedFinalStaticField#isSet = false;
+  late field core::int uninitializedNonFinalInstanceField;
+  field core::int? _#Class#uninitializedFinalInstanceField = null;
+  field core::bool _#Class#uninitializedFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedNonFinalInstanceField = null;
+  field core::bool _#Class#initializedNonFinalInstanceField#isSet = false;
+  field core::int? _#Class#initializedFinalInstanceField = null;
+  field core::bool _#Class#initializedFinalInstanceField#isSet = false;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  static get uninitializedNonFinalStaticField() → core::int
+    return self::Class::_#uninitializedNonFinalStaticField#isSet ?{core::int} let final core::int? #t1 = self::Class::_#uninitializedNonFinalStaticField in #t1{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalStaticField");
+  static set uninitializedNonFinalStaticField(core::int #t2) → void {
+    self::Class::_#uninitializedNonFinalStaticField#isSet = true;
+    self::Class::_#uninitializedNonFinalStaticField = #t2;
+  }
+  static get uninitializedFinalStaticField() → core::int
+    return self::Class::_#uninitializedFinalStaticField#isSet ?{core::int} let final core::int? #t3 = self::Class::_#uninitializedFinalStaticField in #t3{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalStaticField");
+  static set uninitializedFinalStaticField(core::int #t4) → void
+    if(self::Class::_#uninitializedFinalStaticField#isSet)
+      throw new _in::LateError::fieldAI("uninitializedFinalStaticField");
+    else {
+      self::Class::_#uninitializedFinalStaticField#isSet = true;
+      self::Class::_#uninitializedFinalStaticField = #t4;
+    }
+  static get initializedNonFinalStaticField() → core::int {
+    if(!self::Class::_#initializedNonFinalStaticField#isSet) {
+      self::Class::_#initializedNonFinalStaticField = 0;
+      self::Class::_#initializedNonFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t5 = self::Class::_#initializedNonFinalStaticField in #t5{core::int};
+  }
+  static set initializedNonFinalStaticField(core::int #t6) → void {
+    self::Class::_#initializedNonFinalStaticField#isSet = true;
+    self::Class::_#initializedNonFinalStaticField = #t6;
+  }
+  static get initializedFinalStaticField() → core::int {
+    if(!self::Class::_#initializedFinalStaticField#isSet) {
+      final core::int #t7 = 0;
+      if(self::Class::_#initializedFinalStaticField#isSet)
+        throw new _in::LateError::fieldADI("initializedFinalStaticField");
+      self::Class::_#initializedFinalStaticField = #t7;
+      self::Class::_#initializedFinalStaticField#isSet = true;
+    }
+    return let final core::int? #t8 = self::Class::_#initializedFinalStaticField in #t8{core::int};
+  }
+  get uninitializedFinalInstanceField() → core::int
+    return this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} ?{core::int} let final core::int? #t9 = this.{self::Class::_#Class#uninitializedFinalInstanceField} in #t9{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalInstanceField");
+  set uninitializedFinalInstanceField(core::int #t10) → void
+    if(this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet})
+      throw new _in::LateError::fieldAI("uninitializedFinalInstanceField");
+    else {
+      this.{self::Class::_#Class#uninitializedFinalInstanceField#isSet} = true;
+      this.{self::Class::_#Class#uninitializedFinalInstanceField} = #t10;
+    }
+  get initializedNonFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet}) {
+      this.{self::Class::_#Class#initializedNonFinalInstanceField} = 0;
+      this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t11 = this.{self::Class::_#Class#initializedNonFinalInstanceField} in #t11{core::int};
+  }
+  set initializedNonFinalInstanceField(core::int #t12) → void {
+    this.{self::Class::_#Class#initializedNonFinalInstanceField#isSet} = true;
+    this.{self::Class::_#Class#initializedNonFinalInstanceField} = #t12;
+  }
+  get initializedFinalInstanceField() → core::int {
+    if(!this.{self::Class::_#Class#initializedFinalInstanceField#isSet}) {
+      final core::int #t13 = 0;
+      if(this.{self::Class::_#Class#initializedFinalInstanceField#isSet})
+        throw new _in::LateError::fieldADI("initializedFinalInstanceField");
+      this.{self::Class::_#Class#initializedFinalInstanceField} = #t13;
+      this.{self::Class::_#Class#initializedFinalInstanceField#isSet} = true;
+    }
+    return let final core::int? #t14 = this.{self::Class::_#Class#initializedFinalInstanceField} in #t14{core::int};
+  }
+}
+static field core::int? _#uninitializedNonFinalTopLevelField = null;
+static field core::bool _#uninitializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#uninitializedFinalTopLevelField = null;
+static field core::bool _#uninitializedFinalTopLevelField#isSet = false;
+static field core::int? _#initializedNonFinalTopLevelField = null;
+static field core::bool _#initializedNonFinalTopLevelField#isSet = false;
+static field core::int? _#initializedFinalTopLevelField = null;
+static field core::bool _#initializedFinalTopLevelField#isSet = false;
+static method main() → dynamic {}
+static method method() → dynamic {
+  lowered core::int? #nullableUninitializedNonFinalLocal;
+  lowered core::bool #nullableUninitializedNonFinalLocal#isSet = false;
+  function #nullableUninitializedNonFinalLocal#get() → core::int?
+    return #nullableUninitializedNonFinalLocal#isSet ?{core::int?} #nullableUninitializedNonFinalLocal : throw new _in::LateError::localNI("nullableUninitializedNonFinalLocal");
+  function #nullableUninitializedNonFinalLocal#set(core::int? #t15) → dynamic {
+    #nullableUninitializedNonFinalLocal#isSet = true;
+    return #nullableUninitializedNonFinalLocal = #t15;
+  }
+  lowered core::int? #nonNullableUninitializedNonFinalLocal;
+  lowered core::bool #nonNullableUninitializedNonFinalLocal#isSet = false;
+  function #nonNullableUninitializedNonFinalLocal#get() → core::int
+    return #nonNullableUninitializedNonFinalLocal#isSet ?{core::int} #nonNullableUninitializedNonFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedNonFinalLocal");
+  function #nonNullableUninitializedNonFinalLocal#set(core::int #t16) → dynamic {
+    #nonNullableUninitializedNonFinalLocal#isSet = true;
+    return #nonNullableUninitializedNonFinalLocal = #t16;
+  }
+  lowered final core::int? #nullableUninitializedFinalLocal;
+  lowered core::bool #nullableUninitializedFinalLocal#isSet = false;
+  function #nullableUninitializedFinalLocal#get() → core::int?
+    return #nullableUninitializedFinalLocal#isSet ?{core::int?} #nullableUninitializedFinalLocal : throw new _in::LateError::localNI("nullableUninitializedFinalLocal");
+  function #nullableUninitializedFinalLocal#set(core::int? #t17) → dynamic
+    if(#nullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nullableUninitializedFinalLocal");
+    else {
+      #nullableUninitializedFinalLocal#isSet = true;
+      return #nullableUninitializedFinalLocal = #t17;
+    }
+  lowered final core::int? #nonNullableUninitializedFinalLocal;
+  lowered core::bool #nonNullableUninitializedFinalLocal#isSet = false;
+  function #nonNullableUninitializedFinalLocal#get() → core::int
+    return #nonNullableUninitializedFinalLocal#isSet ?{core::int} #nonNullableUninitializedFinalLocal{core::int} : throw new _in::LateError::localNI("nonNullableUninitializedFinalLocal");
+  function #nonNullableUninitializedFinalLocal#set(core::int #t18) → dynamic
+    if(#nonNullableUninitializedFinalLocal#isSet)
+      throw new _in::LateError::localAI("nonNullableUninitializedFinalLocal");
+    else {
+      #nonNullableUninitializedFinalLocal#isSet = true;
+      return #nonNullableUninitializedFinalLocal = #t18;
+    }
+  lowered core::int? #nullableInitializedNonFinalLocal;
+  lowered core::bool #nullableInitializedNonFinalLocal#isSet = false;
+  function #nullableInitializedNonFinalLocal#get() → core::int? {
+    if(!#nullableInitializedNonFinalLocal#isSet) {
+      #nullableInitializedNonFinalLocal = 0;
+      #nullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nullableInitializedNonFinalLocal;
+  }
+  function #nullableInitializedNonFinalLocal#set(core::int? #t19) → dynamic {
+    #nullableInitializedNonFinalLocal#isSet = true;
+    return #nullableInitializedNonFinalLocal = #t19;
+  }
+  lowered core::int? #nonNullableInitializedNonFinalLocal;
+  lowered core::bool #nonNullableInitializedNonFinalLocal#isSet = false;
+  function #nonNullableInitializedNonFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedNonFinalLocal#isSet) {
+      #nonNullableInitializedNonFinalLocal = 0;
+      #nonNullableInitializedNonFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedNonFinalLocal{core::int};
+  }
+  function #nonNullableInitializedNonFinalLocal#set(core::int #t20) → dynamic {
+    #nonNullableInitializedNonFinalLocal#isSet = true;
+    return #nonNullableInitializedNonFinalLocal = #t20;
+  }
+  lowered final core::int? #nullableInitializedFinalLocal;
+  lowered core::bool #nullableInitializedFinalLocal#isSet = false;
+  function #nullableInitializedFinalLocal#get() → core::int? {
+    if(!#nullableInitializedFinalLocal#isSet) {
+      final core::int? #t21 = 0;
+      if(#nullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+      #nullableInitializedFinalLocal = #t21;
+      #nullableInitializedFinalLocal#isSet = true;
+    }
+    return #nullableInitializedFinalLocal;
+  }
+  lowered final core::int? #nonNullableInitializedFinalLocal;
+  lowered core::bool #nonNullableInitializedFinalLocal#isSet = false;
+  function #nonNullableInitializedFinalLocal#get() → core::int {
+    if(!#nonNullableInitializedFinalLocal#isSet) {
+      final core::int #t22 = 0;
+      if(#nonNullableInitializedFinalLocal#isSet)
+        throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+      #nonNullableInitializedFinalLocal = #t22;
+      #nonNullableInitializedFinalLocal#isSet = true;
+    }
+    return #nonNullableInitializedFinalLocal{core::int};
+  }
+}
+static get uninitializedNonFinalTopLevelField() → core::int
+  return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedNonFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t24) → void {
+  self::_#uninitializedNonFinalTopLevelField#isSet = true;
+  self::_#uninitializedNonFinalTopLevelField = #t24;
+}
+static get uninitializedFinalTopLevelField() → core::int
+  return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t26) → void
+  if(self::_#uninitializedFinalTopLevelField#isSet)
+    throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
+  else {
+    self::_#uninitializedFinalTopLevelField#isSet = true;
+    self::_#uninitializedFinalTopLevelField = #t26;
+  }
+static get initializedNonFinalTopLevelField() → core::int {
+  if(!self::_#initializedNonFinalTopLevelField#isSet) {
+    self::_#initializedNonFinalTopLevelField = 0;
+    self::_#initializedNonFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t27 = self::_#initializedNonFinalTopLevelField in #t27{core::int};
+}
+static set initializedNonFinalTopLevelField(core::int #t28) → void {
+  self::_#initializedNonFinalTopLevelField#isSet = true;
+  self::_#initializedNonFinalTopLevelField = #t28;
+}
+static get initializedFinalTopLevelField() → core::int {
+  if(!self::_#initializedFinalTopLevelField#isSet) {
+    final core::int #t29 = 0;
+    if(self::_#initializedFinalTopLevelField#isSet)
+      throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
+    self::_#initializedFinalTopLevelField = #t29;
+    self::_#initializedFinalTopLevelField#isSet = true;
+  }
+  return let final core::int? #t30 = self::_#initializedFinalTopLevelField in #t30{core::int};
+}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart
index 3434c11..fac3e32 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart
@@ -10,5 +10,6 @@
 late final int nonNullableFinalTopLevelField;
 late final int? nullableFinalTopLevelFieldWithInitializer = null;
 late final int nonNullableFinalTopLevelFieldWithInitializer = 0;
+late Never neverTopLevelField;
 
 main() {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.outline.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.outline.expect
index 98525c7..f88db33 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.outline.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.outline.expect
@@ -10,6 +10,7 @@
 static field core::int? _#nonNullableFinalTopLevelField;
 static field core::int? _#nullableFinalTopLevelFieldWithInitializer;
 static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer;
+static field Never? _#neverTopLevelField;
 static get nullableTopLevelField() → core::int?;
 static set nullableTopLevelField(core::int? #t1) → void;
 static get nonNullableTopLevelField() → core::int;
@@ -24,5 +25,7 @@
 static set nonNullableFinalTopLevelField(core::int #t6) → void;
 static get nullableFinalTopLevelFieldWithInitializer() → core::int?;
 static get nonNullableFinalTopLevelFieldWithInitializer() → core::int;
+static get neverTopLevelField() → Never;
+static set neverTopLevelField(Never #t7) → void;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.expect
index 5b254e4..007c84a 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.expect
@@ -11,6 +11,7 @@
 static field core::int? _#nonNullableFinalTopLevelField = null;
 static field core::int? _#nullableFinalTopLevelFieldWithInitializer = _in::createSentinel<core::int?>();
 static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer = null;
+static field Never? _#neverTopLevelField = null;
 static get nullableTopLevelField() → core::int?
   return let final core::int? #t1 = self::_#nullableTopLevelField in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::fieldNI("nullableTopLevelField") : #t1{core::int?};
 static set nullableTopLevelField(core::int? #t2) → void
@@ -45,4 +46,8 @@
   return let final core::int? #t13 = self::_#nullableFinalTopLevelFieldWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(self::_#nullableFinalTopLevelFieldWithInitializer) ?{core::int?} self::_#nullableFinalTopLevelFieldWithInitializer = #t14 : throw new _in::LateError::fieldADI("nullableFinalTopLevelFieldWithInitializer") : #t13;
 static get nonNullableFinalTopLevelFieldWithInitializer() → core::int
   return let final core::int? #t15 = self::_#nonNullableFinalTopLevelFieldWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in self::_#nonNullableFinalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#nonNullableFinalTopLevelFieldWithInitializer = #t16 : throw new _in::LateError::fieldADI("nonNullableFinalTopLevelFieldWithInitializer") : #t15{core::int};
+static get neverTopLevelField() → Never
+  return let final Never? #t17 = self::_#neverTopLevelField in #t17.==(null) ?{Never} throw new _in::LateError::fieldNI("neverTopLevelField") : #t17{Never};
+static set neverTopLevelField(Never #t18) → void
+  self::_#neverTopLevelField = #t18;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.transformed.expect
index 0a63f7d..6713a38 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.strong.transformed.expect
@@ -11,6 +11,7 @@
 static field core::int? _#nonNullableFinalTopLevelField = null;
 static field core::int? _#nullableFinalTopLevelFieldWithInitializer = _in::createSentinel<core::int?>();
 static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer = null;
+static field Never? _#neverTopLevelField = null;
 static get nullableTopLevelField() → core::int?
   return let final core::int? #t1 = self::_#nullableTopLevelField in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::fieldNI("nullableTopLevelField") : #t1{core::int?};
 static set nullableTopLevelField(core::int? #t2) → void
@@ -45,10 +46,14 @@
   return let final core::int? #t13 = self::_#nullableFinalTopLevelFieldWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(self::_#nullableFinalTopLevelFieldWithInitializer) ?{core::int?} self::_#nullableFinalTopLevelFieldWithInitializer = #t14 : throw new _in::LateError::fieldADI("nullableFinalTopLevelFieldWithInitializer") : #t13;
 static get nonNullableFinalTopLevelFieldWithInitializer() → core::int
   return let final core::int? #t15 = self::_#nonNullableFinalTopLevelFieldWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in self::_#nonNullableFinalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#nonNullableFinalTopLevelFieldWithInitializer = #t16 : throw new _in::LateError::fieldADI("nonNullableFinalTopLevelFieldWithInitializer") : #t15{core::int};
+static get neverTopLevelField() → Never
+  return let final Never? #t17 = self::_#neverTopLevelField in #t17.==(null) ?{Never} throw new _in::LateError::fieldNI("neverTopLevelField") : #t17{Never};
+static set neverTopLevelField(Never #t18) → void
+  self::_#neverTopLevelField = #t18;
 static method main() → dynamic {}
 
 
 Extra constant evaluation status:
 Evaluated: VariableGet @ org-dartlang-testcase:///late_fields.dart:11:17 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///late_fields.dart:12:16 -> IntConstant(0)
-Extra constant evaluation: evaluated: 98, effectively constant: 2
+Extra constant evaluation: evaluated: 108, effectively constant: 2
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.textual_outline.expect
index 34e9a83..521d4d6 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.textual_outline.expect
@@ -16,4 +16,6 @@
 final int? nullableFinalTopLevelFieldWithInitializer = null;
 late ;
 final int nonNullableFinalTopLevelFieldWithInitializer = 0;
+late Never ;
+neverTopLevelField;
 main() {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.expect
index 5b254e4..c037d72 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.expect
@@ -4,19 +4,20 @@
 import "dart:_internal" as _in;
 
 static field core::int? _#nullableTopLevelField = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableTopLevelField = null;
+static field core::int? _#nonNullableTopLevelField = _in::createSentinel<core::int>();
 static field core::int? _#nullableTopLevelFieldWithInitializer = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableTopLevelFieldWithInitializer = null;
+static field core::int? _#nonNullableTopLevelFieldWithInitializer = _in::createSentinel<core::int>();
 static field core::int? _#nullableFinalTopLevelField = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableFinalTopLevelField = null;
+static field core::int? _#nonNullableFinalTopLevelField = _in::createSentinel<core::int>();
 static field core::int? _#nullableFinalTopLevelFieldWithInitializer = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer = null;
+static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer = _in::createSentinel<core::int>();
+static field Never? _#neverTopLevelField = _in::createSentinel<Never>();
 static get nullableTopLevelField() → core::int?
   return let final core::int? #t1 = self::_#nullableTopLevelField in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::fieldNI("nullableTopLevelField") : #t1{core::int?};
 static set nullableTopLevelField(core::int? #t2) → void
   self::_#nullableTopLevelField = #t2;
 static get nonNullableTopLevelField() → core::int
-  return let final core::int? #t3 = self::_#nonNullableTopLevelField in #t3.==(null) ?{core::int} throw new _in::LateError::fieldNI("nonNullableTopLevelField") : #t3{core::int};
+  return let final core::int? #t3 = self::_#nonNullableTopLevelField in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::fieldNI("nonNullableTopLevelField") : #t3{core::int};
 static set nonNullableTopLevelField(core::int #t4) → void
   self::_#nonNullableTopLevelField = #t4;
 static get nullableTopLevelFieldWithInitializer() → core::int?
@@ -24,7 +25,7 @@
 static set nullableTopLevelFieldWithInitializer(core::int? #t6) → void
   self::_#nullableTopLevelFieldWithInitializer = #t6;
 static get nonNullableTopLevelFieldWithInitializer() → core::int
-  return let final core::int? #t7 = self::_#nonNullableTopLevelFieldWithInitializer in #t7.==(null) ?{core::int} self::_#nonNullableTopLevelFieldWithInitializer = 0 : #t7{core::int};
+  return let final core::int? #t7 = self::_#nonNullableTopLevelFieldWithInitializer in _in::isSentinel(#t7) ?{core::int} self::_#nonNullableTopLevelFieldWithInitializer = 0 : #t7{core::int};
 static set nonNullableTopLevelFieldWithInitializer(core::int #t8) → void
   self::_#nonNullableTopLevelFieldWithInitializer = #t8;
 static get nullableFinalTopLevelField() → core::int?
@@ -35,14 +36,18 @@
   else
     throw new _in::LateError::fieldAI("nullableFinalTopLevelField");
 static get nonNullableFinalTopLevelField() → core::int
-  return let final core::int? #t11 = self::_#nonNullableFinalTopLevelField in #t11.==(null) ?{core::int} throw new _in::LateError::fieldNI("nonNullableFinalTopLevelField") : #t11{core::int};
+  return let final core::int? #t11 = self::_#nonNullableFinalTopLevelField in _in::isSentinel(#t11) ?{core::int} throw new _in::LateError::fieldNI("nonNullableFinalTopLevelField") : #t11{core::int};
 static set nonNullableFinalTopLevelField(core::int #t12) → void
-  if(self::_#nonNullableFinalTopLevelField.==(null))
+  if(_in::isSentinel(self::_#nonNullableFinalTopLevelField))
     self::_#nonNullableFinalTopLevelField = #t12;
   else
     throw new _in::LateError::fieldAI("nonNullableFinalTopLevelField");
 static get nullableFinalTopLevelFieldWithInitializer() → core::int?
   return let final core::int? #t13 = self::_#nullableFinalTopLevelFieldWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(self::_#nullableFinalTopLevelFieldWithInitializer) ?{core::int?} self::_#nullableFinalTopLevelFieldWithInitializer = #t14 : throw new _in::LateError::fieldADI("nullableFinalTopLevelFieldWithInitializer") : #t13;
 static get nonNullableFinalTopLevelFieldWithInitializer() → core::int
-  return let final core::int? #t15 = self::_#nonNullableFinalTopLevelFieldWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in self::_#nonNullableFinalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#nonNullableFinalTopLevelFieldWithInitializer = #t16 : throw new _in::LateError::fieldADI("nonNullableFinalTopLevelFieldWithInitializer") : #t15{core::int};
+  return let final core::int #t15 = self::_#nonNullableFinalTopLevelFieldWithInitializer in _in::isSentinel(#t15) ?{core::int} let final core::int #t16 = 0 in _in::isSentinel(self::_#nonNullableFinalTopLevelFieldWithInitializer) ?{core::int} self::_#nonNullableFinalTopLevelFieldWithInitializer = #t16 : throw new _in::LateError::fieldADI("nonNullableFinalTopLevelFieldWithInitializer") : #t15;
+static get neverTopLevelField() → Never
+  return let final Never? #t17 = self::_#neverTopLevelField in _in::isSentinel(#t17) ?{Never} throw new _in::LateError::fieldNI("neverTopLevelField") : #t17{Never};
+static set neverTopLevelField(Never #t18) → void
+  self::_#neverTopLevelField = #t18;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.transformed.expect
index 0a63f7d..24976f8 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_fields.dart.weak.transformed.expect
@@ -4,19 +4,20 @@
 import "dart:_internal" as _in;
 
 static field core::int? _#nullableTopLevelField = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableTopLevelField = null;
+static field core::int? _#nonNullableTopLevelField = _in::createSentinel<core::int>();
 static field core::int? _#nullableTopLevelFieldWithInitializer = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableTopLevelFieldWithInitializer = null;
+static field core::int? _#nonNullableTopLevelFieldWithInitializer = _in::createSentinel<core::int>();
 static field core::int? _#nullableFinalTopLevelField = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableFinalTopLevelField = null;
+static field core::int? _#nonNullableFinalTopLevelField = _in::createSentinel<core::int>();
 static field core::int? _#nullableFinalTopLevelFieldWithInitializer = _in::createSentinel<core::int?>();
-static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer = null;
+static field core::int? _#nonNullableFinalTopLevelFieldWithInitializer = _in::createSentinel<core::int>();
+static field Never? _#neverTopLevelField = _in::createSentinel<Never>();
 static get nullableTopLevelField() → core::int?
   return let final core::int? #t1 = self::_#nullableTopLevelField in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::fieldNI("nullableTopLevelField") : #t1{core::int?};
 static set nullableTopLevelField(core::int? #t2) → void
   self::_#nullableTopLevelField = #t2;
 static get nonNullableTopLevelField() → core::int
-  return let final core::int? #t3 = self::_#nonNullableTopLevelField in #t3.==(null) ?{core::int} throw new _in::LateError::fieldNI("nonNullableTopLevelField") : #t3{core::int};
+  return let final core::int? #t3 = self::_#nonNullableTopLevelField in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::fieldNI("nonNullableTopLevelField") : #t3{core::int};
 static set nonNullableTopLevelField(core::int #t4) → void
   self::_#nonNullableTopLevelField = #t4;
 static get nullableTopLevelFieldWithInitializer() → core::int?
@@ -24,7 +25,7 @@
 static set nullableTopLevelFieldWithInitializer(core::int? #t6) → void
   self::_#nullableTopLevelFieldWithInitializer = #t6;
 static get nonNullableTopLevelFieldWithInitializer() → core::int
-  return let final core::int? #t7 = self::_#nonNullableTopLevelFieldWithInitializer in #t7.==(null) ?{core::int} self::_#nonNullableTopLevelFieldWithInitializer = 0 : #t7{core::int};
+  return let final core::int? #t7 = self::_#nonNullableTopLevelFieldWithInitializer in _in::isSentinel(#t7) ?{core::int} self::_#nonNullableTopLevelFieldWithInitializer = 0 : #t7{core::int};
 static set nonNullableTopLevelFieldWithInitializer(core::int #t8) → void
   self::_#nonNullableTopLevelFieldWithInitializer = #t8;
 static get nullableFinalTopLevelField() → core::int?
@@ -35,20 +36,24 @@
   else
     throw new _in::LateError::fieldAI("nullableFinalTopLevelField");
 static get nonNullableFinalTopLevelField() → core::int
-  return let final core::int? #t11 = self::_#nonNullableFinalTopLevelField in #t11.==(null) ?{core::int} throw new _in::LateError::fieldNI("nonNullableFinalTopLevelField") : #t11{core::int};
+  return let final core::int? #t11 = self::_#nonNullableFinalTopLevelField in _in::isSentinel(#t11) ?{core::int} throw new _in::LateError::fieldNI("nonNullableFinalTopLevelField") : #t11{core::int};
 static set nonNullableFinalTopLevelField(core::int #t12) → void
-  if(self::_#nonNullableFinalTopLevelField.==(null))
+  if(_in::isSentinel(self::_#nonNullableFinalTopLevelField))
     self::_#nonNullableFinalTopLevelField = #t12;
   else
     throw new _in::LateError::fieldAI("nonNullableFinalTopLevelField");
 static get nullableFinalTopLevelFieldWithInitializer() → core::int?
   return let final core::int? #t13 = self::_#nullableFinalTopLevelFieldWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(self::_#nullableFinalTopLevelFieldWithInitializer) ?{core::int?} self::_#nullableFinalTopLevelFieldWithInitializer = #t14 : throw new _in::LateError::fieldADI("nullableFinalTopLevelFieldWithInitializer") : #t13;
 static get nonNullableFinalTopLevelFieldWithInitializer() → core::int
-  return let final core::int? #t15 = self::_#nonNullableFinalTopLevelFieldWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in self::_#nonNullableFinalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#nonNullableFinalTopLevelFieldWithInitializer = #t16 : throw new _in::LateError::fieldADI("nonNullableFinalTopLevelFieldWithInitializer") : #t15{core::int};
+  return let final core::int #t15 = self::_#nonNullableFinalTopLevelFieldWithInitializer in _in::isSentinel(#t15) ?{core::int} let final core::int #t16 = 0 in _in::isSentinel(self::_#nonNullableFinalTopLevelFieldWithInitializer) ?{core::int} self::_#nonNullableFinalTopLevelFieldWithInitializer = #t16 : throw new _in::LateError::fieldADI("nonNullableFinalTopLevelFieldWithInitializer") : #t15;
+static get neverTopLevelField() → Never
+  return let final Never? #t17 = self::_#neverTopLevelField in _in::isSentinel(#t17) ?{Never} throw new _in::LateError::fieldNI("neverTopLevelField") : #t17{Never};
+static set neverTopLevelField(Never #t18) → void
+  self::_#neverTopLevelField = #t18;
 static method main() → dynamic {}
 
 
 Extra constant evaluation status:
 Evaluated: VariableGet @ org-dartlang-testcase:///late_fields.dart:11:17 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///late_fields.dart:12:16 -> IntConstant(0)
-Extra constant evaluation: evaluated: 98, effectively constant: 2
+Extra constant evaluation: evaluated: 113, effectively constant: 2
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart
index b0799a6..2f15de4 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart
@@ -11,6 +11,7 @@
   late final int nonNullableFinalTopLevelLocal;
   late final int? nullableFinalTopLevelLocalWithInitializer = null;
   late final int nonNullableFinalTopLevelLocalWithInitializer = 0;
+  late Never neverLocal;
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect
index d8369ba..729f30f 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect
@@ -4,47 +4,52 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic {
-  core::int? nullableTopLevelLocal = _in::createSentinel<core::int?>();
+  lowered core::int? #nullableTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocal#get() → core::int?
-    return let final core::int? #t1 = nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
+    return let final core::int? #t1 = #nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
   function #nullableTopLevelLocal#set(core::int? #t2) → dynamic
-    return nullableTopLevelLocal = #t2;
-  core::int? nonNullableTopLevelLocal;
+    return #nullableTopLevelLocal = #t2;
+  lowered core::int? #nonNullableTopLevelLocal;
   function #nonNullableTopLevelLocal#get() → core::int
-    return let final core::int? #t3 = nonNullableTopLevelLocal in #t3.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
+    return let final core::int? #t3 = #nonNullableTopLevelLocal in #t3.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
   function #nonNullableTopLevelLocal#set(core::int #t4) → dynamic
-    return nonNullableTopLevelLocal = #t4;
-  core::int? nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocal = #t4;
+  lowered core::int? #nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t5 = nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
+    return let final core::int? #t5 = #nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} #nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
   function #nullableTopLevelLocalWithInitializer#set(core::int? #t6) → dynamic
-    return nullableTopLevelLocalWithInitializer = #t6;
-  core::int? nonNullableTopLevelLocalWithInitializer;
+    return #nullableTopLevelLocalWithInitializer = #t6;
+  lowered core::int? #nonNullableTopLevelLocalWithInitializer;
   function #nonNullableTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t7 = nonNullableTopLevelLocalWithInitializer in #t7.==(null) ?{core::int} nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
+    return let final core::int? #t7 = #nonNullableTopLevelLocalWithInitializer in #t7.==(null) ?{core::int} #nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
   function #nonNullableTopLevelLocalWithInitializer#set(core::int #t8) → dynamic
-    return nonNullableTopLevelLocalWithInitializer = #t8;
-  final core::int? nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocalWithInitializer = #t8;
+  lowered final core::int? #nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocal#get() → core::int?
-    return let final core::int? #t9 = nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
+    return let final core::int? #t9 = #nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
   function #nullableFinalTopLevelLocal#set(core::int? #t10) → dynamic
-    if(_in::isSentinel(nullableFinalTopLevelLocal))
-      return nullableFinalTopLevelLocal = #t10;
+    if(_in::isSentinel(#nullableFinalTopLevelLocal))
+      return #nullableFinalTopLevelLocal = #t10;
     else
       throw new _in::LateError::localAI("nullableFinalTopLevelLocal");
-  final core::int? nonNullableFinalTopLevelLocal;
+  lowered final core::int? #nonNullableFinalTopLevelLocal;
   function #nonNullableFinalTopLevelLocal#get() → core::int
-    return let final core::int? #t11 = nonNullableFinalTopLevelLocal in #t11.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
+    return let final core::int? #t11 = #nonNullableFinalTopLevelLocal in #t11.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
   function #nonNullableFinalTopLevelLocal#set(core::int #t12) → dynamic
-    if(nonNullableFinalTopLevelLocal.==(null))
-      return nonNullableFinalTopLevelLocal = #t12;
+    if(#nonNullableFinalTopLevelLocal.==(null))
+      return #nonNullableFinalTopLevelLocal = #t12;
     else
       throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
-  final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+  lowered final core::int? #nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
-  final core::int? nonNullableFinalTopLevelLocalWithInitializer;
+    return let final core::int? #t13 = #nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(#nullableFinalTopLevelLocalWithInitializer) ?{core::int?} #nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
+  lowered final core::int? #nonNullableFinalTopLevelLocalWithInitializer;
   function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in #t14.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+    return let final core::int? #t15 = #nonNullableFinalTopLevelLocalWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in #nonNullableFinalTopLevelLocalWithInitializer.==(null) ?{core::int} #nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15{core::int};
+  lowered Null #neverLocal;
+  function #neverLocal#get() → Never
+    return let final Never? #t17 = #neverLocal in #t17.==(null) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+  function #neverLocal#set(Never #t18) → dynamic
+    return #neverLocal = #t18;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect
index d8369ba..28acc1d 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect
@@ -4,47 +4,58 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic {
-  core::int? nullableTopLevelLocal = _in::createSentinel<core::int?>();
+  lowered core::int? #nullableTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocal#get() → core::int?
-    return let final core::int? #t1 = nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
+    return let final core::int? #t1 = #nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
   function #nullableTopLevelLocal#set(core::int? #t2) → dynamic
-    return nullableTopLevelLocal = #t2;
-  core::int? nonNullableTopLevelLocal;
+    return #nullableTopLevelLocal = #t2;
+  lowered core::int? #nonNullableTopLevelLocal;
   function #nonNullableTopLevelLocal#get() → core::int
-    return let final core::int? #t3 = nonNullableTopLevelLocal in #t3.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
+    return let final core::int? #t3 = #nonNullableTopLevelLocal in #t3.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
   function #nonNullableTopLevelLocal#set(core::int #t4) → dynamic
-    return nonNullableTopLevelLocal = #t4;
-  core::int? nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocal = #t4;
+  lowered core::int? #nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t5 = nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
+    return let final core::int? #t5 = #nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} #nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
   function #nullableTopLevelLocalWithInitializer#set(core::int? #t6) → dynamic
-    return nullableTopLevelLocalWithInitializer = #t6;
-  core::int? nonNullableTopLevelLocalWithInitializer;
+    return #nullableTopLevelLocalWithInitializer = #t6;
+  lowered core::int? #nonNullableTopLevelLocalWithInitializer;
   function #nonNullableTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t7 = nonNullableTopLevelLocalWithInitializer in #t7.==(null) ?{core::int} nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
+    return let final core::int? #t7 = #nonNullableTopLevelLocalWithInitializer in #t7.==(null) ?{core::int} #nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
   function #nonNullableTopLevelLocalWithInitializer#set(core::int #t8) → dynamic
-    return nonNullableTopLevelLocalWithInitializer = #t8;
-  final core::int? nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocalWithInitializer = #t8;
+  lowered final core::int? #nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocal#get() → core::int?
-    return let final core::int? #t9 = nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
+    return let final core::int? #t9 = #nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
   function #nullableFinalTopLevelLocal#set(core::int? #t10) → dynamic
-    if(_in::isSentinel(nullableFinalTopLevelLocal))
-      return nullableFinalTopLevelLocal = #t10;
+    if(_in::isSentinel(#nullableFinalTopLevelLocal))
+      return #nullableFinalTopLevelLocal = #t10;
     else
       throw new _in::LateError::localAI("nullableFinalTopLevelLocal");
-  final core::int? nonNullableFinalTopLevelLocal;
+  lowered final core::int? #nonNullableFinalTopLevelLocal;
   function #nonNullableFinalTopLevelLocal#get() → core::int
-    return let final core::int? #t11 = nonNullableFinalTopLevelLocal in #t11.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
+    return let final core::int? #t11 = #nonNullableFinalTopLevelLocal in #t11.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
   function #nonNullableFinalTopLevelLocal#set(core::int #t12) → dynamic
-    if(nonNullableFinalTopLevelLocal.==(null))
-      return nonNullableFinalTopLevelLocal = #t12;
+    if(#nonNullableFinalTopLevelLocal.==(null))
+      return #nonNullableFinalTopLevelLocal = #t12;
     else
       throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
-  final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+  lowered final core::int? #nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
-  final core::int? nonNullableFinalTopLevelLocalWithInitializer;
+    return let final core::int? #t13 = #nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(#nullableFinalTopLevelLocalWithInitializer) ?{core::int?} #nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
+  lowered final core::int? #nonNullableFinalTopLevelLocalWithInitializer;
   function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in #t14.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+    return let final core::int? #t15 = #nonNullableFinalTopLevelLocalWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in #nonNullableFinalTopLevelLocalWithInitializer.==(null) ?{core::int} #nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15{core::int};
+  lowered Null #neverLocal;
+  function #neverLocal#get() → Never
+    return let final Never? #t17 = #neverLocal in #t17.==(null) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+  function #neverLocal#set(Never #t18) → dynamic
+    return #neverLocal = #t18;
 }
 static method main() → dynamic {}
+
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:12:19 -> NullConstant(null)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:13:18 -> IntConstant(0)
+Extra constant evaluation: evaluated: 108, effectively constant: 2
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect
index d8369ba..98019ae 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect
@@ -4,47 +4,52 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic {
-  core::int? nullableTopLevelLocal = _in::createSentinel<core::int?>();
+  lowered core::int? #nullableTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocal#get() → core::int?
-    return let final core::int? #t1 = nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
+    return let final core::int? #t1 = #nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
   function #nullableTopLevelLocal#set(core::int? #t2) → dynamic
-    return nullableTopLevelLocal = #t2;
-  core::int? nonNullableTopLevelLocal;
+    return #nullableTopLevelLocal = #t2;
+  lowered core::int? #nonNullableTopLevelLocal = _in::createSentinel<core::int>();
   function #nonNullableTopLevelLocal#get() → core::int
-    return let final core::int? #t3 = nonNullableTopLevelLocal in #t3.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
+    return let final core::int? #t3 = #nonNullableTopLevelLocal in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
   function #nonNullableTopLevelLocal#set(core::int #t4) → dynamic
-    return nonNullableTopLevelLocal = #t4;
-  core::int? nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocal = #t4;
+  lowered core::int? #nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t5 = nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
+    return let final core::int? #t5 = #nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} #nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
   function #nullableTopLevelLocalWithInitializer#set(core::int? #t6) → dynamic
-    return nullableTopLevelLocalWithInitializer = #t6;
-  core::int? nonNullableTopLevelLocalWithInitializer;
+    return #nullableTopLevelLocalWithInitializer = #t6;
+  lowered core::int? #nonNullableTopLevelLocalWithInitializer = _in::createSentinel<core::int>();
   function #nonNullableTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t7 = nonNullableTopLevelLocalWithInitializer in #t7.==(null) ?{core::int} nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
+    return let final core::int? #t7 = #nonNullableTopLevelLocalWithInitializer in _in::isSentinel(#t7) ?{core::int} #nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
   function #nonNullableTopLevelLocalWithInitializer#set(core::int #t8) → dynamic
-    return nonNullableTopLevelLocalWithInitializer = #t8;
-  final core::int? nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocalWithInitializer = #t8;
+  lowered final core::int? #nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocal#get() → core::int?
-    return let final core::int? #t9 = nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
+    return let final core::int? #t9 = #nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
   function #nullableFinalTopLevelLocal#set(core::int? #t10) → dynamic
-    if(_in::isSentinel(nullableFinalTopLevelLocal))
-      return nullableFinalTopLevelLocal = #t10;
+    if(_in::isSentinel(#nullableFinalTopLevelLocal))
+      return #nullableFinalTopLevelLocal = #t10;
     else
       throw new _in::LateError::localAI("nullableFinalTopLevelLocal");
-  final core::int? nonNullableFinalTopLevelLocal;
+  lowered final core::int? #nonNullableFinalTopLevelLocal = _in::createSentinel<core::int>();
   function #nonNullableFinalTopLevelLocal#get() → core::int
-    return let final core::int? #t11 = nonNullableFinalTopLevelLocal in #t11.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
+    return let final core::int? #t11 = #nonNullableFinalTopLevelLocal in _in::isSentinel(#t11) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
   function #nonNullableFinalTopLevelLocal#set(core::int #t12) → dynamic
-    if(nonNullableFinalTopLevelLocal.==(null))
-      return nonNullableFinalTopLevelLocal = #t12;
+    if(_in::isSentinel(#nonNullableFinalTopLevelLocal))
+      return #nonNullableFinalTopLevelLocal = #t12;
     else
       throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
-  final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+  lowered final core::int? #nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
-  final core::int? nonNullableFinalTopLevelLocalWithInitializer;
+    return let final core::int? #t13 = #nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(#nullableFinalTopLevelLocalWithInitializer) ?{core::int?} #nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
+  lowered final core::int? #nonNullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int>();
   function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in #t14.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+    return let final core::int #t15 = #nonNullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t15) ?{core::int} let final core::int #t16 = 0 in _in::isSentinel(#nonNullableFinalTopLevelLocalWithInitializer) ?{core::int} #nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15;
+  lowered Null #neverLocal = _in::createSentinel<Never>();
+  function #neverLocal#get() → Never
+    return let final Never? #t17 = #neverLocal in _in::isSentinel(#t17) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+  function #neverLocal#set(Never #t18) → dynamic
+    return #neverLocal = #t18;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect
index d8369ba..01ccc85 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect
@@ -4,47 +4,58 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic {
-  core::int? nullableTopLevelLocal = _in::createSentinel<core::int?>();
+  lowered core::int? #nullableTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocal#get() → core::int?
-    return let final core::int? #t1 = nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
+    return let final core::int? #t1 = #nullableTopLevelLocal in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("nullableTopLevelLocal") : #t1{core::int?};
   function #nullableTopLevelLocal#set(core::int? #t2) → dynamic
-    return nullableTopLevelLocal = #t2;
-  core::int? nonNullableTopLevelLocal;
+    return #nullableTopLevelLocal = #t2;
+  lowered core::int? #nonNullableTopLevelLocal = _in::createSentinel<core::int>();
   function #nonNullableTopLevelLocal#get() → core::int
-    return let final core::int? #t3 = nonNullableTopLevelLocal in #t3.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
+    return let final core::int? #t3 = #nonNullableTopLevelLocal in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::localNI("nonNullableTopLevelLocal") : #t3{core::int};
   function #nonNullableTopLevelLocal#set(core::int #t4) → dynamic
-    return nonNullableTopLevelLocal = #t4;
-  core::int? nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocal = #t4;
+  lowered core::int? #nullableTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t5 = nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
+    return let final core::int? #t5 = #nullableTopLevelLocalWithInitializer in _in::isSentinel(#t5) ?{core::int?} #nullableTopLevelLocalWithInitializer = null : #t5{core::int?};
   function #nullableTopLevelLocalWithInitializer#set(core::int? #t6) → dynamic
-    return nullableTopLevelLocalWithInitializer = #t6;
-  core::int? nonNullableTopLevelLocalWithInitializer;
+    return #nullableTopLevelLocalWithInitializer = #t6;
+  lowered core::int? #nonNullableTopLevelLocalWithInitializer = _in::createSentinel<core::int>();
   function #nonNullableTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t7 = nonNullableTopLevelLocalWithInitializer in #t7.==(null) ?{core::int} nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
+    return let final core::int? #t7 = #nonNullableTopLevelLocalWithInitializer in _in::isSentinel(#t7) ?{core::int} #nonNullableTopLevelLocalWithInitializer = 0 : #t7{core::int};
   function #nonNullableTopLevelLocalWithInitializer#set(core::int #t8) → dynamic
-    return nonNullableTopLevelLocalWithInitializer = #t8;
-  final core::int? nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
+    return #nonNullableTopLevelLocalWithInitializer = #t8;
+  lowered final core::int? #nullableFinalTopLevelLocal = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocal#get() → core::int?
-    return let final core::int? #t9 = nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
+    return let final core::int? #t9 = #nullableFinalTopLevelLocal in _in::isSentinel(#t9) ?{core::int?} throw new _in::LateError::localNI("nullableFinalTopLevelLocal") : #t9{core::int?};
   function #nullableFinalTopLevelLocal#set(core::int? #t10) → dynamic
-    if(_in::isSentinel(nullableFinalTopLevelLocal))
-      return nullableFinalTopLevelLocal = #t10;
+    if(_in::isSentinel(#nullableFinalTopLevelLocal))
+      return #nullableFinalTopLevelLocal = #t10;
     else
       throw new _in::LateError::localAI("nullableFinalTopLevelLocal");
-  final core::int? nonNullableFinalTopLevelLocal;
+  lowered final core::int? #nonNullableFinalTopLevelLocal = _in::createSentinel<core::int>();
   function #nonNullableFinalTopLevelLocal#get() → core::int
-    return let final core::int? #t11 = nonNullableFinalTopLevelLocal in #t11.==(null) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
+    return let final core::int? #t11 = #nonNullableFinalTopLevelLocal in _in::isSentinel(#t11) ?{core::int} throw new _in::LateError::localNI("nonNullableFinalTopLevelLocal") : #t11{core::int};
   function #nonNullableFinalTopLevelLocal#set(core::int #t12) → dynamic
-    if(nonNullableFinalTopLevelLocal.==(null))
-      return nonNullableFinalTopLevelLocal = #t12;
+    if(_in::isSentinel(#nonNullableFinalTopLevelLocal))
+      return #nonNullableFinalTopLevelLocal = #t12;
     else
       throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
-  final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
+  lowered final core::int? #nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
   function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
-    return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
-  final core::int? nonNullableFinalTopLevelLocalWithInitializer;
+    return let final core::int? #t13 = #nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(#nullableFinalTopLevelLocalWithInitializer) ?{core::int?} #nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
+  lowered final core::int? #nonNullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int>();
   function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
-    return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in #t14.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+    return let final core::int #t15 = #nonNullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t15) ?{core::int} let final core::int #t16 = 0 in _in::isSentinel(#nonNullableFinalTopLevelLocalWithInitializer) ?{core::int} #nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15;
+  lowered Null #neverLocal = _in::createSentinel<Never>();
+  function #neverLocal#get() → Never
+    return let final Never? #t17 = #neverLocal in _in::isSentinel(#t17) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+  function #neverLocal#set(Never #t18) → dynamic
+    return #neverLocal = #t18;
 }
 static method main() → dynamic {}
+
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:12:19 -> NullConstant(null)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:13:18 -> IntConstant(0)
+Extra constant evaluation: evaluated: 113, effectively constant: 2
diff --git a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.outline.expect b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.outline.expect
index bed220f..efac096 100644
--- a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.outline.expect
@@ -19,7 +19,7 @@
 export "org-dartlang-testcase:///ambiguous_main_export_lib1.dart";
 export "org-dartlang-testcase:///ambiguous_main_export_lib2.dart";
 
-static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/nnbd/ambiguous_main_export_lib1.dart' and 'pkg/front_end/testcases/nnbd/ambiguous_main_export_lib2.dart'.\"}" /*isNullableByDefault, from null */;
+static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/nnbd/ambiguous_main_export_lib1.dart' and 'pkg/front_end/testcases/nnbd/ambiguous_main_export_lib2.dart'.\"}" /*isLegacy, from null */;
 
 library /*isNonNullableByDefault*/;
 import self as self3;
diff --git a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.expect b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.expect
index 8a5ab57..54558c4 100644
--- a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.expect
@@ -19,7 +19,7 @@
 export "org-dartlang-testcase:///ambiguous_main_export_lib1.dart";
 export "org-dartlang-testcase:///ambiguous_main_export_lib2.dart";
 
-static const field dynamic _exports# = #C1 /*isNullableByDefault, from null */;
+static const field dynamic _exports# = #C1 /*isLegacy, from null */;
 
 library /*isNonNullableByDefault*/;
 import self as self3;
diff --git a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.transformed.expect
index 8a5ab57..54558c4 100644
--- a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.strong.transformed.expect
@@ -19,7 +19,7 @@
 export "org-dartlang-testcase:///ambiguous_main_export_lib1.dart";
 export "org-dartlang-testcase:///ambiguous_main_export_lib2.dart";
 
-static const field dynamic _exports# = #C1 /*isNullableByDefault, from null */;
+static const field dynamic _exports# = #C1 /*isLegacy, from null */;
 
 library /*isNonNullableByDefault*/;
 import self as self3;
diff --git a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.expect b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.expect
index 8a5ab57..54558c4 100644
--- a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.expect
@@ -19,7 +19,7 @@
 export "org-dartlang-testcase:///ambiguous_main_export_lib1.dart";
 export "org-dartlang-testcase:///ambiguous_main_export_lib2.dart";
 
-static const field dynamic _exports# = #C1 /*isNullableByDefault, from null */;
+static const field dynamic _exports# = #C1 /*isLegacy, from null */;
 
 library /*isNonNullableByDefault*/;
 import self as self3;
diff --git a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.transformed.expect
index 8a5ab57..54558c4 100644
--- a/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ambiguous_main_export.dart.weak.transformed.expect
@@ -19,7 +19,7 @@
 export "org-dartlang-testcase:///ambiguous_main_export_lib1.dart";
 export "org-dartlang-testcase:///ambiguous_main_export_lib2.dart";
 
-static const field dynamic _exports# = #C1 /*isNullableByDefault, from null */;
+static const field dynamic _exports# = #C1 /*isLegacy, from null */;
 
 library /*isNonNullableByDefault*/;
 import self as self3;
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
index 2c1bc3e..d02c7bc 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
@@ -276,7 +276,6 @@
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -309,7 +308,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -412,7 +410,6 @@
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -443,7 +440,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -470,4 +466,4 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> NullConstant(null)
-Extra constant evaluation: evaluated: 216, effectively constant: 12
+Extra constant evaluation: evaluated: 210, effectively constant: 12
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
index a63f3a4..9ec61e2 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
@@ -276,7 +276,6 @@
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -309,7 +308,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -412,7 +410,6 @@
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -443,7 +440,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.outline.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.outline.expect
index 5a8fb0d..6cec804 100644
--- a/pkg/front_end/testcases/nnbd/extension_bounds.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.outline.expect
@@ -62,105 +62,105 @@
   method method5 = self::Extension5|method5;
   tearoff method5 = self::Extension5|get#method5;
 }
-static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(final self::Extension1|method1::T #this) → dynamic
+static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(lowered final self::Extension1|method1::T #this) → dynamic
   ;
-static method Extension1|get#method1<T extends core::Object = core::Object>(final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension1|get#method1<T extends core::Object = core::Object>(lowered final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T, S>(#this);
-static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(final self::Extension1|method2::T #this) → dynamic
+static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(lowered final self::Extension1|method2::T #this) → dynamic
   ;
-static method Extension1|get#method2<T extends core::Object = core::Object>(final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension1|get#method2<T extends core::Object = core::Object>(lowered final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T, S>(#this);
-static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(final self::Extension1|method3::T #this) → dynamic
+static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T #this) → dynamic
   ;
-static method Extension1|get#method3<T extends core::Object = core::Object>(final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension1|get#method3<T extends core::Object = core::Object>(lowered final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T, S%>(#this);
-static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(final self::Extension1|method4::T #this) → dynamic
+static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(lowered final self::Extension1|method4::T #this) → dynamic
   ;
-static method Extension1|get#method4<T extends core::Object = core::Object>(final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension1|get#method4<T extends core::Object = core::Object>(lowered final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T, S%>(#this);
-static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(final self::Extension1|method5::T #this) → dynamic
+static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(lowered final self::Extension1|method5::T #this) → dynamic
   ;
-static method Extension1|get#method5<T extends core::Object = core::Object>(final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension1|get#method5<T extends core::Object = core::Object>(lowered final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension1|method5<self::Extension1|get#method5::T, S%>(#this);
-static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(final self::Extension2|method1::T #this) → dynamic
+static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(lowered final self::Extension2|method1::T #this) → dynamic
   ;
-static method Extension2|get#method1<T extends core::String = core::String>(final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension2|get#method1<T extends core::String = core::String>(lowered final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T, S>(#this);
-static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(final self::Extension2|method2::T #this) → dynamic
+static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(lowered final self::Extension2|method2::T #this) → dynamic
   ;
-static method Extension2|get#method2<T extends core::String = core::String>(final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension2|get#method2<T extends core::String = core::String>(lowered final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T, S>(#this);
-static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(final self::Extension2|method3::T #this) → dynamic
+static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T #this) → dynamic
   ;
-static method Extension2|get#method3<T extends core::String = core::String>(final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension2|get#method3<T extends core::String = core::String>(lowered final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T, S%>(#this);
-static method Extension2|get#method4<T extends core::String = core::String>(final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension2|get#method4<T extends core::String = core::String>(lowered final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T, S%>(#this);
-static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(final self::Extension2|method4::T #this) → dynamic
+static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(lowered final self::Extension2|method4::T #this) → dynamic
   ;
-static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(final self::Extension2|method5::T #this) → dynamic
+static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(lowered final self::Extension2|method5::T #this) → dynamic
   ;
-static method Extension2|get#method5<T extends core::String = core::String>(final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension2|get#method5<T extends core::String = core::String>(lowered final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension2|method5<self::Extension2|get#method5::T, S%>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(final self::Extension3|method1::T% #this) → dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(lowered final self::Extension3|method1::T% #this) → dynamic
   ;
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(final self::Extension3|method2::T% #this) → dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(lowered final self::Extension3|method2::T% #this) → dynamic
   ;
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T% #this) → dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T% #this) → dynamic
   ;
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(final self::Extension3|method4::T% #this) → dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension3|method4::T% #this) → dynamic
   ;
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S%>(#this);
-static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(final self::Extension3|method5::T% #this) → dynamic
+static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension3|method5::T% #this) → dynamic
   ;
-static method Extension3|get#method5<T extends dynamic = dynamic>(final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension3|get#method5<T extends dynamic = dynamic>(lowered final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension3|method5<self::Extension3|get#method5::T%, S%>(#this);
-static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(final self::Extension4|method1::T% #this) → dynamic
+static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(lowered final self::Extension4|method1::T% #this) → dynamic
   ;
-static method Extension4|get#method1<T extends core::Object? = dynamic>(final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension4|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T%, S>(#this);
-static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(final self::Extension4|method2::T% #this) → dynamic
+static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(lowered final self::Extension4|method2::T% #this) → dynamic
   ;
-static method Extension4|get#method2<T extends core::Object? = dynamic>(final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension4|get#method2<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T%, S>(#this);
-static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T% #this) → dynamic
+static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T% #this) → dynamic
   ;
-static method Extension4|get#method3<T extends core::Object? = dynamic>(final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension4|get#method3<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T%, S%>(#this);
-static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(final self::Extension4|method4::T% #this) → dynamic
+static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension4|method4::T% #this) → dynamic
   ;
-static method Extension4|get#method4<T extends core::Object? = dynamic>(final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension4|get#method4<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T%, S%>(#this);
-static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(final self::Extension4|method5::T% #this) → dynamic
+static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension4|method5::T% #this) → dynamic
   ;
-static method Extension4|get#method5<T extends core::Object? = dynamic>(final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension4|get#method5<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension4|method5<self::Extension4|get#method5::T%, S%>(#this);
-static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(final self::Extension5|method1::T% #this) → dynamic
+static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(lowered final self::Extension5|method1::T% #this) → dynamic
   ;
-static method Extension5|get#method1<T extends core::Object? = core::Object?>(final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension5|get#method1<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension5|method1<self::Extension5|get#method1::T%, S>(#this);
-static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(final self::Extension5|method2::T% #this) → dynamic
+static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(lowered final self::Extension5|method2::T% #this) → dynamic
   ;
-static method Extension5|get#method2<T extends core::Object? = core::Object?>(final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension5|get#method2<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension5|method2<self::Extension5|get#method2::T%, S>(#this);
-static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(final self::Extension5|method3::T% #this) → dynamic
+static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(lowered final self::Extension5|method3::T% #this) → dynamic
   ;
-static method Extension5|get#method3<T extends core::Object? = core::Object?>(final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension5|get#method3<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension5|method3<self::Extension5|get#method3::T%, S%>(#this);
-static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(final self::Extension5|method4::T% #this) → dynamic
+static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(lowered final self::Extension5|method4::T% #this) → dynamic
   ;
-static method Extension5|get#method4<T extends core::Object? = core::Object?>(final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension5|get#method4<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension5|method4<self::Extension5|get#method4::T%, S%>(#this);
-static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(final self::Extension5|method5::T% #this) → dynamic
+static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(lowered final self::Extension5|method5::T% #this) → dynamic
   ;
-static method Extension5|get#method5<T extends core::Object? = core::Object?>(final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension5|get#method5<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension5|method5<self::Extension5|get#method5::T%, S%>(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.expect
index 0cf68fa..c1de6b4 100644
--- a/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.expect
@@ -62,79 +62,79 @@
   method method5 = self::Extension5|method5;
   tearoff method5 = self::Extension5|get#method5;
 }
-static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(final self::Extension1|method1::T #this) → dynamic {}
-static method Extension1|get#method1<T extends core::Object = core::Object>(final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(lowered final self::Extension1|method1::T #this) → dynamic {}
+static method Extension1|get#method1<T extends core::Object = core::Object>(lowered final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T, S>(#this);
-static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(final self::Extension1|method2::T #this) → dynamic {}
-static method Extension1|get#method2<T extends core::Object = core::Object>(final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(lowered final self::Extension1|method2::T #this) → dynamic {}
+static method Extension1|get#method2<T extends core::Object = core::Object>(lowered final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T, S>(#this);
-static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(final self::Extension1|method3::T #this) → dynamic {}
-static method Extension1|get#method3<T extends core::Object = core::Object>(final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T #this) → dynamic {}
+static method Extension1|get#method3<T extends core::Object = core::Object>(lowered final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T, S%>(#this);
-static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(final self::Extension1|method4::T #this) → dynamic {}
-static method Extension1|get#method4<T extends core::Object = core::Object>(final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(lowered final self::Extension1|method4::T #this) → dynamic {}
+static method Extension1|get#method4<T extends core::Object = core::Object>(lowered final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T, S%>(#this);
-static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(final self::Extension1|method5::T #this) → dynamic {}
-static method Extension1|get#method5<T extends core::Object = core::Object>(final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(lowered final self::Extension1|method5::T #this) → dynamic {}
+static method Extension1|get#method5<T extends core::Object = core::Object>(lowered final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension1|method5<self::Extension1|get#method5::T, S%>(#this);
-static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(final self::Extension2|method1::T #this) → dynamic {}
-static method Extension2|get#method1<T extends core::String = core::String>(final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(lowered final self::Extension2|method1::T #this) → dynamic {}
+static method Extension2|get#method1<T extends core::String = core::String>(lowered final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T, S>(#this);
-static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(final self::Extension2|method2::T #this) → dynamic {}
-static method Extension2|get#method2<T extends core::String = core::String>(final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(lowered final self::Extension2|method2::T #this) → dynamic {}
+static method Extension2|get#method2<T extends core::String = core::String>(lowered final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T, S>(#this);
-static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(final self::Extension2|method3::T #this) → dynamic {}
-static method Extension2|get#method3<T extends core::String = core::String>(final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T #this) → dynamic {}
+static method Extension2|get#method3<T extends core::String = core::String>(lowered final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T, S%>(#this);
-static method Extension2|get#method4<T extends core::String = core::String>(final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension2|get#method4<T extends core::String = core::String>(lowered final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T, S%>(#this);
-static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(final self::Extension2|method4::T #this) → dynamic {}
-static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(final self::Extension2|method5::T #this) → dynamic {}
-static method Extension2|get#method5<T extends core::String = core::String>(final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(lowered final self::Extension2|method4::T #this) → dynamic {}
+static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(lowered final self::Extension2|method5::T #this) → dynamic {}
+static method Extension2|get#method5<T extends core::String = core::String>(lowered final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension2|method5<self::Extension2|get#method5::T, S%>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(final self::Extension3|method1::T% #this) → dynamic {}
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(lowered final self::Extension3|method1::T% #this) → dynamic {}
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(final self::Extension3|method2::T% #this) → dynamic {}
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(lowered final self::Extension3|method2::T% #this) → dynamic {}
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T% #this) → dynamic {}
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T% #this) → dynamic {}
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(final self::Extension3|method4::T% #this) → dynamic {}
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension3|method4::T% #this) → dynamic {}
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S%>(#this);
-static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(final self::Extension3|method5::T% #this) → dynamic {}
-static method Extension3|get#method5<T extends dynamic = dynamic>(final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension3|method5::T% #this) → dynamic {}
+static method Extension3|get#method5<T extends dynamic = dynamic>(lowered final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension3|method5<self::Extension3|get#method5::T%, S%>(#this);
-static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(final self::Extension4|method1::T% #this) → dynamic {}
-static method Extension4|get#method1<T extends core::Object? = dynamic>(final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(lowered final self::Extension4|method1::T% #this) → dynamic {}
+static method Extension4|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T%, S>(#this);
-static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(final self::Extension4|method2::T% #this) → dynamic {}
-static method Extension4|get#method2<T extends core::Object? = dynamic>(final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(lowered final self::Extension4|method2::T% #this) → dynamic {}
+static method Extension4|get#method2<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T%, S>(#this);
-static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T% #this) → dynamic {}
-static method Extension4|get#method3<T extends core::Object? = dynamic>(final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T% #this) → dynamic {}
+static method Extension4|get#method3<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T%, S%>(#this);
-static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(final self::Extension4|method4::T% #this) → dynamic {}
-static method Extension4|get#method4<T extends core::Object? = dynamic>(final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension4|method4::T% #this) → dynamic {}
+static method Extension4|get#method4<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T%, S%>(#this);
-static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(final self::Extension4|method5::T% #this) → dynamic {}
-static method Extension4|get#method5<T extends core::Object? = dynamic>(final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension4|method5::T% #this) → dynamic {}
+static method Extension4|get#method5<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension4|method5<self::Extension4|get#method5::T%, S%>(#this);
-static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(final self::Extension5|method1::T% #this) → dynamic {}
-static method Extension5|get#method1<T extends core::Object? = core::Object?>(final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(lowered final self::Extension5|method1::T% #this) → dynamic {}
+static method Extension5|get#method1<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension5|method1<self::Extension5|get#method1::T%, S>(#this);
-static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(final self::Extension5|method2::T% #this) → dynamic {}
-static method Extension5|get#method2<T extends core::Object? = core::Object?>(final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(lowered final self::Extension5|method2::T% #this) → dynamic {}
+static method Extension5|get#method2<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension5|method2<self::Extension5|get#method2::T%, S>(#this);
-static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(final self::Extension5|method3::T% #this) → dynamic {}
-static method Extension5|get#method3<T extends core::Object? = core::Object?>(final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(lowered final self::Extension5|method3::T% #this) → dynamic {}
+static method Extension5|get#method3<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension5|method3<self::Extension5|get#method3::T%, S%>(#this);
-static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(final self::Extension5|method4::T% #this) → dynamic {}
-static method Extension5|get#method4<T extends core::Object? = core::Object?>(final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(lowered final self::Extension5|method4::T% #this) → dynamic {}
+static method Extension5|get#method4<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension5|method4<self::Extension5|get#method4::T%, S%>(#this);
-static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(final self::Extension5|method5::T% #this) → dynamic {}
-static method Extension5|get#method5<T extends core::Object? = core::Object?>(final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(lowered final self::Extension5|method5::T% #this) → dynamic {}
+static method Extension5|get#method5<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension5|method5<self::Extension5|get#method5::T%, S%>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.transformed.expect
index 0cf68fa..c1de6b4 100644
--- a/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.strong.transformed.expect
@@ -62,79 +62,79 @@
   method method5 = self::Extension5|method5;
   tearoff method5 = self::Extension5|get#method5;
 }
-static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(final self::Extension1|method1::T #this) → dynamic {}
-static method Extension1|get#method1<T extends core::Object = core::Object>(final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(lowered final self::Extension1|method1::T #this) → dynamic {}
+static method Extension1|get#method1<T extends core::Object = core::Object>(lowered final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T, S>(#this);
-static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(final self::Extension1|method2::T #this) → dynamic {}
-static method Extension1|get#method2<T extends core::Object = core::Object>(final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(lowered final self::Extension1|method2::T #this) → dynamic {}
+static method Extension1|get#method2<T extends core::Object = core::Object>(lowered final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T, S>(#this);
-static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(final self::Extension1|method3::T #this) → dynamic {}
-static method Extension1|get#method3<T extends core::Object = core::Object>(final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T #this) → dynamic {}
+static method Extension1|get#method3<T extends core::Object = core::Object>(lowered final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T, S%>(#this);
-static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(final self::Extension1|method4::T #this) → dynamic {}
-static method Extension1|get#method4<T extends core::Object = core::Object>(final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(lowered final self::Extension1|method4::T #this) → dynamic {}
+static method Extension1|get#method4<T extends core::Object = core::Object>(lowered final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T, S%>(#this);
-static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(final self::Extension1|method5::T #this) → dynamic {}
-static method Extension1|get#method5<T extends core::Object = core::Object>(final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(lowered final self::Extension1|method5::T #this) → dynamic {}
+static method Extension1|get#method5<T extends core::Object = core::Object>(lowered final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension1|method5<self::Extension1|get#method5::T, S%>(#this);
-static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(final self::Extension2|method1::T #this) → dynamic {}
-static method Extension2|get#method1<T extends core::String = core::String>(final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(lowered final self::Extension2|method1::T #this) → dynamic {}
+static method Extension2|get#method1<T extends core::String = core::String>(lowered final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T, S>(#this);
-static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(final self::Extension2|method2::T #this) → dynamic {}
-static method Extension2|get#method2<T extends core::String = core::String>(final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(lowered final self::Extension2|method2::T #this) → dynamic {}
+static method Extension2|get#method2<T extends core::String = core::String>(lowered final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T, S>(#this);
-static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(final self::Extension2|method3::T #this) → dynamic {}
-static method Extension2|get#method3<T extends core::String = core::String>(final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T #this) → dynamic {}
+static method Extension2|get#method3<T extends core::String = core::String>(lowered final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T, S%>(#this);
-static method Extension2|get#method4<T extends core::String = core::String>(final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension2|get#method4<T extends core::String = core::String>(lowered final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T, S%>(#this);
-static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(final self::Extension2|method4::T #this) → dynamic {}
-static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(final self::Extension2|method5::T #this) → dynamic {}
-static method Extension2|get#method5<T extends core::String = core::String>(final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(lowered final self::Extension2|method4::T #this) → dynamic {}
+static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(lowered final self::Extension2|method5::T #this) → dynamic {}
+static method Extension2|get#method5<T extends core::String = core::String>(lowered final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension2|method5<self::Extension2|get#method5::T, S%>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(final self::Extension3|method1::T% #this) → dynamic {}
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(lowered final self::Extension3|method1::T% #this) → dynamic {}
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(final self::Extension3|method2::T% #this) → dynamic {}
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(lowered final self::Extension3|method2::T% #this) → dynamic {}
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T% #this) → dynamic {}
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T% #this) → dynamic {}
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(final self::Extension3|method4::T% #this) → dynamic {}
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension3|method4::T% #this) → dynamic {}
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S%>(#this);
-static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(final self::Extension3|method5::T% #this) → dynamic {}
-static method Extension3|get#method5<T extends dynamic = dynamic>(final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension3|method5::T% #this) → dynamic {}
+static method Extension3|get#method5<T extends dynamic = dynamic>(lowered final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension3|method5<self::Extension3|get#method5::T%, S%>(#this);
-static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(final self::Extension4|method1::T% #this) → dynamic {}
-static method Extension4|get#method1<T extends core::Object? = dynamic>(final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(lowered final self::Extension4|method1::T% #this) → dynamic {}
+static method Extension4|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T%, S>(#this);
-static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(final self::Extension4|method2::T% #this) → dynamic {}
-static method Extension4|get#method2<T extends core::Object? = dynamic>(final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(lowered final self::Extension4|method2::T% #this) → dynamic {}
+static method Extension4|get#method2<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T%, S>(#this);
-static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T% #this) → dynamic {}
-static method Extension4|get#method3<T extends core::Object? = dynamic>(final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T% #this) → dynamic {}
+static method Extension4|get#method3<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T%, S%>(#this);
-static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(final self::Extension4|method4::T% #this) → dynamic {}
-static method Extension4|get#method4<T extends core::Object? = dynamic>(final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension4|method4::T% #this) → dynamic {}
+static method Extension4|get#method4<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T%, S%>(#this);
-static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(final self::Extension4|method5::T% #this) → dynamic {}
-static method Extension4|get#method5<T extends core::Object? = dynamic>(final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension4|method5::T% #this) → dynamic {}
+static method Extension4|get#method5<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension4|method5<self::Extension4|get#method5::T%, S%>(#this);
-static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(final self::Extension5|method1::T% #this) → dynamic {}
-static method Extension5|get#method1<T extends core::Object? = core::Object?>(final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(lowered final self::Extension5|method1::T% #this) → dynamic {}
+static method Extension5|get#method1<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension5|method1<self::Extension5|get#method1::T%, S>(#this);
-static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(final self::Extension5|method2::T% #this) → dynamic {}
-static method Extension5|get#method2<T extends core::Object? = core::Object?>(final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(lowered final self::Extension5|method2::T% #this) → dynamic {}
+static method Extension5|get#method2<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension5|method2<self::Extension5|get#method2::T%, S>(#this);
-static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(final self::Extension5|method3::T% #this) → dynamic {}
-static method Extension5|get#method3<T extends core::Object? = core::Object?>(final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(lowered final self::Extension5|method3::T% #this) → dynamic {}
+static method Extension5|get#method3<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension5|method3<self::Extension5|get#method3::T%, S%>(#this);
-static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(final self::Extension5|method4::T% #this) → dynamic {}
-static method Extension5|get#method4<T extends core::Object? = core::Object?>(final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(lowered final self::Extension5|method4::T% #this) → dynamic {}
+static method Extension5|get#method4<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension5|method4<self::Extension5|get#method4::T%, S%>(#this);
-static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(final self::Extension5|method5::T% #this) → dynamic {}
-static method Extension5|get#method5<T extends core::Object? = core::Object?>(final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(lowered final self::Extension5|method5::T% #this) → dynamic {}
+static method Extension5|get#method5<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension5|method5<self::Extension5|get#method5::T%, S%>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.expect
index 0cf68fa..c1de6b4 100644
--- a/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.expect
@@ -62,79 +62,79 @@
   method method5 = self::Extension5|method5;
   tearoff method5 = self::Extension5|get#method5;
 }
-static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(final self::Extension1|method1::T #this) → dynamic {}
-static method Extension1|get#method1<T extends core::Object = core::Object>(final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(lowered final self::Extension1|method1::T #this) → dynamic {}
+static method Extension1|get#method1<T extends core::Object = core::Object>(lowered final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T, S>(#this);
-static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(final self::Extension1|method2::T #this) → dynamic {}
-static method Extension1|get#method2<T extends core::Object = core::Object>(final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(lowered final self::Extension1|method2::T #this) → dynamic {}
+static method Extension1|get#method2<T extends core::Object = core::Object>(lowered final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T, S>(#this);
-static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(final self::Extension1|method3::T #this) → dynamic {}
-static method Extension1|get#method3<T extends core::Object = core::Object>(final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T #this) → dynamic {}
+static method Extension1|get#method3<T extends core::Object = core::Object>(lowered final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T, S%>(#this);
-static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(final self::Extension1|method4::T #this) → dynamic {}
-static method Extension1|get#method4<T extends core::Object = core::Object>(final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(lowered final self::Extension1|method4::T #this) → dynamic {}
+static method Extension1|get#method4<T extends core::Object = core::Object>(lowered final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T, S%>(#this);
-static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(final self::Extension1|method5::T #this) → dynamic {}
-static method Extension1|get#method5<T extends core::Object = core::Object>(final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(lowered final self::Extension1|method5::T #this) → dynamic {}
+static method Extension1|get#method5<T extends core::Object = core::Object>(lowered final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension1|method5<self::Extension1|get#method5::T, S%>(#this);
-static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(final self::Extension2|method1::T #this) → dynamic {}
-static method Extension2|get#method1<T extends core::String = core::String>(final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(lowered final self::Extension2|method1::T #this) → dynamic {}
+static method Extension2|get#method1<T extends core::String = core::String>(lowered final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T, S>(#this);
-static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(final self::Extension2|method2::T #this) → dynamic {}
-static method Extension2|get#method2<T extends core::String = core::String>(final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(lowered final self::Extension2|method2::T #this) → dynamic {}
+static method Extension2|get#method2<T extends core::String = core::String>(lowered final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T, S>(#this);
-static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(final self::Extension2|method3::T #this) → dynamic {}
-static method Extension2|get#method3<T extends core::String = core::String>(final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T #this) → dynamic {}
+static method Extension2|get#method3<T extends core::String = core::String>(lowered final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T, S%>(#this);
-static method Extension2|get#method4<T extends core::String = core::String>(final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension2|get#method4<T extends core::String = core::String>(lowered final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T, S%>(#this);
-static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(final self::Extension2|method4::T #this) → dynamic {}
-static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(final self::Extension2|method5::T #this) → dynamic {}
-static method Extension2|get#method5<T extends core::String = core::String>(final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(lowered final self::Extension2|method4::T #this) → dynamic {}
+static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(lowered final self::Extension2|method5::T #this) → dynamic {}
+static method Extension2|get#method5<T extends core::String = core::String>(lowered final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension2|method5<self::Extension2|get#method5::T, S%>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(final self::Extension3|method1::T% #this) → dynamic {}
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(lowered final self::Extension3|method1::T% #this) → dynamic {}
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(final self::Extension3|method2::T% #this) → dynamic {}
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(lowered final self::Extension3|method2::T% #this) → dynamic {}
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T% #this) → dynamic {}
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T% #this) → dynamic {}
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(final self::Extension3|method4::T% #this) → dynamic {}
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension3|method4::T% #this) → dynamic {}
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S%>(#this);
-static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(final self::Extension3|method5::T% #this) → dynamic {}
-static method Extension3|get#method5<T extends dynamic = dynamic>(final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension3|method5::T% #this) → dynamic {}
+static method Extension3|get#method5<T extends dynamic = dynamic>(lowered final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension3|method5<self::Extension3|get#method5::T%, S%>(#this);
-static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(final self::Extension4|method1::T% #this) → dynamic {}
-static method Extension4|get#method1<T extends core::Object? = dynamic>(final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(lowered final self::Extension4|method1::T% #this) → dynamic {}
+static method Extension4|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T%, S>(#this);
-static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(final self::Extension4|method2::T% #this) → dynamic {}
-static method Extension4|get#method2<T extends core::Object? = dynamic>(final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(lowered final self::Extension4|method2::T% #this) → dynamic {}
+static method Extension4|get#method2<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T%, S>(#this);
-static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T% #this) → dynamic {}
-static method Extension4|get#method3<T extends core::Object? = dynamic>(final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T% #this) → dynamic {}
+static method Extension4|get#method3<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T%, S%>(#this);
-static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(final self::Extension4|method4::T% #this) → dynamic {}
-static method Extension4|get#method4<T extends core::Object? = dynamic>(final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension4|method4::T% #this) → dynamic {}
+static method Extension4|get#method4<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T%, S%>(#this);
-static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(final self::Extension4|method5::T% #this) → dynamic {}
-static method Extension4|get#method5<T extends core::Object? = dynamic>(final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension4|method5::T% #this) → dynamic {}
+static method Extension4|get#method5<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension4|method5<self::Extension4|get#method5::T%, S%>(#this);
-static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(final self::Extension5|method1::T% #this) → dynamic {}
-static method Extension5|get#method1<T extends core::Object? = core::Object?>(final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(lowered final self::Extension5|method1::T% #this) → dynamic {}
+static method Extension5|get#method1<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension5|method1<self::Extension5|get#method1::T%, S>(#this);
-static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(final self::Extension5|method2::T% #this) → dynamic {}
-static method Extension5|get#method2<T extends core::Object? = core::Object?>(final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(lowered final self::Extension5|method2::T% #this) → dynamic {}
+static method Extension5|get#method2<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension5|method2<self::Extension5|get#method2::T%, S>(#this);
-static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(final self::Extension5|method3::T% #this) → dynamic {}
-static method Extension5|get#method3<T extends core::Object? = core::Object?>(final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(lowered final self::Extension5|method3::T% #this) → dynamic {}
+static method Extension5|get#method3<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension5|method3<self::Extension5|get#method3::T%, S%>(#this);
-static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(final self::Extension5|method4::T% #this) → dynamic {}
-static method Extension5|get#method4<T extends core::Object? = core::Object?>(final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(lowered final self::Extension5|method4::T% #this) → dynamic {}
+static method Extension5|get#method4<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension5|method4<self::Extension5|get#method4::T%, S%>(#this);
-static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(final self::Extension5|method5::T% #this) → dynamic {}
-static method Extension5|get#method5<T extends core::Object? = core::Object?>(final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(lowered final self::Extension5|method5::T% #this) → dynamic {}
+static method Extension5|get#method5<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension5|method5<self::Extension5|get#method5::T%, S%>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.transformed.expect
index 0cf68fa..c1de6b4 100644
--- a/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.weak.transformed.expect
@@ -62,79 +62,79 @@
   method method5 = self::Extension5|method5;
   tearoff method5 = self::Extension5|get#method5;
 }
-static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(final self::Extension1|method1::T #this) → dynamic {}
-static method Extension1|get#method1<T extends core::Object = core::Object>(final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension1|method1<T extends core::Object = core::Object, S extends core::Object = core::Object>(lowered final self::Extension1|method1::T #this) → dynamic {}
+static method Extension1|get#method1<T extends core::Object = core::Object>(lowered final self::Extension1|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension1|method1<self::Extension1|get#method1::T, S>(#this);
-static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(final self::Extension1|method2::T #this) → dynamic {}
-static method Extension1|get#method2<T extends core::Object = core::Object>(final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension1|method2<T extends core::Object = core::Object, S extends core::String = core::String>(lowered final self::Extension1|method2::T #this) → dynamic {}
+static method Extension1|get#method2<T extends core::Object = core::Object>(lowered final self::Extension1|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension1|method2<self::Extension1|get#method2::T, S>(#this);
-static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(final self::Extension1|method3::T #this) → dynamic {}
-static method Extension1|get#method3<T extends core::Object = core::Object>(final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension1|method3<T extends core::Object = core::Object, S extends dynamic = dynamic>(lowered final self::Extension1|method3::T #this) → dynamic {}
+static method Extension1|get#method3<T extends core::Object = core::Object>(lowered final self::Extension1|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension1|method3<self::Extension1|get#method3::T, S%>(#this);
-static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(final self::Extension1|method4::T #this) → dynamic {}
-static method Extension1|get#method4<T extends core::Object = core::Object>(final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension1|method4<T extends core::Object = core::Object, S extends core::Object? = dynamic>(lowered final self::Extension1|method4::T #this) → dynamic {}
+static method Extension1|get#method4<T extends core::Object = core::Object>(lowered final self::Extension1|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension1|method4<self::Extension1|get#method4::T, S%>(#this);
-static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(final self::Extension1|method5::T #this) → dynamic {}
-static method Extension1|get#method5<T extends core::Object = core::Object>(final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension1|method5<T extends core::Object = core::Object, S extends core::Object? = core::Object?>(lowered final self::Extension1|method5::T #this) → dynamic {}
+static method Extension1|get#method5<T extends core::Object = core::Object>(lowered final self::Extension1|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension1|method5<self::Extension1|get#method5::T, S%>(#this);
-static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(final self::Extension2|method1::T #this) → dynamic {}
-static method Extension2|get#method1<T extends core::String = core::String>(final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension2|method1<T extends core::String = core::String, S extends core::Object = core::Object>(lowered final self::Extension2|method1::T #this) → dynamic {}
+static method Extension2|get#method1<T extends core::String = core::String>(lowered final self::Extension2|get#method1::T #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension2|method1<self::Extension2|get#method1::T, S>(#this);
-static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(final self::Extension2|method2::T #this) → dynamic {}
-static method Extension2|get#method2<T extends core::String = core::String>(final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
+static method Extension2|method2<T extends core::String = core::String, S extends core::String = core::String>(lowered final self::Extension2|method2::T #this) → dynamic {}
+static method Extension2|get#method2<T extends core::String = core::String>(lowered final self::Extension2|get#method2::T #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension2|method2<self::Extension2|get#method2::T, S>(#this);
-static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(final self::Extension2|method3::T #this) → dynamic {}
-static method Extension2|get#method3<T extends core::String = core::String>(final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension2|method3<T extends core::String = core::String, S extends dynamic = dynamic>(lowered final self::Extension2|method3::T #this) → dynamic {}
+static method Extension2|get#method3<T extends core::String = core::String>(lowered final self::Extension2|get#method3::T #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension2|method3<self::Extension2|get#method3::T, S%>(#this);
-static method Extension2|get#method4<T extends core::String = core::String>(final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension2|get#method4<T extends core::String = core::String>(lowered final self::Extension2|get#method4::T #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension2|method4<self::Extension2|get#method4::T, S%>(#this);
-static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(final self::Extension2|method4::T #this) → dynamic {}
-static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(final self::Extension2|method5::T #this) → dynamic {}
-static method Extension2|get#method5<T extends core::String = core::String>(final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension2|method4<T extends core::String = core::String, S extends core::Object? = dynamic>(lowered final self::Extension2|method4::T #this) → dynamic {}
+static method Extension2|method5<T extends core::String = core::String, S extends core::Object? = core::Object?>(lowered final self::Extension2|method5::T #this) → dynamic {}
+static method Extension2|get#method5<T extends core::String = core::String>(lowered final self::Extension2|get#method5::T #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension2|method5<self::Extension2|get#method5::T, S%>(#this);
-static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(final self::Extension3|method1::T% #this) → dynamic {}
-static method Extension3|get#method1<T extends dynamic = dynamic>(final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension3|method1<T extends dynamic = dynamic, S extends core::Object = core::Object>(lowered final self::Extension3|method1::T% #this) → dynamic {}
+static method Extension3|get#method1<T extends dynamic = dynamic>(lowered final self::Extension3|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension3|method1<self::Extension3|get#method1::T%, S>(#this);
-static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(final self::Extension3|method2::T% #this) → dynamic {}
-static method Extension3|get#method2<T extends dynamic = dynamic>(final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension3|method2<T extends dynamic = dynamic, S extends core::String = core::String>(lowered final self::Extension3|method2::T% #this) → dynamic {}
+static method Extension3|get#method2<T extends dynamic = dynamic>(lowered final self::Extension3|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension3|method2<self::Extension3|get#method2::T%, S>(#this);
-static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(final self::Extension3|method3::T% #this) → dynamic {}
-static method Extension3|get#method3<T extends dynamic = dynamic>(final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension3|method3<T extends dynamic = dynamic, S extends dynamic = dynamic>(lowered final self::Extension3|method3::T% #this) → dynamic {}
+static method Extension3|get#method3<T extends dynamic = dynamic>(lowered final self::Extension3|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension3|method3<self::Extension3|get#method3::T%, S%>(#this);
-static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(final self::Extension3|method4::T% #this) → dynamic {}
-static method Extension3|get#method4<T extends dynamic = dynamic>(final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension3|method4<T extends dynamic = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension3|method4::T% #this) → dynamic {}
+static method Extension3|get#method4<T extends dynamic = dynamic>(lowered final self::Extension3|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension3|method4<self::Extension3|get#method4::T%, S%>(#this);
-static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(final self::Extension3|method5::T% #this) → dynamic {}
-static method Extension3|get#method5<T extends dynamic = dynamic>(final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension3|method5<T extends dynamic = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension3|method5::T% #this) → dynamic {}
+static method Extension3|get#method5<T extends dynamic = dynamic>(lowered final self::Extension3|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension3|method5<self::Extension3|get#method5::T%, S%>(#this);
-static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(final self::Extension4|method1::T% #this) → dynamic {}
-static method Extension4|get#method1<T extends core::Object? = dynamic>(final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension4|method1<T extends core::Object? = dynamic, S extends core::Object = core::Object>(lowered final self::Extension4|method1::T% #this) → dynamic {}
+static method Extension4|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension4|method1<self::Extension4|get#method1::T%, S>(#this);
-static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(final self::Extension4|method2::T% #this) → dynamic {}
-static method Extension4|get#method2<T extends core::Object? = dynamic>(final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension4|method2<T extends core::Object? = dynamic, S extends core::String = core::String>(lowered final self::Extension4|method2::T% #this) → dynamic {}
+static method Extension4|get#method2<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension4|method2<self::Extension4|get#method2::T%, S>(#this);
-static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(final self::Extension4|method3::T% #this) → dynamic {}
-static method Extension4|get#method3<T extends core::Object? = dynamic>(final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension4|method3<T extends core::Object? = dynamic, S extends dynamic = dynamic>(lowered final self::Extension4|method3::T% #this) → dynamic {}
+static method Extension4|get#method3<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension4|method3<self::Extension4|get#method3::T%, S%>(#this);
-static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(final self::Extension4|method4::T% #this) → dynamic {}
-static method Extension4|get#method4<T extends core::Object? = dynamic>(final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension4|method4<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(lowered final self::Extension4|method4::T% #this) → dynamic {}
+static method Extension4|get#method4<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension4|method4<self::Extension4|get#method4::T%, S%>(#this);
-static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(final self::Extension4|method5::T% #this) → dynamic {}
-static method Extension4|get#method5<T extends core::Object? = dynamic>(final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension4|method5<T extends core::Object? = dynamic, S extends core::Object? = core::Object?>(lowered final self::Extension4|method5::T% #this) → dynamic {}
+static method Extension4|get#method5<T extends core::Object? = dynamic>(lowered final self::Extension4|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension4|method5<self::Extension4|get#method5::T%, S%>(#this);
-static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(final self::Extension5|method1::T% #this) → dynamic {}
-static method Extension5|get#method1<T extends core::Object? = core::Object?>(final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
+static method Extension5|method1<T extends core::Object? = core::Object?, S extends core::Object = core::Object>(lowered final self::Extension5|method1::T% #this) → dynamic {}
+static method Extension5|get#method1<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method1::T% #this) → <S extends core::Object = core::Object>() → dynamic
   return <S extends core::Object = core::Object>() → dynamic => self::Extension5|method1<self::Extension5|get#method1::T%, S>(#this);
-static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(final self::Extension5|method2::T% #this) → dynamic {}
-static method Extension5|get#method2<T extends core::Object? = core::Object?>(final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
+static method Extension5|method2<T extends core::Object? = core::Object?, S extends core::String = core::String>(lowered final self::Extension5|method2::T% #this) → dynamic {}
+static method Extension5|get#method2<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method2::T% #this) → <S extends core::String = core::String>() → dynamic
   return <S extends core::String = core::String>() → dynamic => self::Extension5|method2<self::Extension5|get#method2::T%, S>(#this);
-static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(final self::Extension5|method3::T% #this) → dynamic {}
-static method Extension5|get#method3<T extends core::Object? = core::Object?>(final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
+static method Extension5|method3<T extends core::Object? = core::Object?, S extends dynamic = dynamic>(lowered final self::Extension5|method3::T% #this) → dynamic {}
+static method Extension5|get#method3<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method3::T% #this) → <S extends dynamic = dynamic>() → dynamic
   return <S extends dynamic = dynamic>() → dynamic => self::Extension5|method3<self::Extension5|get#method3::T%, S%>(#this);
-static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(final self::Extension5|method4::T% #this) → dynamic {}
-static method Extension5|get#method4<T extends core::Object? = core::Object?>(final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
+static method Extension5|method4<T extends core::Object? = core::Object?, S extends core::Object? = dynamic>(lowered final self::Extension5|method4::T% #this) → dynamic {}
+static method Extension5|get#method4<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method4::T% #this) → <S extends core::Object? = dynamic>() → dynamic
   return <S extends core::Object? = dynamic>() → dynamic => self::Extension5|method4<self::Extension5|get#method4::T%, S%>(#this);
-static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(final self::Extension5|method5::T% #this) → dynamic {}
-static method Extension5|get#method5<T extends core::Object? = core::Object?>(final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
+static method Extension5|method5<T extends core::Object? = core::Object?, S extends core::Object? = core::Object?>(lowered final self::Extension5|method5::T% #this) → dynamic {}
+static method Extension5|get#method5<T extends core::Object? = core::Object?>(lowered final self::Extension5|get#method5::T% #this) → <S extends core::Object? = core::Object?>() → dynamic
   return <S extends core::Object? = core::Object?>() → dynamic => self::Extension5|method5<self::Extension5|get#method5::T%, S%>(#this);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.outline.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.outline.expect
index 718b500..b564483 100644
--- a/pkg/front_end/testcases/nnbd/extension_never.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.outline.expect
@@ -5,9 +5,9 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final Never #this) → dynamic
+static method Extension|extensionMethod(lowered final Never #this) → dynamic
   ;
-static method Extension|get#extensionMethod(final Never #this) → () → dynamic
+static method Extension|get#extensionMethod(lowered final Never #this) → () → dynamic
   return () → dynamic => self::Extension|extensionMethod(#this);
 static method implicitAccess(Never never) → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.strong.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.strong.expect
index 5c20141..0319a8a 100644
--- a/pkg/front_end/testcases/nnbd/extension_never.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.strong.expect
@@ -5,8 +5,8 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final Never #this) → dynamic {}
-static method Extension|get#extensionMethod(final Never #this) → () → dynamic
+static method Extension|extensionMethod(lowered final Never #this) → dynamic {}
+static method Extension|get#extensionMethod(lowered final Never #this) → () → dynamic
   return () → dynamic => self::Extension|extensionMethod(#this);
 static method implicitAccess(Never never) → dynamic {
   never.extensionMethod();
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.strong.transformed.expect
index 5c20141..0319a8a 100644
--- a/pkg/front_end/testcases/nnbd/extension_never.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.strong.transformed.expect
@@ -5,8 +5,8 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final Never #this) → dynamic {}
-static method Extension|get#extensionMethod(final Never #this) → () → dynamic
+static method Extension|extensionMethod(lowered final Never #this) → dynamic {}
+static method Extension|get#extensionMethod(lowered final Never #this) → () → dynamic
   return () → dynamic => self::Extension|extensionMethod(#this);
 static method implicitAccess(Never never) → dynamic {
   never.extensionMethod();
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect
index 5c94642..b3068c2 100644
--- a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect
@@ -6,8 +6,8 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final Never #this) → dynamic {}
-static method Extension|get#extensionMethod(final Never #this) → () → dynamic
+static method Extension|extensionMethod(lowered final Never #this) → dynamic {}
+static method Extension|get#extensionMethod(lowered final Never #this) → () → dynamic
   return () → dynamic => self::Extension|extensionMethod(#this);
 static method implicitAccess(Never never) → dynamic {
   let final Never #t1 = (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).extensionMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect
index 5c94642..b3068c2 100644
--- a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect
@@ -6,8 +6,8 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final Never #this) → dynamic {}
-static method Extension|get#extensionMethod(final Never #this) → () → dynamic
+static method Extension|extensionMethod(lowered final Never #this) → dynamic {}
+static method Extension|get#extensionMethod(lowered final Never #this) → () → dynamic
   return () → dynamic => self::Extension|extensionMethod(#this);
 static method implicitAccess(Never never) → dynamic {
   let final Never #t1 = (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).extensionMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.outline.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.outline.expect
index d373301..7798a93 100644
--- a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.outline.expect
@@ -18,13 +18,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object? = dynamic>(final self::Extension|method1::T% #this) → self::Extension|method1::T%
+static method Extension|method1<T extends core::Object? = dynamic>(lowered final self::Extension|method1::T% #this) → self::Extension|method1::T%
   ;
-static method Extension|get#method1<T extends core::Object? = dynamic>(final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
+static method Extension|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
   return () → self::Extension|get#method1::T% => self::Extension|method1<self::Extension|get#method1::T%>(#this);
-static method BoundExtension|method2<T extends self::Class = self::Class>(final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
+static method BoundExtension|method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
   ;
-static method BoundExtension|get#method2<T extends self::Class = self::Class>(final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
+static method BoundExtension|get#method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
   return () → self::BoundExtension|get#method2::T => self::BoundExtension|method2<self::BoundExtension|get#method2::T>(#this);
 static method test1<T extends core::Object? = dynamic>(self::test1::T% t1) → self::Class
   ;
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.expect
index a948972..4f5c95f 100644
--- a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.expect
@@ -39,13 +39,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object? = dynamic>(final self::Extension|method1::T% #this) → self::Extension|method1::T%
+static method Extension|method1<T extends core::Object? = dynamic>(lowered final self::Extension|method1::T% #this) → self::Extension|method1::T%
   return #this;
-static method Extension|get#method1<T extends core::Object? = dynamic>(final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
+static method Extension|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
   return () → self::Extension|get#method1::T% => self::Extension|method1<self::Extension|get#method1::T%>(#this);
-static method BoundExtension|method2<T extends self::Class = self::Class>(final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
+static method BoundExtension|method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
   return #this;
-static method BoundExtension|get#method2<T extends self::Class = self::Class>(final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
+static method BoundExtension|get#method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
   return () → self::BoundExtension|get#method2::T => self::BoundExtension|method2<self::BoundExtension|get#method2::T>(#this);
 static method test1<T extends core::Object? = dynamic>(self::test1::T% t1) → self::Class {
   if(t1 is{ForNonNullableByDefault} self::SubClass) {
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.transformed.expect
index e6c4be4..c60f2f0 100644
--- a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.strong.transformed.expect
@@ -39,13 +39,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object? = dynamic>(final self::Extension|method1::T% #this) → self::Extension|method1::T%
+static method Extension|method1<T extends core::Object? = dynamic>(lowered final self::Extension|method1::T% #this) → self::Extension|method1::T%
   return #this;
-static method Extension|get#method1<T extends core::Object? = dynamic>(final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
+static method Extension|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
   return () → self::Extension|get#method1::T% => self::Extension|method1<self::Extension|get#method1::T%>(#this);
-static method BoundExtension|method2<T extends self::Class = self::Class>(final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
+static method BoundExtension|method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
   return #this;
-static method BoundExtension|get#method2<T extends self::Class = self::Class>(final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
+static method BoundExtension|get#method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
   return () → self::BoundExtension|get#method2::T => self::BoundExtension|method2<self::BoundExtension|get#method2::T>(#this);
 static method test1<T extends core::Object? = dynamic>(self::test1::T% t1) → self::Class {
   if(t1 is{ForNonNullableByDefault} self::SubClass) {
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.expect
index a948972..4f5c95f 100644
--- a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.expect
@@ -39,13 +39,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object? = dynamic>(final self::Extension|method1::T% #this) → self::Extension|method1::T%
+static method Extension|method1<T extends core::Object? = dynamic>(lowered final self::Extension|method1::T% #this) → self::Extension|method1::T%
   return #this;
-static method Extension|get#method1<T extends core::Object? = dynamic>(final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
+static method Extension|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
   return () → self::Extension|get#method1::T% => self::Extension|method1<self::Extension|get#method1::T%>(#this);
-static method BoundExtension|method2<T extends self::Class = self::Class>(final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
+static method BoundExtension|method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
   return #this;
-static method BoundExtension|get#method2<T extends self::Class = self::Class>(final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
+static method BoundExtension|get#method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
   return () → self::BoundExtension|get#method2::T => self::BoundExtension|method2<self::BoundExtension|get#method2::T>(#this);
 static method test1<T extends core::Object? = dynamic>(self::test1::T% t1) → self::Class {
   if(t1 is{ForNonNullableByDefault} self::SubClass) {
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.transformed.expect
index e6c4be4..c60f2f0 100644
--- a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.weak.transformed.expect
@@ -39,13 +39,13 @@
   method method2 = self::BoundExtension|method2;
   tearoff method2 = self::BoundExtension|get#method2;
 }
-static method Extension|method1<T extends core::Object? = dynamic>(final self::Extension|method1::T% #this) → self::Extension|method1::T%
+static method Extension|method1<T extends core::Object? = dynamic>(lowered final self::Extension|method1::T% #this) → self::Extension|method1::T%
   return #this;
-static method Extension|get#method1<T extends core::Object? = dynamic>(final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
+static method Extension|get#method1<T extends core::Object? = dynamic>(lowered final self::Extension|get#method1::T% #this) → () → self::Extension|get#method1::T%
   return () → self::Extension|get#method1::T% => self::Extension|method1<self::Extension|get#method1::T%>(#this);
-static method BoundExtension|method2<T extends self::Class = self::Class>(final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
+static method BoundExtension|method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|method2::T #this) → self::BoundExtension|method2::T
   return #this;
-static method BoundExtension|get#method2<T extends self::Class = self::Class>(final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
+static method BoundExtension|get#method2<T extends self::Class = self::Class>(lowered final self::BoundExtension|get#method2::T #this) → () → self::BoundExtension|get#method2::T
   return () → self::BoundExtension|get#method2::T => self::BoundExtension|method2<self::BoundExtension|get#method2::T>(#this);
 static method test1<T extends core::Object? = dynamic>(self::test1::T% t1) → self::Class {
   if(t1 is{ForNonNullableByDefault} self::SubClass) {
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
index cfe4af3..c6344c1 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
@@ -9,7 +9,6 @@
     final asy::_Future<self::TestMixin::T%> :async_future = new asy::_Future::•<self::TestMixin::T%>();
     core::bool* :is_sync = false;
     FutureOr<self::TestMixin::T%>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -45,7 +44,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -79,7 +77,6 @@
     final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
     core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -115,7 +112,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -140,7 +136,6 @@
     final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
     core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -176,7 +171,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
index cfe4af3..c6344c1 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
@@ -9,7 +9,6 @@
     final asy::_Future<self::TestMixin::T%> :async_future = new asy::_Future::•<self::TestMixin::T%>();
     core::bool* :is_sync = false;
     FutureOr<self::TestMixin::T%>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -45,7 +44,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -79,7 +77,6 @@
     final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
     core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -115,7 +112,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -140,7 +136,6 @@
     final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
     core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -176,7 +171,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect
index fb834d9..da98632 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect
@@ -222,29 +222,29 @@
   ;
 static set property3(core::int value) → void
   ;
-static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(lowered final core::int #this) → core::int
   ;
-static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(final core::int #this, core::int i) → void
+static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(lowered final core::int #this, core::int i) → void
   ;
-static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(final core::int #this) → core::int
+static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(lowered final core::int #this) → core::int
   ;
-static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(final core::int #this, core::num i) → void
+static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(lowered final core::int #this, core::num i) → void
   ;
-static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(final core::int #this) → core::num
+static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(lowered final core::int #this) → core::num
   ;
-static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(final core::int #this, core::int i) → void
+static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(lowered final core::int #this, core::int i) → void
   ;
-static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(final core::int #this) → self::Extension|get#property4::S%
+static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property4::S%
   ;
-static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(final core::int #this, self::Extension|set#property4::S% i) → void
+static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(lowered final core::int #this, self::Extension|set#property4::S% i) → void
   ;
-static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(final core::int #this) → self::Extension|get#property5::S%
+static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property5::S%
   ;
-static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(final core::int #this, self::Extension|set#property5::T% i) → void
+static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(lowered final core::int #this, self::Extension|set#property5::T% i) → void
   ;
-static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(final core::int #this) → self::Extension|get#property6::T%
+static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property6::T%
   ;
-static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(final core::int #this, self::Extension|set#property6::S% i) → void
+static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(lowered final core::int #this, self::Extension|set#property6::S% i) → void
   ;
 static get Extension|property7() → core::int
   ;
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect
index f346415..f2f3537 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect
@@ -237,30 +237,30 @@
 static get property3() → core::num
   return 0;
 static set property3(core::int value) → void {}
-static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(final core::int #this, core::int i) → void {}
-static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(final core::int #this) → core::int
+static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(final core::int #this, core::num i) → void {}
-static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(final core::int #this) → core::num
+static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(lowered final core::int #this, core::num i) → void {}
+static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(lowered final core::int #this) → core::num
   return 0;
-static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(final core::int #this, core::int i) → void {}
-static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(final core::int #this) → self::Extension|get#property4::S%
+static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property4::S%
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:130:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
   S get property4 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(final core::int #this, self::Extension|set#property4::S% i) → void {}
-static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(final core::int #this) → self::Extension|get#property5::S%
+static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(lowered final core::int #this, self::Extension|set#property4::S% i) → void {}
+static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property5::S%
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
   S get property5 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(final core::int #this, self::Extension|set#property5::T% i) → void {}
-static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(final core::int #this) → self::Extension|get#property6::T%
+static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(lowered final core::int #this, self::Extension|set#property5::T% i) → void {}
+static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property6::T%
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property6 => 0; // error
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(final core::int #this, self::Extension|set#property6::S% i) → void {}
+static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(lowered final core::int #this, self::Extension|set#property6::S% i) → void {}
 static get Extension|property7() → core::int
   return 0;
 static set Extension|property7(core::int value) → void {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect
index f346415..f2f3537 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect
@@ -237,30 +237,30 @@
 static get property3() → core::num
   return 0;
 static set property3(core::int value) → void {}
-static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(final core::int #this, core::int i) → void {}
-static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(final core::int #this) → core::int
+static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(final core::int #this, core::num i) → void {}
-static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(final core::int #this) → core::num
+static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(lowered final core::int #this, core::num i) → void {}
+static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(lowered final core::int #this) → core::num
   return 0;
-static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(final core::int #this, core::int i) → void {}
-static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(final core::int #this) → self::Extension|get#property4::S%
+static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property4::S%
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:130:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
   S get property4 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(final core::int #this, self::Extension|set#property4::S% i) → void {}
-static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(final core::int #this) → self::Extension|get#property5::S%
+static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(lowered final core::int #this, self::Extension|set#property4::S% i) → void {}
+static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property5::S%
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
   S get property5 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(final core::int #this, self::Extension|set#property5::T% i) → void {}
-static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(final core::int #this) → self::Extension|get#property6::T%
+static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(lowered final core::int #this, self::Extension|set#property5::T% i) → void {}
+static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(lowered final core::int #this) → self::Extension|get#property6::T%
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property6 => 0; // error
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(final core::int #this, self::Extension|set#property6::S% i) → void {}
+static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(lowered final core::int #this, self::Extension|set#property6::S% i) → void {}
 static get Extension|property7() → core::int
   return 0;
 static set Extension|property7(core::int value) → void {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect
index 763d5e7..ced9893 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect
@@ -224,33 +224,33 @@
   ;
 static set property3(core::int value) → void
   ;
-static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::num = core::num>(lowered final core::int #this) → core::int
   ;
-static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void
+static method Extension|set#property1<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void
   ;
-static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|get#property2<T extends core::num = core::num>(lowered final core::int #this) → core::int
   ;
-static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void
+static method Extension|set#property2<T extends core::num = core::num>(lowered final core::int #this, core::int? i) → void
   ;
-static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+static method Extension|get#property3<T extends core::num = core::num>(lowered final core::int #this) → core::int?
   ;
-static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void
+static method Extension|set#property3<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void
   ;
-static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+static method Extension|get#property4a<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4a::T
   ;
-static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void
+static method Extension|set#property4a<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4a::T i) → void
   ;
-static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+static method Extension|get#property4b<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4b::T?
   ;
-static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void
+static method Extension|set#property4b<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4b::T? i) → void
   ;
-static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+static method Extension|get#property5<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property5::T
   ;
-static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void
+static method Extension|set#property5<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property5::T? i) → void
   ;
-static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+static method Extension|get#property6<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property6::T?
   ;
-static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void
+static method Extension|set#property6<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property6::T i) → void
   ;
 static get Extension|property7() → core::int
   ;
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect
index 40207f8..93b128d 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect
@@ -243,35 +243,35 @@
 static get property3() → core::int?
   return 0;
 static set property3(core::int value) → void {}
-static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|set#property1<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
-static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+static method Extension|set#property2<T extends core::num = core::num>(lowered final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(lowered final core::int #this) → core::int?
   return 0;
-static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+static method Extension|set#property3<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4a::T
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property4a => 0; // ok
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
-static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+static method Extension|set#property4a<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4b::T?
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property4b => 0; // ok
                        ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
-static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+static method Extension|set#property4b<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property5::T
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property5 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
-static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+static method Extension|set#property5<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property6::T?
   return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property6 => 0; // error
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static method Extension|set#property6<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property6::T i) → void {}
 static get Extension|property7() → core::int
   return 0;
 static set Extension|property7(core::int value) → void {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect
index 40207f8..93b128d 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect
@@ -243,35 +243,35 @@
 static get property3() → core::int?
   return 0;
 static set property3(core::int value) → void {}
-static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|set#property1<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
-static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+static method Extension|set#property2<T extends core::num = core::num>(lowered final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(lowered final core::int #this) → core::int?
   return 0;
-static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+static method Extension|set#property3<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4a::T
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property4a => 0; // ok
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
-static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+static method Extension|set#property4a<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4b::T?
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property4b => 0; // ok
                        ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
-static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+static method Extension|set#property4b<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property5::T
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property5 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
-static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+static method Extension|set#property5<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property6::T?
   return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property6 => 0; // error
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static method Extension|set#property6<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property6::T i) → void {}
 static get Extension|property7() → core::int
   return 0;
 static set Extension|property7(core::int value) → void {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect
index 40207f8..93b128d 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect
@@ -243,35 +243,35 @@
 static get property3() → core::int?
   return 0;
 static set property3(core::int value) → void {}
-static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|set#property1<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
-static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+static method Extension|set#property2<T extends core::num = core::num>(lowered final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(lowered final core::int #this) → core::int?
   return 0;
-static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+static method Extension|set#property3<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4a::T
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property4a => 0; // ok
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
-static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+static method Extension|set#property4a<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4b::T?
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property4b => 0; // ok
                        ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
-static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+static method Extension|set#property4b<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property5::T
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property5 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
-static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+static method Extension|set#property5<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property6::T?
   return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property6 => 0; // error
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static method Extension|set#property6<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property6::T i) → void {}
 static get Extension|property7() → core::int
   return 0;
 static set Extension|property7(core::int value) → void {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect
index 40207f8..93b128d 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect
@@ -243,35 +243,35 @@
 static get property3() → core::int?
   return 0;
 static set property3(core::int value) → void {}
-static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|get#property1<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+static method Extension|set#property1<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(lowered final core::int #this) → core::int
   return 0;
-static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
-static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+static method Extension|set#property2<T extends core::num = core::num>(lowered final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(lowered final core::int #this) → core::int?
   return 0;
-static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
-static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+static method Extension|set#property3<T extends core::num = core::num>(lowered final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4a::T
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property4a => 0; // ok
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
-static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+static method Extension|set#property4a<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property4b::T?
   return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property4b => 0; // ok
                        ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
-static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+static method Extension|set#property4b<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property5::T
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
   T get property5 => 0; // ok
                      ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
-static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+static method Extension|set#property5<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(lowered final core::int #this) → self::Extension|get#property6::T?
   return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
   T? get property6 => 0; // error
                       ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
-static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static method Extension|set#property6<T extends core::num = core::num>(lowered final core::int #this, self::Extension|set#property6::T i) → void {}
 static get Extension|property7() → core::int
   return 0;
 static set Extension|property7(core::int value) → void {}
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.outline.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.outline.expect
index 1c9be60..2a3948c 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.outline.expect
@@ -41,9 +41,9 @@
   ;
 static method test4() → dynamic
   ;
-static method E6|[]=(final core::double #this, core::int index, core::String? value) → void
+static method E6|[]=(lowered final core::double #this, core::int index, core::String? value) → void
   ;
-static method E6|[](final core::double #this, core::int index) → core::String?
+static method E6|[](lowered final core::double #this, core::int index) → core::String?
   ;
 static method test6() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect
index ac0794c..65650a7 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect
@@ -56,8 +56,8 @@
   core::List<core::String?> list = <core::String?>[null];
   core::String s = let final core::List<core::String?> #t10 = list in let final core::int #t11 = 0 in let final core::String? #t12 = #t10.{core::List::[]}(#t11) in #t12.{core::String::==}(null) ?{core::String} let final core::String #t13 = "bar" in let final void #t14 = #t10.{core::List::[]=}(#t11, #t13) in #t13 : #t12{core::String};
 }
-static method E6|[]=(final core::double #this, core::int index, core::String? value) → void {}
-static method E6|[](final core::double #this, core::int index) → core::String?
+static method E6|[]=(lowered final core::double #this, core::int index, core::String? value) → void {}
+static method E6|[](lowered final core::double #this, core::int index) → core::String?
   return null;
 static method test6() → dynamic {
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect
index 571f848..c4ec443 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect
@@ -56,8 +56,8 @@
   core::List<core::String?> list = <core::String?>[null];
   core::String s = let final core::List<core::String?> #t10 = list in let final core::int #t11 = 0 in let final core::String? #t12 = #t10.{core::List::[]}(#t11) in #t12.{core::String::==}(null) ?{core::String} let final core::String #t13 = "bar" in let final void #t14 = #t10.{core::List::[]=}(#t11, #t13) in #t13 : #t12{core::String};
 }
-static method E6|[]=(final core::double #this, core::int index, core::String? value) → void {}
-static method E6|[](final core::double #this, core::int index) → core::String?
+static method E6|[]=(lowered final core::double #this, core::int index, core::String? value) → void {}
+static method E6|[](lowered final core::double #this, core::int index) → core::String?
   return null;
 static method test6() → dynamic {
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect
index ac0794c..65650a7 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect
@@ -56,8 +56,8 @@
   core::List<core::String?> list = <core::String?>[null];
   core::String s = let final core::List<core::String?> #t10 = list in let final core::int #t11 = 0 in let final core::String? #t12 = #t10.{core::List::[]}(#t11) in #t12.{core::String::==}(null) ?{core::String} let final core::String #t13 = "bar" in let final void #t14 = #t10.{core::List::[]=}(#t11, #t13) in #t13 : #t12{core::String};
 }
-static method E6|[]=(final core::double #this, core::int index, core::String? value) → void {}
-static method E6|[](final core::double #this, core::int index) → core::String?
+static method E6|[]=(lowered final core::double #this, core::int index, core::String? value) → void {}
+static method E6|[](lowered final core::double #this, core::int index) → core::String?
   return null;
 static method test6() → dynamic {
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect
index 571f848..c4ec443 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect
@@ -56,8 +56,8 @@
   core::List<core::String?> list = <core::String?>[null];
   core::String s = let final core::List<core::String?> #t10 = list in let final core::int #t11 = 0 in let final core::String? #t12 = #t10.{core::List::[]}(#t11) in #t12.{core::String::==}(null) ?{core::String} let final core::String #t13 = "bar" in let final void #t14 = #t10.{core::List::[]=}(#t11, #t13) in #t13 : #t12{core::String};
 }
-static method E6|[]=(final core::double #this, core::int index, core::String? value) → void {}
-static method E6|[](final core::double #this, core::int index) → core::String?
+static method E6|[]=(lowered final core::double #this, core::int index, core::String? value) → void {}
+static method E6|[](lowered final core::double #this, core::int index) → core::String?
   return null;
 static method test6() → dynamic {
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
diff --git a/pkg/front_end/testcases/nnbd/issue40954.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue40954.dart.outline.expect
index c6641b9..35e6233 100644
--- a/pkg/front_end/testcases/nnbd/issue40954.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue40954.dart.outline.expect
@@ -2,33 +2,39 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test1(var v, [A a]) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test2(var v, {A a}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test11(var v, [A a]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test22(var v, {A a}) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test1(var v, [A a]) {}
 //                      ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test2(var v, {A a}) {}
 //                      ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue40954.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue40954.dart.strong.expect
index e94c384..cbfe037 100644
--- a/pkg/front_end/testcases/nnbd/issue40954.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue40954.dart.strong.expect
@@ -2,33 +2,39 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test1(var v, [A a]) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test2(var v, {A a}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test11(var v, [A a]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test22(var v, {A a}) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test1(var v, [A a]) {}
 //                      ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test2(var v, {A a}) {}
 //                      ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue40954.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue40954.dart.strong.transformed.expect
index e94c384..cbfe037 100644
--- a/pkg/front_end/testcases/nnbd/issue40954.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue40954.dart.strong.transformed.expect
@@ -2,33 +2,39 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test1(var v, [A a]) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test2(var v, {A a}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test11(var v, [A a]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test22(var v, {A a}) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test1(var v, [A a]) {}
 //                      ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test2(var v, {A a}) {}
 //                      ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue40954.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue40954.dart.weak.expect
index e94c384..cbfe037 100644
--- a/pkg/front_end/testcases/nnbd/issue40954.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue40954.dart.weak.expect
@@ -2,33 +2,39 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test1(var v, [A a]) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test2(var v, {A a}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test11(var v, [A a]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test22(var v, {A a}) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test1(var v, [A a]) {}
 //                      ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test2(var v, {A a}) {}
 //                      ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue40954.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue40954.dart.weak.transformed.expect
index e94c384..cbfe037 100644
--- a/pkg/front_end/testcases/nnbd/issue40954.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue40954.dart.weak.transformed.expect
@@ -2,33 +2,39 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:8:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test1(var v, [A a]) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:10:31: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   static void test2(var v, {A a}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:12:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test11(var v, [A a]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:14:25: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void test22(var v, {A a}) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:17:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test1(var v, [A a]) {}
 //                      ^
 //
-// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: Optional parameter 'a' should have a default value because its type 'A' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue40954.dart:19:22: Error: The parameter 'a' can't have a value of 'null' because of its type 'A', but the implicit default value is 'null'.
 //  - 'A' is from 'pkg/front_end/testcases/nnbd/issue40954.dart'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void test2(var v, {A a}) {}
 //                      ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart b/pkg/front_end/testcases/nnbd/issue41102.dart
index a237a56..47353c0 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart
@@ -14,7 +14,7 @@
 
 final s2 = s1?.length;
 
-final s3 = new List<int>(2);
+final s3 = new List<int>.filled(2, null);
 
 final s4 = () {
   var e = 0;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
index 6c3640f..bd670ca 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in null as{TypeError,ForNonNullableByDefault} core::int);
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index 55a469e..0ee6323 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::_List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::_List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in let Null #t3 = null in #t3.==(null) ?{core::int} #t3 as{TypeError,ForNonNullableByDefault} core::int : #t3{core::int});
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
@@ -90,33 +88,33 @@
   }
 }).call();
 static field core::int? s5;
-static final field core::num s6 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:31:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+static final field core::num s6 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:31:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
 final s6 = s5 + 0;
               ^" in self::s5.{core::num::+}(0);
 static field core::List<dynamic>? s7;
-static final field dynamic s8 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:35:14: Error: Operator '[]' cannot be called on 'List<dynamic>?' because it is potentially null.
+static final field dynamic s8 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:35:14: Error: Operator '[]' cannot be called on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 final s8 = s7[0];
              ^" in self::s7.{core::List::[]}(0);
-static final field core::int s9 = let final core::List<dynamic>? #t5 = self::s7 in let final core::int #t6 = 0 in let final core::int #t7 = 0 in let final void #t8 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:37:14: Error: Operator '[]=' cannot be called on 'List<dynamic>?' because it is potentially null.
+static final field core::int s9 = let final core::List<dynamic>? #t6 = self::s7 in let final core::int #t7 = 0 in let final core::int #t8 = 0 in let final void #t9 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:37:14: Error: Operator '[]=' cannot be called on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 final s9 = s7[0] = 0;
-             ^" in #t5.{core::List::[]=}(#t6, #t7) in #t7;
-static final field core::int s10 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:39:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+             ^" in #t6.{core::List::[]=}(#t7, #t8) in #t8;
+static final field core::int s10 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:39:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
 final s10 = s7.length;
                ^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
 final s11 = s7.length = 0;
                ^^^^^^" in self::s7.{core::List::length} = 0;
-static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+static final field core::int s12 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 final s12 = -s5;
             ^" in self::s5.{core::int::unary-}();
 static field () →? core::int s13;
-static final field core::int s14 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:47:18: Error: Can't use an expression of type 'int Function()?' as a function because it's potentially null.
+static final field core::int s14 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:47:18: Error: Can't use an expression of type 'int Function()?' as a function because it's potentially null.
 Try calling using ?.call instead.
 final s14 = (s13)();
                  ^" in self::s13.call();
@@ -132,7 +130,10 @@
 }
 
 Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///issue41102.dart:17:36 -> BoolConstant(true)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:17:36 -> NullConstant(null)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:17:36 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:15 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:20 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:20 -> IntConstant(0)
-Extra constant evaluation: evaluated: 55, effectively constant: 3
+Extra constant evaluation: evaluated: 61, effectively constant: 6
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
index 841a03e..39804ba 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
@@ -6,7 +6,7 @@
     handleDone: (sink) => Future.microtask(() => sink.close()));
 final s1 = [];
 final s2 = s1?.length;
-final s3 = new List<int>(2);
+final s3 = new List<int>.filled(2, null);
 final s4 = () {
   var e = 0;
   switch (e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
index 35fb63f..004471b 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
@@ -8,7 +8,7 @@
 final s14 = (s13)();
 final s15 = throw null;
 final s2 = s1?.length;
-final s3 = new List<int>(2);
+final s3 = new List<int>.filled(2, null);
 final s4 = () {
   var e = 0;
   switch (e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
index 6c3640f..bd670ca 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in null as{TypeError,ForNonNullableByDefault} core::int);
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index 55a469e..61062c1 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::_List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::_List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in null);
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
index 50e24cb..eddf0ff 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
@@ -16,7 +16,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -39,7 +38,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
index 8631965..af24560 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
@@ -16,7 +16,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -39,7 +38,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
index 0d0a5f6..5f03cd5 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
@@ -7,7 +7,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -27,7 +26,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
index 0d0a5f6..5f03cd5 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
@@ -7,7 +7,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -27,7 +26,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
index 2d5c92d..3e9bef1 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
@@ -59,7 +59,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -77,7 +76,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -88,7 +86,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -105,7 +102,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -116,7 +112,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -134,7 +129,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -145,7 +139,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -163,7 +156,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -174,7 +166,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -191,7 +182,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -202,7 +192,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -220,7 +209,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -232,7 +220,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -285,7 +272,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -310,7 +296,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -321,7 +306,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -347,7 +331,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -358,7 +341,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -383,7 +365,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -394,7 +375,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -420,7 +400,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -434,7 +413,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
index f657157..e3ff8f7 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
@@ -60,7 +60,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -78,7 +77,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -89,7 +87,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -106,7 +103,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -117,7 +113,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -135,7 +130,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -146,7 +140,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -164,7 +157,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -175,7 +167,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -192,7 +183,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -203,7 +193,6 @@
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -221,7 +210,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -233,7 +221,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -286,7 +273,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -311,7 +297,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -322,7 +307,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -348,7 +332,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -359,7 +342,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -384,7 +366,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -395,7 +376,6 @@
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -421,7 +401,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -435,7 +414,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
index 15071a6e..6aa4264 100644
--- a/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.outline.expect
@@ -22,21 +22,21 @@
   method call = self::D|call;
   tearoff call = self::D|get#call;
 }
-static method B|foo(final self::A? #this) → dynamic
+static method B|foo(lowered final self::A? #this) → dynamic
   ;
-static method B|get#foo(final self::A? #this) → () → dynamic
+static method B|get#foo(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|foo(#this);
-static method B|bar(final self::A? #this) → dynamic
+static method B|bar(lowered final self::A? #this) → dynamic
   ;
-static method B|get#bar(final self::A? #this) → () → dynamic
+static method B|get#bar(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|bar(#this);
-static method C|bar(final self::A #this) → dynamic
+static method C|bar(lowered final self::A #this) → dynamic
   ;
-static method C|get#bar(final self::A #this) → () → dynamic
+static method C|get#bar(lowered final self::A #this) → () → dynamic
   return () → dynamic => self::C|bar(#this);
-static method D|call(final () →? core::int #this) → core::int
+static method D|call(lowered final () →? core::int #this) → core::int
   ;
-static method D|get#call(final () →? core::int #this) → () → core::int
+static method D|get#call(lowered final () →? core::int #this) → () → core::int
   return () → core::int => self::D|call(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
index 750eec3..e517198 100644
--- a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.expect
@@ -23,21 +23,21 @@
   method call = self::D|call;
   tearoff call = self::D|get#call;
 }
-static method B|foo(final self::A? #this) → dynamic
+static method B|foo(lowered final self::A? #this) → dynamic
   return 42;
-static method B|get#foo(final self::A? #this) → () → dynamic
+static method B|get#foo(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|foo(#this);
-static method B|bar(final self::A? #this) → dynamic
+static method B|bar(lowered final self::A? #this) → dynamic
   return 87;
-static method B|get#bar(final self::A? #this) → () → dynamic
+static method B|get#bar(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|bar(#this);
-static method C|bar(final self::A #this) → dynamic
+static method C|bar(lowered final self::A #this) → dynamic
   return 123;
-static method C|get#bar(final self::A #this) → () → dynamic
+static method C|get#bar(lowered final self::A #this) → () → dynamic
   return () → dynamic => self::C|bar(#this);
-static method D|call(final () →? core::int #this) → core::int
+static method D|call(lowered final () →? core::int #this) → core::int
   return 76;
-static method D|get#call(final () →? core::int #this) → () → core::int
+static method D|get#call(lowered final () →? core::int #this) → () → core::int
   return () → core::int => self::D|call(#this);
 static method main() → dynamic {
   self::testA(new self::A::•());
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
index 750eec3..e517198 100644
--- a/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.strong.transformed.expect
@@ -23,21 +23,21 @@
   method call = self::D|call;
   tearoff call = self::D|get#call;
 }
-static method B|foo(final self::A? #this) → dynamic
+static method B|foo(lowered final self::A? #this) → dynamic
   return 42;
-static method B|get#foo(final self::A? #this) → () → dynamic
+static method B|get#foo(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|foo(#this);
-static method B|bar(final self::A? #this) → dynamic
+static method B|bar(lowered final self::A? #this) → dynamic
   return 87;
-static method B|get#bar(final self::A? #this) → () → dynamic
+static method B|get#bar(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|bar(#this);
-static method C|bar(final self::A #this) → dynamic
+static method C|bar(lowered final self::A #this) → dynamic
   return 123;
-static method C|get#bar(final self::A #this) → () → dynamic
+static method C|get#bar(lowered final self::A #this) → () → dynamic
   return () → dynamic => self::C|bar(#this);
-static method D|call(final () →? core::int #this) → core::int
+static method D|call(lowered final () →? core::int #this) → core::int
   return 76;
-static method D|get#call(final () →? core::int #this) → () → core::int
+static method D|get#call(lowered final () →? core::int #this) → () → core::int
   return () → core::int => self::D|call(#this);
 static method main() → dynamic {
   self::testA(new self::A::•());
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
index 750eec3..e517198 100644
--- a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.expect
@@ -23,21 +23,21 @@
   method call = self::D|call;
   tearoff call = self::D|get#call;
 }
-static method B|foo(final self::A? #this) → dynamic
+static method B|foo(lowered final self::A? #this) → dynamic
   return 42;
-static method B|get#foo(final self::A? #this) → () → dynamic
+static method B|get#foo(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|foo(#this);
-static method B|bar(final self::A? #this) → dynamic
+static method B|bar(lowered final self::A? #this) → dynamic
   return 87;
-static method B|get#bar(final self::A? #this) → () → dynamic
+static method B|get#bar(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|bar(#this);
-static method C|bar(final self::A #this) → dynamic
+static method C|bar(lowered final self::A #this) → dynamic
   return 123;
-static method C|get#bar(final self::A #this) → () → dynamic
+static method C|get#bar(lowered final self::A #this) → () → dynamic
   return () → dynamic => self::C|bar(#this);
-static method D|call(final () →? core::int #this) → core::int
+static method D|call(lowered final () →? core::int #this) → core::int
   return 76;
-static method D|get#call(final () →? core::int #this) → () → core::int
+static method D|get#call(lowered final () →? core::int #this) → () → core::int
   return () → core::int => self::D|call(#this);
 static method main() → dynamic {
   self::testA(new self::A::•());
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
index 750eec3..e517198 100644
--- a/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.weak.transformed.expect
@@ -23,21 +23,21 @@
   method call = self::D|call;
   tearoff call = self::D|get#call;
 }
-static method B|foo(final self::A? #this) → dynamic
+static method B|foo(lowered final self::A? #this) → dynamic
   return 42;
-static method B|get#foo(final self::A? #this) → () → dynamic
+static method B|get#foo(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|foo(#this);
-static method B|bar(final self::A? #this) → dynamic
+static method B|bar(lowered final self::A? #this) → dynamic
   return 87;
-static method B|get#bar(final self::A? #this) → () → dynamic
+static method B|get#bar(lowered final self::A? #this) → () → dynamic
   return () → dynamic => self::B|bar(#this);
-static method C|bar(final self::A #this) → dynamic
+static method C|bar(lowered final self::A #this) → dynamic
   return 123;
-static method C|get#bar(final self::A #this) → () → dynamic
+static method C|get#bar(lowered final self::A #this) → () → dynamic
   return () → dynamic => self::C|bar(#this);
-static method D|call(final () →? core::int #this) → core::int
+static method D|call(lowered final () →? core::int #this) → core::int
   return 76;
-static method D|get#call(final () →? core::int #this) → () → core::int
+static method D|get#call(lowered final () →? core::int #this) → () → core::int
   return () → core::int => self::D|call(#this);
 static method main() → dynamic {
   self::testA(new self::A::•());
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
index 049ebe6..b4ab7d2 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
@@ -37,7 +37,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -55,7 +54,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -66,7 +64,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -84,7 +81,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -95,7 +91,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -115,7 +110,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -130,7 +124,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -150,7 +143,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -168,7 +160,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -186,7 +177,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -197,7 +187,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -210,7 +199,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -230,7 +218,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -245,7 +232,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -265,7 +251,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -283,7 +268,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -301,7 +285,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -315,7 +298,6 @@
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -335,7 +317,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -351,7 +332,6 @@
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -371,7 +351,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -387,7 +366,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -405,7 +383,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -419,7 +396,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
index 049ebe6..b4ab7d2 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
@@ -37,7 +37,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -55,7 +54,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -66,7 +64,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -84,7 +81,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -95,7 +91,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -115,7 +110,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -130,7 +124,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -150,7 +143,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -168,7 +160,6 @@
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -186,7 +177,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -197,7 +187,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -210,7 +199,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -230,7 +218,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -245,7 +232,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -265,7 +251,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -283,7 +268,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -301,7 +285,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -315,7 +298,6 @@
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -335,7 +317,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -351,7 +332,6 @@
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -371,7 +351,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -387,7 +366,6 @@
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -405,7 +383,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -419,7 +396,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
index fb81d0d..1cc9b7b 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
@@ -146,7 +146,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -291,7 +290,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
index fb81d0d..1cc9b7b 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
@@ -146,7 +146,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -291,7 +290,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
index 5bfffb3..6fa863c 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
@@ -46,7 +46,6 @@
 static method getStreamNull() → asy::Stream<dynamic> /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -71,7 +70,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -81,7 +79,6 @@
 static method getStreamBool() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -106,7 +103,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -116,7 +112,6 @@
 static method test1() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -141,7 +136,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -155,7 +149,6 @@
 static method test4() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -183,7 +176,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -200,7 +192,6 @@
 static method test7() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -225,7 +216,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -236,7 +226,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -248,7 +237,6 @@
         function test1() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -273,7 +261,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -287,7 +274,6 @@
         function test4() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -315,7 +301,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -332,7 +317,6 @@
         function test7() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -357,7 +341,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -370,7 +353,6 @@
     ^" in (() → asy::Stream<dynamic> /* originally async* */ {
           asy::_AsyncStarStreamController<dynamic>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -395,7 +377,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -410,7 +391,6 @@
     ^" in (() → asy::Stream<dynamic> /* originally async* */ {
           asy::_AsyncStarStreamController<dynamic>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -435,7 +415,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -450,7 +429,6 @@
         asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -475,7 +453,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -489,7 +466,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
index 5bfffb3..6fa863c 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
@@ -46,7 +46,6 @@
 static method getStreamNull() → asy::Stream<dynamic> /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -71,7 +70,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -81,7 +79,6 @@
 static method getStreamBool() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -106,7 +103,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -116,7 +112,6 @@
 static method test1() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -141,7 +136,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -155,7 +149,6 @@
 static method test4() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -183,7 +176,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -200,7 +192,6 @@
 static method test7() → asy::Stream<core::bool> /* originally async* */ {
   asy::_AsyncStarStreamController<core::bool>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -225,7 +216,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -236,7 +226,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -248,7 +237,6 @@
         function test1() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -273,7 +261,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -287,7 +274,6 @@
         function test4() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -315,7 +301,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -332,7 +317,6 @@
         function test7() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -357,7 +341,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -370,7 +353,6 @@
     ^" in (() → asy::Stream<dynamic> /* originally async* */ {
           asy::_AsyncStarStreamController<dynamic>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -395,7 +377,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -410,7 +391,6 @@
     ^" in (() → asy::Stream<dynamic> /* originally async* */ {
           asy::_AsyncStarStreamController<dynamic>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -435,7 +415,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -450,7 +429,6 @@
         asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> /* originally async* */ {
           asy::_AsyncStarStreamController<core::bool>? :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -475,7 +453,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
@@ -489,7 +466,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
index 1add5c8..e85bc0e 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
@@ -19,7 +19,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -34,7 +33,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -46,7 +44,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -61,7 +58,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -72,7 +68,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -93,7 +88,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -104,7 +98,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -123,7 +116,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
index 1add5c8..e85bc0e 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
@@ -19,7 +19,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -34,7 +33,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -46,7 +44,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -61,7 +58,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -72,7 +68,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -93,7 +88,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -104,7 +98,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -123,7 +116,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
index af60f0b..b287a57 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
@@ -38,7 +38,6 @@
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -58,7 +57,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -76,7 +74,6 @@
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -99,7 +96,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
index af60f0b..b287a57 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
@@ -38,7 +38,6 @@
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -58,7 +57,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -76,7 +74,6 @@
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -99,7 +96,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.outline.expect
index 8b438e7..dbb74c3 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.outline.expect
@@ -2,67 +2,83 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([int i]) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({int i}) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor3([int i]) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor4({int i}) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory8([int i]) => new A.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory9({int i}) => new A.constructor4(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([i]) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({i}) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor3([int i]) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor4({int i}) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory8([int i]) => new C.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory9({int i}) => new C.constructor4(); // error
 //                           ^
 //
@@ -71,7 +87,7 @@
 
 class A extends core::Object {
   final field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isLegacy*/;
   constructor constructor1([core::int i]) → self::A
     ;
   constructor constructor2({core::int i}) → self::A
@@ -129,7 +145,7 @@
 }
 class C extends core::Object implements self::B {
   field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isLegacy*/;
   constructor constructor1([core::int i]) → self::C
     ;
   constructor constructor2({core::int i}) → self::C
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect
index 62f2fb2..327d48b 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect
@@ -2,67 +2,83 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([int i]) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({int i}) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor3([int i]) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor4({int i}) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory8([int i]) => new A.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory9({int i}) => new A.constructor4(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([i]) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({i}) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor3([int i]) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor4({int i}) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory8([int i]) => new C.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory9({int i}) => new C.constructor4(); // error
 //                           ^
 //
@@ -87,7 +103,7 @@
 
 class A extends core::Object {
   final field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::A
     : self::A::i = i, super core::Object::•()
     ;
@@ -154,7 +170,7 @@
 }
 class C extends core::Object implements self::B {
   field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::C
     : self::C::i = i, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
index a58e129..d74b206 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
@@ -2,67 +2,83 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([int i]) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({int i}) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor3([int i]) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor4({int i}) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory8([int i]) => new A.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory9({int i}) => new A.constructor4(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([i]) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({i}) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor3([int i]) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor4({int i}) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory8([int i]) => new C.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory9({int i}) => new C.constructor4(); // error
 //                           ^
 //
@@ -87,7 +103,7 @@
 
 class A extends core::Object {
   final field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::A
     : self::A::i = i, super core::Object::•()
     ;
@@ -154,7 +170,7 @@
 }
 class C extends core::Object implements self::B {
   field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::C
     : self::C::i = i, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect
index 62f2fb2..327d48b 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect
@@ -2,67 +2,83 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([int i]) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({int i}) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor3([int i]) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor4({int i}) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory8([int i]) => new A.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory9({int i}) => new A.constructor4(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([i]) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({i}) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor3([int i]) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor4({int i}) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory8([int i]) => new C.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory9({int i}) => new C.constructor4(); // error
 //                           ^
 //
@@ -87,7 +103,7 @@
 
 class A extends core::Object {
   final field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::A
     : self::A::i = i, super core::Object::•()
     ;
@@ -154,7 +170,7 @@
 }
 class C extends core::Object implements self::B {
   field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::C
     : self::C::i = i, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect
index 33d6b11..9e8520e 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect
@@ -2,67 +2,83 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:45:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([int i]) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:47:16: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({int i}) {} // error
 //                ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:8:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:10:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:12:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor3([int i]) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:15:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   A.constructor4({int i}) // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:41:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory8([int i]) => new A.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:43:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory A.factory9({int i}) => new A.constructor4(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:106:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method3([i]) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:108:12: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   method4({i}) {} // error
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:77:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor1([this.i]); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:79:24: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor2({this.i}); // error
 //                        ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:81:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor3([int i]) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:83:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.constructor4({int i}) : this.i = i; // error
 //                       ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:102:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory8([int i]) => new C.constructor3(); // error
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue42362.dart:104:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.factory9({int i}) => new C.constructor4(); // error
 //                           ^
 //
@@ -87,7 +103,7 @@
 
 class A extends core::Object {
   final field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::factory3, self::A::factory4, self::A::factory5, self::A::factory6, self::A::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::A
     : self::A::i = i, super core::Object::•()
     ;
@@ -154,7 +170,7 @@
 }
 class C extends core::Object implements self::B {
   field core::int i;
-  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::factory3, self::C::factory4, self::C::factory5, self::C::factory6, self::C::factory7]/*isLegacy*/;
   constructor constructor1([core::int i = #C1]) → self::C
     : self::C::i = i, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
index 630569b..4e127a6 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
@@ -9,7 +9,6 @@
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -31,7 +30,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
index d317b87..e61b30d 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
@@ -9,7 +9,6 @@
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -31,7 +30,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.outline.expect
index de61651..8826a30 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.outline.expect
@@ -28,19 +28,19 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:661:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:661:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:661:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:698:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:698:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:698:13 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:725:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:725:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:725:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:622:13 -> SymbolConstant(#then)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:622:13 -> SymbolConstant(#onError)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:709:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:709:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:709:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:709:13 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:664:13 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:664:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:664:13 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:701:13 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:701:13 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:701:13 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:728:13 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:728:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:728:13 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:625:13 -> SymbolConstant(#then)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:625:13 -> SymbolConstant(#onError)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:712:13 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:712:13 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:712:13 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:712:13 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
 Extra constant evaluation: evaluated: 61, effectively constant: 15
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.outline.expect
index 930703f..926252c 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.outline.expect
@@ -9,7 +9,7 @@
 // pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   bool operator ==() => true;
 //                 ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect
index e677ee5..2d987ac 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect
@@ -9,7 +9,7 @@
 // pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   bool operator ==() => true;
 //                 ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect
index e677ee5..2d987ac 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect
@@ -9,7 +9,7 @@
 // pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
 //   bool operator ==() => true;
 //                 ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:17: Context: This is the overridden method ('==').
 //   bool operator ==(Object other) native "Object_equals";
 //                 ^
 //
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
index 47601b2..e489262 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
@@ -7,7 +7,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -25,7 +24,6 @@
           final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
           core::bool* :is_sync = false;
           FutureOr<core::int?>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -45,7 +43,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -59,7 +56,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
index 47601b2..e489262 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
@@ -7,7 +7,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -25,7 +24,6 @@
           final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
           core::bool* :is_sync = false;
           FutureOr<core::int?>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -45,7 +43,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -59,7 +56,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.strong.expect
index e18d2d3..5370148 100644
--- a/pkg/front_end/testcases/nnbd/issue42758.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42758.dart.strong.expect
@@ -80,230 +80,210 @@
 
 static method test1(Never n1, Never? n2, Null n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t1 = <Never>[];
-    for (final Never #t2 in n1)
-      #t1.{core::List::add}{Invariant}(#t2);
+    final core::List<Never> #t1 = core::List::of<Never>(n1);
   } =>#t1;
   core::List<Never> l2 = block {
-    final core::List<Never> #t3 = <Never>[];
-    final core::Iterable<Never>? #t4 = n1;
-    if(!#t4.{core::Object::==}(null))
-      for (final Never #t5 in #t4{core::Iterable<Never>})
-        #t3.{core::List::add}{Invariant}(#t5);
-  } =>#t3;
+    final core::List<Never> #t2 = <Never>[];
+    final core::Iterable<Never>? #t3 = n1;
+    if(!#t3.{core::Object::==}(null))
+      #t2.{core::List::addAll}{Invariant}(#t3{core::Iterable<Never>});
+  } =>#t2;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:8:16: Error: Can't spread a value with static type 'Never?'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t6 = <Never>[];
-    final core::Iterable<Never>? #t7 = n2;
-    if(!#t7.{core::Object::==}(null))
-      for (final Never #t8 in #t7{core::Iterable<Never>})
-        #t6.{core::List::add}{Invariant}(#t8);
-  } =>#t6;
+    final core::List<Never> #t4 = <Never>[];
+    final core::Iterable<Never>? #t5 = n2;
+    if(!#t5.{core::Object::==}(null))
+      #t4.{core::List::addAll}{Invariant}(#t5{core::Iterable<Never>});
+  } =>#t4;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:10:16: Error: Can't spread a value with static type 'Null'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t9 = <Never>[];
-    final core::Iterable<Never>? #t10 = n3;
-    if(!#t10.{core::Object::==}(null))
-      for (final Never #t11 in #t10{core::Iterable<Never>})
-        #t9.{core::List::add}{Invariant}(#t11);
-  } =>#t9;
+    final core::List<Never> #t6 = <Never>[];
+    final core::Iterable<Never>? #t7 = n3;
+    if(!#t7.{core::Object::==}(null))
+      #t6.{core::List::addAll}{Invariant}(#t7{core::Iterable<Never>});
+  } =>#t6;
   core::Set<Never> s1 = block {
-    final core::Set<Never> #t12 = col::LinkedHashSet::•<Never>();
-    for (final Never #t13 in n1)
-      #t12.{core::Set::add}{Invariant}(#t13);
-    #t12.{core::Set::add}{Invariant}(n1);
-  } =>#t12;
+    final core::Set<Never> #t8 = col::LinkedHashSet::of<Never>(n1);
+    #t8.{core::Set::add}{Invariant}(n1);
+  } =>#t8;
   core::Set<Never> s2 = block {
-    final core::Set<Never> #t14 = col::LinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t15 = n1;
-    if(!#t15.{core::Object::==}(null))
-      for (final Never #t16 in #t15{core::Iterable<Never>})
-        #t14.{core::Set::add}{Invariant}(#t16);
-    #t14.{core::Set::add}{Invariant}(n1);
-  } =>#t14;
+    final core::Set<Never> #t9 = col::LinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t10 = n1;
+    if(!#t10.{core::Object::==}(null))
+      #t9.{core::Set::addAll}{Invariant}(#t10{core::Iterable<Never>});
+    #t9.{core::Set::add}{Invariant}(n1);
+  } =>#t9;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t17 = col::LinkedHashSet::•<dynamic>();
-    #t17.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
+    final core::Set<dynamic> #t11 = col::LinkedHashSet::•<dynamic>();
+    #t11.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
   var s3 = {...n2, n1};
                ^");
-    #t17.{core::Set::add}{Invariant}(n1);
-  } =>#t17;
+    #t11.{core::Set::add}{Invariant}(n1);
+  } =>#t11;
   core::Set<Never> s4 = block {
-    final core::Set<Never> #t18 = col::LinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t19 = n2;
-    if(!#t19.{core::Object::==}(null))
-      for (final Never #t20 in #t19{core::Iterable<Never>})
-        #t18.{core::Set::add}{Invariant}(#t20);
-    #t18.{core::Set::add}{Invariant}(n1);
-  } =>#t18;
+    final core::Set<Never> #t12 = col::LinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t13 = n2;
+    if(!#t13.{core::Object::==}(null))
+      #t12.{core::Set::addAll}{Invariant}(#t13{core::Iterable<Never>});
+    #t12.{core::Set::add}{Invariant}(n1);
+  } =>#t12;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t21 = col::LinkedHashSet::•<dynamic>();
-    #t21.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
+    final core::Set<dynamic> #t14 = col::LinkedHashSet::•<dynamic>();
+    #t14.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
   var s5 = {...n3, n1};
                ^");
-    #t21.{core::Set::add}{Invariant}(n1);
-  } =>#t21;
+    #t14.{core::Set::add}{Invariant}(n1);
+  } =>#t14;
   core::Set<Never> s6 = block {
-    final core::Set<Never> #t22 = col::LinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t23 = n3;
-    if(!#t23.{core::Object::==}(null))
-      for (final Never #t24 in #t23{core::Iterable<Never>})
-        #t22.{core::Set::add}{Invariant}(#t24);
-    #t22.{core::Set::add}{Invariant}(n1);
-  } =>#t22;
+    final core::Set<Never> #t15 = col::LinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t16 = n3;
+    if(!#t16.{core::Object::==}(null))
+      #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<Never>});
+    #t15.{core::Set::add}{Invariant}(n1);
+  } =>#t15;
   core::Map<Never, Never> m1 = block {
-    final core::Map<Never, Never> #t25 = <Never, Never>{};
-    for (final core::MapEntry<Never, Never> #t26 in n1.{core::Map::entries})
-      #t25.{core::Map::[]=}{Invariant}(#t26.{core::MapEntry::key}, #t26.{core::MapEntry::value});
-    #t25.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t25;
+    final core::Map<Never, Never> #t17 = <Never, Never>{};
+    for (final core::MapEntry<Never, Never> #t18 in n1.{core::Map::entries})
+      #t17.{core::Map::[]=}{Invariant}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
+    #t17.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t17;
   core::Map<Never, Never> m2 = block {
-    final core::Map<Never, Never> #t27 = <Never, Never>{};
-    final core::Map<Never, Never>? #t28 = n1;
-    if(!#t28.{core::Object::==}(null))
-      for (final core::MapEntry<Never, Never> #t29 in #t28{core::Map<Never, Never>}.{core::Map::entries})
-        #t27.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
-    #t27.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t27;
+    final core::Map<Never, Never> #t19 = <Never, Never>{};
+    final core::Map<Never, Never>? #t20 = n1;
+    if(!#t20.{core::Object::==}(null))
+      for (final core::MapEntry<Never, Never> #t21 in #t20{core::Map<Never, Never>}.{core::Map::entries})
+        #t19.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
+    #t19.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t19;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'.
   var m3 = {...n2, n1: n1};
                ^": null, n1: n1};
   core::Map<Never, Never> m4 = block {
-    final core::Map<Never, Never> #t30 = <Never, Never>{};
-    final core::Map<Never, Never>? #t31 = n2;
-    if(!#t31.{core::Object::==}(null))
-      for (final core::MapEntry<Never, Never> #t32 in #t31{core::Map<Never, Never>}.{core::Map::entries})
-        #t30.{core::Map::[]=}{Invariant}(#t32.{core::MapEntry::key}, #t32.{core::MapEntry::value});
-    #t30.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t30;
+    final core::Map<Never, Never> #t22 = <Never, Never>{};
+    final core::Map<Never, Never>? #t23 = n2;
+    if(!#t23.{core::Object::==}(null))
+      for (final core::MapEntry<Never, Never> #t24 in #t23{core::Map<Never, Never>}.{core::Map::entries})
+        #t22.{core::Map::[]=}{Invariant}(#t24.{core::MapEntry::key}, #t24.{core::MapEntry::value});
+    #t22.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t22;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:22:16: Error: Can't spread a value with static type 'Null'.
   var m5 = {...n3, n1: n1};
                ^": null, n1: n1};
   core::Map<Never, Never> m6 = block {
-    final core::Map<Never, Never> #t33 = <Never, Never>{};
-    final core::Map<Never, Never>? #t34 = n3;
-    if(!#t34.{core::Object::==}(null))
-      for (final core::MapEntry<Never, Never> #t35 in #t34{core::Map<Never, Never>}.{core::Map::entries})
-        #t33.{core::Map::[]=}{Invariant}(#t35.{core::MapEntry::key}, #t35.{core::MapEntry::value});
-    #t33.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t33;
+    final core::Map<Never, Never> #t25 = <Never, Never>{};
+    final core::Map<Never, Never>? #t26 = n3;
+    if(!#t26.{core::Object::==}(null))
+      for (final core::MapEntry<Never, Never> #t27 in #t26{core::Map<Never, Never>}.{core::Map::entries})
+        #t25.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
+    #t25.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t25;
 }
 static method test2<N1 extends Never = Never, N2 extends Never? = Never?, N3 extends Null = Null>(self::test2::N1 n1, self::test2::N2% n2, self::test2::N3% n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t36 = <Never>[];
-    for (final Never #t37 in n1)
-      #t36.{core::List::add}{Invariant}(#t37);
-  } =>#t36;
+    final core::List<Never> #t28 = core::List::of<Never>(n1);
+  } =>#t28;
   core::List<Never> l2 = block {
-    final core::List<Never> #t38 = <Never>[];
-    final core::Iterable<Never>? #t39 = n1;
-    if(!#t39.{core::Object::==}(null))
-      for (final Never #t40 in #t39{core::Iterable<Never>})
-        #t38.{core::List::add}{Invariant}(#t40);
-  } =>#t38;
+    final core::List<Never> #t29 = <Never>[];
+    final core::Iterable<Never>? #t30 = n1;
+    if(!#t30.{core::Object::==}(null))
+      #t29.{core::List::addAll}{Invariant}(#t30{core::Iterable<Never>});
+  } =>#t29;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:30:16: Error: Can't spread a value with static type 'N2'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t41 = <Never>[];
-    final core::Iterable<Never>? #t42 = n2;
-    if(!#t42.{core::Object::==}(null))
-      for (final Never #t43 in #t42{core::Iterable<Never>})
-        #t41.{core::List::add}{Invariant}(#t43);
-  } =>#t41;
+    final core::List<Never> #t31 = <Never>[];
+    final core::Iterable<Never>? #t32 = n2;
+    if(!#t32.{core::Object::==}(null))
+      #t31.{core::List::addAll}{Invariant}(#t32{core::Iterable<Never>});
+  } =>#t31;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:32:16: Error: Can't spread a value with static type 'N3'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t44 = <Never>[];
-    final core::Iterable<Never>? #t45 = n3;
-    if(!#t45.{core::Object::==}(null))
-      for (final Never #t46 in #t45{core::Iterable<Never>})
-        #t44.{core::List::add}{Invariant}(#t46);
-  } =>#t44;
+    final core::List<Never> #t33 = <Never>[];
+    final core::Iterable<Never>? #t34 = n3;
+    if(!#t34.{core::Object::==}(null))
+      #t33.{core::List::addAll}{Invariant}(#t34{core::Iterable<Never>});
+  } =>#t33;
   core::Set<self::test2::N1> s1 = block {
-    final core::Set<self::test2::N1> #t47 = col::LinkedHashSet::•<self::test2::N1>();
-    for (final self::test2::N1 #t48 in n1)
-      #t47.{core::Set::add}{Invariant}(#t48);
-    #t47.{core::Set::add}{Invariant}(n1);
-  } =>#t47;
+    final core::Set<self::test2::N1> #t35 = col::LinkedHashSet::of<self::test2::N1>(n1);
+    #t35.{core::Set::add}{Invariant}(n1);
+  } =>#t35;
   core::Set<self::test2::N1> s2 = block {
-    final core::Set<self::test2::N1> #t49 = col::LinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t50 = n1;
-    if(!#t50.{core::Object::==}(null))
-      for (final self::test2::N1 #t51 in #t50{core::Iterable<self::test2::N1>})
-        #t49.{core::Set::add}{Invariant}(#t51);
-    #t49.{core::Set::add}{Invariant}(n1);
-  } =>#t49;
+    final core::Set<self::test2::N1> #t36 = col::LinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t37 = n1;
+    if(!#t37.{core::Object::==}(null))
+      #t36.{core::Set::addAll}{Invariant}(#t37{core::Iterable<self::test2::N1>});
+    #t36.{core::Set::add}{Invariant}(n1);
+  } =>#t36;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t52 = col::LinkedHashSet::•<dynamic>();
-    #t52.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
+    final core::Set<dynamic> #t38 = col::LinkedHashSet::•<dynamic>();
+    #t38.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
   var s3 = {...n2, n1};
                ^");
-    #t52.{core::Set::add}{Invariant}(n1);
-  } =>#t52;
+    #t38.{core::Set::add}{Invariant}(n1);
+  } =>#t38;
   core::Set<self::test2::N1> s4 = block {
-    final core::Set<self::test2::N1> #t53 = col::LinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t54 = n2;
-    if(!#t54.{core::Object::==}(null))
-      for (final self::test2::N1 #t55 in #t54{core::Iterable<self::test2::N1>})
-        #t53.{core::Set::add}{Invariant}(#t55);
-    #t53.{core::Set::add}{Invariant}(n1);
-  } =>#t53;
+    final core::Set<self::test2::N1> #t39 = col::LinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t40 = n2;
+    if(!#t40.{core::Object::==}(null))
+      #t39.{core::Set::addAll}{Invariant}(#t40{core::Iterable<self::test2::N1>});
+    #t39.{core::Set::add}{Invariant}(n1);
+  } =>#t39;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t56 = col::LinkedHashSet::•<dynamic>();
-    #t56.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
+    final core::Set<dynamic> #t41 = col::LinkedHashSet::•<dynamic>();
+    #t41.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
   var s5 = {...n3, n1};
                ^");
-    #t56.{core::Set::add}{Invariant}(n1);
-  } =>#t56;
+    #t41.{core::Set::add}{Invariant}(n1);
+  } =>#t41;
   core::Set<self::test2::N1> s6 = block {
-    final core::Set<self::test2::N1> #t57 = col::LinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t58 = n3;
-    if(!#t58.{core::Object::==}(null))
-      for (final self::test2::N1 #t59 in #t58{core::Iterable<self::test2::N1>})
-        #t57.{core::Set::add}{Invariant}(#t59);
-    #t57.{core::Set::add}{Invariant}(n1);
-  } =>#t57;
+    final core::Set<self::test2::N1> #t42 = col::LinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t43 = n3;
+    if(!#t43.{core::Object::==}(null))
+      #t42.{core::Set::addAll}{Invariant}(#t43{core::Iterable<self::test2::N1>});
+    #t42.{core::Set::add}{Invariant}(n1);
+  } =>#t42;
   core::Map<self::test2::N1, self::test2::N1> m1 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t60 = <self::test2::N1, self::test2::N1>{};
-    for (final core::MapEntry<self::test2::N1, self::test2::N1> #t61 in n1.{core::Map::entries})
-      #t60.{core::Map::[]=}{Invariant}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value});
-    #t60.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t60;
+    final core::Map<self::test2::N1, self::test2::N1> #t44 = <self::test2::N1, self::test2::N1>{};
+    for (final core::MapEntry<self::test2::N1, self::test2::N1> #t45 in n1.{core::Map::entries})
+      #t44.{core::Map::[]=}{Invariant}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
+    #t44.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t44;
   core::Map<self::test2::N1, self::test2::N1> m2 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t62 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t63 = n1;
-    if(!#t63.{core::Object::==}(null))
-      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t64 in #t63{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
-        #t62.{core::Map::[]=}{Invariant}(#t64.{core::MapEntry::key}, #t64.{core::MapEntry::value});
-    #t62.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t62;
+    final core::Map<self::test2::N1, self::test2::N1> #t46 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t47 = n1;
+    if(!#t47.{core::Object::==}(null))
+      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t48 in #t47{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
+        #t46.{core::Map::[]=}{Invariant}(#t48.{core::MapEntry::key}, #t48.{core::MapEntry::value});
+    #t46.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t46;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:42:16: Error: Can't spread a value with static type 'N2'.
   var m3 = {...n2, n1: n1};
                ^": null, n1: n1};
   core::Map<self::test2::N1, self::test2::N1> m4 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t65 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t66 = n2;
-    if(!#t66.{core::Object::==}(null))
-      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t67 in #t66{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
-        #t65.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
-    #t65.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t65;
+    final core::Map<self::test2::N1, self::test2::N1> #t49 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t50 = n2;
+    if(!#t50.{core::Object::==}(null))
+      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t51 in #t50{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
+        #t49.{core::Map::[]=}{Invariant}(#t51.{core::MapEntry::key}, #t51.{core::MapEntry::value});
+    #t49.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t49;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:44:16: Error: Can't spread a value with static type 'N3'.
   var m5 = {...n3, n1: n1};
                ^": null, n1: n1};
   core::Map<self::test2::N1, self::test2::N1> m6 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t68 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t69 = n3;
-    if(!#t69.{core::Object::==}(null))
-      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t70 in #t69{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
-        #t68.{core::Map::[]=}{Invariant}(#t70.{core::MapEntry::key}, #t70.{core::MapEntry::value});
-    #t68.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t68;
+    final core::Map<self::test2::N1, self::test2::N1> #t52 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t53 = n3;
+    if(!#t53.{core::Object::==}(null))
+      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t54 in #t53{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
+        #t52.{core::Map::[]=}{Invariant}(#t54.{core::MapEntry::key}, #t54.{core::MapEntry::value});
+    #t52.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t52;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect
index b4eff37..b50eeff 100644
--- a/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect
@@ -80,312 +80,244 @@
 
 static method test1(Never n1, Never? n2, Null n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t1 = <Never>[];
-    for (final Never #t2 in n1)
-      #t1.{core::List::add}{Invariant}(#t2);
+    final core::List<Never> #t1 = core::List::of<Never>(n1);
   } =>#t1;
   core::List<Never> l2 = block {
-    final core::List<Never> #t3 = <Never>[];
-    final core::Iterable<Never>? #t4 = n1;
-    if(!#t4.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t4{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t5 = :sync-for-iterator.{core::Iterator::current};
-        #t3.{core::List::add}{Invariant}(#t5);
-      }
-    }
-  } =>#t3;
+    final core::List<Never> #t2 = <Never>[];
+    final core::Iterable<Never>? #t3 = n1;
+    if(!#t3.{core::Object::==}(null))
+      #t2.{core::List::addAll}{Invariant}(#t3{core::Iterable<Never>});
+  } =>#t2;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:8:16: Error: Can't spread a value with static type 'Never?'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t6 = <Never>[];
-    final core::Iterable<Never>? #t7 = n2;
-    if(!#t7.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t7{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t8 = :sync-for-iterator.{core::Iterator::current};
-        #t6.{core::List::add}{Invariant}(#t8);
-      }
-    }
-  } =>#t6;
+    final core::List<Never> #t4 = <Never>[];
+    final core::Iterable<Never>? #t5 = n2;
+    if(!#t5.{core::Object::==}(null))
+      #t4.{core::List::addAll}{Invariant}(#t5{core::Iterable<Never>});
+  } =>#t4;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:10:16: Error: Can't spread a value with static type 'Null'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t9 = <Never>[];
-    final core::Iterable<Never>? #t10 = n3;
-    if(!#t10.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t10{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t11 = :sync-for-iterator.{core::Iterator::current};
-        #t9.{core::List::add}{Invariant}(#t11);
-      }
-    }
-  } =>#t9;
+    final core::List<Never> #t6 = <Never>[];
+    final core::Iterable<Never>? #t7 = n3;
+    if(!#t7.{core::Object::==}(null))
+      #t6.{core::List::addAll}{Invariant}(#t7{core::Iterable<Never>});
+  } =>#t6;
   core::Set<Never> s1 = block {
-    final core::Set<Never> #t12 = new col::_CompactLinkedHashSet::•<Never>();
-    for (final Never #t13 in n1)
-      #t12.{core::Set::add}{Invariant}(#t13);
-    #t12.{core::Set::add}{Invariant}(n1);
-  } =>#t12;
+    final core::Set<Never> #t8 = col::LinkedHashSet::of<Never>(n1);
+    #t8.{core::Set::add}{Invariant}(n1);
+  } =>#t8;
   core::Set<Never> s2 = block {
-    final core::Set<Never> #t14 = new col::_CompactLinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t15 = n1;
-    if(!#t15.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t15{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t16 = :sync-for-iterator.{core::Iterator::current};
-        #t14.{core::Set::add}{Invariant}(#t16);
-      }
-    }
-    #t14.{core::Set::add}{Invariant}(n1);
-  } =>#t14;
+    final core::Set<Never> #t9 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t10 = n1;
+    if(!#t10.{core::Object::==}(null))
+      #t9.{core::Set::addAll}{Invariant}(#t10{core::Iterable<Never>});
+    #t9.{core::Set::add}{Invariant}(n1);
+  } =>#t9;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t17 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t17.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
+    final core::Set<dynamic> #t11 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t11.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
   var s3 = {...n2, n1};
                ^");
-    #t17.{core::Set::add}{Invariant}(n1);
-  } =>#t17;
+    #t11.{core::Set::add}{Invariant}(n1);
+  } =>#t11;
   core::Set<Never> s4 = block {
-    final core::Set<Never> #t18 = new col::_CompactLinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t19 = n2;
-    if(!#t19.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t19{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t20 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Set::add}{Invariant}(#t20);
-      }
-    }
-    #t18.{core::Set::add}{Invariant}(n1);
-  } =>#t18;
+    final core::Set<Never> #t12 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t13 = n2;
+    if(!#t13.{core::Object::==}(null))
+      #t12.{core::Set::addAll}{Invariant}(#t13{core::Iterable<Never>});
+    #t12.{core::Set::add}{Invariant}(n1);
+  } =>#t12;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t21 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t21.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
+    final core::Set<dynamic> #t14 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t14.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
   var s5 = {...n3, n1};
                ^");
-    #t21.{core::Set::add}{Invariant}(n1);
-  } =>#t21;
+    #t14.{core::Set::add}{Invariant}(n1);
+  } =>#t14;
   core::Set<Never> s6 = block {
-    final core::Set<Never> #t22 = new col::_CompactLinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t23 = n3;
-    if(!#t23.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t23{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t24 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::Set::add}{Invariant}(#t24);
-      }
-    }
-    #t22.{core::Set::add}{Invariant}(n1);
-  } =>#t22;
+    final core::Set<Never> #t15 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t16 = n3;
+    if(!#t16.{core::Object::==}(null))
+      #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<Never>});
+    #t15.{core::Set::add}{Invariant}(n1);
+  } =>#t15;
   core::Map<Never, Never> m1 = block {
-    final core::Map<Never, Never> #t25 = <Never, Never>{};
+    final core::Map<Never, Never> #t17 = <Never, Never>{};
     {
       core::Iterator<core::MapEntry<<BottomType>, <BottomType>>> :sync-for-iterator = n1.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t26 = :sync-for-iterator.{core::Iterator::current};
-        #t25.{core::Map::[]=}{Invariant}(#t26.{core::MapEntry::key}, #t26.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t18 = :sync-for-iterator.{core::Iterator::current};
+        #t17.{core::Map::[]=}{Invariant}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
       }
     }
-    #t25.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t25;
+    #t17.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t17;
   core::Map<Never, Never> m2 = block {
-    final core::Map<Never, Never> #t27 = <Never, Never>{};
-    final core::Map<Never, Never>? #t28 = n1;
-    if(!#t28.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t28{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<Never, Never> #t19 = <Never, Never>{};
+    final core::Map<Never, Never>? #t20 = n1;
+    if(!#t20.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t20{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t29 = :sync-for-iterator.{core::Iterator::current};
-        #t27.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t21 = :sync-for-iterator.{core::Iterator::current};
+        #t19.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
       }
     }
-    #t27.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t27;
+    #t19.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t19;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'.
   var m3 = {...n2, n1: n1};
                ^": null, n1: n1};
   core::Map<Never, Never> m4 = block {
-    final core::Map<Never, Never> #t30 = <Never, Never>{};
-    final core::Map<Never, Never>? #t31 = n2;
-    if(!#t31.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t31{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<Never, Never> #t22 = <Never, Never>{};
+    final core::Map<Never, Never>? #t23 = n2;
+    if(!#t23.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t23{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t32 = :sync-for-iterator.{core::Iterator::current};
-        #t30.{core::Map::[]=}{Invariant}(#t32.{core::MapEntry::key}, #t32.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t24 = :sync-for-iterator.{core::Iterator::current};
+        #t22.{core::Map::[]=}{Invariant}(#t24.{core::MapEntry::key}, #t24.{core::MapEntry::value});
       }
     }
-    #t30.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t30;
+    #t22.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t22;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:22:16: Error: Can't spread a value with static type 'Null'.
   var m5 = {...n3, n1: n1};
                ^": null, n1: n1};
   core::Map<Never, Never> m6 = block {
-    final core::Map<Never, Never> #t33 = <Never, Never>{};
-    final core::Map<Never, Never>? #t34 = n3;
-    if(!#t34.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t34{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<Never, Never> #t25 = <Never, Never>{};
+    final core::Map<Never, Never>? #t26 = n3;
+    if(!#t26.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t26{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t35 = :sync-for-iterator.{core::Iterator::current};
-        #t33.{core::Map::[]=}{Invariant}(#t35.{core::MapEntry::key}, #t35.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t27 = :sync-for-iterator.{core::Iterator::current};
+        #t25.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
       }
     }
-    #t33.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t33;
+    #t25.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t25;
 }
 static method test2<N1 extends Never = Never, N2 extends Never? = Never?, N3 extends Null = Null>(self::test2::N1 n1, self::test2::N2% n2, self::test2::N3% n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t36 = <Never>[];
-    for (final Never #t37 in n1)
-      #t36.{core::List::add}{Invariant}(#t37);
-  } =>#t36;
+    final core::List<Never> #t28 = core::List::of<Never>(n1);
+  } =>#t28;
   core::List<Never> l2 = block {
-    final core::List<Never> #t38 = <Never>[];
-    final core::Iterable<Never>? #t39 = n1;
-    if(!#t39.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t39{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t40 = :sync-for-iterator.{core::Iterator::current};
-        #t38.{core::List::add}{Invariant}(#t40);
-      }
-    }
-  } =>#t38;
+    final core::List<Never> #t29 = <Never>[];
+    final core::Iterable<Never>? #t30 = n1;
+    if(!#t30.{core::Object::==}(null))
+      #t29.{core::List::addAll}{Invariant}(#t30{core::Iterable<Never>});
+  } =>#t29;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:30:16: Error: Can't spread a value with static type 'N2'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t41 = <Never>[];
-    final core::Iterable<Never>? #t42 = n2;
-    if(!#t42.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t42{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t43 = :sync-for-iterator.{core::Iterator::current};
-        #t41.{core::List::add}{Invariant}(#t43);
-      }
-    }
-  } =>#t41;
+    final core::List<Never> #t31 = <Never>[];
+    final core::Iterable<Never>? #t32 = n2;
+    if(!#t32.{core::Object::==}(null))
+      #t31.{core::List::addAll}{Invariant}(#t32{core::Iterable<Never>});
+  } =>#t31;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:32:16: Error: Can't spread a value with static type 'N3'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t44 = <Never>[];
-    final core::Iterable<Never>? #t45 = n3;
-    if(!#t45.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t45{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t46 = :sync-for-iterator.{core::Iterator::current};
-        #t44.{core::List::add}{Invariant}(#t46);
-      }
-    }
-  } =>#t44;
+    final core::List<Never> #t33 = <Never>[];
+    final core::Iterable<Never>? #t34 = n3;
+    if(!#t34.{core::Object::==}(null))
+      #t33.{core::List::addAll}{Invariant}(#t34{core::Iterable<Never>});
+  } =>#t33;
   core::Set<self::test2::N1> s1 = block {
-    final core::Set<self::test2::N1> #t47 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    for (final self::test2::N1 #t48 in n1)
-      #t47.{core::Set::add}{Invariant}(#t48);
-    #t47.{core::Set::add}{Invariant}(n1);
-  } =>#t47;
+    final core::Set<self::test2::N1> #t35 = col::LinkedHashSet::of<self::test2::N1>(n1);
+    #t35.{core::Set::add}{Invariant}(n1);
+  } =>#t35;
   core::Set<self::test2::N1> s2 = block {
-    final core::Set<self::test2::N1> #t49 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t50 = n1;
-    if(!#t50.{core::Object::==}(null)) {
-      core::Iterator<self::test2::N1> :sync-for-iterator = #t50{core::Iterable<self::test2::N1>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final self::test2::N1 #t51 = :sync-for-iterator.{core::Iterator::current};
-        #t49.{core::Set::add}{Invariant}(#t51);
-      }
-    }
-    #t49.{core::Set::add}{Invariant}(n1);
-  } =>#t49;
+    final core::Set<self::test2::N1> #t36 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t37 = n1;
+    if(!#t37.{core::Object::==}(null))
+      #t36.{core::Set::addAll}{Invariant}(#t37{core::Iterable<self::test2::N1>});
+    #t36.{core::Set::add}{Invariant}(n1);
+  } =>#t36;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t52 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t52.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
+    final core::Set<dynamic> #t38 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t38.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
   var s3 = {...n2, n1};
                ^");
-    #t52.{core::Set::add}{Invariant}(n1);
-  } =>#t52;
+    #t38.{core::Set::add}{Invariant}(n1);
+  } =>#t38;
   core::Set<self::test2::N1> s4 = block {
-    final core::Set<self::test2::N1> #t53 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t54 = n2;
-    if(!#t54.{core::Object::==}(null)) {
-      core::Iterator<self::test2::N1> :sync-for-iterator = #t54{core::Iterable<self::test2::N1>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final self::test2::N1 #t55 = :sync-for-iterator.{core::Iterator::current};
-        #t53.{core::Set::add}{Invariant}(#t55);
-      }
-    }
-    #t53.{core::Set::add}{Invariant}(n1);
-  } =>#t53;
+    final core::Set<self::test2::N1> #t39 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t40 = n2;
+    if(!#t40.{core::Object::==}(null))
+      #t39.{core::Set::addAll}{Invariant}(#t40{core::Iterable<self::test2::N1>});
+    #t39.{core::Set::add}{Invariant}(n1);
+  } =>#t39;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t56 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t56.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
+    final core::Set<dynamic> #t41 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t41.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
   var s5 = {...n3, n1};
                ^");
-    #t56.{core::Set::add}{Invariant}(n1);
-  } =>#t56;
+    #t41.{core::Set::add}{Invariant}(n1);
+  } =>#t41;
   core::Set<self::test2::N1> s6 = block {
-    final core::Set<self::test2::N1> #t57 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t58 = n3;
-    if(!#t58.{core::Object::==}(null)) {
-      core::Iterator<self::test2::N1> :sync-for-iterator = #t58{core::Iterable<self::test2::N1>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final self::test2::N1 #t59 = :sync-for-iterator.{core::Iterator::current};
-        #t57.{core::Set::add}{Invariant}(#t59);
-      }
-    }
-    #t57.{core::Set::add}{Invariant}(n1);
-  } =>#t57;
+    final core::Set<self::test2::N1> #t42 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t43 = n3;
+    if(!#t43.{core::Object::==}(null))
+      #t42.{core::Set::addAll}{Invariant}(#t43{core::Iterable<self::test2::N1>});
+    #t42.{core::Set::add}{Invariant}(n1);
+  } =>#t42;
   core::Map<self::test2::N1, self::test2::N1> m1 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t60 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1> #t44 = <self::test2::N1, self::test2::N1>{};
     {
       core::Iterator<core::MapEntry<<BottomType>, <BottomType>>> :sync-for-iterator = n1.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t61 = :sync-for-iterator.{core::Iterator::current};
-        #t60.{core::Map::[]=}{Invariant}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t45 = :sync-for-iterator.{core::Iterator::current};
+        #t44.{core::Map::[]=}{Invariant}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
       }
     }
-    #t60.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t60;
+    #t44.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t44;
   core::Map<self::test2::N1, self::test2::N1> m2 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t62 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t63 = n1;
-    if(!#t63.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t63{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<self::test2::N1, self::test2::N1> #t46 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t47 = n1;
+    if(!#t47.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t47{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t64 = :sync-for-iterator.{core::Iterator::current};
-        #t62.{core::Map::[]=}{Invariant}(#t64.{core::MapEntry::key}, #t64.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t48 = :sync-for-iterator.{core::Iterator::current};
+        #t46.{core::Map::[]=}{Invariant}(#t48.{core::MapEntry::key}, #t48.{core::MapEntry::value});
       }
     }
-    #t62.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t62;
+    #t46.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t46;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:42:16: Error: Can't spread a value with static type 'N2'.
   var m3 = {...n2, n1: n1};
                ^": null, n1: n1};
   core::Map<self::test2::N1, self::test2::N1> m4 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t65 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t66 = n2;
-    if(!#t66.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t66{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<self::test2::N1, self::test2::N1> #t49 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t50 = n2;
+    if(!#t50.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t50{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t67 = :sync-for-iterator.{core::Iterator::current};
-        #t65.{core::Map::[]=}{Invariant}(#t67.{core::MapEntry::key}, #t67.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t51 = :sync-for-iterator.{core::Iterator::current};
+        #t49.{core::Map::[]=}{Invariant}(#t51.{core::MapEntry::key}, #t51.{core::MapEntry::value});
       }
     }
-    #t65.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t65;
+    #t49.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t49;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:44:16: Error: Can't spread a value with static type 'N3'.
   var m5 = {...n3, n1: n1};
                ^": null, n1: n1};
   core::Map<self::test2::N1, self::test2::N1> m6 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t68 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t69 = n3;
-    if(!#t69.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t69{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<self::test2::N1, self::test2::N1> #t52 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t53 = n3;
+    if(!#t53.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t53{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t70 = :sync-for-iterator.{core::Iterator::current};
-        #t68.{core::Map::[]=}{Invariant}(#t70.{core::MapEntry::key}, #t70.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t54 = :sync-for-iterator.{core::Iterator::current};
+        #t52.{core::Map::[]=}{Invariant}(#t54.{core::MapEntry::key}, #t54.{core::MapEntry::value});
       }
     }
-    #t68.{core::Map::[]=}{Invariant}(n1, n1);
-  } =>#t68;
+    #t52.{core::Map::[]=}{Invariant}(n1, n1);
+  } =>#t52;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect
index 5672439..79c5408 100644
--- a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect
@@ -81,230 +81,210 @@
 
 static method test1(Never n1, Never? n2, Null n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t1 = <Never>[];
-    for (final Never #t2 in let final Never #t3 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t1.{core::List::add}{Invariant}(#t2);
+    final core::List<Never> #t1 = core::List::of<Never>(let final Never #t2 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
   } =>#t1;
   core::List<Never> l2 = block {
-    final core::List<Never> #t4 = <Never>[];
-    final core::Iterable<Never>? #t5 = let final Never #t6 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t5.{core::Object::==}(null))
-      for (final Never #t7 in #t5{core::Iterable<Never>})
-        #t4.{core::List::add}{Invariant}(#t7);
-  } =>#t4;
+    final core::List<Never> #t3 = <Never>[];
+    final core::Iterable<Never>? #t4 = let final Never #t5 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::List::addAll}{Invariant}(#t4{core::Iterable<Never>});
+  } =>#t3;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:8:16: Error: Can't spread a value with static type 'Never?'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t8 = <Never>[];
-    final core::Iterable<Never>? #t9 = n2;
-    if(!#t9.{core::Object::==}(null))
-      for (final Never #t10 in #t9{core::Iterable<Never>})
-        #t8.{core::List::add}{Invariant}(#t10);
-  } =>#t8;
+    final core::List<Never> #t6 = <Never>[];
+    final core::Iterable<Never>? #t7 = n2;
+    if(!#t7.{core::Object::==}(null))
+      #t6.{core::List::addAll}{Invariant}(#t7{core::Iterable<Never>});
+  } =>#t6;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:10:16: Error: Can't spread a value with static type 'Null'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t11 = <Never>[];
-    final core::Iterable<Never>? #t12 = n3;
-    if(!#t12.{core::Object::==}(null))
-      for (final Never #t13 in #t12{core::Iterable<Never>})
-        #t11.{core::List::add}{Invariant}(#t13);
-  } =>#t11;
+    final core::List<Never> #t8 = <Never>[];
+    final core::Iterable<Never>? #t9 = n3;
+    if(!#t9.{core::Object::==}(null))
+      #t8.{core::List::addAll}{Invariant}(#t9{core::Iterable<Never>});
+  } =>#t8;
   core::Set<Never> s1 = block {
-    final core::Set<Never> #t14 = col::LinkedHashSet::•<Never>();
-    for (final Never #t15 in let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t14.{core::Set::add}{Invariant}(#t15);
-    #t14.{core::Set::add}{Invariant}(let final Never #t17 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t14;
+    final core::Set<Never> #t10 = col::LinkedHashSet::of<Never>(let final Never #t11 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+    #t10.{core::Set::add}{Invariant}(let final Never #t12 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t10;
   core::Set<Never> s2 = block {
-    final core::Set<Never> #t18 = col::LinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t19 = let final Never #t20 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t19.{core::Object::==}(null))
-      for (final Never #t21 in #t19{core::Iterable<Never>})
-        #t18.{core::Set::add}{Invariant}(#t21);
-    #t18.{core::Set::add}{Invariant}(let final Never #t22 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t18;
+    final core::Set<Never> #t13 = col::LinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t14 = let final Never #t15 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t14.{core::Object::==}(null))
+      #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<Never>});
+    #t13.{core::Set::add}{Invariant}(let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t13;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t23 = col::LinkedHashSet::•<dynamic>();
-    #t23.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
+    final core::Set<dynamic> #t17 = col::LinkedHashSet::•<dynamic>();
+    #t17.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
   var s3 = {...n2, n1};
                ^");
-    #t23.{core::Set::add}{Invariant}(let final Never #t24 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t23;
+    #t17.{core::Set::add}{Invariant}(let final Never #t18 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t17;
   core::Set<Never> s4 = block {
-    final core::Set<Never> #t25 = col::LinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t26 = n2;
-    if(!#t26.{core::Object::==}(null))
-      for (final Never #t27 in #t26{core::Iterable<Never>})
-        #t25.{core::Set::add}{Invariant}(#t27);
-    #t25.{core::Set::add}{Invariant}(let final Never #t28 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t25;
+    final core::Set<Never> #t19 = col::LinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t20 = n2;
+    if(!#t20.{core::Object::==}(null))
+      #t19.{core::Set::addAll}{Invariant}(#t20{core::Iterable<Never>});
+    #t19.{core::Set::add}{Invariant}(let final Never #t21 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t19;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t29 = col::LinkedHashSet::•<dynamic>();
-    #t29.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
+    final core::Set<dynamic> #t22 = col::LinkedHashSet::•<dynamic>();
+    #t22.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
   var s5 = {...n3, n1};
                ^");
-    #t29.{core::Set::add}{Invariant}(let final Never #t30 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t29;
+    #t22.{core::Set::add}{Invariant}(let final Never #t23 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t22;
   core::Set<Never> s6 = block {
-    final core::Set<Never> #t31 = col::LinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t32 = n3;
-    if(!#t32.{core::Object::==}(null))
-      for (final Never #t33 in #t32{core::Iterable<Never>})
-        #t31.{core::Set::add}{Invariant}(#t33);
-    #t31.{core::Set::add}{Invariant}(let final Never #t34 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t31;
+    final core::Set<Never> #t24 = col::LinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t25 = n3;
+    if(!#t25.{core::Object::==}(null))
+      #t24.{core::Set::addAll}{Invariant}(#t25{core::Iterable<Never>});
+    #t24.{core::Set::add}{Invariant}(let final Never #t26 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t24;
   core::Map<Never, Never> m1 = block {
-    final core::Map<Never, Never> #t35 = <Never, Never>{};
-    for (final core::MapEntry<Never, Never> #t36 in (let final Never #t37 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries})
-      #t35.{core::Map::[]=}{Invariant}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value});
-    #t35.{core::Map::[]=}{Invariant}(let final Never #t38 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t39 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t35;
+    final core::Map<Never, Never> #t27 = <Never, Never>{};
+    for (final core::MapEntry<Never, Never> #t28 in (let final Never #t29 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries})
+      #t27.{core::Map::[]=}{Invariant}(#t28.{core::MapEntry::key}, #t28.{core::MapEntry::value});
+    #t27.{core::Map::[]=}{Invariant}(let final Never #t30 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t31 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t27;
   core::Map<Never, Never> m2 = block {
-    final core::Map<Never, Never> #t40 = <Never, Never>{};
-    final core::Map<Never, Never>? #t41 = let final Never #t42 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t41.{core::Object::==}(null))
-      for (final core::MapEntry<Never, Never> #t43 in #t41{core::Map<Never, Never>}.{core::Map::entries})
-        #t40.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-    #t40.{core::Map::[]=}{Invariant}(let final Never #t44 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t45 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t40;
+    final core::Map<Never, Never> #t32 = <Never, Never>{};
+    final core::Map<Never, Never>? #t33 = let final Never #t34 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t33.{core::Object::==}(null))
+      for (final core::MapEntry<Never, Never> #t35 in #t33{core::Map<Never, Never>}.{core::Map::entries})
+        #t32.{core::Map::[]=}{Invariant}(#t35.{core::MapEntry::key}, #t35.{core::MapEntry::value});
+    #t32.{core::Map::[]=}{Invariant}(let final Never #t36 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t37 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t32;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'.
   var m3 = {...n2, n1: n1};
-               ^": null, let final Never #t46 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t47 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final Never #t38 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t39 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<Never, Never> m4 = block {
-    final core::Map<Never, Never> #t48 = <Never, Never>{};
-    final core::Map<Never, Never>? #t49 = n2;
-    if(!#t49.{core::Object::==}(null))
-      for (final core::MapEntry<Never, Never> #t50 in #t49{core::Map<Never, Never>}.{core::Map::entries})
-        #t48.{core::Map::[]=}{Invariant}(#t50.{core::MapEntry::key}, #t50.{core::MapEntry::value});
-    #t48.{core::Map::[]=}{Invariant}(let final Never #t51 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t52 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t48;
+    final core::Map<Never, Never> #t40 = <Never, Never>{};
+    final core::Map<Never, Never>? #t41 = n2;
+    if(!#t41.{core::Object::==}(null))
+      for (final core::MapEntry<Never, Never> #t42 in #t41{core::Map<Never, Never>}.{core::Map::entries})
+        #t40.{core::Map::[]=}{Invariant}(#t42.{core::MapEntry::key}, #t42.{core::MapEntry::value});
+    #t40.{core::Map::[]=}{Invariant}(let final Never #t43 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t44 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t40;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:22:16: Error: Can't spread a value with static type 'Null'.
   var m5 = {...n3, n1: n1};
-               ^": null, let final Never #t53 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t54 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final Never #t45 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t46 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<Never, Never> m6 = block {
-    final core::Map<Never, Never> #t55 = <Never, Never>{};
-    final core::Map<Never, Never>? #t56 = n3;
-    if(!#t56.{core::Object::==}(null))
-      for (final core::MapEntry<Never, Never> #t57 in #t56{core::Map<Never, Never>}.{core::Map::entries})
-        #t55.{core::Map::[]=}{Invariant}(#t57.{core::MapEntry::key}, #t57.{core::MapEntry::value});
-    #t55.{core::Map::[]=}{Invariant}(let final Never #t58 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t59 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t55;
+    final core::Map<Never, Never> #t47 = <Never, Never>{};
+    final core::Map<Never, Never>? #t48 = n3;
+    if(!#t48.{core::Object::==}(null))
+      for (final core::MapEntry<Never, Never> #t49 in #t48{core::Map<Never, Never>}.{core::Map::entries})
+        #t47.{core::Map::[]=}{Invariant}(#t49.{core::MapEntry::key}, #t49.{core::MapEntry::value});
+    #t47.{core::Map::[]=}{Invariant}(let final Never #t50 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t51 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t47;
 }
 static method test2<N1 extends Never = Never, N2 extends Never? = Never?, N3 extends Null = Null>(self::test2::N1 n1, self::test2::N2% n2, self::test2::N3% n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t60 = <Never>[];
-    for (final Never #t61 in let final self::test2::N1 #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t60.{core::List::add}{Invariant}(#t61);
-  } =>#t60;
+    final core::List<Never> #t52 = core::List::of<Never>(let final self::test2::N1 #t53 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t52;
   core::List<Never> l2 = block {
-    final core::List<Never> #t63 = <Never>[];
-    final core::Iterable<Never>? #t64 = let final self::test2::N1 #t65 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t64.{core::Object::==}(null))
-      for (final Never #t66 in #t64{core::Iterable<Never>})
-        #t63.{core::List::add}{Invariant}(#t66);
-  } =>#t63;
+    final core::List<Never> #t54 = <Never>[];
+    final core::Iterable<Never>? #t55 = let final self::test2::N1 #t56 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t55.{core::Object::==}(null))
+      #t54.{core::List::addAll}{Invariant}(#t55{core::Iterable<Never>});
+  } =>#t54;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:30:16: Error: Can't spread a value with static type 'N2'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t67 = <Never>[];
-    final core::Iterable<Never>? #t68 = n2;
-    if(!#t68.{core::Object::==}(null))
-      for (final Never #t69 in #t68{core::Iterable<Never>})
-        #t67.{core::List::add}{Invariant}(#t69);
-  } =>#t67;
+    final core::List<Never> #t57 = <Never>[];
+    final core::Iterable<Never>? #t58 = n2;
+    if(!#t58.{core::Object::==}(null))
+      #t57.{core::List::addAll}{Invariant}(#t58{core::Iterable<Never>});
+  } =>#t57;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:32:16: Error: Can't spread a value with static type 'N3'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t70 = <Never>[];
-    final core::Iterable<Never>? #t71 = n3;
-    if(!#t71.{core::Object::==}(null))
-      for (final Never #t72 in #t71{core::Iterable<Never>})
-        #t70.{core::List::add}{Invariant}(#t72);
-  } =>#t70;
+    final core::List<Never> #t59 = <Never>[];
+    final core::Iterable<Never>? #t60 = n3;
+    if(!#t60.{core::Object::==}(null))
+      #t59.{core::List::addAll}{Invariant}(#t60{core::Iterable<Never>});
+  } =>#t59;
   core::Set<self::test2::N1> s1 = block {
-    final core::Set<self::test2::N1> #t73 = col::LinkedHashSet::•<self::test2::N1>();
-    for (final self::test2::N1 #t74 in let final self::test2::N1 #t75 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t73.{core::Set::add}{Invariant}(#t74);
-    #t73.{core::Set::add}{Invariant}(let final self::test2::N1 #t76 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t73;
+    final core::Set<self::test2::N1> #t61 = col::LinkedHashSet::of<self::test2::N1>(let final self::test2::N1 #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+    #t61.{core::Set::add}{Invariant}(let final self::test2::N1 #t63 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t61;
   core::Set<self::test2::N1> s2 = block {
-    final core::Set<self::test2::N1> #t77 = col::LinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t78 = let final self::test2::N1 #t79 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t78.{core::Object::==}(null))
-      for (final self::test2::N1 #t80 in #t78{core::Iterable<self::test2::N1>})
-        #t77.{core::Set::add}{Invariant}(#t80);
-    #t77.{core::Set::add}{Invariant}(let final self::test2::N1 #t81 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t77;
+    final core::Set<self::test2::N1> #t64 = col::LinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t65 = let final self::test2::N1 #t66 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t65.{core::Object::==}(null))
+      #t64.{core::Set::addAll}{Invariant}(#t65{core::Iterable<self::test2::N1>});
+    #t64.{core::Set::add}{Invariant}(let final self::test2::N1 #t67 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t64;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t82 = col::LinkedHashSet::•<dynamic>();
-    #t82.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
+    final core::Set<dynamic> #t68 = col::LinkedHashSet::•<dynamic>();
+    #t68.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
   var s3 = {...n2, n1};
                ^");
-    #t82.{core::Set::add}{Invariant}(let final self::test2::N1 #t83 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t82;
+    #t68.{core::Set::add}{Invariant}(let final self::test2::N1 #t69 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t68;
   core::Set<self::test2::N1> s4 = block {
-    final core::Set<self::test2::N1> #t84 = col::LinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t85 = n2;
-    if(!#t85.{core::Object::==}(null))
-      for (final self::test2::N1 #t86 in #t85{core::Iterable<self::test2::N1>})
-        #t84.{core::Set::add}{Invariant}(#t86);
-    #t84.{core::Set::add}{Invariant}(let final self::test2::N1 #t87 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t84;
+    final core::Set<self::test2::N1> #t70 = col::LinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t71 = n2;
+    if(!#t71.{core::Object::==}(null))
+      #t70.{core::Set::addAll}{Invariant}(#t71{core::Iterable<self::test2::N1>});
+    #t70.{core::Set::add}{Invariant}(let final self::test2::N1 #t72 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t70;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t88 = col::LinkedHashSet::•<dynamic>();
-    #t88.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
+    final core::Set<dynamic> #t73 = col::LinkedHashSet::•<dynamic>();
+    #t73.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
   var s5 = {...n3, n1};
                ^");
-    #t88.{core::Set::add}{Invariant}(let final self::test2::N1 #t89 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t88;
+    #t73.{core::Set::add}{Invariant}(let final self::test2::N1 #t74 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t73;
   core::Set<self::test2::N1> s6 = block {
-    final core::Set<self::test2::N1> #t90 = col::LinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t91 = n3;
-    if(!#t91.{core::Object::==}(null))
-      for (final self::test2::N1 #t92 in #t91{core::Iterable<self::test2::N1>})
-        #t90.{core::Set::add}{Invariant}(#t92);
-    #t90.{core::Set::add}{Invariant}(let final self::test2::N1 #t93 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t90;
+    final core::Set<self::test2::N1> #t75 = col::LinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t76 = n3;
+    if(!#t76.{core::Object::==}(null))
+      #t75.{core::Set::addAll}{Invariant}(#t76{core::Iterable<self::test2::N1>});
+    #t75.{core::Set::add}{Invariant}(let final self::test2::N1 #t77 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t75;
   core::Map<self::test2::N1, self::test2::N1> m1 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t94 = <self::test2::N1, self::test2::N1>{};
-    for (final core::MapEntry<self::test2::N1, self::test2::N1> #t95 in (let final self::test2::N1 #t96 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries})
-      #t94.{core::Map::[]=}{Invariant}(#t95.{core::MapEntry::key}, #t95.{core::MapEntry::value});
-    #t94.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t97 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t98 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t94;
+    final core::Map<self::test2::N1, self::test2::N1> #t78 = <self::test2::N1, self::test2::N1>{};
+    for (final core::MapEntry<self::test2::N1, self::test2::N1> #t79 in (let final self::test2::N1 #t80 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries})
+      #t78.{core::Map::[]=}{Invariant}(#t79.{core::MapEntry::key}, #t79.{core::MapEntry::value});
+    #t78.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t81 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t82 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t78;
   core::Map<self::test2::N1, self::test2::N1> m2 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t99 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t100 = let final self::test2::N1 #t101 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t100.{core::Object::==}(null))
-      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t102 in #t100{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
-        #t99.{core::Map::[]=}{Invariant}(#t102.{core::MapEntry::key}, #t102.{core::MapEntry::value});
-    #t99.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t103 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t104 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t99;
+    final core::Map<self::test2::N1, self::test2::N1> #t83 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t84 = let final self::test2::N1 #t85 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t84.{core::Object::==}(null))
+      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t86 in #t84{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
+        #t83.{core::Map::[]=}{Invariant}(#t86.{core::MapEntry::key}, #t86.{core::MapEntry::value});
+    #t83.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t87 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t88 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t83;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:42:16: Error: Can't spread a value with static type 'N2'.
   var m3 = {...n2, n1: n1};
-               ^": null, let final self::test2::N1 #t105 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t106 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final self::test2::N1 #t89 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t90 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<self::test2::N1, self::test2::N1> m4 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t107 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t108 = n2;
-    if(!#t108.{core::Object::==}(null))
-      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t109 in #t108{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
-        #t107.{core::Map::[]=}{Invariant}(#t109.{core::MapEntry::key}, #t109.{core::MapEntry::value});
-    #t107.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t110 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t111 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t107;
+    final core::Map<self::test2::N1, self::test2::N1> #t91 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t92 = n2;
+    if(!#t92.{core::Object::==}(null))
+      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t93 in #t92{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
+        #t91.{core::Map::[]=}{Invariant}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
+    #t91.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t94 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t95 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t91;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:44:16: Error: Can't spread a value with static type 'N3'.
   var m5 = {...n3, n1: n1};
-               ^": null, let final self::test2::N1 #t112 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t113 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final self::test2::N1 #t96 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t97 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<self::test2::N1, self::test2::N1> m6 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t114 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t115 = n3;
-    if(!#t115.{core::Object::==}(null))
-      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t116 in #t115{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
-        #t114.{core::Map::[]=}{Invariant}(#t116.{core::MapEntry::key}, #t116.{core::MapEntry::value});
-    #t114.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t117 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t118 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t114;
+    final core::Map<self::test2::N1, self::test2::N1> #t98 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t99 = n3;
+    if(!#t99.{core::Object::==}(null))
+      for (final core::MapEntry<self::test2::N1, self::test2::N1> #t100 in #t99{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries})
+        #t98.{core::Map::[]=}{Invariant}(#t100.{core::MapEntry::key}, #t100.{core::MapEntry::value});
+    #t98.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t101 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t102 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t98;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect
index 3c95716..ffce698 100644
--- a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect
@@ -81,312 +81,244 @@
 
 static method test1(Never n1, Never? n2, Null n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t1 = <Never>[];
-    for (final Never #t2 in let final Never #t3 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t1.{core::List::add}{Invariant}(#t2);
+    final core::List<Never> #t1 = core::List::of<Never>(let final Never #t2 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
   } =>#t1;
   core::List<Never> l2 = block {
-    final core::List<Never> #t4 = <Never>[];
-    final core::Iterable<Never>? #t5 = let final Never #t6 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t5{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t7 = :sync-for-iterator.{core::Iterator::current};
-        #t4.{core::List::add}{Invariant}(#t7);
-      }
-    }
-  } =>#t4;
+    final core::List<Never> #t3 = <Never>[];
+    final core::Iterable<Never>? #t4 = let final Never #t5 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::List::addAll}{Invariant}(#t4{core::Iterable<Never>});
+  } =>#t3;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:8:16: Error: Can't spread a value with static type 'Never?'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t8 = <Never>[];
-    final core::Iterable<Never>? #t9 = n2;
-    if(!#t9.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t9{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t10 = :sync-for-iterator.{core::Iterator::current};
-        #t8.{core::List::add}{Invariant}(#t10);
-      }
-    }
-  } =>#t8;
+    final core::List<Never> #t6 = <Never>[];
+    final core::Iterable<Never>? #t7 = n2;
+    if(!#t7.{core::Object::==}(null))
+      #t6.{core::List::addAll}{Invariant}(#t7{core::Iterable<Never>});
+  } =>#t6;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:10:16: Error: Can't spread a value with static type 'Null'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t11 = <Never>[];
-    final core::Iterable<Never>? #t12 = n3;
-    if(!#t12.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t12{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t13 = :sync-for-iterator.{core::Iterator::current};
-        #t11.{core::List::add}{Invariant}(#t13);
-      }
-    }
-  } =>#t11;
+    final core::List<Never> #t8 = <Never>[];
+    final core::Iterable<Never>? #t9 = n3;
+    if(!#t9.{core::Object::==}(null))
+      #t8.{core::List::addAll}{Invariant}(#t9{core::Iterable<Never>});
+  } =>#t8;
   core::Set<Never> s1 = block {
-    final core::Set<Never> #t14 = new col::_CompactLinkedHashSet::•<Never>();
-    for (final Never #t15 in let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t14.{core::Set::add}{Invariant}(#t15);
-    #t14.{core::Set::add}{Invariant}(let final Never #t17 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t14;
+    final core::Set<Never> #t10 = col::LinkedHashSet::of<Never>(let final Never #t11 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+    #t10.{core::Set::add}{Invariant}(let final Never #t12 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t10;
   core::Set<Never> s2 = block {
-    final core::Set<Never> #t18 = new col::_CompactLinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t19 = let final Never #t20 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t19.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t19{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t21 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Set::add}{Invariant}(#t21);
-      }
-    }
-    #t18.{core::Set::add}{Invariant}(let final Never #t22 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t18;
+    final core::Set<Never> #t13 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t14 = let final Never #t15 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t14.{core::Object::==}(null))
+      #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<Never>});
+    #t13.{core::Set::add}{Invariant}(let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t13;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t23 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t23.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
+    final core::Set<dynamic> #t17 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t17.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
   var s3 = {...n2, n1};
                ^");
-    #t23.{core::Set::add}{Invariant}(let final Never #t24 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t23;
+    #t17.{core::Set::add}{Invariant}(let final Never #t18 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t17;
   core::Set<Never> s4 = block {
-    final core::Set<Never> #t25 = new col::_CompactLinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t26 = n2;
-    if(!#t26.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t26{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t27 = :sync-for-iterator.{core::Iterator::current};
-        #t25.{core::Set::add}{Invariant}(#t27);
-      }
-    }
-    #t25.{core::Set::add}{Invariant}(let final Never #t28 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t25;
+    final core::Set<Never> #t19 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t20 = n2;
+    if(!#t20.{core::Object::==}(null))
+      #t19.{core::Set::addAll}{Invariant}(#t20{core::Iterable<Never>});
+    #t19.{core::Set::add}{Invariant}(let final Never #t21 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t19;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t29 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t29.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
+    final core::Set<dynamic> #t22 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t22.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
   var s5 = {...n3, n1};
                ^");
-    #t29.{core::Set::add}{Invariant}(let final Never #t30 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t29;
+    #t22.{core::Set::add}{Invariant}(let final Never #t23 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t22;
   core::Set<Never> s6 = block {
-    final core::Set<Never> #t31 = new col::_CompactLinkedHashSet::•<Never>();
-    final core::Iterable<Never>? #t32 = n3;
-    if(!#t32.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t32{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t33 = :sync-for-iterator.{core::Iterator::current};
-        #t31.{core::Set::add}{Invariant}(#t33);
-      }
-    }
-    #t31.{core::Set::add}{Invariant}(let final Never #t34 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t31;
+    final core::Set<Never> #t24 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Iterable<Never>? #t25 = n3;
+    if(!#t25.{core::Object::==}(null))
+      #t24.{core::Set::addAll}{Invariant}(#t25{core::Iterable<Never>});
+    #t24.{core::Set::add}{Invariant}(let final Never #t26 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t24;
   core::Map<Never, Never> m1 = block {
-    final core::Map<Never, Never> #t35 = <Never, Never>{};
+    final core::Map<Never, Never> #t27 = <Never, Never>{};
     {
-      core::Iterator<core::MapEntry<<BottomType>, <BottomType>>> :sync-for-iterator = (let final Never #t36 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}.{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<<BottomType>, <BottomType>>> :sync-for-iterator = (let final Never #t28 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t37 = :sync-for-iterator.{core::Iterator::current};
-        #t35.{core::Map::[]=}{Invariant}(#t37.{core::MapEntry::key}, #t37.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t29 = :sync-for-iterator.{core::Iterator::current};
+        #t27.{core::Map::[]=}{Invariant}(#t29.{core::MapEntry::key}, #t29.{core::MapEntry::value});
       }
     }
-    #t35.{core::Map::[]=}{Invariant}(let final Never #t38 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t39 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t35;
+    #t27.{core::Map::[]=}{Invariant}(let final Never #t30 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t31 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t27;
   core::Map<Never, Never> m2 = block {
+    final core::Map<Never, Never> #t32 = <Never, Never>{};
+    final core::Map<Never, Never>? #t33 = let final Never #t34 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t33.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t33{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<Never, Never> #t35 = :sync-for-iterator.{core::Iterator::current};
+        #t32.{core::Map::[]=}{Invariant}(#t35.{core::MapEntry::key}, #t35.{core::MapEntry::value});
+      }
+    }
+    #t32.{core::Map::[]=}{Invariant}(let final Never #t36 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t37 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t32;
+  core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'.
+  var m3 = {...n2, n1: n1};
+               ^": null, let final Never #t38 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t39 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+  core::Map<Never, Never> m4 = block {
     final core::Map<Never, Never> #t40 = <Never, Never>{};
-    final core::Map<Never, Never>? #t41 = let final Never #t42 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    final core::Map<Never, Never>? #t41 = n2;
     if(!#t41.{core::Object::==}(null)) {
       core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t41{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t43 = :sync-for-iterator.{core::Iterator::current};
-        #t40.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t42 = :sync-for-iterator.{core::Iterator::current};
+        #t40.{core::Map::[]=}{Invariant}(#t42.{core::MapEntry::key}, #t42.{core::MapEntry::value});
       }
     }
-    #t40.{core::Map::[]=}{Invariant}(let final Never #t44 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t45 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+    #t40.{core::Map::[]=}{Invariant}(let final Never #t43 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t44 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
   } =>#t40;
-  core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'.
-  var m3 = {...n2, n1: n1};
-               ^": null, let final Never #t46 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t47 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
-  core::Map<Never, Never> m4 = block {
-    final core::Map<Never, Never> #t48 = <Never, Never>{};
-    final core::Map<Never, Never>? #t49 = n2;
-    if(!#t49.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t49{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t50 = :sync-for-iterator.{core::Iterator::current};
-        #t48.{core::Map::[]=}{Invariant}(#t50.{core::MapEntry::key}, #t50.{core::MapEntry::value});
-      }
-    }
-    #t48.{core::Map::[]=}{Invariant}(let final Never #t51 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t52 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t48;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:22:16: Error: Can't spread a value with static type 'Null'.
   var m5 = {...n3, n1: n1};
-               ^": null, let final Never #t53 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t54 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final Never #t45 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t46 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<Never, Never> m6 = block {
-    final core::Map<Never, Never> #t55 = <Never, Never>{};
-    final core::Map<Never, Never>? #t56 = n3;
-    if(!#t56.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t56{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<Never, Never> #t47 = <Never, Never>{};
+    final core::Map<Never, Never>? #t48 = n3;
+    if(!#t48.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<Never, Never>> :sync-for-iterator = #t48{core::Map<Never, Never>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<Never, Never> #t57 = :sync-for-iterator.{core::Iterator::current};
-        #t55.{core::Map::[]=}{Invariant}(#t57.{core::MapEntry::key}, #t57.{core::MapEntry::value});
+        final core::MapEntry<Never, Never> #t49 = :sync-for-iterator.{core::Iterator::current};
+        #t47.{core::Map::[]=}{Invariant}(#t49.{core::MapEntry::key}, #t49.{core::MapEntry::value});
       }
     }
-    #t55.{core::Map::[]=}{Invariant}(let final Never #t58 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t59 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t55;
+    #t47.{core::Map::[]=}{Invariant}(let final Never #t50 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t51 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t47;
 }
 static method test2<N1 extends Never = Never, N2 extends Never? = Never?, N3 extends Null = Null>(self::test2::N1 n1, self::test2::N2% n2, self::test2::N3% n3) → dynamic {
   core::List<Never> l1 = block {
-    final core::List<Never> #t60 = <Never>[];
-    for (final Never #t61 in let final self::test2::N1 #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t60.{core::List::add}{Invariant}(#t61);
-  } =>#t60;
+    final core::List<Never> #t52 = core::List::of<Never>(let final self::test2::N1 #t53 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t52;
   core::List<Never> l2 = block {
-    final core::List<Never> #t63 = <Never>[];
-    final core::Iterable<Never>? #t64 = let final self::test2::N1 #t65 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t64.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t64{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t66 = :sync-for-iterator.{core::Iterator::current};
-        #t63.{core::List::add}{Invariant}(#t66);
-      }
-    }
-  } =>#t63;
+    final core::List<Never> #t54 = <Never>[];
+    final core::Iterable<Never>? #t55 = let final self::test2::N1 #t56 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t55.{core::Object::==}(null))
+      #t54.{core::List::addAll}{Invariant}(#t55{core::Iterable<Never>});
+  } =>#t54;
   core::List<dynamic> l3 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:30:16: Error: Can't spread a value with static type 'N2'.
   var l3 = [...n2];
                ^"];
   core::List<Never> l4 = block {
-    final core::List<Never> #t67 = <Never>[];
-    final core::Iterable<Never>? #t68 = n2;
-    if(!#t68.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t68{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t69 = :sync-for-iterator.{core::Iterator::current};
-        #t67.{core::List::add}{Invariant}(#t69);
-      }
-    }
-  } =>#t67;
+    final core::List<Never> #t57 = <Never>[];
+    final core::Iterable<Never>? #t58 = n2;
+    if(!#t58.{core::Object::==}(null))
+      #t57.{core::List::addAll}{Invariant}(#t58{core::Iterable<Never>});
+  } =>#t57;
   core::List<dynamic> l5 = <dynamic>[invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:32:16: Error: Can't spread a value with static type 'N3'.
   var l5 = [...n3];
                ^"];
   core::List<Never> l6 = block {
-    final core::List<Never> #t70 = <Never>[];
-    final core::Iterable<Never>? #t71 = n3;
-    if(!#t71.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t71{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t72 = :sync-for-iterator.{core::Iterator::current};
-        #t70.{core::List::add}{Invariant}(#t72);
-      }
-    }
-  } =>#t70;
+    final core::List<Never> #t59 = <Never>[];
+    final core::Iterable<Never>? #t60 = n3;
+    if(!#t60.{core::Object::==}(null))
+      #t59.{core::List::addAll}{Invariant}(#t60{core::Iterable<Never>});
+  } =>#t59;
   core::Set<self::test2::N1> s1 = block {
-    final core::Set<self::test2::N1> #t73 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    for (final self::test2::N1 #t74 in let final self::test2::N1 #t75 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."))
-      #t73.{core::Set::add}{Invariant}(#t74);
-    #t73.{core::Set::add}{Invariant}(let final self::test2::N1 #t76 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t73;
+    final core::Set<self::test2::N1> #t61 = col::LinkedHashSet::of<self::test2::N1>(let final self::test2::N1 #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+    #t61.{core::Set::add}{Invariant}(let final self::test2::N1 #t63 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t61;
   core::Set<self::test2::N1> s2 = block {
-    final core::Set<self::test2::N1> #t77 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t78 = let final self::test2::N1 #t79 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t78.{core::Object::==}(null)) {
-      core::Iterator<self::test2::N1> :sync-for-iterator = #t78{core::Iterable<self::test2::N1>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final self::test2::N1 #t80 = :sync-for-iterator.{core::Iterator::current};
-        #t77.{core::Set::add}{Invariant}(#t80);
-      }
-    }
-    #t77.{core::Set::add}{Invariant}(let final self::test2::N1 #t81 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t77;
+    final core::Set<self::test2::N1> #t64 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t65 = let final self::test2::N1 #t66 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t65.{core::Object::==}(null))
+      #t64.{core::Set::addAll}{Invariant}(#t65{core::Iterable<self::test2::N1>});
+    #t64.{core::Set::add}{Invariant}(let final self::test2::N1 #t67 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t64;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t82 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t82.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
+    final core::Set<dynamic> #t68 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t68.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
   var s3 = {...n2, n1};
                ^");
-    #t82.{core::Set::add}{Invariant}(let final self::test2::N1 #t83 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t82;
+    #t68.{core::Set::add}{Invariant}(let final self::test2::N1 #t69 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t68;
   core::Set<self::test2::N1> s4 = block {
-    final core::Set<self::test2::N1> #t84 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t85 = n2;
-    if(!#t85.{core::Object::==}(null)) {
-      core::Iterator<self::test2::N1> :sync-for-iterator = #t85{core::Iterable<self::test2::N1>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final self::test2::N1 #t86 = :sync-for-iterator.{core::Iterator::current};
-        #t84.{core::Set::add}{Invariant}(#t86);
-      }
-    }
-    #t84.{core::Set::add}{Invariant}(let final self::test2::N1 #t87 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t84;
+    final core::Set<self::test2::N1> #t70 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t71 = n2;
+    if(!#t71.{core::Object::==}(null))
+      #t70.{core::Set::addAll}{Invariant}(#t71{core::Iterable<self::test2::N1>});
+    #t70.{core::Set::add}{Invariant}(let final self::test2::N1 #t72 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t70;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t88 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t88.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
+    final core::Set<dynamic> #t73 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t73.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
   var s5 = {...n3, n1};
                ^");
-    #t88.{core::Set::add}{Invariant}(let final self::test2::N1 #t89 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t88;
+    #t73.{core::Set::add}{Invariant}(let final self::test2::N1 #t74 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t73;
   core::Set<self::test2::N1> s6 = block {
-    final core::Set<self::test2::N1> #t90 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
-    final core::Iterable<self::test2::N1>? #t91 = n3;
-    if(!#t91.{core::Object::==}(null)) {
-      core::Iterator<self::test2::N1> :sync-for-iterator = #t91{core::Iterable<self::test2::N1>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final self::test2::N1 #t92 = :sync-for-iterator.{core::Iterator::current};
-        #t90.{core::Set::add}{Invariant}(#t92);
-      }
-    }
-    #t90.{core::Set::add}{Invariant}(let final self::test2::N1 #t93 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t90;
+    final core::Set<self::test2::N1> #t75 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Iterable<self::test2::N1>? #t76 = n3;
+    if(!#t76.{core::Object::==}(null))
+      #t75.{core::Set::addAll}{Invariant}(#t76{core::Iterable<self::test2::N1>});
+    #t75.{core::Set::add}{Invariant}(let final self::test2::N1 #t77 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t75;
   core::Map<self::test2::N1, self::test2::N1> m1 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t94 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1> #t78 = <self::test2::N1, self::test2::N1>{};
     {
-      core::Iterator<core::MapEntry<<BottomType>, <BottomType>>> :sync-for-iterator = (let final self::test2::N1 #t95 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}.{core::Iterable::iterator};
+      core::Iterator<core::MapEntry<<BottomType>, <BottomType>>> :sync-for-iterator = (let final self::test2::N1 #t79 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t96 = :sync-for-iterator.{core::Iterator::current};
-        #t94.{core::Map::[]=}{Invariant}(#t96.{core::MapEntry::key}, #t96.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t80 = :sync-for-iterator.{core::Iterator::current};
+        #t78.{core::Map::[]=}{Invariant}(#t80.{core::MapEntry::key}, #t80.{core::MapEntry::value});
       }
     }
-    #t94.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t97 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t98 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t94;
+    #t78.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t81 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t82 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t78;
   core::Map<self::test2::N1, self::test2::N1> m2 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t99 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t100 = let final self::test2::N1 #t101 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-    if(!#t100.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t100{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<self::test2::N1, self::test2::N1> #t83 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t84 = let final self::test2::N1 #t85 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+    if(!#t84.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t84{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t102 = :sync-for-iterator.{core::Iterator::current};
-        #t99.{core::Map::[]=}{Invariant}(#t102.{core::MapEntry::key}, #t102.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t86 = :sync-for-iterator.{core::Iterator::current};
+        #t83.{core::Map::[]=}{Invariant}(#t86.{core::MapEntry::key}, #t86.{core::MapEntry::value});
       }
     }
-    #t99.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t103 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t104 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t99;
+    #t83.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t87 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t88 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t83;
   core::Map<dynamic, dynamic> m3 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:42:16: Error: Can't spread a value with static type 'N2'.
   var m3 = {...n2, n1: n1};
-               ^": null, let final self::test2::N1 #t105 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t106 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final self::test2::N1 #t89 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t90 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<self::test2::N1, self::test2::N1> m4 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t107 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t108 = n2;
-    if(!#t108.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t108{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<self::test2::N1, self::test2::N1> #t91 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t92 = n2;
+    if(!#t92.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t92{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t109 = :sync-for-iterator.{core::Iterator::current};
-        #t107.{core::Map::[]=}{Invariant}(#t109.{core::MapEntry::key}, #t109.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t93 = :sync-for-iterator.{core::Iterator::current};
+        #t91.{core::Map::[]=}{Invariant}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
       }
     }
-    #t107.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t110 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t111 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t107;
+    #t91.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t94 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t95 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t91;
   core::Map<dynamic, dynamic> m5 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:44:16: Error: Can't spread a value with static type 'N3'.
   var m5 = {...n3, n1: n1};
-               ^": null, let final self::test2::N1 #t112 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t113 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
+               ^": null, let final self::test2::N1 #t96 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t97 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")};
   core::Map<self::test2::N1, self::test2::N1> m6 = block {
-    final core::Map<self::test2::N1, self::test2::N1> #t114 = <self::test2::N1, self::test2::N1>{};
-    final core::Map<self::test2::N1, self::test2::N1>? #t115 = n3;
-    if(!#t115.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t115{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<self::test2::N1, self::test2::N1> #t98 = <self::test2::N1, self::test2::N1>{};
+    final core::Map<self::test2::N1, self::test2::N1>? #t99 = n3;
+    if(!#t99.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<self::test2::N1, self::test2::N1>> :sync-for-iterator = #t99{core::Map<self::test2::N1, self::test2::N1>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<self::test2::N1, self::test2::N1> #t116 = :sync-for-iterator.{core::Iterator::current};
-        #t114.{core::Map::[]=}{Invariant}(#t116.{core::MapEntry::key}, #t116.{core::MapEntry::value});
+        final core::MapEntry<self::test2::N1, self::test2::N1> #t100 = :sync-for-iterator.{core::Iterator::current};
+        #t98.{core::Map::[]=}{Invariant}(#t100.{core::MapEntry::key}, #t100.{core::MapEntry::value});
       }
     }
-    #t114.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t117 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t118 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  } =>#t114;
+    #t98.{core::Map::[]=}{Invariant}(let final self::test2::N1 #t101 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t102 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  } =>#t98;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42844_1.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42844_1.dart.outline.expect
index a52904f..1b6e3c7 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_1.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_1.dart.outline.expect
@@ -4,7 +4,7 @@
 
 class C extends core::Object {
   field Never n;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(Never n) → self::C
     let dynamic #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.expect
index 9f1d04c..579f1e9 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.expect
@@ -11,7 +11,7 @@
 
 class C extends core::Object {
   field Never n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(Never n) → self::C
     let dynamic #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.transformed.expect
index 7a9d7ad..9bf278b 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_1.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
 
 class C extends core::Object {
   field Never n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(Never n) → self::C
     let<BottomType> #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.expect
index 9f1d04c..579f1e9 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.expect
@@ -11,7 +11,7 @@
 
 class C extends core::Object {
   field Never n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(Never n) → self::C
     let dynamic #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.transformed.expect
index 7a9d7ad..9bf278b 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_1.dart.weak.transformed.expect
@@ -11,7 +11,7 @@
 
 class C extends core::Object {
   field Never n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(Never n) → self::C
     let<BottomType> #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_2.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42844_2.dart.outline.expect
index 40df7c4..b211f2f 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_2.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_2.dart.outline.expect
@@ -4,7 +4,7 @@
 
 class C extends core::Object {
   final field dynamic n;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(dynamic n) → self::C
     let dynamic #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.expect
index afaa082..1a0f908 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.expect
@@ -12,7 +12,7 @@
 
 class C extends core::Object {
   final field dynamic n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(dynamic n) → self::C
     let dynamic #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.transformed.expect
index 4e1efe4..ba70d21 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_2.dart.strong.transformed.expect
@@ -12,7 +12,7 @@
 
 class C extends core::Object {
   final field dynamic n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(dynamic n) → self::C
     let<BottomType> #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.expect
index afaa082..1a0f908 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.expect
@@ -12,7 +12,7 @@
 
 class C extends core::Object {
   final field dynamic n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(dynamic n) → self::C
     let dynamic #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.transformed.expect
index 4e1efe4..ba70d21 100644
--- a/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42844_2.dart.weak.transformed.expect
@@ -12,7 +12,7 @@
 
 class C extends core::Object {
   final field dynamic n = null;
-  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::•]/*isLegacy*/;
   static factory •(dynamic n) → self::C
     let<BottomType> #redirecting_factory = self::D::• in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.outline.expect
index 2ff42f4..6cde1626 100644
--- a/pkg/front_end/testcases/nnbd/issue43211.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.outline.expect
@@ -121,7 +121,7 @@
     ;
 }
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor internal(dynamic _) → self::C
     ;
   static factory redirect(self::A<self::A<Null>>? a) → self::C
@@ -137,13 +137,13 @@
 }
 extension ext2<X extends self::A<Null>? = self::A<Null>?> on self::A<X%> {
 }
-static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void
+static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void
   ;
-static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
+static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
   return <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%> a, self::A<self::A<Null>>? b) → void => self::Extension1|method1<self::Extension1|get#method1::X%, Y%>(#this, a, b);
-static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void
+static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(lowered final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void
   ;
-static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
+static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
   return <Y extends core::String = core::String>(self::D<Y> a, self::D<core::String>? b) → void => self::Extension1|method2<self::Extension1|get#method2::X%, Y>(#this, a, b);
 static method test() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.strong.expect
index 54f0536..2119a28 100644
--- a/pkg/front_end/testcases/nnbd/issue43211.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.strong.expect
@@ -221,7 +221,7 @@
   }
 }
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor internal(dynamic _) → self::C
     : super core::Object::•() {
     self::A<self::A<Null>>? a;
@@ -243,17 +243,17 @@
 }
 extension ext2<X extends self::A<Null>? = self::A<Null>?> on self::A<X%> {
 }
-static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
+static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
   self::A<self::Extension1|method1::Y%>? c;
   self::A<self::A<Null>>? d;
 }
-static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
+static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
   return <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%> a, self::A<self::A<Null>>? b) → void => self::Extension1|method1<self::Extension1|get#method1::X%, Y%>(#this, a, b);
-static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
+static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(lowered final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
   self::D<self::Extension1|method2::Y>? c;
   self::D<core::String>? d;
 }
-static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
+static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
   return <Y extends core::String = core::String>(self::D<Y> a, self::D<core::String>? b) → void => self::Extension1|method2<self::Extension1|get#method2::X%, Y>(#this, a, b);
 static method test() → dynamic {
   self::A<Null> a = new self::A::•<Null>();
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.strong.transformed.expect
index e77cc1a..1eb8c28 100644
--- a/pkg/front_end/testcases/nnbd/issue43211.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.strong.transformed.expect
@@ -221,7 +221,7 @@
   }
 }
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor internal(dynamic _) → self::C
     : super core::Object::•() {
     self::A<self::A<Null>>? a;
@@ -243,17 +243,17 @@
 }
 extension ext2<X extends self::A<Null>? = self::A<Null>?> on self::A<X%> {
 }
-static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
+static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
   self::A<self::Extension1|method1::Y%>? c;
   self::A<self::A<Null>>? d;
 }
-static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
+static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
   return <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%> a, self::A<self::A<Null>>? b) → void => self::Extension1|method1<self::Extension1|get#method1::X%, Y%>(#this, a, b);
-static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
+static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(lowered final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
   self::D<self::Extension1|method2::Y>? c;
   self::D<core::String>? d;
 }
-static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
+static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
   return <Y extends core::String = core::String>(self::D<Y> a, self::D<core::String>? b) → void => self::Extension1|method2<self::Extension1|get#method2::X%, Y>(#this, a, b);
 static method test() → dynamic {
   self::A<Null> a = new self::A::•<Null>();
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.weak.expect
index 54f0536..2119a28 100644
--- a/pkg/front_end/testcases/nnbd/issue43211.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.weak.expect
@@ -221,7 +221,7 @@
   }
 }
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor internal(dynamic _) → self::C
     : super core::Object::•() {
     self::A<self::A<Null>>? a;
@@ -243,17 +243,17 @@
 }
 extension ext2<X extends self::A<Null>? = self::A<Null>?> on self::A<X%> {
 }
-static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
+static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
   self::A<self::Extension1|method1::Y%>? c;
   self::A<self::A<Null>>? d;
 }
-static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
+static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
   return <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%> a, self::A<self::A<Null>>? b) → void => self::Extension1|method1<self::Extension1|get#method1::X%, Y%>(#this, a, b);
-static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
+static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(lowered final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
   self::D<self::Extension1|method2::Y>? c;
   self::D<core::String>? d;
 }
-static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
+static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
   return <Y extends core::String = core::String>(self::D<Y> a, self::D<core::String>? b) → void => self::Extension1|method2<self::Extension1|get#method2::X%, Y>(#this, a, b);
 static method test() → dynamic {
   self::A<Null> a = new self::A::•<Null>();
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.weak.transformed.expect
index e77cc1a..1eb8c28 100644
--- a/pkg/front_end/testcases/nnbd/issue43211.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.weak.transformed.expect
@@ -221,7 +221,7 @@
   }
 }
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor internal(dynamic _) → self::C
     : super core::Object::•() {
     self::A<self::A<Null>>? a;
@@ -243,17 +243,17 @@
 }
 extension ext2<X extends self::A<Null>? = self::A<Null>?> on self::A<X%> {
 }
-static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
+static method Extension1|method1<X extends self::A<self::Extension1|method1::X%>? = self::A<dynamic>?, Y extends self::A<self::Extension1|method1::Y%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|method1::X%> #this, self::A<self::Extension1|method1::Y%> a, self::A<self::A<Null>>? b) → void {
   self::A<self::Extension1|method1::Y%>? c;
   self::A<self::A<Null>>? d;
 }
-static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
+static method Extension1|get#method1<X extends self::A<self::Extension1|get#method1::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method1::X%> #this) → <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%>, self::A<self::A<Null>>?) → void
   return <Y extends self::A<Y%>? = self::A<dynamic>?>(self::A<Y%> a, self::A<self::A<Null>>? b) → void => self::Extension1|method1<self::Extension1|get#method1::X%, Y%>(#this, a, b);
-static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
+static method Extension1|method2<X extends self::A<self::Extension1|method2::X%>? = self::A<dynamic>?, Y extends core::String = core::String>(lowered final self::A<self::Extension1|method2::X%> #this, self::D<self::Extension1|method2::Y> a, self::D<core::String>? b) → void {
   self::D<self::Extension1|method2::Y>? c;
   self::D<core::String>? d;
 }
-static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
+static method Extension1|get#method2<X extends self::A<self::Extension1|get#method2::X%>? = self::A<dynamic>?>(lowered final self::A<self::Extension1|get#method2::X%> #this) → <Y extends core::String = core::String>(self::D<Y>, self::D<core::String>?) → void
   return <Y extends core::String = core::String>(self::D<Y> a, self::D<core::String>? b) → void => self::Extension1|method2<self::Extension1|get#method2::X%, Y>(#this, a, b);
 static method test() → dynamic {
   self::A<Null> a = new self::A::•<Null>();
diff --git a/pkg/front_end/testcases/nnbd/issue43256.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43256.dart.strong.expect
index d4b69b6..3c826d1 100644
--- a/pkg/front_end/testcases/nnbd/issue43256.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43256.dart.strong.expect
@@ -76,73 +76,67 @@
   if (i > 0) ...nullableList, // error
                 ^");
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t5 in self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>)
-      #t4.{core::Set::add}{Invariant}(#t5);
+    #t4.{core::Set::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t6 in self::nullableList!)
-      #t4.{core::Set::add}{Invariant}(#t6);
+    #t4.{core::Set::addAll}{Invariant}(self::nullableList!);
 } =>#t4;
 static field core::List<dynamic> list1 = block {
-  final core::List<dynamic> #t7 = <dynamic>[];
+  final core::List<dynamic> #t5 = <dynamic>[];
   if(self::i.{core::num::>}(0))
-    #t7.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+    #t5.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   if (i > 0) ...nullableList, // error
                 ^");
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t8 in self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>)
-      #t7.{core::List::add}{Invariant}(#t8);
+    #t5.{core::List::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t9 in self::nullableList!)
-      #t7.{core::List::add}{Invariant}(#t9);
-} =>#t7;
+    #t5.{core::List::addAll}{Invariant}(self::nullableList!);
+} =>#t5;
 static method testMap<X extends dynamic = dynamic, Y extends core::Map<core::int, core::String>? = core::Map<core::int, core::String>?, Z extends core::Map<core::int, core::String> = core::Map<core::int, core::String>>(self::testMap::X% x, self::testMap::Y% y, self::testMap::Z z) → dynamic {
   core::Map<dynamic, dynamic> map2 = block {
-    final core::Map<dynamic, dynamic> #t10 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic> #t6 = <dynamic, dynamic>{};
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
     if (i > 0) ...x, // error
                   ^", null);
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^", null);
     if(self::i.{core::num::>}(0))
-      for (final core::MapEntry<dynamic, dynamic> #t11 in z.{core::Map::entries})
-        #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
+      for (final core::MapEntry<dynamic, dynamic> #t7 in z.{core::Map::entries})
+        #t6.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
     if(self::i.{core::num::>}(0))
-      for (final core::MapEntry<dynamic, dynamic> #t12 in y!.{core::Map::entries})
-        #t10.{core::Map::[]=}{Invariant}(#t12.{core::MapEntry::key}, #t12.{core::MapEntry::value});
-  } =>#t10;
+      for (final core::MapEntry<dynamic, dynamic> #t8 in y!.{core::Map::entries})
+        #t6.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
+  } =>#t6;
 }
 static method testIterables<X extends dynamic = dynamic, Y extends core::List<core::int>? = core::List<core::int>?, Z extends core::List<core::int> = core::List<core::int>>(self::testIterables::X% x, self::testIterables::Y% y, self::testIterables::Z z) → dynamic {
   core::Set<dynamic> set2 = block {
-    final core::Set<dynamic> #t13 = col::LinkedHashSet::•<dynamic>();
-    #t13.{core::Set::add}{Invariant}(0);
+    final core::Set<dynamic> #t9 = col::LinkedHashSet::•<dynamic>();
+    #t9.{core::Set::add}{Invariant}(0);
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      for (final dynamic #t14 in z)
-        #t13.{core::Set::add}{Invariant}(#t14);
-  } =>#t13;
+      #t9.{core::Set::addAll}{Invariant}(z);
+  } =>#t9;
   core::List<dynamic> list2 = block {
-    final core::List<dynamic> #t15 = <dynamic>[];
+    final core::List<dynamic> #t10 = <dynamic>[];
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      for (final dynamic #t16 in z)
-        #t15.{core::List::add}{Invariant}(#t16);
-  } =>#t15;
+      #t10.{core::List::addAll}{Invariant}(z);
+  } =>#t10;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect
index 7babee3..4fddc1b 100644
--- a/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect
@@ -83,106 +83,76 @@
     #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:23:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   if (i > 0) ...nullableList, // error
                 ^");
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<dynamic> :sync-for-iterator = (self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t5 = :sync-for-iterator.{core::Iterator::current};
-      #t4.{core::Set::add}{Invariant}(#t5);
-    }
-  }
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<core::int> :sync-for-iterator = self::nullableList!.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
-      #t4.{core::Set::add}{Invariant}(#t6);
-    }
-  }
+  if(self::i.{core::num::>}(0))
+    #t4.{core::Set::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
+  if(self::i.{core::num::>}(0))
+    #t4.{core::Set::addAll}{Invariant}(self::nullableList!);
 } =>#t4;
 static field core::List<dynamic> list1 = block {
-  final core::List<dynamic> #t7 = <dynamic>[];
+  final core::List<dynamic> #t5 = <dynamic>[];
   if(self::i.{core::num::>}(0))
-    #t7.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+    #t5.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   if (i > 0) ...nullableList, // error
                 ^");
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<dynamic> :sync-for-iterator = (self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
-      #t7.{core::List::add}{Invariant}(#t8);
-    }
-  }
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<core::int> :sync-for-iterator = self::nullableList!.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
-      #t7.{core::List::add}{Invariant}(#t9);
-    }
-  }
-} =>#t7;
+  if(self::i.{core::num::>}(0))
+    #t5.{core::List::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
+  if(self::i.{core::num::>}(0))
+    #t5.{core::List::addAll}{Invariant}(self::nullableList!);
+} =>#t5;
 static method testMap<X extends dynamic = dynamic, Y extends core::Map<core::int, core::String>? = core::Map<core::int, core::String>?, Z extends core::Map<core::int, core::String> = core::Map<core::int, core::String>>(self::testMap::X% x, self::testMap::Y% y, self::testMap::Z z) → dynamic {
   core::Map<dynamic, dynamic> map2 = block {
-    final core::Map<dynamic, dynamic> #t10 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic> #t6 = <dynamic, dynamic>{};
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
     if (i > 0) ...x, // error
                   ^", null);
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^", null);
     if(self::i.{core::num::>}(0)) {
       core::Iterator<core::MapEntry<core::int, core::String>> :sync-for-iterator = z.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic> #t11 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
+        final core::MapEntry<dynamic, dynamic> #t7 = :sync-for-iterator.{core::Iterator::current};
+        #t6.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
       }
     }
     if(self::i.{core::num::>}(0)) {
       core::Iterator<core::MapEntry<core::int, core::String>> :sync-for-iterator = y!.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic> #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::Map::[]=}{Invariant}(#t12.{core::MapEntry::key}, #t12.{core::MapEntry::value});
+        final core::MapEntry<dynamic, dynamic> #t8 = :sync-for-iterator.{core::Iterator::current};
+        #t6.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
       }
     }
-  } =>#t10;
+  } =>#t6;
 }
 static method testIterables<X extends dynamic = dynamic, Y extends core::List<core::int>? = core::List<core::int>?, Z extends core::List<core::int> = core::List<core::int>>(self::testIterables::X% x, self::testIterables::Y% y, self::testIterables::Z z) → dynamic {
   core::Set<dynamic> set2 = block {
-    final core::Set<dynamic> #t13 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t13.{core::Set::add}{Invariant}(0);
+    final core::Set<dynamic> #t9 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t9.{core::Set::add}{Invariant}(0);
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
-    if(self::i.{core::num::>}(0)) {
-      core::Iterator<core::int> :sync-for-iterator = z.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
-        #t13.{core::Set::add}{Invariant}(#t14);
-      }
-    }
-  } =>#t13;
+    if(self::i.{core::num::>}(0))
+      #t9.{core::Set::addAll}{Invariant}(z);
+  } =>#t9;
   core::List<dynamic> list2 = block {
-    final core::List<dynamic> #t15 = <dynamic>[];
+    final core::List<dynamic> #t10 = <dynamic>[];
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
-    if(self::i.{core::num::>}(0)) {
-      core::Iterator<core::int> :sync-for-iterator = z.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
-        #t15.{core::List::add}{Invariant}(#t16);
-      }
-    }
-  } =>#t15;
+    if(self::i.{core::num::>}(0))
+      #t10.{core::List::addAll}{Invariant}(z);
+  } =>#t10;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue43256.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43256.dart.weak.expect
index d4b69b6..3c826d1 100644
--- a/pkg/front_end/testcases/nnbd/issue43256.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43256.dart.weak.expect
@@ -76,73 +76,67 @@
   if (i > 0) ...nullableList, // error
                 ^");
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t5 in self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>)
-      #t4.{core::Set::add}{Invariant}(#t5);
+    #t4.{core::Set::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t6 in self::nullableList!)
-      #t4.{core::Set::add}{Invariant}(#t6);
+    #t4.{core::Set::addAll}{Invariant}(self::nullableList!);
 } =>#t4;
 static field core::List<dynamic> list1 = block {
-  final core::List<dynamic> #t7 = <dynamic>[];
+  final core::List<dynamic> #t5 = <dynamic>[];
   if(self::i.{core::num::>}(0))
-    #t7.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+    #t5.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   if (i > 0) ...nullableList, // error
                 ^");
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t8 in self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>)
-      #t7.{core::List::add}{Invariant}(#t8);
+    #t5.{core::List::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
   if(self::i.{core::num::>}(0))
-    for (final dynamic #t9 in self::nullableList!)
-      #t7.{core::List::add}{Invariant}(#t9);
-} =>#t7;
+    #t5.{core::List::addAll}{Invariant}(self::nullableList!);
+} =>#t5;
 static method testMap<X extends dynamic = dynamic, Y extends core::Map<core::int, core::String>? = core::Map<core::int, core::String>?, Z extends core::Map<core::int, core::String> = core::Map<core::int, core::String>>(self::testMap::X% x, self::testMap::Y% y, self::testMap::Z z) → dynamic {
   core::Map<dynamic, dynamic> map2 = block {
-    final core::Map<dynamic, dynamic> #t10 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic> #t6 = <dynamic, dynamic>{};
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
     if (i > 0) ...x, // error
                   ^", null);
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^", null);
     if(self::i.{core::num::>}(0))
-      for (final core::MapEntry<dynamic, dynamic> #t11 in z.{core::Map::entries})
-        #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
+      for (final core::MapEntry<dynamic, dynamic> #t7 in z.{core::Map::entries})
+        #t6.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
     if(self::i.{core::num::>}(0))
-      for (final core::MapEntry<dynamic, dynamic> #t12 in y!.{core::Map::entries})
-        #t10.{core::Map::[]=}{Invariant}(#t12.{core::MapEntry::key}, #t12.{core::MapEntry::value});
-  } =>#t10;
+      for (final core::MapEntry<dynamic, dynamic> #t8 in y!.{core::Map::entries})
+        #t6.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
+  } =>#t6;
 }
 static method testIterables<X extends dynamic = dynamic, Y extends core::List<core::int>? = core::List<core::int>?, Z extends core::List<core::int> = core::List<core::int>>(self::testIterables::X% x, self::testIterables::Y% y, self::testIterables::Z z) → dynamic {
   core::Set<dynamic> set2 = block {
-    final core::Set<dynamic> #t13 = col::LinkedHashSet::•<dynamic>();
-    #t13.{core::Set::add}{Invariant}(0);
+    final core::Set<dynamic> #t9 = col::LinkedHashSet::•<dynamic>();
+    #t9.{core::Set::add}{Invariant}(0);
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      for (final dynamic #t14 in z)
-        #t13.{core::Set::add}{Invariant}(#t14);
-  } =>#t13;
+      #t9.{core::Set::addAll}{Invariant}(z);
+  } =>#t9;
   core::List<dynamic> list2 = block {
-    final core::List<dynamic> #t15 = <dynamic>[];
+    final core::List<dynamic> #t10 = <dynamic>[];
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      for (final dynamic #t16 in z)
-        #t15.{core::List::add}{Invariant}(#t16);
-  } =>#t15;
+      #t10.{core::List::addAll}{Invariant}(z);
+  } =>#t10;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect
index 7babee3..4fddc1b 100644
--- a/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect
@@ -83,106 +83,76 @@
     #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:23:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   if (i > 0) ...nullableList, // error
                 ^");
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<dynamic> :sync-for-iterator = (self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t5 = :sync-for-iterator.{core::Iterator::current};
-      #t4.{core::Set::add}{Invariant}(#t5);
-    }
-  }
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<core::int> :sync-for-iterator = self::nullableList!.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
-      #t4.{core::Set::add}{Invariant}(#t6);
-    }
-  }
+  if(self::i.{core::num::>}(0))
+    #t4.{core::Set::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
+  if(self::i.{core::num::>}(0))
+    #t4.{core::Set::addAll}{Invariant}(self::nullableList!);
 } =>#t4;
 static field core::List<dynamic> list1 = block {
-  final core::List<dynamic> #t7 = <dynamic>[];
+  final core::List<dynamic> #t5 = <dynamic>[];
   if(self::i.{core::num::>}(0))
-    #t7.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+    #t5.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:29:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   if (i > 0) ...nullableList, // error
                 ^");
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<dynamic> :sync-for-iterator = (self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
-      #t7.{core::List::add}{Invariant}(#t8);
-    }
-  }
-  if(self::i.{core::num::>}(0)) {
-    core::Iterator<core::int> :sync-for-iterator = self::nullableList!.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
-      #t7.{core::List::add}{Invariant}(#t9);
-    }
-  }
-} =>#t7;
+  if(self::i.{core::num::>}(0))
+    #t5.{core::List::addAll}{Invariant}(self::dynamicList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>);
+  if(self::i.{core::num::>}(0))
+    #t5.{core::List::addAll}{Invariant}(self::nullableList!);
+} =>#t5;
 static method testMap<X extends dynamic = dynamic, Y extends core::Map<core::int, core::String>? = core::Map<core::int, core::String>?, Z extends core::Map<core::int, core::String> = core::Map<core::int, core::String>>(self::testMap::X% x, self::testMap::Y% y, self::testMap::Z z) → dynamic {
   core::Map<dynamic, dynamic> map2 = block {
-    final core::Map<dynamic, dynamic> #t10 = <dynamic, dynamic>{};
+    final core::Map<dynamic, dynamic> #t6 = <dynamic, dynamic>{};
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:37:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
     if (i > 0) ...x, // error
                   ^", null);
     if(self::i.{core::num::>}(0))
-      #t10.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:38:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^", null);
     if(self::i.{core::num::>}(0)) {
       core::Iterator<core::MapEntry<core::int, core::String>> :sync-for-iterator = z.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic> #t11 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
+        final core::MapEntry<dynamic, dynamic> #t7 = :sync-for-iterator.{core::Iterator::current};
+        #t6.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
       }
     }
     if(self::i.{core::num::>}(0)) {
       core::Iterator<core::MapEntry<core::int, core::String>> :sync-for-iterator = y!.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic> #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::Map::[]=}{Invariant}(#t12.{core::MapEntry::key}, #t12.{core::MapEntry::value});
+        final core::MapEntry<dynamic, dynamic> #t8 = :sync-for-iterator.{core::Iterator::current};
+        #t6.{core::Map::[]=}{Invariant}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
       }
     }
-  } =>#t10;
+  } =>#t6;
 }
 static method testIterables<X extends dynamic = dynamic, Y extends core::List<core::int>? = core::List<core::int>?, Z extends core::List<core::int> = core::List<core::int>>(self::testIterables::X% x, self::testIterables::Y% y, self::testIterables::Z z) → dynamic {
   core::Set<dynamic> set2 = block {
-    final core::Set<dynamic> #t13 = new col::_CompactLinkedHashSet::•<dynamic>();
-    #t13.{core::Set::add}{Invariant}(0);
+    final core::Set<dynamic> #t9 = new col::_CompactLinkedHashSet::•<dynamic>();
+    #t9.{core::Set::add}{Invariant}(0);
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t13.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t9.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:49:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
-    if(self::i.{core::num::>}(0)) {
-      core::Iterator<core::int> :sync-for-iterator = z.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
-        #t13.{core::Set::add}{Invariant}(#t14);
-      }
-    }
-  } =>#t13;
+    if(self::i.{core::num::>}(0))
+      #t9.{core::Set::addAll}{Invariant}(z);
+  } =>#t9;
   core::List<dynamic> list2 = block {
-    final core::List<dynamic> #t15 = <dynamic>[];
+    final core::List<dynamic> #t10 = <dynamic>[];
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:53:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
     if (i > 0) ...x, // error
                   ^");
     if(self::i.{core::num::>}(0))
-      #t15.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+      #t10.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:54:19: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     if (i > 0) ...y, // error
                   ^");
-    if(self::i.{core::num::>}(0)) {
-      core::Iterator<core::int> :sync-for-iterator = z.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
-        #t15.{core::List::add}{Invariant}(#t16);
-      }
-    }
-  } =>#t15;
+    if(self::i.{core::num::>}(0))
+      #t10.{core::List::addAll}{Invariant}(z);
+  } =>#t10;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue43276.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue43276.dart.outline.expect
index 46f5c3e..83d2e51 100644
--- a/pkg/front_end/testcases/nnbd/issue43276.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43276.dart.outline.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.gen({int i}); // error
 //              ^
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.fact({int i}) /* error */ {
 //                       ^
 //
@@ -14,7 +16,7 @@
 import "dart:core" as core;
 
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor gen({core::int i}) → self::C
     ;
   static factory fact({core::int i}) → self::C
diff --git a/pkg/front_end/testcases/nnbd/issue43276.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43276.dart.strong.expect
index a827c7e..bcb7771 100644
--- a/pkg/front_end/testcases/nnbd/issue43276.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43276.dart.strong.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.gen({int i}); // error
 //              ^
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.fact({int i}) /* error */ {
 //                       ^
 //
@@ -14,7 +16,7 @@
 import "dart:core" as core;
 
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor gen({core::int i = #C1}) → self::C
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue43276.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43276.dart.strong.transformed.expect
index 3a35612..744265d 100644
--- a/pkg/front_end/testcases/nnbd/issue43276.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43276.dart.strong.transformed.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.gen({int i}); // error
 //              ^
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.fact({int i}) /* error */ {
 //                       ^
 //
@@ -14,7 +16,7 @@
 import "dart:core" as core;
 
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor gen({core::int i = #C1}) → self::C
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue43276.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43276.dart.weak.expect
index a827c7e..bcb7771 100644
--- a/pkg/front_end/testcases/nnbd/issue43276.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43276.dart.weak.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.gen({int i}); // error
 //              ^
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.fact({int i}) /* error */ {
 //                       ^
 //
@@ -14,7 +16,7 @@
 import "dart:core" as core;
 
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor gen({core::int i = #C1}) → self::C
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue43276.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43276.dart.weak.transformed.expect
index 3a35612..744265d 100644
--- a/pkg/front_end/testcases/nnbd/issue43276.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43276.dart.weak.transformed.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:6:14: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   C.gen({int i}); // error
 //              ^
 //
-// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/issue43276.dart:8:23: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   factory C.fact({int i}) /* error */ {
 //                       ^
 //
@@ -14,7 +16,7 @@
 import "dart:core" as core;
 
 class C extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C::redirect]/*isLegacy*/;
   constructor gen({core::int i = #C1}) → self::C
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.outline.expect
index 1ca6277..795331a 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.outline.expect
@@ -19,11 +19,11 @@
 }
 static method test<T extends self::A? = self::A?>(self::A? a, self::test::T% t, dynamic d, core::int x) → dynamic
   ;
-static method Extension|get#fooExtension(final self::B #this) → core::int?
+static method Extension|get#fooExtension(lowered final self::B #this) → core::int?
   ;
-static method Extension|set#fooExtension(final self::B #this, core::int? value) → void
+static method Extension|set#fooExtension(lowered final self::B #this, core::int? value) → void
   ;
-static method Extension|get#barExtension(final self::B #this) → self::B
+static method Extension|get#barExtension(lowered final self::B #this) → self::B
   ;
 static method testExtension<T extends self::B? = self::B?>(self::B? b, self::testExtension::T% t, core::int x) → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect
index 3087b3b..caccef7 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect
@@ -71,10 +71,10 @@
   let final dynamic #t7 = d in #t7.foo.{core::Object::==}(null) ?{dynamic} #t7.foo = x : null;
   let final self::A? #t8 = a in #t8.{core::Object::==}(null) ?{core::int?} null : let final self::A #t9 = #t8{self::A}.{self::A::bar} in #t9.{self::A::foo}.{core::num::==}(null) ?{core::int} #t9.{self::A::foo} = x : null;
 }
-static method Extension|get#fooExtension(final self::B #this) → core::int?
+static method Extension|get#fooExtension(lowered final self::B #this) → core::int?
   return null;
-static method Extension|set#fooExtension(final self::B #this, core::int? value) → void {}
-static method Extension|get#barExtension(final self::B #this) → self::B
+static method Extension|set#fooExtension(lowered final self::B #this, core::int? value) → void {}
+static method Extension|get#barExtension(lowered final self::B #this) → self::B
   return new self::B::•();
 static method testExtension<T extends self::B? = self::B?>(self::B? b, self::testExtension::T% t, core::int x) → dynamic {
   let final self::B? #t10 = b in (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:28:5: Error: Property 'fooExtension' cannot be accessed on 'B?' because it is potentially null.
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.transformed.expect
index 3087b3b..caccef7 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.transformed.expect
@@ -71,10 +71,10 @@
   let final dynamic #t7 = d in #t7.foo.{core::Object::==}(null) ?{dynamic} #t7.foo = x : null;
   let final self::A? #t8 = a in #t8.{core::Object::==}(null) ?{core::int?} null : let final self::A #t9 = #t8{self::A}.{self::A::bar} in #t9.{self::A::foo}.{core::num::==}(null) ?{core::int} #t9.{self::A::foo} = x : null;
 }
-static method Extension|get#fooExtension(final self::B #this) → core::int?
+static method Extension|get#fooExtension(lowered final self::B #this) → core::int?
   return null;
-static method Extension|set#fooExtension(final self::B #this, core::int? value) → void {}
-static method Extension|get#barExtension(final self::B #this) → self::B
+static method Extension|set#fooExtension(lowered final self::B #this, core::int? value) → void {}
+static method Extension|get#barExtension(lowered final self::B #this) → self::B
   return new self::B::•();
 static method testExtension<T extends self::B? = self::B?>(self::B? b, self::testExtension::T% t, core::int x) → dynamic {
   let final self::B? #t10 = b in (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:28:5: Error: Property 'fooExtension' cannot be accessed on 'B?' because it is potentially null.
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect
index 3087b3b..caccef7 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect
@@ -71,10 +71,10 @@
   let final dynamic #t7 = d in #t7.foo.{core::Object::==}(null) ?{dynamic} #t7.foo = x : null;
   let final self::A? #t8 = a in #t8.{core::Object::==}(null) ?{core::int?} null : let final self::A #t9 = #t8{self::A}.{self::A::bar} in #t9.{self::A::foo}.{core::num::==}(null) ?{core::int} #t9.{self::A::foo} = x : null;
 }
-static method Extension|get#fooExtension(final self::B #this) → core::int?
+static method Extension|get#fooExtension(lowered final self::B #this) → core::int?
   return null;
-static method Extension|set#fooExtension(final self::B #this, core::int? value) → void {}
-static method Extension|get#barExtension(final self::B #this) → self::B
+static method Extension|set#fooExtension(lowered final self::B #this, core::int? value) → void {}
+static method Extension|get#barExtension(lowered final self::B #this) → self::B
   return new self::B::•();
 static method testExtension<T extends self::B? = self::B?>(self::B? b, self::testExtension::T% t, core::int x) → dynamic {
   let final self::B? #t10 = b in (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:28:5: Error: Property 'fooExtension' cannot be accessed on 'B?' because it is potentially null.
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.transformed.expect
index 3087b3b..caccef7 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.transformed.expect
@@ -71,10 +71,10 @@
   let final dynamic #t7 = d in #t7.foo.{core::Object::==}(null) ?{dynamic} #t7.foo = x : null;
   let final self::A? #t8 = a in #t8.{core::Object::==}(null) ?{core::int?} null : let final self::A #t9 = #t8{self::A}.{self::A::bar} in #t9.{self::A::foo}.{core::num::==}(null) ?{core::int} #t9.{self::A::foo} = x : null;
 }
-static method Extension|get#fooExtension(final self::B #this) → core::int?
+static method Extension|get#fooExtension(lowered final self::B #this) → core::int?
   return null;
-static method Extension|set#fooExtension(final self::B #this, core::int? value) → void {}
-static method Extension|get#barExtension(final self::B #this) → self::B
+static method Extension|set#fooExtension(lowered final self::B #this, core::int? value) → void {}
+static method Extension|get#barExtension(lowered final self::B #this) → self::B
   return new self::B::•();
 static method testExtension<T extends self::B? = self::B?>(self::B? b, self::testExtension::T% t, core::int x) → dynamic {
   let final self::B? #t10 = b in (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:28:5: Error: Property 'fooExtension' cannot be accessed on 'B?' because it is potentially null.
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.outline.expect
index dbf8690..f3c723d 100644
--- a/pkg/front_end/testcases/nnbd/issue43591.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.outline.expect
@@ -5,7 +5,7 @@
 extension E<T extends core::Object? = dynamic> on T% {
   get f = self::E|get#f;
 }
-static method E|get#f<T extends core::Object? = dynamic>(final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
+static method E|get#f<T extends core::Object? = dynamic>(lowered final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
   ;
 static method method1<S extends core::Object? = dynamic>(self::method1::S% s) → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.strong.expect
index aae95d4..d9bdceb 100644
--- a/pkg/front_end/testcases/nnbd/issue43591.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.strong.expect
@@ -5,7 +5,7 @@
 extension E<T extends core::Object? = dynamic> on T% {
   get f = self::E|get#f;
 }
-static method E|get#f<T extends core::Object? = dynamic>(final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
+static method E|get#f<T extends core::Object? = dynamic>(lowered final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
   return (self::E|get#f::T% t) → self::E|get#f::T% => t;
 static method method1<S extends core::Object? = dynamic>(self::method1::S% s) → dynamic {
   (self::method1::S%) → self::method1::S% f = self::E|get#f<self::method1::S%>(s);
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.strong.transformed.expect
index aae95d4..d9bdceb 100644
--- a/pkg/front_end/testcases/nnbd/issue43591.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.strong.transformed.expect
@@ -5,7 +5,7 @@
 extension E<T extends core::Object? = dynamic> on T% {
   get f = self::E|get#f;
 }
-static method E|get#f<T extends core::Object? = dynamic>(final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
+static method E|get#f<T extends core::Object? = dynamic>(lowered final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
   return (self::E|get#f::T% t) → self::E|get#f::T% => t;
 static method method1<S extends core::Object? = dynamic>(self::method1::S% s) → dynamic {
   (self::method1::S%) → self::method1::S% f = self::E|get#f<self::method1::S%>(s);
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.weak.expect
index aae95d4..d9bdceb 100644
--- a/pkg/front_end/testcases/nnbd/issue43591.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.weak.expect
@@ -5,7 +5,7 @@
 extension E<T extends core::Object? = dynamic> on T% {
   get f = self::E|get#f;
 }
-static method E|get#f<T extends core::Object? = dynamic>(final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
+static method E|get#f<T extends core::Object? = dynamic>(lowered final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
   return (self::E|get#f::T% t) → self::E|get#f::T% => t;
 static method method1<S extends core::Object? = dynamic>(self::method1::S% s) → dynamic {
   (self::method1::S%) → self::method1::S% f = self::E|get#f<self::method1::S%>(s);
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.weak.transformed.expect
index aae95d4..d9bdceb 100644
--- a/pkg/front_end/testcases/nnbd/issue43591.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 extension E<T extends core::Object? = dynamic> on T% {
   get f = self::E|get#f;
 }
-static method E|get#f<T extends core::Object? = dynamic>(final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
+static method E|get#f<T extends core::Object? = dynamic>(lowered final self::E|get#f::T% #this) → (self::E|get#f::T%) → self::E|get#f::T%
   return (self::E|get#f::T% t) → self::E|get#f::T% => t;
 static method method1<S extends core::Object? = dynamic>(self::method1::S% s) → dynamic {
   (self::method1::S%) → self::method1::S% f = self::E|get#f<self::method1::S%>(s);
diff --git a/pkg/front_end/testcases/nnbd/issue43918.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue43918.dart.outline.expect
index 2e633c9..9bff7b0 100644
--- a/pkg/front_end/testcases/nnbd/issue43918.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43918.dart.outline.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 abstract class A<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(self::A::•::T% value) → self::A<self::A::•::T%>
     let dynamic #redirecting_factory = self::_A::• in let self::A::•::T% #typeArg0 = null in invalid-expression;
 }
@@ -12,7 +12,7 @@
     ;
 }
 abstract class B<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(core::int value) → self::B<self::B::•::T%>
     let dynamic #redirecting_factory = self::_B::• in let self::B::•::T% #typeArg0 = null in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue43918.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43918.dart.strong.expect
index 1d6771b..33ae9c2 100644
--- a/pkg/front_end/testcases/nnbd/issue43918.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43918.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 abstract class A<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(self::A::•::T% value) → self::A<self::A::•::T%>
     let dynamic #redirecting_factory = self::_A::• in let self::A::•::T% #typeArg0 = null in invalid-expression;
 }
@@ -13,7 +13,7 @@
     ;
 }
 abstract class B<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(core::int value) → self::B<self::B::•::T%>
     let dynamic #redirecting_factory = self::_B::• in let self::B::•::T% #typeArg0 = null in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue43918.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43918.dart.strong.transformed.expect
index 143829a..1669379 100644
--- a/pkg/front_end/testcases/nnbd/issue43918.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43918.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 abstract class A<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(self::A::•::T% value) → self::A<self::A::•::T%>
     let<BottomType> #redirecting_factory = self::_A::• in let self::A::•::T% #typeArg0 = null in invalid-expression;
 }
@@ -13,7 +13,7 @@
     ;
 }
 abstract class B<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(core::int value) → self::B<self::B::•::T%>
     let<BottomType> #redirecting_factory = self::_B::• in let self::B::•::T% #typeArg0 = null in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue43918.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43918.dart.weak.expect
index 1d6771b..33ae9c2 100644
--- a/pkg/front_end/testcases/nnbd/issue43918.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43918.dart.weak.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 abstract class A<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(self::A::•::T% value) → self::A<self::A::•::T%>
     let dynamic #redirecting_factory = self::_A::• in let self::A::•::T% #typeArg0 = null in invalid-expression;
 }
@@ -13,7 +13,7 @@
     ;
 }
 abstract class B<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(core::int value) → self::B<self::B::•::T%>
     let dynamic #redirecting_factory = self::_B::• in let self::B::•::T% #typeArg0 = null in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue43918.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43918.dart.weak.transformed.expect
index 143829a..1669379 100644
--- a/pkg/front_end/testcases/nnbd/issue43918.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43918.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 abstract class A<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::A::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(self::A::•::T% value) → self::A<self::A::•::T%>
     let<BottomType> #redirecting_factory = self::_A::• in let self::A::•::T% #typeArg0 = null in invalid-expression;
 }
@@ -13,7 +13,7 @@
     ;
 }
 abstract class B<T extends core::Object? = dynamic> extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::B::•]/*isLegacy*/;
   static factory •<T extends core::Object? = dynamic>(core::int value) → self::B<self::B::•::T%>
     let<BottomType> #redirecting_factory = self::_B::• in let self::B::•::T% #typeArg0 = null in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart b/pkg/front_end/testcases/nnbd/issue44276.dart
new file mode 100644
index 0000000..8f49a9a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void main() {
+  fun();
+}
+
+class Base {
+  int? value1;
+  int? value2;
+}
+
+int? fun() {
+  Base? a;
+  final b = a?.value1 ?? a?.value2;
+  return b;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.outline.expect
new file mode 100644
index 0000000..665128f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.outline.expect
@@ -0,0 +1,14 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int? value1;
+  field core::int? value2;
+  synthetic constructor •() → self::Base
+    ;
+}
+static method main() → void
+  ;
+static method fun() → core::int?
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.strong.expect
new file mode 100644
index 0000000..9f8c187
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.strong.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int? value1 = null;
+  field core::int? value2 = null;
+  synthetic constructor •() → self::Base
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::fun();
+}
+static method fun() → core::int? {
+  self::Base? a;
+  final core::int? b = let final core::int? #t1 = let final self::Base? #t2 = a in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Base}.{self::Base::value1} in #t1.{core::num::==}(null) ?{core::int?} let final self::Base? #t3 = a in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Base}.{self::Base::value2} : #t1{core::int};
+  return b;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.strong.transformed.expect
new file mode 100644
index 0000000..9f8c187
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int? value1 = null;
+  field core::int? value2 = null;
+  synthetic constructor •() → self::Base
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::fun();
+}
+static method fun() → core::int? {
+  self::Base? a;
+  final core::int? b = let final core::int? #t1 = let final self::Base? #t2 = a in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Base}.{self::Base::value1} in #t1.{core::num::==}(null) ?{core::int?} let final self::Base? #t3 = a in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Base}.{self::Base::value2} : #t1{core::int};
+  return b;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.textual_outline.expect
new file mode 100644
index 0000000..be5c153
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+void main() {}
+
+class Base {
+  int? value1;
+  int? value2;
+}
+
+int? fun() {}
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..75f8632
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Base {
+  int? value1;
+  int? value2;
+}
+
+int? fun() {}
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.weak.expect
new file mode 100644
index 0000000..9f8c187
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.weak.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int? value1 = null;
+  field core::int? value2 = null;
+  synthetic constructor •() → self::Base
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::fun();
+}
+static method fun() → core::int? {
+  self::Base? a;
+  final core::int? b = let final core::int? #t1 = let final self::Base? #t2 = a in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Base}.{self::Base::value1} in #t1.{core::num::==}(null) ?{core::int?} let final self::Base? #t3 = a in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Base}.{self::Base::value2} : #t1{core::int};
+  return b;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue44276.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue44276.dart.weak.transformed.expect
new file mode 100644
index 0000000..9f8c187
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue44276.dart.weak.transformed.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int? value1 = null;
+  field core::int? value2 = null;
+  synthetic constructor •() → self::Base
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::fun();
+}
+static method fun() → core::int? {
+  self::Base? a;
+  final core::int? b = let final core::int? #t1 = let final self::Base? #t2 = a in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Base}.{self::Base::value1} in #t1.{core::num::==}(null) ?{core::int?} let final self::Base? #t3 = a in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Base}.{self::Base::value2} : #t1{core::int};
+  return b;
+}
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.outline.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.outline.expect
index 5032523..3cfc9db 100644
--- a/pkg/front_end/testcases/nnbd/language_issue1182.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.outline.expect
@@ -11,7 +11,7 @@
 extension Test<T extends core::Object? = dynamic> on T% {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object? = dynamic>(final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
+static method Test|get#test<T extends core::Object? = dynamic>(lowered final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
   ;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.expect
index 151bcbd..2057990 100644
--- a/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.expect
@@ -13,6 +13,6 @@
 extension Test<T extends core::Object? = dynamic> on T% {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object? = dynamic>(final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
+static method Test|get#test<T extends core::Object? = dynamic>(lowered final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
   return (self::Test|get#test::T% a) → self::Test|get#test::T% => #this;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.transformed.expect
index 151bcbd..2057990 100644
--- a/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.strong.transformed.expect
@@ -13,6 +13,6 @@
 extension Test<T extends core::Object? = dynamic> on T% {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object? = dynamic>(final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
+static method Test|get#test<T extends core::Object? = dynamic>(lowered final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
   return (self::Test|get#test::T% a) → self::Test|get#test::T% => #this;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.expect
index 151bcbd..2057990 100644
--- a/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.expect
@@ -13,6 +13,6 @@
 extension Test<T extends core::Object? = dynamic> on T% {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object? = dynamic>(final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
+static method Test|get#test<T extends core::Object? = dynamic>(lowered final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
   return (self::Test|get#test::T% a) → self::Test|get#test::T% => #this;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.transformed.expect
index 151bcbd..2057990 100644
--- a/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.weak.transformed.expect
@@ -13,6 +13,6 @@
 extension Test<T extends core::Object? = dynamic> on T% {
   get test = self::Test|get#test;
 }
-static method Test|get#test<T extends core::Object? = dynamic>(final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
+static method Test|get#test<T extends core::Object? = dynamic>(lowered final self::Test|get#test::T% #this) → (self::Test|get#test::T%) → self::Test|get#test::T%
   return (self::Test|get#test::T% a) → self::Test|get#test::T% => #this;
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index 25b17c9..c198bf3 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -127,7 +127,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -172,7 +171,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -183,7 +181,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -207,7 +204,6 @@
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
             core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
-            dynamic :async_stack_trace;
             (dynamic) → dynamic :async_op_then;
             (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
@@ -227,7 +223,6 @@
               on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
                 asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
               }
-            :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
             :async_op.call();
@@ -242,7 +237,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index 25b17c9..c198bf3 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -127,7 +127,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -172,7 +171,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -183,7 +181,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -207,7 +204,6 @@
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
             core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
-            dynamic :async_stack_trace;
             (dynamic) → dynamic :async_op_then;
             (core::Object, core::StackTrace) → dynamic :async_op_error;
             core::int :await_jump_var = 0;
@@ -227,7 +223,6 @@
               on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
                 asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
               }
-            :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
             :async_op.call();
@@ -242,7 +237,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.outline.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.outline.expect
index f59fb9e..9089964 100644
--- a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.outline.expect
@@ -2,19 +2,23 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method1({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method2([int a]) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method3({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method4([int a]) {}
 //              ^
 //
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.expect
index d869c59..f03bd13 100644
--- a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.expect
@@ -2,19 +2,23 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method1({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method2([int a]) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method3({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method4([int a]) {}
 //              ^
 //
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.transformed.expect
index d869c59..f03bd13 100644
--- a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.strong.transformed.expect
@@ -2,19 +2,23 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method1({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method2([int a]) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method3({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method4([int a]) {}
 //              ^
 //
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.expect
index d869c59..f03bd13 100644
--- a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.expect
@@ -2,19 +2,23 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method1({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method2([int a]) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method3({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method4([int a]) {}
 //              ^
 //
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.transformed.expect
index d869c59..f03bd13 100644
--- a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.weak.transformed.expect
@@ -2,19 +2,23 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method1({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional.dart:11:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method2([int a]) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:7:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method3({int a}) {}
 //              ^
 //
-// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/non_nullable_optional_part.dart:9:14: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // method4([int a]) {}
 //              ^
 //
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect
index 7cc6fec..553a098 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect
@@ -12,9 +12,9 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final self::Class #this) → self::Class
+static method Extension|extensionMethod(lowered final self::Class #this) → self::Class
   ;
-static method Extension|get#extensionMethod(final self::Class #this) → () → self::Class
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → self::Class
   return () → self::Class => self::Extension|extensionMethod(#this);
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect
index b67570c..a139a5e 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect
@@ -13,9 +13,9 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final self::Class #this) → self::Class
+static method Extension|extensionMethod(lowered final self::Class #this) → self::Class
   return #this;
-static method Extension|get#extensionMethod(final self::Class #this) → () → self::Class
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → self::Class
   return () → self::Class => self::Extension|extensionMethod(#this);
 static method main() → dynamic {
   self::Class? c;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect
index b67570c..a139a5e 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect
@@ -13,9 +13,9 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final self::Class #this) → self::Class
+static method Extension|extensionMethod(lowered final self::Class #this) → self::Class
   return #this;
-static method Extension|get#extensionMethod(final self::Class #this) → () → self::Class
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → self::Class
   return () → self::Class => self::Extension|extensionMethod(#this);
 static method main() → dynamic {
   self::Class? c;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect
index b67570c..a139a5e 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect
@@ -13,9 +13,9 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final self::Class #this) → self::Class
+static method Extension|extensionMethod(lowered final self::Class #this) → self::Class
   return #this;
-static method Extension|get#extensionMethod(final self::Class #this) → () → self::Class
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → self::Class
   return () → self::Class => self::Extension|extensionMethod(#this);
 static method main() → dynamic {
   self::Class? c;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect
index b67570c..a139a5e 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect
@@ -13,9 +13,9 @@
   method extensionMethod = self::Extension|extensionMethod;
   tearoff extensionMethod = self::Extension|get#extensionMethod;
 }
-static method Extension|extensionMethod(final self::Class #this) → self::Class
+static method Extension|extensionMethod(lowered final self::Class #this) → self::Class
   return #this;
-static method Extension|get#extensionMethod(final self::Class #this) → () → self::Class
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → self::Class
   return () → self::Class => self::Extension|extensionMethod(#this);
 static method main() → dynamic {
   self::Class? c;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect
index 6e17131..8b10ec3 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect
@@ -53,43 +53,43 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   ;
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void
   ;
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   ;
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   ;
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void
   ;
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   ;
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   ;
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   ;
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   ;
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   ;
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   ;
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   ;
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   ;
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   ;
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   ;
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void
   ;
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect
index ba0ed52..4e47ad6 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect
index ba0ed52..4e47ad6 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect
index ba0ed52..4e47ad6 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect
index ba0ed52..4e47ad6 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect
index 6e17131..8b10ec3 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect
@@ -53,43 +53,43 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   ;
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void
   ;
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   ;
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   ;
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void
   ;
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   ;
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   ;
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   ;
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   ;
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   ;
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   ;
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   ;
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   ;
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   ;
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   ;
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void
   ;
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect
index 595c5b9..dead545 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect
index 595c5b9..dead545 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect
index 595c5b9..dead545 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect
index 595c5b9..dead545 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect
@@ -79,46 +79,46 @@
 extension Extension3 on self::Class3 {
   operator [] = self::Extension3|[];
 }
-static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+static method Extension1|get#nullable1(lowered final self::Class1 #this) → self::Class1?
   return #this.{self::Class1::property1};
-static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+static method Extension1|set#nullable1(lowered final self::Class1 #this, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+static method Extension1|nonNullable1Method(lowered final self::Class1 #this) → self::Class1
   return self::Extension1|get#nonNullable1(#this);
-static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+static method Extension1|get#nonNullable1Method(lowered final self::Class1 #this) → () → self::Class1
   return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
-static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+static method Extension1|[](lowered final self::Class1 #this, self::Class1? key) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+static method Extension1|[]=(lowered final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
   #this.{self::Class1::property} = value;
 }
-static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+static method Extension1|+(lowered final self::Class1 #this, core::int value) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+static method Extension1|unary-(lowered final self::Class1 #this) → self::Class1?
   return self::Extension1|get#nullable1(#this);
-static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+static method Extension1|get#nonNullable1(lowered final self::Class1 #this) → self::Class1
   return #this.{self::Class1::property1};
-static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+static method Extension1|get#nonNullable2(lowered final self::Class1 #this) → self::Class2
   return #this.{self::Class1::property2};
-static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+static method Extension2|nonNullable2Method(lowered final self::Class2 #this) → self::Class2
   return self::Extension2|get#nonNullable2(#this);
-static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+static method Extension2|get#nonNullable2Method(lowered final self::Class2 #this) → () → self::Class2
   return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
-static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+static method Extension2|[](lowered final self::Class2 #this, self::Class2? key) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2? key, self::Class2? value) → void
   return #this.{self::Class2::property};
-static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+static method Extension2|+(lowered final self::Class2 #this, core::int value) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|unary-(final self::Class2 #this) → self::Class2
+static method Extension2|unary-(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+static method Extension2|get#nonNullable2(lowered final self::Class2 #this) → self::Class2
   return #this.{self::Class2::property};
-static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+static method Extension2|set#nonNullable2(lowered final self::Class2 #this, self::Class2 value) → void {
   #this.{self::Class2::property} = value;
 }
-static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+static method Extension3|[](lowered final self::Class3 #this, self::Class3? key) → self::Class2?
   return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect
index c13bf31..8e9e154 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect
@@ -21,9 +21,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[](final self::Class2 #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class2 #this, core::int index) → core::int
   ;
-static method Extension|[]=(final self::Class2 #this, core::int index, core::int value) → void
+static method Extension|[]=(lowered final self::Class2 #this, core::int index, core::int value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
index e391c8f..dc52187 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
@@ -77,9 +77,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[](final self::Class2 #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class2 #this, core::int index) → core::int
   return #this.{self::Class2::field};
-static method Extension|[]=(final self::Class2 #this, core::int index, core::int value) → void {
+static method Extension|[]=(lowered final self::Class2 #this, core::int index, core::int value) → void {
   #this.{self::Class2::field} = value;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
index 9838019..5b7b144 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
@@ -77,9 +77,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[](final self::Class2 #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class2 #this, core::int index) → core::int
   return #this.{self::Class2::field};
-static method Extension|[]=(final self::Class2 #this, core::int index, core::int value) → void {
+static method Extension|[]=(lowered final self::Class2 #this, core::int index, core::int value) → void {
   #this.{self::Class2::field} = value;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
index e391c8f..dc52187 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
@@ -77,9 +77,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[](final self::Class2 #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class2 #this, core::int index) → core::int
   return #this.{self::Class2::field};
-static method Extension|[]=(final self::Class2 #this, core::int index, core::int value) → void {
+static method Extension|[]=(lowered final self::Class2 #this, core::int index, core::int value) → void {
   #this.{self::Class2::field} = value;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
index 7e7ea06..e604a49 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
@@ -77,9 +77,9 @@
   operator [] = self::Extension|[];
   operator []= = self::Extension|[]=;
 }
-static method Extension|[](final self::Class2 #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class2 #this, core::int index) → core::int
   return #this.{self::Class2::field};
-static method Extension|[]=(final self::Class2 #this, core::int index, core::int value) → void {
+static method Extension|[]=(lowered final self::Class2 #this, core::int index, core::int value) → void {
   #this.{self::Class2::field} = value;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.outline.expect
index 738963d..79d4bd9 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.outline.expect
@@ -10,7 +10,7 @@
 extension _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final self::A? #this) → core::String
+static method _extension#0|get#text(lowered final self::A? #this) → core::String
   ;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect
index 4b74dec..a732aa4 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect
@@ -11,7 +11,7 @@
 extension _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final self::A? #this) → core::String
+static method _extension#0|get#text(lowered final self::A? #this) → core::String
   return "Lily was here";
 static method main() → void {
   self::A? a = null;
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect
index 4b74dec..a732aa4 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
 extension _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final self::A? #this) → core::String
+static method _extension#0|get#text(lowered final self::A? #this) → core::String
   return "Lily was here";
 static method main() → void {
   self::A? a = null;
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect
index 4b74dec..a732aa4 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect
@@ -11,7 +11,7 @@
 extension _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final self::A? #this) → core::String
+static method _extension#0|get#text(lowered final self::A? #this) → core::String
   return "Lily was here";
 static method main() → void {
   self::A? a = null;
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect
index 4b74dec..a732aa4 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect
@@ -11,7 +11,7 @@
 extension _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final self::A? #this) → core::String
+static method _extension#0|get#text(lowered final self::A? #this) → core::String
   return "Lily was here";
 static method main() → void {
   self::A? a = null;
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.outline.expect
index 3f88610..57f6140 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.outline.expect
@@ -15,9 +15,9 @@
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
-static method _extension#0|set#setter(final self::C? #this, core::String v) → void
+static method _extension#0|set#setter(lowered final self::C? #this, core::String v) → void
   ;
-static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void
+static method _extension#0|[]=(lowered final self::C? #this, core::int index, core::String value) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
index ac016f2..4e21e645 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
@@ -14,10 +14,10 @@
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
-static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
+static method _extension#0|set#setter(lowered final self::C? #this, core::String v) → void {
   let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
 }
-static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
+static method _extension#0|[]=(lowered final self::C? #this, core::int index, core::String value) → void {
   let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect
index d367854..fdac0fc 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect
@@ -14,10 +14,10 @@
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
-static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
+static method _extension#0|set#setter(lowered final self::C? #this, core::String v) → void {
   let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
 }
-static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
+static method _extension#0|[]=(lowered final self::C? #this, core::int index, core::String value) → void {
   let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
index ac016f2..4e21e645 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
@@ -14,10 +14,10 @@
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
-static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
+static method _extension#0|set#setter(lowered final self::C? #this, core::String v) → void {
   let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
 }
-static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
+static method _extension#0|[]=(lowered final self::C? #this, core::int index, core::String value) → void {
   let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect
index d367854..fdac0fc 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect
@@ -14,10 +14,10 @@
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
-static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
+static method _extension#0|set#setter(lowered final self::C? #this, core::String v) → void {
   let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
 }
-static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
+static method _extension#0|[]=(lowered final self::C? #this, core::int index, core::String value) → void {
   let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect
index 45009c6..a3f0156 100644
--- a/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect
@@ -62,7 +62,7 @@
     ;
 }
 class C1 extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isLegacy*/;
   static factory •() → self::C1
     let dynamic #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
 }
@@ -71,7 +71,7 @@
     ;
 }
 class D extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
   constructor foo(core::num x) → self::D
     ;
   static factory bar(core::num? x) → self::D
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect
index 4b9d35a..5ca1bf7 100644
--- a/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect
@@ -62,7 +62,7 @@
   method hest(core::num value) → void {}
 }
 class C1 extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isLegacy*/;
   static factory •() → self::C1
     let dynamic #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
 }
@@ -72,7 +72,7 @@
     ;
 }
 class D extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
   constructor foo(core::num x) → self::D
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect
index eb84971..de6bd24 100644
--- a/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect
@@ -62,7 +62,7 @@
   method hest(core::num value) → void {}
 }
 class C1 extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isLegacy*/;
   static factory •() → self::C1
     let<BottomType> #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
 }
@@ -72,7 +72,7 @@
     ;
 }
 class D extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
   constructor foo(core::num x) → self::D
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect
index 4b9d35a..5ca1bf7 100644
--- a/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect
@@ -62,7 +62,7 @@
   method hest(core::num value) → void {}
 }
 class C1 extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isLegacy*/;
   static factory •() → self::C1
     let dynamic #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
 }
@@ -72,7 +72,7 @@
     ;
 }
 class D extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
   constructor foo(core::num x) → self::D
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect
index eb84971..de6bd24 100644
--- a/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect
@@ -62,7 +62,7 @@
   method hest(core::num value) → void {}
 }
 class C1 extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isLegacy*/;
   static factory •() → self::C1
     let<BottomType> #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
 }
@@ -72,7 +72,7 @@
     ;
 }
 class D extends core::Object {
-  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
   constructor foo(core::num x) → self::D
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.outline.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.outline.expect
index 6a9e27e..49eec30 100644
--- a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.outline.expect
@@ -10,27 +10,33 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void patchedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void _injectedMethod([int i]) {}
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void patchedMethod([int i]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void _injectedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void method([int i]) {}
 //                    ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void method([int i]) {}
 //                  ^
 //
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.expect
index 9762f48..2d71c44 100644
--- a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.expect
@@ -12,27 +12,33 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void patchedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void _injectedMethod([int i]) {}
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void patchedMethod([int i]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void _injectedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void method([int i]) {}
 //                    ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void method([int i]) {}
 //                  ^
 //
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.transformed.expect
index 9762f48..2d71c44 100644
--- a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.strong.transformed.expect
@@ -12,27 +12,33 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void patchedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void _injectedMethod([int i]) {}
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void patchedMethod([int i]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void _injectedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void method([int i]) {}
 //                    ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void method([int i]) {}
 //                  ^
 //
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.expect
index 9762f48..2d71c44 100644
--- a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.expect
@@ -12,27 +12,33 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void patchedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void _injectedMethod([int i]) {}
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void patchedMethod([int i]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void _injectedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void method([int i]) {}
 //                    ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void method([int i]) {}
 //                  ^
 //
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.transformed.expect
index 9762f48..2d71c44 100644
--- a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.weak.transformed.expect
@@ -12,27 +12,33 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:11:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void patchedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:13:29: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void _injectedMethod([int i]) {}
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:17:25: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void patchedMethod([int i]) {}
 //                         ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/patch_lib.dart:19:27: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void _injectedMethod([int i]) {}
 //                           ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:6:20: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void method([int i]) {}
 //                    ^
 //
-// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: Optional parameter 'i' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/platform_optional_parameters/origin_lib.dart:11:18: Error: The parameter 'i' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // void method([int i]) {}
 //                  ^
 //
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
index df25b02..c7750b7 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.outline.expect
@@ -64,29 +64,29 @@
 static field () → core::int topLevelExtensionFunctionTypeTearOff;
 static field dynamic topLevelExtensionFunctionGetter;
 static field void topLevelExtensionFunctionTypeGetter;
-static method Extension|+(final self::Class #this, core::int value) → core::int
+static method Extension|+(lowered final self::Class #this, core::int value) → core::int
   ;
-static method Extension|unary-(final self::Class #this) → core::int
+static method Extension|unary-(lowered final self::Class #this) → core::int
   ;
-static method Extension|[](final self::Class #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class #this, core::int index) → core::int
   ;
-static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void
+static method Extension|[]=(lowered final self::Class #this, core::int index, core::int value) → void
   ;
-static method Extension|call(final self::Class #this) → core::int
+static method Extension|call(lowered final self::Class #this) → core::int
   ;
-static method Extension|get#call(final self::Class #this) → () → core::int
+static method Extension|get#call(lowered final self::Class #this) → () → core::int
   return () → core::int => self::Extension|call(#this);
-static method Extension|get#extensionProperty(final self::Class #this) → core::int
+static method Extension|get#extensionProperty(lowered final self::Class #this) → core::int
   ;
-static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void
+static method Extension|set#extensionProperty(lowered final self::Class #this, core::int value) → void
   ;
-static method Extension|extensionMethod(final self::Class #this) → core::int
+static method Extension|extensionMethod(lowered final self::Class #this) → core::int
   ;
-static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → core::int
   return () → core::int => self::Extension|extensionMethod(#this);
-static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+static method Extension|get#extensionFunctionGetter(lowered final self::Class #this) → core::Function
   ;
-static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+static method Extension|get#extensionFunctionTypeGetter(lowered final self::Class #this) → () → void
   ;
 static get nullableFunction() → core::Function?
   ;
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
index c104f5c..aa9a084 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.expect
@@ -617,27 +617,27 @@
 Try calling using ?.call instead.
     nullableClass.extensionFunctionTypeGetter();
                   ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
-static method Extension|+(final self::Class #this, core::int value) → core::int
+static method Extension|+(lowered final self::Class #this, core::int value) → core::int
   return 0;
-static method Extension|unary-(final self::Class #this) → core::int
+static method Extension|unary-(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|[](final self::Class #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class #this, core::int index) → core::int
   return 0;
-static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void {}
-static method Extension|call(final self::Class #this) → core::int
+static method Extension|[]=(lowered final self::Class #this, core::int index, core::int value) → void {}
+static method Extension|call(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|get#call(final self::Class #this) → () → core::int
+static method Extension|get#call(lowered final self::Class #this) → () → core::int
   return () → core::int => self::Extension|call(#this);
-static method Extension|get#extensionProperty(final self::Class #this) → core::int
+static method Extension|get#extensionProperty(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void {}
-static method Extension|extensionMethod(final self::Class #this) → core::int
+static method Extension|set#extensionProperty(lowered final self::Class #this, core::int value) → void {}
+static method Extension|extensionMethod(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → core::int
   return () → core::int => self::Extension|extensionMethod(#this);
-static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+static method Extension|get#extensionFunctionGetter(lowered final self::Class #this) → core::Function
   return () → Null {};
-static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+static method Extension|get#extensionFunctionTypeGetter(lowered final self::Class #this) → () → void
   return () → void {};
 static get nullableFunction() → core::Function?
   return () → Null {};
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
index c104f5c..aa9a084 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.expect
@@ -617,27 +617,27 @@
 Try calling using ?.call instead.
     nullableClass.extensionFunctionTypeGetter();
                   ^" in self::Extension|get#extensionFunctionTypeGetter(self::nullableClass).call();
-static method Extension|+(final self::Class #this, core::int value) → core::int
+static method Extension|+(lowered final self::Class #this, core::int value) → core::int
   return 0;
-static method Extension|unary-(final self::Class #this) → core::int
+static method Extension|unary-(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|[](final self::Class #this, core::int index) → core::int
+static method Extension|[](lowered final self::Class #this, core::int index) → core::int
   return 0;
-static method Extension|[]=(final self::Class #this, core::int index, core::int value) → void {}
-static method Extension|call(final self::Class #this) → core::int
+static method Extension|[]=(lowered final self::Class #this, core::int index, core::int value) → void {}
+static method Extension|call(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|get#call(final self::Class #this) → () → core::int
+static method Extension|get#call(lowered final self::Class #this) → () → core::int
   return () → core::int => self::Extension|call(#this);
-static method Extension|get#extensionProperty(final self::Class #this) → core::int
+static method Extension|get#extensionProperty(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|set#extensionProperty(final self::Class #this, core::int value) → void {}
-static method Extension|extensionMethod(final self::Class #this) → core::int
+static method Extension|set#extensionProperty(lowered final self::Class #this, core::int value) → void {}
+static method Extension|extensionMethod(lowered final self::Class #this) → core::int
   return 0;
-static method Extension|get#extensionMethod(final self::Class #this) → () → core::int
+static method Extension|get#extensionMethod(lowered final self::Class #this) → () → core::int
   return () → core::int => self::Extension|extensionMethod(#this);
-static method Extension|get#extensionFunctionGetter(final self::Class #this) → core::Function
+static method Extension|get#extensionFunctionGetter(lowered final self::Class #this) → core::Function
   return () → Null {};
-static method Extension|get#extensionFunctionTypeGetter(final self::Class #this) → () → void
+static method Extension|get#extensionFunctionTypeGetter(lowered final self::Class #this) → () → void
   return () → void {};
 static get nullableFunction() → core::Function?
   return () → Null {};
diff --git a/pkg/front_end/testcases/nnbd/required.dart.outline.expect b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
index ff5e088..f5a1db6 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: The parameter 'x' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   foo({x}) {}
 //        ^
 //
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
index 55eb694..dfe4abf 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: The parameter 'x' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   foo({x}) {}
 //        ^
 //
@@ -21,7 +22,8 @@
 //   f2 = (int a = 42, [int b]) {};
 //               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g({int a, required int b = 42}) {}
 //               ^
 //
@@ -29,7 +31,8 @@
 //   void g({int a, required int b = 42}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f = ({int a, required int b = 42}) {};
 //             ^
 //
@@ -37,11 +40,13 @@
 //   f = ({int a, required int b = 42}) {};
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g2(int a = 42, [int b]) {}
 //                            ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f2 = (int a = 42, [int b]) {};
 //                          ^
 //
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
index 55eb694..dfe4abf 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: The parameter 'x' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   foo({x}) {}
 //        ^
 //
@@ -21,7 +22,8 @@
 //   f2 = (int a = 42, [int b]) {};
 //               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g({int a, required int b = 42}) {}
 //               ^
 //
@@ -29,7 +31,8 @@
 //   void g({int a, required int b = 42}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f = ({int a, required int b = 42}) {};
 //             ^
 //
@@ -37,11 +40,13 @@
 //   f = ({int a, required int b = 42}) {};
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g2(int a = 42, [int b]) {}
 //                            ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f2 = (int a = 42, [int b]) {};
 //                          ^
 //
diff --git a/pkg/front_end/testcases/nnbd/required.dart.weak.expect b/pkg/front_end/testcases/nnbd/required.dart.weak.expect
index 55eb694..dfe4abf 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.weak.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: The parameter 'x' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   foo({x}) {}
 //        ^
 //
@@ -21,7 +22,8 @@
 //   f2 = (int a = 42, [int b]) {};
 //               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g({int a, required int b = 42}) {}
 //               ^
 //
@@ -29,7 +31,8 @@
 //   void g({int a, required int b = 42}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f = ({int a, required int b = 42}) {};
 //             ^
 //
@@ -37,11 +40,13 @@
 //   f = ({int a, required int b = 42}) {};
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g2(int a = 42, [int b]) {}
 //                            ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f2 = (int a = 42, [int b]) {};
 //                          ^
 //
diff --git a/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect
index 55eb694..dfe4abf 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect
@@ -2,7 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: The parameter 'x' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   foo({x}) {}
 //        ^
 //
@@ -21,7 +22,8 @@
 //   f2 = (int a = 42, [int b]) {};
 //               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g({int a, required int b = 42}) {}
 //               ^
 //
@@ -29,7 +31,8 @@
 //   void g({int a, required int b = 42}) {}
 //                               ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f = ({int a, required int b = 42}) {};
 //             ^
 //
@@ -37,11 +40,13 @@
 //   f = ({int a, required int b = 42}) {};
 //                             ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   void g2(int a = 42, [int b]) {}
 //                            ^
 //
-// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: The parameter 'b' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   f2 = (int a = 42, [int b]) {};
 //                          ^
 //
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect
index 8dab663..4e786d8 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect
@@ -6,11 +6,13 @@
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo2({int parameter}) {}
 //           ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo3([int parameter]) {}
 //           ^^^^^^^^^
 //
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect
index 41566f3..0f14fea 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect
@@ -6,11 +6,13 @@
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo2({int parameter}) {}
 //           ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo3([int parameter]) {}
 //           ^^^^^^^^^
 //
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect
index 41566f3..0f14fea 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect
@@ -6,11 +6,13 @@
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo2({int parameter}) {}
 //           ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo3([int parameter]) {}
 //           ^^^^^^^^^
 //
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect
index 41566f3..0f14fea 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect
@@ -6,11 +6,13 @@
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo2({int parameter}) {}
 //           ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo3([int parameter]) {}
 //           ^^^^^^^^^
 //
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect
index 41566f3..0f14fea 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect
@@ -6,11 +6,13 @@
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo2({int parameter}) {}
 //           ^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: The parameter 'parameter' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 // foo3([int parameter]) {}
 //           ^^^^^^^^^
 //
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
index 8c64d78..b9094ae 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
@@ -13,7 +13,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -34,7 +33,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -45,7 +43,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -66,7 +63,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -77,7 +73,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -97,7 +92,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -108,7 +102,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -122,7 +115,6 @@
           final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
           core::bool* :is_sync = false;
           FutureOr<Null>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -142,7 +134,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -160,7 +151,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
index 8c64d78..b9094ae 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
@@ -13,7 +13,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -34,7 +33,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -45,7 +43,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -66,7 +63,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -77,7 +73,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -97,7 +92,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -108,7 +102,6 @@
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -122,7 +115,6 @@
           final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
           core::bool* :is_sync = false;
           FutureOr<Null>? :return_value;
-          dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
           (core::Object, core::StackTrace) → dynamic :async_op_error;
           core::int :await_jump_var = 0;
@@ -142,7 +134,6 @@
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -160,7 +151,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index 66eca58..dfdc501 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -97,7 +97,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -112,7 +111,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -123,7 +121,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -138,7 +135,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -149,7 +145,6 @@
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -169,7 +164,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -180,7 +174,6 @@
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -195,7 +188,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -206,7 +198,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -221,7 +212,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -232,7 +222,6 @@
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -250,7 +239,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -261,7 +249,6 @@
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -276,7 +263,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -298,7 +284,6 @@
 static method yieldAsync() → asy::Stream<dynamic> /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -316,7 +301,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -381,7 +365,6 @@
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -396,7 +379,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -407,7 +389,6 @@
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -422,7 +403,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -433,7 +413,6 @@
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -453,7 +432,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -464,7 +442,6 @@
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -479,7 +456,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -490,7 +466,6 @@
     final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
     core::bool* :is_sync = false;
     FutureOr<Null>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -505,7 +480,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -516,7 +490,6 @@
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -534,7 +507,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -545,7 +517,6 @@
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -560,7 +531,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -582,7 +552,6 @@
   function yieldAsync() → asy::Stream<dynamic> /* originally async* */ {
     asy::_AsyncStarStreamController<dynamic>? :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -600,7 +569,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -674,4 +642,4 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///return_null.dart:75:14 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:75:14 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:75:14 -> NullConstant(null)
-Extra constant evaluation: evaluated: 442, effectively constant: 12
+Extra constant evaluation: evaluated: 394, effectively constant: 12
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index 4b3b79c..0c0ae45 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -98,7 +98,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -113,7 +112,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -124,7 +122,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -139,7 +136,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -150,7 +146,6 @@
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -170,7 +165,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -181,7 +175,6 @@
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -196,7 +189,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -207,7 +199,6 @@
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -222,7 +213,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -233,7 +223,6 @@
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -251,7 +240,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -262,7 +250,6 @@
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -277,7 +264,6 @@
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -299,7 +285,6 @@
 static method yieldAsync() → asy::Stream<dynamic> /* originally async* */ {
   asy::_AsyncStarStreamController<dynamic>? :controller;
   dynamic :controller_stream;
-  dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
   (core::Object, core::StackTrace) → dynamic :async_op_error;
   core::int :await_jump_var = 0;
@@ -317,7 +302,6 @@
     finally {
       :controller.{asy::_AsyncStarStreamController::close}();
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -385,7 +369,6 @@
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -400,7 +383,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -411,7 +393,6 @@
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -426,7 +407,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -437,7 +417,6 @@
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -457,7 +436,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -468,7 +446,6 @@
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -483,7 +460,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -494,7 +470,6 @@
     final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
     core::bool* :is_sync = false;
     FutureOr<Null>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -509,7 +484,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -520,7 +494,6 @@
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -538,7 +511,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -549,7 +521,6 @@
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -564,7 +535,6 @@
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :async_op.call();
@@ -586,7 +556,6 @@
   function yieldAsync() → asy::Stream<dynamic> /* originally async* */ {
     asy::_AsyncStarStreamController<dynamic>? :controller;
     dynamic :controller_stream;
-    dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
     (core::Object, core::StackTrace) → dynamic :async_op_error;
     core::int :await_jump_var = 0;
@@ -604,7 +573,6 @@
       finally {
         :controller.{asy::_AsyncStarStreamController::close}();
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
diff --git a/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.expect
index ffceca9..df571c2 100644
--- a/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.expect
@@ -6,155 +6,137 @@
 static method main() → dynamic {
   core::List<core::int>? list = null;
   core::print( block {
-    final core::List<core::int> #t1 = <core::int>[];
-    #t1.{core::List::add}{Invariant}(1);
-    #t1.{core::List::add}{Invariant}(2);
+    final core::List<core::int> #t1 = <core::int>[1, 2];
     final core::Iterable<core::int>? #t2 = list;
     if(!#t2.{core::Object::==}(null))
-      for (final core::int #t3 in #t2{core::Iterable<core::int>})
-        #t1.{core::List::add}{Invariant}(#t3);
+      #t1.{core::List::addAll}{Invariant}(#t2{core::Iterable<core::int>});
     #t1.{core::List::add}{Invariant}(3);
   } =>#t1);
   core::print( block {
-    final core::List<core::int> #t4 = <core::int>[];
-    #t4.{core::List::add}{Invariant}(1);
-    #t4.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t5 = null;
-    if(!#t5.{core::Object::==}(null))
-      for (final core::int #t6 in #t5{core::Iterable<core::int>})
-        #t4.{core::List::add}{Invariant}(#t6);
-    #t4.{core::List::add}{Invariant}(3);
-  } =>#t4);
+    final core::List<core::int> #t3 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t4 = null;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::List::addAll}{Invariant}(#t4{core::Iterable<core::int>});
+    #t3.{core::List::add}{Invariant}(3);
+  } =>#t3);
   core::List<core::int> list1 = block {
-    final core::List<core::int> #t7 = <core::int>[];
-    final core::Iterable<core::int>? #t8 = list;
-    if(!#t8.{core::Object::==}(null))
-      for (final core::int #t9 in #t8{core::Iterable<core::int>})
-        #t7.{core::List::add}{Invariant}(#t9);
-  } =>#t7;
+    final core::List<core::int> #t5 = <core::int>[];
+    final core::Iterable<core::int>? #t6 = list;
+    if(!#t6.{core::Object::==}(null))
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::int>});
+  } =>#t5;
   core::List<Never> list2 = block {
-    final core::List<Never> #t10 = <Never>[];
-    final core::Iterable<Never>? #t11 = null;
-    if(!#t11.{core::Object::==}(null))
-      for (final Never #t12 in #t11{core::Iterable<Never>})
-        #t10.{core::List::add}{Invariant}(#t12);
-  } =>#t10;
+    final core::List<Never> #t7 = <Never>[];
+    final core::Iterable<Never>? #t8 = null;
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::List::addAll}{Invariant}(#t8{core::Iterable<Never>});
+  } =>#t7;
   core::List<core::int> list3 = block {
-    final core::List<core::int> #t13 = <core::int>[];
-    #t13.{core::List::add}{Invariant}(1);
-    #t13.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t14 = list;
-    if(!#t14.{core::Object::==}(null))
-      for (final core::int #t15 in #t14{core::Iterable<core::int>})
-        #t13.{core::List::add}{Invariant}(#t15);
-    #t13.{core::List::add}{Invariant}(3);
-  } =>#t13;
+    final core::List<core::int> #t9 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t10 = list;
+    if(!#t10.{core::Object::==}(null))
+      #t9.{core::List::addAll}{Invariant}(#t10{core::Iterable<core::int>});
+    #t9.{core::List::add}{Invariant}(3);
+  } =>#t9;
   core::List<core::int> list4 = block {
-    final core::List<core::int> #t16 = <core::int>[];
-    #t16.{core::List::add}{Invariant}(1);
-    #t16.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t17 = null;
-    if(!#t17.{core::Object::==}(null))
-      for (final core::int #t18 in #t17{core::Iterable<core::int>})
-        #t16.{core::List::add}{Invariant}(#t18);
-    #t16.{core::List::add}{Invariant}(3);
-  } =>#t16;
+    final core::List<core::int> #t11 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t12 = null;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::List::addAll}{Invariant}(#t12{core::Iterable<core::int>});
+    #t11.{core::List::add}{Invariant}(3);
+  } =>#t11;
   core::Set<core::int>? set = null;
   core::print( block {
-    final core::Set<core::int> #t19 = col::LinkedHashSet::•<core::int>();
-    #t19.{core::Set::add}{Invariant}(1);
-    #t19.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t20 = set;
-    if(!#t20.{core::Object::==}(null))
-      for (final core::int #t21 in #t20{core::Iterable<core::int>})
-        #t19.{core::Set::add}{Invariant}(#t21);
-    #t19.{core::Set::add}{Invariant}(3);
-  } =>#t19);
+    final core::Set<core::int> #t13 = col::LinkedHashSet::•<core::int>();
+    #t13.{core::Set::add}{Invariant}(1);
+    #t13.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t14 = set;
+    if(!#t14.{core::Object::==}(null))
+      #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<core::int>});
+    #t13.{core::Set::add}{Invariant}(3);
+  } =>#t13);
   core::print( block {
-    final core::Set<core::int> #t22 = col::LinkedHashSet::•<core::int>();
-    #t22.{core::Set::add}{Invariant}(1);
-    #t22.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t23 = null;
-    if(!#t23.{core::Object::==}(null))
-      for (final core::int #t24 in #t23{core::Iterable<core::int>})
-        #t22.{core::Set::add}{Invariant}(#t24);
-    #t22.{core::Set::add}{Invariant}(3);
-  } =>#t22);
+    final core::Set<core::int> #t15 = col::LinkedHashSet::•<core::int>();
+    #t15.{core::Set::add}{Invariant}(1);
+    #t15.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t16 = null;
+    if(!#t16.{core::Object::==}(null))
+      #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<core::int>});
+    #t15.{core::Set::add}{Invariant}(3);
+  } =>#t15);
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t25 = col::LinkedHashSet::•<core::int>();
-    final core::Iterable<dynamic>? #t26 = set;
-    if(!#t26.{core::Object::==}(null))
-      for (final dynamic #t27 in #t26{core::Iterable<dynamic>}) {
-        final core::int #t28 = #t27 as{TypeError,ForNonNullableByDefault} core::int;
-        #t25.{core::Set::add}{Invariant}(#t28);
+    final core::Set<core::int> #t17 = col::LinkedHashSet::•<core::int>();
+    final core::Iterable<dynamic>? #t18 = set;
+    if(!#t18.{core::Object::==}(null))
+      for (final dynamic #t19 in #t18{core::Iterable<dynamic>}) {
+        final core::int #t20 = #t19 as{TypeError,ForNonNullableByDefault} core::int;
+        #t17.{core::Set::add}{Invariant}(#t20);
       }
-  } =>#t25;
+  } =>#t17;
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t29 = col::LinkedHashSet::•<core::int>();
-    #t29.{core::Set::add}{Invariant}(1);
-    #t29.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t30 = set;
-    if(!#t30.{core::Object::==}(null))
-      for (final core::int #t31 in #t30{core::Iterable<core::int>})
-        #t29.{core::Set::add}{Invariant}(#t31);
-    #t29.{core::Set::add}{Invariant}(3);
-  } =>#t29;
+    final core::Set<core::int> #t21 = col::LinkedHashSet::•<core::int>();
+    #t21.{core::Set::add}{Invariant}(1);
+    #t21.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t22 = set;
+    if(!#t22.{core::Object::==}(null))
+      #t21.{core::Set::addAll}{Invariant}(#t22{core::Iterable<core::int>});
+    #t21.{core::Set::add}{Invariant}(3);
+  } =>#t21;
   core::Set<core::int> set4 = block {
-    final core::Set<core::int> #t32 = col::LinkedHashSet::•<core::int>();
-    #t32.{core::Set::add}{Invariant}(1);
-    #t32.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t33 = null;
-    if(!#t33.{core::Object::==}(null))
-      for (final core::int #t34 in #t33{core::Iterable<core::int>})
-        #t32.{core::Set::add}{Invariant}(#t34);
-    #t32.{core::Set::add}{Invariant}(3);
-  } =>#t32;
+    final core::Set<core::int> #t23 = col::LinkedHashSet::•<core::int>();
+    #t23.{core::Set::add}{Invariant}(1);
+    #t23.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t24 = null;
+    if(!#t24.{core::Object::==}(null))
+      #t23.{core::Set::addAll}{Invariant}(#t24{core::Iterable<core::int>});
+    #t23.{core::Set::add}{Invariant}(3);
+  } =>#t23;
   core::Map<core::int, core::int>? map = null;
   core::print( block {
-    final core::Map<core::int, core::int> #t35 = <core::int, core::int>{};
-    #t35.{core::Map::[]=}{Invariant}(1, 1);
-    #t35.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t36 = map;
-    if(!#t36.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t37 in #t36{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t35.{core::Map::[]=}{Invariant}(#t37.{core::MapEntry::key}, #t37.{core::MapEntry::value});
-    #t35.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t35);
+    final core::Map<core::int, core::int> #t25 = <core::int, core::int>{};
+    #t25.{core::Map::[]=}{Invariant}(1, 1);
+    #t25.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t26 = map;
+    if(!#t26.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t27 in #t26{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t25.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
+    #t25.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t25);
   core::print( block {
-    final core::Map<core::int, core::int> #t38 = <core::int, core::int>{};
-    #t38.{core::Map::[]=}{Invariant}(1, 1);
-    #t38.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t39 = null;
-    if(!#t39.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t40 in #t39{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t38.{core::Map::[]=}{Invariant}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value});
-    #t38.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t38);
+    final core::Map<core::int, core::int> #t28 = <core::int, core::int>{};
+    #t28.{core::Map::[]=}{Invariant}(1, 1);
+    #t28.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t29 = null;
+    if(!#t29.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t30 in #t29{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t28.{core::Map::[]=}{Invariant}(#t30.{core::MapEntry::key}, #t30.{core::MapEntry::value});
+    #t28.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t28);
   core::Map<core::int, core::int> map1 = block {
-    final core::Map<core::int, core::int> #t41 = <core::int, core::int>{};
-    final core::Map<core::int, core::int>? #t42 = map;
-    if(!#t42.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t43 in #t42{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t41.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-  } =>#t41;
+    final core::Map<core::int, core::int> #t31 = <core::int, core::int>{};
+    final core::Map<core::int, core::int>? #t32 = map;
+    if(!#t32.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t33 in #t32{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t31.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
+  } =>#t31;
   core::Map<core::int, core::int> map3 = block {
-    final core::Map<core::int, core::int> #t44 = <core::int, core::int>{};
-    #t44.{core::Map::[]=}{Invariant}(1, 1);
-    #t44.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t45 = map;
-    if(!#t45.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t46 in #t45{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t44.{core::Map::[]=}{Invariant}(#t46.{core::MapEntry::key}, #t46.{core::MapEntry::value});
-    #t44.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t44;
+    final core::Map<core::int, core::int> #t34 = <core::int, core::int>{};
+    #t34.{core::Map::[]=}{Invariant}(1, 1);
+    #t34.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t35 = map;
+    if(!#t35.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t36 in #t35{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t34.{core::Map::[]=}{Invariant}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value});
+    #t34.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t34;
   core::Map<core::int, core::int> map4 = block {
-    final core::Map<core::int, core::int> #t47 = <core::int, core::int>{};
-    #t47.{core::Map::[]=}{Invariant}(1, 1);
-    #t47.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t48 = null;
-    if(!#t48.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t49 in #t48{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t47.{core::Map::[]=}{Invariant}(#t49.{core::MapEntry::key}, #t49.{core::MapEntry::value});
-    #t47.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t47;
+    final core::Map<core::int, core::int> #t37 = <core::int, core::int>{};
+    #t37.{core::Map::[]=}{Invariant}(1, 1);
+    #t37.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t38 = null;
+    if(!#t38.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t39 in #t38{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t37.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
+    #t37.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t37;
 }
diff --git a/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect
index ba1a66c..a75a6aa 100644
--- a/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect
@@ -6,220 +6,162 @@
 static method main() → dynamic {
   core::List<core::int>? list = null;
   core::print( block {
-    final core::List<core::int> #t1 = <core::int>[];
-    #t1.{core::List::add}{Invariant}(1);
-    #t1.{core::List::add}{Invariant}(2);
+    final core::List<core::int> #t1 = <core::int>[1, 2];
     final core::Iterable<core::int>? #t2 = list;
-    if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t2{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t3 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t3);
-      }
-    }
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2{core::Iterable<core::int>});
     #t1.{core::List::add}{Invariant}(3);
   } =>#t1);
   core::print( block {
-    final core::List<core::int> #t4 = <core::int>[];
-    #t4.{core::List::add}{Invariant}(1);
-    #t4.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t5 = null;
-    if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t5{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t6 = :sync-for-iterator.{core::Iterator::current};
-        #t4.{core::List::add}{Invariant}(#t6);
-      }
-    }
-    #t4.{core::List::add}{Invariant}(3);
-  } =>#t4);
+    final core::List<core::int> #t3 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t4 = null;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::List::addAll}{Invariant}(#t4{core::Iterable<core::int>});
+    #t3.{core::List::add}{Invariant}(3);
+  } =>#t3);
   core::List<core::int> list1 = block {
-    final core::List<core::int> #t7 = <core::int>[];
-    final core::Iterable<core::int>? #t8 = list;
-    if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t8{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t9 = :sync-for-iterator.{core::Iterator::current};
-        #t7.{core::List::add}{Invariant}(#t9);
-      }
-    }
-  } =>#t7;
+    final core::List<core::int> #t5 = <core::int>[];
+    final core::Iterable<core::int>? #t6 = list;
+    if(!#t6.{core::Object::==}(null))
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::int>});
+  } =>#t5;
   core::List<Never> list2 = block {
-    final core::List<Never> #t10 = <Never>[];
-    final core::Iterable<Never>? #t11 = null;
-    if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t11{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::List::add}{Invariant}(#t12);
-      }
-    }
-  } =>#t10;
+    final core::List<Never> #t7 = <Never>[];
+    final core::Iterable<Never>? #t8 = null;
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::List::addAll}{Invariant}(#t8{core::Iterable<Never>});
+  } =>#t7;
   core::List<core::int> list3 = block {
-    final core::List<core::int> #t13 = <core::int>[];
-    #t13.{core::List::add}{Invariant}(1);
-    #t13.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t14 = list;
-    if(!#t14.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t14{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t15 = :sync-for-iterator.{core::Iterator::current};
-        #t13.{core::List::add}{Invariant}(#t15);
-      }
-    }
-    #t13.{core::List::add}{Invariant}(3);
-  } =>#t13;
+    final core::List<core::int> #t9 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t10 = list;
+    if(!#t10.{core::Object::==}(null))
+      #t9.{core::List::addAll}{Invariant}(#t10{core::Iterable<core::int>});
+    #t9.{core::List::add}{Invariant}(3);
+  } =>#t9;
   core::List<core::int> list4 = block {
-    final core::List<core::int> #t16 = <core::int>[];
-    #t16.{core::List::add}{Invariant}(1);
-    #t16.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t17 = null;
-    if(!#t17.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t17{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t18 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::List::add}{Invariant}(#t18);
-      }
-    }
-    #t16.{core::List::add}{Invariant}(3);
-  } =>#t16;
+    final core::List<core::int> #t11 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t12 = null;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::List::addAll}{Invariant}(#t12{core::Iterable<core::int>});
+    #t11.{core::List::add}{Invariant}(3);
+  } =>#t11;
   core::Set<core::int>? set = null;
   core::print( block {
-    final core::Set<core::int> #t19 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t19.{core::Set::add}{Invariant}(1);
-    #t19.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t20 = set;
-    if(!#t20.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t20{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t21 = :sync-for-iterator.{core::Iterator::current};
-        #t19.{core::Set::add}{Invariant}(#t21);
-      }
-    }
-    #t19.{core::Set::add}{Invariant}(3);
-  } =>#t19);
+    final core::Set<core::int> #t13 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t13.{core::Set::add}{Invariant}(1);
+    #t13.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t14 = set;
+    if(!#t14.{core::Object::==}(null))
+      #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<core::int>});
+    #t13.{core::Set::add}{Invariant}(3);
+  } =>#t13);
   core::print( block {
-    final core::Set<core::int> #t22 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t22.{core::Set::add}{Invariant}(1);
-    #t22.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t23 = null;
-    if(!#t23.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t23{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t24 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::Set::add}{Invariant}(#t24);
-      }
-    }
-    #t22.{core::Set::add}{Invariant}(3);
-  } =>#t22);
+    final core::Set<core::int> #t15 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t15.{core::Set::add}{Invariant}(1);
+    #t15.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t16 = null;
+    if(!#t16.{core::Object::==}(null))
+      #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<core::int>});
+    #t15.{core::Set::add}{Invariant}(3);
+  } =>#t15);
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t25 = new col::_CompactLinkedHashSet::•<core::int>();
-    final core::Iterable<dynamic>? #t26 = set;
-    if(!#t26.{core::Object::==}(null)) {
-      core::Iterator<dynamic> :sync-for-iterator = #t26{core::Iterable<dynamic>}.{core::Iterable::iterator};
+    final core::Set<core::int> #t17 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Iterable<dynamic>? #t18 = set;
+    if(!#t18.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t18{core::Iterable<dynamic>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t27 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int #t28 = #t27 as{TypeError,ForNonNullableByDefault} core::int;
-          #t25.{core::Set::add}{Invariant}(#t28);
+          final core::int #t20 = #t19 as{TypeError,ForNonNullableByDefault} core::int;
+          #t17.{core::Set::add}{Invariant}(#t20);
         }
       }
     }
-  } =>#t25;
+  } =>#t17;
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t29 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t29.{core::Set::add}{Invariant}(1);
-    #t29.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t30 = set;
-    if(!#t30.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t30{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t31 = :sync-for-iterator.{core::Iterator::current};
-        #t29.{core::Set::add}{Invariant}(#t31);
-      }
-    }
-    #t29.{core::Set::add}{Invariant}(3);
-  } =>#t29;
+    final core::Set<core::int> #t21 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t21.{core::Set::add}{Invariant}(1);
+    #t21.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t22 = set;
+    if(!#t22.{core::Object::==}(null))
+      #t21.{core::Set::addAll}{Invariant}(#t22{core::Iterable<core::int>});
+    #t21.{core::Set::add}{Invariant}(3);
+  } =>#t21;
   core::Set<core::int> set4 = block {
-    final core::Set<core::int> #t32 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t32.{core::Set::add}{Invariant}(1);
-    #t32.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t33 = null;
-    if(!#t33.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t33{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t34 = :sync-for-iterator.{core::Iterator::current};
-        #t32.{core::Set::add}{Invariant}(#t34);
-      }
-    }
-    #t32.{core::Set::add}{Invariant}(3);
-  } =>#t32;
+    final core::Set<core::int> #t23 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t23.{core::Set::add}{Invariant}(1);
+    #t23.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t24 = null;
+    if(!#t24.{core::Object::==}(null))
+      #t23.{core::Set::addAll}{Invariant}(#t24{core::Iterable<core::int>});
+    #t23.{core::Set::add}{Invariant}(3);
+  } =>#t23;
   core::Map<core::int, core::int>? map = null;
   core::print( block {
-    final core::Map<core::int, core::int> #t35 = <core::int, core::int>{};
-    #t35.{core::Map::[]=}{Invariant}(1, 1);
-    #t35.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t36 = map;
-    if(!#t36.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t36{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t25 = <core::int, core::int>{};
+    #t25.{core::Map::[]=}{Invariant}(1, 1);
+    #t25.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t26 = map;
+    if(!#t26.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t26{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t37 = :sync-for-iterator.{core::Iterator::current};
-        #t35.{core::Map::[]=}{Invariant}(#t37.{core::MapEntry::key}, #t37.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t27 = :sync-for-iterator.{core::Iterator::current};
+        #t25.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
       }
     }
-    #t35.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t35);
+    #t25.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t25);
   core::print( block {
-    final core::Map<core::int, core::int> #t38 = <core::int, core::int>{};
-    #t38.{core::Map::[]=}{Invariant}(1, 1);
-    #t38.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t39 = null;
-    if(!#t39.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t39{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t28 = <core::int, core::int>{};
+    #t28.{core::Map::[]=}{Invariant}(1, 1);
+    #t28.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t29 = null;
+    if(!#t29.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t29{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t40 = :sync-for-iterator.{core::Iterator::current};
-        #t38.{core::Map::[]=}{Invariant}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t30 = :sync-for-iterator.{core::Iterator::current};
+        #t28.{core::Map::[]=}{Invariant}(#t30.{core::MapEntry::key}, #t30.{core::MapEntry::value});
       }
     }
-    #t38.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t38);
+    #t28.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t28);
   core::Map<core::int, core::int> map1 = block {
-    final core::Map<core::int, core::int> #t41 = <core::int, core::int>{};
-    final core::Map<core::int, core::int>? #t42 = map;
-    if(!#t42.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t42{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t31 = <core::int, core::int>{};
+    final core::Map<core::int, core::int>? #t32 = map;
+    if(!#t32.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t32{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t43 = :sync-for-iterator.{core::Iterator::current};
-        #t41.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t33 = :sync-for-iterator.{core::Iterator::current};
+        #t31.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
       }
     }
-  } =>#t41;
+  } =>#t31;
   core::Map<core::int, core::int> map3 = block {
-    final core::Map<core::int, core::int> #t44 = <core::int, core::int>{};
-    #t44.{core::Map::[]=}{Invariant}(1, 1);
-    #t44.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t45 = map;
-    if(!#t45.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t45{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t34 = <core::int, core::int>{};
+    #t34.{core::Map::[]=}{Invariant}(1, 1);
+    #t34.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t35 = map;
+    if(!#t35.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t35{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t46 = :sync-for-iterator.{core::Iterator::current};
-        #t44.{core::Map::[]=}{Invariant}(#t46.{core::MapEntry::key}, #t46.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t36 = :sync-for-iterator.{core::Iterator::current};
+        #t34.{core::Map::[]=}{Invariant}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value});
       }
     }
-    #t44.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t44;
+    #t34.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t34;
   core::Map<core::int, core::int> map4 = block {
-    final core::Map<core::int, core::int> #t47 = <core::int, core::int>{};
-    #t47.{core::Map::[]=}{Invariant}(1, 1);
-    #t47.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t48 = null;
-    if(!#t48.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t48{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t37 = <core::int, core::int>{};
+    #t37.{core::Map::[]=}{Invariant}(1, 1);
+    #t37.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t38 = null;
+    if(!#t38.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t38{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t49 = :sync-for-iterator.{core::Iterator::current};
-        #t47.{core::Map::[]=}{Invariant}(#t49.{core::MapEntry::key}, #t49.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t39 = :sync-for-iterator.{core::Iterator::current};
+        #t37.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
       }
     }
-    #t47.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t47;
+    #t37.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t37;
 }
diff --git a/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.expect
index ffceca9..df571c2 100644
--- a/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.expect
@@ -6,155 +6,137 @@
 static method main() → dynamic {
   core::List<core::int>? list = null;
   core::print( block {
-    final core::List<core::int> #t1 = <core::int>[];
-    #t1.{core::List::add}{Invariant}(1);
-    #t1.{core::List::add}{Invariant}(2);
+    final core::List<core::int> #t1 = <core::int>[1, 2];
     final core::Iterable<core::int>? #t2 = list;
     if(!#t2.{core::Object::==}(null))
-      for (final core::int #t3 in #t2{core::Iterable<core::int>})
-        #t1.{core::List::add}{Invariant}(#t3);
+      #t1.{core::List::addAll}{Invariant}(#t2{core::Iterable<core::int>});
     #t1.{core::List::add}{Invariant}(3);
   } =>#t1);
   core::print( block {
-    final core::List<core::int> #t4 = <core::int>[];
-    #t4.{core::List::add}{Invariant}(1);
-    #t4.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t5 = null;
-    if(!#t5.{core::Object::==}(null))
-      for (final core::int #t6 in #t5{core::Iterable<core::int>})
-        #t4.{core::List::add}{Invariant}(#t6);
-    #t4.{core::List::add}{Invariant}(3);
-  } =>#t4);
+    final core::List<core::int> #t3 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t4 = null;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::List::addAll}{Invariant}(#t4{core::Iterable<core::int>});
+    #t3.{core::List::add}{Invariant}(3);
+  } =>#t3);
   core::List<core::int> list1 = block {
-    final core::List<core::int> #t7 = <core::int>[];
-    final core::Iterable<core::int>? #t8 = list;
-    if(!#t8.{core::Object::==}(null))
-      for (final core::int #t9 in #t8{core::Iterable<core::int>})
-        #t7.{core::List::add}{Invariant}(#t9);
-  } =>#t7;
+    final core::List<core::int> #t5 = <core::int>[];
+    final core::Iterable<core::int>? #t6 = list;
+    if(!#t6.{core::Object::==}(null))
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::int>});
+  } =>#t5;
   core::List<Never> list2 = block {
-    final core::List<Never> #t10 = <Never>[];
-    final core::Iterable<Never>? #t11 = null;
-    if(!#t11.{core::Object::==}(null))
-      for (final Never #t12 in #t11{core::Iterable<Never>})
-        #t10.{core::List::add}{Invariant}(#t12);
-  } =>#t10;
+    final core::List<Never> #t7 = <Never>[];
+    final core::Iterable<Never>? #t8 = null;
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::List::addAll}{Invariant}(#t8{core::Iterable<Never>});
+  } =>#t7;
   core::List<core::int> list3 = block {
-    final core::List<core::int> #t13 = <core::int>[];
-    #t13.{core::List::add}{Invariant}(1);
-    #t13.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t14 = list;
-    if(!#t14.{core::Object::==}(null))
-      for (final core::int #t15 in #t14{core::Iterable<core::int>})
-        #t13.{core::List::add}{Invariant}(#t15);
-    #t13.{core::List::add}{Invariant}(3);
-  } =>#t13;
+    final core::List<core::int> #t9 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t10 = list;
+    if(!#t10.{core::Object::==}(null))
+      #t9.{core::List::addAll}{Invariant}(#t10{core::Iterable<core::int>});
+    #t9.{core::List::add}{Invariant}(3);
+  } =>#t9;
   core::List<core::int> list4 = block {
-    final core::List<core::int> #t16 = <core::int>[];
-    #t16.{core::List::add}{Invariant}(1);
-    #t16.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t17 = null;
-    if(!#t17.{core::Object::==}(null))
-      for (final core::int #t18 in #t17{core::Iterable<core::int>})
-        #t16.{core::List::add}{Invariant}(#t18);
-    #t16.{core::List::add}{Invariant}(3);
-  } =>#t16;
+    final core::List<core::int> #t11 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t12 = null;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::List::addAll}{Invariant}(#t12{core::Iterable<core::int>});
+    #t11.{core::List::add}{Invariant}(3);
+  } =>#t11;
   core::Set<core::int>? set = null;
   core::print( block {
-    final core::Set<core::int> #t19 = col::LinkedHashSet::•<core::int>();
-    #t19.{core::Set::add}{Invariant}(1);
-    #t19.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t20 = set;
-    if(!#t20.{core::Object::==}(null))
-      for (final core::int #t21 in #t20{core::Iterable<core::int>})
-        #t19.{core::Set::add}{Invariant}(#t21);
-    #t19.{core::Set::add}{Invariant}(3);
-  } =>#t19);
+    final core::Set<core::int> #t13 = col::LinkedHashSet::•<core::int>();
+    #t13.{core::Set::add}{Invariant}(1);
+    #t13.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t14 = set;
+    if(!#t14.{core::Object::==}(null))
+      #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<core::int>});
+    #t13.{core::Set::add}{Invariant}(3);
+  } =>#t13);
   core::print( block {
-    final core::Set<core::int> #t22 = col::LinkedHashSet::•<core::int>();
-    #t22.{core::Set::add}{Invariant}(1);
-    #t22.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t23 = null;
-    if(!#t23.{core::Object::==}(null))
-      for (final core::int #t24 in #t23{core::Iterable<core::int>})
-        #t22.{core::Set::add}{Invariant}(#t24);
-    #t22.{core::Set::add}{Invariant}(3);
-  } =>#t22);
+    final core::Set<core::int> #t15 = col::LinkedHashSet::•<core::int>();
+    #t15.{core::Set::add}{Invariant}(1);
+    #t15.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t16 = null;
+    if(!#t16.{core::Object::==}(null))
+      #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<core::int>});
+    #t15.{core::Set::add}{Invariant}(3);
+  } =>#t15);
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t25 = col::LinkedHashSet::•<core::int>();
-    final core::Iterable<dynamic>? #t26 = set;
-    if(!#t26.{core::Object::==}(null))
-      for (final dynamic #t27 in #t26{core::Iterable<dynamic>}) {
-        final core::int #t28 = #t27 as{TypeError,ForNonNullableByDefault} core::int;
-        #t25.{core::Set::add}{Invariant}(#t28);
+    final core::Set<core::int> #t17 = col::LinkedHashSet::•<core::int>();
+    final core::Iterable<dynamic>? #t18 = set;
+    if(!#t18.{core::Object::==}(null))
+      for (final dynamic #t19 in #t18{core::Iterable<dynamic>}) {
+        final core::int #t20 = #t19 as{TypeError,ForNonNullableByDefault} core::int;
+        #t17.{core::Set::add}{Invariant}(#t20);
       }
-  } =>#t25;
+  } =>#t17;
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t29 = col::LinkedHashSet::•<core::int>();
-    #t29.{core::Set::add}{Invariant}(1);
-    #t29.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t30 = set;
-    if(!#t30.{core::Object::==}(null))
-      for (final core::int #t31 in #t30{core::Iterable<core::int>})
-        #t29.{core::Set::add}{Invariant}(#t31);
-    #t29.{core::Set::add}{Invariant}(3);
-  } =>#t29;
+    final core::Set<core::int> #t21 = col::LinkedHashSet::•<core::int>();
+    #t21.{core::Set::add}{Invariant}(1);
+    #t21.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t22 = set;
+    if(!#t22.{core::Object::==}(null))
+      #t21.{core::Set::addAll}{Invariant}(#t22{core::Iterable<core::int>});
+    #t21.{core::Set::add}{Invariant}(3);
+  } =>#t21;
   core::Set<core::int> set4 = block {
-    final core::Set<core::int> #t32 = col::LinkedHashSet::•<core::int>();
-    #t32.{core::Set::add}{Invariant}(1);
-    #t32.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t33 = null;
-    if(!#t33.{core::Object::==}(null))
-      for (final core::int #t34 in #t33{core::Iterable<core::int>})
-        #t32.{core::Set::add}{Invariant}(#t34);
-    #t32.{core::Set::add}{Invariant}(3);
-  } =>#t32;
+    final core::Set<core::int> #t23 = col::LinkedHashSet::•<core::int>();
+    #t23.{core::Set::add}{Invariant}(1);
+    #t23.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t24 = null;
+    if(!#t24.{core::Object::==}(null))
+      #t23.{core::Set::addAll}{Invariant}(#t24{core::Iterable<core::int>});
+    #t23.{core::Set::add}{Invariant}(3);
+  } =>#t23;
   core::Map<core::int, core::int>? map = null;
   core::print( block {
-    final core::Map<core::int, core::int> #t35 = <core::int, core::int>{};
-    #t35.{core::Map::[]=}{Invariant}(1, 1);
-    #t35.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t36 = map;
-    if(!#t36.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t37 in #t36{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t35.{core::Map::[]=}{Invariant}(#t37.{core::MapEntry::key}, #t37.{core::MapEntry::value});
-    #t35.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t35);
+    final core::Map<core::int, core::int> #t25 = <core::int, core::int>{};
+    #t25.{core::Map::[]=}{Invariant}(1, 1);
+    #t25.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t26 = map;
+    if(!#t26.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t27 in #t26{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t25.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
+    #t25.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t25);
   core::print( block {
-    final core::Map<core::int, core::int> #t38 = <core::int, core::int>{};
-    #t38.{core::Map::[]=}{Invariant}(1, 1);
-    #t38.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t39 = null;
-    if(!#t39.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t40 in #t39{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t38.{core::Map::[]=}{Invariant}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value});
-    #t38.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t38);
+    final core::Map<core::int, core::int> #t28 = <core::int, core::int>{};
+    #t28.{core::Map::[]=}{Invariant}(1, 1);
+    #t28.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t29 = null;
+    if(!#t29.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t30 in #t29{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t28.{core::Map::[]=}{Invariant}(#t30.{core::MapEntry::key}, #t30.{core::MapEntry::value});
+    #t28.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t28);
   core::Map<core::int, core::int> map1 = block {
-    final core::Map<core::int, core::int> #t41 = <core::int, core::int>{};
-    final core::Map<core::int, core::int>? #t42 = map;
-    if(!#t42.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t43 in #t42{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t41.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
-  } =>#t41;
+    final core::Map<core::int, core::int> #t31 = <core::int, core::int>{};
+    final core::Map<core::int, core::int>? #t32 = map;
+    if(!#t32.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t33 in #t32{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t31.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
+  } =>#t31;
   core::Map<core::int, core::int> map3 = block {
-    final core::Map<core::int, core::int> #t44 = <core::int, core::int>{};
-    #t44.{core::Map::[]=}{Invariant}(1, 1);
-    #t44.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t45 = map;
-    if(!#t45.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t46 in #t45{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t44.{core::Map::[]=}{Invariant}(#t46.{core::MapEntry::key}, #t46.{core::MapEntry::value});
-    #t44.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t44;
+    final core::Map<core::int, core::int> #t34 = <core::int, core::int>{};
+    #t34.{core::Map::[]=}{Invariant}(1, 1);
+    #t34.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t35 = map;
+    if(!#t35.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t36 in #t35{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t34.{core::Map::[]=}{Invariant}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value});
+    #t34.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t34;
   core::Map<core::int, core::int> map4 = block {
-    final core::Map<core::int, core::int> #t47 = <core::int, core::int>{};
-    #t47.{core::Map::[]=}{Invariant}(1, 1);
-    #t47.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t48 = null;
-    if(!#t48.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t49 in #t48{core::Map<core::int, core::int>}.{core::Map::entries})
-        #t47.{core::Map::[]=}{Invariant}(#t49.{core::MapEntry::key}, #t49.{core::MapEntry::value});
-    #t47.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t47;
+    final core::Map<core::int, core::int> #t37 = <core::int, core::int>{};
+    #t37.{core::Map::[]=}{Invariant}(1, 1);
+    #t37.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t38 = null;
+    if(!#t38.{core::Object::==}(null))
+      for (final core::MapEntry<core::int, core::int> #t39 in #t38{core::Map<core::int, core::int>}.{core::Map::entries})
+        #t37.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
+    #t37.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t37;
 }
diff --git a/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect
index ba1a66c..a75a6aa 100644
--- a/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect
@@ -6,220 +6,162 @@
 static method main() → dynamic {
   core::List<core::int>? list = null;
   core::print( block {
-    final core::List<core::int> #t1 = <core::int>[];
-    #t1.{core::List::add}{Invariant}(1);
-    #t1.{core::List::add}{Invariant}(2);
+    final core::List<core::int> #t1 = <core::int>[1, 2];
     final core::Iterable<core::int>? #t2 = list;
-    if(!#t2.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t2{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t3 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t3);
-      }
-    }
+    if(!#t2.{core::Object::==}(null))
+      #t1.{core::List::addAll}{Invariant}(#t2{core::Iterable<core::int>});
     #t1.{core::List::add}{Invariant}(3);
   } =>#t1);
   core::print( block {
-    final core::List<core::int> #t4 = <core::int>[];
-    #t4.{core::List::add}{Invariant}(1);
-    #t4.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t5 = null;
-    if(!#t5.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t5{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t6 = :sync-for-iterator.{core::Iterator::current};
-        #t4.{core::List::add}{Invariant}(#t6);
-      }
-    }
-    #t4.{core::List::add}{Invariant}(3);
-  } =>#t4);
+    final core::List<core::int> #t3 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t4 = null;
+    if(!#t4.{core::Object::==}(null))
+      #t3.{core::List::addAll}{Invariant}(#t4{core::Iterable<core::int>});
+    #t3.{core::List::add}{Invariant}(3);
+  } =>#t3);
   core::List<core::int> list1 = block {
-    final core::List<core::int> #t7 = <core::int>[];
-    final core::Iterable<core::int>? #t8 = list;
-    if(!#t8.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t8{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t9 = :sync-for-iterator.{core::Iterator::current};
-        #t7.{core::List::add}{Invariant}(#t9);
-      }
-    }
-  } =>#t7;
+    final core::List<core::int> #t5 = <core::int>[];
+    final core::Iterable<core::int>? #t6 = list;
+    if(!#t6.{core::Object::==}(null))
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::int>});
+  } =>#t5;
   core::List<Never> list2 = block {
-    final core::List<Never> #t10 = <Never>[];
-    final core::Iterable<Never>? #t11 = null;
-    if(!#t11.{core::Object::==}(null)) {
-      core::Iterator<Never> :sync-for-iterator = #t11{core::Iterable<Never>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final Never #t12 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::List::add}{Invariant}(#t12);
-      }
-    }
-  } =>#t10;
+    final core::List<Never> #t7 = <Never>[];
+    final core::Iterable<Never>? #t8 = null;
+    if(!#t8.{core::Object::==}(null))
+      #t7.{core::List::addAll}{Invariant}(#t8{core::Iterable<Never>});
+  } =>#t7;
   core::List<core::int> list3 = block {
-    final core::List<core::int> #t13 = <core::int>[];
-    #t13.{core::List::add}{Invariant}(1);
-    #t13.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t14 = list;
-    if(!#t14.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t14{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t15 = :sync-for-iterator.{core::Iterator::current};
-        #t13.{core::List::add}{Invariant}(#t15);
-      }
-    }
-    #t13.{core::List::add}{Invariant}(3);
-  } =>#t13;
+    final core::List<core::int> #t9 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t10 = list;
+    if(!#t10.{core::Object::==}(null))
+      #t9.{core::List::addAll}{Invariant}(#t10{core::Iterable<core::int>});
+    #t9.{core::List::add}{Invariant}(3);
+  } =>#t9;
   core::List<core::int> list4 = block {
-    final core::List<core::int> #t16 = <core::int>[];
-    #t16.{core::List::add}{Invariant}(1);
-    #t16.{core::List::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t17 = null;
-    if(!#t17.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t17{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t18 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::List::add}{Invariant}(#t18);
-      }
-    }
-    #t16.{core::List::add}{Invariant}(3);
-  } =>#t16;
+    final core::List<core::int> #t11 = <core::int>[1, 2];
+    final core::Iterable<core::int>? #t12 = null;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::List::addAll}{Invariant}(#t12{core::Iterable<core::int>});
+    #t11.{core::List::add}{Invariant}(3);
+  } =>#t11;
   core::Set<core::int>? set = null;
   core::print( block {
-    final core::Set<core::int> #t19 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t19.{core::Set::add}{Invariant}(1);
-    #t19.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t20 = set;
-    if(!#t20.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t20{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t21 = :sync-for-iterator.{core::Iterator::current};
-        #t19.{core::Set::add}{Invariant}(#t21);
-      }
-    }
-    #t19.{core::Set::add}{Invariant}(3);
-  } =>#t19);
+    final core::Set<core::int> #t13 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t13.{core::Set::add}{Invariant}(1);
+    #t13.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t14 = set;
+    if(!#t14.{core::Object::==}(null))
+      #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<core::int>});
+    #t13.{core::Set::add}{Invariant}(3);
+  } =>#t13);
   core::print( block {
-    final core::Set<core::int> #t22 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t22.{core::Set::add}{Invariant}(1);
-    #t22.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t23 = null;
-    if(!#t23.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t23{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t24 = :sync-for-iterator.{core::Iterator::current};
-        #t22.{core::Set::add}{Invariant}(#t24);
-      }
-    }
-    #t22.{core::Set::add}{Invariant}(3);
-  } =>#t22);
+    final core::Set<core::int> #t15 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t15.{core::Set::add}{Invariant}(1);
+    #t15.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t16 = null;
+    if(!#t16.{core::Object::==}(null))
+      #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<core::int>});
+    #t15.{core::Set::add}{Invariant}(3);
+  } =>#t15);
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t25 = new col::_CompactLinkedHashSet::•<core::int>();
-    final core::Iterable<dynamic>? #t26 = set;
-    if(!#t26.{core::Object::==}(null)) {
-      core::Iterator<dynamic> :sync-for-iterator = #t26{core::Iterable<dynamic>}.{core::Iterable::iterator};
+    final core::Set<core::int> #t17 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Iterable<dynamic>? #t18 = set;
+    if(!#t18.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t18{core::Iterable<dynamic>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t27 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::int #t28 = #t27 as{TypeError,ForNonNullableByDefault} core::int;
-          #t25.{core::Set::add}{Invariant}(#t28);
+          final core::int #t20 = #t19 as{TypeError,ForNonNullableByDefault} core::int;
+          #t17.{core::Set::add}{Invariant}(#t20);
         }
       }
     }
-  } =>#t25;
+  } =>#t17;
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t29 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t29.{core::Set::add}{Invariant}(1);
-    #t29.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t30 = set;
-    if(!#t30.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t30{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t31 = :sync-for-iterator.{core::Iterator::current};
-        #t29.{core::Set::add}{Invariant}(#t31);
-      }
-    }
-    #t29.{core::Set::add}{Invariant}(3);
-  } =>#t29;
+    final core::Set<core::int> #t21 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t21.{core::Set::add}{Invariant}(1);
+    #t21.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t22 = set;
+    if(!#t22.{core::Object::==}(null))
+      #t21.{core::Set::addAll}{Invariant}(#t22{core::Iterable<core::int>});
+    #t21.{core::Set::add}{Invariant}(3);
+  } =>#t21;
   core::Set<core::int> set4 = block {
-    final core::Set<core::int> #t32 = new col::_CompactLinkedHashSet::•<core::int>();
-    #t32.{core::Set::add}{Invariant}(1);
-    #t32.{core::Set::add}{Invariant}(2);
-    final core::Iterable<core::int>? #t33 = null;
-    if(!#t33.{core::Object::==}(null)) {
-      core::Iterator<core::int> :sync-for-iterator = #t33{core::Iterable<core::int>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int #t34 = :sync-for-iterator.{core::Iterator::current};
-        #t32.{core::Set::add}{Invariant}(#t34);
-      }
-    }
-    #t32.{core::Set::add}{Invariant}(3);
-  } =>#t32;
+    final core::Set<core::int> #t23 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t23.{core::Set::add}{Invariant}(1);
+    #t23.{core::Set::add}{Invariant}(2);
+    final core::Iterable<core::int>? #t24 = null;
+    if(!#t24.{core::Object::==}(null))
+      #t23.{core::Set::addAll}{Invariant}(#t24{core::Iterable<core::int>});
+    #t23.{core::Set::add}{Invariant}(3);
+  } =>#t23;
   core::Map<core::int, core::int>? map = null;
   core::print( block {
-    final core::Map<core::int, core::int> #t35 = <core::int, core::int>{};
-    #t35.{core::Map::[]=}{Invariant}(1, 1);
-    #t35.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t36 = map;
-    if(!#t36.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t36{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t25 = <core::int, core::int>{};
+    #t25.{core::Map::[]=}{Invariant}(1, 1);
+    #t25.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t26 = map;
+    if(!#t26.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t26{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t37 = :sync-for-iterator.{core::Iterator::current};
-        #t35.{core::Map::[]=}{Invariant}(#t37.{core::MapEntry::key}, #t37.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t27 = :sync-for-iterator.{core::Iterator::current};
+        #t25.{core::Map::[]=}{Invariant}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
       }
     }
-    #t35.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t35);
+    #t25.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t25);
   core::print( block {
-    final core::Map<core::int, core::int> #t38 = <core::int, core::int>{};
-    #t38.{core::Map::[]=}{Invariant}(1, 1);
-    #t38.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t39 = null;
-    if(!#t39.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t39{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t28 = <core::int, core::int>{};
+    #t28.{core::Map::[]=}{Invariant}(1, 1);
+    #t28.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t29 = null;
+    if(!#t29.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t29{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t40 = :sync-for-iterator.{core::Iterator::current};
-        #t38.{core::Map::[]=}{Invariant}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t30 = :sync-for-iterator.{core::Iterator::current};
+        #t28.{core::Map::[]=}{Invariant}(#t30.{core::MapEntry::key}, #t30.{core::MapEntry::value});
       }
     }
-    #t38.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t38);
+    #t28.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t28);
   core::Map<core::int, core::int> map1 = block {
-    final core::Map<core::int, core::int> #t41 = <core::int, core::int>{};
-    final core::Map<core::int, core::int>? #t42 = map;
-    if(!#t42.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t42{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t31 = <core::int, core::int>{};
+    final core::Map<core::int, core::int>? #t32 = map;
+    if(!#t32.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t32{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t43 = :sync-for-iterator.{core::Iterator::current};
-        #t41.{core::Map::[]=}{Invariant}(#t43.{core::MapEntry::key}, #t43.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t33 = :sync-for-iterator.{core::Iterator::current};
+        #t31.{core::Map::[]=}{Invariant}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
       }
     }
-  } =>#t41;
+  } =>#t31;
   core::Map<core::int, core::int> map3 = block {
-    final core::Map<core::int, core::int> #t44 = <core::int, core::int>{};
-    #t44.{core::Map::[]=}{Invariant}(1, 1);
-    #t44.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t45 = map;
-    if(!#t45.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t45{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t34 = <core::int, core::int>{};
+    #t34.{core::Map::[]=}{Invariant}(1, 1);
+    #t34.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t35 = map;
+    if(!#t35.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t35{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t46 = :sync-for-iterator.{core::Iterator::current};
-        #t44.{core::Map::[]=}{Invariant}(#t46.{core::MapEntry::key}, #t46.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t36 = :sync-for-iterator.{core::Iterator::current};
+        #t34.{core::Map::[]=}{Invariant}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value});
       }
     }
-    #t44.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t44;
+    #t34.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t34;
   core::Map<core::int, core::int> map4 = block {
-    final core::Map<core::int, core::int> #t47 = <core::int, core::int>{};
-    #t47.{core::Map::[]=}{Invariant}(1, 1);
-    #t47.{core::Map::[]=}{Invariant}(2, 2);
-    final core::Map<core::int, core::int>? #t48 = null;
-    if(!#t48.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t48{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::int, core::int> #t37 = <core::int, core::int>{};
+    #t37.{core::Map::[]=}{Invariant}(1, 1);
+    #t37.{core::Map::[]=}{Invariant}(2, 2);
+    final core::Map<core::int, core::int>? #t38 = null;
+    if(!#t38.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::int, core::int>> :sync-for-iterator = #t38{core::Map<core::int, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int, core::int> #t49 = :sync-for-iterator.{core::Iterator::current};
-        #t47.{core::Map::[]=}{Invariant}(#t49.{core::MapEntry::key}, #t49.{core::MapEntry::value});
+        final core::MapEntry<core::int, core::int> #t39 = :sync-for-iterator.{core::Iterator::current};
+        #t37.{core::Map::[]=}{Invariant}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
       }
     }
-    #t47.{core::Map::[]=}{Invariant}(3, 3);
-  } =>#t47;
+    #t37.{core::Map::[]=}{Invariant}(3, 3);
+  } =>#t37;
 }
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.outline.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.outline.expect
index 6834f82..175965c3 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.outline.expect
@@ -21,11 +21,11 @@
   operator []= = self::E|[]=;
   operator [] = self::E|[];
 }
-static method E|get#foo(final core::String #this) → core::int
+static method E|get#foo(lowered final core::String #this) → core::int
   ;
-static method E|[]=(final core::String #this, core::int index, core::int value) → void
+static method E|[]=(lowered final core::String #this, core::int index, core::int value) → void
   ;
-static method E|[](final core::String #this, core::int index) → core::int
+static method E|[](lowered final core::String #this, core::int index) → core::int
   ;
 static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
index a97650d..bba165a 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
@@ -125,10 +125,10 @@
   operator []= = self::E|[]=;
   operator [] = self::E|[];
 }
-static method E|get#foo(final core::String #this) → core::int
+static method E|get#foo(lowered final core::String #this) → core::int
   return 42;
-static method E|[]=(final core::String #this, core::int index, core::int value) → void {}
-static method E|[](final core::String #this, core::int index) → core::int
+static method E|[]=(lowered final core::String #this, core::int index, core::int value) → void {}
+static method E|[](lowered final core::String #this, core::int index) → core::int
   return 42;
 static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
@@ -141,53 +141,51 @@
     final core::List<core::String> #t5 = <core::String>[];
     final core::Iterable<core::String>? #t6 = l;
     if(!#t6.{core::Object::==}(null))
-      for (final core::String #t7 in #t6{core::Iterable<core::String>})
-        #t5.{core::List::add}{Invariant}(#t7);
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::String>});
   } =>#t5;
   core::Set<core::String> a = block {
-    final core::Set<core::String> #t8 = col::LinkedHashSet::•<core::String>();
-    final core::Iterable<dynamic>? #t9 = l;
-    if(!#t9.{core::Object::==}(null))
-      for (final dynamic #t10 in #t9{core::Iterable<dynamic>}) {
-        final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
-        #t8.{core::Set::add}{Invariant}(#t11);
+    final core::Set<core::String> #t7 = col::LinkedHashSet::•<core::String>();
+    final core::Iterable<dynamic>? #t8 = l;
+    if(!#t8.{core::Object::==}(null))
+      for (final dynamic #t9 in #t8{core::Iterable<dynamic>}) {
+        final core::String #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::String;
+        #t7.{core::Set::add}{Invariant}(#t10);
       }
-  } =>#t8;
+  } =>#t7;
   block {
-    final core::Set<core::String> #t12 = col::LinkedHashSet::•<core::String>();
-    final core::Iterable<core::String>? #t13 = l;
-    if(!#t13.{core::Object::==}(null))
-      for (final core::String #t14 in #t13{core::Iterable<core::String>})
-        #t12.{core::Set::add}{Invariant}(#t14);
-  } =>#t12;
+    final core::Set<core::String> #t11 = col::LinkedHashSet::•<core::String>();
+    final core::Iterable<core::String>? #t12 = l;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::Set::addAll}{Invariant}(#t12{core::Iterable<core::String>});
+  } =>#t11;
   core::Map<core::String, core::int> b = block {
-    final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t16 = m;
-    if(!#t16.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t17 in #t16{core::Map<core::String, core::int>}.{core::Map::entries})
-        #t15.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-  } =>#t15;
+    final core::Map<core::String, core::int> #t13 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t14 = m;
+    if(!#t14.{core::Object::==}(null))
+      for (final core::MapEntry<core::String, core::int> #t15 in #t14{core::Map<core::String, core::int>}.{core::Map::entries})
+        #t13.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+  } =>#t13;
   block {
-    final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t19 = m;
-    if(!#t19.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t20 in #t19{core::Map<core::String, core::int>}.{core::Map::entries})
-        #t18.{core::Map::[]=}{Invariant}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
-  } =>#t18;
+    final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t17 = m;
+    if(!#t17.{core::Object::==}(null))
+      for (final core::MapEntry<core::String, core::int> #t18 in #t17{core::Map<core::String, core::int>}.{core::Map::entries})
+        #t16.{core::Map::[]=}{Invariant}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
+  } =>#t16;
   s!;
-  let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
-  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
-  let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
-  let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
-  let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
-  let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
-  let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
-  let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
-  let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    #t31.{core::List::length} = 42;
-  } =>#t31;
-  let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
-  } =>#t32;
+  let final core::String #t19 = s in #t19.{core::String::==}(null) ?{core::String?} null : #t19.{core::String::substring}(0, 0);
+  let final core::List<core::String> #t20 = l in #t20.{core::List::==}(null) ?{core::int?} null : #t20.{core::List::length} = 42;
+  let final core::List<core::String> #t21 = l in #t21.{core::List::==}(null) ?{core::int?} null : #t21.{core::List::length} = #t21.{core::List::length}.{core::num::+}(42);
+  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length}.{core::num::==}(null) ?{core::int} #t22.{core::List::length} = 42 : null;
+  let final core::String #t23 = s in #t23.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t23);
+  let final core::String #t24 = s in let final core::int #t25 = 42 in self::E|[](#t24, #t25).{core::num::==}(null) ?{core::int} self::E|[]=(#t24, #t25, 42) : null;
+  let final core::List<core::String> #t26 = l in let final core::int #t27 = 42 in #t26.{core::List::[]}(#t27).{core::String::==}(null) ?{core::String} #t26.{core::List::[]=}(#t27, "foo") : null;
+  let final core::List<core::String> #t28 = l in #t28.{core::List::length}.{core::num::==}(null) ?{core::int} #t28.{core::List::length} = 42 : null;
+  let final core::List<core::String> #t29 = l in #t29.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    #t29.{core::List::length} = 42;
+  } =>#t29;
+  let final core::List<core::String> #t30 = l in #t30.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    let final core::List<core::String> #t31 = #t30 in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
+  } =>#t30;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
index df0ca83..7896b4b 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
@@ -125,10 +125,10 @@
   operator []= = self::E|[]=;
   operator [] = self::E|[];
 }
-static method E|get#foo(final core::String #this) → core::int
+static method E|get#foo(lowered final core::String #this) → core::int
   return 42;
-static method E|[]=(final core::String #this, core::int index, core::int value) → void {}
-static method E|[](final core::String #this, core::int index) → core::int
+static method E|[]=(lowered final core::String #this, core::int index, core::int value) → void {}
+static method E|[](lowered final core::String #this, core::int index) → core::int
   return 42;
 static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
@@ -140,76 +140,66 @@
   block {
     final core::List<core::String> #t5 = <core::String>[];
     final core::Iterable<core::String>? #t6 = l;
-    if(!#t6.{core::Object::==}(null)) {
-      core::Iterator<core::String> :sync-for-iterator = #t6{core::Iterable<core::String>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String #t7 = :sync-for-iterator.{core::Iterator::current};
-        #t5.{core::List::add}{Invariant}(#t7);
-      }
-    }
+    if(!#t6.{core::Object::==}(null))
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::String>});
   } =>#t5;
   core::Set<core::String> a = block {
-    final core::Set<core::String> #t8 = new col::_CompactLinkedHashSet::•<core::String>();
-    final core::Iterable<dynamic>? #t9 = l;
-    if(!#t9.{core::Object::==}(null)) {
-      core::Iterator<dynamic> :sync-for-iterator = #t9{core::Iterable<dynamic>}.{core::Iterable::iterator};
+    final core::Set<core::String> #t7 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Iterable<dynamic>? #t8 = l;
+    if(!#t8.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t8{core::Iterable<dynamic>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
-          #t8.{core::Set::add}{Invariant}(#t11);
+          final core::String #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::String;
+          #t7.{core::Set::add}{Invariant}(#t10);
         }
       }
     }
-  } =>#t8;
+  } =>#t7;
   block {
-    final core::Set<core::String> #t12 = new col::_CompactLinkedHashSet::•<core::String>();
-    final core::Iterable<core::String>? #t13 = l;
-    if(!#t13.{core::Object::==}(null)) {
-      core::Iterator<core::String> :sync-for-iterator = #t13{core::Iterable<core::String>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String #t14 = :sync-for-iterator.{core::Iterator::current};
-        #t12.{core::Set::add}{Invariant}(#t14);
-      }
-    }
-  } =>#t12;
+    final core::Set<core::String> #t11 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Iterable<core::String>? #t12 = l;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::Set::addAll}{Invariant}(#t12{core::Iterable<core::String>});
+  } =>#t11;
   core::Map<core::String, core::int> b = block {
-    final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t16 = m;
-    if(!#t16.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t16{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::String, core::int> #t13 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t14 = m;
+    if(!#t14.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t14{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String, core::int> #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t15.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+        final core::MapEntry<core::String, core::int> #t15 = :sync-for-iterator.{core::Iterator::current};
+        #t13.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
       }
     }
-  } =>#t15;
+  } =>#t13;
   block {
-    final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t19 = m;
-    if(!#t19.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t19{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t17 = m;
+    if(!#t17.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t17{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String, core::int> #t20 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Map::[]=}{Invariant}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
+        final core::MapEntry<core::String, core::int> #t18 = :sync-for-iterator.{core::Iterator::current};
+        #t16.{core::Map::[]=}{Invariant}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
       }
     }
-  } =>#t18;
+  } =>#t16;
   s!;
-  let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
-  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
-  let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
-  let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
-  let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
-  let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
-  let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
-  let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
-  let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    #t31.{core::List::length} = 42;
-  } =>#t31;
-  let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
-  } =>#t32;
+  let final core::String #t19 = s in #t19.{core::String::==}(null) ?{core::String?} null : #t19.{core::String::substring}(0, 0);
+  let final core::List<core::String> #t20 = l in #t20.{core::List::==}(null) ?{core::int?} null : #t20.{core::List::length} = 42;
+  let final core::List<core::String> #t21 = l in #t21.{core::List::==}(null) ?{core::int?} null : #t21.{core::List::length} = #t21.{core::List::length}.{core::num::+}(42);
+  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length}.{core::num::==}(null) ?{core::int} #t22.{core::List::length} = 42 : null;
+  let final core::String #t23 = s in #t23.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t23);
+  let final core::String #t24 = s in let final core::int #t25 = 42 in self::E|[](#t24, #t25).{core::num::==}(null) ?{core::int} self::E|[]=(#t24, #t25, 42) : null;
+  let final core::List<core::String> #t26 = l in let final core::int #t27 = 42 in #t26.{core::List::[]}(#t27).{core::String::==}(null) ?{core::String} #t26.{core::List::[]=}(#t27, "foo") : null;
+  let final core::List<core::String> #t28 = l in #t28.{core::List::length}.{core::num::==}(null) ?{core::int} #t28.{core::List::length} = 42 : null;
+  let final core::List<core::String> #t29 = l in #t29.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    #t29.{core::List::length} = 42;
+  } =>#t29;
+  let final core::List<core::String> #t30 = l in #t30.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    let final core::List<core::String> #t31 = #t30 in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
+  } =>#t30;
 }
 static method main() → dynamic {}
 
@@ -221,4 +211,4 @@
 Evaluated: VariableGet @ org-dartlang-testcase:///strictly_non_nullable_warnings.dart:42:8 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///strictly_non_nullable_warnings.dart:43:5 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///strictly_non_nullable_warnings.dart:43:5 -> IntConstant(42)
-Extra constant evaluation: evaluated: 221, effectively constant: 6
+Extra constant evaluation: evaluated: 209, effectively constant: 6
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
index a97650d..bba165a 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
@@ -125,10 +125,10 @@
   operator []= = self::E|[]=;
   operator [] = self::E|[];
 }
-static method E|get#foo(final core::String #this) → core::int
+static method E|get#foo(lowered final core::String #this) → core::int
   return 42;
-static method E|[]=(final core::String #this, core::int index, core::int value) → void {}
-static method E|[](final core::String #this, core::int index) → core::int
+static method E|[]=(lowered final core::String #this, core::int index, core::int value) → void {}
+static method E|[](lowered final core::String #this, core::int index) → core::int
   return 42;
 static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
@@ -141,53 +141,51 @@
     final core::List<core::String> #t5 = <core::String>[];
     final core::Iterable<core::String>? #t6 = l;
     if(!#t6.{core::Object::==}(null))
-      for (final core::String #t7 in #t6{core::Iterable<core::String>})
-        #t5.{core::List::add}{Invariant}(#t7);
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::String>});
   } =>#t5;
   core::Set<core::String> a = block {
-    final core::Set<core::String> #t8 = col::LinkedHashSet::•<core::String>();
-    final core::Iterable<dynamic>? #t9 = l;
-    if(!#t9.{core::Object::==}(null))
-      for (final dynamic #t10 in #t9{core::Iterable<dynamic>}) {
-        final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
-        #t8.{core::Set::add}{Invariant}(#t11);
+    final core::Set<core::String> #t7 = col::LinkedHashSet::•<core::String>();
+    final core::Iterable<dynamic>? #t8 = l;
+    if(!#t8.{core::Object::==}(null))
+      for (final dynamic #t9 in #t8{core::Iterable<dynamic>}) {
+        final core::String #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::String;
+        #t7.{core::Set::add}{Invariant}(#t10);
       }
-  } =>#t8;
+  } =>#t7;
   block {
-    final core::Set<core::String> #t12 = col::LinkedHashSet::•<core::String>();
-    final core::Iterable<core::String>? #t13 = l;
-    if(!#t13.{core::Object::==}(null))
-      for (final core::String #t14 in #t13{core::Iterable<core::String>})
-        #t12.{core::Set::add}{Invariant}(#t14);
-  } =>#t12;
+    final core::Set<core::String> #t11 = col::LinkedHashSet::•<core::String>();
+    final core::Iterable<core::String>? #t12 = l;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::Set::addAll}{Invariant}(#t12{core::Iterable<core::String>});
+  } =>#t11;
   core::Map<core::String, core::int> b = block {
-    final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t16 = m;
-    if(!#t16.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t17 in #t16{core::Map<core::String, core::int>}.{core::Map::entries})
-        #t15.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-  } =>#t15;
+    final core::Map<core::String, core::int> #t13 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t14 = m;
+    if(!#t14.{core::Object::==}(null))
+      for (final core::MapEntry<core::String, core::int> #t15 in #t14{core::Map<core::String, core::int>}.{core::Map::entries})
+        #t13.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+  } =>#t13;
   block {
-    final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t19 = m;
-    if(!#t19.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t20 in #t19{core::Map<core::String, core::int>}.{core::Map::entries})
-        #t18.{core::Map::[]=}{Invariant}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
-  } =>#t18;
+    final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t17 = m;
+    if(!#t17.{core::Object::==}(null))
+      for (final core::MapEntry<core::String, core::int> #t18 in #t17{core::Map<core::String, core::int>}.{core::Map::entries})
+        #t16.{core::Map::[]=}{Invariant}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
+  } =>#t16;
   s!;
-  let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
-  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
-  let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
-  let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
-  let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
-  let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
-  let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
-  let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
-  let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    #t31.{core::List::length} = 42;
-  } =>#t31;
-  let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
-  } =>#t32;
+  let final core::String #t19 = s in #t19.{core::String::==}(null) ?{core::String?} null : #t19.{core::String::substring}(0, 0);
+  let final core::List<core::String> #t20 = l in #t20.{core::List::==}(null) ?{core::int?} null : #t20.{core::List::length} = 42;
+  let final core::List<core::String> #t21 = l in #t21.{core::List::==}(null) ?{core::int?} null : #t21.{core::List::length} = #t21.{core::List::length}.{core::num::+}(42);
+  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length}.{core::num::==}(null) ?{core::int} #t22.{core::List::length} = 42 : null;
+  let final core::String #t23 = s in #t23.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t23);
+  let final core::String #t24 = s in let final core::int #t25 = 42 in self::E|[](#t24, #t25).{core::num::==}(null) ?{core::int} self::E|[]=(#t24, #t25, 42) : null;
+  let final core::List<core::String> #t26 = l in let final core::int #t27 = 42 in #t26.{core::List::[]}(#t27).{core::String::==}(null) ?{core::String} #t26.{core::List::[]=}(#t27, "foo") : null;
+  let final core::List<core::String> #t28 = l in #t28.{core::List::length}.{core::num::==}(null) ?{core::int} #t28.{core::List::length} = 42 : null;
+  let final core::List<core::String> #t29 = l in #t29.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    #t29.{core::List::length} = 42;
+  } =>#t29;
+  let final core::List<core::String> #t30 = l in #t30.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    let final core::List<core::String> #t31 = #t30 in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
+  } =>#t30;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
index df0ca83..7896b4b 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
@@ -125,10 +125,10 @@
   operator []= = self::E|[]=;
   operator [] = self::E|[];
 }
-static method E|get#foo(final core::String #this) → core::int
+static method E|get#foo(lowered final core::String #this) → core::int
   return 42;
-static method E|[]=(final core::String #this, core::int index, core::int value) → void {}
-static method E|[](final core::String #this, core::int index) → core::int
+static method E|[]=(lowered final core::String #this, core::int index, core::int value) → void {}
+static method E|[](lowered final core::String #this, core::int index) → core::int
   return 42;
 static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
@@ -140,76 +140,66 @@
   block {
     final core::List<core::String> #t5 = <core::String>[];
     final core::Iterable<core::String>? #t6 = l;
-    if(!#t6.{core::Object::==}(null)) {
-      core::Iterator<core::String> :sync-for-iterator = #t6{core::Iterable<core::String>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String #t7 = :sync-for-iterator.{core::Iterator::current};
-        #t5.{core::List::add}{Invariant}(#t7);
-      }
-    }
+    if(!#t6.{core::Object::==}(null))
+      #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::String>});
   } =>#t5;
   core::Set<core::String> a = block {
-    final core::Set<core::String> #t8 = new col::_CompactLinkedHashSet::•<core::String>();
-    final core::Iterable<dynamic>? #t9 = l;
-    if(!#t9.{core::Object::==}(null)) {
-      core::Iterator<dynamic> :sync-for-iterator = #t9{core::Iterable<dynamic>}.{core::Iterable::iterator};
+    final core::Set<core::String> #t7 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Iterable<dynamic>? #t8 = l;
+    if(!#t8.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t8{core::Iterable<dynamic>}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
+        final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
         {
-          final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
-          #t8.{core::Set::add}{Invariant}(#t11);
+          final core::String #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::String;
+          #t7.{core::Set::add}{Invariant}(#t10);
         }
       }
     }
-  } =>#t8;
+  } =>#t7;
   block {
-    final core::Set<core::String> #t12 = new col::_CompactLinkedHashSet::•<core::String>();
-    final core::Iterable<core::String>? #t13 = l;
-    if(!#t13.{core::Object::==}(null)) {
-      core::Iterator<core::String> :sync-for-iterator = #t13{core::Iterable<core::String>}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::String #t14 = :sync-for-iterator.{core::Iterator::current};
-        #t12.{core::Set::add}{Invariant}(#t14);
-      }
-    }
-  } =>#t12;
+    final core::Set<core::String> #t11 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Iterable<core::String>? #t12 = l;
+    if(!#t12.{core::Object::==}(null))
+      #t11.{core::Set::addAll}{Invariant}(#t12{core::Iterable<core::String>});
+  } =>#t11;
   core::Map<core::String, core::int> b = block {
-    final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t16 = m;
-    if(!#t16.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t16{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::String, core::int> #t13 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t14 = m;
+    if(!#t14.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t14{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String, core::int> #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t15.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+        final core::MapEntry<core::String, core::int> #t15 = :sync-for-iterator.{core::Iterator::current};
+        #t13.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
       }
     }
-  } =>#t15;
+  } =>#t13;
   block {
-    final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
-    final core::Map<core::String, core::int>? #t19 = m;
-    if(!#t19.{core::Object::==}(null)) {
-      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t19{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+    final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
+    final core::Map<core::String, core::int>? #t17 = m;
+    if(!#t17.{core::Object::==}(null)) {
+      core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t17{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::String, core::int> #t20 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Map::[]=}{Invariant}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
+        final core::MapEntry<core::String, core::int> #t18 = :sync-for-iterator.{core::Iterator::current};
+        #t16.{core::Map::[]=}{Invariant}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
       }
     }
-  } =>#t18;
+  } =>#t16;
   s!;
-  let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
-  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
-  let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
-  let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
-  let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
-  let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
-  let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
-  let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
-  let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    #t31.{core::List::length} = 42;
-  } =>#t31;
-  let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
-    let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
-  } =>#t32;
+  let final core::String #t19 = s in #t19.{core::String::==}(null) ?{core::String?} null : #t19.{core::String::substring}(0, 0);
+  let final core::List<core::String> #t20 = l in #t20.{core::List::==}(null) ?{core::int?} null : #t20.{core::List::length} = 42;
+  let final core::List<core::String> #t21 = l in #t21.{core::List::==}(null) ?{core::int?} null : #t21.{core::List::length} = #t21.{core::List::length}.{core::num::+}(42);
+  let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length}.{core::num::==}(null) ?{core::int} #t22.{core::List::length} = 42 : null;
+  let final core::String #t23 = s in #t23.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t23);
+  let final core::String #t24 = s in let final core::int #t25 = 42 in self::E|[](#t24, #t25).{core::num::==}(null) ?{core::int} self::E|[]=(#t24, #t25, 42) : null;
+  let final core::List<core::String> #t26 = l in let final core::int #t27 = 42 in #t26.{core::List::[]}(#t27).{core::String::==}(null) ?{core::String} #t26.{core::List::[]=}(#t27, "foo") : null;
+  let final core::List<core::String> #t28 = l in #t28.{core::List::length}.{core::num::==}(null) ?{core::int} #t28.{core::List::length} = 42 : null;
+  let final core::List<core::String> #t29 = l in #t29.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    #t29.{core::List::length} = 42;
+  } =>#t29;
+  let final core::List<core::String> #t30 = l in #t30.{core::List::==}(null) ?{core::List<core::String>} null : block {
+    let final core::List<core::String> #t31 = #t30 in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
+  } =>#t30;
 }
 static method main() → dynamic {}
 
@@ -221,4 +211,4 @@
 Evaluated: VariableGet @ org-dartlang-testcase:///strictly_non_nullable_warnings.dart:42:8 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///strictly_non_nullable_warnings.dart:43:5 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///strictly_non_nullable_warnings.dart:43:5 -> IntConstant(42)
-Extra constant evaluation: evaluated: 221, effectively constant: 6
+Extra constant evaluation: evaluated: 209, effectively constant: 6
diff --git a/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.expect
index 2c462af..91bdcec 100644
--- a/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.expect
@@ -16,7 +16,7 @@
   synthetic constructor •() → self::_F&B&D
     : super flu::B::•()
     ;
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 class F extends self::_F&B&D {
   synthetic constructor •() → self::F
diff --git a/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.transformed.expect
index 465aafd..fef3899 100644
--- a/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/flutter_issue_63029/flutter_issue_63029.dart.weak.transformed.expect
@@ -16,16 +16,16 @@
   synthetic constructor •() → self::_F&B&D
     : super flu::B::•()
     ;
-  abstract member-signature operator /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ ==(dynamic other) → core::bool*; -> core::Object::==
-  abstract member-signature get /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _identityHashCode() → core::int*; -> core::Object::_identityHashCode
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
-  abstract member-signature get /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ hashCode() → core::int*; -> core::Object::hashCode
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ toString() → core::String*; -> core::Object::toString
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
-  abstract member-signature get /*isNullableByDefault, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ runtimeType() → core::Type*; -> core::Object::runtimeType
+  abstract member-signature operator /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ toString() → core::String*; -> core::Object::toString
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///flutter_issue_63029_lib2.dart */ runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 class F extends self::_F&B&D {
   synthetic constructor •() → self::F
diff --git a/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.expect
index 9ed16b6..b2fa606 100644
--- a/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.expect
@@ -34,13 +34,13 @@
   synthetic constructor •() → self::Class4b
     : super core::Object::•()
     ;
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 class Class4c extends core::Object implements inh::GenericInterface<core::num?> {
   synthetic constructor •() → self::Class4c
     : super core::Object::•()
     ;
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 class Class4d extends inh::LegacyClass4 implements inh::GenericInterface<core::num> {
   synthetic constructor •() → self::Class4d
diff --git a/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.transformed.expect
index 0bc6430..b6b56b8 100644
--- a/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/inheritance_from_opt_out.dart.weak.transformed.expect
@@ -34,13 +34,13 @@
   synthetic constructor •() → self::Class4b
     : super core::Object::•()
     ;
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 class Class4c extends core::Object implements inh::GenericInterface<core::num?> {
   synthetic constructor •() → self::Class4c
     : super core::Object::•()
     ;
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 class Class4d extends inh::LegacyClass4 implements inh::GenericInterface<core::num> {
   synthetic constructor •() → self::Class4d
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect
index ee6d621..faea41f 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect
@@ -8,7 +8,6 @@
   final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -23,7 +22,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -35,7 +33,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -50,7 +47,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -61,7 +57,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -84,7 +79,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.expect
index 88ec031..1d99576 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.expect
@@ -51,9 +51,9 @@
   method m = iss::E|m;
   tearoff m = iss::E|get#m;
 }
-static method E|m(final core::int #this) → core::String
+static method E|m(lowered final core::int #this) → core::String
   return "m";
-static method E|get#m(final core::int #this) → () → core::String
+static method E|get#m(lowered final core::int #this) → () → core::String
   return () → core::String => iss::E|m(#this);
 static method f() → core::int?
   return 4;
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.transformed.expect
index 88ec031..1d99576 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue42660.dart.weak.transformed.expect
@@ -51,9 +51,9 @@
   method m = iss::E|m;
   tearoff m = iss::E|get#m;
 }
-static method E|m(final core::int #this) → core::String
+static method E|m(lowered final core::int #this) → core::String
   return "m";
-static method E|get#m(final core::int #this) → () → core::String
+static method E|get#m(lowered final core::int #this) → () → core::String
   return () → core::String => iss::E|m(#this);
 static method f() → core::int?
   return 4;
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.expect
index bd160a8..8a40f19 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.expect
@@ -9,7 +9,7 @@
   const synthetic constructor •() → self::_Class&Object&Mixin
     : super core::Object::•()
     ;
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 class Class extends self::_Class&Object&Mixin {
   synthetic constructor •() → self::Class
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.transformed.expect
index ea35440..75f6938 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_out.dart.weak.transformed.expect
@@ -9,18 +9,18 @@
   const synthetic constructor •() → self::_Class&Object&Mixin
     : super core::Object::•()
     ;
-  abstract member-signature operator /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ ==(dynamic other) → core::bool*; -> core::Object::==
-  method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ method(core::int* i) → core::int*
+  abstract member-signature operator /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ ==(dynamic other) → core::bool*; -> core::Object::==
+  method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ method(core::int* i) → core::int*
     return let final core::int* #t1 = i in #t1.{core::num::==}(null) ?{core::int*} 0 : #t1;
-  abstract member-signature get /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _identityHashCode() → core::int*; -> core::Object::_identityHashCode
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
-  abstract member-signature get /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ hashCode() → core::int*; -> core::Object::hashCode
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ toString() → core::String*; -> core::Object::toString
-  abstract member-signature method /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
-  abstract member-signature get /*isNullableByDefault, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ runtimeType() → core::Type*; -> core::Object::runtimeType
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ toString() → core::String*; -> core::Object::toString
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///mixin_from_opt_out_lib.dart */ runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 class Class extends self::_Class&Object&Mixin {
   synthetic constructor •() → self::Class
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.expect
index 4ea1564..a622905 100644
--- a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.expect
@@ -28,23 +28,23 @@
   operator unary- = self::Extension|unary-;
   set field = self::Extension|set#field;
 }
-static method Extension|get#field(final self::Class* #this) → self::Class*
+static method Extension|get#field(lowered final self::Class* #this) → self::Class*
   return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class* #this, self::Class* value) → void {
+static method Extension|set#field(lowered final self::Class* #this, self::Class* value) → void {
   #this.{self::Class::_field} = value;
 }
-static method Extension|method(final self::Class* #this) → self::Class*
+static method Extension|method(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|get#method(final self::Class* #this) → () →* self::Class*
+static method Extension|get#method(lowered final self::Class* #this) → () →* self::Class*
   return () → self::Class* => self::Extension|method(#this);
-static method Extension|[](final self::Class* #this, self::Class* key) → self::Class*
+static method Extension|[](lowered final self::Class* #this, self::Class* key) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class* #this, self::Class* key, self::Class* value) → void {
+static method Extension|[]=(lowered final self::Class* #this, self::Class* key, self::Class* value) → void {
   self::Extension|set#field(#this, value);
 }
-static method Extension|+(final self::Class* #this, core::int* value) → self::Class*
+static method Extension|+(lowered final self::Class* #this, core::int* value) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class* #this) → self::Class*
+static method Extension|unary-(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.transformed.expect
index 4ea1564..a622905 100644
--- a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.weak.transformed.expect
@@ -28,23 +28,23 @@
   operator unary- = self::Extension|unary-;
   set field = self::Extension|set#field;
 }
-static method Extension|get#field(final self::Class* #this) → self::Class*
+static method Extension|get#field(lowered final self::Class* #this) → self::Class*
   return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class* #this, self::Class* value) → void {
+static method Extension|set#field(lowered final self::Class* #this, self::Class* value) → void {
   #this.{self::Class::_field} = value;
 }
-static method Extension|method(final self::Class* #this) → self::Class*
+static method Extension|method(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|get#method(final self::Class* #this) → () →* self::Class*
+static method Extension|get#method(lowered final self::Class* #this) → () →* self::Class*
   return () → self::Class* => self::Extension|method(#this);
-static method Extension|[](final self::Class* #this, self::Class* key) → self::Class*
+static method Extension|[](lowered final self::Class* #this, self::Class* key) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class* #this, self::Class* key, self::Class* value) → void {
+static method Extension|[]=(lowered final self::Class* #this, self::Class* key, self::Class* value) → void {
   self::Extension|set#field(#this, value);
 }
-static method Extension|+(final self::Class* #this, core::int* value) → self::Class*
+static method Extension|+(lowered final self::Class* #this, core::int* value) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class* #this) → self::Class*
+static method Extension|unary-(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.expect
index d0cc332..6b754ec 100644
--- a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.expect
@@ -28,23 +28,23 @@
   operator unary- = self::Extension|unary-;
   set field = self::Extension|set#field;
 }
-static method Extension|get#field(final self::Class* #this) → self::Class*
+static method Extension|get#field(lowered final self::Class* #this) → self::Class*
   return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class* #this, self::Class* value) → void {
+static method Extension|set#field(lowered final self::Class* #this, self::Class* value) → void {
   #this.{self::Class::_field} = value;
 }
-static method Extension|method(final self::Class* #this) → self::Class*
+static method Extension|method(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|get#method(final self::Class* #this) → () →* self::Class*
+static method Extension|get#method(lowered final self::Class* #this) → () →* self::Class*
   return () → self::Class* => self::Extension|method(#this);
-static method Extension|[](final self::Class* #this, self::Class* key) → self::Class*
+static method Extension|[](lowered final self::Class* #this, self::Class* key) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class* #this, self::Class* key, self::Class* value) → void {
+static method Extension|[]=(lowered final self::Class* #this, self::Class* key, self::Class* value) → void {
   self::Extension|set#field(#this, value);
 }
-static method Extension|+(final self::Class* #this, core::int* value) → self::Class*
+static method Extension|+(lowered final self::Class* #this, core::int* value) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class* #this) → self::Class*
+static method Extension|unary-(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.transformed.expect
index d0cc332..6b754ec 100644
--- a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.weak.transformed.expect
@@ -28,23 +28,23 @@
   operator unary- = self::Extension|unary-;
   set field = self::Extension|set#field;
 }
-static method Extension|get#field(final self::Class* #this) → self::Class*
+static method Extension|get#field(lowered final self::Class* #this) → self::Class*
   return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class* #this, self::Class* value) → void {
+static method Extension|set#field(lowered final self::Class* #this, self::Class* value) → void {
   #this.{self::Class::_field} = value;
 }
-static method Extension|method(final self::Class* #this) → self::Class*
+static method Extension|method(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|get#method(final self::Class* #this) → () →* self::Class*
+static method Extension|get#method(lowered final self::Class* #this) → () →* self::Class*
   return () → self::Class* => self::Extension|method(#this);
-static method Extension|[](final self::Class* #this, self::Class* key) → self::Class*
+static method Extension|[](lowered final self::Class* #this, self::Class* key) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class* #this, self::Class* key, self::Class* value) → void {
+static method Extension|[]=(lowered final self::Class* #this, self::Class* key, self::Class* value) → void {
   self::Extension|set#field(#this, value);
 }
-static method Extension|+(final self::Class* #this, core::int* value) → self::Class*
+static method Extension|+(lowered final self::Class* #this, core::int* value) → self::Class*
   return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class* #this) → self::Class*
+static method Extension|unary-(lowered final self::Class* #this) → self::Class*
   return self::Extension|get#field(#this);
 static method main() → dynamic {
   self::propertyAccess(null);
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect
index 1752064..da4369b 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect
@@ -8,7 +8,7 @@
 extension _extension#0 on nul::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final nul::A? #this) → core::String
+static method _extension#0|get#text(lowered final nul::A? #this) → core::String
   return "Lily was here";
 static method main() → void {
   nul::A? a = null;
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect
index 1752064..da4369b 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
 extension _extension#0 on nul::A? {
   get text = self::_extension#0|get#text;
 }
-static method _extension#0|get#text(final nul::A? #this) → core::String
+static method _extension#0|get#text(lowered final nul::A? #this) → core::String
   return "Lily was here";
 static method main() → void {
   nul::A? a = null;
diff --git a/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.expect
index d4f279e..567675d 100644
--- a/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.expect
@@ -34,7 +34,7 @@
 import "dart:core" as core;
 
 class Class1<T extends core::Object? = core::Object?> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class1::redirect, opt::Class1::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class1::redirect, opt::Class1::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class1<opt::Class1::T%>
     : super core::Object::•()
     ;
@@ -46,7 +46,7 @@
     return new opt::Class1::_<opt::Class1::fact::T%>();
 }
 class Class2<T extends core::Object = core::Object> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class2::redirect, opt::Class2::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class2::redirect, opt::Class2::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class2<opt::Class2::T>
     : super core::Object::•()
     ;
@@ -58,7 +58,7 @@
     return new opt::Class2::_<opt::Class2::fact::T>();
 }
 class Class3<T extends core::String = core::String> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class3::redirect, opt::Class3::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class3::redirect, opt::Class3::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class3<opt::Class3::T>
     : super core::Object::•()
     ;
@@ -70,7 +70,7 @@
     return new opt::Class3::_<opt::Class3::fact::T>();
 }
 class Class4<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class4::redirect, opt::Class4::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class4::redirect, opt::Class4::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class4<opt::Class4::T%>
     : super core::Object::•()
     ;
@@ -82,7 +82,7 @@
     return new opt::Class4::_<opt::Class4::fact::T%>();
 }
 class Class5<T extends dynamic = dynamic> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class5::redirect, opt::Class5::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class5::redirect, opt::Class5::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class5<opt::Class5::T%>
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.transformed.expect
index b06177a..789e4fb 100644
--- a/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/object_bound_factory/main.dart.weak.transformed.expect
@@ -34,7 +34,7 @@
 import "dart:core" as core;
 
 class Class1<T extends core::Object? = core::Object?> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class1::redirect, opt::Class1::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class1::redirect, opt::Class1::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class1<opt::Class1::T%>
     : super core::Object::•()
     ;
@@ -46,7 +46,7 @@
     return new opt::Class1::_<opt::Class1::fact::T%>();
 }
 class Class2<T extends core::Object = core::Object> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class2::redirect, opt::Class2::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class2::redirect, opt::Class2::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class2<opt::Class2::T>
     : super core::Object::•()
     ;
@@ -58,7 +58,7 @@
     return new opt::Class2::_<opt::Class2::fact::T>();
 }
 class Class3<T extends core::String = core::String> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class3::redirect, opt::Class3::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class3::redirect, opt::Class3::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class3<opt::Class3::T>
     : super core::Object::•()
     ;
@@ -70,7 +70,7 @@
     return new opt::Class3::_<opt::Class3::fact::T>();
 }
 class Class4<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class4::redirect, opt::Class4::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class4::redirect, opt::Class4::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class4<opt::Class4::T%>
     : super core::Object::•()
     ;
@@ -82,7 +82,7 @@
     return new opt::Class4::_<opt::Class4::fact::T%>();
 }
 class Class5<T extends dynamic = dynamic> extends core::Object /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::Class5::redirect, opt::Class5::constRedirect]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::Class5::redirect, opt::Class5::constRedirect]/*isLegacy*/;
   const constructor _() → opt::Class5<opt::Class5::T%>
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.expect
index cf96979..37158e0 100644
--- a/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.expect
@@ -50,7 +50,7 @@
     ;
 }
 class CP<T extends core::Object = core::Object> extends opt::P<opt::CP::T> /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::CP::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::CP::•]/*isLegacy*/;
   const constructor _(core::Object token) → opt::CP<opt::CP::T>
     : super opt::P::_(token)
     ;
@@ -63,7 +63,7 @@
     ;
 }
 class VP<T extends core::Object = core::Object> extends opt::P<opt::VP::T> /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::VP::forToken]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::VP::forToken]/*isLegacy*/;
   const constructor _(core::Object token, opt::VP::T useValue) → opt::VP<opt::VP::T>
     : super opt::P::_(token)
     ;
diff --git a/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.transformed.expect
index 69f70c8..49ef11a 100644
--- a/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/object_bound_redirecting_factory/main.dart.weak.transformed.expect
@@ -50,7 +50,7 @@
     ;
 }
 class CP<T extends core::Object = core::Object> extends opt::P<opt::CP::T> /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::CP::•]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::CP::•]/*isLegacy*/;
   const constructor _(core::Object token) → opt::CP<opt::CP::T>
     : super opt::P::_(token)
     ;
@@ -63,7 +63,7 @@
     ;
 }
 class VP<T extends core::Object = core::Object> extends opt::P<opt::VP::T> /*hasConstConstructor*/  {
-  static field dynamic _redirecting# = <dynamic>[opt::VP::forToken]/*isNullableByDefault*/;
+  static field dynamic _redirecting# = <dynamic>[opt::VP::forToken]/*isLegacy*/;
   const constructor _(core::Object token, opt::VP::T useValue) → opt::VP<opt::VP::T>
     : super opt::P::_(token)
     ;
diff --git a/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.expect
index 4ca139e..9650648 100644
--- a/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.expect
@@ -10,12 +10,10 @@
     ;
   method method(core::String* node, core::Set<core::String*>* set) → core::List<core::String*>*
     return set.{core::Set::add}(node) ?{core::List<core::String*>*} block {
-      final core::List<core::String*>* #t1 = <core::String*>[];
-      #t1.{core::List::add}{Invariant}(node);
+      final core::List<core::String*>* #t1 = <core::String*>[node];
       final core::Iterable<core::String*>* #t2 = let final core::Iterable<core::String*>* #t3 = let final core::Set<core::String*>* #t4 = this.{self::Class::map}.{core::Map::[]}(node) in #t4.{core::Object::==}(null) ?{core::Iterable<core::String*>*} null : #t4.{core::Iterable::expand}<core::String*>((core::String* node) → core::List<core::String*>* => this.{self::Class::method}(node, set)) in #t3.{core::Object::==}(null) ?{core::List<core::String*>*} null : #t3.{core::Iterable::toList}();
       if(!#t2.{core::Object::==}(null))
-        for (final core::String* #t5 in #t2)
-          #t1.{core::List::add}{Invariant}(#t5);
+        #t1.{core::List::addAll}{Invariant}(#t2);
     } =>#t1 : <core::String*>[];
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -31,6 +29,6 @@
 static method main(dynamic args) → dynamic {
   if(false)
     new self::Class::•().{self::Class::method}("", block {
-      final core::Set<core::String*>* #t6 = col::LinkedHashSet::•<core::String*>();
-    } =>#t6);
+      final core::Set<core::String*>* #t5 = col::LinkedHashSet::•<core::String*>();
+    } =>#t5);
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect
index 32474f7..11de2a4 100644
--- a/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect
@@ -10,16 +10,10 @@
     ;
   method method(core::String* node, core::Set<core::String*>* set) → core::List<core::String*>*
     return set.{core::Set::add}(node) ?{core::List<core::String*>*} block {
-      final core::List<core::String*>* #t1 = <core::String*>[];
-      #t1.{core::List::add}{Invariant}(node);
+      final core::List<core::String*>* #t1 = <core::String*>[node];
       final core::Iterable<core::String*>* #t2 = let final core::Iterable<core::String*>* #t3 = let final core::Set<core::String*>* #t4 = this.{self::Class::map}.{core::Map::[]}(node) in #t4.{core::Object::==}(null) ?{core::Iterable<core::String*>*} null : #t4.{core::Iterable::expand}<core::String*>((core::String* node) → core::List<core::String*>* => this.{self::Class::method}(node, set)) in #t3.{core::Object::==}(null) ?{core::List<core::String*>*} null : #t3.{core::Iterable::toList}();
-      if(!#t2.{core::Object::==}(null)) {
-        core::Iterator<core::String*>* :sync-for-iterator = #t2.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::String* #t5 = :sync-for-iterator.{core::Iterator::current};
-          #t1.{core::List::add}{Invariant}(#t5);
-        }
-      }
+      if(!#t2.{core::Object::==}(null))
+        #t1.{core::List::addAll}{Invariant}(#t2);
     } =>#t1 : <core::String*>[];
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -35,6 +29,6 @@
 static method main(dynamic args) → dynamic {
   if(false)
     new self::Class::•().{self::Class::method}("", block {
-      final core::Set<core::String*>* #t6 = new col::_CompactLinkedHashSet::•<core::String*>();
-    } =>#t6);
+      final core::Set<core::String*>* #t5 = new col::_CompactLinkedHashSet::•<core::String*>();
+    } =>#t5);
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.expect
index e2f0b61..eea3841 100644
--- a/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.expect
@@ -36,7 +36,7 @@
   method test_default({required core::int? i = #C1}) → void {}
   method test_nondefault({required core::int? i = #C1}) → void {}
   method test_legacy({required core::int? i = #C1}) → void {}
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 static method main() → dynamic {
   new self::A::•().{self::A::test_default}(i: 1);
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.transformed.expect
index e2f0b61..eea3841 100644
--- a/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/required_name_override.dart.weak.transformed.expect
@@ -36,7 +36,7 @@
   method test_default({required core::int? i = #C1}) → void {}
   method test_nondefault({required core::int? i = #C1}) → void {}
   method test_legacy({required core::int? i = #C1}) → void {}
-  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
 }
 static method main() → dynamic {
   new self::A::•().{self::A::test_default}(i: 1);
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart
new file mode 100644
index 0000000..a1abf5e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'required_parameter_mixed_from_opt_out_lib.dart';
+
+class Super {
+  void method({required covariant int named}) {}
+}
+
+class Class extends Super with Mixin {}
+
+class SubClass extends Class {
+  void method({required covariant int named}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..ef719ee
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'required_parameter_mixed_from_opt_out_lib.dart';
+
+class Super {
+  void method({required covariant int named}) {}
+}
+
+class Class extends Super with Mixin {}
+
+class SubClass extends Class {
+  void method({required covariant int named}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45cf3b0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'required_parameter_mixed_from_opt_out_lib.dart';
+
+class Class extends Super with Mixin {}
+
+class SubClass extends Class {
+  void method({required covariant int named}) {}
+}
+
+class Super {
+  void method({required covariant int named}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.weak.expect
new file mode 100644
index 0000000..4cc02b1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.weak.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "required_parameter_mixed_from_opt_out_lib.dart" as req;
+
+import "org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart";
+
+class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  method method({required covariant core::int named = #C1}) → void {}
+}
+abstract class _Class&Super&Mixin = self::Super with req::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&Mixin
+    : super self::Super::•()
+    ;
+  forwarding-stub method /*isLegacy*/ method({covariant core::int* named = #C1}) → void
+    return super.{self::Super::method}(named: named);
+  abstract member-signature operator /*isLegacy*/ ==(dynamic other) → core::bool*; -> core::Object::==
+}
+class Class extends self::_Class&Super&Mixin {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Super&Mixin::•()
+    ;
+}
+class SubClass extends self::Class {
+  synthetic constructor •() → self::SubClass
+    : super self::Class::•()
+    ;
+  method method({required covariant core::int named = #C1}) → void {}
+}
+static method main() → dynamic {}
+
+library;
+import self as req;
+import "dart:core" as core;
+
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  method method({core::int* named = #C1}) → void {}
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.weak.transformed.expect
new file mode 100644
index 0000000..36edcc8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out.dart.weak.transformed.expect
@@ -0,0 +1,63 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "required_parameter_mixed_from_opt_out_lib.dart" as req;
+
+import "org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart";
+
+class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  method method({required covariant core::int named = #C1}) → void {}
+}
+abstract class _Class&Super&Mixin extends self::Super implements req::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&Mixin
+    : super self::Super::•()
+    ;
+  method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ method({covariant core::int* named = #C1}) → void {}
+  abstract member-signature operator /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ toString() → core::String*; -> core::Object::toString
+  abstract member-signature method /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get /*isLegacy, from org-dartlang-testcase:///required_parameter_mixed_from_opt_out_lib.dart */ runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Class extends self::_Class&Super&Mixin {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Super&Mixin::•()
+    ;
+}
+class SubClass extends self::Class {
+  synthetic constructor •() → self::SubClass
+    : super self::Class::•()
+    ;
+  method method({required covariant core::int named = #C1}) → void {}
+}
+static method main() → dynamic {}
+
+library;
+import self as req;
+import "dart:core" as core;
+
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  method method({core::int* named = #C1}) → void {}
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out_lib.dart b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out_lib.dart
new file mode 100644
index 0000000..922c203
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/required_parameter_mixed_from_opt_out_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+mixin Mixin {
+  void method({int named}) {}
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart
new file mode 100644
index 0000000..7980d5f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+import 'typedef_from_opt_in_lib.dart';
+
+Handler method1() => (Request r) async => new Response();
+
+Typedef method2() => (r) => 0;
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..90cf0f0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.9
+import 'typedef_from_opt_in_lib.dart';
+
+Handler method1() => (Request r) async => new Response();
+Typedef method2() => (r) => 0;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..90cf0f0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.9
+import 'typedef_from_opt_in_lib.dart';
+
+Handler method1() => (Request r) async => new Response();
+Typedef method2() => (r) => 0;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
new file mode 100644
index 0000000..95d0805
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "typedef_from_opt_in_lib.dart" as typ;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
+
+static method method1() → (typ::Request) →* FutureOr<typ::Response>
+  return (typ::Request* r) → asy::Future<typ::Response*>* async => new typ::Response::•();
+static method method2() → (core::int?) →* core::int
+  return (core::int* r) → core::int* => 0;
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as typ;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef Handler = (typ::Request) → FutureOr<typ::Response>;
+typedef Typedef = (core::int?) → core::int;
+class Request extends core::Object {
+  synthetic constructor •() → typ::Request
+    : super core::Object::•()
+    ;
+}
+class Response extends core::Object {
+  synthetic constructor •() → typ::Response
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
new file mode 100644
index 0000000..504f220
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
@@ -0,0 +1,58 @@
+library;
+import self as self;
+import "typedef_from_opt_in_lib.dart" as typ;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
+
+static method method1() → (typ::Request) →* FutureOr<typ::Response>
+  return (typ::Request* r) → asy::Future<typ::Response*>* /* originally async */ {
+    final asy::_Future<typ::Response*>* :async_future = new asy::_Future::•<typ::Response*>();
+    core::bool* :is_sync = false;
+    FutureOr<typ::Response*>* :return_value;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+    core::int* :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = new typ::Response::•();
+          break #L1;
+        }
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
+  };
+static method method2() → (core::int?) →* core::int
+  return (core::int* r) → core::int* => 0;
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as typ;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef Handler = (typ::Request) → FutureOr<typ::Response>;
+typedef Typedef = (core::int?) → core::int;
+class Request extends core::Object {
+  synthetic constructor •() → typ::Request
+    : super core::Object::•()
+    ;
+}
+class Response extends core::Object {
+  synthetic constructor •() → typ::Response
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in_lib.dart b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in_lib.dart
new file mode 100644
index 0000000..851b087
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in_lib.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+class Request {}
+
+class Response {}
+
+typedef Handler = FutureOr<Response> Function(Request request);
+
+typedef Typedef = int Function(int?);
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
index 20bc8a1..0f9dd17 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
@@ -112,9 +112,9 @@
   return !null.{core::Object::==}(i);
 static method ifNullOptOut(core::int* i) → dynamic
   return let final core::int* #t6 = i in #t6.{core::num::==}(null) ?{core::int*} 42 : #t6;
-static method OptOutExtension|[](final self::OptOutClass1* #this, core::int* index) → core::int*
+static method OptOutExtension|[](lowered final self::OptOutClass1* #this, core::int* index) → core::int*
   return index;
-static method OptOutExtension|[]=(final self::OptOutClass1* #this, core::int* index, core::int* value) → void {}
+static method OptOutExtension|[]=(lowered final self::OptOutClass1* #this, core::int* index, core::int* value) → void {}
 static method extensionIfNullOptOut1(core::int* i) → dynamic
   return let final self::OptOutClass1* #t7 = new self::OptOutClass1::•() in let final core::int* #t8 = i in let final core::int* #t9 = self::OptOutExtension|[](#t7, #t8) in #t9.{core::num::==}(null) ?{core::int*} let final core::int* #t10 = 42 in let final void #t11 = self::OptOutExtension|[]=(#t7, #t8, #t10) in #t10 : #t9;
 static method extensionIfNullOptOut1ForEffect(core::int* i) → dynamic {
@@ -454,9 +454,9 @@
   return !null.{core::Object::==}(i);
 static method ifNullOptIn(core::int i) → dynamic
   return let final core::int #t40 = i in #t40.{core::num::==}(null) ?{core::int} 42 : #t40;
-static method OptInExtension|[](final uns::OptInClass1 #this, core::int index) → core::int
+static method OptInExtension|[](lowered final uns::OptInClass1 #this, core::int index) → core::int
   return index;
-static method OptInExtension|[]=(final uns::OptInClass1 #this, core::int index, core::int value) → void {}
+static method OptInExtension|[]=(lowered final uns::OptInClass1 #this, core::int index, core::int value) → void {}
 static method extensionIfNullOptIn1(core::int i) → dynamic
   return let final uns::OptInClass1 #t41 = new uns::OptInClass1::•() in let final core::int #t42 = i in let final core::int #t43 = uns::OptInExtension|[](#t41, #t42) in #t43.{core::num::==}(null) ?{core::int} let final core::int #t44 = 42 in let final void #t45 = uns::OptInExtension|[]=(#t41, #t42, #t44) in #t44 : #t43;
 static method extensionIfNullOptIn1ForEffect(core::int i) → dynamic {
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
index 272a76b..54fdabb 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
@@ -112,9 +112,9 @@
   return !null.{core::Object::==}(i);
 static method ifNullOptOut(core::int* i) → dynamic
   return let final core::int* #t6 = i in #t6.{core::num::==}(null) ?{core::int*} 42 : #t6;
-static method OptOutExtension|[](final self::OptOutClass1* #this, core::int* index) → core::int*
+static method OptOutExtension|[](lowered final self::OptOutClass1* #this, core::int* index) → core::int*
   return index;
-static method OptOutExtension|[]=(final self::OptOutClass1* #this, core::int* index, core::int* value) → void {}
+static method OptOutExtension|[]=(lowered final self::OptOutClass1* #this, core::int* index, core::int* value) → void {}
 static method extensionIfNullOptOut1(core::int* i) → dynamic
   return let final self::OptOutClass1* #t7 = new self::OptOutClass1::•() in let final core::int* #t8 = i in let final core::int* #t9 = self::OptOutExtension|[](#t7, #t8) in #t9.{core::num::==}(null) ?{core::int*} let final core::int* #t10 = 42 in let final void #t11 = self::OptOutExtension|[]=(#t7, #t8, #t10) in #t10 : #t9;
 static method extensionIfNullOptOut1ForEffect(core::int* i) → dynamic {
@@ -454,9 +454,9 @@
   return !null.{core::Object::==}(i);
 static method ifNullOptIn(core::int i) → dynamic
   return let final core::int #t40 = i in #t40.{core::num::==}(null) ?{core::int} 42 : #t40;
-static method OptInExtension|[](final uns::OptInClass1 #this, core::int index) → core::int
+static method OptInExtension|[](lowered final uns::OptInClass1 #this, core::int index) → core::int
   return index;
-static method OptInExtension|[]=(final uns::OptInClass1 #this, core::int index, core::int value) → void {}
+static method OptInExtension|[]=(lowered final uns::OptInClass1 #this, core::int index, core::int value) → void {}
 static method extensionIfNullOptIn1(core::int i) → dynamic
   return let final uns::OptInClass1 #t41 = new uns::OptInClass1::•() in let final core::int #t42 = i in let final core::int #t43 = uns::OptInExtension|[](#t41, #t42) in #t43.{core::num::==}(null) ?{core::int} let final core::int #t44 = 42 in let final void #t45 = uns::OptInExtension|[]=(#t41, #t42, #t44) in #t44 : #t43;
 static method extensionIfNullOptIn1ForEffect(core::int i) → dynamic {
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 8ddb02d..259a2e3 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -14,7 +14,6 @@
 general_nnbd_opt_out/override_setter_with_field: TypeCheckError
 general/abstract_members: TypeCheckError
 general/bug30695: TypeCheckError
-general/constants/const_collections: TypeCheckError
 general/covariant_field: TypeCheckError
 general/getter_vs_setter_type: TypeCheckError
 general/infer_field_from_multiple: TypeCheckError
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart b/pkg/front_end/testcases/rasta/issue_000070.dart
index 95a5b07..838bc59 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart
@@ -7,7 +7,7 @@
 class A<N, S, U> {
   final List<U> field;
 
-  A(N n, S s) : field = new List<U>() {
+  A(N n, S s) : field = <U>[] {
     Expect.isTrue(n is N);
     Expect.isTrue(s is S);
   }
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
index 2d43401..b0b26de 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
@@ -8,7 +8,7 @@
 class A<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U extends core::Object* = dynamic> extends core::Object /*hasConstConstructor*/  {
   final field core::List<self::A::U*>* field;
   constructor •(self::A::N* n, self::A::S* s) → self::A<self::A::N*, self::A::S*, self::A::U*>*
-    : self::A::field = core::List::•<self::A::U*>(), super core::Object::•() {
+    : self::A::field = <self::A::U*>[], super core::Object::•() {
     exp::Expect::isTrue(n is self::A::N*);
     exp::Expect::isTrue(s is self::A::S*);
   }
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
index b0d7301..b0b26de 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
 class A<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U extends core::Object* = dynamic> extends core::Object /*hasConstConstructor*/  {
   final field core::List<self::A::U*>* field;
   constructor •(self::A::N* n, self::A::S* s) → self::A<self::A::N*, self::A::S*, self::A::U*>*
-    : self::A::field = core::_GrowableList::•<self::A::U*>(0), super core::Object::•() {
+    : self::A::field = <self::A::U*>[], super core::Object::•() {
     exp::Expect::isTrue(n is self::A::N*);
     exp::Expect::isTrue(s is self::A::S*);
   }
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
index 18be5ac..2184938 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
@@ -2,7 +2,7 @@
 
 class A<N, S, U> {
   final List<U> field;
-  A(N n, S s) : field = new List<U>() {}
+  A(N n, S s) : field = <U>[] {}
   A.empty() : field = null {}
   factory A.f(S s) {}
   const A.c(U u, S s) : field = const [null];
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
index cefd17f..919600b 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
@@ -5,7 +5,7 @@
 abstract class J<Aa, B> {}
 
 class A<N, S, U> {
-  A(N n, S s) : field = new List<U>() {}
+  A(N n, S s) : field = <U>[] {}
   A.empty() : field = null {}
   List<U> get getter {}
   const A.c(U u, S s) : field = const [null];
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
index 15f42cb..5b90ebe 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
@@ -63,7 +63,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -81,7 +80,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -92,7 +90,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -110,7 +107,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -121,7 +117,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -143,7 +138,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
index a16254c..8458a57 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
@@ -23,7 +23,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -40,7 +39,6 @@
           final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>* :return_value;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -58,7 +56,6 @@
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
               asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :async_op.call();
@@ -70,7 +67,6 @@
         function f_async_star() → core::int* /* originally async* */ {
           asy::_AsyncStarStreamController<dynamic>* :controller;
           dynamic :controller_stream;
-          dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
           (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
           core::int* :await_jump_var = 0;
@@ -95,7 +91,6 @@
             finally {
               :controller.{asy::_AsyncStarStreamController::close}();
             }
-          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
           :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
@@ -158,7 +153,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
index 01725ee..8e38e87 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
@@ -57,7 +57,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -115,7 +114,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -126,7 +124,6 @@
   final asy::_Future<core::Map<core::int*, core::bool*>*>* :async_future = new asy::_Future::•<core::Map<core::int*, core::bool*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::Map<core::int*, core::bool*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -144,7 +141,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -155,7 +151,6 @@
   final asy::_Future<core::Set<core::int*>*>* :async_future = new asy::_Future::•<core::Set<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::Set<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -175,7 +170,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -186,7 +180,6 @@
   final asy::_Future<core::Iterable<core::int*>*>* :async_future = new asy::_Future::•<core::Iterable<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::Iterable<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -206,7 +199,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -217,7 +209,6 @@
   final asy::_Future<col::LinkedHashSet<core::int*>*>* :async_future = new asy::_Future::•<col::LinkedHashSet<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<col::LinkedHashSet<core::int*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -243,7 +234,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
@@ -254,7 +244,6 @@
   final asy::_Future<col::LinkedHashMap<core::int*, core::bool*>*>* :async_future = new asy::_Future::•<col::LinkedHashMap<core::int*, core::bool*>*>();
   core::bool* :is_sync = false;
   FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -278,7 +267,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   :async_op.call();
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 20825b3..cdc1183 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -24,10 +24,6 @@
 general/callable_type_variable: TypeCheckError
 general/candidate_found: TypeCheckError
 general/cascade: RuntimeError
-general/constants/with_unevaluated_agnostic/const_asserts: TextSerializationFailure
-general/constants/with_unevaluated_agnostic/const_collections_2: TextSerializationFailure
-general/constants/with_unevaluated_agnostic/various: TextSerializationFailure
-general/constants/with_unevaluated_agnostic/various_2: TextSerializationFailure
 general/constructor_initializer_invalid: RuntimeError
 general/covariant_field: TypeCheckError
 general/covariant_generic: RuntimeError
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 1d7593c..0553975 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -118,6 +118,7 @@
 general/invalid_operator: FormatterCrash
 general/issue40242: FormatterCrash
 general/issue42997: FormatterCrash
+general/issue43363: FormatterCrash
 general/many_errors: FormatterCrash
 general/null_safety_invalid_experiment_and_language_version: FormatterCrash
 general/type_parameter_usage_in_static_method_in_extension: FormatterCrash
@@ -163,11 +164,13 @@
 late_lowering/late_final_nullable_field_with_initializer: FormatterCrash
 late_lowering/late_final_nullable_field_without_initializer: FormatterCrash
 late_lowering/late_future_or: FormatterCrash
+late_lowering/late_lowering_bitmasks: FormatterCrash
 late_lowering/late_nullable_field_with_initializer: FormatterCrash
 late_lowering/late_nullable_field_without_initializer: FormatterCrash
 late_lowering/later: FormatterCrash
 late_lowering/override: FormatterCrash
 late_lowering/override_getter_setter: FormatterCrash
+late_lowering/skip_late_final_uninitialized_instance_fields/main: FormatterCrash
 late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
 late_lowering_sentinel/late_fields: FormatterCrash
 nnbd/abstract_field_errors: FormatterCrash
@@ -258,3 +261,4 @@
 variance/generic_covariance_sound_variance: FormatterCrash
 variance/mixin_type_parameter_modifier: FormatterCrash
 variance/unconstrained_inference: FormatterCrash
+
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial.dart b/pkg/front_end/testcases/unified_collections/fold_initial.dart
new file mode 100644
index 0000000..a0fdadd
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/fold_initial.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+void foldInitialElements() {
+  dynamic element0 = 0;
+  num element1 = 1;
+  int element2 = 2;
+  var list = <int>[element0, element1, element2, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{element0, element1, element2, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+void foldInitialSpread1() {
+  dynamic initial = [0, 1, 2];
+  var list = <int>[...initial, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{...initial, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+void foldInitialSpread2() {
+  Iterable<num> initial = [0, 1, 2];
+  var list = <int>[...initial, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{...initial, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+void foldInitialSpread3() {
+  List<num> initial = [0, 1, 2];
+  var list = <int>[...initial, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{...initial, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+void foldInitialSpread4() {
+  Iterable<int> initial = [0, 1, 2];
+  var list = <int>[...initial, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{...initial, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+void foldInitialSpread5() {
+  List<int> initial = [0, 1, 2];
+  var list = <int>[...initial, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{...initial, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+void foldInitialSpread6() {
+  List<int> initial = [0, 1, 2];
+  var list = <int>[...?initial, if (true) 3, 4, 5, 6];
+
+  expect(new List<int>.generate(7, (int i) => i), list);
+
+  var set = <int>{...?initial, if (true) 3, 4, 5, 6};
+
+  expect(new List<int>.generate(7, (int i) => i), set.toList());
+}
+
+main() {
+  foldInitialElements();
+  foldInitialSpread1();
+  foldInitialSpread2();
+  foldInitialSpread3();
+  foldInitialSpread4();
+  foldInitialSpread5();
+  foldInitialSpread6();
+}
+
+void expect(List list1, List list2) {
+  if (list1.length != list2.length) {
+    throw 'Unexpected length. Expected ${list1.length}, actual ${list2.length}.';
+  }
+  for (int i = 0; i < list1.length; i++) {
+    if (list1[i] != list2[i]) {
+      throw 'Unexpected element at index $i. '
+          'Expected ${list1[i]}, actual ${list2[i]}.';
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/fold_initial.dart.textual_outline.expect
new file mode 100644
index 0000000..d2d7d8d
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/fold_initial.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.9
+void foldInitialElements() {}
+void foldInitialSpread1() {}
+void foldInitialSpread2() {}
+void foldInitialSpread3() {}
+void foldInitialSpread4() {}
+void foldInitialSpread5() {}
+void foldInitialSpread6() {}
+main() {}
+void expect(List list1, List list2) {}
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/fold_initial.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aef8b8f
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/fold_initial.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.9
+main() {}
+void expect(List list1, List list2) {}
+void foldInitialElements() {}
+void foldInitialSpread1() {}
+void foldInitialSpread2() {}
+void foldInitialSpread3() {}
+void foldInitialSpread4() {}
+void foldInitialSpread5() {}
+void foldInitialSpread6() {}
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.expect b/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.expect
new file mode 100644
index 0000000..21d66e0
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.expect
@@ -0,0 +1,206 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+static method foldInitialElements() → void {
+  dynamic element0 = 0;
+  core::num* element1 = 1;
+  core::int* element2 = 2;
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t1 = <core::int*>[element0 as{TypeError,ForDynamic} core::int*, element1 as{TypeError} core::int*, element2];
+    if(true)
+      #t1.{core::List::add}{Invariant}(3);
+    #t1.{core::List::add}{Invariant}(4);
+    #t1.{core::List::add}{Invariant}(5);
+    #t1.{core::List::add}{Invariant}(6);
+  } =>#t1;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t2 = col::LinkedHashSet::•<core::int*>();
+    #t2.{core::Set::add}{Invariant}(element0 as{TypeError,ForDynamic} core::int*);
+    #t2.{core::Set::add}{Invariant}(element1 as{TypeError} core::int*);
+    #t2.{core::Set::add}{Invariant}(element2);
+    if(true)
+      #t2.{core::Set::add}{Invariant}(3);
+    #t2.{core::Set::add}{Invariant}(4);
+    #t2.{core::Set::add}{Invariant}(5);
+    #t2.{core::Set::add}{Invariant}(6);
+  } =>#t2;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread1() → void {
+  dynamic initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t3 = <core::int*>[];
+    for (final dynamic #t4 in initial as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t5 = #t4 as{TypeError} core::int*;
+      #t3.{core::List::add}{Invariant}(#t5);
+    }
+    if(true)
+      #t3.{core::List::add}{Invariant}(3);
+    #t3.{core::List::add}{Invariant}(4);
+    #t3.{core::List::add}{Invariant}(5);
+    #t3.{core::List::add}{Invariant}(6);
+  } =>#t3;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t6 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t7 in initial as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t8 = #t7 as{TypeError} core::int*;
+      #t6.{core::Set::add}{Invariant}(#t8);
+    }
+    if(true)
+      #t6.{core::Set::add}{Invariant}(3);
+    #t6.{core::Set::add}{Invariant}(4);
+    #t6.{core::Set::add}{Invariant}(5);
+    #t6.{core::Set::add}{Invariant}(6);
+  } =>#t6;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread2() → void {
+  core::Iterable<core::num*>* initial = <core::num*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t9 = <core::int*>[];
+    for (final dynamic #t10 in initial) {
+      final core::int* #t11 = #t10 as{TypeError} core::int*;
+      #t9.{core::List::add}{Invariant}(#t11);
+    }
+    if(true)
+      #t9.{core::List::add}{Invariant}(3);
+    #t9.{core::List::add}{Invariant}(4);
+    #t9.{core::List::add}{Invariant}(5);
+    #t9.{core::List::add}{Invariant}(6);
+  } =>#t9;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t12 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t13 in initial) {
+      final core::int* #t14 = #t13 as{TypeError} core::int*;
+      #t12.{core::Set::add}{Invariant}(#t14);
+    }
+    if(true)
+      #t12.{core::Set::add}{Invariant}(3);
+    #t12.{core::Set::add}{Invariant}(4);
+    #t12.{core::Set::add}{Invariant}(5);
+    #t12.{core::Set::add}{Invariant}(6);
+  } =>#t12;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread3() → void {
+  core::List<core::num*>* initial = <core::num*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t15 = <core::int*>[];
+    for (final dynamic #t16 in initial) {
+      final core::int* #t17 = #t16 as{TypeError} core::int*;
+      #t15.{core::List::add}{Invariant}(#t17);
+    }
+    if(true)
+      #t15.{core::List::add}{Invariant}(3);
+    #t15.{core::List::add}{Invariant}(4);
+    #t15.{core::List::add}{Invariant}(5);
+    #t15.{core::List::add}{Invariant}(6);
+  } =>#t15;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t18 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t19 in initial) {
+      final core::int* #t20 = #t19 as{TypeError} core::int*;
+      #t18.{core::Set::add}{Invariant}(#t20);
+    }
+    if(true)
+      #t18.{core::Set::add}{Invariant}(3);
+    #t18.{core::Set::add}{Invariant}(4);
+    #t18.{core::Set::add}{Invariant}(5);
+    #t18.{core::Set::add}{Invariant}(6);
+  } =>#t18;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread4() → void {
+  core::Iterable<core::int*>* initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t21 = core::List::of<core::int*>(initial);
+    if(true)
+      #t21.{core::List::add}{Invariant}(3);
+    #t21.{core::List::add}{Invariant}(4);
+    #t21.{core::List::add}{Invariant}(5);
+    #t21.{core::List::add}{Invariant}(6);
+  } =>#t21;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t22 = col::LinkedHashSet::of<core::int*>(initial);
+    if(true)
+      #t22.{core::Set::add}{Invariant}(3);
+    #t22.{core::Set::add}{Invariant}(4);
+    #t22.{core::Set::add}{Invariant}(5);
+    #t22.{core::Set::add}{Invariant}(6);
+  } =>#t22;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread5() → void {
+  core::List<core::int*>* initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t23 = core::List::of<core::int*>(initial);
+    if(true)
+      #t23.{core::List::add}{Invariant}(3);
+    #t23.{core::List::add}{Invariant}(4);
+    #t23.{core::List::add}{Invariant}(5);
+    #t23.{core::List::add}{Invariant}(6);
+  } =>#t23;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t24 = col::LinkedHashSet::of<core::int*>(initial);
+    if(true)
+      #t24.{core::Set::add}{Invariant}(3);
+    #t24.{core::Set::add}{Invariant}(4);
+    #t24.{core::Set::add}{Invariant}(5);
+    #t24.{core::Set::add}{Invariant}(6);
+  } =>#t24;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread6() → void {
+  core::List<core::int*>* initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t25 = <core::int*>[];
+    final core::Iterable<core::int*>* #t26 = initial;
+    if(!#t26.{core::Object::==}(null))
+      #t25.{core::List::addAll}{Invariant}(#t26);
+    if(true)
+      #t25.{core::List::add}{Invariant}(3);
+    #t25.{core::List::add}{Invariant}(4);
+    #t25.{core::List::add}{Invariant}(5);
+    #t25.{core::List::add}{Invariant}(6);
+  } =>#t25;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t27 = col::LinkedHashSet::•<core::int*>();
+    final core::Iterable<core::int*>* #t28 = initial;
+    if(!#t28.{core::Object::==}(null))
+      #t27.{core::Set::addAll}{Invariant}(#t28);
+    if(true)
+      #t27.{core::Set::add}{Invariant}(3);
+    #t27.{core::Set::add}{Invariant}(4);
+    #t27.{core::Set::add}{Invariant}(5);
+    #t27.{core::Set::add}{Invariant}(6);
+  } =>#t27;
+  self::expect(core::List::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method main() → dynamic {
+  self::foldInitialElements();
+  self::foldInitialSpread1();
+  self::foldInitialSpread2();
+  self::foldInitialSpread3();
+  self::foldInitialSpread4();
+  self::foldInitialSpread5();
+  self::foldInitialSpread6();
+}
+static method expect(core::List<dynamic>* list1, core::List<dynamic>* list2) → void {
+  if(!list1.{core::List::length}.{core::num::==}(list2.{core::List::length})) {
+    throw "Unexpected length. Expected ${list1.{core::List::length}}, actual ${list2.{core::List::length}}.";
+  }
+  for (core::int* i = 0; i.{core::num::<}(list1.{core::List::length}); i = i.{core::num::+}(1)) {
+    if(!list1.{core::List::[]}(i).{core::Object::==}(list2.{core::List::[]}(i))) {
+      throw "Unexpected element at index ${i}. Expected ${list1.{core::List::[]}(i)}, actual ${list2.{core::List::[]}(i)}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect
new file mode 100644
index 0000000..9108424
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect
@@ -0,0 +1,242 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+static method foldInitialElements() → void {
+  dynamic element0 = 0;
+  core::num* element1 = 1;
+  core::int* element2 = 2;
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t1 = <core::int*>[element0 as{TypeError,ForDynamic} core::int*, element1 as{TypeError} core::int*, element2];
+    if(true)
+      #t1.{core::List::add}{Invariant}(3);
+    #t1.{core::List::add}{Invariant}(4);
+    #t1.{core::List::add}{Invariant}(5);
+    #t1.{core::List::add}{Invariant}(6);
+  } =>#t1;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t2 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t2.{core::Set::add}{Invariant}(element0 as{TypeError,ForDynamic} core::int*);
+    #t2.{core::Set::add}{Invariant}(element1 as{TypeError} core::int*);
+    #t2.{core::Set::add}{Invariant}(element2);
+    if(true)
+      #t2.{core::Set::add}{Invariant}(3);
+    #t2.{core::Set::add}{Invariant}(4);
+    #t2.{core::Set::add}{Invariant}(5);
+    #t2.{core::Set::add}{Invariant}(6);
+  } =>#t2;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread1() → void {
+  dynamic initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t3 = <core::int*>[];
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (initial as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t5 = #t4 as{TypeError} core::int*;
+          #t3.{core::List::add}{Invariant}(#t5);
+        }
+      }
+    }
+    if(true)
+      #t3.{core::List::add}{Invariant}(3);
+    #t3.{core::List::add}{Invariant}(4);
+    #t3.{core::List::add}{Invariant}(5);
+    #t3.{core::List::add}{Invariant}(6);
+  } =>#t3;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t6 = new col::_CompactLinkedHashSet::•<core::int*>();
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (initial as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t7 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t8 = #t7 as{TypeError} core::int*;
+          #t6.{core::Set::add}{Invariant}(#t8);
+        }
+      }
+    }
+    if(true)
+      #t6.{core::Set::add}{Invariant}(3);
+    #t6.{core::Set::add}{Invariant}(4);
+    #t6.{core::Set::add}{Invariant}(5);
+    #t6.{core::Set::add}{Invariant}(6);
+  } =>#t6;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread2() → void {
+  core::Iterable<core::num*>* initial = <core::num*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t9 = <core::int*>[];
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = initial.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t11 = #t10 as{TypeError} core::int*;
+          #t9.{core::List::add}{Invariant}(#t11);
+        }
+      }
+    }
+    if(true)
+      #t9.{core::List::add}{Invariant}(3);
+    #t9.{core::List::add}{Invariant}(4);
+    #t9.{core::List::add}{Invariant}(5);
+    #t9.{core::List::add}{Invariant}(6);
+  } =>#t9;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t12 = new col::_CompactLinkedHashSet::•<core::int*>();
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = initial.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t13 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t14 = #t13 as{TypeError} core::int*;
+          #t12.{core::Set::add}{Invariant}(#t14);
+        }
+      }
+    }
+    if(true)
+      #t12.{core::Set::add}{Invariant}(3);
+    #t12.{core::Set::add}{Invariant}(4);
+    #t12.{core::Set::add}{Invariant}(5);
+    #t12.{core::Set::add}{Invariant}(6);
+  } =>#t12;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread3() → void {
+  core::List<core::num*>* initial = <core::num*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t15 = <core::int*>[];
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = initial.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t17 = #t16 as{TypeError} core::int*;
+          #t15.{core::List::add}{Invariant}(#t17);
+        }
+      }
+    }
+    if(true)
+      #t15.{core::List::add}{Invariant}(3);
+    #t15.{core::List::add}{Invariant}(4);
+    #t15.{core::List::add}{Invariant}(5);
+    #t15.{core::List::add}{Invariant}(6);
+  } =>#t15;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t18 = new col::_CompactLinkedHashSet::•<core::int*>();
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = initial.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t20 = #t19 as{TypeError} core::int*;
+          #t18.{core::Set::add}{Invariant}(#t20);
+        }
+      }
+    }
+    if(true)
+      #t18.{core::Set::add}{Invariant}(3);
+    #t18.{core::Set::add}{Invariant}(4);
+    #t18.{core::Set::add}{Invariant}(5);
+    #t18.{core::Set::add}{Invariant}(6);
+  } =>#t18;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread4() → void {
+  core::Iterable<core::int*>* initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t21 = core::List::of<core::int*>(initial);
+    if(true)
+      #t21.{core::List::add}{Invariant}(3);
+    #t21.{core::List::add}{Invariant}(4);
+    #t21.{core::List::add}{Invariant}(5);
+    #t21.{core::List::add}{Invariant}(6);
+  } =>#t21;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t22 = col::LinkedHashSet::of<core::int*>(initial);
+    if(true)
+      #t22.{core::Set::add}{Invariant}(3);
+    #t22.{core::Set::add}{Invariant}(4);
+    #t22.{core::Set::add}{Invariant}(5);
+    #t22.{core::Set::add}{Invariant}(6);
+  } =>#t22;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread5() → void {
+  core::List<core::int*>* initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t23 = core::List::of<core::int*>(initial);
+    if(true)
+      #t23.{core::List::add}{Invariant}(3);
+    #t23.{core::List::add}{Invariant}(4);
+    #t23.{core::List::add}{Invariant}(5);
+    #t23.{core::List::add}{Invariant}(6);
+  } =>#t23;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t24 = col::LinkedHashSet::of<core::int*>(initial);
+    if(true)
+      #t24.{core::Set::add}{Invariant}(3);
+    #t24.{core::Set::add}{Invariant}(4);
+    #t24.{core::Set::add}{Invariant}(5);
+    #t24.{core::Set::add}{Invariant}(6);
+  } =>#t24;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method foldInitialSpread6() → void {
+  core::List<core::int*>* initial = <core::int*>[0, 1, 2];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t25 = <core::int*>[];
+    final core::Iterable<core::int*>* #t26 = initial;
+    if(!#t26.{core::Object::==}(null))
+      #t25.{core::List::addAll}{Invariant}(#t26);
+    if(true)
+      #t25.{core::List::add}{Invariant}(3);
+    #t25.{core::List::add}{Invariant}(4);
+    #t25.{core::List::add}{Invariant}(5);
+    #t25.{core::List::add}{Invariant}(6);
+  } =>#t25;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t27 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Iterable<core::int*>* #t28 = initial;
+    if(!#t28.{core::Object::==}(null))
+      #t27.{core::Set::addAll}{Invariant}(#t28);
+    if(true)
+      #t27.{core::Set::add}{Invariant}(3);
+    #t27.{core::Set::add}{Invariant}(4);
+    #t27.{core::Set::add}{Invariant}(5);
+    #t27.{core::Set::add}{Invariant}(6);
+  } =>#t27;
+  self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), set.{core::Iterable::toList}());
+}
+static method main() → dynamic {
+  self::foldInitialElements();
+  self::foldInitialSpread1();
+  self::foldInitialSpread2();
+  self::foldInitialSpread3();
+  self::foldInitialSpread4();
+  self::foldInitialSpread5();
+  self::foldInitialSpread6();
+}
+static method expect(core::List<dynamic>* list1, core::List<dynamic>* list2) → void {
+  if(!list1.{core::List::length}.{core::num::==}(list2.{core::List::length})) {
+    throw "Unexpected length. Expected ${list1.{core::List::length}}, actual ${list2.{core::List::length}}.";
+  }
+  for (core::int* i = 0; i.{core::num::<}(list1.{core::List::length}); i = i.{core::num::+}(1)) {
+    if(!list1.{core::List::[]}(i).{core::Object::==}(list2.{core::List::[]}(i))) {
+      throw "Unexpected element at index ${i}. Expected ${list1.{core::List::[]}(i)}, actual ${list2.{core::List::[]}(i)}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/folder.options b/pkg/front_end/testcases/unified_collections/folder.options
index dbc148e..e69de29 100644
--- a/pkg/front_end/testcases/unified_collections/folder.options
+++ b/pkg/front_end/testcases/unified_collections/folder.options
@@ -1 +0,0 @@
---enable-experiment=no-non-nullable
\ No newline at end of file
diff --git a/pkg/front_end/testcases/unified_collections/invariance.dart.outline.expect b/pkg/front_end/testcases/unified_collections/invariance.dart.outline.expect
deleted file mode 100644
index 6a28c0d..0000000
--- a/pkg/front_end/testcases/unified_collections/invariance.dart.outline.expect
+++ /dev/null
@@ -1,5 +0,0 @@
-library;
-import self as self;
-
-static method main() → dynamic
-  ;
diff --git a/pkg/front_end/testcases/unified_collections/invariance.dart.strong.expect b/pkg/front_end/testcases/unified_collections/invariance.dart.strong.expect
deleted file mode 100644
index ebbf96d..0000000
--- a/pkg/front_end/testcases/unified_collections/invariance.dart.strong.expect
+++ /dev/null
@@ -1,75 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-import "dart:collection" as col;
-
-static method main() → dynamic {
-  core::List<core::int*>* list1 = <core::int*>[0];
-  core::List<core::num*>* list2 = <core::num*>[0];
-  dynamic list3 = <core::int*>[0];
-  core::List<core::int*>* list = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(0);
-    for (final core::int* #t2 in list1)
-      #t1.{core::List::add}{Invariant}(#t2);
-    for (final dynamic #t3 in list2) {
-      final core::int* #t4 = #t3 as{TypeError} core::int*;
-      #t1.{core::List::add}{Invariant}(#t4);
-    }
-    for (final dynamic #t5 in list3 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-      final core::int* #t6 = #t5 as{TypeError} core::int*;
-      #t1.{core::List::add}{Invariant}(#t6);
-    }
-    if(true)
-      #t1.{core::List::add}{Invariant}(2);
-  } =>#t1;
-  core::Set<core::int*>* set1 = block {
-    final core::Set<core::int*>* #t7 = col::LinkedHashSet::•<core::int*>();
-    #t7.{core::Set::add}{Invariant}(0);
-  } =>#t7;
-  core::Set<core::num*>* set2 = block {
-    final core::Set<core::num*>* #t8 = col::LinkedHashSet::•<core::num*>();
-    #t8.{core::Set::add}{Invariant}(0);
-  } =>#t8;
-  dynamic set3 = block {
-    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
-    #t9.{core::Set::add}{Invariant}(0);
-  } =>#t9;
-  core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t10 = col::LinkedHashSet::•<core::int*>();
-    #t10.{core::Set::add}{Invariant}(0);
-    for (final core::int* #t11 in set1)
-      #t10.{core::Set::add}{Invariant}(#t11);
-    for (final dynamic #t12 in set2) {
-      final core::int* #t13 = #t12 as{TypeError} core::int*;
-      #t10.{core::Set::add}{Invariant}(#t13);
-    }
-    for (final dynamic #t14 in set3 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-      final core::int* #t15 = #t14 as{TypeError} core::int*;
-      #t10.{core::Set::add}{Invariant}(#t15);
-    }
-    if(true)
-      #t10.{core::Set::add}{Invariant}(2);
-  } =>#t10;
-  core::Map<core::int*, core::String*>* map1 = <core::int*, core::String*>{0: "foo"};
-  core::Map<core::num*, core::Object*>* map2 = <core::num*, core::Object*>{0: "bar"};
-  dynamic map3 = <core::int*, core::String*>{0: "baz"};
-  core::Map<core::int*, core::String*>* map = block {
-    final core::Map<core::int*, core::String*>* #t16 = <core::int*, core::String*>{};
-    #t16.{core::Map::[]=}{Invariant}(0, "foo");
-    for (final core::MapEntry<core::int*, core::String*>* #t17 in map1.{core::Map::entries})
-      #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-    for (final core::MapEntry<dynamic, dynamic>* #t18 in map2.{core::Map::entries}) {
-      final core::int* #t19 = #t18.{core::MapEntry::key} as{TypeError} core::int*;
-      final core::String* #t20 = #t18.{core::MapEntry::value} as{TypeError} core::String*;
-      #t16.{core::Map::[]=}{Invariant}(#t19, #t20);
-    }
-    for (final core::MapEntry<dynamic, dynamic>* #t21 in (map3 as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
-      final core::int* #t22 = #t21.{core::MapEntry::key} as{TypeError} core::int*;
-      final core::String* #t23 = #t21.{core::MapEntry::value} as{TypeError} core::String*;
-      #t16.{core::Map::[]=}{Invariant}(#t22, #t23);
-    }
-    if(true)
-      #t16.{core::Map::[]=}{Invariant}(2, "baz");
-  } =>#t16;
-}
diff --git a/pkg/front_end/testcases/unified_collections/invariance.dart.strong.transformed.expect b/pkg/front_end/testcases/unified_collections/invariance.dart.strong.transformed.expect
deleted file mode 100644
index a1ce6d8..0000000
--- a/pkg/front_end/testcases/unified_collections/invariance.dart.strong.transformed.expect
+++ /dev/null
@@ -1,126 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-import "dart:collection" as col;
-
-static method main() → dynamic {
-  core::List<core::int*>* list1 = <core::int*>[0];
-  core::List<core::num*>* list2 = <core::num*>[0];
-  dynamic list3 = <core::int*>[0];
-  core::List<core::int*>* list = block {
-    final core::List<core::int*>* #t1 = <core::int*>[];
-    #t1.{core::List::add}{Invariant}(0);
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = list1.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t2 = :sync-for-iterator.{core::Iterator::current};
-        #t1.{core::List::add}{Invariant}(#t2);
-      }
-    }
-    {
-      core::Iterator<core::num*>* :sync-for-iterator = list2.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t3 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t4 = #t3 as{TypeError} core::int*;
-          #t1.{core::List::add}{Invariant}(#t4);
-        }
-      }
-    }
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = (list3 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t5 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t6 = #t5 as{TypeError} core::int*;
-          #t1.{core::List::add}{Invariant}(#t6);
-        }
-      }
-    }
-    if(true)
-      #t1.{core::List::add}{Invariant}(2);
-  } =>#t1;
-  core::Set<core::int*>* set1 = block {
-    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t7.{core::Set::add}{Invariant}(0);
-  } =>#t7;
-  core::Set<core::num*>* set2 = block {
-    final core::Set<core::num*>* #t8 = new col::_CompactLinkedHashSet::•<core::num*>();
-    #t8.{core::Set::add}{Invariant}(0);
-  } =>#t8;
-  dynamic set3 = block {
-    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t9.{core::Set::add}{Invariant}(0);
-  } =>#t9;
-  core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t10 = new col::_CompactLinkedHashSet::•<core::int*>();
-    #t10.{core::Set::add}{Invariant}(0);
-    {
-      core::Iterator<core::int*>* :sync-for-iterator = set1.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::int* #t11 = :sync-for-iterator.{core::Iterator::current};
-        #t10.{core::Set::add}{Invariant}(#t11);
-      }
-    }
-    {
-      core::Iterator<core::num*>* :sync-for-iterator = set2.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t13 = #t12 as{TypeError} core::int*;
-          #t10.{core::Set::add}{Invariant}(#t13);
-        }
-      }
-    }
-    {
-      core::Iterator<dynamic>* :sync-for-iterator = (set3 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t15 = #t14 as{TypeError} core::int*;
-          #t10.{core::Set::add}{Invariant}(#t15);
-        }
-      }
-    }
-    if(true)
-      #t10.{core::Set::add}{Invariant}(2);
-  } =>#t10;
-  core::Map<core::int*, core::String*>* map1 = <core::int*, core::String*>{0: "foo"};
-  core::Map<core::num*, core::Object*>* map2 = <core::num*, core::Object*>{0: "bar"};
-  dynamic map3 = <core::int*, core::String*>{0: "baz"};
-  core::Map<core::int*, core::String*>* map = block {
-    final core::Map<core::int*, core::String*>* #t16 = <core::int*, core::String*>{};
-    #t16.{core::Map::[]=}{Invariant}(0, "foo");
-    {
-      core::Iterator<core::MapEntry<core::int*, core::String*>>* :sync-for-iterator = map1.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int*, core::String*>* #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-      }
-    }
-    {
-      core::Iterator<core::MapEntry<core::num*, core::Object*>>* :sync-for-iterator = map2.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t18 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t19 = #t18.{core::MapEntry::key} as{TypeError} core::int*;
-          final core::String* #t20 = #t18.{core::MapEntry::value} as{TypeError} core::String*;
-          #t16.{core::Map::[]=}{Invariant}(#t19, #t20);
-        }
-      }
-    }
-    {
-      core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (map3 as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, dynamic>* #t21 = :sync-for-iterator.{core::Iterator::current};
-        {
-          final core::int* #t22 = #t21.{core::MapEntry::key} as{TypeError} core::int*;
-          final core::String* #t23 = #t21.{core::MapEntry::value} as{TypeError} core::String*;
-          #t16.{core::Map::[]=}{Invariant}(#t22, #t23);
-        }
-      }
-    }
-    if(true)
-      #t16.{core::Map::[]=}{Invariant}(2, "baz");
-  } =>#t16;
-}
diff --git a/pkg/front_end/testcases/unified_collections/invariance.dart.weak.expect b/pkg/front_end/testcases/unified_collections/invariance.dart.weak.expect
new file mode 100644
index 0000000..63b5ee2
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/invariance.dart.weak.expect
@@ -0,0 +1,72 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+static method main() → dynamic {
+  core::List<core::int*>* list1 = <core::int*>[0];
+  core::List<core::num*>* list2 = <core::num*>[0];
+  dynamic list3 = <core::int*>[0];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t1 = <core::int*>[0];
+    #t1.{core::List::addAll}{Invariant}(list1);
+    for (final dynamic #t2 in list2) {
+      final core::int* #t3 = #t2 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t3);
+    }
+    for (final dynamic #t4 in list3 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t5 = #t4 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t5);
+    }
+    if(true)
+      #t1.{core::List::add}{Invariant}(2);
+  } =>#t1;
+  core::Set<core::int*>* set1 = block {
+    final core::Set<core::int*>* #t6 = col::LinkedHashSet::•<core::int*>();
+    #t6.{core::Set::add}{Invariant}(0);
+  } =>#t6;
+  core::Set<core::num*>* set2 = block {
+    final core::Set<core::num*>* #t7 = col::LinkedHashSet::•<core::num*>();
+    #t7.{core::Set::add}{Invariant}(0);
+  } =>#t7;
+  dynamic set3 = block {
+    final core::Set<core::int*>* #t8 = col::LinkedHashSet::•<core::int*>();
+    #t8.{core::Set::add}{Invariant}(0);
+  } =>#t8;
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
+    #t9.{core::Set::add}{Invariant}(0);
+    #t9.{core::Set::addAll}{Invariant}(set1);
+    for (final dynamic #t10 in set2) {
+      final core::int* #t11 = #t10 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t11);
+    }
+    for (final dynamic #t12 in set3 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t13 = #t12 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t13);
+    }
+    if(true)
+      #t9.{core::Set::add}{Invariant}(2);
+  } =>#t9;
+  core::Map<core::int*, core::String*>* map1 = <core::int*, core::String*>{0: "foo"};
+  core::Map<core::num*, core::Object*>* map2 = <core::num*, core::Object*>{0: "bar"};
+  dynamic map3 = <core::int*, core::String*>{0: "baz"};
+  core::Map<core::int*, core::String*>* map = block {
+    final core::Map<core::int*, core::String*>* #t14 = <core::int*, core::String*>{};
+    #t14.{core::Map::[]=}{Invariant}(0, "foo");
+    for (final core::MapEntry<core::int*, core::String*>* #t15 in map1.{core::Map::entries})
+      #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+    for (final core::MapEntry<dynamic, dynamic>* #t16 in map2.{core::Map::entries}) {
+      final core::int* #t17 = #t16.{core::MapEntry::key} as{TypeError} core::int*;
+      final core::String* #t18 = #t16.{core::MapEntry::value} as{TypeError} core::String*;
+      #t14.{core::Map::[]=}{Invariant}(#t17, #t18);
+    }
+    for (final core::MapEntry<dynamic, dynamic>* #t19 in (map3 as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}) {
+      final core::int* #t20 = #t19.{core::MapEntry::key} as{TypeError} core::int*;
+      final core::String* #t21 = #t19.{core::MapEntry::value} as{TypeError} core::String*;
+      #t14.{core::Map::[]=}{Invariant}(#t20, #t21);
+    }
+    if(true)
+      #t14.{core::Map::[]=}{Invariant}(2, "baz");
+  } =>#t14;
+}
diff --git a/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect
new file mode 100644
index 0000000..8970ba8
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect
@@ -0,0 +1,113 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+static method main() → dynamic {
+  core::List<core::int*>* list1 = <core::int*>[0];
+  core::List<core::num*>* list2 = <core::num*>[0];
+  dynamic list3 = <core::int*>[0];
+  core::List<core::int*>* list = block {
+    final core::List<core::int*>* #t1 = <core::int*>[0];
+    #t1.{core::List::addAll}{Invariant}(list1);
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = list2.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t3 = #t2 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t3);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (list3 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t5 = #t4 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t5);
+        }
+      }
+    }
+    if(true)
+      #t1.{core::List::add}{Invariant}(2);
+  } =>#t1;
+  core::Set<core::int*>* set1 = block {
+    final core::Set<core::int*>* #t6 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t6.{core::Set::add}{Invariant}(0);
+  } =>#t6;
+  core::Set<core::num*>* set2 = block {
+    final core::Set<core::num*>* #t7 = new col::_CompactLinkedHashSet::•<core::num*>();
+    #t7.{core::Set::add}{Invariant}(0);
+  } =>#t7;
+  dynamic set3 = block {
+    final core::Set<core::int*>* #t8 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t8.{core::Set::add}{Invariant}(0);
+  } =>#t8;
+  core::Set<core::int*>* set = block {
+    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t9.{core::Set::add}{Invariant}(0);
+    #t9.{core::Set::addAll}{Invariant}(set1);
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = set2.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t11 = #t10 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t11);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (set3 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t13 = #t12 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t13);
+        }
+      }
+    }
+    if(true)
+      #t9.{core::Set::add}{Invariant}(2);
+  } =>#t9;
+  core::Map<core::int*, core::String*>* map1 = <core::int*, core::String*>{0: "foo"};
+  core::Map<core::num*, core::Object*>* map2 = <core::num*, core::Object*>{0: "bar"};
+  dynamic map3 = <core::int*, core::String*>{0: "baz"};
+  core::Map<core::int*, core::String*>* map = block {
+    final core::Map<core::int*, core::String*>* #t14 = <core::int*, core::String*>{};
+    #t14.{core::Map::[]=}{Invariant}(0, "foo");
+    {
+      core::Iterator<core::MapEntry<core::int*, core::String*>>* :sync-for-iterator = map1.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::int*, core::String*>* #t15 = :sync-for-iterator.{core::Iterator::current};
+        #t14.{core::Map::[]=}{Invariant}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
+      }
+    }
+    {
+      core::Iterator<core::MapEntry<core::num*, core::Object*>>* :sync-for-iterator = map2.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<dynamic, dynamic>* #t16 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t17 = #t16.{core::MapEntry::key} as{TypeError} core::int*;
+          final core::String* #t18 = #t16.{core::MapEntry::value} as{TypeError} core::String*;
+          #t14.{core::Map::[]=}{Invariant}(#t17, #t18);
+        }
+      }
+    }
+    {
+      core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = (map3 as{TypeError,ForDynamic} core::Map<dynamic, dynamic>*).{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<dynamic, dynamic>* #t19 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t20 = #t19.{core::MapEntry::key} as{TypeError} core::int*;
+          final core::String* #t21 = #t19.{core::MapEntry::value} as{TypeError} core::String*;
+          #t14.{core::Map::[]=}{Invariant}(#t20, #t21);
+        }
+      }
+    }
+    if(true)
+      #t14.{core::Map::[]=}{Invariant}(2, "baz");
+  } =>#t14;
+}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all.dart b/pkg/front_end/testcases/unified_collections/list_add_all.dart
new file mode 100644
index 0000000..c6c02de
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+void useAddAll() {
+  dynamic dynamicList1 = <int>[0, 1, 2];
+  dynamic dynamicList2 = <num>[3, 4, 5];
+  Iterable<int> iterableIntList = <int>[6, 7, 8];
+  Iterable<num> iterableNumList1 = <int>[9, 10, 11];
+  Iterable<num> iterableNumList2 = <num>[12, 13, 14];
+  List<int> intList = <int>[15, 16, 17];
+  List<num> numList1 = <int>[18, 19, 20];
+  List<num> numList2 = <num>[21, 22, 23];
+
+  var list1 = <int>[
+    ...dynamicList1,
+    ...dynamicList2,
+    ...iterableIntList,
+    ...iterableNumList1,
+    ...iterableNumList2,
+    ...intList,
+    ...numList1,
+    ...numList2
+  ];
+
+  expect(new List<int>.generate(24, (int i) => i), list1);
+
+  var list2 = <num>[
+    ...dynamicList1,
+    ...dynamicList2,
+    ...iterableIntList,
+    ...iterableNumList1,
+    ...iterableNumList2,
+    ...intList,
+    ...numList1,
+    ...numList2
+  ];
+
+  expect(new List<num>.generate(24, (int i) => i), list2);
+
+  var list3 = <int>[
+    ...?dynamicList1,
+    ...?dynamicList2,
+    ...?iterableIntList,
+    ...?iterableNumList1,
+    ...?iterableNumList2,
+    ...?intList,
+    ...?numList1,
+    ...?numList2
+  ];
+
+  expect(new List<int>.generate(24, (int i) => i), list3);
+
+  var list4 = <num>[
+    ...?dynamicList1,
+    ...?dynamicList2,
+    ...?iterableIntList,
+    ...?iterableNumList1,
+    ...?iterableNumList2,
+    ...?intList,
+    ...?numList1,
+    ...?numList2
+  ];
+
+  expect(new List<num>.generate(24, (int i) => i), list4);
+}
+
+main() {
+  useAddAll();
+}
+
+void expect(List list1, List list2) {
+  if (list1.length != list2.length) {
+    throw 'Unexpected length. Expected ${list1.length}, actual ${list2.length}.';
+  }
+  for (int i = 0; i < list1.length; i++) {
+    if (list1[i] != list2[i]) {
+      throw 'Unexpected element at index $i. '
+          'Expected ${list1[i]}, actual ${list2[i]}.';
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/list_add_all.dart.textual_outline.expect
new file mode 100644
index 0000000..67c81d1
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.9
+void useAddAll() {}
+main() {}
+void expect(List list1, List list2) {}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/list_add_all.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b4ec914
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.9
+main() {}
+void expect(List list1, List list2) {}
+void useAddAll() {}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all.dart.weak.expect b/pkg/front_end/testcases/unified_collections/list_add_all.dart.weak.expect
new file mode 100644
index 0000000..fe00087
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all.dart.weak.expect
@@ -0,0 +1,155 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method useAddAll() → void {
+  dynamic dynamicList1 = <core::int*>[0, 1, 2];
+  dynamic dynamicList2 = <core::num*>[3, 4, 5];
+  core::Iterable<core::int*>* iterableIntList = <core::int*>[6, 7, 8];
+  core::Iterable<core::num*>* iterableNumList1 = <core::int*>[9, 10, 11];
+  core::Iterable<core::num*>* iterableNumList2 = <core::num*>[12, 13, 14];
+  core::List<core::int*>* intList = <core::int*>[15, 16, 17];
+  core::List<core::num*>* numList1 = <core::int*>[18, 19, 20];
+  core::List<core::num*>* numList2 = <core::num*>[21, 22, 23];
+  core::List<core::int*>* list1 = block {
+    final core::List<core::int*>* #t1 = <core::int*>[];
+    for (final dynamic #t2 in dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t3 = #t2 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t3);
+    }
+    for (final dynamic #t4 in dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t5 = #t4 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t5);
+    }
+    #t1.{core::List::addAll}{Invariant}(iterableIntList);
+    for (final dynamic #t6 in iterableNumList1) {
+      final core::int* #t7 = #t6 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t7);
+    }
+    for (final dynamic #t8 in iterableNumList2) {
+      final core::int* #t9 = #t8 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t9);
+    }
+    #t1.{core::List::addAll}{Invariant}(intList);
+    for (final dynamic #t10 in numList1) {
+      final core::int* #t11 = #t10 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t11);
+    }
+    for (final dynamic #t12 in numList2) {
+      final core::int* #t13 = #t12 as{TypeError} core::int*;
+      #t1.{core::List::add}{Invariant}(#t13);
+    }
+  } =>#t1;
+  self::expect(core::List::generate<core::int*>(24, (core::int* i) → core::int* => i), list1);
+  core::List<core::num*>* list2 = block {
+    final core::List<core::num*>* #t14 = <core::num*>[];
+    for (final dynamic #t15 in dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::num* #t16 = #t15 as{TypeError} core::num*;
+      #t14.{core::List::add}{Invariant}(#t16);
+    }
+    for (final dynamic #t17 in dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::num* #t18 = #t17 as{TypeError} core::num*;
+      #t14.{core::List::add}{Invariant}(#t18);
+    }
+    #t14.{core::List::addAll}{Invariant}(iterableIntList);
+    #t14.{core::List::addAll}{Invariant}(iterableNumList1);
+    #t14.{core::List::addAll}{Invariant}(iterableNumList2);
+    #t14.{core::List::addAll}{Invariant}(intList);
+    #t14.{core::List::addAll}{Invariant}(numList1);
+    #t14.{core::List::addAll}{Invariant}(numList2);
+  } =>#t14;
+  self::expect(core::List::generate<core::num*>(24, (core::int* i) → core::int* => i), list2);
+  core::List<core::int*>* list3 = block {
+    final core::List<core::int*>* #t19 = <core::int*>[];
+    final core::Iterable<dynamic>* #t20 = dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t20.{core::Object::==}(null))
+      for (final dynamic #t21 in #t20) {
+        final core::int* #t22 = #t21 as{TypeError} core::int*;
+        #t19.{core::List::add}{Invariant}(#t22);
+      }
+    final core::Iterable<dynamic>* #t23 = dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t23.{core::Object::==}(null))
+      for (final dynamic #t24 in #t23) {
+        final core::int* #t25 = #t24 as{TypeError} core::int*;
+        #t19.{core::List::add}{Invariant}(#t25);
+      }
+    final core::Iterable<core::int*>* #t26 = iterableIntList;
+    if(!#t26.{core::Object::==}(null))
+      #t19.{core::List::addAll}{Invariant}(#t26);
+    final core::Iterable<dynamic>* #t27 = iterableNumList1;
+    if(!#t27.{core::Object::==}(null))
+      for (final dynamic #t28 in #t27) {
+        final core::int* #t29 = #t28 as{TypeError} core::int*;
+        #t19.{core::List::add}{Invariant}(#t29);
+      }
+    final core::Iterable<dynamic>* #t30 = iterableNumList2;
+    if(!#t30.{core::Object::==}(null))
+      for (final dynamic #t31 in #t30) {
+        final core::int* #t32 = #t31 as{TypeError} core::int*;
+        #t19.{core::List::add}{Invariant}(#t32);
+      }
+    final core::Iterable<core::int*>* #t33 = intList;
+    if(!#t33.{core::Object::==}(null))
+      #t19.{core::List::addAll}{Invariant}(#t33);
+    final core::Iterable<dynamic>* #t34 = numList1;
+    if(!#t34.{core::Object::==}(null))
+      for (final dynamic #t35 in #t34) {
+        final core::int* #t36 = #t35 as{TypeError} core::int*;
+        #t19.{core::List::add}{Invariant}(#t36);
+      }
+    final core::Iterable<dynamic>* #t37 = numList2;
+    if(!#t37.{core::Object::==}(null))
+      for (final dynamic #t38 in #t37) {
+        final core::int* #t39 = #t38 as{TypeError} core::int*;
+        #t19.{core::List::add}{Invariant}(#t39);
+      }
+  } =>#t19;
+  self::expect(core::List::generate<core::int*>(24, (core::int* i) → core::int* => i), list3);
+  core::List<core::num*>* list4 = block {
+    final core::List<core::num*>* #t40 = <core::num*>[];
+    final core::Iterable<dynamic>* #t41 = dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t41.{core::Object::==}(null))
+      for (final dynamic #t42 in #t41) {
+        final core::num* #t43 = #t42 as{TypeError} core::num*;
+        #t40.{core::List::add}{Invariant}(#t43);
+      }
+    final core::Iterable<dynamic>* #t44 = dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t44.{core::Object::==}(null))
+      for (final dynamic #t45 in #t44) {
+        final core::num* #t46 = #t45 as{TypeError} core::num*;
+        #t40.{core::List::add}{Invariant}(#t46);
+      }
+    final core::Iterable<core::num*>* #t47 = iterableIntList;
+    if(!#t47.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t47);
+    final core::Iterable<core::num*>* #t48 = iterableNumList1;
+    if(!#t48.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t48);
+    final core::Iterable<core::num*>* #t49 = iterableNumList2;
+    if(!#t49.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t49);
+    final core::Iterable<core::num*>* #t50 = intList;
+    if(!#t50.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t50);
+    final core::Iterable<core::num*>* #t51 = numList1;
+    if(!#t51.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t51);
+    final core::Iterable<core::num*>* #t52 = numList2;
+    if(!#t52.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t52);
+  } =>#t40;
+  self::expect(core::List::generate<core::num*>(24, (core::int* i) → core::int* => i), list4);
+}
+static method main() → dynamic {
+  self::useAddAll();
+}
+static method expect(core::List<dynamic>* list1, core::List<dynamic>* list2) → void {
+  if(!list1.{core::List::length}.{core::num::==}(list2.{core::List::length})) {
+    throw "Unexpected length. Expected ${list1.{core::List::length}}, actual ${list2.{core::List::length}}.";
+  }
+  for (core::int* i = 0; i.{core::num::<}(list1.{core::List::length}); i = i.{core::num::+}(1)) {
+    if(!list1.{core::List::[]}(i).{core::Object::==}(list2.{core::List::[]}(i))) {
+      throw "Unexpected element at index ${i}. Expected ${list1.{core::List::[]}(i)}, actual ${list2.{core::List::[]}(i)}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/list_add_all.dart.weak.transformed.expect
new file mode 100644
index 0000000..5f72074
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all.dart.weak.transformed.expect
@@ -0,0 +1,243 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method useAddAll() → void {
+  dynamic dynamicList1 = <core::int*>[0, 1, 2];
+  dynamic dynamicList2 = <core::num*>[3, 4, 5];
+  core::Iterable<core::int*>* iterableIntList = <core::int*>[6, 7, 8];
+  core::Iterable<core::num*>* iterableNumList1 = <core::int*>[9, 10, 11];
+  core::Iterable<core::num*>* iterableNumList2 = <core::num*>[12, 13, 14];
+  core::List<core::int*>* intList = <core::int*>[15, 16, 17];
+  core::List<core::num*>* numList1 = <core::int*>[18, 19, 20];
+  core::List<core::num*>* numList2 = <core::num*>[21, 22, 23];
+  core::List<core::int*>* list1 = block {
+    final core::List<core::int*>* #t1 = <core::int*>[];
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t3 = #t2 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t3);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t5 = #t4 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t5);
+        }
+      }
+    }
+    #t1.{core::List::addAll}{Invariant}(iterableIntList);
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = iterableNumList1.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t7 = #t6 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t7);
+        }
+      }
+    }
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = iterableNumList2.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t9 = #t8 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t9);
+        }
+      }
+    }
+    #t1.{core::List::addAll}{Invariant}(intList);
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = numList1.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t11 = #t10 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t11);
+        }
+      }
+    }
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = numList2.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t13 = #t12 as{TypeError} core::int*;
+          #t1.{core::List::add}{Invariant}(#t13);
+        }
+      }
+    }
+  } =>#t1;
+  self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i), list1);
+  core::List<core::num*>* list2 = block {
+    final core::List<core::num*>* #t14 = <core::num*>[];
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t15 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t16 = #t15 as{TypeError} core::num*;
+          #t14.{core::List::add}{Invariant}(#t16);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t18 = #t17 as{TypeError} core::num*;
+          #t14.{core::List::add}{Invariant}(#t18);
+        }
+      }
+    }
+    #t14.{core::List::addAll}{Invariant}(iterableIntList);
+    #t14.{core::List::addAll}{Invariant}(iterableNumList1);
+    #t14.{core::List::addAll}{Invariant}(iterableNumList2);
+    #t14.{core::List::addAll}{Invariant}(intList);
+    #t14.{core::List::addAll}{Invariant}(numList1);
+    #t14.{core::List::addAll}{Invariant}(numList2);
+  } =>#t14;
+  self::expect(core::_GrowableList::generate<core::num*>(24, (core::int* i) → core::int* => i), list2);
+  core::List<core::int*>* list3 = block {
+    final core::List<core::int*>* #t19 = <core::int*>[];
+    final core::Iterable<dynamic>* #t20 = dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t20.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t20.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t22 = #t21 as{TypeError} core::int*;
+          #t19.{core::List::add}{Invariant}(#t22);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t23 = dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t23.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t23.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t24 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t25 = #t24 as{TypeError} core::int*;
+          #t19.{core::List::add}{Invariant}(#t25);
+        }
+      }
+    }
+    final core::Iterable<core::int*>* #t26 = iterableIntList;
+    if(!#t26.{core::Object::==}(null))
+      #t19.{core::List::addAll}{Invariant}(#t26);
+    final core::Iterable<dynamic>* #t27 = iterableNumList1;
+    if(!#t27.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t27.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t28 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t29 = #t28 as{TypeError} core::int*;
+          #t19.{core::List::add}{Invariant}(#t29);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t30 = iterableNumList2;
+    if(!#t30.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t30.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t31 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t32 = #t31 as{TypeError} core::int*;
+          #t19.{core::List::add}{Invariant}(#t32);
+        }
+      }
+    }
+    final core::Iterable<core::int*>* #t33 = intList;
+    if(!#t33.{core::Object::==}(null))
+      #t19.{core::List::addAll}{Invariant}(#t33);
+    final core::Iterable<dynamic>* #t34 = numList1;
+    if(!#t34.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t34.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t36 = #t35 as{TypeError} core::int*;
+          #t19.{core::List::add}{Invariant}(#t36);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t37 = numList2;
+    if(!#t37.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t37.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t38 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t39 = #t38 as{TypeError} core::int*;
+          #t19.{core::List::add}{Invariant}(#t39);
+        }
+      }
+    }
+  } =>#t19;
+  self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i), list3);
+  core::List<core::num*>* list4 = block {
+    final core::List<core::num*>* #t40 = <core::num*>[];
+    final core::Iterable<dynamic>* #t41 = dynamicList1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t41.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t41.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t42 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t43 = #t42 as{TypeError} core::num*;
+          #t40.{core::List::add}{Invariant}(#t43);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t44 = dynamicList2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t44.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t44.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t45 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t46 = #t45 as{TypeError} core::num*;
+          #t40.{core::List::add}{Invariant}(#t46);
+        }
+      }
+    }
+    final core::Iterable<core::num*>* #t47 = iterableIntList;
+    if(!#t47.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t47);
+    final core::Iterable<core::num*>* #t48 = iterableNumList1;
+    if(!#t48.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t48);
+    final core::Iterable<core::num*>* #t49 = iterableNumList2;
+    if(!#t49.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t49);
+    final core::Iterable<core::num*>* #t50 = intList;
+    if(!#t50.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t50);
+    final core::Iterable<core::num*>* #t51 = numList1;
+    if(!#t51.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t51);
+    final core::Iterable<core::num*>* #t52 = numList2;
+    if(!#t52.{core::Object::==}(null))
+      #t40.{core::List::addAll}{Invariant}(#t52);
+  } =>#t40;
+  self::expect(core::_GrowableList::generate<core::num*>(24, (core::int* i) → core::int* => i), list4);
+}
+static method main() → dynamic {
+  self::useAddAll();
+}
+static method expect(core::List<dynamic>* list1, core::List<dynamic>* list2) → void {
+  if(!list1.{core::List::length}.{core::num::==}(list2.{core::List::length})) {
+    throw "Unexpected length. Expected ${list1.{core::List::length}}, actual ${list2.{core::List::length}}.";
+  }
+  for (core::int* i = 0; i.{core::num::<}(list1.{core::List::length}); i = i.{core::num::+}(1)) {
+    if(!list1.{core::List::[]}(i).{core::Object::==}(list2.{core::List::[]}(i))) {
+      throw "Unexpected element at index ${i}. Expected ${list1.{core::List::[]}(i)}, actual ${list2.{core::List::[]}(i)}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart
new file mode 100644
index 0000000..f4ce868
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void useAddAll() {
+  dynamic dynamicList1 = <int>[0, 1, 2];
+  dynamic dynamicList2 = <num>[3, 4, 5];
+  dynamic dynamicList3 = <int?>[6, 7, 8];
+  Iterable<int> iterableIntList = <int>[9, 10, 11];
+  List<int> intList = <int>[12, 13, 14];
+
+  var list1 = <int>[
+    ...dynamicList1,
+    ...dynamicList2,
+    ...dynamicList3,
+    ...iterableIntList,
+    ...intList,
+  ];
+
+  expect(new List<int>.generate(15, (int i) => i), list1);
+
+  var list2 = <num>[
+    ...dynamicList1,
+    ...dynamicList2,
+    ...dynamicList3,
+    ...iterableIntList,
+    ...intList,
+  ];
+
+  expect(new List<num>.generate(15, (int i) => i), list2);
+}
+
+void useAddAllNullable() {
+  dynamic dynamicList1 = <int>[0, 1, 2];
+  dynamic dynamicList2 = <num>[3, 4, 5];
+  dynamic dynamicList3 = <int?>[6, 7, 8];
+  Iterable<int>? iterableIntList = true ? <int>[9, 10, 11] : null;
+  List<int>? intList = true ? <int>[12, 13, 14] : null;
+
+  var list1 = <int>[
+    ...?dynamicList1,
+    ...?dynamicList2,
+    ...?dynamicList3,
+    ...?iterableIntList,
+    ...?intList,
+  ];
+
+  expect(new List<int>.generate(15, (int i) => i), list1);
+
+  var list2 = <num>[
+    ...?dynamicList1,
+    ...?dynamicList2,
+    ...?dynamicList3,
+    ...?iterableIntList,
+    ...?intList,
+  ];
+
+  expect(new List<num>.generate(15, (int i) => i), list2);
+}
+
+main() {
+  useAddAll();
+  useAddAllNullable();
+}
+
+void expect(List list1, List list2) {
+  if (list1.length != list2.length) {
+    throw 'Unexpected length. Expected ${list1.length}, actual ${list2.length}.';
+  }
+  for (int i = 0; i < list1.length; i++) {
+    if (list1[i] != list2[i]) {
+      throw 'Unexpected element at index $i. '
+          'Expected ${list1[i]}, actual ${list2[i]}.';
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.textual_outline.expect
new file mode 100644
index 0000000..d8b9259
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+void useAddAll() {}
+void useAddAllNullable() {}
+main() {}
+void expect(List list1, List list2) {}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e022801
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+void expect(List list1, List list2) {}
+void useAddAll() {}
+void useAddAllNullable() {}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.weak.expect b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.weak.expect
new file mode 100644
index 0000000..233316d
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.weak.expect
@@ -0,0 +1,124 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method useAddAll() → void {
+  dynamic dynamicList1 = <core::int>[0, 1, 2];
+  dynamic dynamicList2 = <core::num>[3, 4, 5];
+  dynamic dynamicList3 = <core::int?>[6, 7, 8];
+  core::Iterable<core::int> iterableIntList = <core::int>[9, 10, 11];
+  core::List<core::int> intList = <core::int>[12, 13, 14];
+  core::List<core::int> list1 = block {
+    final core::List<core::int> #t1 = <core::int>[];
+    for (final dynamic #t2 in dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::int #t3 = #t2 as{TypeError,ForNonNullableByDefault} core::int;
+      #t1.{core::List::add}{Invariant}(#t3);
+    }
+    for (final dynamic #t4 in dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::int #t5 = #t4 as{TypeError,ForNonNullableByDefault} core::int;
+      #t1.{core::List::add}{Invariant}(#t5);
+    }
+    for (final dynamic #t6 in dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::int #t7 = #t6 as{TypeError,ForNonNullableByDefault} core::int;
+      #t1.{core::List::add}{Invariant}(#t7);
+    }
+    #t1.{core::List::addAll}{Invariant}(iterableIntList);
+    #t1.{core::List::addAll}{Invariant}(intList);
+  } =>#t1;
+  self::expect(core::List::generate<core::int>(15, (core::int i) → core::int => i), list1);
+  core::List<core::num> list2 = block {
+    final core::List<core::num> #t8 = <core::num>[];
+    for (final dynamic #t9 in dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::num #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::num;
+      #t8.{core::List::add}{Invariant}(#t10);
+    }
+    for (final dynamic #t11 in dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::num #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::num;
+      #t8.{core::List::add}{Invariant}(#t12);
+    }
+    for (final dynamic #t13 in dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::num #t14 = #t13 as{TypeError,ForNonNullableByDefault} core::num;
+      #t8.{core::List::add}{Invariant}(#t14);
+    }
+    #t8.{core::List::addAll}{Invariant}(iterableIntList);
+    #t8.{core::List::addAll}{Invariant}(intList);
+  } =>#t8;
+  self::expect(core::List::generate<core::num>(15, (core::int i) → core::int => i), list2);
+}
+static method useAddAllNullable() → void {
+  dynamic dynamicList1 = <core::int>[0, 1, 2];
+  dynamic dynamicList2 = <core::num>[3, 4, 5];
+  dynamic dynamicList3 = <core::int?>[6, 7, 8];
+  core::Iterable<core::int>? iterableIntList = true ?{core::List<core::int>?} <core::int>[9, 10, 11] : null;
+  core::List<core::int>? intList = true ?{core::List<core::int>?} <core::int>[12, 13, 14] : null;
+  core::List<core::int> list1 = block {
+    final core::List<core::int> #t15 = <core::int>[];
+    final core::Iterable<dynamic>? #t16 = dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t16.{core::Object::==}(null))
+      for (final dynamic #t17 in #t16{core::Iterable<dynamic>}) {
+        final core::int #t18 = #t17 as{TypeError,ForNonNullableByDefault} core::int;
+        #t15.{core::List::add}{Invariant}(#t18);
+      }
+    final core::Iterable<dynamic>? #t19 = dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t19.{core::Object::==}(null))
+      for (final dynamic #t20 in #t19{core::Iterable<dynamic>}) {
+        final core::int #t21 = #t20 as{TypeError,ForNonNullableByDefault} core::int;
+        #t15.{core::List::add}{Invariant}(#t21);
+      }
+    final core::Iterable<dynamic>? #t22 = dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t22.{core::Object::==}(null))
+      for (final dynamic #t23 in #t22{core::Iterable<dynamic>}) {
+        final core::int #t24 = #t23 as{TypeError,ForNonNullableByDefault} core::int;
+        #t15.{core::List::add}{Invariant}(#t24);
+      }
+    final core::Iterable<core::int>? #t25 = iterableIntList;
+    if(!#t25.{core::Object::==}(null))
+      #t15.{core::List::addAll}{Invariant}(#t25{core::Iterable<core::int>});
+    final core::Iterable<core::int>? #t26 = intList;
+    if(!#t26.{core::Object::==}(null))
+      #t15.{core::List::addAll}{Invariant}(#t26{core::Iterable<core::int>});
+  } =>#t15;
+  self::expect(core::List::generate<core::int>(15, (core::int i) → core::int => i), list1);
+  core::List<core::num> list2 = block {
+    final core::List<core::num> #t27 = <core::num>[];
+    final core::Iterable<dynamic>? #t28 = dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t28.{core::Object::==}(null))
+      for (final dynamic #t29 in #t28{core::Iterable<dynamic>}) {
+        final core::num #t30 = #t29 as{TypeError,ForNonNullableByDefault} core::num;
+        #t27.{core::List::add}{Invariant}(#t30);
+      }
+    final core::Iterable<dynamic>? #t31 = dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t31.{core::Object::==}(null))
+      for (final dynamic #t32 in #t31{core::Iterable<dynamic>}) {
+        final core::num #t33 = #t32 as{TypeError,ForNonNullableByDefault} core::num;
+        #t27.{core::List::add}{Invariant}(#t33);
+      }
+    final core::Iterable<dynamic>? #t34 = dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t34.{core::Object::==}(null))
+      for (final dynamic #t35 in #t34{core::Iterable<dynamic>}) {
+        final core::num #t36 = #t35 as{TypeError,ForNonNullableByDefault} core::num;
+        #t27.{core::List::add}{Invariant}(#t36);
+      }
+    final core::Iterable<core::num>? #t37 = iterableIntList;
+    if(!#t37.{core::Object::==}(null))
+      #t27.{core::List::addAll}{Invariant}(#t37{core::Iterable<core::num>});
+    final core::Iterable<core::num>? #t38 = intList;
+    if(!#t38.{core::Object::==}(null))
+      #t27.{core::List::addAll}{Invariant}(#t38{core::Iterable<core::num>});
+  } =>#t27;
+  self::expect(core::List::generate<core::num>(15, (core::int i) → core::int => i), list2);
+}
+static method main() → dynamic {
+  self::useAddAll();
+  self::useAddAllNullable();
+}
+static method expect(core::List<dynamic> list1, core::List<dynamic> list2) → void {
+  if(!list1.{core::List::length}.{core::num::==}(list2.{core::List::length})) {
+    throw "Unexpected length. Expected ${list1.{core::List::length}}, actual ${list2.{core::List::length}}.";
+  }
+  for (core::int i = 0; i.{core::num::<}(list1.{core::List::length}); i = i.{core::num::+}(1)) {
+    if(!list1.{core::List::[]}(i).{core::Object::==}(list2.{core::List::[]}(i))) {
+      throw "Unexpected element at index ${i}. Expected ${list1.{core::List::[]}(i)}, actual ${list2.{core::List::[]}(i)}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.weak.transformed.expect
new file mode 100644
index 0000000..e9211e8
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/list_add_all_nnbd.dart.weak.transformed.expect
@@ -0,0 +1,190 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method useAddAll() → void {
+  dynamic dynamicList1 = <core::int>[0, 1, 2];
+  dynamic dynamicList2 = <core::num>[3, 4, 5];
+  dynamic dynamicList3 = <core::int?>[6, 7, 8];
+  core::Iterable<core::int> iterableIntList = <core::int>[9, 10, 11];
+  core::List<core::int> intList = <core::int>[12, 13, 14];
+  core::List<core::int> list1 = block {
+    final core::List<core::int> #t1 = <core::int>[];
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t3 = #t2 as{TypeError,ForNonNullableByDefault} core::int;
+          #t1.{core::List::add}{Invariant}(#t3);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t5 = #t4 as{TypeError,ForNonNullableByDefault} core::int;
+          #t1.{core::List::add}{Invariant}(#t5);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t6 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t7 = #t6 as{TypeError,ForNonNullableByDefault} core::int;
+          #t1.{core::List::add}{Invariant}(#t7);
+        }
+      }
+    }
+    #t1.{core::List::addAll}{Invariant}(iterableIntList);
+    #t1.{core::List::addAll}{Invariant}(intList);
+  } =>#t1;
+  self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i), list1);
+  core::List<core::num> list2 = block {
+    final core::List<core::num> #t8 = <core::num>[];
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::num;
+          #t8.{core::List::add}{Invariant}(#t10);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::num;
+          #t8.{core::List::add}{Invariant}(#t12);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t13 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t14 = #t13 as{TypeError,ForNonNullableByDefault} core::num;
+          #t8.{core::List::add}{Invariant}(#t14);
+        }
+      }
+    }
+    #t8.{core::List::addAll}{Invariant}(iterableIntList);
+    #t8.{core::List::addAll}{Invariant}(intList);
+  } =>#t8;
+  self::expect(core::_GrowableList::generate<core::num>(15, (core::int i) → core::int => i), list2);
+}
+static method useAddAllNullable() → void {
+  dynamic dynamicList1 = <core::int>[0, 1, 2];
+  dynamic dynamicList2 = <core::num>[3, 4, 5];
+  dynamic dynamicList3 = <core::int?>[6, 7, 8];
+  core::Iterable<core::int>? iterableIntList = true ?{core::List<core::int>?} <core::int>[9, 10, 11] : null;
+  core::List<core::int>? intList = true ?{core::List<core::int>?} <core::int>[12, 13, 14] : null;
+  core::List<core::int> list1 = block {
+    final core::List<core::int> #t15 = <core::int>[];
+    final core::Iterable<dynamic>? #t16 = dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t16.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t16{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t18 = #t17 as{TypeError,ForNonNullableByDefault} core::int;
+          #t15.{core::List::add}{Invariant}(#t18);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t19 = dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t19.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t19{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t20 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t21 = #t20 as{TypeError,ForNonNullableByDefault} core::int;
+          #t15.{core::List::add}{Invariant}(#t21);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t22 = dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t22.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t22{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t24 = #t23 as{TypeError,ForNonNullableByDefault} core::int;
+          #t15.{core::List::add}{Invariant}(#t24);
+        }
+      }
+    }
+    final core::Iterable<core::int>? #t25 = iterableIntList;
+    if(!#t25.{core::Object::==}(null))
+      #t15.{core::List::addAll}{Invariant}(#t25{core::Iterable<core::int>});
+    final core::Iterable<core::int>? #t26 = intList;
+    if(!#t26.{core::Object::==}(null))
+      #t15.{core::List::addAll}{Invariant}(#t26{core::Iterable<core::int>});
+  } =>#t15;
+  self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i), list1);
+  core::List<core::num> list2 = block {
+    final core::List<core::num> #t27 = <core::num>[];
+    final core::Iterable<dynamic>? #t28 = dynamicList1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t28.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t28{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t29 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t30 = #t29 as{TypeError,ForNonNullableByDefault} core::num;
+          #t27.{core::List::add}{Invariant}(#t30);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t31 = dynamicList2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t31.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t31{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t32 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t33 = #t32 as{TypeError,ForNonNullableByDefault} core::num;
+          #t27.{core::List::add}{Invariant}(#t33);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t34 = dynamicList3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t34.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t34{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t35 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t36 = #t35 as{TypeError,ForNonNullableByDefault} core::num;
+          #t27.{core::List::add}{Invariant}(#t36);
+        }
+      }
+    }
+    final core::Iterable<core::num>? #t37 = iterableIntList;
+    if(!#t37.{core::Object::==}(null))
+      #t27.{core::List::addAll}{Invariant}(#t37{core::Iterable<core::num>});
+    final core::Iterable<core::num>? #t38 = intList;
+    if(!#t38.{core::Object::==}(null))
+      #t27.{core::List::addAll}{Invariant}(#t38{core::Iterable<core::num>});
+  } =>#t27;
+  self::expect(core::_GrowableList::generate<core::num>(15, (core::int i) → core::int => i), list2);
+}
+static method main() → dynamic {
+  self::useAddAll();
+  self::useAddAllNullable();
+}
+static method expect(core::List<dynamic> list1, core::List<dynamic> list2) → void {
+  if(!list1.{core::List::length}.{core::num::==}(list2.{core::List::length})) {
+    throw "Unexpected length. Expected ${list1.{core::List::length}}, actual ${list2.{core::List::length}}.";
+  }
+  for (core::int i = 0; i.{core::num::<}(list1.{core::List::length}); i = i.{core::num::+}(1)) {
+    if(!list1.{core::List::[]}(i).{core::Object::==}(list2.{core::List::[]}(i))) {
+      throw "Unexpected element at index ${i}. Expected ${list1.{core::List::[]}(i)}, actual ${list2.{core::List::[]}(i)}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart b/pkg/front_end/testcases/unified_collections/mixed_entries.dart
index 55810a0..fa03bc7 100644
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.9
+
 bool b = false;
 
 var list = [];
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.outline.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.outline.expect
deleted file mode 100644
index a46c9ef..0000000
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.outline.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:33:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error4 = {if (b) 0: 1 else for (var a in list) a};
-//                                ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:34:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error5 = {if (b) for (var a in list) a else 0: 1};
-//                      ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:41:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
-//                                ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:42:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
-//                      ^
-//
-import self as self;
-import "dart:core" as core;
-
-static field core::bool* b;
-static field core::List<dynamic>* list;
-static field core::Map<dynamic, dynamic>* map0;
-static field core::Map<dynamic, dynamic>* map1;
-static field core::Map<dynamic, dynamic>* map2;
-static field core::Map<dynamic, dynamic>* map3;
-static field core::Map<dynamic, core::int*>* map4;
-static field core::Map<dynamic, core::int*>* map5;
-static field core::Map<dynamic, core::int*>* map6;
-static field core::Map<dynamic, core::int*>* map7;
-static field core::Map<dynamic, core::int*>* map8;
-static field core::Map<dynamic, core::int*>* map9;
-static field core::Map<dynamic, core::int*>* map10;
-static field core::Map<dynamic, core::int*>* map11;
-static field core::Map<core::int*, core::int*>* map12;
-static field core::Map<dynamic, Null>* error4;
-static field core::Map<dynamic, Null>* error5;
-static field dynamic error6;
-static field dynamic error7;
-static field core::Map<dynamic, Null>* error8;
-static field core::Map<dynamic, Null>* error9;
-static field dynamic error10;
-static field dynamic error11;
-static field dynamic error12;
-static method main() → dynamic
-  ;
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.expect
deleted file mode 100644
index 1194246..0000000
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.expect
+++ /dev/null
@@ -1,176 +0,0 @@
-library;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:33:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error4 = {if (b) 0: 1 else for (var a in list) a};
-//                                ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:34:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error5 = {if (b) for (var a in list) a else 0: 1};
-//                      ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:41:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
-//                                ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:42:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
-//                      ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error6 = {
-//              ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:38:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error7 = {
-//              ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error10 = {
-//               ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:46:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error11 = {
-//               ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:49:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error12 = {
-//               ^
-//
-import self as self;
-import "dart:core" as core;
-
-static field core::bool* b = false;
-static field core::List<dynamic>* list = <dynamic>[];
-static field core::Map<dynamic, dynamic>* map0 = <dynamic, dynamic>{};
-static field core::Map<dynamic, dynamic>* map1 = block {
-  final core::Map<dynamic, dynamic>* #t1 = <dynamic, dynamic>{};
-  if(self::b)
-    #t1.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (final core::MapEntry<dynamic, dynamic>* #t2 in self::map0.{core::Map::entries})
-      #t1.{core::Map::[]=}{Invariant}(#t2.{core::MapEntry::key}, #t2.{core::MapEntry::value});
-} =>#t1;
-static field core::Map<dynamic, dynamic>* map2 = block {
-  final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
-  if(self::b)
-    for (final core::MapEntry<dynamic, dynamic>* #t4 in self::map0.{core::Map::entries})
-      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
-  else
-    #t3.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t3;
-static field core::Map<dynamic, dynamic>* map3 = block {
-  final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
-  if(self::b)
-    for (final core::MapEntry<dynamic, dynamic>* #t6 in self::map0.{core::Map::entries})
-      #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
-  else
-    for (final core::MapEntry<dynamic, dynamic>* #t7 in self::map0.{core::Map::entries})
-      #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
-} =>#t5;
-static field core::Map<dynamic, core::int*>* map4 = block {
-  final core::Map<dynamic, core::int*>* #t8 = <dynamic, core::int*>{};
-  if(self::b)
-    #t8.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (dynamic a in self::list)
-      #t8.{core::Map::[]=}{Invariant}(a, 1);
-} =>#t8;
-static field core::Map<dynamic, core::int*>* map5 = block {
-  final core::Map<dynamic, core::int*>* #t9 = <dynamic, core::int*>{};
-  if(self::b)
-    for (dynamic a in self::list)
-      #t9.{core::Map::[]=}{Invariant}(a, 1);
-  else
-    #t9.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t9;
-static field core::Map<dynamic, core::int*>* map6 = block {
-  final core::Map<dynamic, core::int*>* #t10 = <dynamic, core::int*>{};
-  if(self::b)
-    #t10.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (dynamic a in self::list)
-      for (final core::MapEntry<dynamic, core::int*>* #t11 in <dynamic, core::int*>{a: 1}.{core::Map::entries})
-        #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
-} =>#t10;
-static field core::Map<dynamic, core::int*>* map7 = block {
-  final core::Map<dynamic, core::int*>* #t12 = <dynamic, core::int*>{};
-  if(self::b)
-    for (dynamic a in self::list)
-      for (final core::MapEntry<dynamic, core::int*>* #t13 in <dynamic, core::int*>{a: 1}.{core::Map::entries})
-        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
-  else
-    #t12.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t12;
-static field core::Map<dynamic, core::int*>* map8 = block {
-  final core::Map<dynamic, core::int*>* #t14 = <dynamic, core::int*>{};
-  if(self::b)
-    #t14.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
-      #t14.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
-} =>#t14;
-static field core::Map<dynamic, core::int*>* map9 = block {
-  final core::Map<dynamic, core::int*>* #t15 = <dynamic, core::int*>{};
-  if(self::b)
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
-      #t15.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
-  else
-    #t15.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t15;
-static field core::Map<dynamic, core::int*>* map10 = block {
-  final core::Map<dynamic, core::int*>* #t16 = <dynamic, core::int*>{};
-  if(self::b)
-    #t16.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
-      for (final core::MapEntry<dynamic, core::int*>* #t17 in <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries})
-        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-} =>#t16;
-static field core::Map<dynamic, core::int*>* map11 = block {
-  final core::Map<dynamic, core::int*>* #t18 = <dynamic, core::int*>{};
-  if(self::b)
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
-      for (final core::MapEntry<dynamic, core::int*>* #t19 in <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries})
-        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
-  else
-    #t18.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t18;
-static field core::Map<core::int*, core::int*>* map12 = block {
-  final core::Map<core::int*, core::int*>* #t20 = <core::int*, core::int*>{};
-  if(self::b)
-    #t20.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    if(self::b)
-      for (final core::MapEntry<core::int*, core::int*>* #t21 in <core::int*, core::int*>{0: 1}.{core::Map::entries})
-        #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
-} =>#t20;
-static field core::Map<dynamic, Null>* error4 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:33:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error4 = {if (b) 0: 1 else for (var a in list) a};
-                               ^": null};
-static field core::Map<dynamic, Null>* error5 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:34:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error5 = {if (b) for (var a in list) a else 0: 1};
-                     ^": null};
-static field dynamic error6 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error6 = {
-             ^";
-static field dynamic error7 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:38:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error7 = {
-             ^";
-static field core::Map<dynamic, Null>* error8 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:41:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
-                               ^": null};
-static field core::Map<dynamic, Null>* error9 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:42:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
-                     ^": null};
-static field dynamic error10 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error10 = {
-              ^";
-static field dynamic error11 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:46:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error11 = {
-              ^";
-static field dynamic error12 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:49:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error12 = {
-              ^";
-static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect
deleted file mode 100644
index ff07e3e..0000000
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.strong.transformed.expect
+++ /dev/null
@@ -1,230 +0,0 @@
-library;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:33:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error4 = {if (b) 0: 1 else for (var a in list) a};
-//                                ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:34:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error5 = {if (b) for (var a in list) a else 0: 1};
-//                      ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:41:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
-//                                ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:42:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
-//                      ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error6 = {
-//              ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:38:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error7 = {
-//              ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error10 = {
-//               ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:46:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error11 = {
-//               ^
-//
-// pkg/front_end/testcases/unified_collections/mixed_entries.dart:49:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-// var error12 = {
-//               ^
-//
-import self as self;
-import "dart:core" as core;
-
-static field core::bool* b = false;
-static field core::List<dynamic>* list = <dynamic>[];
-static field core::Map<dynamic, dynamic>* map0 = <dynamic, dynamic>{};
-static field core::Map<dynamic, dynamic>* map1 = block {
-  final core::Map<dynamic, dynamic>* #t1 = <dynamic, dynamic>{};
-  if(self::b)
-    #t1.{core::Map::[]=}{Invariant}(0, 1);
-  else {
-    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final core::MapEntry<dynamic, dynamic>* #t2 = :sync-for-iterator.{core::Iterator::current};
-      #t1.{core::Map::[]=}{Invariant}(#t2.{core::MapEntry::key}, #t2.{core::MapEntry::value});
-    }
-  }
-} =>#t1;
-static field core::Map<dynamic, dynamic>* map2 = block {
-  final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
-  if(self::b) {
-    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final core::MapEntry<dynamic, dynamic>* #t4 = :sync-for-iterator.{core::Iterator::current};
-      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
-    }
-  }
-  else
-    #t3.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t3;
-static field core::Map<dynamic, dynamic>* map3 = block {
-  final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
-  if(self::b) {
-    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final core::MapEntry<dynamic, dynamic>* #t6 = :sync-for-iterator.{core::Iterator::current};
-      #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
-    }
-  }
-  else {
-    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      final core::MapEntry<dynamic, dynamic>* #t7 = :sync-for-iterator.{core::Iterator::current};
-      #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
-    }
-  }
-} =>#t5;
-static field core::Map<dynamic, core::int*>* map4 = block {
-  final core::Map<dynamic, core::int*>* #t8 = <dynamic, core::int*>{};
-  if(self::b)
-    #t8.{core::Map::[]=}{Invariant}(0, 1);
-  else {
-    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      dynamic a = :sync-for-iterator.{core::Iterator::current};
-      #t8.{core::Map::[]=}{Invariant}(a, 1);
-    }
-  }
-} =>#t8;
-static field core::Map<dynamic, core::int*>* map5 = block {
-  final core::Map<dynamic, core::int*>* #t9 = <dynamic, core::int*>{};
-  if(self::b) {
-    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      dynamic a = :sync-for-iterator.{core::Iterator::current};
-      #t9.{core::Map::[]=}{Invariant}(a, 1);
-    }
-  }
-  else
-    #t9.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t9;
-static field core::Map<dynamic, core::int*>* map6 = block {
-  final core::Map<dynamic, core::int*>* #t10 = <dynamic, core::int*>{};
-  if(self::b)
-    #t10.{core::Map::[]=}{Invariant}(0, 1);
-  else {
-    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      dynamic a = :sync-for-iterator.{core::Iterator::current};
-      {
-        core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{a: 1}.{core::Map::entries}.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<dynamic, core::int*>* #t11 = :sync-for-iterator.{core::Iterator::current};
-          #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
-        }
-      }
-    }
-  }
-} =>#t10;
-static field core::Map<dynamic, core::int*>* map7 = block {
-  final core::Map<dynamic, core::int*>* #t12 = <dynamic, core::int*>{};
-  if(self::b) {
-    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
-    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      dynamic a = :sync-for-iterator.{core::Iterator::current};
-      {
-        core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{a: 1}.{core::Map::entries}.{core::Iterable::iterator};
-        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-          final core::MapEntry<dynamic, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
-          #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
-        }
-      }
-    }
-  }
-  else
-    #t12.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t12;
-static field core::Map<dynamic, core::int*>* map8 = block {
-  final core::Map<dynamic, core::int*>* #t14 = <dynamic, core::int*>{};
-  if(self::b)
-    #t14.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
-      #t14.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
-} =>#t14;
-static field core::Map<dynamic, core::int*>* map9 = block {
-  final core::Map<dynamic, core::int*>* #t15 = <dynamic, core::int*>{};
-  if(self::b)
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
-      #t15.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
-  else
-    #t15.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t15;
-static field core::Map<dynamic, core::int*>* map10 = block {
-  final core::Map<dynamic, core::int*>* #t16 = <dynamic, core::int*>{};
-  if(self::b)
-    #t16.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
-        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
-      }
-    }
-} =>#t16;
-static field core::Map<dynamic, core::int*>* map11 = block {
-  final core::Map<dynamic, core::int*>* #t18 = <dynamic, core::int*>{};
-  if(self::b)
-    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1)) {
-      core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<dynamic, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
-        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
-      }
-    }
-  else
-    #t18.{core::Map::[]=}{Invariant}(0, 1);
-} =>#t18;
-static field core::Map<core::int*, core::int*>* map12 = block {
-  final core::Map<core::int*, core::int*>* #t20 = <core::int*, core::int*>{};
-  if(self::b)
-    #t20.{core::Map::[]=}{Invariant}(0, 1);
-  else
-    if(self::b) {
-      core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{0: 1}.{core::Map::entries}.{core::Iterable::iterator};
-      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-        final core::MapEntry<core::int*, core::int*>* #t21 = :sync-for-iterator.{core::Iterator::current};
-        #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
-      }
-    }
-} =>#t20;
-static field core::Map<dynamic, Null>* error4 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:33:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error4 = {if (b) 0: 1 else for (var a in list) a};
-                               ^": null};
-static field core::Map<dynamic, Null>* error5 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:34:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error5 = {if (b) for (var a in list) a else 0: 1};
-                     ^": null};
-static field dynamic error6 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error6 = {
-             ^";
-static field dynamic error7 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:38:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error7 = {
-             ^";
-static field core::Map<dynamic, Null>* error8 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:41:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
-                               ^": null};
-static field core::Map<dynamic, Null>* error9 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:42:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
-                     ^": null};
-static field dynamic error10 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error10 = {
-              ^";
-static field dynamic error11 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:46:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error11 = {
-              ^";
-static field dynamic error12 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:49:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
-var error12 = {
-              ^";
-static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
index 480a19e..147bb36 100644
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
@@ -1,3 +1,4 @@
+// @dart = 2.9
 bool b = false;
 var list = [];
 var map0 = {};
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
index 1843b5c..1f1b82d 100644
--- a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
@@ -1,3 +1,4 @@
+// @dart = 2.9
 bool b = false;
 main() {}
 var error10 = {
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.weak.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.weak.expect
new file mode 100644
index 0000000..6fce67d
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.weak.expect
@@ -0,0 +1,176 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error4 = {if (b) 0: 1 else for (var a in list) a};
+//                                ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:36:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error5 = {if (b) for (var a in list) a else 0: 1};
+//                      ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
+//                                ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:44:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
+//                      ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:37:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error6 = {
+//              ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:40:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error7 = {
+//              ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:45:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error10 = {
+//               ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:48:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error11 = {
+//               ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:51:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error12 = {
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+static field core::bool* b = false;
+static field core::List<dynamic>* list = <dynamic>[];
+static field core::Map<dynamic, dynamic>* map0 = <dynamic, dynamic>{};
+static field core::Map<dynamic, dynamic>* map1 = block {
+  final core::Map<dynamic, dynamic>* #t1 = <dynamic, dynamic>{};
+  if(self::b)
+    #t1.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (final core::MapEntry<dynamic, dynamic>* #t2 in self::map0.{core::Map::entries})
+      #t1.{core::Map::[]=}{Invariant}(#t2.{core::MapEntry::key}, #t2.{core::MapEntry::value});
+} =>#t1;
+static field core::Map<dynamic, dynamic>* map2 = block {
+  final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
+  if(self::b)
+    for (final core::MapEntry<dynamic, dynamic>* #t4 in self::map0.{core::Map::entries})
+      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+  else
+    #t3.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t3;
+static field core::Map<dynamic, dynamic>* map3 = block {
+  final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
+  if(self::b)
+    for (final core::MapEntry<dynamic, dynamic>* #t6 in self::map0.{core::Map::entries})
+      #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
+  else
+    for (final core::MapEntry<dynamic, dynamic>* #t7 in self::map0.{core::Map::entries})
+      #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
+} =>#t5;
+static field core::Map<dynamic, core::int*>* map4 = block {
+  final core::Map<dynamic, core::int*>* #t8 = <dynamic, core::int*>{};
+  if(self::b)
+    #t8.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (dynamic a in self::list)
+      #t8.{core::Map::[]=}{Invariant}(a, 1);
+} =>#t8;
+static field core::Map<dynamic, core::int*>* map5 = block {
+  final core::Map<dynamic, core::int*>* #t9 = <dynamic, core::int*>{};
+  if(self::b)
+    for (dynamic a in self::list)
+      #t9.{core::Map::[]=}{Invariant}(a, 1);
+  else
+    #t9.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t9;
+static field core::Map<dynamic, core::int*>* map6 = block {
+  final core::Map<dynamic, core::int*>* #t10 = <dynamic, core::int*>{};
+  if(self::b)
+    #t10.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (dynamic a in self::list)
+      for (final core::MapEntry<dynamic, core::int*>* #t11 in <dynamic, core::int*>{a: 1}.{core::Map::entries})
+        #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
+} =>#t10;
+static field core::Map<dynamic, core::int*>* map7 = block {
+  final core::Map<dynamic, core::int*>* #t12 = <dynamic, core::int*>{};
+  if(self::b)
+    for (dynamic a in self::list)
+      for (final core::MapEntry<dynamic, core::int*>* #t13 in <dynamic, core::int*>{a: 1}.{core::Map::entries})
+        #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
+  else
+    #t12.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t12;
+static field core::Map<dynamic, core::int*>* map8 = block {
+  final core::Map<dynamic, core::int*>* #t14 = <dynamic, core::int*>{};
+  if(self::b)
+    #t14.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
+      #t14.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
+} =>#t14;
+static field core::Map<dynamic, core::int*>* map9 = block {
+  final core::Map<dynamic, core::int*>* #t15 = <dynamic, core::int*>{};
+  if(self::b)
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
+      #t15.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
+  else
+    #t15.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t15;
+static field core::Map<dynamic, core::int*>* map10 = block {
+  final core::Map<dynamic, core::int*>* #t16 = <dynamic, core::int*>{};
+  if(self::b)
+    #t16.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
+      for (final core::MapEntry<dynamic, core::int*>* #t17 in <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries})
+        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+} =>#t16;
+static field core::Map<dynamic, core::int*>* map11 = block {
+  final core::Map<dynamic, core::int*>* #t18 = <dynamic, core::int*>{};
+  if(self::b)
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
+      for (final core::MapEntry<dynamic, core::int*>* #t19 in <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries})
+        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
+  else
+    #t18.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t18;
+static field core::Map<core::int*, core::int*>* map12 = block {
+  final core::Map<core::int*, core::int*>* #t20 = <core::int*, core::int*>{};
+  if(self::b)
+    #t20.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    if(self::b)
+      for (final core::MapEntry<core::int*, core::int*>* #t21 in <core::int*, core::int*>{0: 1}.{core::Map::entries})
+        #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
+} =>#t20;
+static field core::Map<dynamic, Null>* error4 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error4 = {if (b) 0: 1 else for (var a in list) a};
+                               ^": null};
+static field core::Map<dynamic, Null>* error5 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:36:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error5 = {if (b) for (var a in list) a else 0: 1};
+                     ^": null};
+static field dynamic error6 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:37:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error6 = {
+             ^";
+static field dynamic error7 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:40:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error7 = {
+             ^";
+static field core::Map<dynamic, Null>* error8 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
+                               ^": null};
+static field core::Map<dynamic, Null>* error9 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:44:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
+                     ^": null};
+static field dynamic error10 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:45:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error10 = {
+              ^";
+static field dynamic error11 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:48:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error11 = {
+              ^";
+static field dynamic error12 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:51:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error12 = {
+              ^";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.weak.transformed.expect
new file mode 100644
index 0000000..691c149
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.weak.transformed.expect
@@ -0,0 +1,230 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error4 = {if (b) 0: 1 else for (var a in list) a};
+//                                ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:36:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error5 = {if (b) for (var a in list) a else 0: 1};
+//                      ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
+//                                ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:44:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
+//                      ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:37:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error6 = {
+//              ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:40:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error7 = {
+//              ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:45:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error10 = {
+//               ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:48:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error11 = {
+//               ^
+//
+// pkg/front_end/testcases/unified_collections/mixed_entries.dart:51:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+// var error12 = {
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+static field core::bool* b = false;
+static field core::List<dynamic>* list = <dynamic>[];
+static field core::Map<dynamic, dynamic>* map0 = <dynamic, dynamic>{};
+static field core::Map<dynamic, dynamic>* map1 = block {
+  final core::Map<dynamic, dynamic>* #t1 = <dynamic, dynamic>{};
+  if(self::b)
+    #t1.{core::Map::[]=}{Invariant}(0, 1);
+  else {
+    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      final core::MapEntry<dynamic, dynamic>* #t2 = :sync-for-iterator.{core::Iterator::current};
+      #t1.{core::Map::[]=}{Invariant}(#t2.{core::MapEntry::key}, #t2.{core::MapEntry::value});
+    }
+  }
+} =>#t1;
+static field core::Map<dynamic, dynamic>* map2 = block {
+  final core::Map<dynamic, dynamic>* #t3 = <dynamic, dynamic>{};
+  if(self::b) {
+    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      final core::MapEntry<dynamic, dynamic>* #t4 = :sync-for-iterator.{core::Iterator::current};
+      #t3.{core::Map::[]=}{Invariant}(#t4.{core::MapEntry::key}, #t4.{core::MapEntry::value});
+    }
+  }
+  else
+    #t3.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t3;
+static field core::Map<dynamic, dynamic>* map3 = block {
+  final core::Map<dynamic, dynamic>* #t5 = <dynamic, dynamic>{};
+  if(self::b) {
+    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      final core::MapEntry<dynamic, dynamic>* #t6 = :sync-for-iterator.{core::Iterator::current};
+      #t5.{core::Map::[]=}{Invariant}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
+    }
+  }
+  else {
+    core::Iterator<core::MapEntry<dynamic, dynamic>>* :sync-for-iterator = self::map0.{core::Map::entries}.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      final core::MapEntry<dynamic, dynamic>* #t7 = :sync-for-iterator.{core::Iterator::current};
+      #t5.{core::Map::[]=}{Invariant}(#t7.{core::MapEntry::key}, #t7.{core::MapEntry::value});
+    }
+  }
+} =>#t5;
+static field core::Map<dynamic, core::int*>* map4 = block {
+  final core::Map<dynamic, core::int*>* #t8 = <dynamic, core::int*>{};
+  if(self::b)
+    #t8.{core::Map::[]=}{Invariant}(0, 1);
+  else {
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      dynamic a = :sync-for-iterator.{core::Iterator::current};
+      #t8.{core::Map::[]=}{Invariant}(a, 1);
+    }
+  }
+} =>#t8;
+static field core::Map<dynamic, core::int*>* map5 = block {
+  final core::Map<dynamic, core::int*>* #t9 = <dynamic, core::int*>{};
+  if(self::b) {
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      dynamic a = :sync-for-iterator.{core::Iterator::current};
+      #t9.{core::Map::[]=}{Invariant}(a, 1);
+    }
+  }
+  else
+    #t9.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t9;
+static field core::Map<dynamic, core::int*>* map6 = block {
+  final core::Map<dynamic, core::int*>* #t10 = <dynamic, core::int*>{};
+  if(self::b)
+    #t10.{core::Map::[]=}{Invariant}(0, 1);
+  else {
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      dynamic a = :sync-for-iterator.{core::Iterator::current};
+      {
+        core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{a: 1}.{core::Map::entries}.{core::Iterable::iterator};
+        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+          final core::MapEntry<dynamic, core::int*>* #t11 = :sync-for-iterator.{core::Iterator::current};
+          #t10.{core::Map::[]=}{Invariant}(#t11.{core::MapEntry::key}, #t11.{core::MapEntry::value});
+        }
+      }
+    }
+  }
+} =>#t10;
+static field core::Map<dynamic, core::int*>* map7 = block {
+  final core::Map<dynamic, core::int*>* #t12 = <dynamic, core::int*>{};
+  if(self::b) {
+    core::Iterator<dynamic>* :sync-for-iterator = self::list.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      dynamic a = :sync-for-iterator.{core::Iterator::current};
+      {
+        core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{a: 1}.{core::Map::entries}.{core::Iterable::iterator};
+        for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+          final core::MapEntry<dynamic, core::int*>* #t13 = :sync-for-iterator.{core::Iterator::current};
+          #t12.{core::Map::[]=}{Invariant}(#t13.{core::MapEntry::key}, #t13.{core::MapEntry::value});
+        }
+      }
+    }
+  }
+  else
+    #t12.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t12;
+static field core::Map<dynamic, core::int*>* map8 = block {
+  final core::Map<dynamic, core::int*>* #t14 = <dynamic, core::int*>{};
+  if(self::b)
+    #t14.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
+      #t14.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
+} =>#t14;
+static field core::Map<dynamic, core::int*>* map9 = block {
+  final core::Map<dynamic, core::int*>* #t15 = <dynamic, core::int*>{};
+  if(self::b)
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1))
+      #t15.{core::Map::[]=}{Invariant}(self::list.{core::List::[]}(i), 1);
+  else
+    #t15.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t15;
+static field core::Map<dynamic, core::int*>* map10 = block {
+  final core::Map<dynamic, core::int*>* #t16 = <dynamic, core::int*>{};
+  if(self::b)
+    #t16.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1)) {
+      core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<dynamic, core::int*>* #t17 = :sync-for-iterator.{core::Iterator::current};
+        #t16.{core::Map::[]=}{Invariant}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+      }
+    }
+} =>#t16;
+static field core::Map<dynamic, core::int*>* map11 = block {
+  final core::Map<dynamic, core::int*>* #t18 = <dynamic, core::int*>{};
+  if(self::b)
+    for (core::int* i = 0; i.{core::num::<}(self::list.{core::List::length}); i = i.{core::num::+}(1)) {
+      core::Iterator<core::MapEntry<dynamic, core::int*>>* :sync-for-iterator = <dynamic, core::int*>{self::list.{core::List::[]}(i): 1}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<dynamic, core::int*>* #t19 = :sync-for-iterator.{core::Iterator::current};
+        #t18.{core::Map::[]=}{Invariant}(#t19.{core::MapEntry::key}, #t19.{core::MapEntry::value});
+      }
+    }
+  else
+    #t18.{core::Map::[]=}{Invariant}(0, 1);
+} =>#t18;
+static field core::Map<core::int*, core::int*>* map12 = block {
+  final core::Map<core::int*, core::int*>* #t20 = <core::int*, core::int*>{};
+  if(self::b)
+    #t20.{core::Map::[]=}{Invariant}(0, 1);
+  else
+    if(self::b) {
+      core::Iterator<core::MapEntry<core::int*, core::int*>>* :sync-for-iterator = <core::int*, core::int*>{0: 1}.{core::Map::entries}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final core::MapEntry<core::int*, core::int*>* #t21 = :sync-for-iterator.{core::Iterator::current};
+        #t20.{core::Map::[]=}{Invariant}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
+      }
+    }
+} =>#t20;
+static field core::Map<dynamic, Null>* error4 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:35:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error4 = {if (b) 0: 1 else for (var a in list) a};
+                               ^": null};
+static field core::Map<dynamic, Null>* error5 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:36:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error5 = {if (b) for (var a in list) a else 0: 1};
+                     ^": null};
+static field dynamic error6 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:37:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error6 = {
+             ^";
+static field dynamic error7 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:40:14: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error7 = {
+             ^";
+static field core::Map<dynamic, Null>* error8 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:43:32: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error8 = {if (b) 0: 1 else for (var i = 0; i < list.length; i++) list[i]};
+                               ^": null};
+static field core::Map<dynamic, Null>* error9 = <dynamic, Null>{invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:44:22: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error9 = {if (b) for (var i = 0; i < list.length; i++) list[i] else 0: 1};
+                     ^": null};
+static field dynamic error10 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:45:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error10 = {
+              ^";
+static field dynamic error11 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:48:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error11 = {
+              ^";
+static field dynamic error12 = invalid-expression "pkg/front_end/testcases/unified_collections/mixed_entries.dart:51:15: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+var error12 = {
+              ^";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all.dart b/pkg/front_end/testcases/unified_collections/set_add_all.dart
new file mode 100644
index 0000000..d1b77d0
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+void useAddAll() {
+  dynamic dynamicSet1 = <int>{0, 1, 2};
+  dynamic dynamicSet2 = <num>{3, 4, 5};
+  Iterable<int> iterableIntSet = <int>{6, 7, 8};
+  Iterable<num> iterableNumSet1 = <int>{9, 10, 11};
+  Iterable<num> iterableNumSet2 = <num>{12, 13, 14};
+  Set<int> intSet = <int>{15, 16, 17};
+  Set<num> numSet1 = <int>{18, 19, 20};
+  Set<num> numSet2 = <num>{21, 22, 23};
+
+  var set1 = <int>{
+    ...dynamicSet1,
+    ...dynamicSet2,
+    ...iterableIntSet,
+    ...iterableNumSet1,
+    ...iterableNumSet2,
+    ...intSet,
+    ...numSet1,
+    ...numSet2
+  };
+
+  expect(new List<int>.generate(24, (int i) => i).toSet(), set1);
+
+  var set2 = <num>{
+    ...dynamicSet1,
+    ...dynamicSet2,
+    ...iterableIntSet,
+    ...iterableNumSet1,
+    ...iterableNumSet2,
+    ...intSet,
+    ...numSet1,
+    ...numSet2
+  };
+
+  expect(new List<num>.generate(24, (int i) => i).toSet(), set2);
+
+  var set3 = <int>{
+    ...?dynamicSet1,
+    ...?dynamicSet2,
+    ...?iterableIntSet,
+    ...?iterableNumSet1,
+    ...?iterableNumSet2,
+    ...?intSet,
+    ...?numSet1,
+    ...?numSet2
+  };
+
+  expect(new List<int>.generate(24, (int i) => i).toSet(), set3);
+
+  var set4 = <num>{
+    ...?dynamicSet1,
+    ...?dynamicSet2,
+    ...?iterableIntSet,
+    ...?iterableNumSet1,
+    ...?iterableNumSet2,
+    ...?intSet,
+    ...?numSet1,
+    ...?numSet2
+  };
+
+  expect(new List<num>.generate(24, (int i) => i).toSet(), set4);
+}
+
+main() {
+  useAddAll();
+}
+
+void expect(Set set1, Set set2) {
+  if (set1.length != set2.length) {
+    throw 'Unexpected length. Expected ${set1.length}, actual ${set2.length}.';
+  }
+  for (dynamic element in set1) {
+    if (!set2.contains(element)) {
+      throw 'Element $element not found. Expected $set1, actual $set2.';
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/set_add_all.dart.textual_outline.expect
new file mode 100644
index 0000000..cabcd88
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.9
+void useAddAll() {}
+main() {}
+void expect(Set set1, Set set2) {}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/set_add_all.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0827941
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.9
+main() {}
+void expect(Set set1, Set set2) {}
+void useAddAll() {}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.expect b/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.expect
new file mode 100644
index 0000000..f31828e
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.expect
@@ -0,0 +1,197 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+import "dart:_internal" as _in;
+
+static method useAddAll() → void {
+  dynamic dynamicSet1 = block {
+    final core::Set<core::int*>* #t1 = col::LinkedHashSet::•<core::int*>();
+    #t1.{core::Set::add}{Invariant}(0);
+    #t1.{core::Set::add}{Invariant}(1);
+    #t1.{core::Set::add}{Invariant}(2);
+  } =>#t1;
+  dynamic dynamicSet2 = block {
+    final core::Set<core::num*>* #t2 = col::LinkedHashSet::•<core::num*>();
+    #t2.{core::Set::add}{Invariant}(3);
+    #t2.{core::Set::add}{Invariant}(4);
+    #t2.{core::Set::add}{Invariant}(5);
+  } =>#t2;
+  core::Iterable<core::int*>* iterableIntSet = block {
+    final core::Set<core::int*>* #t3 = col::LinkedHashSet::•<core::int*>();
+    #t3.{core::Set::add}{Invariant}(6);
+    #t3.{core::Set::add}{Invariant}(7);
+    #t3.{core::Set::add}{Invariant}(8);
+  } =>#t3;
+  core::Iterable<core::num*>* iterableNumSet1 = block {
+    final core::Set<core::int*>* #t4 = col::LinkedHashSet::•<core::int*>();
+    #t4.{core::Set::add}{Invariant}(9);
+    #t4.{core::Set::add}{Invariant}(10);
+    #t4.{core::Set::add}{Invariant}(11);
+  } =>#t4;
+  core::Iterable<core::num*>* iterableNumSet2 = block {
+    final core::Set<core::num*>* #t5 = col::LinkedHashSet::•<core::num*>();
+    #t5.{core::Set::add}{Invariant}(12);
+    #t5.{core::Set::add}{Invariant}(13);
+    #t5.{core::Set::add}{Invariant}(14);
+  } =>#t5;
+  core::Set<core::int*>* intSet = block {
+    final core::Set<core::int*>* #t6 = col::LinkedHashSet::•<core::int*>();
+    #t6.{core::Set::add}{Invariant}(15);
+    #t6.{core::Set::add}{Invariant}(16);
+    #t6.{core::Set::add}{Invariant}(17);
+  } =>#t6;
+  core::Set<core::num*>* numSet1 = block {
+    final core::Set<core::int*>* #t7 = col::LinkedHashSet::•<core::int*>();
+    #t7.{core::Set::add}{Invariant}(18);
+    #t7.{core::Set::add}{Invariant}(19);
+    #t7.{core::Set::add}{Invariant}(20);
+  } =>#t7;
+  core::Set<core::num*>* numSet2 = block {
+    final core::Set<core::num*>* #t8 = col::LinkedHashSet::•<core::num*>();
+    #t8.{core::Set::add}{Invariant}(21);
+    #t8.{core::Set::add}{Invariant}(22);
+    #t8.{core::Set::add}{Invariant}(23);
+  } =>#t8;
+  core::Set<core::int*>* set1 = block {
+    final core::Set<core::int*>* #t9 = col::LinkedHashSet::•<core::int*>();
+    for (final dynamic #t10 in dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t11 = #t10 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t11);
+    }
+    for (final dynamic #t12 in dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::int* #t13 = #t12 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t13);
+    }
+    #t9.{core::Set::addAll}{Invariant}(iterableIntSet);
+    for (final dynamic #t14 in iterableNumSet1) {
+      final core::int* #t15 = #t14 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t15);
+    }
+    for (final dynamic #t16 in iterableNumSet2) {
+      final core::int* #t17 = #t16 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t17);
+    }
+    #t9.{core::Set::addAll}{Invariant}(intSet);
+    for (final dynamic #t18 in numSet1) {
+      final core::int* #t19 = #t18 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t19);
+    }
+    for (final dynamic #t20 in numSet2) {
+      final core::int* #t21 = #t20 as{TypeError} core::int*;
+      #t9.{core::Set::add}{Invariant}(#t21);
+    }
+  } =>#t9;
+  self::expect(core::List::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set1);
+  core::Set<core::num*>* set2 = block {
+    final core::Set<core::num*>* #t22 = col::LinkedHashSet::•<core::num*>();
+    for (final dynamic #t23 in dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::num* #t24 = #t23 as{TypeError} core::num*;
+      #t22.{core::Set::add}{Invariant}(#t24);
+    }
+    for (final dynamic #t25 in dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
+      final core::num* #t26 = #t25 as{TypeError} core::num*;
+      #t22.{core::Set::add}{Invariant}(#t26);
+    }
+    #t22.{core::Set::addAll}{Invariant}(iterableIntSet);
+    #t22.{core::Set::addAll}{Invariant}(iterableNumSet1);
+    #t22.{core::Set::addAll}{Invariant}(iterableNumSet2);
+    #t22.{core::Set::addAll}{Invariant}(intSet);
+    #t22.{core::Set::addAll}{Invariant}(numSet1);
+    #t22.{core::Set::addAll}{Invariant}(numSet2);
+  } =>#t22;
+  self::expect(core::List::generate<core::num*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set2);
+  core::Set<core::int*>* set3 = block {
+    final core::Set<core::int*>* #t27 = col::LinkedHashSet::•<core::int*>();
+    final core::Iterable<dynamic>* #t28 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t28.{core::Object::==}(null))
+      for (final dynamic #t29 in #t28) {
+        final core::int* #t30 = #t29 as{TypeError} core::int*;
+        #t27.{core::Set::add}{Invariant}(#t30);
+      }
+    final core::Iterable<dynamic>* #t31 = dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t31.{core::Object::==}(null))
+      for (final dynamic #t32 in #t31) {
+        final core::int* #t33 = #t32 as{TypeError} core::int*;
+        #t27.{core::Set::add}{Invariant}(#t33);
+      }
+    final core::Iterable<core::int*>* #t34 = iterableIntSet;
+    if(!#t34.{core::Object::==}(null))
+      #t27.{core::Set::addAll}{Invariant}(#t34);
+    final core::Iterable<dynamic>* #t35 = iterableNumSet1;
+    if(!#t35.{core::Object::==}(null))
+      for (final dynamic #t36 in #t35) {
+        final core::int* #t37 = #t36 as{TypeError} core::int*;
+        #t27.{core::Set::add}{Invariant}(#t37);
+      }
+    final core::Iterable<dynamic>* #t38 = iterableNumSet2;
+    if(!#t38.{core::Object::==}(null))
+      for (final dynamic #t39 in #t38) {
+        final core::int* #t40 = #t39 as{TypeError} core::int*;
+        #t27.{core::Set::add}{Invariant}(#t40);
+      }
+    final core::Iterable<core::int*>* #t41 = intSet;
+    if(!#t41.{core::Object::==}(null))
+      #t27.{core::Set::addAll}{Invariant}(#t41);
+    final core::Iterable<dynamic>* #t42 = numSet1;
+    if(!#t42.{core::Object::==}(null))
+      for (final dynamic #t43 in #t42) {
+        final core::int* #t44 = #t43 as{TypeError} core::int*;
+        #t27.{core::Set::add}{Invariant}(#t44);
+      }
+    final core::Iterable<dynamic>* #t45 = numSet2;
+    if(!#t45.{core::Object::==}(null))
+      for (final dynamic #t46 in #t45) {
+        final core::int* #t47 = #t46 as{TypeError} core::int*;
+        #t27.{core::Set::add}{Invariant}(#t47);
+      }
+  } =>#t27;
+  self::expect(core::List::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set3);
+  core::Set<core::num*>* set4 = block {
+    final core::Set<core::num*>* #t48 = col::LinkedHashSet::•<core::num*>();
+    final core::Iterable<dynamic>* #t49 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t49.{core::Object::==}(null))
+      for (final dynamic #t50 in #t49) {
+        final core::num* #t51 = #t50 as{TypeError} core::num*;
+        #t48.{core::Set::add}{Invariant}(#t51);
+      }
+    final core::Iterable<dynamic>* #t52 = dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t52.{core::Object::==}(null))
+      for (final dynamic #t53 in #t52) {
+        final core::num* #t54 = #t53 as{TypeError} core::num*;
+        #t48.{core::Set::add}{Invariant}(#t54);
+      }
+    final core::Iterable<core::num*>* #t55 = iterableIntSet;
+    if(!#t55.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t55);
+    final core::Iterable<core::num*>* #t56 = iterableNumSet1;
+    if(!#t56.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t56);
+    final core::Iterable<core::num*>* #t57 = iterableNumSet2;
+    if(!#t57.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t57);
+    final core::Iterable<core::num*>* #t58 = intSet;
+    if(!#t58.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t58);
+    final core::Iterable<core::num*>* #t59 = numSet1;
+    if(!#t59.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t59);
+    final core::Iterable<core::num*>* #t60 = numSet2;
+    if(!#t60.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t60);
+  } =>#t48;
+  self::expect(core::List::generate<core::num*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set4);
+}
+static method main() → dynamic {
+  self::useAddAll();
+}
+static method expect(core::Set<dynamic>* set1, core::Set<dynamic>* set2) → void {
+  if(!set1.{_in::EfficientLengthIterable::length}.{core::num::==}(set2.{_in::EfficientLengthIterable::length})) {
+    throw "Unexpected length. Expected ${set1.{_in::EfficientLengthIterable::length}}, actual ${set2.{_in::EfficientLengthIterable::length}}.";
+  }
+  for (dynamic element in set1) {
+    if(!set2.{core::Set::contains}(element)) {
+      throw "Element ${element} not found. Expected ${set1}, actual ${set2}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect
new file mode 100644
index 0000000..b8b398a
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect
@@ -0,0 +1,291 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+import "dart:_internal" as _in;
+
+static method useAddAll() → void {
+  dynamic dynamicSet1 = block {
+    final core::Set<core::int*>* #t1 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t1.{core::Set::add}{Invariant}(0);
+    #t1.{core::Set::add}{Invariant}(1);
+    #t1.{core::Set::add}{Invariant}(2);
+  } =>#t1;
+  dynamic dynamicSet2 = block {
+    final core::Set<core::num*>* #t2 = new col::_CompactLinkedHashSet::•<core::num*>();
+    #t2.{core::Set::add}{Invariant}(3);
+    #t2.{core::Set::add}{Invariant}(4);
+    #t2.{core::Set::add}{Invariant}(5);
+  } =>#t2;
+  core::Iterable<core::int*>* iterableIntSet = block {
+    final core::Set<core::int*>* #t3 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t3.{core::Set::add}{Invariant}(6);
+    #t3.{core::Set::add}{Invariant}(7);
+    #t3.{core::Set::add}{Invariant}(8);
+  } =>#t3;
+  core::Iterable<core::num*>* iterableNumSet1 = block {
+    final core::Set<core::int*>* #t4 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t4.{core::Set::add}{Invariant}(9);
+    #t4.{core::Set::add}{Invariant}(10);
+    #t4.{core::Set::add}{Invariant}(11);
+  } =>#t4;
+  core::Iterable<core::num*>* iterableNumSet2 = block {
+    final core::Set<core::num*>* #t5 = new col::_CompactLinkedHashSet::•<core::num*>();
+    #t5.{core::Set::add}{Invariant}(12);
+    #t5.{core::Set::add}{Invariant}(13);
+    #t5.{core::Set::add}{Invariant}(14);
+  } =>#t5;
+  core::Set<core::int*>* intSet = block {
+    final core::Set<core::int*>* #t6 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t6.{core::Set::add}{Invariant}(15);
+    #t6.{core::Set::add}{Invariant}(16);
+    #t6.{core::Set::add}{Invariant}(17);
+  } =>#t6;
+  core::Set<core::num*>* numSet1 = block {
+    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
+    #t7.{core::Set::add}{Invariant}(18);
+    #t7.{core::Set::add}{Invariant}(19);
+    #t7.{core::Set::add}{Invariant}(20);
+  } =>#t7;
+  core::Set<core::num*>* numSet2 = block {
+    final core::Set<core::num*>* #t8 = new col::_CompactLinkedHashSet::•<core::num*>();
+    #t8.{core::Set::add}{Invariant}(21);
+    #t8.{core::Set::add}{Invariant}(22);
+    #t8.{core::Set::add}{Invariant}(23);
+  } =>#t8;
+  core::Set<core::int*>* set1 = block {
+    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t11 = #t10 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t11);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t13 = #t12 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t13);
+        }
+      }
+    }
+    #t9.{core::Set::addAll}{Invariant}(iterableIntSet);
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = iterableNumSet1.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t15 = #t14 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t15);
+        }
+      }
+    }
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = iterableNumSet2.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t17 = #t16 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t17);
+        }
+      }
+    }
+    #t9.{core::Set::addAll}{Invariant}(intSet);
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = numSet1.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t19 = #t18 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t19);
+        }
+      }
+    }
+    {
+      core::Iterator<core::num*>* :sync-for-iterator = numSet2.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t20 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t21 = #t20 as{TypeError} core::int*;
+          #t9.{core::Set::add}{Invariant}(#t21);
+        }
+      }
+    }
+  } =>#t9;
+  self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set1);
+  core::Set<core::num*>* set2 = block {
+    final core::Set<core::num*>* #t22 = new col::_CompactLinkedHashSet::•<core::num*>();
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t24 = #t23 as{TypeError} core::num*;
+          #t22.{core::Set::add}{Invariant}(#t24);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t25 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t26 = #t25 as{TypeError} core::num*;
+          #t22.{core::Set::add}{Invariant}(#t26);
+        }
+      }
+    }
+    #t22.{core::Set::addAll}{Invariant}(iterableIntSet);
+    #t22.{core::Set::addAll}{Invariant}(iterableNumSet1);
+    #t22.{core::Set::addAll}{Invariant}(iterableNumSet2);
+    #t22.{core::Set::addAll}{Invariant}(intSet);
+    #t22.{core::Set::addAll}{Invariant}(numSet1);
+    #t22.{core::Set::addAll}{Invariant}(numSet2);
+  } =>#t22;
+  self::expect(core::_GrowableList::generate<core::num*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set2);
+  core::Set<core::int*>* set3 = block {
+    final core::Set<core::int*>* #t27 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Iterable<dynamic>* #t28 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t28.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t28.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t29 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t30 = #t29 as{TypeError} core::int*;
+          #t27.{core::Set::add}{Invariant}(#t30);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t31 = dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t31.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t31.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t32 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t33 = #t32 as{TypeError} core::int*;
+          #t27.{core::Set::add}{Invariant}(#t33);
+        }
+      }
+    }
+    final core::Iterable<core::int*>* #t34 = iterableIntSet;
+    if(!#t34.{core::Object::==}(null))
+      #t27.{core::Set::addAll}{Invariant}(#t34);
+    final core::Iterable<dynamic>* #t35 = iterableNumSet1;
+    if(!#t35.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t35.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t36 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t37 = #t36 as{TypeError} core::int*;
+          #t27.{core::Set::add}{Invariant}(#t37);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t38 = iterableNumSet2;
+    if(!#t38.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t38.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t39 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t40 = #t39 as{TypeError} core::int*;
+          #t27.{core::Set::add}{Invariant}(#t40);
+        }
+      }
+    }
+    final core::Iterable<core::int*>* #t41 = intSet;
+    if(!#t41.{core::Object::==}(null))
+      #t27.{core::Set::addAll}{Invariant}(#t41);
+    final core::Iterable<dynamic>* #t42 = numSet1;
+    if(!#t42.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t42.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t43 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t44 = #t43 as{TypeError} core::int*;
+          #t27.{core::Set::add}{Invariant}(#t44);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t45 = numSet2;
+    if(!#t45.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t45.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t46 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int* #t47 = #t46 as{TypeError} core::int*;
+          #t27.{core::Set::add}{Invariant}(#t47);
+        }
+      }
+    }
+  } =>#t27;
+  self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set3);
+  core::Set<core::num*>* set4 = block {
+    final core::Set<core::num*>* #t48 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Iterable<dynamic>* #t49 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t49.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t49.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t50 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t51 = #t50 as{TypeError} core::num*;
+          #t48.{core::Set::add}{Invariant}(#t51);
+        }
+      }
+    }
+    final core::Iterable<dynamic>* #t52 = dynamicSet2 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
+    if(!#t52.{core::Object::==}(null)) {
+      core::Iterator<dynamic>* :sync-for-iterator = #t52.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t53 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num* #t54 = #t53 as{TypeError} core::num*;
+          #t48.{core::Set::add}{Invariant}(#t54);
+        }
+      }
+    }
+    final core::Iterable<core::num*>* #t55 = iterableIntSet;
+    if(!#t55.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t55);
+    final core::Iterable<core::num*>* #t56 = iterableNumSet1;
+    if(!#t56.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t56);
+    final core::Iterable<core::num*>* #t57 = iterableNumSet2;
+    if(!#t57.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t57);
+    final core::Iterable<core::num*>* #t58 = intSet;
+    if(!#t58.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t58);
+    final core::Iterable<core::num*>* #t59 = numSet1;
+    if(!#t59.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t59);
+    final core::Iterable<core::num*>* #t60 = numSet2;
+    if(!#t60.{core::Object::==}(null))
+      #t48.{core::Set::addAll}{Invariant}(#t60);
+  } =>#t48;
+  self::expect(core::_GrowableList::generate<core::num*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(), set4);
+}
+static method main() → dynamic {
+  self::useAddAll();
+}
+static method expect(core::Set<dynamic>* set1, core::Set<dynamic>* set2) → void {
+  if(!set1.{_in::EfficientLengthIterable::length}.{core::num::==}(set2.{_in::EfficientLengthIterable::length})) {
+    throw "Unexpected length. Expected ${set1.{_in::EfficientLengthIterable::length}}, actual ${set2.{_in::EfficientLengthIterable::length}}.";
+  }
+  {
+    core::Iterator<dynamic>* :sync-for-iterator = set1.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      dynamic element = :sync-for-iterator.{core::Iterator::current};
+      {
+        if(!set2.{core::Set::contains}(element)) {
+          throw "Element ${element} not found. Expected ${set1}, actual ${set2}.";
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart
new file mode 100644
index 0000000..3361e8e
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void useAddAll() {
+  dynamic dynamicSet1 = <int>{0, 1, 2};
+  dynamic dynamicSet2 = <num>{3, 4, 5};
+  dynamic dynamicSet3 = <int?>{6, 7, 8};
+  Iterable<int> iterableIntSet = <int>{9, 10, 11};
+  Set<int> intSet = <int>{12, 13, 14};
+
+  var set1 = <int>{
+    ...dynamicSet1,
+    ...dynamicSet2,
+    ...dynamicSet3,
+    ...iterableIntSet,
+    ...intSet,
+  };
+
+  expect(new List<int>.generate(15, (int i) => i).toSet(), set1);
+
+  var set2 = <num>{
+    ...dynamicSet1,
+    ...dynamicSet2,
+    ...dynamicSet3,
+    ...iterableIntSet,
+    ...intSet,
+  };
+
+  expect(new List<num>.generate(15, (int i) => i).toSet(), set2);
+}
+
+void useAddAllNullable() {
+  dynamic dynamicSet1 = <int>{0, 1, 2};
+  dynamic dynamicSet2 = <num>{3, 4, 5};
+  dynamic dynamicSet3 = <int?>{6, 7, 8};
+  Iterable<int>? iterableIntSet = true ? <int>{9, 10, 11} : null;
+  Set<int>? intSet = true ? <int>{12, 13, 14} : null;
+
+  var set1 = <int>{
+    ...?dynamicSet1,
+    ...?dynamicSet2,
+    ...?dynamicSet3,
+    ...?iterableIntSet,
+    ...?intSet,
+  };
+
+  expect(new List<int>.generate(15, (int i) => i).toSet(), set1);
+
+  var set2 = <num>{
+    ...?dynamicSet1,
+    ...?dynamicSet2,
+    ...?dynamicSet3,
+    ...?iterableIntSet,
+    ...?intSet,
+  };
+
+  expect(new List<num>.generate(15, (int i) => i).toSet(), set2);
+}
+
+main() {
+  useAddAll();
+  useAddAllNullable();
+}
+
+void expect(Set set1, Set set2) {
+  if (set1.length != set2.length) {
+    throw 'Unexpected length. Expected ${set1.length}, actual ${set2.length}.';
+  }
+  for (dynamic element in set1) {
+    if (!set2.contains(element)) {
+      throw 'Element $element not found. Expected $set1, actual $set2.';
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.textual_outline.expect
new file mode 100644
index 0000000..8b60a79
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+void useAddAll() {}
+void useAddAllNullable() {}
+main() {}
+void expect(Set set1, Set set2) {}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..12854d9
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+void expect(Set set1, Set set2) {}
+void useAddAll() {}
+void useAddAllNullable() {}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.expect b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.expect
new file mode 100644
index 0000000..2ade2ee
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.expect
@@ -0,0 +1,176 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+import "dart:_internal" as _in;
+
+static method useAddAll() → void {
+  dynamic dynamicSet1 = block {
+    final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>();
+    #t1.{core::Set::add}{Invariant}(0);
+    #t1.{core::Set::add}{Invariant}(1);
+    #t1.{core::Set::add}{Invariant}(2);
+  } =>#t1;
+  dynamic dynamicSet2 = block {
+    final core::Set<core::num> #t2 = col::LinkedHashSet::•<core::num>();
+    #t2.{core::Set::add}{Invariant}(3);
+    #t2.{core::Set::add}{Invariant}(4);
+    #t2.{core::Set::add}{Invariant}(5);
+  } =>#t2;
+  dynamic dynamicSet3 = block {
+    final core::Set<core::int?> #t3 = col::LinkedHashSet::•<core::int?>();
+    #t3.{core::Set::add}{Invariant}(6);
+    #t3.{core::Set::add}{Invariant}(7);
+    #t3.{core::Set::add}{Invariant}(8);
+  } =>#t3;
+  core::Iterable<core::int> iterableIntSet = block {
+    final core::Set<core::int> #t4 = col::LinkedHashSet::•<core::int>();
+    #t4.{core::Set::add}{Invariant}(9);
+    #t4.{core::Set::add}{Invariant}(10);
+    #t4.{core::Set::add}{Invariant}(11);
+  } =>#t4;
+  core::Set<core::int> intSet = block {
+    final core::Set<core::int> #t5 = col::LinkedHashSet::•<core::int>();
+    #t5.{core::Set::add}{Invariant}(12);
+    #t5.{core::Set::add}{Invariant}(13);
+    #t5.{core::Set::add}{Invariant}(14);
+  } =>#t5;
+  core::Set<core::int> set1 = block {
+    final core::Set<core::int> #t6 = col::LinkedHashSet::•<core::int>();
+    for (final dynamic #t7 in dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::int #t8 = #t7 as{TypeError,ForNonNullableByDefault} core::int;
+      #t6.{core::Set::add}{Invariant}(#t8);
+    }
+    for (final dynamic #t9 in dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::int #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::int;
+      #t6.{core::Set::add}{Invariant}(#t10);
+    }
+    for (final dynamic #t11 in dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::int #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::int;
+      #t6.{core::Set::add}{Invariant}(#t12);
+    }
+    #t6.{core::Set::addAll}{Invariant}(iterableIntSet);
+    #t6.{core::Set::addAll}{Invariant}(intSet);
+  } =>#t6;
+  self::expect(core::List::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set1);
+  core::Set<core::num> set2 = block {
+    final core::Set<core::num> #t13 = col::LinkedHashSet::•<core::num>();
+    for (final dynamic #t14 in dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::num #t15 = #t14 as{TypeError,ForNonNullableByDefault} core::num;
+      #t13.{core::Set::add}{Invariant}(#t15);
+    }
+    for (final dynamic #t16 in dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::num #t17 = #t16 as{TypeError,ForNonNullableByDefault} core::num;
+      #t13.{core::Set::add}{Invariant}(#t17);
+    }
+    for (final dynamic #t18 in dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+      final core::num #t19 = #t18 as{TypeError,ForNonNullableByDefault} core::num;
+      #t13.{core::Set::add}{Invariant}(#t19);
+    }
+    #t13.{core::Set::addAll}{Invariant}(iterableIntSet);
+    #t13.{core::Set::addAll}{Invariant}(intSet);
+  } =>#t13;
+  self::expect(core::List::generate<core::num>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set2);
+}
+static method useAddAllNullable() → void {
+  dynamic dynamicSet1 = block {
+    final core::Set<core::int> #t20 = col::LinkedHashSet::•<core::int>();
+    #t20.{core::Set::add}{Invariant}(0);
+    #t20.{core::Set::add}{Invariant}(1);
+    #t20.{core::Set::add}{Invariant}(2);
+  } =>#t20;
+  dynamic dynamicSet2 = block {
+    final core::Set<core::num> #t21 = col::LinkedHashSet::•<core::num>();
+    #t21.{core::Set::add}{Invariant}(3);
+    #t21.{core::Set::add}{Invariant}(4);
+    #t21.{core::Set::add}{Invariant}(5);
+  } =>#t21;
+  dynamic dynamicSet3 = block {
+    final core::Set<core::int?> #t22 = col::LinkedHashSet::•<core::int?>();
+    #t22.{core::Set::add}{Invariant}(6);
+    #t22.{core::Set::add}{Invariant}(7);
+    #t22.{core::Set::add}{Invariant}(8);
+  } =>#t22;
+  core::Iterable<core::int>? iterableIntSet = true ?{core::Set<core::int>?} block {
+    final core::Set<core::int> #t23 = col::LinkedHashSet::•<core::int>();
+    #t23.{core::Set::add}{Invariant}(9);
+    #t23.{core::Set::add}{Invariant}(10);
+    #t23.{core::Set::add}{Invariant}(11);
+  } =>#t23 : null;
+  core::Set<core::int>? intSet = true ?{core::Set<core::int>?} block {
+    final core::Set<core::int> #t24 = col::LinkedHashSet::•<core::int>();
+    #t24.{core::Set::add}{Invariant}(12);
+    #t24.{core::Set::add}{Invariant}(13);
+    #t24.{core::Set::add}{Invariant}(14);
+  } =>#t24 : null;
+  core::Set<core::int> set1 = block {
+    final core::Set<core::int> #t25 = col::LinkedHashSet::•<core::int>();
+    final core::Iterable<dynamic>? #t26 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t26.{core::Object::==}(null))
+      for (final dynamic #t27 in #t26{core::Iterable<dynamic>}) {
+        final core::int #t28 = #t27 as{TypeError,ForNonNullableByDefault} core::int;
+        #t25.{core::Set::add}{Invariant}(#t28);
+      }
+    final core::Iterable<dynamic>? #t29 = dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t29.{core::Object::==}(null))
+      for (final dynamic #t30 in #t29{core::Iterable<dynamic>}) {
+        final core::int #t31 = #t30 as{TypeError,ForNonNullableByDefault} core::int;
+        #t25.{core::Set::add}{Invariant}(#t31);
+      }
+    final core::Iterable<dynamic>? #t32 = dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t32.{core::Object::==}(null))
+      for (final dynamic #t33 in #t32{core::Iterable<dynamic>}) {
+        final core::int #t34 = #t33 as{TypeError,ForNonNullableByDefault} core::int;
+        #t25.{core::Set::add}{Invariant}(#t34);
+      }
+    final core::Iterable<core::int>? #t35 = iterableIntSet;
+    if(!#t35.{core::Object::==}(null))
+      #t25.{core::Set::addAll}{Invariant}(#t35{core::Iterable<core::int>});
+    final core::Iterable<core::int>? #t36 = intSet;
+    if(!#t36.{core::Object::==}(null))
+      #t25.{core::Set::addAll}{Invariant}(#t36{core::Iterable<core::int>});
+  } =>#t25;
+  self::expect(core::List::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set1);
+  core::Set<core::num> set2 = block {
+    final core::Set<core::num> #t37 = col::LinkedHashSet::•<core::num>();
+    final core::Iterable<dynamic>? #t38 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t38.{core::Object::==}(null))
+      for (final dynamic #t39 in #t38{core::Iterable<dynamic>}) {
+        final core::num #t40 = #t39 as{TypeError,ForNonNullableByDefault} core::num;
+        #t37.{core::Set::add}{Invariant}(#t40);
+      }
+    final core::Iterable<dynamic>? #t41 = dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t41.{core::Object::==}(null))
+      for (final dynamic #t42 in #t41{core::Iterable<dynamic>}) {
+        final core::num #t43 = #t42 as{TypeError,ForNonNullableByDefault} core::num;
+        #t37.{core::Set::add}{Invariant}(#t43);
+      }
+    final core::Iterable<dynamic>? #t44 = dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t44.{core::Object::==}(null))
+      for (final dynamic #t45 in #t44{core::Iterable<dynamic>}) {
+        final core::num #t46 = #t45 as{TypeError,ForNonNullableByDefault} core::num;
+        #t37.{core::Set::add}{Invariant}(#t46);
+      }
+    final core::Iterable<core::num>? #t47 = iterableIntSet;
+    if(!#t47.{core::Object::==}(null))
+      #t37.{core::Set::addAll}{Invariant}(#t47{core::Iterable<core::num>});
+    final core::Iterable<core::num>? #t48 = intSet;
+    if(!#t48.{core::Object::==}(null))
+      #t37.{core::Set::addAll}{Invariant}(#t48{core::Iterable<core::num>});
+  } =>#t37;
+  self::expect(core::List::generate<core::num>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set2);
+}
+static method main() → dynamic {
+  self::useAddAll();
+  self::useAddAllNullable();
+}
+static method expect(core::Set<dynamic> set1, core::Set<dynamic> set2) → void {
+  if(!set1.{_in::EfficientLengthIterable::length}.{core::num::==}(set2.{_in::EfficientLengthIterable::length})) {
+    throw "Unexpected length. Expected ${set1.{_in::EfficientLengthIterable::length}}, actual ${set2.{_in::EfficientLengthIterable::length}}.";
+  }
+  for (dynamic element in set1) {
+    if(!set2.{core::Set::contains}(element)) {
+      throw "Element ${element} not found. Expected ${set1}, actual ${set2}.";
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect
new file mode 100644
index 0000000..c97ce48
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect
@@ -0,0 +1,248 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+import "dart:_internal" as _in;
+
+static method useAddAll() → void {
+  dynamic dynamicSet1 = block {
+    final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t1.{core::Set::add}{Invariant}(0);
+    #t1.{core::Set::add}{Invariant}(1);
+    #t1.{core::Set::add}{Invariant}(2);
+  } =>#t1;
+  dynamic dynamicSet2 = block {
+    final core::Set<core::num> #t2 = new col::_CompactLinkedHashSet::•<core::num>();
+    #t2.{core::Set::add}{Invariant}(3);
+    #t2.{core::Set::add}{Invariant}(4);
+    #t2.{core::Set::add}{Invariant}(5);
+  } =>#t2;
+  dynamic dynamicSet3 = block {
+    final core::Set<core::int?> #t3 = new col::_CompactLinkedHashSet::•<core::int?>();
+    #t3.{core::Set::add}{Invariant}(6);
+    #t3.{core::Set::add}{Invariant}(7);
+    #t3.{core::Set::add}{Invariant}(8);
+  } =>#t3;
+  core::Iterable<core::int> iterableIntSet = block {
+    final core::Set<core::int> #t4 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t4.{core::Set::add}{Invariant}(9);
+    #t4.{core::Set::add}{Invariant}(10);
+    #t4.{core::Set::add}{Invariant}(11);
+  } =>#t4;
+  core::Set<core::int> intSet = block {
+    final core::Set<core::int> #t5 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t5.{core::Set::add}{Invariant}(12);
+    #t5.{core::Set::add}{Invariant}(13);
+    #t5.{core::Set::add}{Invariant}(14);
+  } =>#t5;
+  core::Set<core::int> set1 = block {
+    final core::Set<core::int> #t6 = new col::_CompactLinkedHashSet::•<core::int>();
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t7 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t8 = #t7 as{TypeError,ForNonNullableByDefault} core::int;
+          #t6.{core::Set::add}{Invariant}(#t8);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t10 = #t9 as{TypeError,ForNonNullableByDefault} core::int;
+          #t6.{core::Set::add}{Invariant}(#t10);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::int;
+          #t6.{core::Set::add}{Invariant}(#t12);
+        }
+      }
+    }
+    #t6.{core::Set::addAll}{Invariant}(iterableIntSet);
+    #t6.{core::Set::addAll}{Invariant}(intSet);
+  } =>#t6;
+  self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set1);
+  core::Set<core::num> set2 = block {
+    final core::Set<core::num> #t13 = new col::_CompactLinkedHashSet::•<core::num>();
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t14 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t15 = #t14 as{TypeError,ForNonNullableByDefault} core::num;
+          #t13.{core::Set::add}{Invariant}(#t15);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t17 = #t16 as{TypeError,ForNonNullableByDefault} core::num;
+          #t13.{core::Set::add}{Invariant}(#t17);
+        }
+      }
+    }
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t19 = #t18 as{TypeError,ForNonNullableByDefault} core::num;
+          #t13.{core::Set::add}{Invariant}(#t19);
+        }
+      }
+    }
+    #t13.{core::Set::addAll}{Invariant}(iterableIntSet);
+    #t13.{core::Set::addAll}{Invariant}(intSet);
+  } =>#t13;
+  self::expect(core::_GrowableList::generate<core::num>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set2);
+}
+static method useAddAllNullable() → void {
+  dynamic dynamicSet1 = block {
+    final core::Set<core::int> #t20 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t20.{core::Set::add}{Invariant}(0);
+    #t20.{core::Set::add}{Invariant}(1);
+    #t20.{core::Set::add}{Invariant}(2);
+  } =>#t20;
+  dynamic dynamicSet2 = block {
+    final core::Set<core::num> #t21 = new col::_CompactLinkedHashSet::•<core::num>();
+    #t21.{core::Set::add}{Invariant}(3);
+    #t21.{core::Set::add}{Invariant}(4);
+    #t21.{core::Set::add}{Invariant}(5);
+  } =>#t21;
+  dynamic dynamicSet3 = block {
+    final core::Set<core::int?> #t22 = new col::_CompactLinkedHashSet::•<core::int?>();
+    #t22.{core::Set::add}{Invariant}(6);
+    #t22.{core::Set::add}{Invariant}(7);
+    #t22.{core::Set::add}{Invariant}(8);
+  } =>#t22;
+  core::Iterable<core::int>? iterableIntSet = true ?{core::Set<core::int>?} block {
+    final core::Set<core::int> #t23 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t23.{core::Set::add}{Invariant}(9);
+    #t23.{core::Set::add}{Invariant}(10);
+    #t23.{core::Set::add}{Invariant}(11);
+  } =>#t23 : null;
+  core::Set<core::int>? intSet = true ?{core::Set<core::int>?} block {
+    final core::Set<core::int> #t24 = new col::_CompactLinkedHashSet::•<core::int>();
+    #t24.{core::Set::add}{Invariant}(12);
+    #t24.{core::Set::add}{Invariant}(13);
+    #t24.{core::Set::add}{Invariant}(14);
+  } =>#t24 : null;
+  core::Set<core::int> set1 = block {
+    final core::Set<core::int> #t25 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Iterable<dynamic>? #t26 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t26.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t26{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t27 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t28 = #t27 as{TypeError,ForNonNullableByDefault} core::int;
+          #t25.{core::Set::add}{Invariant}(#t28);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t29 = dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t29.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t29{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t30 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t31 = #t30 as{TypeError,ForNonNullableByDefault} core::int;
+          #t25.{core::Set::add}{Invariant}(#t31);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t32 = dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t32.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t32{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t33 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::int #t34 = #t33 as{TypeError,ForNonNullableByDefault} core::int;
+          #t25.{core::Set::add}{Invariant}(#t34);
+        }
+      }
+    }
+    final core::Iterable<core::int>? #t35 = iterableIntSet;
+    if(!#t35.{core::Object::==}(null))
+      #t25.{core::Set::addAll}{Invariant}(#t35{core::Iterable<core::int>});
+    final core::Iterable<core::int>? #t36 = intSet;
+    if(!#t36.{core::Object::==}(null))
+      #t25.{core::Set::addAll}{Invariant}(#t36{core::Iterable<core::int>});
+  } =>#t25;
+  self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set1);
+  core::Set<core::num> set2 = block {
+    final core::Set<core::num> #t37 = new col::_CompactLinkedHashSet::•<core::num>();
+    final core::Iterable<dynamic>? #t38 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t38.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t38{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t39 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t40 = #t39 as{TypeError,ForNonNullableByDefault} core::num;
+          #t37.{core::Set::add}{Invariant}(#t40);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t41 = dynamicSet2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t41.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t41{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t42 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t43 = #t42 as{TypeError,ForNonNullableByDefault} core::num;
+          #t37.{core::Set::add}{Invariant}(#t43);
+        }
+      }
+    }
+    final core::Iterable<dynamic>? #t44 = dynamicSet3 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
+    if(!#t44.{core::Object::==}(null)) {
+      core::Iterator<dynamic> :sync-for-iterator = #t44{core::Iterable<dynamic>}.{core::Iterable::iterator};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+        final dynamic #t45 = :sync-for-iterator.{core::Iterator::current};
+        {
+          final core::num #t46 = #t45 as{TypeError,ForNonNullableByDefault} core::num;
+          #t37.{core::Set::add}{Invariant}(#t46);
+        }
+      }
+    }
+    final core::Iterable<core::num>? #t47 = iterableIntSet;
+    if(!#t47.{core::Object::==}(null))
+      #t37.{core::Set::addAll}{Invariant}(#t47{core::Iterable<core::num>});
+    final core::Iterable<core::num>? #t48 = intSet;
+    if(!#t48.{core::Object::==}(null))
+      #t37.{core::Set::addAll}{Invariant}(#t48{core::Iterable<core::num>});
+  } =>#t37;
+  self::expect(core::_GrowableList::generate<core::num>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(), set2);
+}
+static method main() → dynamic {
+  self::useAddAll();
+  self::useAddAllNullable();
+}
+static method expect(core::Set<dynamic> set1, core::Set<dynamic> set2) → void {
+  if(!set1.{_in::EfficientLengthIterable::length}.{core::num::==}(set2.{_in::EfficientLengthIterable::length})) {
+    throw "Unexpected length. Expected ${set1.{_in::EfficientLengthIterable::length}}, actual ${set2.{_in::EfficientLengthIterable::length}}.";
+  }
+  {
+    core::Iterator<dynamic> :sync-for-iterator = set1.{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      dynamic element = :sync-for-iterator.{core::Iterator::current};
+      {
+        if(!set2.{core::Set::contains}(element)) {
+          throw "Element ${element} not found. Expected ${set1}, actual ${set2}.";
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart b/pkg/front_end/testcases/unified_collections/string_concatenation.dart
index 9d9d77c..d1528c2 100644
--- a/pkg/front_end/testcases/unified_collections/string_concatenation.dart
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.9
+
 main() {
   bool b = false;
   ['a' 'b', if (b) 'c' 'd'];
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.outline.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.outline.expect
deleted file mode 100644
index 6a28c0d..0000000
--- a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.outline.expect
+++ /dev/null
@@ -1,5 +0,0 @@
-library;
-import self as self;
-
-static method main() → dynamic
-  ;
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.strong.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.strong.expect
deleted file mode 100644
index f3953a4..0000000
--- a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.strong.expect
+++ /dev/null
@@ -1,13 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main() → dynamic {
-  core::bool* b = false;
-  block {
-    final core::List<core::String*>* #t1 = <core::String*>[];
-    #t1.{core::List::add}{Invariant}("ab");
-    if(b)
-      #t1.{core::List::add}{Invariant}("cd");
-  } =>#t1;
-}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.strong.transformed.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.strong.transformed.expect
deleted file mode 100644
index 44b114b..0000000
--- a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.strong.transformed.expect
+++ /dev/null
@@ -1,19 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main() → dynamic {
-  core::bool* b = false;
-  block {
-    final core::List<core::String*>* #t1 = <core::String*>[];
-    #t1.{core::List::add}{Invariant}("ab");
-    if(b)
-      #t1.{core::List::add}{Invariant}("cd");
-  } =>#t1;
-}
-
-
-Extra constant evaluation status:
-Evaluated: StringConcatenation @ org-dartlang-testcase:///string_concatenation.dart:7:3 -> StringConstant("ab")
-Evaluated: StringConcatenation @ org-dartlang-testcase:///string_concatenation.dart:7:18 -> StringConstant("cd")
-Extra constant evaluation: evaluated: 10, effectively constant: 2
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
index bae895a..7c126a2 100644
--- a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
@@ -1 +1,2 @@
+// @dart = 2.9
 main() {}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
index bae895a..7c126a2 100644
--- a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
@@ -1 +1,2 @@
+// @dart = 2.9
 main() {}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.weak.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.weak.expect
new file mode 100644
index 0000000..0229f5c
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.weak.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::bool* b = false;
+  block {
+    final core::List<core::String*>* #t1 = <core::String*>["ab"];
+    if(b)
+      #t1.{core::List::add}{Invariant}("cd");
+  } =>#t1;
+}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.weak.transformed.expect
new file mode 100644
index 0000000..b8d8ac8
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.weak.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::bool* b = false;
+  block {
+    final core::List<core::String*>* #t1 = <core::String*>["ab"];
+    if(b)
+      #t1.{core::List::add}{Invariant}("cd");
+  } =>#t1;
+}
+
+
+Extra constant evaluation status:
+Evaluated: StringConcatenation @ org-dartlang-testcase:///string_concatenation.dart:9:3 -> StringConstant("ab")
+Evaluated: StringConcatenation @ org-dartlang-testcase:///string_concatenation.dart:9:18 -> StringConstant("cd")
+Extra constant evaluation: evaluated: 8, effectively constant: 2
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect
index 93422d0..f6aa033 100644
--- a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: Optional parameter 'bar' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: The parameter 'bar' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                     ^^^
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: Optional parameter 'bar2' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: The parameter 'bar2' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                              ^^^^
 //
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect
index e404600..4449dd3 100644
--- a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: Optional parameter 'bar' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: The parameter 'bar' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                     ^^^
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: Optional parameter 'bar2' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: The parameter 'bar2' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                              ^^^^
 //
@@ -57,13 +59,13 @@
   synthetic constructor •({required core::int? numberOfWhiskers, core::int? numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 class Foo extends core::Object {
@@ -83,13 +85,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///copy_with_call_sites.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect
index 90ed8ba..57c58e3 100644
--- a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: Optional parameter 'bar' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: The parameter 'bar' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                     ^^^
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: Optional parameter 'bar2' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: The parameter 'bar2' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                              ^^^^
 //
@@ -57,13 +59,13 @@
   synthetic constructor •({required core::int? numberOfWhiskers, core::int? numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 class Foo extends core::Object {
@@ -83,13 +85,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///copy_with_call_sites.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect
index e404600..4449dd3 100644
--- a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: Optional parameter 'bar' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: The parameter 'bar' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                     ^^^
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: Optional parameter 'bar2' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: The parameter 'bar2' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                              ^^^^
 //
@@ -57,13 +59,13 @@
   synthetic constructor •({required core::int? numberOfWhiskers, core::int? numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 class Foo extends core::Object {
@@ -83,13 +85,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///copy_with_call_sites.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect
index 90ed8ba..57c58e3 100644
--- a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect
@@ -2,11 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: Optional parameter 'bar' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:21: Error: The parameter 'bar' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                     ^^^
 //
-// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: Optional parameter 'bar2' should have a default value because its type 'int' doesn't allow null.
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:20:30: Error: The parameter 'bar2' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
+// Try adding either an explicit non-'null' default value or the 'required' modifier.
 //   Foo copyWith({int bar, int bar2}) {
 //                              ^^^^
 //
@@ -57,13 +59,13 @@
   synthetic constructor •({required core::int? numberOfWhiskers, core::int? numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int? numberOfLegs, core::int? numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 class Foo extends core::Object {
@@ -83,13 +85,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///copy_with_call_sites.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/empty.dart.strong.expect b/pkg/front_end/testcases/value_class/empty.dart.strong.expect
index ea8f20e..ad09297 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.strong.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::EmptyClass
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::EmptyClass;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "EmptyClass()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::EmptyClass::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
index 0ce153d..ccb643b 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::EmptyClass
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::EmptyClass;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "EmptyClass()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::EmptyClass::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.weak.expect b/pkg/front_end/testcases/value_class/empty.dart.weak.expect
index ea8f20e..ad09297 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.weak.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::EmptyClass
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::EmptyClass;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "EmptyClass()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::EmptyClass::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
index 0ce153d..ccb643b 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::EmptyClass
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::EmptyClass;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "EmptyClass()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::EmptyClass::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
index 8f5b282..1dddd63 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
@@ -42,13 +42,13 @@
   synthetic constructor •() → self::F
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::F;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "F()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::F::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
index f6df7f8..3265e24 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
@@ -37,26 +37,26 @@
   synthetic constructor •() → self::E
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class F extends self::B implements self::C /*isEliminatedMixin*/  {
   synthetic constructor •() → self::F
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::F;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "F()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::F::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
index 8f5b282..1dddd63 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
@@ -42,13 +42,13 @@
   synthetic constructor •() → self::F
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::F;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "F()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::F::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
index f6df7f8..3265e24 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
@@ -37,26 +37,26 @@
   synthetic constructor •() → self::E
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class F extends self::B implements self::C /*isEliminatedMixin*/  {
   synthetic constructor •() → self::F
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::F;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "F()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::F::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
index 106c4ea..a306bf0 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
@@ -17,13 +17,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
index 106c4ea..a306bf0 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
@@ -17,13 +17,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
index 106c4ea..a306bf0 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
@@ -17,13 +17,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
index 106c4ea..a306bf0 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
@@ -17,13 +17,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
index 8b97d06..d077f3e 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
@@ -18,13 +18,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
index 8b97d06..d077f3e 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
@@ -18,13 +18,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
index 8b97d06..d077f3e 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
@@ -18,13 +18,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
index 8b97d06..d077f3e 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
@@ -18,13 +18,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
index c12b1c3..21c901e 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
@@ -23,13 +23,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends core::Object implements self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
index c12b1c3..21c901e 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
@@ -23,13 +23,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends core::Object implements self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
index c12b1c3..21c901e 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
@@ -23,13 +23,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends core::Object implements self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
index c12b1c3..21c901e 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
@@ -23,13 +23,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 class Cat extends core::Object implements self::Animal {
diff --git a/pkg/front_end/testcases/value_class/simple.dart.strong.expect b/pkg/front_end/testcases/value_class/simple.dart.strong.expect
index 67bbec1..9c011f1 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.strong.expect
@@ -39,13 +39,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
index 88adc14..f8dee0a 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
@@ -39,13 +39,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/simple.dart.weak.expect b/pkg/front_end/testcases/value_class/simple.dart.weak.expect
index 67bbec1..9c011f1 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.weak.expect
@@ -39,13 +39,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
index 88adc14..f8dee0a 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
@@ -39,13 +39,13 @@
   synthetic constructor •({required core::int numberOfLegs}) → self::Animal
     : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Animal(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs}) → dynamic
     return new self::Animal::•(numberOfLegs: numberOfLegs);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
index 8ab2483..9ba8a2f 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
@@ -45,13 +45,13 @@
   synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
index 2227f34..cac374d 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
@@ -45,13 +45,13 @@
   synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
index 8ab2483..9ba8a2f 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
@@ -45,13 +45,13 @@
   synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
index 2227f34..cac374d 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
@@ -45,13 +45,13 @@
   synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
     : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Animal::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
index 95e0356..e039566 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
@@ -27,13 +27,13 @@
   synthetic constructor •() → self::Cat
     : super self::Animal::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat::•();
 }
 class Animal2 extends core::Object {
@@ -46,13 +46,13 @@
   synthetic constructor •() → self::Cat2
     : super self::Animal2::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat2::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
index b55acf5..d80dd8f 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
@@ -27,13 +27,13 @@
   synthetic constructor •() → self::Cat
     : super self::Animal::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat::•();
 }
 class Animal2 extends core::Object {
@@ -46,13 +46,13 @@
   synthetic constructor •() → self::Cat2
     : super self::Animal2::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat2::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
index 95e0356..e039566 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
@@ -27,13 +27,13 @@
   synthetic constructor •() → self::Cat
     : super self::Animal::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat::•();
 }
 class Animal2 extends core::Object {
@@ -46,13 +46,13 @@
   synthetic constructor •() → self::Cat2
     : super self::Animal2::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat2::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
index b55acf5..d80dd8f 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
@@ -27,13 +27,13 @@
   synthetic constructor •() → self::Cat
     : super self::Animal::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat::•();
 }
 class Animal2 extends core::Object {
@@ -46,13 +46,13 @@
   synthetic constructor •() → self::Cat2
     : super self::Animal2::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::Cat2::•();
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
index ea9e6be..e8f803a 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
@@ -87,13 +87,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
     : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Cat::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 abstract class Animal2 extends core::Object {
@@ -108,13 +108,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat2
     : self::Cat2::numberOfLegs = numberOfLegs, self::Cat2::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2(numberOfLegs: ${this.{self::Cat2::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat2::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
index dfd6ccf..bb58694 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
@@ -87,13 +87,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
     : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Cat::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 abstract class Animal2 extends core::Object {
@@ -108,13 +108,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat2
     : self::Cat2::numberOfLegs = numberOfLegs, self::Cat2::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2(numberOfLegs: ${this.{self::Cat2::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat2::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
index ea9e6be..e8f803a 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
@@ -87,13 +87,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
     : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Cat::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 abstract class Animal2 extends core::Object {
@@ -108,13 +108,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat2
     : self::Cat2::numberOfLegs = numberOfLegs, self::Cat2::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2(numberOfLegs: ${this.{self::Cat2::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat2::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
index dfd6ccf..bb58694 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
@@ -87,13 +87,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
     : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat(numberOfLegs: ${this.{self::Cat::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 abstract class Animal2 extends core::Object {
@@ -108,13 +108,13 @@
   synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat2
     : self::Cat2::numberOfLegs = numberOfLegs, self::Cat2::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "Cat2(numberOfLegs: ${this.{self::Cat2::numberOfLegs}.{core::int::toString}()}, numberOfWhiskers: ${this.{self::Cat2::numberOfWhiskers}.{core::int::toString}()})";
-  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+  method /*isLegacy*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
     return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
index 5b97acf..5391b61 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
index 5b474c0..4bf6fa3 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
@@ -27,13 +27,13 @@
   synthetic constructor •() → self::_C&B&A
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class C extends self::_C&B&A {
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
index 5b97acf..5391b61 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
index 5b474c0..4bf6fa3 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
@@ -9,13 +9,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class B extends core::Object {
@@ -27,13 +27,13 @@
   synthetic constructor •() → self::_C&B&A
     : super self::B::•()
     ;
-  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+  operator /*isLegacy*/ ==(core::Object other) → core::bool
     return other is self::A;
-  get /*isNullableByDefault*/ hashCode() → core::int
+  get /*isLegacy*/ hashCode() → core::int
     return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
-  method /*isNullableByDefault*/ toString() → core::String
+  method /*isLegacy*/ toString() → core::String
     return "A()";
-  method /*isNullableByDefault*/ copyWith() → dynamic
+  method /*isLegacy*/ copyWith() → dynamic
     return new self::A::•();
 }
 class C extends self::_C&B&A {
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index deda925..50bd29e 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -79,7 +79,8 @@
         "/testcases/general_nnbd_opt_out/",
         "/testcases/nnbd_mixed/",
         "/testcases/nonfunction_type_aliases/",
-        "/testcases/static_field_lowering/"
+        "/testcases/static_field_lowering/",
+        "/testcases/unified_collections"
       ]
     },
     {
@@ -101,7 +102,8 @@
         "/testcases/general_nnbd_opt_out/",
         "/testcases/nnbd_mixed/",
         "/testcases/nonfunction_type_aliases/",
-        "/testcases/static_field_lowering/"
+        "/testcases/static_field_lowering/",
+        "/testcases/unified_collections"
       ]
     },
     {
@@ -123,7 +125,8 @@
         "/testcases/general_nnbd_opt_out/",
         "/testcases/nnbd_mixed/",
         "/testcases/nonfunction_type_aliases/",
-        "/testcases/static_field_lowering/"
+        "/testcases/static_field_lowering/",
+        "/testcases/unified_collections"
       ]
     },
     {
@@ -145,7 +148,8 @@
         "/testcases/general_nnbd_opt_out/",
         "/testcases/nnbd_mixed/",
         "/testcases/nonfunction_type_aliases/",
-        "/testcases/static_field_lowering/"
+        "/testcases/static_field_lowering/",
+        "/testcases/unified_collections"
       ]
     },
     {
@@ -175,7 +179,6 @@
         "/testcases/runtime_checks",
         "/testcases/runtime_checks_new",
         "/testcases/set_literals",
-        "/testcases/unified_collections",
         "/testcases/variance"
       ]
     },
@@ -284,9 +287,11 @@
       "status": "test/lint_test.status",
       "pattern": [
         "_fe_analyzer_shared/lib/.*\\.dart$",
+        "kernel/lib/.*\\.dart$",
         "front_end/lib/.*\\.dart$"
       ],
       "exclude": [
+        "kernel/lib/transformations/.*\\.dart$",
         "_fe_analyzer_shared/lib/src/messages/codes_generated\\.dart$",
         "front_end/lib/src/fasta/fasta_codes_cfe_generated\\.dart$"
       ]
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 0404554..ed79435 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -51,7 +51,7 @@
     show SchemeBasedFileSystem;
 
 import 'package:kernel/target/targets.dart'
-    show Target, getTarget, TargetFlags, targets;
+    show LateLowering, Target, getTarget, TargetFlags, targets;
 
 class CommandLineProblem {
   final Message message;
@@ -242,7 +242,9 @@
           onWarning: print);
 
   final TargetFlags flags = new TargetFlags(
-      forceLateLoweringForTesting: options[Flags.forceLateLowering],
+      forceLateLoweringsForTesting: options[Flags.forceLateLowering]
+          ? LateLowering.all
+          : LateLowering.none,
       forceStaticFieldLoweringForTesting:
           options[Flags.forceStaticFieldLowering],
       forceNoExplicitGetterCallsForTesting:
diff --git a/pkg/front_end/tool/_fasta/direct_parser_ast_helper_creator.dart b/pkg/front_end/tool/_fasta/direct_parser_ast_helper_creator.dart
index 2153705..8b7cf18 100644
--- a/pkg/front_end/tool/_fasta/direct_parser_ast_helper_creator.dart
+++ b/pkg/front_end/tool/_fasta/direct_parser_ast_helper_creator.dart
@@ -48,6 +48,8 @@
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:front_end/src/fasta/messages.dart';
 
+// ignore_for_file: lines_longer_than_80_chars
+
 // THIS FILE IS AUTO GENERATED BY
 // 'tool/_fasta/direct_parser_ast_helper_creator.dart'
 // Run e.g.
@@ -57,23 +59,23 @@
       > pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
 */
 
-class DirectParserASTContent {
+abstract class DirectParserASTContent {
   final String what;
   final DirectParserASTType type;
-  final Map<String, Object> arguments;
-  List<DirectParserASTContent> content;
+  Map<String, Object> get deprecatedArguments;
+  List<DirectParserASTContent> children;
 
-  DirectParserASTContent(this.what, this.type, this.arguments);
+  DirectParserASTContent(this.what, this.type);
 
   // TODO(jensj): Compare two ASTs.
 }
 
-enum DirectParserASTType { BEGIN, END, HANDLE, DONE }
+enum DirectParserASTType { BEGIN, END, HANDLE }
 
 abstract class AbstractDirectParserASTListener implements Listener {
   List<DirectParserASTContent> data = [];
 
-  void seen(String what, DirectParserASTType type, Map<String, Object> arguments);
+  void seen(DirectParserASTContent entry);
 
 """);
 
@@ -82,6 +84,8 @@
   parser.parseUnit(firstToken);
 
   out.writeln("}");
+  out.writeln("");
+  out.write(listener.newClasses.toString());
 
   if (out is StringBuffer) {
     String text = new DartFormatter().format("$out");
@@ -99,6 +103,7 @@
   String latestSeenParameterTypeToken;
   List<String> parameters = <String>[];
   List<String> parameterTypes = <String>[];
+  StringBuffer newClasses = new StringBuffer();
 
   void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
     if (name.lexeme == "Listener") insideListenerClass = true;
@@ -150,39 +155,79 @@
         return end();
       } else {
         sb.write("\n    ");
-        sb.write('seen("');
         String typeString;
+        String typeStringCamel;
         String name;
         if (currentMethodName.startsWith("begin")) {
           typeString = "BEGIN";
+          typeStringCamel = "Begin";
           name = currentMethodName.substring("begin".length);
         } else if (currentMethodName.startsWith("end")) {
           typeString = "END";
+          typeStringCamel = "End";
           name = currentMethodName.substring("end".length);
         } else if (currentMethodName.startsWith("handle")) {
           typeString = "HANDLE";
+          typeStringCamel = "Handle";
           name = currentMethodName.substring("handle".length);
         } else {
           throw "Unexpected.";
         }
-        sb.write(name);
-        sb.write('", DirectParserASTType.');
+
+        String className = "DirectParserASTContent${name}${typeStringCamel}";
+        sb.write("$className data = new $className(");
+        sb.write("DirectParserASTType.");
         sb.write(typeString);
-        sb.write(", {");
-        String separator = "";
         for (int i = 0; i < parameters.length; i++) {
-          sb.write(separator);
-          sb.write('"');
+          sb.write(', ');
           sb.write(parameters[i]);
-          sb.write('": ');
+          sb.write(': ');
           sb.write(parameters[i]);
-          separator = ", ";
         }
 
-        sb.write("});\n  ");
+        sb.write(");");
+        sb.write("\n    ");
+        sb.write("seen(data);");
+        sb.write("\n  ");
 
-        sb.write("}");
+        newClasses
+            .write("class DirectParserASTContent${name}${typeStringCamel} "
+                "extends DirectParserASTContent {\n");
+
+        for (int i = 0; i < parameters.length; i++) {
+          newClasses.write("  final ");
+          newClasses.write(parameterTypes[i]);
+          newClasses.write(' ');
+          newClasses.write(parameters[i]);
+          newClasses.write(';\n');
+        }
+        newClasses.write('\n');
+        newClasses.write("  DirectParserASTContent${name}${typeStringCamel}"
+            "(DirectParserASTType type");
+        String separator = ", {";
+        for (int i = 0; i < parameters.length; i++) {
+          newClasses.write(separator);
+          newClasses.write('this.');
+          newClasses.write(parameters[i]);
+          separator = ", ";
+        }
+        if (parameters.isNotEmpty) {
+          newClasses.write('}');
+        }
+        newClasses.write(') : super("$name", type);\n\n');
+        newClasses.write("Map<String, Object> get deprecatedArguments => {");
+        for (int i = 0; i < parameters.length; i++) {
+          newClasses.write('"');
+          newClasses.write(parameters[i]);
+          newClasses.write('": ');
+          newClasses.write(parameters[i]);
+          newClasses.write(',');
+        }
+        newClasses.write("};\n");
+        newClasses.write("}\n");
       }
+
+      sb.write("}");
       sb.write("\n\n");
 
       out.write(sb.toString());
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 03a5e96..1aa2265 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -485,7 +485,7 @@
   StringBuffer sb = new StringBuffer();
   sb.write(toRelativeFilePath(output));
   sb.write(":");
-  List<String> paths = new List<String>(allDependencies.length);
+  List<String> paths = new List<String>.filled(allDependencies.length, null);
   for (int i = 0; i < allDependencies.length; i++) {
     paths[i] = toRelativeFilePath(allDependencies[i]);
   }
diff --git a/pkg/front_end/tool/kernel_ast_file_rewriter.dart b/pkg/front_end/tool/kernel_ast_file_rewriter.dart
new file mode 100644
index 0000000..bdefeae
--- /dev/null
+++ b/pkg/front_end/tool/kernel_ast_file_rewriter.dart
@@ -0,0 +1,428 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io" show File, Platform, stdout;
+import "dart:typed_data" show Uint8List;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import "package:front_end/src/fasta/util/direct_parser_ast.dart";
+import "package:front_end/src/fasta/util/direct_parser_ast_helper.dart"
+    show DirectParserASTContent;
+import 'package:_fe_analyzer_shared/src/parser/parser.dart'
+    show IdentifierContext;
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
+
+void main(List<String> args) {
+  Uri uri = Platform.script;
+  uri = uri.resolve("../../kernel/lib/ast.dart");
+  Uint8List bytes = new File.fromUri(uri).readAsBytesSync();
+  DirectParserASTContentCompilationUnitEnd ast =
+      getAST(bytes, includeBody: true, includeComments: true);
+  Map<String, DirectParserASTContentTopLevelDeclarationEnd> classes = {};
+  for (DirectParserASTContentTopLevelDeclarationEnd cls in ast.getClasses()) {
+    DirectParserASTContentIdentifierHandle identifier = cls.getIdentifier();
+    assert(classes[identifier.token] == null);
+    classes[identifier.token.toString()] = cls;
+  }
+
+  Set<String> goodNames = {"TreeNode"};
+  Map<Token, Replacement> replacements = {};
+  for (MapEntry<String, DirectParserASTContentTopLevelDeclarationEnd> entry
+      in classes.entries) {
+    DirectParserASTContentTopLevelDeclarationEnd cls = entry.value;
+
+    // Simple "class hierarchy" to only work on TreeNodes.
+    if (goodNames.contains(entry.key)) {
+      // Cached good.
+    } else {
+      // Check if good.
+      String parent = getExtends(cls);
+      DirectParserASTContentTopLevelDeclarationEnd parentCls = classes[parent];
+      List<String> allParents = [parent];
+      while (
+          parent != null && parentCls != null && !goodNames.contains(parent)) {
+        parent = getExtends(parentCls);
+        allParents.add(parent);
+        parentCls = classes[parent];
+      }
+      if (goodNames.contains(parent)) {
+        goodNames.addAll(allParents);
+      } else {
+        continue;
+      }
+    }
+
+    DirectParserASTContentClassDeclarationEnd classDeclaration =
+        cls.getClassDeclaration();
+    DirectParserASTContentClassOrMixinBodyEnd classOrMixinBody =
+        classDeclaration.getClassOrMixinBody();
+
+    Set<String> namedClassConstructors = {};
+    Set<String> namedFields = {};
+    for (DirectParserASTContentMemberEnd member
+        in classOrMixinBody.getMembers()) {
+      if (member.isClassConstructor()) {
+        DirectParserASTContentClassConstructorEnd constructor =
+            member.getClassConstructor();
+        Token nameToken = constructor.beginToken;
+        // String name = nameToken.lexeme;
+        if (nameToken.next.lexeme == ".") {
+          nameToken = nameToken.next.next;
+          // name += ".$nameToken";
+          namedClassConstructors.add(nameToken.lexeme);
+        }
+        if (nameToken.next.lexeme == ".") {
+          throw "Unexpected";
+        }
+      } else if (member.isClassFields()) {
+        DirectParserASTContentClassFieldsEnd classFields =
+            member.getClassFields();
+        Token identifierToken = classFields.getFieldIdentifiers().single.token;
+        String identifier = identifierToken.toString();
+        namedFields.add(identifier);
+      }
+    }
+
+    // If there isn't a `frozen` field in `TreeNode` we insert one.
+    if (entry.key == "TreeNode" && !namedFields.contains("frozen")) {
+      Token classBraceToken = classOrMixinBody.beginToken;
+      assert(classBraceToken.lexeme == "{");
+      replacements[classBraceToken] = new Replacement(
+          classBraceToken, classBraceToken, "{\n  bool frozen = false;");
+    }
+
+    for (DirectParserASTContentMemberEnd member
+        in classOrMixinBody.getMembers()) {
+      if (member.isClassConstructor()) {
+        processConstructor(
+            member, replacements, namedClassConstructors, namedFields);
+      } else if (member.isClassFields()) {
+        processField(member, entry, replacements);
+      }
+    }
+  }
+  Token token = ast.getBegin().token;
+
+  int endOfLast = token.end;
+  while (token != null) {
+    CommentToken comment = token.precedingComments;
+    while (comment != null) {
+      if (comment.offset > endOfLast) {
+        for (int i = endOfLast; i < comment.offset; i++) {
+          int byte = bytes[i];
+          stdout.writeCharCode(byte);
+        }
+      }
+
+      stdout.write(comment.value());
+      endOfLast = comment.end;
+      comment = comment.next;
+    }
+
+    if (token.isEof) break;
+    if (token.offset > endOfLast) {
+      for (int i = endOfLast; i < token.offset; i++) {
+        int byte = bytes[i];
+        stdout.writeCharCode(byte);
+      }
+    }
+
+    Replacement replacement = replacements[token];
+    if (replacement != null) {
+      stdout.write(replacement.replacement);
+      token = replacement.endToken;
+    } else {
+      stdout.write(token.lexeme);
+    }
+    endOfLast = token.end;
+    token = token.next;
+  }
+}
+
+void processField(
+    DirectParserASTContentMemberEnd member,
+    MapEntry<String, DirectParserASTContentTopLevelDeclarationEnd> entry,
+    Map<Token, Replacement> replacements) {
+  DirectParserASTContentClassFieldsEnd classFields = member.getClassFields();
+
+  if (classFields.count != 1) {
+    throw "Notice ${classFields.count}";
+  }
+
+  Token identifierToken = classFields.getFieldIdentifiers().single.token;
+  String identifier = identifierToken.toString();
+
+  if (identifier == "frozen" && entry.key == "TreeNode") return;
+
+  if (classFields.staticToken != null) {
+    return;
+  }
+  bool isFinal = false;
+  if (classFields.varFinalOrConst?.toString() == "final") {
+    isFinal = true;
+  }
+
+  DirectParserASTContentTypeHandle type = classFields.getFirstType();
+  String typeString = "dynamic";
+  if (type != null) {
+    Token token = type.beginToken;
+    typeString = "";
+    while (token != identifierToken) {
+      typeString += " ${token.lexeme}";
+      token = token.next;
+    }
+    typeString = typeString.trim();
+  }
+
+  DirectParserASTContentFieldInitializerEnd initializer =
+      classFields.getFieldInitializer();
+  String initializerString = "";
+  if (initializer != null) {
+    Token token = initializer.assignment;
+    Token endToken = initializer.token;
+    while (token != endToken) {
+      initializerString += " ${token.lexeme}";
+      token = token.next;
+    }
+    initializerString = initializerString.trim();
+  }
+
+  Token beginToken = classFields.beginToken;
+  Token endToken = classFields.endToken;
+  assert(beginToken != null);
+  assert(endToken != null);
+
+  String frozenCheckCode =
+      """if (frozen) throw "Trying to modify frozen node!";""";
+
+  if (identifier == "parent" && entry.key == "TreeNode") {
+    // We update the parent for libraries for instance all the time (e.g.
+    // when we link).
+    frozenCheckCode = "";
+  } else if (identifier == "transformerFlags" && entry.key == "Member") {
+    // The verifier changes this for all libraries
+    // (and then change it back again).
+    frozenCheckCode = "";
+  } else if (identifier == "initializer" && entry.key == "Field") {
+    // The constant evaluator does some stuff here. Only allow that
+    // when it's basically a no-op though!
+    frozenCheckCode = """
+    if (frozen) {
+      if (_initializer is ConstantExpression && newValue is ConstantExpression) {
+        if ((_initializer as ConstantExpression).constant == newValue.constant) {
+          _initializer = newValue;
+          return;
+        }
+      }
+      throw "Trying to modify frozen node!";
+    }""";
+  }
+
+  if (!isFinal) {
+    replacements[beginToken] = new Replacement(beginToken, endToken, """
+$typeString _$identifier$initializerString;
+$typeString get $identifier => _$identifier;
+void set $identifier($typeString newValue) {
+    $frozenCheckCode
+  _$identifier = newValue;
+}""");
+  } else {
+    // Don't create setter for final field.
+    // TODO: Possibly wrap a list for instance of a non-writable one.
+    replacements[beginToken] = new Replacement(beginToken, endToken, """
+final $typeString _$identifier$initializerString;
+$typeString get $identifier => _$identifier;""");
+  }
+}
+
+void processConstructor(
+    DirectParserASTContentMemberEnd member,
+    Map<Token, Replacement> replacements,
+    Set<String> namedClassConstructors,
+    Set<String> namedFields) {
+  DirectParserASTContentClassConstructorEnd constructor =
+      member.getClassConstructor();
+  DirectParserASTContentFormalParametersEnd formalParameters =
+      constructor.getFormalParameters();
+  List<DirectParserASTContentFormalParameterEnd> parameters =
+      formalParameters.getFormalParameters();
+
+  for (DirectParserASTContentFormalParameterEnd parameter in parameters) {
+    Token token = parameter.getBegin().token;
+    if (token?.lexeme != "this") {
+      continue;
+    }
+    // Here `this.foo` can just be replace with `this._foo`.
+    Token afterDot = token.next.next;
+    replacements[afterDot] = new Replacement(afterDot, afterDot, "_$afterDot");
+  }
+
+  DirectParserASTContentOptionalFormalParametersEnd optionalFormalParameters =
+      formalParameters.getOptionalFormalParameters();
+  Set<String> addInitializers = {};
+  if (optionalFormalParameters != null) {
+    List<DirectParserASTContentFormalParameterEnd> parameters =
+        optionalFormalParameters.getFormalParameters();
+
+    for (DirectParserASTContentFormalParameterEnd parameter in parameters) {
+      Token token = parameter.getBegin().token;
+      if (token?.lexeme != "this") {
+        continue;
+      }
+      // Here `this.foo` can't just be replace with `this._foo` as it is
+      // (possibly) named and we can't use private stuff in named.
+      // Instead we replace it with `dynamic foo` here and add an
+      // initializer `this._foo = foo`.
+      Token afterDot = token.next.next;
+      addInitializers.add(afterDot.lexeme);
+      replacements[token] = new Replacement(token, token.next, "dynamic ");
+    }
+  }
+
+  DirectParserASTContentInitializersEnd initializers =
+      constructor.getInitializers();
+
+  // First patch up any existing initializers.
+  if (initializers != null) {
+    List<DirectParserASTContentInitializerEnd> actualInitializers =
+        initializers.getInitializers();
+    for (DirectParserASTContentInitializerEnd initializer
+        in actualInitializers) {
+      Token token = initializer.getBegin().token;
+      // This is only afterDot if there's a dot --- which (probably) is
+      // only there if there's a `this`.
+      Token afterDot = token.next.next;
+
+      // We need to check it's not a redirecting call!
+      // TODO(jensj): Handle redirects like this:
+      //  class C {
+      //    C();
+      //    C.redirect() : this();
+      //  }
+      if (token.lexeme == "this" &&
+          namedClassConstructors.contains(afterDot.lexeme)) {
+        // Redirect!
+        continue;
+      }
+
+      if (token.lexeme == "this") {
+        // Here `this.foo` can just be replace with `this._foo`.
+        assert(namedFields.contains(afterDot.lexeme));
+        replacements[afterDot] =
+            new Replacement(afterDot, afterDot, "_$afterDot");
+      } else if (token.lexeme == "super") {
+        // Don't try to patch this one.
+      } else if (token.lexeme == "assert") {
+        List<DirectParserASTContentIdentifierHandle> identifiers = initializer
+            .recursivelyFind<DirectParserASTContentIdentifierHandle>();
+        for (Token token in identifiers.map((e) => e.token)) {
+          if (namedFields.contains(token.lexeme)) {
+            replacements[token] = new Replacement(token, token, "_$token");
+          }
+        }
+      } else {
+        assert(namedFields.contains(token.lexeme),
+            "${token.lexeme} isn't a known field among ${namedFields}");
+        replacements[token] = new Replacement(token, token, "_$token");
+      }
+    }
+  }
+
+  // Then add any new ones.
+  if (addInitializers.isNotEmpty && initializers == null) {
+    // No initializers => Fake one by inserting `:` and all `_foo = foo`
+    // entries.
+    Token endToken = formalParameters.endToken;
+    String initializerString =
+        addInitializers.map((e) => "this._$e = $e").join(",\n");
+    replacements[endToken] =
+        new Replacement(endToken, endToken, ") : $initializerString");
+  } else if (addInitializers.isNotEmpty) {
+    // Add to existing initializer list. We add them as the first one(s)
+    // so we don't have to insert before the potential super call.
+    DirectParserASTContentInitializersBegin firstOne = initializers.getBegin();
+    Token colon = firstOne.token;
+    assert(colon.lexeme == ":");
+    String initializerString =
+        addInitializers.map((e) => "this._$e = $e").join(", ");
+    replacements[colon] =
+        new Replacement(colon, colon, ": $initializerString,");
+  }
+
+  // If there are anything in addInitializers we need to patch
+  // up the body too -- if we replace `{this.foo}` with `{dynamic foo}`
+  // and the body says `foo = 42;` before that would change the field,
+  // now it will change the parameter value. We must patch up all usages
+  // - even reads to work on things like
+  //  class C {
+  //    int field1;
+  //    int field2;
+  //    C(this.field1) : field2 = field1 + 1;
+  //  }
+  if (addInitializers.isNotEmpty) {
+    DirectParserASTContentBlockFunctionBodyEnd blockFunctionBody =
+        constructor.getBlockFunctionBody();
+    if (blockFunctionBody != null) {
+      List<DirectParserASTContentIdentifierHandle> identifiers =
+          blockFunctionBody
+              .recursivelyFind<DirectParserASTContentIdentifierHandle>();
+      for (DirectParserASTContentIdentifierHandle identifier in identifiers) {
+        Token token = identifier.token;
+        IdentifierContext context = identifier.context;
+        if (namedFields.contains(token.lexeme) &&
+            addInitializers.contains(token.lexeme)) {
+          // For now naively assume that if it's a continuation it says
+          // `this.`
+          if (!context.isContinuation) {
+            replacements[token] = new Replacement(token, token, "_$token");
+          }
+        }
+      }
+    }
+  }
+}
+
+class Replacement {
+  final Token beginToken;
+  final Token endToken;
+  final String replacement;
+
+  Replacement(this.beginToken, this.endToken, this.replacement);
+}
+
+String getExtends(DirectParserASTContentTopLevelDeclarationEnd cls) {
+  DirectParserASTContentClassDeclarationEnd classDeclaration =
+      cls.getClassDeclaration();
+
+  DirectParserASTContentClassExtendsHandle classExtends =
+      classDeclaration.getClassExtends();
+  Token extendsKeyword = classExtends.extendsKeyword;
+  if (extendsKeyword == null) {
+    return null;
+  } else {
+    return extendsKeyword.next.toString();
+  }
+}
+
+void debugDumpNode(DirectParserASTContent node) {
+  node.children.forEach((element) {
+    print("${element.what} (${element.deprecatedArguments}) "
+        "(${element.children})");
+  });
+}
+
+void debugDumpNodeRecursively(DirectParserASTContent node,
+    {String indent = ""}) {
+  print("$indent${node.what} (${node.deprecatedArguments})");
+  if (node.children == null) return;
+  node.children.forEach((element) {
+    print("$indent${element.what} (${element.deprecatedArguments})");
+    if (element.children != null) {
+      element.children.forEach((element) {
+        debugDumpNodeRecursively(element, indent: "  $indent");
+      });
+    }
+  });
+}
diff --git a/pkg/front_end/tool/parser_direct_ast/viewer.dart b/pkg/front_end/tool/parser_direct_ast/viewer.dart
index 8bcf65e..c516101 100644
--- a/pkg/front_end/tool/parser_direct_ast/viewer.dart
+++ b/pkg/front_end/tool/parser_direct_ast/viewer.dart
@@ -64,22 +64,20 @@
       case DirectParserASTType.BEGIN:
         header = "begin";
         break;
-      case DirectParserASTType.END:
-        throw "Unexpected";
       case DirectParserASTType.HANDLE:
         header = "handle";
         break;
-      case DirectParserASTType.DONE:
+      case DirectParserASTType.END:
         header = withEndHeader ? "end" : "";
         break;
     }
     String extra = " ";
-    if (element.content != null) {
-      extra += element.content.first.arguments.toString();
+    if (element.children != null) {
+      extra += element.children.first.deprecatedArguments.toString();
     }
     return "${indent ? "  " : ""}"
         "${header}${element.what} "
-        "${element.arguments.toString()}${extra}";
+        "${element.deprecatedArguments.toString()}${extra}";
   }
 
   @override
@@ -116,7 +114,7 @@
       selected = selectedElement.selected;
     } else {
       shown = [new PrintedLine.parent(shown, selected)];
-      List<DirectParserASTContent> children = selectedElement.ast.content;
+      List<DirectParserASTContent> children = selectedElement.ast.children;
       if (children != null) {
         for (int i = 0; i < children.length; i++) {
           shown.add(new PrintedLine.ast(
diff --git a/pkg/front_end/tool/smoke_test_quick.dart b/pkg/front_end/tool/smoke_test_quick.dart
index 4956e04..03d3840 100644
--- a/pkg/front_end/tool/smoke_test_quick.dart
+++ b/pkg/front_end/tool/smoke_test_quick.dart
@@ -12,7 +12,7 @@
 
 main(List<String> args) async {
   Stopwatch stopwatch = new Stopwatch()..start();
-  List<Future> futures = new List<Future>();
+  List<Future> futures = <Future>[];
   futures.add(run(
       "pkg/front_end/test/explicit_creation_test.dart", ["--front-end-only"],
       filter: false));
diff --git a/pkg/frontend_server/README.md b/pkg/frontend_server/README.md
new file mode 100644
index 0000000..afebf6c
--- /dev/null
+++ b/pkg/frontend_server/README.md
@@ -0,0 +1,19 @@
+The frontend_server package is used by both the flutter command line tool and the frontend_server_client package (used by webdev and package:test).
+
+## API Stability
+
+Changes to the command line API or behavior should be tested against the follwing test suites (in addition to normal HHH testing):
+  * flutter_tools: https://github.com/flutter/flutter/tree/master/packages/flutter_tools
+  * frontend_server_client: https://github.com/dart-lang/webdev/tree/master/frontend_server_client
+
+Otherwise these changes will need to be carefully coordinated with the flutter tooling and frontend_server_client teams.
+
+This API stability does not cover any of the source code APIs.
+
+
+### Stable subset
+
+* The frontend_server kernel compilation and expression evaluation for kernel should be considered "stable".
+* The frontend_server JavaScript compilation is semi-stable, but clients should anticipate coordinated breaking changes in the future.
+* The frontend_server JavaScript expression evaluation is experimental and is expected to change significantly from Dec 2020 through the end of 2021.
+* Specific flags like the --flutter-widget-cache may be added for experimentation and should not be considered stable.
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 4d9b5ae..c1f089f 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -350,7 +350,7 @@
 
   final ProgramTransformer transformer;
 
-  final List<String> errors = List<String>();
+  final List<String> errors = <String>[];
 
   _onDiagnostic(DiagnosticMessage message) {
     bool printMessage;
@@ -824,7 +824,8 @@
     final String boundaryKey = Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
 
-    _processedOptions.ticker.logMs('Compiling expression to JavaScript');
+    _processedOptions.ticker
+        .logMs('Compiling expression to JavaScript in $moduleName');
 
     var kernel2jsCompiler = _bundler.compilers[moduleName];
     Component component = _generator.lastKnownGoodComponent;
@@ -832,7 +833,7 @@
 
     _processedOptions.ticker.logMs('Computed component');
 
-    var evaluator = new ExpressionCompiler(
+    var expressionCompiler = new ExpressionCompiler(
       _compilerOptions,
       errors,
       _generator.generator,
@@ -840,8 +841,8 @@
       component,
     );
 
-    var procedure = await evaluator.compileExpressionToJs(libraryUri, line,
-        column, jsModules, jsFrameValues, moduleName, expression);
+    var procedure = await expressionCompiler.compileExpressionToJs(
+        libraryUri, line, column, jsFrameValues, expression);
 
     var result = errors.length > 0 ? errors[0] : procedure;
 
@@ -887,8 +888,8 @@
       Component deltaProgram, Sink<List<int>> ioSink) {
     if (deltaProgram == null) return;
 
-    List<Library> packageLibraries = List<Library>();
-    List<Library> libraries = List<Library>();
+    List<Library> packageLibraries = <Library>[];
+    List<Library> libraries = <Library>[];
     deltaProgram.computeCanonicalNames();
 
     for (var lib in deltaProgram.libraries) {
diff --git a/pkg/frontend_server/lib/src/to_string_transformer.dart b/pkg/frontend_server/lib/src/to_string_transformer.dart
new file mode 100644
index 0000000..8969e51
--- /dev/null
+++ b/pkg/frontend_server/lib/src/to_string_transformer.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/visitor.dart';
+import '../frontend_server.dart';
+
+// Transformer/visitor for toString
+// If we add any more of these, they really should go into a separate library.
+
+/// A [RecursiveVisitor] that replaces [Object.toString] overrides with
+/// `super.toString()`.
+class ToStringVisitor extends RecursiveVisitor<void> {
+  /// The [packageUris] must not be null.
+  ToStringVisitor(this._packageUris) : assert(_packageUris != null);
+
+  /// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
+  /// 'package:flutter/foundation.dart'.
+  final Set<String> _packageUris;
+
+  /// Turn 'dart:ui' into 'dart:ui', or
+  /// 'package:flutter/src/semantics_event.dart' into 'package:flutter'.
+  String _importUriToPackage(Uri importUri) =>
+      '${importUri.scheme}:${importUri.pathSegments.first}';
+
+  bool _isInTargetPackage(Procedure node) {
+    return _packageUris
+        .contains(_importUriToPackage(node.enclosingLibrary.importUri));
+  }
+
+  bool _hasKeepAnnotation(Procedure node) {
+    for (ConstantExpression expression
+        in node.annotations.whereType<ConstantExpression>()) {
+      if (expression.constant is! InstanceConstant) {
+        continue;
+      }
+      final InstanceConstant constant = expression.constant as InstanceConstant;
+      if (constant.classNode.name == '_KeepToString' &&
+          constant.classNode.enclosingLibrary.importUri.toString() ==
+              'dart:ui') {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  void visitProcedure(Procedure node) {
+    if (node.name.text == 'toString' &&
+        node.enclosingClass != null &&
+        node.enclosingLibrary != null &&
+        !node.isStatic &&
+        !node.isAbstract &&
+        !node.enclosingClass.isEnum &&
+        _isInTargetPackage(node) &&
+        !_hasKeepAnnotation(node)) {
+      node.function.body.replaceWith(
+        ReturnStatement(
+          SuperMethodInvocation(
+            node.name,
+            Arguments(<Expression>[]),
+          ),
+        ),
+      );
+    }
+  }
+
+  @override
+  void defaultMember(Member node) {}
+}
+
+/// Replaces [Object.toString] overrides with calls to super for the specified
+/// [packageUris].
+class ToStringTransformer extends ProgramTransformer {
+  /// The [packageUris] parameter must not be null, but may be empty.
+  ToStringTransformer(this._child, this._packageUris)
+      : assert(_packageUris != null);
+
+  final ProgramTransformer _child;
+
+  /// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
+  /// 'package:flutter/foundation.dart'.
+  final Set<String> _packageUris;
+
+  @override
+  void transform(Component component) {
+    assert(_child is! ToStringTransformer);
+    if (_packageUris.isNotEmpty) {
+      component.visitChildren(ToStringVisitor(_packageUris));
+    }
+    _child?.transform(component);
+  }
+}
diff --git a/pkg/frontend_server/test/frontend_server_flutter.dart b/pkg/frontend_server/test/frontend_server_flutter.dart
index 0137989..d238293 100644
--- a/pkg/frontend_server/test/frontend_server_flutter.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter.dart
@@ -245,7 +245,7 @@
   String _boundaryKey;
   bool _readingSources;
 
-  List<String> allReceived = new List<String>();
+  List<String> allReceived = <String>[];
 
   void listener(String s) {
     allReceived.add(s);
@@ -331,7 +331,7 @@
 }
 
 class StdoutLogger extends Logger {
-  List<String> _log = new List<String>();
+  List<String> _log = <String>[];
 
   @override
   void logExpectedResult(String testName) {
diff --git a/pkg/frontend_server/test/frontend_server_flutter_suite.dart b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
index 8028d59..d96ee6e 100644
--- a/pkg/frontend_server/test/frontend_server_flutter_suite.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
@@ -70,7 +70,7 @@
 class ResultLogger extends Logger {
   final SuiteConfiguration suiteConfiguration;
   final Map<String, Stopwatch> stopwatches = {};
-  List<String> _log = new List<String>();
+  List<String> _log = <String>[];
 
   ResultLogger(this.suiteConfiguration);
 
diff --git a/pkg/js/analysis_options.yaml b/pkg/js/analysis_options.yaml
index 9951703..afaa4eb 100644
--- a/pkg/js/analysis_options.yaml
+++ b/pkg/js/analysis_options.yaml
@@ -3,8 +3,6 @@
 analyzer:
   strong-mode:
     implicit-casts: false
-  enable-experiment:
-    - non-nullable
 
 linter:
   rules:
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 9ec3bfe..2fee946 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -1522,7 +1522,7 @@
       }
       expectCategory(COLON);
     }
-    List statements = new List<Statement>();
+    List statements = <Statement>[];
     while (lastCategory != RBRACE &&
         lastToken != 'case' &&
         lastToken != 'default') {
@@ -1557,7 +1557,7 @@
     Expression key = parseExpression();
     expectCategory(RPAREN);
     expectCategory(LBRACE);
-    List<SwitchClause> clauses = new List<SwitchClause>();
+    List<SwitchClause> clauses = <SwitchClause>[];
     while (lastCategory != RBRACE) {
       clauses.add(parseSwitchClause());
     }
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 82cdc4f..7a9298a 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -444,6 +444,8 @@
 
   bool get isCommaOperator => false;
 
+  bool get isFinalized => true;
+
   Statement toStatement() {
     throw new UnsupportedError('toStatement');
   }
@@ -1005,6 +1007,9 @@
 
   LiteralStringFromName(this.name) : super(null);
 
+  @override
+  bool get isFinalized => name.isFinalized;
+
   String get value => '"${name.name}"';
 
   void visitChildren<T>(NodeVisitor<T> visitor) {
diff --git a/pkg/kernel/analysis_options.yaml b/pkg/kernel/analysis_options.yaml
index af1bb97..68fdd50 100644
--- a/pkg/kernel/analysis_options.yaml
+++ b/pkg/kernel/analysis_options.yaml
@@ -1,3 +1,19 @@
 analyzer:
   exclude:
     - testcases/**
+
+linter:
+  rules:
+    - curly_braces_in_flow_control_structures
+    - prefer_adjacent_string_concatenation
+    - unawaited_futures
+    - recursive_getters
+    - avoid_empty_else
+    - empty_statements
+    - list_remove_unrelated_type
+    - iterable_contains_unrelated_type
+    - valid_regexps
+    - package_api_docs
+    - lines_longer_than_80_chars
+    - unrelated_type_equality_checks
+    # - always_specify_types
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index cafad21..a93760a 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -99,6 +99,10 @@
   List<UInt> lineStarts;
 
   List<Byte> importUriUtf8Bytes;
+
+  // List of constructors evaluated *by* this library. Note that these can be
+  // in other libraries.
+  List<ConstructorReference> constructorCoverage;
 }
 
 type String {
@@ -143,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 50;
+  UInt32 formatVersion = 52;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -392,6 +396,18 @@
 }
 */
 
+/*
+enum ProcedureStubKind {
+  Regular,
+  ForwardingStub,
+  ForwardingSuperStub,
+  NoSuchMethodForwarder,
+  MemberSignature,
+  MixinStub,
+  MixinSuperStub,
+}
+*/
+
 type Procedure extends Member {
   Byte tag = 6;
   CanonicalNameReference canonicalName;
@@ -401,16 +417,13 @@
   FileOffset fileOffset; // Offset of the procedure name.
   FileOffset fileEndOffset;
   Byte kind; // Index into the ProcedureKind enum above.
-  UInt flags (isStatic, isAbstract, isExternal, isConst, isForwardingStub,
-              isForwardingSemiStub, isRedirectingFactoryConstructor,
-              isNoSuchMethodForwarder, isExtensionMember, isMemberSignature,
+  Byte stubKind; // Index into the ProcedureStubKind enum above.
+  UInt flags (isStatic, isAbstract, isExternal, isConst,
+              isRedirectingFactoryConstructor, isExtensionMember,
               isNonNullableByDefault);
   Name name;
   List<Expression> annotations;
-  // Only present if the 'isForwardingStub' flag is set.
-  MemberReference forwardingStubSuperTarget; // May be NullReference.
-  MemberReference forwardingStubInterfaceTarget; // May be NullReference.
-  MemberReference memberSignatureOrigin; // May be NullReference.
+  MemberReference stubTarget; // May be NullReference.
   // Can only be absent if abstract, but tag is there anyway.
   Option<FunctionNode> function;
 }
@@ -1193,7 +1206,7 @@
   List<Expression> annotations;
 
   Byte flags (isFinal, isConst, isFieldFormal, isCovariant,
-              isInScope, isGenericCovariantImpl, isLate, isRequired);
+              isGenericCovariantImpl, isLate, isRequired, isLowered);
   // For named parameters, this is the parameter name.
   // For other variables, the name is cosmetic, may be empty,
   // and is not necessarily unique.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index ce1824e..41c88aa 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -64,6 +64,8 @@
 ///
 library kernel.ast;
 
+import 'dart:core';
+import 'dart:core' as core show MapEntry;
 import 'dart:collection' show ListBase;
 import 'dart:convert' show utf8;
 
@@ -1030,7 +1032,7 @@
   }
 
   List<Supertype> superclassConstraints() {
-    var constraints = <Supertype>[];
+    List<Supertype> constraints = <Supertype>[];
 
     // Not a mixin declaration.
     if (!isMixinDeclaration) return constraints;
@@ -1077,7 +1079,7 @@
   /// done automatically when accessing the lists.
   void ensureLoaded() {
     if (lazyBuilder != null) {
-      var lazyBuilderLocal = lazyBuilder;
+      void Function() lazyBuilderLocal = lazyBuilder;
       lazyBuilder = null;
       lazyBuilderLocal();
     }
@@ -2139,6 +2141,189 @@
   }
 }
 
+/// Enum for the semantics of the `Procedure.stubTarget` property.
+enum ProcedureStubKind {
+  /// A regular procedure declared in source code.
+  ///
+  /// The stub target is `null`.
+  Regular,
+
+  /// An abstract procedure inserted to add `isCovariant` and
+  /// `isGenericCovariantImpl` to parameters for a set of overridden members.
+  ///
+  /// The stub is inserted when not all of the overridden members agree on
+  /// the covariance flags. For instance:
+  ///
+  ///     class A<T> {
+  ///        void method1(num o) {}
+  ///        void method2(T o) {}
+  ///     }
+  ///     class B {
+  ///        void method1(covariant int o) {}
+  ///        void method2(int o) {}
+  ///     }
+  ///     class C implements A<int>, B {
+  ///        // Forwarding stub needed because the parameter is covariant in
+  ///        // `B.method1` but not in `A.method1`.
+  ///        void method1(covariant num o);
+  ///        // Forwarding stub needed because the parameter is a generic
+  ///        // covariant impl in `A.method2` but not in `B.method2`.
+  ///        void method2(/*generic-covariant-impl*/ int o);
+  ///     }
+  ///
+  /// The stub target is one of the overridden members.
+  ForwardingStub,
+
+  /// A concrete procedure inserted to add `isCovariant` and
+  /// `isGenericCovariantImpl` checks to parameters before calling the
+  /// overridden member in the superclass.
+  ///
+  /// The stub is inserted when not all of the overridden members agree on
+  /// the covariance flags and the overridden super class member does not
+  /// have the same covariance flags. For instance:
+  ///
+  ///     class A<T> {
+  ///        void method1(num o) {}
+  ///        void method2(T o) {}
+  ///     }
+  ///     class B {
+  ///        void method1(covariant int o) {}
+  ///        void method2(int o) {}
+  ///     }
+  ///     class C extends A<int> implements B {
+  ///        // Forwarding stub needed because the parameter is covariant in
+  ///        // `B.method1` but not in `A.method1`.
+  ///        void method1(covariant num o) => super.method1(o);
+  ///        // No need for a super stub for `A.method2` because it has the
+  ///        // right covariance flags already.
+  ///     }
+  ///
+  /// The stub target is the called superclass member.
+  ForwardingSuperStub,
+
+  /// A concrete procedure inserted to forward calls to `noSuchMethod` for
+  /// an inherited member that it does not implement.
+  ///
+  /// The stub is inserted when a class implements private members of another
+  /// library or declares/inherits a user-defined `noSuchMethod` method. For
+  /// instance:
+  ///
+  ///     // lib1:
+  ///     class A {
+  ///       void _privateMethod() {}
+  ///     }
+  ///     // lib2:
+  ///     class B implements A {
+  ///       // Forwarding stub inserted to forward calls to `A._privateMethod`.
+  ///       void _privateMethod() => noSuchMethod(#_privateMethod, ...);
+  ///     }
+  ///     class C {
+  ///       void method() {}
+  ///     }
+  ///     class D implements C {
+  ///       noSuchMethod(o) { ... }
+  ///       // Forwarding stub inserted to forward calls to `C.method`.
+  ///       void method() => noSuchMethod(#method, ...);
+  ///     }
+  ///
+  ///
+  /// The stub target is `null` if the procedure preexisted as an abstract
+  /// procedure. Otherwise the stub target is one of the inherited members.
+  NoSuchMethodForwarder,
+
+  /// An abstract procedure inserted to show the combined member signature type
+  /// of set of overridden members.
+  ///
+  /// The stub is inserted when an opt-in member is inherited into an opt-out
+  /// library or when NNBD_TOP_MERGE was used to compute the type of a merge
+  /// point in an opt-in library. For instance:
+  ///
+  ///     // lib1: opt-in
+  ///     class A {
+  ///       int? method1() => null;
+  ///       void method2(Object? o) {}
+  ///     }
+  ///     class B {
+  ///       dynamic method2(dynamic o);
+  ///     }
+  ///     class C implements A, B {
+  ///       // Member signature inserted for the NNBD_TOP_MERGE type of
+  ///       // `A.method2` and `B.method2`.
+  ///       Object? method2(Object? o);
+  ///     }
+  ///     // lib2: opt-out
+  ///     class D extends A {
+  ///       // Member signature inserted for the LEGACY_ERASURE type of
+  ///       // `A.method1` and `A.method2` with types `int* Function()`
+  ///       // and `void Function(Object*)`, respectively.
+  ///       int method1();
+  ///       void method2(Object o);
+  ///     }
+  ///
+  /// The stub target is one of the overridden members.
+  MemberSignature,
+
+  /// An abstract procedure inserted for the application of an abstract mixin
+  /// member.
+  ///
+  /// The stub is inserted when an abstract member is mixed into a mixin
+  /// application. For instance:
+  ///
+  ///     class Super {}
+  ///     abstract class Mixin {
+  ///        void method();
+  ///     }
+  ///     class Class = Super with Mixin
+  ///       // A mixin stub for `A.method` is added to `Class`
+  ///       void method();
+  ///     ;
+  ///
+  /// This is added to ensure that interface targets are resolved consistently
+  /// in face of cloning. For instance, without the mixin stub, this call:
+  ///
+  ///     method(Class c) => c.method();
+  ///
+  /// would use `Mixin.method` as its target, but after load from a VM .dill
+  /// (which clones all mixin members) the call would resolve to `Class.method`
+  /// instead. By adding the mixin stub to `Class`, all accesses both before
+  /// and after .dill will point to `Class.method`.
+  ///
+  /// The stub target is the mixin member.
+  MixinStub,
+
+  /// A concrete procedure inserted for the application of a concrete mixin
+  /// member. The implementation calls the mixin member via a super-call.
+  ///
+  /// The stub is inserted when a concrete member is mixed into a mixin
+  /// application. For instance:
+  ///
+  ///     class Super {}
+  ///     abstract class Mixin {
+  ///        void method() {}
+  ///     }
+  ///     class Class = Super with Mixin
+  ///       // A mixin stub for `A.method` is added to `Class` which calls
+  ///       // `A.method`.
+  ///       void method() => super.method();
+  ///     ;
+  ///
+  /// This is added to ensure that super accesses are resolved correctly, even
+  /// in face of cloning. For instance, without the mixin super stub, this super
+  /// call:
+  ///
+  ///     class Subclass extends Class {
+  ///       method(Class c) => super.method();
+  ///     }
+  ///
+  /// would use `Mixin.method` as its target, which would to be update to match
+  /// the cloning of mixin member performed for instance by the VM. By adding
+  /// the mixin super stub to `Class`, all accesses both before and after
+  /// cloning will point to `Class.method`.
+  ///
+  /// The stub target is the called mixin member.
+  MixinSuperStub,
+}
+
 /// A method, getter, setter, index-getter, index-setter, operator overloader,
 /// or factory.
 ///
@@ -2192,66 +2377,47 @@
     super.transformerFlags = newValue;
   }
 
-  Reference forwardingStubSuperTargetReference;
-  Reference forwardingStubInterfaceTargetReference;
-  Reference memberSignatureOriginReference;
+  ProcedureStubKind stubKind;
+  Reference stubTargetReference;
 
   Procedure(Name name, ProcedureKind kind, FunctionNode function,
       {bool isAbstract: false,
       bool isStatic: false,
       bool isExternal: false,
       bool isConst: false,
-      bool isForwardingStub: false,
-      bool isForwardingSemiStub: false,
-      bool isMemberSignature: false,
       bool isExtensionMember: false,
+      bool isSynthetic: false,
       int transformerFlags: 0,
       Uri fileUri,
       Reference reference,
-      Member forwardingStubSuperTarget,
-      Member forwardingStubInterfaceTarget,
-      Member memberSignatureOrigin})
-      : this._byReferenceRenamed(
-          name,
-          kind,
-          function,
-          isAbstract: isAbstract,
-          isStatic: isStatic,
-          isExternal: isExternal,
-          isConst: isConst,
-          isForwardingStub: isForwardingStub,
-          isMemberSignature: isMemberSignature,
-          isForwardingSemiStub: isForwardingSemiStub,
-          isExtensionMember: isExtensionMember,
-          transformerFlags: transformerFlags,
-          fileUri: fileUri,
-          reference: reference,
-          forwardingStubSuperTargetReference:
-              getMemberReferenceBasedOnProcedureKind(
-                  forwardingStubSuperTarget, kind),
-          forwardingStubInterfaceTargetReference:
-              getMemberReferenceBasedOnProcedureKind(
-                  forwardingStubInterfaceTarget, kind),
-          memberSignatureOriginReference:
-              getMemberReferenceBasedOnProcedureKind(
-                  memberSignatureOrigin, kind),
-        );
+      ProcedureStubKind stubKind: ProcedureStubKind.Regular,
+      Member stubTarget})
+      : this._byReferenceRenamed(name, kind, function,
+            isAbstract: isAbstract,
+            isStatic: isStatic,
+            isExternal: isExternal,
+            isConst: isConst,
+            isExtensionMember: isExtensionMember,
+            isSynthetic: isSynthetic,
+            transformerFlags: transformerFlags,
+            fileUri: fileUri,
+            reference: reference,
+            stubKind: stubKind,
+            stubTargetReference:
+                getMemberReferenceBasedOnProcedureKind(stubTarget, kind));
 
   Procedure._byReferenceRenamed(Name name, this.kind, this.function,
       {bool isAbstract: false,
       bool isStatic: false,
       bool isExternal: false,
       bool isConst: false,
-      bool isForwardingStub: false,
-      bool isForwardingSemiStub: false,
-      bool isMemberSignature: false,
       bool isExtensionMember: false,
+      bool isSynthetic: false,
       int transformerFlags: 0,
       Uri fileUri,
       Reference reference,
-      this.forwardingStubSuperTargetReference,
-      this.forwardingStubInterfaceTargetReference,
-      this.memberSignatureOriginReference})
+      this.stubKind: ProcedureStubKind.Regular,
+      this.stubTargetReference})
       : assert(kind != null),
         super(name, fileUri, reference) {
     function?.parent = this;
@@ -2259,12 +2425,10 @@
     this.isStatic = isStatic;
     this.isExternal = isExternal;
     this.isConst = isConst;
-    this.isForwardingStub = isForwardingStub;
-    this.isForwardingSemiStub = isForwardingSemiStub;
-    this.isMemberSignature = isMemberSignature;
     this.isExtensionMember = isExtensionMember;
+    this.isSynthetic = isSynthetic;
     this.transformerFlags = transformerFlags;
-    assert(!(isMemberSignature && memberSignatureOriginReference == null),
+    assert(!(isMemberSignature && stubTargetReference == null),
         "No member signature origin for member signature $this.");
     assert(
         !(memberSignatureOrigin is Procedure &&
@@ -2277,14 +2441,11 @@
   static const int FlagAbstract = 1 << 1;
   static const int FlagExternal = 1 << 2;
   static const int FlagConst = 1 << 3; // Only for external const factories.
-  static const int FlagForwardingStub = 1 << 4;
-  static const int FlagForwardingSemiStub = 1 << 5;
   // TODO(29841): Remove this flag after the issue is resolved.
-  static const int FlagRedirectingFactoryConstructor = 1 << 6;
-  static const int FlagNoSuchMethodForwarder = 1 << 7;
-  static const int FlagExtensionMember = 1 << 8;
-  static const int FlagMemberSignature = 1 << 9;
-  static const int FlagNonNullableByDefault = 1 << 10;
+  static const int FlagRedirectingFactoryConstructor = 1 << 4;
+  static const int FlagExtensionMember = 1 << 5;
+  static const int FlagNonNullableByDefault = 1 << 6;
+  static const int FlagSynthetic = 1 << 7;
 
   bool get isStatic => flags & FlagStatic != 0;
   bool get isAbstract => flags & FlagAbstract != 0;
@@ -2302,11 +2463,16 @@
   /// not declared in the source; it's possible that this is a forwarding
   /// semi-stub (see isForwardingSemiStub).  To determine whether this function
   /// was present in the source, consult [isSyntheticForwarder].
-  bool get isForwardingStub => flags & FlagForwardingStub != 0;
+  bool get isForwardingStub =>
+      stubKind == ProcedureStubKind.ForwardingStub ||
+      stubKind == ProcedureStubKind.ForwardingSuperStub;
 
   /// If set, this flag indicates that although this function is a forwarding
   /// stub, it was present in the original source as an abstract method.
-  bool get isForwardingSemiStub => flags & FlagForwardingSemiStub != 0;
+  bool get isForwardingSemiStub =>
+      !isSynthetic &&
+      (stubKind == ProcedureStubKind.ForwardingStub ||
+          stubKind == ProcedureStubKind.ForwardingSuperStub);
 
   /// If set, this method is a class member added to show the type of an
   /// inherited member.
@@ -2315,7 +2481,7 @@
   /// directly from the member(s) in the supertypes. For instance in case of
   /// an nnbd opt-out class inheriting from an nnbd opt-in class; here all nnbd-
   /// aware types are replaced with legacy types in the inherited signature.
-  bool get isMemberSignature => flags & FlagMemberSignature != 0;
+  bool get isMemberSignature => stubKind == ProcedureStubKind.MemberSignature;
 
   // Indicates if this [Procedure] represents a redirecting factory constructor
   // and doesn't have a runnable body.
@@ -2327,8 +2493,10 @@
   /// source, and it exists solely for the purpose of type checking arguments
   /// and forwarding to [forwardingStubSuperTarget].
   bool get isSyntheticForwarder => isForwardingStub && !isForwardingSemiStub;
+  bool get isSynthetic => flags & FlagSynthetic != 0;
 
-  bool get isNoSuchMethodForwarder => flags & FlagNoSuchMethodForwarder != 0;
+  bool get isNoSuchMethodForwarder =>
+      stubKind == ProcedureStubKind.NoSuchMethodForwarder;
 
   @override
   bool get isExtensionMember => flags & FlagExtensionMember != 0;
@@ -2349,39 +2517,21 @@
     flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
   }
 
-  void set isForwardingStub(bool value) {
-    flags =
-        value ? (flags | FlagForwardingStub) : (flags & ~FlagForwardingStub);
-  }
-
-  void set isForwardingSemiStub(bool value) {
-    flags = value
-        ? (flags | FlagForwardingSemiStub)
-        : (flags & ~FlagForwardingSemiStub);
-  }
-
-  void set isMemberSignature(bool value) {
-    flags =
-        value ? (flags | FlagMemberSignature) : (flags & ~FlagMemberSignature);
-  }
-
   void set isRedirectingFactoryConstructor(bool value) {
     flags = value
         ? (flags | FlagRedirectingFactoryConstructor)
         : (flags & ~FlagRedirectingFactoryConstructor);
   }
 
-  void set isNoSuchMethodForwarder(bool value) {
-    flags = value
-        ? (flags | FlagNoSuchMethodForwarder)
-        : (flags & ~FlagNoSuchMethodForwarder);
-  }
-
   void set isExtensionMember(bool value) {
     flags =
         value ? (flags | FlagExtensionMember) : (flags & ~FlagExtensionMember);
   }
 
+  void set isSynthetic(bool value) {
+    flags = value ? (flags | FlagSynthetic) : (flags & ~FlagSynthetic);
+  }
+
   bool get isInstanceMember => !isStatic;
   bool get isGetter => kind == ProcedureKind.Getter;
   bool get isSetter => kind == ProcedureKind.Setter;
@@ -2401,28 +2551,25 @@
   }
 
   Member get forwardingStubSuperTarget =>
-      forwardingStubSuperTargetReference?.asMember;
-
-  void set forwardingStubSuperTarget(Member target) {
-    forwardingStubSuperTargetReference =
-        getMemberReferenceBasedOnProcedureKind(target, kind);
-  }
+      stubKind == ProcedureStubKind.ForwardingSuperStub
+          ? stubTargetReference?.asMember
+          : null;
 
   Member get forwardingStubInterfaceTarget =>
-      forwardingStubInterfaceTargetReference?.asMember;
+      stubKind == ProcedureStubKind.ForwardingStub
+          ? stubTargetReference?.asMember
+          : null;
 
-  void set forwardingStubInterfaceTarget(Member target) {
-    forwardingStubInterfaceTargetReference =
-        getMemberReferenceBasedOnProcedureKind(target, kind);
+  Member get stubTarget => stubTargetReference?.asMember;
+
+  void set stubTarget(Member target) {
+    stubTargetReference = getMemberReferenceBasedOnProcedureKind(target, kind);
   }
 
-  @override
-  Member get memberSignatureOrigin => memberSignatureOriginReference?.asMember;
-
-  void set memberSignatureOrigin(Member target) {
-    memberSignatureOriginReference =
-        getMemberReferenceBasedOnProcedureKind(target, kind);
-  }
+  Member get memberSignatureOrigin =>
+      stubKind == ProcedureStubKind.MemberSignature
+          ? stubTargetReference?.asMember
+          : null;
 
   R accept<R>(MemberVisitor<R> v) => v.visitProcedure(this);
 
@@ -2770,7 +2917,7 @@
 
   void _buildLazy() {
     if (lazyBuilder != null) {
-      var lazyBuilderLocal = lazyBuilder;
+      void Function() lazyBuilderLocal = lazyBuilder;
       lazyBuilder = null;
       lazyBuilderLocal();
     }
@@ -2829,9 +2976,10 @@
     named.sort();
     // We need create a copy of the list of type parameters, otherwise
     // transformations like erasure don't work.
-    var typeParametersCopy = new List<TypeParameter>.from(parent is Constructor
-        ? parent.enclosingClass.typeParameters
-        : typeParameters);
+    List<TypeParameter> typeParametersCopy = new List<TypeParameter>.from(
+        parent is Constructor
+            ? parent.enclosingClass.typeParameters
+            : typeParameters);
     return new FunctionType(
         positionalParameters.map(_getTypeOfVariable).toList(growable: false),
         returnType,
@@ -3062,7 +3210,7 @@
       return context.typeEnvironment.coreTypes
           .rawType(superclass, context.nonNullable);
     }
-    var type = getStaticType(context);
+    DartType type = getStaticType(context);
     while (type is TypeParameterType) {
       TypeParameterType typeParameterType = type;
       type =
@@ -3292,10 +3440,10 @@
 
   @override
   DartType getStaticTypeInternal(StaticTypeContext context) {
-    var interfaceTarget = this.interfaceTarget;
+    Member interfaceTarget = this.interfaceTarget;
     if (interfaceTarget != null) {
       Class superclass = interfaceTarget.enclosingClass;
-      var receiverType =
+      InterfaceType receiverType =
           receiver.getStaticTypeAsInstanceOf(superclass, context);
       return Substitution.fromInterfaceType(receiverType)
           .substituteType(interfaceTarget.getterType);
@@ -3847,7 +3995,7 @@
   }
 
   DartType getStaticTypeInternal(StaticTypeContext context) {
-    var interfaceTarget = this.interfaceTarget;
+    Member interfaceTarget = this.interfaceTarget;
     if (interfaceTarget != null) {
       if (interfaceTarget is Procedure &&
           context.typeEnvironment
@@ -3857,9 +4005,9 @@
             arguments.positional[0].getStaticType(context));
       }
       Class superclass = interfaceTarget.enclosingClass;
-      var receiverType =
+      DartType receiverType =
           receiver.getStaticTypeAsInstanceOf(superclass, context);
-      var getterType = Substitution.fromInterfaceType(receiverType)
+      DartType getterType = Substitution.fromInterfaceType(receiverType)
           .substituteType(interfaceTarget.getterType);
       if (getterType is FunctionType) {
         Substitution substitution;
@@ -3898,7 +4046,7 @@
       return const DynamicType();
     }
     if (name.text == 'call') {
-      var receiverType = receiver.getStaticType(context);
+      DartType receiverType = receiver.getStaticType(context);
       if (receiverType is FunctionType) {
         if (receiverType.typeParameters.length != arguments.types.length) {
           return const BottomType();
@@ -6990,7 +7138,8 @@
       bool isFieldFormal: false,
       bool isCovariant: false,
       bool isLate: false,
-      bool isRequired: false}) {
+      bool isRequired: false,
+      bool isLowered: false}) {
     assert(type != null);
     initializer?.parent = this;
     if (flags != -1) {
@@ -7002,6 +7151,7 @@
       this.isCovariant = isCovariant;
       this.isLate = isLate;
       this.isRequired = isRequired;
+      this.isLowered = isLowered;
     }
   }
 
@@ -7012,6 +7162,7 @@
       bool isFieldFormal: false,
       bool isLate: false,
       bool isRequired: false,
+      bool isLowered: false,
       this.type: const DynamicType()}) {
     assert(type != null);
     initializer?.parent = this;
@@ -7020,16 +7171,17 @@
     this.isFieldFormal = isFieldFormal;
     this.isLate = isLate;
     this.isRequired = isRequired;
+    this.isLowered = isLowered;
   }
 
   static const int FlagFinal = 1 << 0; // Must match serialized bit positions.
   static const int FlagConst = 1 << 1;
   static const int FlagFieldFormal = 1 << 2;
   static const int FlagCovariant = 1 << 3;
-  static const int FlagInScope = 1 << 4; // Temporary flag used by verifier.
-  static const int FlagGenericCovariantImpl = 1 << 5;
-  static const int FlagLate = 1 << 6;
-  static const int FlagRequired = 1 << 7;
+  static const int FlagGenericCovariantImpl = 1 << 4;
+  static const int FlagLate = 1 << 5;
+  static const int FlagRequired = 1 << 6;
+  static const int FlagLowered = 1 << 7;
 
   bool get isFinal => flags & FlagFinal != 0;
   bool get isConst => flags & FlagConst != 0;
@@ -7062,6 +7214,16 @@
   /// positional parameters and local variables.
   bool get isRequired => flags & FlagRequired != 0;
 
+  /// Whether the variable is part of a lowering.
+  ///
+  /// If a variable is part of a lowering its name may be synthesized so that it
+  /// doesn't reflect the name used in the source code and might not have a
+  /// one-to-one correspondence with the variable in the source.
+  ///
+  /// Lowering is used for instance of encoding of 'this' in extension instance
+  /// members and encoding of late locals.
+  bool get isLowered => flags & FlagLowered != 0;
+
   /// Whether the variable is assignable.
   ///
   /// This is `true` if the variable is neither constant nor final, or if it
@@ -7106,6 +7268,10 @@
     flags = value ? (flags | FlagRequired) : (flags & ~FlagRequired);
   }
 
+  void set isLowered(bool value) {
+    flags = value ? (flags | FlagLowered) : (flags & ~FlagLowered);
+  }
+
   void clearAnnotations() {
     annotations = const <Expression>[];
   }
@@ -7923,7 +8089,7 @@
     int upper = namedParameters.length - 1;
     while (lower <= upper) {
       int pivot = (lower + upper) ~/ 2;
-      var namedParameter = namedParameters[pivot];
+      NamedType namedParameter = namedParameters[pivot];
       int comparison = name.compareTo(namedParameter.name);
       if (comparison == 0) {
         return namedParameter.type;
@@ -8499,9 +8665,10 @@
       throw new StateError("Can't compute nullability from an absent bound.");
     }
 
-    // If a type parameter's nullability depends on itself, it is deemed 'undetermined'.
-    // Currently, it's possible if the type parameter has a possibly nested FutureOr containing that type parameter.
-    // If there are other ways for such a dependency to exist, they should be checked here.
+    // If a type parameter's nullability depends on itself, it is deemed
+    // 'undetermined'. Currently, it's possible if the type parameter has a
+    // possibly nested FutureOr containing that type parameter.  If there are
+    // other ways for such a dependency to exist, they should be checked here.
     bool nullabilityDependsOnItself = false;
     {
       DartType type = typeParameter.bound;
@@ -9446,8 +9613,8 @@
 
   DartType getType(StaticTypeContext context) {
     final FunctionType type = tearOffConstant.getType(context);
-    final mapping = <TypeParameter, DartType>{};
-    for (final parameter in type.typeParameters) {
+    final Map<TypeParameter, DartType> mapping = <TypeParameter, DartType>{};
+    for (final TypeParameter parameter in type.typeParameters) {
       mapping[parameter] = types[mapping.length];
     }
     return substitute(type.withoutTypeParameters, mapping);
@@ -9825,7 +9992,7 @@
 
   int readByte();
   List<int> readBytes(int length);
-  int readUInt();
+  int readUInt30();
   int readUint32();
 
   /// Read List<Byte> from the source.
@@ -9859,7 +10026,7 @@
 }
 
 void visitIterable(Iterable<Node> nodes, Visitor visitor) {
-  for (var node in nodes) {
+  for (Node node in nodes) {
     node.accept(visitor);
   }
 }
@@ -9867,7 +10034,7 @@
 void transformTypeList(List<DartType> nodes, Transformer visitor) {
   int storeIndex = 0;
   for (int i = 0; i < nodes.length; ++i) {
-    var result = visitor.visitDartType(nodes[i]);
+    DartType result = visitor.visitDartType(nodes[i]);
     if (result != null) {
       nodes[storeIndex] = result;
       ++storeIndex;
@@ -9881,7 +10048,7 @@
 void transformSupertypeList(List<Supertype> nodes, Transformer visitor) {
   int storeIndex = 0;
   for (int i = 0; i < nodes.length; ++i) {
-    var result = visitor.visitSupertype(nodes[i]);
+    Supertype result = visitor.visitSupertype(nodes[i]);
     if (result != null) {
       nodes[storeIndex] = result;
       ++storeIndex;
@@ -9895,7 +10062,7 @@
 void transformList(List<TreeNode> nodes, Transformer visitor, TreeNode parent) {
   int storeIndex = 0;
   for (int i = 0; i < nodes.length; ++i) {
-    var result = nodes[i].accept(visitor);
+    TreeNode result = nodes[i].accept(visitor);
     if (result != null) {
       nodes[storeIndex] = result;
       result.parent = parent;
@@ -9933,6 +10100,8 @@
 
   final Uri fileUri;
 
+  Set<Reference> constantCoverageConstructors;
+
   String cachedText;
 
   Source(this.lineStarts, this.source, this.importUri, this.fileUri);
@@ -9999,7 +10168,7 @@
       return -1;
     }
     RangeError.checkValueInInterval(line, 1, lineStarts.length, 'line');
-    var offset = lineStarts[line - 1] + column - 1;
+    int offset = lineStarts[line - 1] + column - 1;
     RangeError.checkValueInInterval(offset, 0, lineStarts.last, 'offset');
     return offset;
   }
@@ -10174,15 +10343,15 @@
     return combine2Finish(object2.hashCode, object2.hashCode, 0);
   }
 
-  static int combineListHash(List list, [int hash = 1]) {
-    for (var item in list) {
+  static int combineListHash(List<Object> list, [int hash = 1]) {
+    for (Object item in list) {
       hash = _Hash.combine(item.hashCode, hash);
     }
     return hash;
   }
 
   static int combineList(List<int> hashes, int hash) {
-    for (var item in hashes) {
+    for (int item in hashes) {
       hash = combine(item, hash);
     }
     return hash;
@@ -10190,9 +10359,9 @@
 
   static int combineMapHashUnordered(Map map, [int hash = 2]) {
     if (map == null || map.isEmpty) return hash;
-    List<int> entryHashes = List(map.length);
+    List<int> entryHashes = List.filled(map.length, null);
     int i = 0;
-    for (var entry in map.entries) {
+    for (core.MapEntry entry in map.entries) {
       entryHashes[i++] = combine(entry.key.hashCode, entry.value.hashCode);
     }
     entryHashes.sort();
@@ -10216,8 +10385,12 @@
 }
 
 int mapHashCodeOrdered(Map map, [int hash = 2]) {
-  for (final Object x in map.keys) hash = _Hash.combine(x.hashCode, hash);
-  for (final Object x in map.values) hash = _Hash.combine(x.hashCode, hash);
+  for (final Object x in map.keys) {
+    hash = _Hash.combine(x.hashCode, hash);
+  }
+  for (final Object x in map.values) {
+    hash = _Hash.combine(x.hashCode, hash);
+  }
   return _Hash.finish(hash);
 }
 
@@ -10256,7 +10429,7 @@
 /// Annotation describing information which is not part of Dart semantics; in
 /// other words, if this information (or any information it refers to) changes,
 /// static analysis and runtime behavior of the library are unaffected.
-const informative = null;
+const Null informative = null;
 
 Location _getLocationInComponent(Component component, Uri fileUri, int offset) {
   if (component != null) {
@@ -10361,10 +10534,9 @@
   }
 
   @override
-  bool operator ==(other) {
+  bool operator ==(Object other) {
     if (identical(this, other)) return true;
-    if (other is! Version) return false;
-    return major == other.major && minor == other.minor;
+    return other is Version && major == other.major && minor == other.minor;
   }
 
   @override
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index c0af19e..e4676d9 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -64,7 +64,7 @@
 }
 
 class _ComponentIndex {
-  static const numberOfFixedFields = 10;
+  static const int numberOfFixedFields = 10;
 
   int binaryOffsetForSourceTable;
   int binaryOffsetForCanonicalNames;
@@ -144,8 +144,8 @@
 
   int readByte() => _bytes[_byteOffset++];
 
-  int readUInt() {
-    var byte = readByte();
+  int readUInt30() {
+    int byte = readByte();
     if (byte & 0x80 == 0) {
       // 0xxxxxxx
       return byte;
@@ -192,11 +192,11 @@
   }
 
   Uint8List readByteList() {
-    return readBytes(readUInt());
+    return readBytes(readUInt30());
   }
 
   String readString() {
-    return readStringEntry(readUInt());
+    return readStringEntry(readUInt30());
   }
 
   String readStringEntry(int numBytes) {
@@ -268,10 +268,10 @@
 
   void readStringTable(List<String> table) {
     // Read the table of end offsets.
-    int length = readUInt();
-    List<int> endOffsets = new List<int>(length);
+    int length = readUInt30();
+    List<int> endOffsets = new List<int>.filled(length, null);
     for (int i = 0; i < length; ++i) {
-      endOffsets[i] = readUInt();
+      endOffsets[i] = readUInt30();
     }
     // Read the WTF-8 encoded strings.
     table.length = length;
@@ -283,7 +283,7 @@
   }
 
   void readConstantTable() {
-    final int length = readUInt();
+    final int length = readUInt30();
     final int startOffset = byteOffset;
     for (int i = 0; i < length; i++) {
       _constantTable[byteOffset - startOffset] = readConstantTableEntry();
@@ -309,7 +309,7 @@
       case ConstantTag.MapConstant:
         final DartType keyType = readDartType();
         final DartType valueType = readDartType();
-        final int length = readUInt();
+        final int length = readUInt30();
         final List<ConstantMapEntry> entries =
             new List<ConstantMapEntry>.filled(length, null, growable: true);
         for (int i = 0; i < length; i++) {
@@ -320,7 +320,7 @@
         return new MapConstant(keyType, valueType, entries);
       case ConstantTag.ListConstant:
         final DartType typeArgument = readDartType();
-        final int length = readUInt();
+        final int length = readUInt30();
         final List<Constant> entries =
             new List<Constant>.filled(length, null, growable: true);
         for (int i = 0; i < length; i++) {
@@ -329,7 +329,7 @@
         return new ListConstant(typeArgument, entries);
       case ConstantTag.SetConstant:
         final DartType typeArgument = readDartType();
-        final int length = readUInt();
+        final int length = readUInt30();
         final List<Constant> entries =
             new List<Constant>.filled(length, null, growable: true);
         for (int i = 0; i < length; i++) {
@@ -338,13 +338,13 @@
         return new SetConstant(typeArgument, entries);
       case ConstantTag.InstanceConstant:
         final Reference classReference = readClassReference();
-        final int typeArgumentCount = readUInt();
+        final int typeArgumentCount = readUInt30();
         final List<DartType> typeArguments =
             new List<DartType>.filled(typeArgumentCount, null, growable: true);
         for (int i = 0; i < typeArgumentCount; i++) {
           typeArguments[i] = readDartType();
         }
-        final int fieldValueCount = readUInt();
+        final int fieldValueCount = readUInt30();
         final Map<Reference, Constant> fieldValues = <Reference, Constant>{};
         for (int i = 0; i < fieldValueCount; i++) {
           final Reference fieldRef =
@@ -354,9 +354,10 @@
         }
         return new InstanceConstant(classReference, typeArguments, fieldValues);
       case ConstantTag.PartialInstantiationConstant:
-        final tearOffConstant = readConstantReference() as TearOffConstant;
-        final int length = readUInt();
-        final List<DartType> types = new List<DartType>(length);
+        final TearOffConstant tearOffConstant =
+            readConstantReference() as TearOffConstant;
+        final int length = readUInt30();
+        final List<DartType> types = new List<DartType>.filled(length, null);
         for (int i = 0; i < length; i++) {
           types[i] = readDartType();
         }
@@ -376,22 +377,22 @@
   }
 
   Constant readConstantReference() {
-    final int offset = readUInt();
+    final int offset = readUInt30();
     Constant constant = _constantTable[offset];
     assert(constant != null);
     return constant;
   }
 
   Uri readUriReference() {
-    return _sourceUriTable[readUInt()];
+    return _sourceUriTable[readUInt30()];
   }
 
   String readStringReference() {
-    return _stringTable[readUInt()];
+    return _stringTable[readUInt30()];
   }
 
   List<String> readStringReferenceList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<String> result = new List<String>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
       result[i] = readStringReference();
@@ -400,7 +401,7 @@
   }
 
   String readStringOrNullIfEmpty() {
-    var string = readStringReference();
+    String string = readStringReference();
     return string.isEmpty ? null : string;
   }
 
@@ -416,7 +417,7 @@
   }
 
   List<Expression> readAnnotationList(TreeNode parent) {
-    int length = readUInt();
+    int length = readUInt30();
     if (length == 0) return const <Expression>[];
     List<Expression> list =
         new List<Expression>.filled(length, null, growable: true);
@@ -428,7 +429,7 @@
 
   void _fillTreeNodeList(
       List<TreeNode> list, TreeNode buildObject(int index), TreeNode parent) {
-    var length = readUInt();
+    int length = readUInt30();
     list.length = length;
     for (int i = 0; i < length; ++i) {
       TreeNode object = buildObject(i);
@@ -437,7 +438,7 @@
   }
 
   void _fillNonTreeNodeList(List<Node> list, Node buildObject()) {
-    var length = readUInt();
+    int length = readUInt30();
     list.length = length;
     for (int i = 0; i < length; ++i) {
       Node object = buildObject();
@@ -460,12 +461,12 @@
   }
 
   void readLinkTable(CanonicalName linkRoot) {
-    int length = readUInt();
-    _linkTable = new List<CanonicalName>(length);
+    int length = readUInt30();
+    _linkTable = new List<CanonicalName>.filled(length, null);
     for (int i = 0; i < length; ++i) {
-      int biasedParentIndex = readUInt();
+      int biasedParentIndex = readUInt30();
       String name = readStringReference();
-      var parent =
+      CanonicalName parent =
           biasedParentIndex == 0 ? linkRoot : _linkTable[biasedParentIndex - 1];
       _linkTable[i] = parent.getChild(name);
     }
@@ -497,7 +498,7 @@
   }
 
   void _readAndVerifySdkHash() {
-    final sdkHash = ascii.decode(readBytes(sdkHashLength));
+    final String sdkHash = ascii.decode(readBytes(sdkHashLength));
     if (!isValidSdkHash(sdkHash)) {
       throw InvalidKernelSdkVersionError(sdkHash);
     }
@@ -519,8 +520,8 @@
         "BinaryBuilder.readComponent", () {
       _checkEmptyInput();
 
-      // Check that we have a .dill file and it has the correct version before we
-      // start decoding it.  Otherwise we will fail for cryptic reasons.
+      // Check that we have a .dill file and it has the correct version before
+      // we start decoding it.  Otherwise we will fail for cryptic reasons.
       int offset = _byteOffset;
       int magic = readUint32();
       if (magic != Tag.ComponentFile) {
@@ -542,7 +543,7 @@
       int componentFileIndex = 0;
       List<SubComponentView> views;
       if (createView) {
-        views = new List<SubComponentView>();
+        views = <SubComponentView>[];
       }
       while (_byteOffset < _bytes.length) {
         SubComponentView view = _readOneComponent(
@@ -578,8 +579,8 @@
     }
   }
 
-  /// Reads a single component file from the input and loads it into [component],
-  /// overwriting and reusing any existing data in the component.
+  /// Reads a single component file from the input and loads it into
+  /// [component], overwriting and reusing any existing data in the component.
   ///
   /// When linking with a non-empty component, canonical names must have been
   /// computed ahead of time.
@@ -671,12 +672,12 @@
     result.libraryCount = readUint32();
     // Library offsets are used for start and end offsets, so there is one extra
     // element that this the end offset of the last library
-    result.libraryOffsets = new List<int>(result.libraryCount + 1);
+    result.libraryOffsets = new List<int>.filled(result.libraryCount + 1, null);
     result.componentFileSizeInBytes = readUint32();
     if (result.componentFileSizeInBytes != componentFileSize) {
-      throw "Malformed binary: This component file's component index indicates that"
-          " the file size should be $componentFileSize but other component indexes"
-          " has indicated that the size should be "
+      throw "Malformed binary: This component file's component index indicates "
+          "that the file size should be $componentFileSize but other component "
+          "indexes has indicated that the size should be "
           "${result.componentFileSizeInBytes}.";
     }
 
@@ -782,8 +783,10 @@
 
     SubComponentView result;
     if (createView) {
-      result = new SubComponentView(new List<Library>(numberOfLibraries),
-          _componentStartOffset, componentFileSize);
+      result = new SubComponentView(
+          new List<Library>.filled(numberOfLibraries, null),
+          _componentStartOffset,
+          componentFileSize);
     }
 
     for (int i = 0; i < numberOfLibraries; ++i) {
@@ -807,7 +810,7 @@
 
   /// Read a list of strings. If the list is empty, [null] is returned.
   List<String> readListOfStrings() {
-    int length = readUInt();
+    int length = readUInt30();
     if (length == 0) return null;
     List<String> strings =
         new List<String>.filled(length, null, growable: true);
@@ -829,18 +832,30 @@
       Uri uri = uriString.isEmpty ? null : Uri.parse(uriString);
       _sourceUriTable[i] = uri;
       Uint8List sourceCode = readByteList();
-      int lineCount = readUInt();
-      List<int> lineStarts = new List<int>(lineCount);
+      int lineCount = readUInt30();
+      List<int> lineStarts = new List<int>.filled(lineCount, null);
       int previousLineStart = 0;
       for (int j = 0; j < lineCount; ++j) {
-        int lineStart = readUInt() + previousLineStart;
+        int lineStart = readUInt30() + previousLineStart;
         lineStarts[j] = lineStart;
         previousLineStart = lineStart;
       }
       String importUriString = readString();
       Uri importUri =
           importUriString.isEmpty ? null : Uri.parse(importUriString);
-      uriToSource[uri] = new Source(lineStarts, sourceCode, importUri, uri);
+
+      Set<Reference> coverageConstructors;
+      {
+        int constructorCoverageCount = readUInt30();
+        coverageConstructors =
+            constructorCoverageCount == 0 ? null : new Set<Reference>();
+        for (int j = 0; j < constructorCoverageCount; ++j) {
+          coverageConstructors.add(readMemberReference());
+        }
+      }
+
+      uriToSource[uri] = new Source(lineStarts, sourceCode, importUri, uri)
+        ..constantCoverageConstructors = coverageConstructors;
     }
 
     // Read index.
@@ -860,15 +875,39 @@
       dst.addAll(src);
     } else {
       src.forEach((Uri key, Source value) {
-        if (value.source.isNotEmpty || !dst.containsKey(key)) {
+        Source originalDestinationSource = dst[key];
+        Source mergeFrom;
+        Source mergeTo;
+        if (value.source.isNotEmpty || originalDestinationSource == null) {
           dst[key] = value;
+          mergeFrom = originalDestinationSource;
+          mergeTo = value;
+        } else {
+          mergeFrom = value;
+          mergeTo = originalDestinationSource;
+        }
+
+        // TODO(jensj): Find out what the right thing to do is --- it probably
+        // depends on what we do if read the same library twice - do we merge or
+        // do we overwrite, and should we even support such a thing?
+
+        // Merge coverage. Note that mergeFrom might be null.
+        if (mergeTo.constantCoverageConstructors == null) {
+          mergeTo.constantCoverageConstructors =
+              mergeFrom?.constantCoverageConstructors;
+        } else if (mergeFrom?.constantCoverageConstructors == null) {
+          // Nothing to do.
+        } else {
+          // Bot are non-null: Merge.
+          mergeTo.constantCoverageConstructors
+              .addAll(mergeFrom.constantCoverageConstructors);
         }
       });
     }
   }
 
   CanonicalName readCanonicalNameReference() {
-    var index = readUInt();
+    int index = readUInt30();
     if (index == 0) return null;
     return _linkTable[index - 1];
   }
@@ -886,12 +925,12 @@
   }
 
   LibraryDependency readLibraryDependencyReference() {
-    int index = readUInt();
+    int index = readUInt30();
     return _currentLibrary.dependencies[index];
   }
 
   Reference readClassReference({bool allowNull: false}) {
-    var name = readCanonicalNameReference();
+    CanonicalName name = readCanonicalNameReference();
     if (name == null && !allowNull) {
       throw 'Expected a class reference to be valid but was `null`.';
     }
@@ -899,7 +938,7 @@
   }
 
   Reference readMemberReference({bool allowNull: false}) {
-    var name = readCanonicalNameReference();
+    CanonicalName name = readCanonicalNameReference();
     if (name == null && !allowNull) {
       throw 'Expected a member reference to be valid but was `null`.';
     }
@@ -907,13 +946,13 @@
   }
 
   Reference readInstanceMemberReference({bool allowNull: false}) {
-    var reference = readMemberReference(allowNull: allowNull);
+    Reference reference = readMemberReference(allowNull: allowNull);
     readMemberReference(allowNull: true); // Skip origin
     return reference;
   }
 
   Reference getMemberReferenceFromInt(int index, {bool allowNull: false}) {
-    var name = getCanonicalNameReferenceFromInt(index);
+    CanonicalName name = getCanonicalNameReferenceFromInt(index);
     if (name == null && !allowNull) {
       throw 'Expected a member reference to be valid but was `null`.';
     }
@@ -940,7 +979,7 @@
     // There is a field for the procedure count.
     _byteOffset = endOffset - (1) * 4;
     int procedureCount = readUint32();
-    List<int> procedureOffsets = new List<int>(procedureCount + 1);
+    List<int> procedureOffsets = new List<int>.filled(procedureCount + 1, null);
 
     // There is a field for the procedure count, that number + 1 (for the end)
     // offsets, and then the class count (i.e. procedure count + 3 fields).
@@ -949,7 +988,7 @@
     for (int i = 0; i < procedureCount + 1; i++) {
       procedureOffsets[i] = _componentStartOffset + readUint32();
     }
-    List<int> classOffsets = new List<int>(classCount + 1);
+    List<int> classOffsets = new List<int>.filled(classCount + 1, null);
 
     // There is a field for the procedure count, that number + 1 (for the end)
     // offsets, then the class count and that number + 1 (for the end) offsets.
@@ -962,10 +1001,10 @@
 
     int flags = readByte();
 
-    int languageVersionMajor = readUInt();
-    int languageVersionMinor = readUInt();
+    int languageVersionMajor = readUInt30();
+    int languageVersionMinor = readUInt30();
 
-    var canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readCanonicalNameReference();
     Reference reference = canonicalName.getReference();
     Library library = reference.node;
     if (alwaysCreateNewNamedNodes) {
@@ -1033,7 +1072,7 @@
   }
 
   void _readLibraryDependencies(Library library) {
-    int length = readUInt();
+    int length = readUInt30();
     library.dependencies.length = length;
     for (int i = 0; i < length; ++i) {
       library.dependencies[i] = readLibraryDependency(library);
@@ -1041,12 +1080,12 @@
   }
 
   LibraryDependency readLibraryDependency(Library library) {
-    var fileOffset = readOffset();
-    var flags = readByte();
-    var annotations = readExpressionList();
-    var targetLibrary = readLibraryReference(allowNull: true);
-    var prefixName = readStringOrNullIfEmpty();
-    var names = readCombinatorList();
+    int fileOffset = readOffset();
+    int flags = readByte();
+    List<Expression> annotations = readExpressionList();
+    Reference targetLibrary = readLibraryReference(allowNull: true);
+    String prefixName = readStringOrNullIfEmpty();
+    List<Combinator> names = readCombinatorList();
     return new LibraryDependency.byReference(
         flags, annotations, targetLibrary, prefixName, names)
       ..fileOffset = fileOffset
@@ -1054,7 +1093,7 @@
   }
 
   void _readAdditionalExports(Library library) {
-    int numExportedReference = readUInt();
+    int numExportedReference = readUInt30();
     if (numExportedReference != 0) {
       library.additionalExports.clear();
       for (int i = 0; i < numExportedReference; i++) {
@@ -1066,13 +1105,13 @@
   }
 
   Combinator readCombinator() {
-    var isShow = readByte() == 1;
-    var names = readStringReferenceList();
+    bool isShow = readByte() == 1;
+    List<String> names = readStringReferenceList();
     return new Combinator(isShow, names);
   }
 
   List<Combinator> readCombinatorList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<Combinator> result =
         new List<Combinator>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -1082,7 +1121,7 @@
   }
 
   void _readLibraryParts(Library library) {
-    int length = readUInt();
+    int length = readUInt30();
     library.parts.length = length;
     for (int i = 0; i < length; ++i) {
       library.parts[i] = readLibraryPart(library);
@@ -1096,8 +1135,8 @@
   }
 
   Typedef readTypedef() {
-    var canonicalName = readCanonicalNameReference();
-    var reference = canonicalName.getReference();
+    CanonicalName canonicalName = readCanonicalNameReference();
+    Reference reference = canonicalName.getReference();
     Typedef node = reference.node;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1110,12 +1149,14 @@
     String name = readStringReference();
     node.annotations = readAnnotationList(node);
     readAndPushTypeParameterList(node.typeParameters, node);
-    var type = readDartType();
+    DartType type = readDartType();
     readAndPushTypeParameterList(node.typeParametersOfFunctionType, node);
     node.positionalParameters.clear();
     node.positionalParameters.addAll(readAndPushVariableDeclarationList());
+    setParents(node.positionalParameters, node);
     node.namedParameters.clear();
     node.namedParameters.addAll(readAndPushVariableDeclarationList());
+    setParents(node.namedParameters, node);
     typeParameterStack.length = 0;
     variableStack.length = 0;
     node.fileOffset = fileOffset;
@@ -1134,7 +1175,7 @@
     // There is a field for the procedure count.
     _byteOffset = endOffset - (1) * 4;
     int procedureCount = readUint32();
-    List<int> procedureOffsets = new List<int>(procedureCount + 1);
+    List<int> procedureOffsets = new List<int>.filled(procedureCount + 1, null);
     // There is a field for the procedure count, that number + 1 (for the end)
     // offsets (i.e. procedure count + 2 fields).
     _byteOffset = endOffset - (procedureCount + 2) * 4;
@@ -1143,8 +1184,8 @@
     }
     _byteOffset = savedByteOffset;
 
-    var canonicalName = readCanonicalNameReference();
-    var reference = canonicalName.getReference();
+    CanonicalName canonicalName = readCanonicalNameReference();
+    Reference reference = canonicalName.getReference();
     Class node = reference.node;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1153,14 +1194,14 @@
       node = new Class(reference: reference)..dirty = false;
     }
 
-    var fileUri = readUriReference();
+    Uri fileUri = readUriReference();
     node.startFileOffset = readOffset();
     node.fileOffset = readOffset();
     node.fileEndOffset = readOffset();
     int flags = readByte();
     node.flags = flags;
-    var name = readStringOrNullIfEmpty();
-    var annotations = readAnnotationList(node);
+    String name = readStringOrNullIfEmpty();
+    List<Expression> annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name ?? 'normal-class');
       return true;
@@ -1169,8 +1210,8 @@
     assert(typeParameterStack.length == 0);
 
     readAndPushTypeParameterList(node.typeParameters, node);
-    var supertype = readSupertypeOption();
-    var mixedInType = readSupertypeOption();
+    Supertype supertype = readSupertypeOption();
+    Supertype mixedInType = readSupertypeOption();
     _fillNonTreeNodeList(node.implementedTypes, readSupertype);
     if (_disableLazyClassReading) {
       readClassPartialContent(node, procedureOffsets);
@@ -1222,7 +1263,7 @@
     node.fileUri = fileUri;
     node.onType = onType;
 
-    int length = readUInt();
+    int length = readUInt30();
     node.members.length = length;
     for (int i = 0; i < length; i++) {
       Name name = readName();
@@ -1297,18 +1338,18 @@
       node = new Field(null,
           getterReference: getterReference, setterReference: setterReference);
     }
-    var fileUri = readUriReference();
+    Uri fileUri = readUriReference();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
-    int flags = readUInt();
-    var name = readName();
-    var annotations = readAnnotationList(node);
+    int flags = readUInt30();
+    Name name = readName();
+    List<Expression> annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.text ?? 'field');
       return true;
     }());
-    var type = readDartType();
-    var initializer = readExpressionOption();
+    DartType type = readDartType();
+    Expression initializer = readExpressionOption();
     int transformerFlags = getAndResetTransformerFlags();
     assert(((_) => true)(debugPath.removeLast()));
     node.fileOffset = fileOffset;
@@ -1327,8 +1368,8 @@
   Constructor readConstructor() {
     int tag = readByte();
     assert(tag == Tag.Constructor);
-    var canonicalName = readCanonicalNameReference();
-    var reference = canonicalName.getReference();
+    CanonicalName canonicalName = readCanonicalNameReference();
+    Reference reference = canonicalName.getReference();
     Constructor node = reference.node;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1336,23 +1377,23 @@
     if (node == null) {
       node = new Constructor(null, reference: reference);
     }
-    var fileUri = readUriReference();
-    var startFileOffset = readOffset();
-    var fileOffset = readOffset();
-    var fileEndOffset = readOffset();
-    var flags = readByte();
-    var name = readName();
-    var annotations = readAnnotationList(node);
+    Uri fileUri = readUriReference();
+    int startFileOffset = readOffset();
+    int fileOffset = readOffset();
+    int fileEndOffset = readOffset();
+    int flags = readByte();
+    Name name = readName();
+    List<Expression> annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.text ?? 'constructor');
       return true;
     }());
-    var function = readFunctionNode();
+    FunctionNode function = readFunctionNode();
     pushVariableDeclarations(function.positionalParameters);
     pushVariableDeclarations(function.namedParameters);
     _fillTreeNodeList(node.initializers, (index) => readInitializer(), node);
     variableStack.length = 0;
-    var transformerFlags = getAndResetTransformerFlags();
+    int transformerFlags = getAndResetTransformerFlags();
     assert(((_) => true)(debugPath.removeLast()));
     node.startFileOffset = startFileOffset;
     node.fileOffset = fileOffset;
@@ -1369,26 +1410,27 @@
   Procedure readProcedure(int endOffset) {
     int tag = readByte();
     assert(tag == Tag.Procedure);
-    var canonicalName = readCanonicalNameReference();
-    var reference = canonicalName.getReference();
+    CanonicalName canonicalName = readCanonicalNameReference();
+    Reference reference = canonicalName.getReference();
     Procedure node = reference.node;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
-    var fileUri = readUriReference();
-    var startFileOffset = readOffset();
-    var fileOffset = readOffset();
-    var fileEndOffset = readOffset();
+    Uri fileUri = readUriReference();
+    int startFileOffset = readOffset();
+    int fileOffset = readOffset();
+    int fileEndOffset = readOffset();
     int kindIndex = readByte();
-    var kind = ProcedureKind.values[kindIndex];
+    ProcedureKind kind = ProcedureKind.values[kindIndex];
+    ProcedureStubKind stubKind = ProcedureStubKind.values[readByte()];
     if (node == null) {
       node = new Procedure(null, kind, null, reference: reference);
     } else {
       assert(node.kind == kind);
     }
-    var flags = readUInt();
-    var name = readName();
-    var annotations = readAnnotationList(node);
+    int flags = readUInt30();
+    Name name = readName();
+    List<Expression> annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.text ?? 'procedure');
       return true;
@@ -1398,13 +1440,10 @@
     bool readFunctionNodeNow =
         (kind == ProcedureKind.Factory && functionNodeSize <= 50) ||
             _disableLazyReading;
-    var forwardingStubSuperTargetReference =
-        readMemberReference(allowNull: true);
-    var forwardingStubInterfaceTargetReference =
-        readMemberReference(allowNull: true);
-    var memberSignatureTargetReference = readMemberReference(allowNull: true);
-    var function = readFunctionNodeOption(!readFunctionNodeNow, endOffset);
-    var transformerFlags = getAndResetTransformerFlags();
+    Reference stubTargetReference = readMemberReference(allowNull: true);
+    FunctionNode function =
+        readFunctionNodeOption(!readFunctionNodeNow, endOffset);
+    int transformerFlags = getAndResetTransformerFlags();
     assert(((_) => true)(debugPath.removeLast()));
     node.startFileOffset = startFileOffset;
     node.fileOffset = fileOffset;
@@ -1416,17 +1455,13 @@
     node.function = function;
     function?.parent = node;
     node.setTransformerFlagsWithoutLazyLoading(transformerFlags);
-    node.forwardingStubSuperTargetReference =
-        forwardingStubSuperTargetReference;
-    node.forwardingStubInterfaceTargetReference =
-        forwardingStubInterfaceTargetReference;
-    node.memberSignatureOriginReference = memberSignatureTargetReference;
+    node.stubKind = stubKind;
+    node.stubTargetReference = stubTargetReference;
 
-    assert((node.forwardingStubSuperTargetReference != null) ||
+    assert((node.stubKind == ProcedureStubKind.ForwardingSuperStub &&
+            node.stubTargetReference != null) ||
         !(node.isForwardingStub && node.function.body != null));
-    assert(
-        !(node.isMemberSignature &&
-            node.memberSignatureOriginReference == null),
+    assert(!(node.isMemberSignature && node.stubTargetReference == null),
         "No member signature origin for member signature $node.");
     return node;
   }
@@ -1434,8 +1469,8 @@
   RedirectingFactoryConstructor readRedirectingFactoryConstructor() {
     int tag = readByte();
     assert(tag == Tag.RedirectingFactoryConstructor);
-    var canonicalName = readCanonicalNameReference();
-    var reference = canonicalName.getReference();
+    CanonicalName canonicalName = readCanonicalNameReference();
+    Reference reference = canonicalName.getReference();
     RedirectingFactoryConstructor node = reference.node;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1443,25 +1478,25 @@
     if (node == null) {
       node = new RedirectingFactoryConstructor(null, reference: reference);
     }
-    var fileUri = readUriReference();
-    var fileOffset = readOffset();
-    var fileEndOffset = readOffset();
-    var flags = readByte();
-    var name = readName();
-    var annotations = readAnnotationList(node);
+    Uri fileUri = readUriReference();
+    int fileOffset = readOffset();
+    int fileEndOffset = readOffset();
+    int flags = readByte();
+    Name name = readName();
+    List<Expression> annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.text ?? 'redirecting-factory-constructor');
       return true;
     }());
-    var targetReference = readMemberReference();
-    var typeArguments = readDartTypeList();
+    Reference targetReference = readMemberReference();
+    List<DartType> typeArguments = readDartTypeList();
     int typeParameterStackHeight = typeParameterStack.length;
-    var typeParameters = readAndPushTypeParameterList();
-    readUInt(); // Total parameter count.
-    var requiredParameterCount = readUInt();
+    List<TypeParameter> typeParameters = readAndPushTypeParameterList();
+    readUInt30(); // Total parameter count.
+    int requiredParameterCount = readUInt30();
     int variableStackHeight = variableStack.length;
-    var positional = readAndPushVariableDeclarationList();
-    var named = readAndPushVariableDeclarationList();
+    List<VariableDeclaration> positional = readAndPushVariableDeclarationList();
+    List<VariableDeclaration> named = readAndPushVariableDeclarationList();
     variableStack.length = variableStackHeight;
     typeParameterStack.length = typeParameterStackHeight;
     debugPath.removeLast();
@@ -1487,14 +1522,14 @@
       case Tag.InvalidInitializer:
         return new InvalidInitializer();
       case Tag.FieldInitializer:
-        var reference = readMemberReference();
-        var value = readExpression();
+        Reference reference = readMemberReference();
+        Expression value = readExpression();
         return new FieldInitializer.byReference(reference, value)
           ..isSynthetic = isSynthetic;
       case Tag.SuperInitializer:
         int offset = readOffset();
-        var reference = readMemberReference();
-        var arguments = readArguments();
+        Reference reference = readMemberReference();
+        Arguments arguments = readArguments();
         return new SuperInitializer.byReference(reference, arguments)
           ..isSynthetic = isSynthetic
           ..fileOffset = offset;
@@ -1528,13 +1563,13 @@
     AsyncMarker asyncMarker = AsyncMarker.values[readByte()];
     AsyncMarker dartAsyncMarker = AsyncMarker.values[readByte()];
     int typeParameterStackHeight = typeParameterStack.length;
-    var typeParameters = readAndPushTypeParameterList();
-    readUInt(); // total parameter count.
-    var requiredParameterCount = readUInt();
+    List<TypeParameter> typeParameters = readAndPushTypeParameterList();
+    readUInt30(); // total parameter count.
+    int requiredParameterCount = readUInt30();
     int variableStackHeight = variableStack.length;
-    var positional = readAndPushVariableDeclarationList();
-    var named = readAndPushVariableDeclarationList();
-    var returnType = readDartType();
+    List<VariableDeclaration> positional = readAndPushVariableDeclarationList();
+    List<VariableDeclaration> named = readAndPushVariableDeclarationList();
+    DartType returnType = readDartType();
     int oldLabelStackBase = labelStackBase;
     int oldSwitchCaseStackBase = switchCaseStackBase;
 
@@ -1543,7 +1578,7 @@
           2; // e.g. outline has Tag.Something and Tag.EmptyStatement
     }
 
-    var body;
+    Statement body;
     if (!lazyLoadBody) {
       labelStackBase = labelStack.length;
       switchCaseStackBase = switchCaseStack.length;
@@ -1612,7 +1647,7 @@
   }
 
   VariableDeclaration readVariableReference() {
-    int index = readUInt();
+    int index = readUInt30();
     if (index >= variableStack.length) {
       throw fail('unexpected variable index: $index');
     }
@@ -1631,7 +1666,7 @@
   }
 
   List<Expression> readExpressionList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<Expression> result =
         new List<Expression>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -1660,23 +1695,23 @@
           ..fileOffset = offset;
       case Tag.VariableGet:
         int offset = readOffset();
-        readUInt(); // offset of the variable declaration in the binary.
+        readUInt30(); // offset of the variable declaration in the binary.
         return new VariableGet(readVariableReference(), readDartTypeOption())
           ..fileOffset = offset;
       case Tag.SpecializedVariableGet:
         int index = tagByte & Tag.SpecializedPayloadMask;
         int offset = readOffset();
-        readUInt(); // offset of the variable declaration in the binary.
+        readUInt30(); // offset of the variable declaration in the binary.
         return new VariableGet(variableStack[index])..fileOffset = offset;
       case Tag.VariableSet:
         int offset = readOffset();
-        readUInt(); // offset of the variable declaration in the binary.
+        readUInt30(); // offset of the variable declaration in the binary.
         return new VariableSet(readVariableReference(), readExpression())
           ..fileOffset = offset;
       case Tag.SpecializedVariableSet:
         int index = tagByte & Tag.SpecializedPayloadMask;
         int offset = readOffset();
-        readUInt(); // offset of the variable declaration in the binary.
+        readUInt30(); // offset of the variable declaration in the binary.
         return new VariableSet(variableStack[index], readExpression())
           ..fileOffset = offset;
       case Tag.PropertyGet:
@@ -1764,20 +1799,20 @@
           ..fileOffset = offset;
       case Tag.ListConcatenation:
         int offset = readOffset();
-        var typeArgument = readDartType();
+        DartType typeArgument = readDartType();
         return new ListConcatenation(readExpressionList(),
             typeArgument: typeArgument)
           ..fileOffset = offset;
       case Tag.SetConcatenation:
         int offset = readOffset();
-        var typeArgument = readDartType();
+        DartType typeArgument = readDartType();
         return new SetConcatenation(readExpressionList(),
             typeArgument: typeArgument)
           ..fileOffset = offset;
       case Tag.MapConcatenation:
         int offset = readOffset();
-        var keyType = readDartType();
-        var valueType = readDartType();
+        DartType keyType = readDartType();
+        DartType valueType = readDartType();
         return new MapConcatenation(readExpressionList(),
             keyType: keyType, valueType: valueType)
           ..fileOffset = offset;
@@ -1785,7 +1820,7 @@
         int offset = readOffset();
         Reference classReference = readClassReference();
         List<DartType> typeArguments = readDartTypeList();
-        int fieldValueCount = readUInt();
+        int fieldValueCount = readUInt30();
         Map<Reference, Expression> fieldValues = <Reference, Expression>{};
         for (int i = 0; i < fieldValueCount; i++) {
           final Reference fieldRef =
@@ -1793,8 +1828,9 @@
           final Expression value = readExpression();
           fieldValues[fieldRef] = value;
         }
-        int assertCount = readUInt();
-        List<AssertStatement> asserts = new List<AssertStatement>(assertCount);
+        int assertCount = readUInt30();
+        List<AssertStatement> asserts =
+            new List<AssertStatement>.filled(assertCount, null);
         for (int i = 0; i < assertCount; i++) {
           asserts[i] = readStatement();
         }
@@ -1825,9 +1861,9 @@
         int biasedValue = tagByte & Tag.SpecializedPayloadMask;
         return new IntLiteral(biasedValue - Tag.SpecializedIntLiteralBias);
       case Tag.PositiveIntLiteral:
-        return new IntLiteral(readUInt());
+        return new IntLiteral(readUInt30());
       case Tag.NegativeIntLiteral:
-        return new IntLiteral(-readUInt());
+        return new IntLiteral(-readUInt30());
       case Tag.BigIntLiteral:
         return new IntLiteral(int.parse(readStringReference()));
       case Tag.DoubleLiteral:
@@ -1852,39 +1888,39 @@
         return new Throw(readExpression())..fileOffset = offset;
       case Tag.ListLiteral:
         int offset = readOffset();
-        var typeArgument = readDartType();
+        DartType typeArgument = readDartType();
         return new ListLiteral(readExpressionList(),
             typeArgument: typeArgument, isConst: false)
           ..fileOffset = offset;
       case Tag.ConstListLiteral:
         int offset = readOffset();
-        var typeArgument = readDartType();
+        DartType typeArgument = readDartType();
         return new ListLiteral(readExpressionList(),
             typeArgument: typeArgument, isConst: true)
           ..fileOffset = offset;
       case Tag.SetLiteral:
         int offset = readOffset();
-        var typeArgument = readDartType();
+        DartType typeArgument = readDartType();
         return new SetLiteral(readExpressionList(),
             typeArgument: typeArgument, isConst: false)
           ..fileOffset = offset;
       case Tag.ConstSetLiteral:
         int offset = readOffset();
-        var typeArgument = readDartType();
+        DartType typeArgument = readDartType();
         return new SetLiteral(readExpressionList(),
             typeArgument: typeArgument, isConst: true)
           ..fileOffset = offset;
       case Tag.MapLiteral:
         int offset = readOffset();
-        var keyType = readDartType();
-        var valueType = readDartType();
+        DartType keyType = readDartType();
+        DartType valueType = readDartType();
         return new MapLiteral(readMapEntryList(),
             keyType: keyType, valueType: valueType, isConst: false)
           ..fileOffset = offset;
       case Tag.ConstMapLiteral:
         int offset = readOffset();
-        var keyType = readDartType();
-        var valueType = readDartType();
+        DartType keyType = readDartType();
+        DartType valueType = readDartType();
         return new MapLiteral(readMapEntryList(),
             keyType: keyType, valueType: valueType, isConst: true)
           ..fileOffset = offset;
@@ -1894,21 +1930,21 @@
         int offset = readOffset();
         return new FunctionExpression(readFunctionNode())..fileOffset = offset;
       case Tag.Let:
-        var variable = readVariableDeclaration();
+        VariableDeclaration variable = readVariableDeclaration();
         int stackHeight = variableStack.length;
         pushVariableDeclaration(variable);
-        var body = readExpression();
+        Expression body = readExpression();
         variableStack.length = stackHeight;
         return new Let(variable, body);
       case Tag.BlockExpression:
         int stackHeight = variableStack.length;
-        var statements = readStatementList();
-        var value = readExpression();
+        List<Statement> statements = readStatementList();
+        Expression value = readExpression();
         variableStack.length = stackHeight;
         return new BlockExpression(new Block(statements), value);
       case Tag.Instantiation:
-        var expression = readExpression();
-        var typeArguments = readDartTypeList();
+        Expression expression = readExpression();
+        List<DartType> typeArguments = readDartTypeList();
         return new Instantiation(expression, typeArguments);
       case Tag.ConstantExpression:
         int offset = readOffset();
@@ -1921,7 +1957,7 @@
   }
 
   List<MapEntry> readMapEntryList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<MapEntry> result =
         new List<MapEntry>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -1935,7 +1971,7 @@
   }
 
   List<Statement> readStatementList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<Statement> result =
         new List<Statement>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -1945,7 +1981,7 @@
   }
 
   Statement readStatementOrNullIfEmpty() {
-    var node = readStatement();
+    Statement node = readStatement();
     if (node is EmptyStatement) {
       return null;
     } else {
@@ -1974,31 +2010,32 @@
             conditionEndOffset: readOffset(),
             message: readExpressionOption());
       case Tag.LabeledStatement:
-        var label = new LabeledStatement(null);
+        LabeledStatement label = new LabeledStatement(null);
         labelStack.add(label);
         label.body = readStatement()..parent = label;
         labelStack.removeLast();
         return label;
       case Tag.BreakStatement:
         int offset = readOffset();
-        int index = readUInt();
+        int index = readUInt30();
         return new BreakStatement(labelStack[labelStackBase + index])
           ..fileOffset = offset;
       case Tag.WhileStatement:
-        var offset = readOffset();
+        int offset = readOffset();
         return new WhileStatement(readExpression(), readStatement())
           ..fileOffset = offset;
       case Tag.DoStatement:
-        var offset = readOffset();
+        int offset = readOffset();
         return new DoStatement(readStatement(), readExpression())
           ..fileOffset = offset;
       case Tag.ForStatement:
         int variableStackHeight = variableStack.length;
-        var offset = readOffset();
-        var variables = readAndPushVariableDeclarationList();
-        var condition = readExpressionOption();
-        var updates = readExpressionList();
-        var body = readStatement();
+        int offset = readOffset();
+        List<VariableDeclaration> variables =
+            readAndPushVariableDeclarationList();
+        Expression condition = readExpressionOption();
+        List<Expression> updates = readExpressionList();
+        Statement body = readStatement();
         variableStack.length = variableStackHeight;
         return new ForStatement(variables, condition, updates, body)
           ..fileOffset = offset;
@@ -2006,19 +2043,19 @@
       case Tag.AsyncForInStatement:
         bool isAsync = tag == Tag.AsyncForInStatement;
         int variableStackHeight = variableStack.length;
-        var offset = readOffset();
-        var bodyOffset = readOffset();
-        var variable = readAndPushVariableDeclaration();
-        var iterable = readExpression();
-        var body = readStatement();
+        int offset = readOffset();
+        int bodyOffset = readOffset();
+        VariableDeclaration variable = readAndPushVariableDeclaration();
+        Expression iterable = readExpression();
+        Statement body = readStatement();
         variableStack.length = variableStackHeight;
         return new ForInStatement(variable, iterable, body, isAsync: isAsync)
           ..fileOffset = offset
           ..bodyOffset = bodyOffset;
       case Tag.SwitchStatement:
-        var offset = readOffset();
-        var expression = readExpression();
-        int count = readUInt();
+        int offset = readOffset();
+        Expression expression = readExpression();
+        int count = readUInt30();
         List<SwitchCase> cases =
             new List<SwitchCase>.filled(count, null, growable: true);
         for (int i = 0; i < count; ++i) {
@@ -2032,7 +2069,7 @@
         return new SwitchStatement(expression, cases)..fileOffset = offset;
       case Tag.ContinueSwitchStatement:
         int offset = readOffset();
-        int index = readUInt();
+        int index = readUInt30();
         return new ContinueSwitchStatement(
             switchCaseStack[switchCaseStackBase + index])
           ..fileOffset = offset;
@@ -2058,14 +2095,14 @@
             isNative: flags & YieldStatement.FlagNative != 0)
           ..fileOffset = offset;
       case Tag.VariableDeclaration:
-        var variable = readVariableDeclaration();
+        VariableDeclaration variable = readVariableDeclaration();
         variableStack.add(variable); // Will be popped by the enclosing scope.
         return variable;
       case Tag.FunctionDeclaration:
         int offset = readOffset();
-        var variable = readVariableDeclaration();
+        VariableDeclaration variable = readVariableDeclaration();
         variableStack.add(variable); // Will be popped by the enclosing scope.
-        var function = readFunctionNode();
+        FunctionNode function = readFunctionNode();
         return new FunctionDeclaration(variable, function)..fileOffset = offset;
       default:
         throw fail('unexpected statement tag: $tag');
@@ -2073,7 +2110,7 @@
   }
 
   void readSwitchCaseInto(SwitchCase caseNode) {
-    int length = readUInt();
+    int length = readUInt30();
     caseNode.expressions.length = length;
     caseNode.expressionOffsets.length = length;
     for (int i = 0; i < length; ++i) {
@@ -2085,7 +2122,7 @@
   }
 
   List<Catch> readCatchList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<Catch> result = new List<Catch>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
       result[i] = readCatch();
@@ -2095,11 +2132,11 @@
 
   Catch readCatch() {
     int variableStackHeight = variableStack.length;
-    var offset = readOffset();
-    var guard = readDartType();
-    var exception = readAndPushVariableDeclarationOption();
-    var stackTrace = readAndPushVariableDeclarationOption();
-    var body = readStatement();
+    int offset = readOffset();
+    DartType guard = readDartType();
+    VariableDeclaration exception = readAndPushVariableDeclarationOption();
+    VariableDeclaration stackTrace = readAndPushVariableDeclarationOption();
+    Statement body = readStatement();
     variableStack.length = variableStackHeight;
     return new Catch(exception, body, guard: guard, stackTrace: stackTrace)
       ..fileOffset = offset;
@@ -2107,9 +2144,9 @@
 
   Block readBlock() {
     int stackHeight = variableStack.length;
-    var offset = readOffset();
-    var endOffset = readOffset();
-    var body = readStatementList();
+    int offset = readOffset();
+    int endOffset = readOffset();
+    List<Statement> body = readStatementList();
     variableStack.length = stackHeight;
     return new Block(body)
       ..fileOffset = offset
@@ -2118,7 +2155,7 @@
 
   AssertBlock readAssertBlock() {
     int stackHeight = variableStack.length;
-    var body = readStatementList();
+    List<Statement> body = readStatementList();
     variableStack.length = stackHeight;
     return new AssertBlock(body);
   }
@@ -2138,7 +2175,7 @@
   }
 
   List<Supertype> readSupertypeList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<Supertype> result =
         new List<Supertype>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -2148,7 +2185,7 @@
   }
 
   List<DartType> readDartTypeList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<DartType> result =
         new List<DartType>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -2158,7 +2195,7 @@
   }
 
   List<NamedType> readNamedTypeList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<NamedType> result =
         new List<NamedType>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -2232,14 +2269,14 @@
       case Tag.FunctionType:
         int typeParameterStackHeight = typeParameterStack.length;
         int nullabilityIndex = readByte();
-        var typeParameters = readAndPushTypeParameterList();
-        var requiredParameterCount = readUInt();
-        var totalParameterCount = readUInt();
-        var positional = readDartTypeList();
-        var named = readNamedTypeList();
-        var typedefType = readDartTypeOption();
+        List<TypeParameter> typeParameters = readAndPushTypeParameterList();
+        int requiredParameterCount = readUInt30();
+        int totalParameterCount = readUInt30();
+        List<DartType> positional = readDartTypeList();
+        List<NamedType> named = readNamedTypeList();
+        DartType typedefType = readDartTypeOption();
         assert(positional.length + named.length == totalParameterCount);
-        var returnType = readDartType();
+        DartType returnType = readDartType();
         typeParameterStack.length = typeParameterStackHeight;
         return new FunctionType(
             positional, returnType, Nullability.values[nullabilityIndex],
@@ -2249,14 +2286,14 @@
             typedefType: typedefType);
       case Tag.SimpleFunctionType:
         int nullabilityIndex = readByte();
-        var positional = readDartTypeList();
-        var returnType = readDartType();
+        List<DartType> positional = readDartTypeList();
+        DartType returnType = readDartType();
         return new FunctionType(
             positional, returnType, Nullability.values[nullabilityIndex]);
       case Tag.TypeParameterType:
         int declaredNullabilityIndex = readByte();
-        int index = readUInt();
-        var bound = readDartTypeOption();
+        int index = readUInt30();
+        DartType bound = readDartTypeOption();
         return new TypeParameterType(typeParameterStack[index],
             Nullability.values[declaredNullabilityIndex], bound);
       default:
@@ -2266,7 +2303,7 @@
 
   List<TypeParameter> readAndPushTypeParameterList(
       [List<TypeParameter> list, TreeNode parent]) {
-    int length = readUInt();
+    int length = readUInt30();
     if (length == 0) return list ?? <TypeParameter>[];
     if (list == null) {
       list = new List<TypeParameter>.filled(length, null, growable: true);
@@ -2301,16 +2338,16 @@
   }
 
   Arguments readArguments() {
-    var numArguments = readUInt();
-    var typeArguments = readDartTypeList();
-    var positional = readExpressionList();
-    var named = readNamedExpressionList();
+    int numArguments = readUInt30();
+    List<DartType> typeArguments = readDartTypeList();
+    List<Expression> positional = readExpressionList();
+    List<NamedExpression> named = readNamedExpressionList();
     assert(numArguments == positional.length + named.length);
     return new Arguments(positional, types: typeArguments, named: named);
   }
 
   List<NamedExpression> readNamedExpressionList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<NamedExpression> result =
         new List<NamedExpression>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -2324,7 +2361,7 @@
   }
 
   List<VariableDeclaration> readAndPushVariableDeclarationList() {
-    int length = readUInt();
+    int length = readUInt30();
     List<VariableDeclaration> result =
         new List<VariableDeclaration>.filled(length, null, growable: true);
     for (int i = 0; i < length; ++i) {
@@ -2338,7 +2375,7 @@
   }
 
   VariableDeclaration readAndPushVariableDeclaration() {
-    var variable = readVariableDeclaration();
+    VariableDeclaration variable = readVariableDeclaration();
     variableStack.add(variable);
     return variable;
   }
@@ -2348,15 +2385,18 @@
     int fileEqualsOffset = readOffset();
     // The [VariableDeclaration] instance is not created at this point yet,
     // so `null` is temporarily set as the parent of the annotation nodes.
-    var annotations = readAnnotationList(null);
+    List<Expression> annotations = readAnnotationList(null);
     int flags = readByte();
-    var node = new VariableDeclaration(readStringOrNullIfEmpty(),
-        type: readDartType(), initializer: readExpressionOption(), flags: flags)
+    VariableDeclaration node = new VariableDeclaration(
+        readStringOrNullIfEmpty(),
+        type: readDartType(),
+        initializer: readExpressionOption(),
+        flags: flags)
       ..fileOffset = offset
       ..fileEqualsOffset = fileEqualsOffset;
     if (annotations.isNotEmpty) {
       for (int i = 0; i < annotations.length; ++i) {
-        var annotation = annotations[i];
+        Expression annotation = annotations[i];
         annotation.parent = node;
       }
       node.annotations = annotations;
@@ -2367,7 +2407,7 @@
   int readOffset() {
     // Offset is saved as unsigned,
     // but actually ranges from -1 and up (thus the -1)
-    return readUInt() - 1;
+    return readUInt30() - 1;
   }
 }
 
@@ -2395,27 +2435,28 @@
 
     // Read the length of metadataMappings.
     _byteOffset -= 4;
-    final subSectionCount = readUint32();
+    final int subSectionCount = readUint32();
 
     int endOffset = _byteOffset - 4; // End offset of the current subsection.
-    for (var i = 0; i < subSectionCount; i++) {
+    for (int i = 0; i < subSectionCount; i++) {
       // RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset
       _byteOffset = endOffset - 4;
-      final mappingLength = readUint32();
-      final mappingStart = (endOffset - 4) - 4 * 2 * mappingLength;
+      final int mappingLength = readUint32();
+      final int mappingStart = (endOffset - 4) - 4 * 2 * mappingLength;
       _byteOffset = mappingStart - 4;
 
       // UInt32 tag (fixed size StringReference)
-      final tag = _stringTable[readUint32()];
+      final String tag = _stringTable[readUint32()];
 
-      final repository = component.metadata[tag];
+      final MetadataRepository repository = component.metadata[tag];
       if (repository != null) {
         // Read nodeOffsetToMetadataOffset mapping.
-        final mapping = <int, int>{};
+        final Map<int, int> mapping = <int, int>{};
         _byteOffset = mappingStart;
-        for (var j = 0; j < mappingLength; j++) {
-          final nodeOffset = readUint32();
-          final metadataOffset = binaryOffsetForMetadataPayloads + readUint32();
+        for (int j = 0; j < mappingLength; j++) {
+          final int nodeOffset = readUint32();
+          final int metadataOffset =
+              binaryOffsetForMetadataPayloads + readUint32();
           mapping[nodeOffset] = metadataOffset;
         }
 
@@ -2432,7 +2473,7 @@
     final int savedOffset = _byteOffset;
     _byteOffset = offset;
 
-    final metadata = repository.readFromBinary(node, this);
+    final Object metadata = repository.readFromBinary(node, this);
 
     _byteOffset = savedOffset;
     return metadata;
@@ -2458,9 +2499,9 @@
       return node;
     }
 
-    for (var subsection in _subsections) {
+    for (_MetadataSubsection subsection in _subsections) {
       // First check if there is any metadata associated with this node.
-      final metadataOffset = subsection.mapping[nodeOffset];
+      final int metadataOffset = subsection.mapping[nodeOffset];
       if (metadataOffset != null) {
         subsection.repository.mapping[node] =
             _readMetadata(node, subsection.repository, metadataOffset);
@@ -2472,136 +2513,137 @@
 
   @override
   DartType readDartType({bool forSupertype = false}) {
-    final nodeOffset = _byteOffset;
-    final result = super.readDartType(forSupertype: forSupertype);
+    final int nodeOffset = _byteOffset;
+    final DartType result = super.readDartType(forSupertype: forSupertype);
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Library readLibrary(Component component, int endOffset) {
-    final nodeOffset = _byteOffset;
-    final result = super.readLibrary(component, endOffset);
+    final int nodeOffset = _byteOffset;
+    final Library result = super.readLibrary(component, endOffset);
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Typedef readTypedef() {
-    final nodeOffset = _byteOffset;
-    final result = super.readTypedef();
+    final int nodeOffset = _byteOffset;
+    final Typedef result = super.readTypedef();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Class readClass(int endOffset) {
-    final nodeOffset = _byteOffset;
-    final result = super.readClass(endOffset);
+    final int nodeOffset = _byteOffset;
+    final Class result = super.readClass(endOffset);
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Extension readExtension() {
-    final nodeOffset = _byteOffset;
-    final result = super.readExtension();
+    final int nodeOffset = _byteOffset;
+    final Extension result = super.readExtension();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Field readField() {
-    final nodeOffset = _byteOffset;
-    final result = super.readField();
+    final int nodeOffset = _byteOffset;
+    final Field result = super.readField();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Constructor readConstructor() {
-    final nodeOffset = _byteOffset;
-    final result = super.readConstructor();
+    final int nodeOffset = _byteOffset;
+    final Constructor result = super.readConstructor();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Procedure readProcedure(int endOffset) {
-    final nodeOffset = _byteOffset;
-    final result = super.readProcedure(endOffset);
+    final int nodeOffset = _byteOffset;
+    final Procedure result = super.readProcedure(endOffset);
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   RedirectingFactoryConstructor readRedirectingFactoryConstructor() {
-    final nodeOffset = _byteOffset;
-    final result = super.readRedirectingFactoryConstructor();
+    final int nodeOffset = _byteOffset;
+    final RedirectingFactoryConstructor result =
+        super.readRedirectingFactoryConstructor();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Initializer readInitializer() {
-    final nodeOffset = _byteOffset;
-    final result = super.readInitializer();
+    final int nodeOffset = _byteOffset;
+    final Initializer result = super.readInitializer();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   FunctionNode readFunctionNode(
       {bool lazyLoadBody: false, int outerEndOffset: -1}) {
-    final nodeOffset = _byteOffset;
-    final result = super.readFunctionNode(
+    final int nodeOffset = _byteOffset;
+    final FunctionNode result = super.readFunctionNode(
         lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset);
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Expression readExpression() {
-    final nodeOffset = _byteOffset;
-    final result = super.readExpression();
+    final int nodeOffset = _byteOffset;
+    final Expression result = super.readExpression();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Arguments readArguments() {
-    final nodeOffset = _byteOffset;
-    final result = super.readArguments();
+    final int nodeOffset = _byteOffset;
+    final Arguments result = super.readArguments();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   NamedExpression readNamedExpression() {
-    final nodeOffset = _byteOffset;
-    final result = super.readNamedExpression();
+    final int nodeOffset = _byteOffset;
+    final NamedExpression result = super.readNamedExpression();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   VariableDeclaration readVariableDeclaration() {
-    final nodeOffset = _byteOffset;
-    final result = super.readVariableDeclaration();
+    final int nodeOffset = _byteOffset;
+    final VariableDeclaration result = super.readVariableDeclaration();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Statement readStatement() {
-    final nodeOffset = _byteOffset;
-    final result = super.readStatement();
+    final int nodeOffset = _byteOffset;
+    final Statement result = super.readStatement();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   Combinator readCombinator() {
-    final nodeOffset = _byteOffset;
-    final result = super.readCombinator();
+    final int nodeOffset = _byteOffset;
+    final Combinator result = super.readCombinator();
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   LibraryDependency readLibraryDependency(Library library) {
-    final nodeOffset = _byteOffset;
-    final result = super.readLibraryDependency(library);
+    final int nodeOffset = _byteOffset;
+    final LibraryDependency result = super.readLibraryDependency(library);
     return _associateMetadata(result, nodeOffset);
   }
 
   @override
   LibraryPart readLibraryPart(Library library) {
-    final nodeOffset = _byteOffset;
-    final result = super.readLibraryPart(library);
+    final int nodeOffset = _byteOffset;
+    final LibraryPart result = super.readLibraryPart(library);
     return _associateMetadata(result, nodeOffset);
   }
 
@@ -2619,8 +2661,8 @@
 
   @override
   Supertype readSupertype() {
-    final nodeOffset = _byteOffset;
-    InterfaceType type = super.readDartType();
+    final int nodeOffset = _byteOffset;
+    InterfaceType type = super.readDartType(forSupertype: true);
     return _associateMetadata(
         new Supertype.byReference(type.className, type.typeArguments),
         nodeOffset);
@@ -2628,8 +2670,8 @@
 
   @override
   Name readName() {
-    final nodeOffset = _byteOffset;
-    final result = super.readName();
+    final int nodeOffset = _byteOffset;
+    final Name result = super.readName();
     return _associateMetadata(result, nodeOffset);
   }
 
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index e7bd343..ca92ca9 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -26,8 +26,8 @@
   ConstantIndexer _constantIndexer;
   final UriIndexer _sourceUriIndexer = new UriIndexer();
   bool _currentlyInNonimplementation = false;
-  final List<bool> _sourcesFromRealImplementation = new List<bool>();
-  final List<bool> _sourcesUsedInLibrary = new List<bool>();
+  final List<bool> _sourcesFromRealImplementation = <bool>[];
+  final List<bool> _sourcesUsedInLibrary = <bool>[];
   Map<LibraryDependency, int> _libraryDependencyIndex =
       <LibraryDependency, int>{};
   NonNullableByDefaultCompiledMode compilationMode;
@@ -120,7 +120,7 @@
     _binaryOffsetForStringTable = getBufferOffset();
 
     // Containers for the WTF-8 encoded strings.
-    final List<Uint8List> data = new List<Uint8List>();
+    final List<Uint8List> data = <Uint8List>[];
     int totalLength = 0;
     const int minLength = 1 << 16;
     Uint8List buffer;
@@ -287,92 +287,92 @@
   }
 
   void writeNodeList(List<Node> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Node node = nodes[i];
       writeNode(node);
     }
   }
 
   void writeProcedureNodeList(List<Procedure> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Procedure node = nodes[i];
       writeProcedureNode(node);
     }
   }
 
   void writeFieldNodeList(List<Field> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Field node = nodes[i];
       writeFieldNode(node);
     }
   }
 
   void writeClassNodeList(List<Class> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Class node = nodes[i];
       writeClassNode(node);
     }
   }
 
   void writeExtensionNodeList(List<Extension> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Extension node = nodes[i];
       writeExtensionNode(node);
     }
   }
 
   void writeConstructorNodeList(List<Constructor> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Constructor node = nodes[i];
       writeConstructorNode(node);
     }
   }
 
   void writeRedirectingFactoryConstructorNodeList(
       List<RedirectingFactoryConstructor> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final RedirectingFactoryConstructor node = nodes[i];
       writeRedirectingFactoryConstructorNode(node);
     }
   }
 
   void writeSwitchCaseNodeList(List<SwitchCase> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final SwitchCase node = nodes[i];
       writeSwitchCaseNode(node);
     }
   }
 
   void writeCatchNodeList(List<Catch> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Catch node = nodes[i];
       writeCatchNode(node);
     }
   }
 
   void writeTypedefNodeList(List<Typedef> nodes) {
-    final len = nodes.length;
+    final int len = nodes.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final node = nodes[i];
+      final Typedef node = nodes[i];
       writeTypedefNode(node);
     }
   }
@@ -538,7 +538,7 @@
     Timeline.timeSync("BinaryPrinter.writeComponentFile", () {
       compilationMode = component.mode;
       computeCanonicalNames(component);
-      final componentOffset = getBufferOffset();
+      final int componentOffset = getBufferOffset();
       writeUInt32(Tag.ComponentFile);
       writeUInt32(Tag.BinaryFormatVersion);
       writeBytes(ascii.encode(expectedSdkHash));
@@ -561,7 +561,7 @@
       writeConstantTable(_constantIndexer);
       List<Library> libraries = component.libraries;
       if (libraryFilter != null) {
-        List<Library> librariesNew = new List<Library>();
+        List<Library> librariesNew = <Library>[];
         for (int i = 0; i < libraries.length; i++) {
           Library library = libraries[i];
           if (libraryFilter(library)) librariesNew.add(library);
@@ -605,8 +605,8 @@
 
   void _writeNodeMetadataImpl(Node node, int nodeOffset) {
     for (_MetadataSubsection subsection in _metadataSubsections) {
-      final repository = subsection.repository;
-      final value = repository.mapping[node];
+      final MetadataRepository<Object> repository = subsection.repository;
+      final Object value = repository.mapping[node];
       if (value == null) {
         continue;
       }
@@ -695,7 +695,7 @@
       writeUInt32(stringIndexer.put(subsection.repository.tag));
 
       // RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset
-      final mappingLength = subsection.metadataMapping.length;
+      final int mappingLength = subsection.metadataMapping.length;
       for (int i = 0; i < mappingLength; i += 2) {
         writeUInt32(subsection.metadataMapping[i]); // node offset
         writeUInt32(subsection.metadataMapping[i + 1]); // metadata offset
@@ -773,7 +773,7 @@
 
     int length = _sourceUriIndexer.index.length;
     writeUInt32(length);
-    List<int> index = new List<int>(length);
+    List<int> index = new List<int>.filled(length, null);
 
     // Write data.
     int i = 0;
@@ -794,19 +794,33 @@
 
       writeByteList(source.source);
 
-      List<int> lineStarts = source.lineStarts;
-      writeUInt30(lineStarts.length);
-      int previousLineStart = 0;
-      for (int j = 0; j < lineStarts.length; ++j) {
-        int lineStart = lineStarts[j];
-        writeUInt30(lineStart - previousLineStart);
-        previousLineStart = lineStart;
+      {
+        List<int> lineStarts = source.lineStarts;
+        writeUInt30(lineStarts.length);
+        int previousLineStart = 0;
+        for (int j = 0; j < lineStarts.length; ++j) {
+          int lineStart = lineStarts[j];
+          writeUInt30(lineStart - previousLineStart);
+          previousLineStart = lineStart;
+        }
       }
 
       String importUriAsString =
           source.importUri == null ? "" : "${source.importUri}";
       outputStringViaBuffer(importUriAsString, buffer);
 
+      {
+        Set<Reference> coverage = source.constantCoverageConstructors;
+        if (coverage == null || coverage.isEmpty) {
+          writeUInt30(0);
+        } else {
+          writeUInt30(coverage.length);
+          for (Reference reference in coverage) {
+            writeNonNullReference(reference);
+          }
+        }
+      }
+
       i++;
     }
 
@@ -980,12 +994,12 @@
     leaveScope(memberScope: true);
 
     writeTypedefNodeList(node.typedefs);
-    classOffsets = new List<int>();
+    classOffsets = <int>[];
     writeClassNodeList(node.classes);
     classOffsets.add(getBufferOffset());
     writeExtensionNodeList(node.extensions);
     writeFieldNodeList(node.fields);
-    procedureOffsets = new List<int>();
+    procedureOffsets = <int>[];
     writeProcedureNodeList(node.procedures);
     procedureOffsets.add(getBufferOffset());
 
@@ -1105,10 +1119,10 @@
   }
 
   void writeAnnotationList(List<Expression> annotations) {
-    final len = annotations.length;
+    final int len = annotations.length;
     writeUInt30(len);
     for (int i = 0; i < len; i++) {
-      final annotation = annotations[i];
+      final Expression annotation = annotations[i];
       writeAnnotation(annotation);
     }
   }
@@ -1190,14 +1204,8 @@
 
   @override
   void visitProcedure(Procedure node) {
-    assert(
-        !(node.isMemberSignature &&
-            node.memberSignatureOriginReference == null),
+    assert(!(node.isMemberSignature && node.stubTargetReference == null),
         "No member signature origin for member signature $node.");
-    assert(!(node.isMemberSignature && node.isForwardingStub),
-        "Procedure is both member signature and forwarding stub: $node.");
-    assert(!(node.isMemberSignature && node.isForwardingSemiStub),
-        "Procedure is both member signature and forwarding semi stub: $node.");
     assert(
         !(node.forwardingStubInterfaceTarget is Procedure &&
             (node.forwardingStubInterfaceTarget as Procedure)
@@ -1228,12 +1236,11 @@
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.kind.index);
+    writeByte(node.stubKind.index);
     writeUInt30(node.flags);
     writeName(node.name ?? _emptyName);
     writeAnnotationList(node.annotations);
-    writeNullAllowedReference(node.forwardingStubSuperTargetReference);
-    writeNullAllowedReference(node.forwardingStubInterfaceTargetReference);
-    writeNullAllowedReference(node.memberSignatureOriginReference);
+    writeNullAllowedReference(node.stubTargetReference);
     writeOptionalFunctionNode(node.function);
     leaveScope(memberScope: true);
 
@@ -2511,7 +2518,7 @@
   }
 
   void pushScope() {
-    scopes ??= new List<int>();
+    scopes ??= <int>[];
     scopes.add(stackHeight);
   }
 
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 5b46f8e..5fa202a 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -146,7 +146,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 = 50;
+  static const int BinaryFormatVersion = 52;
 }
 
 abstract class ConstantTag {
@@ -177,7 +177,7 @@
 // If null, local development setting (e.g. run gen_kernel.dart from source),
 // we put 0x00..00 into when producing, do not validate when consuming.
 String get expectedSdkHash {
-  final sdkHash =
+  final String sdkHash =
       const String.fromEnvironment('sdk_hash', defaultValue: sdkHashNull);
   if (sdkHash.length != sdkHashLength) {
     throw '-Dsdk_hash=<hash> must be a ${sdkHashLength} byte string!';
diff --git a/pkg/kernel/lib/canonical_name.dart b/pkg/kernel/lib/canonical_name.dart
index 526c32e..6a1a469 100644
--- a/pkg/kernel/lib/canonical_name.dart
+++ b/pkg/kernel/lib/canonical_name.dart
@@ -105,7 +105,7 @@
   }
 
   CanonicalName getChild(String name) {
-    var map = _children ??= <String, CanonicalName>{};
+    Map<String, CanonicalName> map = _children ??= <String, CanonicalName>{};
     return map[name] ??= new CanonicalName._(this, name);
   }
 
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index cb03a01..dbe15bd 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -369,7 +369,8 @@
   bool invalidated = false;
 
   _ClosedWorldClassHierarchySubtypes(this.hierarchy)
-      : _classesByTopDownIndex = new List<Class>(hierarchy._infoMap.length) {
+      : _classesByTopDownIndex =
+            new List<Class>.filled(hierarchy._infoMap.length, null) {
     hierarchy.allBetsOff = true;
     if (hierarchy._infoMap.isNotEmpty) {
       for (Class class_ in hierarchy._infoMap.keys) {
@@ -388,7 +389,8 @@
     int index = _topDownSortIndex++;
     subInfo.topDownIndex = index;
     _classesByTopDownIndex[index] = subInfo.classInfo.classNode;
-    var subtypeSetBuilder = new _IntervalListBuilder()..addSingleton(index);
+    _IntervalListBuilder subtypeSetBuilder = new _IntervalListBuilder()
+      ..addSingleton(index);
     for (_ClassInfo subtype in subInfo.classInfo.directExtenders) {
       _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode];
       _topDownSortVisit(subtypeInfo);
@@ -459,7 +461,7 @@
       onAmbiguousSupertypes(class_, a, b);
       List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
       if (recorded == null) {
-        recorded = new List<Supertype>();
+        recorded = <Supertype>[];
         _recordedAmbiguousSupertypes[class_] = recorded;
       }
       recorded.add(a);
@@ -472,7 +474,7 @@
       new LinkedHashMap<Class, _ClassInfo>();
 
   List<ForTestingClassInfo> getTestingClassInfo() {
-    List<ForTestingClassInfo> result = new List<ForTestingClassInfo>();
+    List<ForTestingClassInfo> result = <ForTestingClassInfo>[];
     for (_ClassInfo info in _infoMap.values) {
       result.add(new ForTestingClassInfo._(info));
     }
@@ -486,7 +488,7 @@
   }
 
   List<Class> getUsedClasses() {
-    List<Class> result = new List<Class>();
+    List<Class> result = <Class>[];
     for (_ClassInfo classInfo in _infoMap.values) {
       if (classInfo.used) {
         result.add(classInfo.classNode);
@@ -535,8 +537,10 @@
 
   @override
   Iterable<Class> getOrderedClasses(Iterable<Class> unordered) {
-    var unorderedSet = unordered.toSet();
-    for (Class c in unordered) _infoMap[c]?.used = true;
+    Set<Class> unorderedSet = unordered.toSet();
+    for (Class c in unordered) {
+      _infoMap[c]?.used = true;
+    }
     return _infoMap.keys.where(unorderedSet.contains);
   }
 
@@ -564,16 +568,16 @@
 
   List<_ClassInfo> _getRankedSuperclassInfos(_ClassInfo info) {
     if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos;
-    var heap = new _LubHeap()..add(info);
-    var chain = <_ClassInfo>[];
+    _LubHeap heap = new _LubHeap()..add(info);
+    List<_ClassInfo> chain = <_ClassInfo>[];
     info.leastUpperBoundInfos = chain;
     _ClassInfo lastInfo = null;
     while (heap.isNotEmpty) {
-      var nextInfo = heap.remove();
+      _ClassInfo nextInfo = heap.remove();
       if (identical(nextInfo, lastInfo)) continue;
       chain.add(nextInfo);
       lastInfo = nextInfo;
-      var classNode = nextInfo.classNode;
+      Class classNode = nextInfo.classNode;
       void addToHeap(Supertype supertype) {
         heap.add(infoFor(supertype.classNode));
       }
@@ -682,17 +686,17 @@
         if (currentDepth == 0) return candidate;
         ++numCandidatesAtThisDepth;
       } else {
-        var superType1 = identical(info1, next)
+        InterfaceType superType1 = identical(info1, next)
             ? type1
             : Substitution.fromInterfaceType(type1).substituteType(
                 info1.genericSuperType[next.classNode].asInterfaceType);
-        var superType2 = identical(info2, next)
+        InterfaceType superType2 = identical(info2, next)
             ? type2
             : Substitution.fromInterfaceType(type2).substituteType(
                 info2.genericSuperType[next.classNode].asInterfaceType);
         if (!clientLibrary.isNonNullableByDefault) {
-          superType1 = legacyErasure(coreTypes, superType1);
-          superType2 = legacyErasure(coreTypes, superType2);
+          superType1 = legacyErasure(superType1);
+          superType2 = legacyErasure(superType2);
         }
         if (superType1 == superType2) {
           candidate = superType1.withDeclaredNullability(
@@ -798,10 +802,11 @@
       callback(Member declaredMember, Member interfaceMember, bool isSetter),
       {bool crossGettersSetters: false}) {
     _ClassInfo info = infoFor(class_);
-    for (var supertype in class_.supers) {
-      var superclass = supertype.classNode;
-      var superGetters = getInterfaceMembers(superclass);
-      var superSetters = getInterfaceMembers(superclass, setters: true);
+    for (Supertype supertype in class_.supers) {
+      Class superclass = supertype.classNode;
+      List<Member> superGetters = getInterfaceMembers(superclass);
+      List<Member> superSetters =
+          getInterfaceMembers(superclass, setters: true);
       _reportOverrides(_buildDeclaredMembers(class_, info, setters: false),
           superGetters, callback);
       _reportOverrides(_buildDeclaredMembers(class_, info, setters: true),
@@ -837,7 +842,7 @@
 
   @override
   List<Supertype> genericSupertypesOf(Class class_) {
-    final supertypes = infoFor(class_).genericSuperType;
+    Map<Class, Supertype> supertypes = infoFor(class_).genericSuperType;
     if (supertypes == null) return const <Supertype>[];
     return supertypes.values.toList();
   }
@@ -924,7 +929,7 @@
     }
 
     // Add the new classes.
-    List<Class> addedClassesSorted = new List<Class>();
+    List<Class> addedClassesSorted = <Class>[];
     int expectedStartIndex = _topSortIndex;
     for (Library lib in ensureKnownLibraries) {
       if (knownLibraries.contains(lib)) continue;
@@ -951,7 +956,7 @@
       {bool findDescendants: false}) {
     if (classes.isEmpty) return this;
 
-    List<_ClassInfo> infos = new List<_ClassInfo>();
+    List<_ClassInfo> infos = <_ClassInfo>[];
     if (findDescendants) {
       Set<_ClassInfo> processedClasses = new Set<_ClassInfo>();
       List<_ClassInfo> worklist = <_ClassInfo>[];
@@ -1017,19 +1022,22 @@
 
     for (_ClassInfo info in _infoMap.values) {
       for (_ClassInfo subInfo in info.directExtenders) {
-        if (!_infoMap.containsKey(subInfo.classNode))
+        if (!_infoMap.containsKey(subInfo.classNode)) {
           throw new StateError(
               "Found $subInfo (${subInfo.classNode}) in directExtenders");
+        }
       }
       for (_ClassInfo subInfo in info.directMixers) {
-        if (!_infoMap.containsKey(subInfo.classNode))
+        if (!_infoMap.containsKey(subInfo.classNode)) {
           throw new StateError(
               "Found $subInfo (${subInfo.classNode}) in directMixers");
+        }
       }
       for (_ClassInfo subInfo in info.directImplementers) {
-        if (!_infoMap.containsKey(subInfo.classNode))
+        if (!_infoMap.containsKey(subInfo.classNode)) {
           throw new StateError(
               "Found $subInfo (${subInfo.classNode}) in directImplementers");
+        }
       }
     }
     return true;
@@ -1045,14 +1053,14 @@
     if (type.classNode == superclass) {
       return superclass.asThisSupertype;
     }
-    var map = infoFor(type.classNode)?.genericSuperType;
+    Map<Class, Supertype> map = infoFor(type.classNode)?.genericSuperType;
     return map == null ? null : map[superclass];
   }
 
   void _initialize(List<Library> libraries) {
     // Build the class ordering based on a topological sort.
-    for (var library in libraries) {
-      for (var classNode in library.classes) {
+    for (Library library in libraries) {
+      for (Class classNode in library.classes) {
         _topologicalSortVisit(classNode, new Set<Class>());
       }
       knownLibraries.add(library);
@@ -1079,7 +1087,7 @@
       if (class_.mixedInType != null) {
         _infoMap[class_.mixedInType.classNode].directMixers.add(info);
       }
-      for (var supertype in class_.implementedTypes) {
+      for (Supertype supertype in class_.implementedTypes) {
         _infoMap[supertype.classNode].directImplementers.add(info);
       }
       _collectSupersForClass(class_);
@@ -1114,7 +1122,7 @@
   int _topSortIndex = 0;
   int _topologicalSortVisit(Class classNode, Set<Class> beingVisited,
       {List<Class> orderedList}) {
-    var info = _infoMap[classNode];
+    _ClassInfo info = _infoMap[classNode];
     if (info != null) {
       return info.depth;
     }
@@ -1138,7 +1146,7 @@
           _topologicalSortVisit(classNode.mixedInType.classNode, beingVisited,
               orderedList: orderedList));
     }
-    for (var supertype in classNode.implementedTypes) {
+    for (Supertype supertype in classNode.implementedTypes) {
       superDepth = max(
           superDepth,
           _topologicalSortVisit(supertype.classNode, beingVisited,
@@ -1207,7 +1215,7 @@
         }
       }
     } else {
-      members = new List<Member>();
+      members = <Member>[];
       for (Procedure procedure in classNode.procedures) {
         if (procedure.isStatic) continue;
         if (procedure.kind == ProcedureKind.Setter) {
@@ -1376,7 +1384,7 @@
       // Copy over all transitive generic super types, and substitute the
       // free variables with those provided in [supertype].
       Class superclass = supertype.classNode;
-      var substitution = Substitution.fromPairs(
+      Substitution substitution = Substitution.fromPairs(
           superclass.typeParameters, supertype.typeArguments);
       subInfo.genericSuperType ??= <Class, Supertype>{};
       subInfo.genericSuperTypes ??= <Class, List<Supertype>>{};
@@ -1396,9 +1404,9 @@
   void _collectSupersForClass(Class class_) {
     _ClassInfo info = _infoMap[class_];
 
-    var superclassSetBuilder = new _IntervalListBuilder()
+    _IntervalListBuilder superclassSetBuilder = new _IntervalListBuilder()
       ..addSingleton(info.topologicalIndex);
-    var supertypeSetBuilder = new _IntervalListBuilder()
+    _IntervalListBuilder supertypeSetBuilder = new _IntervalListBuilder()
       ..addSingleton(info.topologicalIndex);
 
     if (class_.supertype != null) {
@@ -1429,9 +1437,9 @@
   /// The more numbers are condensed near the beginning, the more efficient the
   /// internal data structure is.
   List<int> getExpenseHistogram() {
-    var result = <int>[];
+    List<int> result = <int>[];
     for (Class class_ in _infoMap.keys) {
-      var info = _infoMap[class_];
+      _ClassInfo info = _infoMap[class_];
       int intervals = info.supertypeIntervalList.length ~/ 2;
       if (intervals >= result.length) {
         int oldLength = result.length;
@@ -1452,7 +1460,7 @@
     int intervals = 0;
     int sizes = 0;
     for (Class class_ in _infoMap.keys) {
-      var info = _infoMap[class_];
+      _ClassInfo info = _infoMap[class_];
       intervals += (info.superclassIntervalList.length +
               info.supertypeIntervalList.length) ~/
           2;
@@ -1521,7 +1529,7 @@
       }
     }
     // Copy the results over to a typed array of the correct length.
-    var result = new Uint32List(storeIndex);
+    Uint32List result = new Uint32List(storeIndex);
     for (int i = 0; i < storeIndex; ++i) {
       result[i] = events[i];
     }
@@ -1650,7 +1658,7 @@
     Supertype canonical = genericSuperType[cls];
     if (canonical == null) {
       if (!classNode.enclosingLibrary.isNonNullableByDefault) {
-        canonical = legacyErasureSupertype(coreTypes, type);
+        canonical = legacyErasureSupertype(type);
       } else {
         canonical = type;
       }
@@ -1672,7 +1680,7 @@
           genericSuperType[cls] = result;
         }
       } else {
-        type = legacyErasureSupertype(coreTypes, type);
+        type = legacyErasureSupertype(type);
         if (type != canonical) {
           onAmbiguousSupertypes(classNode, canonical, type);
         }
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index c14b8d16..3371d54 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -103,6 +103,24 @@
     return result;
   }
 
+  /// Root entry point for cloning a subtree within the same context where the
+  /// file offsets are valid.
+  T cloneInContext<T extends TreeNode>(T node) {
+    assert(_activeFileUri == null);
+    _activeFileUri = _activeFileUriFromContext(node);
+    final TreeNode result = clone<T>(node);
+    _activeFileUri = null;
+    return result;
+  }
+
+  Uri _activeFileUriFromContext(TreeNode node) {
+    while (node != null) {
+      if (node is FileUriNode && node.fileUri != null) return node.fileUri;
+      node = node.parent;
+    }
+    return null;
+  }
+
   DartType visitType(DartType type) {
     return substitute(type, typeSubstitution);
   }
@@ -318,7 +336,7 @@
   }
 
   visitLet(Let node) {
-    var newVariable = clone(node.variable);
+    VariableDeclaration newVariable = clone(node.variable);
     return new Let(newVariable, clone(node.body));
   }
 
@@ -332,7 +350,7 @@
 
   visitBlock(Block node) {
     return new Block(node.statements.map(clone).toList())
-      ..fileOffset = _cloneFileOffset(node.fileOffset);
+      ..fileEndOffset = _cloneFileOffset(node.fileEndOffset);
   }
 
   visitAssertBlock(AssertBlock node) {
@@ -370,13 +388,13 @@
   }
 
   visitForStatement(ForStatement node) {
-    var variables = node.variables.map(clone).toList();
+    List<VariableDeclaration> variables = node.variables.map(clone).toList();
     return new ForStatement(variables, cloneOptional(node.condition),
         node.updates.map(clone).toList(), clone(node.body));
   }
 
   visitForInStatement(ForInStatement node) {
-    var newVariable = clone(node.variable);
+    VariableDeclaration newVariable = clone(node.variable);
     return new ForInStatement(
         newVariable, clone(node.iterable), clone(node.body),
         isAsync: node.isAsync)
@@ -396,7 +414,7 @@
   }
 
   visitSwitchCase(SwitchCase node) {
-    var switchCase = switchCases[node];
+    SwitchCase switchCase = switchCases[node];
     switchCase.body = clone(node.body)..parent = switchCase;
     return switchCase;
   }
@@ -420,8 +438,8 @@
   }
 
   visitCatch(Catch node) {
-    var newException = cloneOptional(node.exception);
-    var newStackTrace = cloneOptional(node.stackTrace);
+    VariableDeclaration newException = cloneOptional(node.exception);
+    VariableDeclaration newStackTrace = cloneOptional(node.stackTrace);
     return new Catch(newException, clone(node.body),
         stackTrace: newStackTrace, guard: visitType(node.guard));
   }
@@ -446,7 +464,7 @@
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
-    var newVariable = clone(node.variable);
+    VariableDeclaration newVariable = clone(node.variable);
     return new FunctionDeclaration(newVariable, clone(node.function));
   }
 
@@ -487,9 +505,11 @@
 
   visitFunctionNode(FunctionNode node) {
     prepareTypeParameters(node.typeParameters);
-    var typeParameters = node.typeParameters.map(clone).toList();
-    var positional = node.positionalParameters.map(clone).toList();
-    var named = node.namedParameters.map(clone).toList();
+    List<TypeParameter> typeParameters =
+        node.typeParameters.map(clone).toList();
+    List<VariableDeclaration> positional =
+        node.positionalParameters.map(clone).toList();
+    List<VariableDeclaration> named = node.namedParameters.map(clone).toList();
     return new FunctionNode(cloneFunctionNodeBody(node),
         typeParameters: typeParameters,
         positionalParameters: positional,
@@ -498,7 +518,6 @@
         returnType: visitType(node.returnType),
         asyncMarker: node.asyncMarker,
         dartAsyncMarker: node.dartAsyncMarker)
-      ..fileOffset = _cloneFileOffset(node.fileOffset)
       ..fileEndOffset = _cloneFileOffset(node.fileEndOffset);
   }
 
@@ -622,15 +641,17 @@
     final Uri activeFileUriSaved = _activeFileUri;
     _activeFileUri = node.fileUri ?? _activeFileUri;
 
-    Constructor result = new Constructor(super.clone(node.function),
-        name: node.name,
-        isConst: node.isConst,
-        isExternal: node.isExternal,
-        isSynthetic: node.isSynthetic,
-        initializers: node.initializers.map(super.clone).toList(),
-        transformerFlags: node.transformerFlags,
-        fileUri: _activeFileUri,
-        reference: referenceFrom?.reference)
+    Constructor result = new Constructor(
+      super.clone(node.function),
+      name: node.name,
+      isConst: node.isConst,
+      isExternal: node.isExternal,
+      isSynthetic: node.isSynthetic,
+      initializers: node.initializers.map(super.clone).toList(),
+      transformerFlags: node.transformerFlags,
+      fileUri: _activeFileUri,
+      reference: referenceFrom?.reference,
+    )
       ..annotations = cloneAnnotations && !node.annotations.isEmpty
           ? node.annotations.map(super.clone).toList()
           : const <Expression>[]
@@ -644,15 +665,13 @@
   Procedure cloneProcedure(Procedure node, Procedure referenceFrom) {
     final Uri activeFileUriSaved = _activeFileUri;
     _activeFileUri = node.fileUri ?? _activeFileUri;
-
     Procedure result = new Procedure(
         node.name, node.kind, super.clone(node.function),
         reference: referenceFrom?.reference,
         transformerFlags: node.transformerFlags,
         fileUri: _activeFileUri,
-        forwardingStubSuperTarget: node.forwardingStubSuperTarget,
-        forwardingStubInterfaceTarget: node.forwardingStubInterfaceTarget,
-        memberSignatureOrigin: node.memberSignatureOrigin)
+        stubKind: node.stubKind,
+        stubTarget: node.stubTarget)
       ..annotations = cloneAnnotations && !node.annotations.isEmpty
           ? node.annotations.map(super.clone).toList()
           : const <Expression>[]
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 24f0250..e7c5646 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -90,12 +90,12 @@
   Constructor _streamIteratorDefaultConstructor;
   Constructor _asyncStarStreamControllerDefaultConstructor;
   Procedure _asyncStarMoveNextHelperProcedure;
-  Procedure _asyncStackTraceHelperProcedure;
   Procedure _asyncThenWrapperHelperProcedure;
   Procedure _asyncErrorWrapperHelperProcedure;
   Procedure _awaitHelperProcedure;
   Procedure _boolFromEnvironment;
   Constructor _lateInitializationFieldAssignedDuringInitializationConstructor;
+  Constructor _lateInitializationLocalAssignedDuringInitializationConstructor;
   Constructor _lateInitializationFieldNotInitializedConstructor;
   Constructor _lateInitializationLocalNotInitializedConstructor;
   Constructor _lateInitializationFieldAlreadyInitializedConstructor;
@@ -233,11 +233,6 @@
         index.getTopLevelMember('dart:async', '_asyncStarMoveNextHelper');
   }
 
-  Procedure get asyncStackTraceHelperProcedure {
-    return _asyncStackTraceHelperProcedure ??=
-        index.getTopLevelMember('dart:async', '_asyncStackTraceHelper');
-  }
-
   Procedure get asyncThenWrapperHelperProcedure {
     return _asyncThenWrapperHelperProcedure ??=
         index.getTopLevelMember('dart:async', '_asyncThenWrapperHelper');
@@ -1226,6 +1221,12 @@
         index.getMember('dart:_internal', 'LateError', 'fieldADI');
   }
 
+  Constructor
+      get lateInitializationLocalAssignedDuringInitializationConstructor {
+    return _lateInitializationLocalAssignedDuringInitializationConstructor ??=
+        index.getMember('dart:_internal', 'LateError', 'localADI');
+  }
+
   Constructor get lateInitializationFieldNotInitializedConstructor {
     return _lateInitializationFieldNotInitializedConstructor ??=
         index.getMember('dart:_internal', 'LateError', 'fieldNI');
diff --git a/pkg/kernel/lib/error_formatter.dart b/pkg/kernel/lib/error_formatter.dart
index 7bb8974..42265e7 100644
--- a/pkg/kernel/lib/error_formatter.dart
+++ b/pkg/kernel/lib/error_formatter.dart
@@ -37,15 +37,15 @@
     String sourceLine = null;
 
     // Try finding original source line.
-    final fileOffset = _findFileOffset(where);
+    final int fileOffset = _findFileOffset(where);
     if (fileOffset != TreeNode.noOffset) {
-      final fileUri = _fileUriOf(context);
+      final Uri fileUri = _fileUriOf(context);
 
-      final component = context.enclosingComponent;
-      final source = component.uriToSource[fileUri];
-      final location = component.getLocation(fileUri, fileOffset);
-      final lineStart = source.lineStarts[location.line - 1];
-      final lineEnd = (location.line < source.lineStarts.length)
+      final Component component = context.enclosingComponent;
+      final Source source = component.uriToSource[fileUri];
+      final Location location = component.getLocation(fileUri, fileOffset);
+      final int lineStart = source.lineStarts[location.line - 1];
+      final int lineEnd = (location.line < source.lineStarts.length)
           ? source.lineStarts[location.line]
           : (source.source.length - 1);
       if (lineStart < source.source.length &&
@@ -58,16 +58,17 @@
     }
 
     // Find the name of the enclosing member.
-    var name = "", body = context;
+    String name = "";
+    dynamic body = context;
     if (context is Class || context is Library) {
       name = context.name;
     } else if (context is Procedure || context is Constructor) {
-      final parent = context.parent;
-      final parentName =
+      final dynamic parent = context.parent;
+      final String parentName =
           parent is Class ? parent.name : (parent as Library).name;
       name = "${parentName}::${context.name.text}";
     } else {
-      final field = context as Field;
+      final Field field = context as Field;
       if (where is Field) {
         name = "${field.parent}.${field.name}";
       } else {
@@ -114,7 +115,7 @@
   }
 
   static Member _findEnclosingMember(TreeNode n) {
-    var context = n;
+    TreeNode context = n;
     while (context is! Member) {
       context = context.parent;
     }
@@ -125,7 +126,7 @@
 /// Extension of a [Printer] that highlights the given node using ANSI
 /// escape sequences.
 class HighlightingPrinter extends Printer {
-  final highlight;
+  final Node highlight;
 
   HighlightingPrinter(this.highlight)
       : super(new StringBuffer(), syntheticNames: globalDebuggingNames);
@@ -133,8 +134,8 @@
   @override
   bool shouldHighlight(Node node) => highlight == node;
 
-  static const kHighlightStart = ansiRed;
-  static const kHighlightEnd = ansiReset;
+  static const String kHighlightStart = ansiRed;
+  static const String kHighlightEnd = ansiReset;
 
   @override
   void startHighlight(Node node) {
@@ -150,7 +151,7 @@
   /// representation of the [highlight] node.
   static String stringifyContainingLines(Node node, Node highlight) {
     if (node == highlight) {
-      final firstLine = debugNodeToString(node).split('\n').first;
+      final String firstLine = debugNodeToString(node).split('\n').first;
       return "${kHighlightStart}${firstLine}${kHighlightEnd}";
     }
 
@@ -161,7 +162,7 @@
   }
 
   static Iterable<String> _onlyHighlightedLines(String text) sync* {
-    for (var line
+    for (String line
         in text.split('\n').skipWhile((l) => !l.contains(kHighlightStart))) {
       yield line;
       if (line.contains(kHighlightEnd)) {
@@ -171,7 +172,7 @@
   }
 }
 
-const ansiBlue = "\u001b[1;34m";
-const ansiYellow = "\u001b[1;33m";
-const ansiRed = "\u001b[1;31m";
-const ansiReset = "\u001b[0;0m";
+const String ansiBlue = "\u001b[1;34m";
+const String ansiYellow = "\u001b[1;33m";
+const String ansiRed = "\u001b[1;31m";
+const String ansiReset = "\u001b[0;0m";
diff --git a/pkg/kernel/lib/external_name.dart b/pkg/kernel/lib/external_name.dart
index 6577041..157981d 100644
--- a/pkg/kernel/lib/external_name.dart
+++ b/pkg/kernel/lib/external_name.dart
@@ -20,7 +20,7 @@
     return null;
   }
   for (final Expression annotation in procedure.annotations) {
-    final value = _getExternalNameValue(annotation);
+    final String value = _getExternalNameValue(annotation);
     if (value != null) {
       return value;
     }
@@ -30,9 +30,9 @@
 
 /// Returns native extension URIs for given [library].
 List<String> getNativeExtensionUris(Library library) {
-  final uris = <String>[];
-  for (var annotation in library.annotations) {
-    final value = _getExternalNameValue(annotation);
+  final List<String> uris = <String>[];
+  for (Expression annotation in library.annotations) {
+    final String value = _getExternalNameValue(annotation);
     if (value != null) {
       uris.add(value);
     }
@@ -46,7 +46,7 @@
       return (annotation.arguments.positional.single as StringLiteral).value;
     }
   } else if (annotation is ConstantExpression) {
-    final constant = annotation.constant;
+    final Constant constant = annotation.constant;
     if (constant is InstanceConstant) {
       if (_isExternalName(constant.classNode)) {
         return (constant.fieldValues.values.single as StringConstant).value;
diff --git a/pkg/kernel/lib/import_table.dart b/pkg/kernel/lib/import_table.dart
index 06d9051..c85e9f3 100644
--- a/pkg/kernel/lib/import_table.dart
+++ b/pkg/kernel/lib/import_table.dart
@@ -76,15 +76,15 @@
   void addLibraryImport(Library target) {
     if (target == referenceLibrary) return; // Self-reference is special.
     if (target == null) return;
-    var referenceUri = referenceLibrary.importUri;
-    var targetUri = target.importUri;
+    Uri referenceUri = referenceLibrary.importUri;
+    Uri targetUri = target.importUri;
     if (targetUri == null) {
       throw '$referenceUri cannot refer to library without an import URI';
     }
     // To support using custom-uris in unit tests, we don't check directly
     // whether the scheme is 'file:', but instead we check that is not 'dart:'
     // or 'package:'.
-    bool isFileOrCustomScheme(uri) =>
+    bool isFileOrCustomScheme(Uri uri) =>
         uri.scheme != '' && uri.scheme != 'package' && uri.scheme != 'dart';
     bool isTargetSchemeFileOrCustom = isFileOrCustomScheme(targetUri);
     bool isReferenceSchemeFileOrCustom = isFileOrCustomScheme(referenceUri);
@@ -144,7 +144,7 @@
     if (targetSegments.last == "") return ".";
     return targetSegments.last;
   }
-  List<String> path = new List<String>();
+  List<String> path = <String>[];
   int oked = same + 1;
   while (oked < refSegments.length - 1) {
     path.add("..");
diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart
index 8504ef3..f30a6cd 100644
--- a/pkg/kernel/lib/kernel.dart
+++ b/pkg/kernel/lib/kernel.dart
@@ -39,14 +39,14 @@
 }
 
 Future writeComponentToBinary(Component component, String path) {
-  var sink;
+  IOSink sink;
   if (path == 'null' || path == 'stdout') {
     sink = stdout.nonBlocking;
   } else {
     sink = new File(path).openWrite();
   }
 
-  var future;
+  Future future;
   try {
     new BinaryPrinter(sink).writeComponentFile(component);
   } finally {
diff --git a/pkg/kernel/lib/library_index.dart b/pkg/kernel/lib/library_index.dart
index 8dbb8ee..d8e36e7 100644
--- a/pkg/kernel/lib/library_index.dart
+++ b/pkg/kernel/lib/library_index.dart
@@ -22,9 +22,9 @@
 
   /// Indexes the libraries with the URIs given in [libraryUris].
   LibraryIndex(Component component, Iterable<String> libraryUris) {
-    var libraryUriSet = libraryUris.toSet();
-    for (var library in component.libraries) {
-      var uri = '${library.importUri}';
+    Set<String> libraryUriSet = libraryUris.toSet();
+    for (Library library in component.libraries) {
+      String uri = '${library.importUri}';
       if (libraryUriSet.contains(uri)) {
         _libraries[uri] = new _ClassTable(library);
       }
@@ -37,7 +37,7 @@
 
   /// Indexes `dart:` libraries.
   LibraryIndex.coreLibraries(Component component) {
-    for (var library in component.libraries) {
+    for (Library library in component.libraries) {
       if (library.importUri.scheme == 'dart') {
         _libraries['${library.importUri}'] = new _ClassTable(library);
       }
@@ -49,7 +49,7 @@
   /// Consider using another constructor to only index the libraries that
   /// are needed.
   LibraryIndex.all(Component component) {
-    for (var library in component.libraries) {
+    for (Library library in component.libraries) {
       _libraries['${library.importUri}'] = new _ClassTable(library);
     }
   }
@@ -139,10 +139,10 @@
     if (_classes == null) {
       _classes = <String, _MemberTable>{};
       _classes[LibraryIndex.topLevel] = new _MemberTable.topLevel(this);
-      for (var class_ in library.classes) {
+      for (Class class_ in library.classes) {
         _classes[class_.name] = new _MemberTable.fromClass(this, class_);
       }
-      for (var extension_ in library.extensions) {
+      for (Extension extension_ in library.extensions) {
         _classes[extension_.name] =
             new _MemberTable.fromExtension(this, extension_);
       }
@@ -163,7 +163,7 @@
   }
 
   _MemberTable _getClassIndex(String name) {
-    var indexer = classes[name];
+    _MemberTable indexer = classes[name];
     if (indexer == null) {
       throw "Class '$name' not found in $containerName";
     }
@@ -237,17 +237,20 @@
 
   String getDisambiguatedExtensionName(
       ExtensionMemberDescriptor extensionMember) {
-    if (extensionMember.kind == ExtensionMemberKind.TearOff)
+    if (extensionMember.kind == ExtensionMemberKind.TearOff) {
       return LibraryIndex.tearoffPrefix + extensionMember.name.text;
-    if (extensionMember.kind == ExtensionMemberKind.Getter)
+    }
+    if (extensionMember.kind == ExtensionMemberKind.Getter) {
       return LibraryIndex.getterPrefix + extensionMember.name.text;
-    if (extensionMember.kind == ExtensionMemberKind.Setter)
+    }
+    if (extensionMember.kind == ExtensionMemberKind.Setter) {
       return LibraryIndex.setterPrefix + extensionMember.name.text;
+    }
     return extensionMember.name.text;
   }
 
   void addExtensionMember(ExtensionMemberDescriptor extensionMember) {
-    final replacement = extensionMember.member.node;
+    final NamedNode replacement = extensionMember.member.node;
     if (replacement is! Member) return;
     Member member = replacement;
     if (member.name.isPrivate && member.name.library != library) {
@@ -256,7 +259,7 @@
       return;
     }
 
-    final name = getDisambiguatedExtensionName(extensionMember);
+    final String name = getDisambiguatedExtensionName(extensionMember);
     _members[name] = replacement;
   }
 
@@ -271,12 +274,12 @@
   }
 
   Member getMember(String name) {
-    var member = members[name];
+    Member member = members[name];
     if (member == null) {
       String message = "A member with disambiguated name '$name' was not found "
           "in $containerName";
-      var getter = LibraryIndex.getterPrefix + name;
-      var setter = LibraryIndex.setterPrefix + name;
+      String getter = LibraryIndex.getterPrefix + name;
+      String setter = LibraryIndex.setterPrefix + name;
       if (members[getter] != null || members[setter] != null) {
         throw "$message. Did you mean '$getter' or '$setter'?";
       }
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index 2eb77b3..6f8d66d 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -41,9 +41,9 @@
   @override
   void checkOverride(
       Class host, Member ownMember, Member superMember, bool isSetter) {
-    final ownMemberIsFieldOrAccessor =
+    final bool ownMemberIsFieldOrAccessor =
         ownMember is Field || (ownMember as Procedure).isAccessor;
-    final superMemberIsFieldOrAccessor =
+    final bool superMemberIsFieldOrAccessor =
         superMember is Field || (superMember as Procedure).isAccessor;
 
     // TODO: move to error reporting code
@@ -51,7 +51,7 @@
       if (m is Field) {
         return 'field';
       } else {
-        final p = m as Procedure;
+        final Procedure p = m as Procedure;
         if (p.isGetter) {
           return 'getter';
         } else if (p.isSetter) {
@@ -75,7 +75,7 @@
       if (isSetter) {
         final DartType ownType = setterType(host, ownMember);
         final DartType superType = setterType(host, superMember);
-        final isCovariant = ownMember is Field
+        final bool isCovariant = ownMember is Field
             ? ownMember.isCovariant
             : ownMember.function.positionalParameters[0].isCovariant;
         if (!_isValidParameterOverride(isCovariant, ownType, superType)) {
@@ -99,7 +99,7 @@
         }
       }
     } else {
-      final msg = _checkFunctionOverride(host, ownMember, superMember);
+      final String msg = _checkFunctionOverride(host, ownMember, superMember);
       if (msg != null) {
         return failures.reportInvalidOverride(ownMember, superMember, msg);
       }
@@ -119,7 +119,7 @@
   }
 
   Substitution _makeSubstitutionForMember(Class host, Member member) {
-    final hostType =
+    final Supertype hostType =
         hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
     return Substitution.fromSupertype(hostType);
   }
@@ -158,10 +158,11 @@
     }
 
     if (ownFunction.typeParameters.isNotEmpty) {
-      final typeParameterMap = <TypeParameter, DartType>{};
+      final Map<TypeParameter, DartType> typeParameterMap =
+          <TypeParameter, DartType>{};
       for (int i = 0; i < ownFunction.typeParameters.length; ++i) {
-        var subParameter = ownFunction.typeParameters[i];
-        var superParameter = superFunction.typeParameters[i];
+        TypeParameter subParameter = ownFunction.typeParameters[i];
+        TypeParameter superParameter = superFunction.typeParameters[i];
         typeParameterMap[subParameter] = new TypeParameterType.forAlphaRenaming(
             subParameter, superParameter);
       }
@@ -169,9 +170,9 @@
       ownSubstitution = Substitution.combine(
           ownSubstitution, Substitution.fromMap(typeParameterMap));
       for (int i = 0; i < ownFunction.typeParameters.length; ++i) {
-        var subParameter = ownFunction.typeParameters[i];
-        var superParameter = superFunction.typeParameters[i];
-        var subBound = ownSubstitution.substituteType(subParameter.bound);
+        TypeParameter subParameter = ownFunction.typeParameters[i];
+        TypeParameter superParameter = superFunction.typeParameters[i];
+        DartType subBound = ownSubstitution.substituteType(subParameter.bound);
         if (!_isSubtypeOf(
             superSubstitution.substituteType(superParameter.bound), subBound)) {
           return 'type parameters have incompatible bounds';
@@ -181,13 +182,15 @@
 
     if (!_isSubtypeOf(ownSubstitution.substituteType(ownFunction.returnType),
         superSubstitution.substituteType(superFunction.returnType))) {
-      return 'return type of override ${ownFunction.returnType} is not a subtype'
-          ' of ${superFunction.returnType}';
+      return 'return type of override ${ownFunction.returnType} is not a'
+          ' subtype of ${superFunction.returnType}';
     }
 
     for (int i = 0; i < superFunction.positionalParameters.length; ++i) {
-      final ownParameter = ownFunction.positionalParameters[i];
-      final superParameter = superFunction.positionalParameters[i];
+      final VariableDeclaration ownParameter =
+          ownFunction.positionalParameters[i];
+      final VariableDeclaration superParameter =
+          superFunction.positionalParameters[i];
       if (!_isValidParameterOverride(
           ownParameter.isCovariant,
           ownSubstitution.substituteType(ownParameter.type),
@@ -206,11 +209,13 @@
 
     // Note: FunctionNode.namedParameters are not sorted so we convert them
     // to map to make lookup faster.
-    final ownParameters = new Map<String, VariableDeclaration>.fromIterable(
-        ownFunction.namedParameters,
-        key: (v) => v.name);
+    final Map<String, VariableDeclaration> ownParameters =
+        new Map<String, VariableDeclaration>.fromIterable(
+            ownFunction.namedParameters,
+            key: (v) => v.name);
     for (VariableDeclaration superParameter in superFunction.namedParameters) {
-      final ownParameter = ownParameters[superParameter.name];
+      final VariableDeclaration ownParameter =
+          ownParameters[superParameter.name];
       if (ownParameter == null) {
         return 'override is missing ${superParameter.name} parameter';
       }
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 7c5ee41..3e152d2 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -46,9 +46,9 @@
   TypeVariableGraph(this.typeParameters, this.bounds) {
     assert(typeParameters.length == bounds.length);
 
-    vertices = new List<int>(typeParameters.length);
+    vertices = new List<int>.filled(typeParameters.length, null);
     Map<TypeParameter, int> typeParameterIndices = <TypeParameter, int>{};
-    edges = new List<List<int>>(typeParameters.length);
+    edges = new List<List<int>>.filled(typeParameters.length, null);
     for (int i = 0; i < vertices.length; i++) {
       vertices[i] = i;
       typeParameterIndices[typeParameters[i]] = i;
@@ -161,7 +161,8 @@
 /// of the algorithm for details.
 List<DartType> calculateBounds(List<TypeParameter> typeParameters,
     Class objectClass, Library contextLibrary) {
-  List<DartType> bounds = new List<DartType>(typeParameters.length);
+  List<DartType> bounds =
+      new List<DartType>.filled(typeParameters.length, null);
   for (int i = 0; i < typeParameters.length; i++) {
     DartType bound = typeParameters[i].bound;
     if (bound == null) {
@@ -236,10 +237,10 @@
     return hash;
   }
 
-  bool operator ==(dynamic other) {
+  bool operator ==(Object other) {
     assert(other is TypeArgumentIssue);
-    if (other is! TypeArgumentIssue) return false;
-    return index == other.index &&
+    return other is TypeArgumentIssue &&
+        index == other.index &&
         argument == other.argument &&
         typeParameter == other.typeParameter &&
         enclosingType == other.enclosingType;
@@ -345,7 +346,7 @@
     } else if (variables[i].bound is! InvalidType) {
       DartType bound = substitute(variables[i].bound, substitutionMap);
       if (!library.isNonNullableByDefault) {
-        bound = legacyErasure(typeEnvironment.coreTypes, bound);
+        bound = legacyErasure(bound);
       }
       if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) {
         // If the bound is InvalidType it's not checked, because an error was
@@ -438,7 +439,7 @@
   assert(bottomType == const NeverType(Nullability.nonNullable) ||
       bottomType is NullType);
   List<TypeArgumentIssue> result;
-  var substitutionMap = <TypeParameter, DartType>{};
+  Map<TypeParameter, DartType> substitutionMap = <TypeParameter, DartType>{};
   for (int i = 0; i < arguments.length; ++i) {
     substitutionMap[parameters[i]] = arguments[i];
   }
@@ -454,7 +455,7 @@
     } else if (parameters[i].bound is! InvalidType) {
       DartType bound = substitute(parameters[i].bound, substitutionMap);
       if (!library.isNonNullableByDefault) {
-        bound = legacyErasure(typeEnvironment.coreTypes, bound);
+        bound = legacyErasure(bound);
       }
       if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) {
         result ??= <TypeArgumentIssue>[];
@@ -500,7 +501,7 @@
     return typeEnvironment.coreTypes.objectLegacyRawType;
   } else if (type is InterfaceType && type.classNode.typeParameters != null) {
     List<DartType> replacedTypeArguments =
-        new List<DartType>(type.typeArguments.length);
+        new List<DartType>.filled(type.typeArguments.length, null);
     for (int i = 0; i < replacedTypeArguments.length; i++) {
       replacedTypeArguments[i] = convertSuperBoundedToRegularBounded(
           clientLibrary, typeEnvironment, type.typeArguments[i], bottomType,
@@ -510,7 +511,7 @@
         type.classNode, type.nullability, replacedTypeArguments);
   } else if (type is TypedefType && type.typedefNode.typeParameters != null) {
     List<DartType> replacedTypeArguments =
-        new List<DartType>(type.typeArguments.length);
+        new List<DartType>.filled(type.typeArguments.length, null);
     for (int i = 0; i < replacedTypeArguments.length; i++) {
       replacedTypeArguments[i] = convertSuperBoundedToRegularBounded(
           clientLibrary, typeEnvironment, type.typeArguments[i], bottomType,
@@ -519,11 +520,11 @@
     return new TypedefType(
         type.typedefNode, type.nullability, replacedTypeArguments);
   } else if (type is FunctionType) {
-    var replacedReturnType = convertSuperBoundedToRegularBounded(
+    DartType replacedReturnType = convertSuperBoundedToRegularBounded(
         clientLibrary, typeEnvironment, type.returnType, bottomType,
         isCovariant: isCovariant);
-    var replacedPositionalParameters =
-        new List<DartType>(type.positionalParameters.length);
+    List<DartType> replacedPositionalParameters =
+        new List<DartType>.filled(type.positionalParameters.length, null);
     for (int i = 0; i < replacedPositionalParameters.length; i++) {
       replacedPositionalParameters[i] = convertSuperBoundedToRegularBounded(
           clientLibrary,
@@ -532,8 +533,8 @@
           bottomType,
           isCovariant: !isCovariant);
     }
-    var replacedNamedParameters =
-        new List<NamedType>(type.namedParameters.length);
+    List<NamedType> replacedNamedParameters =
+        new List<NamedType>.filled(type.namedParameters.length, null);
     for (int i = 0; i < replacedNamedParameters.length; i++) {
       replacedNamedParameters[i] = new NamedType(
           type.namedParameters[i].name,
diff --git a/pkg/kernel/lib/src/legacy_erasure.dart b/pkg/kernel/lib/src/legacy_erasure.dart
index 83c32ce..3628368 100644
--- a/pkg/kernel/lib/src/legacy_erasure.dart
+++ b/pkg/kernel/lib/src/legacy_erasure.dart
@@ -3,15 +3,14 @@
 // BSD-style license that can be found in the LICENSE.md file.
 
 import '../ast.dart' hide MapEntry;
-import '../core_types.dart';
 
 import 'replacement_visitor.dart';
 
 /// Returns legacy erasure of [type], that is, the type in which all nnbd
 /// nullabilities have been replaced with legacy nullability, and all required
 /// named parameters are not required.
-DartType legacyErasure(CoreTypes coreTypes, DartType type) {
-  return rawLegacyErasure(coreTypes, type) ?? type;
+DartType legacyErasure(DartType type) {
+  return rawLegacyErasure(type) ?? type;
 }
 
 /// Returns legacy erasure of [type], that is, the type in which all nnbd
@@ -19,22 +18,21 @@
 /// named parameters are not required.
 ///
 /// Returns `null` if the type wasn't changed.
-DartType rawLegacyErasure(CoreTypes coreTypes, DartType type) {
-  return type.accept(new _LegacyErasure(coreTypes));
+DartType rawLegacyErasure(DartType type) {
+  return type.accept(const _LegacyErasure());
 }
 
 /// Returns legacy erasure of [supertype], that is, the type in which all nnbd
 /// nullabilities have been replaced with legacy nullability, and all required
 /// named parameters are not required.
-Supertype legacyErasureSupertype(CoreTypes coreTypes, Supertype supertype) {
+Supertype legacyErasureSupertype(Supertype supertype) {
   if (supertype.typeArguments.isEmpty) {
     return supertype;
   }
   List<DartType> newTypeArguments;
   for (int i = 0; i < supertype.typeArguments.length; i++) {
     DartType typeArgument = supertype.typeArguments[i];
-    DartType newTypeArgument =
-        typeArgument.accept(new _LegacyErasure(coreTypes));
+    DartType newTypeArgument = typeArgument.accept(const _LegacyErasure());
     if (newTypeArgument != null) {
       newTypeArguments ??= supertype.typeArguments.toList(growable: false);
       newTypeArguments[i] = newTypeArgument;
@@ -51,9 +49,7 @@
 ///
 /// The visitor returns `null` if the type wasn't changed.
 class _LegacyErasure extends ReplacementVisitor {
-  final CoreTypes coreTypes;
-
-  _LegacyErasure(this.coreTypes);
+  const _LegacyErasure();
 
   Nullability visitNullability(DartType node) {
     if (node.declaredNullability != Nullability.legacy) {
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index 4b1e68b..62eb99a 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -35,7 +35,7 @@
     assert(a.namedParameters.length == b.namedParameters.length);
 
     List<TypeParameter> newTypeParameters =
-        new List<TypeParameter>(a.typeParameters.length);
+        new List<TypeParameter>.filled(a.typeParameters.length, null);
     for (int i = 0; i < a.typeParameters.length; i++) {
       TypeParameter aTypeParameter = a.typeParameters[i];
       TypeParameter bTypeParameter = b.typeParameters[i];
@@ -56,7 +56,7 @@
 
     if (newTypeParameters.isNotEmpty) {
       List<TypeParameterType> aTypeParameterTypes =
-          new List<TypeParameterType>(newTypeParameters.length);
+          new List<TypeParameterType>.filled(newTypeParameters.length, null);
       for (int i = 0; i < newTypeParameters.length; i++) {
         aTypeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
             a.typeParameters[i], newTypeParameters[i]);
@@ -64,7 +64,7 @@
       aSubstitution =
           Substitution.fromPairs(a.typeParameters, aTypeParameterTypes);
       List<TypeParameterType> bTypeParameterTypes =
-          new List<TypeParameterType>(newTypeParameters.length);
+          new List<TypeParameterType>.filled(newTypeParameters.length, null);
       for (int i = 0; i < newTypeParameters.length; i++) {
         bTypeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
             b.typeParameters[i], newTypeParameters[i]);
@@ -91,7 +91,7 @@
     DartType newReturnType = mergeTypes(a.returnType, b.returnType);
     if (newReturnType == null) return null;
     List<DartType> newPositionalParameters =
-        new List<DartType>(a.positionalParameters.length);
+        new List<DartType>.filled(a.positionalParameters.length, null);
     for (int i = 0; i < a.positionalParameters.length; i++) {
       DartType newType =
           mergeTypes(a.positionalParameters[i], b.positionalParameters[i]);
@@ -101,7 +101,7 @@
       newPositionalParameters[i] = newType;
     }
     List<NamedType> newNamedParameters =
-        new List<NamedType>(a.namedParameters.length);
+        new List<NamedType>.filled(a.namedParameters.length, null);
     for (int i = 0; i < a.namedParameters.length; i++) {
       DartType newType =
           mergeTypes(a.namedParameters[i].type, b.namedParameters[i].type);
@@ -157,7 +157,7 @@
       return new InterfaceType(a.classNode, nullability);
     }
     List<DartType> newTypeArguments =
-        new List<DartType>(a.typeArguments.length);
+        new List<DartType>.filled(a.typeArguments.length, null);
     for (int i = 0; i < a.typeArguments.length; i++) {
       DartType newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
       if (newType == null) {
@@ -283,10 +283,11 @@
       TypedefType a, TypedefType b, Nullability nullability) {
     assert(a.typedefNode == b.typedefNode);
     assert(a.typeArguments.length == b.typeArguments.length);
-    if (a.typeArguments.isEmpty)
+    if (a.typeArguments.isEmpty) {
       return new TypedefType(a.typedefNode, nullability);
+    }
     List<DartType> newTypeArguments =
-        new List<DartType>(a.typeArguments.length);
+        new List<DartType>.filled(a.typeArguments.length, null);
     for (int i = 0; i < a.typeArguments.length; i++) {
       DartType newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
       if (newType == null) return null;
diff --git a/pkg/kernel/lib/src/nnbd_top_merge.dart b/pkg/kernel/lib/src/nnbd_top_merge.dart
index 5b3634a..9a56df4 100644
--- a/pkg/kernel/lib/src/nnbd_top_merge.dart
+++ b/pkg/kernel/lib/src/nnbd_top_merge.dart
@@ -14,7 +14,8 @@
   if (a.typeArguments.isEmpty) {
     return a;
   }
-  List<DartType> newTypeArguments = new List<DartType>(a.typeArguments.length);
+  List<DartType> newTypeArguments =
+      new List<DartType>.filled(a.typeArguments.length, null);
   for (int i = 0; i < a.typeArguments.length; i++) {
     DartType newTypeArgument =
         nnbdTopMerge(coreTypes, a.typeArguments[i], b.typeArguments[i]);
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index 5aea426..9550e18 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -35,7 +35,7 @@
     Substitution substitution;
     if (newTypeParameters != null) {
       List<TypeParameterType> typeParameterTypes =
-          new List<TypeParameterType>(newTypeParameters.length);
+          new List<TypeParameterType>.filled(newTypeParameters.length, null);
       for (int i = 0; i < newTypeParameters.length; i++) {
         typeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
             node.typeParameters[i], newTypeParameters[i]);
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index 64a1755..d622437 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -271,9 +271,7 @@
           type1, type2, clientLibrary);
     }
     return _getNullabilityObliviousStandardLowerBound(
-        legacyErasure(coreTypes, type1),
-        legacyErasure(coreTypes, type2),
-        clientLibrary);
+        legacyErasure(type1), legacyErasure(type2), clientLibrary);
   }
 
   DartType _getNullabilityAwareStandardLowerBound(
@@ -594,9 +592,7 @@
           type1, type2, clientLibrary);
     }
     return _getNullabilityObliviousStandardUpperBound(
-        legacyErasure(coreTypes, type1),
-        legacyErasure(coreTypes, type2),
-        clientLibrary);
+        legacyErasure(type1), legacyErasure(type2), clientLibrary);
   }
 
   DartType _getNullabilityAwareStandardUpperBound(
@@ -798,7 +794,7 @@
         int n = klass.typeParameters.length;
         List<DartType> leftArguments = type1.typeArguments;
         List<DartType> rightArguments = type2.typeArguments;
-        List<DartType> typeArguments = new List<DartType>(n);
+        List<DartType> typeArguments = new List<DartType>.filled(n, null);
         for (int i = 0; i < n; ++i) {
           int variance = klass.typeParameters[i].variance;
           if (variance == Variance.contravariant) {
@@ -1371,7 +1367,8 @@
     // Calculate the SUB of each corresponding pair of parameters.
     int totalPositional =
         math.max(f.positionalParameters.length, g.positionalParameters.length);
-    List<DartType> positionalParameters = new List<DartType>(totalPositional);
+    List<DartType> positionalParameters =
+        new List<DartType>.filled(totalPositional, null);
     for (int i = 0; i < totalPositional; i++) {
       if (i < f.positionalParameters.length) {
         DartType fType = f.positionalParameters[i];
@@ -1474,7 +1471,8 @@
     // other.
     int totalPositional =
         math.min(f.positionalParameters.length, g.positionalParameters.length);
-    List<DartType> positionalParameters = new List<DartType>(totalPositional);
+    List<DartType> positionalParameters =
+        new List<DartType>.filled(totalPositional, null);
     for (int i = 0; i < totalPositional; i++) {
       positionalParameters[i] = getStandardLowerBound(
           f.positionalParameters[i], g.positionalParameters[i], clientLibrary);
@@ -1553,7 +1551,7 @@
 
       assert(tArgs1.length == tArgs2.length);
       assert(tArgs1.length == tParams.length);
-      List<DartType> tArgs = new List(tArgs1.length);
+      List<DartType> tArgs = new List.filled(tArgs1.length, null);
       for (int i = 0; i < tArgs1.length; i++) {
         if (tParams[i].variance == Variance.contravariant) {
           tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i], clientLibrary);
diff --git a/pkg/kernel/lib/src/tool/batch_util.dart b/pkg/kernel/lib/src/tool/batch_util.dart
index c3cccb6..9412c80 100644
--- a/pkg/kernel/lib/src/tool/batch_util.dart
+++ b/pkg/kernel/lib/src/tool/batch_util.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 library kernel.batch_util;
 
-import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
@@ -22,7 +21,7 @@
 Future runBatch(BatchCallback callback) async {
   int totalTests = 0;
   int testsFailed = 0;
-  var watch = new Stopwatch()..start();
+  Stopwatch watch = new Stopwatch()..start();
   print('>>> BATCH START');
   Stream input = stdin.transform(utf8.decoder).transform(new LineSplitter());
   await for (String line in input) {
@@ -33,9 +32,9 @@
       break;
     }
     ++totalTests;
-    var arguments = line.split(new RegExp(r'\s+'));
+    List<String> arguments = line.split(new RegExp(r'\s+'));
     try {
-      var outcome = await callback(arguments);
+      CompilerOutcome outcome = await callback(arguments);
       stderr.writeln('>>> EOF STDERR');
       if (outcome == CompilerOutcome.Ok) {
         print('>>> TEST PASS ${watch.elapsedMilliseconds}ms');
diff --git a/pkg/kernel/lib/src/tool/command_line_util.dart b/pkg/kernel/lib/src/tool/command_line_util.dart
index d6f3f61..1abadb2 100644
--- a/pkg/kernel/lib/src/tool/command_line_util.dart
+++ b/pkg/kernel/lib/src/tool/command_line_util.dart
@@ -19,8 +19,8 @@
   static requireVariableArgumentCount(
       List<int> ok, List<String> args, void Function() usage) {
     if (!ok.contains(args.length)) {
-      print(
-          "Expected the argument count to be one of ${ok}, got ${args.length}.");
+      print("Expected the argument count to be one of ${ok}, got "
+          "${args.length}.");
       usage();
     }
   }
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 93ea3c9..be01ba0 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -13,7 +13,7 @@
 
 class TargetFlags {
   final bool trackWidgetCreation;
-  final bool forceLateLoweringForTesting;
+  final int forceLateLoweringsForTesting;
   final bool forceLateLoweringSentinelForTesting;
   final bool forceStaticFieldLoweringForTesting;
   final bool forceNoExplicitGetterCallsForTesting;
@@ -21,7 +21,7 @@
 
   const TargetFlags(
       {this.trackWidgetCreation = false,
-      this.forceLateLoweringForTesting = false,
+      this.forceLateLoweringsForTesting = LateLowering.none,
       this.forceLateLoweringSentinelForTesting = false,
       this.forceStaticFieldLoweringForTesting = false,
       this.forceNoExplicitGetterCallsForTesting = false,
@@ -31,7 +31,7 @@
     if (identical(this, other)) return true;
     return other is TargetFlags &&
         trackWidgetCreation == other.trackWidgetCreation &&
-        forceLateLoweringForTesting == other.forceLateLoweringForTesting &&
+        forceLateLoweringsForTesting == other.forceLateLoweringsForTesting &&
         forceLateLoweringSentinelForTesting ==
             other.forceLateLoweringSentinelForTesting &&
         forceStaticFieldLoweringForTesting ==
@@ -45,7 +45,7 @@
     int hash = 485786;
     hash = 0x3fffffff & (hash * 31 + (hash ^ trackWidgetCreation.hashCode));
     hash = 0x3fffffff &
-        (hash * 31 + (hash ^ forceLateLoweringForTesting.hashCode));
+        (hash * 31 + (hash ^ forceLateLoweringsForTesting.hashCode));
     hash = 0x3fffffff &
         (hash * 31 + (hash ^ forceLateLoweringSentinelForTesting.hashCode));
     hash = 0x3fffffff &
@@ -90,12 +90,42 @@
   /// Lowering of a list constant to a backend-specific representation.
   Constant lowerListConstant(ListConstant constant) => constant;
 
+  /// Returns `true` if [constant] is lowered list constant created by
+  /// [lowerListConstant].
+  bool isLoweredListConstant(Constant constant) => false;
+
+  /// Calls `f` for each element in the lowered list [constant].
+  ///
+  /// This assumes that `isLoweredListConstant(constant)` is true.
+  void forEachLoweredListConstantElement(
+      Constant constant, void Function(Constant element) f) {}
+
   /// Lowering of a set constant to a backend-specific representation.
   Constant lowerSetConstant(SetConstant constant) => constant;
 
+  /// Returns `true` if [constant] is lowered set constant created by
+  /// [lowerSetConstant].
+  bool isLoweredSetConstant(Constant constant) => false;
+
+  /// Calls `f` for each element in the lowered set [constant].
+  ///
+  /// This assumes that `isLoweredSetConstant(constant)` is true.
+  void forEachLoweredSetConstantElement(
+      Constant constant, void Function(Constant element) f) {}
+
   /// Lowering of a map constant to a backend-specific representation.
   Constant lowerMapConstant(MapConstant constant) => constant;
 
+  /// Returns `true` if [constant] is lowered map constant created by
+  /// [lowerMapConstant].
+  bool isLoweredMapConstant(Constant constant) => false;
+
+  /// Calls `f` for each key/value pair in the lowered map [constant].
+  ///
+  /// This assumes that `lowerMapConstant(constant)` is true.
+  void forEachLoweredMapConstantEntry(
+      Constant constant, void Function(Constant key, Constant value) f) {}
+
   /// Number semantics to use for this backend.
   NumberSemantics get numberSemantics => NumberSemantics.vm;
 
@@ -281,12 +311,43 @@
   /// literals (for const set literals).
   bool get supportsSetLiterals => true;
 
-  /// Whether late fields and variable are support by this target.
+  /// Bit mask of [LateLowering] values for the late lowerings that should
+  /// be performed by the CFE.
   ///
-  /// If `false`, late fields and variables are lowered fields, getter, setters
-  /// etc. that provide equivalent semantics. See `pkg/kernel/nnbd_api.md` for
-  /// details.
-  bool get supportsLateFields;
+  /// For the selected lowerings, late fields and variables are encoded using
+  /// fields, getter, setters etc. in a way that provide equivalent semantics.
+  /// See `pkg/kernel/nnbd_api.md` for details.
+  int get enabledLateLowerings;
+
+  /// Returns `true` if the CFE should lower a late field given it
+  /// [hasInitializer], [isFinal], and [isStatic].
+  ///
+  /// This is determined by the [enabledLateLowerings] mask.
+  bool isLateFieldLoweringEnabled(
+      {bool hasInitializer, bool isFinal, bool isStatic}) {
+    assert(hasInitializer != null);
+    assert(isFinal != null);
+    assert(isStatic != null);
+    int mask = LateLowering.getFieldLowering(
+        hasInitializer: hasInitializer, isFinal: isFinal, isStatic: isStatic);
+    return enabledLateLowerings & mask != 0;
+  }
+
+  /// Returns `true` if the CFE should lower a late local variable given it
+  /// [hasInitializer], [isFinal], and its type [isPotentiallyNullable].
+  ///
+  /// This is determined by the [enabledLateLowerings] mask.
+  bool isLateLocalLoweringEnabled(
+      {bool hasInitializer, bool isFinal, bool isPotentiallyNullable}) {
+    assert(hasInitializer != null);
+    assert(isFinal != null);
+    assert(isPotentiallyNullable != null);
+    int mask = LateLowering.getLocalLowering(
+        hasInitializer: hasInitializer,
+        isFinal: isFinal,
+        isPotentiallyNullable: isPotentiallyNullable);
+    return enabledLateLowerings & mask != 0;
+  }
 
   /// If `true`, the backend supports creation and checking of a sentinel value
   /// for uninitialized late fields and variables through the `createSentinel`
@@ -359,7 +420,7 @@
   NoneTarget(this.flags);
 
   @override
-  bool get supportsLateFields => !flags.forceLateLoweringForTesting;
+  int get enabledLateLowerings => flags.forceLateLoweringsForTesting;
 
   @override
   bool get supportsLateLoweringSentinel =>
@@ -417,3 +478,97 @@
       // TODO(johnniwinther): Should this vary with the use case?
       const NoneConstantsBackend(supportsUnevaluatedConstants: true);
 }
+
+class LateLowering {
+  static const int nullableUninitializedNonFinalLocal = 1 << 0;
+  static const int nonNullableUninitializedNonFinalLocal = 1 << 1;
+  static const int nullableUninitializedFinalLocal = 1 << 2;
+  static const int nonNullableUninitializedFinalLocal = 1 << 3;
+  static const int nullableInitializedNonFinalLocal = 1 << 4;
+  static const int nonNullableInitializedNonFinalLocal = 1 << 5;
+  static const int nullableInitializedFinalLocal = 1 << 6;
+  static const int nonNullableInitializedFinalLocal = 1 << 7;
+  static const int uninitializedNonFinalStaticField = 1 << 8;
+  static const int uninitializedFinalStaticField = 1 << 9;
+  static const int initializedNonFinalStaticField = 1 << 10;
+  static const int initializedFinalStaticField = 1 << 11;
+  static const int uninitializedNonFinalInstanceField = 1 << 12;
+  static const int uninitializedFinalInstanceField = 1 << 13;
+  static const int initializedNonFinalInstanceField = 1 << 14;
+  static const int initializedFinalInstanceField = 1 << 15;
+
+  static const int none = 0;
+  static const int all = (1 << 16) - 1;
+
+  static int getLocalLowering(
+      {bool hasInitializer, bool isFinal, bool isPotentiallyNullable}) {
+    assert(hasInitializer != null);
+    assert(isFinal != null);
+    assert(isPotentiallyNullable != null);
+    if (hasInitializer) {
+      if (isFinal) {
+        if (isPotentiallyNullable) {
+          return nullableInitializedFinalLocal;
+        } else {
+          return nonNullableInitializedFinalLocal;
+        }
+      } else {
+        if (isPotentiallyNullable) {
+          return nullableInitializedNonFinalLocal;
+        } else {
+          return nonNullableInitializedNonFinalLocal;
+        }
+      }
+    } else {
+      if (isFinal) {
+        if (isPotentiallyNullable) {
+          return nullableUninitializedFinalLocal;
+        } else {
+          return nonNullableUninitializedFinalLocal;
+        }
+      } else {
+        if (isPotentiallyNullable) {
+          return nullableUninitializedNonFinalLocal;
+        } else {
+          return nonNullableUninitializedNonFinalLocal;
+        }
+      }
+    }
+  }
+
+  static int getFieldLowering(
+      {bool hasInitializer, bool isFinal, bool isStatic}) {
+    assert(hasInitializer != null);
+    assert(isFinal != null);
+    assert(isStatic != null);
+    if (hasInitializer) {
+      if (isFinal) {
+        if (isStatic) {
+          return initializedFinalStaticField;
+        } else {
+          return initializedFinalInstanceField;
+        }
+      } else {
+        if (isStatic) {
+          return initializedNonFinalStaticField;
+        } else {
+          return initializedNonFinalInstanceField;
+        }
+      }
+    } else {
+      if (isFinal) {
+        if (isStatic) {
+          return uninitializedFinalStaticField;
+        } else {
+          return uninitializedFinalInstanceField;
+        }
+      } else {
+        if (isStatic) {
+          return uninitializedNonFinalStaticField;
+        } else {
+          return uninitializedNonFinalInstanceField;
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/kernel/lib/testing/mock_sdk_component.dart b/pkg/kernel/lib/testing/mock_sdk_component.dart
index 02ee6c8..180ad92 100644
--- a/pkg/kernel/lib/testing/mock_sdk_component.dart
+++ b/pkg/kernel/lib/testing/mock_sdk_component.dart
@@ -4,11 +4,12 @@
 
 import 'package:kernel/ast.dart';
 
-/// Returns a [Component] object containing empty definitions of core SDK classes.
+/// Returns a [Component] object containing empty definitions of core SDK
+/// classes.
 Component createMockSdkComponent() {
-  var coreLib = new Library(Uri.parse('dart:core'), name: 'dart.core');
-  var asyncLib = new Library(Uri.parse('dart:async'), name: 'dart.async');
-  var internalLib =
+  Library coreLib = new Library(Uri.parse('dart:core'), name: 'dart.core');
+  Library asyncLib = new Library(Uri.parse('dart:async'), name: 'dart.async');
+  Library internalLib =
       new Library(Uri.parse('dart:_internal'), name: 'dart._internal');
 
   Class addClass(Library lib, Class c) {
@@ -16,8 +17,9 @@
     return c;
   }
 
-  var objectClass = addClass(coreLib, new Class(name: 'Object'));
-  var objectType = new InterfaceType(objectClass, coreLib.nonNullable);
+  Class objectClass = addClass(coreLib, new Class(name: 'Object'));
+  InterfaceType objectType =
+      new InterfaceType(objectClass, coreLib.nonNullable);
 
   TypeParameter typeParam(String name, [DartType bound]) {
     return new TypeParameter(name, bound ?? objectType);
@@ -36,12 +38,12 @@
 
   addClass(coreLib, class_('Null'));
   addClass(coreLib, class_('bool'));
-  var num = addClass(coreLib, class_('num'));
+  Class num = addClass(coreLib, class_('num'));
   addClass(coreLib, class_('String'));
-  var iterable =
+  Class iterable =
       addClass(coreLib, class_('Iterable', typeParameters: [typeParam('T')]));
   {
-    var T = typeParam('T');
+    TypeParameter T = typeParam('T');
     addClass(
         coreLib,
         class_('List', typeParameters: [
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 8989064..40484e6 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -98,36 +98,60 @@
 
   TypeParserEnvironment _libraryEnvironment;
 
-  Env(String source) {
+  final bool isNonNullableByDefault;
+
+  Env(String source, {this.isNonNullableByDefault}) {
+    assert(isNonNullableByDefault != null);
     Uri libraryUri = Uri.parse('memory:main.dart');
     Uri coreUri = Uri.parse("dart:core");
     TypeParserEnvironment coreEnvironment =
         new TypeParserEnvironment(coreUri, coreUri);
     Library coreLibrary =
-        parseLibrary(coreUri, mockSdk, environment: coreEnvironment);
+        parseLibrary(coreUri, mockSdk, environment: coreEnvironment)
+          ..isNonNullableByDefault = isNonNullableByDefault;
     _libraryEnvironment = new TypeParserEnvironment(libraryUri, libraryUri)
         ._extend(coreEnvironment._declarations);
     Library library =
-        parseLibrary(libraryUri, source, environment: _libraryEnvironment);
+        parseLibrary(libraryUri, source, environment: _libraryEnvironment)
+          ..isNonNullableByDefault = isNonNullableByDefault;
     library.name = "lib";
     component = new Component(libraries: <Library>[coreLibrary, library]);
     coreTypes = new CoreTypes(component);
   }
 
-  DartType parseType(String text) {
-    return _libraryEnvironment.parseType(text);
+  DartType parseType(String text,
+      {Map<String, DartType Function()> additionalTypes}) {
+    return _libraryEnvironment.parseType(text,
+        additionalTypes: additionalTypes);
   }
 
-  void extendWithTypeParameters(String typeParameters) {
-    _libraryEnvironment =
-        _libraryEnvironment.extendWithTypeParameters(typeParameters);
+  List<DartType> parseTypes(String text,
+      {Map<String, DartType Function()> additionalTypes}) {
+    return _libraryEnvironment.parseTypes(text,
+        additionalTypes: additionalTypes);
   }
 
-  void withTypeParameters(String typeParameters, void Function() f) {
-    TypeParserEnvironment oldLibraryEnvironment = _libraryEnvironment;
-    extendWithTypeParameters(typeParameters);
-    f();
-    _libraryEnvironment = oldLibraryEnvironment;
+  List<TypeParameter> extendWithTypeParameters(String typeParameters) {
+    if (typeParameters == null || typeParameters.isEmpty) {
+      return <TypeParameter>[];
+    }
+    ParameterEnvironment parameterEnvironment =
+        _libraryEnvironment.extendToParameterEnvironment(typeParameters);
+    _libraryEnvironment = parameterEnvironment.environment;
+    return parameterEnvironment.parameters;
+  }
+
+  void withTypeParameters(
+      String typeParameters, void Function(List<TypeParameter>) f) {
+    if (typeParameters == null || typeParameters.isEmpty) {
+      f(<TypeParameter>[]);
+    } else {
+      TypeParserEnvironment oldLibraryEnvironment = _libraryEnvironment;
+      List<TypeParameter> typeParameterNodes =
+          extendWithTypeParameters(typeParameters);
+      f(typeParameterNodes);
+      _libraryEnvironment = oldLibraryEnvironment;
+    }
   }
 }
 
@@ -154,13 +178,26 @@
 
   TypeParserEnvironment(this.uri, this.fileUri, [this._parent]);
 
-  Node _kernelFromParsedType(ParsedType type) {
-    Node node = type.accept(const _KernelFromParsedType(), this);
+  Node _kernelFromParsedType(ParsedType type,
+      {Map<String, DartType Function()> additionalTypes}) {
+    Node node = type.accept(
+        new _KernelFromParsedType(additionalTypes: additionalTypes), this);
     return node;
   }
 
-  DartType parseType(String text) {
-    return _kernelFromParsedType(type_parser.parse(text).single);
+  /// Parses a single type.
+  DartType parseType(String text,
+      {Map<String, DartType Function()> additionalTypes}) {
+    return _kernelFromParsedType(type_parser.parse(text).single,
+        additionalTypes: additionalTypes);
+  }
+
+  /// Parses a list of types separated by commas.
+  List<DartType> parseTypes(String text,
+      {Map<String, DartType Function()> additionalTypes}) {
+    return (parseType("(${text}) -> void", additionalTypes: additionalTypes)
+            as FunctionType)
+        .positionalParameters;
   }
 
   bool isObject(String name) => name == "Object" && "$uri" == "dart:core";
@@ -191,10 +228,13 @@
 
   TypeParserEnvironment extendWithTypeParameters(String typeParameters) {
     if (typeParameters?.isEmpty ?? true) return this;
-    return const _KernelFromParsedType()
-        .computeTypeParameterEnvironment(
-            parseTypeVariables("<${typeParameters}>"), this)
-        .environment;
+    return extendToParameterEnvironment(typeParameters).environment;
+  }
+
+  ParameterEnvironment extendToParameterEnvironment(String typeParameters) {
+    assert(typeParameters != null && typeParameters.isNotEmpty);
+    return const _KernelFromParsedType().computeTypeParameterEnvironment(
+        parseTypeVariables("<${typeParameters}>"), this);
   }
 
   /// Returns the predefined type by the [name], if any.
@@ -209,7 +249,9 @@
 }
 
 class _KernelFromParsedType implements Visitor<Node, TypeParserEnvironment> {
-  const _KernelFromParsedType();
+  final Map<String, DartType Function()> additionalTypes; // Can be null.
+
+  const _KernelFromParsedType({this.additionalTypes});
 
   DartType visitInterfaceType(
       ParsedInterfaceType node, TypeParserEnvironment environment) {
@@ -237,6 +279,8 @@
       // Don't return a const object to ensure we test implementations that use
       // identical.
       return new NullType();
+    } else if (additionalTypes != null && additionalTypes.containsKey(name)) {
+      return additionalTypes[name].call();
     }
     TreeNode declaration = environment.lookupDeclaration(name);
     List<ParsedType> arguments = node.arguments;
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index e05a4b6..b9d95ab 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -44,7 +44,7 @@
       //
       if (constant is InstanceConstant) {
         // Avoid visiting `InstanceConstant.classReference`.
-        for (final value in constant.fieldValues.values) {
+        for (final Constant value in constant.fieldValues.values) {
           // Name everything in post-order visit of DAG.
           getName(value);
         }
@@ -76,8 +76,8 @@
   final Set<String> usedNames = new Set<String>();
 
   String disambiguate(T key1, U key2, String proposeName()) {
-    getNewName() {
-      var proposedName = proposeName();
+    String getNewName() {
+      String proposedName = proposeName();
       if (usedNames.add(proposedName)) return proposedName;
       int i = 2;
       while (!usedNames.add('$proposedName$i')) {
@@ -209,13 +209,13 @@
 
   final RegExp pathSeparator = new RegExp('[\\/]');
 
-  nameLibraryPrefix(Library node, {String proposedName}) {
+  String nameLibraryPrefix(Library node, {String proposedName}) {
     return prefixes.disambiguate(node.reference, node.reference.canonicalName,
         () {
       if (proposedName != null) return proposedName;
       if (node.name != null) return abbreviateName(node.name);
       if (node.importUri != null) {
-        var path = node.importUri.hasEmptyPath
+        String path = node.importUri.hasEmptyPath
             ? '${node.importUri}'
             : node.importUri.pathSegments.last;
         if (path.endsWith('.dart')) {
@@ -233,7 +233,7 @@
       if (proposedName != null) return proposedName;
       CanonicalName canonicalName = name ?? node.canonicalName;
       if (canonicalName?.name != null) {
-        var path = canonicalName.name;
+        String path = canonicalName.name;
         int slash = path.lastIndexOf(pathSeparator);
         if (slash >= 0) {
           path = path.substring(slash + 1);
@@ -436,14 +436,14 @@
   }
 
   void printLibraryImportTable(LibraryImportTable imports) {
-    for (var library in imports.importedLibraries) {
-      var importPath = imports.getImportPath(library);
+    for (Library library in imports.importedLibraries) {
+      String importPath = imports.getImportPath(library);
       if (importPath == "") {
-        var prefix =
+        String prefix =
             syntheticNames.nameLibraryPrefix(library, proposedName: 'self');
         endLine('import self as $prefix;');
       } else {
-        var prefix = syntheticNames.nameLibraryPrefix(library);
+        String prefix = syntheticNames.nameLibraryPrefix(library);
         endLine('import "$importPath" as $prefix;');
       }
     }
@@ -476,7 +476,7 @@
     write('additionalExports = (');
     for (int i = 0; i < additionalExports.length; i++) {
       Reference reference = additionalExports[i];
-      var node = reference.node;
+      NamedNode node = reference.node;
       if (node is Class) {
         Library nodeLibrary = node.enclosingLibrary;
         String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
@@ -514,7 +514,7 @@
 
   void writeComponentFile(Component component) {
     ImportTable imports = new ComponentImportTable(component);
-    var inner = createInner(imports, component.metadata);
+    Printer inner = createInner(imports, component.metadata);
     writeWord('main');
     writeSpaced('=');
     inner.writeMemberReferenceFromReference(component.mainMethodName);
@@ -523,7 +523,7 @@
       inner.writeMetadata(component);
     }
     writeComponentProblems(component);
-    for (var library in component.libraries) {
+    for (Library library in component.libraries) {
       if (showMetadata) {
         inner.writeMetadata(library);
       }
@@ -536,7 +536,7 @@
         writeSpaced('from');
         writeWord('"${library.importUri}"');
       }
-      var prefix = syntheticNames.nameLibraryPrefix(library);
+      String prefix = syntheticNames.nameLibraryPrefix(library);
       writeSpaced('as');
       writeWord(prefix);
       endLine(' {');
@@ -552,7 +552,7 @@
   void writeConstantTable(Component component) {
     if (syntheticNames.constants.map.isEmpty) return;
     ImportTable imports = new ComponentImportTable(component);
-    var inner = createInner(imports, component.metadata);
+    Printer inner = createInner(imports, component.metadata);
     writeWord('constants ');
     endLine(' {');
     ++inner.indentation;
@@ -619,7 +619,7 @@
     if (node == null) {
       writeSymbol("<Null>");
     } else {
-      final highlight = shouldHighlight(node);
+      final bool highlight = shouldHighlight(node);
       if (highlight) {
         startHighlight(node);
       }
@@ -647,8 +647,8 @@
 
   void writeMetadata(TreeNode node) {
     if (metadata != null) {
-      for (var md in metadata.values) {
-        final nodeMetadata = md.mapping[node];
+      for (MetadataRepository<Object> md in metadata.values) {
+        final Object nodeMetadata = md.mapping[node];
         if (nodeMetadata != null) {
           writeWord("[@${md.tag}=${nodeMetadata}]");
         }
@@ -931,7 +931,7 @@
   void writeList<T>(Iterable<T> nodes, void callback(T x),
       {String separator: ','}) {
     bool first = true;
-    for (var node in nodes) {
+    for (T node in nodes) {
       if (first) {
         first = false;
       } else {
@@ -948,8 +948,9 @@
   String getClassReferenceFromReference(Reference reference) {
     if (reference == null) return '<No Class>';
     if (reference.node != null) return getClassReference(reference.asClass);
-    if (reference.canonicalName != null)
+    if (reference.canonicalName != null) {
       return getCanonicalNameString(reference.canonicalName);
+    }
     throw "Neither node nor canonical name found";
   }
 
@@ -960,8 +961,9 @@
   String getMemberReferenceFromReference(Reference reference) {
     if (reference == null) return '<No Member>';
     if (reference.node != null) return getMemberReference(reference.asMember);
-    if (reference.canonicalName != null)
+    if (reference.canonicalName != null) {
       return getCanonicalNameString(reference.canonicalName);
+    }
     throw "Neither node nor canonical name found";
   }
 
@@ -969,21 +971,24 @@
     if (name.isRoot) throw 'unexpected root';
     if (name.name.startsWith('@')) throw 'unexpected @';
 
-    libraryString(CanonicalName lib) {
-      if (lib.reference?.node != null)
+    String libraryString(CanonicalName lib) {
+      if (lib.reference?.node != null) {
         return getLibraryReference(lib.reference.asLibrary);
+      }
       return syntheticNames.nameCanonicalNameAsLibraryPrefix(
           lib.reference, lib);
     }
 
-    classString(CanonicalName cls) =>
+    String classString(CanonicalName cls) =>
         libraryString(cls.parent) + '::' + cls.name;
 
     if (name.parent.isRoot) return libraryString(name);
     if (name.parent.parent.isRoot) return classString(name);
 
     CanonicalName atNode = name.parent;
-    while (!atNode.name.startsWith('@')) atNode = atNode.parent;
+    while (!atNode.name.startsWith('@')) {
+      atNode = atNode.parent;
+    }
 
     String parent = "";
     if (atNode.parent.parent.isRoot) {
@@ -1001,7 +1006,7 @@
   }
 
   void writeVariableReference(VariableDeclaration variable) {
-    final highlight = shouldHighlight(variable);
+    final bool highlight = shouldHighlight(variable);
     if (highlight) {
       startHighlight(variable);
     }
@@ -1016,7 +1021,7 @@
   }
 
   void writeExpression(Expression node, [int minimumPrecedence]) {
-    final highlight = shouldHighlight(node);
+    final bool highlight = shouldHighlight(node);
     if (highlight) {
       startHighlight(node);
     }
@@ -1097,7 +1102,7 @@
       if (node.isNonNullableByDefault) {
         features.add("isNonNullableByDefault");
       } else {
-        features.add("isNullableByDefault");
+        features.add("isLegacy");
       }
     }
     if ((node.enclosingClass == null &&
@@ -1129,7 +1134,7 @@
       if (node.isNonNullableByDefault) {
         features.add("isNonNullableByDefault");
       } else {
-        features.add("isNullableByDefault");
+        features.add("isLegacy");
       }
     }
     if ((node.enclosingClass == null &&
@@ -1141,14 +1146,14 @@
     if (features.isNotEmpty) {
       writeWord("/*${features.join(',')}*/");
     }
-    if (node.memberSignatureOriginReference != null) {
+    if (node.isMemberSignature) {
       writeFunction(node.function,
           name: getMemberName(node), terminateLine: false);
       if (node.function.body is ReturnStatement) {
         writeSymbol(';');
       }
       writeSymbol(' -> ');
-      writeMemberReferenceFromReference(node.memberSignatureOriginReference);
+      writeMemberReferenceFromReference(node.stubTargetReference);
       endLine();
     } else {
       writeFunction(node.function, name: getMemberName(node));
@@ -1168,7 +1173,7 @@
       if (node.isNonNullableByDefault) {
         features.add("isNonNullableByDefault");
       } else {
-        features.add("isNullableByDefault");
+        features.add("isLegacy");
       }
     }
     if (features.isNotEmpty) {
@@ -1204,7 +1209,7 @@
       if (node.isNonNullableByDefault) {
         features.add("isNonNullableByDefault");
       } else {
-        features.add("isNullableByDefault");
+        features.add("isLegacy");
       }
     }
     if (features.isNotEmpty) {
@@ -1252,7 +1257,7 @@
     if (features.isNotEmpty) {
       writeSpaced('/*${features.join(',')}*/');
     }
-    var endLineString = ' {';
+    String endLineString = ' {';
     if (node.enclosingLibrary.fileUri != node.fileUri) {
       endLineString += ' // from ${node.fileUri}';
     }
@@ -1274,7 +1279,7 @@
     writeTypeParameterList(node.typeParameters);
     writeSpaced('on');
     writeType(node.onType);
-    var endLineString = ' {';
+    String endLineString = ' {';
     if (node.enclosingLibrary.fileUri != node.fileUri) {
       endLineString += ' // from ${node.fileUri}';
     }
@@ -1415,7 +1420,7 @@
       writeSpace();
     }
     write('"');
-    for (var part in node.expressions) {
+    for (Expression part in node.expressions) {
       if (part is StringLiteral) {
         writeSymbol(escapeString(part.value));
       } else {
@@ -1677,7 +1682,7 @@
   visitLibraryDependency(LibraryDependency node) {
     writeIndentation();
     writeWord(node.isImport ? 'import' : 'export');
-    var uriString;
+    String uriString;
     if (node.importedLibraryReference?.node != null) {
       uriString = '${node.targetLibrary.importUri}';
     } else {
@@ -1925,7 +1930,7 @@
     writeIndentation();
     writeWord(label);
     endLine(':');
-    for (var expression in node.expressions) {
+    for (Expression expression in node.expressions) {
       writeIndentation();
       writeWord('case');
       writeExpression(expression);
@@ -2046,6 +2051,7 @@
     if (showOffsets) writeWord("[${node.fileOffset}]");
     if (showMetadata) writeMetadata(node);
     writeAnnotationList(node.annotations, separateLines: false);
+    writeModifier(node.isLowered, 'lowered');
     writeModifier(node.isLate, 'late');
     writeModifier(node.isRequired, 'required');
     writeModifier(node.isCovariant, 'covariant');
@@ -2072,7 +2078,7 @@
       writeSymbol('>');
     }
     writeSymbol('(');
-    var allArgs =
+    Iterable<TreeNode> allArgs =
         <List<TreeNode>>[node.positional, node.named].expand((x) => x);
     writeList(allArgs, writeNode);
     writeSymbol(')');
@@ -2331,7 +2337,7 @@
     writeSymbol('<');
     writeList([node.keyType, node.valueType], writeType);
     writeSymbol('>{');
-    writeList(node.entries, (entry) {
+    writeList(node.entries, (ConstantMapEntry entry) {
       writeConstantReference(entry.key);
       writeSymbol(':');
       writeConstantReference(entry.value);
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
index 39435d7..dc8fe50 100644
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ b/pkg/kernel/lib/text/serializer_combinators.dart
@@ -81,8 +81,8 @@
       prefix = "ID";
     }
     String distinctName = "$prefix$separator${nameCount++}";
-    // The following checks for an internal error, not an error caused by the user.
-    // So, an assert is used instead of an exception.
+    // The following checks for an internal error, not an error caused by the
+    // user. So, an assert is used instead of an exception.
     assert(
         lookupDistinctName(node) == null,
         "Can't assign distinct name '${distinctName}' "
@@ -667,7 +667,7 @@
   const Bind(this.pattern, this.term);
 
   Tuple2<P, T> readFrom(Iterator<Object> stream, DeserializationState state) {
-    var bindingState = new DeserializationState(
+    DeserializationState bindingState = new DeserializationState(
         new DeserializationEnvironment(state.environment), state.nameRoot);
     P first = pattern.readFrom(stream, bindingState);
     bindingState.environment.extend();
@@ -677,7 +677,7 @@
 
   void writeTo(
       StringBuffer buffer, Tuple2<P, T> tuple, SerializationState state) {
-    var bindingState =
+    SerializationState bindingState =
         new SerializationState(new SerializationEnvironment(state.environment));
     pattern.writeTo(buffer, tuple.first, bindingState);
     bindingState.environment.extend();
@@ -699,7 +699,7 @@
 
   Tuple2<P, T> readFrom(Iterator<Object> stream, DeserializationState state) {
     P first = pattern1.readFrom(stream, state);
-    var closedState = new DeserializationState(
+    DeserializationState closedState = new DeserializationState(
         new DeserializationEnvironment(state.environment)
           ..binders.addAll(state.environment.binders)
           ..extend(),
@@ -712,7 +712,7 @@
   void writeTo(
       StringBuffer buffer, Tuple2<P, T> tuple, SerializationState state) {
     pattern1.writeTo(buffer, tuple.first, state);
-    var closedState =
+    SerializationState closedState =
         new SerializationState(new SerializationEnvironment(state.environment)
           ..binders.addAll(state.environment.binders)
           ..extend());
@@ -733,7 +733,7 @@
     Tuple2<List<T1>, List<T2>> toZip = lists.readFrom(stream, state);
     List<T1> firsts = toZip.first;
     List<T2> seconds = toZip.second;
-    List<T> zipped = new List<T>(toZip.first.length);
+    List<T> zipped = new List<T>.filled(toZip.first.length, null);
     for (int i = 0; i < zipped.length; ++i) {
       zipped[i] = zip(firsts[i], seconds[i]);
     }
@@ -741,8 +741,8 @@
   }
 
   void writeTo(StringBuffer buffer, List<T> zipped, SerializationState state) {
-    List<T1> firsts = new List<T1>(zipped.length);
-    List<T2> seconds = new List<T2>(zipped.length);
+    List<T1> firsts = new List<T1>.filled(zipped.length, null);
+    List<T2> seconds = new List<T2>.filled(zipped.length, null);
     for (int i = 0; i < zipped.length; ++i) {
       Tuple2<T1, T2> tuple = unzip(zipped[i]);
       firsts[i] = tuple.first;
diff --git a/pkg/kernel/lib/text/text_reader.dart b/pkg/kernel/lib/text/text_reader.dart
index e066fde..a6867e7 100644
--- a/pkg/kernel/lib/text/text_reader.dart
+++ b/pkg/kernel/lib/text/text_reader.dart
@@ -40,7 +40,7 @@
   void skipToEndOfNested() {
     if (current is TextIterator) {
       TextIterator it = current;
-      while (it.moveNext());
+      while (it.moveNext()) {}
       index = it.index + 1;
     }
   }
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 42b5bda..a1c93ab 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -23,7 +23,7 @@
 TextSerializer<Name> publicName =
     Wrapped((w) => w.text, (u) => Name(u), const DartString());
 
-TextSerializer<Name> privateName = Wrapped(
+TextSerializer<Name> privateName = Wrapped<Tuple2<String, CanonicalName>, Name>(
     (w) => Tuple2(w.text, w.library.canonicalName),
     (u) => Name.byReference(u.first, u.second.getReference()),
     Tuple2Serializer(DartString(), CanonicalNameSerializer()));
@@ -347,7 +347,8 @@
 
 Tuple3<DartType, DartType, List<Expression>> unwrapMapLiteral(
     MapLiteral expression) {
-  List<Expression> entries = new List(2 * expression.entries.length);
+  List<Expression> entries =
+      new List.filled(2 * expression.entries.length, null);
   for (int from = 0, to = 0; from < expression.entries.length; ++from) {
     MapEntry entry = expression.entries[from];
     entries[to++] = entry.key;
@@ -357,7 +358,7 @@
 }
 
 MapLiteral wrapMapLiteral(Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapEntry> entries = new List(tuple.third.length ~/ 2);
+  List<MapEntry> entries = new List.filled(tuple.third.length ~/ 2, null);
   for (int from = 0, to = 0; to < entries.length; ++to) {
     entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
   }
@@ -373,7 +374,7 @@
 
 MapLiteral wrapConstMapLiteral(
     Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapEntry> entries = new List(tuple.third.length ~/ 2);
+  List<MapEntry> entries = new List.filled(tuple.third.length ~/ 2, null);
   for (int from = 0, to = 0; to < entries.length; ++to) {
     entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
   }
@@ -629,39 +630,48 @@
   return new FunctionExpression(node);
 }
 
-TextSerializer<ListConcatenation> listConcatenationSerializer = Wrapped(
-    (lc) => Tuple2(lc.typeArgument, lc.lists),
-    (t) => ListConcatenation(t.second, typeArgument: t.first),
-    Tuple2Serializer(dartTypeSerializer, ListSerializer(expressionSerializer)));
+TextSerializer<ListConcatenation> listConcatenationSerializer =
+    Wrapped<Tuple2<DartType, List<Expression>>, ListConcatenation>(
+        (lc) => Tuple2(lc.typeArgument, lc.lists),
+        (t) => ListConcatenation(t.second, typeArgument: t.first),
+        Tuple2Serializer(
+            dartTypeSerializer, ListSerializer(expressionSerializer)));
 
-TextSerializer<SetConcatenation> setConcatenationSerializer = Wrapped(
-    (sc) => Tuple2(sc.typeArgument, sc.sets),
-    (t) => SetConcatenation(t.second, typeArgument: t.first),
-    Tuple2Serializer(dartTypeSerializer, ListSerializer(expressionSerializer)));
+TextSerializer<SetConcatenation> setConcatenationSerializer =
+    Wrapped<Tuple2<DartType, List<Expression>>, SetConcatenation>(
+        (sc) => Tuple2(sc.typeArgument, sc.sets),
+        (t) => SetConcatenation(t.second, typeArgument: t.first),
+        Tuple2Serializer(
+            dartTypeSerializer, ListSerializer(expressionSerializer)));
 
-TextSerializer<MapConcatenation> mapConcatenationSerializer = Wrapped(
-    (mc) => Tuple3(mc.keyType, mc.valueType, mc.maps),
-    (t) => MapConcatenation(t.third, keyType: t.first, valueType: t.second),
-    Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
-        ListSerializer(expressionSerializer)));
+TextSerializer<MapConcatenation> mapConcatenationSerializer =
+    Wrapped<Tuple3<DartType, DartType, List<Expression>>, MapConcatenation>(
+        (mc) => Tuple3(mc.keyType, mc.valueType, mc.maps),
+        (t) => MapConcatenation(t.third, keyType: t.first, valueType: t.second),
+        Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
+            ListSerializer(expressionSerializer)));
 
-TextSerializer<BlockExpression> blockExpressionSerializer = Wrapped(
-    (w) => Tuple2(w.body.statements, w.value),
-    (u) => BlockExpression(Block(u.first), u.second),
-    const BlockSerializer());
+TextSerializer<BlockExpression> blockExpressionSerializer =
+    Wrapped<Tuple2<List<Statement>, Expression>, BlockExpression>(
+        (w) => Tuple2(w.body.statements, w.value),
+        (u) => BlockExpression(Block(u.first), u.second),
+        const BlockSerializer());
 
-TextSerializer<Instantiation> instantiationSerializer = Wrapped(
-    (i) => Tuple2(i.expression, i.typeArguments),
-    (t) => Instantiation(t.first, t.second),
-    Tuple2Serializer(expressionSerializer, ListSerializer(dartTypeSerializer)));
+TextSerializer<Instantiation> instantiationSerializer =
+    Wrapped<Tuple2<Expression, List<DartType>>, Instantiation>(
+        (i) => Tuple2(i.expression, i.typeArguments),
+        (t) => Instantiation(t.first, t.second),
+        Tuple2Serializer(
+            expressionSerializer, ListSerializer(dartTypeSerializer)));
 
 TextSerializer<NullCheck> nullCheckSerializer =
     Wrapped((nc) => nc.operand, (op) => NullCheck(op), expressionSerializer);
 
-TextSerializer<FileUriExpression> fileUriExpressionSerializer = Wrapped(
-    (fue) => Tuple2(fue.expression, fue.fileUri),
-    (t) => FileUriExpression(t.first, t.second),
-    Tuple2Serializer(expressionSerializer, const UriSerializer()));
+TextSerializer<FileUriExpression> fileUriExpressionSerializer =
+    Wrapped<Tuple2<Expression, Uri>, FileUriExpression>(
+        (fue) => Tuple2(fue.expression, fue.fileUri),
+        (t) => FileUriExpression(t.first, t.second),
+        Tuple2Serializer(expressionSerializer, const UriSerializer()));
 
 TextSerializer<CheckLibraryIsLoaded> checkLibraryIsLoadedSerializer = Wrapped(
     (clil) => clil.import,
@@ -671,12 +681,16 @@
 TextSerializer<LoadLibrary> loadLibrarySerializer = Wrapped(
     (ll) => ll.import, (i) => LoadLibrary(i), libraryDependencySerializer);
 
-TextSerializer<ConstantExpression> constantExpressionSerializer = Wrapped(
-    (ce) => Tuple2(ce.constant, ce.type),
-    (t) => ConstantExpression(t.first, t.second),
-    Tuple2Serializer(constantSerializer, dartTypeSerializer));
+TextSerializer<ConstantExpression> constantExpressionSerializer =
+    Wrapped<Tuple2<Constant, DartType>, ConstantExpression>(
+        (ce) => Tuple2(ce.constant, ce.type),
+        (t) => ConstantExpression(t.first, t.second),
+        Tuple2Serializer(constantSerializer, dartTypeSerializer));
 
-TextSerializer<InstanceCreation> instanceCreationSerializer = Wrapped(
+TextSerializer<InstanceCreation> instanceCreationSerializer = Wrapped<
+        Tuple6<CanonicalName, List<DartType>, List<CanonicalName>,
+            List<Expression>, List<AssertStatement>, List<Expression>>,
+        InstanceCreation>(
     (ic) => Tuple6(
         ic.classReference.canonicalName,
         ic.typeArguments,
@@ -684,8 +698,12 @@
         ic.fieldValues.values.toList(),
         ic.asserts,
         ic.unusedArguments),
-    (t) => InstanceCreation(t.first.getReference(), t.second,
-        Map.fromIterables(t.third, t.fourth), t.fifth, t.sixth),
+    (t) => InstanceCreation(
+        t.first.getReference(),
+        t.second,
+        Map.fromIterables(t.third.map((cn) => cn.reference), t.fourth),
+        t.fifth,
+        t.sixth),
     Tuple6Serializer(
         CanonicalNameSerializer(),
         ListSerializer(dartTypeSerializer),
@@ -733,10 +751,10 @@
   VariableDeclaration.FlagConst: "const",
   VariableDeclaration.FlagFieldFormal: "field-formal",
   VariableDeclaration.FlagCovariant: "covariant",
-  VariableDeclaration.FlagInScope: "in-scope",
   VariableDeclaration.FlagGenericCovariantImpl: "generic-covariant-impl",
   VariableDeclaration.FlagLate: "late",
   VariableDeclaration.FlagRequired: "required",
+  VariableDeclaration.FlagLowered: "lowered",
 };
 
 class VariableDeclarationFlagTagger implements Tagger<int> {
@@ -746,36 +764,39 @@
   }
 }
 
-TextSerializer<int> variableDeclarationFlagsSerializer = Wrapped(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        VariableDeclarationFlagTagger(),
-        Map.fromIterable(variableDeclarationFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+TextSerializer<int> variableDeclarationFlagsSerializer =
+    Wrapped<List<int>, int>(
+        (w) => List.generate(30, (i) => w & (1 << i))
+            .where((f) => f != 0)
+            .toList(),
+        (u) => u.fold(0, (fs, f) => fs |= f),
+        ListSerializer(Case(VariableDeclarationFlagTagger(),
+            convertFlagsMap(variableDeclarationFlagToName))));
 
-TextSerializer<VariableDeclaration> variableDeclarationSerializer = Wrapped(
-    (v) => Tuple2(v.name, v),
-    (t) => t.second..name = t.first,
-    Binder<VariableDeclaration>(
-      new Wrapped(
-          (w) => Tuple4(w.flags, w.type, w.initializer, w.annotations),
-          (u) => u.fourth.fold(
-              VariableDeclaration(null,
-                  flags: u.first, type: u.second, initializer: u.third),
-              (v, a) => v..addAnnotation(a)),
-          Tuple4Serializer(
-              variableDeclarationFlagsSerializer,
-              dartTypeSerializer,
-              new Optional(expressionSerializer),
-              new ListSerializer(expressionSerializer))),
-    ));
+TextSerializer<VariableDeclaration> variableDeclarationSerializer =
+    Wrapped<Tuple2<String, VariableDeclaration>, VariableDeclaration>(
+        (v) => Tuple2(v.name, v),
+        (t) => t.second..name = t.first,
+        Binder<VariableDeclaration>(
+          new Wrapped<Tuple4<int, DartType, Expression, List<Expression>>,
+                  VariableDeclaration>(
+              (w) => Tuple4(w.flags, w.type, w.initializer, w.annotations),
+              (u) => u.fourth.fold(
+                  VariableDeclaration(null,
+                      flags: u.first, type: u.second, initializer: u.third),
+                  (v, a) => v..addAnnotation(a)),
+              Tuple4Serializer(
+                  variableDeclarationFlagsSerializer,
+                  dartTypeSerializer,
+                  new Optional(expressionSerializer),
+                  new ListSerializer(expressionSerializer))),
+        ));
 
-TextSerializer<TypeParameter> typeParameterSerializer = Wrapped(
-    (p) => Tuple2(p.name, p),
-    (t) => t.second..name = t.first,
-    Binder(Wrapped((_) => null, (_) => TypeParameter(), const Nothing())));
+TextSerializer<TypeParameter> typeParameterSerializer =
+    Wrapped<Tuple2<String, TypeParameter>, TypeParameter>(
+        (p) => Tuple2(p.name, p),
+        (t) => t.second..name = t.first,
+        Binder(Wrapped((_) => null, (_) => TypeParameter(), const Nothing())));
 
 TextSerializer<List<TypeParameter>> typeParametersSerializer = new Zip(
     new Rebind(
@@ -1048,18 +1069,23 @@
   return new YieldStatement(expression);
 }
 
-TextSerializer<AssertStatement> assertStatementSerializer = Wrapped(
-    (a) => Tuple2(a.condition, a.message),
-    (t) => AssertStatement(t.first, message: t.second),
-    Tuple2Serializer(expressionSerializer, Optional(expressionSerializer)));
+TextSerializer<AssertStatement> assertStatementSerializer =
+    Wrapped<Tuple2<Expression, Expression>, AssertStatement>(
+        (a) => Tuple2(a.condition, a.message),
+        (t) => AssertStatement(t.first, message: t.second),
+        Tuple2Serializer(expressionSerializer, Optional(expressionSerializer)));
 
-TextSerializer<Block> blockSerializer = new Wrapped(
-    (w) => Tuple2(w.statements, null),
-    (u) => Block(u.first),
-    const BlockSerializer());
+TextSerializer<Block> blockSerializer =
+    Wrapped<Tuple2<List<Statement>, Expression>, Block>(
+        (w) => Tuple2(w.statements, null),
+        (u) => Block(u.first),
+        const BlockSerializer());
 
-TextSerializer<AssertBlock> assertBlockSerializer = new Wrapped(
-    (w) => Tuple2(w.statements, null), (u) => u.first, const BlockSerializer());
+TextSerializer<AssertBlock> assertBlockSerializer =
+    Wrapped<Tuple2<List<Statement>, Expression>, AssertBlock>(
+        (w) => Tuple2(w.statements, null),
+        (u) => AssertBlock(u.first),
+        const BlockSerializer());
 
 /// Serializer for [Block]s.
 ///
@@ -1179,7 +1205,10 @@
   return new DoStatement(tuple.first, tuple.second);
 }
 
-TextSerializer<ForStatement> forStatementSerializer = new Wrapped(
+TextSerializer<ForStatement> forStatementSerializer = Wrapped<
+        Tuple2<List<VariableDeclaration>,
+            Tuple3<Expression, List<Expression>, Statement>>,
+        ForStatement>(
     (w) => Tuple2(w.variables, Tuple3(w.condition, w.updates, w.body)),
     (u) =>
         ForStatement(u.first, u.second.first, u.second.second, u.second.third),
@@ -1223,7 +1252,7 @@
         (ls) => Tuple2(ls, ls.body),
         (t) => t.first..body = t.second,
         Bind(
-            Wrapped(
+            Wrapped<Tuple2<String, LabeledStatement>, LabeledStatement>(
                 (ls) => Tuple2("L", ls),
                 (t) => t.second,
                 Binder(Wrapped(
@@ -1243,37 +1272,47 @@
   return new BreakStatement(node);
 }
 
-TextSerializer<TryFinally> tryFinallySerializer = Wrapped(
-    (w) => Tuple2(w.body, w.finalizer),
-    (u) => TryFinally(u.first, u.second),
-    Tuple2Serializer(statementSerializer, statementSerializer));
+TextSerializer<TryFinally> tryFinallySerializer =
+    Wrapped<Tuple2<Statement, Statement>, TryFinally>(
+        (w) => Tuple2(w.body, w.finalizer),
+        (u) => TryFinally(u.first, u.second),
+        Tuple2Serializer(statementSerializer, statementSerializer));
 
-TextSerializer<TryCatch> tryCatchSerializer = Wrapped(
-    (w) => Tuple2(w.body, w.catches),
-    (u) => TryCatch(u.first, u.second),
-    Tuple2Serializer(statementSerializer, ListSerializer(catchSerializer)));
+TextSerializer<TryCatch> tryCatchSerializer =
+    Wrapped<Tuple2<Statement, List<Catch>>, TryCatch>(
+        (w) => Tuple2(w.body, w.catches),
+        (u) => TryCatch(u.first, u.second),
+        Tuple2Serializer(statementSerializer, ListSerializer(catchSerializer)));
 
-TextSerializer<Catch> catchSerializer = Wrapped(
-    (w) => Tuple2(w.guard, Tuple2(Tuple2(w.exception, w.stackTrace), w.body)),
-    (u) => Catch(u.second.first.first, u.second.second,
-        stackTrace: u.second.first.second, guard: u.first),
-    Tuple2Serializer(
-        dartTypeSerializer,
-        Bind(
-            Tuple2Serializer(Optional(variableDeclarationSerializer),
-                Optional(variableDeclarationSerializer)),
-            statementSerializer)));
+TextSerializer<Catch> catchSerializer =
+    Wrapped<
+            Tuple2<
+                DartType,
+                Tuple2<Tuple2<VariableDeclaration, VariableDeclaration>,
+                    Statement>>,
+            Catch>(
+        (w) =>
+            Tuple2(w.guard, Tuple2(Tuple2(w.exception, w.stackTrace), w.body)),
+        (u) => Catch(u.second.first.first, u.second.second,
+            stackTrace: u.second.first.second, guard: u.first),
+        Tuple2Serializer(
+            dartTypeSerializer,
+            Bind(
+                Tuple2Serializer(Optional(variableDeclarationSerializer),
+                    Optional(variableDeclarationSerializer)),
+                statementSerializer)));
 
-TextSerializer<SwitchStatement> switchStatementSerializer = Wrapped(
-    (w) => Tuple2(w.expression, w.cases),
-    (u) => SwitchStatement(u.first, u.second),
-    Tuple2Serializer(
-        expressionSerializer,
-        Zip(
-            Bind(ListSerializer<SwitchCase>(switchCaseSerializer),
-                ListSerializer(statementSerializer)),
-            (SwitchCase c, Statement b) => c..body = b,
-            (SwitchCase z) => Tuple2(z, z.body))));
+TextSerializer<SwitchStatement> switchStatementSerializer =
+    Wrapped<Tuple2<Expression, List<SwitchCase>>, SwitchStatement>(
+        (w) => Tuple2(w.expression, w.cases),
+        (u) => SwitchStatement(u.first, u.second),
+        Tuple2Serializer(
+            expressionSerializer,
+            Zip(
+                Bind(ListSerializer<SwitchCase>(switchCaseSerializer),
+                    ListSerializer(statementSerializer)),
+                (SwitchCase c, Statement b) => c..body = b,
+                (SwitchCase z) => Tuple2(z, z.body))));
 
 class SwitchCaseTagger implements Tagger<SwitchCase> {
   String tag(SwitchCase node) {
@@ -1281,15 +1320,17 @@
   }
 }
 
-TextSerializer<SwitchCase> switchCaseCaseSerializer = Wrapped(
-    (w) => Tuple2("L", w),
-    (u) => u.second,
-    Binder(Wrapped(
-        (w) => w.expressions,
-        (u) => SwitchCase(u, List.filled(u.length, 0), null),
-        ListSerializer(expressionSerializer))));
+TextSerializer<SwitchCase> switchCaseCaseSerializer =
+    Wrapped<Tuple2<String, SwitchCase>, SwitchCase>(
+        (w) => Tuple2("L", w),
+        (u) => u.second,
+        Binder(Wrapped<List<Expression>, SwitchCase>(
+            (w) => w.expressions,
+            (u) => SwitchCase(u, List.filled(u.length, 0), null),
+            ListSerializer(expressionSerializer))));
 
-TextSerializer<SwitchCase> switchCaseDefaultSerializer = Wrapped(
+TextSerializer<SwitchCase> switchCaseDefaultSerializer = Wrapped<
+        Tuple2<String, SwitchCase>, SwitchCase>(
     (w) => Tuple2("L", w),
     (u) => u.second,
     Binder(
@@ -1303,10 +1344,11 @@
 TextSerializer<ContinueSwitchStatement> continueSwitchStatementSerializer =
     Wrapped((w) => w.target, (u) => ContinueSwitchStatement(u), ScopedUse());
 
-TextSerializer<FunctionDeclaration> functionDeclarationSerializer = Wrapped(
-    (w) => Tuple2(w.variable, w.function),
-    (u) => FunctionDeclaration(u.first, u.second),
-    Rebind(variableDeclarationSerializer, functionNodeSerializer));
+TextSerializer<FunctionDeclaration> functionDeclarationSerializer =
+    Wrapped<Tuple2<VariableDeclaration, FunctionNode>, FunctionDeclaration>(
+        (w) => Tuple2(w.variable, w.function),
+        (u) => FunctionDeclaration(u.first, u.second),
+        Rebind(variableDeclarationSerializer, functionNodeSerializer));
 
 Case<Statement> statementSerializer =
     new Case.uninitialized(const StatementTagger());
@@ -1327,14 +1369,24 @@
   }
 }
 
-TextSerializer<AsyncMarker> asyncMarkerSerializer = Case(
-    AsyncMarkerTagger(),
-    Map.fromIterable(asyncMarkerToName.entries,
-        key: (e) => e.value,
-        value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())));
+TextSerializer<AsyncMarker> asyncMarkerSerializer =
+    Case(AsyncMarkerTagger(), convertFlagsMap(asyncMarkerToName));
 
-TextSerializer<Tuple2<FunctionNode, List<Initializer>>>
-    functionNodeWithInitializersSerializer = Wrapped(
+// '/**/' comments added to guide formatting.
+
+TextSerializer<Tuple2<FunctionNode, List<Initializer>>> /**/
+    functionNodeWithInitializersSerializer = Wrapped<
+            Tuple2<
+                AsyncMarker,
+                Tuple2< /**/
+                    Tuple2< /**/
+                        List<TypeParameter>,
+                        Tuple3<
+                            List<VariableDeclaration>,
+                            List<VariableDeclaration>,
+                            List<VariableDeclaration>>>,
+                    Tuple3<DartType, List<Initializer>, Statement>>>,
+            Tuple2<FunctionNode, List<Initializer>>>(
         (w) => Tuple2(
             w.first.asyncMarker,
             Tuple2(
@@ -1371,24 +1423,22 @@
                     Optional(ListSerializer(initializerSerializer)),
                     Optional(statementSerializer)))));
 
-TextSerializer<FunctionNode> functionNodeSerializer = Wrapped(
-    (w) => Tuple2(w, null),
-    (u) => u.first,
-    functionNodeWithInitializersSerializer);
+TextSerializer<FunctionNode> functionNodeSerializer =
+    Wrapped<Tuple2<FunctionNode, List<Initializer>>, FunctionNode>(
+        (w) => Tuple2(w, null),
+        (u) => u.first,
+        functionNodeWithInitializersSerializer);
 
 const Map<int, String> procedureFlagToName = const {
   Procedure.FlagStatic: "static",
   Procedure.FlagAbstract: "abstract",
   Procedure.FlagExternal: "external",
   Procedure.FlagConst: "const",
-  Procedure.FlagForwardingStub: "forwarding-stub",
-  Procedure.FlagForwardingSemiStub: "forwarding-semi-stub",
   Procedure.FlagRedirectingFactoryConstructor:
       "redirecting-factory-constructor",
-  Procedure.FlagNoSuchMethodForwarder: "no-such-method-forwarder",
   Procedure.FlagExtensionMember: "extension-member",
-  Procedure.FlagMemberSignature: "member-signature",
   Procedure.FlagNonNullableByDefault: "non-nullable-by-default",
+  Procedure.FlagSynthetic: "synthetic",
 };
 
 class ProcedureFlagTagger implements Tagger<int> {
@@ -1400,14 +1450,11 @@
   }
 }
 
-TextSerializer<int> procedureFlagsSerializer = Wrapped(
+TextSerializer<int> procedureFlagsSerializer = Wrapped<List<int>, int>(
     (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
     (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        ProcedureFlagTagger(),
-        Map.fromIterable(procedureFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+    ListSerializer(
+        Case(ProcedureFlagTagger(), convertFlagsMap(procedureFlagToName))));
 
 const Map<int, String> fieldFlagToName = const {
   Field.FlagFinal: "final",
@@ -1432,14 +1479,10 @@
   }
 }
 
-TextSerializer<int> fieldFlagsSerializer = Wrapped(
+TextSerializer<int> fieldFlagsSerializer = Wrapped<List<int>, int>(
     (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
     (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        FieldFlagTagger(),
-        Map.fromIterable(fieldFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+    ListSerializer(Case(FieldFlagTagger(), convertFlagsMap(fieldFlagToName))));
 
 const Map<int, String> constructorFlagToName = const {
   Constructor.FlagConst: "const",
@@ -1457,14 +1500,11 @@
   }
 }
 
-TextSerializer<int> constructorFlagsSerializer = Wrapped(
+TextSerializer<int> constructorFlagsSerializer = Wrapped<List<int>, int>(
     (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
     (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        ConstructorFlagTagger(),
-        Map.fromIterable(constructorFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+    ListSerializer(
+        Case(ConstructorFlagTagger(), convertFlagsMap(constructorFlagToName))));
 
 const Map<int, String> redirectingFactoryConstructorFlagToName = const {
   RedirectingFactoryConstructor.FlagConst: "const",
@@ -1483,14 +1523,14 @@
   }
 }
 
-TextSerializer<int> redirectingFactoryConstructorFlagsSerializer = Wrapped(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        RedirectingFactoryConstructorFlagTagger(),
-        Map.fromIterable(redirectingFactoryConstructorFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+TextSerializer<int> redirectingFactoryConstructorFlagsSerializer =
+    Wrapped<List<int>, int>(
+        (w) => List.generate(30, (i) => w & (1 << i))
+            .where((f) => f != 0)
+            .toList(),
+        (u) => u.fold(0, (fs, f) => fs |= f),
+        ListSerializer(Case(RedirectingFactoryConstructorFlagTagger(),
+            convertFlagsMap(redirectingFactoryConstructorFlagToName))));
 
 class MemberTagger implements Tagger<Member> {
   const MemberTagger();
@@ -1523,45 +1563,57 @@
   }
 }
 
-TextSerializer<Field> fieldSerializer = Wrapped(
-    (w) => Tuple4(w.name, w.flags, w.type, w.initializer),
-    (u) =>
-        Field(u.first, type: u.third, initializer: u.fourth)..flags = u.second,
-    Tuple4Serializer(nameSerializer, fieldFlagsSerializer, dartTypeSerializer,
-        Optional(expressionSerializer)));
+TextSerializer<Field> fieldSerializer =
+    Wrapped<Tuple4<Name, int, DartType, Expression>, Field>(
+        (w) => Tuple4(w.name, w.flags, w.type, w.initializer),
+        (u) => Field(u.first, type: u.third, initializer: u.fourth)
+          ..flags = u.second,
+        Tuple4Serializer(nameSerializer, fieldFlagsSerializer,
+            dartTypeSerializer, Optional(expressionSerializer)));
 
-TextSerializer<Procedure> methodSerializer = Wrapped(
-    (w) => Tuple3(w.name, w.flags, w.function),
-    (u) => Procedure(u.first, ProcedureKind.Method, u.third)..flags = u.second,
-    Tuple3Serializer(
-        nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
+TextSerializer<Procedure> methodSerializer =
+    Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
+        (w) => Tuple3(w.name, w.flags, w.function),
+        (u) =>
+            Procedure(u.first, ProcedureKind.Method, u.third)..flags = u.second,
+        Tuple3Serializer(
+            nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
 
-TextSerializer<Procedure> getterSerializer = Wrapped(
-    (w) => Tuple3(w.name, w.flags, w.function),
-    (u) => Procedure(u.first, ProcedureKind.Getter, u.third)..flags = u.second,
-    Tuple3Serializer(
-        nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
+TextSerializer<Procedure> getterSerializer =
+    Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
+        (w) => Tuple3(w.name, w.flags, w.function),
+        (u) =>
+            Procedure(u.first, ProcedureKind.Getter, u.third)..flags = u.second,
+        Tuple3Serializer(
+            nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
 
-TextSerializer<Procedure> setterSerializer = Wrapped(
-    (w) => Tuple3(w.name, w.flags, w.function),
-    (u) => Procedure(u.first, ProcedureKind.Setter, u.third)..flags = u.second,
-    Tuple3Serializer(
-        nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
+TextSerializer<Procedure> setterSerializer =
+    Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
+        (w) => Tuple3(w.name, w.flags, w.function),
+        (u) =>
+            Procedure(u.first, ProcedureKind.Setter, u.third)..flags = u.second,
+        Tuple3Serializer(
+            nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
 
-TextSerializer<Procedure> operatorSerializer = Wrapped(
-    (w) => Tuple3(w.name, w.flags, w.function),
-    (u) =>
-        Procedure(u.first, ProcedureKind.Operator, u.third)..flags = u.second,
-    Tuple3Serializer(
-        nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
+TextSerializer<Procedure> operatorSerializer =
+    Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
+        (w) => Tuple3(w.name, w.flags, w.function),
+        (u) => Procedure(u.first, ProcedureKind.Operator, u.third)
+          ..flags = u.second,
+        Tuple3Serializer(
+            nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
 
-TextSerializer<Procedure> factorySerializer = Wrapped(
-    (w) => Tuple3(w.name, w.flags, w.function),
-    (u) => Procedure(u.first, ProcedureKind.Factory, u.third)..flags = u.second,
-    Tuple3Serializer(
-        nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
+TextSerializer<Procedure> factorySerializer =
+    Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
+        (w) => Tuple3(w.name, w.flags, w.function),
+        (u) => Procedure(u.first, ProcedureKind.Factory, u.third)
+          ..flags = u.second,
+        Tuple3Serializer(
+            nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
 
-TextSerializer<Constructor> constructorSerializer = Wrapped(
+TextSerializer<Constructor> constructorSerializer = Wrapped<
+        Tuple3<Name, int, Tuple2<FunctionNode, List<Initializer>>>,
+        Constructor>(
     (w) => Tuple3(w.name, w.flags, Tuple2(w.function, w.initializers)),
     (u) =>
         Constructor(u.third.first, name: u.first, initializers: u.third.second)
@@ -1570,7 +1622,16 @@
         functionNodeWithInitializersSerializer));
 
 TextSerializer<RedirectingFactoryConstructor>
-    redirectingFactoryConstructorSerializer = Wrapped(
+    redirectingFactoryConstructorSerializer = Wrapped<
+            Tuple4<
+                Name,
+                int,
+                CanonicalName,
+                Tuple2<
+                    List<TypeParameter>,
+                    Tuple4<List<VariableDeclaration>, List<VariableDeclaration>,
+                        List<VariableDeclaration>, List<DartType>>>>,
+            RedirectingFactoryConstructor>(
         (w) => Tuple4(
             w.name,
             w.flags,
@@ -1586,7 +1647,7 @@
                         .toList(),
                     w.namedParameters,
                     w.typeArguments))),
-        (u) => RedirectingFactoryConstructor(u.third,
+        (u) => RedirectingFactoryConstructor(u.third.reference,
             name: u.first,
             typeParameters: u.fourth.first,
             positionalParameters:
@@ -1609,10 +1670,11 @@
 
 Case<Member> memberSerializer = new Case.uninitialized(const MemberTagger());
 
-TextSerializer<LibraryPart> libraryPartSerializer = Wrapped(
-    (w) => Tuple2(w.partUri, w.annotations),
-    (u) => LibraryPart(u.second, u.first),
-    Tuple2Serializer(DartString(), ListSerializer(expressionSerializer)));
+TextSerializer<LibraryPart> libraryPartSerializer =
+    Wrapped<Tuple2<String, List<Expression>>, LibraryPart>(
+        (w) => Tuple2(w.partUri, w.annotations),
+        (u) => LibraryPart(u.second, u.first),
+        Tuple2Serializer(DartString(), ListSerializer(expressionSerializer)));
 
 class LibraryTagger implements Tagger<Library> {
   const LibraryTagger();
@@ -1638,16 +1700,16 @@
   }
 }
 
-TextSerializer<int> libraryFlagsSerializer = Wrapped(
+TextSerializer<int> libraryFlagsSerializer = Wrapped<List<int>, int>(
     (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
     (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        LibraryFlagTagger(),
-        Map.fromIterable(libraryFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+    ListSerializer(
+        Case(LibraryFlagTagger(), convertFlagsMap(libraryFlagToName))));
 
-TextSerializer<Library> librarySerializer = new Wrapped(
+TextSerializer<Library> librarySerializer = new Wrapped<
+    Tuple7<Uri, int, List<LibraryPart>, List<Member>, List<Class>,
+        List<Typedef>, List<Extension>>,
+    Library>(
   (w) => Tuple7(w.importUri, w.flags, w.parts, [...w.fields, ...w.procedures],
       w.classes, w.typedefs, w.extensions),
   (u) => Library(u.first,
@@ -1669,16 +1731,17 @@
       ListSerializer(extensionSerializer)),
 );
 
-TextSerializer<Component> componentSerializer = Wrapped(
-    (w) => w.libraries,
-    (u) => Component(nameRoot: CanonicalName.root(), libraries: u),
-    ListSerializer(librarySerializer));
+TextSerializer<Component> componentSerializer =
+    Wrapped<List<Library>, Component>(
+        (w) => w.libraries,
+        (u) => Component(nameRoot: CanonicalName.root(), libraries: u),
+        ListSerializer(librarySerializer));
 
 class ShowHideTagger implements Tagger<Combinator> {
   String tag(Combinator node) => node.isShow ? "show" : "hide";
 }
 
-TextSerializer<Combinator> showSerializer = Wrapped(
+TextSerializer<Combinator> showSerializer = Wrapped<List<String>, Combinator>(
     (c) => c.names, (ns) => Combinator(true, ns), ListSerializer(DartString()));
 
 TextSerializer<Combinator> hideSerializer = Wrapped((c) => c.names,
@@ -1689,7 +1752,9 @@
   "hide": hideSerializer,
 });
 
-TextSerializer<LibraryDependency> libraryDependencySerializer = Wrapped(
+TextSerializer<LibraryDependency> libraryDependencySerializer = Wrapped<
+        Tuple5<CanonicalName, String, List<Combinator>, int, List<Expression>>,
+        LibraryDependency>(
     (ld) => Tuple5(ld.importedLibraryReference.canonicalName, ld.name,
         ld.combinators, ld.flags, ld.annotations),
     (t) => LibraryDependency.byReference(
@@ -1725,64 +1790,78 @@
 }
 
 TextSerializer<BoolConstant> boolConstantSerializer =
-    Wrapped((w) => w.value, (u) => BoolConstant(u), DartBool());
+    Wrapped<bool, BoolConstant>(
+        (w) => w.value, (u) => BoolConstant(u), DartBool());
 
 TextSerializer<DoubleConstant> doubleConstantSerializer =
-    Wrapped((w) => w.value, (u) => DoubleConstant(u), DartDouble());
+    Wrapped<double, DoubleConstant>(
+        (w) => w.value, (u) => DoubleConstant(u), DartDouble());
 
 TextSerializer<IntConstant> intConstantSerializer =
-    Wrapped((w) => w.value, (u) => IntConstant(u), DartInt());
+    Wrapped<int, IntConstant>((w) => w.value, (u) => IntConstant(u), DartInt());
 
-TextSerializer<ListConstant> listConstantSerializer = Wrapped(
-    (w) => Tuple2(w.typeArgument, w.entries),
-    (u) => ListConstant(u.first, u.second),
-    Tuple2Serializer(dartTypeSerializer, ListSerializer(constantSerializer)));
+TextSerializer<ListConstant> listConstantSerializer =
+    Wrapped<Tuple2<DartType, List<Constant>>, ListConstant>(
+        (w) => Tuple2(w.typeArgument, w.entries),
+        (u) => ListConstant(u.first, u.second),
+        Tuple2Serializer(
+            dartTypeSerializer, ListSerializer(constantSerializer)));
 
-TextSerializer<MapConstant> mapConstantSerializer = Wrapped(
-    (w) => Tuple3(w.keyType, w.valueType, w.entries),
-    (u) => MapConstant(u.first, u.second, u.third),
-    Tuple3Serializer(
-        dartTypeSerializer,
-        dartTypeSerializer,
-        Zip(
-            Tuple2Serializer(ListSerializer(constantSerializer),
-                ListSerializer(constantSerializer)),
-            (k, v) => ConstantMapEntry(k, v),
-            (z) => Tuple2(z.key, z.value))));
+TextSerializer<MapConstant> mapConstantSerializer =
+    Wrapped<Tuple3<DartType, DartType, List<ConstantMapEntry>>, MapConstant>(
+        (w) => Tuple3(w.keyType, w.valueType, w.entries),
+        (u) => MapConstant(u.first, u.second, u.third),
+        Tuple3Serializer(
+            dartTypeSerializer,
+            dartTypeSerializer,
+            Zip(
+                Tuple2Serializer(ListSerializer(constantSerializer),
+                    ListSerializer(constantSerializer)),
+                (k, v) => ConstantMapEntry(k, v),
+                (z) => Tuple2(z.key, z.value))));
 
 TextSerializer<NullConstant> nullConstantSerializer =
-    Wrapped((w) => null, (u) => NullConstant(), Nothing());
+    Wrapped<void, NullConstant>((w) => null, (u) => NullConstant(), Nothing());
 
 TextSerializer<PartialInstantiationConstant>
-    partialInstantiationConstantSerializer = Wrapped(
+    partialInstantiationConstantSerializer = Wrapped<
+            Tuple2<TearOffConstant, List<DartType>>,
+            PartialInstantiationConstant>(
         (w) => Tuple2(w.tearOffConstant, w.types),
         (u) => PartialInstantiationConstant(u.first, u.second),
         Tuple2Serializer(
             tearOffConstantSerializer, ListSerializer(dartTypeSerializer)));
 
-TextSerializer<SetConstant> setConstantSerializer = Wrapped(
-    (w) => Tuple2(w.typeArgument, w.entries),
-    (u) => SetConstant(u.first, u.second),
-    Tuple2Serializer(dartTypeSerializer, ListSerializer(constantSerializer)));
+TextSerializer<SetConstant> setConstantSerializer =
+    Wrapped<Tuple2<DartType, List<Constant>>, SetConstant>(
+        (w) => Tuple2(w.typeArgument, w.entries),
+        (u) => SetConstant(u.first, u.second),
+        Tuple2Serializer(
+            dartTypeSerializer, ListSerializer(constantSerializer)));
 
 TextSerializer<StringConstant> stringConstantSerializer =
-    Wrapped((w) => w.value, (u) => StringConstant(u), DartString());
+    Wrapped<String, StringConstant>(
+        (w) => w.value, (u) => StringConstant(u), DartString());
 
-TextSerializer<SymbolConstant> symbolConstantSerializer = Wrapped(
-    (w) => Tuple2(w.name, w.libraryReference?.canonicalName),
-    (u) => SymbolConstant(u.first, u.second?.getReference()),
-    Tuple2Serializer(DartString(), Optional(CanonicalNameSerializer())));
+TextSerializer<SymbolConstant> symbolConstantSerializer =
+    Wrapped<Tuple2<String, CanonicalName>, SymbolConstant>(
+        (w) => Tuple2(w.name, w.libraryReference?.canonicalName),
+        (u) => SymbolConstant(u.first, u.second?.getReference()),
+        Tuple2Serializer(DartString(), Optional(CanonicalNameSerializer())));
 
-TextSerializer<TearOffConstant> tearOffConstantSerializer = Wrapped(
-    (w) => w.procedureReference.canonicalName,
-    (u) => TearOffConstant.byReference(u.getReference()),
-    CanonicalNameSerializer());
+TextSerializer<TearOffConstant> tearOffConstantSerializer =
+    Wrapped<CanonicalName, TearOffConstant>(
+        (w) => w.procedureReference.canonicalName,
+        (u) => TearOffConstant.byReference(u.getReference()),
+        CanonicalNameSerializer());
 
 TextSerializer<TypeLiteralConstant> typeLiteralConstantSerializer =
-    Wrapped((w) => w.type, (u) => TypeLiteralConstant(u), dartTypeSerializer);
+    Wrapped<DartType, TypeLiteralConstant>(
+        (w) => w.type, (u) => TypeLiteralConstant(u), dartTypeSerializer);
 
-TextSerializer<UnevaluatedConstant> unevaluatedConstantSerializer = Wrapped(
-    (w) => w.expression, (u) => UnevaluatedConstant(u), expressionSerializer);
+TextSerializer<UnevaluatedConstant> unevaluatedConstantSerializer =
+    Wrapped<Expression, UnevaluatedConstant>((w) => w.expression,
+        (u) => UnevaluatedConstant(u), expressionSerializer);
 
 TextSerializer<InstanceConstant> instanceConstantSerializer =
     Wrapped<
@@ -1826,42 +1905,46 @@
   }
 }
 
-TextSerializer<AssertInitializer> assertInitializerSerializer = Wrapped(
-    (w) => w.statement, (u) => AssertInitializer(u), statementSerializer);
+TextSerializer<AssertInitializer> assertInitializerSerializer =
+    Wrapped<Statement, AssertInitializer>(
+        (w) => w.statement, (u) => AssertInitializer(u), statementSerializer);
 
-TextSerializer<FieldInitializer> fieldInitializerSerializer = Wrapped(
-    (w) => Tuple2(w.fieldReference.canonicalName, w.value),
-    (u) => FieldInitializer.byReference(u.first.getReference(), u.second),
-    Tuple2Serializer(CanonicalNameSerializer(), expressionSerializer));
+TextSerializer<FieldInitializer> fieldInitializerSerializer =
+    Wrapped<Tuple2<CanonicalName, Expression>, FieldInitializer>(
+        (w) => Tuple2(w.fieldReference.canonicalName, w.value),
+        (u) => FieldInitializer.byReference(u.first.getReference(), u.second),
+        Tuple2Serializer(CanonicalNameSerializer(), expressionSerializer));
 
 TextSerializer<InvalidInitializer> invalidInitializerSerializer =
-    Wrapped((_) => null, (_) => InvalidInitializer(), Nothing());
+    Wrapped<void, InvalidInitializer>(
+        (_) => null, (_) => InvalidInitializer(), Nothing());
 
-TextSerializer<LocalInitializer> localInitializerSerializer = Wrapped(
-    (w) => w.variable,
-    (u) => LocalInitializer(u),
-    variableDeclarationSerializer);
+TextSerializer<LocalInitializer> localInitializerSerializer =
+    Wrapped<VariableDeclaration, LocalInitializer>((w) => w.variable,
+        (u) => LocalInitializer(u), variableDeclarationSerializer);
 
 TextSerializer<RedirectingInitializer> redirectingInitializerSerializer =
-    Wrapped(
+    Wrapped<Tuple2<CanonicalName, Arguments>, RedirectingInitializer>(
         (w) => Tuple2(w.targetReference.canonicalName, w.arguments),
         (u) => RedirectingInitializer.byReference(
             u.first.getReference(), u.second),
         Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
 
-TextSerializer<SuperInitializer> superInitializerSerializer = Wrapped(
-    (w) => Tuple2(w.targetReference.canonicalName, w.arguments),
-    (u) => SuperInitializer.byReference(u.first.getReference(), u.second),
-    Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
+TextSerializer<SuperInitializer> superInitializerSerializer =
+    Wrapped<Tuple2<CanonicalName, Arguments>, SuperInitializer>(
+        (w) => Tuple2(w.targetReference.canonicalName, w.arguments),
+        (u) => SuperInitializer.byReference(u.first.getReference(), u.second),
+        Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
 
 Case<Initializer> initializerSerializer =
     Case.uninitialized(InitializerTagger());
 
-TextSerializer<Supertype> supertypeSerializer = Wrapped(
-    (w) => Tuple2(w.className.canonicalName, w.typeArguments),
-    (u) => Supertype.byReference(u.first.getReference(), u.second),
-    Tuple2Serializer(
-        CanonicalNameSerializer(), ListSerializer(dartTypeSerializer)));
+TextSerializer<Supertype> supertypeSerializer =
+    Wrapped<Tuple2<CanonicalName, List<DartType>>, Supertype>(
+        (w) => Tuple2(w.className.canonicalName, w.typeArguments),
+        (u) => Supertype.byReference(u.first.getReference(), u.second),
+        Tuple2Serializer(
+            CanonicalNameSerializer(), ListSerializer(dartTypeSerializer)));
 
 const Map<int, String> classFlagToName = const {
   Class.FlagAbstract: "abstract",
@@ -1881,16 +1964,20 @@
   }
 }
 
-TextSerializer<int> classFlagsSerializer = Wrapped(
+TextSerializer<int> classFlagsSerializer = Wrapped<List<int>, int>(
     (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
     (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        ClassFlagTagger(),
-        Map.fromIterable(classFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+    ListSerializer(Case(ClassFlagTagger(), convertFlagsMap(classFlagToName))));
 
-TextSerializer<Class> classSerializer = Wrapped(
+TextSerializer<Class> classSerializer = Wrapped<
+        Tuple3<
+            String,
+            int,
+            Tuple2<
+                List<TypeParameter>,
+                /* Comment added to guide formatting. */
+                Tuple4<Supertype, Supertype, List<Supertype>, List<Member>>>>,
+        Class>(
     (w) => Tuple3(
         w.name,
         w.flags,
@@ -1928,11 +2015,13 @@
                 ListSerializer(supertypeSerializer),
                 ListSerializer(memberSerializer)))));
 
-TextSerializer<Typedef> typedefSerializer = Wrapped(
-    (w) => Tuple2(w.name, Tuple2(w.typeParameters, w.type)),
-    (u) => Typedef(u.first, u.second.second, typeParameters: u.second.first),
-    Tuple2Serializer(
-        DartString(), Bind(typeParametersSerializer, dartTypeSerializer)));
+TextSerializer<Typedef> typedefSerializer =
+    Wrapped<Tuple2<String, Tuple2<List<TypeParameter>, DartType>>, Typedef>(
+        (w) => Tuple2(w.name, Tuple2(w.typeParameters, w.type)),
+        (u) =>
+            Typedef(u.first, u.second.second, typeParameters: u.second.first),
+        Tuple2Serializer(
+            DartString(), Bind(typeParametersSerializer, dartTypeSerializer)));
 
 const Map<int, String> extensionMemberDescriptorFlagToName = const {
   ExtensionMemberDescriptor.FlagStatic: "static",
@@ -1948,14 +2037,14 @@
   }
 }
 
-TextSerializer<int> extensionMemberDescriptorFlagsSerializer = Wrapped(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(
-        ExtensionMemberDescriptorFlagTagger(),
-        Map.fromIterable(extensionMemberDescriptorFlagToName.entries,
-            key: (e) => e.value,
-            value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())))));
+TextSerializer<int> extensionMemberDescriptorFlagsSerializer =
+    Wrapped<List<int>, int>(
+        (w) => List.generate(30, (i) => w & (1 << i))
+            .where((f) => f != 0)
+            .toList(),
+        (u) => u.fold(0, (fs, f) => fs |= f),
+        ListSerializer(Case(ExtensionMemberDescriptorFlagTagger(),
+            convertFlagsMap(extensionMemberDescriptorFlagToName))));
 
 const Map<ExtensionMemberKind, String> extensionMemberKindToName = const {
   ExtensionMemberKind.Field: "field",
@@ -1976,13 +2065,11 @@
 }
 
 TextSerializer<ExtensionMemberKind> extensionMemberKindSerializer = Case(
-    ExtensionMemberKindTagger(),
-    Map.fromIterable(extensionMemberKindToName.entries,
-        key: (e) => e.value,
-        value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())));
+    ExtensionMemberKindTagger(), convertFlagsMap(extensionMemberKindToName));
 
 TextSerializer<ExtensionMemberDescriptor> extensionMemberDescriptorSerializer =
-    Wrapped(
+    Wrapped<Tuple4<Name, ExtensionMemberKind, int, CanonicalName>,
+            ExtensionMemberDescriptor>(
         (w) => Tuple4(w.name, w.kind, w.flags, w.member.canonicalName),
         (u) => ExtensionMemberDescriptor()
           ..name = u.first
@@ -1995,7 +2082,10 @@
             extensionMemberDescriptorFlagsSerializer,
             CanonicalNameSerializer()));
 
-TextSerializer<Extension> extensionSerializer = Wrapped(
+TextSerializer<Extension> extensionSerializer = Wrapped<
+        Tuple3<String, Tuple2<List<TypeParameter>, DartType>,
+            List<ExtensionMemberDescriptor>>,
+        Extension>(
     (w) => Tuple3(w.name, Tuple2(w.typeParameters, w.onType), w.members),
     (u) => Extension(
         name: u.first,
@@ -2135,3 +2225,15 @@
     "super": superInitializerSerializer,
   });
 }
+
+Map<String, Wrapped<void, T>> convertFlagsMap<T>(Map<T, String> map) {
+  return map.entries.toMap(
+      key: (e) => e.value,
+      value: (e) => Wrapped((_) => null, (_) => e.key, Nothing()));
+}
+
+extension MapFromIterable<E> on Iterable<E> {
+  Map<K, V> toMap<K, V>({K Function(E) key, V Function(E) value}) {
+    return {for (E e in this) key(e): value(e)};
+  }
+}
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 3900833..cf5e16f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -22,7 +22,6 @@
   static const asyncOp = ':async_op';
   static const asyncOpThen = ':async_op_then';
   static const asyncOpError = ':async_op_error';
-  static const asyncStackTraceVar = ':async_stack_trace';
   static const controller = ':controller';
   static const controllerStreamVar = ':controller_stream';
   static const forIterator = ':for-iterator';
@@ -342,7 +341,7 @@
 // This allows us to e.g. "shadow" the original parameter variables with copies
 // unique to given sub-closure to prevent shared variables being overwritten.
 class ShadowRewriter extends Transformer {
-  final enclosingFunction;
+  final FunctionNode enclosingFunction;
   Map<VariableDeclaration, VariableDeclaration> _shadowedParameters = {};
 
   ShadowRewriter(this.enclosingFunction) {
@@ -524,8 +523,6 @@
 }
 
 abstract class AsyncRewriterBase extends ContinuationRewriterBase {
-  final VariableDeclaration stackTraceVariable;
-
   // :async_op has type ([dynamic result, dynamic e, StackTrace? s]) -> dynamic
   final VariableDeclaration nestedClosureVariable;
 
@@ -541,9 +538,7 @@
 
   AsyncRewriterBase(HelperNodes helper, FunctionNode enclosingFunction,
       StaticTypeContext staticTypeContext)
-      : stackTraceVariable =
-            VariableDeclaration(ContinuationVariables.asyncStackTraceVar),
-        nestedClosureVariable = VariableDeclaration(
+      : nestedClosureVariable = VariableDeclaration(
             ContinuationVariables.asyncOp,
             type: FunctionType([
               const DynamicType(),
@@ -567,9 +562,6 @@
   void setupAsyncContinuations(List<Statement> statements) {
     expressionRewriter = new ExpressionLifter(this);
 
-    // var :async_stack_trace;
-    statements.add(stackTraceVariable);
-
     // var :async_op_then;
     statements.add(thenContinuationVariable);
 
@@ -609,13 +601,6 @@
           ..fileOffset = enclosingFunction.parent.fileOffset;
     statements.add(closureFunction);
 
-    // :async_stack_trace = _asyncStackTraceHelper(asyncBody);
-    final stackTrace = new StaticInvocation(helper.asyncStackTraceHelper,
-        new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]));
-    final stackTraceAssign = new ExpressionStatement(
-        new VariableSet(stackTraceVariable, stackTrace));
-    statements.add(stackTraceAssign);
-
     // :async_op_then = _asyncThenWrapperHelper(asyncBody);
     final boundThenClosure = new StaticInvocation(helper.asyncThenWrapper,
         new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]));
@@ -833,7 +818,8 @@
     // with await in the loop's variable initializers or update expressions.
     bool isSimple = true;
     int length = stmt.variables.length;
-    List<List<Statement>> initEffects = new List<List<Statement>>(length);
+    List<List<Statement>> initEffects =
+        new List<List<Statement>>.filled(length, null);
     for (int i = 0; i < length; ++i) {
       VariableDeclaration decl = stmt.variables[i];
       initEffects[i] = <Statement>[];
@@ -846,7 +832,8 @@
     }
 
     length = stmt.updates.length;
-    List<List<Statement>> updateEffects = new List<List<Statement>>(length);
+    List<List<Statement>> updateEffects =
+        new List<List<Statement>>.filled(length, null);
     for (int i = 0; i < length; ++i) {
       updateEffects[i] = <Statement>[];
       stmt.updates[i] = expressionRewriter.rewrite(
@@ -1404,7 +1391,6 @@
 class HelperNodes {
   final Procedure asyncErrorWrapper;
   final Library asyncLibrary;
-  final Procedure asyncStackTraceHelper;
   final Member asyncStarStreamControllerAdd;
   final Member asyncStarStreamControllerAddError;
   final Member asyncStarStreamControllerAddStream;
@@ -1442,7 +1428,6 @@
   HelperNodes._(
       this.asyncErrorWrapper,
       this.asyncLibrary,
-      this.asyncStackTraceHelper,
       this.asyncStarStreamControllerAdd,
       this.asyncStarStreamControllerAddError,
       this.asyncStarStreamControllerAddStream,
@@ -1480,7 +1465,6 @@
     return new HelperNodes._(
         coreTypes.asyncErrorWrapperHelperProcedure,
         coreTypes.asyncLibrary,
-        coreTypes.asyncStackTraceHelperProcedure,
         coreTypes.asyncStarStreamControllerAdd,
         coreTypes.asyncStarStreamControllerAddError,
         coreTypes.asyncStarStreamControllerAddStream,
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 7585b5c..f68a5b6 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -11,8 +11,8 @@
 
 // Parameter name used to track were widget constructor calls were made from.
 //
-// The parameter name contains a randomly generated hex string to avoid collision
-// with user generated parameters.
+// The parameter name contains a randomly generated hex string to avoid
+// collision with user generated parameters.
 const String _creationLocationParameterName =
     r'$creationLocationd_0dea112b090073317d4';
 
@@ -381,6 +381,9 @@
         isFinal: true,
         getterReference: clazz.reference.canonicalName
             ?.getChildFromFieldWithName(fieldName)
+            ?.reference,
+        setterReference: clazz.reference.canonicalName
+            ?.getChildFromFieldSetterWithName(fieldName)
             ?.reference);
     clazz.addField(locationField);
 
@@ -433,11 +436,12 @@
         // arguments but it is possible users could add classes with optional
         // positional arguments.
         //
-        // constructor.initializers.add(new AssertInitializer(new AssertStatement(
-        //   new IsExpression(
-        //       new VariableGet(variable), _locationClass.thisType),
-        //   conditionStartOffset: constructor.fileOffset,
-        //   conditionEndOffset: constructor.fileOffset,
+        // constructor.initializers.add(new AssertInitializer(
+        //   new AssertStatement(
+        //     new IsExpression(
+        //         new VariableGet(variable), _locationClass.thisType),
+        //     conditionStartOffset: constructor.fileOffset,
+        //     conditionEndOffset: constructor.fileOffset,
         // )));
       }
     }
@@ -569,7 +573,8 @@
           initializer: new NullLiteral());
       if (_hasNamedParameter(
           constructor.function, _creationLocationParameterName)) {
-        // Constructor was already rewritten. TODO(jacobr): is this case actually hit?
+        // Constructor was already rewritten.
+        // TODO(jacobr): is this case actually hit?
         return;
       }
       if (!_maybeAddNamedParameter(constructor.function, variable)) {
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index b9ca3949..4ec2480 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -34,11 +34,11 @@
 
 Map<TypeParameter, DartType> getUpperBoundSubstitutionMap(Class host) {
   if (host.typeParameters.isEmpty) return const <TypeParameter, DartType>{};
-  var result = <TypeParameter, DartType>{};
-  for (var parameter in host.typeParameters) {
+  Map<TypeParameter, DartType> result = <TypeParameter, DartType>{};
+  for (TypeParameter parameter in host.typeParameters) {
     result[parameter] = const DynamicType();
   }
-  for (var parameter in host.typeParameters) {
+  for (TypeParameter parameter in host.typeParameters) {
     result[parameter] = substitute(parameter.bound, result);
   }
   return result;
@@ -63,8 +63,8 @@
 DartType substituteDeep(
     DartType type, Map<TypeParameter, DartType> substitution) {
   if (substitution.isEmpty) return type;
-  var substitutor = new _DeepTypeSubstitutor(substitution);
-  var result = substitutor.visit(type);
+  _DeepTypeSubstitutor substitutor = new _DeepTypeSubstitutor(substitution);
+  DartType result = substitutor.visit(type);
   return substitutor.isInfinite ? null : result;
 }
 
@@ -93,37 +93,16 @@
   return new _FreeFunctionTypeVariableVisitor().visit(type);
 }
 
-/// Given a set of type variables, finds a substitution of those variables such
-/// that the two given types becomes equal, or returns `null` if no such
-/// substitution exists.
-///
-/// For example, unifying `List<T>` with `List<String>`, where `T` is a
-/// quantified variable, yields the substitution `T = String`.
-///
-/// If successful, this equation holds:
-///
-///     substitute(type1, substitution) == substitute(type2, substitution)
-///
-/// The unification can fail for two reasons:
-/// - incompatible types, e.g. `List<T>` cannot be unified with `Set<T>`.
-/// - infinite types: e.g. `T` cannot be unified with `List<T>` because it
-///   would create the infinite type `List<List<List<...>>>`.
-Map<TypeParameter, DartType> unifyTypes(
-    DartType type1, DartType type2, Set<TypeParameter> quantifiedVariables) {
-  var unifier = new _TypeUnification(type1, type2, quantifiedVariables);
-  return unifier.success ? unifier.substitution : null;
-}
-
 /// Generates a fresh copy of the given type parameters, with their bounds
 /// substituted to reference the new parameters.
 ///
 /// The returned object contains the fresh type parameter list as well as a
 /// mapping to be used for replacing other types to use the new type parameters.
 FreshTypeParameters getFreshTypeParameters(List<TypeParameter> typeParameters) {
-  var freshParameters = new List<TypeParameter>.generate(
+  List<TypeParameter> freshParameters = new List<TypeParameter>.generate(
       typeParameters.length, (i) => new TypeParameter(typeParameters[i].name),
       growable: true);
-  var map = <TypeParameter, DartType>{};
+  Map<TypeParameter, DartType> map = <TypeParameter, DartType>{};
   for (int i = 0; i < typeParameters.length; ++i) {
     map[typeParameters[i]] = new TypeParameterType.forAlphaRenaming(
         typeParameters[i], freshParameters[i]);
@@ -255,11 +234,11 @@
   /// been replaced by dynamic.
   static Substitution upperBoundForClass(Class class_) {
     if (class_.typeParameters.isEmpty) return _NullSubstitution.instance;
-    var upper = <TypeParameter, DartType>{};
-    for (var parameter in class_.typeParameters) {
+    Map<TypeParameter, DartType> upper = <TypeParameter, DartType>{};
+    for (TypeParameter parameter in class_.typeParameters) {
       upper[parameter] = const DynamicType();
     }
-    for (var parameter in class_.typeParameters) {
+    for (TypeParameter parameter in class_.typeParameters) {
       upper[parameter] = substitute(parameter.bound, upper);
     }
     return fromUpperAndLowerBounds(upper, {});
@@ -483,14 +462,14 @@
   Supertype visitSupertype(Supertype node) {
     if (node.typeArguments.isEmpty) return node;
     int before = useCounter;
-    var typeArguments = node.typeArguments.map(visit).toList();
+    List<DartType> typeArguments = node.typeArguments.map(visit).toList();
     if (useCounter == before) return node;
     return new Supertype(node.classNode, typeArguments);
   }
 
   NamedType visitNamedType(NamedType node) {
     int before = useCounter;
-    var type = visit(node.type);
+    DartType type = visit(node.type);
     if (useCounter == before) return node;
     return new NamedType(node.name, type, isRequired: node.isRequired);
   }
@@ -508,7 +487,7 @@
   DartType visitInterfaceType(InterfaceType node) {
     if (node.typeArguments.isEmpty) return node;
     int before = useCounter;
-    var typeArguments = node.typeArguments.map(visit).toList();
+    List<DartType> typeArguments = node.typeArguments.map(visit).toList();
     if (useCounter == before) return node;
     return new InterfaceType(node.classNode, node.nullability, typeArguments);
   }
@@ -523,7 +502,7 @@
   DartType visitTypedefType(TypedefType node) {
     if (node.typeArguments.isEmpty) return node;
     int before = useCounter;
-    var typeArguments = node.typeArguments.map(visit).toList();
+    List<DartType> typeArguments = node.typeArguments.map(visit).toList();
     if (useCounter == before) return node;
     return new TypedefType(node.typedefNode, node.nullability, typeArguments);
   }
@@ -554,19 +533,21 @@
         "Function type variables cannot be substituted while still attached "
         "to the function. Perform substitution on "
         "`FunctionType.withoutTypeParameters` instead.");
-    var inner = node.typeParameters.isEmpty ? this : newInnerEnvironment();
+    _TypeSubstitutor inner =
+        node.typeParameters.isEmpty ? this : newInnerEnvironment();
     int before = this.useCounter;
     // Invert the variance when translating parameters.
     inner.invertVariance();
-    var typeParameters = inner.freshTypeParameters(node.typeParameters);
-    var positionalParameters = node.positionalParameters.isEmpty
+    List<TypeParameter> typeParameters =
+        inner.freshTypeParameters(node.typeParameters);
+    List<DartType> positionalParameters = node.positionalParameters.isEmpty
         ? const <DartType>[]
         : node.positionalParameters.map(inner.visit).toList();
-    var namedParameters = node.namedParameters.isEmpty
+    List<NamedType> namedParameters = node.namedParameters.isEmpty
         ? const <NamedType>[]
         : node.namedParameters.map(inner.visitNamedType).toList();
     inner.invertVariance();
-    var returnType = inner.visit(node.returnType);
+    DartType returnType = inner.visit(node.returnType);
     DartType typedefType =
         node.typedefType == null ? null : inner.visit(node.typedefType);
     if (this.useCounter == before) return node;
@@ -578,7 +559,7 @@
   }
 
   void bumpCountersUntil(_TypeSubstitutor target) {
-    var node = this;
+    _TypeSubstitutor node = this;
     while (node != target) {
       ++node.useCounter;
       node = node.outer;
@@ -587,7 +568,7 @@
   }
 
   DartType getSubstitute(TypeParameter variable) {
-    var environment = this;
+    _TypeSubstitutor environment = this;
     while (environment != null) {
       DartType replacement = environment.lookup(variable, covariantContext);
       if (replacement != null) {
@@ -646,170 +627,6 @@
   }
 }
 
-class _TypeUnification {
-  // Acyclic invariant: There are no cycles in the map, that is, all types can
-  //   be resolved to finite types by substituting all contained type variables.
-  //
-  // The acyclic invariant holds everywhere except during cycle detection.
-  //
-  // It is not checked that the substitution satisfies the bound on the type
-  // parameter.
-  final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
-
-  /// Variables that may be assigned freely in order to obtain unification.
-  ///
-  /// These are sometimes referred to as existentially quantified variables.
-  final Set<TypeParameter> quantifiedVariables;
-
-  /// Variables that are bound by a function type inside one of the types.
-  /// These may not occur in a substitution, because these variables are not in
-  /// scope at the existentially quantified variables.
-  ///
-  /// For example, suppose we are trying to satisfy the equation:
-  ///
-  ///     ∃S. <E>(E, S) => E  =  <E>(E, E) => E
-  ///
-  /// That is, we must choose `S` such that the generic function type
-  /// `<E>(E, S) => E` becomes `<E>(E, E) => E`.  Choosing `S = E` is not a
-  /// valid solution, because `E` is not in scope where `S` is quantified.
-  /// The two function types cannot be unified.
-  final Set<TypeParameter> _universallyQuantifiedVariables =
-      new Set<TypeParameter>();
-
-  bool success = true;
-
-  _TypeUnification(DartType type1, DartType type2, this.quantifiedVariables) {
-    _unify(type1, type2);
-    if (success && substitution.length >= 2) {
-      for (var key in substitution.keys) {
-        substitution[key] = substituteDeep(substitution[key], substitution);
-      }
-    }
-  }
-
-  DartType _substituteHead(TypeParameterType type) {
-    for (int i = 0; i <= substitution.length; ++i) {
-      DartType nextType = substitution[type.parameter];
-      if (nextType == null) return type;
-      if (nextType is TypeParameterType) {
-        type = nextType;
-      } else {
-        return nextType;
-      }
-    }
-    // The cycle should have been found by _trySubstitution when the cycle
-    // was created.
-    throw 'Unexpected cycle found during unification';
-  }
-
-  bool _unify(DartType type1, DartType type2) {
-    if (!success) return false;
-    type1 = type1 is TypeParameterType ? _substituteHead(type1) : type1;
-    type2 = type2 is TypeParameterType ? _substituteHead(type2) : type2;
-    if (type1 is DynamicType && type2 is DynamicType) return true;
-    if (type1 is VoidType && type2 is VoidType) return true;
-    if (type1 is InvalidType && type2 is InvalidType) return true;
-    if (type1 is BottomType && type2 is BottomType) return true;
-    if (type1 is InterfaceType && type2 is InterfaceType) {
-      if (type1.classNode != type2.classNode ||
-          type1.nullability != type2.nullability) {
-        return _fail();
-      }
-      assert(type1.typeArguments.length == type2.typeArguments.length);
-      for (int i = 0; i < type1.typeArguments.length; ++i) {
-        if (!_unify(type1.typeArguments[i], type2.typeArguments[i])) {
-          return false;
-        }
-      }
-      return true;
-    }
-    if (type1 is FunctionType && type2 is FunctionType) {
-      if (type1.typeParameters.length != type2.typeParameters.length ||
-          type1.positionalParameters.length !=
-              type2.positionalParameters.length ||
-          type1.namedParameters.length != type2.namedParameters.length ||
-          type1.requiredParameterCount != type2.requiredParameterCount ||
-          type1.nullability != type2.nullability) {
-        return _fail();
-      }
-      // When unifying two generic functions, transform the equation like this:
-      //
-      //    ∃S. <E>(fn1) = <T>(fn2)
-      //      ==>
-      //    ∃S. ∀G. fn1[G/E] = fn2[G/T]
-      //
-      // That is, assume some fixed identical choice of type parameters for both
-      // functions and try to unify the instantiated function types.
-      assert(!type1.typeParameters.any(quantifiedVariables.contains));
-      assert(!type2.typeParameters.any(quantifiedVariables.contains));
-      var leftInstance = <TypeParameter, DartType>{};
-      var rightInstance = <TypeParameter, DartType>{};
-      for (int i = 0; i < type1.typeParameters.length; ++i) {
-        var instantiator = new TypeParameter(type1.typeParameters[i].name);
-        var instantiatorType = new TypeParameterType.forAlphaRenaming(
-            type1.typeParameters[i], instantiator);
-        leftInstance[type1.typeParameters[i]] = instantiatorType;
-        rightInstance[type2.typeParameters[i]] = instantiatorType;
-        _universallyQuantifiedVariables.add(instantiator);
-      }
-      for (int i = 0; i < type1.typeParameters.length; ++i) {
-        var left = substitute(type1.typeParameters[i].bound, leftInstance);
-        var right = substitute(type2.typeParameters[i].bound, rightInstance);
-        if (!_unify(left, right)) return false;
-      }
-      for (int i = 0; i < type1.positionalParameters.length; ++i) {
-        var left = substitute(type1.positionalParameters[i], leftInstance);
-        var right = substitute(type2.positionalParameters[i], rightInstance);
-        if (!_unify(left, right)) return false;
-      }
-      for (int i = 0; i < type1.namedParameters.length; ++i) {
-        if (type1.namedParameters[i].name != type2.namedParameters[i].name) {
-          return false;
-        }
-        var left = substitute(type1.namedParameters[i].type, leftInstance);
-        var right = substitute(type2.namedParameters[i].type, rightInstance);
-        if (!_unify(left, right)) return false;
-      }
-      var leftReturn = substitute(type1.returnType, leftInstance);
-      var rightReturn = substitute(type2.returnType, rightInstance);
-      if (!_unify(leftReturn, rightReturn)) return false;
-      return true;
-    }
-    if (type1 is TypeParameterType &&
-        type2 is TypeParameterType &&
-        type1.parameter == type2.parameter &&
-        type1.declaredNullability == type2.declaredNullability) {
-      return true;
-    }
-    if (type1 is TypeParameterType &&
-        quantifiedVariables.contains(type1.parameter)) {
-      return _trySubstitution(type1.parameter, type2);
-    }
-    if (type2 is TypeParameterType &&
-        quantifiedVariables.contains(type2.parameter)) {
-      return _trySubstitution(type2.parameter, type1);
-    }
-    return _fail();
-  }
-
-  bool _trySubstitution(TypeParameter variable, DartType type) {
-    if (containsTypeVariable(type, _universallyQuantifiedVariables)) {
-      return _fail();
-    }
-    // Set the plain substitution first and then generate the deep
-    // substitution to detect cycles.
-    substitution[variable] = type;
-    DartType deepSubstitute = substituteDeep(type, substitution);
-    if (deepSubstitute == null) return _fail();
-    substitution[variable] = deepSubstitute;
-    return true;
-  }
-
-  bool _fail() {
-    return success = false;
-  }
-}
-
 class _OccurrenceVisitor implements DartTypeVisitor<bool> {
   final Set<TypeParameter> variables;
 
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 2106e8e..0e24e6f 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -25,37 +25,38 @@
       : environment = new TypeEnvironment(coreTypes, hierarchy);
 
   void checkComponent(Component component) {
-    for (var library in component.libraries) {
+    for (Library library in component.libraries) {
       if (ignoreSdk && library.importUri.scheme == 'dart') continue;
-      for (var class_ in library.classes) {
+      for (Class class_ in library.classes) {
         hierarchy.forEachOverridePair(class_,
             (Member ownMember, Member superMember, bool isSetter) {
           checkOverride(class_, ownMember, superMember, isSetter);
         });
       }
     }
-    var visitor = new TypeCheckingVisitor(this, environment, hierarchy);
-    for (var library in component.libraries) {
+    TypeCheckingVisitor visitor =
+        new TypeCheckingVisitor(this, environment, hierarchy);
+    for (Library library in component.libraries) {
       currentLibrary = library;
       if (ignoreSdk && library.importUri.scheme == 'dart') continue;
-      for (var class_ in library.classes) {
+      for (Class class_ in library.classes) {
         currentThisType = coreTypes.thisInterfaceType(
             class_, class_.enclosingLibrary.nonNullable);
-        for (var field in class_.fields) {
+        for (Field field in class_.fields) {
           visitor.visitField(field);
         }
-        for (var constructor in class_.constructors) {
+        for (Constructor constructor in class_.constructors) {
           visitor.visitConstructor(constructor);
         }
-        for (var procedure in class_.procedures) {
+        for (Procedure procedure in class_.procedures) {
           visitor.visitProcedure(procedure);
         }
       }
       currentThisType = null;
-      for (var procedure in library.procedures) {
+      for (Procedure procedure in library.procedures) {
         visitor.visitProcedure(procedure);
       }
-      for (var field in library.fields) {
+      for (Field field in library.fields) {
         visitor.visitField(field);
       }
       currentLibrary = null;
@@ -63,14 +64,16 @@
   }
 
   DartType getterType(Class host, Member member) {
-    var hostType = hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
-    var substitution = Substitution.fromSupertype(hostType);
+    Supertype hostType =
+        hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
+    Substitution substitution = Substitution.fromSupertype(hostType);
     return substitution.substituteType(member.getterType);
   }
 
   DartType setterType(Class host, Member member) {
-    var hostType = hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
-    var substitution = Substitution.fromSupertype(hostType);
+    Supertype hostType =
+        hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
+    Substitution substitution = Substitution.fromSupertype(hostType);
     return substitution.substituteType(member.setterType, contravariant: true);
   }
 
@@ -141,9 +144,9 @@
   }
 
   Expression checkAndDowncastExpression(Expression from, DartType to) {
-    var parent = from.parent;
-    var type = visitExpression(from);
-    var result = checker.checkAndDowncastExpression(from, type, to);
+    TreeNode parent = from.parent;
+    DartType type = visitExpression(from);
+    Expression result = checker.checkAndDowncastExpression(from, type, to);
     result.parent = parent;
     return result;
   }
@@ -210,7 +213,7 @@
   }
 
   void handleFunctionNode(FunctionNode node) {
-    var oldAsyncMarker = currentAsyncMarker;
+    AsyncMarker oldAsyncMarker = currentAsyncMarker;
     currentAsyncMarker = node.asyncMarker;
     node.positionalParameters
         .skip(node.requiredParameterCount)
@@ -223,8 +226,8 @@
   }
 
   void handleNestedFunctionNode(FunctionNode node) {
-    var oldReturn = currentReturnType;
-    var oldYield = currentYieldType;
+    DartType oldReturn = currentReturnType;
+    DartType oldYield = currentYieldType;
     currentReturnType = _getInternalReturnType(node);
     currentYieldType = _getYieldType(node);
     handleFunctionNode(node);
@@ -241,7 +244,7 @@
 
   Substitution getReceiverType(
       TreeNode access, Expression receiver, Member member) {
-    var type = visitExpression(receiver);
+    DartType type = visitExpression(receiver);
     Class superclass = member.enclosingClass;
     if (superclass.supertype == null) {
       return Substitution.empty; // Members on Object are always accessible.
@@ -291,7 +294,7 @@
         fail(arguments, 'Too many positional arguments');
         return const BottomType();
       }
-      var typeArguments = arguments.types;
+      List<DartType> typeArguments = arguments.types;
       if (typeArguments.length != typeParameters.length) {
         fail(arguments, 'Wrong number of type arguments');
         return const BottomType();
@@ -300,18 +303,18 @@
           typeParameters, typeArguments, arguments,
           receiverSubstitution: receiver);
       for (int i = 0; i < arguments.positional.length; ++i) {
-        var expectedType = substitution.substituteType(
+        DartType expectedType = substitution.substituteType(
             functionType.positionalParameters[i],
             contravariant: true);
         arguments.positional[i] =
             checkAndDowncastExpression(arguments.positional[i], expectedType);
       }
       for (int i = 0; i < arguments.named.length; ++i) {
-        var argument = arguments.named[i];
+        NamedExpression argument = arguments.named[i];
         bool found = false;
         for (int j = 0; j < functionType.namedParameters.length; ++j) {
           if (argument.name == functionType.namedParameters[j].name) {
-            var expectedType = substitution.substituteType(
+            DartType expectedType = substitution.substituteType(
                 functionType.namedParameters[j].type,
                 contravariant: true);
             argument.value =
@@ -357,7 +360,7 @@
         while (parent is! FunctionNode) {
           parent = parent.parent;
         }
-        var enclosingFunction = parent as FunctionNode;
+        FunctionNode enclosingFunction = parent as FunctionNode;
         if (enclosingFunction.dartAsyncMarker == AsyncMarker.Sync) {
           parent = enclosingFunction.parent;
           while (parent is! FunctionNode) {
@@ -403,13 +406,14 @@
   Substitution _instantiateFunction(List<TypeParameter> typeParameters,
       List<DartType> typeArguments, TreeNode where,
       {Substitution receiverSubstitution}) {
-    var instantiation = Substitution.fromPairs(typeParameters, typeArguments);
-    var substitution = receiverSubstitution == null
+    Substitution instantiation =
+        Substitution.fromPairs(typeParameters, typeArguments);
+    Substitution substitution = receiverSubstitution == null
         ? instantiation
         : Substitution.combine(receiverSubstitution, instantiation);
     for (int i = 0; i < typeParameters.length; ++i) {
-      var argument = typeArguments[i];
-      var bound = substitution.substituteType(typeParameters[i].bound);
+      DartType argument = typeArguments[i];
+      DartType bound = substitution.substituteType(typeParameters[i].bound);
       checkAssignable(where, argument, bound);
     }
     return substitution;
@@ -484,7 +488,7 @@
 
   @override
   DartType visitLet(Let node) {
-    var value = visitExpression(node.variable.initializer);
+    DartType value = visitExpression(node.variable.initializer);
     if (node.variable.type is DynamicType) {
       node.variable.type = value;
     }
@@ -543,7 +547,7 @@
 
   @override
   DartType visitMapLiteral(MapLiteral node) {
-    for (var entry in node.entries) {
+    for (MapEntry entry in node.entries) {
       entry.key = checkAndDowncastExpression(entry.key, node.keyType);
       entry.value = checkAndDowncastExpression(entry.value, node.valueType);
     }
@@ -571,20 +575,20 @@
       fail(access, 'Wrong number of type arguments');
       return const BottomType();
     }
-    var instantiation =
+    Substitution instantiation =
         Substitution.fromPairs(function.typeParameters, arguments.types);
     for (int i = 0; i < arguments.positional.length; ++i) {
-      var expectedType = instantiation.substituteType(
+      DartType expectedType = instantiation.substituteType(
           function.positionalParameters[i],
           contravariant: true);
       arguments.positional[i] =
           checkAndDowncastExpression(arguments.positional[i], expectedType);
     }
     for (int i = 0; i < arguments.named.length; ++i) {
-      var argument = arguments.named[i];
-      var parameterType = function.getNamedParameter(argument.name);
+      NamedExpression argument = arguments.named[i];
+      DartType parameterType = function.getNamedParameter(argument.name);
       if (parameterType != null) {
-        var expectedType =
+        DartType expectedType =
             instantiation.substituteType(parameterType, contravariant: true);
         argument.value =
             checkAndDowncastExpression(argument.value, expectedType);
@@ -598,9 +602,9 @@
 
   @override
   DartType visitMethodInvocation(MethodInvocation node) {
-    var target = node.interfaceTarget;
+    Member target = node.interfaceTarget;
     if (target == null) {
-      var receiver = visitExpression(node.receiver);
+      DartType receiver = visitExpression(node.receiver);
       if (node.name.text == '==') {
         visitExpression(node.arguments.positional.single);
         return environment.coreTypes.boolLegacyRawType;
@@ -613,8 +617,8 @@
     } else if (target is Procedure &&
         environment.isSpecialCasedBinaryOperator(target)) {
       assert(node.arguments.positional.length == 1);
-      var receiver = visitExpression(node.receiver);
-      var argument = visitExpression(node.arguments.positional[0]);
+      DartType receiver = visitExpression(node.receiver);
+      DartType argument = visitExpression(node.arguments.positional[0]);
       return environment.getTypeOfSpecialCasedBinaryOperator(
           receiver, argument);
     } else {
@@ -626,27 +630,29 @@
   @override
   DartType visitPropertyGet(PropertyGet node) {
     if (node.interfaceTarget == null) {
-      final receiver = visitExpression(node.receiver);
+      final DartType receiver = visitExpression(node.receiver);
       checkUnresolvedInvocation(receiver, node);
       return const DynamicType();
     } else {
-      var receiver = getReceiverType(node, node.receiver, node.interfaceTarget);
+      Substitution receiver =
+          getReceiverType(node, node.receiver, node.interfaceTarget);
       return receiver.substituteType(node.interfaceTarget.getterType);
     }
   }
 
   @override
   DartType visitPropertySet(PropertySet node) {
-    var value = visitExpression(node.value);
+    DartType value = visitExpression(node.value);
     if (node.interfaceTarget != null) {
-      var receiver = getReceiverType(node, node.receiver, node.interfaceTarget);
+      Substitution receiver =
+          getReceiverType(node, node.receiver, node.interfaceTarget);
       checkAssignable(
           node.value,
           value,
           receiver.substituteType(node.interfaceTarget.setterType,
               contravariant: true));
     } else {
-      final receiver = visitExpression(node.receiver);
+      final DartType receiver = visitExpression(node.receiver);
       checkUnresolvedInvocation(receiver, node);
     }
     return value;
@@ -686,7 +692,7 @@
 
   @override
   DartType visitStaticSet(StaticSet node) {
-    var value = visitExpression(node.value);
+    DartType value = visitExpression(node.value);
     checkAssignable(node.value, value, node.target.setterType);
     return value;
   }
@@ -700,7 +706,7 @@
   @override
   DartType visitListConcatenation(ListConcatenation node) {
     DartType type =
-        environment.listType(node.typeArgument, currentLibrary.nonNullable);
+        environment.iterableType(node.typeArgument, currentLibrary.nonNullable);
     for (Expression part in node.lists) {
       DartType partType = visitExpression(part);
       checkAssignable(node, type, partType);
@@ -711,7 +717,7 @@
   @override
   DartType visitSetConcatenation(SetConcatenation node) {
     DartType type =
-        environment.setType(node.typeArgument, currentLibrary.nonNullable);
+        environment.iterableType(node.typeArgument, currentLibrary.nonNullable);
     for (Expression part in node.sets) {
       DartType partType = visitExpression(part);
       checkAssignable(node, type, partType);
@@ -770,16 +776,16 @@
       checkUnresolvedInvocation(currentThisType, node);
       return const DynamicType();
     } else {
-      var receiver = getSuperReceiverType(node.interfaceTarget);
+      Substitution receiver = getSuperReceiverType(node.interfaceTarget);
       return receiver.substituteType(node.interfaceTarget.getterType);
     }
   }
 
   @override
   DartType visitSuperPropertySet(SuperPropertySet node) {
-    var value = visitExpression(node.value);
+    DartType value = visitExpression(node.value);
     if (node.interfaceTarget != null) {
-      var receiver = getSuperReceiverType(node.interfaceTarget);
+      Substitution receiver = getSuperReceiverType(node.interfaceTarget);
       checkAssignable(
           node.value,
           value,
@@ -819,7 +825,7 @@
 
   @override
   DartType visitVariableSet(VariableSet node) {
-    var value = visitExpression(node.value);
+    DartType value = visitExpression(node.value);
     checkAssignable(node.value, value, node.variable.type);
     return value;
   }
@@ -881,7 +887,7 @@
 
   @override
   visitForInStatement(ForInStatement node) {
-    var iterable = visitExpression(node.iterable);
+    DartType iterable = visitExpression(node.iterable);
     // TODO(asgerf): Store interface targets on for-in loops or desugar them,
     // instead of doing the ad-hoc resolution here.
     if (node.isAsync) {
@@ -898,7 +904,7 @@
 
   DartType getIterableElementType(DartType iterable) {
     if (iterable is InterfaceType) {
-      var iteratorGetter =
+      Member iteratorGetter =
           hierarchy.getInterfaceMember(iterable.classNode, iteratorName);
       if (iteratorGetter == null) return const DynamicType();
       List<DartType> castedIterableArguments =
@@ -909,7 +915,7 @@
               castedIterableArguments)
           .substituteType(iteratorGetter.getterType);
       if (iteratorType is InterfaceType) {
-        var currentGetter =
+        Member currentGetter =
             hierarchy.getInterfaceMember(iteratorType.classNode, currentName);
         if (currentGetter == null) return const DynamicType();
         List<DartType> castedIteratorTypeArguments =
@@ -971,7 +977,7 @@
       if (currentReturnType == null) {
         fail(node, 'Return of a value from void method');
       } else {
-        var type = visitExpression(node.expression);
+        DartType type = visitExpression(node.expression);
         if (currentAsyncMarker == AsyncMarker.Async) {
           type = environment.flatten(type);
         }
@@ -983,7 +989,7 @@
   @override
   visitSwitchStatement(SwitchStatement node) {
     visitExpression(node.expression);
-    for (var switchCase in node.cases) {
+    for (SwitchCase switchCase in node.cases) {
       switchCase.expressions.forEach(visitExpression);
       visitStatement(switchCase.body);
     }
@@ -992,7 +998,7 @@
   @override
   visitTryCatch(TryCatch node) {
     visitStatement(node.body);
-    for (var catchClause in node.catches) {
+    for (Catch catchClause in node.catches) {
       visitStatement(catchClause.body);
     }
   }
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 3ab077d..0db1f2b 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -49,6 +49,8 @@
   final Set<Class> classes = new Set<Class>();
   final Set<Typedef> typedefs = new Set<Typedef>();
   Set<TypeParameter> typeParametersInScope = new Set<TypeParameter>();
+  Set<VariableDeclaration> variableDeclarationsInScope =
+      new Set<VariableDeclaration>();
   final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
   final Map<Typedef, TypedefState> typedefState = <Typedef, TypedefState>{};
   final Set<Constant> seenConstants = <Constant>{};
@@ -119,7 +121,7 @@
           " but found: '${node.parent.runtimeType}'.",
           context: currentParent);
     }
-    var oldParent = currentParent;
+    TreeNode oldParent = currentParent;
     currentParent = node;
     return oldParent;
   }
@@ -138,7 +140,7 @@
   }
 
   void visitChildren(TreeNode node) {
-    var oldParent = enterParent(node);
+    TreeNode oldParent = enterParent(node);
     node.visitChildren(this);
     exitParent(oldParent);
   }
@@ -162,20 +164,20 @@
   }
 
   void declareVariable(VariableDeclaration variable) {
-    if (variable.flags & VariableDeclaration.FlagInScope != 0) {
+    if (variableDeclarationsInScope.contains(variable)) {
       problem(variable, "Variable '$variable' declared more than once.");
     }
-    variable.flags |= VariableDeclaration.FlagInScope;
+    variableDeclarationsInScope.add(variable);
     variableStack.add(variable);
   }
 
   void undeclareVariable(VariableDeclaration variable) {
-    variable.flags &= ~VariableDeclaration.FlagInScope;
+    variableDeclarationsInScope.remove(variable);
   }
 
   void declareTypeParameters(List<TypeParameter> parameters) {
     for (int i = 0; i < parameters.length; ++i) {
-      var parameter = parameters[i];
+      TypeParameter parameter = parameters[i];
       if (parameter.bound == null) {
         problem(
             currentParent, "Missing bound for type parameter '$parameter'.");
@@ -195,34 +197,34 @@
   }
 
   void checkVariableInScope(VariableDeclaration variable, TreeNode where) {
-    if (variable.flags & VariableDeclaration.FlagInScope == 0) {
+    if (!variableDeclarationsInScope.contains(variable)) {
       problem(where, "Variable '$variable' used out of scope.");
     }
   }
 
   visitComponent(Component component) {
     try {
-      for (var library in component.libraries) {
-        for (var class_ in library.classes) {
+      for (Library library in component.libraries) {
+        for (Class class_ in library.classes) {
           if (!classes.add(class_)) {
             problem(class_, "Class '$class_' declared more than once.");
           }
         }
-        for (var typedef_ in library.typedefs) {
+        for (Typedef typedef_ in library.typedefs) {
           if (!typedefs.add(typedef_)) {
             problem(typedef_, "Typedef '$typedef_' declared more than once.");
           }
         }
         library.members.forEach(declareMember);
-        for (var class_ in library.classes) {
+        for (Class class_ in library.classes) {
           class_.members.forEach(declareMember);
         }
       }
       visitChildren(component);
     } finally {
-      for (var library in component.libraries) {
+      for (Library library in component.libraries) {
         library.members.forEach(undeclareMember);
-        for (var class_ in library.classes) {
+        for (Class class_ in library.classes) {
           class_.members.forEach(undeclareMember);
         }
       }
@@ -238,23 +240,23 @@
 
   visitExtension(Extension node) {
     declareTypeParameters(node.typeParameters);
-    final oldParent = enterParent(node);
+    final TreeNode oldParent = enterParent(node);
     node.visitChildren(this);
     exitParent(oldParent);
     undeclareTypeParameters(node.typeParameters);
   }
 
   void checkTypedef(Typedef node) {
-    var state = typedefState[node];
+    TypedefState state = typedefState[node];
     if (state == TypedefState.Done) return;
     if (state == TypedefState.BeingChecked) {
       problem(node, "The typedef '$node' refers to itself", context: node);
     }
     assert(state == null);
     typedefState[node] = TypedefState.BeingChecked;
-    var savedTypeParameters = typeParametersInScope;
+    Set<TypeParameter> savedTypeParameters = typeParametersInScope;
     typeParametersInScope = node.typeParameters.toSet();
-    var savedParent = currentParent;
+    TreeNode savedParent = currentParent;
     currentParent = node;
     // Visit children without checking the parent pointer on the typedef itself
     // since this can be called from a context other than its true parent.
@@ -272,7 +274,7 @@
 
   visitField(Field node) {
     currentMember = node;
-    var oldParent = enterParent(node);
+    TreeNode oldParent = enterParent(node);
     bool isTopLevel = node.parent == currentLibrary;
     if (isTopLevel && !node.isStatic) {
       problem(node, "The top-level field '${node.name.text}' should be static",
@@ -293,7 +295,7 @@
 
   visitProcedure(Procedure node) {
     currentMember = node;
-    var oldParent = enterParent(node);
+    TreeNode oldParent = enterParent(node);
     classTypeParametersAreInScope = !node.isStatic;
     if (node.isAbstract && node.isExternal) {
       problem(node, "Procedure cannot be both abstract and external.");
@@ -346,7 +348,7 @@
     classTypeParametersAreInScope = true;
     // The constructor member needs special treatment due to parameters being
     // in scope in the initializer list.
-    var oldParent = enterParent(node);
+    TreeNode oldParent = enterParent(node);
     int stackHeight = enterLocalScope();
     visitChildren(node.function);
     visitList(node.initializers, this);
@@ -364,7 +366,7 @@
   visitClass(Class node) {
     currentClass = node;
     declareTypeParameters(node.typeParameters);
-    var oldParent = enterParent(node);
+    TreeNode oldParent = enterParent(node);
     classTypeParametersAreInScope = false;
     visitList(node.annotations, this);
     classTypeParametersAreInScope = true;
@@ -397,7 +399,7 @@
       }
     }
     declareTypeParameters(node.typeParameters);
-    for (var typeParameter in node.typeParameters) {
+    for (TypeParameter typeParameter in node.typeParameters) {
       typeParameter.bound?.accept(this);
       if (typeParameter.annotations.isNotEmpty) {
         problem(
@@ -458,8 +460,10 @@
         break;
       case AsyncMarker.SyncStar:
       case AsyncMarker.AsyncStar:
-        problem(node,
-            "Return statement in function with async marker: $currentAsyncMarker");
+        problem(
+            node,
+            "Return statement in function with async marker: "
+            "$currentAsyncMarker");
         break;
     }
     super.visitReturnStatement(node);
@@ -470,8 +474,10 @@
     switch (currentAsyncMarker) {
       case AsyncMarker.Sync:
       case AsyncMarker.Async:
-        problem(node,
-            "Yield statement in function with async marker: $currentAsyncMarker");
+        problem(
+            node,
+            "Yield statement in function with async marker: "
+            "$currentAsyncMarker");
         break;
       case AsyncMarker.SyncStar:
       case AsyncMarker.AsyncStar:
@@ -490,7 +496,7 @@
   }
 
   visitVariableDeclaration(VariableDeclaration node) {
-    var parent = node.parent;
+    TreeNode parent = node.parent;
     if (parent is! Block &&
         !(parent is Catch && parent.body != node) &&
         !(parent is FunctionNode && parent.body != node) &&
@@ -638,7 +644,7 @@
     }
     namedLoop:
     for (int i = 0; i < arguments.named.length; ++i) {
-      var argument = arguments.named[i];
+      NamedExpression argument = arguments.named[i];
       String name = argument.name;
       for (int j = 0; j < function.namedParameters.length; ++j) {
         if (function.namedParameters[j].name == name) continue namedLoop;
@@ -771,7 +777,7 @@
 
   @override
   visitTypeParameterType(TypeParameterType node) {
-    var parameter = node.parameter;
+    TypeParameter parameter = node.parameter;
     if (!typeParametersInScope.contains(parameter)) {
       problem(
           currentParent,
@@ -811,6 +817,7 @@
       }
       problem(currentParent, "Type $node references an anonymous mixin class.");
     }
+    defaultDartType(node);
   }
 
   @override
@@ -904,7 +911,7 @@
           "is '${node.parent.runtimeType}' "
           "but should be '${parent.runtimeType}'.");
     }
-    var oldParent = parent;
+    TreeNode oldParent = parent;
     parent = node;
     node.visitChildren(this);
     parent = oldParent;
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 1fec5a3..fdabdc6 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -414,7 +414,8 @@
 
   /// Visits [node] if not already visited to compute a value for [node].
   ///
-  /// If the value has already been computed the cached value is returned immediately.
+  /// If the value has already been computed the cached value is returned
+  /// immediately.
   ///
   /// Call this method to compute values for subnodes recursively, while only
   /// visiting each subnode once.
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index fb52988..8bb1bac 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -10,8 +10,11 @@
 
 class VmConstantsBackend extends ConstantsBackend {
   final Class immutableMapClass;
+  final Class unmodifiableSetClass;
+  final Field unmodifiableSetMap;
 
-  VmConstantsBackend._(this.immutableMapClass);
+  VmConstantsBackend._(this.immutableMapClass, this.unmodifiableSetMap,
+      this.unmodifiableSetClass);
 
   /// If [defines] is not `null` it will be used for handling
   /// `const {bool,...}.fromEnvironment()` otherwise the current VM's values
@@ -21,8 +24,11 @@
     final Class immutableMapClass = coreLibrary.classes
         .firstWhere((Class klass) => klass.name == '_ImmutableMap');
     assert(immutableMapClass != null);
+    Field unmodifiableSetMap = coreTypes.index
+        .getMember('dart:collection', '_UnmodifiableSet', '_map');
 
-    return new VmConstantsBackend._(immutableMapClass);
+    return new VmConstantsBackend._(immutableMapClass, unmodifiableSetMap,
+        unmodifiableSetMap.enclosingClass);
   }
 
   @override
@@ -30,7 +36,7 @@
     // The _ImmutableMap class is implemented via one field pointing to a list
     // of key/value pairs -- see runtime/lib/immutable_map.dart!
     final List<Constant> kvListPairs =
-        new List<Constant>(2 * constant.entries.length);
+        new List<Constant>.filled(2 * constant.entries.length, null);
     for (int i = 0; i < constant.entries.length; i++) {
       final ConstantMapEntry entry = constant.entries[i];
       kvListPairs[2 * i] = entry.key;
@@ -38,7 +44,8 @@
     }
     // This is a bit fishy, since we merge the key and the value type by
     // putting both into the same list.
-    final kvListConstant = new ListConstant(const DynamicType(), kvListPairs);
+    final ListConstant kvListConstant =
+        new ListConstant(const DynamicType(), kvListPairs);
     assert(immutableMapClass.fields.length == 1);
     final Field kvPairListField = immutableMapClass.fields[0];
     return new InstanceConstant(immutableMapClass.reference, <DartType>[
@@ -49,4 +56,63 @@
       kvPairListField.getterReference: kvListConstant,
     });
   }
+
+  @override
+  bool isLoweredMapConstant(Constant constant) {
+    return constant is InstanceConstant &&
+        constant.classNode == immutableMapClass;
+  }
+
+  @override
+  void forEachLoweredMapConstantEntry(
+      Constant constant, void Function(Constant key, Constant value) f) {
+    assert(isLoweredMapConstant(constant));
+    final InstanceConstant instance = constant;
+    assert(immutableMapClass.fields.length == 1);
+    final Field kvPairListField = immutableMapClass.fields[0];
+    final ListConstant kvListConstant =
+        instance.fieldValues[kvPairListField.getterReference];
+    assert(kvListConstant.entries.length % 2 == 0);
+    for (int index = 0; index < kvListConstant.entries.length; index += 2) {
+      f(kvListConstant.entries[index], kvListConstant.entries[index + 1]);
+    }
+  }
+
+  @override
+  Constant lowerSetConstant(SetConstant constant) {
+    final DartType elementType = constant.typeArgument;
+    final List<Constant> entries = constant.entries;
+    final List<ConstantMapEntry> mapEntries =
+        new List<ConstantMapEntry>.filled(entries.length, null);
+    for (int i = 0; i < entries.length; ++i) {
+      mapEntries[i] = new ConstantMapEntry(entries[i], new NullConstant());
+    }
+    Constant map = lowerMapConstant(
+        new MapConstant(elementType, const NullType(), mapEntries));
+    return new InstanceConstant(unmodifiableSetClass.reference, [elementType],
+        <Reference, Constant>{unmodifiableSetMap.getterReference: map});
+  }
+
+  @override
+  bool isLoweredSetConstant(Constant constant) {
+    if (constant is InstanceConstant &&
+        constant.classNode == unmodifiableSetClass) {
+      InstanceConstant instance = constant;
+      return isLoweredMapConstant(
+          instance.fieldValues[unmodifiableSetMap.getterReference]);
+    }
+    return false;
+  }
+
+  @override
+  void forEachLoweredSetConstantElement(
+      Constant constant, void Function(Constant element) f) {
+    assert(isLoweredSetConstant(constant));
+    final InstanceConstant instance = constant;
+    final Constant mapConstant =
+        instance.fieldValues[unmodifiableSetMap.getterReference];
+    forEachLoweredMapConstantEntry(mapConstant, (Constant key, Constant value) {
+      f(key);
+    });
+  }
 }
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 1732869..3609233 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -6,9 +6,10 @@
 publish_to: none
 
 environment:
-  sdk: '>=2.2.2 <3.0.0'
+  sdk: '>=2.6.0 <3.0.0'
 dependencies:
-  meta: ^1.0.0
+  meta:
+    path: ../meta
 dev_dependencies:
   args: '>=0.13.4 <2.0.0'
   expect:
diff --git a/pkg/kernel/test/binary/can_read_platform_test.dart b/pkg/kernel/test/binary/can_read_platform_test.dart
new file mode 100644
index 0000000..4984a0b
--- /dev/null
+++ b/pkg/kernel/test/binary/can_read_platform_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:kernel/binary/ast_from_binary.dart';
+import 'package:kernel/kernel.dart';
+
+main() {
+  File exe = new File(Platform.resolvedExecutable).absolute;
+  int steps = 0;
+  Directory parent = exe.parent.parent;
+  while (true) {
+    Set<String> foundDirs = {};
+    for (FileSystemEntity entry in parent.listSync(recursive: false)) {
+      if (entry is Directory) {
+        List<String> pathSegments = entry.uri.pathSegments;
+        String name = pathSegments[pathSegments.length - 2];
+        foundDirs.add(name);
+      }
+    }
+    if (foundDirs.contains("pkg") &&
+        foundDirs.contains("tools") &&
+        foundDirs.contains("tests")) {
+      break;
+    }
+    steps++;
+    if (parent.uri == parent.parent.uri) {
+      throw "Reached end without finding the root.";
+    }
+    parent = parent.parent;
+  }
+  // We had to go $steps steps to reach the "root" --- now we should go 2 steps
+  // shorter to be in the "compiled dir".
+  parent = exe.parent;
+  for (int i = steps - 2; i >= 0; i--) {
+    parent = parent.parent;
+  }
+
+  List<File> dills = [];
+  for (FileSystemEntity entry in parent.listSync(recursive: false)) {
+    if (entry is File) {
+      if (entry.path.toLowerCase().endsWith(".dill")) {
+        dills.add(entry);
+      }
+    }
+  }
+  Directory sdk = new Directory.fromUri(parent.uri.resolve("dart-sdk/"));
+  for (FileSystemEntity entry in sdk.listSync(recursive: true)) {
+    if (entry is File) {
+      if (entry.path.toLowerCase().endsWith(".dill")) {
+        dills.add(entry);
+      }
+    }
+  }
+
+  print("Found ${dills.length} dills!");
+
+  List<File> errors = [];
+  for (File dill in dills) {
+    if (!canRead(dill)) {
+      errors.add(dill);
+    }
+  }
+  if (errors.isEmpty) {
+    print("Read all OK.");
+  } else {
+    print("Errors when reading:");
+    for (File error in errors) {
+      print(error);
+    }
+    exitCode = 1;
+  }
+}
+
+bool canRead(File dill) {
+  print("Reading $dill");
+  List<int> bytes = dill.readAsBytesSync();
+
+  try {
+    Component component = new Component();
+    new BinaryBuilderWithMetadata(bytes).readComponent(component);
+    int libs = component.libraries.length;
+
+    component = new Component();
+    new BinaryBuilder(bytes).readComponent(component);
+    if (libs != component.libraries.length) {
+      throw "Didn't get the same number of libraries: $libs when reading with "
+          "BinaryBuilderWithMetadata and ${component.libraries.length} "
+          "when reading with BinaryBuilder";
+    }
+
+    return true;
+  } catch (e, st) {
+    print("Error for $dill:");
+    print(e);
+    print(st);
+    print("");
+    print("--------------------");
+    print("");
+    return false;
+  }
+}
diff --git a/pkg/kernel/test/binary_bench.dart b/pkg/kernel/test/binary_bench.dart
index 18c7610..a30296a 100644
--- a/pkg/kernel/test/binary_bench.dart
+++ b/pkg/kernel/test/binary_bench.dart
@@ -61,7 +61,7 @@
   }
   final warmupUs = sw.elapsedMicroseconds / warmupIterations;
 
-  final runsUs = new List<int>(benchmarkIterations);
+  final runsUs = new List<int>.filled(benchmarkIterations, null);
   for (var i = 0; i < benchmarkIterations; i++) {
     sw.reset();
     _fromBinary(bytes, eager: eager);
@@ -85,7 +85,7 @@
   }
   final warmupUs = sw.elapsedMicroseconds / warmupIterations;
 
-  final runsUs = new List<int>(benchmarkIterations);
+  final runsUs = new List<int>.filled(benchmarkIterations, null);
   for (var i = 0; i < benchmarkIterations; i++) {
     sw.reset();
     _toBinary(p);
diff --git a/pkg/kernel/test/class_hierarchy_bench.dart b/pkg/kernel/test/class_hierarchy_bench.dart
index 8168813..0026781 100644
--- a/pkg/kernel/test/class_hierarchy_bench.dart
+++ b/pkg/kernel/test/class_hierarchy_bench.dart
@@ -243,7 +243,7 @@
     classIds[class_] = classIds.length;
   }
 
-  List<int> depth = new List(classes.length);
+  List<int> depth = new List.filled(classes.length, null);
   for (int i = 0; i < depth.length; ++i) {
     int parentDepth = 0;
     var classNode = classes[i];
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index bd0ad7a..bf078f8 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -453,7 +453,8 @@
 ''');
 
     // The documentation says:
-    // It is possible for two methods to override one another in both directions.
+    // It is possible for two methods to override one another in both
+    // directions.
     _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
   }
 
@@ -1227,12 +1228,12 @@
     void callback(
         Member declaredMember, Member interfaceMember, bool isSetter) {
       var suffix = isSetter ? '=' : '';
-      String declaredName =
-          '${qualifiedMemberNameToString(declaredMember, includeLibraryName: true)}'
-          '$suffix';
-      String interfaceName =
-          '${qualifiedMemberNameToString(interfaceMember, includeLibraryName: true)}'
-          '$suffix';
+      String declaredMemberName =
+          qualifiedMemberNameToString(declaredMember, includeLibraryName: true);
+      String declaredName = '${declaredMemberName}$suffix';
+      String interfaceMemberName = qualifiedMemberNameToString(interfaceMember,
+          includeLibraryName: true);
+      String interfaceName = '${interfaceMemberName}$suffix';
       var desc = '$declaredName overrides $interfaceName';
       overrideDescriptions.add(desc);
     }
diff --git a/pkg/kernel/test/dart_type_equivalence_test.dart b/pkg/kernel/test/dart_type_equivalence_test.dart
index 4f27768..462c637 100644
--- a/pkg/kernel/test/dart_type_equivalence_test.dart
+++ b/pkg/kernel/test/dart_type_equivalence_test.dart
@@ -169,8 +169,9 @@
     bool equateTopTypes = false,
     bool ignoreAllNullabilities = false,
     bool ignoreTopLevelNullability = false}) {
-  Env env = new Env("typedef Typedef<T> () -> T;\n")
-    ..extendWithTypeParameters(typeParameters);
+  Env env =
+      new Env("typedef Typedef<T> () -> T;\n", isNonNullableByDefault: true)
+        ..extendWithTypeParameters(typeParameters);
   DartType t1 = env.parseType(type1);
   DartType t2 = env.parseType(type2);
 
@@ -208,8 +209,9 @@
     bool equateTopTypes = false,
     bool ignoreAllNullabilities = false,
     bool ignoreTopLevelNullability = false}) {
-  Env env = new Env("typedef Typedef<T> () -> T;\n")
-    ..extendWithTypeParameters(typeParameters);
+  Env env =
+      new Env("typedef Typedef<T> () -> T;\n", isNonNullableByDefault: true)
+        ..extendWithTypeParameters(typeParameters);
   DartType t1 = env.parseType(type1);
   DartType t2 = env.parseType(type2);
 
diff --git a/pkg/kernel/test/flatten_test.dart b/pkg/kernel/test/flatten_test.dart
index ab6c1ee..6983445 100644
--- a/pkg/kernel/test/flatten_test.dart
+++ b/pkg/kernel/test/flatten_test.dart
@@ -66,13 +66,14 @@
 }
 
 main() {
-  Env env = new Env('');
+  Env env = new Env('', isNonNullableByDefault: true);
   ClassHierarchy classHierarchy =
       new ClassHierarchy(env.component, env.coreTypes);
   TypeEnvironment typeEnvironment =
       new TypeEnvironment(env.coreTypes, classHierarchy);
   data.forEach((Test test) {
-    env.withTypeParameters(test.typeParameters, () {
+    env.withTypeParameters(test.typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
       String input = test.input;
       String output = test.output;
       DartType inputType = env.parseType(input);
diff --git a/pkg/kernel/test/future_value_type_test.dart b/pkg/kernel/test/future_value_type_test.dart
index 5c0f032..8a7bfac 100644
--- a/pkg/kernel/test/future_value_type_test.dart
+++ b/pkg/kernel/test/future_value_type_test.dart
@@ -68,7 +68,7 @@
 };
 
 main() {
-  Env env = new Env('')
+  Env env = new Env('', isNonNullableByDefault: true)
     ..extendWithTypeParameters('X,'
         'X_extends_FutureInt extends Future<int>,'
         'X_extends_FutureOrInt extends FutureOr<int>');
diff --git a/pkg/kernel/test/import_table_test.dart b/pkg/kernel/test/import_table_test.dart
index d02207f..daef20e 100644
--- a/pkg/kernel/test/import_table_test.dart
+++ b/pkg/kernel/test/import_table_test.dart
@@ -1,7 +1,7 @@
 import 'package:kernel/import_table.dart';
 
 main() {
-  List<String> paths = new List<String>();
+  List<String> paths = <String>[];
   paths.add("file://");
   paths.add("file:///a");
   paths.add("file:///a/b");
diff --git a/pkg/kernel/test/legacy_erasure_test.dart b/pkg/kernel/test/legacy_erasure_test.dart
index 4757d00..0a0902b 100644
--- a/pkg/kernel/test/legacy_erasure_test.dart
+++ b/pkg/kernel/test/legacy_erasure_test.dart
@@ -54,11 +54,11 @@
 };
 
 main() {
-  Env env = new Env('');
+  Env env = new Env('', isNonNullableByDefault: true);
   data.forEach((String input, String output) {
     DartType inputType = env.parseType(input);
     DartType expectedOutputType = env.parseType(output);
-    DartType actualOutputType = legacyErasure(env.coreTypes, inputType);
+    DartType actualOutputType = legacyErasure(inputType);
     print('legacyErasure($inputType) = $actualOutputType: $expectedOutputType');
     Expect.equals(
         expectedOutputType,
diff --git a/pkg/kernel/test/load_concat_dill_keeps_source_test.dart b/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
index 05bbc05..a888455 100644
--- a/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
+++ b/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
@@ -53,7 +53,7 @@
   List<int> partial2Serialized = serialize(cPartial2);
   expectSource(partial2Serialized, false, true);
 
-  List<int> combined = new List<int>();
+  List<int> combined = <int>[];
   combined.addAll(partial1Serialized);
   combined.addAll(partial2Serialized);
   expectSource(combined, true, true);
@@ -83,7 +83,7 @@
   SimpleSink sink = new SimpleSink();
   BinaryPrinter printerWhole = new BinaryPrinter(sink);
   printerWhole.writeComponentFile(c);
-  List<int> result = new List<int>();
+  List<int> result = <int>[];
   for (List<int> chunk in sink.chunks) {
     result.addAll(chunk);
   }
diff --git a/pkg/kernel/test/nnbd_top_merge_test.dart b/pkg/kernel/test/nnbd_top_merge_test.dart
index 4eb5d40..bd82a7e 100644
--- a/pkg/kernel/test/nnbd_top_merge_test.dart
+++ b/pkg/kernel/test/nnbd_top_merge_test.dart
@@ -111,7 +111,7 @@
 };
 
 main() {
-  Env env = new Env('');
+  Env env = new Env('', isNonNullableByDefault: true);
   data.forEach((String input, dynamic output) {
     List<String> parts = input.split(' vs ');
     DartType aType = env.parseType(parts[0]);
diff --git a/pkg/kernel/test/non_null_test.dart b/pkg/kernel/test/non_null_test.dart
index 77750c8..d9a04aa 100644
--- a/pkg/kernel/test/non_null_test.dart
+++ b/pkg/kernel/test/non_null_test.dart
@@ -40,13 +40,18 @@
   'FutureOr<Object*>*': 'FutureOr<Object>',
   'FutureOr<FutureOr<Object?>>': 'FutureOr<FutureOr<Object>>',
   '(List<Object>, {required List<Object> a, List<Object> b}) -> List<Object>':
-      '(List<Object>, {required List<Object> a, List<Object> b}) -> List<Object>',
+      '(List<Object>, {required List<Object> a, List<Object> b})'
+          ' -> List<Object>',
   '(List<Object>, {required List<Object> a, List<Object> b}) ->? List<Object>':
-      '(List<Object>, {required List<Object> a, List<Object> b}) -> List<Object>',
+      '(List<Object>, {required List<Object> a, List<Object> b})'
+          ' -> List<Object>',
   '(List<Object>, {required List<Object> a, List<Object> b}) ->* List<Object>':
-      '(List<Object>, {required List<Object> a, List<Object> b}) -> List<Object>',
-  '(List<Object>?, {required List<Object?> a, List<Object?>? b}) ->? List<Object?>':
-      '(List<Object>?, {required List<Object?> a, List<Object?>? b}) -> List<Object?>',
+      '(List<Object>, {required List<Object> a, List<Object> b})'
+          ' -> List<Object>',
+  '(List<Object>?, {required List<Object?> a, List<Object?>? b})'
+          ' ->? List<Object?>':
+      '(List<Object>?, {required List<Object?> a, List<Object?>? b})'
+          ' -> List<Object?>',
   'X': 'X & Object',
   'X?': 'X & Object',
   'X*': 'X & Object',
@@ -73,7 +78,7 @@
 };
 
 main() {
-  Env env = new Env('')
+  Env env = new Env('', isNonNullableByDefault: true)
     ..extendWithTypeParameters('X,'
         'X_extends_Object extends Object,'
         'X_extends_dynamic extends dynamic,'
diff --git a/pkg/kernel/test/norm_test.dart b/pkg/kernel/test/norm_test.dart
index b8a5f3e..c287025 100644
--- a/pkg/kernel/test/norm_test.dart
+++ b/pkg/kernel/test/norm_test.dart
@@ -143,7 +143,8 @@
 }
 
 check(String input, String output, [String typeParameters = '']) {
-  Env env = new Env('')..extendWithTypeParameters(typeParameters);
+  Env env = new Env('', isNonNullableByDefault: true)
+    ..extendWithTypeParameters(typeParameters);
   DartType inputType = env.parseType(input);
   DartType expectedOutputType = env.parseType(output);
   DartType actualOutputType = norm(env.coreTypes, inputType);
diff --git a/pkg/kernel/test/text_serializer_test.dart b/pkg/kernel/test/text_serializer_test.dart
index f4b3631..521aca4 100644
--- a/pkg/kernel/test/text_serializer_test.dart
+++ b/pkg/kernel/test/text_serializer_test.dart
@@ -83,8 +83,8 @@
     test('(const-list (dynamic) ((int 0) (int 1) (int 2)))');
     test('(set (dynamic) ((bool true) (bool false) (int 0)))');
     test('(const-set (dynamic) ((int 0) (int 1) (int 2)))');
-    test(
-        '(map (dynamic) (void) ((int 0) (null) (int 1) (null) (int 2) (null)))');
+    test('(map (dynamic) (void)'
+        ' ((int 0) (null) (int 1) (null) (int 2) (null)))');
     test('(const-map (dynamic) (void) ((int 0) (null) (int 1) (null) '
         '(int 2) (null)))');
     test('(type (-> () () () ((dynamic)) () () (dynamic)))');
diff --git a/pkg/kernel/test/type_hashcode_test.dart b/pkg/kernel/test/type_hashcode_test.dart
index 468deb6..b988507 100644
--- a/pkg/kernel/test/type_hashcode_test.dart
+++ b/pkg/kernel/test/type_hashcode_test.dart
@@ -3,9 +3,79 @@
 // BSD-style license that can be found in the LICENSE file.
 import 'package:kernel/kernel.dart';
 import 'type_parser.dart';
-import 'type_unification_test.dart' show testCases;
 import 'package:test/test.dart';
 
+final List<TestCase> testCases = <TestCase>[
+  successCase('List<T>', 'List<String>', {'T': 'String'}),
+  successCase('List<String>', 'List<T>', {'T': 'String'}),
+  successCase('List<T>', 'List<T>', {'T': null}),
+  successCase('List<S>', 'List<T>', {'S': 'T'}),
+  successCase('List<S>', 'List<T>', {'T': 'S'}),
+  successCase(
+      'List<S>', 'List<T>', {'S': 'T', 'T': null}), // Require left bias.
+  failureCase('List<S>', 'List<T>', []),
+
+  failureCase('List<T>', 'T', ['T']),
+  failureCase('List<List<T>>', 'List<T>', ['T']),
+  failureCase('Map<S, T>', 'Map<List<T>, List<S>>', ['T', 'S']),
+
+  failureCase('Map<Map<S,String>, Map<int,S>>',
+      'Map<Map<int, S>, Map<S, String>>', ['S']),
+  successCase('Map<Map<S, int>, Map<int, S>>', 'Map<Map<int, S>, Map<S, int>>',
+      {'S': 'int'}),
+  successCase('Map<Map<S, String>, Map<int, T>>',
+      'Map<Map<int, T>, Map<S, String>>', {'S': 'int', 'T': 'String'}),
+
+  successCase('Map<S, List<T>>', 'Map<T, List<S>>', {'S': 'T'}),
+  successCase('Map<S, T>', 'Map<S, List<S>>', {'T': 'List<S>'}),
+  successCase('Map<S, T>', 'Map<S, List<S>>', {'T': 'List<S>', 'S': null}),
+  successCase('Map<List<S>, T>', 'Map<T, List<S>>', {'T': 'List<S>'}),
+  successCase(
+      'Map<List<S>, T>', 'Map<T, List<S>>', {'T': 'List<S>', 'S': null}),
+
+  successCase('<E>(E) => E', '<T>(T) => T', {}),
+  successCase('<E>(E, S) => E', '<T>(T, int) => T', {'S': 'int'}),
+  failureCase('<E>(E, S) => E', '<T>(T, T) => T', ['S']),
+  successCase(
+      '<E>(E) => <T>(T) => Map<E,T>', '<E>(E) => <T>(T) => Map<E,T>', {}),
+  successCase('<E>(E,_) => E', '<T>(T,_) => T', {}),
+
+  successCase('(x:int,y:String) => int', '(y:String,x:int) => int', {}),
+  successCase('<S,T>(x:S,y:T) => S', '<S,T>(y:T,x:S) => S', {}),
+  successCase('(x:<T>(T)=>T,y:<S>(S)=>S) => int',
+      '(y:<S>(S)=>S,x:<T>(T)=>T) => int', {}),
+  successCase('(x:<T>(T)=>T,y:<S>(S,S,S)=>S) => int',
+      '(y:<S>(S,S,S)=>S,x:<T>(T)=>T) => int', {}),
+];
+
+class TestCase {
+  String type1;
+  String type2;
+  Iterable<String> quantifiedVariables;
+  Map<String, String> expectedSubstitution; // Null if unification should fail.
+
+  TestCase.success(this.type1, this.type2, this.expectedSubstitution) {
+    quantifiedVariables = expectedSubstitution.keys;
+  }
+
+  TestCase.fail(this.type1, this.type2, this.quantifiedVariables);
+
+  bool get shouldSucceed => expectedSubstitution != null;
+
+  String toString() => '∃ ${quantifiedVariables.join(',')}. $type1 = $type2';
+}
+
+TestCase successCase(String type1, String type2, Map<String, String> expected,
+    {bool debug: false}) {
+  return new TestCase.success(type1, type2, expected);
+}
+
+TestCase failureCase(
+    String type1, String type2, List<String> quantifiedVariables,
+    {bool debug: false}) {
+  return new TestCase.fail(type1, type2, quantifiedVariables);
+}
+
 void checkHashCodeEquality(DartType type1, DartType type2) {
   if (type1 == type2 && type1.hashCode != type2.hashCode) {
     fail('Equal types with different hash codes: $type1 and $type2');
diff --git a/pkg/kernel/test/type_substitution_identity_test.dart b/pkg/kernel/test/type_substitution_identity_test.dart
index d07da2a..d8fabbd 100644
--- a/pkg/kernel/test/type_substitution_identity_test.dart
+++ b/pkg/kernel/test/type_substitution_identity_test.dart
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 import 'package:kernel/kernel.dart';
 import 'package:kernel/type_algebra.dart';
 import 'type_parser.dart';
-import 'type_unification_test.dart' show testCases;
+import 'type_hashcode_test.dart' show testCases;
 import 'package:test/test.dart';
 
 checkType(DartType type) {
diff --git a/pkg/kernel/test/type_unification_test.dart b/pkg/kernel/test/type_unification_test.dart
deleted file mode 100644
index 2e79fdb..0000000
--- a/pkg/kernel/test/type_unification_test.dart
+++ /dev/null
@@ -1,140 +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:kernel/type_algebra.dart';
-import 'package:test/test.dart';
-import 'type_parser.dart';
-import 'dart:io';
-
-final List<TestCase> testCases = <TestCase>[
-  successCase('List<T>', 'List<String>', {'T': 'String'}),
-  successCase('List<String>', 'List<T>', {'T': 'String'}),
-  successCase('List<T>', 'List<T>', {'T': null}),
-  successCase('List<S>', 'List<T>', {'S': 'T'}),
-  successCase('List<S>', 'List<T>', {'T': 'S'}),
-  successCase(
-      'List<S>', 'List<T>', {'S': 'T', 'T': null}), // Require left bias.
-  failureCase('List<S>', 'List<T>', []),
-
-  failureCase('List<T>', 'T', ['T']),
-  failureCase('List<List<T>>', 'List<T>', ['T']),
-  failureCase('Map<S, T>', 'Map<List<T>, List<S>>', ['T', 'S']),
-
-  failureCase('Map<Map<S,String>, Map<int,S>>',
-      'Map<Map<int, S>, Map<S, String>>', ['S']),
-  successCase('Map<Map<S, int>, Map<int, S>>', 'Map<Map<int, S>, Map<S, int>>',
-      {'S': 'int'}),
-  successCase('Map<Map<S, String>, Map<int, T>>',
-      'Map<Map<int, T>, Map<S, String>>', {'S': 'int', 'T': 'String'}),
-
-  successCase('Map<S, List<T>>', 'Map<T, List<S>>', {'S': 'T'}),
-  successCase('Map<S, T>', 'Map<S, List<S>>', {'T': 'List<S>'}),
-  successCase('Map<S, T>', 'Map<S, List<S>>', {'T': 'List<S>', 'S': null}),
-  successCase('Map<List<S>, T>', 'Map<T, List<S>>', {'T': 'List<S>'}),
-  successCase(
-      'Map<List<S>, T>', 'Map<T, List<S>>', {'T': 'List<S>', 'S': null}),
-
-  successCase('<E>(E) => E', '<T>(T) => T', {}),
-  successCase('<E>(E, S) => E', '<T>(T, int) => T', {'S': 'int'}),
-  failureCase('<E>(E, S) => E', '<T>(T, T) => T', ['S']),
-  successCase(
-      '<E>(E) => <T>(T) => Map<E,T>', '<E>(E) => <T>(T) => Map<E,T>', {}),
-  successCase('<E>(E,_) => E', '<T>(T,_) => T', {}),
-
-  successCase('(x:int,y:String) => int', '(y:String,x:int) => int', {}),
-  successCase('<S,T>(x:S,y:T) => S', '<S,T>(y:T,x:S) => S', {}),
-  successCase('(x:<T>(T)=>T,y:<S>(S)=>S) => int',
-      '(y:<S>(S)=>S,x:<T>(T)=>T) => int', {}),
-  successCase('(x:<T>(T)=>T,y:<S>(S,S,S)=>S) => int',
-      '(y:<S>(S,S,S)=>S,x:<T>(T)=>T) => int', {}),
-];
-
-class TestCase {
-  String type1;
-  String type2;
-  Iterable<String> quantifiedVariables;
-  Map<String, String> expectedSubstitution; // Null if unification should fail.
-
-  TestCase.success(this.type1, this.type2, this.expectedSubstitution) {
-    quantifiedVariables = expectedSubstitution.keys;
-  }
-
-  TestCase.fail(this.type1, this.type2, this.quantifiedVariables);
-
-  bool get shouldSucceed => expectedSubstitution != null;
-
-  String toString() => '∃ ${quantifiedVariables.join(',')}. $type1 = $type2';
-}
-
-TestCase successCase(String type1, String type2, Map<String, String> expected,
-    {bool debug: false}) {
-  return new TestCase.success(type1, type2, expected);
-}
-
-TestCase failureCase(
-    String type1, String type2, List<String> quantifiedVariables,
-    {bool debug: false}) {
-  return new TestCase.fail(type1, type2, quantifiedVariables);
-}
-
-int numFailures = 0;
-
-void reportFailure(TestCase testCase, String message) {
-  ++numFailures;
-  fail('$message in `$testCase`');
-}
-
-main() {
-  for (TestCase testCase in testCases) {
-    test('$testCase', () {
-      var env = new LazyTypeEnvironment();
-      var type1 = env.parse(testCase.type1);
-      var type2 = env.parse(testCase.type2);
-      var quantifiedVariables =
-          testCase.quantifiedVariables.map(env.getTypeParameter).toSet();
-      var substitution = unifyTypes(type1, type2, quantifiedVariables);
-      if (testCase.shouldSucceed) {
-        if (substitution == null) {
-          reportFailure(testCase, 'Unification failed');
-        } else {
-          for (var key in testCase.expectedSubstitution.keys) {
-            var typeParameter = env.getTypeParameter(key);
-            if (testCase.expectedSubstitution[key] == null) {
-              if (substitution.containsKey(key)) {
-                var actualType = substitution[typeParameter];
-                reportFailure(
-                    testCase,
-                    'Incorrect substitution '
-                    '`$key = $actualType` should be unbound');
-              }
-            } else {
-              var expectedType = env.parse(testCase.expectedSubstitution[key]);
-              var actualType = substitution[typeParameter];
-              if (actualType != expectedType) {
-                reportFailure(
-                    testCase,
-                    'Incorrect substitution '
-                    '`$key = $actualType` should be `$key = $expectedType`');
-              }
-            }
-          }
-          var boundTypeVariables = testCase.expectedSubstitution.keys
-              .where((name) => testCase.expectedSubstitution[name] != null);
-          if (substitution.length != boundTypeVariables.length) {
-            reportFailure(
-                testCase,
-                'Substituted `${substitution.keys.join(',')}` '
-                'but should only substitute `${boundTypeVariables.join(',')}`');
-          }
-        }
-      } else {
-        if (substitution != null) {
-          reportFailure(testCase, 'Unification was supposed to fail');
-        }
-      }
-    });
-  }
-  if (numFailures > 0) {
-    exit(1);
-  }
-}
diff --git a/pkg/kernel/tool/smoke_test_quick.dart b/pkg/kernel/tool/smoke_test_quick.dart
index bf32ec3..b5a0b9a 100644
--- a/pkg/kernel/tool/smoke_test_quick.dart
+++ b/pkg/kernel/tool/smoke_test_quick.dart
@@ -10,7 +10,7 @@
 
 main(List<String> args) async {
   Stopwatch stopwatch = new Stopwatch()..start();
-  List<Future> futures = new List<Future>();
+  List<Future> futures = <Future>[];
   futures.add(run("pkg/front_end/test/spelling_test_src_suite.dart",
       ["--", "spelling_test_src/kernel/..."]));
   await Future.wait(futures);
diff --git a/pkg/meta/analysis_options.yaml b/pkg/meta/analysis_options.yaml
deleted file mode 100644
index 4163582..0000000
--- a/pkg/meta/analysis_options.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-analyzer:
-  enable-experiment:
-    - non-nullable
diff --git a/pkg/modular_test/pubspec.yaml b/pkg/modular_test/pubspec.yaml
index 19e04da..68974ee 100644
--- a/pkg/modular_test/pubspec.yaml
+++ b/pkg/modular_test/pubspec.yaml
@@ -10,8 +10,8 @@
 
 dependencies:
   args: any
-  package_config: ^1.0.5
-  yaml: ^2.1.15
+  package_config: any
+  yaml: any
 
 dev_dependencies:
   async_helper:
diff --git a/pkg/native_stack_traces/bin/decode.dart b/pkg/native_stack_traces/bin/decode.dart
index 9a7aee0..4ced1ca 100644
--- a/pkg/native_stack_traces/bin/decode.dart
+++ b/pkg/native_stack_traces/bin/decode.dart
@@ -300,12 +300,12 @@
   if (options['help']) return print(_usages[options.command?.name]);
   if (options.command == null) return errorWithUsage('no command provided');
 
-  switch (options.command.name) {
+  switch (options.command!.name) {
     case 'help':
-      return help(options.command);
+      return help(options.command!);
     case 'find':
-      return find(options.command);
+      return find(options.command!);
     case 'translate':
-      return await translate(options.command);
+      return await translate(options.command!);
   }
 }
diff --git a/pkg/nnbd_migration/TRIAGE.md b/pkg/nnbd_migration/TRIAGE.md
new file mode 100644
index 0000000..1abd578
--- /dev/null
+++ b/pkg/nnbd_migration/TRIAGE.md
@@ -0,0 +1,72 @@
+# Triage Priorities for Dart Migration tool
+
+This document describes the relative priorities for bugs filed under the
+`area-migration` tag in GitHub as in
+[this search](https://github.com/dart-lang/sdk/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-migration).
+While there are always exceptions to any rule, in general try to align our
+priorities with these definitions.
+
+To triage bugs, search for `area-migration`
+[bugs that are not currently triaged](https://github.com/dart-lang/sdk/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-migration+-label%3AP0+-label%3AP1+-label%3AP2+-label%3AP3+-label%3AP4)
+and for each bug, mark priority based on how closely it matches with the below
+constraints.
+
+## Migration tool triage priorities
+
+Descriptions here use [terms and definitions](#terms-and-definitions) from the
+end of this document.  If your bug doesn't precisely match one of these,
+consider how impactful it is compared to examples given here and pick a priority
+reflecting that.
+
+### P0
+
+* Crashes that can't be worked around by `--ignore-exceptions`, typical impact or widespread.
+* Crashes that can be worked around by `--ignore-exceptions`, widespread.
+
+### P1
+
+* Crashes that can be worked around by `--ignore-exceptions`, typical impact.
+* An enhancement required for critical milestones for key users, or that has
+  significant evidence gathered indicating a positive impact if implemented.
+* A problem that is significantly impairing a key user's ability to migrate
+  their code.
+
+### P2
+
+* Crashes, edge case.
+* An enhancement with typical impact that doesn't fit the criteria above but
+  would still be significantly beneficial to users (i.e. more than just a "would
+  be nice" feature).
+* A problem with typical impact that doesn't fit the criteria above, but impairs
+  users' ability to migrate their code.
+
+### P3
+
+* Crashes, theoretical.
+* An enhancement that doesn't fit the criteria above.
+* A problem that doesn't fit the criteria above, but impairs users' ability to
+  migrate their code.
+
+## Terms and definitions
+
+### Terms describing impact
+
+* "widespread" - Impact endemic throughout the ecosystem, or at least far
+  enough that this is impacting multiple key users.
+* "typical impact" - Known to impact a key user, or likely to impact a
+  significant percentage of all users.  Issues are assumed to have typical
+  impact unless we have evidence otherwise.
+* "edge cases" - Impacting only small parts of the ecosystem.  For example, one
+  package, or one key user with a workaround.  Note this is an edge case from
+  the perspective of the ecosystem vs. language definition.  Note that since the
+  migration tool is still in an early adoption phase, if a bug has only been
+  reported by one user, that's not sufficient evidence that it's an edge case.
+  To be considered an edge case, we need to have a concrete reason to suspect
+  that the bug is caused by an unusual pattern in the user's source code, or
+  unusual user behavior.
+* "theoretical" - Something that we think is unlikely to happen in the wild
+  and there's no evidence for it happening in the wild.
+
+### Other terms
+
+* "key users" - Flutter, Pub, Fuchsia, Dart, Google3, 1P
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 3505c90..4dff755 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -101,10 +101,6 @@
   static const previewPortOption = 'preview-port';
   static const sdkPathOption = 'sdk-path';
   static const skipImportCheckFlag = 'skip-import-check';
-
-  /// TODO(paulberry): remove this flag once internal sources have been updated.
-  @Deprecated('The migration tool no longer performs "pub outdated" checks')
-  static const skipPubOutdatedFlag = 'skip-pub-outdated';
   static const summaryOption = 'summary';
   static const verboseFlag = 'verbose';
   static const webPreviewFlag = 'web-preview';
@@ -130,36 +126,16 @@
   final bool webPreview;
 
   CommandLineOptions(
-      {@required
-          this.applyChanges,
-      @required
-          this.directory,
-      @required
-          this.ignoreErrors,
-      @required
-          this.ignoreExceptions,
-      @required
-          this.previewHostname,
-      @required
-          this.previewPort,
-      @required
-          this.sdkPath,
-      // TODO(paulberry): make this parameter required once internal sources
-      // have been updated.
-      bool skipImportCheck,
-      // TODO(paulberry): remove this flag once internal sources have been
-      // updated.
-      @Deprecated('The migration tool no longer performs "pub outdated" checks')
-          bool skipPubOutdated = false,
-      @required
-          this.summary,
-      @required
-          this.webPreview})
-      // `skipImportCheck` has replaced `skipPubOutdated`, so if the caller
-      // specifies the latter but not the former, carry it over.
-      // TODO(paulberry): remove this logic once internal sources have been
-      // updated.
-      : skipImportCheck = skipImportCheck ?? skipPubOutdated;
+      {@required this.applyChanges,
+      @required this.directory,
+      @required this.ignoreErrors,
+      @required this.ignoreExceptions,
+      @required this.previewHostname,
+      @required this.previewPort,
+      @required this.sdkPath,
+      @required this.skipImportCheck,
+      @required this.summary,
+      @required this.webPreview});
 }
 
 // TODO(devoncarew): Refactor so this class extends DartdevCommand.
@@ -520,7 +496,7 @@
 ///
 /// This class may be used directly by clients that with to run migration but
 /// provide their own command-line interface.
-class MigrationCliRunner {
+class MigrationCliRunner implements DartFixListenerClient {
   final MigrationCli cli;
 
   /// Logger instance we use to give feedback to the user.
@@ -637,6 +613,69 @@
         sdkPath: sdkPath);
   }
 
+  @override
+  void onException(String detail) {
+    if (_hasExceptions) {
+      if (!options.ignoreExceptions) {
+        // Our intention is to exit immediately when an exception occurred.  We
+        // tried, but failed (probably due to permissive mode logic in the
+        // migration tool itself catching the MigrationExit exception).  The
+        // stack has now been unwound further, so throw again.
+        throw MigrationExit(1);
+      }
+      // We're not exiting immediately when an exception occurs.  We've already
+      // reported that an exception happened.  So do nothing further.
+      return;
+    }
+    _hasExceptions = true;
+    if (options.ignoreExceptions) {
+      logger.stdout('''
+Exception(s) occurred during migration.  Attempting to perform
+migration anyway due to the use of --${CommandLineOptions.ignoreExceptionsFlag}.
+
+To see exception details, re-run without --${CommandLineOptions.ignoreExceptionsFlag}.
+''');
+    } else {
+      if (_hasAnalysisErrors) {
+        logger.stderr('''
+Aborting migration due to an exception.  This may be due to a bug in
+the migration tool, or it may be due to errors in the source code
+being migrated.  If possible, try to fix errors in the source code and
+re-try migrating.  If that doesn't work, consider filing a bug report
+at:
+''');
+      } else {
+        logger.stderr('''
+Aborting migration due to an exception.  This most likely is due to a
+bug in the migration tool.  Please consider filing a bug report at:
+''');
+      }
+      logger.stderr('https://github.com/dart-lang/sdk/issues/new');
+      var sdkVersion = Platform.version.split(' ')[0];
+      logger.stderr('''
+Please include the SDK version ($sdkVersion) in your bug report.
+
+To attempt to perform migration anyway, you may re-run with
+--${CommandLineOptions.ignoreExceptionsFlag}.
+
+Exception details:
+''');
+      logger.stderr(detail);
+      throw MigrationExit(1);
+    }
+  }
+
+  @override
+  void onFatalError(String detail) {
+    logger.stderr(detail);
+    throw MigrationExit(1);
+  }
+
+  @override
+  void onMessage(String detail) {
+    logger.stdout(detail);
+  }
+
   /// Runs the full migration process.
   ///
   /// If something goes wrong, a message is printed using the logger configured
@@ -660,8 +699,8 @@
 
     logger.stdout(ansi.emphasized('Analyzing project...'));
     _fixCodeProcessor = _FixCodeProcessor(context, this);
-    _dartFixListener = DartFixListener(
-        DriverProviderImpl(resourceProvider, context), _exceptionReported);
+    _dartFixListener =
+        DartFixListener(DriverProviderImpl(resourceProvider, context), this);
     nonNullableFix = createNonNullableFix(_dartFixListener, resourceProvider,
         _fixCodeProcessor.getLineInfo, computeBindAddress(),
         included: [options.directory],
@@ -835,43 +874,6 @@
     }
   }
 
-  void _exceptionReported(String detail) {
-    if (_hasExceptions) return;
-    _hasExceptions = true;
-    if (options.ignoreExceptions) {
-      logger.stdout('''
-Exception(s) occurred during migration.  Attempting to perform
-migration anyway due to the use of --${CommandLineOptions.ignoreExceptionsFlag}.
-
-To see exception details, re-run without --${CommandLineOptions.ignoreExceptionsFlag}.
-''');
-    } else {
-      if (_hasAnalysisErrors) {
-        logger.stderr('''
-Aborting migration due to an exception.  This may be due to a bug in
-the migration tool, or it may be due to errors in the source code
-being migrated.  If possible, try to fix errors in the source code and
-re-try migrating.  If that doesn't work, consider filing a bug report
-at:
-''');
-      } else {
-        logger.stderr('''
-Aborting migration due to an exception.  This most likely is due to a
-bug in the migration tool.  Please consider filing a bug report at:
-''');
-      }
-      logger.stderr('https://github.com/dart-lang/sdk/issues/new');
-      logger.stderr('''
-To attempt to perform migration anyway, you may re-run with
---${CommandLineOptions.ignoreExceptionsFlag}.
-
-Exception details:
-''');
-      logger.stderr(detail);
-      throw MigrationExit(1);
-    }
-  }
-
   void _logAlreadyMigrated() {
     logger.stdout(migratedAlready);
   }
@@ -939,6 +941,7 @@
           _fixCodeProcessor._task.includedRoot,
           _dartFixListener,
           _fixCodeProcessor._task.instrumentationListener,
+          {},
           analysisResult);
     } else if (analysisResult.allSourcesAlreadyMigrated) {
       _logAlreadyMigrated();
@@ -947,6 +950,7 @@
           _fixCodeProcessor._task.includedRoot,
           _dartFixListener,
           _fixCodeProcessor._task.instrumentationListener,
+          {},
           analysisResult);
     } else {
       logger.stdout(ansi.emphasized('Re-generating migration suggestions...'));
@@ -1079,9 +1083,6 @@
   }
 
   Future<AnalysisResult> runFirstPhase() async {
-    // Process package
-    _task.processPackage(context.contextRoot.root);
-
     var analysisErrors = <AnalysisError>[];
 
     // All tasks should be registered; [numPhases] should be finalized.
@@ -1142,6 +1143,7 @@
     _migrationCli.logger.stdout(_migrationCli.ansi
         .emphasized('Compiling instrumentation information...'));
     var state = await _task.finish();
+    _task.processPackage(context.contextRoot.root, state.neededPackages);
     if (_migrationCli.options.webPreview) {
       await _task.startPreviewServer(state, _migrationCli.applyHook);
     }
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 36027a0..25499a8 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -12,6 +12,7 @@
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/src/nullability_migration_impl.dart';
+import 'package:pub_semver/pub_semver.dart';
 
 export 'package:nnbd_migration/src/utilities/hint_utils.dart' show HintComment;
 
@@ -314,31 +315,31 @@
   /// Optional parameter [warnOnWeakCode] indicates whether weak-only code
   /// should be warned about or removed (in the way specified by
   /// [removeViaComments]).
-  ///
-  /// Optional parameter [transformWhereOrNull] indicates whether Iterable
-  /// methods should be transformed to their "OrNull" equivalents when possible.
-  /// This feature is a work in progress, so by default they are not
-  /// transformed.
   factory NullabilityMigration(NullabilityMigrationListener listener,
       LineInfo Function(String) getLineInfo,
       {bool permissive,
       NullabilityMigrationInstrumentation instrumentation,
       bool removeViaComments,
-      bool warnOnWeakCode,
-      bool transformWhereOrNull}) = NullabilityMigrationImpl;
+      bool warnOnWeakCode}) = NullabilityMigrationImpl;
 
   /// Check if this migration is being run permissively.
   bool get isPermissive;
 
-  void finalizeInput(ResolvedUnitResult result);
-
-  void finish();
-
   /// Use this getter after any calls to [prepareInput] to obtain a list of URIs
   /// of unmigrated dependencies.  Ideally, this list should be empty before the
   /// user tries to migrate their package.
   List<String> get unmigratedDependencies;
 
+  void finalizeInput(ResolvedUnitResult result);
+
+  /// Finishes the migration.  Returns a map indicating packages that have been
+  /// newly imported by the migration; the caller should ensure that these
+  /// packages are properly imported by the package's pubspec.
+  ///
+  /// Keys of the returned map are package names; values indicate the minimum
+  /// required version of each package.
+  Map<String, Version> finish();
+
   void prepareInput(ResolvedUnitResult result);
 
   void processInput(ResolvedUnitResult result);
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 3611061..b348db7 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -145,6 +145,12 @@
   /// being visited, or null.
   Element _currentClassOrExtension;
 
+  /// If an extension declaration is being visited, the decorated type of the
+  /// type appearing in the `on` clause (this is the type of `this` inside the
+  /// extension declaration).  Null if an extension declaration is not being
+  /// visited.
+  DecoratedType _currentExtendedType;
+
   /// The [DecoratedType] of the innermost list or set literal being visited, or
   /// `null` if the visitor is not inside any list or set.
   ///
@@ -217,7 +223,7 @@
   final Map<Token, HintComment> _nullCheckHints = {};
 
   /// Helper that assists us in transforming Iterable methods to their "OrNull"
-  /// equivalents, or `null` if we are not doing such transformations.
+  /// equivalents.
   final WhereOrNullTransformer _whereOrNullTransformer;
 
   /// Deferred processing that should be performed once we have finished
@@ -225,20 +231,12 @@
   final Map<MethodInvocation, DecoratedType Function(DecoratedType)>
       _deferredMethodInvocationProcessing = {};
 
-  EdgeBuilder(
-      this.typeProvider,
-      this._typeSystem,
-      this._variables,
-      this._graph,
-      this.source,
-      this.listener,
-      this._decoratedClassHierarchy,
-      bool transformWhereOrNull,
+  EdgeBuilder(this.typeProvider, this._typeSystem, this._variables, this._graph,
+      this.source, this.listener, this._decoratedClassHierarchy,
       {this.instrumentation})
       : _inheritanceManager = InheritanceManager3(),
-        _whereOrNullTransformer = transformWhereOrNull
-            ? WhereOrNullTransformer(typeProvider, _typeSystem)
-            : null;
+        _whereOrNullTransformer =
+            WhereOrNullTransformer(typeProvider, _typeSystem);
 
   /// Gets the decorated type of [element] from [_variables], performing any
   /// necessary substitutions.
@@ -800,9 +798,12 @@
   }
 
   DecoratedType visitExtensionDeclaration(ExtensionDeclaration node) {
-    visitClassOrMixinOrExtensionDeclaration(node);
     _dispatch(node.typeParameters);
     _dispatch(node.extendedType);
+    _currentExtendedType =
+        _variables.decoratedTypeAnnotation(source, node.extendedType);
+    visitClassOrMixinOrExtensionDeclaration(node);
+    _currentExtendedType = null;
     return null;
   }
 
@@ -1128,27 +1129,22 @@
     var type = node.type;
     _dispatch(type);
     var decoratedType = _variables.decoratedTypeAnnotation(source, type);
-    if (type is NamedType) {
-      // The main type of the is check historically could not be nullable.
-      // Making it nullable could change runtime behavior.
-      _graph.makeNonNullable(
-          decoratedType.node, IsCheckMainTypeOrigin(source, type));
-      _conditionInfo = _ConditionInfo(node,
-          isPure: expression is SimpleIdentifier,
-          postDominatingIntent:
-              _postDominatedLocals.isReferenceInScope(expression),
-          trueDemonstratesNonNullIntent: expressionNode);
-      if (node.notOperator != null) {
-        _conditionInfo = _conditionInfo.not(node);
-      }
-      if (!_assumeNonNullabilityInCasts) {
-        // TODO(mfairhurst): wire this to handleDowncast if we do not assume
-        // nullability.
-        assert(false);
-      }
-    } else if (type is GenericFunctionType) {
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'Is expression with GenericFunctionType');
+    // The main type of the is check historically could not be nullable.
+    // Making it nullable could change runtime behavior.
+    _graph.makeNonNullable(
+        decoratedType.node, IsCheckMainTypeOrigin(source, type));
+    _conditionInfo = _ConditionInfo(node,
+        isPure: expression is SimpleIdentifier,
+        postDominatingIntent:
+            _postDominatedLocals.isReferenceInScope(expression),
+        trueDemonstratesNonNullIntent: expressionNode);
+    if (node.notOperator != null) {
+      _conditionInfo = _conditionInfo.not(node);
+    }
+    if (!_assumeNonNullabilityInCasts) {
+      // TODO(mfairhurst): wire this to handleDowncast if we do not assume
+      // nullability.
+      assert(false);
     }
     _flowAnalysis.isExpression_end(
         node, expression, node.notOperator != null, decoratedType);
@@ -2148,15 +2144,20 @@
   }
 
   DecoratedType _dispatch(AstNode node, {bool skipNullCheckHint = false}) {
-    var type = node?.accept(this);
-    if (!skipNullCheckHint &&
-        node is Expression &&
-        // A /*!*/ hint following an AsExpression should be interpreted as a
-        // nullability hint for the type, not a null-check hint.
-        node is! AsExpression) {
-      type = _handleNullCheckHint(node, type);
+    try {
+      var type = node?.accept(this);
+      if (!skipNullCheckHint &&
+          node is Expression &&
+          // A /*!*/ hint following an AsExpression should be interpreted as a
+          // nullability hint for the type, not a null-check hint.
+          node is! AsExpression) {
+        type = _handleNullCheckHint(node, type);
+      }
+      return type;
+    } catch (exception, stackTrace) {
+      listener.reportException(source, node, exception, stackTrace);
+      return null;
     }
-    return type;
   }
 
   void _dispatchList(NodeList nodeList) {
@@ -2304,7 +2305,7 @@
         }
       } else {
         var transformationInfo =
-            _whereOrNullTransformer?.tryTransformOrElseArgument(expression);
+            _whereOrNullTransformer.tryTransformOrElseArgument(expression);
         if (transformationInfo != null) {
           // Don't build any edges for this argument; if necessary we'll transform
           // it rather than make things nullable.  But do save the nullability of
@@ -2658,21 +2659,23 @@
           node is Statement ? node : null, parts.condition);
     } else if (parts is ForEachParts) {
       Element lhsElement;
+      DecoratedType lhsType;
       if (parts is ForEachPartsWithDeclaration) {
         var variableElement = parts.loopVariable.declaredElement;
         _flowAnalysis.declare(variableElement, true);
         lhsElement = variableElement;
         _dispatch(parts.loopVariable?.type);
+        lhsType = _variables.decoratedElementType(lhsElement);
       } else if (parts is ForEachPartsWithIdentifier) {
         lhsElement = parts.identifier.staticElement;
+        lhsType = _dispatch(parts.identifier);
       } else {
         throw StateError(
             'Unexpected ForEachParts subtype: ${parts.runtimeType}');
       }
       var iterableType = _checkExpressionNotNull(parts.iterable);
       DecoratedType elementType;
-      if (lhsElement != null) {
-        DecoratedType lhsType = _variables.decoratedElementType(lhsElement);
+      if (lhsType != null) {
         var iterableTypeType = iterableType.type;
         if (_typeSystem.isSubtypeOf(
             iterableTypeType, typeProvider.iterableDynamicType)) {
@@ -3156,22 +3159,8 @@
               .toList());
     } else {
       assert(_currentClassOrExtension is ExtensionElement);
-      final type = (_currentClassOrExtension as ExtensionElement).extendedType;
-
-      if (type is InterfaceType) {
-        var index = 0;
-        return DecoratedType(type, NullabilityNode.forInferredType(target),
-            typeArguments: type.typeArguments
-                .map((t) => DecoratedType(
-                    t,
-                    NullabilityNode.forInferredType(
-                        target.typeArgument(index++))))
-                .toList());
-      } else if (type is TypeParameterType) {
-        return DecoratedType(type, NullabilityNode.forInferredType(target));
-      } else {
-        _unimplemented(node, 'extension of $type (${type.runtimeType}');
-      }
+      assert(_currentExtendedType != null);
+      return _currentExtendedType;
     }
   }
 
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 32b2777..1d4748f 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -40,6 +40,7 @@
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
 import 'package:nnbd_migration/src/utilities/where_or_null_transformer.dart';
 import 'package:nnbd_migration/src/variables.dart';
+import 'package:pub_semver/pub_semver.dart';
 
 bool _isIncrementOrDecrementOperator(TokenType tokenType) {
   switch (tokenType) {
@@ -121,7 +122,7 @@
   final NullabilityGraph _graph;
 
   /// Helper that assists us in transforming Iterable methods to their "OrNull"
-  /// equivalents, or `null` if we are not doing such transformations.
+  /// equivalents.
   final WhereOrNullTransformer _whereOrNullTransformer;
 
   /// Indicates whether an import of package:collection's `IterableExtension`
@@ -129,6 +130,11 @@
   @visibleForTesting
   bool needsIterableExtension = false;
 
+  /// Map of additional package dependencies that will be required by the
+  /// migrated code.  Keys are package names; values indicate the minimum
+  /// required version of each package.
+  final Map<String, Version> _neededPackages;
+
   factory FixBuilder(
       Source source,
       DecoratedClassHierarchy decoratedClassHierarchy,
@@ -140,7 +146,7 @@
       CompilationUnit unit,
       bool warnOnWeakCode,
       NullabilityGraph graph,
-      bool transformWhereOrNull) {
+      Map<String, Version> neededPackages) {
     var migrationResolutionHooks = MigrationResolutionHooksImpl();
     return FixBuilder._(
         decoratedClassHierarchy,
@@ -156,7 +162,7 @@
         migrationResolutionHooks,
         warnOnWeakCode,
         graph,
-        transformWhereOrNull);
+        neededPackages);
   }
 
   FixBuilder._(
@@ -170,11 +176,10 @@
       this.migrationResolutionHooks,
       this.warnOnWeakCode,
       this._graph,
-      bool transformWhereOrNull)
+      this._neededPackages)
       : typeProvider = _typeSystem.typeProvider,
-        _whereOrNullTransformer = transformWhereOrNull
-            ? WhereOrNullTransformer(_typeSystem.typeProvider, _typeSystem)
-            : null {
+        _whereOrNullTransformer =
+            WhereOrNullTransformer(_typeSystem.typeProvider, _typeSystem) {
     migrationResolutionHooks._fixBuilder = this;
     assert(_typeSystem.isNonNullableByDefault);
     assert((typeProvider as TypeProviderImpl).isNonNullableByDefault);
@@ -459,6 +464,15 @@
           // correct post-migration type.
           return variable.typeInternal;
         }
+        if (variable is ParameterElement) {
+          var enclosingElement = variable.enclosingElement;
+          if (enclosingElement is PropertyAccessorElement &&
+              enclosingElement.isSynthetic) {
+            // This is the parameter of a synthetic getter, so it has the same
+            // type as the corresponding variable.
+            return _fixBuilder._computeMigratedType(enclosingElement.variable);
+          }
+        }
         return _fixBuilder._computeMigratedType(variable);
       });
 
@@ -640,10 +654,12 @@
         InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
     if (!_fixBuilder._typeSystem.isSubtypeOf(type, context)) {
       var transformationInfo =
-          _fixBuilder._whereOrNullTransformer?.tryTransformOrElseArgument(node);
+          _fixBuilder._whereOrNullTransformer.tryTransformOrElseArgument(node);
       if (transformationInfo != null) {
         // We can fix this by dropping the node and changing the method call.
         _fixBuilder.needsIterableExtension = true;
+        _fixBuilder._neededPackages['collection'] =
+            Version.parse('1.15.0-nullsafety.4');
         var info = AtomicEditInfo(
             NullabilityFixDescription.changeMethodName(
                 transformationInfo.originalName,
diff --git a/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart b/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
index 378b136..4c6fa9c 100644
--- a/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
@@ -7,6 +7,7 @@
     hide AnalysisError;
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
+import 'package:pub_semver/src/version.dart';
 
 class DartFixListener {
   final DriverProviderImpl server;
@@ -15,11 +16,9 @@
 
   final List<DartFixSuggestion> suggestions = [];
 
-  /// Add the given [detail] to the list of details to be returned to the
-  /// client.
-  final void Function(String detail) reportException;
+  final DartFixListenerClient client;
 
-  DartFixListener(this.server, this.reportException);
+  DartFixListener(this.server, this.client);
 
   /// Record an edit to be sent to the client.
   ///
@@ -29,11 +28,6 @@
     sourceChange.addEdit(source.fullName, -1, edit);
   }
 
-  /// Record a recommendation to be sent to the client.
-  void addRecommendation(String description, [Location location]) {
-    throw UnimplementedError('TODO(paulberry)');
-  }
-
   /// Record a source change to be sent to the client.
   void addSourceFileEdit(
       String description, Location location, SourceFileEdit fileEdit) {
@@ -51,6 +45,13 @@
     suggestions.add(DartFixSuggestion(description, location: location));
   }
 
+  /// Reports to then user that they need to run `dart pub get` after the
+  /// migration finishes.
+  void reportPubGetNeeded(Map<String, Version> neededPackages) {
+    client.onMessage(
+        'Your pubspec has been updated.  Please run `dart pub get`.');
+  }
+
   /// Reset this listener so that it can accrue a new set of changes.
   void reset() {
     suggestions.clear();
@@ -62,6 +63,18 @@
   }
 }
 
+abstract class DartFixListenerClient {
+  /// Add the given [detail] to the list of details to be returned to the
+  /// client.
+  void onException(String detail);
+
+  /// Callback that reports a fatal error to the client.
+  void onFatalError(String detail);
+
+  /// Reports the given [detail] message to the client; not an error condition.
+  void onMessage(String detail);
+}
+
 class DartFixSuggestion {
   final String description;
 
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index b5b8e56..2b8289c 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -4,6 +4,7 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -23,6 +24,7 @@
 import 'package:nnbd_migration/src/front_end/instrumentation_information.dart';
 import 'package:nnbd_migration/src/front_end/migration_info.dart';
 import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
 import 'package:nnbd_migration/src/utilities/progress_bar.dart';
 
 /// A builder used to build the migration information for a library.
@@ -250,7 +252,8 @@
     var files = collector.files;
     var regions = collector.regions;
     var rawTargets = collector.targets;
-    var convertedTargets = List<NavigationTarget>(rawTargets.length);
+    var convertedTargets =
+        List<NavigationTarget>.filled(rawTargets.length, null);
     return regions.map((region) {
       var targets = region.targets;
       if (targets.isEmpty) {
@@ -347,6 +350,12 @@
     unitInfo.sources ??= _computeNavigationSources(result);
     var content = result.content;
     unitInfo.diskContent = content;
+    var alreadyMigrated =
+        result.unit.featureSet.isEnabled(Feature.non_nullable);
+    unitInfo.wasExplicitlyOptedOut = result.unit.languageVersionToken != null;
+    unitInfo.migrationStatus = alreadyMigrated
+        ? UnitMigrationStatus.alreadyMigrated
+        : UnitMigrationStatus.migrating;
     var regions = unitInfo.regions;
 
     // There are certain rare conditions involving generated code in a bazel
@@ -361,7 +370,7 @@
 
     var lineInfo = result.unit.lineInfo;
     var insertions = <int, List<AtomicEdit>>{};
-    var hintsSeen = <HintComment>{};
+    var infosSeen = Set<AtomicEditInfo>.identity();
 
     // Apply edits and build the regions.
     var changes = sourceInfo.changes ?? {};
@@ -392,8 +401,7 @@
             ? const <TraceInfo>[]
             : _computeTraces(info.fixReasons);
         var description = info?.description;
-        var hint = info?.hintComment;
-        var isCounted = hint == null || hintsSeen.add(hint);
+        var isCounted = info != null && infosSeen.add(info);
         var explanation = description?.appliedMessage;
         var kind = description?.kind;
         if (edit.isInsertion) {
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
index c9d6099..42c3804 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
@@ -10,6 +10,7 @@
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
 import 'package:nnbd_migration/src/front_end/unit_link.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
 import 'package:nnbd_migration/src/preview/preview_site.dart';
 import 'package:path/path.dart' as path;
 
@@ -104,8 +105,8 @@
     var links = <UnitLink>[];
     for (var unit in units) {
       var count = unit.fixRegions.length;
-      links.add(
-          UnitLink(unit.path, pathContext.split(computeName(unit)), count));
+      links.add(UnitLink(unit.path, pathContext.split(computeName(unit)), count,
+          unit.wasExplicitlyOptedOut, unit.migrationStatus));
     }
     return links;
   }
@@ -280,6 +281,25 @@
   /// maintain an offset mapper from current disk state to migration result.
   OffsetMapper diskChangesOffsetMapper = OffsetMapper.identity;
 
+  /// Whether this compilation unit was explicitly opted out of null safety at
+  /// the start of this migration.
+  bool wasExplicitlyOptedOut;
+
+  /// Indicates the migration status of this unit.
+  ///
+  /// After all migration phases have completed, this indicates that a file was
+  /// already migrated, or is being migrated during this migration.
+  ///
+  /// A user can change this migration status from the preview interface:
+  /// * An already migrated unit cannot be changed.
+  /// * During an initial migration, in which a package is migrated to null
+  ///   safety, the user can toggle a file's migration status between
+  ///   "migrating" and "opting out."
+  /// * During a follow-up migration, in which a package has been migrated to
+  ///   null safety, but some files have been opted out, the user can toggle a
+  ///   file's migration status between "migrating" and "keeping opted out."
+  UnitMigrationStatus migrationStatus;
+
   /// Initialize a newly created unit.
   UnitInfo(this.path);
 
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_state.dart b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
index bfbf7cd..016c204 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
@@ -11,6 +11,7 @@
 import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
 import 'package:nnbd_migration/src/front_end/migration_info.dart';
 import 'package:nnbd_migration/src/front_end/path_mapper.dart';
+import 'package:pub_semver/src/version.dart';
 
 /// The state of an NNBD migration.
 class MigrationState {
@@ -44,10 +45,16 @@
 
   /*late*/ List<String> previewUrls;
 
+  /// Map of additional package dependencies that will be required by the
+  /// migrated code.  Keys are package names; values indicate the minimum
+  /// required version of each package.
+  final Map<String, Version> neededPackages;
+
   /// Initialize a newly created migration state with the given values.
   MigrationState(this.migration, this.includedRoot, this.listener,
-      this.instrumentationListener,
-      [this.analysisResult]);
+      this.instrumentationListener, this.neededPackages,
+      [this.analysisResult])
+      : assert(neededPackages != null);
 
   /// If the migration has been applied to disk.
   bool get hasBeenApplied => _hasBeenApplied;
diff --git a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
index 8dc7ffe..290f96e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
@@ -38,7 +38,11 @@
   /// Renders the navigation link tree.
   List<NavigationTreeNode> render() {
     var linkData = migrationInfo.unitLinks();
-    return _renderNavigationSubtree(linkData, 0);
+    var tree = _renderNavigationSubtree(linkData, 0);
+    for (var node in tree) {
+      node.parent = null;
+    }
+    return tree;
   }
 
   /// Renders the navigation link subtree at [depth].
@@ -50,16 +54,20 @@
 
     return [
       for (var entry in linksGroupedByDirectory.entries)
-        NavigationTreeNode.directory(
+        NavigationTreeDirectoryNode(
           name: entry.key,
+          path: pathContext
+              .dirname(pathContext.joinAll(entry.value.first.pathParts)),
           subtree: _renderNavigationSubtree(entry.value, depth + 1),
-        ),
+        )..setSubtreeParents(),
       for (var link in links.where((link) => link.depth == depth))
-        NavigationTreeNode.file(
+        NavigationTreeFileNode(
           name: link.fileName,
           path: pathContext.joinAll(link.pathParts),
           href: pathMapper.map(link.fullPath),
           editCount: link.editCount,
+          wasExplicitlyOptedOut: link.wasExplicitlyOptedOut,
+          migrationStatus: link.migrationStatus,
         ),
     ];
   }
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index 8a5d668..6ec0a2e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -69,11 +69,6 @@
 
   NullabilityMigration migration;
 
-  /// If this flag has a value of `false`, then something happened to prevent
-  /// at least one package from being marked as non-nullable.
-  /// If this occurs, then don't update any code.
-  bool _packageIsNNBD = true;
-
   Future<MigrationState> Function() rerunFunction;
 
   /// A list of the URLs corresponding to the included roots.
@@ -106,24 +101,18 @@
       InstrumentationListener(migrationSummary: migrationSummary);
 
   Future<void> finalizeUnit(ResolvedUnitResult result) async {
-    if (!_packageIsNNBD) {
-      return;
-    }
     migration.finalizeInput(result);
   }
 
   Future<MigrationState> finish() async {
-    migration.finish();
-    final state = MigrationState(
-        migration, includedRoot, listener, instrumentationListener);
+    var neededPackages = migration.finish();
+    final state = MigrationState(migration, includedRoot, listener,
+        instrumentationListener, neededPackages);
     await state.refresh(_logger);
     return state;
   }
 
   Future<void> prepareUnit(ResolvedUnitResult result) async {
-    if (!_packageIsNNBD) {
-      return;
-    }
     migration.prepareInput(result);
   }
 
@@ -131,11 +120,11 @@
   ///
   /// This means updating the pubspec.yaml file, the package_config.json
   /// file, and the analysis_options.yaml file, each only if necessary.
-  void processPackage(Folder pkgFolder) {
-    if (!_packageIsNNBD) {
-      return;
-    }
-
+  ///
+  /// [neededPackages] is a map whose keys are the names of packages that should
+  /// be depended upon by the package's pubspec, and whose values are the
+  /// minimum required versions of those packages.
+  void processPackage(Folder pkgFolder, Map<String, Version> neededPackages) {
     var pubspecFile = pkgFolder.getChildAssumingFile('pubspec.yaml');
     if (!pubspecFile.exists) {
       // If the pubspec file cannot be found, we do not attempt to change the
@@ -154,23 +143,19 @@
       return;
     }
 
-    var updated = _processPubspec(pubspec);
+    var updated = _processPubspec(pubspec, neededPackages);
     if (updated) {
       _processConfigFile(pkgFolder, pubspec);
     }
   }
 
   Future<void> processUnit(ResolvedUnitResult result) async {
-    if (!_packageIsNNBD) {
-      return;
-    }
     migration.processInput(result);
   }
 
   Future<MigrationState> rerun() async {
     reset();
     var state = await rerunFunction();
-    await state.refresh(_logger);
     return state;
   }
 
@@ -217,10 +202,6 @@
   /// Updates the Package Config file to specify a minimum Dart SDK version
   /// which supports null safety.
   void _processConfigFile(Folder pkgFolder, _YamlFile pubspec) {
-    if (!_packageIsNNBD) {
-      return;
-    }
-
     var packageName = pubspec._getName();
     if (packageName == null) {
       return;
@@ -302,7 +283,12 @@
 
   /// Updates the pubspec.yaml file to specify a minimum Dart SDK version which
   /// supports null safety.
-  bool _processPubspec(_YamlFile pubspec) {
+  ///
+  /// Return value indicates whether the user's `package_config.json` file
+  /// should be updated.
+  bool _processPubspec(_YamlFile pubspec, Map<String, Version> neededPackages) {
+    bool packageConfigNeedsUpdate = false;
+    bool packageDepsUpdated = false;
     var pubspecMap = pubspec.content;
     YamlNode environmentOptions;
     if (pubspecMap is YamlMap) {
@@ -313,46 +299,56 @@
       var content = '''
 environment:
   sdk: '$_intendedSdkVersionConstraint'
-
 ''';
       pubspec._insertAfterParent(
           SourceSpan(start, start, ''), content, listener);
+      packageConfigNeedsUpdate = true;
     } else if (environmentOptions is YamlMap) {
-      var sdk = environmentOptions.nodes['sdk'];
-      if (sdk == null) {
-        var content = """
-
-  sdk: '$_intendedSdkVersionConstraint'""";
-        pubspec._insertAfterParent(environmentOptions.span, content, listener);
-      } else if (sdk is YamlScalar) {
-        VersionConstraint currentConstraint;
-        if (sdk.value is String) {
-          currentConstraint = VersionConstraint.parse(sdk.value as String);
-          if (currentConstraint is VersionRange &&
-              currentConstraint.min >= _intendedMinimumSdkVersion) {
-            // The current SDK version constraint already enables Null Safety.
-            // Do not edit pubspec.yaml, nor package_config.json.
-            return false;
-          } else {
-            // TODO(srawlins): This overwrites the current maximum version. In
-            // the uncommon situation that the maximum is not '<3.0.0', it
-            // should not.
-            pubspec._replaceSpan(
-                sdk.span, "'$_intendedSdkVersionConstraint'", listener);
+      if (_updatePubspecConstraint(pubspec, environmentOptions, 'sdk',
+          "'$_intendedSdkVersionConstraint'", _intendedMinimumSdkVersion)) {
+        packageConfigNeedsUpdate = true;
+      }
+    } else {
+      // Odd malformed pubspec.  Leave it alone, but go ahead and update the
+      // package_config.json file.
+      packageConfigNeedsUpdate = true;
+    }
+    if (neededPackages.isNotEmpty) {
+      YamlNode dependencies;
+      if (pubspecMap is YamlMap) {
+        dependencies = pubspecMap.nodes['dependencies'];
+      }
+      if (dependencies == null) {
+        var depLines = [
+          for (var entry in neededPackages.entries)
+            '  ${entry.key}: ^${entry.value}'
+        ];
+        var start = SourceLocation(0, line: 0, column: 0);
+        var content = '''
+dependencies:
+${depLines.join('\n')}
+''';
+        pubspec._insertAfterParent(
+            SourceSpan(start, start, ''), content, listener);
+        packageDepsUpdated = true;
+      } else if (dependencies is YamlMap) {
+        for (var neededPackage in neededPackages.entries) {
+          if (_updatePubspecConstraint(pubspec, dependencies, neededPackage.key,
+              '^${neededPackage.value}', neededPackage.value)) {
+            packageDepsUpdated = true;
           }
-        } else {
-          // Something is odd with the SDK constraint we've found in
-          // pubspec.yaml; Best to leave it alone.
-          return false;
         }
       }
     }
+    if (packageDepsUpdated) {
+      listener.reportPubGetNeeded(neededPackages);
+    }
 
-    return true;
+    return packageConfigNeedsUpdate;
   }
 
   void _processPubspecException(String action, String pubspecPath, error) {
-    listener.addRecommendation('''Failed to $action pubspec file
+    listener.client.onFatalError('''Failed to $action pubspec file
   $pubspecPath
   $error
 
@@ -362,7 +358,49 @@
     environment:
       sdk: '$_intendedSdkVersionConstraint';
 ''');
-    _packageIsNNBD = false;
+    throw StateError('listener.reportFatalError should never return');
+  }
+
+  /// Updates a constraint in the given [pubspec] file.  If [key] is found in
+  /// [map], and the corresponding value does has a minimum less than
+  /// [minimumVersion], it is updated to [fullVersionConstraint].  If it is not
+  /// found, then an entry is added.
+  ///
+  /// Return value indicates whether a change was made.
+  bool _updatePubspecConstraint(_YamlFile pubspec, YamlMap map, String key,
+      String fullVersionConstraint, Version minimumVersion) {
+    var node = map.nodes[key];
+    if (node == null) {
+      var content = '''
+
+  $key: $fullVersionConstraint''';
+      pubspec._insertAfterParent(map.span, content, listener);
+      return true;
+    } else if (node is YamlScalar) {
+      VersionConstraint currentConstraint;
+      if (node.value is String) {
+        currentConstraint = VersionConstraint.parse(node.value as String);
+        if (currentConstraint is VersionRange &&
+            currentConstraint.min >= minimumVersion) {
+          // The current version constraint is already up to date.  Do not edit.
+          return false;
+        } else {
+          // TODO(srawlins): This overwrites the current maximum version. In
+          // the uncommon situation that there is a special maximum, it should
+          // not.
+          pubspec._replaceSpan(node.span, fullVersionConstraint, listener);
+          return true;
+        }
+      } else {
+        // Something is odd with the constraint we've found in pubspec.yaml;
+        // Best to leave it alone.
+        return false;
+      }
+    } else {
+      // Something is odd with the format of pubspec.yaml; best to leave it
+      // alone.
+      return false;
+    }
   }
 
   /// Allows unit tests to shut down any rogue servers that have been started,
@@ -471,8 +509,8 @@
   @override
   void reportException(
       Source source, AstNode node, Object exception, StackTrace stackTrace) {
-    listener.reportException('''
-$exception
+    listener.client.onException('''
+$exception at offset ${node.offset} in $source ($node)
 
 $stackTrace''');
   }
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/index.html b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
index c30f9ae..f56877d 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/index.html
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
@@ -25,7 +25,6 @@
     <h1>Dart</h1>
     <h2 class="before-apply">Proposed null safety changes</h2>
     <h2 class="after-apply">&#10003; Null safety migration applied</h2>
-    <h3 id="unit-name">&nbsp;</h3>
     <a target="_blank"
        href="https://goo.gle/dart-null-safety-migration-tool">
       <button class="action-button">
@@ -63,16 +62,26 @@
             <div class="nav-tree"></div>
         </div><!-- /nav-inner -->
     </div><!-- /nav -->
-    <div class="content">
-        <div class="regions">
-            <!-- The regions overlay code copy of the content to provide -->
-            <!-- tooltips for modified regions. -->
-        </div><!-- /regions -->
-        <div class="code">
-            <!-- Compilation unit content is written here. -->
-            <p class="welcome">
-                Select a source file on the left to preview the proposed edits.
-            </p>
+    <div class="file">
+        <div class="title-bar">
+            <h3 id="unit-name">&nbsp;</h3>
+            <span id="migrate-unit-status-icon-label">Migrate
+                <span
+                    class="material-icons status-icon migrating"
+                    id="migrate-unit-status-icon">check_box</span>
+            </span>
+        </div>
+        <div class="content">
+            <div class="regions">
+                <!-- The regions overlay code copy of the content to provide -->
+                <!-- tooltips for modified regions. -->
+            </div><!-- /regions -->
+            <div class="code">
+                <!-- Compilation unit content is written here. -->
+                <p class="welcome">
+                    Select a source file on the left to preview the proposed edits.
+                </p>
+            </div>
         </div>
     </div><!-- /content -->
     <div class="info-panel">
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
index 0e752ea..257cfef 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -9,7 +9,7 @@
 
 /* Text selection */
 ::selection {
-  background: #6e8eb1; /* $dark-selection-color */;
+  background: #6e8eb1; /* $dark-selection-color */
 }
 
 /* Material icons configuration */
@@ -93,8 +93,7 @@
 }
 
 header h1,
-header h2,
-header h3 {
+header h2 {
   display: inline-block;
   font-family: "Google Sans","Roboto",sans-serif;
   font-weight: 400;
@@ -113,13 +112,6 @@
   top: -2px;
 }
 
-header h3 {
-  /* Shift text up */
-  position: relative;
-  top: -2px;
-}
-
-
 header .action-button, header a {
   right: 0px;
   float: right;
@@ -219,7 +211,27 @@
   position: relative;
   top: 5px;
   margin-right: 8px;
-  color: #676767;
+  color: #676767; /* $secondary-color */
+}
+
+.status-icon.already-migrated {
+  color: #007a27; /* $light-green */
+}
+
+.status-icon.opted-out {
+  color: #676767; /* $secondary-color */
+}
+
+.status-icon.opted-out:hover {
+  color: #ffffff;
+}
+
+.status-icon.migrating {
+  color: #51c686; /* $dark-green */
+}
+
+.status-icon.migrating:hover {
+  color: #ffffff;
 }
 
 .nav-inner ul {
@@ -280,14 +292,41 @@
   line-height: 1em;
 }
 
-.content {
+.file {
   flex: 4 300px;
+  font-family: "Google Sans","Roboto",sans-serif;
   background: #12202f;
-  font-family: "Roboto Mono", monospace;
-  margin: 0 6px;
+  margin: 6px;
+  overflow: scroll;
+}
+
+.title-bar h3 {
+  display: inline-block;
+  font-weight: 400;
+  /* This aligns the title text with the content text, accounting for the width
+   * of the line numbers.
+   */
+  margin: 0.5em 24px 0.5em 63px;
+}
+
+.title-bar #migrate-unit-status-icon-label {
+  display: none;
+  user-select: none;
+}
+
+.title-bar #migrate-unit-status-icon-label.visible {
+  /* Change to 'inline' to enable the incremental migration feature. */
+  display: none;
+}
+
+.title-bar #migrate-unit-status-icon {
+  vertical-align: text-bottom;
+}
+
+.content {
+  font-family: "Roboto Mono",monospace;
   position: relative;
   white-space: pre;
-  overflow: scroll;
 }
 
 .code {
@@ -639,7 +678,7 @@
  * Adjustments to align material icons in the toolbar buttons.
 */
 .action-button > span {
-  position:relative;
+  position: relative;
   top: -3px;
 }
 
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index 0ae2d82..b03dfe6 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -7422,7 +7422,7 @@
 ''';
 
 String _index_html;
-// index_html md5 is 'f17972e91adf7afeeed745126e359ffb'
+// index_html md5 is '4dc4d54418f267d0f9189690626e0f2a'
 String _index_html_base64 = '''
 PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
 cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
@@ -7443,51 +7443,57 @@
 YWx0PSJEYXJ0UGFkIExvZ28iIGNsYXNzPSJsb2dvIi8+CiAgICA8aDE+RGFydDwvaDE+CiAgICA8aDIg
 Y2xhc3M9ImJlZm9yZS1hcHBseSI+UHJvcG9zZWQgbnVsbCBzYWZldHkgY2hhbmdlczwvaDI+CiAgICA8
 aDIgY2xhc3M9ImFmdGVyLWFwcGx5Ij4mIzEwMDAzOyBOdWxsIHNhZmV0eSBtaWdyYXRpb24gYXBwbGll
-ZDwvaDI+CiAgICA8aDMgaWQ9InVuaXQtbmFtZSI+Jm5ic3A7PC9oMz4KICAgIDxhIHRhcmdldD0iX2Js
-YW5rIgogICAgICAgaHJlZj0iaHR0cHM6Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9u
-LXRvb2wiPgogICAgICA8YnV0dG9uIGNsYXNzPSJhY3Rpb24tYnV0dG9uIj4KICAgICAgICA8aSBjbGFz
-cz0ibWF0ZXJpYWwtaWNvbnMiPmxhdW5jaDwvaT4KICAgICAgICA8c3Bhbj5IZWxwPC9zcGFuPgogICAg
-ICA8L2J1dHRvbj4KICAgIDwvYT4KICAgIDxidXR0b24gY2xhc3M9ImFjdGlvbi1idXR0b24gYXBwbHkt
-bWlncmF0aW9uIj4KICAgICAgICA8aSBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMiPmVkaXQ8L2k+CiAgICAg
-ICAgPHNwYW4gY2xhc3M9ImxhYmVsIj4KICAgICAgICAgIEFwcGx5IE1pZ3JhdGlvbgogICAgICAgIDwv
-c3Bhbj4KICAgIDwvYnV0dG9uPgogICAgPGJ1dHRvbiBjbGFzcz0iYWN0aW9uLWJ1dHRvbiBhcHBseS1t
-aWdyYXRpb24iIGRpc2FibGVkPgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+ZWRpdDwv
-aT4KICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPgogICAgICAgICAgQXBwbHkgTWlncmF0aW9uCiAg
-ICAgICAgPC9zcGFuPgogICAgPC9idXR0b24+CiAgICA8YnV0dG9uIGNsYXNzPSJhY3Rpb24tYnV0dG9u
-IHJlcnVuLW1pZ3JhdGlvbiBiZWZvcmUtYXBwbHkiPgogICAgICA8c3BhbiBjbGFzcz0ib3B0aW9uYWwi
-PgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+cmVwbGF5PC9pPgogICAgICAgIFJlcnVu
-IEZyb20gU291cmNlcwogICAgICA8L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJyZXF1aXJlZCI+CiAg
-ICAgICAgPGkgY2xhc3M9Im1hdGVyaWFsLWljb25zIj53YXJuaW5nPC9pPgogICAgICAgIFJlcnVuIFdp
-dGggQ2hhbmdlcwogICAgICA8L3NwYW4+CiAgICA8L2J1dHRvbj4KPC9oZWFkZXI+CjxkaXYgY2xhc3M9
-InBhbmVscyBob3Jpem9udGFsIj4KICAgIDxkaXYgY2xhc3M9Im5hdi1wYW5lbCI+CiAgICAgICAgPGRp
-diBjbGFzcz0ibmF2LWlubmVyIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+
-UHJvamVjdCBGaWxlczwvZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJuYXYtdHJlZSI+PC9kaXY+
-CiAgICAgICAgPC9kaXY+PCEtLSAvbmF2LWlubmVyIC0tPgogICAgPC9kaXY+PCEtLSAvbmF2IC0tPgog
-ICAgPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICAgICAgPGRpdiBjbGFzcz0icmVnaW9ucyI+CiAgICAg
-ICAgICAgIDwhLS0gVGhlIHJlZ2lvbnMgb3ZlcmxheSBjb2RlIGNvcHkgb2YgdGhlIGNvbnRlbnQgdG8g
-cHJvdmlkZSAtLT4KICAgICAgICAgICAgPCEtLSB0b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4g
-LS0+CiAgICAgICAgPC9kaXY+PCEtLSAvcmVnaW9ucyAtLT4KICAgICAgICA8ZGl2IGNsYXNzPSJjb2Rl
-Ij4KICAgICAgICAgICAgPCEtLSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJl
-LiAtLT4KICAgICAgICAgICAgPHAgY2xhc3M9IndlbGNvbWUiPgogICAgICAgICAgICAgICAgU2VsZWN0
-IGEgc291cmNlIGZpbGUgb24gdGhlIGxlZnQgdG8gcHJldmlldyB0aGUgcHJvcG9zZWQgZWRpdHMuCiAg
-ICAgICAgICAgIDwvcD4KICAgICAgICA8L2Rpdj4KICAgIDwvZGl2PjwhLS0gL2NvbnRlbnQgLS0+CiAg
-ICA8ZGl2IGNsYXNzPSJpbmZvLXBhbmVsIj4KICAgICAgICA8ZGl2IGNsYXNzPSJlZGl0LWxpc3QiPgog
-ICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5Qcm9wb3NlZCBFZGl0czwvZGl2Pgog
-ICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1jb250ZW50Ij48L2Rpdj4KICAgICAgICA8L2Rpdj48
-IS0tIC9lZGl0LWxpc3QgLS0+CiAgICAgICAgPGRpdiBjbGFzcz0iZWRpdC1wYW5lbCI+CiAgICAgICAg
-ICAgIDxkaXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPkVkaXQgRGV0YWlsczwvZGl2PgogICAgICAgICAg
-ICA8ZGl2IGNsYXNzPSJwYW5lbC1jb250ZW50Ij4KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJwbGFj
-ZWhvbGRlciI+U2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LjwvcD4KICAgICAgICAgICAg
-PC9kaXY+PCEtLSAvcGFuZWwtY29udGVudCAtLT4KICAgICAgICA8L2Rpdj48IS0tIC9lZGl0LXBhbmVs
-IC0tPgogICAgPC9kaXY+PCEtLSAvaW5mby1wYW5lbCAtLT4KPC9kaXY+PCEtLSAvcGFuZWxzIC0tPgo8
-Zm9vdGVyPgogIDxidXR0b24gY2xhc3M9InJlcG9ydC1wcm9ibGVtIj5TZW5kIEZlZWRiYWNrPC9idXR0
-b24+CiAgICA8c3BhbiBjbGFzcz0id2lkZSI+IDwvc3Bhbj4KICAgIDxkaXYgY2xhc3M9InNkay12ZXJz
-aW9uIj5CYXNlZCBvbiA8c3BhbiBpZD0ic2RrLXZlcnNpb24iPnt7IHNka1ZlcnNpb24gfX08L3NwYW4+
-PC9kaXY+CjwvZm9vdGVyPgo8L2JvZHk+CjwvaHRtbD4K
+ZDwvaDI+CiAgICA8YSB0YXJnZXQ9Il9ibGFuayIKICAgICAgIGhyZWY9Imh0dHBzOi8vZ29vLmdsZS9k
+YXJ0LW51bGwtc2FmZXR5LW1pZ3JhdGlvbi10b29sIj4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYWN0aW9u
+LWJ1dHRvbiI+CiAgICAgICAgPGkgY2xhc3M9Im1hdGVyaWFsLWljb25zIj5sYXVuY2g8L2k+CiAgICAg
+ICAgPHNwYW4+SGVscDwvc3Bhbj4KICAgICAgPC9idXR0b24+CiAgICA8L2E+CiAgICA8YnV0dG9uIGNs
+YXNzPSJhY3Rpb24tYnV0dG9uIGFwcGx5LW1pZ3JhdGlvbiI+CiAgICAgICAgPGkgY2xhc3M9Im1hdGVy
+aWFsLWljb25zIj5lZGl0PC9pPgogICAgICAgIDxzcGFuIGNsYXNzPSJsYWJlbCI+CiAgICAgICAgICBB
+cHBseSBNaWdyYXRpb24KICAgICAgICA8L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxidXR0b24gY2xh
+c3M9ImFjdGlvbi1idXR0b24gYXBwbHktbWlncmF0aW9uIiBkaXNhYmxlZD4KICAgICAgICA8aSBjbGFz
+cz0ibWF0ZXJpYWwtaWNvbnMiPmVkaXQ8L2k+CiAgICAgICAgPHNwYW4gY2xhc3M9ImxhYmVsIj4KICAg
+ICAgICAgIEFwcGx5IE1pZ3JhdGlvbgogICAgICAgIDwvc3Bhbj4KICAgIDwvYnV0dG9uPgogICAgPGJ1
+dHRvbiBjbGFzcz0iYWN0aW9uLWJ1dHRvbiByZXJ1bi1taWdyYXRpb24gYmVmb3JlLWFwcGx5Ij4KICAg
+ICAgPHNwYW4gY2xhc3M9Im9wdGlvbmFsIj4KICAgICAgICA8aSBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMi
+PnJlcGxheTwvaT4KICAgICAgICBSZXJ1biBGcm9tIFNvdXJjZXMKICAgICAgPC9zcGFuPgogICAgICA8
+c3BhbiBjbGFzcz0icmVxdWlyZWQiPgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+d2Fy
+bmluZzwvaT4KICAgICAgICBSZXJ1biBXaXRoIENoYW5nZXMKICAgICAgPC9zcGFuPgogICAgPC9idXR0
+b24+CjwvaGVhZGVyPgo8ZGl2IGNsYXNzPSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2IGNsYXNz
+PSJuYXYtcGFuZWwiPgogICAgICAgIDxkaXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAgICAgIDxk
+aXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAgICAgPGRp
+diBjbGFzcz0ibmF2LXRyZWUiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5lciAtLT4K
+ICAgIDwvZGl2PjwhLS0gL25hdiAtLT4KICAgIDxkaXYgY2xhc3M9ImZpbGUiPgogICAgICAgIDxkaXYg
+Y2xhc3M9InRpdGxlLWJhciI+CiAgICAgICAgICAgIDxoMyBpZD0idW5pdC1uYW1lIj4mbmJzcDs8L2gz
+PgogICAgICAgICAgICA8c3BhbiBpZD0ibWlncmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsIj5NaWdy
+YXRlCiAgICAgICAgICAgICAgICA8c3BhbgogICAgICAgICAgICAgICAgICAgIGNsYXNzPSJtYXRlcmlh
+bC1pY29ucyBzdGF0dXMtaWNvbiBtaWdyYXRpbmciCiAgICAgICAgICAgICAgICAgICAgaWQ9Im1pZ3Jh
+dGUtdW5pdC1zdGF0dXMtaWNvbiI+Y2hlY2tfYm94PC9zcGFuPgogICAgICAgICAgICA8L3NwYW4+CiAg
+ICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICAgICAgICAgIDxkaXYg
+Y2xhc3M9InJlZ2lvbnMiPgogICAgICAgICAgICAgICAgPCEtLSBUaGUgcmVnaW9ucyBvdmVybGF5IGNv
+ZGUgY29weSBvZiB0aGUgY29udGVudCB0byBwcm92aWRlIC0tPgogICAgICAgICAgICAgICAgPCEtLSB0
+b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4gLS0+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3Jl
+Z2lvbnMgLS0+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImNvZGUiPgogICAgICAgICAgICAgICAgPCEt
+LSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJlLiAtLT4KICAgICAgICAgICAg
+ICAgIDxwIGNsYXNzPSJ3ZWxjb21lIj4KICAgICAgICAgICAgICAgICAgICBTZWxlY3QgYSBzb3VyY2Ug
+ZmlsZSBvbiB0aGUgbGVmdCB0byBwcmV2aWV3IHRoZSBwcm9wb3NlZCBlZGl0cy4KICAgICAgICAgICAg
+ICAgIDwvcD4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj48IS0tIC9j
+b250ZW50IC0tPgogICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAgICAgICAgPGRpdiBjbGFzcz0i
+ZWRpdC1saXN0Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+UHJvcG9zZWQg
+RWRpdHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+PC9kaXY+CiAg
+ICAgICAgPC9kaXY+PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxkaXYgY2xhc3M9ImVkaXQtcGFu
+ZWwiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5FZGl0IERldGFpbHM8L2Rp
+dj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+CiAgICAgICAgICAgICAgICA8
+cCBjbGFzcz0icGxhY2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC48L3A+
+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+CiAgICAgICAgPC9kaXY+PCEt
+LSAvZWRpdC1wYW5lbCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFuZWwgLS0+CjwvZGl2PjwhLS0g
+L3BhbmVscyAtLT4KPGZvb3Rlcj4KICA8YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+U2VuZCBG
+ZWVkYmFjazwvYnV0dG9uPgogICAgPHNwYW4gY2xhc3M9IndpZGUiPiA8L3NwYW4+CiAgICA8ZGl2IGNs
+YXNzPSJzZGstdmVyc2lvbiI+QmFzZWQgb24gPHNwYW4gaWQ9InNkay12ZXJzaW9uIj57eyBzZGtWZXJz
+aW9uIH19PC9zcGFuPjwvZGl2Pgo8L2Zvb3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
 ''';
 
 String _migration_css;
-// migration_css md5 is '091ec5ef4e9fd6f11ad8bda81bdd26e4'
+// migration_css md5 is 'cb4dfc4d6f9dd25370605e3a5e35ace6'
 String _migration_css_base64 = '''
 LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
 dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
@@ -7497,198 +7503,211 @@
 bG9yIiBhcmUgZnJvbSBEYXJ0UGFkOgogKiBodHRwczovL2dpdGh1Yi5jb20vZGFydC1sYW5nL2RhcnQt
 cGFkL2Jsb2IvbWFzdGVyL2xpYi9zY3NzL2NvbG9ycy5zY3NzCiAqLwoKLyogVGV4dCBzZWxlY3Rpb24g
 Ki8KOjpzZWxlY3Rpb24gewogIGJhY2tncm91bmQ6ICM2ZThlYjE7IC8qICRkYXJrLXNlbGVjdGlvbi1j
-b2xvciAqLzsKfQoKLyogTWF0ZXJpYWwgaWNvbnMgY29uZmlndXJhdGlvbiAqLwpAZm9udC1mYWNlIHsK
-ICBmb250LWZhbWlseTogJ01hdGVyaWFsIEljb25zJzsKICBmb250LXN0eWxlOiBub3JtYWw7CiAgZm9u
-dC13ZWlnaHQ6IDQwMDsKICBzcmM6IGxvY2FsKCdNYXRlcmlhbCBJY29ucycpLAogIGxvY2FsKCdNYXRl
-cmlhbEljb25zLVJlZ3VsYXInKSwKICB1cmwoL01hdGVyaWFsSWNvbnNSZWd1bGFyLnR0ZikgZm9ybWF0
-KCd0cnVldHlwZScpOwp9CgovKgogKiBSZXF1aXJlZCBmb3IgTWF0ZXJpYWwgSWNvbnM6CiAqIGh0dHBz
-Oi8vZ29vZ2xlLmdpdGh1Yi5pby9tYXRlcmlhbC1kZXNpZ24taWNvbnMvCiAqLwoubWF0ZXJpYWwtaWNv
-bnMgewogIGZvbnQtZmFtaWx5OiAnTWF0ZXJpYWwgSWNvbnMnOwogIGZvbnQtd2VpZ2h0OiBub3JtYWw7
-CiAgZm9udC1zdHlsZTogbm9ybWFsOwogIGZvbnQtc2l6ZTogMjRweDsgIC8qIFByZWZlcnJlZCBpY29u
-IHNpemUgKi8KICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgbGluZS1oZWlnaHQ6IDE7CiAgdGV4dC10
-cmFuc2Zvcm06IG5vbmU7CiAgbGV0dGVyLXNwYWNpbmc6IG5vcm1hbDsKICB3b3JkLXdyYXA6IG5vcm1h
-bDsKICB3aGl0ZS1zcGFjZTogbm93cmFwOwogIGRpcmVjdGlvbjogbHRyOwoKICAvKiBTdXBwb3J0IGZv
-ciBhbGwgV2ViS2l0IGJyb3dzZXJzLiAqLwogIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlh
-c2VkOwogIC8qIFN1cHBvcnQgZm9yIFNhZmFyaSBhbmQgQ2hyb21lLiAqLwogIHRleHQtcmVuZGVyaW5n
-OiBvcHRpbWl6ZUxlZ2liaWxpdHk7CgogIC8qIFN1cHBvcnQgZm9yIEZpcmVmb3guICovCiAgLW1vei1v
-c3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTsKCiAgLyogU3VwcG9ydCBmb3IgSUUuICovCiAgZm9u
-dC1mZWF0dXJlLXNldHRpbmdzOiAnbGlnYSc7Cn0KCmJvZHkgewogIGJhY2tncm91bmQtY29sb3I6ICMx
-MjIwMmY7CiAgY29sb3I6ICNjY2M7CiAgZm9udC1mYW1pbHk6ICJSb2JvdG8iLCBzYW5zLXNlcmlmOwog
-IGZvbnQtc2l6ZTogMTRweDsKICBkaXNwbGF5OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47
-CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRvcDogMDsKICByaWdodDogMDsKICBib3R0b206IDA7CiAg
-bGVmdDogMDsKICBtYXJnaW46IDA7CiAgcGFkZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9Cgou
-cHJvcG9zZWQgLmFmdGVyLWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYmVmb3Jl
-LWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYXBwbHktbWlncmF0aW9uOm5vdChb
-ZGlzYWJsZWRdKSwgLm5lZWRzLXJlcnVuIC5hcHBseS1taWdyYXRpb246bm90KFtkaXNhYmxlZF0pIHsK
-ICBkaXNwbGF5OiBub25lOwp9CgoucHJvcG9zZWQ6bm90KC5uZWVkcy1yZXJ1bikgLmFwcGx5LW1pZ3Jh
-dGlvbltkaXNhYmxlZF0gewogIGRpc3BsYXk6IG5vbmU7Cn0KCmhlYWRlciB7CiAgYmFja2dyb3VuZC1j
-b2xvcjogIzFjMjgzNDsKICBoZWlnaHQ6IDQ4cHg7CiAgcGFkZGluZy1sZWZ0OiAyNHB4OwogIGFsaWdu
-LWl0ZW1zOiBjZW50ZXI7CiAgei1pbmRleDogNDsKfQoKaGVhZGVyIGgxLApoZWFkZXIgaDIsCmhlYWRl
-ciBoMyB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMi
-LCJSb2JvdG8iLHNhbnMtc2VyaWY7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICBtYXJnaW4tcmlnaHQ6IDI0
-cHg7Cn0KCmgxIHsKICBmb250LXNpemU6IDEuNWVtOwp9CgpoZWFkZXIgaDIgewogIGZvbnQtc2l6ZTog
-MS4yZW07CgogIC8qIFNoaWZ0IHRleHQgdXAgKi8KICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9wOiAt
-MnB4Owp9CgpoZWFkZXIgaDMgewogIC8qIFNoaWZ0IHRleHQgdXAgKi8KICBwb3NpdGlvbjogcmVsYXRp
-dmU7CiAgdG9wOiAtMnB4Owp9CgoKaGVhZGVyIC5hY3Rpb24tYnV0dG9uLCBoZWFkZXIgYSB7CiAgcmln
-aHQ6IDBweDsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luOiAxMHB4Owp9CgpoZWFkZXIgaW1nLmxvZ28g
-ewogIGhlaWdodDogMjRweDsKICB3aWR0aDogMjRweDsKICBtYXJnaW4tcmlnaHQ6IDhweDsKICBwb3Np
-dGlvbjogcmVsYXRpdmU7CiAgdG9wOiA0cHg7Cn0KCmZvb3RlciAucmVwb3J0LXByb2JsZW0gewogIHJp
-Z2h0OiAwcHg7CiAgbWFyZ2luOiA0cHggOHB4Owp9CgoucmVydW4tbWlncmF0aW9uIC5yZXF1aXJlZCB7
-CiAgZGlzcGxheTogbm9uZTsKfQoKLm5lZWRzLXJlcnVuIC5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVk
-IHsKICBkaXNwbGF5OiBpbml0aWFsOwp9CgoubmVlZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAub3B0
-aW9uYWwgewogIGRpc3BsYXk6bm9uZTsKfQoKZm9vdGVyIHsKICBjb2xvcjogI2NjYzsKICBiYWNrZ3Jv
-dW5kLWNvbG9yOiAjMjczMjNhOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IHJvdzsK
-ICBhbGlnbi1pdGVtczogY2VudGVyOwogIHBhZGRpbmc6IDhweCAwIDhweCAyNHB4Owp9Cgpmb290ZXIg
-LndpZGUgewogIGZsZXg6IDE7Cn0KCmZvb3RlciAuc2RrLXZlcnNpb24gewogIG1hcmdpbi1yaWdodDog
-MzJweDsKfQoKLmhvcml6b250YWwgewogIGRpc3BsYXk6IGZsZXg7Cn0KCi5wYW5lbHMgewogIGJhY2tn
-cm91bmQtY29sb3I6ICMxMjFhMjU7CiAgZmxleDogMTsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucGFu
-ZWwtaGVhZGluZyB7CiAgY29sb3I6ICM2NzY3Njc7CiAgbWFyZ2luOiA4cHg7Cn0KCi5uYXYtbGluaywK
-LnJlZ2lvbiB7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgoubmF2LXBhbmVsIHsKICBiYWNrZ3JvdW5kLWNv
-bG9yOiAjMTIyMDJmOwogIGZsZXg6IDEgMjAwcHg7CiAgbWFyZ2luOiAwOwogIG92ZXJmbG93OiBzY3Jv
-bGw7CiAgdXNlci1zZWxlY3Q6IG5vbmU7Cn0KCi5uYXYtaW5uZXIgewogIHBhZGRpbmc6IDAgMCA3cHgg
-N3B4Owp9CgouZml4ZWQgewogIHBvc2l0aW9uOiBmaXhlZDsKICB0b3A6IDA7Cn0KCi5yb290IHsKICBt
-YXJnaW46IDA7CiAgZGlzcGxheTogbm9uZTsKfQoKLm5hdi10cmVlID4gdWwgewogIHBhZGRpbmctbGVm
-dDogNnB4Owp9CgoubmF2LXRyZWUgLm1hdGVyaWFsLWljb25zIHsKICBmb250LXNpemU6IDIwcHg7CiAg
-cG9zaXRpb246IHJlbGF0aXZlOwogIHRvcDogNXB4OwogIG1hcmdpbi1yaWdodDogOHB4OwogIGNvbG9y
-OiAjNjc2NzY3Owp9CgoubmF2LWlubmVyIHVsIHsKICBwYWRkaW5nLWxlZnQ6IDEycHg7CiAgbWFyZ2lu
-OiAwOwp9CgoubmF2LWlubmVyIGxpIHsKICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7CiAgd2hpdGUtc3Bh
-Y2U6IG5vd3JhcDsKfQoKLm5hdi1pbm5lciBsaTpub3QoLmRpcikgewogIG1hcmdpbi1sZWZ0OiAyMHB4
-OwogIG1hcmdpbi1ib3R0b206IDNweDsKfQoKLm5hdi1pbm5lciBsaS5kaXIgLmFycm93IHsKICBjdXJz
-b3I6IHBvaW50ZXI7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtc2l6ZTogMTBweDsKICBt
-YXJnaW4tcmlnaHQ6IDRweDsKICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC41cyBlYXNlLW91dDsKfQoK
-Lm5hdi1pbm5lciBsaS5kaXIgLmFycm93LmNvbGxhcHNlZCB7CiAgdHJhbnNmb3JtOiByb3RhdGUoLTkw
-ZGVnKTsKfQoKLm5hdi1pbm5lciB1bCB7CiAgLyogYSBtYXgtaGVpZ2h0IGlzIGFkZGVkIHRvIGVhY2gg
-ZWxlbWVudCBhdCBydW50aW1lLiAqLwogIHRyYW5zaXRpb246IG1heC1oZWlnaHQgMC41cyBlYXNlLW91
-dDsKfQoKLm5hdi1pbm5lciB1bC5jb2xsYXBzZWQgewogIG1heC1oZWlnaHQ6IDAgIWltcG9ydGFudDsK
-ICBvdmVyZmxvdzogaGlkZGVuOwp9CgoubmF2LWlubmVyIC5zZWxlY3RlZC1maWxlIHsKICBjb2xvcjog
-d2hpdGU7CiAgY3Vyc29yOiBpbmhlcml0OwogIGZvbnQtd2VpZ2h0OiA2MDA7CiAgdGV4dC1kZWNvcmF0
-aW9uOiBub25lOwp9CgouZWRpdC1jb3VudCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzY3Njc2NzsKICBi
-b3JkZXItcmFkaXVzOiAxMHB4OwogIGNvbG9yOiAjZmZmOwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsK
-ICBmb250LXNpemU6IDExcHg7CiAgZm9udC13ZWlnaHQ6IDYwMDsKICBtYXJnaW4tbGVmdDogNXB4Owog
-IG1pbi13aWR0aDogMjVweDsKICBwYWRkaW5nOiA0cHggMCAycHggMDsKICB0ZXh0LWFsaWduOiBjZW50
-ZXI7CiAgbGluZS1oZWlnaHQ6IDFlbTsKfQoKLmNvbnRlbnQgewogIGZsZXg6IDQgMzAwcHg7CiAgYmFj
-a2dyb3VuZDogIzEyMjAyZjsKICBmb250LWZhbWlseTogIlJvYm90byBNb25vIiwgbW9ub3NwYWNlOwog
-IG1hcmdpbjogMCA2cHg7CiAgcG9zaXRpb246IHJlbGF0aXZlOwogIHdoaXRlLXNwYWNlOiBwcmU7CiAg
-b3ZlcmZsb3c6IHNjcm9sbDsKfQoKLmNvZGUgewogIHBhZGRpbmc6IDAuNWVtOwogIHBvc2l0aW9uOiBh
-YnNvbHV0ZTsKICBsZWZ0OiAwOwogIHRvcDogMDsKICBtYXJnaW4tbGVmdDogNTZweDsKfQoKLmNvZGUg
-LndlbGNvbWUgewogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNhbnMtc2VyaWY7
-CiAgZm9udC1zaXplOiAxOHB4OwogIG1hcmdpbi1yaWdodDogNjJweDsKICBjb2xvcjogIzc3NzsKfQoK
-LmNvZGUgLm5hdi1saW5rIHsKICBjb2xvcjogIzE2YWRjYTsKICB0ZXh0LWRlY29yYXRpb24tbGluZTog
-bm9uZTsKfQoKLmNvZGUgLm5hdi1saW5rOnZpc2l0ZWQgewogIGNvbG9yOiAjMTM5YmI1OyAvKiAjMTZh
-ZGNhIGRhcmtlbmVkIDEwJSAqLwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAu
-bmF2LWxpbms6aG92ZXIgewogIHRleHQtZGVjb3JhdGlvbi1saW5lOiB1bmRlcmxpbmU7CiAgZm9udC13
-ZWlnaHQ6IDYwMDsKfQoKLnJlZ2lvbnMgewogIHBhZGRpbmc6IDAuNWVtOwogIHBvc2l0aW9uOiBhYnNv
-bHV0ZTsKICBsZWZ0OiAwOwogIHRvcDogMDsKfQoKLnJlZ2lvbnMgdGFibGUgewogIGJvcmRlci1zcGFj
-aW5nOiAwOwogIGZvbnQtc2l6ZTogaW5oZXJpdDsKfQoKLnJlZ2lvbnMgdGQgewogIGJvcmRlcjogbm9u
-ZTsKICAvKiBUaGUgY29udGVudCBvZiB0aGUgcmVnaW9ucyBpcyBub3QgdmlzaWJsZTsgdGhlIHVzZXIg
-aW5zdGVhZCB3aWxsIHNlZSB0aGUKICAgKiBoaWdobGlnaHRlZCBjb3B5IG9mIHRoZSBjb250ZW50LiAq
-LwogIGNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDApOwogIHBhZGRpbmc6IDA7CiAgd2hpdGUtc3Bh
-Y2U6IHByZTsKfQoKLnJlZ2lvbnMgdGQ6ZW1wdHk6YWZ0ZXIgewogIGNvbnRlbnQ6ICJcMDBhMCI7Cn0K
-Ci5yZWdpb25zIHRyLmhpZ2hsaWdodCB0ZDpsYXN0LWNoaWxkIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
-NDQ0NDQ0OwogIGNvbG9yOiB3aGl0ZTsKfQoKLnJlZ2lvbnMgdGQubGluZS1ubyB7CiAgYm9yZGVyLXJp
-Z2h0OiBzb2xpZCAjMTIyMDJmIDJweDsKICBjb2xvcjogIzk5OTk5OTsKICBwYWRkaW5nLXJpZ2h0OiA0
-cHg7CiAgdGV4dC1hbGlnbjogcmlnaHQ7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB3aWR0aDogNTBw
-eDsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7Cn0KCi5yZWdpb25zIHRyLmhpZ2hsaWdodCB0ZC5saW5l
-LW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICNjY2MgMnB4Owp9CgoucmVnaW9uIHsKICBkaXNwbGF5
-OiBpbmxpbmUtYmxvY2s7CiAgcG9zaXRpb246IHJlbGF0aXZlOwogIHZpc2liaWxpdHk6IHZpc2libGU7
-CiAgei1pbmRleDogMjAwOwp9CgoucmVnaW9uLmFkZGVkLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1jb2xv
-cjogIzE3OGFmZDsKICBjb2xvcjogI2ZmZjsKfQoKLnJlZ2lvbi5yZW1vdmVkLXJlZ2lvbiB7CiAgYmFj
-a2dyb3VuZC1jb2xvcjogI0ZBNTU3ZDsgLyogJGRhcmstcGluayAqLwogIGNvbG9yOiAjZmZmOwp9Cgou
-cmVnaW9uLmluZm9ybWF0aXZlLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzI2Mzk1MjsKICBj
-b2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgaGVpZ2h0OiAxNXB4OwogIHBvc2l0
-aW9uOiByZWxhdGl2ZTsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDsKICBwb3Np
-dGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICBmb250LXdlaWdodDogNjAwOwp9
-CgouaW5mby1wYW5lbCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46IDA7CiAgaGVpZ2h0OiAxMDAl
-OwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKfQoKLmluZm8tcGFuZWwg
-LmVkaXQtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgb3ZlcmZsb3c6IGF1dG87
-Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRkaW5nOiA3cHg7Cn0KCi5pbmZvLXBh
-bmVsIC5wYW5lbC1jb250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1hcmdpbi10b3A6IDA7Cn0KCi5pbmZv
-LXBhbmVsIC5ub3dyYXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5pbmZvLXBhbmVsIHVsLAou
-aW5mby1wYW5lbCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9CgouaW5mby1wYW5lbCBsaSB7CiAg
-bWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewogIGNvbG9yOiAjMTM5YmI1Owp9Cgou
-aW5mby1wYW5lbCBhOmhvdmVyIHsKICBjb2xvcjogIzFlYzdlNzsgLyogIzEzOWJiNSBsaWdodGVuZWQg
-MjAlICovCn0KCi5pbmZvLXBhbmVsIC5lZGl0LWxpc3QgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIw
-MmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5lZGl0LXBhbmVsIHsKICBtYXJnaW4tdG9wOiA2cHg7CiAg
-ZmxleDogMSAxMDBweDsKfQoKLmVkaXQtbGlzdCB7CiAgZmxleDogMiAxMDBweDsKfQoKLmVkaXQtbGlz
-dCAuZWRpdCB7CiAgbWFyZ2luOiAzcHggMDsKfQoKLmVkaXQtbGlzdCAuZWRpdC1saW5rIHsKICBjdXJz
-b3I6IHBvaW50ZXI7Cn0KCi5wb3B1cC1wYW5lIHsKICBkaXNwbGF5OiBub25lOwogIHBvc2l0aW9uOiBm
-aXhlZDsKICB0b3A6IDE1MHB4OwogIGxlZnQ6IDE1MHB4OwogIHJpZ2h0OiAxNTBweDsKICBib3R0b206
-IDE1MHB4OwogIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrOwogIGJvcmRlci10b3A6IDJweCBzb2xpZCBi
-bGFjazsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYm94LXNoYWRvdzogMHB4IDBweCAyMHB4IDJweCAj
-YjRiZmNiMjI7CiAgei1pbmRleDogNDAwOwogIGJhY2tncm91bmQ6ICMyYjMwMzY7CiAgcGFkZGluZzog
-MjBweDsKfQoKLnBvcHVwLXBhbmUgLmNsb3NlIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgcmlnaHQ6
-IDEwcHg7CiAgdG9wOiAxMHB4OwogIGN1cnNvcjogcG9pbnRlcjsKICB0ZXh0LXNoYWRvdzogMXB4IDFw
-eCAycHggIzg4ODsKICBib3gtc2hhZG93OiAxcHggMXB4IDJweCAjMTExOwp9CgoucG9wdXAtcGFuZSBo
-MiB7CiAgcGFkZGluZzogMjFweDsKICBoZWlnaHQ6IDEwJTsKICBtYXJnaW46IDBweDsKICBib3gtc2l6
-aW5nOiBib3JkZXItYm94Owp9CgoucG9wdXAtcGFuZSBwIHsKICBoZWlnaHQ6IDEwJTsKICBib3gtc2l6
-aW5nOiBib3JkZXItYm94OwogIHBhZGRpbmc6IDBweCAyMHB4Owp9CgoucG9wdXAtcGFuZSBwcmUgewog
-IGJhY2tncm91bmQ6ICMxMjIwMmY7CiAgcGFkZGluZzogMjBweDsKICBib3R0b206IDBweDsKICBvdmVy
-ZmxvdzogYXV0byBzY3JvbGw7CiAgaGVpZ2h0OiA2NSU7CiAgbWFyZ2luOiAwcHg7CiAgYm94LXNpemlu
-ZzogYm9yZGVyLWJveDsKfQoKLnBvcHVwLXBhbmUgLmJ1dHRvbi5ib3R0b20gewogIG1hcmdpbjogMjBw
-eCAwcHg7CiAgZGlzcGxheTogYmxvY2s7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgoucmVydW5uaW5n
-LXBhbmUgewogIGRpc3BsYXk6IG5vbmU7Cn0KCmJvZHkucmVydW5uaW5nIC5yZXJ1bm5pbmctcGFuZSB7
-CiAgZGlzcGxheTogYmxvY2s7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMHB4OwogIGJvdHRvbTog
-MHB4OwogIGxlZnQ6IDBweDsKICByaWdodDogMHB4OwogIGJhY2tncm91bmQtY29sb3I6ICMwMDAwMDBB
-QTsgLyogdHJhbnNsdWNlbnQgYmxhY2sgKi8KICB6LWluZGV4OiA0MDA7Cn0KCi5yZXJ1bm5pbmctcGFu
-ZSBoMSB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRvcDogNTAlOwogIGxlZnQ6IDUwJTsKICB0cmFu
-c2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTsKfQoKLmVkaXQtcGFuZWwgLnR5cGUtZGVzY3JpcHRp
-b24gewogIC8qIEZyb20gRGFydFBhZCAkZGFyay1vcmFuZ2UgKi8KICBjb2xvcjogI2ZmOTE2ZTsKICBm
-b250LWZhbWlseTogbW9ub3NwYWNlOwp9Cgp1bC50cmFjZSB7CiAgZm9udC1zaXplOiAxM3B4OwogIGxp
-c3Qtc3R5bGUtdHlwZTogbm9uZTsKICBwYWRkaW5nLWxlZnQ6IDBweDsKfQoKdWwudHJhY2UgbGkgewog
-IGNvbG9yOiB3aGl0ZTsKfQoKdWwudHJhY2UgbGkgLmZ1bmN0aW9uIHsKICAvKiBmcm9tIC5obGpzLXZh
-cmlhYmxlICovCiAgY29sb3I6ICMxNmFkY2E7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250
-LXdlaWdodDogNjAwOwp9Cgp1bC50cmFjZSBsaSBwLmRyYXdlciB7CiAgbWFyZ2luOiAzcHggMHB4Owog
-IHBhZGRpbmc6IDBweCAwcHggMHB4IDE0cHg7Cn0KCnVsLnRyYWNlIGxpIHAuZHJhd2VyIGJ1dHRvbiB7
-CiAgbWFyZ2luLXJpZ2h0OiAzcHg7Cn0KCi5lbGV2YXRpb24tejQgewogIGJveC1zaGFkb3c6IDBweCAy
-cHggNHB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjIpLAogICAgICAwcHggNHB4IDVweCAwcHggcmdiYSgw
-LCAwLCAwLCAwLjE0KSwKICAgICAgMHB4IDFweCAxMHB4IDBweCByZ2JhKDAsIDAsIDAsIC4xMik7Cn0K
-CmEgewogIGNvbG9yOiAjY2NjOwogIGZpbGw6ICNjY2M7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9
-CgphOmhvdmVyIHsKICBjb2xvcjogI2RiZGJkYjsgLyogI2NjYyBsaWdodGVudGVkIDMwJSovCiAgZmls
-bDogI2ZmZjsKfQoKLmFkZC1oaW50LWxpbmsgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBtYXJn
-aW46IDNweDsKfQoKLmFkZC1oaW50LWxpbms6aG92ZXIgewogIGNvbG9yOiAjZmZmOwp9CgpoZWFkZXIg
-YnV0dG9uIHsKICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOwp9CgpoZWFkZXIgYSB7CiAgbWFyZ2lu
-OiAwOwp9CgovKiBDYXJlZnVsIGhlcmUuIGBhLmJ1dHRvbmAgaXMgcmVwZXRpdGl2ZSBidXQgcmVxdWly
-ZWQgdG8gZ2V0IGNvcnJlY3QKICogc3BlY2lmaWNpdHkgKi8KYnV0dG9uLCAuYnV0dG9uLCBhLmJ1dHRv
-biB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMiwgMTM4LCAyNTMsIDAuMTUpOwogIGJvcmRlcjog
-bm9uZTsKICBib3JkZXItcmFkaXVzOiAzcHg7CiAgcGFkZGluZzogM3B4IDEwcHg7CiAgZm9udC13ZWln
-aHQ6IDUwMDsKICBmb250LWZvbnQ6IFJvYm90bywgc2Fucy1zZXJpZjsKICBjb2xvcjogI2ZmZjsKfQoK
-YnV0dG9uOmhvdmVyLCAuYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDIyLCAx
-MzgsIDI1MywgMC4yOSk7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgpidXR0b25bZGlzYWJsZWRdIHsKICBi
-YWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwyNTUsMjU1LC4xMik7CiAgY29sb3I6IHJnYmEoMjU1LDI1
-NSwyNTUsLjM3KTsKICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9CgovKiBDaGFuZ2UgZWRpdCBwYW5lbCBi
-dXR0b24gY29sb3JzICovCi5lZGl0LXBhbmVsIC5idXR0b24sIC5lZGl0LXBhbmVsIGJ1dHRvbiB7CiAg
-YmFja2dyb3VuZC1jb2xvcjogcmdiYSg2MywgMTA0LCAxNDgsIDAuNik7CiAgY29sb3I6IHdoaXRlOwp9
-Ci5lZGl0LXBhbmVsIC5idXR0b246aG92ZXIsIC5lZGl0LXBhbmVsIGJ1dHRvbjpob3ZlciB7CiAgYmFj
-a2dyb3VuZC1jb2xvcjogcmdiYSgxMDEsIDE1MywgMjA4LCAwLjYpOwogIGNvbG9yOiB3aGl0ZTsKfQoK
-LyoKICogQWRqdXN0bWVudHMgdG8gYWxpZ24gbWF0ZXJpYWwgaWNvbnMgaW4gdGhlIHRvb2xiYXIgYnV0
-dG9ucy4KKi8KLmFjdGlvbi1idXR0b24gPiBzcGFuIHsKICBwb3NpdGlvbjpyZWxhdGl2ZTsKICB0b3A6
-IC0zcHg7Cn0KCi5hY3Rpb24tYnV0dG9uIC5tYXRlcmlhbC1pY29ucyB7CiAgdG9wOiA0cHg7Cn0KCi8q
-IERvbid0IHNoaWZ0IHRoZSBpY29uIHdoZW4gaXQncyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgYnV0dG9u
-ICovCi5hY3Rpb24tYnV0dG9uID4gLm1hdGVyaWFsLWljb25zIHsKICB0b3A6IDFweDsKfQoKLyogU2hp
-ZnQgdGhlIHRleHQgdG8gY2VudGVyIHdpdGggdGhlIGljb24uICovCi5hY3Rpb24tYnV0dG9uID4gc3Bh
-bi5sYWJlbCB7CiAgcG9zaXRpb246cmVsYXRpdmU7CiAgdG9wOiAtNHB4Owp9CgouYWN0aW9uLWJ1dHRv
-biAubWF0ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7
-Cn0KCi5wbGFjZWhvbGRlciB7CiAgY29sb3I6ICM3Nzc7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1h
-cmdpbi10b3A6IDNlbSAhaW1wb3J0YW50Owp9CgovKioKICogSExKUyBPdmVycmlkZXMKICovCi5obGpz
-IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIyMDJmOyAvKiAkZGFyay1jb2RlLWJhY2tncm91bmQtY29s
-b3IgKi8KICBjb2xvcjogI2MwYzJjNTsgLyogJGRhcmstZWRpdG9yLXRleHQgKi8KICBkaXNwbGF5OiBi
-bG9jazsKICBvdmVyZmxvdy14OiBhdXRvOwogIHBhZGRpbmc6IDAuNWVtOwogIC8qKgogICAqIFRoaXMg
-YWxsb3dzIHRoZSBwZXItbGluZSBoaWdobGlnaHRzIHRvIHNob3cuCiAgICovCiAgYmFja2dyb3VuZDog
-bm9uZTsKfQoKLmhsanMta2V5d29yZCwKLmhsanMtc2VsZWN0b3ItdGFnLAouaGxqcy1kZWxldGlvbiB7
-CiAgY29sb3I6ICM1MWM2ODY7IC8qIGNtLWtleXdvcmQgKi8KfQoKLmhsanMtbnVtYmVyIHsKICBjb2xv
-cjogIzYyNzk3ODsgLyogY20tbnVtYmVyICovCn0KCi5obGpzLWNvbW1lbnQgewogIGNvbG9yOiAjOTE5
-OGI0OyAvKiBjbS1jb21tZW50ICovCn0KCi5obGpzLWxpdGVyYWwgewogIGNvbG9yOiAjZWU4NjY2OyAv
-KiBjbS1hdG9tICovCn0KCi5obGpzLXN0cmluZyB7CiAgY29sb3I6ICNlNTUwNzQ7IC8qIGNtLXN0cmlu
-ZyAqLwp9CgouaGxqcy12YXJpYWJsZSB7CiAgY29sb3I6ICMxNmFkY2E7IC8qIGNtLXZhcmlhYmxlICov
-Cn0KCi5obGpzLWxpbmsgewogIGNvbG9yOiAjZTU1MDc0OyAvKiBjbS1zdHJpbmcgKi8KfQouaGxqcy1z
-ZWN0aW9uLAouaGxqcy10eXBlLAouaGxqcy1idWlsdF9pbiwKLmhsanMtdGl0bGUgewogIGNvbG9yOiAj
-ZWU4NjY2OyAvKiBjbS12YXJpYWJsZS0yICovCn0KCi5obGpzLWFkZGl0aW9uIHsKICBjb2xvcjogIzI2
-Mzk1MjsgLyogJGRhcmstc2VsZWN0aW9uLWNvbG9yICovCn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAj
-NjI3OTc4Owp9Cg==
+b2xvciAqLwp9CgovKiBNYXRlcmlhbCBpY29ucyBjb25maWd1cmF0aW9uICovCkBmb250LWZhY2Ugewog
+IGZvbnQtZmFtaWx5OiAnTWF0ZXJpYWwgSWNvbnMnOwogIGZvbnQtc3R5bGU6IG5vcm1hbDsKICBmb250
+LXdlaWdodDogNDAwOwogIHNyYzogbG9jYWwoJ01hdGVyaWFsIEljb25zJyksCiAgbG9jYWwoJ01hdGVy
+aWFsSWNvbnMtUmVndWxhcicpLAogIHVybCgvTWF0ZXJpYWxJY29uc1JlZ3VsYXIudHRmKSBmb3JtYXQo
+J3RydWV0eXBlJyk7Cn0KCi8qCiAqIFJlcXVpcmVkIGZvciBNYXRlcmlhbCBJY29uczoKICogaHR0cHM6
+Ly9nb29nbGUuZ2l0aHViLmlvL21hdGVyaWFsLWRlc2lnbi1pY29ucy8KICovCi5tYXRlcmlhbC1pY29u
+cyB7CiAgZm9udC1mYW1pbHk6ICdNYXRlcmlhbCBJY29ucyc7CiAgZm9udC13ZWlnaHQ6IG5vcm1hbDsK
+ICBmb250LXN0eWxlOiBub3JtYWw7CiAgZm9udC1zaXplOiAyNHB4OyAgLyogUHJlZmVycmVkIGljb24g
+c2l6ZSAqLwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBsaW5lLWhlaWdodDogMTsKICB0ZXh0LXRy
+YW5zZm9ybTogbm9uZTsKICBsZXR0ZXItc3BhY2luZzogbm9ybWFsOwogIHdvcmQtd3JhcDogbm9ybWFs
+OwogIHdoaXRlLXNwYWNlOiBub3dyYXA7CiAgZGlyZWN0aW9uOiBsdHI7CgogIC8qIFN1cHBvcnQgZm9y
+IGFsbCBXZWJLaXQgYnJvd3NlcnMuICovCiAgLXdlYmtpdC1mb250LXNtb290aGluZzogYW50aWFsaWFz
+ZWQ7CiAgLyogU3VwcG9ydCBmb3IgU2FmYXJpIGFuZCBDaHJvbWUuICovCiAgdGV4dC1yZW5kZXJpbmc6
+IG9wdGltaXplTGVnaWJpbGl0eTsKCiAgLyogU3VwcG9ydCBmb3IgRmlyZWZveC4gKi8KICAtbW96LW9z
+eC1mb250LXNtb290aGluZzogZ3JheXNjYWxlOwoKICAvKiBTdXBwb3J0IGZvciBJRS4gKi8KICBmb250
+LWZlYXR1cmUtc2V0dGluZ3M6ICdsaWdhJzsKfQoKYm9keSB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEy
+MjAyZjsKICBjb2xvcjogI2NjYzsKICBmb250LWZhbWlseTogIlJvYm90byIsIHNhbnMtc2VyaWY7CiAg
+Zm9udC1zaXplOiAxNHB4OwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsK
+ICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9wOiAwOwogIHJpZ2h0OiAwOwogIGJvdHRvbTogMDsKICBs
+ZWZ0OiAwOwogIG1hcmdpbjogMDsKICBwYWRkaW5nOiAwOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5w
+cm9wb3NlZCAuYWZ0ZXItYXBwbHkgewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5hcHBsaWVkIC5iZWZvcmUt
+YXBwbHkgewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5hcHBsaWVkIC5hcHBseS1taWdyYXRpb246bm90KFtk
+aXNhYmxlZF0pLCAubmVlZHMtcmVydW4gLmFwcGx5LW1pZ3JhdGlvbjpub3QoW2Rpc2FibGVkXSkgewog
+IGRpc3BsYXk6IG5vbmU7Cn0KCi5wcm9wb3NlZDpub3QoLm5lZWRzLXJlcnVuKSAuYXBwbHktbWlncmF0
+aW9uW2Rpc2FibGVkXSB7CiAgZGlzcGxheTogbm9uZTsKfQoKaGVhZGVyIHsKICBiYWNrZ3JvdW5kLWNv
+bG9yOiAjMWMyODM0OwogIGhlaWdodDogNDhweDsKICBwYWRkaW5nLWxlZnQ6IDI0cHg7CiAgYWxpZ24t
+aXRlbXM6IGNlbnRlcjsKICB6LWluZGV4OiA0Owp9CgpoZWFkZXIgaDEsCmhlYWRlciBoMiB7CiAgZGlz
+cGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNh
+bnMtc2VyaWY7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICBtYXJnaW4tcmlnaHQ6IDI0cHg7Cn0KCmgxIHsK
+ICBmb250LXNpemU6IDEuNWVtOwp9CgpoZWFkZXIgaDIgewogIGZvbnQtc2l6ZTogMS4yZW07CgogIC8q
+IFNoaWZ0IHRleHQgdXAgKi8KICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9wOiAtMnB4Owp9CgpoZWFk
+ZXIgLmFjdGlvbi1idXR0b24sIGhlYWRlciBhIHsKICByaWdodDogMHB4OwogIGZsb2F0OiByaWdodDsK
+ICBtYXJnaW46IDEwcHg7Cn0KCmhlYWRlciBpbWcubG9nbyB7CiAgaGVpZ2h0OiAyNHB4OwogIHdpZHRo
+OiAyNHB4OwogIG1hcmdpbi1yaWdodDogOHB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IDRw
+eDsKfQoKZm9vdGVyIC5yZXBvcnQtcHJvYmxlbSB7CiAgcmlnaHQ6IDBweDsKICBtYXJnaW46IDRweCA4
+cHg7Cn0KCi5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIHsKICBkaXNwbGF5OiBub25lOwp9CgoubmVl
+ZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgewogIGRpc3BsYXk6IGluaXRpYWw7Cn0K
+Ci5uZWVkcy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5vcHRpb25hbCB7CiAgZGlzcGxheTpub25lOwp9
+Cgpmb290ZXIgewogIGNvbG9yOiAjY2NjOwogIGJhY2tncm91bmQtY29sb3I6ICMyNzMyM2E7CiAgZGlz
+cGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogcm93OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAg
+cGFkZGluZzogOHB4IDAgOHB4IDI0cHg7Cn0KCmZvb3RlciAud2lkZSB7CiAgZmxleDogMTsKfQoKZm9v
+dGVyIC5zZGstdmVyc2lvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzMnB4Owp9CgouaG9yaXpvbnRhbCB7CiAg
+ZGlzcGxheTogZmxleDsKfQoKLnBhbmVscyB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMWEyNTsKICBm
+bGV4OiAxOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5wYW5lbC1oZWFkaW5nIHsKICBjb2xvcjogIzY3
+Njc2NzsKICBtYXJnaW46IDhweDsKfQoKLm5hdi1saW5rLAoucmVnaW9uIHsKICBjdXJzb3I6IHBvaW50
+ZXI7Cn0KCi5uYXYtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgZmxleDogMSAy
+MDBweDsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKICB1c2VyLXNlbGVjdDogbm9uZTsK
+fQoKLm5hdi1pbm5lciB7CiAgcGFkZGluZzogMCAwIDdweCA3cHg7Cn0KCi5maXhlZCB7CiAgcG9zaXRp
+b246IGZpeGVkOwogIHRvcDogMDsKfQoKLnJvb3QgewogIG1hcmdpbjogMDsKICBkaXNwbGF5OiBub25l
+Owp9CgoubmF2LXRyZWUgPiB1bCB7CiAgcGFkZGluZy1sZWZ0OiA2cHg7Cn0KCi5uYXYtdHJlZSAubWF0
+ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9w
+OiA1cHg7CiAgbWFyZ2luLXJpZ2h0OiA4cHg7CiAgY29sb3I6ICM2NzY3Njc7IC8qICRzZWNvbmRhcnkt
+Y29sb3IgKi8KfQoKLnN0YXR1cy1pY29uLmFscmVhZHktbWlncmF0ZWQgewogIGNvbG9yOiAjMDA3YTI3
+OyAvKiAkbGlnaHQtZ3JlZW4gKi8KfQoKLnN0YXR1cy1pY29uLm9wdGVkLW91dCB7CiAgY29sb3I6ICM2
+NzY3Njc7IC8qICRzZWNvbmRhcnktY29sb3IgKi8KfQoKLnN0YXR1cy1pY29uLm9wdGVkLW91dDpob3Zl
+ciB7CiAgY29sb3I6ICNmZmZmZmY7Cn0KCi5zdGF0dXMtaWNvbi5taWdyYXRpbmcgewogIGNvbG9yOiAj
+NTFjNjg2OyAvKiAkZGFyay1ncmVlbiAqLwp9Cgouc3RhdHVzLWljb24ubWlncmF0aW5nOmhvdmVyIHsK
+ICBjb2xvcjogI2ZmZmZmZjsKfQoKLm5hdi1pbm5lciB1bCB7CiAgcGFkZGluZy1sZWZ0OiAxMnB4Owog
+IG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwogIHdo
+aXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5uYXYtaW5uZXIgbGk6bm90KC5kaXIpIHsKICBtYXJnaW4tbGVm
+dDogMjBweDsKICBtYXJnaW4tYm90dG9tOiAzcHg7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdyB7
+CiAgY3Vyc29yOiBwb2ludGVyOwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250LXNpemU6IDEw
+cHg7CiAgbWFyZ2luLXJpZ2h0OiA0cHg7CiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNXMgZWFzZS1v
+dXQ7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdy5jb2xsYXBzZWQgewogIHRyYW5zZm9ybTogcm90
+YXRlKC05MGRlZyk7Cn0KCi5uYXYtaW5uZXIgdWwgewogIC8qIGEgbWF4LWhlaWdodCBpcyBhZGRlZCB0
+byBlYWNoIGVsZW1lbnQgYXQgcnVudGltZS4gKi8KICB0cmFuc2l0aW9uOiBtYXgtaGVpZ2h0IDAuNXMg
+ZWFzZS1vdXQ7Cn0KCi5uYXYtaW5uZXIgdWwuY29sbGFwc2VkIHsKICBtYXgtaGVpZ2h0OiAwICFpbXBv
+cnRhbnQ7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLm5hdi1pbm5lciAuc2VsZWN0ZWQtZmlsZSB7CiAg
+Y29sb3I6IHdoaXRlOwogIGN1cnNvcjogaW5oZXJpdDsKICBmb250LXdlaWdodDogNjAwOwogIHRleHQt
+ZGVjb3JhdGlvbjogbm9uZTsKfQoKLmVkaXQtY291bnQgewogIGJhY2tncm91bmQtY29sb3I6ICM2NzY3
+Njc7CiAgYm9yZGVyLXJhZGl1czogMTBweDsKICBjb2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUt
+YmxvY2s7CiAgZm9udC1zaXplOiAxMXB4OwogIGZvbnQtd2VpZ2h0OiA2MDA7CiAgbWFyZ2luLWxlZnQ6
+IDVweDsKICBtaW4td2lkdGg6IDI1cHg7CiAgcGFkZGluZzogNHB4IDAgMnB4IDA7CiAgdGV4dC1hbGln
+bjogY2VudGVyOwogIGxpbmUtaGVpZ2h0OiAxZW07Cn0KCi5maWxlIHsKICBmbGV4OiA0IDMwMHB4Owog
+IGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNhbnMtc2VyaWY7CiAgYmFja2dyb3Vu
+ZDogIzEyMjAyZjsKICBtYXJnaW46IDZweDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgoudGl0bGUtYmFy
+IGgzIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICAvKiBUaGlz
+IGFsaWducyB0aGUgdGl0bGUgdGV4dCB3aXRoIHRoZSBjb250ZW50IHRleHQsIGFjY291bnRpbmcgZm9y
+IHRoZSB3aWR0aAogICAqIG9mIHRoZSBsaW5lIG51bWJlcnMuCiAgICovCiAgbWFyZ2luOiAwLjVlbSAy
+NHB4IDAuNWVtIDYzcHg7Cn0KCi50aXRsZS1iYXIgI21pZ3JhdGUtdW5pdC1zdGF0dXMtaWNvbi1sYWJl
+bCB7CiAgZGlzcGxheTogbm9uZTsKICB1c2VyLXNlbGVjdDogbm9uZTsKfQoKLnRpdGxlLWJhciAjbWln
+cmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsLnZpc2libGUgewogIC8qIENoYW5nZSB0byAnaW5saW5l
+JyB0byBlbmFibGUgdGhlIGluY3JlbWVudGFsIG1pZ3JhdGlvbiBmZWF0dXJlLiAqLwogIGRpc3BsYXk6
+IG5vbmU7Cn0KCi50aXRsZS1iYXIgI21pZ3JhdGUtdW5pdC1zdGF0dXMtaWNvbiB7CiAgdmVydGljYWwt
+YWxpZ246IHRleHQtYm90dG9tOwp9CgouY29udGVudCB7CiAgZm9udC1mYW1pbHk6ICJSb2JvdG8gTW9u
+byIsbW9ub3NwYWNlOwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB3aGl0ZS1zcGFjZTogcHJlOwp9Cgou
+Y29kZSB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAg
+dG9wOiAwOwogIG1hcmdpbi1sZWZ0OiA1NnB4Owp9CgouY29kZSAud2VsY29tZSB7CiAgZm9udC1mYW1p
+bHk6ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDE4cHg7CiAg
+bWFyZ2luLXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29kZSAubmF2LWxpbmsgewogIGNv
+bG9yOiAjMTZhZGNhOwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAubmF2LWxp
+bms6dmlzaXRlZCB7CiAgY29sb3I6ICMxMzliYjU7IC8qICMxNmFkY2EgZGFya2VuZWQgMTAlICovCiAg
+dGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5jb2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4
+dC1kZWNvcmF0aW9uLWxpbmU6IHVuZGVybGluZTsKICBmb250LXdlaWdodDogNjAwOwp9CgoucmVnaW9u
+cyB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9w
+OiAwOwp9CgoucmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVyLXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBp
+bmhlcml0Owp9CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVyOiBub25lOwogIC8qIFRoZSBjb250ZW50IG9m
+IHRoZSByZWdpb25zIGlzIG5vdCB2aXNpYmxlOyB0aGUgdXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQog
+ICAqIGhpZ2hsaWdodGVkIGNvcHkgb2YgdGhlIGNvbnRlbnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAy
+NTUsIDI1NSwgMCk7CiAgcGFkZGluZzogMDsKICB3aGl0ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0
+ZDplbXB0eTphZnRlciB7CiAgY29udGVudDogIlwwMGEwIjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0
+IHRkOmxhc3QtY2hpbGQgewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRl
+Owp9CgoucmVnaW9ucyB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICMxMjIwMmYgMnB4
+OwogIGNvbG9yOiAjOTk5OTk5OwogIHBhZGRpbmctcmlnaHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdo
+dDsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHdpZHRoOiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1i
+bG9jazsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkLmxpbmUtbm8gewogIGJvcmRlci1yaWdodDog
+c29saWQgI2NjYyAycHg7Cn0KCi5yZWdpb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwb3Np
+dGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5y
+ZWdpb24uYWRkZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTc4YWZkOwogIGNvbG9yOiAj
+ZmZmOwp9CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjRkE1NTdk
+OyAvKiAkZGFyay1waW5rICovCiAgY29sb3I6ICNmZmY7Cn0KCi5yZWdpb24uaW5mb3JtYXRpdmUtcmVn
+aW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjYzOTUyOwogIGNvbG9yOiAjZmZmOwogIGRpc3BsYXk6
+IGlubGluZS1ibG9jazsKICBoZWlnaHQ6IDE1cHg7CiAgcG9zaXRpb246IHJlbGF0aXZlOwp9CgoudGFy
+Z2V0IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB2aXNp
+YmlsaXR5OiB2aXNpYmxlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCi5pbmZvLXBhbmVsIHsKICBmbGV4
+OiAxIDIwMHB4OwogIG1hcmdpbjogMDsKICBoZWlnaHQ6IDEwMCU7CiAgZGlzcGxheTogZmxleDsKICBm
+bGV4LWRpcmVjdGlvbjogY29sdW1uOwp9CgouaW5mby1wYW5lbCAuZWRpdC1wYW5lbCB7CiAgYmFja2dy
+b3VuZC1jb2xvcjogIzEyMjAyZjsKICBvdmVyZmxvdzogYXV0bzsKfQoKLmluZm8tcGFuZWwgLnBhbmVs
+LWNvbnRlbnQgewogIHBhZGRpbmc6IDdweDsKfQoKLmluZm8tcGFuZWwgLnBhbmVsLWNvbnRlbnQ+IDpm
+aXJzdC1jaGlsZCB7CiAgbWFyZ2luLXRvcDogMDsKfQoKLmluZm8tcGFuZWwgLm5vd3JhcCB7CiAgd2hp
+dGUtc3BhY2U6IG5vd3JhcDsKfQoKLmluZm8tcGFuZWwgdWwsCi5pbmZvLXBhbmVsIG9sIHsKICBwYWRk
+aW5nLWxlZnQ6IDIwcHg7Cn0KCi5pbmZvLXBhbmVsIGxpIHsKICBtYXJnaW46IDAgMCA1cHggMDsKfQoK
+LmluZm8tcGFuZWwgYSB7CiAgY29sb3I6ICMxMzliYjU7Cn0KCi5pbmZvLXBhbmVsIGE6aG92ZXIgewog
+IGNvbG9yOiAjMWVjN2U3OyAvKiAjMTM5YmI1IGxpZ2h0ZW5lZCAyMCUgKi8KfQoKLmluZm8tcGFuZWwg
+LmVkaXQtbGlzdCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMjAyZjsKICBvdmVyZmxvdzogYXV0bzsK
+fQoKLmVkaXQtcGFuZWwgewogIG1hcmdpbi10b3A6IDZweDsKICBmbGV4OiAxIDEwMHB4Owp9CgouZWRp
+dC1saXN0IHsKICBmbGV4OiAyIDEwMHB4Owp9CgouZWRpdC1saXN0IC5lZGl0IHsKICBtYXJnaW46IDNw
+eCAwOwp9CgouZWRpdC1saXN0IC5lZGl0LWxpbmsgewogIGN1cnNvcjogcG9pbnRlcjsKfQoKLnBvcHVw
+LXBhbmUgewogIGRpc3BsYXk6IG5vbmU7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMTUwcHg7CiAg
+bGVmdDogMTUwcHg7CiAgcmlnaHQ6IDE1MHB4OwogIGJvdHRvbTogMTUwcHg7CiAgYm9yZGVyOiAxcHgg
+c29saWQgYmxhY2s7CiAgYm9yZGVyLXRvcDogMnB4IHNvbGlkIGJsYWNrOwogIGJvcmRlci1yYWRpdXM6
+IDdweDsKICBib3gtc2hhZG93OiAwcHggMHB4IDIwcHggMnB4ICNiNGJmY2IyMjsKICB6LWluZGV4OiA0
+MDA7CiAgYmFja2dyb3VuZDogIzJiMzAzNjsKICBwYWRkaW5nOiAyMHB4Owp9CgoucG9wdXAtcGFuZSAu
+Y2xvc2UgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICByaWdodDogMTBweDsKICB0b3A6IDEwcHg7CiAg
+Y3Vyc29yOiBwb2ludGVyOwogIHRleHQtc2hhZG93OiAxcHggMXB4IDJweCAjODg4OwogIGJveC1zaGFk
+b3c6IDFweCAxcHggMnB4ICMxMTE7Cn0KCi5wb3B1cC1wYW5lIGgyIHsKICBwYWRkaW5nOiAyMXB4Owog
+IGhlaWdodDogMTAlOwogIG1hcmdpbjogMHB4OwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5w
+b3B1cC1wYW5lIHAgewogIGhlaWdodDogMTAlOwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgcGFk
+ZGluZzogMHB4IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIHByZSB7CiAgYmFja2dyb3VuZDogIzEyMjAyZjsK
+ICBwYWRkaW5nOiAyMHB4OwogIGJvdHRvbTogMHB4OwogIG92ZXJmbG93OiBhdXRvIHNjcm9sbDsKICBo
+ZWlnaHQ6IDY1JTsKICBtYXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9w
+dXAtcGFuZSAuYnV0dG9uLmJvdHRvbSB7CiAgbWFyZ2luOiAyMHB4IDBweDsKICBkaXNwbGF5OiBibG9j
+azsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCi5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9u
+ZTsKfQoKYm9keS5yZXJ1bm5pbmcgLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBw
+b3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJp
+Z2h0OiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFj
+ayAqLwogIHotaW5kZXg6IDQwMDsKfQoKLnJlcnVubmluZy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJz
+b2x1dGU7CiAgdG9wOiA1MCU7CiAgbGVmdDogNTAlOwogIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUs
+IC01MCUpOwp9CgouZWRpdC1wYW5lbCAudHlwZS1kZXNjcmlwdGlvbiB7CiAgLyogRnJvbSBEYXJ0UGFk
+ICRkYXJrLW9yYW5nZSAqLwogIGNvbG9yOiAjZmY5MTZlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7
+Cn0KCnVsLnRyYWNlIHsKICBmb250LXNpemU6IDEzcHg7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwog
+IHBhZGRpbmctbGVmdDogMHB4Owp9Cgp1bC50cmFjZSBsaSB7CiAgY29sb3I6IHdoaXRlOwp9Cgp1bC50
+cmFjZSBsaSAuZnVuY3Rpb24gewogIC8qIGZyb20gLmhsanMtdmFyaWFibGUgKi8KICBjb2xvcjogIzE2
+YWRjYTsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCnVsLnRy
+YWNlIGxpIHAuZHJhd2VyIHsKICBtYXJnaW46IDNweCAwcHg7CiAgcGFkZGluZzogMHB4IDBweCAwcHgg
+MTRweDsKfQoKdWwudHJhY2UgbGkgcC5kcmF3ZXIgYnV0dG9uIHsKICBtYXJnaW4tcmlnaHQ6IDNweDsK
+fQoKLmVsZXZhdGlvbi16NCB7CiAgYm94LXNoYWRvdzogMHB4IDJweCA0cHggLTFweCByZ2JhKDAsIDAs
+IDAsIDAuMiksCiAgICAgIDBweCA0cHggNXB4IDBweCByZ2JhKDAsIDAsIDAsIDAuMTQpLAogICAgICAw
+cHggMXB4IDEwcHggMHB4IHJnYmEoMCwgMCwgMCwgLjEyKTsKfQoKYSB7CiAgY29sb3I6ICNjY2M7CiAg
+ZmlsbDogI2NjYzsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCmE6aG92ZXIgewogIGNvbG9yOiAj
+ZGJkYmRiOyAvKiAjY2NjIGxpZ2h0ZW50ZWQgMzAlKi8KICBmaWxsOiAjZmZmOwp9CgouYWRkLWhpbnQt
+bGluayB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIG1hcmdpbjogM3B4Owp9CgouYWRkLWhpbnQt
+bGluazpob3ZlciB7CiAgY29sb3I6ICNmZmY7Cn0KCmhlYWRlciBidXR0b24gewogIHRleHQtdHJhbnNm
+b3JtOiB1cHBlcmNhc2U7Cn0KCmhlYWRlciBhIHsKICBtYXJnaW46IDA7Cn0KCi8qIENhcmVmdWwgaGVy
+ZS4gYGEuYnV0dG9uYCBpcyByZXBldGl0aXZlIGJ1dCByZXF1aXJlZCB0byBnZXQgY29ycmVjdAogKiBz
+cGVjaWZpY2l0eSAqLwpidXR0b24sIC5idXR0b24sIGEuYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiByZ2JhKDIyLCAxMzgsIDI1MywgMC4xNSk7CiAgYm9yZGVyOiBub25lOwogIGJvcmRlci1yYWRpdXM6
+IDNweDsKICBwYWRkaW5nOiAzcHggMTBweDsKICBmb250LXdlaWdodDogNTAwOwogIGZvbnQtZm9udDog
+Um9ib3RvLCBzYW5zLXNlcmlmOwogIGNvbG9yOiAjZmZmOwp9CgpidXR0b246aG92ZXIsIC5idXR0b246
+aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjIsIDEzOCwgMjUzLCAwLjI5KTsKICBjdXJz
+b3I6IHBvaW50ZXI7Cn0KCmJ1dHRvbltkaXNhYmxlZF0gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEo
+MjU1LDI1NSwyNTUsLjEyKTsKICBjb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwuMzcpOwogIGN1cnNvcjog
+bm90LWFsbG93ZWQ7Cn0KCi8qIENoYW5nZSBlZGl0IHBhbmVsIGJ1dHRvbiBjb2xvcnMgKi8KLmVkaXQt
+cGFuZWwgLmJ1dHRvbiwgLmVkaXQtcGFuZWwgYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2Jh
+KDYzLCAxMDQsIDE0OCwgMC42KTsKICBjb2xvcjogd2hpdGU7Cn0KLmVkaXQtcGFuZWwgLmJ1dHRvbjpo
+b3ZlciwgLmVkaXQtcGFuZWwgYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDEw
+MSwgMTUzLCAyMDgsIDAuNik7CiAgY29sb3I6IHdoaXRlOwp9CgovKgogKiBBZGp1c3RtZW50cyB0byBh
+bGlnbiBtYXRlcmlhbCBpY29ucyBpbiB0aGUgdG9vbGJhciBidXR0b25zLgoqLwouYWN0aW9uLWJ1dHRv
+biA+IHNwYW4gewogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IC0zcHg7Cn0KCi5hY3Rpb24tYnV0
+dG9uIC5tYXRlcmlhbC1pY29ucyB7CiAgdG9wOiA0cHg7Cn0KCi8qIERvbid0IHNoaWZ0IHRoZSBpY29u
+IHdoZW4gaXQncyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgYnV0dG9uICovCi5hY3Rpb24tYnV0dG9uID4g
+Lm1hdGVyaWFsLWljb25zIHsKICB0b3A6IDFweDsKfQoKLyogU2hpZnQgdGhlIHRleHQgdG8gY2VudGVy
+IHdpdGggdGhlIGljb24uICovCi5hY3Rpb24tYnV0dG9uID4gc3Bhbi5sYWJlbCB7CiAgcG9zaXRpb246
+cmVsYXRpdmU7CiAgdG9wOiAtNHB4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewog
+IGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7Cn0KCi5wbGFjZWhvbGRlciB7CiAg
+Y29sb3I6ICM3Nzc7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0
+YW50Owp9CgovKioKICogSExKUyBPdmVycmlkZXMKICovCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiAjMTIyMDJmOyAvKiAkZGFyay1jb2RlLWJhY2tncm91bmQtY29sb3IgKi8KICBjb2xvcjogI2MwYzJj
+NTsgLyogJGRhcmstZWRpdG9yLXRleHQgKi8KICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBh
+dXRvOwogIHBhZGRpbmc6IDAuNWVtOwogIC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBo
+aWdobGlnaHRzIHRvIHNob3cuCiAgICovCiAgYmFja2dyb3VuZDogbm9uZTsKfQoKLmhsanMta2V5d29y
+ZCwKLmhsanMtc2VsZWN0b3ItdGFnLAouaGxqcy1kZWxldGlvbiB7CiAgY29sb3I6ICM1MWM2ODY7IC8q
+IGNtLWtleXdvcmQgKi8KfQoKLmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzYyNzk3ODsgLyogY20tbnVt
+YmVyICovCn0KCi5obGpzLWNvbW1lbnQgewogIGNvbG9yOiAjOTE5OGI0OyAvKiBjbS1jb21tZW50ICov
+Cn0KCi5obGpzLWxpdGVyYWwgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS1hdG9tICovCn0KCi5obGpz
+LXN0cmluZyB7CiAgY29sb3I6ICNlNTUwNzQ7IC8qIGNtLXN0cmluZyAqLwp9CgouaGxqcy12YXJpYWJs
+ZSB7CiAgY29sb3I6ICMxNmFkY2E7IC8qIGNtLXZhcmlhYmxlICovCn0KCi5obGpzLWxpbmsgewogIGNv
+bG9yOiAjZTU1MDc0OyAvKiBjbS1zdHJpbmcgKi8KfQouaGxqcy1zZWN0aW9uLAouaGxqcy10eXBlLAou
+aGxqcy1idWlsdF9pbiwKLmhsanMtdGl0bGUgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS12YXJpYWJs
+ZS0yICovCn0KCi5obGpzLWFkZGl0aW9uIHsKICBjb2xvcjogIzI2Mzk1MjsgLyogJGRhcmstc2VsZWN0
+aW9uLWNvbG9yICovCn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjNjI3OTc4Owp9Cg==
 ''';
 
 String _migration_js;
-// migration_dart md5 is '4e8037b6c5e790a11515f71f5c8a76c2'
+// migration_dart md5 is 'fd54888536280a9cc3c222ccaf1597fa'
 String _migration_js_base64 = '''
 KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgcz1P
 YmplY3Qua2V5cyhhKQpmb3IodmFyIHI9MDtyPHMubGVuZ3RoO3IrKyl7dmFyIHE9c1tyXQpiW3FdPWFb
@@ -7770,254 +7789,257 @@
 KWNvbnRpbnVlCmlmKHdbc11bYV0pcmV0dXJuIHdbc11bYV19fXZhciBDPXt9LEg9e0ZLOmZ1bmN0aW9u
 IEZLKCl7fSwKR0o6ZnVuY3Rpb24oYSxiLGMpe2lmKGIuQygiYlE8MD4iKS5iKGEpKXJldHVybiBuZXcg
 SC5vbChhLGIuQygiQDwwPiIpLktxKGMpLkMoIm9sPDEsMj4iKSkKcmV0dXJuIG5ldyBILlp5KGEsYi5D
-KCJAPDA+IikuS3EoYykuQygiWnk8MSwyPiIpKX0sCmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILm4o
-YSl9LApCaTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgucjMoYSl9LApvbzpmdW5jdGlvbihhKXt2YXIg
-cyxyPWFeNDgKaWYocjw9OSlyZXR1cm4gcgpzPWF8MzIKaWYoOTc8PXMmJnM8PTEwMilyZXR1cm4gcy04
-NwpyZXR1cm4tMX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3RhcnQiKQppZihjIT1udWxs
-KXtQLmsxKGMsImVuZCIpCmlmKGI+YylILnYoUC5URShiLDAsYywic3RhcnQiLG51bGwpKX1yZXR1cm4g
-bmV3IEgubkgoYSxiLGMsZC5DKCJuSDwwPiIpKX0sCksxOmZ1bmN0aW9uKGEsYixjLGQpe2lmKHQuYi5i
-KGEpKXJldHVybiBuZXcgSC54eShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygieHk8MSwyPiIpKQpyZXR1
-cm4gbmV3IEguaTEoYSxiLGMuQygiQDwwPiIpLktxKGQpLkMoImkxPDEsMj4iKSl9LApiSzpmdW5jdGlv
-bihhLGIsYyl7dmFyIHM9ImNvdW50IgppZih0LmIuYihhKSl7UC5VSShiLHMsdC5TKQpQLmsxKGIscykK
-cmV0dXJuIG5ldyBILmQ1KGEsYixjLkMoImQ1PDA+IikpfVAuVUkoYixzLHQuUykKUC5rMShiLHMpCnJl
-dHVybiBuZXcgSC5BTShhLGIsYy5DKCJBTTwwPiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQ
-LmxqKCJObyBlbGVtZW50Iil9LApBbTpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigiVG9vIG1hbnkg
-ZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJUb28gZmV3IGVsZW1lbnRz
-Iil9LApCUjpmdW5jdGlvbiBCUigpe30sCkU3OmZ1bmN0aW9uIEU3KGEsYil7dGhpcy5hPWEKdGhpcy4k
-dGk9Yn0sClp5OmZ1bmN0aW9uIFp5KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCm9sOmZ1bmN0aW9u
-IG9sKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sClVxOmZ1bmN0aW9uIFVxKCl7fSwKalY6ZnVuY3Rp
-b24galYoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKbjpmdW5jdGlvbiBuKGEpe3RoaXMuYT1hfSwK
-cjM6ZnVuY3Rpb24gcjMoYSl7dGhpcy5hPWF9LApxajpmdW5jdGlvbiBxaihhKXt0aGlzLmE9YX0sCmJR
-OmZ1bmN0aW9uIGJRKCl7fSwKYUw6ZnVuY3Rpb24gYUwoKXt9LApuSDpmdW5jdGlvbiBuSChhLGIsYyxk
-KXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAphNzpmdW5jdGlvbiBhNyhhLGIs
-Yyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKaTE6ZnVuY3Rp
-b24gaTEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp4eTpmdW5jdGlvbiB4eShh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCk1IOmZ1bmN0aW9uIE1IKGEsYixjKXt2
-YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uJHRpPWN9LApsSjpmdW5jdGlvbiBsSihhLGIs
-Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClU1OmZ1bmN0aW9uIFU1KGEsYixjKXt0aGlz
-LmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKU086ZnVuY3Rpb24gU08oYSxiLGMpe3RoaXMuYT1hCnRo
-aXMuYj1iCnRoaXMuJHRpPWN9LApBTTpmdW5jdGlvbiBBTShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
-dGhpcy4kdGk9Y30sCmQ1OmZ1bmN0aW9uIGQ1KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0
-aT1jfSwKVTE6ZnVuY3Rpb24gVTEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApN
-QjpmdW5jdGlvbiBNQihhKXt0aGlzLiR0aT1hfSwKRnU6ZnVuY3Rpb24gRnUoYSl7dGhpcy4kdGk9YX0s
-CnU2OmZ1bmN0aW9uIHU2KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCkpCOmZ1bmN0aW9uIEpCKGEs
-Yil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sClNVOmZ1bmN0aW9uIFNVKCl7fSwKUmU6ZnVuY3Rpb24gUmUo
-KXt9LAp3MjpmdW5jdGlvbiB3Migpe30sCnd2OmZ1bmN0aW9uIHd2KGEpe3RoaXMuYT1hfSwKUUM6ZnVu
-Y3Rpb24gUUMoKXt9LApkYzpmdW5jdGlvbigpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IHVu
-bW9kaWZpYWJsZSBNYXAiKSl9LApOUTpmdW5jdGlvbihhKXt2YXIgcyxyPUguSmcoYSkKaWYociE9bnVs
-bClyZXR1cm4gcgpzPSJtaW5pZmllZDoiK2EKcmV0dXJuIHN9LAp3VjpmdW5jdGlvbihhLGIpe3ZhciBz
-CmlmKGIhPW51bGwpe3M9Yi54CmlmKHMhPW51bGwpcmV0dXJuIHN9cmV0dXJuIHQuYVUuYihhKX0sCkVq
-OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2Yg
-YT09Im51bWJlciIpe2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUi
-CmVsc2UgaWYoITE9PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgpz
-PUouaihhKQppZih0eXBlb2YgcyE9InN0cmluZyIpdGhyb3cgSC5iKEgudEwoYSkpCnJldHVybiBzfSwK
-ZVE6ZnVuY3Rpb24oYSl7dmFyIHM9YS4kaWRlbnRpdHlIYXNoCmlmKHM9PW51bGwpe3M9TWF0aC5yYW5k
-b20oKSoweDNmZmZmZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXN9cmV0dXJuIHN9LApIcDpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIscSxwLG8sbixtPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudihILnRMKGEp
-KQpzPS9eXHMqWystXT8oKDB4W2EtZjAtOV0rKXwoXGQrKXwoW2EtejAtOV0rKSlccyokL2kuZXhlYyhh
-KQppZihzPT1udWxsKXJldHVybiBtCmlmKDM+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsMykKcj1zWzNd
-CmlmKGI9PW51bGwpe2lmKHIhPW51bGwpcmV0dXJuIHBhcnNlSW50KGEsMTApCmlmKHNbMl0hPW51bGwp
-cmV0dXJuIHBhcnNlSW50KGEsMTYpCnJldHVybiBtfWlmKGI8Mnx8Yj4zNil0aHJvdyBILmIoUC5URShi
-LDIsMzYsInJhZGl4IixtKSkKaWYoYj09PTEwJiZyIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQpp
-ZihiPDEwfHxyPT1udWxsKXtxPWI8PTEwPzQ3K2I6ODYrYgpwPXNbMV0KZm9yKG89cC5sZW5ndGgsbj0w
-O248bzsrK24paWYoKEMueEIuVyhwLG4pfDMyKT5xKXJldHVybiBtfXJldHVybiBwYXJzZUludChhLGIp
-fSwKTTpmdW5jdGlvbihhKXtyZXR1cm4gSC5INShhKX0sCkg1OmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpp
-ZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gSC5kbShILnooYSksbnVsbCkKaWYoSi5pYShhKT09PUMu
-T2t8fHQuYkouYihhKSl7cz1DLk80KGEpCmlmKEguQmUocykpcmV0dXJuIHMKcj1hLmNvbnN0cnVjdG9y
-CmlmKHR5cGVvZiByPT0iZnVuY3Rpb24iKXtxPXIubmFtZQppZih0eXBlb2YgcT09InN0cmluZyImJkgu
-QmUocSkpcmV0dXJuIHF9fXJldHVybiBILmRtKEgueihhKSxudWxsKX0sCkJlOmZ1bmN0aW9uKGEpe3Zh
-ciBzPWEhPT0iT2JqZWN0IiYmYSE9PSIiCnJldHVybiBzfSwKTTA6ZnVuY3Rpb24oKXtpZighIXNlbGYu
-bG9jYXRpb24pcmV0dXJuIHNlbGYubG9jYXRpb24uaHJlZgpyZXR1cm4gbnVsbH0sClZLOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscSxwLG89YS5sZW5ndGgKaWYobzw9NTAwKXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
-b2RlLmFwcGx5KG51bGwsYSkKZm9yKHM9IiIscj0wO3I8bztyPXEpe3E9cis1MDAKcD1xPG8/cTpvCnMr
-PVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnNsaWNlKHIscCkpfXJldHVybiBzfSwKQ3E6
-ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9SC5WTShbXSx0LmEpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEu
-bGVuZ3RoO2EubGVuZ3RoPT09c3x8KDAsSC5saykoYSksKytyKXtxPWFbcl0KaWYoIUgub2socSkpdGhy
-b3cgSC5iKEgudEwocSkpCmlmKHE8PTY1NTM1KUMuTm0uaShwLHEpCmVsc2UgaWYocTw9MTExNDExMSl7
-Qy5ObS5pKHAsNTUyOTYrKEMuam4ud0cocS02NTUzNiwxMCkmMTAyMykpCkMuTm0uaShwLDU2MzIwKyhx
-JjEwMjMpKX1lbHNlIHRocm93IEguYihILnRMKHEpKX1yZXR1cm4gSC5WSyhwKX0sCmVUOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxzOysrcil7cT1hW3JdCmlmKCFILm9rKHEp
-KXRocm93IEguYihILnRMKHEpKQppZihxPDApdGhyb3cgSC5iKEgudEwocSkpCmlmKHE+NjU1MzUpcmV0
-dXJuIEguQ3EoYSl9cmV0dXJuIEguVksoYSl9LApmdzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAK
-aWYoYzw9NTAwJiZiPT09MCYmYz09PWEubGVuZ3RoKXJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFw
-cGx5KG51bGwsYSkKZm9yKHM9YixyPSIiO3M8YztzPXEpe3E9cys1MDAKcD1xPGM/cTpjCnIrPVN0cmlu
-Zy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KHMscCkpfXJldHVybiByfSwKTHc6ZnVu
-Y3Rpb24oYSl7dmFyIHMKaWYoMDw9YSl7aWYoYTw9NjU1MzUpcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNv
-ZGUoYSkKaWYoYTw9MTExNDExMSl7cz1hLTY1NTM2CnJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKChD
-LmpuLndHKHMsMTApfDU1Mjk2KT4+PjAscyYxMDIzfDU2MzIwKX19dGhyb3cgSC5iKFAuVEUoYSwwLDEx
-MTQxMTEsbnVsbCxudWxsKSl9LApvMjpmdW5jdGlvbihhKXtpZihhLmRhdGU9PT12b2lkIDApYS5kYXRl
-PW5ldyBEYXRlKGEuYSkKcmV0dXJuIGEuZGF0ZX0sCnRKOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSku
-Z2V0RnVsbFllYXIoKSswCnJldHVybiBzfSwKTlM6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRN
-b250aCgpKzEKcmV0dXJuIHN9LApqQTpmdW5jdGlvbihhKXt2YXIgcz1ILm8yKGEpLmdldERhdGUoKSsw
-CnJldHVybiBzfSwKSVg6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRIb3VycygpKzAKcmV0dXJu
-IHN9LApjaDpmdW5jdGlvbihhKXt2YXIgcz1ILm8yKGEpLmdldE1pbnV0ZXMoKSswCnJldHVybiBzfSwK
-SmQ6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRTZWNvbmRzKCkrMApyZXR1cm4gc30sCm8xOmZ1
-bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0TWlsbGlzZWNvbmRzKCkrMApyZXR1cm4gc30sCnpvOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9e30KcS5hPTAKcz1bXQpyPVtdCnEuYT1iLmxlbmd0aApDLk5t
-LkZWKHMsYikKcS5iPSIiCmlmKGMhPW51bGwmJmMuYSE9PTApYy5LKDAsbmV3IEguQ2oocSxyLHMpKQoi
-IitxLmEKcmV0dXJuIEouSnkoYSxuZXcgSC5MSShDLlRlLDAscyxyLDApKX0sCkVrOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEscAppZihiIGluc3RhbmNlb2YgQXJyYXkpcz1jPT1udWxsfHxjLmE9PT0wCmVs
-c2Ugcz0hMQppZihzKXtyPWIKcT1yLmxlbmd0aAppZihxPT09MCl7aWYoISFhLiQwKXJldHVybiBhLiQw
-KCl9ZWxzZSBpZihxPT09MSl7aWYoISFhLiQxKXJldHVybiBhLiQxKHJbMF0pfWVsc2UgaWYocT09PTIp
-e2lmKCEhYS4kMilyZXR1cm4gYS4kMihyWzBdLHJbMV0pfWVsc2UgaWYocT09PTMpe2lmKCEhYS4kMyly
-ZXR1cm4gYS4kMyhyWzBdLHJbMV0sclsyXSl9ZWxzZSBpZihxPT09NCl7aWYoISFhLiQ0KXJldHVybiBh
-LiQ0KHJbMF0sclsxXSxyWzJdLHJbM10pfWVsc2UgaWYocT09PTUpaWYoISFhLiQ1KXJldHVybiBhLiQ1
-KHJbMF0sclsxXSxyWzJdLHJbM10scls0XSkKcD1hWyIiKyIkIitxXQppZihwIT1udWxsKXJldHVybiBw
-LmFwcGx5KGEscil9cmV0dXJuIEguZTEoYSxiLGMpfSwKZTE6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
-cSxwLG8sbixtLGwsayxqLGk9YiBpbnN0YW5jZW9mIEFycmF5P2I6UC5DSChiLCEwLHQueiksaD1pLmxl
-bmd0aCxnPWEuJFIKaWYoaDxnKXJldHVybiBILnpvKGEsaSxjKQpzPWEuJEQKcj1zPT1udWxsCnE9IXI/
-cygpOm51bGwKcD1KLmlhKGEpCm89cC4kQwppZih0eXBlb2Ygbz09InN0cmluZyIpbz1wW29dCmlmKHIp
-e2lmKGMhPW51bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxpLGMpCmlmKGg9PT1nKXJldHVybiBvLmFw
-cGx5KGEsaSkKcmV0dXJuIEguem8oYSxpLGMpfWlmKHEgaW5zdGFuY2VvZiBBcnJheSl7aWYoYyE9bnVs
-bCYmYy5hIT09MClyZXR1cm4gSC56byhhLGksYykKaWYoaD5nK3EubGVuZ3RoKXJldHVybiBILnpvKGEs
-aSxudWxsKQpDLk5tLkZWKGkscS5zbGljZShoLWcpKQpyZXR1cm4gby5hcHBseShhLGkpfWVsc2V7aWYo
-aD5nKXJldHVybiBILnpvKGEsaSxjKQpuPU9iamVjdC5rZXlzKHEpCmlmKGM9PW51bGwpZm9yKHI9bi5s
-ZW5ndGgsbT0wO208bi5sZW5ndGg7bi5sZW5ndGg9PT1yfHwoMCxILmxrKShuKSwrK20pe2w9cVtILmgo
-blttXSldCmlmKEMuTnY9PT1sKXJldHVybiBILnpvKGEsaSxjKQpDLk5tLmkoaSxsKX1lbHNle2Zvcihy
-PW4ubGVuZ3RoLGs9MCxtPTA7bTxuLmxlbmd0aDtuLmxlbmd0aD09PXJ8fCgwLEgubGspKG4pLCsrbSl7
-aj1ILmgoblttXSkKaWYoYy54NChqKSl7KytrCkMuTm0uaShpLGMucSgwLGopKX1lbHNle2w9cVtqXQpp
-ZihDLk52PT09bClyZXR1cm4gSC56byhhLGksYykKQy5ObS5pKGksbCl9fWlmKGshPT1jLmEpcmV0dXJu
-IEguem8oYSxpLGMpfXJldHVybiBvLmFwcGx5KGEsaSl9fSwKcFk6ZnVuY3Rpb24oYSl7dGhyb3cgSC5i
-KEgudEwoYSkpfSwKT0g6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKUouSG0oYSkKdGhyb3cgSC5iKEgu
-SFkoYSxiKSl9LApIWTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iaW5kZXgiCmlmKCFILm9rKGIpKXJl
-dHVybiBuZXcgUC51KCEwLGIscSxudWxsKQpzPUgudVAoSi5IbShhKSkKaWYoIShiPDApKXtpZih0eXBl
-b2YgcyE9PSJudW1iZXIiKXJldHVybiBILnBZKHMpCnI9Yj49c31lbHNlIHI9ITAKaWYocilyZXR1cm4g
-UC5DZihiLGEscSxudWxsLHMpCnJldHVybiBQLk83KGIscSl9LAphdTpmdW5jdGlvbihhLGIsYyl7aWYo
-YT5jKXJldHVybiBQLlRFKGEsMCxjLCJzdGFydCIsbnVsbCkKaWYoYiE9bnVsbClpZihiPGF8fGI+Yyly
-ZXR1cm4gUC5URShiLGEsYywiZW5kIixudWxsKQpyZXR1cm4gbmV3IFAudSghMCxiLCJlbmQiLG51bGwp
-fSwKdEw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITAsYSxudWxsLG51bGwpfSwKYjpmdW5jdGlv
-bihhKXt2YXIgcyxyCmlmKGE9PW51bGwpYT1uZXcgUC5GKCkKcz1uZXcgRXJyb3IoKQpzLmRhcnRFeGNl
-cHRpb249YQpyPUgueAppZigiZGVmaW5lUHJvcGVydHkiIGluIE9iamVjdCl7T2JqZWN0LmRlZmluZVBy
-b3BlcnR5KHMsIm1lc3NhZ2UiLHtnZXQ6cn0pCnMubmFtZT0iIn1lbHNlIHMudG9TdHJpbmc9cgpyZXR1
-cm4gc30sCng6ZnVuY3Rpb24oKXtyZXR1cm4gSi5qKHRoaXMuZGFydEV4Y2VwdGlvbil9LAp2OmZ1bmN0
-aW9uKGEpe3Rocm93IEguYihhKX0sCmxrOmZ1bmN0aW9uKGEpe3Rocm93IEguYihQLmE0KGEpKX0sCmNN
-OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbgphPUguZUEoYS5yZXBsYWNlKFN0cmluZyh7fSksJyRy
-ZWNlaXZlciQnKSkKcz1hLm1hdGNoKC9cXFwkW2EtekEtWl0rXFxcJC9nKQppZihzPT1udWxsKXM9SC5W
-TShbXSx0LnMpCnI9cy5pbmRleE9mKCJcXCRhcmd1bWVudHNcXCQiKQpxPXMuaW5kZXhPZigiXFwkYXJn
-dW1lbnRzRXhwclxcJCIpCnA9cy5pbmRleE9mKCJcXCRleHByXFwkIikKbz1zLmluZGV4T2YoIlxcJG1l
-dGhvZFxcJCIpCm49cy5pbmRleE9mKCJcXCRyZWNlaXZlclxcJCIpCnJldHVybiBuZXcgSC5mOShhLnJl
-cGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGFyZ3VtZW50c1xcXFxcXCQnLCdnJyksJygoPzp4fFteeF0p
-KiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNFeHByXFxcXFxcJCcsJ2cnKSwn
-KCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGV4cHJcXFxcXFwkJywnZycp
-LCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkbWV0aG9kXFxcXFxcJCcs
-J2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJHJlY2VpdmVyXFxc
-XFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLHIscSxwLG8sbil9LApTNzpmdW5jdGlvbihhKXtyZXR1
-cm4gZnVuY3Rpb24oJGV4cHIkKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5eyRl
-eHByJC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fShh
-KX0sCk1qOmZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbigkZXhwciQpe3RyeXskZXhwciQuJG1ldGhv
-ZCR9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KGEpfSwKSWo6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-bmV3IEguVzAoYSxiPT1udWxsP251bGw6Yi5tZXRob2QpfSwKVDM6ZnVuY3Rpb24oYSxiKXt2YXIgcz1i
-PT1udWxsLHI9cz9udWxsOmIubWV0aG9kCnJldHVybiBuZXcgSC5heihhLHIscz9udWxsOmIucmVjZWl2
-ZXIpfSwKUnU6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gbmV3IEgudGUoYSkKaWYoYSBpbnN0
-YW5jZW9mIEguYnEpcmV0dXJuIEgudFcoYSxhLmEpCmlmKHR5cGVvZiBhIT09Im9iamVjdCIpcmV0dXJu
-IGEKaWYoImRhcnRFeGNlcHRpb24iIGluIGEpcmV0dXJuIEgudFcoYSxhLmRhcnRFeGNlcHRpb24pCnJl
-dHVybiBILnRsKGEpfSwKdFc6ZnVuY3Rpb24oYSxiKXtpZih0LnIuYihiKSlpZihiLiR0aHJvd25Kc0Vy
-cm9yPT1udWxsKWIuJHRocm93bkpzRXJyb3I9YQpyZXR1cm4gYn0sCnRsOmZ1bmN0aW9uKGEpe3ZhciBz
-LHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1udWxsCmlmKCEoIm1lc3NhZ2UiIGluIGEpKXJldHVy
-biBhCnM9YS5tZXNzYWdlCmlmKCJudW1iZXIiIGluIGEmJnR5cGVvZiBhLm51bWJlcj09Im51bWJlciIp
-e3I9YS5udW1iZXIKcT1yJjY1NTM1CmlmKChDLmpuLndHKHIsMTYpJjgxOTEpPT09MTApc3dpdGNoKHEp
-e2Nhc2UgNDM4OnJldHVybiBILnRXKGEsSC5UMyhILkVqKHMpKyIgKEVycm9yICIrcSsiKSIsZSkpCmNh
-c2UgNDQ1OmNhc2UgNTAwNzpyZXR1cm4gSC50VyhhLEguSWooSC5FaihzKSsiIChFcnJvciAiK3ErIiki
-LGUpKX19aWYoYSBpbnN0YW5jZW9mIFR5cGVFcnJvcil7cD0kLlNuKCkKbz0kLmxxKCkKbj0kLk45KCkK
-bT0kLmlJKCkKbD0kLlVOKCkKaz0kLlpoKCkKaj0kLnJOKCkKJC5jMygpCmk9JC5ISygpCmg9JC5yMSgp
-Cmc9cC5xUyhzKQppZihnIT1udWxsKXJldHVybiBILnRXKGEsSC5UMyhILmgocyksZykpCmVsc2V7Zz1v
-LnFTKHMpCmlmKGchPW51bGwpe2cubWV0aG9kPSJjYWxsIgpyZXR1cm4gSC50VyhhLEguVDMoSC5oKHMp
-LGcpKX1lbHNle2c9bi5xUyhzKQppZihnPT1udWxsKXtnPW0ucVMocykKaWYoZz09bnVsbCl7Zz1sLnFT
-KHMpCmlmKGc9PW51bGwpe2c9ay5xUyhzKQppZihnPT1udWxsKXtnPWoucVMocykKaWYoZz09bnVsbCl7
-Zz1tLnFTKHMpCmlmKGc9PW51bGwpe2c9aS5xUyhzKQppZihnPT1udWxsKXtnPWgucVMocykKZj1nIT1u
-dWxsfWVsc2UgZj0hMH1lbHNlIGY9ITB9ZWxzZSBmPSEwfWVsc2UgZj0hMH1lbHNlIGY9ITB9ZWxzZSBm
-PSEwfWVsc2UgZj0hMAppZihmKXJldHVybiBILnRXKGEsSC5JaihILmgocyksZykpfX1yZXR1cm4gSC50
-VyhhLG5ldyBILnZWKHR5cGVvZiBzPT0ic3RyaW5nIj9zOiIiKSl9aWYoYSBpbnN0YW5jZW9mIFJhbmdl
-RXJyb3Ipe2lmKHR5cGVvZiBzPT0ic3RyaW5nIiYmcy5pbmRleE9mKCJjYWxsIHN0YWNrIikhPT0tMSly
-ZXR1cm4gbmV3IFAuS1koKQpzPWZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gU3RyaW5nKGIpfWNhdGNoKGQp
-e31yZXR1cm4gbnVsbH0oYSkKcmV0dXJuIEgudFcoYSxuZXcgUC51KCExLGUsZSx0eXBlb2Ygcz09InN0
-cmluZyI/cy5yZXBsYWNlKC9eUmFuZ2VFcnJvcjpccyovLCIiKTpzKSl9aWYodHlwZW9mIEludGVybmFs
-RXJyb3I9PSJmdW5jdGlvbiImJmEgaW5zdGFuY2VvZiBJbnRlcm5hbEVycm9yKWlmKHR5cGVvZiBzPT0i
-c3RyaW5nIiYmcz09PSJ0b28gbXVjaCByZWN1cnNpb24iKXJldHVybiBuZXcgUC5LWSgpCnJldHVybiBh
-fSwKdHM6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoYSBpbnN0YW5jZW9mIEguYnEpcmV0dXJuIGEuYgppZihh
-PT1udWxsKXJldHVybiBuZXcgSC5YTyhhKQpzPWEuJGNhY2hlZFRyYWNlCmlmKHMhPW51bGwpcmV0dXJu
-IHMKcmV0dXJuIGEuJGNhY2hlZFRyYWNlPW5ldyBILlhPKGEpfSwKQjc6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHEscD1hLmxlbmd0aApmb3Iocz0wO3M8cDtzPXEpe3I9cysxCnE9cisxCmIuWSgwLGFbc10sYVty
-XSl9cmV0dXJuIGJ9LApmdDpmdW5jdGlvbihhLGIsYyxkLGUsZil7dC5ZLmEoYSkKc3dpdGNoKEgudVAo
-Yikpe2Nhc2UgMDpyZXR1cm4gYS4kMCgpCmNhc2UgMTpyZXR1cm4gYS4kMShjKQpjYXNlIDI6cmV0dXJu
-IGEuJDIoYyxkKQpjYXNlIDM6cmV0dXJuIGEuJDMoYyxkLGUpCmNhc2UgNDpyZXR1cm4gYS4kNChjLGQs
-ZSxmKX10aHJvdyBILmIobmV3IFAuQ0QoIlVuc3VwcG9ydGVkIG51bWJlciBvZiBhcmd1bWVudHMgZm9y
-IHdyYXBwZWQgY2xvc3VyZSIpKX0sCnRSOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYT09bnVsbClyZXR1
-cm4gbnVsbApzPWEuJGlkZW50aXR5CmlmKCEhcylyZXR1cm4gcwpzPWZ1bmN0aW9uKGMsZCxlKXtyZXR1
-cm4gZnVuY3Rpb24oZixnLGgsaSl7cmV0dXJuIGUoYyxkLGYsZyxoLGkpfX0oYSxiLEguZnQpCmEuJGlk
-ZW50aXR5PXMKcmV0dXJuIHN9LAppQTpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyLHEscCxv
-LG4sbSxsPWJbMF0saz1sLiRjYWxsTmFtZSxqPWU/T2JqZWN0LmNyZWF0ZShuZXcgSC56eCgpLmNvbnN0
-cnVjdG9yLnByb3RvdHlwZSk6T2JqZWN0LmNyZWF0ZShuZXcgSC5yVChudWxsLG51bGwsbnVsbCwiIiku
-Y29uc3RydWN0b3IucHJvdG90eXBlKQpqLiRpbml0aWFsaXplPWouY29uc3RydWN0b3IKaWYoZSlzPWZ1
-bmN0aW9uIHN0YXRpY190ZWFyX29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtyPSQueWoKaWYo
-dHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5oKCkKJC55aj1yKzEKcj1uZXcgRnVuY3Rpb24oImEs
-YixjLGQiK3IsInRoaXMuJGluaXRpYWxpemUoYSxiLGMsZCIrcisiKSIpCnM9cn1qLmNvbnN0cnVjdG9y
-PXMKcy5wcm90b3R5cGU9agppZighZSl7cT1ILmJ4KGEsbCxmKQpxLiRyZWZsZWN0aW9uSW5mbz1kfWVs
-c2V7ai4kc3RhdGljX25hbWU9ZwpxPWx9ai4kUz1ILmltKGQsZSxmKQpqW2tdPXEKZm9yKHA9cSxvPTE7
-bzxiLmxlbmd0aDsrK28pe249YltvXQptPW4uJGNhbGxOYW1lCmlmKG0hPW51bGwpe249ZT9uOkguYngo
-YSxuLGYpCmpbbV09bn1pZihvPT09Yyl7bi4kcmVmbGVjdGlvbkluZm89ZApwPW59fWouJEM9cApqLiRS
-PWwuJFIKai4kRD1sLiRECnJldHVybiBzfSwKaW06ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCmlmKHR5cGVv
-ZiBhPT0ibnVtYmVyIilyZXR1cm4gZnVuY3Rpb24oZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4g
-ZChlKX19KEguQnAsYSkKaWYodHlwZW9mIGE9PSJzdHJpbmciKXtpZihiKXRocm93IEguYigiQ2Fubm90
-IGNvbXB1dGUgc2lnbmF0dXJlIGZvciBzdGF0aWMgdGVhcm9mZi4iKQpzPWM/SC5QVzpILlRuCnJldHVy
-biBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBlKHRoaXMsZCl9fShhLHMpfXRo
-cm93IEguYigiRXJyb3IgaW4gZnVuY3Rpb25UeXBlIG9mIHRlYXJvZmYiKX0sCnZxOmZ1bmN0aW9uKGEs
-YixjLGQpe3ZhciBzPUguRFYKc3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnJldHVybiBmdW5jdGlvbihlLGYp
-e3JldHVybiBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2VdKCl9fShjLHMpCmNhc2UgMTpyZXR1cm4g
-ZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyl7cmV0dXJuIGYodGhpcylbZV0oZyl9fShjLHMp
-CmNhc2UgMjpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyxoKXtyZXR1cm4gZih0
-aGlzKVtlXShnLGgpfX0oYyxzKQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0
-aW9uKGcsaCxpKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSl9fShjLHMpCmNhc2UgNDpyZXR1cm4gZnVu
-Y3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyxoLGksail7cmV0dXJuIGYodGhpcylbZV0oZyxoLGks
-ail9fShjLHMpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyxoLGks
-aixrKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqLGspfX0oYyxzKQpkZWZhdWx0OnJldHVybiBmdW5j
-dGlvbihlLGYpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBlLmFwcGx5KGYodGhpcyksYXJndW1lbnRz
-KX19KGQscyl9fSwKYng6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtCmlmKGMpcmV0dXJu
-IEguSGYoYSxiKQpzPWIuJHN0dWJOYW1lCnI9Yi5sZW5ndGgKcT1hW3NdCnA9Yj09bnVsbD9xPT1udWxs
-OmI9PT1xCm89IXB8fHI+PTI3CmlmKG8pcmV0dXJuIEgudnEociwhcCxzLGIpCmlmKHI9PT0wKXtwPSQu
-eWoKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKbj0ic2VsZiIrcApy
-ZXR1cm4gbmV3IEZ1bmN0aW9uKCJyZXR1cm4gZnVuY3Rpb24oKXt2YXIgIituKyIgPSB0aGlzLiIrSC5F
-aihILm9OKCkpKyI7cmV0dXJuICIrbisiLiIrSC5FaihzKSsiKCk7fSIpKCl9bT0iYWJjZGVmZ2hpamts
-bW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxyKS5qb2luKCIsIikKcD0kLnlqCmlmKHR5
-cGVvZiBwIT09Im51bWJlciIpcmV0dXJuIHAuaCgpCiQueWo9cCsxCm0rPXAKcmV0dXJuIG5ldyBGdW5j
-dGlvbigicmV0dXJuIGZ1bmN0aW9uKCIrbSsiKXtyZXR1cm4gdGhpcy4iK0guRWooSC5vTigpKSsiLiIr
-SC5FaihzKSsiKCIrbSsiKTt9IikoKX0sClo0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPUguRFYscj1I
-LnlTCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDp0aHJvdyBILmIobmV3IEguRXEoIkludGVyY2VwdGVkIGZ1
-bmN0aW9uIHdpdGggbm8gYXJndW1lbnRzLiIpKQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXty
-ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpKX19KGMscyxyKQpjYXNlIDI6
-cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCl7cmV0dXJuIGYodGhpcylbZV0o
-Zyh0aGlzKSxoKX19KGMscyxyKQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVu
-Y3Rpb24oaCxpKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSl9fShjLHMscikKY2FzZSA0OnJl
-dHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqKXtyZXR1cm4gZih0aGlzKVtl
-XShnKHRoaXMpLGgsaSxqKX19KGMscyxyKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1
-cm4gZnVuY3Rpb24oaCxpLGosayl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrKX19KGMs
-cyxyKQpjYXNlIDY6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGosayxs
-KXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGssbCl9fShjLHMscikKZGVmYXVsdDpyZXR1
-cm4gZnVuY3Rpb24oZSxmLGcsaCl7cmV0dXJuIGZ1bmN0aW9uKCl7aD1bZyh0aGlzKV0KQXJyYXkucHJv
-dG90eXBlLnB1c2guYXBwbHkoaCxhcmd1bWVudHMpCnJldHVybiBlLmFwcGx5KGYodGhpcyksaCl9fShk
-LHMscil9fSwKSGY6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT1ILm9OKCksbD0kLlA0Cmlm
-KGw9PW51bGwpbD0kLlA0PUguRTIoInJlY2VpdmVyIikKcz1iLiRzdHViTmFtZQpyPWIubGVuZ3RoCnE9
-YVtzXQpwPWI9PW51bGw/cT09bnVsbDpiPT09cQpvPSFwfHxyPj0yOAppZihvKXJldHVybiBILlo0KHIs
-IXAscyxiKQppZihyPT09MSl7cD0icmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuIitILkVqKG0p
-KyIuIitILkVqKHMpKyIodGhpcy4iK2wrIik7IgpvPSQueWoKaWYodHlwZW9mIG8hPT0ibnVtYmVyIily
-ZXR1cm4gby5oKCkKJC55aj1vKzEKcmV0dXJuIG5ldyBGdW5jdGlvbihwK28rIn0iKSgpfW49ImFiY2Rl
-ZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAsci0xKS5qb2luKCIsIikKcD0i
-cmV0dXJuIGZ1bmN0aW9uKCIrbisiKXtyZXR1cm4gdGhpcy4iK0guRWoobSkrIi4iK0guRWoocykrIih0
-aGlzLiIrbCsiLCAiK24rIik7IgpvPSQueWoKaWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1cm4gby5o
-KCkKJC55aj1vKzEKcmV0dXJuIG5ldyBGdW5jdGlvbihwK28rIn0iKSgpfSwKS3E6ZnVuY3Rpb24oYSxi
-LGMsZCxlLGYsZyl7cmV0dXJuIEguaUEoYSxiLGMsZCwhIWUsISFmLGcpfSwKVG46ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnooYS5hKSxiKX0sClBXOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC56KGEuYyksYil9LApEVjpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY30sCm9OOmZ1bmN0aW9uKCl7dmFyIHM9JC5t
-SgpyZXR1cm4gcz09bnVsbD8kLm1KPUguRTIoInNlbGYiKTpzfSwKRTI6ZnVuY3Rpb24oYSl7dmFyIHMs
-cixxLHA9bmV3IEguclQoInNlbGYiLCJ0YXJnZXQiLCJyZWNlaXZlciIsIm5hbWUiKSxvPUouRXAoT2Jq
-ZWN0LmdldE93blByb3BlcnR5TmFtZXMocCksdC5SKQpmb3Iocz1vLmxlbmd0aCxyPTA7cjxzOysrcil7
-cT1vW3JdCmlmKHBbcV09PT1hKXJldHVybiBxfXRocm93IEguYihQLnhZKCJGaWVsZCBuYW1lICIrYSsi
-IG5vdCBmb3VuZC4iKSl9LApvVDpmdW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8oImJvb2xlYW4gZXhw
-cmVzc2lvbiBtdXN0IG5vdCBiZSBudWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlvbihhKXt0aHJvdyBI
-LmIobmV3IEgua1koYSkpfSwKYWc6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQLnAoYSkpfSwKWWc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHYuZ2V0SXNvbGF0ZVRhZyhhKX0sCkJvOmZ1bmN0aW9uKGEpe3JldHVy
-biBILnYoSC5jKGEpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxi
+KCJAPDA+IikuS3EoYykuQygiWnk8MSwyPiIpKX0sCkdROmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5u
+KCJGaWVsZCAnIithKyInIGhhcyBiZWVuIGFzc2lnbmVkIGR1cmluZyBpbml0aWFsaXphdGlvbi4iKX0s
+CkJpOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5yMyhhKX0sCm9vOmZ1bmN0aW9uKGEpe3ZhciBzLHI9
+YV40OAppZihyPD05KXJldHVybiByCnM9YXwzMgppZig5Nzw9cyYmczw9MTAyKXJldHVybiBzLTg3CnJl
+dHVybi0xfSwKY2I6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5iKG5ldyBILkdNKGIs
+Yy5DKCJHTTwwPiIpKSkKcmV0dXJuIGF9LApxQzpmdW5jdGlvbihhLGIsYyxkKXtQLmsxKGIsInN0YXJ0
+IikKaWYoYyE9bnVsbCl7UC5rMShjLCJlbmQiKQppZihiPmMpSC52KFAuVEUoYiwwLGMsInN0YXJ0Iixu
+dWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihhLGIs
+YyxkKXtpZih0LmIuYihhKSlyZXR1cm4gbmV3IEgueHkoYSxiLGMuQygiQDwwPiIpLktxKGQpLkMoInh5
+PDEsMj4iKSkKcmV0dXJuIG5ldyBILmkxKGEsYixjLkMoIkA8MD4iKS5LcShkKS5DKCJpMTwxLDI+Iikp
+fSwKYks6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPSJjb3VudCIKaWYodC5iLmIoYSkpe1AuTVIoYixzLHQu
+UykKUC5rMShiLHMpCnJldHVybiBuZXcgSC5kNShhLGIsYy5DKCJkNTwwPiIpKX1QLk1SKGIscyx0LlMp
+ClAuazEoYixzKQpyZXR1cm4gbmV3IEguQU0oYSxiLGMuQygiQU08MD4iKSl9LApXcDpmdW5jdGlvbigp
+e3JldHVybiBuZXcgUC5saigiTm8gZWxlbWVudCIpfSwKQW06ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFAu
+bGooIlRvbyBtYW55IGVsZW1lbnRzIil9LAphcjpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigiVG9v
+IGZldyBlbGVtZW50cyIpfSwKQlI6ZnVuY3Rpb24gQlIoKXt9LApFNzpmdW5jdGlvbiBFNyhhLGIpe3Ro
+aXMuYT1hCnRoaXMuJHRpPWJ9LApaeTpmdW5jdGlvbiBaeShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
+LApvbDpmdW5jdGlvbiBvbChhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApVcTpmdW5jdGlvbiBVcSgp
+e30sCmpWOmZ1bmN0aW9uIGpWKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCm46ZnVuY3Rpb24gbihh
+KXt0aGlzLmE9YX0sCnIzOmZ1bmN0aW9uIHIzKGEpe3RoaXMuYT1hfSwKcWo6ZnVuY3Rpb24gcWooYSl7
+dGhpcy5hPWF9LApHTTpmdW5jdGlvbiBHTShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApiUTpmdW5j
+dGlvbiBiUSgpe30sCmFMOmZ1bmN0aW9uIGFMKCl7fSwKbkg6ZnVuY3Rpb24gbkgoYSxiLGMsZCl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKYTc6ZnVuY3Rpb24gYTcoYSxiLGMpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwKXy4kdGk9Y30sCmkxOmZ1bmN0aW9uIGkx
+KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKeHk6ZnVuY3Rpb24geHkoYSxiLGMp
+e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApNSDpmdW5jdGlvbiBNSChhLGIsYyl7dmFyIF89
+dGhpcwpfLmE9bnVsbApfLmI9YQpfLmM9YgpfLiR0aT1jfSwKbEo6ZnVuY3Rpb24gbEooYSxiLGMpe3Ro
+aXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApVNTpmdW5jdGlvbiBVNShhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy4kdGk9Y30sClNPOmZ1bmN0aW9uIFNPKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
+Ygp0aGlzLiR0aT1jfSwKQU06ZnVuY3Rpb24gQU0oYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+JHRpPWN9LApkNTpmdW5jdGlvbiBkNShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30s
+ClUxOmZ1bmN0aW9uIFUxKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKTUI6ZnVu
+Y3Rpb24gTUIoYSl7dGhpcy4kdGk9YX0sCkZ1OmZ1bmN0aW9uIEZ1KGEpe3RoaXMuJHRpPWF9LAp1Njpm
+dW5jdGlvbiB1NihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApKQjpmdW5jdGlvbiBKQihhLGIpe3Ro
+aXMuYT1hCnRoaXMuJHRpPWJ9LApTVTpmdW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9uIFJlKCl7fSwK
+dzI6ZnVuY3Rpb24gdzIoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sClFDOmZ1bmN0aW9u
+IFFDKCl7fSwKZGM6ZnVuY3Rpb24oKXt0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlm
+aWFibGUgTWFwIikpfSwKTlE6ZnVuY3Rpb24oYSl7dmFyIHMscj1ILkpnKGEpCmlmKHIhPW51bGwpcmV0
+dXJuIHIKcz0ibWluaWZpZWQ6IithCnJldHVybiBzfSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihi
+IT1udWxsKXtzPWIueAppZihzIT1udWxsKXJldHVybiBzfXJldHVybiB0LmFVLmIoYSl9LApFajpmdW5j
+dGlvbihhKXt2YXIgcwppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJu
+dW1iZXIiKXtpZihhIT09MClyZXR1cm4iIithfWVsc2UgaWYoITA9PT1hKXJldHVybiJ0cnVlIgplbHNl
+IGlmKCExPT09YSlyZXR1cm4iZmFsc2UiCmVsc2UgaWYoYT09bnVsbClyZXR1cm4ibnVsbCIKcz1KLmoo
+YSkKaWYodHlwZW9mIHMhPSJzdHJpbmciKXRocm93IEguYihILnRMKGEpKQpyZXR1cm4gc30sCmVROmZ1
+bmN0aW9uKGEpe3ZhciBzPWEuJGlkZW50aXR5SGFzaAppZihzPT1udWxsKXtzPU1hdGgucmFuZG9tKCkq
+MHgzZmZmZmZmZnwwCmEuJGlkZW50aXR5SGFzaD1zfXJldHVybiBzfSwKSHA6ZnVuY3Rpb24oYSxiKXt2
+YXIgcyxyLHEscCxvLG4sbT1udWxsCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnYoSC50TChhKSkKcz0v
+XlxzKlsrLV0/KCgweFthLWYwLTldKyl8KFxkKyl8KFthLXowLTldKykpXHMqJC9pLmV4ZWMoYSkKaWYo
+cz09bnVsbClyZXR1cm4gbQppZigzPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLDMpCnI9c1szXQppZihi
+PT1udWxsKXtpZihyIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZihzWzJdIT1udWxsKXJldHVy
+biBwYXJzZUludChhLDE2KQpyZXR1cm4gbX1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2
+LCJyYWRpeCIsbSkpCmlmKGI9PT0xMCYmciE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYoYjwx
+MHx8cj09bnVsbCl7cT1iPD0xMD80NytiOjg2K2IKcD1zWzFdCmZvcihvPXAubGVuZ3RoLG49MDtuPG87
+KytuKWlmKChDLnhCLlcocCxuKXwzMik+cSlyZXR1cm4gbX1yZXR1cm4gcGFyc2VJbnQoYSxiKX0sCk06
+ZnVuY3Rpb24oYSl7cmV0dXJuIEguSDUoYSl9LApINTpmdW5jdGlvbihhKXt2YXIgcyxyLHEKaWYoYSBp
+bnN0YW5jZW9mIFAuTWgpcmV0dXJuIEguZG0oSC56KGEpLG51bGwpCmlmKEouaWEoYSk9PT1DLk9rfHx0
+LmJKLmIoYSkpe3M9Qy5PNChhKQppZihILkJlKHMpKXJldHVybiBzCnI9YS5jb25zdHJ1Y3RvcgppZih0
+eXBlb2Ygcj09ImZ1bmN0aW9uIil7cT1yLm5hbWUKaWYodHlwZW9mIHE9PSJzdHJpbmciJiZILkJlKHEp
+KXJldHVybiBxfX1yZXR1cm4gSC5kbShILnooYSksbnVsbCl9LApCZTpmdW5jdGlvbihhKXt2YXIgcz1h
+IT09Ik9iamVjdCImJmEhPT0iIgpyZXR1cm4gc30sCk0wOmZ1bmN0aW9uKCl7aWYoISFzZWxmLmxvY2F0
+aW9uKXJldHVybiBzZWxmLmxvY2F0aW9uLmhyZWYKcmV0dXJuIG51bGx9LApWSzpmdW5jdGlvbihhKXt2
+YXIgcyxyLHEscCxvPWEubGVuZ3RoCmlmKG88PTUwMClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5h
+cHBseShudWxsLGEpCmZvcihzPSIiLHI9MDtyPG87cj1xKXtxPXIrNTAwCnA9cTxvP3E6bwpzKz1TdHJp
+bmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zbGljZShyLHApKX1yZXR1cm4gc30sCkNxOmZ1bmN0
+aW9uKGEpe3ZhciBzLHIscSxwPUguVk0oW10sdC5hKQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxhLmxlbmd0
+aDthLmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsrcil7cT1hW3JdCmlmKCFILm9rKHEpKXRocm93IEgu
+YihILnRMKHEpKQppZihxPD02NTUzNSlDLk5tLmkocCxxKQplbHNlIGlmKHE8PTExMTQxMTEpe0MuTm0u
+aShwLDU1Mjk2KyhDLmpuLndHKHEtNjU1MzYsMTApJjEwMjMpKQpDLk5tLmkocCw1NjMyMCsocSYxMDIz
+KSl9ZWxzZSB0aHJvdyBILmIoSC50TChxKSl9cmV0dXJuIEguVksocCl9LAplVDpmdW5jdGlvbihhKXt2
+YXIgcyxyLHEKZm9yKHM9YS5sZW5ndGgscj0wO3I8czsrK3Ipe3E9YVtyXQppZighSC5vayhxKSl0aHJv
+dyBILmIoSC50TChxKSkKaWYocTwwKXRocm93IEguYihILnRMKHEpKQppZihxPjY1NTM1KXJldHVybiBI
+LkNxKGEpfXJldHVybiBILlZLKGEpfSwKZnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwCmlmKGM8
+PTUwMCYmYj09PTAmJmM9PT1hLmxlbmd0aClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShu
+dWxsLGEpCmZvcihzPWIscj0iIjtzPGM7cz1xKXtxPXMrNTAwCnA9cTxjP3E6YwpyKz1TdHJpbmcuZnJv
+bUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zdWJhcnJheShzLHApKX1yZXR1cm4gcn0sCkx3OmZ1bmN0aW9u
+KGEpe3ZhciBzCmlmKDA8PWEpe2lmKGE8PTY1NTM1KXJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGEp
+CmlmKGE8PTExMTQxMTEpe3M9YS02NTUzNgpyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoQy5qbi53
+RyhzLDEwKXw1NTI5Nik+Pj4wLHMmMTAyM3w1NjMyMCl9fXRocm93IEguYihQLlRFKGEsMCwxMTE0MTEx
+LG51bGwsbnVsbCkpfSwKbzI6ZnVuY3Rpb24oYSl7aWYoYS5kYXRlPT09dm9pZCAwKWEuZGF0ZT1uZXcg
+RGF0ZShhLmEpCnJldHVybiBhLmRhdGV9LAp0SjpmdW5jdGlvbihhKXt2YXIgcz1ILm8yKGEpLmdldEZ1
+bGxZZWFyKCkrMApyZXR1cm4gc30sCk5TOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0TW9udGgo
+KSsxCnJldHVybiBzfSwKakE6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXREYXRlKCkrMApyZXR1
+cm4gc30sCklYOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0SG91cnMoKSswCnJldHVybiBzfSwK
+Y2g6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRNaW51dGVzKCkrMApyZXR1cm4gc30sCkpkOmZ1
+bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0U2Vjb25kcygpKzAKcmV0dXJuIHN9LApvMTpmdW5jdGlv
+bihhKXt2YXIgcz1ILm8yKGEpLmdldE1pbGxpc2Vjb25kcygpKzAKcmV0dXJuIHN9LAp6bzpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxPXt9CnEuYT0wCnM9W10Kcj1bXQpxLmE9Yi5sZW5ndGgKQy5ObS5GVihz
+LGIpCnEuYj0iIgppZihjIT1udWxsJiZjLmEhPT0wKWMuSygwLG5ldyBILkNqKHEscixzKSkKIiIrcS5h
+CnJldHVybiBKLkp5KGEsbmV3IEguTEkoQy5UZSwwLHMsciwwKSl9LApFazpmdW5jdGlvbihhLGIsYyl7
+dmFyIHMscixxLHAKaWYoYiBpbnN0YW5jZW9mIEFycmF5KXM9Yz09bnVsbHx8Yy5hPT09MAplbHNlIHM9
+ITEKaWYocyl7cj1iCnE9ci5sZW5ndGgKaWYocT09PTApe2lmKCEhYS4kMClyZXR1cm4gYS4kMCgpfWVs
+c2UgaWYocT09PTEpe2lmKCEhYS4kMSlyZXR1cm4gYS4kMShyWzBdKX1lbHNlIGlmKHE9PT0yKXtpZigh
+IWEuJDIpcmV0dXJuIGEuJDIoclswXSxyWzFdKX1lbHNlIGlmKHE9PT0zKXtpZighIWEuJDMpcmV0dXJu
+IGEuJDMoclswXSxyWzFdLHJbMl0pfWVsc2UgaWYocT09PTQpe2lmKCEhYS4kNClyZXR1cm4gYS4kNChy
+WzBdLHJbMV0sclsyXSxyWzNdKX1lbHNlIGlmKHE9PT01KWlmKCEhYS4kNSlyZXR1cm4gYS4kNShyWzBd
+LHJbMV0sclsyXSxyWzNdLHJbNF0pCnA9YVsiIisiJCIrcV0KaWYocCE9bnVsbClyZXR1cm4gcC5hcHBs
+eShhLHIpfXJldHVybiBILmUxKGEsYixjKX0sCmUxOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxv
+LG4sbSxsLGssaixpPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx0LnopLGg9aS5sZW5ndGgs
+Zz1hLiRSCmlmKGg8ZylyZXR1cm4gSC56byhhLGksYykKcz1hLiRECnI9cz09bnVsbApxPSFyP3MoKTpu
+dWxsCnA9Si5pYShhKQpvPXAuJEMKaWYodHlwZW9mIG89PSJzdHJpbmciKW89cFtvXQppZihyKXtpZihj
+IT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsaSxjKQppZihoPT09ZylyZXR1cm4gby5hcHBseShh
+LGkpCnJldHVybiBILnpvKGEsaSxjKX1pZihxIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMhPW51bGwmJmMu
+YSE9PTApcmV0dXJuIEguem8oYSxpLGMpCmlmKGg+ZytxLmxlbmd0aClyZXR1cm4gSC56byhhLGksbnVs
+bCkKQy5ObS5GVihpLHEuc2xpY2UoaC1nKSkKcmV0dXJuIG8uYXBwbHkoYSxpKX1lbHNle2lmKGg+Zyly
+ZXR1cm4gSC56byhhLGksYykKbj1PYmplY3Qua2V5cyhxKQppZihjPT1udWxsKWZvcihyPW4ubGVuZ3Ro
+LG09MDttPG4ubGVuZ3RoO24ubGVuZ3RoPT09cnx8KDAsSC5saykobiksKyttKXtsPXFbSC5oKG5bbV0p
+XQppZihDLk52PT09bClyZXR1cm4gSC56byhhLGksYykKQy5ObS5pKGksbCl9ZWxzZXtmb3Iocj1uLmxl
+bmd0aCxrPTAsbT0wO208bi5sZW5ndGg7bi5sZW5ndGg9PT1yfHwoMCxILmxrKShuKSwrK20pe2o9SC5o
+KG5bbV0pCmlmKGMueDQoaikpeysrawpDLk5tLmkoaSxjLnEoMCxqKSl9ZWxzZXtsPXFbal0KaWYoQy5O
+dj09PWwpcmV0dXJuIEguem8oYSxpLGMpCkMuTm0uaShpLGwpfX1pZihrIT09Yy5hKXJldHVybiBILnpv
+KGEsaSxjKX1yZXR1cm4gby5hcHBseShhLGkpfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEguYihILnRM
+KGEpKX0sCk9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihILkhZKGEs
+YikpfSwKSFk6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9ImluZGV4IgppZighSC5vayhiKSlyZXR1cm4g
+bmV3IFAudSghMCxiLHEsbnVsbCkKcz1ILnVQKEouSG0oYSkpCmlmKCEoYjwwKSl7aWYodHlwZW9mIHMh
+PT0ibnVtYmVyIilyZXR1cm4gSC5wWShzKQpyPWI+PXN9ZWxzZSByPSEwCmlmKHIpcmV0dXJuIFAuQ2Yo
+YixhLHEsbnVsbCxzKQpyZXR1cm4gUC5PNyhiLHEpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Yyly
+ZXR1cm4gUC5URShhLDAsYywic3RhcnQiLG51bGwpCmlmKGIhPW51bGwpaWYoYjxhfHxiPmMpcmV0dXJu
+IFAuVEUoYixhLGMsImVuZCIsbnVsbCkKcmV0dXJuIG5ldyBQLnUoITAsYiwiZW5kIixudWxsKX0sCnRM
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51KCEwLGEsbnVsbCxudWxsKX0sCmI6ZnVuY3Rpb24oYSl7
+dmFyIHMscgppZihhPT1udWxsKWE9bmV3IFAuRigpCnM9bmV3IEVycm9yKCkKcy5kYXJ0RXhjZXB0aW9u
+PWEKcj1ILngKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qpe09iamVjdC5kZWZpbmVQcm9wZXJ0
+eShzLCJtZXNzYWdlIix7Z2V0OnJ9KQpzLm5hbWU9IiJ9ZWxzZSBzLnRvU3RyaW5nPXIKcmV0dXJuIHN9
+LAp4OmZ1bmN0aW9uKCl7cmV0dXJuIEouaih0aGlzLmRhcnRFeGNlcHRpb24pfSwKdjpmdW5jdGlvbihh
+KXt0aHJvdyBILmIoYSl9LApsazpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5hNChhKSl9LApjTTpmdW5j
+dGlvbihhKXt2YXIgcyxyLHEscCxvLG4KYT1ILmVBKGEucmVwbGFjZShTdHJpbmcoe30pLCckcmVjZWl2
+ZXIkJykpCnM9YS5tYXRjaCgvXFxcJFthLXpBLVpdK1xcXCQvZykKaWYocz09bnVsbClzPUguVk0oW10s
+dC5zKQpyPXMuaW5kZXhPZigiXFwkYXJndW1lbnRzXFwkIikKcT1zLmluZGV4T2YoIlxcJGFyZ3VtZW50
+c0V4cHJcXCQiKQpwPXMuaW5kZXhPZigiXFwkZXhwclxcJCIpCm89cy5pbmRleE9mKCJcXCRtZXRob2Rc
+XCQiKQpuPXMuaW5kZXhPZigiXFwkcmVjZWl2ZXJcXCQiKQpyZXR1cm4gbmV3IEguZjkoYS5yZXBsYWNl
+KG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNcXFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJyku
+cmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkYXJndW1lbnRzRXhwclxcXFxcXCQnLCdnJyksJygoPzp4
+fFteeF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRleHByXFxcXFxcJCcsJ2cnKSwnKCg/
+Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJG1ldGhvZFxcXFxcXCQnLCdnJyks
+JygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRyZWNlaXZlclxcXFxcXCQn
+LCdnJyksJygoPzp4fFteeF0pKiknKSxyLHEscCxvLG4pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1
+bmN0aW9uKCRleHByJCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXskZXhwciQu
+JG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oYSl9LApN
+ajpmdW5jdGlvbihhKXtyZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRob2QkfWNh
+dGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fShhKX0sCklqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBI
+LlcwKGEsYj09bnVsbD9udWxsOmIubWV0aG9kKX0sClQzOmZ1bmN0aW9uKGEsYil7dmFyIHM9Yj09bnVs
+bCxyPXM/bnVsbDpiLm1ldGhvZApyZXR1cm4gbmV3IEguYXooYSxyLHM/bnVsbDpiLnJlY2VpdmVyKX0s
+ClJ1OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG5ldyBILnRlKGEpCmlmKGEgaW5zdGFuY2Vv
+ZiBILmJxKXJldHVybiBILnRXKGEsYS5hKQppZih0eXBlb2YgYSE9PSJvYmplY3QiKXJldHVybiBhCmlm
+KCJkYXJ0RXhjZXB0aW9uIiBpbiBhKXJldHVybiBILnRXKGEsYS5kYXJ0RXhjZXB0aW9uKQpyZXR1cm4g
+SC50bChhKX0sCnRXOmZ1bmN0aW9uKGEsYil7aWYodC5yLmIoYikpaWYoYi4kdGhyb3duSnNFcnJvcj09
+bnVsbCliLiR0aHJvd25Kc0Vycm9yPWEKcmV0dXJuIGJ9LAp0bDpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
+cCxvLG4sbSxsLGssaixpLGgsZyxmLGU9bnVsbAppZighKCJtZXNzYWdlIiBpbiBhKSlyZXR1cm4gYQpz
+PWEubWVzc2FnZQppZigibnVtYmVyIiBpbiBhJiZ0eXBlb2YgYS5udW1iZXI9PSJudW1iZXIiKXtyPWEu
+bnVtYmVyCnE9ciY2NTUzNQppZigoQy5qbi53RyhyLDE2KSY4MTkxKT09PTEwKXN3aXRjaChxKXtjYXNl
+IDQzODpyZXR1cm4gSC50VyhhLEguVDMoSC5FaihzKSsiIChFcnJvciAiK3ErIikiLGUpKQpjYXNlIDQ0
+NTpjYXNlIDUwMDc6cmV0dXJuIEgudFcoYSxILklqKEguRWoocykrIiAoRXJyb3IgIitxKyIpIixlKSl9
+fWlmKGEgaW5zdGFuY2VvZiBUeXBlRXJyb3Ipe3A9JC5TbigpCm89JC5scSgpCm49JC5OOSgpCm09JC5p
+SSgpCmw9JC5VTigpCms9JC5aaCgpCmo9JC5yTigpCiQuYzMoKQppPSQuSEsoKQpoPSQucjEoKQpnPXAu
+cVMocykKaWYoZyE9bnVsbClyZXR1cm4gSC50VyhhLEguVDMoSC5oKHMpLGcpKQplbHNle2c9by5xUyhz
+KQppZihnIT1udWxsKXtnLm1ldGhvZD0iY2FsbCIKcmV0dXJuIEgudFcoYSxILlQzKEguaChzKSxnKSl9
+ZWxzZXtnPW4ucVMocykKaWYoZz09bnVsbCl7Zz1tLnFTKHMpCmlmKGc9PW51bGwpe2c9bC5xUyhzKQpp
+ZihnPT1udWxsKXtnPWsucVMocykKaWYoZz09bnVsbCl7Zz1qLnFTKHMpCmlmKGc9PW51bGwpe2c9bS5x
+UyhzKQppZihnPT1udWxsKXtnPWkucVMocykKaWYoZz09bnVsbCl7Zz1oLnFTKHMpCmY9ZyE9bnVsbH1l
+bHNlIGY9ITB9ZWxzZSBmPSEwfWVsc2UgZj0hMH1lbHNlIGY9ITB9ZWxzZSBmPSEwfWVsc2UgZj0hMH1l
+bHNlIGY9ITAKaWYoZilyZXR1cm4gSC50VyhhLEguSWooSC5oKHMpLGcpKX19cmV0dXJuIEgudFcoYSxu
+ZXcgSC52Vih0eXBlb2Ygcz09InN0cmluZyI/czoiIikpfWlmKGEgaW5zdGFuY2VvZiBSYW5nZUVycm9y
+KXtpZih0eXBlb2Ygcz09InN0cmluZyImJnMuaW5kZXhPZigiY2FsbCBzdGFjayIpIT09LTEpcmV0dXJu
+IG5ldyBQLktZKCkKcz1mdW5jdGlvbihiKXt0cnl7cmV0dXJuIFN0cmluZyhiKX1jYXRjaChkKXt9cmV0
+dXJuIG51bGx9KGEpCnJldHVybiBILnRXKGEsbmV3IFAudSghMSxlLGUsdHlwZW9mIHM9PSJzdHJpbmci
+P3MucmVwbGFjZSgvXlJhbmdlRXJyb3I6XHMqLywiIik6cykpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9y
+PT0iZnVuY3Rpb24iJiZhIGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2Ygcz09InN0cmlu
+ZyImJnM9PT0idG9vIG11Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRz
+OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVs
+bClyZXR1cm4gbmV3IEguWE8oYSkKcz1hLiRjYWNoZWRUcmFjZQppZihzIT1udWxsKXJldHVybiBzCnJl
+dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
+LHA9YS5sZW5ndGgKZm9yKHM9MDtzPHA7cz1xKXtyPXMrMQpxPXIrMQpiLlk1KDAsYVtzXSxhW3JdKX1y
+ZXR1cm4gYn0sCmZ0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt0LlkuYShhKQpzd2l0Y2goSC51UChiKSl7
+Y2FzZSAwOnJldHVybiBhLiQwKCkKY2FzZSAxOnJldHVybiBhLiQxKGMpCmNhc2UgMjpyZXR1cm4gYS4k
+MihjLGQpCmNhc2UgMzpyZXR1cm4gYS4kMyhjLGQsZSkKY2FzZSA0OnJldHVybiBhLiQ0KGMsZCxlLGYp
+fXRocm93IEguYihuZXcgUC5DRCgiVW5zdXBwb3J0ZWQgbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3Igd3Jh
+cHBlZCBjbG9zdXJlIikpfSwKdFI6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBu
+dWxsCnM9YS4kaWRlbnRpdHkKaWYoISFzKXJldHVybiBzCnM9ZnVuY3Rpb24oYyxkLGUpe3JldHVybiBm
+dW5jdGlvbihmLGcsaCxpKXtyZXR1cm4gZShjLGQsZixnLGgsaSl9fShhLGIsSC5mdCkKYS4kaWRlbnRp
+dHk9cwpyZXR1cm4gc30sCmlBOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbixt
+LGw9YlswXSxrPWwuJGNhbGxOYW1lLGo9ZT9PYmplY3QuY3JlYXRlKG5ldyBILnp4KCkuY29uc3RydWN0
+b3IucHJvdG90eXBlKTpPYmplY3QuY3JlYXRlKG5ldyBILnJUKG51bGwsbnVsbCxudWxsLCIiKS5jb25z
+dHJ1Y3Rvci5wcm90b3R5cGUpCmouJGluaXRpYWxpemU9ai5jb25zdHJ1Y3RvcgppZihlKXM9ZnVuY3Rp
+b24gc3RhdGljX3RlYXJfb2ZmKCl7dGhpcy4kaW5pdGlhbGl6ZSgpfQplbHNle3I9JC55agppZih0eXBl
+b2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKQokLnlqPXIrMQpyPW5ldyBGdW5jdGlvbigiYSxiLGMs
+ZCIrciwidGhpcy4kaW5pdGlhbGl6ZShhLGIsYyxkIityKyIpIikKcz1yfWouY29uc3RydWN0b3I9cwpz
+LnByb3RvdHlwZT1qCmlmKCFlKXtxPUguYngoYSxsLGYpCnEuJHJlZmxlY3Rpb25JbmZvPWR9ZWxzZXtq
+LiRzdGF0aWNfbmFtZT1nCnE9bH1qLiRTPUguaW0oZCxlLGYpCmpba109cQpmb3IocD1xLG89MTtvPGIu
+bGVuZ3RoOysrbyl7bj1iW29dCm09bi4kY2FsbE5hbWUKaWYobSE9bnVsbCl7bj1lP246SC5ieChhLG4s
+ZikKalttXT1ufWlmKG89PT1jKXtuLiRyZWZsZWN0aW9uSW5mbz1kCnA9bn19ai4kQz1wCmouJFI9bC4k
+UgpqLiREPWwuJEQKcmV0dXJuIHN9LAppbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYodHlwZW9mIGE9
+PSJudW1iZXIiKXJldHVybiBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBkKGUp
+fX0oSC5CcCxhKQppZih0eXBlb2YgYT09InN0cmluZyIpe2lmKGIpdGhyb3cgSC5iKCJDYW5ub3QgY29t
+cHV0ZSBzaWduYXR1cmUgZm9yIHN0YXRpYyB0ZWFyb2ZmLiIpCnM9Yz9ILlBXOkguVG4KcmV0dXJuIGZ1
+bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcyxkKX19KGEscyl9dGhyb3cg
+SC5iKCJFcnJvciBpbiBmdW5jdGlvblR5cGUgb2YgdGVhcm9mZiIpfSwKdnE6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHM9SC5EVgpzd2l0Y2goYj8tMTphKXtjYXNlIDA6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0
+dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oKX19KGMscykKY2FzZSAxOnJldHVybiBmdW5j
+dGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZih0aGlzKVtlXShnKX19KGMscykKY2Fz
+ZSAyOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgpe3JldHVybiBmKHRoaXMp
+W2VdKGcsaCl9fShjLHMpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24o
+ZyxoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcsaCxpKX19KGMscykKY2FzZSA0OnJldHVybiBmdW5jdGlv
+bihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqKX19
+KGMscykKY2FzZSA1OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqLGsp
+e3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGosayl9fShjLHMpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9u
+KGUsZil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkoZih0aGlzKSxhcmd1bWVudHMpfX0o
+ZCxzKX19LApieDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0KaWYoYylyZXR1cm4gSC5I
+ZihhLGIpCnM9Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51bGw6Yj09
+PXEKbz0hcHx8cj49MjcKaWYobylyZXR1cm4gSC52cShyLCFwLHMsYikKaWYocj09PTApe3A9JC55agpp
+Zih0eXBlb2YgcCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQpuPSJzZWxmIitwCnJldHVy
+biBuZXcgRnVuY3Rpb24oInJldHVybiBmdW5jdGlvbigpe3ZhciAiK24rIiA9IHRoaXMuIitILkVqKEgu
+b04oKSkrIjtyZXR1cm4gIituKyIuIitILkVqKHMpKyIoKTt9IikoKX1tPSJhYmNkZWZnaGlqa2xtbm9w
+cXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHIpLmpvaW4oIiwiKQpwPSQueWoKaWYodHlwZW9m
+IHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKbSs9cApyZXR1cm4gbmV3IEZ1bmN0aW9u
+KCJyZXR1cm4gZnVuY3Rpb24oIittKyIpe3JldHVybiB0aGlzLiIrSC5FaihILm9OKCkpKyIuIitILkVq
+KHMpKyIoIittKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9SC5EVixyPUgueVMK
+c3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihuZXcgSC5FcSgiSW50ZXJjZXB0ZWQgZnVuY3Rp
+b24gd2l0aCBubyBhcmd1bWVudHMuIikpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVy
+biBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcykpfX0oYyxzLHIpCmNhc2UgMjpyZXR1
+cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
+aXMpLGgpfX0oYyxzLHIpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlv
+bihoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpKX19KGMscyxyKQpjYXNlIDQ6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGco
+dGhpcyksaCxpLGopfX0oYyxzLHIpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBm
+dW5jdGlvbihoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGspfX0oYyxzLHIp
+CmNhc2UgNjpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksaixrLGwpe3Jl
+dHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayxsKX19KGMscyxyKQpkZWZhdWx0OnJldHVybiBm
+dW5jdGlvbihlLGYsZyxoKXtyZXR1cm4gZnVuY3Rpb24oKXtoPVtnKHRoaXMpXQpBcnJheS5wcm90b3R5
+cGUucHVzaC5hcHBseShoLGFyZ3VtZW50cykKcmV0dXJuIGUuYXBwbHkoZih0aGlzKSxoKX19KGQscyxy
+KX19LApIZjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPUgub04oKSxsPSQuUDQKaWYobD09
+bnVsbClsPSQuUDQ9SC5FMigicmVjZWl2ZXIiKQpzPWIuJHN0dWJOYW1lCnI9Yi5sZW5ndGgKcT1hW3Nd
+CnA9Yj09bnVsbD9xPT1udWxsOmI9PT1xCm89IXB8fHI+PTI4CmlmKG8pcmV0dXJuIEguWjQociwhcCxz
+LGIpCmlmKHI9PT0xKXtwPSJyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4iK0guRWoobSkrIi4i
+K0guRWoocykrIih0aGlzLiIrbCsiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVy
+biBvLmgoKQokLnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9bj0iYWJjZGVmZ2hp
+amtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxyLTEpLmpvaW4oIiwiKQpwPSJyZXR1
+cm4gZnVuY3Rpb24oIituKyIpe3JldHVybiB0aGlzLiIrSC5FaihtKSsiLiIrSC5FaihzKSsiKHRoaXMu
+IitsKyIsICIrbisiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLmgoKQok
+LnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9LApLcTpmdW5jdGlvbihhLGIsYyxk
+LGUsZixnKXtyZXR1cm4gSC5pQShhLGIsYyxkLCEhZSwhIWYsZyl9LApUbjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgueihhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnooYS5jKSxiKX0sCkRWOmZ1bmN0aW9uKGEpe3JldHVybiBh
+LmF9LAp5UzpmdW5jdGlvbihhKXtyZXR1cm4gYS5jfSwKb046ZnVuY3Rpb24oKXt2YXIgcz0kLm1KCnJl
+dHVybiBzPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnN9LApFMjpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
+cD1uZXcgSC5yVCgic2VsZiIsInRhcmdldCIsInJlY2VpdmVyIiwibmFtZSIpLG89Si5FcChPYmplY3Qu
+Z2V0T3duUHJvcGVydHlOYW1lcyhwKSx0LlcpCmZvcihzPW8ubGVuZ3RoLHI9MDtyPHM7KytyKXtxPW9b
+cl0KaWYocFtxXT09PWEpcmV0dXJuIHF9dGhyb3cgSC5iKFAueFkoIkZpZWxkIG5hbWUgIithKyIgbm90
+IGZvdW5kLiIpKX0sCm9UOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBleHByZXNz
+aW9uIG11c3Qgbm90IGJlIG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93IEguYihu
+ZXcgSC5rWShhKSl9LAphZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApZZzpmdW5j
+dGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKQm86ZnVuY3Rpb24oYSl7cmV0dXJuIEgu
+dihuZXcgSC5uKGEpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxi
 LHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0p
 fSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuPUguaCgkLk5GLiQxKGEpKSxtPSQubndbbl0K
 aWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
@@ -8067,2258 +8089,2291 @@
 IGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBuCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBw
 YXR0ZXJuICgiK1N0cmluZyhuKSsiKSIsYSxudWxsKSl9LApTUTpmdW5jdGlvbihhLGIsYyl7dmFyIHMK
 aWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5z
-dGFuY2VvZiBILlZSKXtzPUMueEIuRyhhLGMpCnJldHVybiBiLmIudGVzdChzKX1lbHNle3M9Si5GTChi
-LEMueEIuRyhhLGMpKQpyZXR1cm4hcy5nbDAocyl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9m
-KCIkIiwwKT49MClyZXR1cm4gYS5yZXBsYWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5j
-dGlvbihhKXtpZigvW1tcXXt9KCkqKz8uXFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tb
-XF17fSgpKis/LlxcXiR8XS9nLCJcXCQmIikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFy
-IHM9SC5uTShhLGIsYykKcmV0dXJuIHN9LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAKaWYo
-Yj09PSIiKXtpZihhPT09IiIpcmV0dXJuIGMKcz1hLmxlbmd0aApmb3Iocj1jLHE9MDtxPHM7KytxKXI9
-cithW3FdK2MKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9cD1hLmluZGV4T2YoYiwwKQppZihw
-PDApcmV0dXJuIGEKaWYoYS5sZW5ndGg8NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNw
-bGl0KGIpLmpvaW4oYykKcmV0dXJuIGEucmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0
-KGMpKX0sClBEOmZ1bmN0aW9uIFBEKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9u
-IFdVKCl7fSwKTFA6ZnVuY3Rpb24gTFAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
-YwpfLiR0aT1kfSwKWFI6ZnVuY3Rpb24gWFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVu
-Y3Rpb24gTEkoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1l
-fSwKQ2o6ZnVuY3Rpb24gQ2ooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVu
-Y3Rpb24gZjkoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5l
-PWUKXy5mPWZ9LApXMDpmdW5jdGlvbiBXMChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rp
-b24gYXooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7
-dGhpcy5hPWF9LAp0ZTpmdW5jdGlvbiB0ZShhKXt0aGlzLmE9YX0sCmJxOmZ1bmN0aW9uIGJxKGEsYil7
-dGhpcy5hPWEKdGhpcy5iPWJ9LApYTzpmdW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0s
-ClRwOmZ1bmN0aW9uIFRwKCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30s
-CnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
-LApFcTpmdW5jdGlvbiBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwK
-a3I6ZnVuY3Rpb24ga3IoKXt9LApONTpmdW5jdGlvbiBONShhKXt2YXIgXz10aGlzCl8uYT0wCl8uZj1f
-LmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKdmg6ZnVuY3Rpb24gdmgoYSxiKXt2YXIg
-Xz10aGlzCl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbH0sCmk1OmZ1bmN0aW9uIGk1KGEsYil7dGhpcy5h
-PWEKdGhpcy4kdGk9Yn0sCk42OmZ1bmN0aW9uIE42KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uZD1fLmM9bnVsbApfLiR0aT1jfSwKZEM6ZnVuY3Rpb24gZEMoYSl7dGhpcy5hPWF9LAp3TjpmdW5j
-dGlvbiB3TihhKXt0aGlzLmE9YX0sClZYOmZ1bmN0aW9uIFZYKGEpe3RoaXMuYT1hfSwKVlI6ZnVuY3Rp
-b24gVlIoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbH0sCkVLOmZ1bmN0aW9u
-IEVLKGEpe3RoaXMuYj1hfSwKS1c6ZnVuY3Rpb24gS1coYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRo
-aXMuYz1jfSwKUGI6ZnVuY3Rpb24gUGIoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMK
-Xy5kPW51bGx9LAp0UTpmdW5jdGlvbiB0UShhLGIpe3RoaXMuYT1hCnRoaXMuYz1ifSwKdW46ZnVuY3Rp
-b24gdW4oYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKU2Q6ZnVuY3Rpb24gU2QoYSxi
-LGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPW51bGx9LApYRjpmdW5jdGlvbihhKXty
-ZXR1cm4gYX0sCm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9PWF8fGE+PWMpdGhyb3cgSC5iKEgu
-SFkoYixhKSl9LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYoIShhPj4+MCE9PWEpKXM9Yj4+PjAh
-PT1ifHxhPmJ8fGI+YwplbHNlIHM9ITAKaWYocyl0aHJvdyBILmIoSC5hdShhLGIsYykpCnJldHVybiBi
-fSwKRVQ6ZnVuY3Rpb24gRVQoKXt9LApYSDpmdW5jdGlvbiBYSCgpe30sCkRnOmZ1bmN0aW9uIERnKCl7
-fSwKUGc6ZnVuY3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigpe30sCmRFOmZ1bmN0aW9uIGRFKCl7
-fSwKWkE6ZnVuY3Rpb24gWkEoKXt9LApkVDpmdW5jdGlvbiBkVCgpe30sClBxOmZ1bmN0aW9uIFBxKCl7
-fSwKZUU6ZnVuY3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigpe30sClJHOmZ1bmN0aW9uIFJHKCl7
-fSwKVlA6ZnVuY3Rpb24gVlAoKXt9LApXQjpmdW5jdGlvbiBXQigpe30sClpHOmZ1bmN0aW9uIFpHKCl7
-fSwKY3o6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5jPUguQihhLGIueiwh
-MCk6c30sCnhaOmZ1bmN0aW9uKGEsYil7dmFyIHM9Yi5jCnJldHVybiBzPT1udWxsP2IuYz1ILkooYSwi
-YjgiLFtiLnpdKTpzfSwKUTE6ZnVuY3Rpb24oYSl7dmFyIHM9YS55CmlmKHM9PT02fHxzPT09N3x8cz09
-PTgpcmV0dXJuIEguUTEoYS56KQpyZXR1cm4gcz09PTExfHxzPT09MTJ9LAptRDpmdW5jdGlvbihhKXty
-ZXR1cm4gYS5jeX0sCk4wOmZ1bmN0aW9uKGEpe3JldHVybiBILkUodi50eXBlVW5pdmVyc2UsYSwhMSl9
-LApQTDpmdW5jdGlvbihhLGIsYTAsYTEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxk
-LGM9Yi55CnN3aXRjaChjKXtjYXNlIDU6Y2FzZSAxOmNhc2UgMjpjYXNlIDM6Y2FzZSA0OnJldHVybiBi
-CmNhc2UgNjpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihyPT09cylyZXR1cm4gYgpyZXR1cm4gSC5D
-KGEsciwhMCkKY2FzZSA3OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJl
-dHVybiBILkIoYSxyLCEwKQpjYXNlIDg6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0
-dXJuIGIKcmV0dXJuIEguZihhLHIsITApCmNhc2UgOTpxPWIuUQpwPUguYlooYSxxLGEwLGExKQppZihw
-PT09cSlyZXR1cm4gYgpyZXR1cm4gSC5KKGEsYi56LHApCmNhc2UgMTA6bz1iLnoKbj1ILlBMKGEsbyxh
-MCxhMSkKbT1iLlEKbD1ILmJaKGEsbSxhMCxhMSkKaWYobj09PW8mJmw9PT1tKXJldHVybiBiCnJldHVy
-biBILmEoYSxuLGwpCmNhc2UgMTE6az1iLnoKaj1ILlBMKGEsayxhMCxhMSkKaT1iLlEKaD1ILnFUKGEs
-aSxhMCxhMSkKaWYoaj09PWsmJmg9PT1pKXJldHVybiBiCnJldHVybiBILmQoYSxqLGgpCmNhc2UgMTI6
-Zz1iLlEKYTErPWcubGVuZ3RoCmY9SC5iWihhLGcsYTAsYTEpCm89Yi56Cm49SC5QTChhLG8sYTAsYTEp
-CmlmKGY9PT1nJiZuPT09bylyZXR1cm4gYgpyZXR1cm4gSC5EKGEsbixmLCEwKQpjYXNlIDEzOmU9Yi56
-CmlmKGU8YTEpcmV0dXJuIGIKZD1hMFtlLWExXQppZihkPT1udWxsKXJldHVybiBiCnJldHVybiBkCmRl
-ZmF1bHQ6dGhyb3cgSC5iKFAuaFYoIkF0dGVtcHRlZCB0byBzdWJzdGl0dXRlIHVuZXhwZWN0ZWQgUlRJ
-IGtpbmQgIitjKSl9fSwKYlo6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbz1iLmxlbmd0aCxu
-PVtdCmZvcihzPSExLHI9MDtyPG87KytyKXtxPWJbcl0KcD1ILlBMKGEscSxjLGQpCmlmKHAhPT1xKXM9
-ITAKbi5wdXNoKHApfXJldHVybiBzP246Yn0sCnZPOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxw
-LG8sbixtPWIubGVuZ3RoLGw9W10KZm9yKHM9ITEscj0wO3I8bTtyKz0zKXtxPWJbcl0KcD1iW3IrMV0K
-bz1iW3IrMl0Kbj1ILlBMKGEsbyxjLGQpCmlmKG4hPT1vKXM9ITAKbC5wdXNoKHEpCmwucHVzaChwKQps
-LnB1c2gobil9cmV0dXJuIHM/bDpifSwKcVQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscj1iLmEscT1I
-LmJaKGEscixjLGQpLHA9Yi5iLG89SC5iWihhLHAsYyxkKSxuPWIuYyxtPUgudk8oYSxuLGMsZCkKaWYo
-cT09PXImJm89PT1wJiZtPT09bilyZXR1cm4gYgpzPW5ldyBILkcoKQpzLmE9cQpzLmI9bwpzLmM9bQpy
-ZXR1cm4gc30sClZNOmZ1bmN0aW9uKGEsYil7YVt2LmFycmF5UnRpXT1iCnJldHVybiBhfSwKSlM6ZnVu
-Y3Rpb24oYSl7dmFyIHM9YS4kUwppZihzIT1udWxsKXtpZih0eXBlb2Ygcz09Im51bWJlciIpcmV0dXJu
-IEguQnAocykKcmV0dXJuIGEuJFMoKX1yZXR1cm4gbnVsbH0sClVlOmZ1bmN0aW9uKGEsYil7dmFyIHMK
-aWYoSC5RMShiKSlpZihhIGluc3RhbmNlb2YgSC5UcCl7cz1ILkpTKGEpCmlmKHMhPW51bGwpcmV0dXJu
-IHN9cmV0dXJuIEgueihhKX0sCno6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoYSBpbnN0YW5jZW9mIFAuTWgp
-e3M9YS4kdGkKcmV0dXJuIHMhPW51bGw/czpILlZVKGEpfWlmKEFycmF5LmlzQXJyYXkoYSkpcmV0dXJu
-IEgudDYoYSkKcmV0dXJuIEguVlUoSi5pYShhKSl9LAp0NjpmdW5jdGlvbihhKXt2YXIgcz1hW3YuYXJy
-YXlSdGldLHI9dC54CmlmKHM9PW51bGwpcmV0dXJuIHIKaWYocy5jb25zdHJ1Y3RvciE9PXIuY29uc3Ry
-dWN0b3IpcmV0dXJuIHIKcmV0dXJuIHN9LApMaDpmdW5jdGlvbihhKXt2YXIgcz1hLiR0aQpyZXR1cm4g
-cyE9bnVsbD9zOkguVlUoYSl9LApWVTpmdW5jdGlvbihhKXt2YXIgcz1hLmNvbnN0cnVjdG9yLHI9cy4k
-Y2NhY2hlCmlmKHIhPW51bGwpcmV0dXJuIHIKcmV0dXJuIEgucjkoYSxzKX0sCnI5OmZ1bmN0aW9uKGEs
-Yil7dmFyIHM9YSBpbnN0YW5jZW9mIEguVHA/YS5fX3Byb3RvX18uX19wcm90b19fLmNvbnN0cnVjdG9y
-OmIscj1ILmFpKHYudHlwZVVuaXZlcnNlLHMubmFtZSkKYi4kY2NhY2hlPXIKcmV0dXJuIHJ9LApCcDpm
-dW5jdGlvbihhKXt2YXIgcyxyLHEKSC51UChhKQpzPXYudHlwZXMKcj1zW2FdCmlmKHR5cGVvZiByPT0i
-c3RyaW5nIil7cT1ILkUodi50eXBlVW5pdmVyc2UsciwhMSkKc1thXT1xCnJldHVybiBxfXJldHVybiBy
-fSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXApcmV0dXJuIEguUkUo
-cSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNlIHA9ITAKZWxzZSBw
-PSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56OnEKaWYocz09PXQu
-UylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2UgaWYocz09PXQuTily
-PUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4gSC5SRShxLGEscikK
-aWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitwCnJldHVybiBILlJF
-KHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkKcmV0dXJuIEguUkUo
-cSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIoYil9LApBdTpmdW5j
-dGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8pKXM9cT09PXQuSwpl
-bHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSylyPUguVGkKZWxzZSBy
-PUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55CmlmKCFI
-LkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1yPT09OCYmSC5Raihh
-LnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0h
-MApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5R
-aihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxzLG51bGwpfSwKQVE6
-ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIoYSl9LAp0NDpmdW5j
-dGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpzPXIucgppZihhIGlu
-c3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVuY3Rpb24o
-YSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVybiBhCkgu
-bTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gYQplbHNl
-IGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIpe3Rocm93IEguYihI
-LlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMsZCl7
-dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVybiBhCnRocm93IEgu
-YihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicgaXMgbm90IGEgc3Vi
-dHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixzKSkrIicgb2YgdHlw
-ZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwKV0s6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciBzPVAuaGwoYSkscj1ILmRtKGI9PW51bGw/SC56KGEpOmIsbnVsbCkKcmV0dXJuIHMr
-IjogdHlwZSAnIitILkVqKHIpKyInIGlzIG5vdCBhIHN1YnR5cGUgb2YgdHlwZSAnIitILkVqKGMpKyIn
-In0sClpjOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK2EpfSwKcTpmdW5j
-dGlvbihhLGIpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK0guV0soYSxudWxsLGIpKX0sCmtl
-OmZ1bmN0aW9uKGEpe3JldHVybiBhIT1udWxsfSwKVGk6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApJdzpm
-dW5jdGlvbihhKXtyZXR1cm4hMH0sCmhuOmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKbDpmdW5jdGlvbihh
-KXtyZXR1cm4hMD09PWF8fCExPT09YX0sCnA4OmZ1bmN0aW9uKGEpe2lmKCEwPT09YSlyZXR1cm4hMApp
-ZighMT09PWEpcmV0dXJuITEKdGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKeTg6ZnVuY3Rpb24oYSl7
-aWYoITA9PT1hKXJldHVybiEwCmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRo
-cm93IEguYihILnEoYSwiYm9vbCIpKX0sCmRwOmZ1bmN0aW9uKGEpe2lmKCEwPT09YSlyZXR1cm4hMApp
-ZighMT09PWEpcmV0dXJuITEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImJvb2w/
-IikpfSwKRkc6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEgu
-YihILnEoYSwiZG91YmxlIikpfSwKR0g6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJl
-dHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApRazpm
-dW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4g
-YQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZT8iKSl9LApvazpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9m
-IGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YX0sCklaOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
-PT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJpbnQi
-KSl9LAp1UDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1h
-KXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJpbnQiKSl9LApVYzpm
-dW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBh
-CmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJpbnQ/IikpfSwKS0g6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIn0sCno1OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0i
-bnVtYmVyIilyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bSIpKX0sClcxOmZ1bmN0aW9uKGEpe2lm
-KHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihI
-LnEoYSwibnVtIikpfSwKY1U6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBh
-CmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJudW0/IikpfSwKTU06ZnVuY3Rpb24o
-YSl7cmV0dXJuIHR5cGVvZiBhPT0ic3RyaW5nIn0sCkJ0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0i
-c3RyaW5nIilyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIlN0cmluZyIpKX0sCmg6ZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5i
-KEgucShhLCJTdHJpbmciKSl9LAprOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1
-cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nPyIpKX0sCmlvOmZ1
-bmN0aW9uKGEsYil7dmFyIHMscixxCmZvcihzPSIiLHI9IiIscT0wO3E8YS5sZW5ndGg7KytxLHI9Iiwg
-IilzKz1DLnhCLmgocixILmRtKGFbcV0sYikpCnJldHVybiBzfSwKYkk6ZnVuY3Rpb24oYTUsYTYsYTcp
-e3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYixhLGEwLGExLGEyLGEzLGE0PSIs
-ICIKaWYoYTchPW51bGwpe3M9YTcubGVuZ3RoCmlmKGE2PT1udWxsKXthNj1ILlZNKFtdLHQucykKcj1u
-dWxsfWVsc2Ugcj1hNi5sZW5ndGgKcT1hNi5sZW5ndGgKZm9yKHA9cztwPjA7LS1wKUMuTm0uaShhNiwi
-VCIrKHErcCkpCmZvcihvPXQuUixuPXQuXyxtPXQuSyxsPSI8IixrPSIiLHA9MDtwPHM7KytwLGs9YTQp
-e2wrPWsKaj1hNi5sZW5ndGgKaT1qLTEtcAppZihpPDApcmV0dXJuIEguT0goYTYsaSkKbD1DLnhCLmgo
-bCxhNltpXSkKaD1hN1twXQpnPWgueQppZighKGc9PT0yfHxnPT09M3x8Zz09PTR8fGc9PT01fHxoPT09
-bykpaWYoIShoPT09bikpaj1oPT09bQplbHNlIGo9ITAKZWxzZSBqPSEwCmlmKCFqKWwrPUMueEIuaCgi
-IGV4dGVuZHMgIixILmRtKGgsYTYpKX1sKz0iPiJ9ZWxzZXtsPSIiCnI9bnVsbH1vPWE1LnoKZj1hNS5R
-CmU9Zi5hCmQ9ZS5sZW5ndGgKYz1mLmIKYj1jLmxlbmd0aAphPWYuYwphMD1hLmxlbmd0aAphMT1ILmRt
-KG8sYTYpCmZvcihhMj0iIixhMz0iIixwPTA7cDxkOysrcCxhMz1hNClhMis9Qy54Qi5oKGEzLEguZG0o
-ZVtwXSxhNikpCmlmKGI+MCl7YTIrPWEzKyJbIgpmb3IoYTM9IiIscD0wO3A8YjsrK3AsYTM9YTQpYTIr
-PUMueEIuaChhMyxILmRtKGNbcF0sYTYpKQphMis9Il0ifWlmKGEwPjApe2EyKz1hMysieyIKZm9yKGEz
-PSIiLHA9MDtwPGEwO3ArPTMsYTM9YTQpe2EyKz1hMwppZihhW3ArMV0pYTIrPSJyZXF1aXJlZCAiCmEy
-Kz1KLmJiKEguZG0oYVtwKzJdLGE2KSwiICIpK2FbcF19YTIrPSJ9In1pZihyIT1udWxsKXthNi50b1N0
-cmluZwphNi5sZW5ndGg9cn1yZXR1cm4gbCsiKCIrYTIrIikgPT4gIitILkVqKGExKX0sCmRtOmZ1bmN0
-aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbD1hLnkKaWYobD09PTUpcmV0dXJuImVyYXNlZCIKaWYo
-bD09PTIpcmV0dXJuImR5bmFtaWMiCmlmKGw9PT0zKXJldHVybiJ2b2lkIgppZihsPT09MSlyZXR1cm4i
-TmV2ZXIiCmlmKGw9PT00KXJldHVybiJhbnkiCmlmKGw9PT02KXtzPUguZG0oYS56LGIpCnJldHVybiBz
-fWlmKGw9PT03KXtyPWEuegpzPUguZG0ocixiKQpxPXIueQpyZXR1cm4gSi5iYihxPT09MTF8fHE9PT0x
-Mj9DLnhCLmgoIigiLHMpKyIpIjpzLCI/Iil9aWYobD09PTgpcmV0dXJuIkZ1dHVyZU9yPCIrSC5FaihI
-LmRtKGEueixiKSkrIj4iCmlmKGw9PT05KXtwPUgubzMoYS56KQpvPWEuUQpyZXR1cm4gby5sZW5ndGgh
-PT0wP3ArKCI8IitILmlvKG8sYikrIj4iKTpwfWlmKGw9PT0xMSlyZXR1cm4gSC5iSShhLGIsbnVsbCkK
-aWYobD09PTEyKXJldHVybiBILmJJKGEueixiLGEuUSkKaWYobD09PTEzKXtiLnRvU3RyaW5nCm49YS56
-Cm09Yi5sZW5ndGgKbj1tLTEtbgppZihuPDB8fG4+PW0pcmV0dXJuIEguT0goYixuKQpyZXR1cm4gYltu
-XX1yZXR1cm4iPyJ9LApvMzpmdW5jdGlvbihhKXt2YXIgcyxyPUguSmcoYSkKaWYociE9bnVsbClyZXR1
-cm4gcgpzPSJtaW5pZmllZDoiK2EKcmV0dXJuIHN9LApRbzpmdW5jdGlvbihhLGIpe3ZhciBzPWEudFJb
-Yl0KZm9yKDt0eXBlb2Ygcz09InN0cmluZyI7KXM9YS50UltzXQpyZXR1cm4gc30sCmFpOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscixxLHAsbyxuPWEuZVQsbT1uW2JdCmlmKG09PW51bGwpcmV0dXJuIEguRShhLGIs
-ITEpCmVsc2UgaWYodHlwZW9mIG09PSJudW1iZXIiKXtzPW0Kcj1ILm0oYSw1LCIjIikKcT1bXQpmb3Io
-cD0wO3A8czsrK3ApcS5wdXNoKHIpCm89SC5KKGEsYixxKQpuW2JdPW8KcmV0dXJuIG99ZWxzZSByZXR1
-cm4gbX0sCnhiOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguSXgoYS50UixiKX0sCkZGOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIEguSXgoYS5lVCxiKX0sCkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9YS5lQyxxPXIu
-Z2V0KGIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmkoSC5vKGEsbnVsbCxiLGMpKQpyLnNldChiLHMp
-CnJldHVybiBzfSwKY0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscT1iLmNoCmlmKHE9PW51bGwpcT1i
-LmNoPW5ldyBNYXAoKQpzPXEuZ2V0KGMpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmkoSC5vKGEsYixj
-LCEwKSkKcS5zZXQoYyxyKQpyZXR1cm4gcn0sCnY1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1i
-LmN4CmlmKHA9PW51bGwpcD1iLmN4PW5ldyBNYXAoKQpzPWMuY3kKcj1wLmdldChzKQppZihyIT1udWxs
-KXJldHVybiByCnE9SC5hKGEsYixjLnk9PT0xMD9jLlE6W2NdKQpwLnNldChzLHEpCnJldHVybiBxfSwK
-QkQ6ZnVuY3Rpb24oYSxiKXtiLmE9SC5BdQpiLmI9SC5KSgpyZXR1cm4gYn0sCm06ZnVuY3Rpb24oYSxi
-LGMpe3ZhciBzLHIscT1hLmVDLmdldChjKQppZihxIT1udWxsKXJldHVybiBxCnM9bmV3IEguSmMobnVs
-bCxudWxsKQpzLnk9YgpzLmN5PWMKcj1ILkJEKGEscykKYS5lQy5zZXQoYyxyKQpyZXR1cm4gcn0sCkM6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9Yi5jeSsiKiIscT1hLmVDLmdldChyKQppZihxIT1udWxsKXJl
-dHVybiBxCnM9SC5aNyhhLGIscixjKQphLmVDLnNldChyLHMpCnJldHVybiBzfSwKWjc6ZnVuY3Rpb24o
-YSxiLGMsZCl7dmFyIHMscixxCmlmKGQpe3M9Yi55CmlmKCFILkE4KGIpKXI9Yj09PXQuUHx8Yj09PXQu
-VHx8cz09PTd8fHM9PT02CmVsc2Ugcj0hMAppZihyKXJldHVybiBifXE9bmV3IEguSmMobnVsbCxudWxs
-KQpxLnk9NgpxLno9YgpxLmN5PWMKcmV0dXJuIEguQkQoYSxxKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzLHI9Yi5jeSsiPyIscT1hLmVDLmdldChyKQppZihxIT1udWxsKXJldHVybiBxCnM9SC5sbChhLGIs
-cixjKQphLmVDLnNldChyLHMpCnJldHVybiBzfSwKbGw6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
-LHAKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5QfHxiPT09dC5UKSlpZihzIT09Nyly
-PXM9PT04JiZILmxSKGIueikKZWxzZSByPSEwCmVsc2Ugcj0hMAplbHNlIHI9ITAKaWYocilyZXR1cm4g
-YgplbHNlIGlmKHM9PT0xfHxiPT09dC5jRilyZXR1cm4gdC5QCmVsc2UgaWYocz09PTYpe3E9Yi56Cmlm
-KHEueT09PTgmJkgubFIocS56KSlyZXR1cm4gcQplbHNlIHJldHVybiBILmN6KGEsYil9fXA9bmV3IEgu
-SmMobnVsbCxudWxsKQpwLnk9NwpwLno9YgpwLmN5PWMKcmV0dXJuIEguQkQoYSxwKX0sCmY6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzLHI9Yi5jeSsiLyIscT1hLmVDLmdldChyKQppZihxIT1udWxsKXJldHVybiBx
-CnM9SC5lVihhLGIscixjKQphLmVDLnNldChyLHMpCnJldHVybiBzfSwKZVY6ZnVuY3Rpb24oYSxiLGMs
-ZCl7dmFyIHMscixxCmlmKGQpe3M9Yi55CmlmKCFILkE4KGIpKWlmKCEoYj09PXQuXykpcj1iPT09dC5L
-CmVsc2Ugcj0hMAplbHNlIHI9ITAKaWYocnx8Yj09PXQuSylyZXR1cm4gYgplbHNlIGlmKHM9PT0xKXJl
-dHVybiBILkooYSwiYjgiLFtiXSkKZWxzZSBpZihiPT09dC5QfHxiPT09dC5UKXJldHVybiB0LmJHfXE9
-bmV3IEguSmMobnVsbCxudWxsKQpxLnk9OApxLno9YgpxLmN5PWMKcmV0dXJuIEguQkQoYSxxKX0sCkg6
-ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9IiIrYisiXiIscD1hLmVDLmdldChxKQppZihwIT1udWxsKXJl
-dHVybiBwCnM9bmV3IEguSmMobnVsbCxudWxsKQpzLnk9MTMKcy56PWIKcy5jeT1xCnI9SC5CRChhLHMp
-CmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApVeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLmxlbmd0
-aApmb3Iocz0iIixyPSIiLHE9MDtxPHA7KytxLHI9IiwiKXMrPXIrYVtxXS5jeQpyZXR1cm4gc30sClM0
-OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtPWEubGVuZ3RoCmZvcihzPSIiLHI9IiIscT0wO3E8
-bTtxKz0zLHI9IiwiKXtwPWFbcV0Kbz1hW3ErMV0/IiEiOiI6IgpuPWFbcSsyXS5jeQpzKz1yK3Arbytu
-fXJldHVybiBzfSwKSjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHA9YgppZihjLmxlbmd0aCE9PTAp
-cCs9IjwiK0guVXgoYykrIj4iCnM9YS5lQy5nZXQocCkKaWYocyE9bnVsbClyZXR1cm4gcwpyPW5ldyBI
-LkpjKG51bGwsbnVsbCkKci55PTkKci56PWIKci5RPWMKaWYoYy5sZW5ndGg+MClyLmM9Y1swXQpyLmN5
-PXAKcT1ILkJEKGEscikKYS5lQy5zZXQocCxxKQpyZXR1cm4gcX0sCmE6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzLHIscSxwLG8sbgppZihiLnk9PT0xMCl7cz1iLnoKcj1iLlEuY29uY2F0KGMpfWVsc2V7cj1jCnM9
-Yn1xPXMuY3krKCI7PCIrSC5VeChyKSsiPiIpCnA9YS5lQy5nZXQocSkKaWYocCE9bnVsbClyZXR1cm4g
-cApvPW5ldyBILkpjKG51bGwsbnVsbCkKby55PTEwCm8uej1zCm8uUT1yCm8uY3k9cQpuPUguQkQoYSxv
-KQphLmVDLnNldChxLG4pCnJldHVybiBufSwKZDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxu
-PWIuY3ksbT1jLmEsbD1tLmxlbmd0aCxrPWMuYixqPWsubGVuZ3RoLGk9Yy5jLGg9aS5sZW5ndGgsZz0i
-KCIrSC5VeChtKQppZihqPjApe3M9bD4wPyIsIjoiIgpyPUguVXgoaykKZys9cysiWyIrcisiXSJ9aWYo
-aD4wKXtzPWw+MD8iLCI6IiIKcj1ILlM0KGkpCmcrPXMrInsiK3IrIn0ifXE9bisoZysiKSIpCnA9YS5l
-Qy5nZXQocSkKaWYocCE9bnVsbClyZXR1cm4gcApvPW5ldyBILkpjKG51bGwsbnVsbCkKby55PTExCm8u
-ej1iCm8uUT1jCm8uY3k9cQpyPUguQkQoYSxvKQphLmVDLnNldChxLHIpCnJldHVybiByfSwKRDpmdW5j
-dGlvbihhLGIsYyxkKXt2YXIgcyxyPWIuY3krKCI8IitILlV4KGMpKyI+IikscT1hLmVDLmdldChyKQpp
-ZihxIT1udWxsKXJldHVybiBxCnM9SC5odyhhLGIsYyxyLGQpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9
-LApodzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxwLG8sbixtLGwKaWYoZSl7cz1jLmxlbmd0
-aApyPW5ldyBBcnJheShzKQpmb3IocT0wLHA9MDtwPHM7KytwKXtvPWNbcF0KaWYoby55PT09MSl7cltw
-XT1vOysrcX19aWYocT4wKXtuPUguUEwoYSxiLHIsMCkKbT1ILmJaKGEsYyxyLDApCnJldHVybiBILkQo
-YSxuLG0sYyE9PW0pfX1sPW5ldyBILkpjKG51bGwsbnVsbCkKbC55PTEyCmwuej1iCmwuUT1jCmwuY3k9
-ZApyZXR1cm4gSC5CRChhLGwpfSwKbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57dTphLGU6YixyOmMs
-czpbXSxwOjAsbjpkfX0sCmk6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9
-YS5yLGY9YS5zCmZvcihzPWcubGVuZ3RoLHI9MDtyPHM7KXtxPWcuY2hhckNvZGVBdChyKQppZihxPj00
-OCYmcTw9NTcpcj1ILkEocisxLHEsZyxmKQplbHNlIGlmKCgoKHF8MzIpPj4+MCktOTcmNjU1MzUpPDI2
-fHxxPT09OTV8fHE9PT0zNilyPUgudChhLHIsZyxmLCExKQplbHNlIGlmKHE9PT00NilyPUgudChhLHIs
-ZyxmLCEwKQplbHNleysrcgpzd2l0Y2gocSl7Y2FzZSA0NDpicmVhawpjYXNlIDU4OmYucHVzaCghMSkK
-YnJlYWsKY2FzZSAzMzpmLnB1c2goITApCmJyZWFrCmNhc2UgNTk6Zi5wdXNoKEguSyhhLnUsYS5lLGYu
-cG9wKCkpKQpicmVhawpjYXNlIDk0OmYucHVzaChILkgoYS51LGYucG9wKCkpKQpicmVhawpjYXNlIDM1
-OmYucHVzaChILm0oYS51LDUsIiMiKSkKYnJlYWsKY2FzZSA2NDpmLnB1c2goSC5tKGEudSwyLCJAIikp
-CmJyZWFrCmNhc2UgMTI2OmYucHVzaChILm0oYS51LDMsIn4iKSkKYnJlYWsKY2FzZSA2MDpmLnB1c2go
-YS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2FzZSA2MjpwPWEudQpvPWYuc3BsaWNlKGEucCkKSC5yKGEu
-dSxhLmUsbykKYS5wPWYucG9wKCkKbj1mLnBvcCgpCmlmKHR5cGVvZiBuPT0ic3RyaW5nIilmLnB1c2go
-SC5KKHAsbixvKSkKZWxzZXttPUguSyhwLGEuZSxuKQpzd2l0Y2gobS55KXtjYXNlIDExOmYucHVzaChI
-LkQocCxtLG8sYS5uKSkKYnJlYWsKZGVmYXVsdDpmLnB1c2goSC5hKHAsbSxvKSkKYnJlYWt9fWJyZWFr
-CmNhc2UgMzg6SC5JKGEsZikKYnJlYWsKY2FzZSA0MjpsPWEudQpmLnB1c2goSC5DKGwsSC5LKGwsYS5l
-LGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNjM6bD1hLnUKZi5wdXNoKEguQihsLEguSyhsLGEuZSxm
-LnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQ3Omw9YS51CmYucHVzaChILmYobCxILksobCxhLmUsZi5w
-b3AoKSksYS5uKSkKYnJlYWsKY2FzZSA0MDpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2Fz
-ZSA0MTpwPWEudQprPW5ldyBILkcoKQpqPXAuc0VBCmk9cC5zRUEKbj1mLnBvcCgpCmlmKHR5cGVvZiBu
-PT0ibnVtYmVyIilzd2l0Y2gobil7Y2FzZS0xOmo9Zi5wb3AoKQpicmVhawpjYXNlLTI6aT1mLnBvcCgp
-CmJyZWFrCmRlZmF1bHQ6Zi5wdXNoKG4pCmJyZWFrfWVsc2UgZi5wdXNoKG4pCm89Zi5zcGxpY2UoYS5w
-KQpILnIoYS51LGEuZSxvKQphLnA9Zi5wb3AoKQprLmE9bwprLmI9agprLmM9aQpmLnB1c2goSC5kKHAs
-SC5LKHAsYS5lLGYucG9wKCkpLGspKQpicmVhawpjYXNlIDkxOmYucHVzaChhLnApCmEucD1mLmxlbmd0
-aApicmVhawpjYXNlIDkzOm89Zi5zcGxpY2UoYS5wKQpILnIoYS51LGEuZSxvKQphLnA9Zi5wb3AoKQpm
-LnB1c2gobykKZi5wdXNoKC0xKQpicmVhawpjYXNlIDEyMzpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgK
-YnJlYWsKY2FzZSAxMjU6bz1mLnNwbGljZShhLnApCkgueShhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmYu
-cHVzaChvKQpmLnB1c2goLTIpCmJyZWFrCmRlZmF1bHQ6dGhyb3ciQmFkIGNoYXJhY3RlciAiK3F9fX1o
-PWYucG9wKCkKcmV0dXJuIEguSyhhLnUsYS5lLGgpfSwKQTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-LHE9Yi00OApmb3Iocz1jLmxlbmd0aDthPHM7KythKXtyPWMuY2hhckNvZGVBdChhKQppZighKHI+PTQ4
-JiZyPD01NykpYnJlYWsKcT1xKjEwKyhyLTQ4KX1kLnB1c2gocSkKcmV0dXJuIGF9LAp0OmZ1bmN0aW9u
-KGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG09YisxCmZvcihzPWMubGVuZ3RoO208czsrK20pe3I9
-Yy5jaGFyQ29kZUF0KG0pCmlmKHI9PT00Nil7aWYoZSlicmVhawplPSEwfWVsc2V7aWYoISgoKChyfDMy
-KT4+PjApLTk3JjY1NTM1KTwyNnx8cj09PTk1fHxyPT09MzYpKXE9cj49NDgmJnI8PTU3CmVsc2UgcT0h
-MAppZighcSlicmVha319cD1jLnN1YnN0cmluZyhiLG0pCmlmKGUpe3M9YS51Cm89YS5lCmlmKG8ueT09
-PTEwKW89by56Cm49SC5RbyhzLG8ueilbcF0KaWYobj09bnVsbClILnYoJ05vICInK3ArJyIgaW4gIicr
-SC5tRChvKSsnIicpCmQucHVzaChILmNFKHMsbyxuKSl9ZWxzZSBkLnB1c2gocCkKcmV0dXJuIG19LApJ
-OmZ1bmN0aW9uKGEsYil7dmFyIHM9Yi5wb3AoKQppZigwPT09cyl7Yi5wdXNoKEgubShhLnUsMSwiMCYi
-KSkKcmV0dXJufWlmKDE9PT1zKXtiLnB1c2goSC5tKGEudSw0LCIxJiIpKQpyZXR1cm59dGhyb3cgSC5i
-KFAuaFYoIlVuZXhwZWN0ZWQgZXh0ZW5kZWQgb3BlcmF0aW9uICIrSC5FaihzKSkpfSwKSzpmdW5jdGlv
-bihhLGIsYyl7aWYodHlwZW9mIGM9PSJzdHJpbmciKXJldHVybiBILkooYSxjLGEuc0VBKQplbHNlIGlm
-KHR5cGVvZiBjPT0ibnVtYmVyIilyZXR1cm4gSC5UVihhLGIsYykKZWxzZSByZXR1cm4gY30sCnI6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciBzLHI9Yy5sZW5ndGgKZm9yKHM9MDtzPHI7KytzKWNbc109SC5LKGEsYixj
-W3NdKX0sCnk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9Yy5sZW5ndGgKZm9yKHM9MjtzPHI7cys9Mylj
-W3NdPUguSyhhLGIsY1tzXSl9LApUVjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIueQppZihxPT09
-MTApe2lmKGM9PT0wKXJldHVybiBiLnoKcz1iLlEKcj1zLmxlbmd0aAppZihjPD1yKXJldHVybiBzW2Mt
-MV0KYy09cgpiPWIuegpxPWIueX1lbHNlIGlmKGM9PT0wKXJldHVybiBiCmlmKHEhPT05KXRocm93IEgu
-YihQLmhWKCJJbmRleGVkIGJhc2UgbXVzdCBiZSBhbiBpbnRlcmZhY2UgdHlwZSIpKQpzPWIuUQppZihj
-PD1zLmxlbmd0aClyZXR1cm4gc1tjLTFdCnRocm93IEguYihQLmhWKCJCYWQgaW5kZXggIitjKyIgZm9y
-ICIrYi53KDApKSl9LApXZTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxwLG8sbixtLGwsayxq
-CmlmKGI9PT1kKXJldHVybiEwCmlmKCFILkE4KGQpKWlmKCEoZD09PXQuXykpcz1kPT09dC5LCmVsc2Ug
-cz0hMAplbHNlIHM9ITAKaWYocylyZXR1cm4hMApyPWIueQppZihyPT09NClyZXR1cm4hMAppZihILkE4
-KGIpKXJldHVybiExCmlmKGIueSE9PTEpcz1iPT09dC5QfHxiPT09dC5UCmVsc2Ugcz0hMAppZihzKXJl
-dHVybiEwCnE9cj09PTEzCmlmKHEpaWYoSC5XZShhLGNbYi56XSxjLGQsZSkpcmV0dXJuITAKcD1kLnkK
-aWYocj09PTYpcmV0dXJuIEguV2UoYSxiLnosYyxkLGUpCmlmKHA9PT02KXtzPWQuegpyZXR1cm4gSC5X
-ZShhLGIsYyxzLGUpfWlmKHI9PT04KXtpZighSC5XZShhLGIueixjLGQsZSkpcmV0dXJuITEKcmV0dXJu
-IEguV2UoYSxILnhaKGEsYiksYyxkLGUpfWlmKHI9PT03KXtzPUguV2UoYSxiLnosYyxkLGUpCnJldHVy
-biBzfWlmKHA9PT04KXtpZihILldlKGEsYixjLGQueixlKSlyZXR1cm4hMApyZXR1cm4gSC5XZShhLGIs
-YyxILnhaKGEsZCksZSl9aWYocD09PTcpe3M9SC5XZShhLGIsYyxkLnosZSkKcmV0dXJuIHN9aWYocSly
-ZXR1cm4hMQpzPXIhPT0xMQppZigoIXN8fHI9PT0xMikmJmQ9PT10LlkpcmV0dXJuITAKaWYocD09PTEy
-KXtpZihiPT09dC5EKXJldHVybiEwCmlmKHIhPT0xMilyZXR1cm4hMQpvPWIuUQpuPWQuUQptPW8ubGVu
-Z3RoCmlmKG0hPT1uLmxlbmd0aClyZXR1cm4hMQpjPWM9PW51bGw/bzpvLmNvbmNhdChjKQplPWU9PW51
-bGw/bjpuLmNvbmNhdChlKQpmb3IobD0wO2w8bTsrK2wpe2s9b1tsXQpqPW5bbF0KaWYoIUguV2UoYSxr
-LGMsaixlKXx8IUguV2UoYSxqLGUsayxjKSlyZXR1cm4hMX1yZXR1cm4gSC5iTyhhLGIueixjLGQueixl
-KX1pZihwPT09MTEpe2lmKGI9PT10LkQpcmV0dXJuITAKaWYocylyZXR1cm4hMQpyZXR1cm4gSC5iTyhh
-LGIsYyxkLGUpfWlmKHI9PT05KXtpZihwIT09OSlyZXR1cm4hMQpyZXR1cm4gSC5wRyhhLGIsYyxkLGUp
-fXJldHVybiExfSwKYk86ZnVuY3Rpb24oYTIsYTMsYTQsYTUsYTYpe3ZhciBzLHIscSxwLG8sbixtLGws
-ayxqLGksaCxnLGYsZSxkLGMsYixhLGEwLGExCmlmKCFILldlKGEyLGEzLnosYTQsYTUueixhNikpcmV0
-dXJuITEKcz1hMy5RCnI9YTUuUQpxPXMuYQpwPXIuYQpvPXEubGVuZ3RoCm49cC5sZW5ndGgKaWYobz5u
-KXJldHVybiExCm09bi1vCmw9cy5iCms9ci5iCmo9bC5sZW5ndGgKaT1rLmxlbmd0aAppZihvK2o8bitp
-KXJldHVybiExCmZvcihoPTA7aDxvOysraCl7Zz1xW2hdCmlmKCFILldlKGEyLHBbaF0sYTYsZyxhNCkp
-cmV0dXJuITF9Zm9yKGg9MDtoPG07KytoKXtnPWxbaF0KaWYoIUguV2UoYTIscFtvK2hdLGE2LGcsYTQp
-KXJldHVybiExfWZvcihoPTA7aDxpOysraCl7Zz1sW20raF0KaWYoIUguV2UoYTIsa1toXSxhNixnLGE0
-KSlyZXR1cm4hMX1mPXMuYwplPXIuYwpkPWYubGVuZ3RoCmM9ZS5sZW5ndGgKZm9yKGI9MCxhPTA7YTxj
-O2ErPTMpe2EwPWVbYV0KZm9yKDshMDspe2lmKGI+PWQpcmV0dXJuITEKYTE9ZltiXQpiKz0zCmlmKGEw
-PGExKXJldHVybiExCmlmKGExPGEwKWNvbnRpbnVlCmc9ZltiLTFdCmlmKCFILldlKGEyLGVbYSsyXSxh
-NixnLGE0KSlyZXR1cm4hMQpicmVha319cmV0dXJuITB9LApwRzpmdW5jdGlvbihhLGIsYyxkLGUpe3Zh
-ciBzLHIscSxwLG8sbixtLGwsaz1iLnosaj1kLnoKaWYoaz09PWope3M9Yi5RCnI9ZC5RCnE9cy5sZW5n
-dGgKZm9yKHA9MDtwPHE7KytwKXtvPXNbcF0Kbj1yW3BdCmlmKCFILldlKGEsbyxjLG4sZSkpcmV0dXJu
-ITF9cmV0dXJuITB9aWYoZD09PXQuSylyZXR1cm4hMAptPUguUW8oYSxrKQppZihtPT1udWxsKXJldHVy
-biExCmw9bVtqXQppZihsPT1udWxsKXJldHVybiExCnE9bC5sZW5ndGgKcj1kLlEKZm9yKHA9MDtwPHE7
-KytwKWlmKCFILldlKGEsSC5jRShhLGIsbFtwXSksYyxyW3BdLGUpKXJldHVybiExCnJldHVybiEwfSwK
-bFI6ZnVuY3Rpb24oYSl7dmFyIHMscj1hLnkKaWYoIShhPT09dC5QfHxhPT09dC5UKSlpZighSC5BOChh
-KSlpZihyIT09NylpZighKHI9PT02JiZILmxSKGEueikpKXM9cj09PTgmJkgubFIoYS56KQplbHNlIHM9
-ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMAplbHNlIHM9ITAKcmV0dXJuIHN9LApjYzpmdW5jdGlvbihhKXt2
-YXIgcwppZighSC5BOChhKSlpZighKGE9PT10Ll8pKXM9YT09PXQuSwplbHNlIHM9ITAKZWxzZSBzPSEw
-CnJldHVybiBzfSwKQTg6ZnVuY3Rpb24oYSl7dmFyIHM9YS55CnJldHVybiBzPT09Mnx8cz09PTN8fHM9
-PT00fHxzPT09NXx8YT09PXQuUn0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPU9iamVjdC5rZXlz
-KGIpLHA9cS5sZW5ndGgKZm9yKHM9MDtzPHA7KytzKXtyPXFbc10KYVtyXT1iW3JdfX0sCkpjOmZ1bmN0
-aW9uIEpjKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLng9Xy5yPV8uYz1udWxsCl8ueT0wCl8u
-Y3k9Xy5jeD1fLmNoPV8uUT1fLno9bnVsbH0sCkc6ZnVuY3Rpb24gRygpe3RoaXMuYz10aGlzLmI9dGhp
-cy5hPW51bGx9LAprUzpmdW5jdGlvbiBrUygpe30sCmlNOmZ1bmN0aW9uIGlNKGEpe3RoaXMuYT1hfSwK
-Ujk6ZnVuY3Rpb24oYSl7cmV0dXJuIHQudy5iKGEpfHx0LkIuYihhKXx8dC5kei5iKGEpfHx0LkkuYihh
-KXx8dC5BLmIoYSl8fHQuZzQuYihhKXx8dC5nMi5iKGEpfSwKSmc6ZnVuY3Rpb24oYSl7cmV0dXJuIHYu
-bWFuZ2xlZEdsb2JhbE5hbWVzW2FdfX0sSj17ClF1OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybntpOmEs
-cDpiLGU6Yyx4OmR9fSwKa3M6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz1hW3YuZGlzcGF0Y2hQcm9w
-ZXJ0eU5hbWVdCmlmKG89PW51bGwpaWYoJC5Cdj09bnVsbCl7SC5YRCgpCm89YVt2LmRpc3BhdGNoUHJv
-cGVydHlOYW1lXX1pZihvIT1udWxsKXtzPW8ucAppZighMT09PXMpcmV0dXJuIG8uaQppZighMD09PXMp
-cmV0dXJuIGEKcj1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkKaWYocz09PXIpcmV0dXJuIG8uaQppZihv
-LmU9PT1yKXRocm93IEguYihQLlNZKCJSZXR1cm4gaW50ZXJjZXB0b3IgZm9yICIrSC5FaihzKGEsbykp
-KSl9cT1hLmNvbnN0cnVjdG9yCnA9cT09bnVsbD9udWxsOnFbSi5SUCgpXQppZihwIT1udWxsKXJldHVy
-biBwCnA9SC53MyhhKQppZihwIT1udWxsKXJldHVybiBwCmlmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJl
-dHVybiBDLkRHCnM9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCmlmKHM9PW51bGwpcmV0dXJuIEMuWlEK
-aWYocz09PU9iamVjdC5wcm90b3R5cGUpcmV0dXJuIEMuWlEKaWYodHlwZW9mIHE9PSJmdW5jdGlvbiIp
-e09iamVjdC5kZWZpbmVQcm9wZXJ0eShxLEouUlAoKSx7dmFsdWU6Qy52QixlbnVtZXJhYmxlOmZhbHNl
-LHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gQy52Qn1yZXR1cm4gQy52Qn0s
-ClJQOmZ1bmN0aW9uKCl7dmFyIHM9JC56bQpyZXR1cm4gcz09bnVsbD8kLnptPXYuZ2V0SXNvbGF0ZVRh
-ZygiXyRkYXJ0X2pzIik6c30sClFpOmZ1bmN0aW9uKGEsYil7aWYoYTwwfHxhPjQyOTQ5NjcyOTUpdGhy
-b3cgSC5iKFAuVEUoYSwwLDQyOTQ5NjcyOTUsImxlbmd0aCIsbnVsbCkpCnJldHVybiBKLnB5KG5ldyBB
-cnJheShhKSxiKX0sCktoOmZ1bmN0aW9uKGEsYil7aWYoYTwwKXRocm93IEguYihQLnhZKCJMZW5ndGgg
-bXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyOiAiK2EpKQpyZXR1cm4gSC5WTShuZXcgQXJyYXko
-YSksYi5DKCJqZDwwPiIpKX0sCnB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouRXAoSC5WTShhLGIuQygi
-amQ8MD4iKSksYil9LApFcDpmdW5jdGlvbihhLGIpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CnJldHVybiBh
-fSwKekM6ZnVuY3Rpb24oYSl7YS5maXhlZCRsZW5ndGg9QXJyYXkKYS5pbW11dGFibGUkbGlzdD1BcnJh
-eQpyZXR1cm4gYX0sCkdhOmZ1bmN0aW9uKGEpe2lmKGE8MjU2KXN3aXRjaChhKXtjYXNlIDk6Y2FzZSAx
-MDpjYXNlIDExOmNhc2UgMTI6Y2FzZSAxMzpjYXNlIDMyOmNhc2UgMTMzOmNhc2UgMTYwOnJldHVybiEw
-CmRlZmF1bHQ6cmV0dXJuITF9c3dpdGNoKGEpe2Nhc2UgNTc2MDpjYXNlIDgxOTI6Y2FzZSA4MTkzOmNh
-c2UgODE5NDpjYXNlIDgxOTU6Y2FzZSA4MTk2OmNhc2UgODE5NzpjYXNlIDgxOTg6Y2FzZSA4MTk5OmNh
-c2UgODIwMDpjYXNlIDgyMDE6Y2FzZSA4MjAyOmNhc2UgODIzMjpjYXNlIDgyMzM6Y2FzZSA4MjM5OmNh
-c2UgODI4NzpjYXNlIDEyMjg4OmNhc2UgNjUyNzk6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX19LApt
-bTpmdW5jdGlvbihhLGIpe3ZhciBzLHIKZm9yKHM9YS5sZW5ndGg7YjxzOyl7cj1DLnhCLlcoYSxiKQpp
-ZihyIT09MzImJnIhPT0xMyYmIUouR2EocikpYnJlYWs7KytifXJldHVybiBifSwKYzE6ZnVuY3Rpb24o
-YSxiKXt2YXIgcyxyCmZvcig7Yj4wO2I9cyl7cz1iLTEKcj1DLnhCLk8yKGEscykKaWYociE9PTMyJiZy
-IT09MTMmJiFKLkdhKHIpKWJyZWFrfXJldHVybiBifSwKVEo6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9
-PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJu
-IEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkp
-cmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJm
-dW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1o
-KXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKVTY6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJp
-bmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0
-b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5
-cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3Rh
-bmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sCllFOmZ1bmN0aW9uKGEpe2lmKGE9PW51
-bGwpcmV0dXJuIGEKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIily
-ZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEK
-cmV0dXJuIEoua3MoYSl9LAppYTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpe2lmKE1h
-dGguZmxvb3IoYSk9PWEpcmV0dXJuIEouYlUucHJvdG90eXBlCnJldHVybiBKLlZBLnByb3RvdHlwZX1p
-Zih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJu
-IEoud2UucHJvdG90eXBlCmlmKHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIEoueUUucHJvdG90eXBl
-CmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBlb2YgYSE9
-Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlwZQpyZXR1
-cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sCnJZOmZ1bmN0
-aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVs
-bClyZXR1cm4gYQppZighKGEgaW5zdGFuY2VvZiBQLk1oKSlyZXR1cm4gSi5rZC5wcm90b3R5cGUKcmV0
-dXJuIGF9LAp2ZDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJv
-dG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNlb2YgUC5NaCkpcmV0dXJuIEou
-a2QucHJvdG90eXBlCnJldHVybiBhfSwKdzE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gYQpp
-ZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJv
-YmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJu
-IGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApBNTpmdW5jdGlv
-bihhLGIpe3JldHVybiBKLncxKGEpLmVSKGEsYil9LApFaDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEou
-WUUoYSkubUsoYSxiLGMpfSwKRWw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5kcihhLGIpfSwK
-Rjc6ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYoYSkuZ29yKGEpfSwKRkw6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gSi5yWShhKS5kZChhLGIpfSwKR0E6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5FKGEsYil9
-LApIbTpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS5nQShhKX0sCklUOmZ1bmN0aW9uKGEpe3JldHVy
-biBKLncxKGEpLmdtKGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwK
-S1Y6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1
-cm4gSi5ZRShhKS53ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIs
-Yyl9LApNdTpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNEKGEsYil9LApRejpmdW5jdGlvbihh
-LGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClyZXR1
-cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51bGwmJmE9PT1iCnJldHVy
-biBKLmlhKGEpLkROKGEsYil9LApSWDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5icihhKX0sClQw
-OmZ1bmN0aW9uKGEpe3JldHVybiBKLnJZKGEpLmJTKGEpfSwKVnU6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
-dmQoYSkuelEoYSl9LAphNjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLk8yKGEsYil9LApiVDpm
-dW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS5ENChhKX0sCmJiOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9m
-IGE9PSJudW1iZXIiJiZ0eXBlb2YgYj09Im51bWJlciIpcmV0dXJuIGErYgpyZXR1cm4gSi5USihhKS5o
-KGEsYil9LApjSDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5oYyhhKX0sCmRSOmZ1bmN0aW9uKGEp
-e3JldHVybiBKLllFKGEpLmdEKGEpfSwKZFo6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouWUUoYSku
-T24oYSxiLGMsZCl9LApkZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5yWShhKS5pNyhhLGIsYyxk
-KX0sCmRoOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLkZGKGEpfSwKZHI6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gSi5ZRShhKS5zYTQoYSxiKX0sCmhmOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLmdpTyhh
-KX0sCmlnOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLmdRZyhhKX0sCmo6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEouaWEoYSkudyhhKX0sCmw1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUoYSkuc2hmKGEsYil9
-LApsZDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuTmooYSxiLGMpfSwKcDQ6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gSi5yWShhKS5UYyhhLGIpfSwKcTA6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnJZ
-KGEpLlFpKGEsYixjKX0sCnFGOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLmdWbChhKX0sCnRIOmZ1
-bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5ZRShhKS5wayhhLGIsYyl9LAp1OTpmdW5jdGlvbihhLGIsYyl7
-cmV0dXJuIEoudzEoYSkuWShhLGIsYyl9LAp1VTpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS5nbDAo
-YSl9LAp3ZjpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNSTihhLGIpfSwKeDk6ZnVuY3Rpb24o
-YSxiKXtpZih0eXBlb2YgYj09PSJudW1iZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0eXBlb2Yg
-YT09InN0cmluZyJ8fEgud1YoYSxhW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+MD09PWIm
-JmI8YS5sZW5ndGgpcmV0dXJuIGFbYl0KcmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gSi5VNihhKS50ZyhhLGIpfSwKdkI6ZnVuY3Rpb24gdkIoKXt9LAp5RTpmdW5jdGlv
-biB5RSgpe30sCndlOmZ1bmN0aW9uIHdlKCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpmdW5jdGlv
-biBpQygpe30sCmtkOmZ1bmN0aW9uIGtkKCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpmdW5jdGlv
-biBqZChhKXt0aGlzLiR0aT1hfSwKUG86ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0xOmZ1bmN0
-aW9uIG0xKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRpPWN9
-LApxSTpmdW5jdGlvbiBxSSgpe30sCmJVOmZ1bmN0aW9uIGJVKCl7fSwKVkE6ZnVuY3Rpb24gVkEoKXt9
-LApEcjpmdW5jdGlvbiBEcigpe319LFA9ewpPajpmdW5jdGlvbigpe3ZhciBzLHIscT17fQppZihzZWxm
-LnNjaGVkdWxlSW1tZWRpYXRlIT1udWxsKXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlvbk9ic2Vy
-dmVyIT1udWxsJiZzZWxmLmRvY3VtZW50IT1udWxsKXtzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVu
-dCgiZGl2IikKcj1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpxLmE9bnVsbApuZXcg
-c2VsZi5NdXRhdGlvbk9ic2VydmVyKEgudFIobmV3IFAudGgocSksMSkpLm9ic2VydmUocyx7Y2hpbGRM
-aXN0OnRydWV9KQpyZXR1cm4gbmV3IFAuaGEocSxzLHIpfWVsc2UgaWYoc2VsZi5zZXRJbW1lZGlhdGUh
-PW51bGwpcmV0dXJuIFAueXQoKQpyZXR1cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2VsZi5zY2hl
-ZHVsZUltbWVkaWF0ZShILnRSKG5ldyBQLlZzKHQuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlvbihhKXtz
-ZWxmLnNldEltbWVkaWF0ZShILnRSKG5ldyBQLkZ0KHQuTS5hKGEpKSwwKSl9LApCejpmdW5jdGlvbihh
-KXt0Lk0uYShhKQpQLlFOKDAsYSl9LApRTjpmdW5jdGlvbihhLGIpe3ZhciBzPW5ldyBQLlczKCkKcy5D
-WShhLGIpCnJldHVybiBzfSwKRlg6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQLnZzKCQu
-WDMsYS5DKCJ2czwwPiIpKSxhLkMoImloPDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQyKDAsbnVs
-bCkKYi5iPSEwCnJldHVybiBiLmF9LApqUTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlDOmZ1bmN0
-aW9uKGEsYil7Yi5hTSgwLGEpfSwKZjM6ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50cyhhKSl9
-LApKZTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1uZXcgUC5XTShiKSxwPW5ldyBQLlNYKGIpCmlmKGEg
-aW5zdGFuY2VvZiBQLnZzKWEuUWQocSxwLHQueikKZWxzZXtzPXQuegppZih0LmQuYihhKSlhLlNxKHEs
-cCxzKQplbHNle3I9bmV3IFAudnMoJC5YMyx0LmMpCnIuYT00CnIuYz1hCnIuUWQocSxwLHMpfX19LAps
-ejpmdW5jdGlvbihhKXt2YXIgcz1mdW5jdGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUpe3doaWxl
-KHRydWUpdHJ5e2IoZCxlKQpicmVha31jYXRjaChyKXtlPXIKZD1jfX19KGEsMSkKcmV0dXJuICQuWDMu
-TGoobmV3IFAuR3MocyksdC5ILHQuUyx0LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5
-KGEsMSl9LApUaDpmdW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygicTQ8MD4i
-KSl9LAprMzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQpiLmE9MQp0cnl7YS5TcShuZXcgUC5wVihiKSxu
-ZXcgUC5VNyhiKSx0LlApfWNhdGNoKHEpe3M9SC5SdShxKQpyPUgudHMocSkKUC5yYihuZXcgUC52cihi
-LHMscikpfX0sCkE5OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCmZvcihzPXQuYztyPWEuYSxyPT09Mjsp
-YT1zLmEoYS5jKQppZihyPj00KXtxPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHEpfWVsc2V7
-cT10LkYuYShiLmMpCmIuYT0yCmIuYz1hCmEualEocSl9fSwKSFo6ZnVuY3Rpb24oYTAsYTEpe3ZhciBz
-LHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGM9bnVsbCxiPXt9LGE9Yi5hPWEwCmZvcihzPXQu
-bixyPXQuRixxPXQuZDshMDspe3A9e30Kbz1hLmE9PT04CmlmKGExPT1udWxsKXtpZihvKXtuPXMuYShh
-LmMpClAuTDIoYyxjLGEuYixuLmEsbi5iKX1yZXR1cm59cC5hPWExCm09YTEuYQpmb3IoYT1hMTttIT1u
-dWxsO2E9bSxtPWwpe2EuYT1udWxsClAuSFooYi5hLGEpCnAuYT1tCmw9bS5hfWs9Yi5hCmo9ay5jCnAu
-Yj1vCnAuYz1qCmk9IW8KaWYoaSl7aD1hLmMKaD0oaCYxKSE9PTB8fChoJjE1KT09PTh9ZWxzZSBoPSEw
-CmlmKGgpe2c9YS5iLmIKaWYobyl7aD1rLmI9PT1nCmg9IShofHxoKX1lbHNlIGg9ITEKaWYoaCl7cy5h
-KGopClAuTDIoYyxjLGsuYixqLmEsai5iKQpyZXR1cm59Zj0kLlgzCmlmKGYhPT1nKSQuWDM9ZwplbHNl
-IGY9YwphPWEuYwppZigoYSYxNSk9PT04KW5ldyBQLlJUKHAsYixvKS4kMCgpCmVsc2UgaWYoaSl7aWYo
-KGEmMSkhPT0wKW5ldyBQLnJxKHAsaikuJDAoKX1lbHNlIGlmKChhJjIpIT09MCluZXcgUC5SVyhiLHAp
-LiQwKCkKaWYoZiE9bnVsbCkkLlgzPWYKYT1wLmMKaWYocS5iKGEpKXtlPXAuYS5iCmlmKGEuYT49NCl7
-ZD1yLmEoZS5jKQplLmM9bnVsbAphMT1lLk44KGQpCmUuYT1hLmEKZS5jPWEuYwpiLmE9YQpjb250aW51
-ZX1lbHNlIFAuQTkoYSxlKQpyZXR1cm59fWU9cC5hLmIKZD1yLmEoZS5jKQplLmM9bnVsbAphMT1lLk44
-KGQpCmE9cC5iCms9cC5jCmlmKCFhKXtlLiR0aS5jLmEoaykKZS5hPTQKZS5jPWt9ZWxzZXtzLmEoaykK
-ZS5hPTgKZS5jPWt9Yi5hPWUKYT1lfX0sClZIOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYodC5hZy5iKGEp
-KXJldHVybiBiLkxqKGEsdC56LHQuSyx0LmwpCnM9dC5iSQppZihzLmIoYSkpcmV0dXJuIHMuYShhKQp0
-aHJvdyBILmIoUC5MMyhhLCJvbkVycm9yIiwiRXJyb3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUgT2Jq
-ZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEgU3RhY2tUcmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm4g
-YSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1OmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz0kLlM2O3MhPW51
-bGw7cz0kLlM2KXskLm1nPW51bGwKcj1zLmIKJC5TNj1yCmlmKHI9PW51bGwpJC5rOD1udWxsCnMuYS4k
-MCgpfX0sCmVOOmZ1bmN0aW9uKCl7JC5VRD0hMAp0cnl7UC5wdSgpfWZpbmFsbHl7JC5tZz1udWxsCiQu
-VUQ9ITEKaWYoJC5TNiE9bnVsbCkkLnV0KCkuJDEoUC5WOSgpKX19LAplVzpmdW5jdGlvbihhKXt2YXIg
-cz1uZXcgUC5PTShhKSxyPSQuazgKaWYocj09bnVsbCl7JC5TNj0kLms4PXMKaWYoISQuVUQpJC51dCgp
-LiQxKFAuVjkoKSl9ZWxzZSAkLms4PXIuYj1zfSwKclI6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9JC5T
-NgppZihwPT1udWxsKXtQLmVXKGEpCiQubWc9JC5rOApyZXR1cm59cz1uZXcgUC5PTShhKQpyPSQubWcK
-aWYocj09bnVsbCl7cy5iPXAKJC5TNj0kLm1nPXN9ZWxzZXtxPXIuYgpzLmI9cQokLm1nPXIuYj1zCmlm
-KHE9PW51bGwpJC5rOD1zfX0sCnJiOmZ1bmN0aW9uKGEpe3ZhciBzPW51bGwscj0kLlgzCmlmKEMuTlU9
-PT1yKXtQLlRrKHMscyxDLk5VLGEpCnJldHVybn1QLlRrKHMscyxyLHQuTS5hKHIuR1koYSkpKX0sClF3
-OmZ1bmN0aW9uKGEsYil7UC5VSShhLCJzdHJlYW0iLHQuUikKcmV0dXJuIG5ldyBQLnhJKGIuQygieEk8
-MD4iKSl9LApUbDpmdW5jdGlvbihhLGIpe3ZhciBzPWI9PW51bGw/UC52MChhKTpiClAuVUkoYSwiZXJy
-b3IiLHQuSykKcmV0dXJuIG5ldyBQLkN3KGEscyl9LAp2MDpmdW5jdGlvbihhKXt2YXIgcwppZih0LnIu
-YihhKSl7cz1hLmdJSSgpCmlmKHMhPW51bGwpcmV0dXJuIHN9cmV0dXJuIEMucGR9LApMMjpmdW5jdGlv
-bihhLGIsYyxkLGUpe1AuclIobmV3IFAucEsoZCxlKSl9LApUODpmdW5jdGlvbihhLGIsYyxkLGUpe3Zh
-ciBzLHI9JC5YMwppZihyPT09YylyZXR1cm4gZC4kMCgpCiQuWDM9YwpzPXIKdHJ5e3I9ZC4kMCgpCnJl
-dHVybiByfWZpbmFsbHl7JC5YMz1zfX0sCnl2OmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHI9
-JC5YMwppZihyPT09YylyZXR1cm4gZC4kMShlKQokLlgzPWMKcz1yCnRyeXtyPWQuJDEoZSkKcmV0dXJu
-IHJ9ZmluYWxseXskLlgzPXN9fSwKUXg6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyxoLGkpe3ZhciBzLHI9
-JC5YMwppZihyPT09YylyZXR1cm4gZC4kMihlLGYpCiQuWDM9YwpzPXIKdHJ5e3I9ZC4kMihlLGYpCnJl
-dHVybiByfWZpbmFsbHl7JC5YMz1zfX0sClRrOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzCnQuTS5hKGQp
-CnM9Qy5OVSE9PWMKaWYocylkPSEoIXN8fCExKT9jLkdZKGQpOmMuUlQoZCx0LkgpClAuZVcoZCl9LAp0
-aDpmdW5jdGlvbiB0aChhKXt0aGlzLmE9YX0sCmhhOmZ1bmN0aW9uIGhhKGEsYixjKXt0aGlzLmE9YQp0
-aGlzLmI9Ygp0aGlzLmM9Y30sClZzOmZ1bmN0aW9uIFZzKGEpe3RoaXMuYT1hfSwKRnQ6ZnVuY3Rpb24g
-RnQoYSl7dGhpcy5hPWF9LApXMzpmdW5jdGlvbiBXMygpe30sCnlIOmZ1bmN0aW9uIHlIKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWJ9LAppaDpmdW5jdGlvbiBpaChhLGIpe3RoaXMuYT1hCnRoaXMuYj0hMQp0aGlz
-LiR0aT1ifSwKV006ZnVuY3Rpb24gV00oYSl7dGhpcy5hPWF9LApTWDpmdW5jdGlvbiBTWChhKXt0aGlz
-LmE9YX0sCkdzOmZ1bmN0aW9uIEdzKGEpe3RoaXMuYT1hfSwKRnk6ZnVuY3Rpb24gRnkoYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCkdWOmZ1bmN0aW9uIEdWKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmQ9Xy5j
-PV8uYj1udWxsCl8uJHRpPWJ9LApxNDpmdW5jdGlvbiBxNChhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
-LApQZjpmdW5jdGlvbiBQZigpe30sClpmOmZ1bmN0aW9uIFpmKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
-Yn0sCkZlOmZ1bmN0aW9uIEZlKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmE9bnVsbApfLmI9YQpfLmM9
-YgpfLmQ9YwpfLmU9ZApfLiR0aT1lfSwKdnM6ZnVuY3Rpb24gdnMoYSxiKXt2YXIgXz10aGlzCl8uYT0w
-Cl8uYj1hCl8uYz1udWxsCl8uJHRpPWJ9LApkYTpmdW5jdGlvbiBkYShhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKb1E6ZnVuY3Rpb24gb1EoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnBWOmZ1bmN0aW9uIHBW
-KGEpe3RoaXMuYT1hfSwKVTc6ZnVuY3Rpb24gVTcoYSl7dGhpcy5hPWF9LAp2cjpmdW5jdGlvbiB2cihh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApydDpmdW5jdGlvbiBydChhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKS0Y6ZnVuY3Rpb24gS0YoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClpMOmZ1
-bmN0aW9uIFpMKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClJUOmZ1bmN0aW9uIFJU
-KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmpaOmZ1bmN0aW9uIGpaKGEpe3RoaXMu
-YT1hfSwKcnE6ZnVuY3Rpb24gcnEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClJXOmZ1bmN0aW9uIFJX
-KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApPTTpmdW5jdGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9
-bnVsbH0sCnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVuY3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCnVPOmZ1bmN0aW9uIHVPKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBN
-Tygpe30sCmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVuY3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCkN3
-OmZ1bmN0aW9uIEN3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBL
-OmZ1bmN0aW9uIHBLKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApKaTpmdW5jdGlvbiBKaSgpe30sCmhq
-OmZ1bmN0aW9uIGhqKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClZwOmZ1bmN0aW9u
-IFZwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApPUjpmdW5jdGlvbiBPUihhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApFRjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGIuQygiQDwwPiIpLktx
-KGMpLkMoIkZvPDEsMj4iKS5hKEguQjcoYSxuZXcgSC5ONShiLkMoIkA8MD4iKS5LcShjKS5DKCJONTwx
-LDI+IikpKSl9LApGbDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5ONShhLkMoIkA8MD4iKS5LcShi
-KS5DKCJONTwxLDI+IikpfSwKTHM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmI2KGEuQygiYjY8MD4i
-KSl9LApUMjpmdW5jdGlvbigpe3ZhciBzPU9iamVjdC5jcmVhdGUobnVsbCkKc1siPG5vbi1pZGVudGlm
-aWVyLWtleT4iXT1zCmRlbGV0ZSBzWyI8bm9uLWlkZW50aWZpZXIta2V5PiJdCnJldHVybiBzfSwKcmo6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5ldyBQLmxtKGEsYixjLkMoImxtPDA+IikpCnMuYz1hLmUKcmV0
-dXJuIHN9LApFUDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscgppZihQLmhCKGEpKXtpZihiPT09IigiJiZj
-PT09IikiKXJldHVybiIoLi4uKSIKcmV0dXJuIGIrIi4uLiIrY31zPUguVk0oW10sdC5zKQpDLk5tLmko
-JC54ZyxhKQp0cnl7UC5WcihhLHMpfWZpbmFsbHl7aWYoMD49JC54Zy5sZW5ndGgpcmV0dXJuIEguT0go
-JC54ZywtMSkKJC54Zy5wb3AoKX1yPVAudmcoYix0LnUuYShzKSwiLCAiKStjCnJldHVybiByLmNoYXJD
-b2RlQXQoMCk9PTA/cjpyfSwKV0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIKaWYoUC5oQihhKSlyZXR1
-cm4gYisiLi4uIitjCnM9bmV3IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3I9cwpyLmE9UC52Zyhy
-LmEsYSwiLCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQu
-eGcucG9wKCl9cy5hKz1jCnI9cy5hCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfSwKaEI6ZnVu
-Y3Rpb24oYSl7dmFyIHMscgpmb3Iocz0kLnhnLmxlbmd0aCxyPTA7cjxzOysrcilpZihhPT09JC54Z1ty
-XSlyZXR1cm4hMApyZXR1cm4hMX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbD1h
-LmdtKGEpLGs9MCxqPTAKd2hpbGUoITApe2lmKCEoazw4MHx8ajwzKSlicmVhawppZighbC5GKCkpcmV0
-dXJuCnM9SC5FaihsLmdsKCkpCkMuTm0uaShiLHMpCmsrPXMubGVuZ3RoKzI7KytqfWlmKCFsLkYoKSl7
-aWYoajw9NSlyZXR1cm4KaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcj1iLnBvcCgpCmlm
-KDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCnE9Yi5wb3AoKX1lbHNle3A9bC5nbCgpOysragpp
-ZighbC5GKCkpe2lmKGo8PTQpe0MuTm0uaShiLEguRWoocCkpCnJldHVybn1yPUguRWoocCkKaWYoMD49
-Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcT1iLnBvcCgpCmsrPXIubGVuZ3RoKzJ9ZWxzZXtvPWwu
-Z2woKTsrK2oKZm9yKDtsLkYoKTtwPW8sbz1uKXtuPWwuZ2woKTsrK2oKaWYoaj4xMDApe3doaWxlKCEw
-KXtpZighKGs+NzUmJmo+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKay09
-Yi5wb3AoKS5sZW5ndGgrMjstLWp9Qy5ObS5pKGIsIi4uLiIpCnJldHVybn19cT1ILkVqKHApCnI9SC5F
-aihvKQprKz1yLmxlbmd0aCtxLmxlbmd0aCs0fX1pZihqPmIubGVuZ3RoKzIpe2srPTUKbT0iLi4uIn1l
-bHNlIG09bnVsbAp3aGlsZSghMCl7aWYoIShrPjgwJiZiLmxlbmd0aD4zKSlicmVhawppZigwPj1iLmxl
-bmd0aClyZXR1cm4gSC5PSChiLC0xKQprLT1iLnBvcCgpLmxlbmd0aCsyCmlmKG09PW51bGwpe2srPTUK
-bT0iLi4uIn19aWYobSE9bnVsbClDLk5tLmkoYixtKQpDLk5tLmkoYixxKQpDLk5tLmkoYixyKX0sCnRN
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPVAuTHMoYikKZm9yKHM9YS5sZW5ndGgscj0wO3I8YS5sZW5n
-dGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3IpcS5pKDAsYi5hKGFbcl0pKQpyZXR1cm4gcX0s
-Cm5POmZ1bmN0aW9uKGEpe3ZhciBzLHI9e30KaWYoUC5oQihhKSlyZXR1cm4iey4uLn0iCnM9bmV3IFAu
-Um4oIiIpCnRyeXtDLk5tLmkoJC54ZyxhKQpzLmErPSJ7IgpyLmE9ITAKYS5LKDAsbmV3IFAucmEocixz
-KSkKcy5hKz0ifSJ9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQok
-LnhnLnBvcCgpfXI9cy5hCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfSwKYjY6ZnVuY3Rpb24g
-YjYoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwKXy5yPTAKXy4kdGk9
-YX0sCmJuOmZ1bmN0aW9uIGJuKGEpe3RoaXMuYT1hCnRoaXMuYz10aGlzLmI9bnVsbH0sCmxtOmZ1bmN0
-aW9uIGxtKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbApfLiR0aT1jfSwK
-bVc6ZnVuY3Rpb24gbVcoKXt9LAp1eTpmdW5jdGlvbiB1eSgpe30sCmxEOmZ1bmN0aW9uIGxEKCl7fSwK
-aWw6ZnVuY3Rpb24gaWwoKXt9LApyYTpmdW5jdGlvbiByYShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-WWs6ZnVuY3Rpb24gWWsoKXt9LAp5UTpmdW5jdGlvbiB5UShhKXt0aGlzLmE9YX0sCktQOmZ1bmN0aW9u
-IEtQKCl7fSwKUG46ZnVuY3Rpb24gUG4oKXt9LApHajpmdW5jdGlvbiBHaihhLGIpe3RoaXMuYT1hCnRo
-aXMuJHRpPWJ9LApsZjpmdW5jdGlvbiBsZigpe30sClZqOmZ1bmN0aW9uIFZqKCl7fSwKWHY6ZnVuY3Rp
-b24gWHYoKXt9LApuWTpmdW5jdGlvbiBuWSgpe30sCldZOmZ1bmN0aW9uIFdZKCl7fSwKUlU6ZnVuY3Rp
-b24gUlUoKXt9LApwUjpmdW5jdGlvbiBwUigpe30sCkJTOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAK
-aWYodHlwZW9mIGEhPSJzdHJpbmciKXRocm93IEguYihILnRMKGEpKQpzPW51bGwKdHJ5e3M9SlNPTi5w
-YXJzZShhKX1jYXRjaChxKXtyPUguUnUocSkKcD1QLnJyKFN0cmluZyhyKSxudWxsLG51bGwpCnRocm93
-IEguYihwKX1wPVAuUWUocykKcmV0dXJuIHB9LApRZTpmdW5jdGlvbihhKXt2YXIgcwppZihhPT1udWxs
-KXJldHVybiBudWxsCmlmKHR5cGVvZiBhIT0ib2JqZWN0IilyZXR1cm4gYQppZihPYmplY3QuZ2V0UHJv
-dG90eXBlT2YoYSkhPT1BcnJheS5wcm90b3R5cGUpcmV0dXJuIG5ldyBQLnV3KGEsT2JqZWN0LmNyZWF0
-ZShudWxsKSkKZm9yKHM9MDtzPGEubGVuZ3RoOysrcylhW3NdPVAuUWUoYVtzXSkKcmV0dXJuIGF9LApr
-eTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyCmlmKGIgaW5zdGFuY2VvZiBVaW50OEFycmF5KXtzPWIK
-ZD1zLmxlbmd0aAppZihkLWM8MTUpcmV0dXJuIG51bGwKcj1QLkNHKGEscyxjLGQpCmlmKHIhPW51bGwm
-JmEpaWYoci5pbmRleE9mKCJcdWZmZmQiKT49MClyZXR1cm4gbnVsbApyZXR1cm4gcn1yZXR1cm4gbnVs
-bH0sCkNHOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPWE/JC5IRygpOiQucmYoKQppZihzPT1udWxsKXJl
-dHVybiBudWxsCmlmKDA9PT1jJiZkPT09Yi5sZW5ndGgpcmV0dXJuIFAuUmIocyxiKQpyZXR1cm4gUC5S
-YihzLGIuc3ViYXJyYXkoYyxQLmpCKGMsZCxiLmxlbmd0aCkpKX0sClJiOmZ1bmN0aW9uKGEsYil7dmFy
-IHMscgp0cnl7cz1hLmRlY29kZShiKQpyZXR1cm4gc31jYXRjaChyKXtILlJ1KHIpfXJldHVybiBudWxs
-fSwKeE06ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2lmKEMuam4uelkoZiw0KSE9PTApdGhyb3cgSC5iKFAu
-cnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIHBhZGRlZCBsZW5ndGggbXVzdCBiZSBtdWx0aXBsZSBv
-ZiBmb3VyLCBpcyAiK2YsYSxjKSkKaWYoZCtlIT09Zil0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNl
-NjQgcGFkZGluZywgJz0nIG5vdCBhdCB0aGUgZW5kIixhLGIpKQppZihlPjIpdGhyb3cgSC5iKFAucnIo
-IkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIG1vcmUgdGhhbiB0d28gJz0nIGNoYXJhY3RlcnMiLGEsYikp
-fSwKR3k6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgUC5VZChhLGIpfSwKTkM6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEuTHQoKX0sClVnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLnR1KGEsW10sUC5DeSgp
-KX0sCnVYOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPW5ldyBQLlJuKCIiKSxxPVAuVWcocixiKQpxLmlV
-KGEpCnM9ci5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKajQ6ZnVuY3Rpb24oYSl7c3dp
-dGNoKGEpe2Nhc2UgNjU6cmV0dXJuIk1pc3NpbmcgZXh0ZW5zaW9uIGJ5dGUiCmNhc2UgNjc6cmV0dXJu
-IlVuZXhwZWN0ZWQgZXh0ZW5zaW9uIGJ5dGUiCmNhc2UgNjk6cmV0dXJuIkludmFsaWQgVVRGLTggYnl0
-ZSIKY2FzZSA3MTpyZXR1cm4iT3ZlcmxvbmcgZW5jb2RpbmciCmNhc2UgNzM6cmV0dXJuIk91dCBvZiB1
-bmljb2RlIHJhbmdlIgpjYXNlIDc1OnJldHVybiJFbmNvZGVkIHN1cnJvZ2F0ZSIKY2FzZSA3NzpyZXR1
-cm4iVW5maW5pc2hlZCBVVEYtOCBvY3RldCBzZXF1ZW5jZSIKZGVmYXVsdDpyZXR1cm4iIn19LApqeTpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHA9Yy1iLG89bmV3IFVpbnQ4QXJyYXkocCkKZm9yKHM9Si5V
-NihhKSxyPTA7cjxwOysrcil7cT1zLnEoYSxiK3IpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJu
-IHEuek0oKQppZigocSY0Mjk0OTY3MDQwKT4+PjAhPT0wKXE9MjU1CmlmKHI+PXApcmV0dXJuIEguT0go
-byxyKQpvW3JdPXF9cmV0dXJuIG99LAp1dzpmdW5jdGlvbiB1dyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
-CnRoaXMuYz1udWxsfSwKaTg6ZnVuY3Rpb24gaTgoYSl7dGhpcy5hPWF9LApwZzpmdW5jdGlvbiBwZygp
-e30sCmMyOmZ1bmN0aW9uIGMyKCl7fSwKQ1Y6ZnVuY3Rpb24gQ1YoKXt9LApVODpmdW5jdGlvbiBVOCgp
-e30sClVrOmZ1bmN0aW9uIFVrKCl7fSwKd0k6ZnVuY3Rpb24gd0koKXt9LApaaTpmdW5jdGlvbiBaaSgp
-e30sClVkOmZ1bmN0aW9uIFVkKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLODpmdW5jdGlvbiBLOChh
-LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYnk6ZnVuY3Rpb24gYnkoKXt9LApvajpmdW5jdGlvbiBvaihh
-KXt0aGlzLmI9YX0sCk14OmZ1bmN0aW9uIE14KGEpe3RoaXMuYT1hfSwKU2g6ZnVuY3Rpb24gU2goKXt9
-LAp0aTpmdW5jdGlvbiB0aShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdHU6ZnVuY3Rpb24gdHUoYSxi
-LGMpe3RoaXMuYz1hCnRoaXMuYT1iCnRoaXMuYj1jfSwKdTU6ZnVuY3Rpb24gdTUoKXt9LApFMzpmdW5j
-dGlvbiBFMygpe30sClJ3OmZ1bmN0aW9uIFJ3KGEpe3RoaXMuYj0wCnRoaXMuYz1hfSwKR1k6ZnVuY3Rp
-b24gR1koYSl7dGhpcy5hPWF9LApiejpmdW5jdGlvbiBieihhKXt0aGlzLmE9YQp0aGlzLmI9MTYKdGhp
-cy5jPTB9LApRQTpmdW5jdGlvbihhLGIpe3ZhciBzPUguSHAoYSxiKQppZihzIT1udWxsKXJldHVybiBz
-CnRocm93IEguYihQLnJyKGEsbnVsbCxudWxsKSl9LApvczpmdW5jdGlvbihhKXtpZihhIGluc3RhbmNl
-b2YgSC5UcClyZXR1cm4gYS53KDApCnJldHVybiJJbnN0YW5jZSBvZiAnIitILkVqKEguTShhKSkrIici
-fSwKTzg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscj1jP0ouS2goYSxkKTpKLlFpKGEsZCkKaWYoYSE9
-PTAmJmIhPW51bGwpZm9yKHM9MDtzPHIubGVuZ3RoOysrcylyW3NdPWIKcmV0dXJuIHJ9LApDSDpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscj1ILlZNKFtdLGMuQygiamQ8MD4iKSkKZm9yKHM9Si5JVChhKTtzLkYo
-KTspQy5ObS5pKHIsYy5hKHMuZ2woKSkpCmlmKGIpcmV0dXJuIHIKcmV0dXJuIEouRXAocixjKX0sCmRI
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPUouS2goYSxjKQpmb3Iocz0wO3M8YTsrK3MpQy5ObS5ZKHIs
-cyxiLiQxKHMpKQpyZXR1cm4gcn0sCkFGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouekMoUC5DSChhLCEx
-LGIpKX0sCkhNOmZ1bmN0aW9uKGEsYixjKXtpZih0LmJtLmIoYSkpcmV0dXJuIEguZncoYSxiLFAuakIo
-YixjLGEubGVuZ3RoKSkKcmV0dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24oYSl7cmV0dXJuIEgu
-THcoYSl9LApidzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuPW51bGwKaWYoYjwwKXRocm93
-IEguYihQLlRFKGIsMCxhLmxlbmd0aCxuLG4pKQpzPWM9PW51bGwKaWYoIXMmJmM8Yil0aHJvdyBILmIo
-UC5URShjLGIsYS5sZW5ndGgsbixuKSkKcj1uZXcgSC5hNyhhLGEubGVuZ3RoLEgueihhKS5DKCJhNzxs
-RC5FPiIpKQpmb3IocT0wO3E8YjsrK3EpaWYoIXIuRigpKXRocm93IEguYihQLlRFKGIsMCxxLG4sbikp
-CnA9W10KaWYocylmb3IoO3IuRigpOyl7bz1yLmQKcC5wdXNoKG8pfWVsc2UgZm9yKHE9YjtxPGM7Kytx
-KXtpZighci5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHEsbixuKSkKbz1yLmQKcC5wdXNoKG8pfXJldHVy
-biBILmVUKHApfSwKbnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52NChhLCExLCEwLCEx
-LCExLCExKSl9LAp2ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Si5JVChiKQppZighcy5GKCkpcmV0dXJu
-IGEKaWYoYy5sZW5ndGg9PT0wKXtkbyBhKz1ILkVqKHMuZ2woKSkKd2hpbGUocy5GKCkpfWVsc2V7YSs9
-SC5FaihzLmdsKCkpCmZvcig7cy5GKCk7KWE9YStjK0guRWoocy5nbCgpKX1yZXR1cm4gYX0sCmxyOmZ1
-bmN0aW9uKGEsYixjLGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0aW9uKCl7dmFy
-IHM9SC5NMCgpCmlmKHMhPW51bGwpcmV0dXJuIFAuaEsocykKdGhyb3cgSC5iKFAuTDQoIidVcmkuYmFz
-ZScgaXMgbm90IHN1cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8s
-bixtPSIwMTIzNDU2Nzg5QUJDREVGIgppZihjPT09Qy54TSl7cz0kLno0KCkuYgppZih0eXBlb2YgYiE9
-InN0cmluZyIpSC52KEgudEwoYikpCnM9cy50ZXN0KGIpfWVsc2Ugcz0hMQppZihzKXJldHVybiBiCkgu
-TGgoYykuQygiVWsuUyIpLmEoYikKcj1jLmdaRSgpLldKKGIpCmZvcihzPXIubGVuZ3RoLHE9MCxwPSIi
-O3E8czsrK3Epe289cltxXQppZihvPDEyOCl7bj1vPj4+NAppZihuPj04KXJldHVybiBILk9IKGEsbikK
-bj0oYVtuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobilwKz1ILkx3KG8pCmVsc2UgcD1kJiZv
-PT09MzI/cCsiKyI6cCsiJSIrbVtvPj4+NCYxNV0rbVtvJjE1XX1yZXR1cm4gcC5jaGFyQ29kZUF0KDAp
-PT0wP3A6cH0sCkdxOmZ1bmN0aW9uKGEpe3ZhciBzPU1hdGguYWJzKGEpLHI9YTwwPyItIjoiIgppZihz
-Pj0xMDAwKXJldHVybiIiK2EKaWYocz49MTAwKXJldHVybiByKyIwIitzCmlmKHM+PTEwKXJldHVybiBy
-KyIwMCIrcwpyZXR1cm4gcisiMDAwIitzfSwKVng6ZnVuY3Rpb24oYSl7aWYoYT49MTAwKXJldHVybiIi
-K2EKaWYoYT49MTApcmV0dXJuIjAiK2EKcmV0dXJuIjAwIithfSwKaDA6ZnVuY3Rpb24oYSl7aWYoYT49
-MTApcmV0dXJuIiIrYQpyZXR1cm4iMCIrYX0sCmhsOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVt
-YmVyInx8SC5sKGEpfHxudWxsPT1hKXJldHVybiBKLmooYSkKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJl
-dHVybiBKU09OLnN0cmluZ2lmeShhKQpyZXR1cm4gUC5vcyhhKX0sCmhWOmZ1bmN0aW9uKGEpe3JldHVy
-biBuZXcgUC5DNihhKX0sCnhZOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51KCExLG51bGwsbnVsbCxh
-KX0sCkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAudSghMCxhLGIsYyl9LApVSTpmdW5jdGlv
-bihhLGIsYyl7aWYoYT09bnVsbCl0aHJvdyBILmIobmV3IFAudSghMSxudWxsLGIsIk11c3Qgbm90IGJl
-IG51bGwiKSkKcmV0dXJuIGF9LApPNzpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5iSihudWxsLG51
-bGwsITAsYSxiLCJWYWx1ZSBub3QgaW4gcmFuZ2UiKX0sClRFOmZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0
-dXJuIG5ldyBQLmJKKGIsYywhMCxhLGQsIkludmFsaWQgdmFsdWUiKX0sCndBOmZ1bmN0aW9uKGEsYixj
-LGQpe2lmKGE8Ynx8YT5jKXRocm93IEguYihQLlRFKGEsYixjLGQsbnVsbCkpCnJldHVybiBhfSwKakI6
-ZnVuY3Rpb24oYSxiLGMpe2lmKDA+YXx8YT5jKXRocm93IEguYihQLlRFKGEsMCxjLCJzdGFydCIsbnVs
-bCkpCmlmKGIhPW51bGwpe2lmKGE+Ynx8Yj5jKXRocm93IEguYihQLlRFKGIsYSxjLCJlbmQiLG51bGwp
-KQpyZXR1cm4gYn1yZXR1cm4gY30sCmsxOmZ1bmN0aW9uKGEsYil7aWYoYTwwKXRocm93IEguYihQLlRF
-KGEsMCxudWxsLGIsbnVsbCkpCnJldHVybiBhfSwKQ2Y6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcz1I
-LnVQKGU9PW51bGw/Si5IbShiKTplKQpyZXR1cm4gbmV3IFAuZVkocywhMCxhLGMsIkluZGV4IG91dCBv
-ZiByYW5nZSIpfSwKTDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnViKGEpfSwKU1k6ZnVuY3Rpb24o
-YSl7cmV0dXJuIG5ldyBQLmRzKGEpfSwKUFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmxqKGEpfSwK
-YTQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlVWKGEpfSwKcnI6ZnVuY3Rpb24oYSxiLGMpe3JldHVy
-biBuZXcgUC5hRShhLGIsYyl9LApoSzpmdW5jdGlvbihhNSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGos
-aSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTM9bnVsbCxhND1hNS5sZW5ndGgKaWYoYTQ+PTUpe3M9
-KChKLlF6KGE1LDQpXjU4KSozfEMueEIuVyhhNSwwKV4xMDB8Qy54Qi5XKGE1LDEpXjk3fEMueEIuVyhh
-NSwyKV4xMTZ8Qy54Qi5XKGE1LDMpXjk3KT4+PjAKaWYocz09PTApcmV0dXJuIFAuS0QoYTQ8YTQ/Qy54
-Qi5OaihhNSwwLGE0KTphNSw1LGEzKS5nbFIoKQplbHNlIGlmKHM9PT0zMilyZXR1cm4gUC5LRChDLnhC
-Lk5qKGE1LDUsYTQpLDAsYTMpLmdsUigpfXI9UC5POCg4LDAsITEsdC5TKQpDLk5tLlkociwwLDApCkMu
-Tm0uWShyLDEsLTEpCkMuTm0uWShyLDIsLTEpCkMuTm0uWShyLDcsLTEpCkMuTm0uWShyLDMsMCkKQy5O
-bS5ZKHIsNCwwKQpDLk5tLlkociw1LGE0KQpDLk5tLlkociw2LGE0KQppZihQLlVCKGE1LDAsYTQsMCxy
-KT49MTQpQy5ObS5ZKHIsNyxhNCkKcT1yWzFdCmlmKHE+PTApaWYoUC5VQihhNSwwLHEsMjAscik9PT0y
-MClyWzddPXEKcD1yWzJdKzEKbz1yWzNdCm49cls0XQptPXJbNV0KbD1yWzZdCmlmKGw8bSltPWwKaWYo
-bjxwKW49bQplbHNlIGlmKG48PXEpbj1xKzEKaWYobzxwKW89bgprPXJbN108MAppZihrKWlmKHA+cSsz
-KXtqPWEzCms9ITF9ZWxzZXtpPW8+MAppZihpJiZvKzE9PT1uKXtqPWEzCms9ITF9ZWxzZXtpZighKG08
-YTQmJm09PT1uKzImJkoucTAoYTUsIi4uIixuKSkpaD1tPm4rMiYmSi5xMChhNSwiLy4uIixtLTMpCmVs
-c2UgaD0hMAppZihoKXtqPWEzCms9ITF9ZWxzZXtpZihxPT09NClpZihKLnEwKGE1LCJmaWxlIiwwKSl7
-aWYocDw9MCl7aWYoIUMueEIuUWkoYTUsIi8iLG4pKXtnPSJmaWxlOi8vLyIKcz0zfWVsc2V7Zz0iZmls
-ZTovLyIKcz0yfWE1PWcrQy54Qi5OaihhNSxuLGE0KQpxLT0wCmk9cy0wCm0rPWkKbCs9aQphND1hNS5s
-ZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihuPT09bSl7KytsCmY9bSsxCmE1PUMueEIuaTcoYTUsbixt
-LCIvIik7KythNAptPWZ9aj0iZmlsZSJ9ZWxzZSBpZihDLnhCLlFpKGE1LCJodHRwIiwwKSl7aWYoaSYm
-byszPT09biYmQy54Qi5RaShhNSwiODAiLG8rMSkpe2wtPTMKZT1uLTMKbS09MwphNT1DLnhCLmk3KGE1
-LG8sbiwiIikKYTQtPTMKbj1lfWo9Imh0dHAifWVsc2Ugaj1hMwplbHNlIGlmKHE9PT01JiZKLnEwKGE1
-LCJodHRwcyIsMCkpe2lmKGkmJm8rND09PW4mJkoucTAoYTUsIjQ0MyIsbysxKSl7bC09NAplPW4tNApt
-LT00CmE1PUouZGcoYTUsbyxuLCIiKQphNC09MwpuPWV9aj0iaHR0cHMifWVsc2Ugaj1hMwprPSEwfX19
-ZWxzZSBqPWEzCmlmKGspe2k9YTUubGVuZ3RoCmlmKGE0PGkpe2E1PUoubGQoYTUsMCxhNCkKcS09MApw
-LT0wCm8tPTAKbi09MAptLT0wCmwtPTB9cmV0dXJuIG5ldyBQLlVmKGE1LHEscCxvLG4sbSxsLGopfWlm
-KGo9PW51bGwpaWYocT4wKWo9UC5QaShhNSwwLHEpCmVsc2V7aWYocT09PTApe1AuUjMoYTUsMCwiSW52
-YWxpZCBlbXB0eSBzY2hlbWUiKQpILkJpKHUuZyl9aj0iIn1pZihwPjApe2Q9cSszCmM9ZDxwP1AuelIo
-YTUsZCxwLTEpOiIiCmI9UC5PZShhNSxwLG8sITEpCmk9bysxCmlmKGk8bil7YT1ILkhwKEoubGQoYTUs
-aSxuKSxhMykKYTA9UC53QihhPT1udWxsP0gudihQLnJyKCJJbnZhbGlkIHBvcnQiLGE1LGkpKTphLGop
-fWVsc2UgYTA9YTN9ZWxzZXthMD1hMwpiPWEwCmM9IiJ9YTE9UC5rYShhNSxuLG0sYTMsaixiIT1udWxs
-KQphMj1tPGw/UC5sZShhNSxtKzEsbCxhMyk6YTMKcmV0dXJuIG5ldyBQLkRuKGosYyxiLGEwLGExLGEy
-LGw8YTQ/UC50RyhhNSxsKzEsYTQpOmEzKX0sCk10OmZ1bmN0aW9uKGEpe0guaChhKQpyZXR1cm4gUC5r
-dShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpmdW5jdGlvbihhKXt2YXIgcz10Lk4KcmV0dXJuIEMu
-Tm0uTjAoSC5WTShhLnNwbGl0KCImIiksdC5zKSxQLkZsKHMscyksbmV3IFAubjEoQy54TSksdC5KKX0s
-CkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbT0iSVB2NCBhZGRyZXNzIHNob3VsZCBj
-b250YWluIGV4YWN0bHkgNCBwYXJ0cyIsbD0iZWFjaCBwYXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIDAu
-LjI1NSIsaz1uZXcgUC5jUyhhKSxqPW5ldyBVaW50OEFycmF5KDQpCmZvcihzPWIscj1zLHE9MDtzPGM7
-KytzKXtwPUMueEIuTzIoYSxzKQppZihwIT09NDYpe2lmKChwXjQ4KT45KWsuJDIoImludmFsaWQgY2hh
-cmFjdGVyIixzKX1lbHNle2lmKHE9PT0zKWsuJDIobSxzKQpvPVAuUUEoQy54Qi5OaihhLHIscyksbnVs
-bCkKaWYobz4yNTUpay4kMihsLHIpCm49cSsxCmlmKHE+PTQpcmV0dXJuIEguT0goaixxKQpqW3FdPW8K
-cj1zKzEKcT1ufX1pZihxIT09MylrLiQyKG0sYykKbz1QLlFBKEMueEIuTmooYSxyLGMpLG51bGwpCmlm
-KG8+MjU1KWsuJDIobCxyKQppZihxPj00KXJldHVybiBILk9IKGoscSkKaltxXT1vCnJldHVybiBqfSwK
-ZWc6ZnVuY3Rpb24oYSxiLGEwKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZD1uZXcg
-UC5WQyhhKSxjPW5ldyBQLkpUKGQsYSkKaWYoYS5sZW5ndGg8MilkLiQxKCJhZGRyZXNzIGlzIHRvbyBz
-aG9ydCIpCnM9SC5WTShbXSx0LmEpCmZvcihyPWIscT1yLHA9ITEsbz0hMTtyPGEwOysrcil7bj1DLnhC
-Lk8yKGEscikKaWYobj09PTU4KXtpZihyPT09Yil7KytyCmlmKEMueEIuTzIoYSxyKSE9PTU4KWQuJDIo
-ImludmFsaWQgc3RhcnQgY29sb24uIixyKQpxPXJ9aWYocj09PXEpe2lmKHApZC4kMigib25seSBvbmUg
-d2lsZGNhcmQgYDo6YCBpcyBhbGxvd2VkIixyKQpDLk5tLmkocywtMSkKcD0hMH1lbHNlIEMuTm0uaShz
-LGMuJDIocSxyKSkKcT1yKzF9ZWxzZSBpZihuPT09NDYpbz0hMH1pZihzLmxlbmd0aD09PTApZC4kMSgi
-dG9vIGZldyBwYXJ0cyIpCm09cT09PWEwCmw9Qy5ObS5ncloocykKaWYobSYmbCE9PS0xKWQuJDIoImV4
-cGVjdGVkIGEgcGFydCBhZnRlciBsYXN0IGA6YCIsYTApCmlmKCFtKWlmKCFvKUMuTm0uaShzLGMuJDIo
-cSxhMCkpCmVsc2V7az1QLkhoKGEscSxhMCkKQy5ObS5pKHMsKGtbMF08PDh8a1sxXSk+Pj4wKQpDLk5t
-Lmkocywoa1syXTw8OHxrWzNdKT4+PjApfWlmKHApe2lmKHMubGVuZ3RoPjcpZC4kMSgiYW4gYWRkcmVz
-cyB3aXRoIGEgd2lsZGNhcmQgbXVzdCBoYXZlIGxlc3MgdGhhbiA3IHBhcnRzIil9ZWxzZSBpZihzLmxl
-bmd0aCE9PTgpZC4kMSgiYW4gYWRkcmVzcyB3aXRob3V0IGEgd2lsZGNhcmQgbXVzdCBjb250YWluIGV4
-YWN0bHkgOCBwYXJ0cyIpCmo9bmV3IFVpbnQ4QXJyYXkoMTYpCmZvcihsPXMubGVuZ3RoLGk9OS1sLHI9
-MCxoPTA7cjxsOysrcil7Zz1zW3JdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8aTsrK2Ype2lmKGg8MHx8aD49
-MTYpcmV0dXJuIEguT0goaixoKQpqW2hdPTAKZT1oKzEKaWYoZT49MTYpcmV0dXJuIEguT0goaixlKQpq
-W2VdPTAKaCs9Mn1lbHNle2U9Qy5qbi53RyhnLDgpCmlmKGg8MHx8aD49MTYpcmV0dXJuIEguT0goaixo
-KQpqW2hdPWUKZT1oKzEKaWYoZT49MTYpcmV0dXJuIEguT0goaixlKQpqW2VdPWcmMjU1CmgrPTJ9fXJl
-dHVybiBqfSwKS0w6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuCmY9Zj09bnVs
-bD8iIjpQLlBpKGYsMCxmLmxlbmd0aCkKZz1QLnpSKGcsMCxnPT1udWxsPzA6Zy5sZW5ndGgpCmE9UC5P
-ZShhLDAsYT09bnVsbD8wOmEubGVuZ3RoLCExKQpzPVAubGUobnVsbCwwLDAsZSkKcj1QLnRHKG51bGws
-MCwwKQpkPVAud0IoZCxmKQpxPWY9PT0iZmlsZSIKaWYoYT09bnVsbClwPWcubGVuZ3RoIT09MHx8ZCE9
-bnVsbHx8cQplbHNlIHA9ITEKaWYocClhPSIiCnA9YT09bnVsbApvPSFwCmI9UC5rYShiLDAsYj09bnVs
-bD8wOmIubGVuZ3RoLGMsZixvKQpuPWYubGVuZ3RoPT09MAppZihuJiZwJiYhQy54Qi5uKGIsIi8iKSli
-PVAud0YoYiwhbnx8bykKZWxzZSBiPVAueGUoYikKcmV0dXJuIG5ldyBQLkRuKGYsZyxwJiZDLnhCLm4o
-YiwiLy8iKT8iIjphLGQsYixzLHIpfSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4g
-ODAKaWYoYT09PSJodHRwcyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixjKXt0
-aHJvdyBILmIoUC5ycihjLGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxu
-LG0sbCxrLGosaSxoPW51bGwsZz1iLmxlbmd0aAppZihnIT09MCl7cT0wCndoaWxlKCEwKXtpZighKHE8
-Zykpe3M9IiIKcj0wCmJyZWFrfWlmKEMueEIuVyhiLHEpPT09NjQpe3M9Qy54Qi5OaihiLDAscSkKcj1x
-KzEKYnJlYWt9KytxfWlmKHI8ZyYmQy54Qi5XKGIscik9PT05MSl7Zm9yKHA9cixvPS0xO3A8ZzsrK3Ap
-e249Qy54Qi5XKGIscCkKaWYobj09PTM3JiZvPDApe209Qy54Qi5RaShiLCIyNSIscCsxKT9wKzI6cApv
-PXAKcD1tfWVsc2UgaWYobj09PTkzKWJyZWFrfWlmKHA9PT1nKXRocm93IEguYihQLnJyKCJJbnZhbGlk
-IElQdjYgaG9zdCBlbnRyeS4iLGIscikpCmw9bzwwP3A6bwpQLmVnKGIscisxLGwpOysrcAppZihwIT09
-ZyYmQy54Qi5XKGIscCkhPT01OCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9yaXR5
-IixiLHApKX1lbHNlIHA9cgp3aGlsZSghMCl7aWYoIShwPGcpKXtrPWgKYnJlYWt9aWYoQy54Qi5XKGIs
-cCk9PT01OCl7aj1DLnhCLkcoYixwKzEpCms9ai5sZW5ndGghPT0wP1AuUUEoaixoKTpoCmJyZWFrfSsr
-cH1pPUMueEIuTmooYixyLHApfWVsc2V7az1oCmk9awpzPSIifXJldHVybiBQLktMKGksaCxILlZNKGMu
-c3BsaXQoIi8iKSx0LnMpLGssZCxhLHMpfSwKa0U6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCmZv
-cihzPWEubGVuZ3RoLHI9MDtyPHM7KytyKXtxPWFbcl0KcS50b1N0cmluZwpwPUouVTYocSkKbz1wLmdB
-KHEpCmlmKDA+bylILnYoUC5URSgwLDAscC5nQShxKSxudWxsLG51bGwpKQppZihILlNRKHEsIi8iLDAp
-KXtzPVAuTDQoIklsbGVnYWwgcGF0aCBjaGFyYWN0ZXIgIitILkVqKHEpKQp0aHJvdyBILmIocyl9fX0s
-CkhOOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEKZm9yKHM9SC5xQyhhLGMsbnVsbCxILnQ2KGEpLmMp
-LHM9bmV3IEguYTcocyxzLmdBKHMpLHMuJHRpLkMoImE3PGFMLkU+IikpO3MuRigpOyl7cj1zLmQKcT1Q
-Lm51KCdbIiovOjw+P1xcXFx8XScpCnIudG9TdHJpbmcKaWYoSC5TUShyLHEsMCkpe3M9UC5MNCgiSWxs
-ZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIityKQp0aHJvdyBILmIocyl9fX0sCnJnOmZ1bmN0aW9uKGEs
-Yil7dmFyIHMKaWYoISg2NTw9YSYmYTw9OTApKXM9OTc8PWEmJmE8PTEyMgplbHNlIHM9ITAKaWYocyly
-ZXR1cm4Kcz1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93IEguYihzKX0s
-CndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51bGwKcmV0dXJu
-IGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4KaWYoYT09bnVsbClyZXR1cm4g
-bnVsbAppZihiPT09YylyZXR1cm4iIgppZihDLnhCLk8yKGEsYik9PT05MSl7cz1jLTEKaWYoQy54Qi5P
-MihhLHMpIT09OTMpe1AuUjMoYSxiLCJNaXNzaW5nIGVuZCBgXWAgdG8gbWF0Y2ggYFtgIGluIGhvc3Qi
-KQpILkJpKHUuZyl9cj1iKzEKcT1QLnRvKGEscixzKQppZihxPHMpe3A9cSsxCm89UC5PQShhLEMueEIu
-UWkoYSwiMjUiLHApP3ErMzpwLHMsIiUyNSIpfWVsc2Ugbz0iIgpQLmVnKGEscixxKQpyZXR1cm4gQy54
-Qi5OaihhLGIscSkudG9Mb3dlckNhc2UoKStvKyJdIn1mb3Iobj1iO248YzsrK24paWYoQy54Qi5PMihh
-LG4pPT09NTgpe3E9Qy54Qi5YVShhLCIlIixiKQpxPXE+PWImJnE8Yz9xOmMKaWYocTxjKXtwPXErMQpv
-PVAuT0EoYSxDLnhCLlFpKGEsIjI1IixwKT9xKzM6cCxjLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLGIs
-cSkKcmV0dXJuIlsiK0MueEIuTmooYSxiLHEpK28rIl0ifXJldHVybiBQLk9MKGEsYixjKX0sCnRvOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcz1DLnhCLlhVKGEsIiUiLGIpCnJldHVybiBzPj1iJiZzPGM/czpjfSwK
-T0E6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaT1kIT09IiI/bmV3IFAu
-Um4oZCk6bnVsbApmb3Iocz1iLHI9cyxxPSEwO3M8Yzspe3A9Qy54Qi5PMihhLHMpCmlmKHA9PT0zNyl7
-bz1QLnJ2KGEscywhMCkKbj1vPT1udWxsCmlmKG4mJnEpe3MrPTMKY29udGludWV9aWYoaT09bnVsbClp
-PW5ldyBQLlJuKCIiKQptPWkuYSs9Qy54Qi5OaihhLHIscykKaWYobilvPUMueEIuTmooYSxzLHMrMykK
-ZWxzZSBpZihvPT09IiUiKXtQLlIzKGEscywiWm9uZUlEIHNob3VsZCBub3QgY29udGFpbiAlIGFueW1v
-cmUiKQpILkJpKHUuZyl9aS5hPW0rbwpzKz0zCnI9cwpxPSEwfWVsc2V7aWYocDwxMjcpe249cD4+PjQK
-aWYobj49OClyZXR1cm4gSC5PSChDLkYzLG4pCm49KEMuRjNbbl0mMTw8KHAmMTUpKSE9PTB9ZWxzZSBu
-PSExCmlmKG4pe2lmKHEmJjY1PD1wJiY5MD49cCl7aWYoaT09bnVsbClpPW5ldyBQLlJuKCIiKQppZihy
-PHMpe2kuYSs9Qy54Qi5OaihhLHIscykKcj1zfXE9ITF9KytzfWVsc2V7aWYoKHAmNjQ1MTIpPT09NTUy
-OTYmJnMrMTxjKXtsPUMueEIuTzIoYSxzKzEpCmlmKChsJjY0NTEyKT09PTU2MzIwKXtwPShwJjEwMjMp
-PDwxMHxsJjEwMjN8NjU1MzYKaz0yfWVsc2Ugaz0xfWVsc2Ugaz0xCmo9Qy54Qi5OaihhLHIscykKaWYo
-aT09bnVsbCl7aT1uZXcgUC5SbigiIikKbj1pfWVsc2Ugbj1pCm4uYSs9agpuLmErPVAuelgocCkKcys9
-awpyPXN9fX1pZihpPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihyPGMpaS5hKz1DLnhCLk5q
-KGEscixjKQpuPWkuYQpyZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sCk9MOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpCmZvcihzPWIscj1zLHE9bnVsbCxwPSEwO3M8Yzsp
-e289Qy54Qi5PMihhLHMpCmlmKG89PT0zNyl7bj1QLnJ2KGEscywhMCkKbT1uPT1udWxsCmlmKG0mJnAp
-e3MrPTMKY29udGludWV9aWYocT09bnVsbClxPW5ldyBQLlJuKCIiKQpsPUMueEIuTmooYSxyLHMpCms9
-cS5hKz0hcD9sLnRvTG93ZXJDYXNlKCk6bAppZihtKXtuPUMueEIuTmooYSxzLHMrMykKaj0zfWVsc2Ug
-aWYobj09PSIlIil7bj0iJTI1IgpqPTF9ZWxzZSBqPTMKcS5hPWsrbgpzKz1qCnI9cwpwPSEwfWVsc2V7
-aWYobzwxMjcpe209bz4+PjQKaWYobT49OClyZXR1cm4gSC5PSChDLmVhLG0pCm09KEMuZWFbbV0mMTw8
-KG8mMTUpKSE9PTB9ZWxzZSBtPSExCmlmKG0pe2lmKHAmJjY1PD1vJiY5MD49byl7aWYocT09bnVsbClx
-PW5ldyBQLlJuKCIiKQppZihyPHMpe3EuYSs9Qy54Qi5OaihhLHIscykKcj1zfXA9ITF9KytzfWVsc2V7
-aWYobzw9OTMpe209bz4+PjQKaWYobT49OClyZXR1cm4gSC5PSChDLmFrLG0pCm09KEMuYWtbbV0mMTw8
-KG8mMTUpKSE9PTB9ZWxzZSBtPSExCmlmKG0pe1AuUjMoYSxzLCJJbnZhbGlkIGNoYXJhY3RlciIpCkgu
-QmkodS5nKX1lbHNle2lmKChvJjY0NTEyKT09PTU1Mjk2JiZzKzE8Yyl7aT1DLnhCLk8yKGEscysxKQpp
-ZigoaSY2NDUxMik9PT01NjMyMCl7bz0obyYxMDIzKTw8MTB8aSYxMDIzfDY1NTM2Cmo9Mn1lbHNlIGo9
-MX1lbHNlIGo9MQpsPUMueEIuTmooYSxyLHMpCmlmKCFwKWw9bC50b0xvd2VyQ2FzZSgpCmlmKHE9PW51
-bGwpe3E9bmV3IFAuUm4oIiIpCm09cX1lbHNlIG09cQptLmErPWwKbS5hKz1QLnpYKG8pCnMrPWoKcj1z
-fX19fWlmKHE9PW51bGwpcmV0dXJuIEMueEIuTmooYSxiLGMpCmlmKHI8Yyl7bD1DLnhCLk5qKGEscixj
-KQpxLmErPSFwP2wudG9Mb3dlckNhc2UoKTpsfW09cS5hCnJldHVybiBtLmNoYXJDb2RlQXQoMCk9PTA/
-bTptfSwKUGk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89dS5nCmlmKGI9PT1jKXJldHVybiIi
-CmlmKCFQLkV0KEouclkoYSkuVyhhLGIpKSl7UC5SMyhhLGIsIlNjaGVtZSBub3Qgc3RhcnRpbmcgd2l0
-aCBhbHBoYWJldGljIGNoYXJhY3RlciIpCkguQmkobyl9Zm9yKHM9YixyPSExO3M8YzsrK3Mpe3E9Qy54
-Qi5XKGEscykKaWYocTwxMjgpe3A9cT4+PjQKaWYocD49OClyZXR1cm4gSC5PSChDLm1LLHApCnA9KEMu
-bUtbcF0mMTw8KHEmMTUpKSE9PTB9ZWxzZSBwPSExCmlmKCFwKXtQLlIzKGEscywiSWxsZWdhbCBzY2hl
-bWUgY2hhcmFjdGVyIikKSC5CaShvKX1pZig2NTw9cSYmcTw9OTApcj0hMH1hPUMueEIuTmooYSxiLGMp
-CnJldHVybiBQLllhKHI/YS50b0xvd2VyQ2FzZSgpOmEpfSwKWWE6ZnVuY3Rpb24oYSl7aWYoYT09PSJo
-dHRwIilyZXR1cm4iaHR0cCIKaWYoYT09PSJmaWxlIilyZXR1cm4iZmlsZSIKaWYoYT09PSJodHRwcyIp
-cmV0dXJuImh0dHBzIgppZihhPT09InBhY2thZ2UiKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gYX0sCnpS
-OmZ1bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXJldHVybiIiCnJldHVybiBQLlBJKGEsYixjLEMudG8s
-ITEpfSwKa2E6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciBzLHIscT1lPT09ImZpbGUiLHA9cXx8Zgpp
-ZihhPT1udWxsKXtpZihkPT1udWxsKXJldHVybiBxPyIvIjoiIgpzPUgudDYoZCkKcj1uZXcgSC5sSihk
-LHMuQygicVUoMSkiKS5hKG5ldyBQLlJaKCkpLHMuQygibEo8MSxxVT4iKSkuSCgwLCIvIil9ZWxzZSBp
-ZihkIT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHBhdGggYW5kIHBhdGhTZWdtZW50cyBzcGVjaWZp
-ZWQiKSkKZWxzZSByPVAuUEkoYSxiLGMsQy5XZCwhMCkKaWYoci5sZW5ndGg9PT0wKXtpZihxKXJldHVy
-biIvIn1lbHNlIGlmKHAmJiFDLnhCLm4ociwiLyIpKXI9Ii8iK3IKcmV0dXJuIFAuSnIocixlLGYpfSwK
-SnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPWIubGVuZ3RoPT09MAppZihzJiYhYyYmIUMueEIubihhLCIv
-IikpcmV0dXJuIFAud0YoYSwhc3x8YykKcmV0dXJuIFAueGUoYSl9LApsZTpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgcyxyPXt9CmlmKGEhPW51bGwpe2lmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJvdGggcXVl
-cnkgYW5kIHF1ZXJ5UGFyYW1ldGVycyBzcGVjaWZpZWQiKSkKcmV0dXJuIFAuUEkoYSxiLGMsQy5WQywh
-MCl9aWYoZD09bnVsbClyZXR1cm4gbnVsbApzPW5ldyBQLlJuKCIiKQpyLmE9IiIKZC5LKDAsbmV3IFAu
-eTUobmV3IFAuTUUocixzKSkpCnI9cy5hCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfSwKdEc6
-ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFAuUEkoYSxiLGMsQy5W
-QywhMCl9LApydjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuPWIrMgppZihuPj1hLmxlbmd0
-aClyZXR1cm4iJSIKcz1DLnhCLk8yKGEsYisxKQpyPUMueEIuTzIoYSxuKQpxPUgub28ocykKcD1ILm9v
-KHIpCmlmKHE8MHx8cDwwKXJldHVybiIlIgpvPXEqMTYrcAppZihvPDEyNyl7bj1DLmpuLndHKG8sNCkK
-aWYobj49OClyZXR1cm4gSC5PSChDLkYzLG4pCm49KEMuRjNbbl0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBu
-PSExCmlmKG4pcmV0dXJuIEguTHcoYyYmNjU8PW8mJjkwPj1vPyhvfDMyKT4+PjA6bykKaWYocz49OTd8
-fHI+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51bGx9LAp6
-WDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9IjAxMjM0NTY3ODlBQkNERUYiCmlmKGE8
-MTI4KXtzPW5ldyBVaW50OEFycmF5KDMpCnNbMF09MzcKc1sxXT1DLnhCLlcoayxhPj4+NCkKc1syXT1D
-LnhCLlcoayxhJjE1KX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0MApxPTR9ZWxzZXtyPTIy
-NApxPTN9ZWxzZXtyPTE5MgpxPTJ9cD0zKnEKcz1uZXcgVWludDhBcnJheShwKQpmb3Iobz0wOy0tcSxx
-Pj0wO3I9MTI4KXtuPUMuam4uYmYoYSw2KnEpJjYzfHIKaWYobz49cClyZXR1cm4gSC5PSChzLG8pCnNb
-b109MzcKbT1vKzEKbD1DLnhCLlcoayxuPj4+NCkKaWYobT49cClyZXR1cm4gSC5PSChzLG0pCnNbbV09
-bApsPW8rMgptPUMueEIuVyhrLG4mMTUpCmlmKGw+PXApcmV0dXJuIEguT0gocyxsKQpzW2xdPW0Kbys9
-M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcz1QLlVs
-KGEsYixjLGQsZSkKcmV0dXJuIHM9PW51bGw/Qy54Qi5OaihhLGIsYyk6c30sClVsOmZ1bmN0aW9uKGEs
-YixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9bnVsbApmb3Iocz0hZSxyPWIscT1yLHA9ajty
-PGM7KXtvPUMueEIuTzIoYSxyKQppZihvPDEyNyl7bj1vPj4+NAppZihuPj04KXJldHVybiBILk9IKGQs
-bikKbj0oZFtuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobikrK3IKZWxzZXtpZihvPT09Mzcp
-e209UC5ydihhLHIsITEpCmlmKG09PW51bGwpe3IrPTMKY29udGludWV9aWYoIiUiPT09bSl7bT0iJTI1
-IgpsPTF9ZWxzZSBsPTN9ZWxzZXtpZihzKWlmKG88PTkzKXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEgu
-T0goQy5hayxuKQpuPShDLmFrW25dJjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQplbHNlIG49ITEKaWYo
-bil7UC5SMyhhLHIsIkludmFsaWQgY2hhcmFjdGVyIikKSC5CaSh1LmcpCmw9agptPWx9ZWxzZXtpZigo
-byY2NDUxMik9PT01NTI5Nil7bj1yKzEKaWYobjxjKXtrPUMueEIuTzIoYSxuKQppZigoayY2NDUxMik9
-PT01NjMyMCl7bz0obyYxMDIzKTw8MTB8ayYxMDIzfDY1NTM2Cmw9Mn1lbHNlIGw9MX1lbHNlIGw9MX1l
-bHNlIGw9MQptPVAuelgobyl9fWlmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCm49cH1lbHNlIG49cApu
-LmErPUMueEIuTmooYSxxLHIpCm4uYSs9SC5FaihtKQppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVy
-biBILnBZKGwpCnIrPWwKcT1yfX1pZihwPT1udWxsKXJldHVybiBqCmlmKHE8YylwLmErPUMueEIuTmoo
-YSxxLGMpCnM9cC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKeUI6ZnVuY3Rpb24oYSl7
-aWYoQy54Qi5uKGEsIi4iKSlyZXR1cm4hMApyZXR1cm4gQy54Qi5PWShhLCIvLiIpIT09LTF9LAp4ZTpm
-dW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbQppZighUC55QihhKSlyZXR1cm4gYQpzPUguVk0oW10s
-dC5zKQpmb3Iocj1hLnNwbGl0KCIvIikscT1yLmxlbmd0aCxwPSExLG89MDtvPHE7KytvKXtuPXJbb10K
-aWYoSi5STShuLCIuLiIpKXttPXMubGVuZ3RoCmlmKG0hPT0wKXtpZigwPj1tKXJldHVybiBILk9IKHMs
-LTEpCnMucG9wKCkKaWYocy5sZW5ndGg9PT0wKUMuTm0uaShzLCIiKX1wPSEwfWVsc2UgaWYoIi4iPT09
-bilwPSEwCmVsc2V7Qy5ObS5pKHMsbikKcD0hMX19aWYocClDLk5tLmkocywiIikKcmV0dXJuIEMuTm0u
-SChzLCIvIil9LAp3RjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbgppZighUC55QihhKSlyZXR1
-cm4hYj9QLkMxKGEpOmEKcz1ILlZNKFtdLHQucykKZm9yKHI9YS5zcGxpdCgiLyIpLHE9ci5sZW5ndGgs
-cD0hMSxvPTA7bzxxOysrbyl7bj1yW29dCmlmKCIuLiI9PT1uKWlmKHMubGVuZ3RoIT09MCYmQy5ObS5n
-cloocykhPT0iLi4iKXtpZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnA9ITB9
-ZWxzZXtDLk5tLmkocywiLi4iKQpwPSExfWVsc2UgaWYoIi4iPT09bilwPSEwCmVsc2V7Qy5ObS5pKHMs
-bikKcD0hMX19cj1zLmxlbmd0aAppZihyIT09MClpZihyPT09MSl7aWYoMD49cilyZXR1cm4gSC5PSChz
-LDApCnI9c1swXS5sZW5ndGg9PT0wfWVsc2Ugcj0hMQplbHNlIHI9ITAKaWYocilyZXR1cm4iLi8iCmlm
-KHB8fEMuTm0uZ3JaKHMpPT09Ii4uIilDLk5tLmkocywiIikKaWYoIWIpe2lmKDA+PXMubGVuZ3RoKXJl
-dHVybiBILk9IKHMsMCkKQy5ObS5ZKHMsMCxQLkMxKHNbMF0pKX1yZXR1cm4gQy5ObS5IKHMsIi8iKX0s
-CkMxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVuZ3RoCmlmKHA+PTImJlAuRXQoSi5ReihhLDAp
-KSlmb3Iocz0xO3M8cDsrK3Mpe3I9Qy54Qi5XKGEscykKaWYocj09PTU4KXJldHVybiBDLnhCLk5qKGEs
-MCxzKSsiJTNBIitDLnhCLkcoYSxzKzEpCmlmKHI8PTEyNyl7cT1yPj4+NAppZihxPj04KXJldHVybiBI
-Lk9IKEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpPT09MH1lbHNlIHE9ITAKaWYocSlicmVha31y
-ZXR1cm4gYX0sCm1uOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEuZ0ZqKCksbz1wLmxlbmd0aAppZihv
-PjAmJkouSG0ocFswXSk9PT0yJiZKLmE2KHBbMF0sMSk9PT01OCl7aWYoMD49bylyZXR1cm4gSC5PSChw
-LDApClAucmcoSi5hNihwWzBdLDApLCExKQpQLkhOKHAsITEsMSkKcz0hMH1lbHNle1AuSE4ocCwhMSww
-KQpzPSExfXI9YS5ndFQoKSYmIXM/IlxcIjoiIgppZihhLmdjaigpKXtxPWEuZ0pmKGEpCmlmKHEubGVu
-Z3RoIT09MClyPXIrIlxcIitxKyJcXCJ9cj1QLnZnKHIscCwiXFwiKQpvPXMmJm89PT0xP3IrIlxcIjpy
-CnJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKSWg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEK
-Zm9yKHM9MCxyPTA7cjwyOysrcil7cT1DLnhCLlcoYSxiK3IpCmlmKDQ4PD1xJiZxPD01NylzPXMqMTYr
-cS00OAplbHNle3F8PTMyCmlmKDk3PD1xJiZxPD0xMDIpcz1zKjE2K3EtODcKZWxzZSB0aHJvdyBILmIo
-UC54WSgiSW52YWxpZCBVUkwgZW5jb2RpbmciKSl9fXJldHVybiBzfSwKa3U6ZnVuY3Rpb24oYSxiLGMs
-ZCxlKXt2YXIgcyxyLHEscCxvPUouclkoYSksbj1iCndoaWxlKCEwKXtpZighKG48Yykpe3M9ITAKYnJl
-YWt9cj1vLlcoYSxuKQppZihyPD0xMjcpaWYociE9PTM3KXE9ZSYmcj09PTQzCmVsc2UgcT0hMAplbHNl
-IHE9ITAKaWYocSl7cz0hMQpicmVha30rK259aWYocyl7aWYoQy54TSE9PWQpcT0hMQplbHNlIHE9ITAK
-aWYocSlyZXR1cm4gby5OaihhLGIsYykKZWxzZSBwPW5ldyBILnFqKG8uTmooYSxiLGMpKX1lbHNle3A9
-SC5WTShbXSx0LmEpCmZvcihuPWI7bjxjOysrbil7cj1vLlcoYSxuKQppZihyPjEyNyl0aHJvdyBILmIo
-UC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihyPT09Mzcpe2lmKG4rMz5h
-Lmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocCxQLkloKGEsbisx
-KSkKbis9Mn1lbHNlIGlmKGUmJnI9PT00MylDLk5tLmkocCwzMikKZWxzZSBDLk5tLmkocCxyKX19dC5M
-LmEocCkKcmV0dXJuIEMub0UuV0oocCl9LApFdDpmdW5jdGlvbihhKXt2YXIgcz1hfDMyCnJldHVybiA5
-Nzw9cyYmczw9MTIyfSwKS0Q6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtLGwsaz0iSW52
-YWxpZCBNSU1FIHR5cGUiLGo9SC5WTShbYi0xXSx0LmEpCmZvcihzPWEubGVuZ3RoLHI9YixxPS0xLHA9
-bnVsbDtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT00NHx8cD09PTU5KWJyZWFrCmlmKHA9PT00
-Nyl7aWYocTwwKXtxPXIKY29udGludWV9dGhyb3cgSC5iKFAucnIoayxhLHIpKX19aWYocTwwJiZyPmIp
-dGhyb3cgSC5iKFAucnIoayxhLHIpKQpmb3IoO3AhPT00NDspe0MuTm0uaShqLHIpOysrcgpmb3Iobz0t
-MTtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT02MSl7aWYobzwwKW89cn1lbHNlIGlmKHA9PT01
-OXx8cD09PTQ0KWJyZWFrfWlmKG8+PTApQy5ObS5pKGosbykKZWxzZXtuPUMuTm0uZ3JaKGopCmlmKHAh
-PT00NHx8ciE9PW4rN3x8IUMueEIuUWkoYSwiYmFzZTY0IixuKzEpKXRocm93IEguYihQLnJyKCJFeHBl
-Y3RpbmcgJz0nIixhLHIpKQpicmVha319Qy5ObS5pKGoscikKbT1yKzEKaWYoKGoubGVuZ3RoJjEpPT09
-MSlhPUMuaDkueXIoYSxtLHMpCmVsc2V7bD1QLlVsKGEsbSxzLEMuVkMsITApCmlmKGwhPW51bGwpYT1D
-LnhCLmk3KGEsbSxzLGwpfXJldHVybiBuZXcgUC5QRShhLGosYyl9LApLTjpmdW5jdGlvbigpe3ZhciBz
-PSIwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2
-d3h5ei0uX34hJCYnKCkqKyw7PSIscj0iLiIscT0iOiIscD0iLyIsbz0iPyIsbj0iIyIsbT10LmdjLGw9
-UC5kSCgyMixuZXcgUC5xMygpLG0pLGs9bmV3IFAueUkobCksaj1uZXcgUC5jNigpLGk9bmV3IFAucWQo
-KSxoPW0uYShrLiQyKDAsMjI1KSkKai4kMyhoLHMsMSkKai4kMyhoLHIsMTQpCmouJDMoaCxxLDM0KQpq
-LiQzKGgscCwzKQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkKaD1tLmEoay4kMigxNCwyMjUpKQpq
-LiQzKGgscywxKQpqLiQzKGgsciwxNSkKai4kMyhoLHEsMzQpCmouJDMoaCxwLDIzNCkKai4kMyhoLG8s
-MTcyKQpqLiQzKGgsbiwyMDUpCmg9bS5hKGsuJDIoMTUsMjI1KSkKai4kMyhoLHMsMSkKai4kMyhoLCIl
-IiwyMjUpCmouJDMoaCxxLDM0KQpqLiQzKGgscCw5KQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkK
-aD1tLmEoay4kMigxLDIyNSkpCmouJDMoaCxzLDEpCmouJDMoaCxxLDM0KQpqLiQzKGgscCwxMCkKai4k
-MyhoLG8sMTcyKQpqLiQzKGgsbiwyMDUpCmg9bS5hKGsuJDIoMiwyMzUpKQpqLiQzKGgscywxMzkpCmou
-JDMoaCxwLDEzMSkKai4kMyhoLHIsMTQ2KQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkKaD1tLmEo
-ay4kMigzLDIzNSkpCmouJDMoaCxzLDExKQpqLiQzKGgscCw2OCkKai4kMyhoLHIsMTgpCmouJDMoaCxv
-LDE3MikKai4kMyhoLG4sMjA1KQpoPW0uYShrLiQyKDQsMjI5KSkKai4kMyhoLHMsNSkKaS4kMyhoLCJB
-WiIsMjI5KQpqLiQzKGgscSwxMDIpCmouJDMoaCwiQCIsNjgpCmouJDMoaCwiWyIsMjMyKQpqLiQzKGgs
-cCwxMzgpCmouJDMoaCxvLDE3MikKai4kMyhoLG4sMjA1KQpoPW0uYShrLiQyKDUsMjI5KSkKai4kMyho
-LHMsNSkKaS4kMyhoLCJBWiIsMjI5KQpqLiQzKGgscSwxMDIpCmouJDMoaCwiQCIsNjgpCmouJDMoaCxw
-LDEzOCkKai4kMyhoLG8sMTcyKQpqLiQzKGgsbiwyMDUpCmg9bS5hKGsuJDIoNiwyMzEpKQppLiQzKGgs
-IjE5Iiw3KQpqLiQzKGgsIkAiLDY4KQpqLiQzKGgscCwxMzgpCmouJDMoaCxvLDE3MikKai4kMyhoLG4s
-MjA1KQpoPW0uYShrLiQyKDcsMjMxKSkKaS4kMyhoLCIwOSIsNykKai4kMyhoLCJAIiw2OCkKai4kMyho
-LHAsMTM4KQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkKai4kMyhtLmEoay4kMig4LDgpKSwiXSIs
-NSkKaD1tLmEoay4kMig5LDIzNSkpCmouJDMoaCxzLDExKQpqLiQzKGgsciwxNikKai4kMyhoLHAsMjM0
-KQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkKaD1tLmEoay4kMigxNiwyMzUpKQpqLiQzKGgscywx
-MSkKai4kMyhoLHIsMTcpCmouJDMoaCxwLDIzNCkKai4kMyhoLG8sMTcyKQpqLiQzKGgsbiwyMDUpCmg9
-bS5hKGsuJDIoMTcsMjM1KSkKai4kMyhoLHMsMTEpCmouJDMoaCxwLDkpCmouJDMoaCxvLDE3MikKai4k
-MyhoLG4sMjA1KQpoPW0uYShrLiQyKDEwLDIzNSkpCmouJDMoaCxzLDExKQpqLiQzKGgsciwxOCkKai4k
-MyhoLHAsMjM0KQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkKaD1tLmEoay4kMigxOCwyMzUpKQpq
-LiQzKGgscywxMSkKai4kMyhoLHIsMTkpCmouJDMoaCxwLDIzNCkKai4kMyhoLG8sMTcyKQpqLiQzKGgs
-biwyMDUpCmg9bS5hKGsuJDIoMTksMjM1KSkKai4kMyhoLHMsMTEpCmouJDMoaCxwLDIzNCkKai4kMyho
-LG8sMTcyKQpqLiQzKGgsbiwyMDUpCmg9bS5hKGsuJDIoMTEsMjM1KSkKai4kMyhoLHMsMTEpCmouJDMo
-aCxwLDEwKQpqLiQzKGgsbywxNzIpCmouJDMoaCxuLDIwNSkKaD1tLmEoay4kMigxMiwyMzYpKQpqLiQz
-KGgscywxMikKai4kMyhoLG8sMTIpCmouJDMoaCxuLDIwNSkKaD1tLmEoay4kMigxMywyMzcpKQpqLiQz
-KGgscywxMykKai4kMyhoLG8sMTMpCmkuJDMobS5hKGsuJDIoMjAsMjQ1KSksImF6IiwyMSkKaz1tLmEo
-ay4kMigyMSwyNDUpKQppLiQzKGssImF6IiwyMSkKaS4kMyhrLCIwOSIsMjEpCmouJDMoaywiKy0uIiwy
-MSkKcmV0dXJuIGx9LApVQjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxwLG8sbj0kLnZaKCkK
-Zm9yKHM9Si5yWShhKSxyPWI7cjxjOysrcil7bi5sZW5ndGgKaWYoZDwwfHxkPj0yMilyZXR1cm4gSC5P
-SChuLGQpCnE9bltkXQpwPXMuVyhhLHIpXjk2Cm89cVtwPjk1PzMxOnBdCmQ9byYzMQpDLk5tLlkoZSxv
-Pj4+NSxyKX1yZXR1cm4gZH0sCldGOmZ1bmN0aW9uIFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApp
-UDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWFM6ZnVuY3Rpb24gWFMoKXt9LApD
-NjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCkV6OmZ1bmN0aW9uIEV6KCl7fSwKRjpmdW5jdGlvbiBG
-KCl7fSwKdTpmdW5jdGlvbiB1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5k
-PWR9LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9
-YwpfLmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpf
-LmY9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBf
-PXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0s
-CmRzOmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApV
-VjpmdW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24g
-S1koKXt9LApwOmZ1bmN0aW9uIHAoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlzLmE9
-YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmNYOmZ1
-bmN0aW9uIGNYKCl7fSwKQW46ZnVuY3Rpb24gQW4oKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7dGhp
-cy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKTWg6ZnVuY3Rpb24g
-TWgoKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwKbjE6
-ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZDOmZ1
-bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
-Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5j
-PWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PW51bGwKXy55PSExCl8uej1udWxsCl8uUT0hMQpf
-LmNoPW51bGwKXy5jeD0hMQpfLmN5PW51bGwKXy5kYj0hMX0sClJaOmZ1bmN0aW9uIFJaKCl7fSwKTUU6
-ZnVuY3Rpb24gTUUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3RoaXMu
-YT1hfSwKUEU6ZnVuY3Rpb24gUEUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcTM6
-ZnVuY3Rpb24gcTMoKXt9LAp5STpmdW5jdGlvbiB5SShhKXt0aGlzLmE9YX0sCmM2OmZ1bmN0aW9uIGM2
-KCl7fSwKcWQ6ZnVuY3Rpb24gcWQoKXt9LApVZjpmdW5jdGlvbiBVZihhLGIsYyxkLGUsZixnLGgpe3Zh
-ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PWgKXy55
-PW51bGx9LApxZTpmdW5jdGlvbiBxZShhLGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1udWxsCl8ueT0hMQpfLno9bnVsbApfLlE9
-ITEKXy5jaD1udWxsCl8uY3g9ITEKXy5jeT1udWxsCl8uZGI9ITF9LAppSjpmdW5jdGlvbiBpSigpe30s
-CmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApUYTpmdW5jdGlvbiBUYShhLGIp
-e3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6ZnVuY3Rpb24gQmYoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-CkFzOmZ1bmN0aW9uIEFzKCl7fSwKR0U6ZnVuY3Rpb24gR0UoYSl7dGhpcy5hPWF9LApONzpmdW5jdGlv
-biBONyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdVE6ZnVuY3Rpb24gdVEoKXt9LApoRjpmdW5jdGlv
-biBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQpILnk4KGIpCnQuai5hKGQpCmlm
-KEgub1QoYikpe3M9W2NdCkMuTm0uRlYocyxkKQpkPXN9cj10LnoKcT1QLkNIKEouTTEoZCxQLncwKCks
-ciksITAscikKdC5ZLmEoYSkKcmV0dXJuIFAud1koSC5FayhhLHEsbnVsbCkpfSwKRG06ZnVuY3Rpb24o
-YSxiLGMpe3ZhciBzCnRyeXtpZihPYmplY3QuaXNFeHRlbnNpYmxlKGEpJiYhT2JqZWN0LnByb3RvdHlw
-ZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVl
-OmN9KQpyZXR1cm4hMH19Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4hMX0sCk9tOmZ1bmN0aW9uKGEsYil7
-aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpcmV0dXJuIGFbYl0KcmV0
-dXJuIG51bGx9LAp3WTpmdW5jdGlvbihhKXtpZihhPT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5
-cGVvZiBhPT0ibnVtYmVyInx8SC5sKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLkU0KXJldHVy
-biBhLmEKaWYoSC5SOShhKSlyZXR1cm4gYQppZih0LmFrLmIoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5j
-ZW9mIFAuaVApcmV0dXJuIEgubzIoYSkKaWYodC5ZLmIoYSkpcmV0dXJuIFAuaEUoYSwiJGRhcnRfanNG
-dW5jdGlvbiIsbmV3IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwiXyRkYXJ0X2pzT2JqZWN0IixuZXcgUC5t
-dCgkLmtJKCkpKX0sCmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1QLk9tKGEsYikKaWYocz09bnVsbCl7
-cz1jLiQxKGEpClAuRG0oYSxiLHMpfXJldHVybiBzfSwKZFU6ZnVuY3Rpb24oYSl7dmFyIHMscgppZihh
-PT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8dHlwZW9mIGE9PSJi
-b29sZWFuIilyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJkguUjkoYSkpcmV0dXJu
-IGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZ0LmFrLmIoYSkpcmV0dXJuIGEKZWxzZSBpZihh
-IGluc3RhbmNlb2YgRGF0ZSl7cz1ILnVQKGEuZ2V0VGltZSgpKQppZihNYXRoLmFicyhzKTw9ODY0ZTEz
-KXI9ITEKZWxzZSByPSEwCmlmKHIpSC52KFAueFkoIkRhdGVUaW1lIGlzIG91dHNpZGUgdmFsaWQgcmFu
-Z2U6ICIrcykpClAuVUkoITEsImlzVXRjIix0LnkpCnJldHVybiBuZXcgUC5pUChzLCExKX1lbHNlIGlm
-KGEuY29uc3RydWN0b3I9PT0kLmtJKCkpcmV0dXJuIGEubwplbHNlIHJldHVybiBQLk5EKGEpfSwKTkQ6
-ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIFAuaVEoYSwkLncoKSxuZXcg
-UC5OeigpKQppZihhIGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuIFAuaVEoYSwkLlI4KCksbmV3IFAuUVMo
-KSkKcmV0dXJuIFAuaVEoYSwkLlI4KCksbmV3IFAubnAoKSl9LAppUTpmdW5jdGlvbihhLGIsYyl7dmFy
-IHM9UC5PbShhLGIpCmlmKHM9PW51bGx8fCEoYSBpbnN0YW5jZW9mIE9iamVjdCkpe3M9Yy4kMShhKQpQ
-LkRtKGEsYixzKX1yZXR1cm4gc30sClBDOmZ1bmN0aW9uIFBDKCl7fSwKbXQ6ZnVuY3Rpb24gbXQoYSl7
-dGhpcy5hPWF9LApOejpmdW5jdGlvbiBOeigpe30sClFTOmZ1bmN0aW9uIFFTKCl7fSwKbnA6ZnVuY3Rp
-b24gbnAoKXt9LApFNDpmdW5jdGlvbiBFNChhKXt0aGlzLmE9YX0sCnI3OmZ1bmN0aW9uIHI3KGEpe3Ro
-aXMuYT1hfSwKVHo6ZnVuY3Rpb24gVHooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY286ZnVuY3Rp
-b24gY28oKXt9LApuZDpmdW5jdGlvbiBuZCgpe30sCktlOmZ1bmN0aW9uIEtlKGEpe3RoaXMuYT1hfSwK
-aGk6ZnVuY3Rpb24gaGkoKXt9fSxXPXsKeDM6ZnVuY3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVu
-Y3Rpb24oKXtyZXR1cm4gZG9jdW1lbnR9LApKNjpmdW5jdGlvbihhKXt2YXIgcz1kb2N1bWVudC5jcmVh
-dGVFbGVtZW50KCJhIikKaWYoYSE9bnVsbClDLnhuLnNMVShzLGEpCnJldHVybiBzfSwKVTk6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzLHI9ZG9jdW1lbnQuYm9keQpyLnRvU3RyaW5nCnM9Qy5SWS5yNihyLGEsYixj
-KQpzLnRvU3RyaW5nCnI9dC5hYwpyPW5ldyBILlU1KG5ldyBXLmU3KHMpLHIuQygiYTIobEQuRSkiKS5h
-KG5ldyBXLkN2KCkpLHIuQygiVTU8bEQuRT4iKSkKcmV0dXJuIHQuaC5hKHIuZ3I4KHIpKX0sCnJTOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscT0iZWxlbWVudCB0YWcgdW5hdmFpbGFibGUiCnRyeXtzPUouWUUoYSkK
-aWYodHlwZW9mIHMuZ25zKGEpPT0ic3RyaW5nIilxPXMuZ25zKGEpfWNhdGNoKHIpe0guUnUocil9cmV0
-dXJuIHF9LApDMDpmdW5jdGlvbihhLGIpe2E9YStiJjUzNjg3MDkxMQphPWErKChhJjUyNDI4Nyk8PDEw
-KSY1MzY4NzA5MTEKcmV0dXJuIGFeYT4+PjZ9LApyRTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcz1XLkMw
-KFcuQzAoVy5DMChXLkMwKDAsYSksYiksYyksZCkscj1zKygocyY2NzEwODg2Myk8PDMpJjUzNjg3MDkx
-MQpyXj1yPj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUpJjUzNjg3MDkxMX0sClROOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscixxPWEuY2xhc3NMaXN0CmZvcihzPWIubGVuZ3RoLHI9MDtyPGIubGVuZ3RoO2Iu
-bGVuZ3RoPT09c3x8KDAsSC5saykoYiksKytyKXEuYWRkKGJbcl0pfSwKSkU6ZnVuY3Rpb24oYSxiLGMs
-ZCxlKXt2YXIgcz1XLmFGKG5ldyBXLnZOKGMpLHQuQikKaWYocyE9bnVsbCYmITApSi5kWihhLGIscywh
-MSkKcmV0dXJuIG5ldyBXLnhDKGEsYixzLCExLGUuQygieEM8MD4iKSl9LApUdzpmdW5jdGlvbihhKXt2
-YXIgcz1XLko2KG51bGwpLHI9d2luZG93LmxvY2F0aW9uCnM9bmV3IFcuSlEobmV3IFcubWsocyxyKSkK
-cy5DWShhKQpyZXR1cm4gc30sCnFEOmZ1bmN0aW9uKGEsYixjLGQpe3QuaC5hKGEpCkguaChiKQpILmgo
-YykKdC5jci5hKGQpCnJldHVybiEwfSwKUVc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxCnQuaC5h
-KGEpCkguaChiKQpILmgoYykKcz10LmNyLmEoZCkuYQpyPXMuYQpDLnhuLnNMVShyLGMpCnE9ci5ob3N0
-bmFtZQpzPXMuYgppZighKHE9PXMuaG9zdG5hbWUmJnIucG9ydD09cy5wb3J0JiZyLnByb3RvY29sPT1z
-LnByb3RvY29sKSlpZihxPT09IiIpaWYoci5wb3J0PT09IiIpe3M9ci5wcm90b2NvbApzPXM9PT0iOiJ8
-fHM9PT0iIn1lbHNlIHM9ITEKZWxzZSBzPSExCmVsc2Ugcz0hMApyZXR1cm4gc30sCkJsOmZ1bmN0aW9u
-KCl7dmFyIHM9dC5OLHI9UC50TShDLlF4LHMpLHE9dC5kMC5hKG5ldyBXLklBKCkpLHA9SC5WTShbIlRF
-TVBMQVRFIl0sdC5zKQpzPW5ldyBXLmN0KHIsUC5McyhzKSxQLkxzKHMpLFAuTHMocyksbnVsbCkKcy5D
-WShudWxsLG5ldyBILmxKKEMuUXgscSx0LmZqKSxwLG51bGwpCnJldHVybiBzfSwKcWM6ZnVuY3Rpb24o
-YSl7dmFyIHMKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZigicG9zdE1lc3NhZ2UiIGluIGEpe3M9Vy5Q
-MShhKQppZih0LmFTLmIocykpcmV0dXJuIHMKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4gdC5jaC5hKGEp
-fSwKUDE6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdylyZXR1cm4gdC5jaS5hKGEpCmVsc2UgcmV0dXJu
-IG5ldyBXLmRXKCl9LAphRjpmdW5jdGlvbihhLGIpe3ZhciBzPSQuWDMKaWYocz09PUMuTlUpcmV0dXJu
-IGEKcmV0dXJuIHMuUHkoYSxiKX0sCnFFOmZ1bmN0aW9uIHFFKCl7fSwKR2g6ZnVuY3Rpb24gR2goKXt9
-LApmWTpmdW5jdGlvbiBmWSgpe30sCm5COmZ1bmN0aW9uIG5CKCl7fSwKQXo6ZnVuY3Rpb24gQXooKXt9
-LApRUDpmdW5jdGlvbiBRUCgpe30sCm54OmZ1bmN0aW9uIG54KCl7fSwKb0o6ZnVuY3Rpb24gb0ooKXt9
-LAppZDpmdW5jdGlvbiBpZCgpe30sClFGOmZ1bmN0aW9uIFFGKCl7fSwKTmg6ZnVuY3Rpb24gTmgoKXt9
-LAphZTpmdW5jdGlvbiBhZSgpe30sCklCOmZ1bmN0aW9uIElCKCl7fSwKbjc6ZnVuY3Rpb24gbjcoKXt9
-LAp3ejpmdW5jdGlvbiB3eihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApjdjpmdW5jdGlvbiBjdigp
-e30sCkN2OmZ1bmN0aW9uIEN2KCl7fSwKZWE6ZnVuY3Rpb24gZWEoKXt9LApEMDpmdW5jdGlvbiBEMCgp
-e30sCmhIOmZ1bmN0aW9uIGhIKCl7fSwKaDQ6ZnVuY3Rpb24gaDQoKXt9LApicjpmdW5jdGlvbiBicigp
-e30sClZiOmZ1bmN0aW9uIFZiKCl7fSwKZko6ZnVuY3Rpb24gZkooKXt9LAp3YTpmdW5jdGlvbiB3YSgp
-e30sClNnOmZ1bmN0aW9uIFNnKCl7fSwKdTg6ZnVuY3Rpb24gdTgoKXt9LApBajpmdW5jdGlvbiBBaigp
-e30sCmU3OmZ1bmN0aW9uIGU3KGEpe3RoaXMuYT1hfSwKdUg6ZnVuY3Rpb24gdUgoKXt9LApCSDpmdW5j
-dGlvbiBCSCgpe30sClNOOmZ1bmN0aW9uIFNOKCl7fSwKZXc6ZnVuY3Rpb24gZXcoKXt9LApscDpmdW5j
-dGlvbiBscCgpe30sClRiOmZ1bmN0aW9uIFRiKCl7fSwKSXY6ZnVuY3Rpb24gSXYoKXt9LApXUDpmdW5j
-dGlvbiBXUCgpe30sCnlZOmZ1bmN0aW9uIHlZKCl7fSwKdzY6ZnVuY3Rpb24gdzYoKXt9LApLNTpmdW5j
-dGlvbiBLNSgpe30sCkNtOmZ1bmN0aW9uIENtKCl7fSwKQ1E6ZnVuY3Rpb24gQ1EoKXt9LAp3NDpmdW5j
-dGlvbiB3NCgpe30sCnJoOmZ1bmN0aW9uIHJoKCl7fSwKY2Y6ZnVuY3Rpb24gY2YoKXt9LAppNzpmdW5j
-dGlvbiBpNyhhKXt0aGlzLmE9YX0sClN5OmZ1bmN0aW9uIFN5KGEpe3RoaXMuYT1hfSwKS1M6ZnVuY3Rp
-b24gS1MoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkEzOmZ1bmN0aW9uIEEzKGEsYil7dGhpcy5hPWEK
-dGhpcy5iPWJ9LApJNDpmdW5jdGlvbiBJNChhKXt0aGlzLmE9YX0sCkZrOmZ1bmN0aW9uIEZrKGEsYil7
-dGhpcy5hPWEKdGhpcy4kdGk9Yn0sClJPOmZ1bmN0aW9uIFJPKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5h
-PWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sCmV1OmZ1bmN0aW9uIGV1KGEsYixjLGQpe3ZhciBfPXRoaXMK
-Xy5hPWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sCnhDOmZ1bmN0aW9uIHhDKGEsYixjLGQsZSl7dmFyIF89
-dGhpcwpfLmI9YQpfLmM9YgpfLmQ9YwpfLmU9ZApfLiR0aT1lfSwKdk46ZnVuY3Rpb24gdk4oYSl7dGhp
-cy5hPWF9LApKUTpmdW5jdGlvbiBKUShhKXt0aGlzLmE9YX0sCkdtOmZ1bmN0aW9uIEdtKCl7fSwKdkQ6
-ZnVuY3Rpb24gdkQoYSl7dGhpcy5hPWF9LApVdjpmdW5jdGlvbiBVdihhKXt0aGlzLmE9YX0sCkVnOmZ1
-bmN0aW9uIEVnKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCm02OmZ1bmN0aW9uIG02
-KCl7fSwKRW86ZnVuY3Rpb24gRW8oKXt9LApXazpmdW5jdGlvbiBXaygpe30sCmN0OmZ1bmN0aW9uIGN0
-KGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmU9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCklBOmZ1
-bmN0aW9uIElBKCl7fSwKT3c6ZnVuY3Rpb24gT3coKXt9LApXOTpmdW5jdGlvbiBXOShhLGIsYyl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9LTEKXy5kPW51bGwKXy4kdGk9Y30sCmRXOmZ1bmN0aW9uIGRX
-KCl7fSwKbWs6ZnVuY3Rpb24gbWsoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktvOmZ1bmN0aW9uIEtv
-KGEpe3RoaXMuYT1hCnRoaXMuYj0hMX0sCmZtOmZ1bmN0aW9uIGZtKGEpe3RoaXMuYT1hfSwKTGU6ZnVu
-Y3Rpb24gTGUoKXt9LApLNzpmdW5jdGlvbiBLNygpe30sCnJCOmZ1bmN0aW9uIHJCKCl7fSwKWFc6ZnVu
-Y3Rpb24gWFcoKXt9LApvYTpmdW5jdGlvbiBvYSgpe319LE09ewpPWDpmdW5jdGlvbihhKXtzd2l0Y2go
-YSl7Y2FzZSBDLkFkOnJldHVybiJBZGQgLyo/Ki8gaGludCIKY2FzZSBDLm5lOnJldHVybiJBZGQgLyoh
-Ki8gaGludCIKY2FzZSBDLndWOnJldHVybiJSZW1vdmUgLyo/Ki8gaGludCIKY2FzZSBDLmZSOnJldHVy
-biJSZW1vdmUgLyohKi8gaGludCIKY2FzZSBDLm15OnJldHVybiJDaGFuZ2UgdG8gLyo/Ki8gaGludCIK
-Y2FzZSBDLnJ4OnJldHVybiJDaGFuZ2UgdG8gLyohKi8gaGludCJ9cmV0dXJuIG51bGx9LApINzpmdW5j
-dGlvbiBINyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWUY6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEs
-cCxvLG4sbSxsCmZvcihzPWIubGVuZ3RoLHI9MTtyPHM7KytyKXtpZihiW3JdPT1udWxsfHxiW3ItMV0h
-PW51bGwpY29udGludWUKZm9yKDtzPj0xO3M9cSl7cT1zLTEKaWYoYltxXSE9bnVsbClicmVha31wPW5l
-dyBQLlJuKCIiKQpvPWErIigiCnAuYT1vCm49SC50NihiKQptPW4uQygibkg8MT4iKQpsPW5ldyBILm5I
-KGIsMCxzLG0pCmwuSGQoYiwwLHMsbi5jKQptPW8rbmV3IEgubEoobCxtLkMoInFVKGFMLkUpIikuYShu
-ZXcgTS5ObygpKSxtLkMoImxKPGFMLkUscVU+IikpLkgoMCwiLCAiKQpwLmE9bQpwLmE9bSsoIik6IHBh
-cnQgIisoci0xKSsiIHdhcyBudWxsLCBidXQgcGFydCAiK3IrIiB3YXMgbm90LiIpCnRocm93IEguYihQ
-LnhZKHAudygwKSkpfX0sCmxJOmZ1bmN0aW9uIGxJKGEpe3RoaXMuYT1hfSwKcTc6ZnVuY3Rpb24gcTco
-KXt9LApObzpmdW5jdGlvbiBObygpe319LFU9ewpuejpmdW5jdGlvbihhKXt2YXIgcz1ILnVQKGEucSgw
-LCJub2RlSWQiKSkKcmV0dXJuIG5ldyBVLkxMKEMuTm0uSHQoQy5yayxuZXcgVS5NRChhKSkscyl9LApM
-TDpmdW5jdGlvbiBMTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTUQ6ZnVuY3Rpb24gTUQoYSl7dGhp
-cy5hPWF9LApqZjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscAppZihhPT1udWxsKXM9bnVsbAplbHNle3M9
-SC5WTShbXSx0LmQ3KQpmb3Iocj1KLklUKHQuVS5hKGEpKTtyLkYoKTspe3E9ci5nbCgpCnA9Si5VNihx
-KQpDLk5tLmkocyxuZXcgVS5TZShILmgocC5xKHEsImRlc2NyaXB0aW9uIikpLEguaChwLnEocSwiaHJl
-ZiIpKSkpfX1yZXR1cm4gc30sCk5kOmZ1bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbClzPW51bGwK
-ZWxzZXtzPUguVk0oW10sdC5hQSkKZm9yKHI9Si5JVCh0LlUuYShhKSk7ci5GKCk7KUMuTm0uaShzLFUu
-TmYoci5nbCgpKSl9cmV0dXJuIHN9LApOZjpmdW5jdGlvbihhKXt2YXIgcz1KLlU2KGEpLHI9SC5oKHMu
-cShhLCJkZXNjcmlwdGlvbiIpKSxxPUguVk0oW10sdC5hSikKZm9yKHM9Si5JVCh0LlUuYShzLnEoYSwi
-ZW50cmllcyIpKSk7cy5GKCk7KUMuTm0uaShxLFUuUmoocy5nbCgpKSkKcmV0dXJuIG5ldyBVLnlEKHIs
-cSl9LApSajpmdW5jdGlvbihhKXt2YXIgcyxyPUouVTYoYSkscT1ILmgoci5xKGEsImRlc2NyaXB0aW9u
-IikpLHA9SC5oKHIucShhLCJmdW5jdGlvbiIpKSxvPXIucShhLCJsaW5rIikKaWYobz09bnVsbClvPW51
-bGwKZWxzZXtzPUouVTYobykKbz1uZXcgVS5NbChILmgocy5xKG8sImhyZWYiKSksSC51UChzLnEobywi
-bGluZSIpKSxILmgocy5xKG8sInBhdGgiKSkpfXI9dC5mSy5hKHIucShhLCJoaW50QWN0aW9ucyIpKQpy
-PXI9PW51bGw/bnVsbDpKLk0xKHIsbmV3IFUuYU4oKSx0LmFYKQpyPXI9PW51bGw/bnVsbDpyLmJyKDAp
-CnJldHVybiBuZXcgVS53YihxLHAsbyxyPT1udWxsP0MuZG46cil9LApkMjpmdW5jdGlvbiBkMihhLGIs
-YyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sClNl
-OmZ1bmN0aW9uIFNlKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNbDpmdW5jdGlvbiBNbChhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp5RDpmdW5jdGlvbiB5RChhLGIpe3RoaXMuYT1hCnRo
-aXMuYj1ifSwKd2I6ZnVuY3Rpb24gd2IoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
-YwpfLmQ9ZH0sCmFOOmZ1bmN0aW9uIGFOKCl7fSwKYjA6ZnVuY3Rpb24gYjAoKXt9fSxCPXsKd1I6ZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IEIucXAoIiIsIiIsIiIsQy5EeCl9LApZZjpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscCxvLG4sbSxsLGs9SC5oKGEucSgwLCJyZWdpb25zIikpLGo9SC5oKGEucSgwLCJuYXZpZ2F0
-aW9uQ29udGVudCIpKSxpPUguaChhLnEoMCwic291cmNlQ29kZSIpKSxoPVAuRmwodC5YLHQuZF8pCmZv
-cihzPXQudC5hKGEucSgwLCJlZGl0cyIpKSxzPXMuZ1B1KHMpLHM9cy5nbShzKSxyPXQuVSxxPXQuaDQ7
-cy5GKCk7KXtwPXMuZ2woKQpvPXAuYQpuPUguVk0oW10scSkKZm9yKHA9Si5JVChyLmEocC5iKSk7cC5G
-KCk7KXttPXAuZ2woKQpsPUouVTYobSkKQy5ObS5pKG4sbmV3IEIuajgoSC51UChsLnEobSwibGluZSIp
-KSxILmgobC5xKG0sImV4cGxhbmF0aW9uIikpLEgudVAobC5xKG0sIm9mZnNldCIpKSkpfWguWSgwLG8s
-bil9cmV0dXJuIG5ldyBCLnFwKGssaixpLGgpfSwKajg6ZnVuY3Rpb24gajgoYSxiLGMpe3RoaXMuYT1h
-CnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9
-YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2OmZ1bmN0aW9uIGZ2KCl7fSwKT1M6ZnVuY3Rpb24oYSl7dmFy
-IHMKaWYoIShhPj02NSYmYTw9OTApKXM9YT49OTcmJmE8PTEyMgplbHNlIHM9ITAKcmV0dXJuIHN9LApZ
-dTpmdW5jdGlvbihhLGIpe3ZhciBzPWEubGVuZ3RoLHI9YisyCmlmKHM8cilyZXR1cm4hMQppZighQi5P
-UyhDLnhCLk8yKGEsYikpKXJldHVybiExCmlmKEMueEIuTzIoYSxiKzEpIT09NTgpcmV0dXJuITEKaWYo
-cz09PXIpcmV0dXJuITAKcmV0dXJuIEMueEIuTzIoYSxyKT09PTQ3fX0sVD17bVE6ZnVuY3Rpb24gbVEo
-KXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRlbnRMb2FkZWQiLG5l
-dyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwoKSl9LAprejpmdW5jdGlvbihh
-KXt2YXIgcyxyPXQuZy5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNjb3BlID4gdWwiKSxx
-PXIuc3R5bGUscD0iIitDLkNELnpRKHIub2Zmc2V0SGVpZ2h0KSoyKyJweCIKcS5tYXhIZWlnaHQ9cApx
-PUoucUYoYSkKcD1xLiR0aQpzPXAuQygifigxKT8iKS5hKG5ldyBMLld4KHIsYSkpCnQuWi5hKG51bGwp
-ClcuSkUocS5hLHEuYixzLCExLHAuYyl9LAp5WDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixt
-PSJxdWVyeVNlbGVjdG9yQWxsIixsPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSksaz10LmcKbC50b1N0
-cmluZwpzPXQuaApILkRoKGsscywiVCIsbSkKcj10LlcKcT1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JB
-bGwoIi5uYXYtbGluayIpLHIpCnEuSyhxLG5ldyBMLkFPKGIpKQpILkRoKGsscywiVCIsbSkKcD1uZXcg
-Vy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSxyKQppZighcC5nbDAocCkpe289bC5xdWVy
-eVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKby50b1N0cmluZwpwLksocCxuZXcgTC5IbyhvLmdl
-dEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KG8pKS5PKCJwYXRoIikpKSl9SC5EaChr
-LHMsIlQiLG0pCm49bmV3IFcud3oobC5xdWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhpbnQtbGluayIpLHIp
-Cm4uSyhuLG5ldyBMLklDKCkpfSwKUTY6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5ldyBYTUxIdHRwUmVx
-dWVzdCgpCkMuRHQuZW8ocywiR0VUIixMLlE0KGEsYiksITApCnMuc2V0UmVxdWVzdEhlYWRlcigiQ29u
-dGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHMs
-bnVsbCxjLkMoIjAqIikpfSwKdHk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1uZXcgWE1MSHR0cFJlcXVlc3Qo
-KSxyPXQuWApDLkR0LmVvKHMsIlBPU1QiLEwuUTQoYSxQLkZsKHIscikpLCEwKQpzLnNldFJlcXVlc3RI
-ZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiKQpyZXR1
-cm4gTC5MVShzLGIsdC50KX0sCkxVOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTC5UZyhhLGIsYyxjLkMo
-IjAqIikpfSwKVGc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9MCxyPVAuRlgoZCkscSxwPTIsbyxuPVtd
-LG0sbCxrLGosaSxoLGcsZgp2YXIgJGFzeW5jJExVPVAubHooZnVuY3Rpb24oZSxhMCl7aWYoZT09PTEp
-e289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppPW5ldyBQLlpmKG5ldyBQLnZzKCQu
-WDMsdC5nViksdC5iQykKaD10LmViCmc9aC5hKG5ldyBMLmZDKGksYSkpCnQuWi5hKG51bGwpCmw9dC5l
-UQpXLkpFKGEsImxvYWQiLGcsITEsbCkKVy5KRShhLCJlcnJvciIsaC5hKGkuZ1lKKCkpLCExLGwpCmEu
-c2VuZChiPT1udWxsP251bGw6Qy5DdC5PQihiLG51bGwpKQpwPTQKcz03CnJldHVybiBQLmpRKGkuYSwk
-YXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZj1vCkguUnUoZikKbT1ILnRz
-KGYpCmg9UC5UbCgiRXJyb3IgcmVhY2hpbmcgbWlncmF0aW9uIHByZXZpZXcgc2VydmVyLiIsbSkKdGhy
-b3cgSC5iKGgpCnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpqPUMuQ3QucFcoMCxhLnJl
-c3BvbnNlVGV4dCxudWxsKQppZihhLnN0YXR1cz09PTIwMCl7cT1jLkMoIjAqIikuYShqKQpzPTEKYnJl
-YWt9ZWxzZSB0aHJvdyBILmIoaikKY2FzZSAxOnJldHVybiBQLnlDKHEscikKY2FzZSAyOnJldHVybiBQ
-LmYzKG8scil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJExVLHIpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHM9
-UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0s
-Ckc2OmZ1bmN0aW9uKGEpe3ZhciBzPVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gcz09
-bnVsbD9udWxsOkguSHAocyxudWxsKX0sCmk2OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHQuTy5hKGEp
-KX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGos
-aSxoCnZhciAkYXN5bmMkaTY9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1xfXdoaWxl
-KHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppPXQuZy5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0
-cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVsdCgpCnE9MwprPWRvY3VtZW50Cm49Qy5DRC56UShr
-LnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50Iikuc2Nyb2xsVG9wKQpzPTYKcmV0dXJuIFAualEoTC50eShp
-LG51bGwpLCRhc3luYyRpNikKY2FzZSA2OnM9NwpyZXR1cm4gUC5qUShMLkc3KHdpbmRvdy5sb2NhdGlv
-bi5wYXRobmFtZSxudWxsLG51bGwsITEsbnVsbCksJGFzeW5jJGk2KQpjYXNlIDc6az1rLnF1ZXJ5U2Vs
-ZWN0b3IoIi5jb250ZW50IikKay50b1N0cmluZwprLnNjcm9sbFRvcD1KLlZ1KG4pCnE9MQpzPTUKYnJl
-YWsKY2FzZSAzOnE9MgpoPXAKbT1ILlJ1KGgpCmw9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgYWRkL3Jl
-bW92ZSBoaW50IixtLGwpCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55
-QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixy
-KX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD0iZXhjZXB0aW9uIixvPSJzdGFja1RyYWNl
-IixuPXQudC5iKGIpJiZKLlJNKGIucSgwLCJzdWNjZXNzIiksITEpJiZiLng0KHApJiZiLng0KG8pLG09
-Si5pYShiKQppZihuKXtzPUguaChtLnEoYixwKSkKYz1tLnEoYixvKX1lbHNlIHM9bS53KGIpCm49ZG9j
-dW1lbnQKcj1uLnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikKci5xdWVyeVNlbGVjdG9yKCJoMiIp
-LmlubmVyVGV4dD1hCnIucXVlcnlTZWxlY3RvcigicCIpLmlubmVyVGV4dD1zCnIucXVlcnlTZWxlY3Rv
-cigicHJlIikuaW5uZXJUZXh0PUouaihjKQpxPXQuZGQuYShyLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9t
-IikpCm09dC5YOyhxJiZDLnhuKS5zTFUocSxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxh
-bmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYoWyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdp
-dGggTk5CRCBtaWdyYXRpb24gdG9vbDogIithLCJsYWJlbHMiLHUuZCwiYm9keSIsYSsiXG5cbkVycm9y
-OiAiK0guRWoocykrIlxuXG5QbGVhc2UgZmlsbCBpbiB0aGUgZm9sbG93aW5nOlxuXG4qKk5hbWUgb2Yg
-cGFja2FnZSBiZWluZyBtaWdyYXRlZCAoaWYgcHVibGljKSoqOlxuKipXaGF0IEkgd2FzIGRvaW5nIHdo
-ZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoqOlxuKipJcyBpdCBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0
-aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlzIGlzc3VlIGhhcHBlbmVkIGJlZm9yZSwgYW5kIGlmIHNvLCBo
-b3cgb2Z0ZW4qKjpcbioqRGFydCBTREsgdmVyc2lvbioqOiAiK0guRWoobi5nZXRFbGVtZW50QnlJZCgi
-c2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuKipBZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhh
-bmtzIGZvciBmaWxpbmchXG5cblN0YWNrdHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24g
-cHJldmlldyB0b29sLl9cblxuYGBgXG4iK0guRWooYykrIlxuYGBgXG4iXSxtLG0pKS5nbkQoKSkKbT1x
-LnN0eWxlCm0uZGlzcGxheT0iaW5pdGlhbCIKbj1yLnN0eWxlCm4uZGlzcGxheT0iaW5pdGlhbCIKbj1h
-KyI6ICIrSC5FaihiKQp3aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5j
-b25zb2xlLmVycm9yKG4pCndpbmRvdwpuPUguRWooYykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
-ZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pfSwKdDI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
-LG89dC5nLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKcz1vLmdldEF0
-dHJpYnV0ZSgiaHJlZiIpCnI9TC5VcyhzKQpxPUwuRzYocykKcD1MLmFLKHMpCmlmKHEhPW51bGwpTC5h
-ZihyLHEscCxiLG5ldyBMLm5UKHIscSxwKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuTlko
-cikpfSwKSzA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBv
-cHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0PSJGYWlsZWQgdG8gcmVydW4g
-ZnJvbSBzb3VyY2VzIgpwLnF1ZXJ5U2VsZWN0b3IoInAiKS5pbm5lclRleHQ9IlNvdXJjZXMgY29udGFp
-biBzdGF0aWMgYW5hbHlzaXMgZXJyb3JzOiIKcz1wLnF1ZXJ5U2VsZWN0b3IoInByZSIpCnI9Si5FbChh
-LHQuYXcpCnE9SC5MaChyKQpzLmlubmVyVGV4dD1uZXcgSC5sSihyLHEuQygicVUqKGxELkUpIikuYShu
-ZXcgTC51ZSgpKSxxLkMoImxKPGxELkUscVUqPiIpKS5IKDAsIlxuIikKcT1wLnF1ZXJ5U2VsZWN0b3Io
-ImEuYm90dG9tIikuc3R5bGUKcS5kaXNwbGF5PSJub25lIgpzPXAuc3R5bGUKcy5kaXNwbGF5PSJpbml0
-aWFsIn0sCnZVOmZ1bmN0aW9uKCl7dmFyIHM9ZG9jdW1lbnQKSC5EaCh0LmcsdC5oLCJUIiwicXVlcnlT
-ZWxlY3RvckFsbCIpCnM9bmV3IFcud3oocy5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHQuVykKcy5L
-KHMsbmV3IEwuZVgoKSl9LApoWDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEwuWXcoYSxiLGMpfSwKWXc6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxo
-LGcKdmFyICRhc3luYyRoWD1QLmx6KGZ1bmN0aW9uKGQsZSl7aWYoZD09PTEpe3A9ZQpzPXF9d2hpbGUo
-dHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9MwpqPXQuWApzPTYKcmV0dXJuIFAualEoTC5RNihhLFAuRUYo
-WyJyZWdpb24iLCJyZWdpb24iLCJvZmZzZXQiLEguRWooYildLGosaiksdC50KSwkYXN5bmMkaFgpCmNh
-c2UgNjpuPWUKaj1uCmk9Si5VNihqKQptPW5ldyBVLmQyKFUuamYoaS5xKGosImVkaXRzIikpLEguaChp
-LnEoaiwiZXhwbGFuYXRpb24iKSksSC51UChpLnEoaiwibGluZSIpKSxILmgoaS5xKGosImRpc3BsYXlQ
-YXRoIikpLEguaChpLnEoaiwidXJpUGF0aCIpKSxVLk5kKGkucShqLCJ0cmFjZXMiKSkpCkwuVDEobSkK
-TC5GcihhLGIsYykKTC55WCgiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKQpxPTEKcz01CmJy
-ZWFrCmNhc2UgMzpxPTIKZz1wCmw9SC5SdShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQg
-ZWRpdCBkZXRhaWxzIixsLGspCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4g
-UC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRo
-WCxyKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1
-bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9MCxyPVAuRlgodC5IKSxxLHA9MixvLG49W10sbSxsLGssaixp
-LGgsZwp2YXIgJGFzeW5jJEc3PVAubHooZnVuY3Rpb24oZixhMCl7aWYoZj09PTEpe289YTAKcz1wfXdo
-aWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppZighSi5wNChhLCIuZGFydCIpKXtMLkJFKGEsQi53Uigp
-LGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00Cmk9dC5YCnM9Nwpy
-ZXR1cm4gUC5qUShMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSxpLGkpLHQudCksJGFzeW5jJEc3
-KQpjYXNlIDc6bT1hMApMLkJFKGEsQi5ZZihtKSxkKQpMLmZHKGIsYykKbD1MLlVzKGEpCkwuQlgobCxi
-KQppZihlIT1udWxsKWUuJDAoKQpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZz1vCms9SC5SdShnKQpq
-PUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgZGFydCBmaWxlICIrYSxrLGopCnM9NgpicmVhawpj
-YXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpjYXNlIDE6cmV0dXJuIFAueUMocSxyKQpjYXNlIDI6cmV0dXJu
-IFAuZjMobyxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkRzcscil9LApHZTpmdW5jdGlvbigpe3ZhciBz
-PTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkR2U9UC5seihm
-dW5jdGlvbihhLGIpe2lmKGE9PT0xKXtwPWIKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpp
-PSIvX3ByZXZpZXcvbmF2aWdhdGlvblRyZWUuanNvbiIKcT0zCnM9NgpyZXR1cm4gUC5qUShMLlE2KGks
-Qy5DTSx0Lm0pLCRhc3luYyRHZSkKY2FzZSA2Om49YgptPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5u
-YXYtdHJlZSIpCkoubDUobSwiIikKTC50WChtLEwubUsobikpCnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9
-MgpoPXAKbD1ILlJ1KGgpCms9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgbG9hZCBuYXZpZ2F0aW9uIHRy
-ZWUiLGwsaykKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGws
-cikKY2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJEdlLHIpfSwKcU86
-ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHE9Qy5DRC56USgkLmZp
-KCkub2Zmc2V0SGVpZ2h0KSxwPXdpbmRvdy5pbm5lckhlaWdodCxvPUMuQ0QuelEoJC5EVygpLm9mZnNl
-dEhlaWdodCkKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5ITigpCnM9ci5ib3R0b20Kcy50
-b1N0cmluZwppZihzPnAtKG8rMTQpKUouZGgoYSkKZWxzZXtwPXIudG9wCnAudG9TdHJpbmcKaWYocDxx
-KzE0KUouZGgoYSl9fSwKZkc6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCmlmKGEhPW51bGwpe3M9
-ZG9jdW1lbnQKcj1zLmdldEVsZW1lbnRCeUlkKCJvIitILkVqKGEpKQpxPXMucXVlcnlTZWxlY3Rvcigi
-LmxpbmUtIitILkVqKGIpKQppZihyIT1udWxsKXtMLnFPKHIpCkouZFIocikuaSgwLCJ0YXJnZXQiKX1l
-bHNlIGlmKHEhPW51bGwpTC5xTyhxLnBhcmVudEVsZW1lbnQpCmlmKHEhPW51bGwpSi5kUih0LmcuYShx
-LnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2V7cz1kb2N1bWVudApwPXQuZwpILkRoKHAs
-dC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9cy5xdWVyeVNlbGVjdG9yQWxsKCIubGluZS1ubyIp
-Cm89bmV3IFcud3oocyx0LlcpCmlmKG8uZ0Eobyk9PT0wKXJldHVybgpMLnFPKHAuYShDLnQ1Lmd0SChz
-KSkpfX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxPUwuRzYod2luZG93LmxvY2F0aW9u
-LmhyZWYpLHA9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYocSE9bnVsbCl7cz1kb2N1bWVudC5n
-ZXRFbGVtZW50QnlJZCgibyIrSC5FaihxKSkKaWYocyE9bnVsbClKLmRSKHMpLlIoMCwidGFyZ2V0Iil9
-aWYocCE9bnVsbCl7cj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guRWoocCkpCmlmKHIh
-PW51bGwpSi5kUihyLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09d2luZG93Lmxv
-Y2F0aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhhLGIsYyxkLGUpfSwKUTQ6
-ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5oSyhhKSxwPXQuWApwPVAuRmwocCxwKQpmb3Iocz1xLmdo
-WSgpLHM9cy5nUHUocykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5ZKDAsci5hLHIuYil9Zm9y
-KHM9Yi5nUHUoYikscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5ZKDAsci5hLHIuYil9cC5ZKDAs
-ImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gcS5ubSgwLHApLmduRCgpfSwKVDE6ZnVuY3Rpb24oYSl7
-dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9JC5oTCgpCkoubDUoaiwiIikKaWYoYT09bnVsbCl7cz1kb2N1
-bWVudC5jcmVhdGVFbGVtZW50KCJwIikKQy5MdC5zYTQocywiU2VlIGRldGFpbHMgYWJvdXQgYSBwcm9w
-b3NlZCBlZGl0LiIpCkMuTHQuc0QocyxILlZNKFsicGxhY2Vob2xkZXIiXSx0LmkpKQpqLmFwcGVuZENo
-aWxkKHMpCkMuTHQuRkYocykKcmV0dXJufXI9YS5kCnE9JC5uVSgpCnA9cS56ZihyKQpvPWEuYgpuPWRv
-Y3VtZW50Cm09cS5IUChyLEouVDAobi5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkK
-bD1hLmMKaz1uLmNyZWF0ZUVsZW1lbnQoInAiKQpqLmFwcGVuZENoaWxkKGspCmsuYXBwZW5kQ2hpbGQo
-bi5jcmVhdGVUZXh0Tm9kZShILkVqKG8pKyIgYXQgIikpCnE9dC5YCnE9Vy5KNihMLlE0KGEuZSxQLkVG
-KFsibGluZSIsSi5qKGwpXSxxLHEpKSkKcS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKEguRWoo
-bSkrIjoiK0guRWoobCkrIi4iKSkKay5hcHBlbmRDaGlsZChxKQpKLmRoKGspCkwuQ0MoYSxqLHApCkwu
-RnooYSxqKX0sCkxIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
-LGU9JC55UCgpCkoubDUoZSwiIikKaWYoYi5nQShiKT09PTApe3M9ZG9jdW1lbnQKcj1zLmNyZWF0ZUVs
-ZW1lbnQoInAiKQplLmFwcGVuZENoaWxkKHIpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZSgi
-Tm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZT1iLmdQdShiKSxlPWUuZ20oZSkscz10LlgscT10
-LmsscD1xLkMoIn4oMSk/Iiksbz10LloscT1xLmM7ZS5GKCk7KXtuPWUuZ2woKQptPWRvY3VtZW50CnI9
-bS5jcmVhdGVFbGVtZW50KCJwIikKbD0kLnlQKCkKbC5hcHBlbmRDaGlsZChyKQpyLmFwcGVuZENoaWxk
-KG0uY3JlYXRlVGV4dE5vZGUoSC5FaihuLmEpKyI6IikpCms9bS5jcmVhdGVFbGVtZW50KCJ1bCIpCmwu
-YXBwZW5kQ2hpbGQoaykKZm9yKG49Si5JVChuLmIpO24uRigpOyl7bD1uLmdsKCkKaj1tLmNyZWF0ZUVs
-ZW1lbnQoImxpIikKay5hcHBlbmRDaGlsZChqKQpKLmRSKGopLmkoMCwiZWRpdCIpCmk9bS5jcmVhdGVF
-bGVtZW50KCJhIikKai5hcHBlbmRDaGlsZChpKQppLmNsYXNzTGlzdC5hZGQoImVkaXQtbGluayIpCmg9
-bC5jCmc9SC5FaihoKQppLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGkpKS5P
-KCJvZmZzZXQiKSxnKQpmPWwuYQpnPUguRWooZikKaS5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5T
-eShuZXcgVy5pNyhpKSkuTygibGluZSIpLGcpCmkuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgi
-bGluZSAiK0guRWooZikpKQppLnNldEF0dHJpYnV0ZSgiaHJlZiIsTC5RNCh3aW5kb3cubG9jYXRpb24u
-cGF0aG5hbWUsUC5FRihbImxpbmUiLEguRWooZiksIm9mZnNldCIsSC5FaihoKV0scyxzKSkpCmc9cC5h
-KG5ldyBMLkVFKGgsZixhKSkKby5hKG51bGwpClcuSkUoaSwiY2xpY2siLGcsITEscSkKai5hcHBlbmRD
-aGlsZChtLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5FaihsLmIpKSl9fWlmKGMpTC5UMShudWxsKX0sCkZy
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9d2luZG93LmxvY2F0aW9uLHA9UC5oSygocSYmQy5FeCku
-Z0RyKHEpK0guRWooYSkpCnE9dC5YCnE9UC5GbChxLHEpCmlmKGIhPW51bGwpcS5ZKDAsIm9mZnNldCIs
-SC5FaihiKSkKaWYoYyE9bnVsbClxLlkoMCwibGluZSIsSC5FaihjKSkKcS5ZKDAsImF1dGhUb2tlbiIs
-JC5VRSgpKQpwPXAubm0oMCxxKQpxPXdpbmRvdy5oaXN0b3J5CnM9dC56CnI9cC5nbkQoKQpxLnRvU3Ry
-aW5nCnEucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHMscykpLCIiLHIpfSwKRW46ZnVu
-Y3Rpb24oYSl7dmFyIHM9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250
-ZW50LCIvIikKaWYoQy54Qi5uKGEscykpcmV0dXJuIEMueEIuRyhhLHMubGVuZ3RoKQplbHNlIHJldHVy
-biBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQpKLmRy
-KCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgodC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQpz
-PW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx0LlcpCnMu
-SyhzLG5ldyBMLlZTKHIpKX0sCkJFOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz0iLnJlZ2lvbnMiLHI9ZG9j
-dW1lbnQscT1yLnF1ZXJ5U2VsZWN0b3IocykscD1yLnF1ZXJ5U2VsZWN0b3IoIi5jb2RlIikKSi50SChx
-LGIuYSwkLktHKCkpCkoudEgocCxiLmIsJC5LRygpKQpMLkxIKGEsYi5kLGMpCkwudlUoKQpMLnlYKCIu
-Y29kZSIsITApCkwueVgocywhMCl9LAp0WDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGws
-ayxqLGksaCxnLGYsZT1kb2N1bWVudCxkPWUuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENoaWxk
-KGQpCmZvcihzPWIubGVuZ3RoLHI9dC5YLHE9dC5aLHA9MDtwPGIubGVuZ3RoO2IubGVuZ3RoPT09c3x8
-KDAsSC5saykoYiksKytwKXtvPWJbcF0Kbj1lLmNyZWF0ZUVsZW1lbnQoImxpIikKZC5hcHBlbmRDaGls
-ZChuKQptPUouWUUobikKaWYoby5hPT09Qy5ZMil7bS5nRChuKS5pKDAsImRpciIpCmw9ZS5jcmVhdGVF
-bGVtZW50KCJzcGFuIikKbi5hcHBlbmRDaGlsZChsKQptPUouWUUobCkKbS5nRChsKS5pKDAsImFycm93
-IikKbS5zaGYobCwiJiN4MjVCQzsiKQprPWUuY3JlYXRlRWxlbWVudCgic3BhbiIpCm4uYXBwZW5kQ2hp
-bGQoaykKSi5sNShrLCc8c3BhbiBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMiPmZvbGRlcl9vcGVuPC9zcGFu
-PicpCm4uYXBwZW5kQ2hpbGQoZS5jcmVhdGVUZXh0Tm9kZShvLmIpKQpMLnRYKG4sby5jKQpMLmt6KGwp
-fWVsc2V7bS5zaGYobiwnPHNwYW4gY2xhc3M9Im1hdGVyaWFsLWljb25zIj5pbnNlcnRfZHJpdmVfZmls
-ZTwvc3Bhbj4nKQpqPWUuY3JlYXRlRWxlbWVudCgiYSIpCm4uYXBwZW5kQ2hpbGQoaikKbT1KLllFKGop
-Cm0uZ0QoaikuaSgwLCJuYXYtbGluayIpCmouc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3
-IFcuaTcoaikpLk8oIm5hbWUiKSxvLmQpCmouc2V0QXR0cmlidXRlKCJocmVmIixMLlE0KG8uZSxQLkZs
-KHIscikpKQpqLmFwcGVuZENoaWxkKGUuY3JlYXRlVGV4dE5vZGUoby5iKSkKbT1tLmdWbChqKQppPW0u
-JHRpCmg9aS5DKCJ+KDEpPyIpLmEobmV3IEwuVEQoKSkKcS5hKG51bGwpClcuSkUobS5hLG0uYixoLCEx
-LGkuYykKZz1vLmYKaWYodHlwZW9mIGchPT0ibnVtYmVyIilyZXR1cm4gZy5vcygpCmlmKGc+MCl7Zj1l
-LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpuLmFwcGVuZENoaWxkKGYpCkouZFIoZikuaSgwLCJlZGl0LWNv
-dW50IikKbT0iIitnKyIgIgppZihnPT09MSlpPSJlZGl0IgplbHNlIGk9ImVkaXRzIgpmLnNldEF0dHJp
-YnV0ZSgidGl0bGUiLG0raSkKZi5hcHBlbmRDaGlsZChlLmNyZWF0ZVRleHROb2RlKEMuam4udyhnKSkp
-fX19fSwKdXo6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPWRvY3VtZW50LHI9cy5jcmVhdGVFbGVtZW50KCJi
-dXR0b24iKSxxPXQuayxwPXEuQygifigxKT8iKS5hKG5ldyBMLm0yKGEsYykpCnQuWi5hKG51bGwpClcu
-SkUociwiY2xpY2siLHAsITEscS5jKQpyLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoTS5PWChh
-LmEpKSkKYi5hcHBlbmRDaGlsZChyKX0sCkZ6OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0s
-bCxrLGosaSxoPWEuYQppZihoPT1udWxsKXJldHVybgpzPWRvY3VtZW50CnI9cy5jcmVhdGVFbGVtZW50
-KCJwIikKcT1iLmFwcGVuZENoaWxkKHIpCnI9cy5jcmVhdGVFbGVtZW50KCJzcGFuIikKcD10LmkKSi5N
-dShyLEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scCkpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0
-Tm9kZSgiQWN0aW9ucyIpKQpxLmFwcGVuZENoaWxkKHIpCnEuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0
-Tm9kZSgiOiIpKQpvPXMuY3JlYXRlRWxlbWVudCgicCIpCmIuYXBwZW5kQ2hpbGQobykKZm9yKHI9aC5s
-ZW5ndGgsbj10LlEsbT0wO208aC5sZW5ndGg7aC5sZW5ndGg9PT1yfHwoMCxILmxrKShoKSwrK20pe2w9
-aFttXQprPXMuY3JlYXRlRWxlbWVudCgiYSIpCm8uYXBwZW5kQ2hpbGQoaykKay5hcHBlbmRDaGlsZChz
-LmNyZWF0ZVRleHROb2RlKGwuYSkpCmsuc2V0QXR0cmlidXRlKCJocmVmIixsLmIpCmo9bi5hKEguVk0o
-WyJhZGQtaGludC1saW5rIiwiYmVmb3JlLWFwcGx5IiwiYnV0dG9uIl0scCkpCmk9Si5kUihrKQppLlYx
-KDApCmkuRlYoMCxqKX19LApDQzpmdW5jdGlvbihhNCxhNSxhNil7dmFyIHMscixxLHAsbyxuLG0sbCxr
-LGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMKZm9yKHM9YTQuZixyPXMubGVuZ3RoLHE9dC5p
-LHA9dC5RLG89MDtvPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAsSC5saykocyksKytvKXtuPXNbb10K
-bT1kb2N1bWVudApsPW0uY3JlYXRlRWxlbWVudCgicCIpCms9cC5hKEguVk0oWyJ0cmFjZSJdLHEpKQpq
-PUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykKaT1hNS5hcHBlbmRDaGlsZChsKQpsPW0uY3JlYXRlRWxl
-bWVudCgic3BhbiIpCms9cC5hKEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scSkpCmo9Si5kUihsKQpq
-LlYxKDApCmouRlYoMCxrKQpsLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUobi5hKSkKaS5hcHBl
-bmRDaGlsZChsKQppLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIjoiKSkKbD1tLmNyZWF0ZUVs
-ZW1lbnQoInVsIikKaz1wLmEoSC5WTShbInRyYWNlIl0scSkpCmo9Si5kUihsKQpqLlYxKDApCmouRlYo
-MCxrKQpoPWkuYXBwZW5kQ2hpbGQobCkKZm9yKGw9bi5iLGs9bC5sZW5ndGgsZz0wO2c8bC5sZW5ndGg7
-bC5sZW5ndGg9PT1rfHwoMCxILmxrKShsKSwrK2cpe2Y9bFtnXQplPW0uY3JlYXRlRWxlbWVudCgibGki
-KQpoLmFwcGVuZENoaWxkKGUpCmQ9bS5jcmVhdGVFbGVtZW50KCJzcGFuIikKYz1wLmEoSC5WTShbImZ1
-bmN0aW9uIl0scSkpCmo9Si5kUihkKQpqLlYxKDApCmouRlYoMCxjKQpjPWYuYgpMLmtEKGQsYz09bnVs
-bD8idW5rbm93biI6YykKZS5hcHBlbmRDaGlsZChkKQpiPWYuYwppZihiIT1udWxsKXtlLmFwcGVuZENo
-aWxkKG0uY3JlYXRlVGV4dE5vZGUoIiAoIikpCmE9Yi5iCmEwPW0uY3JlYXRlRWxlbWVudCgiYSIpCmEw
-LmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoSC5FaihiLmMpKyI6IitILkVqKGEpKSkKYTAuc2V0
-QXR0cmlidXRlKCJocmVmIixiLmEpCmEwLmNsYXNzTGlzdC5hZGQoIm5hdi1saW5rIikKZS5hcHBlbmRD
-aGlsZChhMCkKZS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKCIpIikpfWUuYXBwZW5kQ2hpbGQo
-bS5jcmVhdGVUZXh0Tm9kZSgiOiAiKSkKZD1mLmEKTC5rRChlLGQ9PW51bGw/InVua25vd24iOmQpCmQ9
-Zi5kCmlmKGQubGVuZ3RoIT09MCl7Yz1tLmNyZWF0ZUVsZW1lbnQoInAiKQphMT1wLmEoSC5WTShbImRy
-YXdlciIsImJlZm9yZS1hcHBseSJdLHEpKQpqPUouZFIoYykKai5WMSgwKQpqLkZWKDAsYTEpCmEyPWUu
-YXBwZW5kQ2hpbGQoYykKZm9yKGM9ZC5sZW5ndGgsYTM9MDthMzxkLmxlbmd0aDtkLmxlbmd0aD09PWN8
-fCgwLEgubGspKGQpLCsrYTMpTC51eihkW2EzXSxhMixiKX19fX0sClVzOmZ1bmN0aW9uKGEpe3JldHVy
-biBKLlU2KGEpLnRnKGEsIj8iKT9DLnhCLk5qKGEsMCxDLnhCLk9ZKGEsIj8iKSk6YX0sCmtEOmZ1bmN0
-aW9uKGEsYil7dmFyIHMscixxPUguVk0oYi5zcGxpdCgiLiIpLHQucykscD1DLk5tLmd0SChxKSxvPWRv
-Y3VtZW50CmEuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShwKSkKZm9yKHA9SC5xQyhxLDEsbnVs
-bCx0Lk4pLHA9bmV3IEguYTcocCxwLmdBKHApLHAuJHRpLkMoImE3PGFMLkU+IikpLHM9Si5ZRShhKTtw
-LkYoKTspe3I9cC5kCnMubnooYSwiYmVmb3JlZW5kIiwiJiM4MjAzOy4iLG51bGwsbnVsbCkKYS5hcHBl
-bmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKHIpKX19LAplOmZ1bmN0aW9uIGUoKXt9LApWVzpmdW5jdGlv
-biBWVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApvWjpmdW5jdGlvbiBvWigpe30s
-CmpyOmZ1bmN0aW9uIGpyKCl7fSwKcWw6ZnVuY3Rpb24gcWwoKXt9LApIaTpmdW5jdGlvbiBIaSgpe30s
-CkJUOmZ1bmN0aW9uIEJUKCl7fSwKUFk6ZnVuY3Rpb24gUFkoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApX
-eDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhp
-cy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMu
-YT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElD
-KCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm5UOmZ1bmN0aW9uIG5U
-KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMu
-YT1hfSwKdWU6ZnVuY3Rpb24gdWUoKXt9LAplWDpmdW5jdGlvbiBlWCgpe30sCkVFOmZ1bmN0aW9uIEVF
-KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhhKXt0aGlzLmE9YX0sClREOmZ1bmN0aW9uIFRE
-KCl7fSwKbTI6ZnVuY3Rpb24gbTIoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClhBOmZ1bmN0aW9uIFhB
-KCl7fSwKbUs6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09SC5WTShbXSx0LmNRKQpmb3Iocz1K
-LklUKHQuVS5hKGEpKTtzLkYoKTspe3I9cy5nbCgpCnE9Si5VNihyKQpwPUwucDIoSC5oKHEucShyLCJ0
-eXBlIikpKQpvPUguaChxLnEociwibmFtZSIpKQpuPXEucShyLCJzdWJ0cmVlIikKbj1uPT1udWxsP251
-bGw6TC5tSyhuKQpDLk5tLmkobSxuZXcgTC5aWihwLG8sbixILmgocS5xKHIsInBhdGgiKSksSC5oKHEu
-cShyLCJocmVmIikpLEgudVAocS5xKHIsImVkaXRDb3VudCIpKSkpfXJldHVybiBtfSwKVkQ6ZnVuY3Rp
-b24oYSl7dmFyIHMscixxPUguVk0oW10sdC5HKQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxhLmxlbmd0aDth
-Lmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsrcilDLk5tLmkocSxhW3JdLkx0KCkpCnJldHVybiBxfSwK
-cDI6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5IjpyZXR1cm4gQy5ZMgpjYXNlImZp
-bGUiOnJldHVybiBDLnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYoIlVucmVjb2duaXplZCBuYXZpZ2F0
-aW9uIHRyZWUgbm9kZSB0eXBlOiAiK0guRWooYSkpKX19LAp2eTpmdW5jdGlvbihhKXtzd2l0Y2goYSl7
-Y2FzZSBDLlkyOnJldHVybiJkaXJlY3RvcnkiCmNhc2UgQy5yZjpyZXR1cm4iZmlsZSJ9dGhyb3cgSC5i
-KFAuUFYoIlVucmVjb2duaXplZCBuYXZpZ2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK2EudygwKSkpfSwK
-Wlo6ZnVuY3Rpb24gWlooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5k
-PWQKXy5lPWUKXy5mPWZ9LApPOTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCklWOmZ1bmN0aW9uIElW
-KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxYPXsKQ0w6ZnVuY3Rp
-b24oYSxiKXt2YXIgcyxyLHEscCxvLG49Yi54WihhKQpiLmhLKGEpCmlmKG4hPW51bGwpYT1KLktWKGEs
-bi5sZW5ndGgpCnM9dC5zCnI9SC5WTShbXSxzKQpxPUguVk0oW10scykKcz1hLmxlbmd0aAppZihzIT09
-MCYmYi5yNChDLnhCLlcoYSwwKSkpe2lmKDA+PXMpcmV0dXJuIEguT0goYSwwKQpDLk5tLmkocSxhWzBd
-KQpwPTF9ZWxzZXtDLk5tLmkocSwiIikKcD0wfWZvcihvPXA7bzxzOysrbylpZihiLnI0KEMueEIuVyhh
-LG8pKSl7Qy5ObS5pKHIsQy54Qi5OaihhLHAsbykpCkMuTm0uaShxLGFbb10pCnA9bysxfWlmKHA8cyl7
-Qy5ObS5pKHIsQy54Qi5HKGEscCkpCkMuTm0uaShxLCIiKX1yZXR1cm4gbmV3IFguV0QoYixuLHIscSl9
-LApXRDpmdW5jdGlvbiBXRChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1jCl8uZT1k
-fSwKSTc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7dGhp
-cy5hPWF9fSxPPXsKUmg6ZnVuY3Rpb24oKXt2YXIgcyxyPW51bGwKaWYoUC51bygpLmdGaSgpIT09ImZp
-bGUiKXJldHVybiAkLkViKCkKcz1QLnVvKCkKaWYoIUMueEIuVGMocy5nSWkocyksIi8iKSlyZXR1cm4g
-JC5FYigpCmlmKFAuS0wociwiYS9iIixyLHIscixyLHIpLnQ0KCk9PT0iYVxcYiIpcmV0dXJuICQuS2so
-KQpyZXR1cm4gJC5iRCgpfSwKekw6ZnVuY3Rpb24gekwoKXt9fSxFPXtPRjpmdW5jdGlvbiBPRihhLGIs
-Yyl7dGhpcy5kPWEKdGhpcy5lPWIKdGhpcy5mPWN9fSxGPXtydTpmdW5jdGlvbiBydShhLGIsYyxkKXt2
-YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sRD17CmFiOmZ1bmN0aW9uKCl7dmFyIHMs
-cixxLHAsbz1udWxsCnRyeXtvPVAudW8oKX1jYXRjaChzKXtpZih0Lmc4LmIoSC5SdShzKSkpe3I9JC5G
-ZgppZihyIT1udWxsKXJldHVybiByCnRocm93IHN9ZWxzZSB0aHJvdyBzfWlmKEouUk0obywkLkk2KSl7
-cj0kLkZmCnIudG9TdHJpbmcKcmV0dXJuIHJ9JC5JNj1vCmlmKCQuSGsoKT09JC5FYigpKXI9JC5GZj1v
-LlpJKCIuIikudygwKQplbHNle3E9by50NCgpCnA9cS5sZW5ndGgtMQpyPSQuRmY9cD09PTA/cTpDLnhC
-Lk5qKHEsMCxwKX1yLnRvU3RyaW5nCnJldHVybiByfX0KdmFyIHc9W0MsSCxKLFAsVyxNLFUsQixULEws
-WCxPLEUsRixEXQpodW5rSGVscGVycy5zZXRGdW5jdGlvbk5hbWVzSWZOZWNlc3NhcnkodykKdmFyICQ9
-e30KSC5GSy5wcm90b3R5cGU9e30KSi52Qi5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVy
-biBhPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0sCnc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIkluc3RhbmNlIG9mICciK0guRWooSC5NKGEpKSsiJyJ9LAplNzpmdW5jdGlvbihhLGIpe3Quby5h
-KGIpCnRocm93IEguYihQLmxyKGEsYi5nV2EoKSxiLmduZCgpLGIuZ1ZtKCkpKX19CkoueUUucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVy
-biBhPzUxOTAxODoyMTgxNTl9LAokaWEyOjF9Ckoud2UucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbnVsbD09Yn0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIm51bGwifSwKZ2lPOmZ1bmN0aW9u
-KGEpe3JldHVybiAwfSwKZTc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TaihhLHQuby5hKGIpKX0s
-CiRpYzg6MX0KSi5NRi5wcm90b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9LAp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXZtOjF9CkouaUMucHJvdG90eXBlPXt9Ckoua2QucHJv
-dG90eXBlPXt9CkouYzUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz1hWyQudygpXQppZihz
-PT1udWxsKXJldHVybiB0aGlzLnQoYSkKcmV0dXJuIkphdmFTY3JpcHQgZnVuY3Rpb24gZm9yICIrSC5F
-aihKLmoocykpfSwKJGlFSDoxfQpKLmpkLnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IG5ldyBILmpWKGEsSC50NihhKS5DKCJAPDE+IikuS3EoYikuQygialY8MSwyPiIpKX0sCmk6ZnVuY3Rp
-b24oYSxiKXtILnQ2KGEpLmMuYShiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudihQLkw0KCJhZGQiKSkK
-YS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZighIWEuZml4ZWQkbGVuZ3RoKUgudihQ
-Lkw0KCJyZW1vdmVBdCIpKQpzPWEubGVuZ3RoCmlmKGI+PXMpdGhyb3cgSC5iKFAuTzcoYixudWxsKSkK
-cmV0dXJuIGEuc3BsaWNlKGIsMSlbMF19LApVRzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscgpILnQ2KGEp
-LkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudihQLkw0KCJpbnNlcnRBbGwiKSkK
-UC53QShiLDAsYS5sZW5ndGgsImluZGV4IikKaWYoIXQuYi5iKGMpKWM9Si5SWChjKQpzPUouSG0oYykK
-YS5sZW5ndGg9YS5sZW5ndGgrcwpyPWIrcwp0aGlzLllXKGEscixhLmxlbmd0aCxhLGIpCnRoaXMudmco
-YSxiLHIsYyl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciBzCkgudDYoYSkuQygiY1g8MT4iKS5hKGIpCmlm
-KCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFkZEFsbCIpKQpmb3Iocz1KLklUKGIpO3MuRigpOylh
-LnB1c2gocy5nbCgpKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILnQ2KGEpCnJldHVybiBuZXcg
-SC5sSihhLHMuS3EoYykuQygiMSgyKSIpLmEoYikscy5DKCJAPDE+IikuS3EoYykuQygibEo8MSwyPiIp
-KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPVAuTzgoYS5sZW5ndGgsIiIsITEsdC5OKQpmb3Iocz0w
-O3M8YS5sZW5ndGg7KytzKXRoaXMuWShyLHMsSC5FaihhW3NdKSkKcmV0dXJuIHIuam9pbihiKX0sCmVS
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEgucUMoYSxiLG51bGwsSC50NihhKS5jKX0sCk4wOmZ1bmN0aW9u
-KGEsYixjLGQpe3ZhciBzLHIscQpkLmEoYikKSC50NihhKS5LcShkKS5DKCIxKDEsMikiKS5hKGMpCnM9
-YS5sZW5ndGgKZm9yKHI9YixxPTA7cTxzOysrcSl7cj1jLiQyKHIsYVtxXSkKaWYoYS5sZW5ndGghPT1z
-KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4gcn0sCkh0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAs
-bwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZvcihyPW51bGwscT0hMSxwPTA7cDxz
-OysrcCl7bz1hW3BdCmlmKEgub1QoYi4kMShvKSkpe2lmKHEpdGhyb3cgSC5iKEguQW0oKSkKcj1vCnE9
-ITB9aWYocyE9PWEubGVuZ3RoKXRocm93IEguYihQLmE0KGEpKX1pZihxKXJldHVybiByCnRocm93IEgu
-YihILldwKCkpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0go
-YSxiKQpyZXR1cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBd
-CnRocm93IEguYihILldwKCkpfSwKZ3JaOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCmlmKHM+MCly
-ZXR1cm4gYVtzLTFdCnRocm93IEguYihILldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
-cyxyLHEscCxvCkgudDYoYSkuQygiY1g8MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYo
-UC5MNCgic2V0UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnM9Yy1iCmlmKHM9PT0wKXJldHVybgpQ
-LmsxKGUsInNraXBDb3VudCIpCmlmKHQuai5iKGQpKXtyPWQKcT1lfWVsc2V7cj1KLkE1KGQsZSkudHQo
-MCwhMSkKcT0wfXA9Si5VNihyKQppZihxK3M+cC5nQShyKSl0aHJvdyBILmIoSC5hcigpKQppZihxPGIp
-Zm9yKG89cy0xO28+PTA7LS1vKWFbYitvXT1wLnEocixxK28pCmVsc2UgZm9yKG89MDtvPHM7KytvKWFb
-YitvXT1wLnEocixxK28pfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMs
-ZCwwKX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnQ2KGEpLkMoImEyKDEpIikuYShiKQpzPWEu
-bGVuZ3RoCmZvcihyPTA7cjxzOysrcil7aWYoSC5vVChiLiQxKGFbcl0pKSlyZXR1cm4hMAppZihhLmxl
-bmd0aCE9PXMpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIg
-cwpmb3Iocz0wO3M8YS5sZW5ndGg7KytzKWlmKEouUk0oYVtzXSxiKSlyZXR1cm4hMApyZXR1cm4hMX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmxlbmd0aCE9PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LAp0dDpm
-dW5jdGlvbihhLGIpe3ZhciBzPUguVk0oYS5zbGljZSgwKSxILnQ2KGEpKQpyZXR1cm4gc30sCmJyOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLnR0KGEsITApfSwKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBK
-Lm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4g
-SC5lUShhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9uKGEsYil7
-aWYoISFhLmZpeGVkJGxlbmd0aClILnYoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5i
-KFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEs
-Yil7SC51UChiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBh
-W2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC50NihhKS5jLmEoYykKaWYoISFhLmltbXV0YWJsZSRsaXN0
-KUgudihQLkw0KCJpbmRleGVkIHNldCIpKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZ
-KGEsYikpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkouUG8ucHJvdG90eXBlPXt9Ckou
-bTEucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3Zh
-ciBzLHI9dGhpcyxxPXIuYSxwPXEubGVuZ3RoCmlmKHIuYiE9PXApdGhyb3cgSC5iKEgubGsocSkpCnM9
-ci5jCmlmKHM+PXApe3Iuc00obnVsbCkKcmV0dXJuITF9ci5zTShxW3NdKTsrK3IuYwpyZXR1cm4hMH0s
-CnNNOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkoucUku
-cHJvdG90eXBlPXsKelE6ZnVuY3Rpb24oYSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJv
-dW5kKGEpfWVsc2UgaWYoYT4tMS8wKXJldHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5M
-NCgiIithKyIucm91bmQoKSIpKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiIt
-MC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz1hfDAKaWYo
-YT09PW8pcmV0dXJuIG8mNTM2ODcwOTExCnM9TWF0aC5hYnMoYSkKcj1NYXRoLmxvZyhzKS8wLjY5MzE0
-NzE4MDU1OTk0NTN8MApxPU1hdGgucG93KDIscikKcD1zPDE/cy9xOnEvcwpyZXR1cm4oKHAqOTAwNzE5
-OTI1NDc0MDk5MnwwKSsocCozNTQyMjQzMTgxMTc2NTIxfDApKSo1OTkxOTcrcioxMjU5JjUzNjg3MDkx
-MX0sCnpZOmZ1bmN0aW9uKGEsYil7dmFyIHM9YSViCmlmKHM9PT0wKXJldHVybiAwCmlmKHM+MClyZXR1
-cm4gcwppZihiPDApcmV0dXJuIHMtYgplbHNlIHJldHVybiBzK2J9LApCVTpmdW5jdGlvbihhLGIpe3Jl
-dHVybihhfDApPT09YT9hL2J8MDp0aGlzLkRKKGEsYil9LApESjpmdW5jdGlvbihhLGIpe3ZhciBzPWEv
-YgppZihzPj0tMjE0NzQ4MzY0OCYmczw9MjE0NzQ4MzY0NylyZXR1cm4gc3wwCmlmKHM+MCl7aWYocyE9
-PTEvMClyZXR1cm4gTWF0aC5mbG9vcihzKX1lbHNlIGlmKHM+LTEvMClyZXR1cm4gTWF0aC5jZWlsKHMp
-CnRocm93IEguYihQLkw0KCJSZXN1bHQgb2YgdHJ1bmNhdGluZyBkaXZpc2lvbiBpcyAiK0guRWoocykr
-IjogIitILkVqKGEpKyIgfi8gIitiKSl9LAp3RzpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGE+MClzPXRo
-aXMucDMoYSxiKQplbHNle3M9Yj4zMT8zMTpiCnM9YT4+cz4+PjB9cmV0dXJuIHN9LApiZjpmdW5jdGlv
-bihhLGIpe2lmKGI8MCl0aHJvdyBILmIoSC50TChiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIGI+MzE/MDphPj4+Yn0sCiRpQ1A6MSwKJGlMWjoxfQpKLmJVLnByb3Rv
-dHlwZT17JGlJZjoxfQpKLlZBLnByb3RvdHlwZT17fQpKLkRyLnByb3RvdHlwZT17Ck8yOmZ1bmN0aW9u
-KGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikpCmlmKGI+PWEubGVuZ3RoKUgudihILkhZKGEs
-YikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgp
-dGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIG5ldyBILnVuKGIsYSwwKX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0
-cmluZyIpdGhyb3cgSC5iKFAuTDMoYixudWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24o
-YSxiKXt2YXIgcz1iLmxlbmd0aCxyPWEubGVuZ3RoCmlmKHM+cilyZXR1cm4hMQpyZXR1cm4gYj09PXRo
-aXMuRyhhLHItcyl9LAppNzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcz1QLmpCKGIsYyxhLmxlbmd0aCks
-cj1hLnN1YnN0cmluZygwLGIpLHE9YS5zdWJzdHJpbmcocykKcmV0dXJuIHIrZCtxfSwKUWk6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzCmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5n
-dGgsbnVsbCxudWxsKSkKcz1jK2IubGVuZ3RoCmlmKHM+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9
-PT1hLnN1YnN0cmluZyhjLHMpfSwKbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0s
-Ck5qOmZ1bmN0aW9uKGEsYixjKXtpZihjPT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQ
-Lk83KGIsbnVsbCkpCmlmKGI+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRo
-cm93IEguYihQLk83KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihh
-LGIpe3JldHVybiB0aGlzLk5qKGEsYixudWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93
-ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLnRyaW0oKSxvPXAubGVuZ3RoCmlm
-KG89PT0wKXJldHVybiBwCmlmKHRoaXMuVyhwLDApPT09MTMzKXtzPUoubW0ocCwxKQppZihzPT09byly
-ZXR1cm4iIn1lbHNlIHM9MApyPW8tMQpxPXRoaXMuTzIocCxyKT09PTEzMz9KLmMxKHAscik6bwppZihz
-PT09MCYmcT09PW8pcmV0dXJuIHAKcmV0dXJuIHAuc3Vic3RyaW5nKHMscSl9LApJeDpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJldHVybiBh
-CmlmKGIhPT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHM9YSxyPSIiOyEwOyl7aWYoKGImMSk9PT0x
-KXI9cytyCmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKcys9c31yZXR1cm4gcn0sClhVOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcwppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51
-bGwsbnVsbCkpCnM9YS5pbmRleE9mKGIsYykKcmV0dXJuIHN9LApPWTpmdW5jdGlvbihhLGIpe3JldHVy
-biB0aGlzLlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKGM9PW51bGwpYz1h
-Lmxlbmd0aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgs
-bnVsbCxudWxsKSkKcz1iLmxlbmd0aApyPWEubGVuZ3RoCmlmKGMrcz5yKWM9ci1zCnJldHVybiBhLmxh
-c3RJbmRleE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixudWxsKX0s
-CklzOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1hLmxlbmd0aAppZihjPnMpdGhyb3cgSC5iKFAuVEUoYyww
-LHMsbnVsbCxudWxsKSkKcmV0dXJuIEguU1EoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-dGhpcy5JcyhhLGIsMCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIscQpmb3Iocz1hLmxlbmd0aCxyPTAscT0wO3E8czsrK3Epe3I9cithLmNoYXJDb2RlQXQocSkm
-NTM2ODcwOTExCnI9cisoKHImNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyXj1yPj42fXI9cisoKHImNjcx
-MDg4NjMpPDwzKSY1MzY4NzA5MTEKcl49cj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUpJjUzNjg3
-MDkxMX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQ
-KGIpCmlmKGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sCiRp
-dlg6MSwKJGlxVToxfQpILkJSLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUguTGgodGhp
-cykKcmV0dXJuIG5ldyBILkU3KEouSVQodGhpcy5nT04oKSkscy5DKCJAPDE+IikuS3Eocy5RWzFdKS5D
-KCJFNzwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nT04oKSl9LApnbDA6
-ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5nT04oKSl9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouRjcodGhpcy5nT04oKSl9LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJu
-IEguR0ooSi5BNSh0aGlzLmdPTigpLGIpLHMuYyxzLlFbMV0pfSwKRTpmdW5jdGlvbihhLGIpe3JldHVy
-biBILkxoKHRoaXMpLlFbMV0uYShKLkdBKHRoaXMuZ09OKCksYikpfSwKdzpmdW5jdGlvbihhKXtyZXR1
-cm4gSi5qKHRoaXMuZ09OKCkpfX0KSC5FNy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuYS5GKCl9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5RWzFdLmEodGhpcy5hLmdsKCkp
-fSwKJGlBbjoxfQpILlp5LnByb3RvdHlwZT17CmdPTjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9fQpI
-Lm9sLnByb3RvdHlwZT17JGliUToxfQpILlVxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gdGhpcy4kdGkuUVsxXS5hKEoueDkodGhpcy5hLEgudVAoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzPXRoaXMuJHRpCkoudTkodGhpcy5hLGIscy5jLmEocy5RWzFdLmEoYykpKX0sCiRpYlE6MSwK
-JGl6TToxfQpILmpWLnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmpWKHRo
-aXMuYSx0aGlzLiR0aS5DKCJAPDE+IikuS3EoYikuQygialY8MSwyPiIpKX0sCmdPTjpmdW5jdGlvbigp
-e3JldHVybiB0aGlzLmF9fQpILm4ucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEK
-cmV0dXJuIHMhPW51bGw/IkxhdGVJbml0aWFsaXphdGlvbkVycm9yOiAiK3M6IkxhdGVJbml0aWFsaXph
-dGlvbkVycm9yIn19CkgucjMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz0iUmVhY2hhYmls
-aXR5RXJyb3I6ICIrdGhpcy5hCnJldHVybiBzfX0KSC5xai5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy54Qi5PMih0aGlz
-LmEsSC51UChiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9u
-KGEpe3ZhciBzPXRoaXMKcmV0dXJuIG5ldyBILmE3KHMscy5nQShzKSxILkxoKHMpLkMoImE3PGFMLkU+
-IikpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCkg6ZnVuY3Rpb24o
-YSxiKXt2YXIgcyxyLHEscD10aGlzLG89cC5nQShwKQppZihiLmxlbmd0aCE9PTApe2lmKG89PT0wKXJl
-dHVybiIiCnM9SC5FaihwLkUoMCwwKSkKaWYobyE9PXAuZ0EocCkpdGhyb3cgSC5iKFAuYTQocCkpCmZv
-cihyPXMscT0xO3E8bzsrK3Epe3I9citiK0guRWoocC5FKDAscSkpCmlmKG8hPT1wLmdBKHApKXRocm93
-IEguYihQLmE0KHApKX1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1lbHNle2ZvcihxPTAscj0i
-IjtxPG87KytxKXtyKz1ILkVqKHAuRSgwLHEpKQppZihvIT09cC5nQShwKSl0aHJvdyBILmIoUC5hNChw
-KSl9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9fSwKZXY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-dGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHMuS3EoYykuQygiMShhTC5FKSIp
-LmEoYikscy5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmVSOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIEgucUModGhpcyxiLG51bGwsSC5MaCh0aGlzKS5DKCJhTC5FIikpfSwKdHQ6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gUC5DSCh0aGlzLCEwLEguTGgodGhpcykuQygiYUwuRSIpKX0sCmJyOmZ1bmN0aW9u
-KGEpe3JldHVybiB0aGlzLnR0KGEsITApfX0KSC5uSC5wcm90b3R5cGU9ewpIZDpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgcyxyPXRoaXMuYgpQLmsxKHIsInN0YXJ0IikKcz10aGlzLmMKaWYocyE9bnVsbCl7UC5r
-MShzLCJlbmQiKQppZihyPnMpdGhyb3cgSC5iKFAuVEUociwwLHMsInN0YXJ0IixudWxsKSl9fSwKZ1VE
-OmZ1bmN0aW9uKCl7dmFyIHM9Si5IbSh0aGlzLmEpLHI9dGhpcy5jCmlmKHI9PW51bGx8fHI+cylyZXR1
-cm4gcwpyZXR1cm4gcn0sCmdBczpmdW5jdGlvbigpe3ZhciBzPUouSG0odGhpcy5hKSxyPXRoaXMuYgpp
-ZihyPnMpcmV0dXJuIHMKcmV0dXJuIHJ9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPUouSG0odGhpcy5h
-KSxxPXRoaXMuYgppZihxPj1yKXJldHVybiAwCnM9dGhpcy5jCmlmKHM9PW51bGx8fHM+PXIpcmV0dXJu
-IHItcQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcmV0dXJuIHMtcX0sCkU6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz10aGlzLHI9cy5nQXMoKStiCmlmKGI8MHx8cj49cy5nVUQoKSl0aHJvdyBI
-LmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQShzLmEscil9LAplUjpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscT10aGlzClAuazEoYiwiY291bnQiKQpzPXEuYitiCnI9cS5jCmlmKHIh
-PW51bGwmJnM+PXIpcmV0dXJuIG5ldyBILk1CKHEuJHRpLkMoIk1CPDE+IikpCnJldHVybiBILnFDKHEu
-YSxzLHIscS4kdGkuYyl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPXRoaXMsbz1wLmIsbj1w
-LmEsbT1KLlU2KG4pLGw9bS5nQShuKSxrPXAuYwppZihrIT1udWxsJiZrPGwpbD1rCmlmKHR5cGVvZiBs
-IT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQpzPWwtbwppZihzPD0wKXtuPUouUWkoMCxwLiR0aS5jKQpy
-ZXR1cm4gbn1yPVAuTzgocyxtLkUobixvKSwhMSxwLiR0aS5jKQpmb3IocT0xO3E8czsrK3Epe0MuTm0u
-WShyLHEsbS5FKG4sbytxKSkKaWYobS5nQShuKTxsKXRocm93IEguYihQLmE0KHApKX1yZXR1cm4gcn19
-CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmQKcmV0dXJuIHN9LApGOmZ1
-bmN0aW9uKCl7dmFyIHMscj10aGlzLHE9ci5hLHA9Si5VNihxKSxvPXAuZ0EocSkKaWYoci5iIT09byl0
-aHJvdyBILmIoUC5hNChxKSkKcz1yLmMKaWYocz49byl7ci5zSShudWxsKQpyZXR1cm4hMX1yLnNJKHAu
-RShxLHMpKTsrK3IuYwpyZXR1cm4hMH0sCnNJOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5DKCIx
-PyIpLmEoYSl9LAokaUFuOjF9CkguaTEucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9SC5M
-aCh0aGlzKQpyZXR1cm4gbmV3IEguTUgoSi5JVCh0aGlzLmEpLHRoaXMuYixzLkMoIkA8MT4iKS5LcShz
-LlFbMV0pLkMoIk1IPDEsMj4iKSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwK
-Z2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILnh5LnByb3RvdHlwZT17JGliUToxfQpILk1ILnBy
-b3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5iCmlmKHIuRigpKXtzLnNJKHMuYy4k
-MShyLmdsKCkpKQpyZXR1cm4hMH1zLnNJKG51bGwpCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXt2YXIg
-cz10aGlzLmEKcmV0dXJuIHN9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuQygiMj8iKS5h
-KGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwK
-RTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90
-b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMuYix0
-aGlzLiR0aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzLHIK
-Zm9yKHM9dGhpcy5hLHI9dGhpcy5iO3MuRigpOylpZihILm9UKHIuJDEocy5nbCgpKSkpcmV0dXJuITAK
-cmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguQU0ucHJvdG90eXBl
-PXsKZVI6ZnVuY3Rpb24oYSxiKXtQLlVJKGIsImNvdW50Iix0LlMpClAuazEoYiwiY291bnQiKQpyZXR1
-cm4gbmV3IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcykuQygiQU08MT4iKSl9LApnbTpmdW5j
-dGlvbihhKXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRoaXMuYixILkxoKHRoaXMpLkMoIlUx
-PDE+IikpfX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcz1KLkhtKHRoaXMuYSkt
-dGhpcy5iCmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpmdW5jdGlvbihhLGIpe1AuVUkoYiwi
-Y291bnQiLHQuUykKUC5rMShiLCJjb3VudCIpCnJldHVybiBuZXcgSC5kNSh0aGlzLmEsdGhpcy5iK2Is
-dGhpcy4kdGkpfSwKJGliUToxfQpILlUxLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcyxyCmZv
-cihzPXRoaXMuYSxyPTA7cjx0aGlzLmI7KytyKXMuRigpCnRoaXMuYj0wCnJldHVybiBzLkYoKX0sCmds
-OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5NQi5wcm90b3R5cGU9ewpnbTpmdW5jdGlv
-bihhKXtyZXR1cm4gQy5Hd30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmdBOmZ1bmN0aW9uKGEp
-e3JldHVybiAwfSwKRTpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLlRFKGIsMCwwLCJpbmRleCIsbnVs
-bCkpfSwKZVI6ZnVuY3Rpb24oYSxiKXtQLmsxKGIsImNvdW50IikKcmV0dXJuIHRoaXN9fQpILkZ1LnBy
-b3RvdHlwZT17CkY6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7dGhyb3cgSC5iKEgu
-V3AoKSl9LAokaUFuOjF9CkgudTYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBI
-LkpCKEouSVQodGhpcy5hKSx0aGlzLiR0aS5DKCJKQjwxPiIpKX19CkguSkIucHJvdG90eXBlPXsKRjpm
-dW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9dGhpcy5hLHI9dGhpcy4kdGkuYztzLkYoKTspaWYoci5iKHMu
-Z2woKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5jLmEo
-dGhpcy5hLmdsKCkpfSwKJGlBbjoxfQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk6
-ZnVuY3Rpb24oYSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNh
-bm5vdCBtb2RpZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncyLnByb3RvdHlwZT17fQpILnd2
-LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLl9oYXNoQ29kZQppZihzIT1udWxs
-KXJldHVybiBzCnM9NjY0NTk3KkouaGYodGhpcy5hKSY1MzY4NzA5MTEKdGhpcy5faGFzaENvZGU9cwpy
-ZXR1cm4gc30sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytILkVqKHRoaXMuYSkrJyIpJ30s
-CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIEgu
-d3YmJnRoaXMuYT09Yi5hfSwKJGlHRDoxfQpILlFDLnByb3RvdHlwZT17fQpILlBELnByb3RvdHlwZT17
-fQpILldVLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlzKT09PTB9
-LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9
-SC5MaCh0aGlzKQpzLmMuYShiKQpzLlFbMV0uYShjKQpILmRjKCkKSC5CaSh1LmcpfSwKZ1B1OmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLnE0KGEsSC5MaCh0aGlzKS5DKCJOMzwxLDI+IikpfSwKcTQ6ZnVuY3Rp
-b24oYSxiKXt2YXIgcz10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9uKCl7dmFyIHI9YQp2YXIgcT0wLHA9
-MSxvLG4sbSxsLGsKcmV0dXJuIGZ1bmN0aW9uICRhc3luYyRnUHUoYyxkKXtpZihjPT09MSl7bz1kCnE9
-cH13aGlsZSh0cnVlKXN3aXRjaChxKXtjYXNlIDA6bj1zLmdWKCksbj1uLmdtKG4pLG09SC5MaChzKSxt
-PW0uQygiQDwxPiIpLktxKG0uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighbi5GKCkpe3E9Mwpi
-cmVha31sPW4uZ2woKQprPXMucSgwLGwpCmsudG9TdHJpbmcKcT00CnJldHVybiBuZXcgUC5OMyhsLGss
-bSkKY2FzZSA0OnE9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0o
-byl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19w
-cm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVu
-Y3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0sCnFQ
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEscCxvPUguTGgodGhpcykKby5DKCJ+KDEsMikiKS5hKGIpCnM9dGhpcy5jCmZvcihyPXMubGVuZ3Ro
-LG89by5RWzFdLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLG8uYSh0aGlzLnFQKHApKSl9fSwKZ1Y6
-ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+IikpfX0KSC5Y
-Ui5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEuYwpyZXR1cm4gbmV3IEoubTEo
-cyxzLmxlbmd0aCxILnQ2KHMpLkMoIm0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YS5jLmxlbmd0aH19CkguTEkucHJvdG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5hCnJl
-dHVybiBzfSwKZ25kOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8uYz09PTEpcmV0dXJu
-IEMuaFUKcz1vLmQKcj1zLmxlbmd0aC1vLmUubGVuZ3RoLW8uZgppZihyPT09MClyZXR1cm4gQy5oVQpx
-PVtdCmZvcihwPTA7cDxyOysrcCl7aWYocD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxwKQpxLnB1c2go
-c1twXSl9cmV0dXJuIEouekMocSl9LApnVm06ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9
-dGhpcwppZihrLmMhPT0wKXJldHVybiBDLldPCnM9ay5lCnI9cy5sZW5ndGgKcT1rLmQKcD1xLmxlbmd0
-aC1yLWsuZgppZihyPT09MClyZXR1cm4gQy5XTwpvPW5ldyBILk41KHQuZW8pCmZvcihuPTA7bjxyOysr
-bil7aWYobj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxuKQptPXNbbl0KbD1wK24KaWYobDwwfHxsPj1x
-Lmxlbmd0aClyZXR1cm4gSC5PSChxLGwpCm8uWSgwLG5ldyBILnd2KG0pLHFbbF0pfXJldHVybiBuZXcg
-SC5QRChvLHQuZ0YpfSwKJGl2UToxfQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFy
-IHMKSC5oKGEpCnM9dGhpcy5hCnMuYj1zLmIrIiQiK0guRWooYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5t
-LmkodGhpcy5jLGIpOysrcy5hfSwKJFM6MTN9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7
-dmFyIHMscixxPXRoaXMscD1uZXcgUmVnRXhwKHEuYSkuZXhlYyhhKQppZihwPT1udWxsKXJldHVybiBu
-dWxsCnM9T2JqZWN0LmNyZWF0ZShudWxsKQpyPXEuYgppZihyIT09LTEpcy5hcmd1bWVudHM9cFtyKzFd
-CnI9cS5jCmlmKHIhPT0tMSlzLmFyZ3VtZW50c0V4cHI9cFtyKzFdCnI9cS5kCmlmKHIhPT0tMSlzLmV4
-cHI9cFtyKzFdCnI9cS5lCmlmKHIhPT0tMSlzLm1ldGhvZD1wW3IrMV0Kcj1xLmYKaWYociE9PS0xKXMu
-cmVjZWl2ZXI9cFtyKzFdCnJldHVybiBzfX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILkVqKHRoaXMu
-YSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitzKyInIG9uIG51
-bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPSJOb1N1Y2hN
-ZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIscD1yLmIKaWYocD09bnVsbClyZXR1cm4iTm9T
-dWNoTWV0aG9kRXJyb3I6ICIrSC5FaihyLmEpCnM9ci5jCmlmKHM9PW51bGwpcmV0dXJuIHErcCsiJyAo
-IitILkVqKHIuYSkrIikiCnJldHVybiBxK3ArIicgb24gJyIrcysiJyAoIitILkVqKHIuYSkrIikifX0K
-SC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5sZW5ndGg9
-PT0wPyJFcnJvciI6IkVycm9yOiAiK3N9fQpILnRlLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIlRocm93IG9mIG51bGwgKCciKyh0aGlzLmE9PT1udWxsPyJudWxsIjoidW5kZWZpbmVkIikrIicg
-ZnJvbSBKYXZhU2NyaXB0KSJ9LAokaVJ6OjF9CkguYnEucHJvdG90eXBlPXt9CkguWE8ucHJvdG90eXBl
-PXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuYgppZihyIT1udWxsKXJldHVybiByCnI9dGhpcy5h
-CnM9ciE9PW51bGwmJnR5cGVvZiByPT09Im9iamVjdCI/ci5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9
-cz09bnVsbD8iIjpzfSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9
-dGhpcy5jb25zdHJ1Y3RvcixyPXM9PW51bGw/bnVsbDpzLm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5O
-UShyPT1udWxsPyJ1bmtub3duIjpyKSsiJyJ9LAokaUVIOjEsCmdLdTpmdW5jdGlvbigpe3JldHVybiB0
-aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5
-cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHN0YXRpY19uYW1lCmlmKHM9PW51bGwpcmV0dXJu
-IkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHMp
-KyInIn19CkguclQucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlmKGI9PW51
-bGwpcmV0dXJuITEKaWYocz09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5yVCkpcmV0dXJu
-ITEKcmV0dXJuIHMuYT09PWIuYSYmcy5iPT09Yi5iJiZzLmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7
-dmFyIHMscj10aGlzLmMKaWYocj09bnVsbClzPUguZVEodGhpcy5hKQplbHNlIHM9dHlwZW9mIHIhPT0i
-b2JqZWN0Ij9KLmhmKHIpOkguZVEocikKcj1ILmVRKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVtYmVy
-IilyZXR1cm4gcy53TygpCnJldHVybihzXnIpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5j
-CmlmKHM9PW51bGwpcz10aGlzLmEKcmV0dXJuIkNsb3N1cmUgJyIrSC5Faih0aGlzLmQpKyInIG9mICIr
-KCJJbnN0YW5jZSBvZiAnIitILkVqKEguTShzKSkrIiciKX19CkguRXEucHJvdG90eXBlPXsKdzpmdW5j
-dGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK3RoaXMuYX19Ckgua1kucHJvdG90eXBlPXsKdzpm
-dW5jdGlvbihhKXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLmhsKHRoaXMuYSl9fQpILmtyLnBy
-b3RvdHlwZT17fQpILk41LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApn
-bDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09PTB9LApnVjpmdW5jdGlvbigpe3JldHVybiBuZXcg
-SC5pNSh0aGlzLEguTGgodGhpcykuQygiaTU8MT4iKSl9LAp4NDpmdW5jdGlvbihhKXt2YXIgcyxyCmlm
-KHR5cGVvZiBhPT0ic3RyaW5nIil7cz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhp
-cy5YdShzLGEpfWVsc2V7cj10aGlzLkNYKGEpCnJldHVybiByfX0sCkNYOmZ1bmN0aW9uKGEpe3ZhciBz
-PXRoaXMuZAppZihzPT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkZoKHRoaXMuQnQocyxKLmhmKGEp
-JjB4M2ZmZmZmZiksYSk+PTB9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz10aGlzLG49bnVs
-bAppZih0eXBlb2YgYj09InN0cmluZyIpe3M9by5iCmlmKHM9PW51bGwpcmV0dXJuIG4Kcj1vLmoyKHMs
-YikKcT1yPT1udWxsP246ci5iCnJldHVybiBxfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYw
-eDNmZmZmZmYpPT09Yil7cD1vLmMKaWYocD09bnVsbClyZXR1cm4gbgpyPW8uajIocCxiKQpxPXI9PW51
-bGw/bjpyLmIKcmV0dXJuIHF9ZWxzZSByZXR1cm4gby5hYShiKX0sCmFhOmZ1bmN0aW9uKGEpe3ZhciBz
-LHIscT10aGlzLmQKaWYocT09bnVsbClyZXR1cm4gbnVsbApzPXRoaXMuQnQocSxKLmhmKGEpJjB4M2Zm
-ZmZmZikKcj10aGlzLkZoKHMsYSkKaWYocjwwKXJldHVybiBudWxsCnJldHVybiBzW3JdLmJ9LApZOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9SC5MaChtKQpsLmMuYShiKQpsLlFb
-MV0uYShjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3M9bS5iCm0uRUgocz09bnVsbD9tLmI9bS56Sygp
-OnMsYixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3I9bS5j
-Cm0uRUgocj09bnVsbD9tLmM9bS56SygpOnIsYixjKX1lbHNle3E9bS5kCmlmKHE9PW51bGwpcT1tLmQ9
-bS56SygpCnA9Si5oZihiKSYweDNmZmZmZmYKbz1tLkJ0KHEscCkKaWYobz09bnVsbCltLkVJKHEscCxb
-bS5IbihiLGMpXSkKZWxzZXtuPW0uRmgobyxiKQppZihuPj0wKW9bbl0uYj1jCmVsc2Ugby5wdXNoKG0u
-SG4oYixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9dGhpcwpILkxoKHEpLkMoIn4oMSwy
-KSIpLmEoYikKcz1xLmUKcj1xLnIKZm9yKDtzIT1udWxsOyl7Yi4kMihzLmEscy5iKQppZihyIT09cS5y
-KXRocm93IEguYihQLmE0KHEpKQpzPXMuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj10aGlz
-LHE9SC5MaChyKQpxLmMuYShiKQpxLlFbMV0uYShjKQpzPXIuajIoYSxiKQppZihzPT1udWxsKXIuRUko
-YSxiLHIuSG4oYixjKSkKZWxzZSBzLmI9Y30sCmtzOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjY3
-MTA4ODYzfSwKSG46ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLHI9SC5MaChzKSxxPW5ldyBILnZoKHIu
-Yy5hKGEpLHIuUVsxXS5hKGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7cj1zLmYKci50b1N0
-cmluZwpxLmQ9cgpzLmY9ci5jPXF9KytzLmEKcy5rcygpCnJldHVybiBxfSwKRmg6ZnVuY3Rpb24oYSxi
-KXt2YXIgcyxyCmlmKGE9PW51bGwpcmV0dXJuLTEKcz1hLmxlbmd0aApmb3Iocj0wO3I8czsrK3IpaWYo
-Si5STShhW3JdLmEsYikpcmV0dXJuIHIKcmV0dXJuLTF9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5P
-KHRoaXMpfSwKajI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkJ0OmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIGFbYl19LApFSTpmdW5jdGlvbihhLGIsYyl7YVtiXT1jfSwKcm46ZnVuY3Rpb24oYSxiKXtkZWxl
-dGUgYVtiXX0sClh1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuajIoYSxiKSE9bnVsbH0sCnpLOmZ1
-bmN0aW9uKCl7dmFyIHM9Ijxub24taWRlbnRpZmllci1rZXk+IixyPU9iamVjdC5jcmVhdGUobnVsbCkK
-dGhpcy5FSShyLHMscikKdGhpcy5ybihyLHMpCnJldHVybiByfSwKJGlGbzoxfQpILnZoLnByb3RvdHlw
-ZT17fQpILmk1LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYX0sCmdsMDpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmE9PT0wfSwKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5h
-LHI9bmV3IEguTjYocyxzLnIsdGhpcy4kdGkuQygiTjY8MT4iKSkKci5jPXMuZQpyZXR1cm4gcn0sCnRn
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19CkguTjYucHJvdG90eXBlPXsKZ2w6ZnVu
-Y3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihy
-LmIhPT1xLnIpdGhyb3cgSC5iKFAuYTQocSkpCnM9ci5jCmlmKHM9PW51bGwpe3Iuc3FZKG51bGwpCnJl
-dHVybiExfWVsc2V7ci5zcVkocy5hKQpyLmM9cy5jCnJldHVybiEwfX0sCnNxWTpmdW5jdGlvbihhKXt0
-aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpILmRDLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoYSl9LAokUzo0fQpILndOLnByb3RvdHlwZT17CiQyOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuYShhLGIpfSwKJFM6NDJ9CkguVlgucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYShILmgoYSkpfSwKJFM6MzV9CkguVlIucHJvdG90eXBlPXsKdzpm
-dW5jdGlvbihhKXtyZXR1cm4iUmVnRXhwLyIrdGhpcy5hKyIvIit0aGlzLmIuZmxhZ3N9LApnSGM6ZnVu
-Y3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jCmlmKHIhPW51bGwpcmV0dXJuIHIKcj1zLmIKcmV0dXJuIHMu
-Yz1ILnY0KHMuYSxyLm11bHRpbGluZSwhci5pZ25vcmVDYXNlLHIudW5pY29kZSxyLmRvdEFsbCwhMCl9
-LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5LVyh0aGlzLGIsMCl9LApVWjpmdW5jdGlvbihh
-LGIpe3ZhciBzLHI9dGhpcy5nSGMoKQpyLmxhc3RJbmRleD1iCnM9ci5leGVjKGEpCmlmKHM9PW51bGwp
-cmV0dXJuIG51bGwKcmV0dXJuIG5ldyBILkVLKHMpfSwKJGl2WDoxLAokaXdMOjF9CkguRUsucHJvdG90
-eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciBzCkgudVAoYikKcz10aGlzLmIKaWYoYj49cy5sZW5ndGgp
-cmV0dXJuIEguT0gocyxiKQpyZXR1cm4gc1tiXX0sCiRpT2Q6MSwKJGlpYjoxfQpILktXLnByb3RvdHlw
-ZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5QYih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpI
-LlBiLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2
-YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9bS5iCmlmKGw9PW51bGwpcmV0dXJuITEKcz1tLmMKcj1sLmxl
-bmd0aAppZihzPD1yKXtxPW0uYQpwPXEuVVoobCxzKQppZihwIT1udWxsKXttLmQ9cApzPXAuYgpvPXMu
-aW5kZXgKbj1vK3NbMF0ubGVuZ3RoCmlmKG89PT1uKXtpZihxLmIudW5pY29kZSl7cz1tLmMKcT1zKzEK
-aWYocTxyKXtzPUMueEIuTzIobCxzKQppZihzPj01NTI5NiYmczw9NTYzMTkpe3M9Qy54Qi5PMihsLHEp
-CnM9cz49NTYzMjAmJnM8PTU3MzQzfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExCm49KHM/bisx
-Om4pKzF9bS5jPW4KcmV0dXJuITB9fW0uYj1tLmQ9bnVsbApyZXR1cm4hMX0sCiRpQW46MX0KSC50US5w
-cm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQppZihiIT09MClILnYoUC5PNyhiLG51bGwp
-KQpyZXR1cm4gdGhpcy5jfSwKJGlPZDoxfQpILnVuLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVu
-Y3Rpb24oKXt2YXIgcyxyLHE9dGhpcyxwPXEuYyxvPXEuYixuPW8ubGVuZ3RoLG09cS5hLGw9bS5sZW5n
-dGgKaWYocCtuPmwpe3EuZD1udWxsCnJldHVybiExfXM9bS5pbmRleE9mKG8scCkKaWYoczwwKXtxLmM9
-bCsxCnEuZD1udWxsCnJldHVybiExfXI9cytuCnEuZD1uZXcgSC50UShzLG8pCnEuYz1yPT09cS5jP3Ir
-MTpyCnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmQKcy50b1N0cmluZwpyZXR1cm4g
-c30sCiRpQW46MX0KSC5FVC5wcm90b3R5cGU9eyRpRVQ6MSwkaUFTOjF9CkguWEgucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKJGlYajoxfQpILkRnLnByb3RvdHlwZT17CnE6
-ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sClk6ZnVu
+dGFuY2VvZiBILlZSKXtzPUMueEIueW4oYSxjKQpyZXR1cm4gYi5iLnRlc3Qocyl9ZWxzZXtzPUouRkwo
+YixDLnhCLnluKGEsYykpCnJldHVybiFzLmdsMChzKX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4
+T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1
+bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgv
+W1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcz1ILm5NKGEsYixjKQpyZXR1cm4gc30sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscApp
+ZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwpzPWEubGVuZ3RoCmZvcihyPWMscT0wO3E8czsrK3Ep
+cj1yK2FbcV0rYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1wPWEuaW5kZXhPZihiLDApCmlm
+KHA8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEu
+c3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEgu
+QTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rp
+b24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
+Yz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpm
+dW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5m
+PWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpm
+dW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApf
+LmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5j
+dGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2Vihh
+KXt0aGlzLmE9YX0sCnRlOmZ1bmN0aW9uIHRlKGEpe3RoaXMuYT1hfSwKYnE6ZnVuY3Rpb24gYnEoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxs
+fSwKVHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5jdGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7
+fSwKclQ6ZnVuY3Rpb24gclQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9
+ZH0sCkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1hfSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9
+LAprcjpmdW5jdGlvbiBrcigpe30sCk41OmZ1bmN0aW9uIE41KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5m
+PV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LAp2aDpmdW5jdGlvbiB2aChhLGIpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKaTU6ZnVuY3Rpb24gaTUoYSxiKXt0aGlz
+LmE9YQp0aGlzLiR0aT1ifSwKTjY6ZnVuY3Rpb24gTjYoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
+PWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LApkQzpmdW5jdGlvbiBkQyhhKXt0aGlzLmE9YX0sCndOOmZ1
+bmN0aW9uIHdOKGEpe3RoaXMuYT1hfSwKVlg6ZnVuY3Rpb24gVlgoYSl7dGhpcy5hPWF9LApWUjpmdW5j
+dGlvbiBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rp
+b24gRUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
+dGhpcy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhpcy5hPWEKdGhpcy5jPWJ9LAp1bjpmdW5j
+dGlvbiB1bihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApTZDpmdW5jdGlvbiBTZChh
+LGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEp
+e3JldHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIo
+SC5IWShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZighKGE+Pj4wIT09YSkpcz1iPj4+
+MCE9PWJ8fGE+Ynx8Yj5jCmVsc2Ugcz0hMAppZihzKXRocm93IEguYihILmF1KGEsYixjKSkKcmV0dXJu
+IGJ9LApFVDpmdW5jdGlvbiBFVCgpe30sCkxaOmZ1bmN0aW9uIExaKCl7fSwKRGc6ZnVuY3Rpb24gRGco
+KXt9LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9uIHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUo
+KXt9LApaQTpmdW5jdGlvbiBaQSgpe30sCmRUOmZ1bmN0aW9uIGRUKCl7fSwKUHE6ZnVuY3Rpb24gUHEo
+KXt9LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9uIFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkco
+KXt9LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9uIFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkco
+KXt9LApjejpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4gcz09bnVsbD9iLmM9SC5CKGEsYi56
+LCEwKTpzfSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5jPUguSihh
+LCJiOCIsW2Iuel0pOnN9LApRMTpmdW5jdGlvbihhKXt2YXIgcz1hLnkKaWYocz09PTZ8fHM9PT03fHxz
+PT09OClyZXR1cm4gSC5RMShhLnopCnJldHVybiBzPT09MTF8fHM9PT0xMn0sCm1EOmZ1bmN0aW9uKGEp
+e3JldHVybiBhLmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCEx
+KX0sClBMOmZ1bmN0aW9uKGEsYixhMCxhMSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixl
+LGQsYz1iLnkKc3dpdGNoKGMpe2Nhc2UgNTpjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6cmV0dXJu
+IGIKY2FzZSA2OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJldHVybiBI
+LkMoYSxyLCEwKQpjYXNlIDc6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0dXJuIGIK
+cmV0dXJuIEguQihhLHIsITApCmNhc2UgODpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihyPT09cyly
+ZXR1cm4gYgpyZXR1cm4gSC5mKGEsciwhMCkKY2FzZSA5OnE9Yi5RCnA9SC5iWihhLHEsYTAsYTEpCmlm
+KHA9PT1xKXJldHVybiBiCnJldHVybiBILkooYSxiLnoscCkKY2FzZSAxMDpvPWIuegpuPUguUEwoYSxv
+LGEwLGExKQptPWIuUQpsPUguYlooYSxtLGEwLGExKQppZihuPT09byYmbD09PW0pcmV0dXJuIGIKcmV0
+dXJuIEguYShhLG4sbCkKY2FzZSAxMTprPWIuegpqPUguUEwoYSxrLGEwLGExKQppPWIuUQpoPUgucVQo
+YSxpLGEwLGExKQppZihqPT09ayYmaD09PWkpcmV0dXJuIGIKcmV0dXJuIEguZChhLGosaCkKY2FzZSAx
+MjpnPWIuUQphMSs9Zy5sZW5ndGgKZj1ILmJaKGEsZyxhMCxhMSkKbz1iLnoKbj1ILlBMKGEsbyxhMCxh
+MSkKaWYoZj09PWcmJm49PT1vKXJldHVybiBiCnJldHVybiBILkQoYSxuLGYsITApCmNhc2UgMTM6ZT1i
+LnoKaWYoZTxhMSlyZXR1cm4gYgpkPWEwW2UtYTFdCmlmKGQ9PW51bGwpcmV0dXJuIGIKcmV0dXJuIGQK
+ZGVmYXVsdDp0aHJvdyBILmIoUC5oVigiQXR0ZW1wdGVkIHRvIHN1YnN0aXR1dGUgdW5leHBlY3RlZCBS
+VEkga2luZCAiK2MpKX19LApiWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvPWIubGVuZ3Ro
+LG49W10KZm9yKHM9ITEscj0wO3I8bzsrK3Ipe3E9YltyXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEp
+cz0hMApuLnB1c2gocCl9cmV0dXJuIHM/bjpifSwKdk86ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
+LHAsbyxuLG09Yi5sZW5ndGgsbD1bXQpmb3Iocz0hMSxyPTA7cjxtO3IrPTMpe3E9YltyXQpwPWJbcisx
+XQpvPWJbcisyXQpuPUguUEwoYSxvLGMsZCkKaWYobiE9PW8pcz0hMApsLnB1c2gocSkKbC5wdXNoKHAp
+CmwucHVzaChuKX1yZXR1cm4gcz9sOmJ9LApxVDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyPWIuYSxx
+PUguYlooYSxyLGMsZCkscD1iLmIsbz1ILmJaKGEscCxjLGQpLG49Yi5jLG09SC52TyhhLG4sYyxkKQpp
+ZihxPT09ciYmbz09PXAmJm09PT1uKXJldHVybiBiCnM9bmV3IEguRygpCnMuYT1xCnMuYj1vCnMuYz1t
+CnJldHVybiBzfSwKVk06ZnVuY3Rpb24oYSxiKXthW3YuYXJyYXlSdGldPWIKcmV0dXJuIGF9LApKUzpm
+dW5jdGlvbihhKXt2YXIgcz1hLiRTCmlmKHMhPW51bGwpe2lmKHR5cGVvZiBzPT0ibnVtYmVyIilyZXR1
+cm4gSC5CcChzKQpyZXR1cm4gYS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIg
+cwppZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILlRwKXtzPUguSlMoYSkKaWYocyE9bnVsbClyZXR1
+cm4gc31yZXR1cm4gSC56KGEpfSwKejpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNlb2YgUC5N
+aCl7cz1hLiR0aQpyZXR1cm4gcyE9bnVsbD9zOkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1
+cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciBzPWFbdi5h
+cnJheVJ0aV0scj10LngKaWYocz09bnVsbClyZXR1cm4gcgppZihzLmNvbnN0cnVjdG9yIT09ci5jb25z
+dHJ1Y3RvcilyZXR1cm4gcgpyZXR1cm4gc30sCkxoOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJHRpCnJldHVy
+biBzIT1udWxsP3M6SC5WVShhKX0sClZVOmZ1bmN0aW9uKGEpe3ZhciBzPWEuY29uc3RydWN0b3Iscj1z
+LiRjY2FjaGUKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gSC5yOShhLHMpfSwKcjk6ZnVuY3Rpb24o
+YSxiKXt2YXIgcz1hIGluc3RhbmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0
+b3I6YixyPUguYWkodi50eXBlVW5pdmVyc2Uscy5uYW1lKQpiLiRjY2FjaGU9cgpyZXR1cm4gcn0sCkJw
+OmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpILnVQKGEpCnM9di50eXBlcwpyPXNbYV0KaWYodHlwZW9mIHI9
+PSJzdHJpbmciKXtxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCExKQpzW2FdPXEKcmV0dXJuIHF9cmV0dXJu
+IHJ9LApLeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLngKaWYocCE9bnVsbClyZXR1cm4gcApzPWEu
+Y3kKcj1zLnJlcGxhY2UoL1wqL2csIiIpCmlmKHI9PT1zKXJldHVybiBhLng9bmV3IEgubFkoYSkKcT1I
+LkUodi50eXBlVW5pdmVyc2UsciwhMCkKcD1xLngKcmV0dXJuIGEueD1wPT1udWxsP3EueD1uZXcgSC5s
+WShxKTpwfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXApcmV0dXJu
+IEguUkUocSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNlIHA9ITAK
+ZWxzZSBwPSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56OnEKaWYo
+cz09PXQuUylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2UgaWYocz09
+PXQuTilyPUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4gSC5SRShx
+LGEscikKaWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitwCnJldHVy
+biBILlJFKHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkKcmV0dXJu
+IEguUkUocSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIoYil9LApB
+dTpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8pKXM9cT09
+PXQuSwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSylyPUguVGkK
+ZWxzZSByPUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55
+CmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1yPT09OCYm
+SC5RaihhLnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVs
+c2Ugcz0hMApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1
+cm4gSC5RaihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxzLG51bGwp
+fSwKQVE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIoYSl9LAp0
+NDpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpzPXIucgpp
+ZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVu
+Y3Rpb24oYSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVy
+biBhCkgubTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4g
+YQplbHNlIGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIpe3Rocm93
+IEguYihILlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVybiBhCnRo
+cm93IEguYihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicgaXMgbm90
+IGEgc3VidHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixzKSkrIicg
+b2YgdHlwZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwKV0s6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzPVAucChhKSxyPUguZG0oYj09bnVsbD9ILnooYSk6YixudWxsKQpyZXR1
+cm4gcysiOiB0eXBlICciK0guRWoocikrIicgaXMgbm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guRWoo
+YykrIicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrYSl9LApx
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrSC5XSyhhLG51bGwsYikp
+fSwKa2U6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPW51bGx9LApUaTpmdW5jdGlvbihhKXtyZXR1cm4gYX0s
+Ckl3OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApsOmZ1bmN0
+aW9uKGEpe3JldHVybiEwPT09YXx8ITE9PT1hfSwKcDg6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVy
+biEwCmlmKCExPT09YSlyZXR1cm4hMQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LAp5ODpmdW5jdGlv
+bihhKXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKZHA6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVy
+biEwCmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwi
+Ym9vbD8iKSl9LApGRzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKdGhy
+b3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApHSDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJl
+ciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZSIpKX0s
+ClFrOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJl
+dHVybiBhCnRocm93IEguYihILnEoYSwiZG91YmxlPyIpKX0sCm9rOmZ1bmN0aW9uKGEpe3JldHVybiB0
+eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hfSwKSVo6ZnVuY3Rpb24oYSl7aWYodHlw
+ZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEs
+ImludCIpKX0sCnVQOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihh
+KT09PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludCIpKX0s
+ClVjOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludD8iKSl9LApLSDpmdW5j
+dGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKejU6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
+IGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKVzE6ZnVuY3Rpb24o
+YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
+SC5iKEgucShhLCJudW0iKSl9LApjVTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bT8iKSl9LApNTTpmdW5j
+dGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKQnQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
+IGE9PSJzdHJpbmciKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaDpmdW5jdGlv
+bihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJv
+dyBILmIoSC5xKGEsIlN0cmluZyIpKX0sCms6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmci
+KXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmc/IikpfSwK
+aW86ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKZm9yKHM9IiIscj0iIixxPTA7cTxhLmxlbmd0aDsrK3Es
+cj0iLCAiKXMrPUMueEIuaChyLEguZG0oYVtxXSxiKSkKcmV0dXJuIHN9LApiSTpmdW5jdGlvbihhNSxh
+NixhNyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMs
+YTQ9IiwgIgppZihhNyE9bnVsbCl7cz1hNy5sZW5ndGgKaWYoYTY9PW51bGwpe2E2PUguVk0oW10sdC5z
+KQpyPW51bGx9ZWxzZSByPWE2Lmxlbmd0aApxPWE2Lmxlbmd0aApmb3IocD1zO3A+MDstLXApQy5ObS5p
+KGE2LCJUIisocStwKSkKZm9yKG89dC5XLG49dC5fLG09dC5LLGw9IjwiLGs9IiIscD0wO3A8czsrK3As
+az1hNCl7bCs9awpqPWE2Lmxlbmd0aAppPWotMS1wCmlmKGk8MClyZXR1cm4gSC5PSChhNixpKQpsPUMu
+eEIuaChsLGE2W2ldKQpoPWE3W3BdCmc9aC55CmlmKCEoZz09PTJ8fGc9PT0zfHxnPT09NHx8Zz09PTV8
+fGg9PT1vKSlpZighKGg9PT1uKSlqPWg9PT1tCmVsc2Ugaj0hMAplbHNlIGo9ITAKaWYoIWopbCs9Qy54
+Qi5oKCIgZXh0ZW5kcyAiLEguZG0oaCxhNikpfWwrPSI+In1lbHNle2w9IiIKcj1udWxsfW89YTUuegpm
+PWE1LlEKZT1mLmEKZD1lLmxlbmd0aApjPWYuYgpiPWMubGVuZ3RoCmE9Zi5jCmEwPWEubGVuZ3RoCmEx
+PUguZG0obyxhNikKZm9yKGEyPSIiLGEzPSIiLHA9MDtwPGQ7KytwLGEzPWE0KWEyKz1DLnhCLmgoYTMs
+SC5kbShlW3BdLGE2KSkKaWYoYj4wKXthMis9YTMrIlsiCmZvcihhMz0iIixwPTA7cDxiOysrcCxhMz1h
+NClhMis9Qy54Qi5oKGEzLEguZG0oY1twXSxhNikpCmEyKz0iXSJ9aWYoYTA+MCl7YTIrPWEzKyJ7Igpm
+b3IoYTM9IiIscD0wO3A8YTA7cCs9MyxhMz1hNCl7YTIrPWEzCmlmKGFbcCsxXSlhMis9InJlcXVpcmVk
+ICIKYTIrPUouYmIoSC5kbShhW3ArMl0sYTYpLCIgIikrYVtwXX1hMis9In0ifWlmKHIhPW51bGwpe2E2
+LnRvU3RyaW5nCmE2Lmxlbmd0aD1yfXJldHVybiBsKyIoIithMisiKSA9PiAiK0guRWooYTEpfSwKZG06
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEueQppZihsPT09NSlyZXR1cm4iZXJhc2Vk
+IgppZihsPT09MilyZXR1cm4iZHluYW1pYyIKaWYobD09PTMpcmV0dXJuInZvaWQiCmlmKGw9PT0xKXJl
+dHVybiJOZXZlciIKaWYobD09PTQpcmV0dXJuImFueSIKaWYobD09PTYpe3M9SC5kbShhLnosYikKcmV0
+dXJuIHN9aWYobD09PTcpe3I9YS56CnM9SC5kbShyLGIpCnE9ci55CnJldHVybiBKLmJiKHE9PT0xMXx8
+cT09PTEyP0MueEIuaCgiKCIscykrIikiOnMsIj8iKX1pZihsPT09OClyZXR1cm4iRnV0dXJlT3I8IitI
+LkVqKEguZG0oYS56LGIpKSsiPiIKaWYobD09PTkpe3A9SC5vMyhhLnopCm89YS5RCnJldHVybiBvLmxl
+bmd0aCE9PTA/cCsoIjwiK0guaW8obyxiKSsiPiIpOnB9aWYobD09PTExKXJldHVybiBILmJJKGEsYixu
+dWxsKQppZihsPT09MTIpcmV0dXJuIEguYkkoYS56LGIsYS5RKQppZihsPT09MTMpe2IudG9TdHJpbmcK
+bj1hLnoKbT1iLmxlbmd0aApuPW0tMS1uCmlmKG48MHx8bj49bSlyZXR1cm4gSC5PSChiLG4pCnJldHVy
+biBiW25dfXJldHVybiI/In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5KZyhhKQppZihyIT1udWxs
+KXJldHVybiByCnM9Im1pbmlmaWVkOiIrYQpyZXR1cm4gc30sClFvOmZ1bmN0aW9uKGEsYil7dmFyIHM9
+YS50UltiXQpmb3IoO3R5cGVvZiBzPT0ic3RyaW5nIjspcz1hLnRSW3NdCnJldHVybiBzfSwKYWk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49YS5lVCxtPW5bYl0KaWYobT09bnVsbClyZXR1cm4gSC5F
+KGEsYiwhMSkKZWxzZSBpZih0eXBlb2YgbT09Im51bWJlciIpe3M9bQpyPUgubShhLDUsIiMiKQpxPVtd
+CmZvcihwPTA7cDxzOysrcClxLnB1c2gocikKbz1ILkooYSxiLHEpCm5bYl09bwpyZXR1cm4gb31lbHNl
+IHJldHVybiBtfSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1hLmVD
+LHE9ci5nZXQoYikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaShILm8oYSxudWxsLGIsYykpCnIuc2V0
+KGIscykKcmV0dXJuIHN9LApjRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIuY2gKaWYocT09bnVs
+bClxPWIuY2g9bmV3IE1hcCgpCnM9cS5nZXQoYykKaWYocyE9bnVsbClyZXR1cm4gcwpyPUguaShILm8o
+YSxiLGMsITApKQpxLnNldChjLHIpCnJldHVybiByfSwKdjU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
+cSxwPWIuY3gKaWYocD09bnVsbClwPWIuY3g9bmV3IE1hcCgpCnM9Yy5jeQpyPXAuZ2V0KHMpCmlmKHIh
+PW51bGwpcmV0dXJuIHIKcT1ILmEoYSxiLGMueT09PTEwP2MuUTpbY10pCnAuc2V0KHMscSkKcmV0dXJu
+IHF9LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILkF1CmIuYj1ILkpKCnJldHVybiBifSwKbTpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxPWEuZUMuZ2V0KGMpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1uZXcgSC5K
+YyhudWxsLG51bGwpCnMueT1iCnMuY3k9YwpyPUguQkQoYSxzKQphLmVDLnNldChjLHIpCnJldHVybiBy
+fSwKQzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIqIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51
+bGwpcmV0dXJuIHEKcz1ILlo3KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApaNzpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpcj1iPT09dC5QfHxi
+PT09dC5UfHxzPT09N3x8cz09PTYKZWxzZSByPSEwCmlmKHIpcmV0dXJuIGJ9cT1uZXcgSC5KYyhudWxs
+LG51bGwpCnEueT02CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwKQjpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMscj1iLmN5KyI/IixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmxs
+KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
+cyxyLHEscAppZihkKXtzPWIueQppZighSC5BOChiKSlpZighKGI9PT10LlB8fGI9PT10LlQpKWlmKHMh
+PT03KXI9cz09PTgmJkgubFIoYi56KQplbHNlIHI9ITAKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXJl
+dHVybiBiCmVsc2UgaWYocz09PTF8fGI9PT10LmNGKXJldHVybiB0LlAKZWxzZSBpZihzPT09Nil7cT1i
+LnoKaWYocS55PT09OCYmSC5sUihxLnopKXJldHVybiBxCmVsc2UgcmV0dXJuIEguY3ooYSxiKX19cD1u
+ZXcgSC5KYyhudWxsLG51bGwpCnAueT03CnAuej1iCnAuY3k9YwpyZXR1cm4gSC5CRChhLHApfSwKZjpm
+dW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIvIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0
+dXJuIHEKcz1ILmVWKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LAplVjpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5fKSlyPWI9
+PT10LksKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyfHxiPT09dC5LKXJldHVybiBiCmVsc2UgaWYocz09
+PTEpcmV0dXJuIEguSihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT10LlB8fGI9PT10LlQpcmV0dXJuIHQu
+Ykd9cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT04CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEp
+fSwKSDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iIitiKyJeIixwPWEuZUMuZ2V0KHEpCmlmKHAhPW51
+bGwpcmV0dXJuIHAKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT0xMwpzLno9YgpzLmN5PXEKcj1ILkJE
+KGEscykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sClV4OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEu
+bGVuZ3RoCmZvcihzPSIiLHI9IiIscT0wO3E8cDsrK3Escj0iLCIpcys9cithW3FdLmN5CnJldHVybiBz
+fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09YS5sZW5ndGgKZm9yKHM9IiIscj0iIixx
+PTA7cTxtO3ErPTMscj0iLCIpe3A9YVtxXQpvPWFbcSsxXT8iISI6IjoiCm49YVtxKzJdLmN5CnMrPXIr
+cCtvK259cmV0dXJuIHN9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1iCmlmKGMubGVuZ3Ro
+IT09MClwKz0iPCIrSC5VeChjKSsiPiIKcz1hLmVDLmdldChwKQppZihzIT1udWxsKXJldHVybiBzCnI9
+bmV3IEguSmMobnVsbCxudWxsKQpyLnk9OQpyLno9YgpyLlE9YwppZihjLmxlbmd0aD4wKXIuYz1jWzBd
+CnIuY3k9cApxPUguQkQoYSxyKQphLmVDLnNldChwLHEpCnJldHVybiBxfSwKYTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMscixxLHAsbyxuCmlmKGIueT09PTEwKXtzPWIuegpyPWIuUS5jb25jYXQoYyl9ZWxzZXty
+PWMKcz1ifXE9cy5jeSsoIjs8IitILlV4KHIpKyI+IikKcD1hLmVDLmdldChxKQppZihwIT1udWxsKXJl
+dHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56PXMKby5RPXIKby5jeT1xCm49SC5C
+RChhLG8pCmEuZUMuc2V0KHEsbikKcmV0dXJuIG59LApkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEs
+cCxvLG49Yi5jeSxtPWMuYSxsPW0ubGVuZ3RoLGs9Yy5iLGo9ay5sZW5ndGgsaT1jLmMsaD1pLmxlbmd0
+aCxnPSIoIitILlV4KG0pCmlmKGo+MCl7cz1sPjA/IiwiOiIiCnI9SC5VeChrKQpnKz1zKyJbIityKyJd
+In1pZihoPjApe3M9bD4wPyIsIjoiIgpyPUguUzQoaSkKZys9cysieyIrcisifSJ9cT1uKyhnKyIpIikK
+cD1hLmVDLmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9
+MTEKby56PWIKby5RPWMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApE
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9Yi5jeSsoIjwiK0guVXgoYykrIj4iKSxxPWEuZUMuZ2V0
+KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmh3KGEsYixjLHIsZCkKYS5lQy5zZXQocixzKQpyZXR1
+cm4gc30sCmh3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbAppZihlKXtzPWMu
+bGVuZ3RoCnI9bmV3IEFycmF5KHMpCmZvcihxPTAscD0wO3A8czsrK3Ape289Y1twXQppZihvLnk9PT0x
+KXtyW3BdPW87KytxfX1pZihxPjApe249SC5QTChhLGIsciwwKQptPUguYlooYSxjLHIsMCkKcmV0dXJu
+IEguRChhLG4sbSxjIT09bSl9fWw9bmV3IEguSmMobnVsbCxudWxsKQpsLnk9MTIKbC56PWIKbC5RPWMK
+bC5jeT1kCnJldHVybiBILkJEKGEsbCl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1OmEsZTpi
+LHI6YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZz1hLnIsZj1hLnMKZm9yKHM9Zy5sZW5ndGgscj0wO3I8czspe3E9Zy5jaGFyQ29kZUF0KHIpCmlm
+KHE+PTQ4JiZxPD01NylyPUguQShyKzEscSxnLGYpCmVsc2UgaWYoKCgocXwzMik+Pj4wKS05NyY2NTUz
+NSk8MjZ8fHE9PT05NXx8cT09PTM2KXI9SC50KGEscixnLGYsITEpCmVsc2UgaWYocT09PTQ2KXI9SC50
+KGEscixnLGYsITApCmVsc2V7KytyCnN3aXRjaChxKXtjYXNlIDQ0OmJyZWFrCmNhc2UgNTg6Zi5wdXNo
+KCExKQpicmVhawpjYXNlIDMzOmYucHVzaCghMCkKYnJlYWsKY2FzZSA1OTpmLnB1c2goSC5LKGEudSxh
+LmUsZi5wb3AoKSkpCmJyZWFrCmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJyZWFrCmNh
+c2UgMzU6Zi5wdXNoKEgubShhLnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0oYS51LDIs
+IkAiKSkKYnJlYWsKY2FzZSAxMjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNlIDYwOmYu
+cHVzaChhLnApCmEucD1mLmxlbmd0aApicmVhawpjYXNlIDYyOnA9YS51Cm89Zi5zcGxpY2UoYS5wKQpI
+LnIoYS51LGEuZSxvKQphLnA9Zi5wb3AoKQpuPWYucG9wKCkKaWYodHlwZW9mIG49PSJzdHJpbmciKWYu
+cHVzaChILkoocCxuLG8pKQplbHNle209SC5LKHAsYS5lLG4pCnN3aXRjaChtLnkpe2Nhc2UgMTE6Zi5w
+dXNoKEguRChwLG0sbyxhLm4pKQpicmVhawpkZWZhdWx0OmYucHVzaChILmEocCxtLG8pKQpicmVha319
+YnJlYWsKY2FzZSAzODpILkkoYSxmKQpicmVhawpjYXNlIDQyOmw9YS51CmYucHVzaChILkMobCxILkso
+bCxhLmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA2MzpsPWEudQpmLnB1c2goSC5CKGwsSC5LKGws
+YS5lLGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDc6bD1hLnUKZi5wdXNoKEguZihsLEguSyhsLGEu
+ZSxmLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQwOmYucHVzaChhLnApCmEucD1mLmxlbmd0aApicmVh
+awpjYXNlIDQxOnA9YS51Cms9bmV3IEguRygpCmo9cC5zRUEKaT1wLnNFQQpuPWYucG9wKCkKaWYodHlw
+ZW9mIG49PSJudW1iZXIiKXN3aXRjaChuKXtjYXNlLTE6aj1mLnBvcCgpCmJyZWFrCmNhc2UtMjppPWYu
+cG9wKCkKYnJlYWsKZGVmYXVsdDpmLnB1c2gobikKYnJlYWt9ZWxzZSBmLnB1c2gobikKbz1mLnNwbGlj
+ZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmsuYT1vCmsuYj1qCmsuYz1pCmYucHVzaChI
+LmQocCxILksocCxhLmUsZi5wb3AoKSksaykpCmJyZWFrCmNhc2UgOTE6Zi5wdXNoKGEucCkKYS5wPWYu
+bGVuZ3RoCmJyZWFrCmNhc2UgOTM6bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBv
+cCgpCmYucHVzaChvKQpmLnB1c2goLTEpCmJyZWFrCmNhc2UgMTIzOmYucHVzaChhLnApCmEucD1mLmxl
+bmd0aApicmVhawpjYXNlIDEyNTpvPWYuc3BsaWNlKGEucCkKSC55KGEudSxhLmUsbykKYS5wPWYucG9w
+KCkKZi5wdXNoKG8pCmYucHVzaCgtMikKYnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIr
+cX19fWg9Zi5wb3AoKQpyZXR1cm4gSC5LKGEudSxhLmUsaCl9LApBOmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzLHIscT1iLTQ4CmZvcihzPWMubGVuZ3RoO2E8czsrK2Epe3I9Yy5jaGFyQ29kZUF0KGEpCmlmKCEo
+cj49NDgmJnI8PTU3KSlicmVhawpxPXEqMTArKHItNDgpfWQucHVzaChxKQpyZXR1cm4gYX0sCnQ6ZnVu
+Y3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbT1iKzEKZm9yKHM9Yy5sZW5ndGg7bTxzOysr
+bSl7cj1jLmNoYXJDb2RlQXQobSkKaWYocj09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgo
+KHJ8MzIpPj4+MCktOTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNikpcT1yPj00OCYmcjw9NTcKZWxz
+ZSBxPSEwCmlmKCFxKWJyZWFrfX1wPWMuc3Vic3RyaW5nKGIsbSkKaWYoZSl7cz1hLnUKbz1hLmUKaWYo
+by55PT09MTApbz1vLnoKbj1ILlFvKHMsby56KVtwXQppZihuPT1udWxsKUgudignTm8gIicrcCsnIiBp
+biAiJytILm1EKG8pKyciJykKZC5wdXNoKEguY0UocyxvLG4pKX1lbHNlIGQucHVzaChwKQpyZXR1cm4g
+bX0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLnBvcCgpCmlmKDA9PT1zKXtiLnB1c2goSC5tKGEudSwx
+LCIwJiIpKQpyZXR1cm59aWYoMT09PXMpe2IucHVzaChILm0oYS51LDQsIjEmIikpCnJldHVybn10aHJv
+dyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILkVqKHMpKSl9LApLOmZ1
+bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguSihhLGMsYS5zRUEpCmVs
+c2UgaWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixjKQplbHNlIHJldHVybiBjfSwK
+cjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0wO3M8cjsrK3MpY1tzXT1ILkso
+YSxiLGNbc10pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0yO3M8cjtz
+Kz0zKWNbc109SC5LKGEsYixjW3NdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9Yi55Cmlm
+KHE9PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegpzPWIuUQpyPXMubGVuZ3RoCmlmKGM8PXIpcmV0dXJu
+IHNbYy0xXQpjLT1yCmI9Yi56CnE9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYocSE9PTkpdGhy
+b3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnM9Yi5R
+CmlmKGM8PXMubGVuZ3RoKXJldHVybiBzW2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2Mr
+IiBmb3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0s
+bCxrLGoKaWYoYj09PWQpcmV0dXJuITAKaWYoIUguQTgoZCkpaWYoIShkPT09dC5fKSlzPWQ9PT10LksK
+ZWxzZSBzPSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiEwCnI9Yi55CmlmKHI9PT00KXJldHVybiEwCmlm
+KEguQTgoYikpcmV0dXJuITEKaWYoYi55IT09MSlzPWI9PT10LlB8fGI9PT10LlQKZWxzZSBzPSEwCmlm
+KHMpcmV0dXJuITAKcT1yPT09MTMKaWYocSlpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApw
+PWQueQppZihyPT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocD09PTYpe3M9ZC56CnJldHVy
+biBILldlKGEsYixjLHMsZSl9aWYocj09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpy
+ZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYocj09PTcpe3M9SC5XZShhLGIueixjLGQsZSkK
+cmV0dXJuIHN9aWYocD09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldl
+KGEsYixjLEgueFooYSxkKSxlKX1pZihwPT09Nyl7cz1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gc31p
+ZihxKXJldHVybiExCnM9ciE9PTExCmlmKCghc3x8cj09PTEyKSYmZD09PXQuWSlyZXR1cm4hMAppZihw
+PT09MTIpe2lmKGI9PT10LkQpcmV0dXJuITAKaWYociE9PTEyKXJldHVybiExCm89Yi5RCm49ZC5RCm09
+by5sZW5ndGgKaWYobSE9PW4ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9vOm8uY29uY2F0KGMpCmU9
+ZT09bnVsbD9uOm4uY29uY2F0KGUpCmZvcihsPTA7bDxtOysrbCl7az1vW2xdCmo9bltsXQppZighSC5X
+ZShhLGssYyxqLGUpfHwhSC5XZShhLGosZSxrLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMs
+ZC56LGUpfWlmKHA9PT0xMSl7aWYoYj09PXQuRClyZXR1cm4hMAppZihzKXJldHVybiExCnJldHVybiBI
+LmJPKGEsYixjLGQsZSl9aWYocj09PTkpe2lmKHAhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixj
+LGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMixhMyxhNCxhNSxhNil7dmFyIHMscixxLHAsbyxu
+LG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEKaWYoIUguV2UoYTIsYTMueixhNCxhNS56LGE2
+KSlyZXR1cm4hMQpzPWEzLlEKcj1hNS5RCnE9cy5hCnA9ci5hCm89cS5sZW5ndGgKbj1wLmxlbmd0aApp
+ZihvPm4pcmV0dXJuITEKbT1uLW8KbD1zLmIKaz1yLmIKaj1sLmxlbmd0aAppPWsubGVuZ3RoCmlmKG8r
+ajxuK2kpcmV0dXJuITEKZm9yKGg9MDtoPG87KytoKXtnPXFbaF0KaWYoIUguV2UoYTIscFtoXSxhNixn
+LGE0KSlyZXR1cm4hMX1mb3IoaD0wO2g8bTsrK2gpe2c9bFtoXQppZighSC5XZShhMixwW28raF0sYTYs
+ZyxhNCkpcmV0dXJuITF9Zm9yKGg9MDtoPGk7KytoKXtnPWxbbStoXQppZighSC5XZShhMixrW2hdLGE2
+LGcsYTQpKXJldHVybiExfWY9cy5jCmU9ci5jCmQ9Zi5sZW5ndGgKYz1lLmxlbmd0aApmb3IoYj0wLGE9
+MDthPGM7YSs9Myl7YTA9ZVthXQpmb3IoOyEwOyl7aWYoYj49ZClyZXR1cm4hMQphMT1mW2JdCmIrPTMK
+aWYoYTA8YTEpcmV0dXJuITEKaWYoYTE8YTApY29udGludWUKZz1mW2ItMV0KaWYoIUguV2UoYTIsZVth
+KzJdLGE2LGcsYTQpKXJldHVybiExCmJyZWFrfX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQs
+ZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPWIueixqPWQuegppZihrPT09ail7cz1iLlEKcj1kLlEKcT1z
+Lmxlbmd0aApmb3IocD0wO3A8cTsrK3Ape289c1twXQpuPXJbcF0KaWYoIUguV2UoYSxvLGMsbixlKSly
+ZXR1cm4hMX1yZXR1cm4hMH1pZihkPT09dC5LKXJldHVybiEwCm09SC5RbyhhLGspCmlmKG09PW51bGwp
+cmV0dXJuITEKbD1tW2pdCmlmKGw9PW51bGwpcmV0dXJuITEKcT1sLmxlbmd0aApyPWQuUQpmb3IocD0w
+O3A8cTsrK3ApaWYoIUguV2UoYSxILmNFKGEsYixsW3BdKSxjLHJbcF0sZSkpcmV0dXJuITEKcmV0dXJu
+ITB9LApsUjpmdW5jdGlvbihhKXt2YXIgcyxyPWEueQppZighKGE9PT10LlB8fGE9PT10LlQpKWlmKCFI
+LkE4KGEpKWlmKHIhPT03KWlmKCEocj09PTYmJkgubFIoYS56KSkpcz1yPT09OCYmSC5sUihhLnopCmVs
+c2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCmNjOmZ1bmN0aW9u
+KGEpe3ZhciBzCmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpcz1hPT09dC5LCmVsc2Ugcz0hMAplbHNl
+IHM9ITAKcmV0dXJuIHN9LApBODpmdW5jdGlvbihhKXt2YXIgcz1hLnkKcmV0dXJuIHM9PT0yfHxzPT09
+M3x8cz09PTR8fHM9PT01fHxhPT09dC5XfSwKSXg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9T2JqZWN0
+LmtleXMoYikscD1xLmxlbmd0aApmb3Iocz0wO3M8cDsrK3Mpe3I9cVtzXQphW3JdPWJbcl19fSwKSmM6
+ZnVuY3Rpb24gSmMoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55
+PTAKXy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1udWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMu
+Yj10aGlzLmE9bnVsbH0sCmxZOmZ1bmN0aW9uIGxZKGEpe3RoaXMuYT1hfSwKa1M6ZnVuY3Rpb24ga1Mo
+KXt9LAppTTpmdW5jdGlvbiBpTShhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB0Lncu
+YihhKXx8dC5CLmIoYSl8fHQuZHouYihhKXx8dC5JLmIoYSl8fHQuQS5iKGEpfHx0Lmc0LmIoYSl8fHQu
+ZzIuYihhKX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9
+ewpRdTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9u
+KGEpe3ZhciBzLHIscSxwLG89YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihvPT1udWxsKWlmKCQu
+QnY9PW51bGwpe0guWEQoKQpvPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV19aWYobyE9bnVsbCl7cz1v
+LnAKaWYoITE9PT1zKXJldHVybiBvLmkKaWYoITA9PT1zKXJldHVybiBhCnI9T2JqZWN0LmdldFByb3Rv
+dHlwZU9mKGEpCmlmKHM9PT1yKXJldHVybiBvLmkKaWYoby5lPT09cil0aHJvdyBILmIoUC5TWSgiUmV0
+dXJuIGludGVyY2VwdG9yIGZvciAiK0guRWoocyhhLG8pKSkpfXE9YS5jb25zdHJ1Y3RvcgpwPXE9PW51
+bGw/bnVsbDpxW0ouUlAoKV0KaWYocCE9bnVsbClyZXR1cm4gcApwPUgudzMoYSkKaWYocCE9bnVsbCly
+ZXR1cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwpzPU9iamVjdC5nZXRQcm90
+b3R5cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1PYmplY3QucHJvdG90eXBlKXJl
+dHVybiBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkocSxK
+LlJQKCkse3ZhbHVlOkMudkIsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJs
+ZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJuIEMudkJ9LApSUDpmdW5jdGlvbigpe3ZhciBzPSQuem0K
+cmV0dXJuIHM9PW51bGw/JC56bT12LmdldElzb2xhdGVUYWcoIl8kZGFydF9qcyIpOnN9LApRaTpmdW5j
+dGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRFKGEsMCw0Mjk0OTY3Mjk1
+LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9LApLaDpmdW5jdGlvbihh
+LGIpe2lmKGE8MCl0aHJvdyBILmIoUC54WSgiTGVuZ3RoIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50
+ZWdlcjogIithKSkKcmV0dXJuIEguVk0obmV3IEFycmF5KGEpLGIuQygiamQ8MD4iKSl9LApweTpmdW5j
+dGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpLGIpfSwKRXA6ZnVuY3Rpb24o
+YSxiKXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpDOmZ1bmN0aW9uKGEpe2EuZml4ZWQk
+bGVuZ3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0dXJuIGF9LApHYTpmdW5jdGlvbihh
+KXtpZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMTpjYXNlIDEyOmNhc2UgMTM6
+Y2FzZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfXN3aXRjaChh
+KXtjYXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgxOTQ6Y2FzZSA4MTk1OmNhc2UgODE5
+NjpjYXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgyMDA6Y2FzZSA4MjAxOmNhc2UgODIw
+MjpjYXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgyODc6Y2FzZSAxMjI4ODpjYXNlIDY1
+Mjc5OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZv
+cihzPWEubGVuZ3RoO2I8czspe3I9Qy54Qi5XKGEsYikKaWYociE9PTMyJiZyIT09MTMmJiFKLkdhKHIp
+KWJyZWFrOysrYn1yZXR1cm4gYn0sCmMxOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3IoO2I+MDtiPXMp
+e3M9Yi0xCnI9Qy54Qi5PMihhLHMpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVha31yZXR1
+cm4gYn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5wcm90
+b3R5cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxs
+KXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0
+eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3Rv
+dHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0s
+ClU2OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUK
+aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90
+b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4g
+Si5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJu
+IEoua3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVy
+biBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVuY3Rp
+b24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBKLmJV
+LnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBlb2Yg
+YT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSly
+ZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1
+bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgp
+cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmlu
+ZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNl
+b2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdmQ6ZnVuY3Rpb24oYSl7aWYo
+dHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBh
+CmlmKCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0sCncx
+OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0
+dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5j
+dGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJl
+dHVybiBhCnJldHVybiBKLmtzKGEpfSwKQTU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5lUihh
+LGIpfSwKRWg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllFKGEpLm1LKGEsYixjKX0sCkVsOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuZHIoYSxiKX0sCkY3OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2
+KGEpLmdvcihhKX0sCkZMOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuZGQoYSxiKX0sCkdBOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuRShhLGIpfSwKSG06ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+VTYoYSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5nbShhKX0sCkp5OmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEouaWEoYSkuZTcoYSxiKX0sCktWOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEou
+clkoYSkueW4oYSxiKX0sCkx0OmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLndnKGEpfSwKTTE6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLkUyKGEsYixjKX0sCk11OmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIEouWUUoYSkuc24oYSxiKX0sClF6OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVyhhLGIp
+fSwKUk06ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiPT1udWxsCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0IilyZXR1cm4gYiE9bnVsbCYmYT09PWIKcmV0dXJuIEouaWEoYSkuRE4oYSxiKX0sClJYOmZ1
+bmN0aW9uKGEpe3JldHVybiBKLncxKGEpLmJyKGEpfSwKVDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEouclko
+YSkuYlMoYSl9LApWdTpmdW5jdGlvbihhKXtyZXR1cm4gSi52ZChhKS56UShhKX0sCmE2OmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEouclkoYSkuTzIoYSxiKX0sCmJUOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEp
+LkQ0KGEpfSwKYmI6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYT09Im51bWJlciImJnR5cGVvZiBiPT0i
+bnVtYmVyIilyZXR1cm4gYStiCnJldHVybiBKLlRKKGEpLmgoYSxiKX0sCmNIOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBKLnJZKGEpLmhjKGEpfSwKZFI6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkuZ24oYSl9LApk
+WjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5ZRShhKS5PbihhLGIsYyxkKX0sCmRnOmZ1bmN0aW9u
+KGEsYixjLGQpe3JldHVybiBKLnJZKGEpLmk3KGEsYixjLGQpfSwKZGg6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouWUUoYSkuRkYoYSl9LApkcjpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNhNChhLGIpfSwK
+aGY6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuZ2lPKGEpfSwKaWc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouWUUoYSkuZ1FnKGEpfSwKajpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS53KGEpfSwKbDU6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5ZRShhKS5zaGYoYSxiKX0sCmxkOmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gSi5yWShhKS5OaihhLGIsYyl9LApwNDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlRjKGEs
+Yil9LApxMDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuUWkoYSxiLGMpfSwKcUY6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouWUUoYSkuZ1ZsKGEpfSwKdEg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllF
+KGEpLnBrKGEsYixjKX0sCnU5OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5ZNShhLGIsYyl9
+LAp1VTpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS5nbDAoYSl9LAp3ZjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBKLllFKGEpLnNSTihhLGIpfSwKeDk6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYj09PSJudW1i
+ZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0eXBlb2YgYT09InN0cmluZyJ8fEgud1YoYSxhW3Yu
+ZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+MD09PWImJmI8YS5sZW5ndGgpcmV0dXJuIGFbYl0K
+cmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5VNihhKS50Zyhh
+LGIpfSwKR3Y6ZnVuY3Rpb24gR3YoKXt9LAp5RTpmdW5jdGlvbiB5RSgpe30sCndlOmZ1bmN0aW9uIHdl
+KCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpmdW5jdGlvbiBpQygpe30sCmtkOmZ1bmN0aW9uIGtk
+KCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpmdW5jdGlvbiBqZChhKXt0aGlzLiR0aT1hfSwKUG86
+ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0xOmZ1bmN0aW9uIG0xKGEsYixjKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRpPWN9LApxSTpmdW5jdGlvbiBxSSgpe30sCmJV
+OmZ1bmN0aW9uIGJVKCl7fSwKVkE6ZnVuY3Rpb24gVkEoKXt9LApEcjpmdW5jdGlvbiBEcigpe319LFA9
+ewpPajpmdW5jdGlvbigpe3ZhciBzLHIscT17fQppZihzZWxmLnNjaGVkdWxlSW1tZWRpYXRlIT1udWxs
+KXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlvbk9ic2VydmVyIT1udWxsJiZzZWxmLmRvY3VtZW50
+IT1udWxsKXtzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IikKcj1zZWxmLmRvY3VtZW50
+LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpxLmE9bnVsbApuZXcgc2VsZi5NdXRhdGlvbk9ic2VydmVyKEgu
+dFIobmV3IFAudGgocSksMSkpLm9ic2VydmUocyx7Y2hpbGRMaXN0OnRydWV9KQpyZXR1cm4gbmV3IFAu
+aGEocSxzLHIpfWVsc2UgaWYoc2VsZi5zZXRJbW1lZGlhdGUhPW51bGwpcmV0dXJuIFAueXQoKQpyZXR1
+cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2VsZi5zY2hlZHVsZUltbWVkaWF0ZShILnRSKG5ldyBQ
+LlZzKHQuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlvbihhKXtzZWxmLnNldEltbWVkaWF0ZShILnRSKG5l
+dyBQLkZ0KHQuTS5hKGEpKSwwKSl9LApCejpmdW5jdGlvbihhKXt0Lk0uYShhKQpQLlFOKDAsYSl9LApR
+TjpmdW5jdGlvbihhLGIpe3ZhciBzPW5ldyBQLlczKCkKcy5DWShhLGIpCnJldHVybiBzfSwKRlg6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQLnZzKCQuWDMsYS5DKCJ2czwwPiIpKSxhLkMoImlo
+PDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQyKDAsbnVsbCkKYi5iPSEwCnJldHVybiBiLmF9LApq
+UTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlDOmZ1bmN0aW9uKGEsYil7Yi5hTSgwLGEpfSwKZjM6
+ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50cyhhKSl9LApKZTpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscT1uZXcgUC5XTShiKSxwPW5ldyBQLlNYKGIpCmlmKGEgaW5zdGFuY2VvZiBQLnZzKWEuUWQocSxw
+LHQueikKZWxzZXtzPXQuegppZih0LmQuYihhKSlhLlNxKHEscCxzKQplbHNle3I9bmV3IFAudnMoJC5Y
+Myx0LmMpCnIuYT00CnIuYz1hCnIuUWQocSxwLHMpfX19LApsejpmdW5jdGlvbihhKXt2YXIgcz1mdW5j
+dGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUpe3doaWxlKHRydWUpdHJ5e2IoZCxlKQpicmVha31j
+YXRjaChyKXtlPXIKZD1jfX19KGEsMSkKcmV0dXJuICQuWDMuTGoobmV3IFAuR3MocyksdC5ILHQuUyx0
+LnopfSwKSUc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3Jl
+dHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygicTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIscQpiLmE9MQp0cnl7YS5TcShuZXcgUC5wVihiKSxuZXcgUC5VNyhiKSx0LlApfWNhdGNoKHEp
+e3M9SC5SdShxKQpyPUgudHMocSkKUC5yYihuZXcgUC52cihiLHMscikpfX0sCkE5OmZ1bmN0aW9uKGEs
+Yil7dmFyIHMscixxCmZvcihzPXQuYztyPWEuYSxyPT09MjspYT1zLmEoYS5jKQppZihyPj00KXtxPWIu
+YWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHEpfWVsc2V7cT10LkYuYShiLmMpCmIuYT0yCmIuYz1h
+CmEualEocSl9fSwKSFo6ZnVuY3Rpb24oYTAsYTEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxn
+LGYsZSxkLGM9bnVsbCxiPXt9LGE9Yi5hPWEwCmZvcihzPXQubixyPXQuRixxPXQuZDshMDspe3A9e30K
+bz1hLmE9PT04CmlmKGExPT1udWxsKXtpZihvKXtuPXMuYShhLmMpClAuTDIoYyxjLGEuYixuLmEsbi5i
+KX1yZXR1cm59cC5hPWExCm09YTEuYQpmb3IoYT1hMTttIT1udWxsO2E9bSxtPWwpe2EuYT1udWxsClAu
+SFooYi5hLGEpCnAuYT1tCmw9bS5hfWs9Yi5hCmo9ay5jCnAuYj1vCnAuYz1qCmk9IW8KaWYoaSl7aD1h
+LmMKaD0oaCYxKSE9PTB8fChoJjE1KT09PTh9ZWxzZSBoPSEwCmlmKGgpe2c9YS5iLmIKaWYobyl7aD1r
+LmI9PT1nCmg9IShofHxoKX1lbHNlIGg9ITEKaWYoaCl7cy5hKGopClAuTDIoYyxjLGsuYixqLmEsai5i
+KQpyZXR1cm59Zj0kLlgzCmlmKGYhPT1nKSQuWDM9ZwplbHNlIGY9YwphPWEuYwppZigoYSYxNSk9PT04
+KW5ldyBQLlJUKHAsYixvKS4kMCgpCmVsc2UgaWYoaSl7aWYoKGEmMSkhPT0wKW5ldyBQLnJxKHAsaiku
+JDAoKX1lbHNlIGlmKChhJjIpIT09MCluZXcgUC5SVyhiLHApLiQwKCkKaWYoZiE9bnVsbCkkLlgzPWYK
+YT1wLmMKaWYocS5iKGEpKXtlPXAuYS5iCmlmKGEuYT49NCl7ZD1yLmEoZS5jKQplLmM9bnVsbAphMT1l
+Lk44KGQpCmUuYT1hLmEKZS5jPWEuYwpiLmE9YQpjb250aW51ZX1lbHNlIFAuQTkoYSxlKQpyZXR1cm59
+fWU9cC5hLmIKZD1yLmEoZS5jKQplLmM9bnVsbAphMT1lLk44KGQpCmE9cC5iCms9cC5jCmlmKCFhKXtl
+LiR0aS5jLmEoaykKZS5hPTQKZS5jPWt9ZWxzZXtzLmEoaykKZS5hPTgKZS5jPWt9Yi5hPWUKYT1lfX0s
+ClZIOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYodC5hZy5iKGEpKXJldHVybiBiLkxqKGEsdC56LHQuSyx0
+LmwpCnM9dC5iSQppZihzLmIoYSkpcmV0dXJuIHMuYShhKQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9y
+IiwiRXJyb3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUgT2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEg
+U3RhY2tUcmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm4gYSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1
+OmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz0kLlM2O3MhPW51bGw7cz0kLlM2KXskLm1nPW51bGwKcj1z
+LmIKJC5TNj1yCmlmKHI9PW51bGwpJC5rOD1udWxsCnMuYS4kMCgpfX0sCmVOOmZ1bmN0aW9uKCl7JC5V
+RD0hMAp0cnl7UC5wdSgpfWZpbmFsbHl7JC5tZz1udWxsCiQuVUQ9ITEKaWYoJC5TNiE9bnVsbCkkLnV0
+KCkuJDEoUC5VSSgpKX19LAplVzpmdW5jdGlvbihhKXt2YXIgcz1uZXcgUC5PTShhKSxyPSQuazgKaWYo
+cj09bnVsbCl7JC5TNj0kLms4PXMKaWYoISQuVUQpJC51dCgpLiQxKFAuVUkoKSl9ZWxzZSAkLms4PXIu
+Yj1zfSwKclI6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9JC5TNgppZihwPT1udWxsKXtQLmVXKGEpCiQu
+bWc9JC5rOApyZXR1cm59cz1uZXcgUC5PTShhKQpyPSQubWcKaWYocj09bnVsbCl7cy5iPXAKJC5TNj0k
+Lm1nPXN9ZWxzZXtxPXIuYgpzLmI9cQokLm1nPXIuYj1zCmlmKHE9PW51bGwpJC5rOD1zfX0sCnJiOmZ1
+bmN0aW9uKGEpe3ZhciBzPW51bGwscj0kLlgzCmlmKEMuTlU9PT1yKXtQLlRrKHMscyxDLk5VLGEpCnJl
+dHVybn1QLlRrKHMscyxyLHQuTS5hKHIudDgoYSkpKX0sClF3OmZ1bmN0aW9uKGEsYil7SC5jYihhLCJz
+dHJlYW0iLHQuSykKcmV0dXJuIG5ldyBQLnhJKGIuQygieEk8MD4iKSl9LApUbDpmdW5jdGlvbihhLGIp
+e3ZhciBzPUguY2IoYSwiZXJyb3IiLHQuSykKcmV0dXJuIG5ldyBQLkN3KHMsYj09bnVsbD9QLnYwKGEp
+OmIpfSwKdjA6ZnVuY3Rpb24oYSl7dmFyIHMKaWYodC5yLmIoYSkpe3M9YS5nSUkoKQppZihzIT1udWxs
+KXJldHVybiBzfXJldHVybiBDLnBkfSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXtQLnJSKG5ldyBQLnBL
+KGQsZSkpfSwKVDg6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJu
+IGQuJDAoKQokLlgzPWMKcz1yCnRyeXtyPWQuJDAoKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LAp5
+djpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDEo
+ZSkKJC5YMz1jCnM9cgp0cnl7cj1kLiQxKGUpCnJldHVybiByfWZpbmFsbHl7JC5YMz1zfX0sClF4OmZ1
+bmN0aW9uKGEsYixjLGQsZSxmLGcsaCxpKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDIo
+ZSxmKQokLlgzPWMKcz1yCnRyeXtyPWQuJDIoZSxmKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LApU
+azpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwp0Lk0uYShkKQpzPUMuTlUhPT1jCmlmKHMpZD0hKCFzfHwh
+MSk/Yy50OChkKTpjLlJUKGQsdC5IKQpQLmVXKGQpfSwKdGg6ZnVuY3Rpb24gdGgoYSl7dGhpcy5hPWF9
+LApoYTpmdW5jdGlvbiBoYShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWczpmdW5j
+dGlvbiBWcyhhKXt0aGlzLmE9YX0sCkZ0OmZ1bmN0aW9uIEZ0KGEpe3RoaXMuYT1hfSwKVzM6ZnVuY3Rp
+b24gVzMoKXt9LAp5SDpmdW5jdGlvbiB5SChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKaWg6ZnVuY3Rp
+b24gaWgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9ITEKdGhpcy4kdGk9Yn0sCldNOmZ1bmN0aW9uIFdNKGEp
+e3RoaXMuYT1hfSwKU1g6ZnVuY3Rpb24gU1goYSl7dGhpcy5hPWF9LApHczpmdW5jdGlvbiBHcyhhKXt0
+aGlzLmE9YX0sCkZ5OmZ1bmN0aW9uIEZ5KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApHVjpmdW5jdGlv
+biBHVihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5kPV8uYz1fLmI9bnVsbApfLiR0aT1ifSwKcTQ6ZnVu
+Y3Rpb24gcTQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpm
+dW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxk
+LGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZz
+OmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwK
+ZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9u
+IFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRo
+aXMuYz1jfSwKcnQ6ZnVuY3Rpb24gcnQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9u
+IEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
+dGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0sCnJxOmZ1bmN0aW9uIHJxKGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
+T006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9LApxaDpmdW5jdGlvbiBxaCgpe30s
+CkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1TzpmdW5jdGlvbiB1TyhhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9LAprVDpmdW5jdGlvbiBrVCgpe30s
+CnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApDdzpmdW5jdGlvbiBDdyhhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlvbiBwSyhhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIsYyl7dGhpcy5h
+PWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
+fSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUY6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+IikuYShILkI3KGEs
+bmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0sCkxzOmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24oKXt2YXIgcz1P
+YmplY3QuY3JlYXRlKG51bGwpCnNbIjxub24taWRlbnRpZmllci1rZXk+Il09cwpkZWxldGUgc1siPG5v
+bi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gc30sCnJqOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1uZXcg
+UC5sbShhLGIsYy5DKCJsbTwwPiIpKQpzLmM9YS5lCnJldHVybiBzfSwKRVA6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciBzLHIKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4uLikiCnJldHVy
+biBiKyIuLi4iK2N9cz1ILlZNKFtdLHQucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIoYSxzKX1maW5h
+bGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9cj1QLnZn
+KGIsdC51LmEocyksIiwgIikrYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCldFOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcyxyCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4uLiIrYwpzPW5ldyBQLlJuKGIp
+CkMuTm0uaSgkLnhnLGEpCnRyeXtyPXMKci5hPVAudmcoci5hLGEsIiwgIil9ZmluYWxseXtpZigwPj0k
+LnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXMuYSs9YwpyPXMuYQpyZXR1
+cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCmhCOmZ1bmN0aW9uKGEpe3ZhciBzLHIKZm9yKHM9JC54
+Zy5sZW5ndGgscj0wO3I8czsrK3IpaWYoYT09PSQueGdbcl0pcmV0dXJuITAKcmV0dXJuITF9LApWcjpm
+dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9YS5nbShhKSxrPTAsaj0wCndoaWxlKCEwKXtp
+ZighKGs8ODB8fGo8MykpYnJlYWsKaWYoIWwuRigpKXJldHVybgpzPUguRWoobC5nbCgpKQpDLk5tLmko
+YixzKQprKz1zLmxlbmd0aCsyOysran1pZighbC5GKCkpe2lmKGo8PTUpcmV0dXJuCmlmKDA+PWIubGVu
+Z3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChi
+LC0xKQpxPWIucG9wKCl9ZWxzZXtwPWwuZ2woKTsrK2oKaWYoIWwuRigpKXtpZihqPD00KXtDLk5tLmko
+YixILkVqKHApKQpyZXR1cm59cj1ILkVqKHApCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEp
+CnE9Yi5wb3AoKQprKz1yLmxlbmd0aCsyfWVsc2V7bz1sLmdsKCk7KytqCmZvcig7bC5GKCk7cD1vLG89
+bil7bj1sLmdsKCk7KytqCmlmKGo+MTAwKXt3aGlsZSghMCl7aWYoIShrPjc1JiZqPjMpKWJyZWFrCmlm
+KDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmstPWIucG9wKCkubGVuZ3RoKzI7LS1qfUMuTm0u
+aShiLCIuLi4iKQpyZXR1cm59fXE9SC5FaihwKQpyPUguRWoobykKays9ci5sZW5ndGgrcS5sZW5ndGgr
+NH19aWYoaj5iLmxlbmd0aCsyKXtrKz01Cm09Ii4uLiJ9ZWxzZSBtPW51bGwKd2hpbGUoITApe2lmKCEo
+az44MCYmYi5sZW5ndGg+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKay09
+Yi5wb3AoKS5sZW5ndGgrMgppZihtPT1udWxsKXtrKz01Cm09Ii4uLiJ9fWlmKG0hPW51bGwpQy5ObS5p
+KGIsbSkKQy5ObS5pKGIscSkKQy5ObS5pKGIscil9LAp0TTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1Q
+LkxzKGIpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3RoPT09c3x8KDAsSC5sayko
+YSksKytyKXEuaSgwLGIuYShhW3JdKSkKcmV0dXJuIHF9LApuTzpmdW5jdGlvbihhKXt2YXIgcyxyPXt9
+CmlmKFAuaEIoYSkpcmV0dXJuInsuLi59IgpzPW5ldyBQLlJuKCIiKQp0cnl7Qy5ObS5pKCQueGcsYSkK
+cy5hKz0ieyIKci5hPSEwCmEuSygwLG5ldyBQLnJhKHIscykpCnMuYSs9In0ifWZpbmFsbHl7aWYoMD49
+JC54Zy5sZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1yPXMuYQpyZXR1cm4gci5j
+aGFyQ29kZUF0KDApPT0wP3I6cn0sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5m
+PV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlz
+LmE9YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpf
+LmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKdXk6ZnVu
+Y3Rpb24gdXkoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVu
+Y3Rpb24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVu
+Y3Rpb24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7
+fSwKR2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKbGY6ZnVuY3Rpb24gbGYo
+KXt9LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblko
+KXt9LApXWTpmdW5jdGlvbiBXWSgpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKcFI6ZnVuY3Rpb24gcFIo
+KXt9LApCUzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCmlmKHR5cGVvZiBhIT0ic3RyaW5nIil0aHJv
+dyBILmIoSC50TChhKSkKcz1udWxsCnRyeXtzPUpTT04ucGFyc2UoYSl9Y2F0Y2gocSl7cj1ILlJ1KHEp
+CnA9UC5ycihTdHJpbmcociksbnVsbCxudWxsKQp0aHJvdyBILmIocCl9cD1QLlFlKHMpCnJldHVybiBw
+fSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9
+Im9iamVjdCIpcmV0dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90
+eXBlKXJldHVybiBuZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkpCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpYVtzXT1QLlFlKGFbc10pCnJldHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMs
+cgppZihiIGluc3RhbmNlb2YgVWludDhBcnJheSl7cz1iCmQ9cy5sZW5ndGgKaWYoZC1jPDE1KXJldHVy
+biBudWxsCnI9UC5DRyhhLHMsYyxkKQppZihyIT1udWxsJiZhKWlmKHIuaW5kZXhPZigiXHVmZmZkIik+
+PTApcmV0dXJuIG51bGwKcmV0dXJuIHJ9cmV0dXJuIG51bGx9LApDRzpmdW5jdGlvbihhLGIsYyxkKXt2
+YXIgcz1hPyQuSEcoKTokLnJmKCkKaWYocz09bnVsbClyZXR1cm4gbnVsbAppZigwPT09YyYmZD09PWIu
+bGVuZ3RoKXJldHVybiBQLlJiKHMsYikKcmV0dXJuIFAuUmIocyxiLnN1YmFycmF5KGMsUC5qQihjLGQs
+Yi5sZW5ndGgpKSl9LApSYjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKdHJ5e3M9YS5kZWNvZGUoYikKcmV0
+dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCnhNOmZ1bmN0aW9uKGEsYixjLGQsZSxm
+KXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5n
+LCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMgIitmLGEsYykpCmlmKGQr
+ZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsICc9JyBub3QgYXQgdGhl
+IGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCBt
+b3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0KCl9LApVZzpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC50dShhLFtdLFAuQ3koKSl9LAp1WDpmdW5jdGlvbihhLGIsYyl7dmFy
+IHMscj1uZXcgUC5SbigiIikscT1QLlVnKHIsYikKcS5pVShhKQpzPXIuYQpyZXR1cm4gcy5jaGFyQ29k
+ZUF0KDApPT0wP3M6c30sCmo0OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIDY1OnJldHVybiJNaXNz
+aW5nIGV4dGVuc2lvbiBieXRlIgpjYXNlIDY3OnJldHVybiJVbmV4cGVjdGVkIGV4dGVuc2lvbiBieXRl
+IgpjYXNlIDY5OnJldHVybiJJbnZhbGlkIFVURi04IGJ5dGUiCmNhc2UgNzE6cmV0dXJuIk92ZXJsb25n
+IGVuY29kaW5nIgpjYXNlIDczOnJldHVybiJPdXQgb2YgdW5pY29kZSByYW5nZSIKY2FzZSA3NTpyZXR1
+cm4iRW5jb2RlZCBzdXJyb2dhdGUiCmNhc2UgNzc6cmV0dXJuIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQg
+c2VxdWVuY2UiCmRlZmF1bHQ6cmV0dXJuIiJ9fSwKank6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
+PWMtYixvPW5ldyBVaW50OEFycmF5KHApCmZvcihzPUouVTYoYSkscj0wO3I8cDsrK3Ipe3E9cy5xKGEs
+YityKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLnpNKCkKaWYoKHEmNDI5NDk2NzA0MCk+
+Pj4wIT09MClxPTI1NQppZihyPj1wKXJldHVybiBILk9IKG8scikKb1tyXT1xfXJldHVybiBvfSwKdXc6
+ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9bnVsbH0sCmk4OmZ1bmN0aW9u
+IGk4KGEpe3RoaXMuYT1hfSwKcGc6ZnVuY3Rpb24gcGcoKXt9LApjMjpmdW5jdGlvbiBjMigpe30sCkNW
+OmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlvbiBVaygpe30sCndJ
+OmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpmdW5jdGlvbiBVZChhLGIpe3Ro
+aXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmJ5
+OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5iPWF9LApNeDpmdW5jdGlvbiBN
+eChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVuY3Rpb24gdGkoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlzLmM9YQp0aGlzLmE9Ygp0aGlz
+LmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlvbiBS
+dyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6ZnVu
+Y3Rpb24gYnooYSl7dGhpcy5hPWEKdGhpcy5iPTE2CnRoaXMuYz0wfSwKUUE6ZnVuY3Rpb24oYSxiKXt2
+YXIgcz1ILkhwKGEsYikKaWYocyE9bnVsbClyZXR1cm4gcwp0aHJvdyBILmIoUC5ycihhLG51bGwsbnVs
+bCkpfSwKb3M6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0dXJuIGEudygwKQpyZXR1
+cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzLHI9Yz9KLktoKGEsZCk6Si5RaShhLGQpCmlmKGEhPT0wJiZiIT1udWxsKWZvcihzPTA7czxyLmxl
+bmd0aDsrK3MpcltzXT1iCnJldHVybiByfSwKQ0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9SC5WTShb
+XSxjLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMuTm0uaShyLGMuYShzLmdsKCkpKQpp
+ZihiKXJldHVybiByCnJldHVybiBKLkVwKHIsYyl9LApZMTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYo
+YilyZXR1cm4gUC5ldihhLGMpCnM9Si5FcChQLmV2KGEsYyksYykKcmV0dXJuIHN9LApldjpmdW5jdGlv
+bihhLGIpe3ZhciBzLHI9SC5WTShbXSxiLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMu
+Tm0uaShyLHMuZ2woKSkKcmV0dXJuIHJ9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnpDKFAuQ0go
+YSwhMSxiKSl9LApITTpmdW5jdGlvbihhLGIsYyl7aWYodC5ibS5iKGEpKXJldHVybiBILmZ3KGEsYixQ
+LmpCKGIsYyxhLmxlbmd0aCkpCnJldHVybiBQLmJ3KGEsYixjKX0sCk9vOmZ1bmN0aW9uKGEpe3JldHVy
+biBILkx3KGEpfSwKYnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89bnVsbAppZihiPDApdGhy
+b3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLG8sbykpCnM9Yz09bnVsbAppZighcyYmYzxiKXRocm93IEgu
+YihQLlRFKGMsYixhLmxlbmd0aCxvLG8pKQpyPW5ldyBILmE3KGEsYS5sZW5ndGgsSC56KGEpLkMoImE3
+PGxELkU+IikpCmZvcihxPTA7cTxiOysrcSlpZighci5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHEsbyxv
+KSkKcD1bXQppZihzKWZvcig7ci5GKCk7KXAucHVzaChyLmQpCmVsc2UgZm9yKHE9YjtxPGM7KytxKXtp
+Zighci5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHEsbyxvKSkKcC5wdXNoKHIuZCl9cmV0dXJuIEguZVQo
+cCl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEsITEsITEp
+KX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1KLklUKGIpCmlmKCFzLkYoKSlyZXR1cm4gYQppZihj
+Lmxlbmd0aD09PTApe2RvIGErPUguRWoocy5nbCgpKQp3aGlsZShzLkYoKSl9ZWxzZXthKz1ILkVqKHMu
+Z2woKSkKZm9yKDtzLkYoKTspYT1hK2MrSC5FaihzLmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rpb24o
+YSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgcz1ILk0w
+KCkKaWYocyE9bnVsbClyZXR1cm4gUC5oSyhzKQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBpcyBu
+b3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG09IjAx
+MjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXtzPSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3RyaW5n
+IilILnYoSC50TChiKSkKcz1zLnRlc3QoYil9ZWxzZSBzPSExCmlmKHMpcmV0dXJuIGIKSC5MaChjKS5D
+KCJVay5TIikuYShiKQpyPWMuZ1pFKCkuV0ooYikKZm9yKHM9ci5sZW5ndGgscT0wLHA9IiI7cTxzOysr
+cSl7bz1yW3FdCmlmKG88MTI4KXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goYSxuKQpuPShhW25d
+JjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXArPUguTHcobykKZWxzZSBwPWQmJm89PT0zMj9w
+KyIrIjpwKyIlIittW28+Pj40JjE1XSttW28mMTVdfXJldHVybiBwLmNoYXJDb2RlQXQoMCk9PTA/cDpw
+fSwKR3E6ZnVuY3Rpb24oYSl7dmFyIHM9TWF0aC5hYnMoYSkscj1hPDA/Ii0iOiIiCmlmKHM+PTEwMDAp
+cmV0dXJuIiIrYQppZihzPj0xMDApcmV0dXJuIHIrIjAiK3MKaWYocz49MTApcmV0dXJuIHIrIjAwIitz
+CnJldHVybiByKyIwMDAiK3N9LApWeDpmdW5jdGlvbihhKXtpZihhPj0xMDApcmV0dXJuIiIrYQppZihh
+Pj0xMClyZXR1cm4iMCIrYQpyZXR1cm4iMDAiK2F9LApoMDpmdW5jdGlvbihhKXtpZihhPj0xMClyZXR1
+cm4iIithCnJldHVybiIwIithfSwKcDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciJ8fEgu
+bChhKXx8bnVsbD09YSlyZXR1cm4gSi5qKGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSlNP
+Ti5zdHJpbmdpZnkoYSkKcmV0dXJuIFAub3MoYSl9LApoVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAu
+QzYoYSl9LAp4WTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSghMSxudWxsLG51bGwsYSl9LApMMzpm
+dW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLnUoITAsYSxiLGMpfSwKTVI6ZnVuY3Rpb24oYSxiLGMp
+e3JldHVybiBhfSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxudWxsLCEwLGEs
+YiwiVmFsdWUgbm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBuZXcg
+UC5iSihiLGMsITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIsYyxkKXtpZihh
+PGJ8fGE+Yyl0aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpCOmZ1bmN0aW9u
+KGEsYixjKXtpZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51bGwpKQppZihi
+IT1udWxsKXtpZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxsKSkKcmV0dXJu
+IGJ9cmV0dXJuIGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVs
+bCxiLG51bGwpKQpyZXR1cm4gYX0sCkNmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9SC51UChlPT1u
+dWxsP0ouSG0oYik6ZSkKcmV0dXJuIG5ldyBQLmVZKHMsITAsYSxjLCJJbmRleCBvdXQgb2YgcmFuZ2Ui
+KX0sCkw0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51YihhKX0sClNZOmZ1bmN0aW9uKGEpe3JldHVy
+biBuZXcgUC5kcyhhKX0sClBWOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5saihhKX0sCmE0OmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAu
+YUUoYSxiLGMpfSwKaEs6ZnVuY3Rpb24oYTUpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYs
+ZSxkLGMsYixhLGEwLGExLGEyLGEzPW51bGwsYTQ9YTUubGVuZ3RoCmlmKGE0Pj01KXtzPSgoSi5Reihh
+NSw0KV41OCkqM3xDLnhCLlcoYTUsMCleMTAwfEMueEIuVyhhNSwxKV45N3xDLnhCLlcoYTUsMileMTE2
+fEMueEIuVyhhNSwzKV45Nyk+Pj4wCmlmKHM9PT0wKXJldHVybiBQLktEKGE0PGE0P0MueEIuTmooYTUs
+MCxhNCk6YTUsNSxhMykuZ2xSKCkKZWxzZSBpZihzPT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhNSw1
+LGE0KSwwLGEzKS5nbFIoKX1yPVAuTzgoOCwwLCExLHQuUykKQy5ObS5ZNShyLDAsMCkKQy5ObS5ZNShy
+LDEsLTEpCkMuTm0uWTUociwyLC0xKQpDLk5tLlk1KHIsNywtMSkKQy5ObS5ZNShyLDMsMCkKQy5ObS5Z
+NShyLDQsMCkKQy5ObS5ZNShyLDUsYTQpCkMuTm0uWTUociw2LGE0KQppZihQLlVCKGE1LDAsYTQsMCxy
+KT49MTQpQy5ObS5ZNShyLDcsYTQpCnE9clsxXQppZihxPj0wKWlmKFAuVUIoYTUsMCxxLDIwLHIpPT09
+MjApcls3XT1xCnA9clsyXSsxCm89clszXQpuPXJbNF0KbT1yWzVdCmw9cls2XQppZihsPG0pbT1sCmlm
+KG48cCluPW0KZWxzZSBpZihuPD1xKW49cSsxCmlmKG88cClvPW4Kaz1yWzddPDAKaWYoaylpZihwPnEr
+Myl7aj1hMwprPSExfWVsc2V7aT1vPjAKaWYoaSYmbysxPT09bil7aj1hMwprPSExfWVsc2V7aWYoISht
+PGE0JiZtPT09bisyJiZKLnEwKGE1LCIuLiIsbikpKWg9bT5uKzImJkoucTAoYTUsIi8uLiIsbS0zKQpl
+bHNlIGg9ITAKaWYoaCl7aj1hMwprPSExfWVsc2V7aWYocT09PTQpaWYoSi5xMChhNSwiZmlsZSIsMCkp
+e2lmKHA8PTApe2lmKCFDLnhCLlFpKGE1LCIvIixuKSl7Zz0iZmlsZTovLy8iCnM9M31lbHNle2c9ImZp
+bGU6Ly8iCnM9Mn1hNT1nK0MueEIuTmooYTUsbixhNCkKcS09MAppPXMtMAptKz1pCmwrPWkKYTQ9YTUu
+bGVuZ3RoCnA9NwpvPTcKbj03fWVsc2UgaWYobj09PW0peysrbApmPW0rMQphNT1DLnhCLmk3KGE1LG4s
+bSwiLyIpOysrYTQKbT1mfWo9ImZpbGUifWVsc2UgaWYoQy54Qi5RaShhNSwiaHR0cCIsMCkpe2lmKGkm
+Jm8rMz09PW4mJkMueEIuUWkoYTUsIjgwIixvKzEpKXtsLT0zCmU9bi0zCm0tPTMKYTU9Qy54Qi5pNyhh
+NSxvLG4sIiIpCmE0LT0zCm49ZX1qPSJodHRwIn1lbHNlIGo9YTMKZWxzZSBpZihxPT09NSYmSi5xMChh
+NSwiaHR0cHMiLDApKXtpZihpJiZvKzQ9PT1uJiZKLnEwKGE1LCI0NDMiLG8rMSkpe2wtPTQKZT1uLTQK
+bS09NAphNT1KLmRnKGE1LG8sbiwiIikKYTQtPTMKbj1lfWo9Imh0dHBzIn1lbHNlIGo9YTMKaz0hMH19
+fWVsc2Ugaj1hMwppZihrKXtpPWE1Lmxlbmd0aAppZihhNDxpKXthNT1KLmxkKGE1LDAsYTQpCnEtPTAK
+cC09MApvLT0wCm4tPTAKbS09MApsLT0wfXJldHVybiBuZXcgUC5VZihhNSxxLHAsbyxuLG0sbCxqKX1p
+ZihqPT1udWxsKWlmKHE+MClqPVAuUGkoYTUsMCxxKQplbHNle2lmKHE9PT0wKXtQLlIzKGE1LDAsIklu
+dmFsaWQgZW1wdHkgc2NoZW1lIikKSC5CaSh1LmcpfWo9IiJ9aWYocD4wKXtkPXErMwpjPWQ8cD9QLnpS
+KGE1LGQscC0xKToiIgpiPVAuT2UoYTUscCxvLCExKQppPW8rMQppZihpPG4pe2E9SC5IcChKLmxkKGE1
+LGksbiksYTMpCmEwPVAud0IoYT09bnVsbD9ILnYoUC5ycigiSW52YWxpZCBwb3J0IixhNSxpKSk6YSxq
+KX1lbHNlIGEwPWEzfWVsc2V7YTA9YTMKYj1hMApjPSIifWExPVAua2EoYTUsbixtLGEzLGosYiE9bnVs
+bCkKYTI9bTxsP1AubGUoYTUsbSsxLGwsYTMpOmEzCnJldHVybiBuZXcgUC5EbihqLGMsYixhMCxhMSxh
+MixsPGE0P1AudEcoYTUsbCsxLGE0KTphMyl9LApNdDpmdW5jdGlvbihhKXtILmgoYSkKcmV0dXJuIFAu
+a3UoYSwwLGEubGVuZ3RoLEMueE0sITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHM9dC5OCnJldHVybiBD
+Lk5tLk4wKEguVk0oYS5zcGxpdCgiJiIpLHQucyksUC5GbChzLHMpLG5ldyBQLm4xKEMueE0pLHQuSil9
+LApIaDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG09IklQdjQgYWRkcmVzcyBzaG91bGQg
+Y29udGFpbiBleGFjdGx5IDQgcGFydHMiLGw9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAw
+Li4yNTUiLGs9bmV3IFAuY1MoYSksaj1uZXcgVWludDhBcnJheSg0KQpmb3Iocz1iLHI9cyxxPTA7czxj
+Oysrcyl7cD1DLnhCLk8yKGEscykKaWYocCE9PTQ2KXtpZigocF40OCk+OSlrLiQyKCJpbnZhbGlkIGNo
+YXJhY3RlciIscyl9ZWxzZXtpZihxPT09MylrLiQyKG0scykKbz1QLlFBKEMueEIuTmooYSxyLHMpLG51
+bGwpCmlmKG8+MjU1KWsuJDIobCxyKQpuPXErMQppZihxPj00KXJldHVybiBILk9IKGoscSkKaltxXT1v
+CnI9cysxCnE9bn19aWYocSE9PTMpay4kMihtLGMpCm89UC5RQShDLnhCLk5qKGEscixjKSxudWxsKQpp
+ZihvPjI1NSlrLiQyKGwscikKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyZXR1cm4gan0s
+CmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9bmV3
+IFAuVkMoYSksYz1uZXcgUC5KVChkLGEpCmlmKGEubGVuZ3RoPDIpZC4kMSgiYWRkcmVzcyBpcyB0b28g
+c2hvcnQiKQpzPUguVk0oW10sdC5hKQpmb3Iocj1iLHE9cixwPSExLG89ITE7cjxhMDsrK3Ipe249Qy54
+Qi5PMihhLHIpCmlmKG49PT01OCl7aWYocj09PWIpeysrcgppZihDLnhCLk8yKGEscikhPT01OClkLiQy
+KCJpbnZhbGlkIHN0YXJ0IGNvbG9uLiIscikKcT1yfWlmKHI9PT1xKXtpZihwKWQuJDIoIm9ubHkgb25l
+IHdpbGRjYXJkIGA6OmAgaXMgYWxsb3dlZCIscikKQy5ObS5pKHMsLTEpCnA9ITB9ZWxzZSBDLk5tLmko
+cyxjLiQyKHEscikpCnE9cisxfWVsc2UgaWYobj09PTQ2KW89ITB9aWYocy5sZW5ndGg9PT0wKWQuJDEo
+InRvbyBmZXcgcGFydHMiKQptPXE9PT1hMApsPUMuTm0uZ3JaKHMpCmlmKG0mJmwhPT0tMSlkLiQyKCJl
+eHBlY3RlZCBhIHBhcnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbSlpZighbylDLk5tLmkocyxjLiQy
+KHEsYTApKQplbHNle2s9UC5IaChhLHEsYTApCkMuTm0uaShzLChrWzBdPDw4fGtbMV0pPj4+MCkKQy5O
+bS5pKHMsKGtbMl08PDh8a1szXSk+Pj4wKX1pZihwKXtpZihzLmxlbmd0aD43KWQuJDEoImFuIGFkZHJl
+c3Mgd2l0aCBhIHdpbGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYocy5s
+ZW5ndGghPT04KWQuJDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBl
+eGFjdGx5IDggcGFydHMiKQpqPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobD1zLmxlbmd0aCxpPTktbCxy
+PTAsaD0wO3I8bDsrK3Ipe2c9c1tyXQppZihnPT09LTEpZm9yKGY9MDtmPGk7KytmKXtpZihoPDB8fGg+
+PTE2KXJldHVybiBILk9IKGosaCkKaltoXT0wCmU9aCsxCmlmKGU+PTE2KXJldHVybiBILk9IKGosZSkK
+altlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PTE2KXJldHVybiBILk9IKGos
+aCkKaltoXT1lCmU9aCsxCmlmKGU+PTE2KXJldHVybiBILk9IKGosZSkKaltlXT1nJjI1NQpoKz0yfX1y
+ZXR1cm4gan0sCktMOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbgpmPWY9PW51
+bGw/IiI6UC5QaShmLDAsZi5sZW5ndGgpCmc9UC56UihnLDAsZz09bnVsbD8wOmcubGVuZ3RoKQphPVAu
+T2UoYSwwLGE9PW51bGw/MDphLmxlbmd0aCwhMSkKcz1QLmxlKG51bGwsMCwwLGUpCnI9UC50RyhudWxs
+LDAsMCkKZD1QLndCKGQsZikKcT1mPT09ImZpbGUiCmlmKGE9PW51bGwpcD1nLmxlbmd0aCE9PTB8fGQh
+PW51bGx8fHEKZWxzZSBwPSExCmlmKHApYT0iIgpwPWE9PW51bGwKbz0hcApiPVAua2EoYiwwLGI9PW51
+bGw/MDpiLmxlbmd0aCxjLGYsbykKbj1mLmxlbmd0aD09PTAKaWYobiYmcCYmIUMueEIubkMoYiwiLyIp
+KWI9UC53RihiLCFufHxvKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHAmJkMueEIu
+bkMoYiwiLy8iKT8iIjphLGQsYixzLHIpfSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1
+cm4gODAKaWYoYT09PSJodHRwcyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixj
+KXt0aHJvdyBILmIoUC5ycihjLGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAs
+byxuLG0sbCxrLGosaSxoPW51bGwsZz1iLmxlbmd0aAppZihnIT09MCl7cT0wCndoaWxlKCEwKXtpZigh
+KHE8Zykpe3M9IiIKcj0wCmJyZWFrfWlmKEMueEIuVyhiLHEpPT09NjQpe3M9Qy54Qi5OaihiLDAscSkK
+cj1xKzEKYnJlYWt9KytxfWlmKHI8ZyYmQy54Qi5XKGIscik9PT05MSl7Zm9yKHA9cixvPS0xO3A8Zzsr
+K3Ape249Qy54Qi5XKGIscCkKaWYobj09PTM3JiZvPDApe209Qy54Qi5RaShiLCIyNSIscCsxKT9wKzI6
+cApvPXAKcD1tfWVsc2UgaWYobj09PTkzKWJyZWFrfWlmKHA9PT1nKXRocm93IEguYihQLnJyKCJJbnZh
+bGlkIElQdjYgaG9zdCBlbnRyeS4iLGIscikpCmw9bzwwP3A6bwpQLmVnKGIscisxLGwpOysrcAppZihw
+IT09ZyYmQy54Qi5XKGIscCkhPT01OCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9y
+aXR5IixiLHApKX1lbHNlIHA9cgp3aGlsZSghMCl7aWYoIShwPGcpKXtrPWgKYnJlYWt9aWYoQy54Qi5X
+KGIscCk9PT01OCl7aj1DLnhCLnluKGIscCsxKQprPWoubGVuZ3RoIT09MD9QLlFBKGosaCk6aApicmVh
+a30rK3B9aT1DLnhCLk5qKGIscixwKX1lbHNle2s9aAppPWsKcz0iIn1yZXR1cm4gUC5LTChpLGgsSC5W
+TShjLnNwbGl0KCIvIiksdC5zKSxrLGQsYSxzKX0sCmtFOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAs
+bwpmb3Iocz1hLmxlbmd0aCxyPTA7cjxzOysrcil7cT1hW3JdCnEudG9TdHJpbmcKcD1KLlU2KHEpCm89
+cC5nQShxKQppZigwPm8pSC52KFAuVEUoMCwwLHAuZ0EocSksbnVsbCxudWxsKSkKaWYoSC5TUShxLCIv
+IiwwKSl7cz1QLkw0KCJJbGxlZ2FsIHBhdGggY2hhcmFjdGVyICIrSC5FaihxKSkKdGhyb3cgSC5iKHMp
+fX19LApITjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxCmZvcihzPUgucUMoYSxjLG51bGwsSC50Nihh
+KS5jKSxzPW5ldyBILmE3KHMscy5nQShzKSxzLiR0aS5DKCJhNzxhTC5FPiIpKTtzLkYoKTspe3I9cy5k
+CnE9UC5udSgnWyIqLzo8Pj9cXFxcfF0nKQpyLnRvU3RyaW5nCmlmKEguU1EocixxLDApKXtzPVAuTDQo
+IklsbGVnYWwgY2hhcmFjdGVyIGluIHBhdGg6ICIrcikKdGhyb3cgSC5iKHMpfX19LApyZzpmdW5jdGlv
+bihhLGIpe3ZhciBzCmlmKCEoNjU8PWEmJmE8PTkwKSlzPTk3PD1hJiZhPD0xMjIKZWxzZSBzPSEwCmlm
+KHMpcmV0dXJuCnM9UC5MNCgiSWxsZWdhbCBkcml2ZSBsZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIo
+cyl9LAp3QjpmdW5jdGlvbihhLGIpe2lmKGEhPW51bGwmJmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJl
+dHVybiBhfSwKT2U6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGE9PW51bGwpcmV0
+dXJuIG51bGwKaWYoYj09PWMpcmV0dXJuIiIKaWYoQy54Qi5PMihhLGIpPT09OTEpe3M9Yy0xCmlmKEMu
+eEIuTzIoYSxzKSE9PTkzKXtQLlIzKGEsYiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBo
+b3N0IikKSC5CaSh1LmcpfXI9YisxCnE9UC50byhhLHIscykKaWYocTxzKXtwPXErMQpvPVAuT0EoYSxD
+LnhCLlFpKGEsIjI1IixwKT9xKzM6cCxzLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLHIscSkKcmV0dXJu
+IEMueEIuTmooYSxiLHEpLnRvTG93ZXJDYXNlKCkrbysiXSJ9Zm9yKG49YjtuPGM7KytuKWlmKEMueEIu
+TzIoYSxuKT09PTU4KXtxPUMueEIuWFUoYSwiJSIsYikKcT1xPj1iJiZxPGM/cTpjCmlmKHE8Yyl7cD1x
+KzEKbz1QLk9BKGEsQy54Qi5RaShhLCIyNSIscCk/cSszOnAsYywiJTI1Iil9ZWxzZSBvPSIiClAuZWco
+YSxiLHEpCnJldHVybiJbIitDLnhCLk5qKGEsYixxKStvKyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0
+bzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Qy54Qi5YVShhLCIlIixiKQpyZXR1cm4gcz49YiYmczxjP3M6
+Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9ZCE9PSIiP25l
+dyBQLlJuKGQpOm51bGwKZm9yKHM9YixyPXMscT0hMDtzPGM7KXtwPUMueEIuTzIoYSxzKQppZihwPT09
+Mzcpe289UC5ydihhLHMsITApCm49bz09bnVsbAppZihuJiZxKXtzKz0zCmNvbnRpbnVlfWlmKGk9PW51
+bGwpaT1uZXcgUC5SbigiIikKbT1pLmErPUMueEIuTmooYSxyLHMpCmlmKG4pbz1DLnhCLk5qKGEscyxz
+KzMpCmVsc2UgaWYobz09PSIlIil7UC5SMyhhLHMsIlpvbmVJRCBzaG91bGQgbm90IGNvbnRhaW4gJSBh
+bnltb3JlIikKSC5CaSh1LmcpfWkuYT1tK28Kcys9MwpyPXMKcT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+
+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goQy5GMyxuKQpuPShDLkYzW25dJjE8PChwJjE1KSkhPT0wfWVs
+c2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lmKGk9PW51bGwpaT1uZXcgUC5SbigiIikK
+aWYocjxzKXtpLmErPUMueEIuTmooYSxyLHMpCnI9c31xPSExfSsrc31lbHNle2lmKChwJjY0NTEyKT09
+PTU1Mjk2JiZzKzE8Yyl7bD1DLnhCLk8yKGEscysxKQppZigobCY2NDUxMik9PT01NjMyMCl7cD0ocCYx
+MDIzKTw8MTB8bCYxMDIzfDY1NTM2Cms9Mn1lbHNlIGs9MX1lbHNlIGs9MQpqPUMueEIuTmooYSxyLHMp
+CmlmKGk9PW51bGwpe2k9bmV3IFAuUm4oIiIpCm49aX1lbHNlIG49aQpuLmErPWoKbi5hKz1QLnpYKHAp
+CnMrPWsKcj1zfX19aWYoaT09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKWkuYSs9Qy54
+Qi5OaihhLHIsYykKbj1pLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApPTDpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaQpmb3Iocz1iLHI9cyxxPW51bGwscD0hMDtz
+PGM7KXtvPUMueEIuTzIoYSxzKQppZihvPT09Mzcpe249UC5ydihhLHMsITApCm09bj09bnVsbAppZiht
+JiZwKXtzKz0zCmNvbnRpbnVlfWlmKHE9PW51bGwpcT1uZXcgUC5SbigiIikKbD1DLnhCLk5qKGEscixz
+KQprPXEuYSs9IXA/bC50b0xvd2VyQ2FzZSgpOmwKaWYobSl7bj1DLnhCLk5qKGEscyxzKzMpCmo9M31l
+bHNlIGlmKG49PT0iJSIpe249IiUyNSIKaj0xfWVsc2Ugaj0zCnEuYT1rK24Kcys9agpyPXMKcD0hMH1l
+bHNle2lmKG88MTI3KXttPW8+Pj40CmlmKG0+PTgpcmV0dXJuIEguT0goQy5lYSxtKQptPShDLmVhW21d
+JjE8PChvJjE1KSkhPT0wfWVsc2UgbT0hMQppZihtKXtpZihwJiY2NTw9byYmOTA+PW8pe2lmKHE9PW51
+bGwpcT1uZXcgUC5SbigiIikKaWYocjxzKXtxLmErPUMueEIuTmooYSxyLHMpCnI9c31wPSExfSsrc31l
+bHNle2lmKG88PTkzKXttPW8+Pj40CmlmKG0+PTgpcmV0dXJuIEguT0goQy5hayxtKQptPShDLmFrW21d
+JjE8PChvJjE1KSkhPT0wfWVsc2UgbT0hMQppZihtKXtQLlIzKGEscywiSW52YWxpZCBjaGFyYWN0ZXIi
+KQpILkJpKHUuZyl9ZWxzZXtpZigobyY2NDUxMik9PT01NTI5NiYmcysxPGMpe2k9Qy54Qi5PMihhLHMr
+MSkKaWYoKGkmNjQ1MTIpPT09NTYzMjApe289KG8mMTAyMyk8PDEwfGkmMTAyM3w2NTUzNgpqPTJ9ZWxz
+ZSBqPTF9ZWxzZSBqPTEKbD1DLnhCLk5qKGEscixzKQppZighcClsPWwudG9Mb3dlckNhc2UoKQppZihx
+PT1udWxsKXtxPW5ldyBQLlJuKCIiKQptPXF9ZWxzZSBtPXEKbS5hKz1sCm0uYSs9UC56WChvKQpzKz1q
+CnI9c319fX1pZihxPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihyPGMpe2w9Qy54Qi5Oaihh
+LHIsYykKcS5hKz0hcD9sLnRvTG93ZXJDYXNlKCk6bH1tPXEuYQpyZXR1cm4gbS5jaGFyQ29kZUF0KDAp
+PT0wP206bX0sClBpOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvPXUuZwppZihiPT09YylyZXR1
+cm4iIgppZighUC5FdChKLnJZKGEpLlcoYSxiKSkpe1AuUjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5n
+IHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpILkJpKG8pfWZvcihzPWIscj0hMTtzPGM7KytzKXtx
+PUMueEIuVyhhLHMpCmlmKHE8MTI4KXtwPXE+Pj40CmlmKHA+PTgpcmV0dXJuIEguT0goQy5tSyxwKQpw
+PShDLm1LW3BdJjE8PChxJjE1KSkhPT0wfWVsc2UgcD0hMQppZighcCl7UC5SMyhhLHMsIklsbGVnYWwg
+c2NoZW1lIGNoYXJhY3RlciIpCkguQmkobyl9aWYoNjU8PXEmJnE8PTkwKXI9ITB9YT1DLnhCLk5qKGEs
+YixjKQpyZXR1cm4gUC5ZYShyP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9
+PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0
+cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9
+LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxD
+LnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgcyxyLHE9ZT09PSJmaWxlIixwPXF8
+fGYKaWYoYT09bnVsbCl7aWYoZD09bnVsbClyZXR1cm4gcT8iLyI6IiIKcz1ILnQ2KGQpCnI9bmV3IEgu
+bEooZCxzLkMoInFVKDEpIikuYShuZXcgUC5SWigpKSxzLkMoImxKPDEscVU+IikpLmsoMCwiLyIpfWVs
+c2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBwYXRoIGFuZCBwYXRoU2VnbWVudHMgc3Bl
+Y2lmaWVkIikpCmVsc2Ugcj1QLlBJKGEsYixjLEMuV2QsITApCmlmKHIubGVuZ3RoPT09MCl7aWYocSly
+ZXR1cm4iLyJ9ZWxzZSBpZihwJiYhQy54Qi5uQyhyLCIvIikpcj0iLyIrcgpyZXR1cm4gUC5KcihyLGUs
+Zil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Yi5sZW5ndGg9PT0wCmlmKHMmJiFjJiYhQy54Qi5u
+QyhhLCIvIikpcmV0dXJuIFAud0YoYSwhc3x8YykKcmV0dXJuIFAueGUoYSl9LApsZTpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyPXt9CmlmKGEhPW51bGwpe2lmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
+dGggcXVlcnkgYW5kIHF1ZXJ5UGFyYW1ldGVycyBzcGVjaWZpZWQiKSkKcmV0dXJuIFAuUEkoYSxiLGMs
+Qy5WQywhMCl9aWYoZD09bnVsbClyZXR1cm4gbnVsbApzPW5ldyBQLlJuKCIiKQpyLmE9IiIKZC5LKDAs
+bmV3IFAueTUobmV3IFAuTUUocixzKSkpCnI9cy5hCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpy
+fSwKdEc6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFAuUEkoYSxi
+LGMsQy5WQywhMCl9LApydjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuPWIrMgppZihuPj1h
+Lmxlbmd0aClyZXR1cm4iJSIKcz1DLnhCLk8yKGEsYisxKQpyPUMueEIuTzIoYSxuKQpxPUgub28ocykK
+cD1ILm9vKHIpCmlmKHE8MHx8cDwwKXJldHVybiIlIgpvPXEqMTYrcAppZihvPDEyNyl7bj1DLmpuLndH
+KG8sNCkKaWYobj49OClyZXR1cm4gSC5PSChDLkYzLG4pCm49KEMuRjNbbl0mMTw8KG8mMTUpKSE9PTB9
+ZWxzZSBuPSExCmlmKG4pcmV0dXJuIEguTHcoYyYmNjU8PW8mJjkwPj1vPyhvfDMyKT4+PjA6bykKaWYo
+cz49OTd8fHI+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51
+bGx9LAp6WDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9IjAxMjM0NTY3ODlBQkNERUYi
+CmlmKGE8MTI4KXtzPW5ldyBVaW50OEFycmF5KDMpCnNbMF09MzcKc1sxXT1DLnhCLlcoayxhPj4+NCkK
+c1syXT1DLnhCLlcoayxhJjE1KX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0MApxPTR9ZWxz
+ZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9cD0zKnEKcz1uZXcgVWludDhBcnJheShwKQpmb3Iobz0w
+Oy0tcSxxPj0wO3I9MTI4KXtuPUMuam4uYmYoYSw2KnEpJjYzfHIKaWYobz49cClyZXR1cm4gSC5PSChz
+LG8pCnNbb109MzcKbT1vKzEKbD1DLnhCLlcoayxuPj4+NCkKaWYobT49cClyZXR1cm4gSC5PSChzLG0p
+CnNbbV09bApsPW8rMgptPUMueEIuVyhrLG4mMTUpCmlmKGw+PXApcmV0dXJuIEguT0gocyxsKQpzW2xd
+PW0Kbys9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
+cz1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHM9PW51bGw/Qy54Qi5OaihhLGIsYyk6c30sClVsOmZ1bmN0
+aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9bnVsbApmb3Iocz0hZSxyPWIscT1y
+LHA9ajtyPGM7KXtvPUMueEIuTzIoYSxyKQppZihvPDEyNyl7bj1vPj4+NAppZihuPj04KXJldHVybiBI
+Lk9IKGQsbikKbj0oZFtuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobikrK3IKZWxzZXtpZihv
+PT09Mzcpe209UC5ydihhLHIsITEpCmlmKG09PW51bGwpe3IrPTMKY29udGludWV9aWYoIiUiPT09bSl7
+bT0iJTI1IgpsPTF9ZWxzZSBsPTN9ZWxzZXtpZihzKWlmKG88PTkzKXtuPW8+Pj40CmlmKG4+PTgpcmV0
+dXJuIEguT0goQy5hayxuKQpuPShDLmFrW25dJjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQplbHNlIG49
+ITEKaWYobil7UC5SMyhhLHIsIkludmFsaWQgY2hhcmFjdGVyIikKSC5CaSh1LmcpCmw9agptPWx9ZWxz
+ZXtpZigobyY2NDUxMik9PT01NTI5Nil7bj1yKzEKaWYobjxjKXtrPUMueEIuTzIoYSxuKQppZigoayY2
+NDUxMik9PT01NjMyMCl7bz0obyYxMDIzKTw8MTB8ayYxMDIzfDY1NTM2Cmw9Mn1lbHNlIGw9MX1lbHNl
+IGw9MX1lbHNlIGw9MQptPVAuelgobyl9fWlmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCm49cH1lbHNl
+IG49cApuLmErPUMueEIuTmooYSxxLHIpCm4uYSs9SC5FaihtKQppZih0eXBlb2YgbCE9PSJudW1iZXIi
+KXJldHVybiBILnBZKGwpCnIrPWwKcT1yfX1pZihwPT1udWxsKXJldHVybiBqCmlmKHE8YylwLmErPUMu
+eEIuTmooYSxxLGMpCnM9cC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKeUI6ZnVuY3Rp
+b24oYSl7aWYoQy54Qi5uQyhhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0x
+fSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0KaWYoIVAueUIoYSkpcmV0dXJuIGEKcz1I
+LlZNKFtdLHQucykKZm9yKHI9YS5zcGxpdCgiLyIpLHE9ci5sZW5ndGgscD0hMSxvPTA7bzxxOysrbyl7
+bj1yW29dCmlmKEouUk0obiwiLi4iKSl7bT1zLmxlbmd0aAppZihtIT09MCl7aWYoMD49bSlyZXR1cm4g
+SC5PSChzLC0xKQpzLnBvcCgpCmlmKHMubGVuZ3RoPT09MClDLk5tLmkocywiIil9cD0hMH1lbHNlIGlm
+KCIuIj09PW4pcD0hMAplbHNle0MuTm0uaShzLG4pCnA9ITF9fWlmKHApQy5ObS5pKHMsIiIpCnJldHVy
+biBDLk5tLmsocywiLyIpfSwKd0Y6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4KaWYoIVAueUIo
+YSkpcmV0dXJuIWI/UC5DMShhKTphCnM9SC5WTShbXSx0LnMpCmZvcihyPWEuc3BsaXQoIi8iKSxxPXIu
+bGVuZ3RoLHA9ITEsbz0wO288cTsrK28pe249cltvXQppZigiLi4iPT09bilpZihzLmxlbmd0aCE9PTAm
+JkMuTm0uZ3JaKHMpIT09Ii4uIil7aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3Ao
+KQpwPSEwfWVsc2V7Qy5ObS5pKHMsIi4uIikKcD0hMX1lbHNlIGlmKCIuIj09PW4pcD0hMAplbHNle0Mu
+Tm0uaShzLG4pCnA9ITF9fXI9cy5sZW5ndGgKaWYociE9PTApaWYocj09PTEpe2lmKDA+PXIpcmV0dXJu
+IEguT0gocywwKQpyPXNbMF0ubGVuZ3RoPT09MH1lbHNlIHI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJu
+Ii4vIgppZihwfHxDLk5tLmdyWihzKT09PSIuLiIpQy5ObS5pKHMsIiIpCmlmKCFiKXtpZigwPj1zLmxl
+bmd0aClyZXR1cm4gSC5PSChzLDApCkMuTm0uWTUocywwLFAuQzEoc1swXSkpfXJldHVybiBDLk5tLmso
+cywiLyIpfSwKQzE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS5sZW5ndGgKaWYocD49MiYmUC5FdChK
+LlF6KGEsMCkpKWZvcihzPTE7czxwOysrcyl7cj1DLnhCLlcoYSxzKQppZihyPT09NTgpcmV0dXJuIEMu
+eEIuTmooYSwwLHMpKyIlM0EiK0MueEIueW4oYSxzKzEpCmlmKHI8PTEyNyl7cT1yPj4+NAppZihxPj04
+KXJldHVybiBILk9IKEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpPT09MH1lbHNlIHE9ITAKaWYo
+cSlicmVha31yZXR1cm4gYX0sCm1uOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEuZ0ZqKCksbz1wLmxl
+bmd0aAppZihvPjAmJkouSG0ocFswXSk9PT0yJiZKLmE2KHBbMF0sMSk9PT01OCl7aWYoMD49bylyZXR1
+cm4gSC5PSChwLDApClAucmcoSi5hNihwWzBdLDApLCExKQpQLkhOKHAsITEsMSkKcz0hMH1lbHNle1Au
+SE4ocCwhMSwwKQpzPSExfXI9YS5ndFQoKSYmIXM/IlxcIjoiIgppZihhLmdjaigpKXtxPWEuZ0pmKGEp
+CmlmKHEubGVuZ3RoIT09MClyPXIrIlxcIitxKyJcXCJ9cj1QLnZnKHIscCwiXFwiKQpvPXMmJm89PT0x
+P3IrIlxcIjpyCnJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKSWg6ZnVuY3Rpb24oYSxiKXt2
+YXIgcyxyLHEKZm9yKHM9MCxyPTA7cjwyOysrcil7cT1DLnhCLlcoYSxiK3IpCmlmKDQ4PD1xJiZxPD01
+NylzPXMqMTYrcS00OAplbHNle3F8PTMyCmlmKDk3PD1xJiZxPD0xMDIpcz1zKjE2K3EtODcKZWxzZSB0
+aHJvdyBILmIoUC54WSgiSW52YWxpZCBVUkwgZW5jb2RpbmciKSl9fXJldHVybiBzfSwKa3U6ZnVuY3Rp
+b24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvPUouclkoYSksbj1iCndoaWxlKCEwKXtpZighKG48Yykp
+e3M9ITAKYnJlYWt9cj1vLlcoYSxuKQppZihyPD0xMjcpaWYociE9PTM3KXE9ZSYmcj09PTQzCmVsc2Ug
+cT0hMAplbHNlIHE9ITAKaWYocSl7cz0hMQpicmVha30rK259aWYocyl7aWYoQy54TSE9PWQpcT0hMQpl
+bHNlIHE9ITAKaWYocSlyZXR1cm4gby5OaihhLGIsYykKZWxzZSBwPW5ldyBILnFqKG8uTmooYSxiLGMp
+KX1lbHNle3A9SC5WTShbXSx0LmEpCmZvcihuPWI7bjxjOysrbil7cj1vLlcoYSxuKQppZihyPjEyNyl0
+aHJvdyBILmIoUC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihyPT09Mzcp
+e2lmKG4rMz5hLmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocCxQ
+LkloKGEsbisxKSkKbis9Mn1lbHNlIGlmKGUmJnI9PT00MylDLk5tLmkocCwzMikKZWxzZSBDLk5tLmko
+cCxyKX19dC5MLmEocCkKcmV0dXJuIEMub0UuV0oocCl9LApFdDpmdW5jdGlvbihhKXt2YXIgcz1hfDMy
+CnJldHVybiA5Nzw9cyYmczw9MTIyfSwKS0Q6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixt
+LGwsaz0iSW52YWxpZCBNSU1FIHR5cGUiLGo9SC5WTShbYi0xXSx0LmEpCmZvcihzPWEubGVuZ3RoLHI9
+YixxPS0xLHA9bnVsbDtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT00NHx8cD09PTU5KWJyZWFr
+CmlmKHA9PT00Nyl7aWYocTwwKXtxPXIKY29udGludWV9dGhyb3cgSC5iKFAucnIoayxhLHIpKX19aWYo
+cTwwJiZyPmIpdGhyb3cgSC5iKFAucnIoayxhLHIpKQpmb3IoO3AhPT00NDspe0MuTm0uaShqLHIpOysr
+cgpmb3Iobz0tMTtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT02MSl7aWYobzwwKW89cn1lbHNl
+IGlmKHA9PT01OXx8cD09PTQ0KWJyZWFrfWlmKG8+PTApQy5ObS5pKGosbykKZWxzZXtuPUMuTm0uZ3Ja
+KGopCmlmKHAhPT00NHx8ciE9PW4rN3x8IUMueEIuUWkoYSwiYmFzZTY0IixuKzEpKXRocm93IEguYihQ
+LnJyKCJFeHBlY3RpbmcgJz0nIixhLHIpKQpicmVha319Qy5ObS5pKGoscikKbT1yKzEKaWYoKGoubGVu
+Z3RoJjEpPT09MSlhPUMuaDkueXIoYSxtLHMpCmVsc2V7bD1QLlVsKGEsbSxzLEMuVkMsITApCmlmKGwh
+PW51bGwpYT1DLnhCLmk3KGEsbSxzLGwpfXJldHVybiBuZXcgUC5QRShhLGosYyl9LApLTjpmdW5jdGlv
+bigpe3ZhciBzLHIscSxwLG8sbixtPSIwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVph
+YmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0uX34hJCYnKCkqKyw7PSIsbD0iLiIsaz0iOiIsaj0iLyIs
+aT0iPyIsaD0iIyIsZz1ILlZNKG5ldyBBcnJheSgyMiksdC5nTikKZm9yKHM9MDtzPDIyOysrcylnW3Nd
+PW5ldyBVaW50OEFycmF5KDk2KQpyPW5ldyBQLnlJKGcpCnE9bmV3IFAuYzYoKQpwPW5ldyBQLnFkKCkK
+bz10LmdjCm49by5hKHIuJDIoMCwyMjUpKQpxLiQzKG4sbSwxKQpxLiQzKG4sbCwxNCkKcS4kMyhuLGss
+MzQpCnEuJDMobixqLDMpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE0LDIy
+NSkpCnEuJDMobixtLDEpCnEuJDMobixsLDE1KQpxLiQzKG4saywzNCkKcS4kMyhuLGosMjM0KQpxLiQz
+KG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxNSwyMjUpKQpxLiQzKG4sbSwxKQpxLiQz
+KG4sIiUiLDIyNSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDkpCnEuJDMobixpLDE3MikKcS4kMyhuLGgs
+MjA1KQpuPW8uYShyLiQyKDEsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDEw
+KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigyLDIzNSkpCnEuJDMobixtLDEz
+OSkKcS4kMyhuLGosMTMxKQpxLiQzKG4sbCwxNDYpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpu
+PW8uYShyLiQyKDMsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixqLDY4KQpxLiQzKG4sbCwxOCkKcS4k
+MyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNCwyMjkpKQpxLiQzKG4sbSw1KQpwLiQz
+KG4sIkFaIiwyMjkpCnEuJDMobixrLDEwMikKcS4kMyhuLCJAIiw2OCkKcS4kMyhuLCJbIiwyMzIpCnEu
+JDMobixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNSwyMjkpKQpx
+LiQzKG4sbSw1KQpwLiQzKG4sIkFaIiwyMjkpCnEuJDMobixrLDEwMikKcS4kMyhuLCJAIiw2OCkKcS4k
+MyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig2LDIzMSkpCnAu
+JDMobiwiMTkiLDcpCnEuJDMobiwiQCIsNjgpCnEuJDMobixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQz
+KG4saCwyMDUpCm49by5hKHIuJDIoNywyMzEpKQpwLiQzKG4sIjA5Iiw3KQpxLiQzKG4sIkAiLDY4KQpx
+LiQzKG4saiwxMzgpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpxLiQzKG8uYShyLiQyKDgsOCkp
+LCJdIiw1KQpuPW8uYShyLiQyKDksMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE2KQpxLiQzKG4s
+aiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE2LDIzNSkpCnEuJDMo
+bixtLDExKQpxLiQzKG4sbCwxNykKcS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIw
+NSkKbj1vLmEoci4kMigxNywyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGosOSkKcS4kMyhuLGksMTcy
+KQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTAsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE4
+KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE4LDIz
+NSkpCnEuJDMobixtLDExKQpxLiQzKG4sbCwxOSkKcS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEu
+JDMobixoLDIwNSkKbj1vLmEoci4kMigxOSwyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGosMjM0KQpx
+LiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxMSwyMzUpKQpxLiQzKG4sbSwxMSkK
+cS4kMyhuLGosMTApCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEyLDIzNikp
+CnEuJDMobixtLDEyKQpxLiQzKG4saSwxMikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEzLDIzNykp
+CnEuJDMobixtLDEzKQpxLiQzKG4saSwxMykKcC4kMyhvLmEoci4kMigyMCwyNDUpKSwiYXoiLDIxKQpy
+PW8uYShyLiQyKDIxLDI0NSkpCnAuJDMociwiYXoiLDIxKQpwLiQzKHIsIjA5IiwyMSkKcS4kMyhyLCIr
+LS4iLDIxKQpyZXR1cm4gZ30sClVCOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuPSQu
+dlooKQpmb3Iocz1KLnJZKGEpLHI9YjtyPGM7KytyKXtpZihkPDB8fGQ+PW4ubGVuZ3RoKXJldHVybiBI
+Lk9IKG4sZCkKcT1uW2RdCnA9cy5XKGEscileOTYKbz1xW3A+OTU/MzE6cF0KZD1vJjMxCkMuTm0uWTUo
+ZSxvPj4+NSxyKX1yZXR1cm4gZH0sCldGOmZ1bmN0aW9uIFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWFM6ZnVuY3Rpb24gWFMoKXt9
+LApDNjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCkV6OmZ1bmN0aW9uIEV6KCl7fSwKRjpmdW5jdGlv
+biBGKCl7fSwKdTpmdW5jdGlvbiB1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMK
+Xy5kPWR9LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9Ygpf
+LmE9YwpfLmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhp
+cwpfLmY9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9
+YX0sCmRzOmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9
+LApVVjpmdW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rp
+b24gS1koKXt9LApjOmZ1bmN0aW9uIGMoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlz
+LmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmNY
+OmZ1bmN0aW9uIGNYKCl7fSwKQW46ZnVuY3Rpb24gQW4oKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKTWg6ZnVuY3Rp
+b24gTWgoKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwK
+bjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZD
+OmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
+Xy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PW51bGwKXy55PSExCl8uej1udWxsCl8uUT0h
+MQpfLmNoPW51bGwKXy5jeD0hMQpfLmN5PW51bGwKXy5kYj0hMX0sClJaOmZ1bmN0aW9uIFJaKCl7fSwK
+TUU6ZnVuY3Rpb24gTUUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3Ro
+aXMuYT1hfSwKUEU6ZnVuY3Rpb24gUEUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwK
+eUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9u
+IHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8u
+Yj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rp
+b24gcWUoYSxiLGMsZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9
+ZQpfLmY9ZgpfLnI9ZwpfLng9bnVsbApfLnk9ITEKXy56PW51bGwKXy5RPSExCl8uY2g9bnVsbApfLmN4
+PSExCl8uY3k9bnVsbApfLmRiPSExfSwKaUo6ZnVuY3Rpb24gaUooKXt9LApqZzpmdW5jdGlvbiBqZyhh
+LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVGE6ZnVuY3Rpb24gVGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sCkJmOmZ1bmN0aW9uIEJmKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBczpmdW5jdGlvbiBBcygp
+e30sCkdFOmZ1bmN0aW9uIEdFKGEpe3RoaXMuYT1hfSwKTjc6ZnVuY3Rpb24gTjcoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCnVROmZ1bmN0aW9uIHVRKCl7fSwKaEY6ZnVuY3Rpb24gaEYoKXt9LApSNDpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKSC55OChiKQp0LmouYShkKQppZihILm9UKGIpKXtzPVtjXQpD
+Lk5tLkZWKHMsZCkKZD1zfXI9dC56CnE9UC5DSChKLk0xKGQsUC53MCgpLHIpLCEwLHIpCnQuWS5hKGEp
+CnJldHVybiBQLndZKEguRWsoYSxxLG51bGwpKX0sCkRtOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwp0cnl7
+aWYoT2JqZWN0LmlzRXh0ZW5zaWJsZShhKSYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHku
+Y2FsbChhLGIpKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxiLHt2YWx1ZTpjfSkKcmV0dXJuITB9fWNh
+dGNoKHMpe0guUnUocyl9cmV0dXJuITF9LApPbTpmdW5jdGlvbihhLGIpe2lmKE9iamVjdC5wcm90b3R5
+cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXJldHVybiBhW2JdCnJldHVybiBudWxsfSwKd1k6ZnVu
+Y3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8
+fEgubChhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkp
+cmV0dXJuIGEKaWYodC5hay5iKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBI
+Lm8yKGEpCmlmKHQuWS5iKGEpKXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBD
+KCkpCnJldHVybiBQLmhFKGEsIl8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApoRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHM9UC5PbShhLGIpCmlmKHM9PW51bGwpe3M9Yy4kMShhKQpQLkRtKGEs
+YixzKX1yZXR1cm4gc30sCmRVOmZ1bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbHx8dHlwZW9mIGE9
+PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEK
+ZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0
+YW5jZW9mIE9iamVjdCYmdC5hay5iKGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIERhdGUp
+e3M9SC51UChhLmdldFRpbWUoKSkKaWYoTWF0aC5hYnMocyk8PTg2NGUxMylyPSExCmVsc2Ugcj0hMApp
+ZihyKUgudihQLnhZKCJEYXRlVGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdlOiAiK3MpKQpILmNiKCEx
+LCJpc1V0YyIsdC55KQpyZXR1cm4gbmV3IFAuaVAocywhMSl9ZWxzZSBpZihhLmNvbnN0cnVjdG9yPT09
+JC5rSSgpKXJldHVybiBhLm8KZWxzZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1bmN0aW9uKGEpe2lmKHR5
+cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBQLmlRKGEsJC53KCksbmV3IFAuTnooKSkKaWYoYSBpbnN0
+YW5jZW9mIEFycmF5KXJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEs
+JC5SOCgpLG5ldyBQLm5wKCkpfSwKaVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPVAuT20oYSxiKQppZihz
+PT1udWxsfHwhKGEgaW5zdGFuY2VvZiBPYmplY3QpKXtzPWMuJDEoYSkKUC5EbShhLGIscyl9cmV0dXJu
+IHN9LApQQzpmdW5jdGlvbiBQQygpe30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVu
+Y3Rpb24gTnooKXt9LApRUzpmdW5jdGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVu
+Y3Rpb24gRTQoYSl7dGhpcy5hPWF9LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0
+aW9uIFR6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVu
+Y3Rpb24gbmQoKXt9LApLZTpmdW5jdGlvbiBLZShhKXt0aGlzLmE9YX0sCmhpOmZ1bmN0aW9uIGhpKCl7
+fX0sVz17CngzOmZ1bmN0aW9uKCl7cmV0dXJuIHdpbmRvd30sClpyOmZ1bmN0aW9uKCl7cmV0dXJuIGRv
+Y3VtZW50fSwKSjY6ZnVuY3Rpb24oYSl7dmFyIHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpCmlm
+KGEhPW51bGwpQy54bi5zTFUocyxhKQpyZXR1cm4gc30sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxy
+PWRvY3VtZW50LmJvZHkKci50b1N0cmluZwpzPUMuUlkucjYocixhLGIsYykKcy50b1N0cmluZwpyPXQu
+YWMKcj1uZXcgSC5VNShuZXcgVy5lNyhzKSxyLkMoImEyKGxELkUpIikuYShuZXcgVy5DdigpKSxyLkMo
+IlU1PGxELkU+IikpCnJldHVybiB0LmguYShyLmdyOChyKSl9LApyUzpmdW5jdGlvbihhKXt2YXIgcyxy
+LHE9ImVsZW1lbnQgdGFnIHVuYXZhaWxhYmxlIgp0cnl7cz1KLllFKGEpCmlmKHR5cGVvZiBzLmducyhh
+KT09InN0cmluZyIpcT1zLmducyhhKX1jYXRjaChyKXtILlJ1KHIpfXJldHVybiBxfSwKQzA6ZnVuY3Rp
+b24oYSxiKXthPWErYiY1MzY4NzA5MTEKYT1hKygoYSY1MjQyODcpPDwxMCkmNTM2ODcwOTExCnJldHVy
+biBhXmE+Pj42fSwKckU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9Vy5DMChXLkMwKFcuQzAoVy5DMCgw
+LGEpLGIpLGMpLGQpLHI9cysoKHMmNjcxMDg4NjMpPDwzKSY1MzY4NzA5MTEKcl49cj4+PjExCnJldHVy
+biByKygociYxNjM4Myk8PDE1KSY1MzY4NzA5MTF9LApUTjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1h
+LmNsYXNzTGlzdApmb3Iocz1iLmxlbmd0aCxyPTA7cjxiLmxlbmd0aDtiLmxlbmd0aD09PXN8fCgwLEgu
+bGspKGIpLCsrcilxLmFkZChiW3JdKX0sCkpFOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9Vy5hRihu
+ZXcgVy52TihjKSx0LkIpCmlmKHMhPW51bGwmJiEwKUouZFooYSxiLHMsITEpCnJldHVybiBuZXcgVy54
+QyhhLGIscywhMSxlLkMoInhDPDA+IikpfSwKVHc6ZnVuY3Rpb24oYSl7dmFyIHM9Vy5KNihudWxsKSxy
+PXdpbmRvdy5sb2NhdGlvbgpzPW5ldyBXLkpRKG5ldyBXLm1rKHMscikpCnMuQ1koYSkKcmV0dXJuIHN9
+LApxRDpmdW5jdGlvbihhLGIsYyxkKXt0LmguYShhKQpILmgoYikKSC5oKGMpCnQuY3IuYShkKQpyZXR1
+cm4hMH0sClFXOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0LmguYShhKQpILmgoYikKSC5oKGMp
+CnM9dC5jci5hKGQpLmEKcj1zLmEKQy54bi5zTFUocixjKQpxPXIuaG9zdG5hbWUKcz1zLmIKaWYoIShx
+PT1zLmhvc3RuYW1lJiZyLnBvcnQ9PXMucG9ydCYmci5wcm90b2NvbD09cy5wcm90b2NvbCkpaWYocT09
+PSIiKWlmKHIucG9ydD09PSIiKXtzPXIucHJvdG9jb2wKcz1zPT09IjoifHxzPT09IiJ9ZWxzZSBzPSEx
+CmVsc2Ugcz0hMQplbHNlIHM9ITAKcmV0dXJuIHN9LApCbDpmdW5jdGlvbigpe3ZhciBzPXQuTixyPVAu
+dE0oQy5ReCxzKSxxPXQuZDAuYShuZXcgVy5JQSgpKSxwPUguVk0oWyJURU1QTEFURSJdLHQucykKcz1u
+ZXcgVy5jdChyLFAuTHMocyksUC5McyhzKSxQLkxzKHMpLG51bGwpCnMuQ1kobnVsbCxuZXcgSC5sSihD
+LlF4LHEsdC5maikscCxudWxsKQpyZXR1cm4gc30sCnFjOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGE9PW51
+bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXtzPVcuUDEoYSkKaWYodC5hUy5iKHMp
+KXJldHVybiBzCnJldHVybiBudWxsfWVsc2UgcmV0dXJuIHQuY2guYShhKX0sClAxOmZ1bmN0aW9uKGEp
+e2lmKGE9PT13aW5kb3cpcmV0dXJuIHQuY2kuYShhKQplbHNlIHJldHVybiBuZXcgVy5kVygpfSwKYUY6
+ZnVuY3Rpb24oYSxiKXt2YXIgcz0kLlgzCmlmKHM9PT1DLk5VKXJldHVybiBhCnJldHVybiBzLlB5KGEs
+Yil9LApxRTpmdW5jdGlvbiBxRSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlko
+KXt9LApuQjpmdW5jdGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAo
+KXt9LApueDpmdW5jdGlvbiBueCgpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQo
+KXt9LApRRjpmdW5jdGlvbiBRRigpe30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKYWU6ZnVuY3Rpb24gYWUo
+KXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rpb24gd3oo
+YSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5jdGlvbiBD
+digpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApoSDpmdW5jdGlvbiBo
+SCgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5jdGlvbiBW
+Yigpe30sCmZKOmZ1bmN0aW9uIGZKKCl7fSwKd2E6ZnVuY3Rpb24gd2EoKXt9LApTZzpmdW5jdGlvbiBT
+Zygpe30sCnc3OmZ1bmN0aW9uIHc3KCl7fSwKQWo6ZnVuY3Rpb24gQWooKXt9LAplNzpmdW5jdGlvbiBl
+NyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rpb24gQkgoKXt9LApTTjpm
+dW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rpb24gbHAoKXt9LApUYjpm
+dW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rpb24gV1AoKXt9LAp5WTpm
+dW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rpb24gSzUoKXt9LApDbTpm
+dW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rpb24gdzQoKXt9LApyaDpm
+dW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rpb24gaTcoYSl7dGhpcy5h
+PWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9uIEtTKGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSTQ6ZnVu
+Y3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3RoaXMuYT1hCnRoaXMuJHRp
+PWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8u
+JHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5iPWEKXy5jPWIK
+Xy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMuYT1hfSwKSlE6ZnVuY3Rp
+b24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1bmN0aW9uIHZEKGEpe3Ro
+aXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5jdGlvbiBFZyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigpe30sCkVvOmZ1bmN0aW9u
+IEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChhLGIsYyxkLGUpe3ZhciBf
+PXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5jdGlvbiBJQSgpe30sCk93
+OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
+PWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVygpe30sCm1rOmZ1bmN0aW9u
+IG1rKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLbzpmdW5jdGlvbiBLbyhhKXt0aGlzLmE9YQp0aGlz
+LmI9ITF9LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6
+ZnVuY3Rpb24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6
+ZnVuY3Rpb24gb2EoKXt9fSxNPXsKT1g6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UgQy5BZDpyZXR1
+cm4iQWRkIC8qPyovIGhpbnQiCmNhc2UgQy5uZTpyZXR1cm4iQWRkIC8qISovIGhpbnQiCmNhc2UgQy53
+VjpyZXR1cm4iUmVtb3ZlIC8qPyovIGhpbnQiCmNhc2UgQy5mUjpyZXR1cm4iUmVtb3ZlIC8qISovIGhp
+bnQiCmNhc2UgQy5teTpyZXR1cm4iQ2hhbmdlIHRvIC8qPyovIGhpbnQiCmNhc2UgQy5yeDpyZXR1cm4i
+Q2hhbmdlIHRvIC8qISovIGhpbnQifXJldHVybiBudWxsfSwKSDc6ZnVuY3Rpb24gSDcoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCllGOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbApmb3Iocz1i
+Lmxlbmd0aCxyPTE7cjxzOysrcil7aWYoYltyXT09bnVsbHx8YltyLTFdIT1udWxsKWNvbnRpbnVlCmZv
+cig7cz49MTtzPXEpe3E9cy0xCmlmKGJbcV0hPW51bGwpYnJlYWt9cD1uZXcgUC5SbigiIikKbz1hKyIo
+IgpwLmE9bwpuPUgudDYoYikKbT1uLkMoIm5IPDE+IikKbD1uZXcgSC5uSChiLDAscyxtKQpsLkhkKGIs
+MCxzLG4uYykKbT1vK25ldyBILmxKKGwsbS5DKCJxVShhTC5FKSIpLmEobmV3IE0uTm8oKSksbS5DKCJs
+SjxhTC5FLHFVPiIpKS5rKDAsIiwgIikKcC5hPW0KcC5hPW0rKCIpOiBwYXJ0ICIrKHItMSkrIiB3YXMg
+bnVsbCwgYnV0IHBhcnQgIityKyIgd2FzIG5vdC4iKQp0aHJvdyBILmIoUC54WShwLncoMCkpKX19LAps
+STpmdW5jdGlvbiBsSShhKXt0aGlzLmE9YX0sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24g
+Tm8oKXt9fSxVPXsKbno6ZnVuY3Rpb24oYSl7dmFyIHM9SC51UChhLnEoMCwibm9kZUlkIikpCnJldHVy
+biBuZXcgVS5MTChDLk5tLkh0KEMucmssbmV3IFUuTUQoYSkpLHMpfSwKTEw6ZnVuY3Rpb24gTEwoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1EOmZ1bmN0aW9uIE1EKGEpe3RoaXMuYT1hfSwKamY6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxLHAKaWYoYT09bnVsbClzPW51bGwKZWxzZXtzPUguVk0oW10sdC5kNykKZm9y
+KHI9Si5JVCh0LlUuYShhKSk7ci5GKCk7KXtxPXIuZ2woKQpwPUouVTYocSkKcy5wdXNoKG5ldyBVLlNl
+KEguaChwLnEocSwiZGVzY3JpcHRpb24iKSksSC5oKHAucShxLCJocmVmIikpKSl9fXJldHVybiBzfSwK
+TmQ6ZnVuY3Rpb24oYSl7dmFyIHMscgppZihhPT1udWxsKXM9bnVsbAplbHNle3M9SC5WTShbXSx0LmFB
+KQpmb3Iocj1KLklUKHQuVS5hKGEpKTtyLkYoKTspcy5wdXNoKFUuTmYoci5nbCgpKSl9cmV0dXJuIHN9
+LApOZjpmdW5jdGlvbihhKXt2YXIgcz1KLlU2KGEpLHI9SC5oKHMucShhLCJkZXNjcmlwdGlvbiIpKSxx
+PUguVk0oW10sdC5hSikKZm9yKHM9Si5JVCh0LlUuYShzLnEoYSwiZW50cmllcyIpKSk7cy5GKCk7KXEu
+cHVzaChVLlJqKHMuZ2woKSkpCnJldHVybiBuZXcgVS55RChyLHEpfSwKUmo6ZnVuY3Rpb24oYSl7dmFy
+IHMscj1KLlU2KGEpLHE9SC5oKHIucShhLCJkZXNjcmlwdGlvbiIpKSxwPUguaChyLnEoYSwiZnVuY3Rp
+b24iKSksbz1yLnEoYSwibGluayIpCmlmKG89PW51bGwpbz1udWxsCmVsc2V7cz1KLlU2KG8pCm89bmV3
+IFUuTWwoSC5oKHMucShvLCJocmVmIikpLEgudVAocy5xKG8sImxpbmUiKSksSC5oKHMucShvLCJwYXRo
+IikpKX1yPXQuZksuYShyLnEoYSwiaGludEFjdGlvbnMiKSkKcj1yPT1udWxsP251bGw6Si5NMShyLG5l
+dyBVLmFOKCksdC5hWCkKcj1yPT1udWxsP251bGw6ci5icigwKQpyZXR1cm4gbmV3IFUud2IocSxwLG8s
+cj09bnVsbD9DLmRuOnIpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApTZTpmdW5jdGlvbiBTZShhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKTWw6ZnVuY3Rpb24gTWwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+Yz1jfSwKeUQ6ZnVuY3Rpb24geUQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndiOmZ1bmN0aW9uIHdi
+KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAphTjpmdW5jdGlvbiBh
+Tigpe30sCmIwOmZ1bmN0aW9uIGIwKCl7fX0sQj17CndSOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBCLnFw
+KCIiLCIiLCIiLEMuRHgpfSwKWWY6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPUguaChh
+LnEoMCwicmVnaW9ucyIpKSxqPUguaChhLnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSksaT1ILmgoYS5x
+KDAsInNvdXJjZUNvZGUiKSksaD1QLkZsKHQuWCx0LmRfKQpmb3Iocz10LnQuYShhLnEoMCwiZWRpdHMi
+KSkscz1zLmdQdShzKSxzPXMuZ20ocykscj10LlUscT10Lmg0O3MuRigpOyl7cD1zLmdsKCkKbz1wLmEK
+bj1ILlZNKFtdLHEpCmZvcihwPUouSVQoci5hKHAuYikpO3AuRigpOyl7bT1wLmdsKCkKbD1KLlU2KG0p
+Cm4ucHVzaChuZXcgQi5qOChILnVQKGwucShtLCJsaW5lIikpLEguaChsLnEobSwiZXhwbGFuYXRpb24i
+KSksSC51UChsLnEobSwib2Zmc2V0IikpKSl9aC5ZNSgwLG8sbil9cmV0dXJuIG5ldyBCLnFwKGssaixp
+LGgpfSwKajg6ZnVuY3Rpb24gajgoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6
+ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2
+OmZ1bmN0aW9uIGZ2KCl7fSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIShhPj02NSYmYTw9OTApKXM9
+YT49OTcmJmE8PTEyMgplbHNlIHM9ITAKcmV0dXJuIHN9LApZdTpmdW5jdGlvbihhLGIpe3ZhciBzPWEu
+bGVuZ3RoLHI9YisyCmlmKHM8cilyZXR1cm4hMQppZighQi5PUyhDLnhCLk8yKGEsYikpKXJldHVybiEx
+CmlmKEMueEIuTzIoYSxiKzEpIT09NTgpcmV0dXJuITEKaWYocz09PXIpcmV0dXJuITAKcmV0dXJuIEMu
+eEIuTzIoYSxyKT09PTQ3fX0sVD17bVE6ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtD
+LkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRlbnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywi
+cG9wc3RhdGUiLG5ldyBMLkwoKSl9LAprejpmdW5jdGlvbihhKXt2YXIgcyxyPXQuZy5hKGEucGFyZW50
+Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNjb3BlID4gdWwiKSxxPXIuc3R5bGUscD0iIitDLkNELnpRKHIu
+b2Zmc2V0SGVpZ2h0KSoyKyJweCIKcS5tYXhIZWlnaHQ9cApxPUoucUYoYSkKcD1xLiR0aQpzPXAuQygi
+figxKT8iKS5hKG5ldyBMLld4KHIsYSkpCnQuWi5hKG51bGwpClcuSkUocS5hLHEuYixzLCExLHAuYyl9
+LAp5WDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPSJxdWVyeVNlbGVjdG9yQWxsIixsPWRv
+Y3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSksaz10LmcKbC50b1N0cmluZwpzPXQuaApILkRoKGsscywiVCIs
+bSkKcj10LlIKcT1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHIpCnEuSyhx
+LG5ldyBMLkFPKGIpKQpILkRoKGsscywiVCIsbSkKcD1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwo
+Ii5yZWdpb24iKSxyKQppZighcC5nbDAocCkpe289bC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBh
+dGhdIikKby50b1N0cmluZwpwLksocCxuZXcgTC5IbyhvLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
+LlN5KG5ldyBXLmk3KG8pKS5QKCJwYXRoIikpKSl9SC5EaChrLHMsIlQiLG0pCm49bmV3IFcud3oobC5x
+dWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhpbnQtbGluayIpLHIpCm4uSyhuLG5ldyBMLklDKCkpfSwKUTY6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8ocywiR0VUIixM
+LlE0KGEsYiksITApCnMuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24v
+anNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHMsbnVsbCxjLkMoIjAqIikpfSwKdHk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcz1uZXcgWE1MSHR0cFJlcXVlc3QoKSxyPXQuWApDLkR0LmVvKHMsIlBPU1Qi
+LEwuUTQoYSxQLkZsKHIscikpLCEwKQpzLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFw
+cGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiKQpyZXR1cm4gTC5MVShzLGIsdC50KX0sCkxVOmZ1
+bmN0aW9uKGEsYixjKXtyZXR1cm4gTC5UZyhhLGIsYyxjLkMoIjAqIikpfSwKVGc6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHM9MCxyPVAuRlgoZCkscSxwPTIsbyxuPVtdLG0sbCxrLGosaSxoLGcsZgp2YXIgJGFz
+eW5jJExVPVAubHooZnVuY3Rpb24oZSxhMCl7aWYoZT09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dp
+dGNoKHMpe2Nhc2UgMDppPW5ldyBQLlpmKG5ldyBQLnZzKCQuWDMsdC5nViksdC5iQykKaD10LmViCmc9
+aC5hKG5ldyBMLmZDKGksYSkpCnQuWi5hKG51bGwpCmw9dC5lUQpXLkpFKGEsImxvYWQiLGcsITEsbCkK
+Vy5KRShhLCJlcnJvciIsaC5hKGkuZ1lKKCkpLCExLGwpCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5P
+QihiLG51bGwpKQpwPTQKcz03CnJldHVybiBQLmpRKGkuYSwkYXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02
+CmJyZWFrCmNhc2UgNDpwPTMKZj1vCkguUnUoZikKbT1ILnRzKGYpCmg9UC5UbCgiRXJyb3IgcmVhY2hp
+bmcgbWlncmF0aW9uIHByZXZpZXcgc2VydmVyLiIsbSkKdGhyb3cgSC5iKGgpCnM9NgpicmVhawpjYXNl
+IDM6cz0yCmJyZWFrCmNhc2UgNjpqPUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQppZihhLnN0
+YXR1cz09PTIwMCl7cT1jLkMoIjAqIikuYShqKQpzPTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaikKY2Fz
+ZSAxOnJldHVybiBQLnlDKHEscikKY2FzZSAyOnJldHVybiBQLmYzKG8scil9fSkKcmV0dXJuIFAuREko
+JGFzeW5jJExVLHIpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHM9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUi
+KQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciBzPVAu
+aEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0s
+Cmk2OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHQuTy5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciBz
+PTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaTY9UC5seihm
+dW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpp
+PXQuZy5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50
+RGVmYXVsdCgpCnE9MwprPWRvY3VtZW50Cm49Qy5DRC56UShrLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50
+Iikuc2Nyb2xsVG9wKQpzPTYKcmV0dXJuIFAualEoTC50eShpLG51bGwpLCRhc3luYyRpNikKY2FzZSA2
+OnM9NwpyZXR1cm4gUC5qUShMLkc3KHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxudWxsLG51bGwsITEs
+bnVsbCksJGFzeW5jJGk2KQpjYXNlIDc6az1rLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50IikKay50b1N0
+cmluZwprLnNjcm9sbFRvcD1KLlZ1KG4pCnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9MgpoPXAKbT1ILlJ1
+KGgpCmw9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgYWRkL3JlbW92ZSBoaW50IixtLGwpCnM9NQpicmVh
+awpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4g
+UC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixyKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcyxyLHEscD0iZXhjZXB0aW9uIixvPSJzdGFja1RyYWNlIixuPXQudC5iKGIpJiZKLlJNKGIucSgw
+LCJzdWNjZXNzIiksITEpJiZiLng0KHApJiZiLng0KG8pLG09Si5pYShiKQppZihuKXtzPUguaChtLnEo
+YixwKSkKYz1tLnEoYixvKX1lbHNlIHM9bS53KGIpCm49ZG9jdW1lbnQKcj1uLnF1ZXJ5U2VsZWN0b3Io
+Ii5wb3B1cC1wYW5lIikKci5xdWVyeVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnIucXVlcnlTZWxl
+Y3RvcigicCIpLmlubmVyVGV4dD1zCnIucXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUouaihj
+KQpxPXQuZGQuYShyLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikpCm09dC5YOyhxJiZDLnhuKS5zTFUo
+cSxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYo
+WyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbDog
+IithLCJsYWJlbHMiLHUuZCwiYm9keSIsYSsiXG5cbkVycm9yOiAiK0guRWoocykrIlxuXG5QbGVhc2Ug
+ZmlsbCBpbiB0aGUgZm9sbG93aW5nOlxuXG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAo
+aWYgcHVibGljKSoqOlxuKipXaGF0IEkgd2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoq
+OlxuKipJcyBpdCBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlz
+IGlzc3VlIGhhcHBlbmVkIGJlZm9yZSwgYW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsg
+dmVyc2lvbioqOiAiK0guRWoobi5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVu
+dCkrIlxuKipBZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNr
+dHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4i
+K0guRWooYykrIlxuYGBgXG4iXSxtLG0pKS5nbkQoKSkKbT1xLnN0eWxlCm0uZGlzcGxheT0iaW5pdGlh
+bCIKbj1yLnN0eWxlCm4uZGlzcGxheT0iaW5pdGlhbCIKbj1hKyI6ICIrSC5FaihiKQp3aW5kb3cKaWYo
+dHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pCndpbmRvdwpu
+PUguRWooYykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9y
+KG4pfSwKdDI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89dC5nLmEoVy5xYyhhLmN1cnJlbnRU
+YXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKcz1vLmdldEF0dHJpYnV0ZSgiaHJlZiIpCnI9TC5Vcyhz
+KQpxPUwuRzYocykKcD1MLmFLKHMpCmlmKHEhPW51bGwpTC5hZihyLHEscCxiLG5ldyBMLm5UKHIscSxw
+KSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuTlkocikpfSwKSzA6ZnVuY3Rpb24oYSl7dmFy
+IHMscixxLHA9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0
+b3IoImgyIikuaW5uZXJUZXh0PSJGYWlsZWQgdG8gcmVydW4gZnJvbSBzb3VyY2VzIgpwLnF1ZXJ5U2Vs
+ZWN0b3IoInAiKS5pbm5lclRleHQ9IlNvdXJjZXMgY29udGFpbiBzdGF0aWMgYW5hbHlzaXMgZXJyb3Jz
+OiIKcz1wLnF1ZXJ5U2VsZWN0b3IoInByZSIpCnI9Si5FbChhLHQuYXcpCnE9SC5MaChyKQpzLmlubmVy
+VGV4dD1uZXcgSC5sSihyLHEuQygicVUqKGxELkUpIikuYShuZXcgTC51ZSgpKSxxLkMoImxKPGxELkUs
+cVUqPiIpKS5rKDAsIlxuIikKcT1wLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikuc3R5bGUKcS5kaXNw
+bGF5PSJub25lIgpzPXAuc3R5bGUKcy5kaXNwbGF5PSJpbml0aWFsIn0sCnZVOmZ1bmN0aW9uKCl7dmFy
+IHM9ZG9jdW1lbnQKSC5EaCh0LmcsdC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9bmV3IFcud3oo
+cy5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHQuUikKcy5LKHMsbmV3IEwuZVgoKSl9LApoWDpmdW5j
+dGlvbihhLGIsYyl7cmV0dXJuIEwuWXcoYSxiLGMpfSwKWXc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPTAs
+cj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRoWD1QLmx6KGZ1
+bmN0aW9uKGQsZSl7aWYoZD09PTEpe3A9ZQpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9
+MwpqPXQuWApzPTYKcmV0dXJuIFAualEoTC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdpb24iLCJvZmZz
+ZXQiLEguRWooYildLGosaiksdC50KSwkYXN5bmMkaFgpCmNhc2UgNjpuPWUKaj1uCmk9Si5VNihqKQpt
+PW5ldyBVLmQyKFUuamYoaS5xKGosImVkaXRzIikpLEguaChpLnEoaiwiZXhwbGFuYXRpb24iKSksSC51
+UChpLnEoaiwibGluZSIpKSxILmgoaS5xKGosImRpc3BsYXlQYXRoIikpLEguaChpLnEoaiwidXJpUGF0
+aCIpKSxVLk5kKGkucShqLCJ0cmFjZXMiKSkpCkwuVDEobSkKTC5GcihhLGIsYykKTC55WCgiLmVkaXQt
+cGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9SC5S
+dShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixsLGspCnM9NQpi
+cmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1
+cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRoWCxyKX0sCkc3OmZ1bmN0aW9uKGEsYixj
+LGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9
+MCxyPVAuRlgodC5IKSxxLHA9MixvLG49W10sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEc3PVAubHoo
+ZnVuY3Rpb24oZixhMCl7aWYoZj09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2Ug
+MDppZighSi5wNChhLCIuZGFydCIpKXtMLkJFKGEsQi53UigpLGQpCkwuQlgoYSxudWxsKQppZihlIT1u
+dWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00Cmk9dC5YCnM9NwpyZXR1cm4gUC5qUShMLlE2KGEsUC5FRihb
+ImlubGluZSIsInRydWUiXSxpLGkpLHQudCksJGFzeW5jJEc3KQpjYXNlIDc6bT1hMApMLkJFKGEsQi5Z
+ZihtKSxkKQpMLmZHKGIsYykKbD1MLlVzKGEpCkwuQlgobCxiKQppZihlIT1udWxsKWUuJDAoKQpwPTIK
+cz02CmJyZWFrCmNhc2UgNDpwPTMKZz1vCms9SC5SdShnKQpqPUgudHMoZykKTC5DMigiQ291bGQgbm90
+IGxvYWQgZGFydCBmaWxlICIrYSxrLGopCnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpj
+YXNlIDE6cmV0dXJuIFAueUMocSxyKQpjYXNlIDI6cmV0dXJuIFAuZjMobyxyKX19KQpyZXR1cm4gUC5E
+SSgkYXN5bmMkRzcscil9LApHZTpmdW5jdGlvbigpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1b
+XSxuLG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRHZT1QLmx6KGZ1bmN0aW9uKGEsYil7aWYoYT09PTEp
+e3A9YgpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOmg9Ii9fcHJldmlldy9uYXZpZ2F0aW9u
+VHJlZS5qc29uIgpxPTMKcz02CnJldHVybiBQLmpRKEwuUTYoaCxDLkNNLHQubSksJGFzeW5jJEdlKQpj
+YXNlIDY6bj1iCm09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLm5hdi10cmVlIikKSi5sNShtLCIiKQpq
+PUwubUsobikKJC5JUj1qCkwudFgobSxqLCExKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9
+SC5SdShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgbmF2aWdhdGlvbiB0cmVlIixsLGsp
+CnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2Ug
+MTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRHZSxyKX0sCnFPOmZ1bmN0aW9u
+KGEpe3ZhciBzLHI9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxxPUMuQ0QuelEoJC5maSgpLm9mZnNl
+dEhlaWdodCkscD13aW5kb3cuaW5uZXJIZWlnaHQsbz1DLkNELnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQp
+CmlmKHR5cGVvZiBwIT09Im51bWJlciIpcmV0dXJuIHAuSE4oKQpzPXIuYm90dG9tCnMudG9TdHJpbmcK
+aWYocz5wLShvKzE0KSlKLmRoKGEpCmVsc2V7cD1yLnRvcApwLnRvU3RyaW5nCmlmKHA8cSsxNClKLmRo
+KGEpfX0sCmZHOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwppZihhIT1udWxsKXtzPWRvY3VtZW50
+CnI9cy5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihhKSkKcT1zLnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIr
+SC5FaihiKSkKaWYociE9bnVsbCl7TC5xTyhyKQpKLmRSKHIpLmkoMCwidGFyZ2V0Iil9ZWxzZSBpZihx
+IT1udWxsKUwucU8ocS5wYXJlbnRFbGVtZW50KQppZihxIT1udWxsKUouZFIodC5nLmEocS5wYXJlbnRO
+b2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNle3M9ZG9jdW1lbnQKcD10LmcKSC5EaChwLHQuaCwiVCIs
+InF1ZXJ5U2VsZWN0b3JBbGwiKQpzPXMucXVlcnlTZWxlY3RvckFsbCgiLmxpbmUtbm8iKQpvPW5ldyBX
+Lnd6KHMsdC5SKQppZihvLmdBKG8pPT09MClyZXR1cm4KTC5xTyhwLmEoQy50NS5ndEgocykpKX19LAph
+ZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscT1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxw
+PUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHEhPW51bGwpe3M9ZG9jdW1lbnQuZ2V0RWxlbWVu
+dEJ5SWQoIm8iK0guRWoocSkpCmlmKHMhPW51bGwpSi5kUihzKS5MKDAsInRhcmdldCIpfWlmKHAhPW51
+bGwpe3I9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILkVqKHApKQppZihyIT1udWxsKUou
+ZFIoci5wYXJlbnRFbGVtZW50KS5MKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRvdy5sb2NhdGlvbi5w
+YXRobmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sClE0OmZ1bmN0aW9u
+KGEsYil7dmFyIHMscixxPVAuaEsoYSkscD10LlgKcD1QLkZsKHAscCkKZm9yKHM9cS5naFkoKSxzPXMu
+Z1B1KHMpLHM9cy5nbShzKTtzLkYoKTspe3I9cy5nbCgpCnAuWTUoMCxyLmEsci5iKX1mb3Iocz1iLmdQ
+dShiKSxzPXMuZ20ocyk7cy5GKCk7KXtyPXMuZ2woKQpwLlk1KDAsci5hLHIuYil9cC5ZNSgwLCJhdXRo
+VG9rZW4iLCQuVUUoKSkKcmV0dXJuIHEubm0oMCxwKS5nbkQoKX0sClQxOmZ1bmN0aW9uKGEpe3ZhciBz
+LHIscSxwLG8sbixtLGwsayxqPSQuaEwoKQpKLmw1KGosIiIpCmlmKGE9PW51bGwpe3M9ZG9jdW1lbnQu
+Y3JlYXRlRWxlbWVudCgicCIpCkMuTHQuc2E0KHMsIlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQg
+ZWRpdC4iKQpDLkx0LnNuKHMsSC5WTShbInBsYWNlaG9sZGVyIl0sdC5pKSkKai5hcHBlbmRDaGlsZChz
+KQpDLkx0LkZGKHMpCnJldHVybn1yPWEuZApxPSQublUoKQpwPXEuemYocikKbz1hLmIKbj1kb2N1bWVu
+dAptPXEuSFAocixKLlQwKG4ucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpCmw9YS5j
+Cms9bi5jcmVhdGVFbGVtZW50KCJwIikKai5hcHBlbmRDaGlsZChrKQprLmFwcGVuZENoaWxkKG4uY3Jl
+YXRlVGV4dE5vZGUoSC5FaihvKSsiIGF0ICIpKQpxPXQuWApxPVcuSjYoTC5RNChhLmUsUC5FRihbImxp
+bmUiLEouaihsKV0scSxxKSkpCnEuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShILkVqKG0pKyI6
+IitILkVqKGwpKyIuIikpCmsuYXBwZW5kQ2hpbGQocSkKSi5kaChrKQpMLkNDKGEsaixwKQpMLkZ6KGEs
+ail9LApMSDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPSQu
+eVAoKQpKLmw1KGUsIiIpCmlmKGIuZ0EoYik9PT0wKXtzPWRvY3VtZW50CnI9cy5jcmVhdGVFbGVtZW50
+KCJwIikKZS5hcHBlbmRDaGlsZChyKQpyLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIk5vIHBy
+b3Bvc2VkIGVkaXRzIikpfWVsc2UgZm9yKGU9Yi5nUHUoYiksZT1lLmdtKGUpLHM9dC5YLHE9dC5rLHA9
+cS5DKCJ+KDEpPyIpLG89dC5aLHE9cS5jO2UuRigpOyl7bj1lLmdsKCkKbT1kb2N1bWVudApyPW0uY3Jl
+YXRlRWxlbWVudCgicCIpCmw9JC55UCgpCmwuYXBwZW5kQ2hpbGQocikKci5hcHBlbmRDaGlsZChtLmNy
+ZWF0ZVRleHROb2RlKEguRWoobi5hKSsiOiIpKQprPW0uY3JlYXRlRWxlbWVudCgidWwiKQpsLmFwcGVu
+ZENoaWxkKGspCmZvcihuPUouSVQobi5iKTtuLkYoKTspe2w9bi5nbCgpCmo9bS5jcmVhdGVFbGVtZW50
+KCJsaSIpCmsuYXBwZW5kQ2hpbGQoaikKSi5kUihqKS5pKDAsImVkaXQiKQppPW0uY3JlYXRlRWxlbWVu
+dCgiYSIpCmouYXBwZW5kQ2hpbGQoaSkKaS5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsiKQpoPWwuYwpn
+PUguRWooaCkKaS5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhpKSkuUCgib2Zm
+c2V0IiksZykKZj1sLmEKZz1ILkVqKGYpCmkuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3
+IFcuaTcoaSkpLlAoImxpbmUiKSxnKQppLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoImxpbmUg
+IitILkVqKGYpKSkKaS5zZXRBdHRyaWJ1dGUoImhyZWYiLEwuUTQod2luZG93LmxvY2F0aW9uLnBhdGhu
+YW1lLFAuRUYoWyJsaW5lIixILkVqKGYpLCJvZmZzZXQiLEguRWooaCldLHMscykpKQpnPXAuYShuZXcg
+TC5FRShoLGYsYSkpCm8uYShudWxsKQpXLkpFKGksImNsaWNrIixnLCExLHEpCmouYXBwZW5kQ2hpbGQo
+bS5jcmVhdGVUZXh0Tm9kZSgiOiAiK0guRWoobC5iKSkpfX1pZihjKUwuVDEobnVsbCl9LApGcjpmdW5j
+dGlvbihhLGIsYyl7dmFyIHMscixxPXdpbmRvdy5sb2NhdGlvbixwPVAuaEsoKHEmJkMuRXgpLmdEcihx
+KStILkVqKGEpKQpxPXQuWApxPVAuRmwocSxxKQppZihiIT1udWxsKXEuWTUoMCwib2Zmc2V0IixILkVq
+KGIpKQppZihjIT1udWxsKXEuWTUoMCwibGluZSIsSC5FaihjKSkKcS5ZNSgwLCJhdXRoVG9rZW4iLCQu
+VUUoKSkKcD1wLm5tKDAscSkKcT13aW5kb3cuaGlzdG9yeQpzPXQuegpyPXAuZ25EKCkKcS50b1N0cmlu
+ZwpxLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxbXSkuUHYoUC5GbChzLHMpKSwiIixyKX0sCkVuOmZ1bmN0
+aW9uKGEpe3ZhciBzPUouYmIoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVu
+dCwiLyIpCmlmKEMueEIubkMoYSxzKSlyZXR1cm4gQy54Qi55bihhLHMubGVuZ3RoKQplbHNlIHJldHVy
+biBhfSwKT3Q6ZnVuY3Rpb24oYSl7c3dpdGNoKGEucil7Y2FzZSBDLmN3OmJyZWFrCmNhc2UgQy5XRDph
+LnI9Qy5YagpicmVhawpjYXNlIEMuWGo6YS5yPUMuV0QKYnJlYWsKY2FzZSBDLmRjOnRocm93IEguYihQ
+LlBWKCJGaWxlICIrSC5FaihhLmMpKyIgc2hvdWxkIG5vdCBoYXZlIGluZGV0ZXJtaW5hdGUgbWlncmF0
+aW9uIHN0YXR1cyIpKX19LAp4bjpmdW5jdGlvbihhLGIpe0wudGEoYSxiLmdkNigpKQppZihiLmM9PSQu
+RDkoKS5pbm5lclRleHQpTC50YSgkLmMwKCksYi5nZDYoKSl9LAp0YTpmdW5jdGlvbihhLGIpe3ZhciBz
+LHI9ImNoZWNrX2JveCIscT0idGl0bGUiLHA9Im9wdGVkLW91dCIsbz0ibWlncmF0aW5nIgpzd2l0Y2go
+Yil7Y2FzZSBDLmN3OmEuaW5uZXJUZXh0PXIKSi5kUihhKS5pKDAsImFscmVhZHktbWlncmF0ZWQiKQph
+LnNldEF0dHJpYnV0ZShxLCJBbHJlYWR5IG1pZ3JhdGVkIikKYnJlYWsKY2FzZSBDLldEOmEuaW5uZXJU
+ZXh0PXIKcz1KLllFKGEpCnMuZ24oYSkuTCgwLHApCnMuZ24oYSkuaSgwLG8pCmEuc2V0QXR0cmlidXRl
+KHEsIk1pZ3JhdGluZyB0byBudWxsIHNhZmV0eSIpCmJyZWFrCmNhc2UgQy5YajphLmlubmVyVGV4dD0i
+Y2hlY2tfYm94X291dGxpbmVfYmxhbmsiCnM9Si5ZRShhKQpzLmduKGEpLkwoMCxvKQpzLmduKGEpLmko
+MCxwKQphLnNldEF0dHJpYnV0ZShxLCJPcHRpbmcgb3V0IG9mIG51bGwgc2FmZXR5IikKYnJlYWsKZGVm
+YXVsdDphLmlubmVyVGV4dD0iaW5kZXRlcm1pbmF0ZV9jaGVja19ib3giCnM9Si5ZRShhKQpzLmduKGEp
+LkwoMCxvKQpzLmduKGEpLmkoMCxwKQphLnNldEF0dHJpYnV0ZShxLCJNaXhlZCBzdGF0dXNlcyBvZiAn
+bWlncmF0aW5nJyBhbmQgJ29wdGluZyBvdXQnIikKYnJlYWt9fSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIg
+cyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQpKLmRyKCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgo
+dC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQpzPW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFs
+bCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx0LlIpCnMuSyhzLG5ldyBMLlZTKHIpKQpKLmRSKCQuYk4o
+KSkuaSgwLCJ2aXNpYmxlIil9LApBUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1iLmIKaWYocSE9bnVs
+bCl7cz10LmcKcj1zLmEocy5hKGEucGFyZW50Tm9kZSkucGFyZW50Tm9kZSkKTC54bihyLnF1ZXJ5U2Vs
+ZWN0b3IoIjpzY29wZSA+IC5zdGF0dXMtaWNvbiIpLHEpCkwuQVIocixxKX19LApCRTpmdW5jdGlvbihh
+LGIsYyl7dmFyIHM9Ii5yZWdpb25zIixyPWRvY3VtZW50LHE9ci5xdWVyeVNlbGVjdG9yKHMpLHA9ci5x
+dWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocSxiLmEsJC5LRygpKQpKLnRIKHAsYi5iLCQuS0coKSkK
+TC5MSChhLGIuZCxjKQppZihiLmMubGVuZ3RoPDJlNSlMLnZVKCkKTC55WCgiLmNvZGUiLCEwKQpMLnlY
+KHMsITApfSwKdFg6ZnVuY3Rpb24oYSxiLGEwKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
+LGU9Im1hdGVyaWFsLWljb25zIixkPWRvY3VtZW50LGM9ZC5jcmVhdGVFbGVtZW50KCJ1bCIpCmEuYXBw
+ZW5kQ2hpbGQoYykKZm9yKHM9Yi5sZW5ndGgscj10LlgscT10LloscD0wO3A8Yi5sZW5ndGg7Yi5sZW5n
+dGg9PT1zfHwoMCxILmxrKShiKSwrK3Ape289YltwXQpuPWQuY3JlYXRlRWxlbWVudCgibGkiKQpjLmFw
+cGVuZENoaWxkKG4pCmlmKG8gaW5zdGFuY2VvZiBMLnZ0KXtKLmRSKG4pLmkoMCwiZGlyIikKbi5zZXRB
+dHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhuKSkuUCgibmFtZSIpLG8uYykKbT1kLmNy
+ZWF0ZUVsZW1lbnQoInNwYW4iKQpuLmFwcGVuZENoaWxkKG0pCmw9Si5ZRShtKQpsLmduKG0pLmkoMCwi
+YXJyb3ciKQpsLnNoZihtLCImI3gyNUJDOyIpCms9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihr
+KS5pKDAsZSkKay5pbm5lclRleHQ9ImZvbGRlcl9vcGVuIgpuLmFwcGVuZENoaWxkKGspCm4uYXBwZW5k
+Q2hpbGQoZC5jcmVhdGVUZXh0Tm9kZShvLmEpKQpMLnRYKG4sby5kLCExKQpMLmt6KG0pfWVsc2UgaWYo
+byBpbnN0YW5jZW9mIEwuY0Qpe2w9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihsKS5pKDAsZSkK
+bC5pbm5lclRleHQ9Imluc2VydF9kcml2ZV9maWxlIgpuLmFwcGVuZENoaWxkKGwpCmo9ZC5jcmVhdGVF
+bGVtZW50KCJhIikKbi5hcHBlbmRDaGlsZChqKQpsPUouWUUoaikKbC5nbihqKS5pKDAsIm5hdi1saW5r
+IikKai5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhqKSkuUCgibmFtZSIpLG8u
+YykKai5zZXRBdHRyaWJ1dGUoImhyZWYiLEwuUTQoby5kLFAuRmwocixyKSkpCmouYXBwZW5kQ2hpbGQo
+ZC5jcmVhdGVUZXh0Tm9kZShvLmEpKQpsPWwuZ1ZsKGopCmk9bC4kdGkKaD1pLkMoIn4oMSk/IikuYShu
+ZXcgTC5URCgpKQpxLmEobnVsbCkKVy5KRShsLmEsbC5iLGgsITEsaS5jKQpnPW8uZQppZih0eXBlb2Yg
+ZyE9PSJudW1iZXIiKXJldHVybiBnLm9zKCkKaWYoZz4wKXtmPWQuY3JlYXRlRWxlbWVudCgic3BhbiIp
+Cm4uYXBwZW5kQ2hpbGQoZikKSi5kUihmKS5pKDAsImVkaXQtY291bnQiKQpsPSIiK2crIiAiCmlmKGc9
+PT0xKWk9InByb3Bvc2VkIGVkaXQiCmVsc2UgaT0icHJvcG9zZWQgZWRpdHMiCmYuc2V0QXR0cmlidXRl
+KCJ0aXRsZSIsbCtpKQpmLmFwcGVuZENoaWxkKGQuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGcpKSl9fX19
+LAp1ejpmdW5jdGlvbihhLGIsYyl7dmFyIHM9ZG9jdW1lbnQscj1zLmNyZWF0ZUVsZW1lbnQoImJ1dHRv
+biIpLHE9dC5rLHA9cS5DKCJ+KDEpPyIpLmEobmV3IEwubTIoYSxjKSkKdC5aLmEobnVsbCkKVy5KRShy
+LCJjbGljayIscCwhMSxxLmMpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZShNLk9YKGEuYSkp
+KQpiLmFwcGVuZENoaWxkKHIpfSwKRno6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGss
+aixpLGg9YS5hCmlmKGg9PW51bGwpcmV0dXJuCnM9ZG9jdW1lbnQKcj1zLmNyZWF0ZUVsZW1lbnQoInAi
+KQpxPWIuYXBwZW5kQ2hpbGQocikKcj1zLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwPXQuaQpKLk11KHIs
+SC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxwKSkKci5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2Rl
+KCJBY3Rpb25zIikpCnEuYXBwZW5kQ2hpbGQocikKcS5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2Rl
+KCI6IikpCm89cy5jcmVhdGVFbGVtZW50KCJwIikKYi5hcHBlbmRDaGlsZChvKQpmb3Iocj1oLmxlbmd0
+aCxuPXQuUSxtPTA7bTxoLmxlbmd0aDtoLmxlbmd0aD09PXJ8fCgwLEgubGspKGgpLCsrbSl7bD1oW21d
+Cms9cy5jcmVhdGVFbGVtZW50KCJhIikKby5hcHBlbmRDaGlsZChrKQprLmFwcGVuZENoaWxkKHMuY3Jl
+YXRlVGV4dE5vZGUobC5hKSkKay5zZXRBdHRyaWJ1dGUoImhyZWYiLGwuYikKaj1uLmEoSC5WTShbImFk
+ZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHkiLCJidXR0b24iXSxwKSkKaT1KLmRSKGspCmkuVjEoMCkK
+aS5GVigwLGopfX0sCkNDOmZ1bmN0aW9uKGE0LGE1LGE2KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZyxmLGUsZCxjLGIsYSxhMCxhMSxhMixhMwpmb3Iocz1hNC5mLHI9cy5sZW5ndGgscT10LmkscD10
+LlEsbz0wO288cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK28pe249c1tvXQptPWRv
+Y3VtZW50Cmw9bS5jcmVhdGVFbGVtZW50KCJwIikKaz1wLmEoSC5WTShbInRyYWNlIl0scSkpCmo9Si5k
+UihsKQpqLlYxKDApCmouRlYoMCxrKQppPWE1LmFwcGVuZENoaWxkKGwpCmw9bS5jcmVhdGVFbGVtZW50
+KCJzcGFuIikKaz1wLmEoSC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxxKSkKaj1KLmRSKGwpCmouVjEo
+MCkKai5GVigwLGspCmwuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZShuLmEpKQppLmFwcGVuZENo
+aWxkKGwpCmkuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpsPW0uY3JlYXRlRWxlbWVu
+dCgidWwiKQprPXAuYShILlZNKFsidHJhY2UiXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkKai5GVigwLGsp
+Cmg9aS5hcHBlbmRDaGlsZChsKQpmb3IobD1uLmIsaz1sLmxlbmd0aCxnPTA7ZzxsLmxlbmd0aDtsLmxl
+bmd0aD09PWt8fCgwLEgubGspKGwpLCsrZyl7Zj1sW2ddCmU9bS5jcmVhdGVFbGVtZW50KCJsaSIpCmgu
+YXBwZW5kQ2hpbGQoZSkKZD1tLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpjPXAuYShILlZNKFsiZnVuY3Rp
+b24iXSxxKSkKaj1KLmRSKGQpCmouVjEoMCkKai5GVigwLGMpCmM9Zi5iCkwua0QoZCxjPT1udWxsPyJ1
+bmtub3duIjpjKQplLmFwcGVuZENoaWxkKGQpCmI9Zi5jCmlmKGIhPW51bGwpe2UuYXBwZW5kQ2hpbGQo
+bS5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKYT1iLmIKYTA9bS5jcmVhdGVFbGVtZW50KCJhIikKYTAuYXBw
+ZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZShILkVqKGIuYykrIjoiK0guRWooYSkpKQphMC5zZXRBdHRy
+aWJ1dGUoImhyZWYiLGIuYSkKYTAuY2xhc3NMaXN0LmFkZCgibmF2LWxpbmsiKQplLmFwcGVuZENoaWxk
+KGEwKQplLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIikiKSl9ZS5hcHBlbmRDaGlsZChtLmNy
+ZWF0ZVRleHROb2RlKCI6ICIpKQpkPWYuYQpMLmtEKGUsZD09bnVsbD8idW5rbm93biI6ZCkKZD1mLmQK
+aWYoZC5sZW5ndGghPT0wKXtjPW0uY3JlYXRlRWxlbWVudCgicCIpCmExPXAuYShILlZNKFsiZHJhd2Vy
+IiwiYmVmb3JlLWFwcGx5Il0scSkpCmo9Si5kUihjKQpqLlYxKDApCmouRlYoMCxhMSkKYTI9ZS5hcHBl
+bmRDaGlsZChjKQpmb3IoYz1kLmxlbmd0aCxhMz0wO2EzPGQubGVuZ3RoO2QubGVuZ3RoPT09Y3x8KDAs
+SC5saykoZCksKythMylMLnV6KGRbYTNdLGEyLGIpfX19fSwKVXM6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+VTYoYSkudGcoYSwiPyIpP0MueEIuTmooYSwwLEMueEIuT1koYSwiPyIpKTphfSwKa0Q6ZnVuY3Rpb24o
+YSxiKXt2YXIgcyxyLHE9SC5WTShiLnNwbGl0KCIuIiksdC5zKSxwPUMuTm0uZ3RIKHEpLG89ZG9jdW1l
+bnQKYS5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKHApKQpmb3IocD1ILnFDKHEsMSxudWxsLHQu
+TikscD1uZXcgSC5hNyhwLHAuZ0EocCkscC4kdGkuQygiYTc8YUwuRT4iKSkscz1KLllFKGEpO3AuRigp
+Oyl7cj1wLmQKcy5ueihhLCJiZWZvcmVlbmQiLCImIzgyMDM7LiIsbnVsbCxudWxsKQphLmFwcGVuZENo
+aWxkKG8uY3JlYXRlVGV4dE5vZGUocikpfX0sCm1IOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAKZm9y
+KHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3Ipe3E9
+YVtyXQppZihxIGluc3RhbmNlb2YgTC52dCl7cD1MLm1IKHEuZCxiKQppZihwIT1udWxsKXJldHVybiBw
+fWVsc2UgaWYocS5jPT1iKXJldHVybiBxfXJldHVybiBudWxsfSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6
+ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24g
+b1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKSGk6ZnVuY3Rpb24g
+SGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30sClBZOmZ1bmN0aW9uIFBZKCl7fSwKdTg6ZnVuY3Rpb24g
+dTgoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9
+YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCm5UOmZ1bmN0aW9uIG5UKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKdWU6ZnVuY3Rpb24gdWUoKXt9LAplWDpmdW5j
+dGlvbiBlWCgpe30sCkVFOmZ1bmN0aW9uIEVFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhh
+KXt0aGlzLmE9YX0sClREOmZ1bmN0aW9uIFREKCl7fSwKbTI6ZnVuY3Rpb24gbTIoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sClhBOmZ1bmN0aW9uIFhBKCl7fSwKWnM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUou
+VTYoYSkKaWYoTC5wMihILmgocS5xKGEsInR5cGUiKSkpPT09Qy5ZMil7cz1ILmgocS5xKGEsIm5hbWUi
+KSkKcj1ILmgocS5xKGEsInBhdGgiKSkKcT1xLnEoYSwic3VidHJlZSIpCnE9bmV3IEwudnQocT09bnVs
+bD9udWxsOkwubUsocSkscyxyKQpxLkxWKCkKcmV0dXJuIHF9ZWxzZXtzPUguaChxLnEoYSwibmFtZSIp
+KQpyPUguaChxLnEoYSwicGF0aCIpKQpyZXR1cm4gbmV3IEwuY0QoSC5oKHEucShhLCJocmVmIikpLEgu
+dVAocS5xKGEsImVkaXRDb3VudCIpKSxILnk4KHEucShhLCJ3YXNFeHBsaWNpdGx5T3B0ZWRPdXQiKSks
+TC52QihILnVQKHEucShhLCJtaWdyYXRpb25TdGF0dXMiKSkpLHMscil9fSwKbUs6ZnVuY3Rpb24oYSl7
+dmFyIHMscj1ILlZNKFtdLHQuY1EpCmZvcihzPUouSVQodC5VLmEoYSkpO3MuRigpOylyLnB1c2goTC5a
+cyhzLmdsKCkpKQpyZXR1cm4gcn0sClZEOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1ILlZNKFtdLHQuRykK
+Zm9yKHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3Ip
+cS5wdXNoKGFbcl0uTHQoKSkKcmV0dXJuIHF9LAp2QjpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVy
+biBudWxsCmlmKGE+Pj4wIT09YXx8YT49NClyZXR1cm4gSC5PSChDLmwwLGEpCnJldHVybiBDLmwwW2Fd
+fSwKcDI6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5IjpyZXR1cm4gQy5ZMgpjYXNl
+ImZpbGUiOnJldHVybiBDLnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYoIlVucmVjb2duaXplZCBuYXZp
+Z2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK0guRWooYSkpKX19LAp2dDpmdW5jdGlvbiB2dChhLGIsYyl7
+dmFyIF89dGhpcwpfLmQ9YQpfLmE9YgpfLmI9bnVsbApfLmM9Y30sCmNEOmZ1bmN0aW9uIGNEKGEsYixj
+LGQsZSxmKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kCl8uYT1lCl8uYj1udWxsCl8u
+Yz1mfSwKRDg6ZnVuY3Rpb24gRDgoKXt9LApPOTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCkdiOmZ1
+bmN0aW9uIEdiKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJVjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2
+YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFy
+IHMscixxLHAsbyxuPWIueFooYSkKYi5oSyhhKQppZihuIT1udWxsKWE9Si5LVihhLG4ubGVuZ3RoKQpz
+PXQucwpyPUguVk0oW10scykKcT1ILlZNKFtdLHMpCnM9YS5sZW5ndGgKaWYocyE9PTAmJmIucjQoQy54
+Qi5XKGEsMCkpKXtpZigwPj1zKXJldHVybiBILk9IKGEsMCkKQy5ObS5pKHEsYVswXSkKcD0xfWVsc2V7
+Qy5ObS5pKHEsIiIpCnA9MH1mb3Iobz1wO288czsrK28paWYoYi5yNChDLnhCLlcoYSxvKSkpe0MuTm0u
+aShyLEMueEIuTmooYSxwLG8pKQpDLk5tLmkocSxhW29dKQpwPW8rMX1pZihwPHMpe0MuTm0uaShyLEMu
+eEIueW4oYSxwKSkKQy5ObS5pKHEsIiIpfXJldHVybiBuZXcgWC5XRChiLG4scixxKX0sCldEOmZ1bmN0
+aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApJNzpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89
+ewpSaDpmdW5jdGlvbigpe3ZhciBzLHI9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJu
+ICQuRWIoKQpzPVAudW8oKQppZighQy54Qi5UYyhzLmdJaShzKSwiLyIpKXJldHVybiAkLkViKCkKaWYo
+UC5LTChyLCJhL2IiLHIscixyLHIscikudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAk
+LmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9
+YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMK
+Xy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKYWI6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPW51
+bGwKdHJ5e289UC51bygpfWNhdGNoKHMpe2lmKHQuZzguYihILlJ1KHMpKSl7cj0kLkZmCmlmKHIhPW51
+bGwpcmV0dXJuIHIKdGhyb3cgc31lbHNlIHRocm93IHN9aWYoSi5STShvLCQuSTYpKXtyPSQuRmYKci50
+b1N0cmluZwpyZXR1cm4gcn0kLkk2PW8KaWYoJC5IaygpPT0kLkViKCkpcj0kLkZmPW8uWkkoIi4iKS53
+KDApCmVsc2V7cT1vLnQ0KCkKcD1xLmxlbmd0aC0xCnI9JC5GZj1wPT09MD9xOkMueEIuTmoocSwwLHAp
+fXIudG9TdHJpbmcKcmV0dXJuIHJ9fQp2YXIgdz1bQyxILEosUCxXLE0sVSxCLFQsTCxYLE8sRSxGLERd
+Cmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILkZLLnBy
+b3RvdHlwZT17fQpKLkd2LnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwK
+Z2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFu
+Y2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dC5vLmEoYikKdGhyb3cg
+SC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/NTE5MDE4
+OjIxODE1OX0sCiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBu
+dWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdC5vLmEoYikpfSwKJGljODoxfQpK
+Lk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90b3R5cGU9e30K
+Si5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPWFbJC53KCldCmlmKHM9PW51bGwpcmV0
+dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILkVqKEouaihzKSl9
+LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYo
+YSxILnQ2KGEpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKaTpmdW5jdGlvbihhLGIpe0gu
+dDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFkZCIpKQphLnB1c2goYil9
+LApXNDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoInJlbW92
+ZUF0IikpCnM9YS5sZW5ndGgKaWYoYj49cyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQpyZXR1cm4gYS5z
+cGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCkgudDYoYSkuQygiY1g8MT4i
+KS5hKGMpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImluc2VydEFsbCIpKQpQLndBKGIsMCxh
+Lmxlbmd0aCwiaW5kZXgiKQppZighdC5iLmIoYykpYz1KLlJYKGMpCnM9Si5IbShjKQphLmxlbmd0aD1h
+Lmxlbmd0aCtzCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0s
+CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC50NihhKS5DKCJjWDwxPiIpLmEoYikKaWYoISFhLmZpeGVk
+JGxlbmd0aClILnYoUC5MNCgiYWRkQWxsIikpCmZvcihzPUouSVQoYik7cy5GKCk7KWEucHVzaChzLmds
+KCkpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgudDYoYSkKcmV0dXJuIG5ldyBILmxKKGEscy5L
+cShjKS5DKCIxKDIpIikuYShiKSxzLkMoIkA8MT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKazpmdW5j
+dGlvbihhLGIpe3ZhciBzLHI9UC5POChhLmxlbmd0aCwiIiwhMSx0Lk4pCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpdGhpcy5ZNShyLHMsSC5FaihhW3NdKSkKcmV0dXJuIHIuam9pbihiKX0sCmVSOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEgucUMoYSxiLG51bGwsSC50NihhKS5jKX0sCk4wOmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciBzLHIscQpkLmEoYikKSC50NihhKS5LcShkKS5DKCIxKDEsMikiKS5hKGMpCnM9YS5sZW5ndGgK
+Zm9yKHI9YixxPTA7cTxzOysrcSl7cj1jLiQyKHIsYVtxXSkKaWYoYS5sZW5ndGghPT1zKXRocm93IEgu
+YihQLmE0KGEpKX1yZXR1cm4gcn0sCkh0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwpILnQ2KGEp
+LkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZvcihyPW51bGwscT0hMSxwPTA7cDxzOysrcCl7bz1h
+W3BdCmlmKEgub1QoYi4kMShvKSkpe2lmKHEpdGhyb3cgSC5iKEguQW0oKSkKcj1vCnE9ITB9aWYocyE9
+PWEubGVuZ3RoKXRocm93IEguYihQLmE0KGEpKX1pZihxKXJldHVybiByCnRocm93IEguYihILldwKCkp
+fSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1
+cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEgu
+YihILldwKCkpfSwKZ3JaOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCmlmKHM+MClyZXR1cm4gYVtz
+LTFdCnRocm93IEguYihILldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxv
+CkgudDYoYSkuQygiY1g8MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYoUC5MNCgic2V0
+UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnM9Yy1iCmlmKHM9PT0wKXJldHVybgpQLmsxKGUsInNr
+aXBDb3VudCIpCmlmKHQuai5iKGQpKXtyPWQKcT1lfWVsc2V7cj1KLkE1KGQsZSkudHQoMCwhMSkKcT0w
+fXA9Si5VNihyKQppZihxK3M+cC5nQShyKSl0aHJvdyBILmIoSC5hcigpKQppZihxPGIpZm9yKG89cy0x
+O28+PTA7LS1vKWFbYitvXT1wLnEocixxK28pCmVsc2UgZm9yKG89MDtvPHM7KytvKWFbYitvXT1wLnEo
+cixxK28pfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZy
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnQ2KGEpLkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZv
+cihyPTA7cjxzOysrcil7aWYoSC5vVChiLiQxKGFbcl0pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXMp
+dGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgcwpmb3Iocz0w
+O3M8YS5sZW5ndGg7KytzKWlmKEouUk0oYVtzXSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsMDpmdW5j
+dGlvbihhKXtyZXR1cm4gYS5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0
+aCE9PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LAp0dDpmdW5jdGlvbihh
+LGIpe3ZhciBzPUguVk0oYS5zbGljZSgwKSxILnQ2KGEpKQpyZXR1cm4gc30sCmJyOmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLnR0KGEsITApfSwKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBKLm0xKGEsYS5s
+ZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9uKGEsYil7aWYoISFhLmZp
+eGVkJGxlbmd0aClILnYoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiww
+LG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC51UChi
+KQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTU6
+ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYoUC5M
+NCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQph
+W2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpKLlBvLnByb3RvdHlwZT17fQpKLm0xLnByb3Rv
+dHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyPXRo
+aXMscT1yLmEscD1xLmxlbmd0aAppZihyLmIhPT1wKXRocm93IEguYihILmxrKHEpKQpzPXIuYwppZihz
+Pj1wKXtyLnNNKG51bGwpCnJldHVybiExfXIuc00ocVtzXSk7KytyLmMKcmV0dXJuITB9LApzTTpmdW5j
+dGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpKLnFJLnByb3RvdHlw
+ZT17CnpROmZ1bmN0aW9uKGEpe2lmKGE+MCl7aWYoYSE9PTEvMClyZXR1cm4gTWF0aC5yb3VuZChhKX1l
+bHNlIGlmKGE+LTEvMClyZXR1cm4gMC1NYXRoLnJvdW5kKDAtYSkKdGhyb3cgSC5iKFAuTDQoIiIrYSsi
+LnJvdW5kKCkiKSl9LAp3OmZ1bmN0aW9uKGEpe2lmKGE9PT0wJiYxL2E8MClyZXR1cm4iLTAuMCIKZWxz
+ZSByZXR1cm4iIithfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89YXwwCmlmKGE9PT1vKXJl
+dHVybiBvJjUzNjg3MDkxMQpzPU1hdGguYWJzKGEpCnI9TWF0aC5sb2cocykvMC42OTMxNDcxODA1NTk5
+NDUzfDAKcT1NYXRoLnBvdygyLHIpCnA9czwxP3MvcTpxL3MKcmV0dXJuKChwKjkwMDcxOTkyNTQ3NDA5
+OTJ8MCkrKHAqMzU0MjI0MzE4MTE3NjUyMXwwKSkqNTk5MTk3K3IqMTI1OSY1MzY4NzA5MTF9LAp6WTpm
+dW5jdGlvbihhLGIpe3ZhciBzPWElYgppZihzPT09MClyZXR1cm4gMAppZihzPjApcmV0dXJuIHMKaWYo
+YjwwKXJldHVybiBzLWIKZWxzZSByZXR1cm4gcytifSwKQlU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4oYXww
+KT09PWE/YS9ifDA6dGhpcy5ESihhLGIpfSwKREo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1hL2IKaWYocz49
+LTIxNDc0ODM2NDgmJnM8PTIxNDc0ODM2NDcpcmV0dXJuIHN8MAppZihzPjApe2lmKHMhPT0xLzApcmV0
+dXJuIE1hdGguZmxvb3Iocyl9ZWxzZSBpZihzPi0xLzApcmV0dXJuIE1hdGguY2VpbChzKQp0aHJvdyBI
+LmIoUC5MNCgiUmVzdWx0IG9mIHRydW5jYXRpbmcgZGl2aXNpb24gaXMgIitILkVqKHMpKyI6ICIrSC5F
+aihhKSsiIH4vICIrYikpfSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPjApcz10aGlzLnAzKGEs
+YikKZWxzZXtzPWI+MzE/MzE6YgpzPWE+PnM+Pj4wfXJldHVybiBzfSwKYmY6ZnVuY3Rpb24oYSxiKXtp
+ZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihh
+LGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEsCiRpWlo6MX0KSi5iVS5wcm90b3R5cGU9eyRp
+SWY6MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90b3R5cGU9ewpPMjpmdW5jdGlvbihhLGIpe2lm
+KGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQppZihiPj1hLmxlbmd0aClILnYoSC5IWShhLGIpKQpyZXR1
+cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEgu
+YihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVy
+biBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRo
+cm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJuIGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFy
+IHM9Yi5sZW5ndGgscj1hLmxlbmd0aAppZihzPnIpcmV0dXJuITEKcmV0dXJuIGI9PT10aGlzLnluKGEs
+ci1zKX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPVAuakIoYixjLGEubGVuZ3RoKSxyPWEuc3Vi
+c3RyaW5nKDAsYikscT1hLnN1YnN0cmluZyhzKQpyZXR1cm4gcitkK3F9LApRaTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxs
+LG51bGwpKQpzPWMrYi5sZW5ndGgKaWYocz5hLmxlbmd0aClyZXR1cm4hMQpyZXR1cm4gYj09PWEuc3Vi
+c3RyaW5nKGMscyl9LApuQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1
+bmN0aW9uKGEsYixjKXtpZihjPT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIs
+bnVsbCkpCmlmKGI+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEgu
+YihQLk83KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKeW46ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gdGhpcy5OaihhLGIsbnVsbCl9LApoYzpmdW5jdGlvbihhKXtyZXR1cm4gYS50b0xvd2VyQ2Fz
+ZSgpfSwKYlM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS50cmltKCksbz1wLmxlbmd0aAppZihvPT09
+MClyZXR1cm4gcAppZih0aGlzLlcocCwwKT09PTEzMyl7cz1KLm1tKHAsMSkKaWYocz09PW8pcmV0dXJu
+IiJ9ZWxzZSBzPTAKcj1vLTEKcT10aGlzLk8yKHAscik9PT0xMzM/Si5jMShwLHIpOm8KaWYocz09PTAm
+JnE9PT1vKXJldHVybiBwCnJldHVybiBwLnN1YnN0cmluZyhzLHEpfSwKVDpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJldHVybiBhCmlmKGIh
+PT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHM9YSxyPSIiOyEwOyl7aWYoKGImMSk9PT0xKXI9cyty
+CmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKcys9c31yZXR1cm4gcn0sClhVOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcwppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVs
+bCkpCnM9YS5pbmRleE9mKGIsYykKcmV0dXJuIHN9LApPWTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+LlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKGM9PW51bGwpYz1hLmxlbmd0
+aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxu
+dWxsKSkKcz1iLmxlbmd0aApyPWEubGVuZ3RoCmlmKGMrcz5yKWM9ci1zCnJldHVybiBhLmxhc3RJbmRl
+eE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixudWxsKX0sCklzOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcz1hLmxlbmd0aAppZihjPnMpdGhyb3cgSC5iKFAuVEUoYywwLHMsbnVs
+bCxudWxsKSkKcmV0dXJuIEguU1EoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5J
+cyhhLGIsMCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cQpmb3Iocz1hLmxlbmd0aCxyPTAscT0wO3E8czsrK3Epe3I9cithLmNoYXJDb2RlQXQocSkmNTM2ODcw
+OTExCnI9cisoKHImNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyXj1yPj42fXI9cisoKHImNjcxMDg4NjMp
+PDwzKSY1MzY4NzA5MTEKcl49cj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUpJjUzNjg3MDkxMX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlm
+KGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sCiRpdlg6MSwK
+JGlxVToxfQpILkJSLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUguTGgodGhpcykKcmV0
+dXJuIG5ldyBILkU3KEouSVQodGhpcy5nT04oKSkscy5DKCJAPDE+IikuS3Eocy5RWzFdKS5DKCJFNzwx
+LDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nT04oKSl9LApnbDA6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEoudVUodGhpcy5nT04oKSl9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIEouRjco
+dGhpcy5nT04oKSl9LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIEguR0oo
+Si5BNSh0aGlzLmdPTigpLGIpLHMuYyxzLlFbMV0pfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiBILkxo
+KHRoaXMpLlFbMV0uYShKLkdBKHRoaXMuZ09OKCksYikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5q
+KHRoaXMuZ09OKCkpfX0KSC5FNy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5G
+KCl9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5RWzFdLmEodGhpcy5hLmdsKCkpfSwKJGlB
+bjoxfQpILlp5LnByb3RvdHlwZT17CmdPTjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9fQpILm9sLnBy
+b3RvdHlwZT17JGliUToxfQpILlVxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
+cy4kdGkuUVsxXS5hKEoueDkodGhpcy5hLEgudVAoYikpKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIg
+cz10aGlzLiR0aQpKLnU5KHRoaXMuYSxiLHMuYy5hKHMuUVsxXS5hKGMpKSl9LAokaWJROjEsCiRpek06
+MX0KSC5qVi5wcm90b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5qVih0aGlzLmEs
+dGhpcy4kdGkuQygiQDwxPiIpLktxKGIpLkMoImpWPDEsMj4iKSl9LApnT046ZnVuY3Rpb24oKXtyZXR1
+cm4gdGhpcy5hfX0KSC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVy
+biBzIT1udWxsPyJMYXRlSW5pdGlhbGl6YXRpb25FcnJvcjogIitzOiJMYXRlSW5pdGlhbGl6YXRpb25F
+cnJvciJ9fQpILnIzLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9IlJlYWNoYWJpbGl0eUVy
+cm9yOiAiK3RoaXMuYQpyZXR1cm4gc319CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIuTzIodGhpcy5hLEgu
+dVAoYikpfX0KSC5HTS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJOdWxsIGlzIG5vdCBh
+IHZhbGlkIHZhbHVlIGZvciB0aGUgcGFyYW1ldGVyICciK3RoaXMuYSsiJyBvZiB0eXBlICciK0guS3go
+dGhpcy4kdGkuYykudygwKSsiJyJ9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17Cmdt
+OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKcmV0dXJuIG5ldyBILmE3KHMscy5nQShzKSxILkxoKHMpLkMo
+ImE3PGFMLkU+IikpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCms6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscD10aGlzLG89cC5nQShwKQppZihiLmxlbmd0aCE9PTApe2lm
+KG89PT0wKXJldHVybiIiCnM9SC5FaihwLkUoMCwwKSkKaWYobyE9PXAuZ0EocCkpdGhyb3cgSC5iKFAu
+YTQocCkpCmZvcihyPXMscT0xO3E8bzsrK3Epe3I9citiK0guRWoocC5FKDAscSkpCmlmKG8hPT1wLmdB
+KHApKXRocm93IEguYihQLmE0KHApKX1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1lbHNle2Zv
+cihxPTAscj0iIjtxPG87KytxKXtyKz1ILkVqKHAuRSgwLHEpKQppZihvIT09cC5nQShwKSl0aHJvdyBI
+LmIoUC5hNChwKSl9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9fSwKZXY6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHMuS3EoYykuQygi
+MShhTC5FKSIpLmEoYikscy5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmVSOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEgucUModGhpcyxiLG51bGwsSC5MaCh0aGlzKS5DKCJhTC5FIikpfSwKdHQ6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5ZMSh0aGlzLCEwLEguTGgodGhpcykuQygiYUwuRSIpKX0sCmJy
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnR0KGEsITApfX0KSC5uSC5wcm90b3R5cGU9ewpIZDpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyPXRoaXMuYgpQLmsxKHIsInN0YXJ0IikKcz10aGlzLmMKaWYocyE9
+bnVsbCl7UC5rMShzLCJlbmQiKQppZihyPnMpdGhyb3cgSC5iKFAuVEUociwwLHMsInN0YXJ0IixudWxs
+KSl9fSwKZ1VEOmZ1bmN0aW9uKCl7dmFyIHM9Si5IbSh0aGlzLmEpLHI9dGhpcy5jCmlmKHI9PW51bGx8
+fHI+cylyZXR1cm4gcwpyZXR1cm4gcn0sCmdBczpmdW5jdGlvbigpe3ZhciBzPUouSG0odGhpcy5hKSxy
+PXRoaXMuYgppZihyPnMpcmV0dXJuIHMKcmV0dXJuIHJ9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPUou
+SG0odGhpcy5hKSxxPXRoaXMuYgppZihxPj1yKXJldHVybiAwCnM9dGhpcy5jCmlmKHM9PW51bGx8fHM+
+PXIpcmV0dXJuIHItcQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcmV0dXJuIHMt
+cX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLHI9cy5nQXMoKStiCmlmKGI8MHx8cj49cy5nVUQo
+KSl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQShzLmEscil9
+LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzClAuazEoYiwiY291bnQiKQpzPXEuYitiCnI9
+cS5jCmlmKHIhPW51bGwmJnM+PXIpcmV0dXJuIG5ldyBILk1CKHEuJHRpLkMoIk1CPDE+IikpCnJldHVy
+biBILnFDKHEuYSxzLHIscS4kdGkuYyl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPXRoaXMs
+bz1wLmIsbj1wLmEsbT1KLlU2KG4pLGw9bS5nQShuKSxrPXAuYwppZihrIT1udWxsJiZrPGwpbD1rCmlm
+KHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQpzPWwtbwppZihzPD0wKXtuPUouUWkoMCxw
+LiR0aS5jKQpyZXR1cm4gbn1yPVAuTzgocyxtLkUobixvKSwhMSxwLiR0aS5jKQpmb3IocT0xO3E8czsr
+K3Epe0MuTm0uWTUocixxLG0uRShuLG8rcSkpCmlmKG0uZ0Eobik8bCl0aHJvdyBILmIoUC5hNChwKSl9
+cmV0dXJuIHJ9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6
+ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEscD1KLlU2KHEpLG89cC5nQShxKQppZihyLmIhPT1v
+KXRocm93IEguYihQLmE0KHEpKQpzPXIuYwppZihzPj1vKXtyLnNJKG51bGwpCnJldHVybiExfXIuc0ko
+cC5FKHEscykpOysrci5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMo
+IjE/IikuYShhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz1I
+LkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHMuQygiQDwxPiIpLktx
+KHMuUVsxXSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9
+LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5hKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5iLiQxKEouR0EodGhpcy5hLGIpKX19CkgueHkucHJvdG90eXBlPXskaWJROjF9CkguTUgu
+cHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYoci5GKCkpe3Muc0kocy5j
+LiQxKHIuZ2woKSkpCnJldHVybiEwfXMuc0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuQygiMj8iKS5hKGEpfX0K
+SC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwKRTpmdW5j
+dGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90b3R5cGU9
+ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMuYix0aGlzLiR0
+aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9
+dGhpcy5hLHI9dGhpcy5iO3MuRigpOylpZihILm9UKHIuJDEocy5nbCgpKSkpcmV0dXJuITAKcmV0dXJu
+ITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguQU0ucHJvdG90eXBlPXsKZVI6
+ZnVuY3Rpb24oYSxiKXtQLk1SKGIsImNvdW50Iix0LlMpClAuazEoYiwiY291bnQiKQpyZXR1cm4gbmV3
+IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcykuQygiQU08MT4iKSl9LApnbTpmdW5jdGlvbihh
+KXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRoaXMuYixILkxoKHRoaXMpLkMoIlUxPDE+Iikp
+fX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcz1KLkhtKHRoaXMuYSktdGhpcy5i
+CmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpmdW5jdGlvbihhLGIpe1AuTVIoYiwiY291bnQi
+LHQuUykKUC5rMShiLCJjb3VudCIpCnJldHVybiBuZXcgSC5kNSh0aGlzLmEsdGhpcy5iK2IsdGhpcy4k
+dGkpfSwKJGliUToxfQpILlUxLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcyxyCmZvcihzPXRo
+aXMuYSxyPTA7cjx0aGlzLmI7KytyKXMuRigpCnRoaXMuYj0wCnJldHVybiBzLkYoKX0sCmdsOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5NQi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXty
+ZXR1cm4gQy5Hd30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biAwfSwKRTpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLlRFKGIsMCwwLCJpbmRleCIsbnVsbCkpfSwK
+ZVI6ZnVuY3Rpb24oYSxiKXtQLmsxKGIsImNvdW50IikKcmV0dXJuIHRoaXN9fQpILkZ1LnByb3RvdHlw
+ZT17CkY6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7dGhyb3cgSC5iKEguV3AoKSl9
+LAokaUFuOjF9CkgudTYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILkpCKEou
+SVQodGhpcy5hKSx0aGlzLiR0aS5DKCJKQjwxPiIpKX19CkguSkIucHJvdG90eXBlPXsKRjpmdW5jdGlv
+bigpe3ZhciBzLHIKZm9yKHM9dGhpcy5hLHI9dGhpcy4kdGkuYztzLkYoKTspaWYoci5iKHMuZ2woKSkp
+cmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5jLmEodGhpcy5h
+LmdsKCkpfSwKJGlBbjoxfQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk1OmZ1bmN0
+aW9uKGEsYixjKXtILkxoKHRoaXMpLkMoIlJlLkUiKS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
+bW9kaWZ5IGFuIHVubW9kaWZpYWJsZSBsaXN0IikpfX0KSC53Mi5wcm90b3R5cGU9e30KSC53di5wcm90
+b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5faGFzaENvZGUKaWYocyE9bnVsbClyZXR1
+cm4gcwpzPTY2NDU5NypKLmhmKHRoaXMuYSkmNTM2ODcwOTExCnRoaXMuX2hhc2hDb2RlPXMKcmV0dXJu
+IHN9LAp3OmZ1bmN0aW9uKGEpe3JldHVybidTeW1ib2woIicrSC5Faih0aGlzLmEpKyciKSd9LApETjpm
+dW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0
+aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5RQy5wcm90b3R5cGU9e30KSC5QRC5wcm90b3R5cGU9e30KSC5X
+VS5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKdzpm
+dW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxo
+KHRoaXMpCnMuYy5hKGIpCnMuUVsxXS5hKGMpCkguZGMoKQpILkJpKHUuZyl9LApnUHU6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMucTQoYSxILkxoKHRoaXMpLkMoIk4zPDEsMj4iKSl9LApxNDpmdW5jdGlvbihh
+LGIpe3ZhciBzPXRoaXMKcmV0dXJuIFAubDAoZnVuY3Rpb24oKXt2YXIgcj1hCnZhciBxPTAscD0xLG8s
+bixtLGwsawpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lmKGM9PT0xKXtvPWQKcT1wfXdo
+aWxlKHRydWUpc3dpdGNoKHEpe2Nhc2UgMDpuPXMuZ3ZjKCksbj1uLmdtKG4pLG09SC5MaChzKSxtPW0u
+QygiQDwxPiIpLktxKG0uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighbi5GKCkpe3E9MwpicmVh
+a31sPW4uZ2woKQprPXMucSgwLGwpCmsudG9TdHJpbmcKcT00CnJldHVybiBuZXcgUC5OMyhsLGssbSkK
+Y2FzZSA0OnE9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0obyl9
+fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90
+b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rp
+b24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0sCnFQOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEs
+cCxvPUguTGgodGhpcykKby5DKCJ+KDEsMikiKS5hKGIpCnM9dGhpcy5jCmZvcihyPXMubGVuZ3RoLG89
+by5RWzFdLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLG8uYSh0aGlzLnFQKHApKSl9fSwKZ3ZjOmZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBILlhSKHRoaXMsSC5MaCh0aGlzKS5DKCJYUjwxPiIpKX19CkguWFIu
+cHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hLmMKcmV0dXJuIG5ldyBKLm0xKHMs
+cy5sZW5ndGgsSC50NihzKS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
+Yy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYQpyZXR1
+cm4gc30sCmduZDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhpcwppZihvLmM9PT0xKXJldHVybiBD
+LmhVCnM9by5kCnI9cy5sZW5ndGgtby5lLmxlbmd0aC1vLmYKaWYocj09PTApcmV0dXJuIEMuaFUKcT1b
+XQpmb3IocD0wO3A8cjsrK3Ape2lmKHA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscCkKcS5wdXNoKHNb
+cF0pfXJldHVybiBKLnpDKHEpfSwKZ1ZtOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMKaWYoay5jIT09MClyZXR1cm4gQy5XTwpzPWsuZQpyPXMubGVuZ3RoCnE9ay5kCnA9cS5sZW5ndGgt
+ci1rLmYKaWYocj09PTApcmV0dXJuIEMuV08Kbz1uZXcgSC5ONSh0LmVvKQpmb3Iobj0wO248cjsrK24p
+e2lmKG4+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsbikKbT1zW25dCmw9cCtuCmlmKGw8MHx8bD49cS5s
+ZW5ndGgpcmV0dXJuIEguT0gocSxsKQpvLlk1KDAsbmV3IEgud3YobSkscVtsXSl9cmV0dXJuIG5ldyBI
+LlBEKG8sdC5nRil9LAokaXZROjF9CkguQ2oucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIg
+cwpILmgoYSkKcz10aGlzLmEKcy5iPXMuYisiJCIrSC5FaihhKQpDLk5tLmkodGhpcy5iLGEpCkMuTm0u
+aSh0aGlzLmMsYik7KytzLmF9LAokUzoxMn0KSC5mOS5wcm90b3R5cGU9ewpxUzpmdW5jdGlvbihhKXt2
+YXIgcyxyLHE9dGhpcyxwPW5ldyBSZWdFeHAocS5hKS5leGVjKGEpCmlmKHA9PW51bGwpcmV0dXJuIG51
+bGwKcz1PYmplY3QuY3JlYXRlKG51bGwpCnI9cS5iCmlmKHIhPT0tMSlzLmFyZ3VtZW50cz1wW3IrMV0K
+cj1xLmMKaWYociE9PS0xKXMuYXJndW1lbnRzRXhwcj1wW3IrMV0Kcj1xLmQKaWYociE9PS0xKXMuZXhw
+cj1wW3IrMV0Kcj1xLmUKaWYociE9PS0xKXMubWV0aG9kPXBbcisxXQpyPXEuZgppZihyIT09LTEpcy5y
+ZWNlaXZlcj1wW3IrMV0KcmV0dXJuIHN9fQpILlcwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFy
+IHM9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiAiK0guRWoodGhpcy5h
+KQpyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3MrIicgb24gbnVs
+bCJ9fQpILmF6LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLHE9Ik5vU3VjaE1l
+dGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixwPXIuYgppZihwPT1udWxsKXJldHVybiJOb1N1
+Y2hNZXRob2RFcnJvcjogIitILkVqKHIuYSkKcz1yLmMKaWYocz09bnVsbClyZXR1cm4gcStwKyInICgi
+K0guRWooci5hKSsiKSIKcmV0dXJuIHErcCsiJyBvbiAnIitzKyInICgiK0guRWooci5hKSsiKSJ9fQpI
+LnZWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmxlbmd0aD09
+PTA/IkVycm9yIjoiRXJyb3I6ICIrc319CkgudGUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4iVGhyb3cgb2YgbnVsbCAoJyIrKHRoaXMuYT09PW51bGw/Im51bGwiOiJ1bmRlZmluZWQiKSsiJyBm
+cm9tIEphdmFTY3JpcHQpIn0sCiRpUno6MX0KSC5icS5wcm90b3R5cGU9e30KSC5YTy5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5iCmlmKHIhPW51bGwpcmV0dXJuIHIKcj10aGlzLmEK
+cz1yIT09bnVsbCYmdHlwZW9mIHI9PT0ib2JqZWN0Ij9yLnN0YWNrOm51bGwKcmV0dXJuIHRoaXMuYj1z
+PT1udWxsPyIiOnN9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmNvbnN0cnVjdG9yLHI9cz09bnVsbD9udWxsOnMubmFtZQpyZXR1cm4iQ2xvc3VyZSAnIitILk5R
+KHI9PW51bGw/InVua25vd24iOnIpKyInIn0sCiRpRUg6MSwKZ0t1OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlwZT17fQpILnp4LnByb3RvdHlw
+ZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy4kc3RhdGljX25hbWUKaWYocz09bnVsbClyZXR1cm4i
+Q2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJDbG9zdXJlICciK0guTlEocykr
+IicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMKaWYoYj09bnVs
+bClyZXR1cm4hMQppZihzPT09YilyZXR1cm4hMAppZighKGIgaW5zdGFuY2VvZiBILnJUKSlyZXR1cm4h
+MQpyZXR1cm4gcy5hPT09Yi5hJiZzLmI9PT1iLmImJnMuYz09PWIuY30sCmdpTzpmdW5jdGlvbihhKXt2
+YXIgcyxyPXRoaXMuYwppZihyPT1udWxsKXM9SC5lUSh0aGlzLmEpCmVsc2Ugcz10eXBlb2YgciE9PSJv
+YmplY3QiP0ouaGYocik6SC5lUShyKQpyPUguZVEodGhpcy5iKQppZih0eXBlb2YgcyE9PSJudW1iZXIi
+KXJldHVybiBzLlkoKQpyZXR1cm4oc15yKT4+PjB9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpp
+ZihzPT1udWxsKXM9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guRWoodGhpcy5kKSsiJyBvZiAiKygi
+SW5zdGFuY2Ugb2YgJyIrSC5FaihILk0ocykpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJvcjogIit0aGlzLmF9fQpILmtZLnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHRoaXMuYSl9fQpILmtyLnByb3Rv
+dHlwZT17fQpILk41LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09PTB9LApndmM6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEgu
+aTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFyIHMscgppZih0
+eXBlb2YgYT09InN0cmluZyIpe3M9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMu
+WHUocyxhKX1lbHNle3I9dGhpcy5DWChhKQpyZXR1cm4gcn19LApDWDpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmQKaWYocz09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHMsSi5oZihhKSYw
+eDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcyxuPW51bGwK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXtzPW8uYgppZihzPT1udWxsKXJldHVybiBuCnI9by5qMihzLGIp
+CnE9cj09bnVsbD9uOnIuYgpyZXR1cm4gcX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgz
+ZmZmZmZmKT09PWIpe3A9by5jCmlmKHA9PW51bGwpcmV0dXJuIG4Kcj1vLmoyKHAsYikKcT1yPT1udWxs
+P246ci5iCnJldHVybiBxfWVsc2UgcmV0dXJuIG8uYWEoYil9LAphYTpmdW5jdGlvbihhKXt2YXIgcyxy
+LHE9dGhpcy5kCmlmKHE9PW51bGwpcmV0dXJuIG51bGwKcz10aGlzLkJ0KHEsSi5oZihhKSYweDNmZmZm
+ZmYpCnI9dGhpcy5GaChzLGEpCmlmKHI8MClyZXR1cm4gbnVsbApyZXR1cm4gc1tyXS5ifSwKWTU6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILkxoKG0pCmwuYy5hKGIpCmwuUVsx
+XS5hKGMpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1tLmIKbS5FSChzPT1udWxsP20uYj1tLnpLKCk6
+cyxiLGMpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNmZmZmZmYpPT09Yil7cj1tLmMK
+bS5FSChyPT1udWxsP20uYz1tLnpLKCk6cixiLGMpfWVsc2V7cT1tLmQKaWYocT09bnVsbClxPW0uZD1t
+LnpLKCkKcD1KLmhmKGIpJjB4M2ZmZmZmZgpvPW0uQnQocSxwKQppZihvPT1udWxsKW0uRUkocSxwLFtt
+LkhuKGIsYyldKQplbHNle249bS5GaChvLGIpCmlmKG4+PTApb1tuXS5iPWMKZWxzZSBvLnB1c2gobS5I
+bihiLGMpKX19fSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzCkguTGgocSkuQygifigxLDIp
+IikuYShiKQpzPXEuZQpyPXEucgpmb3IoO3MhPW51bGw7KXtiLiQyKHMuYSxzLmIpCmlmKHIhPT1xLnIp
+dGhyb3cgSC5iKFAuYTQocSkpCnM9cy5jfX0sCkVIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRoaXMs
+cT1ILkxoKHIpCnEuYy5hKGIpCnEuUVsxXS5hKGMpCnM9ci5qMihhLGIpCmlmKHM9PW51bGwpci5FSShh
+LGIsci5IbihiLGMpKQplbHNlIHMuYj1jfSwKa3M6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5yKzEmNjcx
+MDg4NjN9LApIbjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMscj1ILkxoKHMpLHE9bmV3IEgudmgoci5j
+LmEoYSksci5RWzFdLmEoYikpCmlmKHMuZT09bnVsbClzLmU9cy5mPXEKZWxzZXtyPXMuZgpyLnRvU3Ry
+aW5nCnEuZD1yCnMuZj1yLmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihhLGIp
+e3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3RoCmZvcihyPTA7cjxzOysrcilpZihK
+LlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8o
+dGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2RlbGV0
+ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6ZnVu
+Y3Rpb24oKXt2YXIgcz0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHI9T2JqZWN0LmNyZWF0ZShudWxsKQp0
+aGlzLkVJKHIscyxyKQp0aGlzLnJuKHIscykKcmV0dXJuIHJ9LAokaUZvOjF9CkgudmgucHJvdG90eXBl
+PXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2wwOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYT09PTB9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEs
+cj1uZXcgSC5ONihzLHMucix0aGlzLiR0aS5DKCJONjwxPiIpKQpyLmM9cy5lCnJldHVybiByfSwKdGc6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHMscj10aGlzLHE9ci5hCmlmKHIu
+YiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkKcz1yLmMKaWYocz09bnVsbCl7ci5zcVkobnVsbCkKcmV0
+dXJuITF9ZWxzZXtyLnNxWShzLmEpCnIuYz1zLmMKcmV0dXJuITB9fSwKc3FZOmZ1bmN0aW9uKGEpe3Ro
+aXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkguZEMucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjR9Ckgud04ucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzo0Nn0KSC5WWC5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0MX0KSC5WUi5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpmdW5j
+dGlvbigpe3ZhciBzPXRoaXMscj1zLmMKaWYociE9bnVsbClyZXR1cm4gcgpyPXMuYgpyZXR1cm4gcy5j
+PUgudjQocy5hLHIubXVsdGlsaW5lLCFyLmlnbm9yZUNhc2Usci51bmljb2RlLHIuZG90QWxsLCEwKX0s
+CmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9uKGEs
+Yil7dmFyIHMscj10aGlzLmdIYygpCnIubGFzdEluZGV4PWIKcz1yLmV4ZWMoYSkKaWYocz09bnVsbCly
+ZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsocyl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5
+cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYgppZihiPj1zLmxlbmd0aCly
+ZXR1cm4gSC5PSChzLGIpCnJldHVybiBzW2JdfSwKJGlPZDoxLAokaWliOjF9CkguS1cucHJvdG90eXBl
+PXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19Ckgu
+UGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3Zh
+ciBzLHIscSxwLG8sbixtPXRoaXMsbD1tLmIKaWYobD09bnVsbClyZXR1cm4hMQpzPW0uYwpyPWwubGVu
+Z3RoCmlmKHM8PXIpe3E9bS5hCnA9cS5VWihsLHMpCmlmKHAhPW51bGwpe20uZD1wCnM9cC5iCm89cy5p
+bmRleApuPW8rc1swXS5sZW5ndGgKaWYobz09PW4pe2lmKHEuYi51bmljb2RlKXtzPW0uYwpxPXMrMQpp
+ZihxPHIpe3M9Qy54Qi5PMihsLHMpCmlmKHM+PTU1Mjk2JiZzPD01NjMxOSl7cz1DLnhCLk8yKGwscSkK
+cz1zPj01NjMyMCYmczw9NTczNDN9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITEKbj0ocz9uKzE6
+bikrMX1tLmM9bgpyZXR1cm4hMH19bS5iPW0uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnBy
+b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudihQLk83KGIsbnVsbCkp
+CnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBILlNkKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBlPXsKRjpmdW5j
+dGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cS5iLG49by5sZW5ndGgsbT1xLmEsbD1tLmxlbmd0
+aAppZihwK24+bCl7cS5kPW51bGwKcmV0dXJuITF9cz1tLmluZGV4T2YobyxwKQppZihzPDApe3EuYz1s
+KzEKcS5kPW51bGwKcmV0dXJuITF9cj1zK24KcS5kPW5ldyBILnRRKHMsbykKcS5jPXI9PT1xLmM/cisx
+OnIKcmV0dXJuITB9LApnbDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZApzLnRvU3RyaW5nCnJldHVybiBz
+fSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5MWi5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpm
+dW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTU6ZnVu
 Y3Rpb24oYSxiLGMpe0guR0goYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGlj
-WDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC51UChjKQpILm9k
-KGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC54ai5wcm90b3R5
-cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19
-fQpILmRFLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3Ro
-KQpyZXR1cm4gYVtiXX19CkguWkEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5v
-ZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5kVC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEs
-Yil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlBxLnByb3RvdHlwZT17
-CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19Ckgu
-ZUUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihh
-LGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5WNi5wcm90b3R5cGU9
-ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpI
-Lm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LAokaVY2OjEsCiRpbjY6MX0KSC5SRy5wcm90b3R5
-cGU9e30KSC5WUC5wcm90b3R5cGU9e30KSC5XQi5wcm90b3R5cGU9e30KSC5aRy5wcm90b3R5cGU9e30K
-SC5KYy5wcm90b3R5cGU9ewpDOmZ1bmN0aW9uKGEpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLHRo
-aXMsYSl9LApLcTpmdW5jdGlvbihhKXtyZXR1cm4gSC52NSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfX0K
-SC5HLnByb3RvdHlwZT17fQpILmtTLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YX19CkguaU0ucHJvdG90eXBlPXt9ClAudGgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9
-dGhpcy5hLHI9cy5hCnMuYT1udWxsCnIuJDAoKX0sCiRTOjl9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscgp0aGlzLmEuYT10Lk0uYShhKQpzPXRoaXMuYgpyPXRoaXMuYwpzLmZpcnN0
-Q2hpbGQ/cy5yZW1vdmVDaGlsZChyKTpzLmFwcGVuZENoaWxkKHIpfSwKJFM6NTN9ClAuVnMucHJvdG90
-eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9ClAuRnQu
-cHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9
-ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwp
-c2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQ
-Lkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5paC5wcm90b3R5cGU9ewph
-TTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8/IikuYShiKQppZighci5i
-KXIuYS5YZihiKQplbHNle3M9ci5hCmlmKHEuQygiYjg8MT4iKS5iKGIpKXMuY1UoYikKZWxzZSBzLlgy
-KHEuYy5hKGIpKX19LAp3MDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGI9PW51bGwpYj1QLnYwKGEpCnM9
-dGhpcy5hCmlmKHRoaXMuYilzLlpMKGEsYikKZWxzZSBzLk5rKGEsYil9fQpQLldNLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDIoMCxhKX0sCiRTOjQ3fQpQLlNYLnByb3RvdHlw
-ZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLiQyKDEsbmV3IEguYnEoYSx0LmwuYShiKSkpfSwKJEM6
-IiQyIiwKJFI6MiwKJFM6Mjd9ClAuR3MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEo
-SC51UChhKSxiKX0sCiRTOjI1fQpQLkZ5LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkl0
-ZXJhdGlvbk1hcmtlcigiK3RoaXMuYisiLCAiK0guRWoodGhpcy5hKSsiKSJ9fQpQLkdWLnByb3RvdHlw
-ZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5jCmlmKHM9PW51bGwpcmV0dXJuIHRoaXMuJHRpLmMu
-YSh0aGlzLmIpCnJldHVybiBzLmdsKCl9LApGOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhp
-cwpmb3Iocz1tLiR0aS5DKCJBbjwxPiIpOyEwOyl7cj1tLmMKaWYociE9bnVsbClpZihyLkYoKSlyZXR1
-cm4hMAplbHNlIG0uc1g5KG51bGwpCnE9ZnVuY3Rpb24oYSxiLGMpe3ZhciBsLGs9Ygp3aGlsZSh0cnVl
-KXRyeXtyZXR1cm4gYShrLGwpfWNhdGNoKGope2w9agprPWN9fShtLmEsMCwxKQppZihxIGluc3RhbmNl
-b2YgUC5GeSl7cD1xLmIKaWYocD09PTIpe289bS5kCmlmKG89PW51bGx8fG8ubGVuZ3RoPT09MCl7bS5z
-RUMobnVsbCkKcmV0dXJuITF9aWYoMD49by5sZW5ndGgpcmV0dXJuIEguT0gobywtMSkKbS5hPW8ucG9w
-KCkKY29udGludWV9ZWxzZXtyPXEuYQppZihwPT09Myl0aHJvdyByCmVsc2V7bj1zLmEoSi5JVChyKSkK
-aWYobiBpbnN0YW5jZW9mIFAuR1Ype3I9bS5kCmlmKHI9PW51bGwpcj1tLmQ9W10KQy5ObS5pKHIsbS5h
-KQptLmE9bi5hCmNvbnRpbnVlfWVsc2V7bS5zWDkobikKY29udGludWV9fX19ZWxzZXttLnNFQyhxKQpy
-ZXR1cm4hMH19cmV0dXJuITF9LApzRUM6ZnVuY3Rpb24oYSl7dGhpcy5iPXRoaXMuJHRpLkMoIjE/Iiku
-YShhKX0sCnNYOTpmdW5jdGlvbihhKXt0aGlzLmM9dGhpcy4kdGkuQygiQW48MT4/IikuYShhKX0sCiRp
-QW46MX0KUC5xNC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5h
-KCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKUC5VSShhLCJlcnJvciIsdC5LKQpzPXRoaXMuYQppZihzLmEhPT0wKXRocm93IEguYihQLlBW
-KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKaWYoYj09bnVsbCliPVAudjAoYSkKcy5OayhhLGIp
-fSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsK
-YU06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuJHRpCnIuQygiMS8/IikuYShiKQpzPXRoaXMuYQpp
-ZihzLmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKcy5YZihy
-LkMoIjEvIikuYShiKSl9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMm
-MTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodC5hbC5hKHRoaXMuZCksYS5hLHQueSx0
-LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5lLHI9dC56LHE9dC5LLHA9dGhpcy4kdGkuQygi
-Mi8iKSxvPXRoaXMuYi5iCmlmKHQuYWcuYihzKSlyZXR1cm4gcC5hKG8ucnAocyxhLmEsYS5iLHIscSx0
-LmwpKQplbHNlIHJldHVybiBwLmEoby5idih0LmJJLmEocyksYS5hLHIscSkpfX0KUC52cy5wcm90b3R5
-cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHA9dGhpcy4kdGkKcC5LcShjKS5DKCIxLygy
-KSIpLmEoYSkKcz0kLlgzCmlmKHMhPT1DLk5VKXtjLkMoIkA8MC8+IikuS3EocC5jKS5DKCIxKDIpIiku
-YShhKQppZihiIT1udWxsKWI9UC5WSChiLHMpfXI9bmV3IFAudnMocyxjLkMoInZzPDA+IikpCnE9Yj09
-bnVsbD8xOjMKdGhpcy54ZihuZXcgUC5GZShyLHEsYSxiLHAuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEs
-Mj4iKSkpCnJldHVybiByfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGwsYil9
-LApRZDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj10aGlzLiR0aQpyLktxKGMpLkMoIjEvKDIpIikuYShh
-KQpzPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZlKHMsMTksYSxiLHIu
-QygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiBzfSwKeGY6ZnVuY3Rpb24oYSl7dmFy
-IHMscj10aGlzLHE9ci5hCmlmKHE8PTEpe2EuYT10LkYuYShyLmMpCnIuYz1hfWVsc2V7aWYocT09PTIp
-e3M9dC5jLmEoci5jKQpxPXMuYQppZihxPDQpe3MueGYoYSkKcmV0dXJufXIuYT1xCnIuYz1zLmN9UC5U
-ayhudWxsLG51bGwsci5iLHQuTS5hKG5ldyBQLmRhKHIsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscCxvLG4sbT10aGlzLGw9e30KbC5hPWEKaWYoYT09bnVsbClyZXR1cm4Kcz1tLmEKaWYoczw9
-MSl7cj10LkYuYShtLmMpCm0uYz1hCmlmKHIhPW51bGwpe3E9YS5hCmZvcihwPWE7cSE9bnVsbDtwPXEs
-cT1vKW89cS5hCnAuYT1yfX1lbHNle2lmKHM9PT0yKXtuPXQuYy5hKG0uYykKcz1uLmEKaWYoczw0KXtu
-LmpRKGEpCnJldHVybn1tLmE9cwptLmM9bi5jfWwuYT1tLk44KGEpClAuVGsobnVsbCxudWxsLG0uYix0
-Lk0uYShuZXcgUC5vUShsLG0pKSl9fSwKYWg6ZnVuY3Rpb24oKXt2YXIgcz10LkYuYSh0aGlzLmMpCnRo
-aXMuYz1udWxsCnJldHVybiB0aGlzLk44KHMpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHMscixxCmZvcihz
-PWEscj1udWxsO3MhPW51bGw7cj1zLHM9cSl7cT1zLmEKcy5hPXJ9cmV0dXJuIHJ9LApISDpmdW5jdGlv
-bihhKXt2YXIgcyxyPXRoaXMscT1yLiR0aQpxLkMoIjEvIikuYShhKQppZihxLkMoImI4PDE+IikuYihh
-KSlpZihxLmIoYSkpUC5BOShhLHIpCmVsc2UgUC5rMyhhLHIpCmVsc2V7cz1yLmFoKCkKcS5jLmEoYSkK
-ci5hPTQKci5jPWEKUC5IWihyLHMpfX0sClgyOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcwpyLiR0aS5j
-LmEoYSkKcz1yLmFoKCkKci5hPTQKci5jPWEKUC5IWihyLHMpfSwKWkw6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHE9dGhpcwp0LmwuYShiKQpzPXEuYWgoKQpyPVAuVGwoYSxiKQpxLmE9OApxLmM9cgpQLkhaKHEs
-cyl9LApYZjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLiR0aQpzLkMoIjEvIikuYShhKQppZihzLkMoImI4
-PDE+IikuYihhKSl7dGhpcy5jVShhKQpyZXR1cm59dGhpcy53VShzLmMuYShhKSl9LAp3VTpmdW5jdGlv
-bihhKXt2YXIgcz10aGlzCnMuJHRpLmMuYShhKQpzLmE9MQpQLlRrKG51bGwsbnVsbCxzLmIsdC5NLmEo
-bmV3IFAucnQocyxhKSkpfSwKY1U6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPXMuJHRpCnIuQygiYjg8
-MT4iKS5hKGEpCmlmKHIuYihhKSl7aWYoYS5hPT09OCl7cy5hPTEKUC5UayhudWxsLG51bGwscy5iLHQu
-TS5hKG5ldyBQLktGKHMsYSkpKX1lbHNlIFAuQTkoYSxzKQpyZXR1cm59UC5rMyhhLHMpfSwKTms6ZnVu
-Y3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRrKG51bGwsbnVsbCx0aGlzLmIsdC5NLmEobmV3IFAuWkwodGhp
-cyxhLGIpKSl9LAokaWI4OjF9ClAuZGEucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMu
-YSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5i
-LHRoaXMuYS5hKX0sCiRTOjB9ClAucFYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5hCnMuYT0wCnMuSEgoYSl9LAokUzo5fQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dGhpcy5hLlpMKGEsdC5sLmEoYikpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MzB9ClAudnIucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLnJ0LnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlgyKHRoaXMuYil9LAokUzowfQpQLktGLnByb3RvdHlw
-ZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLlJULnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPW51bGwKdHJ5e3E9bS5h
-LmEKbD1xLmIuYi56eih0LmZPLmEocS5kKSx0LnopfWNhdGNoKHApe3M9SC5SdShwKQpyPUgudHMocCkK
-aWYobS5jKXtxPXQubi5hKG0uYi5hLmMpLmEKbz1zCm89cT09bnVsbD9vPT1udWxsOnE9PT1vCnE9b31l
-bHNlIHE9ITEKbz1tLmEKaWYocSlvLmM9dC5uLmEobS5iLmEuYykKZWxzZSBvLmM9UC5UbChzLHIpCm8u
-Yj0hMApyZXR1cm59aWYobCBpbnN0YW5jZW9mIFAudnMmJmwuYT49NCl7aWYobC5hPT09OCl7cT1tLmEK
-cS5jPXQubi5hKGwuYykKcS5iPSEwfXJldHVybn1pZih0LmQuYihsKSl7bj1tLmIuYQpxPW0uYQpxLmM9
-bC5XNyhuZXcgUC5qWihuKSx0LnopCnEuYj0hMX19LAokUzowfQpQLmpaLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokUzozM30KUC5ycS5wcm90b3R5cGU9ewokMDpmdW5jdGlv
-bigpe3ZhciBzLHIscSxwLG8sbixtLGwKdHJ5e3E9dGhpcy5hCnA9cS5hCm89cC4kdGkKbj1vLmMKbT1u
-LmEodGhpcy5iKQpxLmM9cC5iLmIuYnYoby5DKCIyLygxKSIpLmEocC5kKSxtLG8uQygiMi8iKSxuKX1j
-YXRjaChsKXtzPUguUnUobCkKcj1ILnRzKGwpCnE9dGhpcy5hCnEuYz1QLlRsKHMscikKcS5iPSEwfX0s
-CiRTOjB9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9
-dGhpcwp0cnl7cz10Lm4uYShrLmEuYS5jKQpwPWsuYgppZihILm9UKHAuYS5IUihzKSkmJnAuYS5lIT1u
-dWxsKXtwLmM9cC5hLkt3KHMpCnAuYj0hMX19Y2F0Y2gobyl7cj1ILlJ1KG8pCnE9SC50cyhvKQpwPXQu
-bi5hKGsuYS5hLmMpCm49cC5hCm09cgpsPWsuYgppZihuPT1udWxsP209PW51bGw6bj09PW0pbC5jPXAK
-ZWxzZSBsLmM9UC5UbChyLHEpCmwuYj0hMH19LAokUzowfQpQLk9NLnByb3RvdHlwZT17fQpQLnFoLnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9e30sbz1uZXcgUC52cygkLlgz
-LHQuZkopCnAuYT0wCnM9SC5MaChxKQpyPXMuQygifigxKT8iKS5hKG5ldyBQLkI1KHAscSkpCnQuWi5h
-KG5ldyBQLnVPKHAsbykpClcuSkUocS5hLHEuYixyLCExLHMuYykKcmV0dXJuIG99fQpQLkI1LnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5jLmEoYSk7Kyt0aGlzLmEuYX0sCiRTOmZ1
-bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJ+KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQw
-OmZ1bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAu
-a1QucHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXtyZXR1cm4gSC5Faih0aGlzLmEpfSwKJGlYUzoxLApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5ifX0KUC5tMC5wcm90b3R5cGU9eyRpUW06MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e3ZhciBzPUguYih0aGlzLmEpCnMuc3RhY2s9Si5qKHRoaXMuYikKdGhyb3cgc30sCiRTOjB9ClAuSmku
-cHJvdG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9bnVsbAp0Lk0uYShhKQp0cnl7aWYo
-Qy5OVT09PSQuWDMpe2EuJDAoKQpyZXR1cm59UC5UOChwLHAsdGhpcyxhLHQuSCl9Y2F0Y2gocSl7cz1I
-LlJ1KHEpCnI9SC50cyhxKQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sCkRsOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEscD1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09
-JC5YMyl7YS4kMShiKQpyZXR1cm59UC55dihwLHAsdGhpcyxhLGIsdC5ILGMpfWNhdGNoKHEpe3M9SC5S
-dShxKQpyPUgudHMocSkKUC5MMihwLHAsdGhpcyxzLHQubC5hKHIpKX19LApSVDpmdW5jdGlvbihhLGIp
-e3JldHVybiBuZXcgUC5oaih0aGlzLGIuQygiMCgpIikuYShhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgUC5WcCh0aGlzLHQuTS5hKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQ
-Lk9SKHRoaXMsYi5DKCJ+KDApIikuYShhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0s
-Cnp6OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5hKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQw
-KCkKcmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2Mu
-QygiQDwwPiIpLktxKGQpLkMoIjEoMikiKS5hKGEpCmQuYShiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4g
-YS4kMShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEs
-YixjLGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5hKGEpCmUuYShiKQpm
-LmEoYykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGws
-dGhpcyxhLGIsYyxkLGUsZil9LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+Iiku
-S3EoYykuS3EoZCkuQygiMSgyLDMpIikuYShhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5jLkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEu
-YkgodGhpcy5iKX0sCiRTOjB9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHMuYShhKSxzKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMscj1uZXcgUC5sbShzLHMucixILkxoKHMpLkMoImxtPDE+IikpCnIuYz1zLmUKcmV0dXJuIHJ9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmE9
-PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEhPT0wfSwKdGc6ZnVuY3Rpb24oYSxiKXt2
-YXIgcyxyCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtzPXRoaXMuYgppZihz
-PT1udWxsKXJldHVybiExCnJldHVybiB0LmUuYShzW2JdKSE9bnVsbH1lbHNle3I9dGhpcy5QUihiKQpy
-ZXR1cm4gcn19LApQUjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKaWYocz09bnVsbClyZXR1cm4hMQpy
-ZXR1cm4gdGhpcy5ERihzW3RoaXMuTihhKV0sYSk+PTB9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-PXRoaXMKSC5MaChxKS5jLmEoYikKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIp
-e3M9cS5iCnJldHVybiBxLmJRKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlwZW9mIGI9
-PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLmJRKHI9PW51bGw/cS5j
-PVAuVDIoKTpyLGIpfWVsc2UgcmV0dXJuIHEuQjcoYil9LApCNzpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
-cD10aGlzCkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9cC5OKGEp
-CnE9c1tyXQppZihxPT1udWxsKXNbcl09W3AueW8oYSldCmVsc2V7aWYocC5ERihxLGEpPj0wKXJldHVy
-biExCnEucHVzaChwLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlm
-KHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkwocy5iLGIpCmVsc2Ug
-aWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHMuTChzLmMsYikK
-ZWxzZSByZXR1cm4gcy5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89dGhpcyxuPW8u
-ZAppZihuPT1udWxsKXJldHVybiExCnM9by5OKGEpCnI9bltzXQpxPW8uREYocixhKQppZihxPDApcmV0
-dXJuITEKcD1yLnNwbGljZShxLDEpWzBdCmlmKDA9PT1yLmxlbmd0aClkZWxldGUgbltzXQpvLkdTKHAp
-CnJldHVybiEwfSwKYlE6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih0LmUuYShhW2Jd
-KSE9bnVsbClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJuITB9LApMOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKaWYoYT09bnVsbClyZXR1cm4hMQpzPXQuZS5hKGFbYl0pCmlmKHM9PW51bGwpcmV0dXJuITEK
-dGhpcy5HUyhzKQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5y
-KzEmMTA3Mzc0MTgyM30sCnlvOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgo
-cikuYy5hKGEpKQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9
-cwpyLmY9cy5iPXF9KytyLmEKci5TKCkKcmV0dXJuIHF9LApHUzpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LHI9YS5jLHE9YS5iCmlmKHI9PW51bGwpcy5lPXEKZWxzZSByLmI9cQppZihxPT1udWxsKXMuZj1yCmVs
-c2UgcS5jPXI7LS1zLmEKcy5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4
-MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3Ro
-CmZvcihyPTA7cjxzOysrcilpZihKLlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX19ClAuYm4u
-cHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
-RjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMscT1zLmEKaWYocy5iIT09cS5yKXRocm93IEguYihQ
-LmE0KHEpKQplbHNlIGlmKHI9PW51bGwpe3Muc2oobnVsbCkKcmV0dXJuITF9ZWxzZXtzLnNqKHMuJHRp
-LkMoIjE/IikuYShyLmEpKQpzLmM9ci5iCnJldHVybiEwfX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMuZD10
-aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXkucHJvdG90
-eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueihhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnooYSku
-QygifihsRC5FKSIpLmEoYikKcz10aGlzLmdBKGEpCmZvcihyPTA7cjxzOysrcil7Yi4kMSh0aGlzLnEo
-YSxyKSkKaWYocyE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCmdsMDpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5nQShhKT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2wwKGEp
-fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgueihhKQpyZXR1cm4gbmV3IEgubEooYSxzLktxKGMp
-LkMoIjEobEQuRSkiKS5hKGIpLHMuQygiQDxsRC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAplUjpm
-dW5jdGlvbihhLGIpe3JldHVybiBILnFDKGEsYixudWxsLEgueihhKS5DKCJsRC5FIikpfSwKZHI6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYoYSxILnooYSkuQygiQDxsRC5FPiIpLktxKGIpLkMoImpW
-PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwpILnooYSkuQygibEQuRT8iKS5hKGQp
-ClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcihzPWI7czxjOysrcyl0aGlzLlkoYSxzLGQpfSwKdzpmdW5j
-dGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90b3R5cGU9e30KUC5yYS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5hCmlmKCFyLmEpdGhpcy5iLmErPSIs
-ICIKci5hPSExCnI9dGhpcy5iCnM9ci5hKz1ILkVqKGEpCnIuYT1zKyI6ICIKci5hKz1ILkVqKGIpfSwK
-JFM6MTF9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5MaCh0aGlzKS5D
-KCJ+KFlrLkssWWsuVikiKS5hKGIpCmZvcihzPUouSVQodGhpcy5nVigpKTtzLkYoKTspe3I9cy5nbCgp
-CmIuJDIocix0aGlzLnEoMCxyKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ1Yo
-KSxuZXcgUC55USh0aGlzKSxILkxoKHRoaXMpLkMoIk4zPFlrLkssWWsuVj4iKSl9LAp4NDpmdW5jdGlv
-bihhKXtyZXR1cm4gSi56bCh0aGlzLmdWKCksYSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0
-aGlzLmdWKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuZ1YoKSl9LAp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciBzPXRoaXMuYSxyPUguTGgocykKci5DKCJZay5LIikuYShhKQpyZXR1cm4gbmV3IFAu
-TjMoYSxzLnEoMCxhKSxyLkMoIkA8WWsuSz4iKS5LcShyLkMoIllrLlYiKSkuQygiTjM8MSwyPiIpKX0s
-CiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5LLFlrLlY+KFlrLkspIil9
-fQpQLktQLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUguTGgodGhpcykKcy5jLmEo
-YikKcy5RWzFdLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1h
-cCIpKX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIp
-fSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHMuYy5hKGIpLHMu
-UVsxXS5hKGMpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEueDQoYSl9LApLOmZ1bmN0aW9u
-KGEsYil7dGhpcy5hLksoMCxILkxoKHRoaXMpLkMoIn4oMSwyKSIpLmEoYikpfSwKZ2wwOmZ1bmN0aW9u
-KGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5nbDAocyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LmEKcmV0dXJuIHMuZ0Eocyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBKLmoodGhpcy5hKX0sCmdQdTpm
-dW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ1B1KHMpfSwKJGlaMDoxfQpQLkdqLnByb3Rv
-dHlwZT17fQpQLmxmLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
-KT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcykhPT0wfSwKRlY6ZnVuY3Rp
-b24oYSxiKXt2YXIgcwpmb3Iocz1KLklUKEguTGgodGhpcykuQygiY1g8bGYuRT4iKS5hKGIpKTtzLkYo
-KTspdGhpcy5pKDAscy5nbCgpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0i
-KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKaWYoIXIuRigpKXJldHVybiIi
-CmlmKGI9PT0iIil7cz0iIgpkbyBzKz1ILkVqKHIuZCkKd2hpbGUoci5GKCkpfWVsc2V7cz1ILkVqKHIu
-ZCkKZm9yKDtyLkYoKTspcz1zK2IrSC5FaihyLmQpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
-fSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5iSyh0aGlzLGIsSC5MaCh0aGlzKS5DKCJsZi5FIikp
-fSwKRTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPSJpbmRleCIKUC5VSShiLHAsdC5TKQpQLmsxKGIs
-cCkKZm9yKHM9dGhpcy5nbSh0aGlzKSxyPTA7cy5GKCk7KXtxPXMuZAppZihiPT09cilyZXR1cm4gcTsr
-K3J9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLHAsbnVsbCxyKSl9fQpQLlZqLnByb3RvdHlwZT17JGliUTox
-LCRpY1g6MSwkaXh1OjF9ClAuWHYucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpeHU6MX0KUC5uWS5w
-cm90b3R5cGU9e30KUC5XWS5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC5wUi5wcm90b3R5
-cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmIKaWYocj09
-bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4g
-bnVsbAplbHNle3M9cltiXQpyZXR1cm4gdHlwZW9mIHM9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6c319
-LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5n
-dGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24o
-KXtpZih0aGlzLmI9PW51bGwpe3ZhciBzPXRoaXMuYwpyZXR1cm4gbmV3IEguaTUocyxILkxoKHMpLkMo
-Imk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
-cT10aGlzCmlmKHEuYj09bnVsbClxLmMuWSgwLGIsYykKZWxzZSBpZihxLng0KGIpKXtzPXEuYgpzW2Jd
-PWMKcj1xLmEKaWYocj09bnVsbD9zIT1udWxsOnIhPT1zKXJbYl09bnVsbH1lbHNlIHEuWEsoKS5ZKDAs
-YixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJl
-dHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcwp0LmNBLmEoYikKaWYoby5iPT1udWxsKXJldHVybiBv
-LmMuSygwLGIpCnM9by5DZigpCmZvcihyPTA7cjxzLmxlbmd0aDsrK3Ipe3E9c1tyXQpwPW8uYltxXQpp
-Zih0eXBlb2YgcD09InVuZGVmaW5lZCIpe3A9UC5RZShvLmFbcV0pCm8uYltxXT1wfWIuJDIocSxwKQpp
-ZihzIT09by5jKXRocm93IEguYihQLmE0KG8pKX19LApDZjpmdW5jdGlvbigpe3ZhciBzPXQuYk0uYSh0
-aGlzLmMpCmlmKHM9PW51bGwpcz10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEpLHQucykKcmV0
-dXJuIHN9LApYSzpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKG4uYj09bnVsbClyZXR1
-cm4gbi5jCnM9UC5GbCh0Lk4sdC56KQpyPW4uQ2YoKQpmb3IocT0wO3A9ci5sZW5ndGgscTxwOysrcSl7
-bz1yW3FdCnMuWSgwLG8sbi5xKDAsbykpfWlmKHA9PT0wKUMuTm0uaShyLCIiKQplbHNlIEMuTm0uc0Eo
-ciwwKQpuLmE9bi5iPW51bGwKcmV0dXJuIG4uYz1zfSwKZmI6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIU9i
-amVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSkpcmV0dXJuIG51bGwKcz1Q
-LlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT1zfX0KUC5pOC5wcm90b3R5cGU9ewpnQTpmdW5j
-dGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-dGhpcy5hCmlmKHMuYj09bnVsbClzPXMuZ1YoKS5FKDAsYikKZWxzZXtzPXMuQ2YoKQppZihiPDB8fGI+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcz1zW2JdfXJldHVybiBzfSwKZ206ZnVuY3Rpb24oYSl7
-dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbCl7cz1zLmdWKCkKcz1zLmdtKHMpfWVsc2V7cz1zLkNmKCkK
-cz1uZXcgSi5tMShzLHMubGVuZ3RoLEgudDYocykuQygibTE8MT4iKSl9cmV0dXJuIHN9LAp0ZzpmdW5j
-dGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLnBnLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
-KCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVy
-biBzfWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAokUzoxMn0KUC5jMi5wcm90b3R5cGU9ewok
-MDpmdW5jdGlvbigpe3ZhciBzLHIKdHJ5e3M9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFsOmZh
-bHNlfSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCiRTOjEyfQpQLkNWLnBy
-b3RvdHlwZT17CnlyOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgs
-ZyxmLGUsZCxjLGIsYT0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3RoICIKYTI9UC5qQihhMSxh
-MixhMC5sZW5ndGgpCnM9JC5WNygpCmZvcihyPWExLHE9cixwPW51bGwsbz0tMSxuPS0xLG09MDtyPGEy
-O3I9bCl7bD1yKzEKaz1DLnhCLlcoYTAscikKaWYoaz09PTM3KXtqPWwrMgppZihqPD1hMil7aT1ILm9v
-KEMueEIuVyhhMCxsKSkKaD1ILm9vKEMueEIuVyhhMCxsKzEpKQpnPWkqMTYraC0oaCYyNTYpCmlmKGc9
-PT0zNylnPS0xCmw9an1lbHNlIGc9LTF9ZWxzZSBnPWsKaWYoMDw9ZyYmZzw9MTI3KXtpZihnPDB8fGc+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsZykKZj1zW2ddCmlmKGY+PTApe2c9Qy54Qi5PMigiQUJDREVG
-R0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyIs
-ZikKaWYoZz09PWspY29udGludWUKaz1nfWVsc2V7aWYoZj09PS0xKXtpZihvPDApe2U9cD09bnVsbD9u
-dWxsOnAuYS5sZW5ndGgKaWYoZT09bnVsbCllPTAKbz1lKyhyLXEpCm49cn0rK20KaWYoaz09PTYxKWNv
-bnRpbnVlfWs9Z31pZihmIT09LTIpe2lmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCmU9cH1lbHNlIGU9
-cAplLmErPUMueEIuTmooYTAscSxyKQplLmErPUguTHcoaykKcT1sCmNvbnRpbnVlfX10aHJvdyBILmIo
-UC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYTAscikpfWlmKHAhPW51bGwpe2U9cC5hKz1DLnhCLk5q
-KGEwLHEsYTIpCmQ9ZS5sZW5ndGgKaWYobz49MClQLnhNKGEwLG4sYTIsbyxtLGQpCmVsc2V7Yz1DLmpu
-LnpZKGQtMSw0KSsxCmlmKGM9PT0xKXRocm93IEguYihQLnJyKGEsYTAsYTIpKQpmb3IoO2M8NDspe2Ur
-PSI9IgpwLmE9ZTsrK2N9fWU9cC5hCnJldHVybiBDLnhCLmk3KGEwLGExLGEyLGUuY2hhckNvZGVBdCgw
-KT09MD9lOmUpfWI9YTItYTEKaWYobz49MClQLnhNKGEwLG4sYTIsbyxtLGIpCmVsc2V7Yz1DLmpuLnpZ
-KGIsNCkKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmlmKGM+MSlhMD1DLnhCLmk3KGEw
-LGEyLGEyLGM9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYTB9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnBy
-b3RvdHlwZT17fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLlVkLnByb3RvdHlw
-ZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9UC5obCh0aGlzLmEpCnJldHVybih0aGlzLmIhPW51bGw/IkNv
-bnZlcnRpbmcgb2JqZWN0IHRvIGFuIGVuY29kYWJsZSBvYmplY3QgZmFpbGVkOiI6IkNvbnZlcnRpbmcg
-b2JqZWN0IGRpZCBub3QgcmV0dXJuIGFuIGVuY29kYWJsZSBvYmplY3Q6IikrIiAiK3N9fQpQLks4LnBy
-b3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkN5Y2xpYyBlcnJvciBpbiBKU09OIHN0cmluZ2lm
-eSJ9fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwp0LmZWLmEoYykKcz1Q
-LkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4gc30sCk9COmZ1bmN0aW9uKGEsYil7dmFyIHMKdC5kQS5h
-KGIpCnM9UC51WChhLHRoaXMuZ1pFKCkuYixudWxsKQpyZXR1cm4gc30sCmdaRTpmdW5jdGlvbigpe3Jl
-dHVybiBDLm5YfSwKZ0hlOmZ1bmN0aW9uKCl7cmV0dXJuIEMuQTN9fQpQLm9qLnByb3RvdHlwZT17fQpQ
-Lk14LnByb3RvdHlwZT17fQpQLlNoLnByb3RvdHlwZT17CnZwOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxw
-LG8sbixtLGw9YS5sZW5ndGgKZm9yKHM9Si5yWShhKSxyPXRoaXMuYyxxPTAscD0wO3A8bDsrK3Ape289
-cy5XKGEscCkKaWYobz45Mil7aWYobz49NTUyOTYpe249byY2NDUxMgppZihuPT09NTUyOTYpe209cCsx
-Cm09IShtPGwmJihDLnhCLlcoYSxtKSY2NDUxMik9PT01NjMyMCl9ZWxzZSBtPSExCmlmKCFtKWlmKG49
-PT01NjMyMCl7bj1wLTEKbj0hKG4+PTAmJihDLnhCLk8yKGEsbikmNjQ1MTIpPT09NTUyOTYpfWVsc2Ug
-bj0hMQplbHNlIG49ITAKaWYobil7aWYocD5xKXIuYSs9Qy54Qi5OaihhLHEscCkKcT1wKzEKci5hKz1I
-Lkx3KDkyKQpyLmErPUguTHcoMTE3KQpyLmErPUguTHcoMTAwKQpuPW8+Pj44JjE1CnIuYSs9SC5Mdyhu
-PDEwPzQ4K246ODcrbikKbj1vPj4+NCYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3K24pCm49byYxNQpy
-LmErPUguTHcobjwxMD80OCtuOjg3K24pfX1jb250aW51ZX1pZihvPDMyKXtpZihwPnEpci5hKz1DLnhC
-Lk5qKGEscSxwKQpxPXArMQpyLmErPUguTHcoOTIpCnN3aXRjaChvKXtjYXNlIDg6ci5hKz1ILkx3KDk4
-KQpicmVhawpjYXNlIDk6ci5hKz1ILkx3KDExNikKYnJlYWsKY2FzZSAxMDpyLmErPUguTHcoMTEwKQpi
-cmVhawpjYXNlIDEyOnIuYSs9SC5MdygxMDIpCmJyZWFrCmNhc2UgMTM6ci5hKz1ILkx3KDExNCkKYnJl
-YWsKZGVmYXVsdDpyLmErPUguTHcoMTE3KQpyLmErPUguTHcoNDgpCnIuYSs9SC5Mdyg0OCkKbj1vPj4+
-NCYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3K24pCm49byYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3
-K24pCmJyZWFrfX1lbHNlIGlmKG89PT0zNHx8bz09PTkyKXtpZihwPnEpci5hKz1DLnhCLk5qKGEscSxw
-KQpxPXArMQpyLmErPUguTHcoOTIpCnIuYSs9SC5MdyhvKX19aWYocT09PTApci5hKz1ILkVqKGEpCmVs
-c2UgaWYocTxsKXIuYSs9cy5OaihhLHEsbCl9LApKbjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscApmb3Io
-cz10aGlzLmEscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1zW3FdCmlmKGE9PW51bGw/cD09bnVsbDph
-PT09cCl0aHJvdyBILmIobmV3IFAuSzgoYSxudWxsKSl9Qy5ObS5pKHMsYSl9LAppVTpmdW5jdGlvbihh
-KXt2YXIgcyxyLHEscCxvPXRoaXMKaWYoby50TShhKSlyZXR1cm4Kby5KbihhKQp0cnl7cz1vLmIuJDEo
-YSkKaWYoIW8udE0ocykpe3E9UC5HeShhLG51bGwsby5nVksoKSkKdGhyb3cgSC5iKHEpfXE9by5hCmlm
-KDA+PXEubGVuZ3RoKXJldHVybiBILk9IKHEsLTEpCnEucG9wKCl9Y2F0Y2gocCl7cj1ILlJ1KHApCnE9
-UC5HeShhLHIsby5nVksoKSkKdGhyb3cgSC5iKHEpfX0sCnRNOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10
-aGlzCmlmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoIWlzRmluaXRlKGEpKXJldHVybiExCnEuYy5hKz1D
-LkNELncoYSkKcmV0dXJuITB9ZWxzZSBpZihhPT09ITApe3EuYy5hKz0idHJ1ZSIKcmV0dXJuITB9ZWxz
-ZSBpZihhPT09ITEpe3EuYy5hKz0iZmFsc2UiCnJldHVybiEwfWVsc2UgaWYoYT09bnVsbCl7cS5jLmEr
-PSJudWxsIgpyZXR1cm4hMH1lbHNlIGlmKHR5cGVvZiBhPT0ic3RyaW5nIil7cz1xLmMKcy5hKz0nIicK
-cS52cChhKQpzLmErPSciJwpyZXR1cm4hMH1lbHNlIGlmKHQuai5iKGEpKXtxLkpuKGEpCnEubEsoYSkK
-cz1xLmEKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpyZXR1cm4hMH1lbHNl
-IGlmKHQuZi5iKGEpKXtxLkpuKGEpCnI9cS5qdyhhKQpzPXEuYQppZigwPj1zLmxlbmd0aClyZXR1cm4g
-SC5PSChzLC0xKQpzLnBvcCgpCnJldHVybiByfWVsc2UgcmV0dXJuITF9LApsSzpmdW5jdGlvbihhKXt2
-YXIgcyxyLHE9dGhpcy5jCnEuYSs9IlsiCnM9Si5VNihhKQppZihzLmdvcihhKSl7dGhpcy5pVShzLnEo
-YSwwKSkKZm9yKHI9MTtyPHMuZ0EoYSk7KytyKXtxLmErPSIsIgp0aGlzLmlVKHMucShhLHIpKX19cS5h
-Kz0iXSJ9LApqdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9e30KaWYoYS5nbDAo
-YSkpe20uYy5hKz0ie30iCnJldHVybiEwfXM9YS5nQShhKSoyCnI9UC5POChzLG51bGwsITEsdC5SKQpx
-PWwuYT0wCmwuYj0hMAphLksoMCxuZXcgUC50aShsLHIpKQppZighbC5iKXJldHVybiExCnA9bS5jCnAu
-YSs9InsiCmZvcihvPSciJztxPHM7cSs9MixvPScsIicpe3AuYSs9bwptLnZwKEguaChyW3FdKSkKcC5h
-Kz0nIjonCm49cSsxCmlmKG4+PXMpcmV0dXJuIEguT0gocixuKQptLmlVKHJbbl0pfXAuYSs9In0iCnJl
-dHVybiEwfX0KUC50aS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYodHlwZW9m
-IGEhPSJzdHJpbmciKXRoaXMuYS5iPSExCnM9dGhpcy5iCnI9dGhpcy5hCkMuTm0uWShzLHIuYSsrLGEp
-CkMuTm0uWShzLHIuYSsrLGIpfSwKJFM6MTF9ClAudHUucHJvdG90eXBlPXsKZ1ZLOmZ1bmN0aW9uKCl7
-dmFyIHM9dGhpcy5jLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fQpQLnU1LnByb3RvdHlw
-ZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90b3R5cGU9ewpXSjpmdW5jdGlv
-bihhKXt2YXIgcyxyLHEscD1QLmpCKDAsbnVsbCxhLmxlbmd0aCksbz1wLTAKaWYobz09PTApcmV0dXJu
-IG5ldyBVaW50OEFycmF5KDApCnM9byozCnI9bmV3IFVpbnQ4QXJyYXkocykKcT1uZXcgUC5SdyhyKQpp
-ZihxLkd4KGEsMCxwKSE9PXApe0ouYTYoYSxwLTEpCnEuUk8oKX1yZXR1cm4gbmV3IFVpbnQ4QXJyYXko
-ci5zdWJhcnJheSgwLEguck0oMCxxLmIscykpKX19ClAuUncucHJvdG90eXBlPXsKUk86ZnVuY3Rpb24o
-KXt2YXIgcz10aGlzLHI9cy5jLHE9cy5iLHA9cy5iPXErMSxvPXIubGVuZ3RoCmlmKHE+PW8pcmV0dXJu
-IEguT0gocixxKQpyW3FdPTIzOQpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09
-MTkxCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTg5fSwKTzY6ZnVuY3Rpb24o
-YSxiKXt2YXIgcyxyLHEscCxvLG49dGhpcwppZigoYiY2NDUxMik9PT01NjMyMCl7cz02NTUzNisoKGEm
-MTAyMyk8PDEwKXxiJjEwMjMKcj1uLmMKcT1uLmIKcD1uLmI9cSsxCm89ci5sZW5ndGgKaWYocT49byly
-ZXR1cm4gSC5PSChyLHEpCnJbcV09cz4+PjE4fDI0MApxPW4uYj1wKzEKaWYocD49bylyZXR1cm4gSC5P
-SChyLHApCnJbcF09cz4+PjEyJjYzfDEyOApwPW4uYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEp
-CnJbcV09cz4+PjYmNjN8MTI4Cm4uYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09cyY2
-M3wxMjgKcmV0dXJuITB9ZWxzZXtuLlJPKCkKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzLHIscSxwLG8sbixtLGw9dGhpcwppZihiIT09YyYmKEMueEIuTzIoYSxjLTEpJjY0NTEyKT09PTU1
-Mjk2KS0tYwpmb3Iocz1sLmMscj1zLmxlbmd0aCxxPWI7cTxjOysrcSl7cD1DLnhCLlcoYSxxKQppZihw
-PD0xMjcpe289bC5iCmlmKG8+PXIpYnJlYWsKbC5iPW8rMQpzW29dPXB9ZWxzZXtvPXAmNjQ1MTIKaWYo
-bz09PTU1Mjk2KXtpZihsLmIrND5yKWJyZWFrCm49cSsxCmlmKGwuTzYocCxDLnhCLlcoYSxuKSkpcT1u
-fWVsc2UgaWYobz09PTU2MzIwKXtpZihsLmIrMz5yKWJyZWFrCmwuUk8oKX1lbHNlIGlmKHA8PTIwNDcp
-e289bC5iCm09bysxCmlmKG0+PXIpYnJlYWsKbC5iPW0KaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNb
-b109cD4+PjZ8MTkyCmwuYj1tKzEKc1ttXT1wJjYzfDEyOH1lbHNle289bC5iCmlmKG8rMj49cilicmVh
-awptPWwuYj1vKzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cD4+PjEyfDIyNApvPWwuYj1t
-KzEKaWYobT49cilyZXR1cm4gSC5PSChzLG0pCnNbbV09cD4+PjYmNjN8MTI4CmwuYj1vKzEKaWYobz49
-cilyZXR1cm4gSC5PSChzLG8pCnNbb109cCY2M3wxMjh9fX1yZXR1cm4gcX19ClAuR1kucHJvdG90eXBl
-PXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHMscgp0LkwuYShhKQpzPXRoaXMuYQpyPVAua3kocyxhLDAsbnVs
-bCkKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gbmV3IFAuYnoocykuTmUoYSwwLG51bGwsITApfX0K
-UC5iei5wcm90b3R5cGU9ewpOZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG49dGhpcwp0
-LkwuYShhKQpzPVAuakIoYixjLEouSG0oYSkpCmlmKGI9PT1zKXJldHVybiIiCnI9UC5qeShhLGIscykK
-cT1uLmhPKHIsMCxzLWIsITApCnA9bi5iCmlmKChwJjEpIT09MCl7bz1QLmo0KHApCm4uYj0wCnRocm93
-IEguYihQLnJyKG8sYSxiK24uYykpfXJldHVybiBxfSwKaE86ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMs
-cixxPXRoaXMKaWYoYy1iPjEwMDApe3M9Qy5qbi5CVShiK2MsMikKcj1xLmhPKGEsYixzLCExKQppZigo
-cS5iJjEpIT09MClyZXR1cm4gcgpyZXR1cm4gcitxLmhPKGEscyxjLGQpfXJldHVybiBxLkVoKGEsYixj
-LGQpfSwKRWg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRoaXMsaj02NTUz
-MyxpPWsuYixoPWsuYyxnPW5ldyBQLlJuKCIiKSxmPWIrMSxlPWEubGVuZ3RoCmlmKGI8MHx8Yj49ZSly
-ZXR1cm4gSC5PSChhLGIpCnM9YVtiXQokbGFiZWwwJDA6Zm9yKHI9ay5hOyEwOyl7Zm9yKDshMDtmPW8p
-e3E9Qy54Qi5XKCJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
+WDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTU6ZnVuY3Rpb24oYSxiLGMpe0gudVAoYykKSC5v
+ZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90
+eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
+fX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0
+aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgu
+b2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZFQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
+LGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9
+ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpI
+LmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24o
+YSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikK
+SC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90
+eXBlPXt9CkguVlAucHJvdG90eXBlPXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9
+CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0
+aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19
+CkguRy5wcm90b3R5cGU9e30KSC5sWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBILmRt
+KHRoaXMuYSxudWxsKX19Ckgua1MucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+fX0KSC5pTS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmEscj1zLmEKcy5hPW51bGwKci4kMCgpfSwKJFM6OX0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXt2YXIgcyxyCnRoaXMuYS5hPXQuTS5hKGEpCnM9dGhpcy5iCnI9dGhpcy5jCnMuZmlyc3RD
+aGlsZD9zLnJlbW92ZUNoaWxkKHIpOnMuYXBwZW5kQ2hpbGQocil9LAokUzozNH0KUC5Wcy5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5GdC5w
+cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0K
+UC5XMy5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClz
+ZWxmLnNldFRpbWVvdXQoSC50UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAu
+TDQoImBzZXRUaW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0
+aW9uKCl7dGhpcy5iLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLmloLnByb3RvdHlwZT17CmFN
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLHE9ci4kdGkKcS5DKCIxLz8iKS5hKGIpCmlmKCFyLmIp
+ci5hLlhmKGIpCmVsc2V7cz1yLmEKaWYocS5DKCJiODwxPiIpLmIoYikpcy5jVShiKQplbHNlIHMuWDIo
+cS5jLmEoYikpfX0sCncwOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYj09bnVsbCliPVAudjAoYSkKcz10
+aGlzLmEKaWYodGhpcy5iKXMuWkwoYSxiKQplbHNlIHMuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6NTJ9ClAuU1gucHJvdG90eXBl
+PXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHQubC5hKGIpKSl9LAokQzoi
+JDIiLAokUjoyLAokUzoyNH0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShI
+LnVQKGEpLGIpfSwKJFM6MjZ9ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRl
+cmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5Faih0aGlzLmEpKyIpIn19ClAuR1YucHJvdG90eXBl
+PXsKZ2w6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmMKaWYocz09bnVsbClyZXR1cm4gdGhpcy4kdGkuYy5h
+KHRoaXMuYikKcmV0dXJuIHMuZ2woKX0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlz
+CmZvcihzPW0uJHRpLkMoIkFuPDE+Iik7ITA7KXtyPW0uYwppZihyIT1udWxsKWlmKHIuRigpKXJldHVy
+biEwCmVsc2UgbS5zWDkobnVsbCkKcT1mdW5jdGlvbihhLGIsYyl7dmFyIGwsaz1iCndoaWxlKHRydWUp
+dHJ5e3JldHVybiBhKGssbCl9Y2F0Y2goail7bD1qCms9Y319KG0uYSwwLDEpCmlmKHEgaW5zdGFuY2Vv
+ZiBQLkZ5KXtwPXEuYgppZihwPT09Mil7bz1tLmQKaWYobz09bnVsbHx8by5sZW5ndGg9PT0wKXttLnNF
+QyhudWxsKQpyZXR1cm4hMX1pZigwPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLC0xKQptLmE9by5wb3Ao
+KQpjb250aW51ZX1lbHNle3I9cS5hCmlmKHA9PT0zKXRocm93IHIKZWxzZXtuPXMuYShKLklUKHIpKQpp
+ZihuIGluc3RhbmNlb2YgUC5HVil7cj1tLmQKaWYocj09bnVsbClyPW0uZD1bXQpDLk5tLmkocixtLmEp
+Cm0uYT1uLmEKY29udGludWV9ZWxzZXttLnNYOShuKQpjb250aW51ZX19fX1lbHNle20uc0VDKHEpCnJl
+dHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuQygiMT8iKS5h
+KGEpfSwKc1g5OmZ1bmN0aW9uKGEpe3RoaXMuYz10aGlzLiR0aS5DKCJBbjwxPj8iKS5hKGEpfSwKJGlB
+bjoxfQpQLnE0LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0aGlzLmEo
+KSx0aGlzLiR0aS5DKCJHVjwxPiIpKX19ClAuUGYucHJvdG90eXBlPXsKdzA6ZnVuY3Rpb24oYSxiKXt2
+YXIgcwpILmNiKGEsImVycm9yIix0LkspCnM9dGhpcy5hCmlmKHMuYSE9PTApdGhyb3cgSC5iKFAuUFYo
+IkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQppZihiPT1udWxsKWI9UC52MChhKQpzLk5rKGEsYil9
+LApwbTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5cGU9ewph
+TTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy4kdGkKci5DKCIxLz8iKS5hKGIpCnM9dGhpcy5hCmlm
+KHMuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQpzLlhmKHIu
+QygiMS8iKS5hKGIpKX19ClAuRmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYx
+NSkhPT02KXJldHVybiEwCnJldHVybiB0aGlzLmIuYi5idih0LmFsLmEodGhpcy5kKSxhLmEsdC55LHQu
+Syl9LApLdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmUscj10LnoscT10LksscD10aGlzLiR0aS5DKCIy
+LyIpLG89dGhpcy5iLmIKaWYodC5hZy5iKHMpKXJldHVybiBwLmEoby5ycChzLGEuYSxhLmIscixxLHQu
+bCkpCmVsc2UgcmV0dXJuIHAuYShvLmJ2KHQuYkkuYShzKSxhLmEscixxKSl9fQpQLnZzLnByb3RvdHlw
+ZT17ClNxOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD10aGlzLiR0aQpwLktxKGMpLkMoIjEvKDIp
+IikuYShhKQpzPSQuWDMKaWYocyE9PUMuTlUpe2MuQygiQDwwLz4iKS5LcShwLmMpLkMoIjEoMikiKS5h
+KGEpCmlmKGIhPW51bGwpYj1QLlZIKGIscyl9cj1uZXcgUC52cyhzLGMuQygidnM8MD4iKSkKcT1iPT1u
+dWxsPzE6Mwp0aGlzLnhmKG5ldyBQLkZlKHIscSxhLGIscC5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwy
+PiIpKSkKcmV0dXJuIHJ9LApXNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNxKGEsbnVsbCxiKX0s
+ClFkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRoaXMuJHRpCnIuS3EoYykuQygiMS8oMikiKS5hKGEp
+CnM9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAuRmUocywxOSxhLGIsci5D
+KCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHN9LAp4ZjpmdW5jdGlvbihhKXt2YXIg
+cyxyPXRoaXMscT1yLmEKaWYocTw9MSl7YS5hPXQuRi5hKHIuYykKci5jPWF9ZWxzZXtpZihxPT09Mil7
+cz10LmMuYShyLmMpCnE9cy5hCmlmKHE8NCl7cy54ZihhKQpyZXR1cm59ci5hPXEKci5jPXMuY31QLlRr
+KG51bGwsbnVsbCxyLmIsdC5NLmEobmV3IFAuZGEocixhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciBz
+LHIscSxwLG8sbixtPXRoaXMsbD17fQpsLmE9YQppZihhPT1udWxsKXJldHVybgpzPW0uYQppZihzPD0x
+KXtyPXQuRi5hKG0uYykKbS5jPWEKaWYociE9bnVsbCl7cT1hLmEKZm9yKHA9YTtxIT1udWxsO3A9cSxx
+PW8pbz1xLmEKcC5hPXJ9fWVsc2V7aWYocz09PTIpe249dC5jLmEobS5jKQpzPW4uYQppZihzPDQpe24u
+alEoYSkKcmV0dXJufW0uYT1zCm0uYz1uLmN9bC5hPW0uTjgoYSkKUC5UayhudWxsLG51bGwsbS5iLHQu
+TS5hKG5ldyBQLm9RKGwsbSkpKX19LAphaDpmdW5jdGlvbigpe3ZhciBzPXQuRi5hKHRoaXMuYykKdGhp
+cy5jPW51bGwKcmV0dXJuIHRoaXMuTjgocyl9LApOODpmdW5jdGlvbihhKXt2YXIgcyxyLHEKZm9yKHM9
+YSxyPW51bGw7cyE9bnVsbDtyPXMscz1xKXtxPXMuYQpzLmE9cn1yZXR1cm4gcn0sCkhIOmZ1bmN0aW9u
+KGEpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8iKS5hKGEpCmlmKHEuQygiYjg8MT4iKS5iKGEp
+KWlmKHEuYihhKSlQLkE5KGEscikKZWxzZSBQLmszKGEscikKZWxzZXtzPXIuYWgoKQpxLmMuYShhKQpy
+LmE9NApyLmM9YQpQLkhaKHIscyl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzCnIuJHRpLmMu
+YShhKQpzPXIuYWgoKQpyLmE9NApyLmM9YQpQLkhaKHIscyl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscT10aGlzCnQubC5hKGIpCnM9cS5haCgpCnI9UC5UbChhLGIpCnEuYT04CnEuYz1yClAuSFoocSxz
+KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHRpCnMuQygiMS8iKS5hKGEpCmlmKHMuQygiYjg8
+MT4iKS5iKGEpKXt0aGlzLmNVKGEpCnJldHVybn10aGlzLndVKHMuYy5hKGEpKX0sCndVOmZ1bmN0aW9u
+KGEpe3ZhciBzPXRoaXMKcy4kdGkuYy5hKGEpCnMuYT0xClAuVGsobnVsbCxudWxsLHMuYix0Lk0uYShu
+ZXcgUC5ydChzLGEpKSl9LApjVTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLHI9cy4kdGkKci5DKCJiODwx
+PiIpLmEoYSkKaWYoci5iKGEpKXtpZihhLmE9PT04KXtzLmE9MQpQLlRrKG51bGwsbnVsbCxzLmIsdC5N
+LmEobmV3IFAuS0YocyxhKSkpfWVsc2UgUC5BOShhLHMpCnJldHVybn1QLmszKGEscyl9LApOazpmdW5j
+dGlvbihhLGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix0Lk0uYShuZXcgUC5aTCh0aGlz
+LGEsYikpKX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5h
+LHRoaXMuYil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIs
+dGhpcy5hLmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmEKcy5hPTAKcy5ISChhKX0sCiRTOjl9ClAuVTcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0
+aGlzLmEuWkwoYSx0LmwuYShiKSl9LAokQzoiJDIiLAokUjoyLAokUzoyOX0KUC52ci5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAucnQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWDIodGhpcy5iKX0sCiRTOjB9ClAuS0YucHJvdG90eXBl
+PXsKJDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9bnVsbAp0cnl7cT1tLmEu
+YQpsPXEuYi5iLnp6KHQuZk8uYShxLmQpLHQueil9Y2F0Y2gocCl7cz1ILlJ1KHApCnI9SC50cyhwKQpp
+ZihtLmMpe3E9dC5uLmEobS5iLmEuYykuYQpvPXMKbz1xPT1udWxsP289PW51bGw6cT09PW8KcT1vfWVs
+c2UgcT0hMQpvPW0uYQppZihxKW8uYz10Lm4uYShtLmIuYS5jKQplbHNlIG8uYz1QLlRsKHMscikKby5i
+PSEwCnJldHVybn1pZihsIGluc3RhbmNlb2YgUC52cyYmbC5hPj00KXtpZihsLmE9PT04KXtxPW0uYQpx
+LmM9dC5uLmEobC5jKQpxLmI9ITB9cmV0dXJufWlmKHQuZC5iKGwpKXtuPW0uYi5hCnE9bS5hCnEuYz1s
+Llc3KG5ldyBQLmpaKG4pLHQueikKcS5iPSExfX0sCiRTOjB9ClAualoucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMyfQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
+KCl7dmFyIHMscixxLHAsbyxuLG0sbAp0cnl7cT10aGlzLmEKcD1xLmEKbz1wLiR0aQpuPW8uYwptPW4u
+YSh0aGlzLmIpCnEuYz1wLmIuYi5idihvLkMoIjIvKDEpIikuYShwLmQpLG0sby5DKCIyLyIpLG4pfWNh
+dGNoKGwpe3M9SC5SdShsKQpyPUgudHMobCkKcT10aGlzLmEKcS5jPVAuVGwocyxyKQpxLmI9ITB9fSwK
+JFM6MH0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtLGwsaz10
+aGlzCnRyeXtzPXQubi5hKGsuYS5hLmMpCnA9ay5iCmlmKEgub1QocC5hLkhSKHMpKSYmcC5hLmUhPW51
+bGwpe3AuYz1wLmEuS3cocykKcC5iPSExfX1jYXRjaChvKXtyPUguUnUobykKcT1ILnRzKG8pCnA9dC5u
+LmEoay5hLmEuYykKbj1wLmEKbT1yCmw9ay5iCmlmKG49PW51bGw/bT09bnVsbDpuPT09bSlsLmM9cApl
+bHNlIGwuYz1QLlRsKHIscSkKbC5iPSEwfX0sCiRTOjB9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJv
+dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD17fSxvPW5ldyBQLnZzKCQuWDMs
+dC5mSikKcC5hPTAKcz1ILkxoKHEpCnI9cy5DKCJ+KDEpPyIpLmEobmV3IFAuQjUocCxxKSkKdC5aLmEo
+bmV3IFAudU8ocCxvKSkKVy5KRShxLmEscS5iLHIsITEscy5jKQpyZXR1cm4gb319ClAuQjUucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVu
+Y3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoIn4oMSkiKX19ClAudU8ucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt0aGlzLmIuSEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5r
+VC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5Ddy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiBILkVqKHRoaXMuYSl9LAokaVhTOjEsCmdJSTpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmJ9fQpQLm0wLnByb3RvdHlwZT17JGlRbToxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+dmFyIHM9SC5iKHRoaXMuYSkKcy5zdGFjaz1KLmoodGhpcy5iKQp0aHJvdyBzfSwKJFM6MH0KUC5KaS5w
+cm90b3R5cGU9ewpiSDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1udWxsCnQuTS5hKGEpCnRyeXtpZihD
+Lk5VPT09JC5YMyl7YS4kMCgpCnJldHVybn1QLlQ4KHAscCx0aGlzLGEsdC5IKX1jYXRjaChxKXtzPUgu
+UnUocSkKcj1ILnRzKHEpClAuTDIocCxwLHRoaXMscyx0LmwuYShyKSl9fSwKRGw6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscSxwPW51bGwKYy5DKCJ+KDApIikuYShhKQpjLmEoYikKdHJ5e2lmKEMuTlU9PT0k
+LlgzKXthLiQxKGIpCnJldHVybn1QLnl2KHAscCx0aGlzLGEsYix0LkgsYyl9Y2F0Y2gocSl7cz1ILlJ1
+KHEpCnI9SC50cyhxKQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sClJUOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIG5ldyBQLmhqKHRoaXMsYi5DKCIwKCkiKS5hKGEpLGIpfSwKdDg6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLlZwKHRoaXMsdC5NLmEoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAu
+T1IodGhpcyxiLkMoIn4oMCkiKS5hKGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwK
+eno6ZnVuY3Rpb24oYSxiKXtiLkMoIjAoKSIpLmEoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAo
+KQpyZXR1cm4gUC5UOChudWxsLG51bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5D
+KCJAPDA+IikuS3EoZCkuQygiMSgyKSIpLmEoYSkKZC5hKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBh
+LiQxKGIpCnJldHVybiBQLnl2KG51bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxi
+LGMsZCxlLGYpe2QuQygiQDwwPiIpLktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmEoYSkKZS5hKGIpCmYu
+YShjKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0
+aGlzLGEsYixjLGQsZSxmKX0sCkxqOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5L
+cShjKS5LcShkKS5DKCIxKDIsMykiKS5hKGEpfX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmEuenoodGhpcy5iLHRoaXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmMuQygiMCgpIil9fQpQLlZwLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5i
+SCh0aGlzLmIpfSwKJFM6MH0KUC5PUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmMKcmV0dXJuIHRoaXMuYS5EbCh0aGlzLmIscy5hKGEpLHMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5jLkMoIn4oMCkiKX19ClAuYjYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cyxyPW5ldyBQLmxtKHMscy5yLEguTGgocykuQygibG08MT4iKSkKci5jPXMuZQpyZXR1cm4gcn0sCmdB
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09
+PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYSE9PTB9LAp0ZzpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3M9dGhpcy5iCmlmKHM9
+PW51bGwpcmV0dXJuITEKcmV0dXJuIHQuZS5hKHNbYl0pIT1udWxsfWVsc2V7cj10aGlzLlBSKGIpCnJl
+dHVybiByfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZAppZihzPT1udWxsKXJldHVybiExCnJl
+dHVybiB0aGlzLlIoc1t0aGlzLk4oYSldLGEpPj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10
+aGlzCkguTGgocSkuYy5hKGIpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtz
+PXEuYgpyZXR1cm4gcS5TKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlwZW9mIGI9PSJu
+dW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLlMocj09bnVsbD9xLmM9UC5U
+MigpOnIsYil9ZWxzZSByZXR1cm4gcS5HKGIpfSwKRzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD10aGlz
+CkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9cC5OKGEpCnE9c1ty
+XQppZihxPT1udWxsKXNbcl09W3AuSChhKV0KZWxzZXtpZihwLlIocSxhKT49MClyZXR1cm4hMQpxLnB1
+c2gocC5IKGEpKX1yZXR1cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlmKHR5cGVvZiBi
+PT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkg0KHMuYixiKQplbHNlIGlmKHR5cGVv
+ZiBiPT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXJldHVybiBzLkg0KHMuYyxiKQplbHNlIHJl
+dHVybiBzLnFnKGIpfSwKcWc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzLG49by5kCmlmKG49
+PW51bGwpcmV0dXJuITEKcz1vLk4oYSkKcj1uW3NdCnE9by5SKHIsYSkKaWYocTwwKXJldHVybiExCnA9
+ci5zcGxpY2UocSwxKVswXQppZigwPT09ci5sZW5ndGgpZGVsZXRlIG5bc10Kby5HUyhwKQpyZXR1cm4h
+MH0sClM6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih0LmUuYShhW2JdKSE9bnVsbCly
+ZXR1cm4hMQphW2JdPXRoaXMuSChiKQpyZXR1cm4hMH0sCkg0OmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYo
+YT09bnVsbClyZXR1cm4hMQpzPXQuZS5hKGFbYl0pCmlmKHM9PW51bGwpcmV0dXJuITEKdGhpcy5HUyhz
+KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sCkdZOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjEwNzM3
+NDE4MjN9LApIOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgocikuYy5hKGEp
+KQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9cwpyLmY9cy5i
+PXF9KytyLmEKci5HWSgpCnJldHVybiBxfSwKR1M6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPWEuYyxx
+PWEuYgppZihyPT1udWxsKXMuZT1xCmVsc2Ugci5iPXEKaWYocT09bnVsbClzLmY9cgplbHNlIHEuYz1y
+Oy0tcy5hCnMuR1koKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sClI6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGE9PW51bGwpcmV0dXJuLTEKcz1hLmxlbmd0aApmb3Iocj0w
+O3I8czsrK3IpaWYoSi5STShhW3JdLmEsYikpcmV0dXJuIHIKcmV0dXJuLTF9fQpQLmJuLnByb3RvdHlw
+ZT17fQpQLmxtLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rp
+b24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5hCmlmKHMuYiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkK
+ZWxzZSBpZihyPT1udWxsKXtzLnNqKG51bGwpCnJldHVybiExfWVsc2V7cy5zaihzLiR0aS5DKCIxPyIp
+LmEoci5hKSkKcy5jPXIuYgpyZXR1cm4hMH19LApzajpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
+QygiMT8iKS5hKGEpfSwKJGlBbjoxfQpQLm1XLnByb3RvdHlwZT17fQpQLnV5LnByb3RvdHlwZT17JGli
+UToxLCRpY1g6MSwkaXpNOjF9ClAubEQucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBILmE3KGEsdGhpcy5nQShhKSxILnooYSkuQygiYTc8bEQuRT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC56KGEpLkMoIn4obEQu
+RSkiKS5hKGIpCnM9dGhpcy5nQShhKQpmb3Iocj0wO3I8czsrK3Ipe2IuJDEodGhpcy5xKGEscikpCmlm
+KHMhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ0EoYSk9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdsMChhKX0sCkUyOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcz1ILnooYSkKcmV0dXJuIG5ldyBILmxKKGEscy5LcShjKS5DKCIxKGxE
+LkUpIikuYShiKSxzLkMoIkA8bEQuRT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKZVI6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gSC5xQyhhLGIsbnVsbCxILnooYSkuQygibEQuRSIpKX0sCmRyOmZ1bmN0aW9uKGEs
+Yil7cmV0dXJuIG5ldyBILmpWKGEsSC56KGEpLkMoIkA8bEQuRT4iKS5LcShiKS5DKCJqVjwxLDI+Iikp
+fSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMKSC56KGEpLkMoImxELkU/IikuYShkKQpQLmpCKGIs
+Yyx0aGlzLmdBKGEpKQpmb3Iocz1iO3M8YzsrK3MpdGhpcy5ZNShhLHMsZCl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQLmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3RvdHlwZT17
+CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmEKaWYoIXIuYSl0aGlzLmIuYSs9IiwgIgpyLmE9
+ITEKcj10aGlzLmIKcz1yLmErPUguRWooYSkKci5hPXMrIjogIgpyLmErPUguRWooYil9LAokUzoxMH0K
+UC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILkxoKHRoaXMpLkMoIn4oWWsu
+SyxZay5WKSIpLmEoYikKZm9yKHM9Si5JVCh0aGlzLmd2YygpKTtzLkYoKTspe3I9cy5nbCgpCmIuJDIo
+cix0aGlzLnEoMCxyKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ3ZjKCksbmV3
+IFAueVEodGhpcyksSC5MaCh0aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEouemwodGhpcy5ndmMoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMu
+Z3ZjKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuZ3ZjKCkpfSwKdzpmdW5jdGlv
+bihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCiRpWjA6MX0KUC55US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt2YXIgcz10aGlzLmEscj1ILkxoKHMpCnIuQygiWWsuSyIpLmEoYSkKcmV0dXJuIG5ldyBQLk4z
+KGEscy5xKDAsYSksci5DKCJAPFlrLks+IikuS3Eoci5DKCJZay5WIikpLkMoIk4zPDEsMj4iKSl9LAok
+UzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYSkuQygiTjM8WWsuSyxZay5WPihZay5LKSIpfX0K
+UC5LUC5wcm90b3R5cGU9ewpZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQpzLmMuYShi
+KQpzLlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgbWFw
+IikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5xKDAsYil9
+LApZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQp0aGlzLmEuWTUoMCxzLmMuYShiKSxz
+LlFbMV0uYShjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlv
+bihhLGIpe3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5hKGIpKX0sCmdsMDpmdW5jdGlv
+bihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ2wwKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cy5hCnJldHVybiBzLmdBKHMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5qKHRoaXMuYSl9LApnUHU6
+ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmdQdShzKX0sCiRpWjA6MX0KUC5Hai5wcm90
+b3R5cGU9e30KUC5sZi5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhp
+cyk9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpIT09MH0sCkZWOmZ1bmN0
+aW9uKGEsYil7dmFyIHMKZm9yKHM9Si5JVChILkxoKHRoaXMpLkMoImNYPGxmLkU+IikuYShiKSk7cy5G
+KCk7KXRoaXMuaSgwLHMuZ2woKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsiLCJ9
+Iil9LAprOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSlyZXR1cm4i
+IgppZihiPT09IiIpe3M9IiIKZG8gcys9SC5FaihyLmQpCndoaWxlKHIuRigpKX1lbHNle3M9SC5Faihy
+LmQpCmZvcig7ci5GKCk7KXM9cytiK0guRWooci5kKX1yZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6
+c30sCmVSOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguYksodGhpcyxiLEguTGgodGhpcykuQygibGYuRSIp
+KX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscD0iaW5kZXgiCkguY2IoYixwLHQuUykKUC5rMShi
+LHApCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmQKaWYoYj09PXIpcmV0dXJuIHE7
+KytyfXRocm93IEguYihQLkNmKGIsdGhpcyxwLG51bGwscikpfX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6
+MSwkaWNYOjEsJGl4dToxfQpQLlh2LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAublku
+cHJvdG90eXBlPXt9ClAuV1kucHJvdG90eXBlPXt9ClAuUlUucHJvdG90eXBlPXt9ClAucFIucHJvdG90
+eXBlPXt9ClAudXcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5iCmlmKHI9
+PW51bGwpcmV0dXJuIHRoaXMuYy5xKDAsYikKZWxzZSBpZih0eXBlb2YgYiE9InN0cmluZyIpcmV0dXJu
+IG51bGwKZWxzZXtzPXJbYl0KcmV0dXJuIHR5cGVvZiBzPT0idW5kZWZpbmVkIj90aGlzLmZiKGIpOnN9
+fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYj09bnVsbD90aGlzLmMuYTp0aGlzLkNmKCkubGVu
+Z3RofSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCmd2YzpmdW5jdGlv
+bigpe2lmKHRoaXMuYj09bnVsbCl7dmFyIHM9dGhpcy5jCnJldHVybiBuZXcgSC5pNShzLEguTGgocyku
+QygiaTU8MT4iKSl9cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBz
+LHIscT10aGlzCmlmKHEuYj09bnVsbClxLmMuWTUoMCxiLGMpCmVsc2UgaWYocS54NChiKSl7cz1xLmIK
+c1tiXT1jCnI9cS5hCmlmKHI9PW51bGw/cyE9bnVsbDpyIT09cylyW2JdPW51bGx9ZWxzZSBxLlhLKCku
+WTUoMCxiLGMpfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodGhpcy5iPT1udWxsKXJldHVybiB0aGlzLmMueDQo
+YSkKcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSl9LApL
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz10aGlzCnQuY0EuYShiKQppZihvLmI9PW51bGwpcmV0
+dXJuIG8uYy5LKDAsYikKcz1vLkNmKCkKZm9yKHI9MDtyPHMubGVuZ3RoOysrcil7cT1zW3JdCnA9by5i
+W3FdCmlmKHR5cGVvZiBwPT0idW5kZWZpbmVkIil7cD1QLlFlKG8uYVtxXSkKby5iW3FdPXB9Yi4kMihx
+LHApCmlmKHMhPT1vLmMpdGhyb3cgSC5iKFAuYTQobykpfX0sCkNmOmZ1bmN0aW9uKCl7dmFyIHM9dC5i
+TS5hKHRoaXMuYykKaWYocz09bnVsbClzPXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdC5z
+KQpyZXR1cm4gc30sClhLOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuPXRoaXMKaWYobi5iPT1udWxs
+KXJldHVybiBuLmMKcz1QLkZsKHQuTix0LnopCnI9bi5DZigpCmZvcihxPTA7cD1yLmxlbmd0aCxxPHA7
+KytxKXtvPXJbcV0Kcy5ZNSgwLG8sbi5xKDAsbykpfWlmKHA9PT0wKUMuTm0uaShyLCIiKQplbHNlIEMu
+Tm0uc0EociwwKQpuLmE9bi5iPW51bGwKcmV0dXJuIG4uYz1zfSwKZmI6ZnVuY3Rpb24oYSl7dmFyIHMK
+aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSkpcmV0dXJuIG51
+bGwKcz1QLlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT1zfX0KUC5pOC5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LApFOmZ1bmN0aW9uKGEsYil7
+dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbClzPXMuZ3ZjKCkuRSgwLGIpCmVsc2V7cz1zLkNmKCkKaWYo
+YjwwfHxiPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnM9c1tiXX1yZXR1cm4gc30sCmdtOmZ1bmN0
+aW9uKGEpe3ZhciBzPXRoaXMuYQppZihzLmI9PW51bGwpe3M9cy5ndmMoKQpzPXMuZ20ocyl9ZWxzZXtz
+PXMuQ2YoKQpzPW5ldyBKLm0xKHMscy5sZW5ndGgsSC50NihzKS5DKCJtMTwxPiIpKX1yZXR1cm4gc30s
+CnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19ClAucGcucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt2YXIgcyxyCnRyeXtzPW5ldyBUZXh0RGVjb2RlcigidXRmLTgiLHtmYXRhbDp0cnVl
+fSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCiRTOjExfQpQLmMyLnByb3Rv
+dHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7
+ZmF0YWw6ZmFsc2V9KQpyZXR1cm4gc31jYXRjaChyKXtILlJ1KHIpfXJldHVybiBudWxsfSwKJFM6MTF9
+ClAuQ1YucHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYTAsYTEsYTIpe3ZhciBzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGMsYixhPSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMj1Q
+LmpCKGExLGEyLGEwLmxlbmd0aCkKcz0kLlY3KCkKZm9yKHI9YTEscT1yLHA9bnVsbCxvPS0xLG49LTEs
+bT0wO3I8YTI7cj1sKXtsPXIrMQprPUMueEIuVyhhMCxyKQppZihrPT09Mzcpe2o9bCsyCmlmKGo8PWEy
+KXtpPUgub28oQy54Qi5XKGEwLGwpKQpoPUgub28oQy54Qi5XKGEwLGwrMSkpCmc9aSoxNitoLShoJjI1
+NikKaWYoZz09PTM3KWc9LTEKbD1qfWVsc2UgZz0tMX1lbHNlIGc9awppZigwPD1nJiZnPD0xMjcpe2lm
+KGc8MHx8Zz49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxnKQpmPXNbZ10KaWYoZj49MCl7Zz1DLnhCLk8y
+KCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1
+Njc4OSsvIixmKQppZihnPT09ayljb250aW51ZQprPWd9ZWxzZXtpZihmPT09LTEpe2lmKG88MCl7ZT1w
+PT1udWxsP251bGw6cC5hLmxlbmd0aAppZihlPT1udWxsKWU9MApvPWUrKHItcSkKbj1yfSsrbQppZihr
+PT09NjEpY29udGludWV9az1nfWlmKGYhPT0tMil7aWYocD09bnVsbCl7cD1uZXcgUC5SbigiIikKZT1w
+fWVsc2UgZT1wCmUuYSs9Qy54Qi5OaihhMCxxLHIpCmUuYSs9SC5MdyhrKQpxPWwKY29udGludWV9fXRo
+cm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBkYXRhIixhMCxyKSl9aWYocCE9bnVsbCl7ZT1wLmEr
+PUMueEIuTmooYTAscSxhMikKZD1lLmxlbmd0aAppZihvPj0wKVAueE0oYTAsbixhMixvLG0sZCkKZWxz
+ZXtjPUMuam4uelkoZC0xLDQpKzEKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmZvcig7
+Yzw0Oyl7ZSs9Ij0iCnAuYT1lOysrY319ZT1wLmEKcmV0dXJuIEMueEIuaTcoYTAsYTEsYTIsZS5jaGFy
+Q29kZUF0KDApPT0wP2U6ZSl9Yj1hMi1hMQppZihvPj0wKVAueE0oYTAsbixhMixvLG0sYikKZWxzZXtj
+PUMuam4uelkoYiw0KQppZihjPT09MSl0aHJvdyBILmIoUC5ycihhLGEwLGEyKSkKaWYoYz4xKWEwPUMu
+eEIuaTcoYTAsYTIsYTIsYz09PTI/Ij09IjoiPSIpfXJldHVybiBhMH19ClAuVTgucHJvdG90eXBlPXt9
+ClAuVWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9ClAuVWQu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz1QLnAodGhpcy5hKQpyZXR1cm4odGhpcy5iIT1u
+dWxsPyJDb252ZXJ0aW5nIG9iamVjdCB0byBhbiBlbmNvZGFibGUgb2JqZWN0IGZhaWxlZDoiOiJDb252
+ZXJ0aW5nIG9iamVjdCBkaWQgbm90IHJldHVybiBhbiBlbmNvZGFibGUgb2JqZWN0OiIpKyIgIitzfX0K
+UC5LOC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJDeWNsaWMgZXJyb3IgaW4gSlNPTiBz
+dHJpbmdpZnkifX0KUC5ieS5wcm90b3R5cGU9ewpwVzpmdW5jdGlvbihhLGIsYyl7dmFyIHMKdC5mVi5h
+KGMpCnM9UC5CUyhiLHRoaXMuZ0hlKCkuYSkKcmV0dXJuIHN9LApPQjpmdW5jdGlvbihhLGIpe3ZhciBz
+CnQuZEEuYShiKQpzPVAudVgoYSx0aGlzLmdaRSgpLmIsbnVsbCkKcmV0dXJuIHN9LApnWkU6ZnVuY3Rp
+b24oKXtyZXR1cm4gQy5uWH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5vai5wcm90b3R5
+cGU9e30KUC5NeC5wcm90b3R5cGU9e30KUC5TaC5wcm90b3R5cGU9ewp2cDpmdW5jdGlvbihhKXt2YXIg
+cyxyLHEscCxvLG4sbSxsPWEubGVuZ3RoCmZvcihzPUouclkoYSkscj10aGlzLmMscT0wLHA9MDtwPGw7
+KytwKXtvPXMuVyhhLHApCmlmKG8+OTIpe2lmKG8+PTU1Mjk2KXtuPW8mNjQ1MTIKaWYobj09PTU1Mjk2
+KXttPXArMQptPSEobTxsJiYoQy54Qi5XKGEsbSkmNjQ1MTIpPT09NTYzMjApfWVsc2UgbT0hMQppZigh
+bSlpZihuPT09NTYzMjApe249cC0xCm49IShuPj0wJiYoQy54Qi5PMihhLG4pJjY0NTEyKT09PTU1Mjk2
+KX1lbHNlIG49ITEKZWxzZSBuPSEwCmlmKG4pe2lmKHA+cSlyLmErPUMueEIuTmooYSxxLHApCnE9cCsx
+CnIuYSs9SC5Mdyg5MikKci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDEwMCkKbj1vPj4+OCYxNQpyLmEr
+PUguTHcobjwxMD80OCtuOjg3K24pCm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpu
+PW8mMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKX19Y29udGludWV9aWYobzwzMil7aWYocD5xKXIu
+YSs9Qy54Qi5OaihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpzd2l0Y2gobyl7Y2FzZSA4OnIuYSs9
+SC5Mdyg5OCkKYnJlYWsKY2FzZSA5OnIuYSs9SC5MdygxMTYpCmJyZWFrCmNhc2UgMTA6ci5hKz1ILkx3
+KDExMCkKYnJlYWsKY2FzZSAxMjpyLmErPUguTHcoMTAyKQpicmVhawpjYXNlIDEzOnIuYSs9SC5Mdygx
+MTQpCmJyZWFrCmRlZmF1bHQ6ci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDQ4KQpyLmErPUguTHcoNDgp
+Cm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpuPW8mMTUKci5hKz1ILkx3KG48MTA/
+NDgrbjo4NytuKQpicmVha319ZWxzZSBpZihvPT09MzR8fG89PT05Mil7aWYocD5xKXIuYSs9Qy54Qi5O
+aihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpyLmErPUguTHcobyl9fWlmKHE9PT0wKXIuYSs9SC5F
+aihhKQplbHNlIGlmKHE8bClyLmErPXMuTmooYSxxLGwpfSwKSm46ZnVuY3Rpb24oYSl7dmFyIHMscixx
+LHAKZm9yKHM9dGhpcy5hLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9c1txXQppZihhPT1udWxsP3A9
+PW51bGw6YT09PXApdGhyb3cgSC5iKG5ldyBQLks4KGEsbnVsbCkpfUMuTm0uaShzLGEpfSwKaVU6ZnVu
+Y3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8udE0oYSkpcmV0dXJuCm8uSm4oYSkKdHJ5e3M9
+by5iLiQxKGEpCmlmKCFvLnRNKHMpKXtxPVAuR3koYSxudWxsLG8uZ1ZLKCkpCnRocm93IEguYihxKX1x
+PW8uYQppZigwPj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLC0xKQpxLnBvcCgpfWNhdGNoKHApe3I9SC5S
+dShwKQpxPVAuR3koYSxyLG8uZ1ZLKCkpCnRocm93IEguYihxKX19LAp0TTpmdW5jdGlvbihhKXt2YXIg
+cyxyLHE9dGhpcwppZih0eXBlb2YgYT09Im51bWJlciIpe2lmKCFpc0Zpbml0ZShhKSlyZXR1cm4hMQpx
+LmMuYSs9Qy5DRC53KGEpCnJldHVybiEwfWVsc2UgaWYoYT09PSEwKXtxLmMuYSs9InRydWUiCnJldHVy
+biEwfWVsc2UgaWYoYT09PSExKXtxLmMuYSs9ImZhbHNlIgpyZXR1cm4hMH1lbHNlIGlmKGE9PW51bGwp
+e3EuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxzZSBpZih0eXBlb2YgYT09InN0cmluZyIpe3M9cS5jCnMu
+YSs9JyInCnEudnAoYSkKcy5hKz0nIicKcmV0dXJuITB9ZWxzZSBpZih0LmouYihhKSl7cS5KbihhKQpx
+LmxLKGEpCnM9cS5hCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcmV0dXJu
+ITB9ZWxzZSBpZih0LmYuYihhKSl7cS5KbihhKQpyPXEuancoYSkKcz1xLmEKaWYoMD49cy5sZW5ndGgp
+cmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpyZXR1cm4gcn1lbHNlIHJldHVybiExfSwKbEs6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxPXRoaXMuYwpxLmErPSJbIgpzPUouVTYoYSkKaWYocy5nb3IoYSkpe3RoaXMu
+aVUocy5xKGEsMCkpCmZvcihyPTE7cjxzLmdBKGEpOysrcil7cS5hKz0iLCIKdGhpcy5pVShzLnEoYSxy
+KSl9fXEuYSs9Il0ifSwKanc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPXt9Cmlm
+KGEuZ2wwKGEpKXttLmMuYSs9Int9IgpyZXR1cm4hMH1zPWEuZ0EoYSkqMgpyPVAuTzgocyxudWxsLCEx
+LHQuVykKcT1sLmE9MApsLmI9ITAKYS5LKDAsbmV3IFAudGkobCxyKSkKaWYoIWwuYilyZXR1cm4hMQpw
+PW0uYwpwLmErPSJ7Igpmb3Iobz0nIic7cTxzO3ErPTIsbz0nLCInKXtwLmErPW8KbS52cChILmgocltx
+XSkpCnAuYSs9JyI6JwpuPXErMQppZihuPj1zKXJldHVybiBILk9IKHIsbikKbS5pVShyW25dKX1wLmEr
+PSJ9IgpyZXR1cm4hMH19ClAudGkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlm
+KHR5cGVvZiBhIT0ic3RyaW5nIil0aGlzLmEuYj0hMQpzPXRoaXMuYgpyPXRoaXMuYQpDLk5tLlk1KHMs
+ci5hKyssYSkKQy5ObS5ZNShzLHIuYSsrLGIpfSwKJFM6MTB9ClAudHUucHJvdG90eXBlPXsKZ1ZLOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcy5jLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fQpQLnU1
+LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90b3R5cGU9ewpX
+SjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1QLmpCKDAsbnVsbCxhLmxlbmd0aCksbz1wLTAKaWYobz09
+PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDApCnM9byozCnI9bmV3IFVpbnQ4QXJyYXkocykKcT1uZXcg
+UC5SdyhyKQppZihxLkd4KGEsMCxwKSE9PXApe0ouYTYoYSxwLTEpCnEuUk8oKX1yZXR1cm4gbmV3IFVp
+bnQ4QXJyYXkoci5zdWJhcnJheSgwLEguck0oMCxxLmIscykpKX19ClAuUncucHJvdG90eXBlPXsKUk86
+ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5iLHA9cy5iPXErMSxvPXIubGVuZ3RoCmlmKHE+
+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIzOQpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChy
+LHApCnJbcF09MTkxCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTg5fSwKTzY6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49dGhpcwppZigoYiY2NDUxMik9PT01NjMyMCl7cz02
+NTUzNisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcj1uLmMKcT1uLmIKcD1uLmI9cSsxCm89ci5sZW5ndGgK
+aWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09cz4+PjE4fDI0MApxPW4uYj1wKzEKaWYocD49byly
+ZXR1cm4gSC5PSChyLHApCnJbcF09cz4+PjEyJjYzfDEyOApwPW4uYj1xKzEKaWYocT49bylyZXR1cm4g
+SC5PSChyLHEpCnJbcV09cz4+PjYmNjN8MTI4Cm4uYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHAp
+CnJbcF09cyY2M3wxMjgKcmV0dXJuITB9ZWxzZXtuLlJPKCkKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciBzLHIscSxwLG8sbixtLGw9dGhpcwppZihiIT09YyYmKEMueEIuTzIoYSxjLTEpJjY0
+NTEyKT09PTU1Mjk2KS0tYwpmb3Iocz1sLmMscj1zLmxlbmd0aCxxPWI7cTxjOysrcSl7cD1DLnhCLlco
+YSxxKQppZihwPD0xMjcpe289bC5iCmlmKG8+PXIpYnJlYWsKbC5iPW8rMQpzW29dPXB9ZWxzZXtvPXAm
+NjQ1MTIKaWYobz09PTU1Mjk2KXtpZihsLmIrND5yKWJyZWFrCm49cSsxCmlmKGwuTzYocCxDLnhCLlco
+YSxuKSkpcT1ufWVsc2UgaWYobz09PTU2MzIwKXtpZihsLmIrMz5yKWJyZWFrCmwuUk8oKX1lbHNlIGlm
+KHA8PTIwNDcpe289bC5iCm09bysxCmlmKG0+PXIpYnJlYWsKbC5iPW0KaWYobz49cilyZXR1cm4gSC5P
+SChzLG8pCnNbb109cD4+PjZ8MTkyCmwuYj1tKzEKc1ttXT1wJjYzfDEyOH1lbHNle289bC5iCmlmKG8r
+Mj49cilicmVhawptPWwuYj1vKzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cD4+PjEyfDIy
+NApvPWwuYj1tKzEKaWYobT49cilyZXR1cm4gSC5PSChzLG0pCnNbbV09cD4+PjYmNjN8MTI4CmwuYj1v
+KzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cCY2M3wxMjh9fX1yZXR1cm4gcX19ClAuR1ku
+cHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHMscgp0LkwuYShhKQpzPXRoaXMuYQpyPVAua3ko
+cyxhLDAsbnVsbCkKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gbmV3IFAuYnoocykuTmUoYSwwLG51
+bGwsITApfX0KUC5iei5wcm90b3R5cGU9ewpOZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxv
+LG49dGhpcwp0LkwuYShhKQpzPVAuakIoYixjLEouSG0oYSkpCmlmKGI9PT1zKXJldHVybiIiCnI9UC5q
+eShhLGIscykKcT1uLmhPKHIsMCxzLWIsITApCnA9bi5iCmlmKChwJjEpIT09MCl7bz1QLmo0KHApCm4u
+Yj0wCnRocm93IEguYihQLnJyKG8sYSxiK24uYykpfXJldHVybiBxfSwKaE86ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHMscixxPXRoaXMKaWYoYy1iPjEwMDApe3M9Qy5qbi5CVShiK2MsMikKcj1xLmhPKGEsYixz
+LCExKQppZigocS5iJjEpIT09MClyZXR1cm4gcgpyZXR1cm4gcitxLmhPKGEscyxjLGQpfXJldHVybiBx
+LkVoKGEsYixjLGQpfSwKRWg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMsaj02NTUzMyxpPWsuYixoPWsuYyxnPW5ldyBQLlJuKCIiKSxmPWIrMSxlPWEubGVuZ3RoCmlmKGI8
+MHx8Yj49ZSlyZXR1cm4gSC5PSChhLGIpCnM9YVtiXQokbGFiZWwwJDA6Zm9yKHI9ay5hOyEwOyl7Zm9y
+KDshMDtmPW8pe3E9Qy54Qi5XKCJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
 QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
-QUFBQUFBQUFBQUFBQUFBQUFBQUZGRkZGRkZGRkZGRkZGRkZHR0dHR0dHR0dHR0dHR0dHSEhISEhISEhI
-SEhISEhISEhISEhISEhISEhISUhISEpFRUJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQktDQ0ND
-Q0NDQ0NDQ0NEQ0xPTk5OTUVFRUVFRUVFRUVFIixzKSYzMQpoPWk8PTMyP3MmNjE2OTQ+Pj5xOihzJjYz
-fGg8PDYpPj4+MAppPUMueEIuVygiIFx4MDAwOlhFQ0NDQ0NOOmxEYiBceDAwMDpYRUNDQ0NDTnZsRGIg
-XHgwMDA6WEVDQ0NDQ046bERiIEFBQUFBXHgwMFx4MDBceDAwXHgwMFx4MDBBQUFBQTAwMDAwQUFBQUE6
-Ojo6OkFBQUFBR0cwMDBBQUFBQTAwS0tLQUFBQUFHOjo6OkFBQUFBOklJSUlBQUFBQTAwMFx4ODAwQUFB
-QUFceDAwXHgwMFx4MDBceDAwIEFBQUFBIixpK3EpCmlmKGk9PT0wKXtnLmErPUguTHcoaCkKaWYoZj09
-PWMpYnJlYWsgJGxhYmVsMCQwCmJyZWFrfWVsc2UgaWYoKGkmMSkhPT0wKXtpZihyKXN3aXRjaChpKXtj
-YXNlIDY5OmNhc2UgNjc6Zy5hKz1ILkx3KGopCmJyZWFrCmNhc2UgNjU6Zy5hKz1ILkx3KGopOy0tZgpi
-cmVhawpkZWZhdWx0OnA9Zy5hKz1ILkx3KGopCmcuYT1wK0guTHcoaikKYnJlYWt9ZWxzZXtrLmI9aQpr
-LmM9Zi0xCnJldHVybiIifWk9MH1pZihmPT09YylicmVhayAkbGFiZWwwJDAKbz1mKzEKaWYoZjwwfHxm
-Pj1lKXJldHVybiBILk9IKGEsZikKcz1hW2ZdfW89ZisxCmlmKGY8MHx8Zj49ZSlyZXR1cm4gSC5PSChh
-LGYpCnM9YVtmXQppZihzPDEyOCl7d2hpbGUoITApe2lmKCEobzxjKSl7bj1jCmJyZWFrfW09bysxCmlm
-KG88MHx8bz49ZSlyZXR1cm4gSC5PSChhLG8pCnM9YVtvXQppZihzPj0xMjgpe249bS0xCm89bQpicmVh
-a31vPW19aWYobi1mPDIwKWZvcihsPWY7bDxuOysrbCl7aWYobD49ZSlyZXR1cm4gSC5PSChhLGwpCmcu
-YSs9SC5MdyhhW2xdKX1lbHNlIGcuYSs9UC5ITShhLGYsbikKaWYobj09PWMpYnJlYWsgJGxhYmVsMCQw
-CmY9b31lbHNlIGY9b31pZihkJiZpPjMyKWlmKHIpZy5hKz1ILkx3KGopCmVsc2V7ay5iPTc3CmsuYz1j
-CnJldHVybiIifWsuYj1pCmsuYz1oCmU9Zy5hCnJldHVybiBlLmNoYXJDb2RlQXQoMCk9PTA/ZTplfX0K
-UC5XRi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQp0LmZvLmEoYSkKcz10aGlz
-LmIKcj10aGlzLmEKcy5hKz1yLmEKcT1zLmErPUguRWooYS5hKQpzLmE9cSsiOiAiCnMuYSs9UC5obChi
-KQpyLmE9IiwgIn0sCiRTOjQzfQpQLmlQLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09
-bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApn
-aU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybihzXkMuam4ud0cocywzMCkpJjEwNzM3NDE4
-MjN9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1QLkdxKEgudEoocykpLHE9UC5oMChILk5TKHMp
-KSxwPVAuaDAoSC5qQShzKSksbz1QLmgwKEguSVgocykpLG49UC5oMChILmNoKHMpKSxtPVAuaDAoSC5K
-ZChzKSksbD1QLlZ4KEgubzEocykpLGs9cisiLSIrcSsiLSIrcCsiICIrbysiOiIrbisiOiIrbSsiLiIr
-bApyZXR1cm4ga319ClAuWFMucHJvdG90eXBlPXsKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIEgudHModGhp
-cy4kdGhyb3duSnNFcnJvcil9fQpQLkM2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5hCmlmKHMhPW51bGwpcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5obChzKQpyZXR1cm4iQXNz
-ZXJ0aW9uIGZhaWxlZCJ9fQpQLkV6LnByb3RvdHlwZT17fQpQLkYucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7
-cmV0dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7
-cmV0dXJuIiJ9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cD09bnVsbD8iIjoi
-ICgiK3ArIikiLG49cS5kLG09bj09bnVsbD8iIjoiOiAiK0guRWoobiksbD1xLmdaKCkrbyttCmlmKCFx
-LmEpcmV0dXJuIGwKcz1xLmd1KCkKcj1QLmhsKHEuYikKcmV0dXJuIGwrcysiOiAiK3J9fQpQLmJKLnBy
-b3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2
-YXIgcyxyPXRoaXMuZSxxPXRoaXMuZgppZihyPT1udWxsKXM9cSE9bnVsbD8iOiBOb3QgbGVzcyB0aGFu
-IG9yIGVxdWFsIHRvICIrSC5FaihxKToiIgplbHNlIGlmKHE9PW51bGwpcz0iOiBOb3QgZ3JlYXRlciB0
-aGFuIG9yIGVxdWFsIHRvICIrSC5FaihyKQplbHNlIGlmKHE+cilzPSI6IE5vdCBpbiBpbmNsdXNpdmUg
-cmFuZ2UgIitILkVqKHIpKyIuLiIrSC5FaihxKQplbHNlIHM9cTxyPyI6IFZhbGlkIHZhbHVlIHJhbmdl
-IGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5FaihyKQpyZXR1cm4gc319ClAuZVku
-cHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigp
-e3ZhciBzLHI9SC51UCh0aGlzLmIpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuSigpCmlm
-KHI8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKcz10aGlzLmYKaWYocz09PTAp
-cmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNob3VsZCBiZSBsZXNz
-IHRoYW4gIitILkVqKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPXt9LGk9bmV3IFAu
-Um4oIiIpCmouYT0iIgpzPWsuYwpmb3Iocj1zLmxlbmd0aCxxPTAscD0iIixvPSIiO3E8cjsrK3Esbz0i
-LCAiKXtuPXNbcV0KaS5hPXArbwpwPWkuYSs9UC5obChuKQpqLmE9IiwgIn1rLmQuSygwLG5ldyBQLldG
-KGosaSkpCm09UC5obChrLmEpCmw9aS53KDApCnI9Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90
-IGZvdW5kOiAnIitILkVqKGsuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbSsiXG5Bcmd1bWVudHM6IFsiK2wr
-Il0iCnJldHVybiByfX0KUC51Yi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJVbnN1cHBv
-cnRlZCBvcGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMuYQpyZXR1cm4gcyE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAiK3M6IlVuaW1wbGVt
-ZW50ZWRFcnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkJhZCBzdGF0
-ZTogIit0aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCmlm
-KHM9PW51bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb24uIgpy
-ZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjogIitQLmhsKHMpKyIu
-In19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9LApn
-SUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0s
-CiRpWFM6MX0KUC5wLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBz
-PT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9uIjoi
-UmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrcysiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9uIn19
-ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMuYX0s
-CiRpUno6MX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGws
-ayxqLGksaCxnPXRoaXMuYSxmPWchPW51bGwmJiIiIT09Zz8iRm9ybWF0RXhjZXB0aW9uOiAiK0guRWoo
-Zyk6IkZvcm1hdEV4Y2VwdGlvbiIsZT10aGlzLmMsZD10aGlzLmIKaWYodHlwZW9mIGQ9PSJzdHJpbmci
-KXtpZihlIT1udWxsKXM9ZTwwfHxlPmQubGVuZ3RoCmVsc2Ugcz0hMQppZihzKWU9bnVsbAppZihlPT1u
-dWxsKXtpZihkLmxlbmd0aD43OClkPUMueEIuTmooZCwwLDc1KSsiLi4uIgpyZXR1cm4gZisiXG4iK2R9
-Zm9yKHI9MSxxPTAscD0hMSxvPTA7bzxlOysrbyl7bj1DLnhCLlcoZCxvKQppZihuPT09MTApe2lmKHEh
-PT1vfHwhcCkrK3IKcT1vKzEKcD0hMX1lbHNlIGlmKG49PT0xMyl7KytyCnE9bysxCnA9ITB9fWY9cj4x
-P2YrKCIgKGF0IGxpbmUgIityKyIsIGNoYXJhY3RlciAiKyhlLXErMSkrIilcbiIpOmYrKCIgKGF0IGNo
-YXJhY3RlciAiKyhlKzEpKyIpXG4iKQptPWQubGVuZ3RoCmZvcihvPWU7bzxtOysrbyl7bj1DLnhCLk8y
-KGQsbykKaWYobj09PTEwfHxuPT09MTMpe209bwpicmVha319aWYobS1xPjc4KWlmKGUtcTw3NSl7bD1x
-Kzc1Cms9cQpqPSIiCmk9Ii4uLiJ9ZWxzZXtpZihtLWU8NzUpe2s9bS03NQpsPW0KaT0iIn1lbHNle2s9
-ZS0zNgpsPWUrMzYKaT0iLi4uIn1qPSIuLi4ifWVsc2V7bD1tCms9cQpqPSIiCmk9IiJ9aD1DLnhCLk5q
-KGQsayxsKQpyZXR1cm4gZitqK2graSsiXG4iK0MueEIuSXgoIiAiLGUtaytqLmxlbmd0aCkrIl5cbiJ9
-ZWxzZSByZXR1cm4gZSE9bnVsbD9mKygiIChhdCBvZmZzZXQgIitILkVqKGUpKyIpIik6Zn0sCiRpUno6
-MX0KUC5jWC5wcm90b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBILkdKKHRoaXMsSC5MaCh0
-aGlzKS5DKCJjWC5FIiksYil9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQpyZXR1
-cm4gSC5LMSh0aGlzLHMuS3EoYykuQygiMShjWC5FKSIpLmEoYikscy5DKCJjWC5FIiksYyl9LApldjpm
-dW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIG5ldyBILlU1KHRoaXMscy5DKCJhMihj
-WC5FKSIpLmEoYikscy5DKCJVNTxjWC5FPiIpKX0sCnR0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIFAuQ0go
-dGhpcyxiLEguTGgodGhpcykuQygiY1guRSIpKX0sCmJyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnR0
-KGEsITApfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmdtKHRoaXMpCmZvcihzPTA7ci5GKCk7
-KSsrcwpyZXR1cm4gc30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbSh0aGlzKS5GKCl9LApn
-b3I6ZnVuY3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2wwKHRoaXMpfSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gSC5iSyh0aGlzLGIsSC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKZ3I4OmZ1bmN0aW9uKGEpe3ZhciBz
-LHI9dGhpcy5nbSh0aGlzKQppZighci5GKCkpdGhyb3cgSC5iKEguV3AoKSkKcz1yLmdsKCkKaWYoci5G
-KCkpdGhyb3cgSC5iKEguQW0oKSkKcmV0dXJuIHN9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxClAu
-azEoYiwiaW5kZXgiKQpmb3Iocz10aGlzLmdtKHRoaXMpLHI9MDtzLkYoKTspe3E9cy5nbCgpCmlmKGI9
-PT1yKXJldHVybiBxOysrcn10aHJvdyBILmIoUC5DZihiLHRoaXMsImluZGV4IixudWxsLHIpKX0sCnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90eXBlPXt9ClAu
-TjMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iTWFwRW50cnkoIitILkVqKEouaih0aGlz
-LmEpKSsiOiAiK0guRWooSi5qKHRoaXMuYikpKyIpIn19ClAuYzgucHJvdG90eXBlPXsKZ2lPOmZ1bmN0
-aW9uKGEpe3JldHVybiBQLk1oLnByb3RvdHlwZS5naU8uY2FsbChDLmpOLHRoaXMpfSwKdzpmdW5jdGlv
-bihhKXtyZXR1cm4ibnVsbCJ9fQpQLk1oLnByb3RvdHlwZT17Y29uc3RydWN0b3I6UC5NaCwkaU1oOjEs
-CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBI
-LmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0odGhp
-cykpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dC5vLmEoYikKdGhyb3cgSC5iKFAubHIodGhpcyxiLmdX
-YSgpLGIuZ25kKCksYi5nVm0oKSkpfSwKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy53KHRo
-aXMpfX0KUC5aZC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiIifSwKJGlHejoxfQpQLlJu
-LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlv
-bihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LAokaUJMOjF9ClAu
-bjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscAp0LkouYShhKQpILmgoYikK
-cz1KLnJZKGIpLk9ZKGIsIj0iKQppZihzPT09LTEpe2lmKGIhPT0iIilhLlkoMCxQLmt1KGIsMCxiLmxl
-bmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHMhPT0wKXtyPUMueEIuTmooYiwwLHMpCnE9Qy54Qi5H
-KGIscysxKQpwPXRoaXMuYQphLlkoMCxQLmt1KHIsMCxyLmxlbmd0aCxwLCEwKSxQLmt1KHEsMCxxLmxl
-bmd0aCxwLCEwKSl9cmV0dXJuIGF9LAokUzo0NX0KUC5jUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
-LGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAok
-UzoyMX0KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxl
-Z2FsIElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy4kMihhLG51bGwpfSwKJFM6NTB9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIg
-cwppZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250YWluIGEgbWF4aW11
-bSBvZiA0IGhleCBkaWdpdHMiLGEpCnM9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIpLDE2KQppZihzPDB8
-fHM+NjU1MzUpdGhpcy5hLiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4u
-MHhGRkZGYCIsYSkKcmV0dXJuIHN9LAokUzo1Mn0KUC5Ebi5wcm90b3R5cGU9ewpnbkQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscCxvPXRoaXMKaWYoIW8ueSl7cz1vLmEKcj1zLmxlbmd0aCE9PTA/cysiOiI6IiIK
-cT1vLmMKcD1xPT1udWxsCmlmKCFwfHxzPT09ImZpbGUiKXtzPXIrIi8vIgpyPW8uYgppZihyLmxlbmd0
-aCE9PTApcz1zK3IrIkAiCmlmKCFwKXMrPXEKcj1vLmQKaWYociE9bnVsbClzPXMrIjoiK0guRWoocil9
-ZWxzZSBzPXIKcys9by5lCnI9by5mCmlmKHIhPW51bGwpcz1zKyI/IityCnI9by5yCmlmKHIhPW51bGwp
-cz1zKyIjIityCmlmKG8ueSl0aHJvdyBILmIoSC5jKCJGaWVsZCAnX3RleHQnIGhhcyBiZWVuIGFzc2ln
-bmVkIGR1cmluZyBpbml0aWFsaXphdGlvbi4iKSkKby54PXMuY2hhckNvZGVBdCgwKT09MD9zOnMKby55
-PSEwfXJldHVybiBvLnh9LApnRmo6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcwppZighcS5RKXtzPXEu
-ZQppZihzLmxlbmd0aCE9PTAmJkMueEIuVyhzLDApPT09NDcpcz1DLnhCLkcocywxKQpyPXMubGVuZ3Ro
-PT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTShzLnNwbGl0KCIvIiksdC5zKSx0LmRPLmEoUC5QSCgp
-KSx0LmRvKSx0Lk4pCmlmKHEuUSl0aHJvdyBILmIoSC5jKCJGaWVsZCAncGF0aFNlZ21lbnRzJyBoYXMg
-YmVlbiBhc3NpZ25lZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24uIikpCnEuc0twKHIpCnEuUT0hMH1yZXR1
-cm4gcS56fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcwppZighci5jeCl7cz1KLmhmKHIuZ25E
-KCkpCmlmKHIuY3gpdGhyb3cgSC5iKEguYygiRmllbGQgJ2hhc2hDb2RlJyBoYXMgYmVlbiBhc3NpZ25l
-ZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24uIikpCnIuY2g9cwpyLmN4PSEwfXJldHVybiByLmNofSwKZ2hZ
-OmZ1bmN0aW9uKCl7dmFyIHMscj10aGlzCmlmKCFyLmRiKXtzPVAuV1goci5ndFAoKSkKaWYoci5kYil0
-aHJvdyBILmIoSC5jKCJGaWVsZCAncXVlcnlQYXJhbWV0ZXJzJyBoYXMgYmVlbiBhc3NpZ25lZCBkdXJp
-bmcgaW5pdGlhbGl6YXRpb24uIikpCnIuc05NKG5ldyBQLkdqKHMsdC5kdykpCnIuZGI9ITB9cmV0dXJu
-IHIuY3l9LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBz
-PXRoaXMuYwppZihzPT1udWxsKXJldHVybiIiCmlmKEMueEIubihzLCJbIikpcmV0dXJuIEMueEIuTmoo
-cywxLHMubGVuZ3RoLTEpCnJldHVybiBzfSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZApyZXR1
-cm4gcz09bnVsbD9QLndLKHRoaXMuYSk6c30sCmd0UDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZgpyZXR1
-cm4gcz09bnVsbD8iIjpzfSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5yCnJldHVybiBzPT1udWxs
-PyIiOnN9LApubTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqPXRoaXMKdC5jOS5h
-KGIpCnM9ai5hCnI9cz09PSJmaWxlIgpxPWouYgpwPWouZApvPWouYwppZighKG8hPW51bGwpKW89cS5s
-ZW5ndGghPT0wfHxwIT1udWxsfHxyPyIiOm51bGwKbj1qLmUKaWYoIXIpbT1vIT1udWxsJiZuLmxlbmd0
-aCE9PTAKZWxzZSBtPSEwCmlmKG0mJiFDLnhCLm4obiwiLyIpKW49Ii8iK24KbD1uCms9UC5sZShudWxs
-LDAsMCxiKQpyZXR1cm4gbmV3IFAuRG4ocyxxLG8scCxsLGssai5yKX0sCkpoOmZ1bmN0aW9uKGEsYil7
-dmFyIHMscixxLHAsbyxuCmZvcihzPTAscj0wO0MueEIuUWkoYiwiLi4vIixyKTspe3IrPTM7KytzfXE9
-Qy54Qi5jbihhLCIvIikKd2hpbGUoITApe2lmKCEocT4wJiZzPjApKWJyZWFrCnA9Qy54Qi5QayhhLCIv
-IixxLTEpCmlmKHA8MClicmVhawpvPXEtcApuPW8hPT0yCmlmKCFufHxvPT09MylpZihDLnhCLk8yKGEs
-cCsxKT09PTQ2KW49IW58fEMueEIuTzIoYSxwKzIpPT09NDYKZWxzZSBuPSExCmVsc2Ugbj0hMQppZihu
-KWJyZWFrOy0tcwpxPXB9cmV0dXJuIEMueEIuaTcoYSxxKzEsbnVsbCxDLnhCLkcoYixyLTMqcykpfSwK
-Wkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscCxvLG4sbSxsLGssaj10aGlzLGk9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3M9YS5n
-RmkoKQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPWEuZ3hBKCk/YS5ndHAoYSk6aX1l
-bHNle3A9aQpxPXAKcj0iIn1vPVAueGUoYS5nSWkoYSkpCm49YS5nUUQoKT9hLmd0UCgpOml9ZWxzZXtz
-PWouYQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPVAud0IoYS5neEEoKT9hLmd0cChh
-KTppLHMpCm89UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aX1lbHNle3I9ai5iCnE9ai5j
-CnA9ai5kCmlmKGEuZ0lpKGEpPT09IiIpe289ai5lCm49YS5nUUQoKT9hLmd0UCgpOmouZn1lbHNle2lm
-KGEuZ3RUKCkpbz1QLnhlKGEuZ0lpKGEpKQplbHNle209ai5lCmlmKG0ubGVuZ3RoPT09MClpZihxPT1u
-dWxsKW89cy5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2Ugbz1QLnhlKCIvIith
-LmdJaShhKSkKZWxzZXtsPWouSmgobSxhLmdJaShhKSkKaz1zLmxlbmd0aD09PTAKaWYoIWt8fHEhPW51
-bGx8fEMueEIubihtLCIvIikpbz1QLnhlKGwpCmVsc2Ugbz1QLndGKGwsIWt8fHEhPW51bGwpfX1uPWEu
-Z1FEKCk/YS5ndFAoKTppfX19cmV0dXJuIG5ldyBQLkRuKHMscixxLHAsbyxuLGEuZ1o4KCk/YS5nS2Eo
-KTppKX0sCmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMhPW51bGx9LApneEE6ZnVuY3Rpb24oKXty
-ZXR1cm4gdGhpcy5kIT1udWxsfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZiE9bnVsbH0sCmda
-ODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54
-Qi5uKHRoaXMuZSwiLyIpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEKaWYocSE9PSIi
-JiZxIT09ImZpbGUiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9t
-IGEgIitxKyIgVVJJIikpCmlmKHIuZ3RQKCkhPT0iIil0aHJvdyBILmIoUC5MNCh1LmkpKQppZihyLmdL
-YSgpIT09IiIpdGhyb3cgSC5iKFAuTDQodS5sKSkKcT0kLndRKCkKaWYoSC5vVChxKSlxPVAubW4ocikK
-ZWxzZXtpZihyLmMhPW51bGwmJnIuZ0pmKHIpIT09IiIpSC52KFAuTDQodS5qKSkKcz1yLmdGaigpClAu
-a0UocywhMSkKcT1QLnZnKEMueEIubihyLmUsIi8iKT8iLyI6IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0
+QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZGRkZGRkZGRkZGRkZGRkZHR0dHR0dHR0dHR0dHR0dH
+SEhISEhISEhISEhISEhISEhISEhISEhISEhISUhISEpFRUJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC
+QkJCQktDQ0NDQ0NDQ0NDQ0NEQ0xPTk5OTUVFRUVFRUVFRUVFIixzKSYzMQpoPWk8PTMyP3MmNjE2OTQ+
+Pj5xOihzJjYzfGg8PDYpPj4+MAppPUMueEIuVygiIFx4MDAwOlhFQ0NDQ0NOOmxEYiBceDAwMDpYRUND
+Q0NDTnZsRGIgXHgwMDA6WEVDQ0NDQ046bERiIEFBQUFBXHgwMFx4MDBceDAwXHgwMFx4MDBBQUFBQTAw
+MDAwQUFBQUE6Ojo6OkFBQUFBR0cwMDBBQUFBQTAwS0tLQUFBQUFHOjo6OkFBQUFBOklJSUlBQUFBQTAw
+MFx4ODAwQUFBQUFceDAwXHgwMFx4MDBceDAwIEFBQUFBIixpK3EpCmlmKGk9PT0wKXtnLmErPUguTHco
+aCkKaWYoZj09PWMpYnJlYWsgJGxhYmVsMCQwCmJyZWFrfWVsc2UgaWYoKGkmMSkhPT0wKXtpZihyKXN3
+aXRjaChpKXtjYXNlIDY5OmNhc2UgNjc6Zy5hKz1ILkx3KGopCmJyZWFrCmNhc2UgNjU6Zy5hKz1ILkx3
+KGopOy0tZgpicmVhawpkZWZhdWx0OnA9Zy5hKz1ILkx3KGopCmcuYT1wK0guTHcoaikKYnJlYWt9ZWxz
+ZXtrLmI9aQprLmM9Zi0xCnJldHVybiIifWk9MH1pZihmPT09YylicmVhayAkbGFiZWwwJDAKbz1mKzEK
+aWYoZjwwfHxmPj1lKXJldHVybiBILk9IKGEsZikKcz1hW2ZdfW89ZisxCmlmKGY8MHx8Zj49ZSlyZXR1
+cm4gSC5PSChhLGYpCnM9YVtmXQppZihzPDEyOCl7d2hpbGUoITApe2lmKCEobzxjKSl7bj1jCmJyZWFr
+fW09bysxCmlmKG88MHx8bz49ZSlyZXR1cm4gSC5PSChhLG8pCnM9YVtvXQppZihzPj0xMjgpe249bS0x
+Cm89bQpicmVha31vPW19aWYobi1mPDIwKWZvcihsPWY7bDxuOysrbCl7aWYobD49ZSlyZXR1cm4gSC5P
+SChhLGwpCmcuYSs9SC5MdyhhW2xdKX1lbHNlIGcuYSs9UC5ITShhLGYsbikKaWYobj09PWMpYnJlYWsg
+JGxhYmVsMCQwCmY9b31lbHNlIGY9b31pZihkJiZpPjMyKWlmKHIpZy5hKz1ILkx3KGopCmVsc2V7ay5i
+PTc3CmsuYz1jCnJldHVybiIifWsuYj1pCmsuYz1oCmU9Zy5hCnJldHVybiBlLmNoYXJDb2RlQXQoMCk9
+PTA/ZTplfX0KUC5XRi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQp0LmZvLmEo
+YSkKcz10aGlzLmIKcj10aGlzLmEKcy5hKz1yLmEKcT1zLmErPUguRWooYS5hKQpzLmE9cSsiOiAiCnMu
+YSs9UC5wKGIpCnIuYT0iLCAifSwKJFM6NDJ9ClAuaVAucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxi
+KXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5pUCYmdGhpcy5hPT09Yi5h
+JiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuKHNeQy5qbi53RyhzLDMwKSkm
+MTA3Mzc0MTgyM30sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPVAuR3EoSC50SihzKSkscT1QLmgw
+KEguTlMocykpLHA9UC5oMChILmpBKHMpKSxvPVAuaDAoSC5JWChzKSksbj1QLmgwKEguY2gocykpLG09
+UC5oMChILkpkKHMpKSxsPVAuVngoSC5vMShzKSksaz1yKyItIitxKyItIitwKyIgIitvKyI6IituKyI6
+IittKyIuIitsCnJldHVybiBrfX0KUC5YUy5wcm90b3R5cGU9ewpnSUk6ZnVuY3Rpb24oKXtyZXR1cm4g
+SC50cyh0aGlzLiR0aHJvd25Kc0Vycm9yKX19ClAuQzYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2
+YXIgcz10aGlzLmEKaWYocyE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAocykKcmV0
+dXJuIkFzc2VydGlvbiBmYWlsZWQifX0KUC5Fei5wcm90b3R5cGU9e30KUC5GLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9mIG51bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpmdW5j
+dGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5j
+dGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXEuYyxvPXA9PW51
+bGw/IiI6IiAoIitwKyIpIixuPXEuZCxtPW49PW51bGw/IiI6IjogIitILkVqKG4pLGw9cS5nWigpK28r
+bQppZighcS5hKXJldHVybiBsCnM9cS5ndSgpCnI9UC5wKHEuYikKcmV0dXJuIGwrcysiOiAiK3J9fQpQ
+LmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rp
+b24oKXt2YXIgcyxyPXRoaXMuZSxxPXRoaXMuZgppZihyPT1udWxsKXM9cSE9bnVsbD8iOiBOb3QgbGVz
+cyB0aGFuIG9yIGVxdWFsIHRvICIrSC5FaihxKToiIgplbHNlIGlmKHE9PW51bGwpcz0iOiBOb3QgZ3Jl
+YXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5FaihyKQplbHNlIGlmKHE+cilzPSI6IE5vdCBpbiBpbmNs
+dXNpdmUgcmFuZ2UgIitILkVqKHIpKyIuLiIrSC5FaihxKQplbHNlIHM9cTxyPyI6IFZhbGlkIHZhbHVl
+IHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5FaihyKQpyZXR1cm4gc319
+ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5j
+dGlvbigpe3ZhciBzLHI9SC51UCh0aGlzLmIpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIu
+SigpCmlmKHI8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKcz10aGlzLmYKaWYo
+cz09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNob3VsZCBi
+ZSBsZXNzIHRoYW4gIitILkVqKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPXt9LGk9
+bmV3IFAuUm4oIiIpCmouYT0iIgpzPWsuYwpmb3Iocj1zLmxlbmd0aCxxPTAscD0iIixvPSIiO3E8cjsr
+K3Esbz0iLCAiKXtuPXNbcV0KaS5hPXArbwpwPWkuYSs9UC5wKG4pCmouYT0iLCAifWsuZC5LKDAsbmV3
+IFAuV0YoaixpKSkKbT1QLnAoay5hKQpsPWkudygwKQpyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9k
+IG5vdCBmb3VuZDogJyIrSC5FaihrLmIuYSkrIidcblJlY2VpdmVyOiAiK20rIlxuQXJndW1lbnRzOiBb
+IitsKyJdIgpyZXR1cm4gcn19ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5z
+dXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXt2YXIgcz10aGlzLmEKcmV0dXJuIHMhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIitzOiJVbmlt
+cGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQg
+c3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
+YQppZihzPT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9u
+LiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHMp
+KyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9
+LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVs
+bH0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVy
+biBzPT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+IjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrcysiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+In19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMu
+YX0sCiRpUno6MX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnPXRoaXMuYSxmPWchPW51bGwmJiIiIT09Zz8iRm9ybWF0RXhjZXB0aW9uOiAiK0gu
+RWooZyk6IkZvcm1hdEV4Y2VwdGlvbiIsZT10aGlzLmMsZD10aGlzLmIKaWYodHlwZW9mIGQ9PSJzdHJp
+bmciKXtpZihlIT1udWxsKXM9ZTwwfHxlPmQubGVuZ3RoCmVsc2Ugcz0hMQppZihzKWU9bnVsbAppZihl
+PT1udWxsKXtpZihkLmxlbmd0aD43OClkPUMueEIuTmooZCwwLDc1KSsiLi4uIgpyZXR1cm4gZisiXG4i
+K2R9Zm9yKHI9MSxxPTAscD0hMSxvPTA7bzxlOysrbyl7bj1DLnhCLlcoZCxvKQppZihuPT09MTApe2lm
+KHEhPT1vfHwhcCkrK3IKcT1vKzEKcD0hMX1lbHNlIGlmKG49PT0xMyl7KytyCnE9bysxCnA9ITB9fWY9
+cj4xP2YrKCIgKGF0IGxpbmUgIityKyIsIGNoYXJhY3RlciAiKyhlLXErMSkrIilcbiIpOmYrKCIgKGF0
+IGNoYXJhY3RlciAiKyhlKzEpKyIpXG4iKQptPWQubGVuZ3RoCmZvcihvPWU7bzxtOysrbyl7bj1DLnhC
+Lk8yKGQsbykKaWYobj09PTEwfHxuPT09MTMpe209bwpicmVha319aWYobS1xPjc4KWlmKGUtcTw3NSl7
+bD1xKzc1Cms9cQpqPSIiCmk9Ii4uLiJ9ZWxzZXtpZihtLWU8NzUpe2s9bS03NQpsPW0KaT0iIn1lbHNl
+e2s9ZS0zNgpsPWUrMzYKaT0iLi4uIn1qPSIuLi4ifWVsc2V7bD1tCms9cQpqPSIiCmk9IiJ9aD1DLnhC
+Lk5qKGQsayxsKQpyZXR1cm4gZitqK2graSsiXG4iK0MueEIuVCgiICIsZS1rK2oubGVuZ3RoKSsiXlxu
+In1lbHNlIHJldHVybiBlIT1udWxsP2YrKCIgKGF0IG9mZnNldCAiK0guRWooZSkrIikiKTpmfSwKJGlS
+ejoxfQpQLmNYLnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguR0oodGhpcyxILkxo
+KHRoaXMpLkMoImNYLkUiKSxiKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJl
+dHVybiBILksxKHRoaXMscy5LcShjKS5DKCIxKGNYLkUpIikuYShiKSxzLkMoImNYLkUiKSxjKX0sCmV2
+OmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyxzLkMoImEy
+KGNYLkUpIikuYShiKSxzLkMoIlU1PGNYLkU+IikpfSwKdHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5Z
+MSh0aGlzLGIsSC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+dHQoYSwhMCl9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKZm9yKHM9MDtyLkYo
+KTspKytzCnJldHVybiBzfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdtKHRoaXMpLkYoKX0s
+CmdvcjpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbDAodGhpcyl9LAplUjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBILmJLKHRoaXMsYixILkxoKHRoaXMpLkMoImNYLkUiKSl9LApncjg6ZnVuY3Rpb24oYSl7dmFy
+IHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSl0aHJvdyBILmIoSC5XcCgpKQpzPXIuZ2woKQppZihy
+LkYoKSl0aHJvdyBILmIoSC5BbSgpKQpyZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEK
+UC5rMShiLCJpbmRleCIpCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmdsKCkKaWYo
+Yj09PXIpcmV0dXJuIHE7KytyfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscikpfSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9e30K
+UC5OMy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guRWooSi5qKHRo
+aXMuYSkpKyI6ICIrSC5FaihKLmoodGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9ewpnaU86ZnVu
+Y3Rpb24oYSl7cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKEMuak4sdGhpcyl9LAp3OmZ1bmN0
+aW9uKGEpe3JldHVybiJudWxsIn19ClAuTWgucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6
+MSwKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IEguZVEodGhpcyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILkVqKEguTSh0
+aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt0Lm8uYShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIu
+Z1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnco
+dGhpcyl9fQpQLlpkLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAu
+Um4ucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LAp3OmZ1bmN0
+aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCiRpQkw6MX0K
+UC5uMS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuSi5hKGEpCkguaChi
+KQpzPUouclkoYikuT1koYiwiPSIpCmlmKHM9PT0tMSl7aWYoYiE9PSIiKWEuWTUoMCxQLmt1KGIsMCxi
+Lmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHMhPT0wKXtyPUMueEIuTmooYiwwLHMpCnE9Qy54
+Qi55bihiLHMrMSkKcD10aGlzLmEKYS5ZNSgwLFAua3UociwwLHIubGVuZ3RoLHAsITApLFAua3UocSww
+LHEubGVuZ3RoLHAsITApKX1yZXR1cm4gYX0sCiRTOjQ0fQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIp
+KX0sCiRTOjIxfQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIo
+IklsbGVnYWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLiQyKGEsbnVsbCl9LAokUzo0OX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3ZhciBzCmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBt
+YXhpbXVtIG9mIDQgaGV4IGRpZ2l0cyIsYSkKcz1QLlFBKEMueEIuTmoodGhpcy5iLGEsYiksMTYpCmlm
+KHM8MHx8cz42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBg
+MHgwLi4weEZGRkZgIixhKQpyZXR1cm4gc30sCiRTOjUxfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5j
+dGlvbigpe3ZhciBzLHIscSxwLG89dGhpcwppZighby55KXtzPW8uYQpyPXMubGVuZ3RoIT09MD9zKyI6
+IjoiIgpxPW8uYwpwPXE9PW51bGwKaWYoIXB8fHM9PT0iZmlsZSIpe3M9cisiLy8iCnI9by5iCmlmKHIu
+bGVuZ3RoIT09MClzPXMrcisiQCIKaWYoIXApcys9cQpyPW8uZAppZihyIT1udWxsKXM9cysiOiIrSC5F
+aihyKX1lbHNlIHM9cgpzKz1vLmUKcj1vLmYKaWYociE9bnVsbClzPXMrIj8iK3IKcj1vLnIKaWYociE9
+bnVsbClzPXMrIiMiK3IKaWYoby55KXRocm93IEguYihILkdRKCJfdGV4dCIpKQpvLng9cy5jaGFyQ29k
+ZUF0KDApPT0wP3M6cwpvLnk9ITB9cmV0dXJuIG8ueH0sCmdGajpmdW5jdGlvbigpe3ZhciBzLHIscT10
+aGlzCmlmKCFxLlEpe3M9cS5lCmlmKHMubGVuZ3RoIT09MCYmQy54Qi5XKHMsMCk9PT00NylzPUMueEIu
+eW4ocywxKQpyPXMubGVuZ3RoPT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTShzLnNwbGl0KCIvIiks
+dC5zKSx0LmRPLmEoUC5QSCgpKSx0LmRvKSx0Lk4pCmlmKHEuUSl0aHJvdyBILmIoSC5HUSgicGF0aFNl
+Z21lbnRzIikpCnEuc0twKHIpCnEuUT0hMH1yZXR1cm4gcS56fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBz
+LHI9dGhpcwppZighci5jeCl7cz1KLmhmKHIuZ25EKCkpCmlmKHIuY3gpdGhyb3cgSC5iKEguR1EoImhh
+c2hDb2RlIikpCnIuY2g9cwpyLmN4PSEwfXJldHVybiByLmNofSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHMs
+cj10aGlzCmlmKCFyLmRiKXtzPVAuV1goci5ndFAoKSkKaWYoci5kYil0aHJvdyBILmIoSC5HUSgicXVl
+cnlQYXJhbWV0ZXJzIikpCnIuc05NKG5ldyBQLkdqKHMsdC5kdykpCnIuZGI9ITB9cmV0dXJuIHIuY3l9
+LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
+YwppZihzPT1udWxsKXJldHVybiIiCmlmKEMueEIubkMocywiWyIpKXJldHVybiBDLnhCLk5qKHMsMSxz
+Lmxlbmd0aC0xKQpyZXR1cm4gc30sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKcmV0dXJuIHM9
+PW51bGw/UC53Syh0aGlzLmEpOnN9LApndFA6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmYKcmV0dXJuIHM9
+PW51bGw/IiI6c30sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucgpyZXR1cm4gcz09bnVsbD8iIjpz
+fSwKbm06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaj10aGlzCnQuYzkuYShiKQpz
+PWouYQpyPXM9PT0iZmlsZSIKcT1qLmIKcD1qLmQKbz1qLmMKaWYoIShvIT1udWxsKSlvPXEubGVuZ3Ro
+IT09MHx8cCE9bnVsbHx8cj8iIjpudWxsCm49ai5lCmlmKCFyKW09byE9bnVsbCYmbi5sZW5ndGghPT0w
+CmVsc2UgbT0hMAppZihtJiYhQy54Qi5uQyhuLCIvIikpbj0iLyIrbgpsPW4Kaz1QLmxlKG51bGwsMCww
+LGIpCnJldHVybiBuZXcgUC5EbihzLHEsbyxwLGwsayxqLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIg
+cyxyLHEscCxvLG4KZm9yKHM9MCxyPTA7Qy54Qi5RaShiLCIuLi8iLHIpOyl7cis9MzsrK3N9cT1DLnhC
+LmNuKGEsIi8iKQp3aGlsZSghMCl7aWYoIShxPjAmJnM+MCkpYnJlYWsKcD1DLnhCLlBrKGEsIi8iLHEt
+MSkKaWYocDwwKWJyZWFrCm89cS1wCm49byE9PTIKaWYoIW58fG89PT0zKWlmKEMueEIuTzIoYSxwKzEp
+PT09NDYpbj0hbnx8Qy54Qi5PMihhLHArMik9PT00NgplbHNlIG49ITEKZWxzZSBuPSExCmlmKG4pYnJl
+YWs7LS1zCnE9cH1yZXR1cm4gQy54Qi5pNyhhLHErMSxudWxsLEMueEIueW4oYixyLTMqcykpfSwKWkk6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgcyxy
+LHEscCxvLG4sbSxsLGssaj10aGlzLGk9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3M9YS5nRmko
+KQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPWEuZ3hBKCk/YS5ndHAoYSk6aX1lbHNl
+e3A9aQpxPXAKcj0iIn1vPVAueGUoYS5nSWkoYSkpCm49YS5nUUQoKT9hLmd0UCgpOml9ZWxzZXtzPWou
+YQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPVAud0IoYS5neEEoKT9hLmd0cChhKTpp
+LHMpCm89UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aX1lbHNle3I9ai5iCnE9ai5jCnA9
+ai5kCmlmKGEuZ0lpKGEpPT09IiIpe289ai5lCm49YS5nUUQoKT9hLmd0UCgpOmouZn1lbHNle2lmKGEu
+Z3RUKCkpbz1QLnhlKGEuZ0lpKGEpKQplbHNle209ai5lCmlmKG0ubGVuZ3RoPT09MClpZihxPT1udWxs
+KW89cy5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2Ugbz1QLnhlKCIvIithLmdJ
+aShhKSkKZWxzZXtsPWouSmgobSxhLmdJaShhKSkKaz1zLmxlbmd0aD09PTAKaWYoIWt8fHEhPW51bGx8
+fEMueEIubkMobSwiLyIpKW89UC54ZShsKQplbHNlIG89UC53RihsLCFrfHxxIT1udWxsKX19bj1hLmdR
+RCgpP2EuZ3RQKCk6aX19fXJldHVybiBuZXcgUC5EbihzLHIscSxwLG8sbixhLmdaOCgpP2EuZ0thKCk6
+aSl9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmYhPW51bGx9LApnWjg6
+ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1udWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIu
+bkModGhpcy5lLCIvIil9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxIT09IiIm
+JnEhPT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20g
+YSAiK3ErIiBVUkkiKSkKaWYoci5ndFAoKSE9PSIiKXRocm93IEguYihQLkw0KHUuaSkpCmlmKHIuZ0th
+KCkhPT0iIil0aHJvdyBILmIoUC5MNCh1LmwpKQpxPSQud1EoKQppZihILm9UKHEpKXE9UC5tbihyKQpl
+bHNle2lmKHIuYyE9bnVsbCYmci5nSmYocikhPT0iIilILnYoUC5MNCh1LmopKQpzPXIuZ0ZqKCkKUC5r
+RShzLCExKQpxPVAudmcoQy54Qi5uQyhyLmUsIi8iKT8iLyI6IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0
 KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ25EKCl9LApETjpm
 dW5jdGlvbihhLGIpe3ZhciBzPXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihzPT09YilyZXR1cm4h
 MApyZXR1cm4gdC5kRC5iKGIpJiZzLmE9PT1iLmdGaSgpJiZzLmMhPW51bGw9PT1iLmdjaigpJiZzLmI9
@@ -10333,1369 +10388,1395 @@
 bGwmJmIubGVuZ3RoIT09MCl7cy5hPXIrIj0iCnMuYSs9SC5FaihQLmVQKEMuRjMsYixDLnhNLCEwKSl9
 fSwKJFM6MjJ9ClAueTUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkguaChhKQpp
 ZihiPT1udWxsfHx0eXBlb2YgYj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC5rKGIpKQplbHNlIGZvcihz
-PUouSVQodC51LmEoYikpLHI9dGhpcy5hO3MuRigpOylyLiQyKGEsSC5oKHMuZ2woKSkpfSwKJFM6MTN9
+PUouSVQodC51LmEoYikpLHI9dGhpcy5hO3MuRigpOylyLiQyKGEsSC5oKHMuZ2woKSkpfSwKJFM6MTJ9
 ClAuUEUucHJvdG90eXBlPXsKZ2xSOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzLG49bnVsbCxt
 PW8uYwppZihtPT1udWxsKXttPW8uYgppZigwPj1tLmxlbmd0aClyZXR1cm4gSC5PSChtLDApCnM9by5h
 Cm09bVswXSsxCnI9Qy54Qi5YVShzLCI/IixtKQpxPXMubGVuZ3RoCmlmKHI+PTApe3A9UC5QSShzLHIr
 MSxxLEMuVkMsITEpCnE9cn1lbHNlIHA9bgptPW8uYz1uZXcgUC5xZSgiZGF0YSIsIiIsbixuLFAuUEko
 cyxtLHEsQy5XZCwhMSkscCxuKX1yZXR1cm4gbX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmIK
 aWYoMD49ci5sZW5ndGgpcmV0dXJuIEguT0gociwwKQpzPXRoaXMuYQpyZXR1cm4gclswXT09PS0xPyJk
-YXRhOiIrczpzfX0KUC5xMy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFVpbnQ4
-QXJyYXkoOTYpfSwKJFM6MjN9ClAueUkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10
-aGlzLmEKaWYoYT49MjIpcmV0dXJuIEguT0gocyxhKQpzPXNbYV0KQy5OQS5kdShzLDAsOTYsYikKcmV0
-dXJuIHN9LAokUzoyNH0KUC5jNi5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixx
-CmZvcihzPWIubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUMueEIuVyhiLHIpXjk2CmlmKHE+PTk2KXJldHVy
-biBILk9IKGEscSkKYVtxXT1jfX0sCiRTOjE0fQpQLnFkLnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEKZm9yKHM9Qy54Qi5XKGIsMCkscj1DLnhCLlcoYiwxKTtzPD1yOysrcyl7cT0o
-c145Nik+Pj4wCmlmKHE+PTk2KXJldHVybiBILk9IKGEscSkKYVtxXT1jfX0sCiRTOjE0fQpQLlVmLnBy
-b3RvdHlwZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLmM+MCYmdGhpcy5kKzE8dGhpcy5lfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
-Zjx0aGlzLnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ1daOmZ1
-bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmI9PT01JiZDLnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0
-aW9uKCl7cmV0dXJuIEMueEIuUWkodGhpcy5hLCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFy
-IHM9dGhpcy54CnJldHVybiBzPT1udWxsP3RoaXMueD10aGlzLlUyKCk6c30sClUyOmZ1bmN0aW9uKCl7
-dmFyIHM9dGhpcyxyPXMuYgppZihyPD0wKXJldHVybiIiCmlmKHMuZ1daKCkpcmV0dXJuImh0dHAiCmlm
-KHMuZ1JlKCkpcmV0dXJuImh0dHBzIgppZihzLmdOdygpKXJldHVybiJmaWxlIgppZihyPT09NyYmQy54
-Qi5uKHMuYSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5OaihzLmEsMCxyKX0s
-CmdrdTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYyxyPXRoaXMuYiszCnJldHVybiBzPnI/Qy54Qi5Oaih0
-aGlzLmEscixzLTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpyZXR1cm4gcz4wP0Mu
-eEIuTmoodGhpcy5hLHMsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzCmlmKHMu
-Z3hBKCkpcmV0dXJuIFAuUUEoQy54Qi5OaihzLmEscy5kKzEscy5lKSxudWxsKQppZihzLmdXWigpKXJl
-dHVybiA4MAppZihzLmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEMueEIuTmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHM9dGhp
-cy5mLHI9dGhpcy5yCnJldHVybiBzPHI/Qy54Qi5Oaih0aGlzLmEscysxLHIpOiIifSwKZ0thOmZ1bmN0
-aW9uKCl7dmFyIHM9dGhpcy5yLHI9dGhpcy5hCnJldHVybiBzPHIubGVuZ3RoP0MueEIuRyhyLHMrMSk6
-IiJ9LApnRmo6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcy5lLHA9dGhpcy5mLG89dGhpcy5hCmlmKEMu
-eEIuUWkobywiLyIscSkpKytxCmlmKHE9PT1wKXJldHVybiBDLnhECnM9SC5WTShbXSx0LnMpCmZvcihy
-PXE7cjxwOysrcilpZihDLnhCLk8yKG8scik9PT00Nyl7Qy5ObS5pKHMsQy54Qi5OaihvLHEscikpCnE9
-cisxfUMuTm0uaShzLEMueEIuTmoobyxxLHApKQpyZXR1cm4gUC5BRihzLHQuTil9LApnaFk6ZnVuY3Rp
-b24oKXtpZih0aGlzLmY+PXRoaXMucilyZXR1cm4gQy5DTQpyZXR1cm4gbmV3IFAuR2ooUC5XWCh0aGlz
-Lmd0UCgpKSx0LmR3KX0sCmtYOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZCsxCnJldHVybiBzK2EubGVu
-Z3RoPT09dGhpcy5lJiZDLnhCLlFpKHRoaXMuYSxhLHMpfSwKTjk6ZnVuY3Rpb24oKXt2YXIgcz10aGlz
-LHI9cy5yLHE9cy5hCmlmKHI+PXEubGVuZ3RoKXJldHVybiBzCnJldHVybiBuZXcgUC5VZihDLnhCLk5q
-KHEsMCxyKSxzLmIscy5jLHMuZCxzLmUscy5mLHIscy54KX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHMs
-cixxLHAsbyxuLG0sbCxrLGosaT10aGlzLGg9bnVsbAp0LmM5LmEoYikKcz1pLmdGaSgpCnI9cz09PSJm
-aWxlIgpxPWkuYwpwPXE+MD9DLnhCLk5qKGkuYSxpLmIrMyxxKToiIgpvPWkuZ3hBKCk/aS5ndHAoaSk6
-aApxPWkuYwppZihxPjApbj1DLnhCLk5qKGkuYSxxLGkuZCkKZWxzZSBuPXAubGVuZ3RoIT09MHx8byE9
-bnVsbHx8cj8iIjpoCnE9aS5hCm09Qy54Qi5OaihxLGkuZSxpLmYpCmlmKCFyKWw9biE9bnVsbCYmbS5s
-ZW5ndGghPT0wCmVsc2UgbD0hMAppZihsJiYhQy54Qi5uKG0sIi8iKSltPSIvIittCms9UC5sZShoLDAs
-MCxiKQpsPWkucgpqPWw8cS5sZW5ndGg/Qy54Qi5HKHEsbCsxKTpoCnJldHVybiBuZXcgUC5EbihzLHAs
-bixvLG0sayxqKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVu
-Y3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1cm4g
-dGhpcy52cygpLm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
-LGgsZz1iLmIKaWYoZz4wKXJldHVybiBiCnM9Yi5jCmlmKHM+MCl7cj1hLmIKaWYocjw9MClyZXR1cm4g
-YgppZihhLmdOdygpKXE9Yi5lIT09Yi5mCmVsc2UgaWYoYS5nV1ooKSlxPSFiLmtYKCI4MCIpCmVsc2Ug
-cT0hYS5nUmUoKXx8IWIua1goIjQ0MyIpCmlmKHEpe3A9cisxCnJldHVybiBuZXcgUC5VZihDLnhCLk5q
-KGEuYSwwLHApK0MueEIuRyhiLmEsZysxKSxyLHMrcCxiLmQrcCxiLmUrcCxiLmYrcCxiLnIrcCxhLngp
-fWVsc2UgcmV0dXJuIHRoaXMudnMoKS5tUyhiKX1vPWIuZQpnPWIuZgppZihvPT09Zyl7cz1iLnIKaWYo
-ZzxzKXtyPWEuZgpwPXItZwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLkcoYi5h
-LGcpLGEuYixhLmMsYS5kLGEuZSxnK3AscytwLGEueCl9Zz1iLmEKaWYoczxnLmxlbmd0aCl7cj1hLnIK
-cmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54Qi5HKGcscyksYS5iLGEuYyxhLmQsYS5l
-LGEuZixzKyhyLXMpLGEueCl9cmV0dXJuIGEuTjkoKX1zPWIuYQppZihDLnhCLlFpKHMsIi8iLG8pKXty
-PWEuZQpwPXItbwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLkcocyxvKSxhLmIs
-YS5jLGEuZCxyLGcrcCxiLnIrcCxhLngpfW49YS5lCm09YS5mCmlmKG49PT1tJiZhLmM+MCl7Zm9yKDtD
-LnhCLlFpKHMsIi4uLyIsbyk7KW8rPTMKcD1uLW8rMQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEs
-MCxuKSsiLyIrQy54Qi5HKHMsbyksYS5iLGEuYyxhLmQsbixnK3AsYi5yK3AsYS54KX1sPWEuYQpmb3Io
-az1uO0MueEIuUWkobCwiLi4vIixrKTspays9MwpqPTAKd2hpbGUoITApe2k9byszCmlmKCEoaTw9ZyYm
-Qy54Qi5RaShzLCIuLi8iLG8pKSlicmVhazsrK2oKbz1pfWZvcihoPSIiO20+azspey0tbQppZihDLnhC
-Lk8yKGwsbSk9PT00Nyl7aWYoaj09PTApe2g9Ii8iCmJyZWFrfS0tagpoPSIvIn19aWYobT09PWsmJmEu
-Yjw9MCYmIUMueEIuUWkobCwiLyIsbikpe28tPWoqMwpoPSIifXA9bS1vK2gubGVuZ3RoCnJldHVybiBu
-ZXcgUC5VZihDLnhCLk5qKGwsMCxtKStoK0MueEIuRyhzLG8pLGEuYixhLmMsYS5kLG4sZytwLGIucitw
-LGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHIscSxwPXRoaXMKaWYocC5iPj0wJiYhcC5nTncoKSl0
-aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrcC5nRmkoKSsi
-IFVSSSIpKQpzPXAuZgpyPXAuYQppZihzPHIubGVuZ3RoKXtpZihzPHAucil0aHJvdyBILmIoUC5MNCh1
-LmkpKQp0aHJvdyBILmIoUC5MNCh1LmwpKX1xPSQud1EoKQppZihILm9UKHEpKXM9UC5tbihwKQplbHNl
-e2lmKHAuYzxwLmQpSC52KFAuTDQodS5qKSkKcz1DLnhCLk5qKHIscC5lLHMpfXJldHVybiBzfSwKZ2lP
-OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMueQpyZXR1cm4gcz09bnVsbD90aGlzLnk9Qy54Qi5naU8odGhp
-cy5hKTpzfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCmlmKHRoaXM9PT1iKXJl
-dHVybiEwCnJldHVybiB0LmRELmIoYikmJnRoaXMuYT09PWIudygwKX0sCnZzOmZ1bmN0aW9uKCl7dmFy
-IHM9dGhpcyxyPW51bGwscT1zLmdGaSgpLHA9cy5na3UoKSxvPXMuYz4wP3MuZ0pmKHMpOnIsbj1zLmd4
-QSgpP3MuZ3RwKHMpOnIsbT1zLmEsbD1zLmYsaz1DLnhCLk5qKG0scy5lLGwpLGo9cy5yCmw9bDxqP3Mu
-Z3RQKCk6cgpyZXR1cm4gbmV3IFAuRG4ocSxwLG8sbixrLGwsajxtLmxlbmd0aD9zLmdLYSgpOnIpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3RvdHlwZT17fQpXLnFF
-LnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17CnNMVTpmdW5jdGlvbihhLGIpe2EuaHJlZj1ifSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnByb3RvdHlwZT17Cnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXskaW5COjF9ClcuQXou
-cHJvdG90eXBlPXskaUF6OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9ClcubngucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
-bihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnByb3RvdHlwZT17fQpX
-Lk5oLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcuYWUucHJvdG90
-eXBlPXsKRGM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5jcmVhdGVIVE1MRG9jdW1lbnQoYil9fQpXLklC
-LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0cmluZwpyPSJSZWN0
-YW5nbGUgKCIrSC5FaihyKSsiLCAiCnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5FaihzKSsiKSAiCnI9
-YS53aWR0aApyLnRvU3RyaW5nCnI9cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQKcy50b1N0cmluZwpy
-ZXR1cm4gcitILkVqKHMpfSwKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9PW51bGwpcmV0dXJu
-ITEKaWYodC5xLmIoYikpe3M9YS5sZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50b1N0cmluZwppZihz
-PT09cil7cz1hLnRvcApzLnRvU3RyaW5nCnI9Yi50b3AKci50b1N0cmluZwppZihzPT09cil7cz1hLndp
-ZHRoCnMudG9TdHJpbmcKcj1iLndpZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS5oZWlnaHQKcy50
-b1N0cmluZwpyPWIuaGVpZ2h0CnIudG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBzPSExfWVsc2Ugcz0h
-MX1lbHNlIHM9ITF9ZWxzZSBzPSExCnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxw
-PWEubGVmdApwLnRvU3RyaW5nCnA9Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3RyaW5nCnM9Qy5DRC5n
-aU8ocykKcj1hLndpZHRoCnIudG9TdHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVpZ2h0CnEudG9TdHJp
-bmcKcmV0dXJuIFcuckUocCxzLHIsQy5DRC5naU8ocSkpfSwKJGl0bjoxfQpXLm43LnByb3RvdHlwZT17
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcud3oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpz
-PXRoaXMuYQppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcmV0dXJuIHRoaXMuJHRp
-LmMuYShzW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuJHRpLmMuYShjKQp0aHJvdyBILmIoUC5M
-NCgiQ2Fubm90IG1vZGlmeSBsaXN0IikpfX0KVy5jdi5wcm90b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBXLmk3KGEpfSwKZ0Q6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLkk0KGEpfSwKc0Q6
-ZnVuY3Rpb24oYSxiKXt2YXIgcwp0LlEuYShiKQpzPXRoaXMuZ0QoYSkKcy5WMSgwKQpzLkZWKDAsYil9
-LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2FsTmFtZX0sCkZGOmZ1bmN0aW9uKGEpe3ZhciBzPSEh
-YS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkCmlmKHMpYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkKCkKZWxz
-ZSBhLnNjcm9sbEludG9WaWV3KCl9LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHI9dGhpcy5y
-NihhLGMsZCxlKQpzd2l0Y2goYi50b0xvd2VyQ2FzZSgpKXtjYXNlImJlZm9yZWJlZ2luIjpzPWEucGFy
-ZW50Tm9kZQpzLnRvU3RyaW5nCkouRWgocyxyLGEpCmJyZWFrCmNhc2UiYWZ0ZXJiZWdpbiI6cz1hLmNo
-aWxkTm9kZXMKdGhpcy5tSyhhLHIscy5sZW5ndGg+MD9zWzBdOm51bGwpCmJyZWFrCmNhc2UiYmVmb3Jl
-ZW5kIjphLmFwcGVuZENoaWxkKHIpCmJyZWFrCmNhc2UiYWZ0ZXJlbmQiOnM9YS5wYXJlbnROb2RlCnMu
-dG9TdHJpbmcKSi5FaChzLHIsYS5uZXh0U2libGluZykKYnJlYWsKZGVmYXVsdDpILnYoUC54WSgiSW52
-YWxpZCBwb3NpdGlvbiAiK2IpKX19LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscAppZihj
-PT1udWxsKXtpZihkPT1udWxsKXtzPSQubHQKaWYocz09bnVsbCl7cz1ILlZNKFtdLHQudikKcj1uZXcg
-Vy52RChzKQpDLk5tLmkocyxXLlR3KG51bGwpKQpDLk5tLmkocyxXLkJsKCkpCiQubHQ9cgpkPXJ9ZWxz
-ZSBkPXN9cz0kLkVVCmlmKHM9PW51bGwpe3M9bmV3IFcuS28oZCkKJC5FVT1zCmM9c31lbHNle3MuYT1k
-CmM9c319ZWxzZSBpZihkIT1udWxsKXRocm93IEguYihQLnhZKCJ2YWxpZGF0b3IgY2FuIG9ubHkgYmUg
-cGFzc2VkIGlmIHRyZWVTYW5pdGl6ZXIgaXMgbnVsbCIpKQppZigkLnhvPT1udWxsKXtzPWRvY3VtZW50
-CnI9cy5pbXBsZW1lbnRhdGlvbgpyLnRvU3RyaW5nCnI9Qy5tSC5EYyhyLCIiKQokLnhvPXIKJC5CTz1y
-LmNyZWF0ZVJhbmdlKCkKcj0kLnhvLmNyZWF0ZUVsZW1lbnQoImJhc2UiKQp0LmNSLmEocikKcz1zLmJh
-c2VVUkkKcy50b1N0cmluZwpyLmhyZWY9cwokLnhvLmhlYWQuYXBwZW5kQ2hpbGQocil9cz0kLnhvCmlm
-KHMuYm9keT09bnVsbCl7cj1zLmNyZWF0ZUVsZW1lbnQoImJvZHkiKQpDLkJaLnNYRyhzLHQucC5hKHIp
-KX1zPSQueG8KaWYodC5wLmIoYSkpe3M9cy5ib2R5CnMudG9TdHJpbmcKcT1zfWVsc2V7cy50b1N0cmlu
-ZwpxPXMuY3JlYXRlRWxlbWVudChhLnRhZ05hbWUpCiQueG8uYm9keS5hcHBlbmRDaGlsZChxKX1pZigi
-Y3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlJiYhQy5ObS50
-ZyhDLlNxLGEudGFnTmFtZSkpeyQuQk8uc2VsZWN0Tm9kZUNvbnRlbnRzKHEpCnM9JC5CTwpzLnRvU3Ry
-aW5nCnA9cy5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoYj09bnVsbD8ibnVsbCI6Yil9ZWxzZXtKLndm
-KHEsYikKcD0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3IoO3M9cS5maXJzdENoaWxkLHMh
-PW51bGw7KXAuYXBwZW5kQ2hpbGQocyl9aWYocSE9PSQueG8uYm9keSlKLkx0KHEpCmMuUG4ocCkKZG9j
-dW1lbnQuYWRvcHROb2RlKHApCnJldHVybiBwfSwKQUg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlz
-LnI2KGEsYixjLG51bGwpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcGs6ZnVuY3Rp
-b24oYSxiLGMpe3RoaXMuc2E0KGEsbnVsbCkKYS5hcHBlbmRDaGlsZCh0aGlzLnI2KGEsYixudWxsLGMp
-KX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKc1JOOmZ1bmN0aW9u
-KGEsYil7YS5pbm5lckhUTUw9Yn0sCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1lfSwKZ1Zs
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdC5rKX0sCiRpY3Y6MX0KVy5D
-di5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5oLmIodC5BLmEoYSkpfSwKJFM6MjZ9
-ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24oYSxiLGMs
-ZCl7dC5idy5hKGMpCmlmKGMhPW51bGwpdGhpcy52KGEsYixjLGQpfSwKQjpmdW5jdGlvbihhLGIsYyl7
-cmV0dXJuIHRoaXMuT24oYSxiLGMsbnVsbCl9LAp2OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBhLmFk
-ZEV2ZW50TGlzdGVuZXIoYixILnRSKHQuYncuYShjKSwxKSxkKX0sCiRpRDA6MX0KVy5oSC5wcm90b3R5
-cGU9eyRpaEg6MX0KVy5oNC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9
-fQpXLmJyLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVmIucHJv
-dG90eXBlPXsKc1hHOmZ1bmN0aW9uKGEsYil7YS5ib2R5PWJ9fQpXLmZKLnByb3RvdHlwZT17CmVvOmZ1
-bmN0aW9uKGEsYixjLGQpe3JldHVybiBhLm9wZW4oYixjLCEwKX0sCiRpZko6MX0KVy53YS5wcm90b3R5
-cGU9e30KVy5TZy5wcm90b3R5cGU9eyRpU2c6MX0KVy51OC5wcm90b3R5cGU9ewpnRHI6ZnVuY3Rpb24o
-YSl7aWYoIm9yaWdpbiIgaW4gYSlyZXR1cm4gYS5vcmlnaW4KcmV0dXJuIEguRWooYS5wcm90b2NvbCkr
-Ii8vIitILkVqKGEuaG9zdCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9
-ClcuQWoucHJvdG90eXBlPXskaUFqOjF9ClcuZTcucHJvdG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMuYSxyPXMuY2hpbGROb2Rlcy5sZW5ndGgKaWYocj09PTApdGhyb3cgSC5iKFAuUFYoIk5v
-IGVsZW1lbnRzIikpCmlmKHI+MSl0aHJvdyBILmIoUC5QVigiTW9yZSB0aGFuIG9uZSBlbGVtZW50Iikp
-CnM9cy5maXJzdENoaWxkCnMudG9TdHJpbmcKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3ZhciBz
-LHIscSxwLG8KdC5laC5hKGIpCmlmKGIgaW5zdGFuY2VvZiBXLmU3KXtzPWIuYQpyPXRoaXMuYQppZihz
-IT09cilmb3IocT1zLmNoaWxkTm9kZXMubGVuZ3RoLHA9MDtwPHE7KytwKXtvPXMuZmlyc3RDaGlsZApv
-LnRvU3RyaW5nCnIuYXBwZW5kQ2hpbGQobyl9cmV0dXJufWZvcihzPWIuZ20oYikscj10aGlzLmE7cy5G
-KCk7KXIuYXBwZW5kQ2hpbGQocy5nbCgpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIKdC5BLmEo
-YykKcz10aGlzLmEKcj1zLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj1yLmxlbmd0aClyZXR1cm4gSC5PSChy
-LGIpCnMucmVwbGFjZUNoaWxkKGMscltiXSl9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEuY2hp
-bGROb2RlcwpyZXR1cm4gbmV3IFcuVzkocyxzLmxlbmd0aCxILnoocykuQygiVzk8R20uRT4iKSl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNoaWxkTm9kZXMubGVuZ3RofSwKcTpmdW5jdGlvbihh
-LGIpe3ZhciBzCkgudVAoYikKcz10aGlzLmEuY2hpbGROb2RlcwppZihiPDB8fGI+PXMubGVuZ3RoKXJl
-dHVybiBILk9IKHMsYikKcmV0dXJuIHNbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEp
-e3ZhciBzPWEucGFyZW50Tm9kZQppZihzIT1udWxsKXMucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlv
-bihhKXt2YXIgcwpmb3IoO3M9YS5maXJzdENoaWxkLHMhPW51bGw7KWEucmVtb3ZlQ2hpbGQocyl9LAp3
-OmZ1bmN0aW9uKGEpe3ZhciBzPWEubm9kZVZhbHVlCnJldHVybiBzPT1udWxsP3RoaXMuVShhKTpzfSwK
-c2E0OmZ1bmN0aW9uKGEsYil7YS50ZXh0Q29udGVudD1ifSwKbUs6ZnVuY3Rpb24oYSxiLGMpe3JldHVy
-biBhLmluc2VydEJlZm9yZShiLGMpfSwKJGl1SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGI+Pj4wIT09Ynx8
-Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19
-LApZOmZ1bmN0aW9uKGEsYixjKXt0LkEuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBl
-bGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCmd0SDpmdW5jdGlvbihhKXtpZihhLmxlbmd0aD4w
-KXJldHVybiBhWzBdCnRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKX0sCkU6ZnVuY3Rpb24oYSxi
-KXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEs
-CiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBlPXt9ClcuZXcucHJvdG90eXBlPXsk
-aWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5U
-Yi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyCmlmKCJjcmVhdGVDb250ZXh0
-dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMs
-ZCkKcz1XLlU5KCI8dGFibGU+IitILkVqKGIpKyI8L3RhYmxlPiIsYyxkKQpyPWRvY3VtZW50LmNyZWF0
-ZURvY3VtZW50RnJhZ21lbnQoKQpyLnRvU3RyaW5nCnMudG9TdHJpbmcKbmV3IFcuZTcocikuRlYoMCxu
-ZXcgVy5lNyhzKSkKcmV0dXJuIHJ9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQp
-e3ZhciBzLHIscSxwCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5w
+YXRhOiIrczpzfX0KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuYQpp
+ZihhPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGEpCnM9c1thXQpDLk5BLmR1KHMsMCw5NixiKQpyZXR1
+cm4gc30sCiRTOjIzfQpQLmM2LnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEK
+Zm9yKHM9Yi5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49OTYpcmV0dXJu
+IEguT0goYSxxKQphW3FdPWN9fSwKJFM6MTN9ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscQpmb3Iocz1DLnhCLlcoYiwwKSxyPUMueEIuVyhiLDEpO3M8PXI7KytzKXtxPShz
+Xjk2KT4+PjAKaWYocT49OTYpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fSwKJFM6MTN9ClAuVWYucHJv
+dG90eXBlPXsKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz4wfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuYz4wJiZ0aGlzLmQrMTx0aGlzLmV9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5m
+PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpm
+dW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm5DKHRoaXMuYSwiZmlsZSIpfSwKZ1daOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubkModGhpcy5hLCJodHRwIil9LApnUmU6ZnVu
+Y3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NSYmQy54Qi5uQyh0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVu
+Y3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2
+YXIgcz10aGlzLngKcmV0dXJuIHM9PW51bGw/dGhpcy54PXRoaXMuVTIoKTpzfSwKVTI6ZnVuY3Rpb24o
+KXt2YXIgcz10aGlzLHI9cy5iCmlmKHI8PTApcmV0dXJuIiIKaWYocy5nV1ooKSlyZXR1cm4iaHR0cCIK
+aWYocy5nUmUoKSlyZXR1cm4iaHR0cHMiCmlmKHMuZ053KCkpcmV0dXJuImZpbGUiCmlmKHI9PT03JiZD
+LnhCLm5DKHMuYSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5OaihzLmEsMCxy
+KX0sCmdrdTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYyxyPXRoaXMuYiszCnJldHVybiBzPnI/Qy54Qi5O
+aih0aGlzLmEscixzLTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpyZXR1cm4gcz4w
+P0MueEIuTmoodGhpcy5hLHMsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzCmlm
+KHMuZ3hBKCkpcmV0dXJuIFAuUUEoQy54Qi5OaihzLmEscy5kKzEscy5lKSxudWxsKQppZihzLmdXWigp
+KXJldHVybiA4MAppZihzLmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEMueEIuTmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHM9
+dGhpcy5mLHI9dGhpcy5yCnJldHVybiBzPHI/Qy54Qi5Oaih0aGlzLmEscysxLHIpOiIifSwKZ0thOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcy5yLHI9dGhpcy5hCnJldHVybiBzPHIubGVuZ3RoP0MueEIueW4ocixz
+KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHMscixxPXRoaXMuZSxwPXRoaXMuZixvPXRoaXMuYQpp
+ZihDLnhCLlFpKG8sIi8iLHEpKSsrcQppZihxPT09cClyZXR1cm4gQy54RApzPUguVk0oW10sdC5zKQpm
+b3Iocj1xO3I8cDsrK3IpaWYoQy54Qi5PMihvLHIpPT09NDcpe0MuTm0uaShzLEMueEIuTmoobyxxLHIp
+KQpxPXIrMX1DLk5tLmkocyxDLnhCLk5qKG8scSxwKSkKcmV0dXJuIFAuQUYocyx0Lk4pfSwKZ2hZOmZ1
+bmN0aW9uKCl7aWYodGhpcy5mPj10aGlzLnIpcmV0dXJuIEMuQ00KcmV0dXJuIG5ldyBQLkdqKFAuV1go
+dGhpcy5ndFAoKSksdC5kdyl9LAprWDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQrMQpyZXR1cm4gcyth
+Lmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSxzKX0sCk45OmZ1bmN0aW9uKCl7dmFyIHM9
+dGhpcyxyPXMucixxPXMuYQppZihyPj1xLmxlbmd0aClyZXR1cm4gcwpyZXR1cm4gbmV3IFAuVWYoQy54
+Qi5OaihxLDAscikscy5iLHMuYyxzLmQscy5lLHMuZixyLHMueCl9LApubTpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIscSxwLG8sbixtLGwsayxqLGk9dGhpcyxoPW51bGwKdC5jOS5hKGIpCnM9aS5nRmkoKQpyPXM9
+PT0iZmlsZSIKcT1pLmMKcD1xPjA/Qy54Qi5OaihpLmEsaS5iKzMscSk6IiIKbz1pLmd4QSgpP2kuZ3Rw
+KGkpOmgKcT1pLmMKaWYocT4wKW49Qy54Qi5OaihpLmEscSxpLmQpCmVsc2Ugbj1wLmxlbmd0aCE9PTB8
+fG8hPW51bGx8fHI/IiI6aApxPWkuYQptPUMueEIuTmoocSxpLmUsaS5mKQppZighcilsPW4hPW51bGwm
+Jm0ubGVuZ3RoIT09MAplbHNlIGw9ITAKaWYobCYmIUMueEIubkMobSwiLyIpKW09Ii8iK20Kaz1QLmxl
+KGgsMCwwLGIpCmw9aS5yCmo9bDxxLmxlbmd0aD9DLnhCLnluKHEsbCsxKTpoCnJldHVybiBuZXcgUC5E
+bihzLHAsbixvLG0sayxqKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwK
+bVM6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpy
+ZXR1cm4gdGhpcy52cygpLm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxs
+LGssaixpLGgsZz1iLmIKaWYoZz4wKXJldHVybiBiCnM9Yi5jCmlmKHM+MCl7cj1hLmIKaWYocjw9MCly
+ZXR1cm4gYgppZihhLmdOdygpKXE9Yi5lIT09Yi5mCmVsc2UgaWYoYS5nV1ooKSlxPSFiLmtYKCI4MCIp
+CmVsc2UgcT0hYS5nUmUoKXx8IWIua1goIjQ0MyIpCmlmKHEpe3A9cisxCnJldHVybiBuZXcgUC5VZihD
+LnhCLk5qKGEuYSwwLHApK0MueEIueW4oYi5hLGcrMSkscixzK3AsYi5kK3AsYi5lK3AsYi5mK3AsYi5y
+K3AsYS54KX1lbHNlIHJldHVybiB0aGlzLnZzKCkubVMoYil9bz1iLmUKZz1iLmYKaWYobz09PWcpe3M9
+Yi5yCmlmKGc8cyl7cj1hLmYKcD1yLWcKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54
+Qi55bihiLmEsZyksYS5iLGEuYyxhLmQsYS5lLGcrcCxzK3AsYS54KX1nPWIuYQppZihzPGcubGVuZ3Ro
+KXtyPWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnluKGcscyksYS5iLGEu
+YyxhLmQsYS5lLGEuZixzKyhyLXMpLGEueCl9cmV0dXJuIGEuTjkoKX1zPWIuYQppZihDLnhCLlFpKHMs
+Ii8iLG8pKXtyPWEuZQpwPXItbwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnlu
+KHMsbyksYS5iLGEuYyxhLmQscixnK3AsYi5yK3AsYS54KX1uPWEuZQptPWEuZgppZihuPT09bSYmYS5j
+PjApe2Zvcig7Qy54Qi5RaShzLCIuLi8iLG8pOylvKz0zCnA9bi1vKzEKcmV0dXJuIG5ldyBQLlVmKEMu
+eEIuTmooYS5hLDAsbikrIi8iK0MueEIueW4ocyxvKSxhLmIsYS5jLGEuZCxuLGcrcCxiLnIrcCxhLngp
+fWw9YS5hCmZvcihrPW47Qy54Qi5RaShsLCIuLi8iLGspOylrKz0zCmo9MAp3aGlsZSghMCl7aT1vKzMK
+aWYoIShpPD1nJiZDLnhCLlFpKHMsIi4uLyIsbykpKWJyZWFrOysragpvPWl9Zm9yKGg9IiI7bT5rOyl7
+LS1tCmlmKEMueEIuTzIobCxtKT09PTQ3KXtpZihqPT09MCl7aD0iLyIKYnJlYWt9LS1qCmg9Ii8ifX1p
+ZihtPT09ayYmYS5iPD0wJiYhQy54Qi5RaShsLCIvIixuKSl7by09aiozCmg9IiJ9cD1tLW8raC5sZW5n
+dGgKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmoobCwwLG0pK2grQy54Qi55bihzLG8pLGEuYixhLmMsYS5k
+LG4sZytwLGIucitwLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHIscSxwPXRoaXMKaWYocC5iPj0w
+JiYhcC5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+ICIrcC5nRmkoKSsiIFVSSSIpKQpzPXAuZgpyPXAuYQppZihzPHIubGVuZ3RoKXtpZihzPHAucil0aHJv
+dyBILmIoUC5MNCh1LmkpKQp0aHJvdyBILmIoUC5MNCh1LmwpKX1xPSQud1EoKQppZihILm9UKHEpKXM9
+UC5tbihwKQplbHNle2lmKHAuYzxwLmQpSC52KFAuTDQodS5qKSkKcz1DLnhCLk5qKHIscC5lLHMpfXJl
+dHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMueQpyZXR1cm4gcz09bnVsbD90aGlzLnk9
+Qy54Qi5naU8odGhpcy5hKTpzfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCmlm
+KHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB0LmRELmIoYikmJnRoaXMuYT09PWIudygwKX0sCnZzOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcyxyPW51bGwscT1zLmdGaSgpLHA9cy5na3UoKSxvPXMuYz4wP3MuZ0pm
+KHMpOnIsbj1zLmd4QSgpP3MuZ3RwKHMpOnIsbT1zLmEsbD1zLmYsaz1DLnhCLk5qKG0scy5lLGwpLGo9
+cy5yCmw9bDxqP3MuZ3RQKCk6cgpyZXR1cm4gbmV3IFAuRG4ocSxwLG8sbixrLGwsajxtLmxlbmd0aD9z
+LmdLYSgpOnIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3Rv
+dHlwZT17fQpXLnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17CnNMVTpmdW5jdGlvbihhLGIp
+e2EuaHJlZj1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnBy
+b3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXsk
+aW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9Clcubngu
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9
+ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnBy
+b3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19
+ClcuYWUucHJvdG90eXBlPXsKRGM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5jcmVhdGVIVE1MRG9jdW1l
+bnQoYil9fQpXLklCLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0
+cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAiCnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5F
+aihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQK
+cy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9
+PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5sZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50
+b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3RyaW5nCnI9Yi50b3AKci50b1N0cmluZwppZihz
+PT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndpZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9
+YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIudG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBz
+PSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExCnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3Ry
+aW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9TdHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVp
+Z2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIsQy5DRC5naU8ocSkpfSwKJGl0bjoxfQpXLm43
+LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcud3oucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7dmFy
+IHMKSC51UChiKQpzPXRoaXMuYQppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcmV0
+dXJuIHRoaXMuJHRpLmMuYShzW2JdKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykK
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1Fn
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0sCmduOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
+Vy5JNChhKX0sCnNuOmZ1bmN0aW9uKGEsYil7dmFyIHMKdC5RLmEoYikKcz10aGlzLmduKGEpCnMuVjEo
+MCkKcy5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlv
+bihhKXt2YXIgcz0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZAppZihzKWEuc2Nyb2xsSW50b1ZpZXdJ
+Zk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2
+YXIgcyxyPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmVi
+ZWdpbiI6cz1hLnBhcmVudE5vZGUKcy50b1N0cmluZwpKLkVoKHMscixhKQpicmVhawpjYXNlImFmdGVy
+YmVnaW4iOnM9YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxyLHMubGVuZ3RoPjA/c1swXTpudWxsKQpicmVh
+awpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChyKQpicmVhawpjYXNlImFmdGVyZW5kIjpzPWEu
+cGFyZW50Tm9kZQpzLnRvU3RyaW5nCkouRWgocyxyLGEubmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6
+SC52KFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
+IHMscixxLHAKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7cz0kLmx0CmlmKHM9PW51bGwpe3M9SC5WTShb
+XSx0LnYpCnI9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5CbCgpKQok
+Lmx0PXIKZD1yfWVsc2UgZD1zfXM9JC5FVQppZihzPT1udWxsKXtzPW5ldyBXLktvKGQpCiQuRVU9cwpj
+PXN9ZWxzZXtzLmE9ZApjPXN9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9y
+IGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVs
+bCl7cz1kb2N1bWVudApyPXMuaW1wbGVtZW50YXRpb24Kci50b1N0cmluZwpyPUMubUguRGMociwiIikK
+JC54bz1yCiQuQk89ci5jcmVhdGVSYW5nZSgpCnI9JC54by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdC5j
+Ui5hKHIpCnM9cy5iYXNlVVJJCnMudG9TdHJpbmcKci5ocmVmPXMKJC54by5oZWFkLmFwcGVuZENoaWxk
+KHIpfXM9JC54bwppZihzLmJvZHk9PW51bGwpe3I9cy5jcmVhdGVFbGVtZW50KCJib2R5IikKQy5CWi5z
+WEcocyx0LnAuYShyKSl9cz0kLnhvCmlmKHQucC5iKGEpKXtzPXMuYm9keQpzLnRvU3RyaW5nCnE9c31l
+bHNle3MudG9TdHJpbmcKcT1zLmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5k
+Q2hpbGQocSl9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3Rv
+dHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhxKQpz
+PSQuQk8Kcy50b1N0cmluZwpwPXMuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGI9PW51bGw/Im51bGwi
+OmIpfWVsc2V7Si53ZihxLGIpCnA9JC54by5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKZm9yKDtzPXEu
+Zmlyc3RDaGlsZCxzIT1udWxsOylwLmFwcGVuZENoaWxkKHMpfWlmKHEhPT0kLnhvLmJvZHkpSi5MdChx
+KQpjLlBuKHApCmRvY3VtZW50LmFkb3B0Tm9kZShwKQpyZXR1cm4gcH0sCkFIOmZ1bmN0aW9uKGEsYixj
+KXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxi
+KX0sCnBrOmZ1bmN0aW9uKGEsYixjKXt0aGlzLnNhNChhLG51bGwpCmEuYXBwZW5kQ2hpbGQodGhpcy5y
+NihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0s
+CnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+dGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHQuayl9
+LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuaC5iKHQuQS5h
+KGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGllYToxfQpXLkQwLnByb3RvdHlwZT17Ck9uOmZ1
+bmN0aW9uKGEsYixjLGQpe3QuYncuYShjKQppZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxk
+KXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50Uih0LmJ3LmEoYyksMSksZCl9LAokaUQwOjF9
+ClcuaEgucHJvdG90eXBlPXskaWhIOjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
+dGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlvbihhLGIpe2EuYm9keT1ifX0KVy5mSi5wcm90
+b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5vcGVuKGIsYywhMCl9LAokaWZKOjF9
+Clcud2EucHJvdG90eXBlPXt9ClcuU2cucHJvdG90eXBlPXskaVNnOjF9ClcudzcucHJvdG90eXBlPXsK
+Z0RyOmZ1bmN0aW9uKGEpe2lmKCJvcmlnaW4iIGluIGEpcmV0dXJuIGEub3JpZ2luCnJldHVybiBILkVq
+KGEucHJvdG9jb2wpKyIvLyIrSC5FaihhLmhvc3QpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5n
+KGEpfSwKJGl3NzoxfQpXLkFqLnByb3RvdHlwZT17JGlBajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpm
+dW5jdGlvbihhKXt2YXIgcz10aGlzLmEscj1zLmNoaWxkTm9kZXMubGVuZ3RoCmlmKHI9PT0wKXRocm93
+IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihyPjEpdGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBv
+bmUgZWxlbWVudCIpKQpzPXMuZmlyc3RDaGlsZApzLnRvU3RyaW5nCnJldHVybiBzfSwKRlY6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHEscCxvCnQuZWguYShiKQppZihiIGluc3RhbmNlb2YgVy5lNyl7cz1iLmEK
+cj10aGlzLmEKaWYocyE9PXIpZm9yKHE9cy5jaGlsZE5vZGVzLmxlbmd0aCxwPTA7cDxxOysrcCl7bz1z
+LmZpcnN0Q2hpbGQKby50b1N0cmluZwpyLmFwcGVuZENoaWxkKG8pfXJldHVybn1mb3Iocz1iLmdtKGIp
+LHI9dGhpcy5hO3MuRigpOylyLmFwcGVuZENoaWxkKHMuZ2woKSl9LApZNTpmdW5jdGlvbihhLGIsYyl7
+dmFyIHMscgp0LkEuYShjKQpzPXRoaXMuYQpyPXMuY2hpbGROb2RlcwppZihiPDB8fGI+PXIubGVuZ3Ro
+KXJldHVybiBILk9IKHIsYikKcy5yZXBsYWNlQ2hpbGQoYyxyW2JdKX0sCmdtOmZ1bmN0aW9uKGEpe3Zh
+ciBzPXRoaXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcgVy5XOShzLHMubGVuZ3RoLEgueihzKS5DKCJX
+OTxHbS5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2hpbGROb2Rlcy5sZW5ndGh9
+LApxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYS5jaGlsZE5vZGVzCmlmKGI8MHx8
+Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQpyZXR1cm4gc1tiXX19ClcudUgucHJvdG90eXBlPXsK
+d2c6ZnVuY3Rpb24oYSl7dmFyIHM9YS5wYXJlbnROb2RlCmlmKHMhPW51bGwpcy5yZW1vdmVDaGlsZChh
+KX0sCkQ0OmZ1bmN0aW9uKGEpe3ZhciBzCmZvcig7cz1hLmZpcnN0Q2hpbGQscyE9bnVsbDspYS5yZW1v
+dmVDaGlsZChzKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9YS5ub2RlVmFsdWUKcmV0dXJuIHM9PW51bGw/
+dGhpcy5VKGEpOnN9LApzYTQ6ZnVuY3Rpb24oYSxiKXthLnRleHRDb250ZW50PWJ9LAptSzpmdW5jdGlv
+bihhLGIsYyl7cmV0dXJuIGEuaW5zZXJ0QmVmb3JlKGIsYyl9LAokaXVIOjF9ClcuQkgucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikK
+aWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwp
+KQpyZXR1cm4gYVtiXX0sClk1OmZ1bmN0aW9uKGEsYixjKXt0LkEuYShjKQp0aHJvdyBILmIoUC5MNCgi
+Q2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCmd0SDpmdW5jdGlvbihh
+KXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKX0s
+CkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJu
+IGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBlPXt9Clcu
+ZXcucHJvdG90eXBlPXskaWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEubGVuZ3RofX0KVy5UYi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyCmlm
+KCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJu
+IHRoaXMuRFcoYSxiLGMsZCkKcz1XLlU5KCI8dGFibGU+IitILkVqKGIpKyI8L3RhYmxlPiIsYyxkKQpy
+PWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpyLnRvU3RyaW5nCnMudG9TdHJpbmcKbmV3
+IFcuZTcocikuRlYoMCxuZXcgVy5lNyhzKSkKcmV0dXJuIHJ9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGlu
+IHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApy
+PXMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnM9Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxl
+IiksYixjLGQpCnMudG9TdHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnEudG9TdHJpbmcKcz1u
+ZXcgVy5lNyhxKQpwPXMuZ3I4KHMpCnIudG9TdHJpbmcKcC50b1N0cmluZwpuZXcgVy5lNyhyKS5GVigw
+LG5ldyBXLmU3KHApKQpyZXR1cm4gcn19ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5w
 cm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApyPXMuY3JlYXRlRG9jdW1l
 bnRGcmFnbWVudCgpCnM9Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnMudG9T
-dHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnEudG9TdHJpbmcKcz1uZXcgVy5lNyhxKQpwPXMu
-Z3I4KHMpCnIudG9TdHJpbmcKcC50b1N0cmluZwpuZXcgVy5lNyhyKS5GVigwLG5ldyBXLmU3KHApKQpy
-ZXR1cm4gcn19ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxCmlm
-KCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJu
-IHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApyPXMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnM9
-Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnMudG9TdHJpbmcKcz1uZXcgVy5l
-NyhzKQpxPXMuZ3I4KHMpCnIudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhyKS5GVigwLG5ldyBX
-LmU3KHEpKQpyZXR1cm4gcn19ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciBz
-LHIKdGhpcy5zYTQoYSxudWxsKQpzPWEuY29udGVudApzLnRvU3RyaW5nCkouYlQocykKcj10aGlzLnI2
-KGEsYixudWxsLGMpCmEuY29udGVudC5hcHBlbmRDaGlsZChyKX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKJGl5WToxfQpXLnc2LnByb3RvdHlwZT17fQpXLks1LnByb3Rv
-dHlwZT17ClBvOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1XLlAxKGEub3BlbihiLGMpKQpyZXR1cm4gc30s
-CmdtVzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhdGlvbn0sCnVzOmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IGEuY29uZmlybShiKX0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnByb3RvdHlwZT17JGlDbToxfQpXLkNR
-LnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj1h
-LmxlZnQKci50b1N0cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAiCnM9YS50b3AKcy50b1N0
-cmluZwpzPXIrSC5FaihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9cytILkVqKHIpKyIgeCAi
-CnM9YS5oZWlnaHQKcy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46ZnVuY3Rpb24oYSxiKXt2
-YXIgcyxyCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5sZWZ0CnMudG9TdHJpbmcK
-cj1iLmxlZnQKci50b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3RyaW5nCnI9Yi50b3AKci50
-b1N0cmluZwppZihzPT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndpZHRoCnIudG9TdHJpbmcK
-aWYocz09PXIpe3M9YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIudG9TdHJpbmcKcj1zPT09
-cgpzPXJ9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExCnJldHVybiBzfSwKZ2lP
-OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9Qy5DRC5naU8ocCkKcz1h
-LnRvcApzLnRvU3RyaW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9TdHJpbmcKcj1DLkNELmdp
-TyhyKQpxPWEuaGVpZ2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIsQy5DRC5naU8ocSkpfX0K
-Vy5yaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9u
-KGEsYil7SC51UChiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxu
-dWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dC5BLmEoYykKdGhy
-b3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApF
-OmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBh
-W2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLmNmLnByb3RvdHlwZT17Cks6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCnQuZUEuYShiKQpmb3Iocz10aGlzLmdWKCkscj1zLmxlbmd0
-aCxxPXRoaXMuYSxwPTA7cDxzLmxlbmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsrcCl7bz1z
-W3BdCmIuJDIobyxxLmdldEF0dHJpYnV0ZShvKSl9fSwKZ1Y6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxv
-LG4sbT10aGlzLmEuYXR0cmlidXRlcwptLnRvU3RyaW5nCnM9SC5WTShbXSx0LnMpCmZvcihyPW0ubGVu
-Z3RoLHE9dC5oOSxwPTA7cDxyOysrcCl7aWYocD49bS5sZW5ndGgpcmV0dXJuIEguT0gobSxwKQpvPXEu
-YShtW3BdKQppZihvLm5hbWVzcGFjZVVSST09bnVsbCl7bj1vLm5hbWUKbi50b1N0cmluZwpDLk5tLmko
-cyxuKX19cmV0dXJuIHN9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0w
-fX0KVy5pNy5wcm90b3R5cGU9ewp4NDpmdW5jdGlvbihhKXt2YXIgcz1ILm9UKHRoaXMuYS5oYXNBdHRy
-aWJ1dGUoYSkpCnJldHVybiBzfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0QXR0cmli
-dXRlKEguaChiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIsYyl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBlPXsKeDQ6
-ZnVuY3Rpb24oYSl7dmFyIHM9SC5vVCh0aGlzLmEuYS5oYXNBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8o
-YSkpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLmEuZ2V0QXR0cmlidXRl
-KCJkYXRhLSIrdGhpcy5PKEguaChiKSkpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhpcy5hLmEuc2V0QXR0
-cmlidXRlKCJkYXRhLSIrdGhpcy5PKGIpLGMpfSwKSzpmdW5jdGlvbihhLGIpe3RoaXMuYS5LKDAsbmV3
-IFcuS1ModGhpcyx0LmVBLmEoYikpKX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHM9SC5WTShbXSx0LnMpCnRo
-aXMuYS5LKDAsbmV3IFcuQTModGhpcyxzKSkKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5nVigpLmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aD09
-PTB9LAprOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1ILlZNKGEuc3BsaXQoIi0iKSx0LnMpCmZvcihzPTE7
-czxxLmxlbmd0aDsrK3Mpe3I9cVtzXQppZihyLmxlbmd0aD4wKUMuTm0uWShxLHMsclswXS50b1VwcGVy
-Q2FzZSgpK0ouS1YociwxKSl9cmV0dXJuIEMuTm0uSChxLCIiKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHMs
-cixxLHAsbwpmb3Iocz1hLmxlbmd0aCxyPTAscT0iIjtyPHM7KytyKXtwPWFbcl0Kbz1wLnRvTG93ZXJD
-YXNlKCkKcT0ocCE9PW8mJnI+MD9xKyItIjpxKStvfXJldHVybiBxLmNoYXJDb2RlQXQoMCk9PTA/cTpx
-fX0KVy5LUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIp
-KXRoaXMuYi4kMih0aGlzLmEuayhDLnhCLkcoYSw1KSksYil9LAokUzoxMH0KVy5BMy5wcm90b3R5cGU9
-ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0aGlzLmIsdGhp
-cy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRTOjEwfQpXLkk0LnByb3RvdHlwZT17ClA6ZnVuY3Rpb24oKXt2
-YXIgcyxyLHEscCxvPVAuTHModC5OKQpmb3Iocz10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscj1z
-Lmxlbmd0aCxxPTA7cTxyOysrcSl7cD1KLlQwKHNbcV0pCmlmKHAubGVuZ3RoIT09MClvLmkoMCxwKX1y
-ZXR1cm4gb30sClg6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT10LkMuYShhKS5IKDAsIiAiKX0s
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aH0sCmdsMDpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3Jl
-dHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aCE9PTB9LApWMTpmdW5jdGlvbihhKXt0aGlzLmEuY2xh
-c3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLmEuY2xhc3NMaXN0LmNvbnRhaW5z
-KGIpCnJldHVybiBzfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5oKGIpCnM9dGhpcy5hLmNsYXNz
-TGlzdApyPXMuY29udGFpbnMoYikKcy5hZGQoYikKcmV0dXJuIXJ9LApSOmZ1bmN0aW9uKGEsYil7dmFy
-IHMscixxCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz10aGlzLmEuY2xhc3NMaXN0CnI9cy5jb250YWlu
-cyhiKQpzLnJlbW92ZShiKQpxPXJ9ZWxzZSBxPSExCnJldHVybiBxfSwKRlY6ZnVuY3Rpb24oYSxiKXtX
-LlROKHRoaXMuYSx0LlEuYShiKSl9fQpXLkZrLnByb3RvdHlwZT17fQpXLlJPLnByb3RvdHlwZT17fQpX
-LmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZOLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodC5CLmEoYSkpfSwKJFM6Mjh9ClcuSlEucHJvdG90eXBlPXsK
-Q1k6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoJC5vci5hPT09MCl7Zm9yKHM9MDtzPDI2MjsrK3MpJC5vci5Z
-KDAsQy5jbVtzXSxXLnBTKCkpCmZvcihzPTA7czwxMjsrK3MpJC5vci5ZKDAsQy5CSVtzXSxXLlY0KCkp
-fX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiAkLkFOKCkudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgcz0kLm9yLnEoMCxILkVqKFcuclMoYSkpKyI6OiIrYikKaWYocz09bnVsbClzPSQu
-b3IucSgwLCIqOjoiK2IpCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIEgueTgocy4kNChhLGIsYyx0
-aGlzKSl9LAokaWtGOjF9ClcuR20ucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBX
-Llc5KGEsdGhpcy5nQShhKSxILnooYSkuQygiVzk8R20uRT4iKSl9fQpXLnZELnByb3RvdHlwZT17Cmkw
-OmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5VdihhKSl9LApFYjpmdW5jdGlv
-bihhLGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVnKGEsYixjKSl9LAokaWtGOjF9Clcu
-VXYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuZjYuYShhKS5pMCh0aGlzLmEpfSwK
-JFM6MTV9ClcuRWcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuZjYuYShhKS5FYih0
-aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoxNX0KVy5tNi5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihh
-LGIsYyxkKXt2YXIgcyxyLHEKdGhpcy5hLkZWKDAsYykKcz1iLmV2KDAsbmV3IFcuRW8oKSkKcj1iLmV2
-KDAsbmV3IFcuV2soKSkKdGhpcy5iLkZWKDAscykKcT10aGlzLmMKcS5GVigwLEMueEQpCnEuRlYoMCxy
-KX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgcz10aGlzLHI9Vy5yUyhhKSxxPXMuYwppZihxLnRnKDAsSC5FaihyKSsiOjoiK2Ip
-KXJldHVybiBzLmQuRHQoYykKZWxzZSBpZihxLnRnKDAsIio6OiIrYikpcmV0dXJuIHMuZC5EdChjKQpl
-bHNle3E9cy5iCmlmKHEudGcoMCxILkVqKHIpKyI6OiIrYikpcmV0dXJuITAKZWxzZSBpZihxLnRnKDAs
-Iio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihxLnRnKDAsSC5FaihyKSsiOjoqIikpcmV0dXJuITAKZWxz
-ZSBpZihxLnRnKDAsIio6OioiKSlyZXR1cm4hMH1yZXR1cm4hMX0sCiRpa0Y6MX0KVy5Fby5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4hQy5ObS50ZyhDLkJJLEguaChhKSl9LAokUzo2fQpXLldr
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLnRnKEMuQkksSC5oKGEpKX0sCiRT
-OjZ9ClcuY3QucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKHRoaXMuakYoYSxiLGMpKXJl
-dHVybiEwCmlmKGI9PT0idGVtcGxhdGUiJiZjPT09IiIpcmV0dXJuITAKaWYoYS5nZXRBdHRyaWJ1dGUo
-InRlbXBsYXRlIik9PT0iIilyZXR1cm4gdGhpcy5lLnRnKDAsYikKcmV0dXJuITF9fQpXLklBLnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiJURU1QTEFURTo6IitILkVqKEguaChhKSl9LAokUzo1
-fQpXLk93LnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKHQuZXcuYihhKSlyZXR1cm4h
-MQpzPXQuZzcuYihhKQppZihzJiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiExCmlmKHMp
-cmV0dXJuITAKcmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMueEIubihi
-LCJvbiIpKXJldHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17
-CkY6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jKzEscT1zLmIKaWYocjxxKXtzLnNwKEoueDkocy5h
-LHIpKQpzLmM9cgpyZXR1cm4hMH1zLnNwKG51bGwpCnMuYz1xCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShh
-KX0sCiRpQW46MX0KVy5kVy5wcm90b3R5cGU9eyRpRDA6MSwkaXY2OjF9ClcubWsucHJvdG90eXBlPXsk
-aXkwOjF9ClcuS28ucHJvdG90eXBlPXsKUG46ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPW5ldyBXLmZt
-KHMpCnMuYj0hMQpyLiQyKGEsbnVsbCkKZm9yKDtzLmI7KXtzLmI9ITEKci4kMihhLG51bGwpfX0sCkVQ
-OmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTpz
-KUouTHQoYSkKZWxzZSBiLnJlbW92ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEs
-cCxvLG49ITAsbT1udWxsLGw9bnVsbAp0cnl7bT1KLmlnKGEpCmw9bS5hLmdldEF0dHJpYnV0ZSgiaXMi
-KQp0LmguYShhKQpzPWZ1bmN0aW9uKGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWRO
-b2RlTWFwKSlyZXR1cm4gdHJ1ZQppZihjLmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxk
-J3x8Yy5pZD09J3ByZXZpb3VzU2libGluZyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9
-PSdjaGlsZHJlbid8fGMubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgaz1jLmNoaWxkTm9k
-ZXMKaWYoYy5sYXN0Q2hpbGQmJmMubGFzdENoaWxkIT09a1trLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQpp
-ZihjLmNoaWxkcmVuKWlmKCEoYy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNo
-aWxkcmVuIGluc3RhbmNlb2YgTm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBqPTAKaWYoYy5jaGlsZHJl
-bilqPWMuY2hpbGRyZW4ubGVuZ3RoCmZvcih2YXIgaT0wO2k8ajtpKyspe3ZhciBoPWMuY2hpbGRyZW5b
-aV0KaWYoaC5pZD09J2F0dHJpYnV0ZXMnfHxoLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aC5pZD09J2xhc3RD
-aGlsZCd8fGgubmFtZT09J2xhc3RDaGlsZCd8fGguaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxoLm5hbWU9
-PSdwcmV2aW91c1NpYmxpbmcnfHxoLmlkPT0nY2hpbGRyZW4nfHxoLm5hbWU9PSdjaGlsZHJlbicpcmV0
-dXJuIHRydWV9cmV0dXJuIGZhbHNlfShhKQpuPUgub1Qocyk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFu
-Y2VvZiBOYW1lZE5vZGVNYXApfWNhdGNoKHApe0guUnUocCl9cj0iZWxlbWVudCB1bnByaW50YWJsZSIK
-dHJ5e3I9Si5qKGEpfWNhdGNoKHApe0guUnUocCl9dHJ5e3E9Vy5yUyhhKQp0aGlzLmtSKHQuaC5hKGEp
-LGIsbixyLHEsdC5mLmEobSksSC5rKGwpKX1jYXRjaChwKXtpZihILlJ1KHApIGluc3RhbmNlb2YgUC51
-KXRocm93IHAKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93Cm89IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVt
-ZW50ICIrSC5FaihyKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUu
-d2FybihvKX19fSwKa1I6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG09dGhp
-cwppZihjKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRl
-ZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4iCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5k
-b3cuY29uc29sZS53YXJuKHMpCnJldHVybn1pZighbS5hLmkwKGEpKXttLkVQKGEsYikKd2luZG93CnM9
-IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxlbWVudCA8IitILkVqKGUpKyI+IGZyb20gIitILkVqKGIpCmlm
-KHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVybn1p
-ZihnIT1udWxsKWlmKCFtLmEuRWIoYSwiaXMiLGcpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5n
-IGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5FaihlKSsnIGlzPSInK2crJyI+JwppZih0eXBl
-b2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59cz1mLmdW
-KCkKcj1ILlZNKHMuc2xpY2UoMCksSC50NihzKSkKZm9yKHE9Zi5nVigpLmxlbmd0aC0xLHM9Zi5hO3E+
-PTA7LS1xKXtpZihxPj1yLmxlbmd0aClyZXR1cm4gSC5PSChyLHEpCnA9cltxXQpvPW0uYQpuPUouY0go
-cCkKSC5oKHApCmlmKCFvLkViKGEsbixzLmdldEF0dHJpYnV0ZShwKSkpe3dpbmRvdwpvPSJSZW1vdmlu
-ZyBkaXNhbGxvd2VkIGF0dHJpYnV0ZSA8IitILkVqKGUpKyIgIitwKyc9IicrSC5FaihzLmdldEF0dHJp
-YnV0ZShwKSkrJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUu
-d2FybihvKQpzLnJlbW92ZUF0dHJpYnV0ZShwKX19aWYodC5hVy5iKGEpKXtzPWEuY29udGVudApzLnRv
-U3RyaW5nCm0uUG4ocyl9fSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dmFyIHMscixxLHAsbyxuLG09dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtjYXNlIDE6bS5JNChhLGIp
-CmJyZWFrCmNhc2UgODpjYXNlIDExOmNhc2UgMzpjYXNlIDQ6YnJlYWsKZGVmYXVsdDptLkVQKGEsYil9
-cz1hLmxhc3RDaGlsZApmb3IocT10LkE7bnVsbCE9czspe3I9bnVsbAp0cnl7cj1zLnByZXZpb3VzU2li
-bGluZwppZihyIT1udWxsKXtwPXIubmV4dFNpYmxpbmcKbz1zCm89cD09bnVsbD9vIT1udWxsOnAhPT1v
-CnA9b31lbHNlIHA9ITEKaWYocCl7cD1QLlBWKCJDb3JydXB0IEhUTUwiKQp0aHJvdyBILmIocCl9fWNh
-dGNoKG4pe0guUnUobikKcD1xLmEocykKbS5iPSEwCm89cC5wYXJlbnROb2RlCm89YT09bnVsbD9vIT1u
-dWxsOmEhPT1vCmlmKG8pe289cC5wYXJlbnROb2RlCmlmKG8hPW51bGwpby5yZW1vdmVDaGlsZChwKX1l
-bHNlIGEucmVtb3ZlQ2hpbGQocCkKcz1udWxsCnI9YS5sYXN0Q2hpbGR9aWYocyE9bnVsbCl0aGlzLiQy
-KHMsYSkKcz1yfX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnByb3RvdHlwZT17fQpXLnJC
-LnByb3RvdHlwZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlwZT17fQpQLmlKLnByb3Rv
-dHlwZT17ClZIOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5hLHE9ci5sZW5ndGgKZm9yKHM9MDtzPHE7
-KytzKWlmKHJbc109PT1hKXJldHVybiBzCkMuTm0uaShyLGEpCkMuTm0uaSh0aGlzLmIsbnVsbCkKcmV0
-dXJuIHF9LApQdjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD10aGlzLG89e30KaWYoYT09bnVsbClyZXR1
-cm4gYQppZihILmwoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKHR5
-cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1cm4gbmV3IERh
-dGUoYS5hKQppZih0LmZ2LmIoYSkpdGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2YgUmVn
-RXhwIikpCmlmKHQuYzguYihhKSlyZXR1cm4gYQppZih0LncuYihhKSlyZXR1cm4gYQppZih0LkkuYihh
-KSlyZXR1cm4gYQpzPXQuZEUuYihhKXx8ITEKaWYocylyZXR1cm4gYQppZih0LmYuYihhKSl7cj1wLlZI
-KGEpCnM9cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1vLmE9c1tyXQppZihxIT1u
-dWxsKXJldHVybiBxCnE9e30Kby5hPXEKQy5ObS5ZKHMscixxKQphLksoMCxuZXcgUC5qZyhvLHApKQpy
-ZXR1cm4gby5hfWlmKHQuai5iKGEpKXtyPXAuVkgoYSkKbz1wLmIKaWYocj49by5sZW5ndGgpcmV0dXJu
-IEguT0gobyxyKQpxPW9bcl0KaWYocSE9bnVsbClyZXR1cm4gcQpyZXR1cm4gcC5layhhLHIpfWlmKHQu
-ZUguYihhKSl7cj1wLlZIKGEpCnM9cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1v
-LmI9c1tyXQppZihxIT1udWxsKXJldHVybiBxCnE9e30Kby5iPXEKQy5ObS5ZKHMscixxKQpwLmltKGEs
-bmV3IFAuVGEobyxwKSkKcmV0dXJuIG8uYn10aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBv
-ZiBvdGhlciB0eXBlIikpfSwKZWs6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPUouVTYoYSkscT1yLmdBKGEp
-LHA9bmV3IEFycmF5KHEpCkMuTm0uWSh0aGlzLmIsYixwKQpmb3Iocz0wO3M8cTsrK3MpQy5ObS5ZKHAs
-cyx0aGlzLlB2KHIucShhLHMpKSkKcmV0dXJuIHB9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9u
-KGEsYil7dGhpcy5hLmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6MzJ9ClAuVGEucHJvdG90eXBlPXsKJDI6
-ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlthXT10aGlzLmIuUHYoYil9LAokUzoxNn0KUC5CZi5wcm90b3R5
-cGU9ewppbTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuYjguYShiKQpmb3Iocz1PYmplY3Qua2V5
-cyhhKSxyPXMubGVuZ3RoLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLGFbcF0pfX19ClAuQXMucHJv
-dG90eXBlPXsKVDpmdW5jdGlvbihhKXt2YXIgcwpILmgoYSkKcz0kLmhHKCkuYgppZih0eXBlb2YgYSE9
-InN0cmluZyIpSC52KEgudEwoYSkpCmlmKHMudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhh
-LCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5QKCkuSCgwLCIgIil9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLlAoKQpyZXR1cm4gUC5y
-aihzLHMucixILkxoKHMpLmMpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlAoKS5hPT09MH0s
-CmdvcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QKCkuYSE9PTB9LApnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5QKCkuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiB0aGlzLlAoKS50
-ZygwLGIpfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzCkguaChiKQp0aGlzLlQoYikKcz10aGlzLk9TKG5l
-dyBQLkdFKGIpKQpyZXR1cm4gSC55OChzPT1udWxsPyExOnMpfSwKUjpmdW5jdGlvbihhLGIpe3ZhciBz
-LHIKaWYodHlwZW9mIGIhPSJzdHJpbmciKXJldHVybiExCnRoaXMuVChiKQpzPXRoaXMuUCgpCnI9cy5S
-KDAsYikKdGhpcy5YKHMpCnJldHVybiByfSwKRlY6ZnVuY3Rpb24oYSxiKXt0aGlzLk9TKG5ldyBQLk43
-KHRoaXMsdC5RLmEoYikpKX0sCmVSOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5QKCkKcmV0dXJuIEgu
-YksocyxiLEguTGgocykuQygibGYuRSIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5QKCku
-RSgwLGIpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIKdC5iVS5hKGEpCnM9dGhpcy5QKCkKcj1hLiQxKHMpCnRoaXMuWChzKQpyZXR1cm4gcn19
-ClAuR0UucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuQy5hKGEpLmkoMCx0aGlzLmEp
-fSwKJFM6MzR9ClAuTjcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5iLHI9SC50
-NihzKQpyZXR1cm4gdC5DLmEoYSkuRlYoMCxuZXcgSC5sSihzLHIuQygicVUoMSkiKS5hKHRoaXMuYS5n
-dU0oKSksci5DKCJsSjwxLHFVPiIpKSl9LAokUzoxN30KUC51US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt0LkMuYShhKQppZihhLmE+MCl7YS5iPWEuYz1hLmQ9YS5lPWEuZj1udWxsCmEuYT0wCmEuUygp
-fXJldHVybiBudWxsfSwKJFM6MTd9ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5ZLmEoYSkKcz1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1
-bmN0aW9uKCl7cmV0dXJuIGIoYyxkLHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3Vt
-ZW50cykpfX0oUC5SNCxhLCExKQpQLkRtKHMsJC53KCksYSkKcmV0dXJuIHN9LAokUzo0fQpQLm10LnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6NH0KUC5Oei5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzo1NX0KUC5RUy5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVHooYSx0LmFtKX0sCiRTOjM3fQpQ
-Lm5wLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM4fQpQ
-LkU0LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVv
-ZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51
-bSIpKQpyZXR1cm4gUC5kVSh0aGlzLmFbYl0pfSwKWTpmdW5jdGlvbihhLGIsYyl7aWYodHlwZW9mIGIh
-PSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5v
-dCBhIFN0cmluZyBvciBudW0iKSkKdGhpcy5hW2JdPVAud1koYyl9LApETjpmdW5jdGlvbihhLGIpe2lm
-KGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLkU0JiZ0aGlzLmE9PT1iLmF9LAp3
-OmZ1bmN0aW9uKGEpe3ZhciBzLHIKdHJ5e3M9U3RyaW5nKHRoaXMuYSkKcmV0dXJuIHN9Y2F0Y2gocil7
-SC5SdShyKQpzPXRoaXMueGIoMCkKcmV0dXJuIHN9fSwKVjc6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRo
-aXMuYQppZihiPT1udWxsKXM9bnVsbAplbHNle3M9SC50NihiKQpzPVAuQ0gobmV3IEgubEooYixzLkMo
-IkAoMSkiKS5hKFAuaUcoKSkscy5DKCJsSjwxLEA+IikpLCEwLHQueil9cmV0dXJuIFAuZFUoclthXS5h
-cHBseShyLHMpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH19ClAucjcucHJvdG90eXBlPXt9ClAu
-VHoucHJvdG90eXBlPXsKY1A6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPWE8MHx8YT49cy5nQShzKQpp
-ZihyKXRocm93IEguYihQLlRFKGEsMCxzLmdBKHMpLG51bGwsbnVsbCkpfSwKcTpmdW5jdGlvbihhLGIp
-e2lmKEgub2soYikpdGhpcy5jUChiKQpyZXR1cm4gdGhpcy4kdGkuYy5hKHRoaXMuVXIoMCxiKSl9LApZ
-OmZ1bmN0aW9uKGEsYixjKXt0aGlzLmNQKGIpCnRoaXMuZTQoMCxiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7
-dmFyIHM9dGhpcy5hLmxlbmd0aAppZih0eXBlb2Ygcz09PSJudW1iZXIiJiZzPj4+MD09PXMpcmV0dXJu
-IHMKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0sCiRpYlE6MSwKJGljWDoxLAok
-aXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAubmQucHJvdG90eXBlPXskaW5kOjF9ClAuS2UucHJvdG90
-eXBlPXsKUDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhpcy5hLmdldEF0dHJpYnV0ZSgiY2xhc3Mi
-KSxuPVAuTHModC5OKQppZihvPT1udWxsKXJldHVybiBuCmZvcihzPW8uc3BsaXQoIiAiKSxyPXMubGVu
-Z3RoLHE9MDtxPHI7KytxKXtwPUouVDAoc1txXSkKaWYocC5sZW5ndGghPT0wKW4uaSgwLHApfXJldHVy
-biBufSwKWDpmdW5jdGlvbihhKXt0aGlzLmEuc2V0QXR0cmlidXRlKCJjbGFzcyIsYS5IKDAsIiAiKSl9
-fQpQLmhpLnByb3RvdHlwZT17CmdEOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5LZShhKX0sCnNoZjpm
-dW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxw
-LG8sbgppZihkPT1udWxsKXtzPUguVk0oW10sdC52KQpkPW5ldyBXLnZEKHMpCkMuTm0uaShzLFcuVHco
-bnVsbCkpCkMuTm0uaShzLFcuQmwoKSkKQy5ObS5pKHMsbmV3IFcuT3coKSl9Yz1uZXcgVy5LbyhkKQpy
-PSc8c3ZnIHZlcnNpb249IjEuMSI+JytILkVqKGIpKyI8L3N2Zz4iCnM9ZG9jdW1lbnQKcT1zLmJvZHkK
-cS50b1N0cmluZwpwPUMuUlkuQUgocSxyLGMpCm89cy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKcC50
-b1N0cmluZwpzPW5ldyBXLmU3KHApCm49cy5ncjgocykKZm9yKDtzPW4uZmlyc3RDaGlsZCxzIT1udWxs
-OylvLmFwcGVuZENoaWxkKHMpCnJldHVybiBvfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt0aHJvdyBI
-LmIoUC5MNCgiQ2Fubm90IGludm9rZSBpbnNlcnRBZGphY2VudEh0bWwgb24gU1ZHLiIpKX0sCmdWbDpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHQuayl9LAokaWhpOjF9Ck0uSDcu
-cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KVS5MTC5wcm90b3R5cGU9ewpM
-dDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibm9kZUlkIix0aGlzLmIsImtpbmQiLHRoaXMuYS5hXSx0
-LlgsdC5fKX19ClUuTUQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuZkUuYShhKS5h
-PT09dGhpcy5hLnEoMCwia2luZCIpfSwKJFM6Mzl9ClUuZDIucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscCxvPXRoaXMsbj10LlgsbT10Ll8sbD1QLkZsKG4sbSksaz1vLmEKaWYoayE9bnVs
-bCl7cz1ILlZNKFtdLHQuRykKZm9yKHI9ay5sZW5ndGgscT0wO3E8ay5sZW5ndGg7ay5sZW5ndGg9PT1y
-fHwoMCxILmxrKShrKSwrK3Epe3A9a1txXQpDLk5tLmkocyxQLkVGKFsiZGVzY3JpcHRpb24iLHAuYSwi
-aHJlZiIscC5iXSxuLG0pKX1sLlkoMCwiZWRpdHMiLHMpfWwuWSgwLCJleHBsYW5hdGlvbiIsby5iKQps
-LlkoMCwibGluZSIsby5jKQpsLlkoMCwiZGlzcGxheVBhdGgiLG8uZCkKbC5ZKDAsInVyaVBhdGgiLG8u
-ZSkKbj1vLmYKaWYobiE9bnVsbCl7bT1ILlZNKFtdLHQuRykKZm9yKGs9bi5sZW5ndGgscT0wO3E8bi5s
-ZW5ndGg7bi5sZW5ndGg9PT1rfHwoMCxILmxrKShuKSwrK3EpQy5ObS5pKG0sbltxXS5MdCgpKQpsLlko
-MCwidHJhY2VzIixtKX1yZXR1cm4gbH19ClUuU2UucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1
-cm4gUC5FRihbImRlc2NyaXB0aW9uIix0aGlzLmEsImhyZWYiLHRoaXMuYl0sdC5YLHQuXyl9fQpVLk1s
-LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJocmVmIix0aGlzLmEsImxpbmUi
-LHRoaXMuYiwicGF0aCIsdGhpcy5jXSx0LlgsdC5fKX19ClUueUQucHJvdG90eXBlPXsKTHQ6ZnVuY3Rp
-b24oKXt2YXIgcyxyLHEscD1ILlZNKFtdLHQuRykKZm9yKHM9dGhpcy5iLHI9cy5sZW5ndGgscT0wO3E8
-cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK3EpQy5ObS5pKHAsc1txXS5MdCgpKQpy
-ZXR1cm4gUC5FRihbImRlc2NyaXB0aW9uIix0aGlzLmEsImVudHJpZXMiLHBdLHQuWCx0Ll8pfX0KVS53
-Yi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHIscSxwPXRoaXMsbz1QLkZsKHQuWCx0Ll8p
-Cm8uWSgwLCJkZXNjcmlwdGlvbiIscC5hKQpzPXAuYgppZihzIT1udWxsKW8uWSgwLCJmdW5jdGlvbiIs
-cykKcz1wLmMKaWYocyE9bnVsbClvLlkoMCwibGluayIscy5MdCgpKQpzPXAuZAppZihzLmxlbmd0aCE9
-PTApe3I9SC50NihzKQpxPXIuQygibEo8MSxaMDxxVSosTWgqPio+IikKby5ZKDAsImhpbnRBY3Rpb25z
-IixQLkNIKG5ldyBILmxKKHMsci5DKCJaMDxxVSosTWgqPiooMSkiKS5hKG5ldyBVLmIwKCkpLHEpLCEw
-LHEuQygiYUwuRSIpKSl9cmV0dXJuIG99fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBVLm56KHQudC5hKGEpKX0sCiRTOjQwfQpVLmIwLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3JldHVybiB0LmFYLmEoYSkuTHQoKX0sCiRTOjQxfQpCLmo4LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9u
-KCl7cmV0dXJuIFAuRUYoWyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlzLmIsIm9mZnNldCIs
-dGhpcy5jXSx0LlgsdC5fKX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEs
-cCxvLG4sbSxsPXRoaXMsaz10Llgsaj1QLkZsKGssdC5kcCkKZm9yKHM9bC5kLHM9cy5nUHUocykscz1z
-LmdtKHMpLHI9dC5fLHE9dC5HO3MuRigpOyl7cD1zLmdsKCkKbz1wLmEKbj1ILlZNKFtdLHEpCmZvcihw
-PUouSVQocC5iKTtwLkYoKTspe209cC5nbCgpCkMuTm0uaShuLFAuRUYoWyJsaW5lIixtLmEsImV4cGxh
-bmF0aW9uIixtLmIsIm9mZnNldCIsbS5jXSxrLHIpKX1qLlkoMCxvLG4pfXJldHVybiBQLkVGKFsicmVn
-aW9ucyIsbC5hLCJuYXZpZ2F0aW9uQ29udGVudCIsbC5iLCJzb3VyY2VDb2RlIixsLmMsImVkaXRzIixq
-XSxrLHIpfX0KVC5tUS5wcm90b3R5cGU9e30KTC5lLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIscSxwLG8sbixtCnQuYUwuYShhKQpzPXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpyPUwuRzYo
-d2luZG93LmxvY2F0aW9uLmhyZWYpCnE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlm
-KHMhPT0iLyImJnMhPT1KLlQwKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRl
-bnQpKUwuRzcocyxyLHEsITAsbmV3IEwuVlcocyxyLHEpKQpwPWRvY3VtZW50Cm89Si5xRihwLnF1ZXJ5
-U2VsZWN0b3IoIi5hcHBseS1taWdyYXRpb24iKSkKbj1vLiR0aQptPW4uQygifigxKT8iKS5hKG5ldyBM
-Lm9aKCkpCnQuWi5hKG51bGwpClcuSkUoby5hLG8uYixtLCExLG4uYykKbj1KLnFGKHAucXVlcnlTZWxl
-Y3RvcigiLnJlcnVuLW1pZ3JhdGlvbiIpKQptPW4uJHRpClcuSkUobi5hLG4uYixtLkMoIn4oMSk/Iiku
-YShuZXcgTC5IaSgpKSwhMSxtLmMpCm09Si5xRihwLnF1ZXJ5U2VsZWN0b3IoIi5yZXBvcnQtcHJvYmxl
-bSIpKQpuPW0uJHRpClcuSkUobS5hLG0uYixuLkMoIn4oMSk/IikuYShuZXcgTC5CVCgpKSwhMSxuLmMp
-CnA9Si5xRihwLnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIC5jbG9zZSIpKQpuPXAuJHRpClcuSkUo
-cC5hLHAuYixuLkMoIn4oMSk/IikuYShuZXcgTC5QWSgpKSwhMSxuLmMpfSwKJFM6MTh9CkwuVlcucHJv
-dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjF9Ckwu
-b1oucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAKdC5PLmEoYSkKaWYoSC5vVChD
-Lm9sLnVzKHdpbmRvdywiVGhpcyB3aWxsIGFwcGx5IHRoZSBjaGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQg
-dG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVjb21tZW5kZWQgeW91IGNvbW1pdCBhbnkg
-Y2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4iKSkpe3M9TC50eSgiL2FwcGx5LW1pZ3Jh
-dGlvbiIsbnVsbCkuVzcobmV3IEwuanIoKSx0LlApCnI9bmV3IEwucWwoKQp0LmI3LmEobnVsbCkKcT1z
-LiR0aQpwPSQuWDMKaWYocCE9PUMuTlUpcj1QLlZIKHIscCkKcy54ZihuZXcgUC5GZShuZXcgUC52cyhw
-LHEpLDIsbnVsbCxyLHEuQygiQDwxPiIpLktxKHEuYykuQygiRmU8MSwyPiIpKSl9fSwKJFM6Mn0KTC5q
-ci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0LnQuYShhKQpzPWRvY3VtZW50LmJvZHkK
-cy5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnMuY2xhc3NMaXN0LmFkZCgiYXBwbGllZCIpfSwK
-JFM6NDR9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLkMyKCJDb3VsZCBub3QgYXBw
-bHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MTZ9CkwuSGkucHJvdG90eXBlPXsK
-JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMueG4odC5PLmEoYSkpfSwKeG46ZnVuY3Rpb24oYSl7dmFy
-IHM9MCxyPVAuRlgodC5QKSxxPTEscCxvPVtdLG4sbSxsLGssagp2YXIgJGFzeW5jJCQxPVAubHooZnVu
-Y3Rpb24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13aGlsZSh0cnVlKXN3aXRjaChzKXtjYXNlIDA6cT0z
-CmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5nIikKcz02CnJldHVybiBQLmpRKEwu
-dHkoIi9yZXJ1bi1taWdyYXRpb24iLG51bGwpLCRhc3luYyQkMSkKY2FzZSA2Om49YwppZihILm9UKEgu
-eTgoSi54OShuLCJzdWNjZXNzIikpKSl3aW5kb3cubG9jYXRpb24ucmVsb2FkKCkKZWxzZSBMLkswKHQu
-bS5hKEoueDkobiwiZXJyb3JzIikpKQpvLnB1c2goNSkKcz00CmJyZWFrCmNhc2UgMzpxPTIKaj1wCm09
-SC5SdShqKQpsPUgudHMoaikKTC5DMigiRmFpbGVkIHRvIHJlcnVuIG1pZ3JhdGlvbiIsbSxsKQpvLnB1
-c2goNSkKcz00CmJyZWFrCmNhc2UgMjpvPVsxXQpjYXNlIDQ6cT0xCmRvY3VtZW50LmJvZHkuY2xhc3NM
-aXN0LnJlbW92ZSgicmVydW5uaW5nIikKcz1vLnBvcCgpCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55Qyhu
-dWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyQkMSxyKX0s
-CiRTOjE5fQpMLkJULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9dC5Y
-CkMub2wuUG8od2luZG93LFAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNz
-dWVzL25ldyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0aCBOTkJEIG1p
-Z3JhdGlvbiB0b29sIiwibGFiZWxzIix1LmQsImJvZHkiLCIjIyMjIFN0ZXBzIHRvIHJlcHJvZHVjZVxu
-XG4jIyMjIFdoYXQgZGlkIHlvdSBleHBlY3QgdG8gaGFwcGVuP1xuXG4jIyMjIFdoYXQgYWN0dWFsbHkg
-aGFwcGVuZWQ/XG5cbl9TY3JlZW5zaG90cyBhcmUgYXBwcmVjaWF0ZWRfXG5cbioqRGFydCBTREsgdmVy
-c2lvbioqOiAiK0guRWooZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNkay12ZXJzaW9uIikudGV4dENv
-bnRlbnQpKyJcblxuVGhhbmtzIGZvciBmaWxpbmchXG4iXSxzLHMpKS5nbkQoKSwicmVwb3J0LXByb2Js
-ZW0iKX0sCiRTOjJ9CkwuUFkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkK
-cz1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFuZSIpLnN0eWxlCnMuZGlzcGxheT0ibm9u
-ZSIKcmV0dXJuIm5vbmUifSwKJFM6NDZ9CkwuTC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEKdC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cubG9j
-YXRpb24uaHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZihzLmxlbmd0aD4xKUwuRzco
-cyxyLHEsITEsbnVsbCkKZWxzZXtMLkJFKHMsQi53UigpLCEwKQpMLkJYKCImbmJzcDsiLG51bGwpfX0s
-CiRTOjE4fQpMLld4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPSJjb2xsYXBz
-ZWQiCnQuTy5hKGEpCnM9dGhpcy5hCnI9Si5ZRShzKQpxPXRoaXMuYgppZighci5nRChzKS50ZygwLHAp
-KXtyLmdEKHMpLmkoMCxwKQpKLmRSKHEpLmkoMCxwKX1lbHNle3IuZ0QocykuUigwLHApCkouZFIocSku
-UigwLHApfX0sCiRTOjJ9CkwuQU8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9Si5xRih0
-LmcuYShhKSkscj1zLiR0aSxxPXIuQygifigxKT8iKS5hKG5ldyBMLmROKHRoaXMuYSkpCnQuWi5hKG51
-bGwpClcuSkUocy5hLHMuYixxLCExLHIuYyl9LAokUzozfQpMLmROLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1w
-YXRoXSIpCnMudG9TdHJpbmcKTC50MihhLHRoaXMuYSxzLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
-LlN5KG5ldyBXLmk3KHMpKS5PKCJwYXRoIikpKX0sCiRTOjJ9CkwuSG8ucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscixxCnQuZy5hKGEpCnM9Si5xRihhKQpyPXMuJHRpCnE9ci5DKCJ+KDEpPyIp
-LmEobmV3IEwueHooYSx0aGlzLmEpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIscSwhMSxyLmMpfSwK
-JFM6M30KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPXRoaXMu
-YQpMLmhYKHRoaXMuYixQLlFBKHMuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTco
-cykpLk8oIm9mZnNldCIpKSxudWxsKSxQLlFBKHMuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3ko
-bmV3IFcuaTcocykpLk8oImxpbmUiKSksbnVsbCkpfSwKJFM6Mn0KTC5JQy5wcm90b3R5cGU9ewokMTpm
-dW5jdGlvbihhKXt2YXIgcz1KLnFGKHQuZy5hKGEpKSxyPXMuJHRpCnIuQygifigxKT8iKS5hKEwuaVMo
-KSkKdC5aLmEobnVsbCkKVy5KRShzLmEscy5iLEwuaVMoKSwhMSxyLmMpfSwKJFM6M30KTC5mQy5wcm90
-b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0LmVRLmEoYSkKdGhpcy5hLmFNKDAsdGhpcy5iKX0sCiRTOjQ4
-fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9
-LAokUzoxfQpMLk5ZLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsbnVsbCxudWxs
-KX0sCiRTOjF9CkwudWUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5hdy5hKGEpCnJldHVybiBI
-LkVqKGEucSgwLCJzZXZlcml0eSIpKSsiIC0gIitILkVqKGEucSgwLCJtZXNzYWdlIikpKyIgYXQgIitI
-LkVqKGEucSgwLCJsb2NhdGlvbiIpKSsiIC0gKCIrSC5FaihhLnEoMCwiY29kZSIpKSsiKSJ9LAokUzo0
-OX0KTC5lWC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0LmcuYShhKQokLnpCKCkudG9TdHJpbmcK
-dC5kSC5hKCQub3coKS5xKDAsImhsanMiKSkuVjcoImhpZ2hsaWdodEJsb2NrIixbYV0pfSwKJFM6M30K
-TC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcyxyCnQuTy5hKGEpLnByZXZlbnREZWZh
-dWx0KCkKcz10aGlzLmEKcj10aGlzLmIKTC5hZih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUscyxyLCEw
-LG5ldyBMLlFMKHMscikpCkwuaFgodGhpcy5jLHMscil9LAokUzoyfQpMLlFMLnByb3RvdHlwZT17CiQw
-OmZ1bmN0aW9uKCl7TC5Gcih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdGhpcy5hLHRoaXMuYil9LAok
-UzoxfQpMLlZTLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHI9InNlbGVjdGVkLWZpbGUi
-CnQuZy5hKGEpCmEudG9TdHJpbmcKcz1KLllFKGEpCmlmKGEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3
-IFcuU3kobmV3IFcuaTcoYSkpLk8oIm5hbWUiKSk9PT10aGlzLmEuYSlzLmdEKGEpLmkoMCxyKQplbHNl
-IHMuZ0QoYSkuUigwLHIpfSwKJFM6M30KTC5URC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
-cm4gTC50Mih0Lk8uYShhKSwhMCxudWxsKX0sCiRTOjIwfQpMLm0yLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLlJJKHQuTy5hKGEpKX0sClJJOmZ1bmN0aW9uKGEpe3ZhciBzPTAscj1Q
-LkZYKHQuUCkscT0xLHAsbz1bXSxuPXRoaXMsbSxsLGssaixpLGgsZyxmCnZhciAkYXN5bmMkJDE9UC5s
-eihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2Ug
-MDpxPTMKaT1kb2N1bWVudAptPUMuQ0QuelEoaS5xdWVyeVNlbGVjdG9yKCIuY29udGVudCIpLnNjcm9s
-bFRvcCkKaD10LlgKcz02CnJldHVybiBQLmpRKEwudHkoTC5RNCgiL2FwcGx5LWhpbnQiLFAuRmwoaCxo
-KSksbi5hLkx0KCkpLCRhc3luYyQkMSkKY2FzZSA2Omg9bi5iCmw9TC5VcyhoLmEpCnM9NwpyZXR1cm4g
-UC5qUShMLkc3KGwsbnVsbCxoLmIsITEsbnVsbCksJGFzeW5jJCQxKQpjYXNlIDc6aS5ib2R5LmNsYXNz
-TGlzdC5hZGQoIm5lZWRzLXJlcnVuIikKaT1pLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50IikKaS50b1N0
-cmluZwppLnNjcm9sbFRvcD1KLlZ1KG0pCnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9MgpmPXAKaz1ILlJ1
-KGYpCmo9SC50cyhmKQpMLkMyKCJDb3VsZCBub3QgYXBwbHkgaGludCIsayxqKQpzPTUKYnJlYWsKY2Fz
-ZSAyOnM9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxyKQpjYXNlIDE6cmV0dXJuIFAuZjMo
-cCxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscil9LAokUzoxOX0KTC5YQS5wcm90b3R5cGU9ewpF
-YjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6
-MX0KTC5aWi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPVAuRmwodC5YLHQu
-XykKcS5ZKDAsInR5cGUiLEwudnkoci5hKSkKcS5ZKDAsIm5hbWUiLHIuYikKcz1yLmMKaWYocyE9bnVs
-bClxLlkoMCwic3VidHJlZSIsTC5WRChzKSkKcz1yLmQKaWYocyE9bnVsbClxLlkoMCwicGF0aCIscykK
-cz1yLmUKaWYocyE9bnVsbClxLlkoMCwiaHJlZiIscykKcz1yLmYKaWYocyE9bnVsbClxLlkoMCwiZWRp
-dENvdW50IixzKQpyZXR1cm4gcX19CkwuTzkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5ifX0KTS5sSS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciBzPUQuYWIoKQpyZXR1cm4g
-c30sCldPOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPXQuZDQKTS5ZRigiYWJzb2x1dGUiLEguVk0oW2Is
-bnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGxdLHEpKQpzPXRoaXMuYQpzPXMuWXIoYik+MCYmIXMu
-aEsoYikKaWYocylyZXR1cm4gYgpyPUguVk0oW3RoaXMuZ2woKSxiLG51bGwsbnVsbCxudWxsLG51bGws
-bnVsbCxudWxsXSxxKQpNLllGKCJqb2luIixyKQpyZXR1cm4gdGhpcy5JUChuZXcgSC51NihyLHQuZUop
-KX0sCnpmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1YLkNMKGEsdGhpcy5hKQpxLklWKCkKcz1xLmQKcj1z
-Lmxlbmd0aAppZihyPT09MCl7cz1xLmIKcmV0dXJuIHM9PW51bGw/Ii4iOnN9aWYocj09PTEpe3M9cS5i
-CnJldHVybiBzPT1udWxsPyIuIjpzfWlmKDA+PXIpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEu
-ZQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnEuSVYoKQpyZXR1cm4gcS53
-KDApfSwKSVA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGoKdC5RLmEoYSkKZm9yKHM9
-YS4kdGkscj1zLkMoImEyKGNYLkUpIikuYShuZXcgTS5xNygpKSxxPWEuZ20oYSkscz1uZXcgSC5TTyhx
-LHIscy5DKCJTTzxjWC5FPiIpKSxyPXRoaXMuYSxwPSExLG89ITEsbj0iIjtzLkYoKTspe209cS5nbCgp
-CmlmKHIuaEsobSkmJm8pe2w9WC5DTChtLHIpCms9bi5jaGFyQ29kZUF0KDApPT0wP246bgpuPUMueEIu
-TmooaywwLHIuU3AoaywhMCkpCmwuYj1uCmlmKHIuZHMobikpQy5ObS5ZKGwuZSwwLHIuZ21JKCkpCm49
-bC53KDApfWVsc2UgaWYoci5ZcihtKT4wKXtvPSFyLmhLKG0pCm49SC5FaihtKX1lbHNle2o9bS5sZW5n
-dGgKaWYoaiE9PTApe2lmKDA+PWopcmV0dXJuIEguT0gobSwwKQpqPXIuVWQobVswXSl9ZWxzZSBqPSEx
-CmlmKCFqKWlmKHApbis9ci5nbUkoKQpuKz1tfXA9ci5kcyhtKX1yZXR1cm4gbi5jaGFyQ29kZUF0KDAp
-PT0wP246bn0sCm81OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnM9WC5D
-TChhLHRoaXMuYSkKcy5yUigpCnJldHVybiBzLncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
-cCxvLG4sbSxsLGssagphLnRvU3RyaW5nCnM9dGhpcy5hCnI9cy5ZcihhKQppZihyIT09MCl7aWYocz09
-PSQuS2soKSlmb3IocT0wO3E8cjsrK3EpaWYoQy54Qi5XKGEscSk9PT00NylyZXR1cm4hMApwPXIKbz00
-N31lbHNle3A9MApvPW51bGx9Zm9yKG49bmV3IEgucWooYSkuYSxtPW4ubGVuZ3RoLHE9cCxsPW51bGw7
-cTxtOysrcSxsPW8sbz1rKXtrPUMueEIuTzIobixxKQppZihzLnI0KGspKXtpZihzPT09JC5LaygpJiZr
-PT09NDcpcmV0dXJuITAKaWYobyE9bnVsbCYmcy5yNChvKSlyZXR1cm4hMAppZihvPT09NDYpaj1sPT1u
-dWxsfHxsPT09NDZ8fHMucjQobCkKZWxzZSBqPSExCmlmKGopcmV0dXJuITB9fWlmKG89PW51bGwpcmV0
-dXJuITAKaWYocy5yNChvKSlyZXR1cm4hMAppZihvPT09NDYpcz1sPT1udWxsfHxzLnI0KGwpfHxsPT09
-NDYKZWxzZSBzPSExCmlmKHMpcmV0dXJuITAKcmV0dXJuITF9LApIUDpmdW5jdGlvbihhLGIpe3ZhciBz
-LHIscSxwLG8sbixtLGw9dGhpcyxrPSdVbmFibGUgdG8gZmluZCBhIHBhdGggdG8gIicKYj1sLldPKDAs
-YikKcz1sLmEKaWYocy5ZcihiKTw9MCYmcy5ZcihhKT4wKXJldHVybiBsLm81KGEpCmlmKHMuWXIoYSk8
-PTB8fHMuaEsoYSkpYT1sLldPKDAsYSkKaWYocy5ZcihhKTw9MCYmcy5ZcihiKT4wKXRocm93IEguYihY
-Lkk3KGsrSC5FaihhKSsnIiBmcm9tICInK0guRWooYikrJyIuJykpCnI9WC5DTChiLHMpCnIuclIoKQpx
-PVguQ0woYSxzKQpxLnJSKCkKcD1yLmQKbz1wLmxlbmd0aAppZihvIT09MCl7aWYoMD49bylyZXR1cm4g
-SC5PSChwLDApCnA9Si5STShwWzBdLCIuIil9ZWxzZSBwPSExCmlmKHApcmV0dXJuIHEudygwKQpwPXIu
-YgpvPXEuYgppZihwIT1vKXA9cD09bnVsbHx8bz09bnVsbHx8IXMuTmMocCxvKQplbHNlIHA9ITEKaWYo
-cClyZXR1cm4gcS53KDApCndoaWxlKCEwKXtwPXIuZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtuPXEuZApt
-PW4ubGVuZ3RoCmlmKG0hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1wWzBdCmlmKDA+PW0p
-cmV0dXJuIEguT0gobiwwKQpuPXMuTmMocCxuWzBdKQpwPW59ZWxzZSBwPSExfWVsc2UgcD0hMQppZigh
-cClicmVhawpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKQpDLk5tLlc0KHEuZCwwKQpDLk5tLlc0
-KHEuZSwxKX1wPXIuZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkK
-cD1KLlJNKHBbMF0sIi4uIil9ZWxzZSBwPSExCmlmKHApdGhyb3cgSC5iKFguSTcoaytILkVqKGEpKyci
-IGZyb20gIicrSC5FaihiKSsnIi4nKSkKcD10Lk4KQy5ObS5VRyhxLmQsMCxQLk84KHIuZC5sZW5ndGgs
-Ii4uIiwhMSxwKSkKQy5ObS5ZKHEuZSwwLCIiKQpDLk5tLlVHKHEuZSwxLFAuTzgoci5kLmxlbmd0aCxz
-LmdtSSgpLCExLHApKQpzPXEuZApwPXMubGVuZ3RoCmlmKHA9PT0wKXJldHVybiIuIgppZihwPjEmJkou
-Uk0oQy5ObS5ncloocyksIi4iKSl7cz1xLmQKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkK
-cy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKDA+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKQy5ObS5pKHMsIiIpfXEuYj0iIgpxLklW
-KCkKcmV0dXJuIHEudygwKX19Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEgu
-aChhKSE9PSIifSwKJFM6Nn0KTS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILmsoYSkKcmV0
-dXJuIGE9PW51bGw/Im51bGwiOiciJythKyciJ30sCiRTOjUxfQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1
-bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5ZcihhKQppZihyPjApcmV0dXJuIEoubGQoYSwwLHIpCmlmKHRo
-aXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsMCkKcz1hWzBdfWVsc2Ugcz1udWxs
-CnJldHVybiBzfSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsK
-SVY6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcwp3aGlsZSghMCl7cz1xLmQKaWYoIShzLmxlbmd0aCE9
-PTAmJkouUk0oQy5ObS5ncloocyksIiIpKSlicmVhawpzPXEuZAppZigwPj1zLmxlbmd0aClyZXR1cm4g
-SC5PSChzLC0xKQpzLnBvcCgpCnM9cS5lCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMu
-cG9wKCl9cz1xLmUKcj1zLmxlbmd0aAppZihyIT09MClDLk5tLlkocyxyLTEsIiIpfSwKclI6ZnVuY3Rp
-b24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9SC5WTShbXSx0LnMpCmZvcihzPW0uZCxyPXMubGVu
-Z3RoLHE9MCxwPTA7cDxzLmxlbmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsrcCl7bz1zW3Bd
-Cm49Si5pYShvKQppZighKG4uRE4obywiLiIpfHxuLkROKG8sIiIpKSlpZihuLkROKG8sIi4uIikpe249
-bC5sZW5ndGgKaWYobiE9PTApe2lmKDA+PW4pcmV0dXJuIEguT0gobCwtMSkKbC5wb3AoKX1lbHNlICsr
-cX1lbHNlIEMuTm0uaShsLG8pfWlmKG0uYj09bnVsbClDLk5tLlVHKGwsMCxQLk84KHEsIi4uIiwhMSx0
-Lk4pKQppZihsLmxlbmd0aD09PTAmJm0uYj09bnVsbClDLk5tLmkobCwiLiIpCm0uc25KKGwpCnM9bS5h
-Cm0uc1BoKFAuTzgobC5sZW5ndGgrMSxzLmdtSSgpLCEwLHQuTikpCnI9bS5iCmlmKHI9PW51bGx8fGwu
-bGVuZ3RoPT09MHx8IXMuZHMocikpQy5ObS5ZKG0uZSwwLCIiKQpyPW0uYgppZihyIT1udWxsJiZzPT09
-JC5LaygpKXtyLnRvU3RyaW5nCm0uYj1ILnlzKHIsIi8iLCJcXCIpfW0uSVYoKX0sCnc6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxPXRoaXMscD1xLmIKcD1wIT1udWxsP3A6IiIKZm9yKHM9MDtzPHEuZC5sZW5ndGg7
-KytzKXtyPXEuZQppZihzPj1yLmxlbmd0aClyZXR1cm4gSC5PSChyLHMpCnI9cCtILkVqKHJbc10pCnA9
-cS5kCmlmKHM+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscykKcD1yK0guRWoocFtzXSl9cCs9SC5FaihD
-Lk5tLmdyWihxLmUpKQpyZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0wP3A6cH0sCnNuSjpmdW5jdGlvbihh
-KXt0aGlzLmQ9dC5FLmEoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhpcy5lPXQuRS5hKGEpfX0KWC5kdi5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhjZXB0aW9uOiAiK3RoaXMuYX0sCiRp
-Uno6MX0KTy56TC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdvYyh0aGlzKX19
-CkUuT0YucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCnJl
-dHVybiBzIT09MCYmQy54Qi5PMihhLHMtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYoYS5sZW5n
-dGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7
-cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpmdW5jdGlv
-bigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnByb3RvdHlw
-ZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgcz1hLmxlbmd0aAppZihzPT09MClyZXR1cm4h
-MQppZihDLnhCLk8yKGEscy0xKSE9PTQ3KXJldHVybiEwCnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0
-aGlzLllyKGEpPT09c30sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz1hLmxlbmd0aAppZihv
-PT09MClyZXR1cm4gMAppZihDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCmZvcihzPTA7czxvOysrcyl7
-cj1DLnhCLlcoYSxzKQppZihyPT09NDcpcmV0dXJuIDAKaWYocj09PTU4KXtpZihzPT09MClyZXR1cm4g
-MApxPUMueEIuWFUoYSwiLyIsQy54Qi5RaShhLCIvLyIscysxKT9zKzM6cykKaWYocTw9MClyZXR1cm4g
-bwppZighYnx8bzxxKzMpcmV0dXJuIHEKaWYoIUMueEIubihhLCJmaWxlOi8vIikpcmV0dXJuIHEKaWYo
-IUIuWXUoYSxxKzEpKXJldHVybiBxCnA9cSszCnJldHVybiBvPT09cD9wOnErNH19cmV0dXJuIDB9LApZ
-cjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBh
-Lmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0s
-CmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19CkwuSVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7
-cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTky
-fSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKaWYocz09PTApcmV0dXJuITEKcz1DLnhCLk8y
-KGEscy0xKQpyZXR1cm4hKHM9PT00N3x8cz09PTkyKX0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-PWEubGVuZ3RoCmlmKHE9PT0wKXJldHVybiAwCnM9Qy54Qi5XKGEsMCkKaWYocz09PTQ3KXJldHVybiAx
-CmlmKHM9PT05Mil7aWYocTwyfHxDLnhCLlcoYSwxKSE9PTkyKXJldHVybiAxCnI9Qy54Qi5YVShhLCJc
-XCIsMikKaWYocj4wKXtyPUMueEIuWFUoYSwiXFwiLHIrMSkKaWYocj4wKXJldHVybiByfXJldHVybiBx
-fWlmKHE8MylyZXR1cm4gMAppZighQi5PUyhzKSlyZXR1cm4gMAppZihDLnhCLlcoYSwxKSE9PTU4KXJl
-dHVybiAwCnE9Qy54Qi5XKGEsMikKaWYoIShxPT09NDd8fHE9PT05MikpcmV0dXJuIDAKcmV0dXJuIDN9
-LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLllyKGEpPT09MX0sCk90OmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYT09PWIpcmV0dXJuITAK
-aWYoYT09PTQ3KXJldHVybiBiPT09OTIKaWYoYT09PTkyKXJldHVybiBiPT09NDcKaWYoKGFeYikhPT0z
-MilyZXR1cm4hMQpzPWF8MzIKcmV0dXJuIHM+PTk3JiZzPD0xMjJ9LApOYzpmdW5jdGlvbihhLGIpe3Zh
-ciBzLHIscQppZihhPT1iKXJldHVybiEwCnM9YS5sZW5ndGgKaWYocyE9PWIubGVuZ3RoKXJldHVybiEx
-CmZvcihyPUouclkoYikscT0wO3E8czsrK3EpaWYoIXRoaXMuT3QoQy54Qi5XKGEscSksci5XKGIscSkp
-KXJldHVybiExCnJldHVybiEwfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuIndpbmRvd3MifSwKZ21JOmZ1
-bmN0aW9uKCl7cmV0dXJuIlxcIn19OyhmdW5jdGlvbiBhbGlhc2VzKCl7dmFyIHM9Si52Qi5wcm90b3R5
-cGUKcy5VPXMudwpzLlNqPXMuZTcKcz1KLk1GLnByb3RvdHlwZQpzLnQ9cy53CnM9UC5jWC5wcm90b3R5
-cGUKcy5HRz1zLmV2CnM9UC5NaC5wcm90b3R5cGUKcy54Yj1zLncKcz1XLmN2LnByb3RvdHlwZQpzLkRX
-PXMucjYKcz1XLm02LnByb3RvdHlwZQpzLmpGPXMuRWIKcz1QLkU0LnByb3RvdHlwZQpzLlVyPXMucQpz
-LmU0PXMuWX0pKCk7KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciBzPWh1bmtIZWxwZXJzLl9z
-dGF0aWNfMSxyPWh1bmtIZWxwZXJzLl9zdGF0aWNfMCxxPWh1bmtIZWxwZXJzLmluc3RhbGxJbnN0YW5j
-ZVRlYXJPZmYscD1odW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZixvPWh1bmtIZWxwZXJzLl9p
-bnN0YW5jZV8xdQpzKFAsIkVYIiwiWlYiLDcpCnMoUCwieXQiLCJvQSIsNykKcyhQLCJxVyIsIkJ6Iiw3
-KQpyKFAsIlY5IiwiZU4iLDApCnEoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwxLG51bGwsWyIkMiIsIiQx
-Il0sWyJ3MCIsInBtIl0sMjksMCkKcyhQLCJDeSIsIk5DIiw0KQpzKFAsIlBIIiwiTXQiLDUpCnAoVywi
-cFMiLDQsbnVsbCxbIiQ0Il0sWyJxRCJdLDgsMCkKcChXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0s
-OCwwKQpvKFAuQXMucHJvdG90eXBlLCJndU0iLCJUIiw1KQpzKFAsImlHIiwid1kiLDU0KQpzKFAsIncw
-IiwiZFUiLDM2KQpzKEwsImlTIiwiaTYiLDIwKX0pKCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFy
-IHM9aHVua0hlbHBlcnMubWl4aW4scj1odW5rSGVscGVycy5pbmhlcml0LHE9aHVua0hlbHBlcnMuaW5o
-ZXJpdE1hbnkKcihQLk1oLG51bGwpCnEoUC5NaCxbSC5GSyxKLnZCLEoubTEsUC5jWCxILkU3LFAuWFMs
-UC5uWSxILmE3LFAuQW4sSC5GdSxILkpCLEguU1UsSC5SZSxILnd2LFAuUG4sSC5XVSxILkxJLEguVHAs
-SC5mOSxILnRlLEguYnEsSC5YTyxILmtyLFAuWWssSC52aCxILk42LEguVlIsSC5FSyxILlBiLEgudFEs
-SC5TZCxILkpjLEguRyxQLlczLFAuaWgsUC5GeSxQLkdWLFAuUGYsUC5GZSxQLnZzLFAuT00sUC5xaCxQ
-Lk1PLFAua1QsUC54SSxQLkN3LFAubTAsUC5wUixQLmJuLFAubG0sUC5sRCxQLktQLFAubGYsUC5XWSxQ
-LlVrLFAuU2gsUC5SdyxQLmJ6LFAuaVAsUC5rNSxQLktZLFAuQ0QsUC5hRSxQLk4zLFAuYzgsUC5aZCxQ
-LlJuLFAuRG4sUC5QRSxQLlVmLFcuaWQsVy5GayxXLkpRLFcuR20sVy52RCxXLm02LFcuT3csVy5XOSxX
-LmRXLFcubWssVy5LbyxQLmlKLFAuRTQsTS5INyxVLkxMLFUuZDIsVS5TZSxVLk1sLFUueUQsVS53YixC
-Lmo4LEIucXAsVC5tUSxMLlhBLEwuWlosTC5POSxNLmxJLE8uekwsWC5XRCxYLmR2XSkKcShKLnZCLFtK
-LnlFLEoud2UsSi5NRixKLmpkLEoucUksSi5EcixILkVULFcuRDAsVy5BeixXLkxlLFcuTmgsVy5hZSxX
-LklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51OCxXLks3LFcuWFcsUC5oRl0pCnEoSi5NRixbSi5pQyxK
-LmtkLEouYzVdKQpyKEouUG8sSi5qZCkKcShKLnFJLFtKLmJVLEouVkFdKQpxKFAuY1gsW0guQlIsSC5i
-USxILmkxLEguVTUsSC5BTSxILnU2LEguWFIsUC5tVyxILnVuXSkKcShILkJSLFtILlp5LEguUUNdKQpy
-KEgub2wsSC5aeSkKcihILlVxLEguUUMpCnIoSC5qVixILlVxKQpxKFAuWFMsW0gubixILnIzLFAuRXos
-SC5heixILnZWLEguRXEsUC5DNixILmtTLFAuVWQsUC5GLFAudSxQLm1wLFAudWIsUC5kcyxQLmxqLFAu
-VVYsUC5wXSkKcihQLnV5LFAublkpCnEoUC51eSxbSC53MixXLnd6LFcuZTddKQpyKEgucWosSC53MikK
-cShILmJRLFtILmFMLEguTUIsSC5pNV0pCnEoSC5hTCxbSC5uSCxILmxKLFAuaThdKQpyKEgueHksSC5p
-MSkKcShQLkFuLFtILk1ILEguU08sSC5VMV0pCnIoSC5kNSxILkFNKQpyKFAuUlUsUC5QbikKcihQLkdq
-LFAuUlUpCnIoSC5QRCxQLkdqKQpyKEguTFAsSC5XVSkKcShILlRwLFtILkNqLEgubGMsSC5kQyxILndO
-LEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEsUC5vUSxQLnBW
-LFAuVTcsUC52cixQLnJ0LFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUsUC51TyxQLnBL
-LFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLnBnLFAuYzIsUC50aSxQLldGLFAubjEsUC5jUyxQLlZD
-LFAuSlQsUC5SWixQLk1FLFAueTUsUC5xMyxQLnlJLFAuYzYsUC5xZCxXLkN2LFcuS1MsVy5BMyxXLnZO
-LFcuVXYsVy5FZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAuamcsUC5UYSxQLkdFLFAuTjcsUC51USxQLlBD
-LFAubXQsUC5OeixQLlFTLFAubnAsVS5NRCxVLmFOLFUuYjAsTC5lLEwuVlcsTC5vWixMLmpyLEwucWws
-TC5IaSxMLkJULEwuUFksTC5MLEwuV3gsTC5BTyxMLmROLEwuSG8sTC54eixMLklDLEwuZkMsTC5uVCxM
-Lk5ZLEwudWUsTC5lWCxMLkVFLEwuUUwsTC5WUyxMLlRELEwubTIsTS5xNyxNLk5vXSkKcihILlcwLFAu
-RXopCnEoSC5sYyxbSC56eCxILnJUXSkKcihILmtZLFAuQzYpCnIoUC5pbCxQLllrKQpxKFAuaWwsW0gu
-TjUsUC51dyxXLmNmLFcuU3ldKQpxKFAubVcsW0guS1csUC5xNF0pCnIoSC5YSCxILkVUKQpxKEguWEgs
-W0guUkcsSC5XQl0pCnIoSC5WUCxILlJHKQpyKEguRGcsSC5WUCkKcihILlpHLEguV0IpCnIoSC5QZyxI
-LlpHKQpxKEguUGcsW0gueGosSC5kRSxILlpBLEguZFQsSC5QcSxILmVFLEguVjZdKQpyKEguaU0sSC5r
-UykKcihQLlpmLFAuUGYpCnIoUC5KaSxQLm0wKQpyKFAuWHYsUC5wUikKcihQLmI2LFAuWHYpCnIoUC5W
-aixQLldZKQpxKFAuVWssW1AuQ1YsUC5aaSxQLmJ5XSkKcihQLndJLFAua1QpCnEoUC53SSxbUC5VOCxQ
-Lm9qLFAuTXgsUC5FMyxQLkdZXSkKcihQLks4LFAuVWQpCnIoUC50dSxQLlNoKQpyKFAudTUsUC5aaSkK
-cShQLnUsW1AuYkosUC5lWV0pCnIoUC5xZSxQLkRuKQpxKFcuRDAsW1cudUgsVy53YSxXLks1LFcuQ21d
-KQpxKFcudUgsW1cuY3YsVy5ueCxXLlFGLFcuQ1FdKQpxKFcuY3YsW1cucUUsUC5oaV0pCnEoVy5xRSxb
-Vy5HaCxXLmZZLFcubkIsVy5RUCxXLmg0LFcuU04sVy5scCxXLlRiLFcuSXYsVy5XUCxXLnlZXSkKcihX
-Lm9KLFcuTGUpCnIoVy5oSCxXLkF6KQpyKFcuVmIsVy5RRikKcihXLmZKLFcud2EpCnEoVy5lYSxbVy53
-NixXLmV3XSkKcihXLkFqLFcudzYpCnIoVy5yQixXLks3KQpyKFcuQkgsVy5yQikKcihXLnc0LFcuSUIp
-CnIoVy5vYSxXLlhXKQpyKFcucmgsVy5vYSkKcihXLmk3LFcuY2YpCnIoUC5BcyxQLlZqKQpxKFAuQXMs
-W1cuSTQsUC5LZV0pCnIoVy5STyxQLnFoKQpyKFcuZXUsVy5STykKcihXLnhDLFAuTU8pCnIoVy5jdCxX
-Lm02KQpyKFAuQmYsUC5pSikKcShQLkU0LFtQLnI3LFAuY29dKQpyKFAuVHosUC5jbykKcihQLm5kLFAu
-aGkpCnIoQi5mdixPLnpMKQpxKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkKcyhILncyLEguUmUpCnMoSC5R
-QyxQLmxEKQpzKEguUkcsUC5sRCkKcyhILlZQLEguU1UpCnMoSC5XQixQLmxEKQpzKEguWkcsSC5TVSkK
-cyhQLm5ZLFAubEQpCnMoUC5XWSxQLmxmKQpzKFAuUlUsUC5LUCkKcyhQLnBSLFAubGYpCnMoVy5MZSxX
-LmlkKQpzKFcuSzcsUC5sRCkKcyhXLnJCLFcuR20pCnMoVy5YVyxQLmxEKQpzKFcub2EsVy5HbSkKcyhQ
-LmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30sZVQ6e30s
-dFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoiaW50IixDUDoiZG91YmxlIixMWjoi
-bnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xlZE5hbWVz
-Ont9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBlczpbIn4o
-KSIsImM4KCkiLCJjOChBaiopIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJhMihxVSkiLCJ+KH4o
-KSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsIn4ocVUscVUpIiwifihNaD8sTWg/KSIsIkAoKSIs
-In4ocVUsQCkiLCJ+KG42LHFVLElmKSIsImEyKGtGKSIsImM4KEAsQCkiLCJ+KHh1PHFVPikiLCJjOChl
-YSopIiwiYjg8Yzg+KihBaiopIiwifihBaiopIiwifihxVSxJZikiLCJ+KHFVLHFVPykiLCJuNihJZiki
-LCJuNihALEApIiwifihJZixAKSIsImEyKHVIKSIsImM4KEAsR3opIiwifihlYSkiLCJ+KE1oW0d6P10p
-IiwiYzgoTWgsR3opIiwifih1SCx1SD8pIiwifihALEApIiwidnM8QD4oQCkiLCJhMih4dTxxVT4pIiwi
-QChxVSkiLCJNaD8oQCkiLCJUejxAPihAKSIsIkU0KEApIiwiYTIqKEg3KikiLCJMTCooQCkiLCJaMDxx
-VSosTWgqPiooTEwqKSIsIkAoQCxxVSkiLCJ+KEdELEApIiwiYzgoWjA8cVUqLE1oKj4qKSIsIlowPHFV
-LHFVPihaMDxxVSxxVT4scVUpIiwicVUqKEFqKikiLCJ+KEApIiwiYzgoZXcqKSIsInFVKihaMDxALEA+
-KikiLCJ+KHFVW0BdKSIsInFVKHFVPykiLCJJZihJZixJZikiLCJjOCh+KCkpIiwiTWg/KE1oPykiLCJy
-NyhAKSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2Yg
-U3ltYm9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6
-IiR0aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIs
-ImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiaGkiLCJ0cCI6ImhpIiwiRzgiOiJldyIs
-Ik1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJBaiIs
-Ink0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIs
-InlFIjp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsi
-ek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJd
-LCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiTFoi
-OltdfSwiYlUiOnsiQ1AiOltdLCJJZiI6W10sIkxaIjpbXX0sIlZBIjp7IkNQIjpbXSwiTFoiOltdfSwi
-RHIiOnsicVUiOltdLCJ2WCI6W119LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6WyIyIl19LCJa
-eSI6eyJCUiI6WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5IjpbIjEiLCIy
-Il0sIkJSIjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJVcSI6eyJs
-RCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl19LCJq
-ViI6eyJVcSI6WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEi
-OlsiMiJdLCJjWCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6W119LCJyMyI6
-eyJYUyI6W119LCJxaiI6eyJsRCI6WyJJZiJdLCJSZSI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJ
-ZiJdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiYlEiOnsiY1giOlsiMSJdfSwi
-YUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1gi
-OlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpb
-IjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0s
-ImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJj
-WCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
-LCJTTyI6eyJBbiI6WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sImQ1Ijp7IkFNIjpb
-IjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlUxIjp7IkFuIjpbIjEiXX0sIk1C
-Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJGdSI6eyJBbiI6WyIxIl19LCJ1NiI6
-eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpbIjEiXX0sIncyIjp7ImxEIjpbIjEiXSwi
-UmUiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwid3YiOnsiR0QiOltdfSwi
-UEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIs
-IjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEiLCIyIl19LCJMUCI6eyJXVSI6WyIxIiwi
-MiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJMSSI6eyJ2USI6
-W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6eyJYUyI6W119LCJ0ZSI6eyJSeiI6
-W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119LCJ6eCI6eyJFSCI6
-W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119LCJONSI6eyJZayI6
-WyIxIiwiMiJdLCJGbyI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoiMSIsIllrLlYiOiIy
-In0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJBbiI6WyIxIl19
-LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ciOnsiY1giOlsi
-aWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119LCJ1biI6eyJj
-WCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFTIjpbXX0sIlhI
-Ijp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJYaiI6WyJDUCJd
-LCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIkFTIjpbXSwiY1giOlsiQ1AiXSwiU1UiOlsi
-Q1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0s
-IkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdfSwieGoiOnsi
-bEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6
-W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJsRCI6WyJJZiJdLCJY
-aiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYi
-XSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpN
-IjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJd
-LCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwiRVQi
-OltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJZiJ9
-LCJQcSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklm
-Il0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImVFIjp7ImxEIjpb
-IklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJj
-WCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiVjYiOnsibEQiOlsiSWYiXSwibjYiOltd
-LCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsi
-SWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImtTIjp7IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0s
-IkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiWmYiOnsiUGYiOlsi
-MSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltdfSwibTAiOnsiUW0iOltdfSwiSmkiOnsi
-bTAiOltdLCJRbSI6W119LCJiNiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6
-WyIxIl0sImxmLkUiOiIxIn0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpbIjEiXX0sInV5Ijp7
-ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImlsIjp7IllrIjpbIjEi
-LCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4iOnsiWjAiOlsiMSIs
-IjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlow
-IjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIx
-Il19LCJYdiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6
-eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4
-Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJx
-VSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5TIjoiek08SWY+In0sIlU4Ijp7IndJIjpb
-InpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPElmPiJdfSwiVWQiOnsiWFMiOltdfSwi
-SzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsiTWg/IiwicVUiXSwiVWsuUyI6Ik1oPyJ9LCJvaiI6eyJ3
-SSI6WyJNaD8iLCJxVSJdfSwiTXgiOnsid0kiOlsicVUiLCJNaD8iXX0sInU1Ijp7IlVrIjpbInFVIiwi
-ek08SWY+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPElmPiJdfSwiR1kiOnsid0ki
-Olsiek08SWY+IiwicVUiXX0sIkNQIjp7IkxaIjpbXX0sIklmIjp7IkxaIjpbXX0sInpNIjp7ImJRIjpb
-IjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19
-LCJxVSI6eyJ2WCI6W119LCJDNiI6eyJYUyI6W119LCJFeiI6eyJYUyI6W119LCJGIjp7IlhTIjpbXX0s
-InUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwi
-dWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwi
-azUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwicCI6eyJYUyI6W119LCJDRCI6eyJSeiI6W119LCJh
-RSI6eyJSeiI6W119LCJaZCI6eyJHeiI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6eyJpRCI6W119LCJV
-ZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
-R2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
-LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
-XX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119LCJJQiI6eyJ0biI6
-WyJMWiJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJs
-RC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImhIIjp7IkF6IjpbXX0sImg0Ijp7ImN2Ijpb
-XSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQwIjpbXX0sImZKIjp7IkQwIjpbXX0sIndh
-Ijp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpNIjpbInVIIl0sImJR
-IjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119LCJCSCI6eyJsRCI6
-WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6
-WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiU04iOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
-XX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJUYiI6eyJjdiI6
-W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIldQIjp7ImN2
-IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwidzYiOnsi
-ZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJDUSI6eyJ1SCI6W10s
-IkQwIjpbXX0sInc0Ijp7InRuIjpbIkxaIl19LCJyaCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6
-TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJH
-bS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl19LCJpNyI6eyJZ
-ayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIlN5
-Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoicVUi
-fSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXSwibGYu
-RSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgiOlsiMSJdfSwieEMi
-OnsiTU8iOlsiMSJdfSwiSlEiOnsia0YiOltdfSwidkQiOnsia0YiOltdfSwibTYiOnsia0YiOltdfSwi
-Y3QiOnsia0YiOltdfSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwiZFciOnsidjYiOltd
-LCJEMCI6W119LCJtayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJsZiI6WyJxVSJdLCJ4
-dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltdfSwiVHoiOnsibEQi
-OlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0s
-Im5kIjp7ImhpIjpbXSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7ImxmIjpbInFVIl0sInh1
-IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxmLkUiOiJxVSJ9LCJoaSI6eyJjdiI6W10s
-InVIIjpbXSwiRDAiOltdfSwiWEEiOnsia0YiOltdfSwiZHYiOnsiUnoiOltdfSwiT0YiOnsiZnYiOltd
-fSwicnUiOnsiZnYiOltdfSwiSVYiOnsiZnYiOltdfSwibjYiOnsiek0iOlsiSWYiXSwiYlEiOlsiSWYi
-XSwiY1giOlsiSWYiXSwiQVMiOltdfX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7
-IncyIjoxLCJRQyI6MiwiWEgiOjEsImtUIjoyLCJtVyI6MSwidXkiOjEsImlsIjoyLCJWaiI6MSwiWHYi
-OjEsIm5ZIjoxLCJXWSI6MSwicFIiOjEsImNvIjoxfScpKQp2YXIgdT17bDoiQ2Fubm90IGV4dHJhY3Qg
-YSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IixpOiJDYW5ub3Qg
-ZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiLGo6IkNh
-bm5vdCBleHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFu
-IGF1dGhvcml0eSIsZzoiYG51bGxgIGVuY291bnRlcmVkIGFzIHRoZSByZXN1bHQgZnJvbSBleHByZXNz
-aW9uIHdpdGggdHlwZSBgTmV2ZXJgLiIsZDoiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3Jh
-dGlvbix0eXBlLWJ1ZyJ9CnZhciB0PShmdW5jdGlvbiBydGlpKCl7dmFyIHM9SC5OMApyZXR1cm57bjpz
-KCJDdyIpLGNSOnMoIm5CIiksdzpzKCJBeiIpLHA6cygiUVAiKSxnRjpzKCJQRDxHRCxAPiIpLGI6cygi
-YlE8QD4iKSxoOnMoImN2IikscjpzKCJYUyIpLEI6cygiZWEiKSxhUzpzKCJEMCIpLGc4OnMoIlJ6Iiks
-Yzg6cygiaEgiKSxZOnMoIkVIIiksZDpzKCJiODxAPiIpLEk6cygiU2ciKSxvOnMoInZRIiksZWg6cygi
-Y1g8dUg+IiksUTpzKCJjWDxxVT4iKSx1OnMoImNYPEA+IiksdjpzKCJqZDxrRj4iKSxzOnMoImpkPHFV
-PiIpLHg6cygiamQ8QD4iKSxhOnMoImpkPElmPiIpLGQ3OnMoImpkPFNlKj4iKSxoNDpzKCJqZDxqOCo+
-IiksRzpzKCJqZDxaMDxxVSosTWgqPio+IiksY1E6cygiamQ8WloqPiIpLGk6cygiamQ8cVUqPiIpLGFB
-OnMoImpkPHlEKj4iKSxhSjpzKCJqZDx3Yio+IiksVjpzKCJqZDxJZio+IiksZDQ6cygiamQ8cVU/PiIp
-LFQ6cygid2UiKSxlSDpzKCJ2bSIpLEQ6cygiYzUiKSxhVTpzKCJYajxAPiIpLGFtOnMoIlR6PEA+Iiks
-ZW86cygiTjU8R0QsQD4iKSxkejpzKCJoRiIpLEU6cygiek08cVU+IiksajpzKCJ6TTxAPiIpLEw6cygi
-ek08SWY+IiksSjpzKCJaMDxxVSxxVT4iKSxmOnMoIlowPEAsQD4iKSxkbzpzKCJsSjxxVSxAPiIpLGZq
-OnMoImxKPHFVKixxVT4iKSxkRTpzKCJFVCIpLGJtOnMoIlY2IiksQTpzKCJ1SCIpLGY2OnMoImtGIiks
-UDpzKCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPExaPiIpLGZ2OnMoIndMIiksZXc6cygibmQiKSxDOnMo
-Inh1PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIpLGc3OnMoImhpIiksZm86
-cygiR0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpzKCJrZCIpLGR3OnMoIkdq
-PHFVLHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUiKSxjaTpzKCJ2NiIpLGcy
-OnMoIkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTciKSxrOnMoImV1PEFqKj4i
-KSxXOnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWY+IiksZ1Y6cygidnM8ZkoqPiIp
-LGNyOnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQIiksejpzKCJAIiksZk86
-cygiQCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMoIkAoeHU8cVU+KSIpLGRP
-OnMoIkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJZiIpLGRkOnMoIkdoKiIpLGc6cygiY3YqIiks
-YUw6cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxAPioiKSxkSDpzKCJFNCoi
-KSxmSzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFowPHFVKixNaCo+Kj4qIiks
-bTpzKCJ6TTxNaCo+KiIpLGF3OnMoIlowPEAsQD4qIiksdDpzKCJaMDxxVSosTWgqPioiKSxPOnMoIkFq
-KiIpLGNGOnMoIjAmKiIpLF86cygiTWgqIiksZVE6cygiZXcqIiksWDpzKCJxVSoiKSxjaDpzKCJEMD8i
-KSxiRzpzKCJiODxjOD4/IiksYms6cygiek08cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNaOnMoIlowPHFV
-LHFVPj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxSOnMoIk1oPyIpLEY6cygiRmU8QCxAPj8iKSxlOnMoImJu
-PyIpLGI3OnMoImEyKE1oKT8iKSxidzpzKCJAKGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1oPyk/IiksZEE6
-cygiTWg/KEApPyIpLFo6cygifigpPyIpLGViOnMoIn4oZXcqKT8iKSxkaTpzKCJMWiIpLEg6cygifiIp
-LE06cygifigpIiksZUE6cygifihxVSxxVSkiKSxjQTpzKCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24g
-Y29uc3RhbnRzKCl7dmFyIHM9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLnhuPVcuR2gucHJvdG90
-eXBlCkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5tSD1XLmFlLnByb3RvdHlwZQpDLkJaPVcuVmIucHJvdG90
-eXBlCkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLnZCLnByb3RvdHlwZQpDLk5tPUouamQucHJvdG90
-eXBlCkMuam49Si5iVS5wcm90b3R5cGUKQy5qTj1KLndlLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90
-eXBlCkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudTgucHJvdG90
-eXBlCkMuTkE9SC5WNi5wcm90b3R5cGUKQy50NT1XLkJILnByb3RvdHlwZQpDLkx0PVcuU04ucHJvdG90
-eXBlCkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJvdG90
-eXBlCkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpDLkd3
-PW5ldyBILkZ1KEguTjAoIkZ1PGM4PiIpKQpDLk80PWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNrKG8pIHsK
-ICB2YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4gcy5zdWJz
-dHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLllxPWZ1bmN0aW9uKCkgewogIHZhciB0b1N0cmluZ0Z1
-bmN0aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWcobykgewog
-ICAgdmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJzdHJpbmco
-OCwgcy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZykg
-ewogICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZhciBuYW1l
-ID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09ICJbb2JqZWN0
-IE9iamVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICB9CiAg
-fQogIGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykgewogICAg
-aWYgKHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHJldHVy
-biAiSFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpOwogIH0K
-ICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAi
-dW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09ICJ1bmRl
-ZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAg
-aWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAgIHJldHVy
-biBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3IodGFnKSB7
-IHJldHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVj
-dCI7CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzogaXNCcm93
-c2VyID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywKICAgIHByb3Rv
-dHlwZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlzY3JpbWluYXRv
-ciB9Owp9CkMud2I9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rpb24oaG9v
-a3MpIHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9va3M7CiAg
-ICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1bXBSZW5k
-ZXJUcmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9tZSIpID49
-IDApIHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5k
-b3cgPT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAgICAgIH0K
-ICAgICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50IikpIHJldHVy
-biBob29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07Cn0KQy5L
-VT1mdW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFn
-ICE9ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhwZXJpbWVu
-dGFsRml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFy
-IGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3MucHJvdG90
-eXBlRm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWco
-byk7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJzaW9uKSBy
-ZXR1cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9CiAgICBy
-ZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsKICAgIGlm
-ICh0YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBlRm9yVGFn
-KHRhZyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3RvdHlwZUZv
-clRhZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMuZGs9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIg
-dXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdl
-bnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0dXJuIGhv
-b2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJl
-Zm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwK
-ICAgICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAiIUxvY2F0
-aW9uIiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJYTUxEb2N1
-bWVudCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAgIHZhciB0
-YWcgPSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQogIGhvb2tz
-LmdldFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewogIHZhciB1c2Vy
-QWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6
-ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJuIGhvb2tz
+dHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnIudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5l
+NyhyKS5GVigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gcn19ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciBzLHIKdGhpcy5zYTQoYSxudWxsKQpzPWEuY29udGVudApzLnRvU3RyaW5nCkou
+YlQocykKcj10aGlzLnI2KGEsYixudWxsLGMpCmEuY29udGVudC5hcHBlbmRDaGlsZChyKX0sCllDOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKJGl5WToxfQpXLnc2LnByb3RvdHlw
+ZT17fQpXLks1LnByb3RvdHlwZT17ClBvOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1XLlAxKGEub3Blbihi
+LGMpKQpyZXR1cm4gc30sCmdtVzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhdGlvbn0sCnVzOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIGEuY29uZmlybShiKX0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnByb3RvdHlw
+ZT17JGlDbToxfQpXLkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAi
+CnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5FaihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9
+cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQKcy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5s
+ZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3Ry
+aW5nCnI9Yi50b3AKci50b1N0cmluZwppZihzPT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndp
+ZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIu
+dG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSEx
+CnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9
+Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3RyaW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9T
+dHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVpZ2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIs
+Qy5DRC5naU8ocSkpfX0KVy5yaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
+dGh9LApxOmZ1bmN0aW9uKGEsYil7SC51UChiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93
+IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTU6ZnVuY3Rpb24oYSxi
+LGMpe3QuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRh
+YmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEgu
+T0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5jZi5w
+cm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwp0LmVBLmEoYikKZm9yKHM9dGhp
+cy5ndmMoKSxyPXMubGVuZ3RoLHE9dGhpcy5hLHA9MDtwPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAs
+SC5saykocyksKytwKXtvPXNbcF0KYi4kMihvLHEuZ2V0QXR0cmlidXRlKG8pKX19LApndmM6ZnVuY3Rp
+b24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLmEuYXR0cmlidXRlcwptLnRvU3RyaW5nCnM9SC5WTShb
+XSx0LnMpCmZvcihyPW0ubGVuZ3RoLHE9dC5oOSxwPTA7cDxyOysrcCl7aWYocD49bS5sZW5ndGgpcmV0
+dXJuIEguT0gobSxwKQpvPXEuYShtW3BdKQppZihvLm5hbWVzcGFjZVVSST09bnVsbCl7bj1vLm5hbWUK
+bi50b1N0cmluZwpDLk5tLmkocyxuKX19cmV0dXJuIHN9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuZ3ZjKCkubGVuZ3RoPT09MH19ClcuaTcucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7dmFyIHM9
+SC5vVCh0aGlzLmEuaGFzQXR0cmlidXRlKGEpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5hLmdldEF0dHJpYnV0ZShILmgoYikpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5z
+ZXRBdHRyaWJ1dGUoYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2YygpLmxlbmd0aH19
+ClcuU3kucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vVCh0aGlzLmEuYS5oYXNBdHRy
+aWJ1dGUoImRhdGEtIit0aGlzLlAoYSkpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+dGhpcy5hLmEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5QKEguaChiKSkpfSwKWTU6ZnVuY3Rpb24o
+YSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuUChiKSxjKX0sCks6ZnVuY3Rp
+b24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdC5lQS5hKGIpKSl9LApndmM6ZnVuY3Rpb24o
+KXt2YXIgcz1ILlZNKFtdLHQucykKdGhpcy5hLksoMCxuZXcgVy5BMyh0aGlzLHMpKQpyZXR1cm4gc30s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2YygpLmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5ndmMoKS5sZW5ndGg9PT0wfSwKeHE6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUguVk0o
+YS5zcGxpdCgiLSIpLHQucykKZm9yKHM9MTtzPHEubGVuZ3RoOysrcyl7cj1xW3NdCmlmKHIubGVuZ3Ro
+PjApQy5ObS5ZNShxLHMsclswXS50b1VwcGVyQ2FzZSgpK0ouS1YociwxKSl9cmV0dXJuIEMuTm0uayhx
+LCIiKX0sClA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbwpmb3Iocz1hLmxlbmd0aCxyPTAscT0iIjty
+PHM7KytyKXtwPWFbcl0Kbz1wLnRvTG93ZXJDYXNlKCkKcT0ocCE9PW8mJnI+MD9xKyItIjpxKStvfXJl
+dHVybiBxLmNoYXJDb2RlQXQoMCk9PTA/cTpxfX0KVy5LUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe2lmKEouclkoYSkubkMoYSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLnhxKEMueEIueW4oYSw1
+KSksYil9LAokUzoxNH0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSku
+bkMoYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS54cShDLnhCLnluKGEsNSkpKX0sCiRTOjE0
+fQpXLkk0LnByb3RvdHlwZT17CkQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPVAuTHModC5OKQpmb3Io
+cz10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1KLlQw
+KHNbcV0pCmlmKHAubGVuZ3RoIT09MClvLmkoMCxwKX1yZXR1cm4gb30sClg6ZnVuY3Rpb24oYSl7dGhp
+cy5hLmNsYXNzTmFtZT10LkMuYShhKS5rKDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEuY2xhc3NMaXN0Lmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlz
+dC5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0
+aCE9PTB9LApWMTpmdW5jdGlvbihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxi
+KXt2YXIgcz10aGlzLmEuY2xhc3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiBzfSwKaTpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIKSC5oKGIpCnM9dGhpcy5hLmNsYXNzTGlzdApyPXMuY29udGFpbnMoYikKcy5hZGQo
+YikKcmV0dXJuIXJ9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCmlmKHR5cGVvZiBiPT0ic3RyaW5n
+Iil7cz10aGlzLmEuY2xhc3NMaXN0CnI9cy5jb250YWlucyhiKQpzLnJlbW92ZShiKQpxPXJ9ZWxzZSBx
+PSExCnJldHVybiBxfSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRoaXMuYSx0LlEuYShiKSl9fQpXLkZr
+LnByb3RvdHlwZT17fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3Rv
+dHlwZT17fQpXLnZOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodC5C
+LmEoYSkpfSwKJFM6Mjd9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoJC5v
+ci5hPT09MCl7Zm9yKHM9MDtzPDI2MjsrK3MpJC5vci5ZNSgwLEMuY21bc10sVy5wUygpKQpmb3Iocz0w
+O3M8MTI7KytzKSQub3IuWTUoMCxDLkJJW3NdLFcuVjQoKSl9fSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJu
+ICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPSQub3IucSgwLEgu
+RWooVy5yUyhhKSkrIjo6IitiKQppZihzPT1udWxsKXM9JC5vci5xKDAsIio6OiIrYikKaWYocz09bnVs
+bClyZXR1cm4hMQpyZXR1cm4gSC55OChzLiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90
+b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgueihhKS5D
+KCJXOTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0u
+VnIodGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQy5ObS5Wcih0
+aGlzLmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gdC5mNi5hKGEpLmkwKHRoaXMuYSl9LAokUzoxNX0KVy5FZy5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gdC5mNi5hKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRT
+OjE1fQpXLm02LnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0aGlzLmEu
+RlYoMCxjKQpzPWIuZXYoMCxuZXcgVy5FbygpKQpyPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYo
+MCxzKQpxPXRoaXMuYwpxLkZWKDAsQy54RCkKcS5GVigwLHIpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuYS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPXRoaXMscj1XLnJT
+KGEpLHE9cy5jCmlmKHEudGcoMCxILkVqKHIpKyI6OiIrYikpcmV0dXJuIHMuZC5EdChjKQplbHNlIGlm
+KHEudGcoMCwiKjo6IitiKSlyZXR1cm4gcy5kLkR0KGMpCmVsc2V7cT1zLmIKaWYocS50ZygwLEguRWoo
+cikrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlm
+KHEudGcoMCxILkVqKHIpKyI6OioiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6KiIpKXJldHVy
+biEwfXJldHVybiExfSwKJGlrRjoxfQpXLkVvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biFDLk5tLnRnKEMuQkksSC5oKGEpKX0sCiRTOjZ9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEMuTm0udGcoQy5CSSxILmgoYSkpfSwKJFM6Nn0KVy5jdC5wcm90b3R5cGU9ewpFYjpm
+dW5jdGlvbihhLGIsYyl7aWYodGhpcy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSIm
+JmM9PT0iIilyZXR1cm4hMAppZihhLmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0
+aGlzLmUudGcoMCxiKQpyZXR1cm4hMX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
+dXJuIlRFTVBMQVRFOjoiK0guRWooSC5oKGEpKX0sCiRTOjV9ClcuT3cucHJvdG90eXBlPXsKaTA6ZnVu
+Y3Rpb24oYSl7dmFyIHMKaWYodC5ldy5iKGEpKXJldHVybiExCnM9dC5nNy5iKGEpCmlmKHMmJlcuclMo
+YSk9PT0iZm9yZWlnbk9iamVjdCIpcmV0dXJuITEKaWYocylyZXR1cm4hMApyZXR1cm4hMX0sCkViOmZ1
+bmN0aW9uKGEsYixjKXtpZihiPT09ImlzInx8Qy54Qi5uQyhiLCJvbiIpKXJldHVybiExCnJldHVybiB0
+aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcz10aGlz
+LHI9cy5jKzEscT1zLmIKaWYocjxxKXtzLnNwKEoueDkocy5hLHIpKQpzLmM9cgpyZXR1cm4hMH1zLnNw
+KG51bGwpCnMuYz1xCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVu
+Y3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KVy5kVy5wcm90b3R5
+cGU9eyRpRDA6MSwkaXY2OjF9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90eXBlPXsK
+UG46ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPW5ldyBXLmZtKHMpCnMuYj0hMQpyLiQyKGEsbnVsbCkK
+Zm9yKDtzLmI7KXtzLmI9ITEKci4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhp
+cy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTpzKUouTHQoYSkKZWxzZSBiLnJlbW92ZUNo
+aWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49ITAsbT1udWxsLGw9bnVsbAp0
+cnl7bT1KLmlnKGEpCmw9bS5hLmdldEF0dHJpYnV0ZSgiaXMiKQp0LmguYShhKQpzPWZ1bmN0aW9uKGMp
+e2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQppZihj
+LmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3VzU2libGlu
+Zyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFtZT09J2No
+aWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgaz1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQmJmMubGFz
+dENoaWxkIT09a1trLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEoYy5jaGls
+ZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2YgTm9kZUxp
+c3QpKXJldHVybiB0cnVlCnZhciBqPTAKaWYoYy5jaGlsZHJlbilqPWMuY2hpbGRyZW4ubGVuZ3RoCmZv
+cih2YXIgaT0wO2k8ajtpKyspe3ZhciBoPWMuY2hpbGRyZW5baV0KaWYoaC5pZD09J2F0dHJpYnV0ZXMn
+fHxoLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aC5pZD09J2xhc3RDaGlsZCd8fGgubmFtZT09J2xhc3RDaGls
+ZCd8fGguaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxoLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxoLmlk
+PT0nY2hpbGRyZW4nfHxoLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfShh
+KQpuPUgub1Qocyk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNhdGNo
+KHApe0guUnUocCl9cj0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3I9Si5qKGEpfWNhdGNoKHApe0gu
+UnUocCl9dHJ5e3E9Vy5yUyhhKQp0aGlzLmtSKHQuaC5hKGEpLGIsbixyLHEsdC5mLmEobSksSC5rKGwp
+KX1jYXRjaChwKXtpZihILlJ1KHApIGluc3RhbmNlb2YgUC51KXRocm93IHAKZWxzZXt0aGlzLkVQKGEs
+YikKd2luZG93Cm89IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5FaihyKQppZih0eXBlb2Yg
+Y29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihvKX19fSwKa1I6ZnVuY3Rpb24o
+YSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG09dGhpcwppZihjKXttLkVQKGEsYikKd2luZG93
+CnM9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4i
+CmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVy
+bn1pZighbS5hLmkwKGEpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxl
+bWVudCA8IitILkVqKGUpKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZp
+bmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVybn1pZihnIT1udWxsKWlmKCFtLmEuRWIoYSwi
+aXMiLGcpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNp
+b24gPCIrSC5FaihlKSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIp
+d2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59cz1mLmd2YygpCnI9SC5WTShzLnNsaWNlKDApLEgu
+dDYocykpCmZvcihxPWYuZ3ZjKCkubGVuZ3RoLTEscz1mLmE7cT49MDstLXEpe2lmKHE+PXIubGVuZ3Ro
+KXJldHVybiBILk9IKHIscSkKcD1yW3FdCm89bS5hCm49Si5jSChwKQpILmgocCkKaWYoIW8uRWIoYSxu
+LHMuZ2V0QXR0cmlidXRlKHApKSl7d2luZG93Cm89IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRl
+IDwiK0guRWooZSkrIiAiK3ArJz0iJytILkVqKHMuZ2V0QXR0cmlidXRlKHApKSsnIj4nCmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKG8pCnMucmVtb3ZlQXR0cmli
+dXRlKHApfX1pZih0LmFXLmIoYSkpe3M9YS5jb250ZW50CnMudG9TdHJpbmcKbS5QbihzKX19LAokaW9u
+OjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT10aGlz
+LmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTptLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6
+Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0Om0uRVAoYSxiKX1zPWEubGFzdENoaWxkCmZvcihxPXQu
+QTtudWxsIT1zOyl7cj1udWxsCnRyeXtyPXMucHJldmlvdXNTaWJsaW5nCmlmKHIhPW51bGwpe3A9ci5u
+ZXh0U2libGluZwpvPXMKbz1wPT1udWxsP28hPW51bGw6cCE9PW8KcD1vfWVsc2UgcD0hMQppZihwKXtw
+PVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRocm93IEguYihwKX19Y2F0Y2gobil7SC5SdShuKQpwPXEuYShz
+KQptLmI9ITAKbz1wLnBhcmVudE5vZGUKbz1hPT1udWxsP28hPW51bGw6YSE9PW8KaWYobyl7bz1wLnBh
+cmVudE5vZGUKaWYobyE9bnVsbClvLnJlbW92ZUNoaWxkKHApfWVsc2UgYS5yZW1vdmVDaGlsZChwKQpz
+PW51bGwKcj1hLmxhc3RDaGlsZH1pZihzIT1udWxsKXRoaXMuJDIocyxhKQpzPXJ9fSwKJFM6MzB9Clcu
+TGUucHJvdG90eXBlPXt9ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJv
+dG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7
+dmFyIHMscj10aGlzLmEscT1yLmxlbmd0aApmb3Iocz0wO3M8cTsrK3MpaWYocltzXT09PWEpcmV0dXJu
+IHMKQy5ObS5pKHIsYSkKQy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4gcX0sClB2OmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPXRoaXMsbz17fQppZihhPT1udWxsKXJldHVybiBhCmlmKEgubChhKSlyZXR1cm4g
+YQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHQuZnYuYihhKSl0
+aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodC5jOC5iKGEpKXJl
+dHVybiBhCmlmKHQudy5iKGEpKXJldHVybiBhCmlmKHQuSS5iKGEpKXJldHVybiBhCnM9dC5kRS5iKGEp
+fHwhMQppZihzKXJldHVybiBhCmlmKHQuZi5iKGEpKXtyPXAuVkgoYSkKcz1wLmIKaWYocj49cy5sZW5n
+dGgpcmV0dXJuIEguT0gocyxyKQpxPW8uYT1zW3JdCmlmKHEhPW51bGwpcmV0dXJuIHEKcT17fQpvLmE9
+cQpDLk5tLlk1KHMscixxKQphLksoMCxuZXcgUC5qZyhvLHApKQpyZXR1cm4gby5hfWlmKHQuai5iKGEp
+KXtyPXAuVkgoYSkKbz1wLmIKaWYocj49by5sZW5ndGgpcmV0dXJuIEguT0gobyxyKQpxPW9bcl0KaWYo
+cSE9bnVsbClyZXR1cm4gcQpyZXR1cm4gcC5layhhLHIpfWlmKHQuZUguYihhKSl7cj1wLlZIKGEpCnM9
+cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1vLmI9c1tyXQppZihxIT1udWxsKXJl
+dHVybiBxCnE9e30Kby5iPXEKQy5ObS5ZNShzLHIscSkKcC5pbShhLG5ldyBQLlRhKG8scCkpCnJldHVy
+biBvLmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVr
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscj1KLlU2KGEpLHE9ci5nQShhKSxwPW5ldyBBcnJheShxKQpDLk5t
+Llk1KHRoaXMuYixiLHApCmZvcihzPTA7czxxOysrcylDLk5tLlk1KHAscyx0aGlzLlB2KHIucShhLHMp
+KSkKcmV0dXJuIHB9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmFbYV09
+dGhpcy5iLlB2KGIpfSwKJFM6MzF9ClAuVGEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlz
+LmEuYlthXT10aGlzLmIuUHYoYil9LAokUzoxNn0KUC5CZi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIscSxwCnQuYjguYShiKQpmb3Iocz1PYmplY3Qua2V5cyhhKSxyPXMubGVuZ3RoLHE9
+MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLGFbcF0pfX19ClAuQXMucHJvdG90eXBlPXsKVjpmdW5jdGlv
+bihhKXt2YXIgcwpILmgoYSkKcz0kLmhHKCkuYgppZih0eXBlb2YgYSE9InN0cmluZyIpSC52KEgudEwo
+YSkpCmlmKHMudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZh
+bGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuaygwLCIgIil9
+LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLkQoKQpyZXR1cm4gUC5yaihzLHMucixILkxoKHMpLmMp
+fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkQoKS5hPT09MH0sCmdvcjpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5EKCkuYSE9PTB9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuYX0sCnRn
+OmZ1bmN0aW9uKGEsYil7dGhpcy5WKGIpCnJldHVybiB0aGlzLkQoKS50ZygwLGIpfSwKaTpmdW5jdGlv
+bihhLGIpe3ZhciBzCkguaChiKQp0aGlzLlYoYikKcz10aGlzLk8obmV3IFAuR0UoYikpCnJldHVybiBI
+Lnk4KHM9PW51bGw/ITE6cyl9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZih0eXBlb2YgYiE9InN0
+cmluZyIpcmV0dXJuITEKdGhpcy5WKGIpCnM9dGhpcy5EKCkKcj1zLkwoMCxiKQp0aGlzLlgocykKcmV0
+dXJuIHJ9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuTyhuZXcgUC5ONyh0aGlzLHQuUS5hKGIpKSl9LApl
+UjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuRCgpCnJldHVybiBILmJLKHMsYixILkxoKHMpLkMoImxm
+LkUiKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuRCgpLkUoMCxiKX0sClYxOmZ1bmN0aW9u
+KGEpe3RoaXMuTyhuZXcgUC51USgpKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHMscgp0LmJVLmEoYSkKcz10
+aGlzLkQoKQpyPWEuJDEocykKdGhpcy5YKHMpCnJldHVybiByfX0KUC5HRS5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4gdC5DLmEoYSkuaSgwLHRoaXMuYSl9LAokUzozM30KUC5ONy5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmIscj1ILnQ2KHMpCnJldHVybiB0LkMuYShhKS5G
+VigwLG5ldyBILmxKKHMsci5DKCJxVSgxKSIpLmEodGhpcy5hLmd1TSgpKSxyLkMoImxKPDEscVU+Iikp
+KX0sCiRTOjE3fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3QuQy5hKGEpCmlmKGEuYT4w
+KXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5HWSgpfXJldHVybiBudWxsfSwKJFM6MTd9
+ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMKdC5ZLmEoYSkKcz1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGIoYyxk
+LHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3VtZW50cykpfX0oUC5SNCxhLCExKQpQ
+LkRtKHMsJC53KCksYSkKcmV0dXJuIHN9LAokUzo0fQpQLm10LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
+KGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6NH0KUC5Oei5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5RUy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAuVHooYSx0LmFtKX0sCiRTOjU0fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3fQpQLkU0LnByb3RvdHlwZT17CnE6ZnVu
+Y3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBI
+LmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQpyZXR1cm4gUC5kVSh0aGlz
+LmFbYl0pfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIh
+PSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikp
+CnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJl
+dHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxy
+CnRyeXtzPVN0cmluZyh0aGlzLmEpCnJldHVybiBzfWNhdGNoKHIpe0guUnUocikKcz10aGlzLnhiKDAp
+CnJldHVybiBzfX0sClY3OmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmEKaWYoYj09bnVsbClzPW51
+bGwKZWxzZXtzPUgudDYoYikKcz1QLkNIKG5ldyBILmxKKGIscy5DKCJAKDEpIikuYShQLmlHKCkpLHMu
+QygibEo8MSxAPiIpKSwhMCx0LnopfXJldHVybiBQLmRVKHJbYV0uYXBwbHkocixzKSl9LApnaU86ZnVu
+Y3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1
+bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1hPDB8fGE+PXMuZ0EocykKaWYocil0aHJvdyBILmIoUC5URShh
+LDAscy5nQShzKSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZihILm9rKGIpKXRoaXMuY1Ao
+YikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3Ro
+aXMuY1AoYikKdGhpcy5lNCgwLGIsYyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEubGVuZ3Ro
+CmlmKHR5cGVvZiBzPT09Im51bWJlciImJnM+Pj4wPT09cylyZXR1cm4gcwp0aHJvdyBILmIoUC5QVigi
+QmFkIEpzQXJyYXkgbGVuZ3RoIikpfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KUC5jby5wcm90b3R5
+cGU9e30KUC5uZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpEOmZ1bmN0aW9uKCl7
+dmFyIHMscixxLHAsbz10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG49UC5Mcyh0Lk4pCmlmKG89
+PW51bGwpcmV0dXJuIG4KZm9yKHM9by5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9
+Si5UMChzW3FdKQppZihwLmxlbmd0aCE9PTApbi5pKDAscCl9cmV0dXJuIG59LApYOmZ1bmN0aW9uKGEp
+e3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixhLmsoMCwiICIpKX19ClAuaGkucHJvdG90eXBlPXsK
+Z246ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5Z
+QyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGQ9PW51bGwpe3M9
+SC5WTShbXSx0LnYpCmQ9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5C
+bCgpKQpDLk5tLmkocyxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnI9JzxzdmcgdmVyc2lvbj0iMS4x
+Ij4nK0guRWooYikrIjwvc3ZnPiIKcz1kb2N1bWVudApxPXMuYm9keQpxLnRvU3RyaW5nCnA9Qy5SWS5B
+SChxLHIsYykKbz1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpwLnRvU3RyaW5nCnM9bmV3IFcuZTco
+cCkKbj1zLmdyOChzKQpmb3IoO3M9bi5maXJzdENoaWxkLHMhPW51bGw7KW8uYXBwZW5kQ2hpbGQocykK
+cmV0dXJuIG99LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52
+b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcuIikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgVy5ldShhLCJjbGljayIsITEsdC5rKX0sCiRpaGk6MX0KTS5INy5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpVLkxMLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJu
+IFAuRUYoWyJub2RlSWQiLHRoaXMuYiwia2luZCIsdGhpcy5hLmFdLHQuWCx0Ll8pfX0KVS5NRC5wcm90
+b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5mRS5hKGEpLmE9PT10aGlzLmEucSgwLCJraW5k
+Iil9LAokUzozOH0KVS5kMi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhp
+cyxuPXQuWCxtPXQuXyxsPVAuRmwobixtKSxrPW8uYQppZihrIT1udWxsKXtzPUguVk0oW10sdC5HKQpm
+b3Iocj1rLmxlbmd0aCxxPTA7cTxrLmxlbmd0aDtrLmxlbmd0aD09PXJ8fCgwLEgubGspKGspLCsrcSl7
+cD1rW3FdCnMucHVzaChQLkVGKFsiZGVzY3JpcHRpb24iLHAuYSwiaHJlZiIscC5iXSxuLG0pKX1sLlk1
+KDAsImVkaXRzIixzKX1sLlk1KDAsImV4cGxhbmF0aW9uIixvLmIpCmwuWTUoMCwibGluZSIsby5jKQps
+Llk1KDAsImRpc3BsYXlQYXRoIixvLmQpCmwuWTUoMCwidXJpUGF0aCIsby5lKQpuPW8uZgppZihuIT1u
+dWxsKXttPUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0aCxxPTA7cTxuLmxlbmd0aDtuLmxlbmd0aD09
+PWt8fCgwLEgubGspKG4pLCsrcSltLnB1c2gobltxXS5MdCgpKQpsLlk1KDAsInRyYWNlcyIsbSl9cmV0
+dXJuIGx9fQpVLlNlLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJkZXNjcmlw
+dGlvbiIsdGhpcy5hLCJocmVmIix0aGlzLmJdLHQuWCx0Ll8pfX0KVS5NbC5wcm90b3R5cGU9ewpMdDpm
+dW5jdGlvbigpe3JldHVybiBQLkVGKFsiaHJlZiIsdGhpcy5hLCJsaW5lIix0aGlzLmIsInBhdGgiLHRo
+aXMuY10sdC5YLHQuXyl9fQpVLnlELnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHA9
+SC5WTShbXSx0LkcpCmZvcihzPXRoaXMuYixyPXMubGVuZ3RoLHE9MDtxPHMubGVuZ3RoO3MubGVuZ3Ro
+PT09cnx8KDAsSC5saykocyksKytxKXAucHVzaChzW3FdLkx0KCkpCnJldHVybiBQLkVGKFsiZGVzY3Jp
+cHRpb24iLHRoaXMuYSwiZW50cmllcyIscF0sdC5YLHQuXyl9fQpVLndiLnByb3RvdHlwZT17Ckx0OmZ1
+bmN0aW9uKCl7dmFyIHMscixxLHA9dGhpcyxvPVAuRmwodC5YLHQuXykKby5ZNSgwLCJkZXNjcmlwdGlv
+biIscC5hKQpzPXAuYgppZihzIT1udWxsKW8uWTUoMCwiZnVuY3Rpb24iLHMpCnM9cC5jCmlmKHMhPW51
+bGwpby5ZNSgwLCJsaW5rIixzLkx0KCkpCnM9cC5kCmlmKHMubGVuZ3RoIT09MCl7cj1ILnQ2KHMpCnE9
+ci5DKCJsSjwxLFowPHFVKixNaCo+Kj4iKQpvLlk1KDAsImhpbnRBY3Rpb25zIixQLlkxKG5ldyBILmxK
+KHMsci5DKCJaMDxxVSosTWgqPiooMSkiKS5hKG5ldyBVLmIwKCkpLHEpLCEwLHEuQygiYUwuRSIpKSl9
+cmV0dXJuIG99fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBVLm56KHQudC5h
+KGEpKX0sCiRTOjM5fQpVLmIwLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmFYLmEo
+YSkuTHQoKX0sCiRTOjQwfQpCLmo4LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYo
+WyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlzLmIsIm9mZnNldCIsdGhpcy5jXSx0LlgsdC5f
+KX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsPXRoaXMs
+az10Llgsaj1QLkZsKGssdC5kcCkKZm9yKHM9bC5kLHM9cy5nUHUocykscz1zLmdtKHMpLHI9dC5fLHE9
+dC5HO3MuRigpOyl7cD1zLmdsKCkKbz1wLmEKbj1ILlZNKFtdLHEpCmZvcihwPUouSVQocC5iKTtwLkYo
+KTspe209cC5nbCgpCm4ucHVzaChQLkVGKFsibGluZSIsbS5hLCJleHBsYW5hdGlvbiIsbS5iLCJvZmZz
+ZXQiLG0uY10sayxyKSl9ai5ZNSgwLG8sbil9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixsLmEsIm5hdmln
+YXRpb25Db250ZW50IixsLmIsInNvdXJjZUNvZGUiLGwuYywiZWRpdHMiLGpdLGsscil9fQpULm1RLnBy
+b3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0K
+dC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cubG9jYXRpb24u
+aHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYocyE9PSIvIiYmcyE9PUou
+VDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyhzLHIscSwh
+MCxuZXcgTC5WVyhzLHIscSkpCnA9ZG9jdW1lbnQKbz1KLnFGKHAucXVlcnlTZWxlY3RvcigiLmFwcGx5
+LW1pZ3JhdGlvbiIpKQpuPW8uJHRpCm09bi5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdC5aLmEobnVs
+bCkKVy5KRShvLmEsby5iLG0sITEsbi5jKQpuPUoucUYocC5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWln
+cmF0aW9uIikpCm09bi4kdGkKVy5KRShuLmEsbi5iLG0uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCEx
+LG0uYykKbT1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm49bS4kdGkKVy5K
+RShtLmEsbS5iLG4uQygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG4uYykKcD1KLnFGKHAucXVlcnlT
+ZWxlY3RvcigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm49cC4kdGkKVy5KRShwLmEscC5iLG4uQygifigx
+KT8iKS5hKG5ldyBMLlBZKCkpLCExLG4uYykKbj1KLnFGKCQuYzAoKSkKcD1uLiR0aQpXLkpFKG4uYSxu
+LmIscC5DKCJ+KDEpPyIpLmEobmV3IEwudTgoKSksITEscC5jKX0sCiRTOjE4fQpMLlZXLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoyfQpMLm9aLnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCnQuTy5hKGEpCmlmKEgub1QoQy5vbC51
+cyh3aW5kb3csIlRoaXMgd2lsbCBhcHBseSB0aGUgY2hhbmdlcyB5b3UndmUgcHJldmlld2VkIHRvIHlv
+dXIgd29ya2luZyBkaXJlY3RvcnkuIEl0IGlzIHJlY29tbWVuZGVkIHlvdSBjb21taXQgYW55IGNoYW5n
+ZXMgeW91IG1hZGUgYmVmb3JlIGRvaW5nIHRoaXMuIikpKXtzPUwudHkoIi9hcHBseS1taWdyYXRpb24i
+LG51bGwpLlc3KG5ldyBMLmpyKCksdC5QKQpyPW5ldyBMLnFsKCkKdC5iNy5hKG51bGwpCnE9cy4kdGkK
+cD0kLlgzCmlmKHAhPT1DLk5VKXI9UC5WSChyLHApCnMueGYobmV3IFAuRmUobmV3IFAudnMocCxxKSwy
+LG51bGwscixxLkMoIkA8MT4iKS5LcShxLmMpLkMoIkZlPDEsMj4iKSkpfX0sCiRTOjF9CkwuanIucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC50LmEoYSkKcz1kb2N1bWVudC5ib2R5CnMuY2xh
+c3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQpzLmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjQz
+fQpMLnFsLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5DMigiQ291bGQgbm90IGFwcGx5IG1p
+Z3JhdGlvbiIsYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjE2fQpMLkhpLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLnhuKHQuTy5hKGEpKX0sCnhuOmZ1bmN0aW9uKGEpe3ZhciBzPTAs
+cj1QLkZYKHQuUCkscT0xLHAsbz1bXSxuLG0sbCxrLGoKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9u
+KGIsYyl7aWYoYj09PTEpe3A9YwpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9Mwpkb2N1
+bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVubmluZyIpCnM9NgpyZXR1cm4gUC5qUShMLnR5KCIv
+cmVydW4tbWlncmF0aW9uIixudWxsKSwkYXN5bmMkJDEpCmNhc2UgNjpuPWMKaWYoSC5vVChILnk4KEou
+eDkobiwic3VjY2VzcyIpKSkpd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpCmVsc2UgTC5LMCh0Lm0uYShK
+Lng5KG4sImVycm9ycyIpKSkKby5wdXNoKDUpCnM9NApicmVhawpjYXNlIDM6cT0yCmo9cAptPUguUnUo
+aikKbD1ILnRzKGopCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG0sbCkKby5wdXNoKDUp
+CnM9NApicmVhawpjYXNlIDI6bz1bMV0KY2FzZSA0OnE9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5y
+ZW1vdmUoInJlcnVubmluZyIpCnM9by5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxy
+KQpjYXNlIDE6cmV0dXJuIFAuZjMocCxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscil9LAokUzox
+OX0KTC5CVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPXQuWApDLm9s
+LlBvKHdpbmRvdyxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9u
+ZXciLFAuRUYoWyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRp
+b24gdG9vbCIsImxhYmVscyIsdS5kLCJib2R5IiwiIyMjIyBTdGVwcyB0byByZXByb2R1Y2VcblxuIyMj
+IyBXaGF0IGRpZCB5b3UgZXhwZWN0IHRvIGhhcHBlbj9cblxuIyMjIyBXaGF0IGFjdHVhbGx5IGhhcHBl
+bmVkP1xuXG5fU2NyZWVuc2hvdHMgYXJlIGFwcHJlY2lhdGVkX1xuXG4qKkRhcnQgU0RLIHZlcnNpb24q
+KjogIitILkVqKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRleHRDb250ZW50
+KSsiXG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuIl0scyxzKSkuZ25EKCksInJlcG9ydC1wcm9ibGVtIil9
+LAokUzoxfQpMLlBZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9ZG9j
+dW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQpzLmRpc3BsYXk9Im5vbmUiCnJl
+dHVybiJub25lIn0sCiRTOjQ1fQpMLnU4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cSxwCnQuTy5hKGEpCnM9JC5EOSgpLmlubmVyVGV4dApyPXQuZy5hKGRvY3VtZW50LnF1ZXJ5U2VsZWN0
+b3IoJy5uYXYtcGFuZWwgW2RhdGEtbmFtZSo9IicrSC5FaihzKSsnIl0nKS5wYXJlbnROb2RlKQpxPXIu
+cXVlcnlTZWxlY3RvcigiLnN0YXR1cy1pY29uIikKcD1MLm1IKCQuSVIscykKaWYocCBpbnN0YW5jZW9m
+IEwuY0Qpe0wuT3QocCkKTC54bihxLHApCkwuQVIocixwKX19LAokUzoxfQpMLkwucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxCnQuYUwuYShhKQpzPXdpbmRvdy5sb2NhdGlvbi5wYXRobmFt
+ZQpyPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikK
+aWYocy5sZW5ndGg+MSlMLkc3KHMscixxLCExLG51bGwpCmVsc2V7TC5CRShzLEIud1IoKSwhMCkKTC5C
+WCgiJm5ic3A7IixudWxsKX19LAokUzoxOH0KTC5XeC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgcyxyLHEscD0iY29sbGFwc2VkIgp0Lk8uYShhKQpzPXRoaXMuYQpyPUouWUUocykKcT10aGlzLmIK
+aWYoIXIuZ24ocykudGcoMCxwKSl7ci5nbihzKS5pKDAscCkKSi5kUihxKS5pKDAscCl9ZWxzZXtyLmdu
+KHMpLkwoMCxwKQpKLmRSKHEpLkwoMCxwKX19LAokUzoxfQpMLkFPLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciBzPUoucUYodC5nLmEoYSkpLHI9cy4kdGkscT1yLkMoIn4oMSk/IikuYShuZXcgTC5k
+Tih0aGlzLmEpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIscSwhMSxyLmMpfSwKJFM6M30KTC5kTi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPWRvY3VtZW50LnF1ZXJ5U2Vs
+ZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpzLnRvU3RyaW5nCkwudDIoYSx0aGlzLmEscy5nZXRBdHRy
+aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuUCgicGF0aCIpKSl9LAokUzoxfQpMLkhv
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQp0LmcuYShhKQpzPUoucUYoYSkKcj1z
+LiR0aQpxPXIuQygifigxKT8iKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdC5aLmEobnVsbCkKVy5KRShz
+LmEscy5iLHEsITEsci5jKX0sCiRTOjN9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMKdC5PLmEoYSkKcz10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQShzLmdldEF0dHJpYnV0ZSgiZGF0YS0i
+K25ldyBXLlN5KG5ldyBXLmk3KHMpKS5QKCJvZmZzZXQiKSksbnVsbCksUC5RQShzLmdldEF0dHJpYnV0
+ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHMpKS5QKCJsaW5lIikpLG51bGwpKX0sCiRTOjF9Ckwu
+SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9Si5xRih0LmcuYShhKSkscj1zLiR0aQpy
+LkMoIn4oMSk/IikuYShMLmlTKCkpCnQuWi5hKG51bGwpClcuSkUocy5hLHMuYixMLmlTKCksITEsci5j
+KX0sCiRTOjN9CkwuZkMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5lUS5hKGEpCnRoaXMuYS5h
+TSgwLHRoaXMuYil9LAokUzo0N30KTC5uVC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhp
+cy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6Mn0KTC5OWS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
+RnIodGhpcy5hLG51bGwsbnVsbCl9LAokUzoyfQpMLnVlLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3QuYXcuYShhKQpyZXR1cm4gSC5FaihhLnEoMCwic2V2ZXJpdHkiKSkrIiAtICIrSC5FaihhLnEoMCwi
+bWVzc2FnZSIpKSsiIGF0ICIrSC5FaihhLnEoMCwibG9jYXRpb24iKSkrIiAtICgiK0guRWooYS5xKDAs
+ImNvZGUiKSkrIikifSwKJFM6NDh9CkwuZVgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5nLmEo
+YSkKJC56QigpLnRvU3RyaW5nCnQuZEguYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRC
+bG9jayIsW2FdKX0sCiRTOjN9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscgp0
+Lk8uYShhKS5wcmV2ZW50RGVmYXVsdCgpCnM9dGhpcy5hCnI9dGhpcy5iCkwuYWYod2luZG93LmxvY2F0
+aW9uLnBhdGhuYW1lLHMsciwhMCxuZXcgTC5RTChzLHIpKQpMLmhYKHRoaXMuYyxzLHIpfSwKJFM6MX0K
+TC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1l
+LHRoaXMuYSx0aGlzLmIpfSwKJFM6Mn0KTC5WUy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
+cyxyPSJzZWxlY3RlZC1maWxlIgp0LmcuYShhKQphLnRvU3RyaW5nCnM9Si5ZRShhKQppZihhLmdldEF0
+dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEpKS5QKCJuYW1lIikpPT09dGhpcy5hLmEp
+cy5nbihhKS5pKDAscikKZWxzZSBzLmduKGEpLkwoMCxyKX0sCiRTOjN9CkwuVEQucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodC5PLmEoYSksITAsbnVsbCl9LAokUzoyMH0KTC5tMi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5SSSh0Lk8uYShhKSl9LApSSTpmdW5j
+dGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89W10sbj10aGlzLG0sbCxrLGosaSxoLGcs
+Zgp2YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13aGlsZSh0
+cnVlKXN3aXRjaChzKXtjYXNlIDA6cT0zCmk9ZG9jdW1lbnQKbT1DLkNELnpRKGkucXVlcnlTZWxlY3Rv
+cigiLmNvbnRlbnQiKS5zY3JvbGxUb3ApCmg9dC5YCnM9NgpyZXR1cm4gUC5qUShMLnR5KEwuUTQoIi9h
+cHBseS1oaW50IixQLkZsKGgsaCkpLG4uYS5MdCgpKSwkYXN5bmMkJDEpCmNhc2UgNjpoPW4uYgpsPUwu
+VXMoaC5hKQpzPTcKcmV0dXJuIFAualEoTC5HNyhsLG51bGwsaC5iLCExLG51bGwpLCRhc3luYyQkMSkK
+Y2FzZSA3OmkuYm9keS5jbGFzc0xpc3QuYWRkKCJuZWVkcy1yZXJ1biIpCmk9aS5xdWVyeVNlbGVjdG9y
+KCIuY29udGVudCIpCmkudG9TdHJpbmcKaS5zY3JvbGxUb3A9Si5WdShtKQpxPTEKcz01CmJyZWFrCmNh
+c2UgMzpxPTIKZj1wCms9SC5SdShmKQpqPUgudHMoZikKTC5DMigiQ291bGQgbm90IGFwcGx5IGhpbnQi
+LGssaikKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikK
+Y2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MTl9
+CkwuWEEucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiEwfSwKaTA6ZnVuY3Rpb24o
+YSl7cmV0dXJuITB9LAokaWtGOjF9CkwudnQucHJvdG90eXBlPXsKZ2Q2OmZ1bmN0aW9uKCl7dmFyIHMs
+cixxLHAsbyxuLG0sbD10aGlzLmQKaWYobC5sZW5ndGg9PT0wKXJldHVybiBDLmN3CnM9Qy5ObS5ndEgo
+bCkuZ2Q2KCkKZm9yKHI9bC5sZW5ndGgscT0hMCxwPSEwLG89MDtvPGwubGVuZ3RoO2wubGVuZ3RoPT09
+cnx8KDAsSC5saykobCksKytvKXtuPWxbb10uZ2Q2KCkKaWYobiE9cylzPW51bGwKbT1uIT09Qy5jdwpp
+ZihtJiZuIT09Qy5XRClxPSExCmlmKG0mJm4hPT1DLlhqKXA9ITF9aWYocyE9bnVsbClyZXR1cm4gcwpp
+ZihxKXJldHVybiBDLldECmlmKHApcmV0dXJuIEMuWGoKcmV0dXJuIEMuZGN9LApMVjpmdW5jdGlvbigp
+e3ZhciBzLHIscT10aGlzLmQKaWYocSE9bnVsbClmb3Iocz1xLmxlbmd0aCxyPTA7cjxzOysrcilxW3Jd
+LmI9dGhpc30sCkx0OmZ1bmN0aW9uKCl7dmFyIHMscj1QLkZsKHQuWCx0Ll8pCnIuWTUoMCwidHlwZSIs
+ImRpcmVjdG9yeSIpCnIuWTUoMCwibmFtZSIsdGhpcy5hKQpyLlk1KDAsInN1YnRyZWUiLEwuVkQodGhp
+cy5kKSkKcz10aGlzLmMKaWYocyE9bnVsbClyLlk1KDAsInBhdGgiLHMpCnJldHVybiByfX0KTC5jRC5w
+cm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPVAuRmwodC5YLHQuXykKcS5ZNSgw
+LCJ0eXBlIiwiZmlsZSIpCnEuWTUoMCwibmFtZSIsci5hKQpzPXIuYwppZihzIT1udWxsKXEuWTUoMCwi
+cGF0aCIscykKcz1yLmQKaWYocyE9bnVsbClxLlk1KDAsImhyZWYiLHMpCnM9ci5lCmlmKHMhPW51bGwp
+cS5ZNSgwLCJlZGl0Q291bnQiLHMpCnM9ci5mCmlmKHMhPW51bGwpcS5ZNSgwLCJ3YXNFeHBsaWNpdGx5
+T3B0ZWRPdXQiLHMpCnM9ci5yCmlmKHMhPW51bGwpcS5ZNSgwLCJtaWdyYXRpb25TdGF0dXMiLHMuYSkK
+cmV0dXJuIHF9LApnZDY6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yfX0KTC5EOC5wcm90b3R5cGU9e30K
+TC5POS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpMLkdiLnByb3RvdHlw
+ZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19Ck0ubEkucHJvdG90eXBlPXsKZ2w6ZnVuY3Rp
+b24oKXt2YXIgcz1ELmFiKCkKcmV0dXJuIHN9LApXTzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10LmQ0
+Ck0uWUYoImFic29sdXRlIixILlZNKFtiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxxKSkK
+cz10aGlzLmEKcz1zLllyKGIpPjAmJiFzLmhLKGIpCmlmKHMpcmV0dXJuIGIKcj1ILlZNKFt0aGlzLmds
+KCksYixudWxsLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbF0scSkKTS5ZRigiam9pbiIscikKcmV0dXJu
+IHRoaXMuSVAobmV3IEgudTYocix0LmVKKSl9LAp6ZjpmdW5jdGlvbihhKXt2YXIgcyxyLHE9WC5DTChh
+LHRoaXMuYSkKcS5JeCgpCnM9cS5kCnI9cy5sZW5ndGgKaWYocj09PTApe3M9cS5iCnJldHVybiBzPT1u
+dWxsPyIuIjpzfWlmKHI9PT0xKXtzPXEuYgpyZXR1cm4gcz09bnVsbD8iLiI6c31pZigwPj1yKXJldHVy
+biBILk9IKHMsLTEpCnMucG9wKCkKcz1xLmUKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkK
+cy5wb3AoKQpxLkl4KCkKcmV0dXJuIHEudygwKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8s
+bixtLGwsayxqCnQuUS5hKGEpCmZvcihzPWEuJHRpLHI9cy5DKCJhMihjWC5FKSIpLmEobmV3IE0ucTco
+KSkscT1hLmdtKGEpLHM9bmV3IEguU08ocSxyLHMuQygiU088Y1guRT4iKSkscj10aGlzLmEscD0hMSxv
+PSExLG49IiI7cy5GKCk7KXttPXEuZ2woKQppZihyLmhLKG0pJiZvKXtsPVguQ0wobSxyKQprPW4uY2hh
+ckNvZGVBdCgwKT09MD9uOm4Kbj1DLnhCLk5qKGssMCxyLlNwKGssITApKQpsLmI9bgppZihyLmRzKG4p
+KUMuTm0uWTUobC5lLDAsci5nbUkoKSkKbj1sLncoMCl9ZWxzZSBpZihyLllyKG0pPjApe289IXIuaEso
+bSkKbj1ILkVqKG0pfWVsc2V7aj1tLmxlbmd0aAppZihqIT09MCl7aWYoMD49ailyZXR1cm4gSC5PSCht
+LDApCmo9ci5VZChtWzBdKX1lbHNlIGo9ITEKaWYoIWopaWYocCluKz1yLmdtSSgpCm4rPW19cD1yLmRz
+KG0pfXJldHVybiBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKbzU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYo
+IXRoaXMueTMoYSkpcmV0dXJuIGEKcz1YLkNMKGEsdGhpcy5hKQpzLnJSKCkKcmV0dXJuIHMudygwKX0s
+CnkzOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqCmEudG9TdHJpbmcKcz10aGlzLmEK
+cj1zLllyKGEpCmlmKHIhPT0wKXtpZihzPT09JC5LaygpKWZvcihxPTA7cTxyOysrcSlpZihDLnhCLlco
+YSxxKT09PTQ3KXJldHVybiEwCnA9cgpvPTQ3fWVsc2V7cD0wCm89bnVsbH1mb3Iobj1uZXcgSC5xaihh
+KS5hLG09bi5sZW5ndGgscT1wLGw9bnVsbDtxPG07KytxLGw9byxvPWspe2s9Qy54Qi5PMihuLHEpCmlm
+KHMucjQoaykpe2lmKHM9PT0kLktrKCkmJms9PT00NylyZXR1cm4hMAppZihvIT1udWxsJiZzLnI0KG8p
+KXJldHVybiEwCmlmKG89PT00NilqPWw9PW51bGx8fGw9PT00Nnx8cy5yNChsKQplbHNlIGo9ITEKaWYo
+ailyZXR1cm4hMH19aWYobz09bnVsbClyZXR1cm4hMAppZihzLnI0KG8pKXJldHVybiEwCmlmKG89PT00
+NilzPWw9PW51bGx8fHMucjQobCl8fGw9PT00NgplbHNlIHM9ITEKaWYocylyZXR1cm4hMApyZXR1cm4h
+MX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzLGs9J1VuYWJsZSB0byBm
+aW5kIGEgcGF0aCB0byAiJwpiPWwuV08oMCxiKQpzPWwuYQppZihzLllyKGIpPD0wJiZzLllyKGEpPjAp
+cmV0dXJuIGwubzUoYSkKaWYocy5ZcihhKTw9MHx8cy5oSyhhKSlhPWwuV08oMCxhKQppZihzLllyKGEp
+PD0wJiZzLllyKGIpPjApdGhyb3cgSC5iKFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5FaihiKSsn
+Ii4nKSkKcj1YLkNMKGIscykKci5yUigpCnE9WC5DTChhLHMpCnEuclIoKQpwPXIuZApvPXAubGVuZ3Ro
+CmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0sIi4iKX1lbHNlIHA9
+ITEKaWYocClyZXR1cm4gcS53KDApCnA9ci5iCm89cS5iCmlmKHAhPW8pcD1wPT1udWxsfHxvPT1udWxs
+fHwhcy5OYyhwLG8pCmVsc2UgcD0hMQppZihwKXJldHVybiBxLncoMCkKd2hpbGUoITApe3A9ci5kCm89
+cC5sZW5ndGgKaWYobyE9PTApe249cS5kCm09bi5sZW5ndGgKaWYobSE9PTApe2lmKDA+PW8pcmV0dXJu
+IEguT0gocCwwKQpwPXBbMF0KaWYoMD49bSlyZXR1cm4gSC5PSChuLDApCm49cy5OYyhwLG5bMF0pCnA9
+bn1lbHNlIHA9ITF9ZWxzZSBwPSExCmlmKCFwKWJyZWFrCkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5l
+LDEpCkMuTm0uVzQocS5kLDApCkMuTm0uVzQocS5lLDEpfXA9ci5kCm89cC5sZW5ndGgKaWYobyE9PTAp
+e2lmKDA+PW8pcmV0dXJuIEguT0gocCwwKQpwPUouUk0ocFswXSwiLi4iKX1lbHNlIHA9ITEKaWYocCl0
+aHJvdyBILmIoWC5JNyhrK0guRWooYSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpwPXQuTgpDLk5t
+LlVHKHEuZCwwLFAuTzgoci5kLmxlbmd0aCwiLi4iLCExLHApKQpDLk5tLlk1KHEuZSwwLCIiKQpDLk5t
+LlVHKHEuZSwxLFAuTzgoci5kLmxlbmd0aCxzLmdtSSgpLCExLHApKQpzPXEuZApwPXMubGVuZ3RoCmlm
+KHA9PT0wKXJldHVybiIuIgppZihwPjEmJkouUk0oQy5ObS5ncloocyksIi4iKSl7cz1xLmQKaWYoMD49
+cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aClyZXR1
+cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9w
+KCkKQy5ObS5pKHMsIiIpfXEuYj0iIgpxLkl4KCkKcmV0dXJuIHEudygwKX19Ck0ucTcucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguaChhKSE9PSIifSwKJFM6Nn0KTS5Oby5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXtILmsoYSkKcmV0dXJuIGE9PW51bGw/Im51bGwiOiciJythKyciJ30sCiRT
+OjUwfQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5ZcihhKQppZihy
+PjApcmV0dXJuIEoubGQoYSwwLHIpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBI
+Lk9IKGEsMCkKcz1hWzBdfWVsc2Ugcz1udWxsCnJldHVybiBzfSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSXg6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcwp3aGls
+ZSghMCl7cz1xLmQKaWYoIShzLmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloocyksIiIpKSlicmVhawpz
+PXEuZAppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnM9cS5lCmlmKDA+PXMu
+bGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCl9cz1xLmUKcj1zLmxlbmd0aAppZihyIT09MClD
+Lk5tLlk1KHMsci0xLCIiKX0sCnJSOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPUgu
+Vk0oW10sdC5zKQpmb3Iocz1tLmQscj1zLmxlbmd0aCxxPTAscD0wO3A8cy5sZW5ndGg7cy5sZW5ndGg9
+PT1yfHwoMCxILmxrKShzKSwrK3Ape289c1twXQpuPUouaWEobykKaWYoIShuLkROKG8sIi4iKXx8bi5E
+TihvLCIiKSkpaWYobi5ETihvLCIuLiIpKXtuPWwubGVuZ3RoCmlmKG4hPT0wKXtpZigwPj1uKXJldHVy
+biBILk9IKGwsLTEpCmwucG9wKCl9ZWxzZSArK3F9ZWxzZSBDLk5tLmkobCxvKX1pZihtLmI9PW51bGwp
+Qy5ObS5VRyhsLDAsUC5POChxLCIuLiIsITEsdC5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9PW51bGwp
+Qy5ObS5pKGwsIi4iKQptLnNuSihsKQpzPW0uYQptLnNQaChQLk84KGwubGVuZ3RoKzEscy5nbUkoKSwh
+MCx0Lk4pKQpyPW0uYgppZihyPT1udWxsfHxsLmxlbmd0aD09PTB8fCFzLmRzKHIpKUMuTm0uWTUobS5l
+LDAsIiIpCnI9bS5iCmlmKHIhPW51bGwmJnM9PT0kLktrKCkpe3IudG9TdHJpbmcKbS5iPUgueXMociwi
+LyIsIlxcIil9bS5JeCgpfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXEuYgpwPXAhPW51
+bGw/cDoiIgpmb3Iocz0wO3M8cS5kLmxlbmd0aDsrK3Mpe3I9cS5lCmlmKHM+PXIubGVuZ3RoKXJldHVy
+biBILk9IKHIscykKcj1wK0guRWoocltzXSkKcD1xLmQKaWYocz49cC5sZW5ndGgpcmV0dXJuIEguT0go
+cCxzKQpwPXIrSC5FaihwW3NdKX1wKz1ILkVqKEMuTm0uZ3JaKHEuZSkpCnJldHVybiBwLmNoYXJDb2Rl
+QXQoMCk9PTA/cDpwfSwKc25KOmZ1bmN0aW9uKGEpe3RoaXMuZD10LkUuYShhKX0sCnNQaDpmdW5jdGlv
+bihhKXt0aGlzLmU9dC5FLmEoYSl9fQpYLmR2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlBhdGhFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejoxfQpPLnpMLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihh
+KXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6
+ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKcmV0dXJuIHMhPT0wJiZDLnhCLk8yKGEscy0xKSE9PTQ3
+fSwKU3A6ZnVuY3Rpb24oYSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDcpcmV0dXJu
+IDEKcmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0
+aW9uKGEpe3JldHVybiExfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInBvc2l4In0sCmdtSTpmdW5jdGlv
+bigpe3JldHVybiIvIn19CkYucnUucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
+dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3Zh
+ciBzPWEubGVuZ3RoCmlmKHM9PT0wKXJldHVybiExCmlmKEMueEIuTzIoYSxzLTEpIT09NDcpcmV0dXJu
+ITAKcmV0dXJuIEMueEIuVGMoYSwiOi8vIikmJnRoaXMuWXIoYSk9PT1zfSwKU3A6ZnVuY3Rpb24oYSxi
+KXt2YXIgcyxyLHEscCxvPWEubGVuZ3RoCmlmKG89PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09
+NDcpcmV0dXJuIDEKZm9yKHM9MDtzPG87KytzKXtyPUMueEIuVyhhLHMpCmlmKHI9PT00NylyZXR1cm4g
+MAppZihyPT09NTgpe2lmKHM9PT0wKXJldHVybiAwCnE9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8v
+IixzKzEpP3MrMzpzKQppZihxPD0wKXJldHVybiBvCmlmKCFifHxvPHErMylyZXR1cm4gcQppZighQy54
+Qi5uQyhhLCJmaWxlOi8vIikpcmV0dXJuIHEKaWYoIUIuWXUoYSxxKzEpKXJldHVybiBxCnA9cSszCnJl
+dHVybiBvPT09cD9wOnErNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChh
+LCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9
+LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19Ckwu
+SVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5n
+dGgKaWYocz09PTApcmV0dXJuITEKcz1DLnhCLk8yKGEscy0xKQpyZXR1cm4hKHM9PT00N3x8cz09PTky
+KX0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPWEubGVuZ3RoCmlmKHE9PT0wKXJldHVybiAwCnM9
+Qy54Qi5XKGEsMCkKaWYocz09PTQ3KXJldHVybiAxCmlmKHM9PT05Mil7aWYocTwyfHxDLnhCLlcoYSwx
+KSE9PTkyKXJldHVybiAxCnI9Qy54Qi5YVShhLCJcXCIsMikKaWYocj4wKXtyPUMueEIuWFUoYSwiXFwi
+LHIrMSkKaWYocj4wKXJldHVybiByfXJldHVybiBxfWlmKHE8MylyZXR1cm4gMAppZighQi5PUyhzKSly
+ZXR1cm4gMAppZihDLnhCLlcoYSwxKSE9PTU4KXJldHVybiAwCnE9Qy54Qi5XKGEsMikKaWYoIShxPT09
+NDd8fHE9PT05MikpcmV0dXJuIDAKcmV0dXJuIDN9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5T
+cChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLllyKGEpPT09MX0sCk90OmZ1bmN0aW9u
+KGEsYil7dmFyIHMKaWYoYT09PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJldHVybiBiPT09OTIKaWYoYT09
+PTkyKXJldHVybiBiPT09NDcKaWYoKGFeYikhPT0zMilyZXR1cm4hMQpzPWF8MzIKcmV0dXJuIHM+PTk3
+JiZzPD0xMjJ9LApOYzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZihhPT1iKXJldHVybiEwCnM9YS5s
+ZW5ndGgKaWYocyE9PWIubGVuZ3RoKXJldHVybiExCmZvcihyPUouclkoYikscT0wO3E8czsrK3EpaWYo
+IXRoaXMuT3QoQy54Qi5XKGEscSksci5XKGIscSkpKXJldHVybiExCnJldHVybiEwfSwKZ29jOmZ1bmN0
+aW9uKCl7cmV0dXJuIndpbmRvd3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIlxcIn19OyhmdW5jdGlv
+biBhbGlhc2VzKCl7dmFyIHM9Si5Hdi5wcm90b3R5cGUKcy5VPXMudwpzLlNqPXMuZTcKcz1KLk1GLnBy
+b3RvdHlwZQpzLnQ9cy53CnM9UC5jWC5wcm90b3R5cGUKcy5HRz1zLmV2CnM9UC5NaC5wcm90b3R5cGUK
+cy54Yj1zLncKcz1XLmN2LnByb3RvdHlwZQpzLkRXPXMucjYKcz1XLm02LnByb3RvdHlwZQpzLmpGPXMu
+RWIKcz1QLkU0LnByb3RvdHlwZQpzLlVyPXMucQpzLmU0PXMuWTV9KSgpOyhmdW5jdGlvbiBpbnN0YWxs
+VGVhck9mZnMoKXt2YXIgcz1odW5rSGVscGVycy5fc3RhdGljXzEscj1odW5rSGVscGVycy5fc3RhdGlj
+XzAscT1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHA9aHVua0hlbHBlcnMuaW5zdGFs
+bFN0YXRpY1RlYXJPZmYsbz1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKcyhQLCJFWCIsIlpWIiw3KQpz
+KFAsInl0Iiwib0EiLDcpCnMoUCwicVciLCJCeiIsNykKcihQLCJVSSIsImVOIiwwKQpxKFAuUGYucHJv
+dG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJdLDI4LDApCnMoUCwiQ3ki
+LCJOQyIsNCkKcyhQLCJQSCIsIk10Iiw1KQpwKFcsInBTIiw0LG51bGwsWyIkNCJdLFsicUQiXSw4LDAp
+CnAoVywiVjQiLDQsbnVsbCxbIiQ0Il0sWyJRVyJdLDgsMCkKbyhQLkFzLnByb3RvdHlwZSwiZ3VNIiwi
+ViIsNSkKcyhQLCJpRyIsIndZIiw1MykKcyhQLCJ3MCIsImRVIiwzNikKcyhMLCJpUyIsImk2IiwyMCl9
+KSgpOyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciBzPWh1bmtIZWxwZXJzLm1peGluLHI9aHVua0hl
+bHBlcnMuaW5oZXJpdCxxPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnIoUC5NaCxudWxsKQpxKFAuTWgs
+W0guRkssSi5HdixKLm0xLFAuY1gsSC5FNyxQLlhTLFAublksSC5hNyxQLkFuLEguRnUsSC5KQixILlNV
+LEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksSC50ZSxILmJxLEguWE8sSC5rcixQLllr
+LEgudmgsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5KYyxILkcsSC5sWSxQLlczLFAuaWgs
+UC5GeSxQLkdWLFAuUGYsUC5GZSxQLnZzLFAuT00sUC5xaCxQLk1PLFAua1QsUC54SSxQLkN3LFAubTAs
+UC5wUixQLmJuLFAubG0sUC5sRCxQLktQLFAubGYsUC5XWSxQLlVrLFAuU2gsUC5SdyxQLmJ6LFAuaVAs
+UC5rNSxQLktZLFAuQ0QsUC5hRSxQLk4zLFAuYzgsUC5aZCxQLlJuLFAuRG4sUC5QRSxQLlVmLFcuaWQs
+Vy5GayxXLkpRLFcuR20sVy52RCxXLm02LFcuT3csVy5XOSxXLmRXLFcubWssVy5LbyxQLmlKLFAuRTQs
+TS5INyxVLkxMLFUuZDIsVS5TZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5tUSxMLlhBLEwuRDgs
+TC5POSxMLkdiLE0ubEksTy56TCxYLldELFguZHZdKQpxKEouR3YsW0oueUUsSi53ZSxKLk1GLEouamQs
+Si5xSSxKLkRyLEguRVQsVy5EMCxXLkF6LFcuTGUsVy5OaCxXLmFlLFcuSUIsVy5uNyxXLmVhLFcuYnIs
+Vy5TZyxXLnc3LFcuSzcsVy5YVyxQLmhGXSkKcShKLk1GLFtKLmlDLEoua2QsSi5jNV0pCnIoSi5QbyxK
+LmpkKQpxKEoucUksW0ouYlUsSi5WQV0pCnEoUC5jWCxbSC5CUixILmJRLEguaTEsSC5VNSxILkFNLEgu
+dTYsSC5YUixQLm1XLEgudW5dKQpxKEguQlIsW0guWnksSC5RQ10pCnIoSC5vbCxILlp5KQpyKEguVXEs
+SC5RQykKcihILmpWLEguVXEpCnEoUC5YUyxbSC5uLEgucjMsSC5HTSxQLkV6LEguYXosSC52VixILkVx
+LFAuQzYsSC5rUyxQLlVkLFAuRixQLnUsUC5tcCxQLnViLFAuZHMsUC5saixQLlVWLFAuY10pCnIoUC51
+eSxQLm5ZKQpxKFAudXksW0gudzIsVy53eixXLmU3XSkKcihILnFqLEgudzIpCnEoSC5iUSxbSC5hTCxI
+Lk1CLEguaTVdKQpxKEguYUwsW0gubkgsSC5sSixQLmk4XSkKcihILnh5LEguaTEpCnEoUC5BbixbSC5N
+SCxILlNPLEguVTFdKQpyKEguZDUsSC5BTSkKcihQLlJVLFAuUG4pCnIoUC5HaixQLlJVKQpyKEguUEQs
+UC5HaikKcihILkxQLEguV1UpCnEoSC5UcCxbSC5DaixILmxjLEguZEMsSC53TixILlZYLFAudGgsUC5o
+YSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gsUC5HcyxQLmRhLFAub1EsUC5wVixQLlU3LFAudnIsUC5y
+dCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEsUC5SVyxQLkI1LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5P
+UixQLnJhLFAueVEsUC5wZyxQLmMyLFAudGksUC5XRixQLm4xLFAuY1MsUC5WQyxQLkpULFAuUlosUC5N
+RSxQLnk1LFAueUksUC5jNixQLnFkLFcuQ3YsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVnLFcuRW8sVy5X
+ayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5tdCxQLk56LFAuUVMsUC5u
+cCxVLk1ELFUuYU4sVS5iMCxMLmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkhpLEwuQlQsTC5QWSxMLnU4
+LEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxMLmZDLEwublQsTC5OWSxMLnVlLEwuZVgs
+TC5FRSxMLlFMLEwuVlMsTC5URCxMLm0yLE0ucTcsTS5Ob10pCnIoSC5XMCxQLkV6KQpxKEgubGMsW0gu
+engsSC5yVF0pCnIoSC5rWSxQLkM2KQpyKFAuaWwsUC5ZaykKcShQLmlsLFtILk41LFAudXcsVy5jZixX
+LlN5XSkKcShQLm1XLFtILktXLFAucTRdKQpyKEguTFosSC5FVCkKcShILkxaLFtILlJHLEguV0JdKQpy
+KEguVlAsSC5SRykKcihILkRnLEguVlApCnIoSC5aRyxILldCKQpyKEguUGcsSC5aRykKcShILlBnLFtI
+LnhqLEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcihILmlNLEgua1MpCnIoUC5aZixQLlBm
+KQpyKFAuSmksUC5tMCkKcihQLlh2LFAucFIpCnIoUC5iNixQLlh2KQpyKFAuVmosUC5XWSkKcShQLlVr
+LFtQLkNWLFAuWmksUC5ieV0pCnIoUC53SSxQLmtUKQpxKFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMs
+UC5HWV0pCnIoUC5LOCxQLlVkKQpyKFAudHUsUC5TaCkKcihQLnU1LFAuWmkpCnEoUC51LFtQLmJKLFAu
+ZVldKQpyKFAucWUsUC5EbikKcShXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkKcShXLnVILFtXLmN2
+LFcubngsVy5RRixXLkNRXSkKcShXLmN2LFtXLnFFLFAuaGldKQpxKFcucUUsW1cuR2gsVy5mWSxXLm5C
+LFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnIoVy5vSixXLkxlKQpyKFcu
+aEgsVy5BeikKcihXLlZiLFcuUUYpCnIoVy5mSixXLndhKQpxKFcuZWEsW1cudzYsVy5ld10pCnIoVy5B
+aixXLnc2KQpyKFcuckIsVy5LNykKcihXLkJILFcuckIpCnIoVy53NCxXLklCKQpyKFcub2EsVy5YVykK
+cihXLnJoLFcub2EpCnIoVy5pNyxXLmNmKQpyKFAuQXMsUC5WaikKcShQLkFzLFtXLkk0LFAuS2VdKQpy
+KFcuUk8sUC5xaCkKcihXLmV1LFcuUk8pCnIoVy54QyxQLk1PKQpyKFcuY3QsVy5tNikKcihQLkJmLFAu
+aUopCnEoUC5FNCxbUC5yNyxQLmNvXSkKcihQLlR6LFAuY28pCnIoUC5uZCxQLmhpKQpxKEwuRDgsW0wu
+dnQsTC5jRF0pCnIoQi5mdixPLnpMKQpxKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkKcyhILncyLEguUmUp
+CnMoSC5RQyxQLmxEKQpzKEguUkcsUC5sRCkKcyhILlZQLEguU1UpCnMoSC5XQixQLmxEKQpzKEguWkcs
+SC5TVSkKcyhQLm5ZLFAubEQpCnMoUC5XWSxQLmxmKQpzKFAuUlUsUC5LUCkKcyhQLnBSLFAubGYpCnMo
+Vy5MZSxXLmlkKQpzKFcuSzcsUC5sRCkKcyhXLnJCLFcuR20pCnMoVy5YVyxQLmxEKQpzKFcub2EsVy5H
+bSkKcyhQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30s
+ZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoiaW50IixDUDoiZG91Ymxl
+IixaWjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xl
+ZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBl
+czpbIn4oKSIsImM4KEFqKikiLCJjOCgpIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJhMihxVSki
+LCJ+KH4oKSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsIn4oTWg/LE1oPykiLCJAKCkiLCJ+KHFV
+LEApIiwifihuNixxVSxJZikiLCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEAsQCkiLCJ+KHh1PHFVPiki
+LCJjOChlYSopIiwiYjg8Yzg+KihBaiopIiwifihBaiopIiwifihxVSxJZikiLCJ+KHFVLHFVPykiLCJu
+NihALEApIiwiYzgoQCxHeikiLCJhMih1SCkiLCJ+KElmLEApIiwifihlYSkiLCJ+KE1oW0d6P10pIiwi
+YzgoTWgsR3opIiwifih1SCx1SD8pIiwifihALEApIiwidnM8QD4oQCkiLCJhMih4dTxxVT4pIiwiYzgo
+figpKSIsInI3KEApIiwiTWg/KEApIiwiRTQoQCkiLCJhMiooSDcqKSIsIkxMKihAKSIsIlowPHFVKixN
+aCo+KihMTCopIiwiQChxVSkiLCJ+KEdELEApIiwiYzgoWjA8cVUqLE1oKj4qKSIsIlowPHFVLHFVPiha
+MDxxVSxxVT4scVUpIiwicVUqKEFqKikiLCJAKEAscVUpIiwiYzgoZXcqKSIsInFVKihaMDxALEA+Kiki
+LCJ+KHFVW0BdKSIsInFVKHFVPykiLCJJZihJZixJZikiLCJ+KEApIiwiTWg/KE1oPykiLCJUejxAPihA
+KSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3lt
+Ym9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0
+aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtk
+IjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiaGkiLCJ0cCI6ImhpIiwiRzgiOiJldyIsIk1y
+IjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJBaiIsInk0
+IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlF
+Ijp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0i
+OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiWloiOltd
+fSwiYlUiOnsiQ1AiOltdLCJJZiI6W10sIlpaIjpbXX0sIlZBIjp7IkNQIjpbXSwiWloiOltdfSwiRHIi
+OnsicVUiOltdLCJ2WCI6W119LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6WyIyIl19LCJaeSI6
+eyJCUiI6WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5IjpbIjEiLCIyIl0s
+IkJSIjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJVcSI6eyJsRCI6
+WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl19LCJqViI6
+eyJVcSI6WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsi
+MiJdLCJjWCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6W119LCJyMyI6eyJY
+UyI6W119LCJxaiI6eyJsRCI6WyJJZiJdLCJSZSI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJd
+LCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiR00iOnsiWFMiOltdfSwiYlEiOnsi
+Y1giOlsiMSJdfSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJR
+IjpbIjEiXSwiY1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0s
+ImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJd
+LCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwi
+YlEiOlsiMiJdLCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJd
+LCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0s
+ImQ1Ijp7IkFNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlUxIjp7IkFu
+IjpbIjEiXX0sIk1CIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJGdSI6eyJBbiI6
+WyIxIl19LCJ1NiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpbIjEiXX0sIncyIjp7
+ImxEIjpbIjEiXSwiUmUiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwid3Yi
+OnsiR0QiOltdfSwiUEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIi
+XSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEiLCIyIl19LCJMUCI6
+eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
+LCJMSSI6eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6eyJYUyI6W119
+LCJ0ZSI6eyJSeiI6W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119
+LCJ6eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119
+LCJONSI6eyJZayI6WyIxIiwiMiJdLCJGbyI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoi
+MSIsIllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6
+eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwi
+S1ciOnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6
+W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7
+IkFTIjpbXX0sIkxaIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJd
+LCJYaiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIkFTIjpbXSwiY1giOlsi
+Q1AiXSwiU1UiOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0s
+InpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJ
+ZiJdfSwieGoiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwiRVQiOltdLCJiUSI6
+WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJs
+RCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpb
+XSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sIlhq
+IjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
+LCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0i
+OlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0s
+ImxELkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6
+W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0s
+ImVFIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYi
+XSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiVjYiOnsibEQiOlsi
+SWYiXSwibjYiOltdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFT
+IjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImtTIjp7IlhTIjpbXX0sImlN
+Ijp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwi
+WmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltdfSwibTAiOnsiUW0i
+OltdfSwiSmkiOnsibTAiOltdLCJRbSI6W119LCJiNiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEi
+OlsiMSJdLCJjWCI6WyIxIl0sImxmLkUiOiIxIn0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpb
+IjEiXX0sInV5Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImls
+Ijp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4i
+OnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpb
+IjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJYdiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6
+WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllr
+LlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJx
+VSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5TIjoiek08SWY+In0s
+IlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPElmPiJdfSwiVWQi
+OnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsiTWg/IiwicVUiXSwiVWsuUyI6Ik1o
+PyJ9LCJvaiI6eyJ3SSI6WyJNaD8iLCJxVSJdfSwiTXgiOnsid0kiOlsicVUiLCJNaD8iXX0sInU1Ijp7
+IlVrIjpbInFVIiwiek08SWY+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPElmPiJd
+fSwiR1kiOnsid0kiOlsiek08SWY+IiwicVUiXX0sIkNQIjp7IlpaIjpbXX0sIklmIjp7IlpaIjpbXX0s
+InpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJd
+LCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJDNiI6eyJYUyI6W119LCJFeiI6eyJYUyI6W119LCJG
+Ijp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAi
+OnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYi
+OnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJDRCI6
+eyJSeiI6W119LCJhRSI6eyJSeiI6W119LCJaZCI6eyJHeiI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6
+eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgi
+OltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119
+LCJJQiI6eyJ0biI6WyJaWiJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwi
+Y1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImhIIjp7IkF6IjpbXX0s
+Img0Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQwIjpbXX0sImZKIjp7
+IkQwIjpbXX0sIndhIjp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpN
+IjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119
+LCJCSCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6
+WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiU04iOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJUYiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sIldQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpbXSwiRDAi
+OltdfSwidzYiOnsiZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJD
+USI6eyJ1SCI6W10sIkQwIjpbXX0sInc0Ijp7InRuIjpbIlpaIl19LCJyaCI6eyJsRCI6WyJ1SCJdLCJH
+bSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJs
+RC5FIjoidUgiLCJHbS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
+Il19LCJpNyI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsu
+ViI6InFVIn0sIlN5Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUi
+LCJZay5WIjoicVUifSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1gi
+OlsicVUiXSwibGYuRSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgi
+OlsiMSJdfSwieEMiOnsiTU8iOlsiMSJdfSwiSlEiOnsia0YiOltdfSwidkQiOnsia0YiOltdfSwibTYi
+Onsia0YiOltdfSwiY3QiOnsia0YiOltdfSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwi
+ZFciOnsidjYiOltdLCJEMCI6W119LCJtayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJs
+ZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltd
+fSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0s
+ImxELkUiOiIxIn0sIm5kIjp7ImhpIjpbXSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7Imxm
+IjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxmLkUiOiJxVSJ9LCJo
+aSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiWEEiOnsia0YiOltdfSwidnQiOnsiRDgiOltdfSwi
+Y0QiOnsiRDgiOltdfSwiZHYiOnsiUnoiOltdfSwiT0YiOnsiZnYiOltdfSwicnUiOnsiZnYiOltdfSwi
+SVYiOnsiZnYiOltdfSwibjYiOnsiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1giOlsiSWYiXSwiQVMi
+OltdfX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7IncyIjoxLCJRQyI6MiwiTFoi
+OjEsImtUIjoyLCJtVyI6MSwidXkiOjEsImlsIjoyLCJWaiI6MSwiWHYiOjEsIm5ZIjoxLCJXWSI6MSwi
+cFIiOjEsImNvIjoxfScpKQp2YXIgdT17bDoiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+IFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IixpOiJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0
+aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiLGo6IkNhbm5vdCBleHRyYWN0IGEgbm9u
+LVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIsZzoiYG51
+bGxgIGVuY291bnRlcmVkIGFzIHRoZSByZXN1bHQgZnJvbSBleHByZXNzaW9uIHdpdGggdHlwZSBgTmV2
+ZXJgLiIsZDoiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3JhdGlvbix0eXBlLWJ1ZyJ9CnZh
+ciB0PShmdW5jdGlvbiBydGlpKCl7dmFyIHM9SC5OMApyZXR1cm57bjpzKCJDdyIpLGNSOnMoIm5CIiks
+dzpzKCJBeiIpLHA6cygiUVAiKSxnRjpzKCJQRDxHRCxAPiIpLGI6cygiYlE8QD4iKSxoOnMoImN2Iiks
+cjpzKCJYUyIpLEI6cygiZWEiKSxhUzpzKCJEMCIpLGc4OnMoIlJ6IiksYzg6cygiaEgiKSxZOnMoIkVI
+IiksZDpzKCJiODxAPiIpLEk6cygiU2ciKSxvOnMoInZRIiksZWg6cygiY1g8dUg+IiksUTpzKCJjWDxx
+VT4iKSx1OnMoImNYPEA+IiksdjpzKCJqZDxrRj4iKSxzOnMoImpkPHFVPiIpLGdOOnMoImpkPG42PiIp
+LHg6cygiamQ8QD4iKSxhOnMoImpkPElmPiIpLGQ3OnMoImpkPFNlKj4iKSxoNDpzKCJqZDxqOCo+Iiks
+RzpzKCJqZDxaMDxxVSosTWgqPio+IiksY1E6cygiamQ8RDgqPiIpLGk6cygiamQ8cVUqPiIpLGFBOnMo
+ImpkPHlEKj4iKSxhSjpzKCJqZDx3Yio+IiksVjpzKCJqZDxJZio+IiksZDQ6cygiamQ8cVU/PiIpLFQ6
+cygid2UiKSxlSDpzKCJ2bSIpLEQ6cygiYzUiKSxhVTpzKCJYajxAPiIpLGFtOnMoIlR6PEA+IiksZW86
+cygiTjU8R0QsQD4iKSxkejpzKCJoRiIpLEU6cygiek08cVU+IiksajpzKCJ6TTxAPiIpLEw6cygiek08
+SWY+IiksSjpzKCJaMDxxVSxxVT4iKSxmOnMoIlowPEAsQD4iKSxkbzpzKCJsSjxxVSxAPiIpLGZqOnMo
+ImxKPHFVKixxVT4iKSxkRTpzKCJFVCIpLGJtOnMoIlY2IiksQTpzKCJ1SCIpLGY2OnMoImtGIiksUDpz
+KCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPFpaPiIpLGZ2OnMoIndMIiksZXc6cygibmQiKSxDOnMoInh1
+PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIpLGc3OnMoImhpIiksZm86cygi
+R0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpzKCJrZCIpLGR3OnMoIkdqPHFV
+LHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUiKSxjaTpzKCJ2NiIpLGcyOnMo
+IkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTciKSxrOnMoImV1PEFqKj4iKSxS
+OnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWY+IiksZ1Y6cygidnM8ZkoqPiIpLGNy
+OnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQIiksejpzKCJAIiksZk86cygi
+QCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMoIkAoeHU8cVU+KSIpLGRPOnMo
+IkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJZiIpLGRkOnMoIkdoKiIpLGc6cygiY3YqIiksYUw6
+cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxAPioiKSxkSDpzKCJFNCoiKSxm
+SzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFowPHFVKixNaCo+Kj4qIiksbTpz
+KCJ6TTxNaCo+KiIpLGF3OnMoIlowPEAsQD4qIiksdDpzKCJaMDxxVSosTWgqPioiKSxPOnMoIkFqKiIp
+LGNGOnMoIjAmKiIpLF86cygiTWgqIiksZVE6cygiZXcqIiksWDpzKCJxVSoiKSxjaDpzKCJEMD8iKSxi
+RzpzKCJiODxjOD4/IiksYms6cygiek08cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNaOnMoIlowPHFVLHFV
+Pj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxXOnMoIk1oPyIpLEY6cygiRmU8QCxAPj8iKSxlOnMoImJuPyIp
+LGI3OnMoImEyKE1oKT8iKSxidzpzKCJAKGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1oPyk/IiksZEE6cygi
+TWg/KEApPyIpLFo6cygifigpPyIpLGViOnMoIn4oZXcqKT8iKSxkaTpzKCJaWiIpLEg6cygifiIpLE06
+cygifigpIiksZUE6cygifihxVSxxVSkiKSxjQTpzKCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29u
+c3RhbnRzKCl7dmFyIHM9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLnhuPVcuR2gucHJvdG90eXBl
+CkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5tSD1XLmFlLnByb3RvdHlwZQpDLkJaPVcuVmIucHJvdG90eXBl
+CkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLkd2LnByb3RvdHlwZQpDLk5tPUouamQucHJvdG90eXBl
+CkMuam49Si5iVS5wcm90b3R5cGUKQy5qTj1KLndlLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBl
+CkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudzcucHJvdG90eXBl
+CkMuTkE9SC5WNi5wcm90b3R5cGUKQy50NT1XLkJILnByb3RvdHlwZQpDLkx0PVcuU04ucHJvdG90eXBl
+CkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJvdG90eXBl
+CkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpDLkd3PW5l
+dyBILkZ1KEguTjAoIkZ1PGM4PiIpKQpDLk80PWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNrKG8pIHsKICB2
+YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4gcy5zdWJzdHJp
+bmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLllxPWZ1bmN0aW9uKCkgewogIHZhciB0b1N0cmluZ0Z1bmN0
+aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWcobykgewogICAg
+dmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJzdHJpbmcoOCwg
+cy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZykgewog
+ICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZhciBuYW1lID0g
+dG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09ICJbb2JqZWN0IE9i
+amVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICB9CiAgfQog
+IGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykgewogICAgaWYg
+KHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHJldHVybiAi
+SFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpOwogIH0KICBm
+dW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAidW5k
+ZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09ICJ1bmRlZmlu
+ZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYg
+KHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBj
+b25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3IodGFnKSB7IHJl
+dHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCI7
+CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzogaXNCcm93c2Vy
+ID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywKICAgIHByb3RvdHlw
+ZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlzY3JpbWluYXRvciB9
+Owp9CkMud2I9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rpb24oaG9va3Mp
+IHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9va3M7CiAgICB2
+YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1bXBSZW5kZXJU
+cmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9tZSIpID49IDAp
+IHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5kb3cg
+PT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAgICAgIH0KICAg
+ICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50IikpIHJldHVybiBo
+b29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07Cn0KQy5LVT1m
+dW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnICE9
+ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhwZXJpbWVudGFs
+Rml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIGdl
+dFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3MucHJvdG90eXBl
+Rm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7
+CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJzaW9uKSByZXR1
+cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9CiAgICByZXR1
+cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsKICAgIGlmICh0
+YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBlRm9yVGFnKHRh
+Zyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3RvdHlwZUZvclRh
+ZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMuZGs9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNl
+ckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQg
+OiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0dXJuIGhvb2tz
 OwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9y
 ZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAg
-ICJIVE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50IjogIkhUTUxF
-bGVtZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiUG9zaXRp
-b24iOiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2YXIgdGFn
-ID0gZ2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAobmV3VGFn
-KSByZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAod2luZG93
-LkRhdGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJEYXRhVmll
-dyI7CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdJRSh0
-YWcpIHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0cnVjdG9y
-ID09IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9
-CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90
-eXBlRm9yVGFnSUU7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7IH0KCkMuQ3Q9
-bmV3IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAuRTMoKQpD
-Lk52PW5ldyBILmtyKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkFkPW5ldyBNLkg3
-KDAsIkhpbnRBY3Rpb25LaW5kLmFkZE51bGxhYmxlSGludCIpCkMubmU9bmV3IE0uSDcoMSwiSGludEFj
-dGlvbktpbmQuYWRkTm9uTnVsbGFibGVIaW50IikKQy5teT1uZXcgTS5INygyLCJIaW50QWN0aW9uS2lu
-ZC5jaGFuZ2VUb051bGxhYmxlSGludCIpCkMucng9bmV3IE0uSDcoMywiSGludEFjdGlvbktpbmQuY2hh
-bmdlVG9Ob25OdWxsYWJsZUhpbnQiKQpDLndWPW5ldyBNLkg3KDQsIkhpbnRBY3Rpb25LaW5kLnJlbW92
-ZU51bGxhYmxlSGludCIpCkMuZlI9bmV3IE0uSDcoNSwiSGludEFjdGlvbktpbmQucmVtb3ZlTm9uTnVs
-bGFibGVIaW50IikKQy5BMz1uZXcgUC5NeChudWxsKQpDLm5YPW5ldyBQLm9qKG51bGwpCkMuYWs9SC5W
-TShzKFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx0LlYpCkMuY209SC5WTShzKFsiKjo6Y2xh
-c3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0Iiwi
-Kjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxs
-Y2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIs
-IkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQi
-LCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJF
-QTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFV
-RElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0
-ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9y
-IiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRP
-Tjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFi
-aW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5W
-QVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpj
-aGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFs
-aWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwi
-Q09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01N
-QU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6
-OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwi
-REVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJ
-RUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJG
-T1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0
-aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6
-bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1Ojph
-bGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6
-d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIi
-LCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0
-aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklN
-Rzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2Vt
-YXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vz
-c2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5Q
-VVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6Omlu
-cHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjpt
-YXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBV
-VDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6
-c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6
-dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJL
-RVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZv
-ciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVl
-IiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJN
-RU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjpt
-aW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9M
-OjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BU
-R1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNl
-bGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxp
-Z24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6
-dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11
-bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNF
-TEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xv
-ciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmci
-LCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0
-aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFs
-aWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNo
-YXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0Iiwi
-VEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0
-aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6
-OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6
-Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJF
-QTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVB
-Ojp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09U
-Ojp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJU
-SDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWln
-aHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6
-OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFE
-Ojp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYi
-LCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIs
-IlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIs
-IlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11
-dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdC5pKQpDLlZDPUguVk0ocyhbMCww
-LDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLm1LPUguVk0ocyhbMCww
-LDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdC5WKQpDLlNxPUguVk0ocyhbIkhFQUQi
-LCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJB
-TUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwi
-TUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx0LmkpCkMuaFU9SC5W
-TShzKFtdKSx0LngpCkMuZG49SC5WTShzKFtdKSxILk4wKCJqZDxMTCo+IikpCkMueEQ9SC5WTShzKFtd
-KSx0LmkpCkMudG89SC5WTShzKFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFd
-KSx0LlYpCkMucms9SC5WTShzKFtDLkFkLEMubmUsQy5teSxDLnJ4LEMud1YsQy5mUl0pLEguTjAoImpk
-PEg3Kj4iKSkKQy5GMz1ILlZNKHMoWzAsMCwyNDU3NiwxMDIzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMx
-XSksdC5WKQpDLmVhPUguVk0ocyhbMCwwLDMyNzU0LDExMjYzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMx
-XSksdC5WKQpDLlpKPUguVk0ocyhbMCwwLDMyNzIyLDEyMjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMx
-XSksdC5WKQpDLldkPUguVk0ocyhbMCwwLDY1NDkwLDEyMjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMx
-XSksdC5WKQpDLlF4PUguVk0ocyhbImJpbmQiLCJpZiIsInJlZiIsInJlcGVhdCIsInN5bnRheCJdKSx0
-LmkpCkMuQkk9SC5WTShzKFsiQTo6aHJlZiIsIkFSRUE6OmhyZWYiLCJCTE9DS1FVT1RFOjpjaXRlIiwi
-Qk9EWTo6YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24iLCJERUw6OmNpdGUiLCJGT1JNOjphY3Rpb24i
-LCJJTUc6OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNpdGUiLCJROjpjaXRlIiwiVklERU86OnBvc3Rl
-ciJdKSx0LmkpCkMuRHg9bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVKix6TTxqOCo+Kj4iKSkK
-Qy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8cVUqLHFVKj4iKSkKQy5pSD1ILlZNKHMoW10p
-LEguTjAoImpkPEdEKj4iKSkKQy5XTz1uZXcgSC5MUCgwLHt9LEMuaUgsSC5OMCgiTFA8R0QqLEA+Iikp
-CkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcg
-TC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMu
-b0U9bmV3IFAuR1koITEpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0Zp
-ZWxkcygpeyQuem09bnVsbAokLnlqPTAKJC5tSj1udWxsCiQuUDQ9bnVsbAokLk5GPW51bGwKJC5UWD1u
-dWxsCiQueDc9bnVsbAokLm53PW51bGwKJC52dj1udWxsCiQuQnY9bnVsbAokLlM2PW51bGwKJC5rOD1u
-dWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPUguVk0oW10sSC5OMCgiamQ8TWg+Iikp
-CiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9yPVAuRmwodC5OLHQuWSkK
-JC5JNj1udWxsCiQuRmY9bnVsbH0pKCk7KGZ1bmN0aW9uIGxhenlJbml0aWFsaXplcnMoKXt2YXIgcz1o
-dW5rSGVscGVycy5sYXp5RmluYWwscj1odW5rSGVscGVycy5sYXp5T2xkCnMoJCwiZmEiLCJ3IixmdW5j
-dGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydENsb3N1cmUiKX0pCnMoJCwiVTIiLCJTbiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2Vp
-dmVyJCJ9fSkpfSkKcygkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRo
-b2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwi
-UjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnMoJCwiZk4iLCJpSSIs
-ZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1
-bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBx
-Lm1lc3NhZ2V9fSgpKX0pCnMoJCwicWkiLCJVTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZv
-aWQgMCkpfSkKcygkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFy
-ICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1l
-bnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwia3EiLCJyTiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnMoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXty
-ZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHEpe3JldHVybiBxLm1l
-c3NhZ2V9fSgpKX0pCnMoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQg
-MCkpfSkKcygkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2
-b2lkIDApLiRtZXRob2QkfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwiV2MiLCJ1
-dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKcygkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVy
-biBuZXcgUC5wZygpLiQwKCl9KQpzKCQsImFYIiwiSEciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmMy
-KCkuJDAoKX0pCnMoJCwiYnQiLCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEludDhBcnJheShILlhG
-KEguVk0oWy0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0x
-LC0yLC0yLC0yLC0yLC0yLDYyLC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYx
-LC0yLC0yLC0yLC0xLC0yLC0yLC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUs
-MTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjks
-MzAsMzEsMzIsMzMsMzQsMzUsMzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDks
-NTAsNTEsLTIsLTIsLTIsLTIsLTJdLHQuYSkpKX0pCnMoJCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1
-cm4gdHlwZW9mIHByb2Nlc3MhPSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNh
-bGwocHJvY2Vzcyk9PSJbb2JqZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0p
-CnMoJCwibWYiLCJ6NCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0q
-JCIpfSkKcygkLCJPUSIsInZaIixmdW5jdGlvbigpe3JldHVybiBQLktOKCl9KQpzKCQsIlNDIiwiQU4i
-LGZ1bmN0aW9uKCl7cmV0dXJuIFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJF
-QSIsIkFSVElDTEUiLCJBU0lERSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVP
-VEUiLCJCUiIsIkJVVFRPTiIsIkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIs
-IkNPTCIsIkNPTEdST1VQIiwiQ09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVU
-QUlMUyIsIkRGTiIsIkRJUiIsIkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElP
-TiIsIkZJR1VSRSIsIkZPTlQiLCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIs
-Ikg2IiwiSEVBREVSIiwiSEdST1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMi
-LCJLQkQiLCJMQUJFTCIsIkxFR0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5B
-ViIsIk5PQlIiLCJPTCIsIk9QVEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dS
-RVNTIiwiUSIsIlMiLCJTQU1QIiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BB
-TiIsIlNUUklLRSIsIlNUUk9ORyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwi
-VEQiLCJURVhUQVJFQSIsIlRGT09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQi
-LCJVIiwiVUwiLCJWQVIiLCJWSURFTyIsIldCUiJdLHQuTil9KQpzKCQsIlg0IiwiaEciLGZ1bmN0aW9u
-KCl7cmV0dXJuIFAubnUoIl5cXFMrJCIpfSkKcygkLCJ3TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQ
-Lk5EKHNlbGYpfSkKcygkLCJrdCIsIlI4IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFy
-dE9iamVjdCIpfSkKcygkLCJmSyIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2Jq
-ZWN0KGEpe3RoaXMubz1hfX0pCnIoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEo
-KX0pCnIoJCwiT2wiLCJVRSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhy
-ZWYpLmdoWSgpLnEoMCwiYXV0aFRva2VuIil9KQpyKCQsImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJu
-IFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQpyKCQsIlc2
-IiwiaEwiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAu
-cGFuZWwtY29udGVudCIpfSkKcigkLCJUUiIsIkRXIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVl
-cnlTZWxlY3RvcigiZm9vdGVyIil9KQpyKCQsIkVZIiwiZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIo
-KS5xdWVyeVNlbGVjdG9yKCJoZWFkZXIiKX0pCnIoJCwiYXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4g
-Vy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1bml0LW5hbWUiKX0pCnIoJCwiZmUiLCJLRyIsZnVuY3Rpb24o
-KXtyZXR1cm4gbmV3IEwuWEEoKX0pCnMoJCwiZW8iLCJuVSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0u
-bEkoJC5IaygpKX0pCnMoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgi
-LyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQpzKCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0
-dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxc
-XFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0o
-PyFbL1xcXFxdKSIpKX0pCnMoJCwiYWsiLCJFYiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5u
-dSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2Et
-ekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4vIikpfSkKcygkLCJscyIsIkhrIixm
-dW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVu
-Y3Rpb24oKXt2YXIgcz1mdW5jdGlvbihhKXt2YXIgbT17fQptW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlz
-KGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3QobSkpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHMoIl9fX2RhcnRfIithK3YuaXNvbGF0ZVRhZyl9CnZhciByPSJfX19kYXJ0
-X2lzb2xhdGVfdGFnc18iCnZhciBxPU9iamVjdFtyXXx8KE9iamVjdFtyXT1PYmplY3QuY3JlYXRlKG51
-bGwpKQp2YXIgcD0iX1p4WXhYIgpmb3IodmFyIG89MDs7bysrKXt2YXIgbj1zKHArIl8iK28rIl8iKQpp
-ZighKG4gaW4gcSkpe3Fbbl09MQp2Lmlzb2xhdGVUYWc9bgpicmVha319di5kaXNwYXRjaFByb3BlcnR5
-TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9y
-VXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmln
-YXRvcjpKLnZCLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRp
-YUVycm9yOkoudkIsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFu
-Z2U6Si52QixTUUxFcnJvcjpKLnZCLERhdGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxv
-YXQzMkFycmF5OkguRGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6
-SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZBcnJheTpILmRULFVpbnQzMkFycmF5OkguUHEsVWludDhD
-bGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxB
-dWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxI
-VE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1l
-bnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERl
-dGFpbHNFbGVtZW50OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFF
-LEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVu
-dDpXLnFFLEhUTUxIZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1s
-RWxlbWVudDpXLnFFLEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhU
-TUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFF
-LEhUTUxMZWdlbmRFbGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6
-Vy5xRSxIVE1MTWVkaWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVt
-ZW50OlcucUUsSFRNTE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0
-RWxlbWVudDpXLnFFLEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFF
-LEhUTUxPcHRpb25FbGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVt
-ZW50OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJv
-Z3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50Olcu
-cUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxl
-bWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFi
-bGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0
-YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVD
-b2xFbGVtZW50OlcucUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFF
-LEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVu
-dDpXLnFFLEhUTUxVbmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGly
-ZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5x
-RSxIVE1MRnJhbWVTZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1l
-bnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNl
-RWxlbWVudDpXLm5CLEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5u
-eCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54
-LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5v
-SixDU1MyUHJvcGVydGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNl
-cHRpb246Vy5OaCxET01JbXBsZW1lbnRhdGlvbjpXLmFlLERPTVJlY3RSZWFkT25seTpXLklCLERPTVRv
-a2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2
-ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2
-ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50
-OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpX
-LmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxv
-YkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xv
-c2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VP
-cmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4
-dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZl
-bnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VF
-dmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtl
-eU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50
-OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5l
-Y3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90
-aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RF
-dmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEs
-UHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVj
-dGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5l
-YSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1Bl
-ZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lW
-aW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVy
-cm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50Olcu
-ZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRp
-b25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxW
-UkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RF
-dmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVh
-LEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEs
-V2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVu
-dDpXLmVhLEV2ZW50VGFyZ2V0OlcuRDAsRmlsZTpXLmhILEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rv
-cnk6Vy5icixIVE1MRG9jdW1lbnQ6Vy5WYixYTUxIdHRwUmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0
-RXZlbnRUYXJnZXQ6Vy53YSxJbWFnZURhdGE6Vy5TZyxMb2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5B
-aixEcmFnRXZlbnQ6Vy5BaixQb2ludGVyRXZlbnQ6Vy5BaixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRG
-cmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9k
-ZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9n
-cmVzc0V2ZW50OlcuZXcsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6
-Vy5scCxIVE1MVGFibGVFbGVtZW50OlcuVGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJs
-ZVNlY3Rpb25FbGVtZW50OlcuV1AsSFRNTFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZl
-bnQ6Vy53NixGb2N1c0V2ZW50OlcudzYsS2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRv
-dWNoRXZlbnQ6Vy53NixVSUV2ZW50OlcudzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNh
-dGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFy
-ZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENs
-aWVudFJlY3Q6Vy53NCxET01SZWN0OlcudzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFw
-OlcucmgsSURCS2V5UmFuZ2U6UC5oRixTVkdTY3JpcHRFbGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5o
-aSxTVkdBbmltYXRlRWxlbWVudDpQLmhpLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuaGksU1ZHQW5p
-bWF0ZVRyYW5zZm9ybUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRpb25FbGVtZW50OlAuaGksU1ZHQ2lyY2xl
-RWxlbWVudDpQLmhpLFNWR0NsaXBQYXRoRWxlbWVudDpQLmhpLFNWR0RlZnNFbGVtZW50OlAuaGksU1ZH
-RGVzY0VsZW1lbnQ6UC5oaSxTVkdEaXNjYXJkRWxlbWVudDpQLmhpLFNWR0VsbGlwc2VFbGVtZW50OlAu
-aGksU1ZHRkVCbGVuZEVsZW1lbnQ6UC5oaSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmhpLFNWR0ZF
-Q29tcG9uZW50VHJhbnNmZXJFbGVtZW50OlAuaGksU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuaGksU1ZH
-RkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6UC5oaSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5o
-aSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6UC5oaSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6
-UC5oaSxTVkdGRUZsb29kRWxlbWVudDpQLmhpLFNWR0ZFRnVuY0FFbGVtZW50OlAuaGksU1ZHRkVGdW5j
-QkVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNHRWxlbWVudDpQLmhpLFNWR0ZFRnVuY1JFbGVtZW50OlAuaGks
-U1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OlAuaGksU1ZHRkVJbWFnZUVsZW1lbnQ6UC5oaSxTVkdGRU1l
-cmdlRWxlbWVudDpQLmhpLFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDpQLmhpLFNWR0ZFTW9ycGhvbG9neUVs
-ZW1lbnQ6UC5oaSxTVkdGRU9mZnNldEVsZW1lbnQ6UC5oaSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAu
-aGksU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDpQLmhpLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQ
-LmhpLFNWR0ZFVGlsZUVsZW1lbnQ6UC5oaSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuaGksU1ZHRmls
-dGVyRWxlbWVudDpQLmhpLFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OlAuaGksU1ZHR0VsZW1lbnQ6UC5o
-aSxTVkdHZW9tZXRyeUVsZW1lbnQ6UC5oaSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5oaSxTVkdJbWFnZUVs
-ZW1lbnQ6UC5oaSxTVkdMaW5lRWxlbWVudDpQLmhpLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmhp
-LFNWR01hcmtlckVsZW1lbnQ6UC5oaSxTVkdNYXNrRWxlbWVudDpQLmhpLFNWR01ldGFkYXRhRWxlbWVu
-dDpQLmhpLFNWR1BhdGhFbGVtZW50OlAuaGksU1ZHUGF0dGVybkVsZW1lbnQ6UC5oaSxTVkdQb2x5Z29u
-RWxlbWVudDpQLmhpLFNWR1BvbHlsaW5lRWxlbWVudDpQLmhpLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVu
-dDpQLmhpLFNWR1JlY3RFbGVtZW50OlAuaGksU1ZHU2V0RWxlbWVudDpQLmhpLFNWR1N0b3BFbGVtZW50
-OlAuaGksU1ZHU3R5bGVFbGVtZW50OlAuaGksU1ZHU1ZHRWxlbWVudDpQLmhpLFNWR1N3aXRjaEVsZW1l
-bnQ6UC5oaSxTVkdTeW1ib2xFbGVtZW50OlAuaGksU1ZHVFNwYW5FbGVtZW50OlAuaGksU1ZHVGV4dENv
-bnRlbnRFbGVtZW50OlAuaGksU1ZHVGV4dEVsZW1lbnQ6UC5oaSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5o
-aSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OlAuaGksU1ZHVGl0bGVFbGVtZW50OlAuaGksU1ZHVXNl
-RWxlbWVudDpQLmhpLFNWR1ZpZXdFbGVtZW50OlAuaGksU1ZHR3JhZGllbnRFbGVtZW50OlAuaGksU1ZH
-Q29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6UC5oaSxTVkdGRURyb3BTaGFkb3dFbGVtZW50
-OlAuaGksU1ZHTVBhdGhFbGVtZW50OlAuaGksU1ZHRWxlbWVudDpQLmhpfSkKaHVua0hlbHBlcnMuc2V0
-T3JVcGRhdGVMZWFmVGFncyh7RE9NRXJyb3I6dHJ1ZSxNZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRy
-dWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRydWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6
-dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBvc2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVl
-LFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFy
-cmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZBcnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJ
-bnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVpbnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVk
-QXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUsVWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9F
-bGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhUTUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENh
-bnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRy
-dWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFMaXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxz
-RWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRydWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1M
-RW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxlbWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1
-ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGluZ0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1l
-bnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhUTUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5w
-dXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVlLEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1M
-TGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVudDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUs
-SFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxlbWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0
-cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9kRWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1l
-bnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhUTUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1M
-T3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVtZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0
-cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQcmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNz
-RWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhU
-TUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVtZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6
-dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2Fw
-dGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxs
-RWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxl
-bWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1M
-VGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVudDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1
-ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlkZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9y
-eUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRN
-TEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVlRWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZh
-bHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFyZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVt
-ZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1lbnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxD
-aGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRl
-eHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUsTVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxD
-U1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0
-aW9uOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9r
-ZW5MaXN0OnRydWUsRWxlbWVudDpmYWxzZSxBYm9ydFBheW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2
-ZW50OnRydWUsQW5pbWF0aW9uUGxheWJhY2tFdmVudDp0cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2
-ZW50OnRydWUsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50
-OnRydWUsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0
-cnVlLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDp0cnVlLEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxv
-YkV2ZW50OnRydWUsQ2FuTWFrZVBheW1lbnRFdmVudDp0cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xv
-c2VFdmVudDp0cnVlLEN1c3RvbUV2ZW50OnRydWUsRGV2aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VP
-cmllbnRhdGlvbkV2ZW50OnRydWUsRXJyb3JFdmVudDp0cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4
-dGVuZGFibGVNZXNzYWdlRXZlbnQ6dHJ1ZSxGZXRjaEV2ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZl
-bnQ6dHJ1ZSxGb3JlaWduRmV0Y2hFdmVudDp0cnVlLEdhbWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VF
-dmVudDp0cnVlLEluc3RhbGxFdmVudDp0cnVlLE1lZGlhRW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtl
-eU1lc3NhZ2VFdmVudDp0cnVlLE1lZGlhUXVlcnlMaXN0RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50
-OnRydWUsTWVkaWFTdHJlYW1UcmFja0V2ZW50OnRydWUsTWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5l
-Y3Rpb25FdmVudDp0cnVlLE1JRElNZXNzYWdlRXZlbnQ6dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90
-aWZpY2F0aW9uRXZlbnQ6dHJ1ZSxQYWdlVHJhbnNpdGlvbkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RF
-dmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUs
-UHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVj
-dGlvbkNsb3NlRXZlbnQ6dHJ1ZSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1
-ZSxSVENEYXRhQ2hhbm5lbEV2ZW50OnRydWUsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1Bl
-ZXJDb25uZWN0aW9uSWNlRXZlbnQ6dHJ1ZSxSVENUcmFja0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lW
-aW9sYXRpb25FdmVudDp0cnVlLFNlbnNvckVycm9yRXZlbnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVy
-cm9yOnRydWUsU3BlZWNoUmVjb2duaXRpb25FdmVudDp0cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRy
-dWUsU3RvcmFnZUV2ZW50OnRydWUsU3luY0V2ZW50OnRydWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRp
-b25FdmVudDp0cnVlLFdlYktpdFRyYW5zaXRpb25FdmVudDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxW
-UkRpc3BsYXlFdmVudDp0cnVlLFZSU2Vzc2lvbkV2ZW50OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RF
-dmVudDp0cnVlLFVTQkNvbm5lY3Rpb25FdmVudDp0cnVlLElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVl
-LEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OnRydWUsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUs
-V2ViR0xDb250ZXh0RXZlbnQ6dHJ1ZSxFdmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2
-ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZhbHNlLEZpbGU6dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxI
-aXN0b3J5OnRydWUsSFRNTERvY3VtZW50OnRydWUsWE1MSHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVx
-dWVzdEV2ZW50VGFyZ2V0OmZhbHNlLEltYWdlRGF0YTp0cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVu
-dDp0cnVlLERyYWdFdmVudDp0cnVlLFBvaW50ZXJFdmVudDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1
-bWVudEZyYWdtZW50OnRydWUsU2hhZG93Um9vdDp0cnVlLERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFs
-c2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05vZGVMaXN0OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1
-ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVs
-ZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRydWUsSFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhU
-TUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRNTFRlbXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0
-aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50OnRydWUsS2V5Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0
-cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2ZW50OmZhbHNlLFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVl
-LERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRy
-dWUsU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxXb3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6
-dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9NUmVjdDp0cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVk
-QXR0ck1hcDp0cnVlLElEQktleVJhbmdlOnRydWUsU1ZHU2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVt
-ZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVl
-LFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OnRydWUsU1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNW
-R0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdDbGlwUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0
-cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUsU1ZHRGlzY2FyZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxl
-bWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVtZW50OnRydWUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1
-ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0
-cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVt
-ZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRF
-bGVtZW50OnRydWUsU1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNW
-R0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZHRkVGdW5jR0VsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVu
-dDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDp0cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUs
-U1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBo
-b2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVPZmZzZXRFbGVtZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxl
-bWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVs
-ZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVtZW50OnRydWUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVl
-LFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVt
-ZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVtZW50OnRydWUsU1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZH
-SW1hZ2VFbGVtZW50OnRydWUsU1ZHTGluZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1l
-bnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50OnRydWUsU1ZHTWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0
-YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxlbWVudDp0cnVlLFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZH
-UG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5bGluZUVsZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVu
-dEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxlbWVudDp0cnVlLFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9w
-RWxlbWVudDp0cnVlLFNWR1N0eWxlRWxlbWVudDp0cnVlLFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0
-Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9sRWxlbWVudDp0cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNW
-R1RleHRDb250ZW50RWxlbWVudDp0cnVlLFNWR1RleHRFbGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVt
-ZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVl
-LFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdWaWV3RWxlbWVudDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0
-cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93
-RWxlbWVudDp0cnVlLFNWR01QYXRoRWxlbWVudDp0cnVlLFNWR0VsZW1lbnQ6ZmFsc2V9KQpILlhILiRu
-YXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NU
-YWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJW
-aWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2
-ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0i
-QXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXci
-fSkoKQpjb252ZXJ0QWxsVG9GYXN0T2JqZWN0KHcpCmNvbnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0
-aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVudD09PSJ1bmRlZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0
-eXBlb2YgZG9jdW1lbnQuY3VycmVudFNjcmlwdCE9J3VuZGVmaW5lZCcpe2EoZG9jdW1lbnQuY3VycmVu
-dFNjcmlwdCkKcmV0dXJufXZhciBzPWRvY3VtZW50LnNjcmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zv
-cih2YXIgcT0wO3E8cy5sZW5ndGg7KytxKXNbcV0ucmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25M
-b2FkLGZhbHNlKQphKGIudGFyZ2V0KX1mb3IodmFyIHI9MDtyPHMubGVuZ3RoOysrcilzW3JdLmFkZEV2
-ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSl9KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3Jp
-cHQ9YQppZih0eXBlb2YgZGFydE1haW5SdW5uZXI9PT0iZnVuY3Rpb24iKWRhcnRNYWluUnVubmVyKEwu
-SXEsW10pCmVsc2UgTC5JcShbXSl9KX0pKCkKLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWlncmF0aW9uLmpz
-Lm1hcAo=
+ICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAiIUxvY2F0aW9u
+IiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJYTUxEb2N1bWVu
+dCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAgIHZhciB0YWcg
+PSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQogIGhvb2tzLmdl
+dFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdl
+bnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIi
+OwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwog
+IHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVu
+bG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJI
+VE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50IjogIkhUTUxFbGVt
+ZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiUG9zaXRpb24i
+OiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2YXIgdGFnID0g
+Z2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAobmV3VGFnKSBy
+ZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAod2luZG93LkRh
+dGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJEYXRhVmlldyI7
+CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdJRSh0YWcp
+IHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0cnVjdG9yID09
+IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAg
+aG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBl
+Rm9yVGFnSUU7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7IH0KCkMuQ3Q9bmV3
+IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAuRTMoKQpDLk52
+PW5ldyBILmtyKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkFkPW5ldyBNLkg3KDAs
+IkhpbnRBY3Rpb25LaW5kLmFkZE51bGxhYmxlSGludCIpCkMubmU9bmV3IE0uSDcoMSwiSGludEFjdGlv
+bktpbmQuYWRkTm9uTnVsbGFibGVIaW50IikKQy5teT1uZXcgTS5INygyLCJIaW50QWN0aW9uS2luZC5j
+aGFuZ2VUb051bGxhYmxlSGludCIpCkMucng9bmV3IE0uSDcoMywiSGludEFjdGlvbktpbmQuY2hhbmdl
+VG9Ob25OdWxsYWJsZUhpbnQiKQpDLndWPW5ldyBNLkg3KDQsIkhpbnRBY3Rpb25LaW5kLnJlbW92ZU51
+bGxhYmxlSGludCIpCkMuZlI9bmV3IE0uSDcoNSwiSGludEFjdGlvbktpbmQucmVtb3ZlTm9uTnVsbGFi
+bGVIaW50IikKQy5BMz1uZXcgUC5NeChudWxsKQpDLm5YPW5ldyBQLm9qKG51bGwpCkMuY3c9bmV3IEwu
+R2IoMCwiVW5pdE1pZ3JhdGlvblN0YXR1cy5hbHJlYWR5TWlncmF0ZWQiKQpDLmRjPW5ldyBMLkdiKDEs
+IlVuaXRNaWdyYXRpb25TdGF0dXMuaW5kZXRlcm1pbmF0ZSIpCkMuV0Q9bmV3IEwuR2IoMiwiVW5pdE1p
+Z3JhdGlvblN0YXR1cy5taWdyYXRpbmciKQpDLlhqPW5ldyBMLkdiKDMsIlVuaXRNaWdyYXRpb25TdGF0
+dXMub3B0aW5nT3V0IikKQy5sMD1ILlZNKHMoW0MuY3csQy5kYyxDLldELEMuWGpdKSxILk4wKCJqZDxH
+Yio+IikpCkMuYWs9SC5WTShzKFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx0LlYpCkMuY209
+SC5WTShzKFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjpp
+ZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6
+bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tl
+eSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5k
+ZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJF
+QTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFS
+RUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3Jv
+dXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsi
+LCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJS
+OjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFt
+ZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFT
+OjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09M
+OjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRo
+IiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNP
+TEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6
+OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjps
+YWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJE
+RUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJE
+TDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIs
+IkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0
+eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0
+YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0
+OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwi
+SFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFN
+RTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZS
+QU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJ
+TUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpu
+YW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0
+IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0
+b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2Fi
+bGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6
+Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5Q
+VVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVx
+dWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6
+OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdF
+Tjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNz
+a2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0
+eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0Iiwi
+TUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6
+Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJP
+TDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6
+OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFi
+ZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVU
+OjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjpt
+aW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJs
+ZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNF
+TEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24i
+LCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJM
+RTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFy
+eSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJv
+ZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpi
+Z2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMi
+LCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZh
+bGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBs
+ZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRt
+b2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVh
+ZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJp
+bmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6
+Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwi
+VEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVh
+ZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJU
+SDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6
+Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFy
+IiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIs
+IlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJ
+REVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdy
+b3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdC5pKQpD
+LlZDPUguVk0ocyhbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpD
+Lm1LPUguVk0ocyhbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdC5WKQpDLlNx
+PUguVk0ocyhbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9V
+UCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklT
+SU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJd
+KSx0LmkpCkMuaFU9SC5WTShzKFtdKSx0LngpCkMuZG49SC5WTShzKFtdKSxILk4wKCJqZDxMTCo+Iikp
+CkMueEQ9SC5WTShzKFtdKSx0LmkpCkMudG89SC5WTShzKFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4
+MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMucms9SC5WTShzKFtDLkFkLEMubmUsQy5teSxDLnJ4LEMud1Ys
+Qy5mUl0pLEguTjAoImpkPEg3Kj4iKSkKQy5GMz1ILlZNKHMoWzAsMCwyNDU3NiwxMDIzLDY1NTM0LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLmVhPUguVk0ocyhbMCwwLDMyNzU0LDExMjYzLDY1NTM0LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlpKPUguVk0ocyhbMCwwLDMyNzIyLDEyMjg3LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLldkPUguVk0ocyhbMCwwLDY1NDkwLDEyMjg3LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlF4PUguVk0ocyhbImJpbmQiLCJpZiIsInJlZiIsInJlcGVh
+dCIsInN5bnRheCJdKSx0LmkpCkMuQkk9SC5WTShzKFsiQTo6aHJlZiIsIkFSRUE6OmhyZWYiLCJCTE9D
+S1FVT1RFOjpjaXRlIiwiQk9EWTo6YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24iLCJERUw6OmNpdGUi
+LCJGT1JNOjphY3Rpb24iLCJJTUc6OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNpdGUiLCJROjpjaXRl
+IiwiVklERU86OnBvc3RlciJdKSx0LmkpCkMuRHg9bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFV
+Kix6TTxqOCo+Kj4iKSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8cVUqLHFVKj4iKSkK
+Qy5pSD1ILlZNKHMoW10pLEguTjAoImpkPEdEKj4iKSkKQy5XTz1uZXcgSC5MUCgwLHt9LEMuaUgsSC5O
+MCgiTFA8R0QqLEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0
+b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcg
+SC53digiY2FsbCIpCkMub0U9bmV3IFAuR1koITEpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1
+bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQuem09bnVsbAokLnlqPTAKJC5tSj1udWxsCiQuUDQ9bnVsbAok
+Lk5GPW51bGwKJC5UWD1udWxsCiQueDc9bnVsbAokLm53PW51bGwKJC52dj1udWxsCiQuQnY9bnVsbAok
+LlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPUguVk0oW10s
+SC5OMCgiamQ8TWg+IikpCiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9y
+PVAuRmwodC5OLHQuWSkKJC5JUj1udWxsCiQuSTY9bnVsbAokLkZmPW51bGx9KSgpOyhmdW5jdGlvbiBs
+YXp5SW5pdGlhbGl6ZXJzKCl7dmFyIHM9aHVua0hlbHBlcnMubGF6eUZpbmFsLHI9aHVua0hlbHBlcnMu
+bGF6eU9sZApzKCQsImZhIiwidyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRDbG9z
+dXJlIil9KQpzKCQsIlUyIiwiU24iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7CnRvU3RyaW5n
+OmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwieHEiLCJscSIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILlM3KHskbWV0aG9kJDpudWxsLAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVy
+biIkcmVjZWl2ZXIkIn19KSl9KQpzKCQsIlIxIiwiTjkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5T
+NyhudWxsKSl9KQpzKCQsImZOIiwiaUkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2
+YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50
+c0V4cHIkKX1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdlfX0oKSl9KQpzKCQsInFpIiwiVU4iLGZ1bmN0
+aW9uKCl7cmV0dXJuIEguY00oSC5TNyh2b2lkIDApKX0pCnMoJCwicloiLCJaaCIsZnVuY3Rpb24oKXty
+ZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7
+KHZvaWQgMCkuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdl
+fX0oKSl9KQpzKCQsImtxIiwick4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5NaihudWxsKSl9KQpz
+KCQsInR0IiwiYzMiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0
+aG9kJH1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdlfX0oKSl9KQpzKCQsImR0IiwiSEsiLGZ1bmN0aW9u
+KCl7cmV0dXJuIEguY00oSC5Naih2b2lkIDApKX0pCnMoJCwiQTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1
+cm4gSC5jTShmdW5jdGlvbigpe3RyeXsodm9pZCAwKS4kbWV0aG9kJH1jYXRjaChxKXtyZXR1cm4gcS5t
+ZXNzYWdlfX0oKSl9KQpzKCQsIldjIiwidXQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuT2ooKX0pCnMoJCwi
+a2giLCJyZiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFAucGcoKS4kMCgpfSkKcygkLCJkSCIsIkhHIixm
+dW5jdGlvbigpe3JldHVybiBuZXcgUC5jMigpLiQwKCl9KQpzKCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBJbnQ4QXJyYXkoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1Miw1
+Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQsNSw2
+LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0yLC0y
+LC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQx
+LDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx0LmEpKSl9KQpzKCQs
+Ik01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYmT2Jq
+ZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSImJnBy
+b2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQpzKCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAu
+bnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnMoJCwiT1EiLCJ2WiIsZnVuY3Rpb24oKXtyZXR1
+cm4gUC5LTigpfSkKcygkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFCQlIi
+LCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIiLCJC
+REkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBUSU9O
+IiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRBIiwi
+REFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRUIiwi
+RU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9STSIs
+IkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIsIklG
+UkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1BUCIs
+Ik1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElPTiIs
+Ik9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJTRUxF
+Q1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1NQVJZ
+IiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhFQUQi
+LCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx0Lk4p
+fSkKcygkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnMoJCwid08i
+LCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5ORChzZWxmKX0pCnMoJCwia3QiLCJSOCIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRPYmplY3QiKX0pCnMoJCwiZksiLCJrSSIsZnVuY3Rpb24o
+KXtyZXR1cm4gZnVuY3Rpb24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQpyKCQsInF0IiwiekIiLGZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBULm1RKCl9KQpyKCQsIk9sIiwiVUUiLGZ1bmN0aW9uKCl7cmV0dXJu
+IFAuaEsoQy5vbC5nbVcoVy54MygpKS5ocmVmKS5naFkoKS5xKDAsImF1dGhUb2tlbiIpfSkKcigkLCJo
+VCIsInlQIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVkaXQtbGlzdCAu
+cGFuZWwtY29udGVudCIpfSkKcigkLCJXNiIsImhMIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVl
+cnlTZWxlY3RvcigiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX0pCnIoJCwiVFIiLCJEVyIsZnVu
+Y3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoImZvb3RlciIpfSkKcigkLCJFWSIsImZp
+IixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQpyKCQsImF2
+IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIil9
+KQpyKCQsInQwIiwiYk4iLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjbWln
+cmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsIil9KQpyKCQsImJBIiwiYzAiLGZ1bmN0aW9uKCl7cmV0
+dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjbWlncmF0ZS11bml0LXN0YXR1cy1pY29uIil9KQpyKCQs
+ImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQpzKCQsImVvIiwiblUiLGZ1bmN0
+aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQpzKCQsInlyIiwiYkQiLGZ1bmN0aW9uKCl7cmV0
+dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkKcygkLCJNayIs
+IktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5udSgiW14vXFxc
+XF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1aXTpbL1xcXFxd
+KSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQpzKCQsImFrIiwiRWIiLGZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8v
+fFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQLm51KCJeLyIp
+KX0pCnMoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhmdW5jdGlvbiBu
+YXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHM9ZnVuY3Rpb24oYSl7dmFyIG09e30KbVthXT0x
+CnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0KG0pKVswXX0K
+di5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiBzKCJfX19kYXJ0XyIrYSt2Lmlzb2xhdGVU
+YWcpfQp2YXIgcj0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcT1PYmplY3Rbcl18fChPYmplY3Rb
+cl09T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHA9Il9aeFl4WCIKZm9yKHZhciBvPTA7O28rKyl7dmFy
+IG49cyhwKyJfIitvKyJfIikKaWYoIShuIGluIHEpKXtxW25dPTEKdi5pc29sYXRlVGFnPW4KYnJlYWt9
+fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9yZWNvcmQiKX0o
+KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJvcjpKLkd2LE1l
+ZGlhRXJyb3I6Si5HdixOYXZpZ2F0b3I6Si5HdixOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6Si5H
+dixOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLkd2LE92ZXJjb25zdHJhaW5lZEVycm9yOkouR3YsUG9z
+aXRpb25FcnJvcjpKLkd2LFJhbmdlOkouR3YsU1FMRXJyb3I6Si5HdixEYXRhVmlldzpILkVULEFycmF5
+QnVmZmVyVmlldzpILkVULEZsb2F0MzJBcnJheTpILkRnLEZsb2F0NjRBcnJheTpILkRnLEludDE2QXJy
+YXk6SC54aixJbnQzMkFycmF5OkguZEUsSW50OEFycmF5OkguWkEsVWludDE2QXJyYXk6SC5kVCxVaW50
+MzJBcnJheTpILlBxLFVpbnQ4Q2xhbXBlZEFycmF5OkguZUUsQ2FudmFzUGl4ZWxBcnJheTpILmVFLFVp
+bnQ4QXJyYXk6SC5WNixIVE1MQXVkaW9FbGVtZW50OlcucUUsSFRNTEJSRWxlbWVudDpXLnFFLEhUTUxC
+dXR0b25FbGVtZW50OlcucUUsSFRNTENhbnZhc0VsZW1lbnQ6Vy5xRSxIVE1MQ29udGVudEVsZW1lbnQ6
+Vy5xRSxIVE1MRExpc3RFbGVtZW50OlcucUUsSFRNTERhdGFFbGVtZW50OlcucUUsSFRNTERhdGFMaXN0
+RWxlbWVudDpXLnFFLEhUTUxEZXRhaWxzRWxlbWVudDpXLnFFLEhUTUxEaWFsb2dFbGVtZW50OlcucUUs
+SFRNTERpdkVsZW1lbnQ6Vy5xRSxIVE1MRW1iZWRFbGVtZW50OlcucUUsSFRNTEZpZWxkU2V0RWxlbWVu
+dDpXLnFFLEhUTUxIUkVsZW1lbnQ6Vy5xRSxIVE1MSGVhZEVsZW1lbnQ6Vy5xRSxIVE1MSGVhZGluZ0Vs
+ZW1lbnQ6Vy5xRSxIVE1MSHRtbEVsZW1lbnQ6Vy5xRSxIVE1MSUZyYW1lRWxlbWVudDpXLnFFLEhUTUxJ
+bWFnZUVsZW1lbnQ6Vy5xRSxIVE1MSW5wdXRFbGVtZW50OlcucUUsSFRNTExJRWxlbWVudDpXLnFFLEhU
+TUxMYWJlbEVsZW1lbnQ6Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5rRWxlbWVudDpX
+LnFFLEhUTUxNYXBFbGVtZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxNZW51RWxlbWVu
+dDpXLnFFLEhUTUxNZXRhRWxlbWVudDpXLnFFLEhUTUxNZXRlckVsZW1lbnQ6Vy5xRSxIVE1MTW9kRWxl
+bWVudDpXLnFFLEhUTUxPTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MT2JqZWN0RWxlbWVudDpXLnFFLEhUTUxP
+cHRHcm91cEVsZW1lbnQ6Vy5xRSxIVE1MT3B0aW9uRWxlbWVudDpXLnFFLEhUTUxPdXRwdXRFbGVtZW50
+OlcucUUsSFRNTFBhcmFtRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVudDpXLnFFLEhUTUxQcmVF
+bGVtZW50OlcucUUsSFRNTFByb2dyZXNzRWxlbWVudDpXLnFFLEhUTUxRdW90ZUVsZW1lbnQ6Vy5xRSxI
+VE1MU2NyaXB0RWxlbWVudDpXLnFFLEhUTUxTaGFkb3dFbGVtZW50OlcucUUsSFRNTFNsb3RFbGVtZW50
+OlcucUUsSFRNTFNvdXJjZUVsZW1lbnQ6Vy5xRSxIVE1MU3BhbkVsZW1lbnQ6Vy5xRSxIVE1MU3R5bGVF
+bGVtZW50OlcucUUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDZWxsRWxlbWVu
+dDpXLnFFLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVt
+ZW50OlcucUUsSFRNTFRhYmxlQ29sRWxlbWVudDpXLnFFLEhUTUxUZXh0QXJlYUVsZW1lbnQ6Vy5xRSxI
+VE1MVGltZUVsZW1lbnQ6Vy5xRSxIVE1MVGl0bGVFbGVtZW50OlcucUUsSFRNTFRyYWNrRWxlbWVudDpX
+LnFFLEhUTUxVTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MVW5rbm93bkVsZW1lbnQ6Vy5xRSxIVE1MVmlkZW9F
+bGVtZW50OlcucUUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6Vy5xRSxIVE1MRm9udEVsZW1lbnQ6Vy5xRSxI
+VE1MRnJhbWVFbGVtZW50OlcucUUsSFRNTEZyYW1lU2V0RWxlbWVudDpXLnFFLEhUTUxNYXJxdWVlRWxl
+bWVudDpXLnFFLEhUTUxFbGVtZW50OlcucUUsSFRNTEFuY2hvckVsZW1lbnQ6Vy5HaCxIVE1MQXJlYUVs
+ZW1lbnQ6Vy5mWSxIVE1MQmFzZUVsZW1lbnQ6Vy5uQixCbG9iOlcuQXosSFRNTEJvZHlFbGVtZW50Olcu
+UVAsQ0RBVEFTZWN0aW9uOlcubngsQ2hhcmFjdGVyRGF0YTpXLm54LENvbW1lbnQ6Vy5ueCxQcm9jZXNz
+aW5nSW5zdHJ1Y3Rpb246Vy5ueCxUZXh0OlcubngsQ1NTU3R5bGVEZWNsYXJhdGlvbjpXLm9KLE1TU3R5
+bGVDU1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixYTUxEb2N1bWVudDpXLlFGLERv
+Y3VtZW50OlcuUUYsRE9NRXhjZXB0aW9uOlcuTmgsRE9NSW1wbGVtZW50YXRpb246Vy5hZSxET01SZWN0
+UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQYXltZW50RXZl
+bnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6Vy5lYSxBcHBs
+aWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6Vy5lYSxC
+YWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpXLmVhLEJhY2tn
+cm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5lYSxCZWZvcmVV
+bmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6Vy5lYSxDbGlw
+Ym9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERldmljZU1vdGlv
+bkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6Vy5lYSxFeHRl
+bmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hFdmVudDpXLmVh
+LEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxHYW1lcGFkRXZl
+bnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRpYUVuY3J5cHRl
+ZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlzdEV2ZW50Olcu
+ZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVhLE1lc3NhZ2VF
+dmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50OlcuZWEsTXV0
+YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRpb25FdmVudDpX
+LmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OlcuZWEs
+UG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDpXLmVh
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVjdGlvbkV2ZW50
+OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RUTUZUb25lQ2hh
+bmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJhY2tFdmVudDpX
+LmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2ZW50OlcuZWEs
+U3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6Vy5lYSxTcGVl
+Y2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpXLmVhLFRyYWNr
+RXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxW
+UkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVudDpXLmVhLE1v
+am9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5lYSxJREJWZXJz
+aW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxpbmVBdWRpb0Nv
+bXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2
+ZW50OlcuZWEsU3VibWl0RXZlbnQ6Vy5lYSxFdmVudFRhcmdldDpXLkQwLEZpbGU6Vy5oSCxIVE1MRm9y
+bUVsZW1lbnQ6Vy5oNCxIaXN0b3J5OlcuYnIsSFRNTERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6
+Vy5mSixYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246
+Vy53NyxNb3VzZUV2ZW50OlcuQWosRHJhZ0V2ZW50OlcuQWosUG9pbnRlckV2ZW50OlcuQWosV2hlZWxF
+dmVudDpXLkFqLERvY3VtZW50RnJhZ21lbnQ6Vy51SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBl
+OlcudUgsTm9kZTpXLnVILE5vZGVMaXN0OlcuQkgsUmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3Jh
+cGhFbGVtZW50OlcuU04sUHJvZ3Jlc3NFdmVudDpXLmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3
+LEhUTUxTZWxlY3RFbGVtZW50OlcubHAsSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0Vs
+ZW1lbnQ6Vy5JdixIVE1MVGFibGVTZWN0aW9uRWxlbWVudDpXLldQLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6
+Vy55WSxDb21wb3NpdGlvbkV2ZW50OlcudzYsRm9jdXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53
+NixUZXh0RXZlbnQ6Vy53NixUb3VjaEV2ZW50OlcudzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERP
+TVdpbmRvdzpXLks1LERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckds
+b2JhbFNjb3BlOlcuQ20sU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29w
+ZTpXLkNtLEF0dHI6Vy5DUSxDbGllbnRSZWN0OlcudzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpX
+LnJoLE1vek5hbWVkQXR0ck1hcDpXLnJoLElEQktleVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQ
+Lm5kLFNWR0FFbGVtZW50OlAuaGksU1ZHQW5pbWF0ZUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlTW90aW9u
+RWxlbWVudDpQLmhpLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OlAuaGksU1ZHQW5pbWF0aW9uRWxl
+bWVudDpQLmhpLFNWR0NpcmNsZUVsZW1lbnQ6UC5oaSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5oaSxTVkdE
+ZWZzRWxlbWVudDpQLmhpLFNWR0Rlc2NFbGVtZW50OlAuaGksU1ZHRGlzY2FyZEVsZW1lbnQ6UC5oaSxT
+VkdFbGxpcHNlRWxlbWVudDpQLmhpLFNWR0ZFQmxlbmRFbGVtZW50OlAuaGksU1ZHRkVDb2xvck1hdHJp
+eEVsZW1lbnQ6UC5oaSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9z
+aXRlRWxlbWVudDpQLmhpLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OlAuaGksU1ZHRkVEaWZmdXNl
+TGlnaHRpbmdFbGVtZW50OlAuaGksU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OlAuaGksU1ZHRkVE
+aXN0YW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVGbG9vZEVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNBRWxl
+bWVudDpQLmhpLFNWR0ZFRnVuY0JFbGVtZW50OlAuaGksU1ZHRkVGdW5jR0VsZW1lbnQ6UC5oaSxTVkdG
+RUZ1bmNSRWxlbWVudDpQLmhpLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDpQLmhpLFNWR0ZFSW1hZ2VF
+bGVtZW50OlAuaGksU1ZHRkVNZXJnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5o
+aSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OlAuaGksU1ZHRkVPZmZzZXRFbGVtZW50OlAuaGksU1ZHRkVQ
+b2ludExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdG
+RVNwb3RMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRVRpbGVFbGVtZW50OlAuaGksU1ZHRkVUdXJidWxlbmNl
+RWxlbWVudDpQLmhpLFNWR0ZpbHRlckVsZW1lbnQ6UC5oaSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQ
+LmhpLFNWR0dFbGVtZW50OlAuaGksU1ZHR2VvbWV0cnlFbGVtZW50OlAuaGksU1ZHR3JhcGhpY3NFbGVt
+ZW50OlAuaGksU1ZHSW1hZ2VFbGVtZW50OlAuaGksU1ZHTGluZUVsZW1lbnQ6UC5oaSxTVkdMaW5lYXJH
+cmFkaWVudEVsZW1lbnQ6UC5oaSxTVkdNYXJrZXJFbGVtZW50OlAuaGksU1ZHTWFza0VsZW1lbnQ6UC5o
+aSxTVkdNZXRhZGF0YUVsZW1lbnQ6UC5oaSxTVkdQYXRoRWxlbWVudDpQLmhpLFNWR1BhdHRlcm5FbGVt
+ZW50OlAuaGksU1ZHUG9seWdvbkVsZW1lbnQ6UC5oaSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5oaSxTVkdS
+YWRpYWxHcmFkaWVudEVsZW1lbnQ6UC5oaSxTVkdSZWN0RWxlbWVudDpQLmhpLFNWR1NldEVsZW1lbnQ6
+UC5oaSxTVkdTdG9wRWxlbWVudDpQLmhpLFNWR1N0eWxlRWxlbWVudDpQLmhpLFNWR1NWR0VsZW1lbnQ6
+UC5oaSxTVkdTd2l0Y2hFbGVtZW50OlAuaGksU1ZHU3ltYm9sRWxlbWVudDpQLmhpLFNWR1RTcGFuRWxl
+bWVudDpQLmhpLFNWR1RleHRDb250ZW50RWxlbWVudDpQLmhpLFNWR1RleHRFbGVtZW50OlAuaGksU1ZH
+VGV4dFBhdGhFbGVtZW50OlAuaGksU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDpQLmhpLFNWR1RpdGxl
+RWxlbWVudDpQLmhpLFNWR1VzZUVsZW1lbnQ6UC5oaSxTVkdWaWV3RWxlbWVudDpQLmhpLFNWR0dyYWRp
+ZW50RWxlbWVudDpQLmhpLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuaGksU1ZH
+RkVEcm9wU2hhZG93RWxlbWVudDpQLmhpLFNWR01QYXRoRWxlbWVudDpQLmhpLFNWR0VsZW1lbnQ6UC5o
+aX0pCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlTGVhZlRhZ3Moe0RPTUVycm9yOnRydWUsTWVkaWFFcnJv
+cjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTp0cnVlLE5hdmln
+YXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6dHJ1ZSxQb3NpdGlvbkVy
+cm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRydWUsQXJyYXlCdWZmZXJW
+aWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVlLEludDE2QXJyYXk6dHJ1
+ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6dHJ1ZSxVaW50MzJBcnJh
+eTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJheTp0cnVlLFVpbnQ4QXJy
+YXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9u
+RWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRlbnRFbGVtZW50OnRydWUs
+SFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhUTUxEYXRhTGlzdEVsZW1l
+bnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxlbWVudDp0cnVlLEhUTUxE
+aXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVsZFNldEVsZW1lbnQ6dHJ1
+ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRNTEhlYWRpbmdFbGVtZW50
+OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VF
+bGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1lbnQ6dHJ1ZSxIVE1MTGFi
+ZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxI
+VE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1
+ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUsSFRNTE1vZEVsZW1lbnQ6
+dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0R3Jv
+dXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0cHV0RWxlbWVudDp0cnVl
+LEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxlbWVu
+dDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVtZW50OnRydWUsSFRNTFNj
+cmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxTbG90RWxlbWVudDp0cnVl
+LEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUsSFRNTFN0eWxlRWxlbWVu
+dDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1
+ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDp0
+cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVtZW50OnRydWUsSFRNTFRp
+bWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFja0VsZW1lbnQ6dHJ1ZSxI
+VE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUsSFRNTFZpZGVvRWxlbWVu
+dDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVtZW50OnRydWUsSFRNTEZy
+YW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1MTWFycXVlZUVsZW1lbnQ6
+dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVlLEhUTUxBcmVhRWxlbWVu
+dDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJvZHlFbGVtZW50OnRydWUs
+Q0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6dHJ1ZSxQcm9jZXNzaW5n
+SW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlvbjp0cnVlLE1TU3R5bGVD
+U1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1bWVudDp0cnVlLERvY3Vt
+ZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTUltcGxlbWVudGF0aW9uOnRydWUsRE9NUmVjdFJl
+YWRPbmx5OmZhbHNlLERPTVRva2VuTGlzdDp0cnVlLEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZl
+bnQ6dHJ1ZSxBbmltYXRpb25FdmVudDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBs
+aWNhdGlvbkNhY2hlRXJyb3JFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxC
+YWNrZ3JvdW5kRmV0Y2hFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tn
+cm91bmRGZXRjaGVkRXZlbnQ6dHJ1ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVV
+bmxvYWRFdmVudDp0cnVlLEJsb2JFdmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlw
+Ym9hcmRFdmVudDp0cnVlLENsb3NlRXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlv
+bkV2ZW50OnRydWUsRGV2aWNlT3JpZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRl
+bmRhYmxlRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVl
+LEZvbnRGYWNlU2V0TG9hZEV2ZW50OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZl
+bnQ6dHJ1ZSxIYXNoQ2hhbmdlRXZlbnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRl
+ZEV2ZW50OnRydWUsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRy
+dWUsTWVkaWFTdHJlYW1FdmVudDp0cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VF
+dmVudDp0cnVlLE1JRElDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0
+YXRpb25FdmVudDp0cnVlLE5vdGlmaWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0
+cnVlLFBheW1lbnRSZXF1ZXN0RXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUs
+UG9wU3RhdGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVl
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50
+OnRydWUsUHVzaEV2ZW50OnRydWUsUlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hh
+bmdlRXZlbnQ6dHJ1ZSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0
+cnVlLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUs
+U3BlZWNoUmVjb2duaXRpb25FcnJvcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVl
+Y2hTeW50aGVzaXNFdmVudDp0cnVlLFN0b3JhZ2VFdmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNr
+RXZlbnQ6dHJ1ZSxUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxW
+UkRldmljZUV2ZW50OnRydWUsVlJEaXNwbGF5RXZlbnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1v
+am9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6dHJ1ZSxVU0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJz
+aW9uQ2hhbmdlRXZlbnQ6dHJ1ZSxBdWRpb1Byb2Nlc3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0Nv
+bXBsZXRpb25FdmVudDp0cnVlLFdlYkdMQ29udGV4dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRF
+dmVudDpmYWxzZSxTdWJtaXRFdmVudDpmYWxzZSxFdmVudFRhcmdldDpmYWxzZSxGaWxlOnRydWUsSFRN
+TEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhUTUxEb2N1bWVudDp0cnVlLFhNTEh0dHBSZXF1
+ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpmYWxzZSxJbWFnZURhdGE6dHJ1ZSxMb2Nh
+dGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZlbnQ6dHJ1ZSxQb2ludGVyRXZlbnQ6dHJ1ZSxX
+aGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0cnVlLFNoYWRvd1Jvb3Q6dHJ1ZSxEb2N1bWVu
+dFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRydWUsUmFkaW9Ob2RlTGlzdDp0cnVlLEhUTUxQ
+YXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVudDp0cnVlLFJlc291cmNlUHJvZ3Jlc3NFdmVu
+dDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRNTFRhYmxlRWxlbWVudDp0cnVlLEhUTUxUYWJs
+ZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9uRWxlbWVudDp0cnVlLEhUTUxUZW1wbGF0ZUVs
+ZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUsRm9jdXNFdmVudDp0cnVlLEtleWJvYXJkRXZl
+bnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50OnRydWUsVUlFdmVudDpmYWxzZSxXaW5kb3c6
+dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNlcnZpY2VX
+b3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUsV29ya2VyR2xv
+YmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVjdDp0cnVlLERPTVJlY3Q6dHJ1ZSxOYW1lZE5v
+ZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJREJLZXlSYW5nZTp0cnVlLFNWR1NjcmlwdEVs
+ZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVFbGVtZW50OnRydWUsU1ZHQW5pbWF0
+ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDp0cnVlLFNWR0FuaW1h
+dGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50OnRydWUsU1ZHQ2xpcFBhdGhFbGVtZW50OnRy
+dWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxlbWVudDp0cnVlLFNWR0Rpc2NhcmRFbGVtZW50
+OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdGRUJsZW5kRWxlbWVudDp0cnVlLFNWR0ZFQ29s
+b3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6dHJ1ZSxTVkdG
+RUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZF
+RGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDp0cnVl
+LFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFRmxvb2RFbGVtZW50OnRydWUsU1ZHRkVG
+dW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0dFbGVtZW50OnRy
+dWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6dHJ1ZSxTVkdG
+RUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZU5vZGVFbGVt
+ZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0cnVlLFNWR0ZFT2Zmc2V0RWxlbWVudDp0cnVl
+LFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OnRy
+dWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVUaWxlRWxlbWVudDp0cnVlLFNWR0ZFVHVy
+YnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVtZW50OnRydWUsU1ZHRm9yZWlnbk9iamVjdEVs
+ZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dlb21ldHJ5RWxlbWVudDp0cnVlLFNWR0dyYXBo
+aWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0cnVlLFNWR0xpbmVFbGVtZW50OnRydWUsU1ZH
+TGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFya2VyRWxlbWVudDp0cnVlLFNWR01hc2tFbGVt
+ZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUsU1ZHUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdQYXR0
+ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50OnRydWUsU1ZHUG9seWxpbmVFbGVtZW50OnRy
+dWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHUmVjdEVsZW1lbnQ6dHJ1ZSxTVkdTZXRF
+bGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxTVkdTdHlsZUVsZW1lbnQ6dHJ1ZSxTVkdTVkdF
+bGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVlLFNWR1N5bWJvbEVsZW1lbnQ6dHJ1ZSxTVkdU
+U3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0RWxlbWVudDp0
+cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6dHJ1ZSxT
+VkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50OnRydWUsU1ZHVmlld0VsZW1lbnQ6dHJ1ZSxT
+VkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDp0
+cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxTVkdNUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdFbGVt
+ZW50OmZhbHNlfSkKSC5MWi4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlJH
+LiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguVlAuJG5hdGl2ZVN1cGVyY2xh
+c3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZm
+ZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguWkcuJG5h
+dGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5QZy4kbmF0aXZlU3VwZXJjbGFzc1Rh
+Zz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFsbFRvRmFzdE9iamVjdCh3KQpjb252ZXJ0VG9G
+YXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBlb2YgZG9jdW1lbnQ9PT0idW5kZWZpbmVkIil7
+YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50LmN1cnJlbnRTY3JpcHQhPSd1bmRlZmluZWQn
+KXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVybn12YXIgcz1kb2N1bWVudC5zY3JpcHRzCmZ1
+bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHE9MDtxPHMubGVuZ3RoOysrcSlzW3FdLnJlbW92ZUV2ZW50
+TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShiLnRhcmdldCl9Zm9yKHZhciByPTA7cjxzLmxl
+bmd0aDsrK3Ipc1tyXS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFsc2UpfSkoZnVuY3Rp
+b24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9mIGRhcnRNYWluUnVubmVyPT09ImZ1bmN0aW9u
+IilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwuSXEoW10pfSl9KSgpCi8vIyBzb3VyY2VNYXBw
+aW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
 ''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/unit_link.dart b/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
index c5becbf..c345775 100644
--- a/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+
 /// Information about a link to a compilation unit.
 class UnitLink {
   final String fullPath;
@@ -13,7 +15,14 @@
   /// A compilation unit in the root has a depth of 0.
   final int depth;
 
-  UnitLink(this.fullPath, this.pathParts, this.editCount)
+  /// Whether this compilation unit was explicitly opted out of null safety at
+  /// the start of this migration.
+  final bool wasExplicitlyOptedOut;
+
+  UnitMigrationStatus migrationStatus;
+
+  UnitLink(this.fullPath, this.pathParts, this.editCount,
+      this.wasExplicitlyOptedOut, this.migrationStatus)
       : depth = pathParts.length - 1;
 
   String get fileName => pathParts.last;
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index ec45fbb..e98bbea 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -72,6 +72,20 @@
 
     document.querySelector('.popup-pane .close').onClick.listen(
         (_) => document.querySelector('.popup-pane').style.display = 'none');
+
+    migrateUnitStatusIcon.onClick.listen((MouseEvent event) {
+      var unitPath = unitName.innerText;
+      var unitNavItem = document
+          .querySelector('.nav-panel [data-name*="$unitPath"]')
+          .parentNode as Element;
+      var statusIcon = unitNavItem.querySelector('.status-icon');
+      var entity = navigationTree.find(unitPath);
+      if (entity is NavigationTreeFileNode) {
+        toggleFileMigrationStatus(entity);
+        updateIconsForNode(statusIcon, entity);
+        updateParentIcons(unitNavItem, entity);
+      }
+    });
   });
 
   window.addEventListener('popstate', (event) {
@@ -109,10 +123,18 @@
 
 final Element unitName = document.querySelector('#unit-name');
 
+final Element migrateUnitStatusIconLabel =
+    document.querySelector('#migrate-unit-status-icon-label');
+
+final Element migrateUnitStatusIcon =
+    document.querySelector('#migrate-unit-status-icon');
+
 String get rootPath => querySelector('.root').text.trim();
 
 String get sdkVersion => document.getElementById('sdk-version').text;
 
+/*late final*/ List<NavigationTreeNode> navigationTree;
+
 void addArrowClickHandler(Element arrow) {
   var childList = (arrow.parentNode as Element).querySelector(':scope > ul');
   // Animating height from "auto" to "0" is not supported by CSS [1], so all we
@@ -163,6 +185,13 @@
   });
 }
 
+/// Creates an icon using a `<span>` element and the Material Icons font.
+Element createIcon([String name = '']) {
+  return document.createElement('span')
+    ..classes.add('material-icons')
+    ..innerText = name;
+}
+
 /// Perform a GET request on the path, return the json decoded response.
 ///
 /// Returns a T so that the various json objects can be requested (lists, maps,
@@ -423,7 +452,9 @@
     final response = await doGet<List<Object>>(path);
     var navTree = document.querySelector('.nav-tree');
     navTree.innerHtml = '';
-    writeNavigationSubtree(navTree, NavigationTreeNode.listFromJson(response));
+    navigationTree = NavigationTreeNode.listFromJson(response);
+    writeNavigationSubtree(navTree, navigationTree,
+        enablePartialMigration: false);
   } catch (e, st) {
     handleError('Could not load navigation tree', e, st);
   }
@@ -659,6 +690,89 @@
   }
 }
 
+void toggleDirectoryMigrationStatus(NavigationTreeDirectoryNode entity) {
+  switch (entity.migrationStatus) {
+    case UnitMigrationStatus.alreadyMigrated:
+      // This tree cannot be toggled.
+      break;
+    case UnitMigrationStatus.migrating:
+      // At least one child file is 'migrating' (some may be 'already
+      // migrated'). Toggle all 'migrating' children to opt out.
+      entity.toggleChildrenToOptOut();
+      break;
+    case UnitMigrationStatus.optingOut:
+      // At least one child file is 'opting out' (some may be 'already
+      // migrated'). Toggle all 'migrating' children to migrate.
+      entity.toggleChildrenToMigrate();
+      break;
+    case UnitMigrationStatus.indeterminate:
+      // At least one child file is 'migrating' and at least one child file is
+      // 'opting out' (some may be 'already migrated'). Toggle all 'migrating'
+      // children to migrate.
+      entity.toggleChildrenToMigrate();
+  }
+}
+
+void toggleFileMigrationStatus(NavigationTreeFileNode entity) {
+  switch (entity.migrationStatus) {
+    case UnitMigrationStatus.alreadyMigrated:
+      // This file cannot be toggled.
+      break;
+    case UnitMigrationStatus.migrating:
+      entity.migrationStatus = UnitMigrationStatus.optingOut;
+      break;
+    case UnitMigrationStatus.optingOut:
+      entity.migrationStatus = UnitMigrationStatus.migrating;
+      break;
+    case UnitMigrationStatus.indeterminate:
+      throw StateError('File ${entity.path} should not have '
+          'indeterminate migration status');
+  }
+}
+
+/// Updates the navigation [icon] and current file icon according to the current
+/// migration status of [entity].
+void updateIconsForNode(Element icon, NavigationTreeNode entity) {
+  updateIconForStatus(icon, entity.migrationStatus);
+  // Update the status at the top of the file view if [entity] represents the
+  // current file.
+  var unitPath = unitName.innerText;
+  if (entity.path == unitPath) {
+    updateIconForStatus(migrateUnitStatusIcon, entity.migrationStatus);
+  }
+}
+
+/// Updates [icon] according to [status].
+void updateIconForStatus(Element icon, UnitMigrationStatus status) {
+  switch (status) {
+    case UnitMigrationStatus.alreadyMigrated:
+      icon.innerText = 'check_box';
+      icon.classes.add('already-migrated');
+      icon.setAttribute('title', 'Already migrated');
+      break;
+    case UnitMigrationStatus.migrating:
+      icon.innerText = 'check_box';
+      icon.classes.remove('opted-out');
+      icon.classes.add('migrating');
+      icon.setAttribute('title', 'Migrating to null safety');
+      break;
+    case UnitMigrationStatus.optingOut:
+      icon.innerText = 'check_box_outline_blank';
+      icon.classes.remove('migrating');
+      icon.classes.add('opted-out');
+      icon.setAttribute('title', 'Opting out of null safety');
+      break;
+    default:
+      icon.innerText = 'indeterminate_check_box';
+      icon.classes.remove('migrating');
+      // 'opted-out' is the same style as 'indeterminate'.
+      icon.classes.add('opted-out');
+      icon.setAttribute(
+          'title', "Mixed statuses of 'migrating' and 'opting out'");
+      break;
+  }
+}
+
 /// Update the heading and navigation links.
 ///
 /// Call this after updating page content on a navigation.
@@ -675,6 +789,35 @@
       link.classes.remove('selected-file');
     }
   });
+  migrateUnitStatusIconLabel.classes.add('visible');
+}
+
+/// Updates the parent icons of [entity] with list item [element] in the
+/// navigation tree.
+void updateParentIcons(Element element, NavigationTreeNode entity) {
+  var parent = entity.parent;
+  if (parent != null) {
+    var parentElement = (element.parentNode as Element).parentNode as Element;
+    var statusIcon = parentElement.querySelector(':scope > .status-icon');
+    updateIconsForNode(statusIcon, parent);
+    updateParentIcons(parentElement, parent);
+  }
+}
+
+/// Updates subtree icons for the children [entity] with list item [element].
+void updateSubtreeIcons(Element element, NavigationTreeDirectoryNode entity) {
+  for (var child in entity.subtree) {
+    var childNode = element.querySelector('[data-name*="${child.path}"]');
+    if (child is NavigationTreeDirectoryNode) {
+      updateSubtreeIcons(childNode, child);
+      var childIcon = childNode.querySelector(':scope > .status-icon');
+      updateIconsForNode(childIcon, entity);
+    } else {
+      var childIcon = (childNode.parentNode as Element)
+          .querySelector(':scope > .status-icon');
+      updateIconsForNode(childIcon, child);
+    }
+  }
 }
 
 /// Load data from [data] into the .code and the .regions divs.
@@ -686,32 +829,60 @@
   _PermissiveNodeValidator.setInnerHtml(codeElement, data.navigationContent);
   populateProposedEdits(path, data.edits, clearEditDetails);
 
-  highlightAllCode();
+  // highlightAllCode is remarkably slow (about 4 seconds to handle a 300k file
+  // on a Pixelbook), so skip it for large files.
+  if (data.sourceCode.length < 200000) {
+    highlightAllCode();
+  }
   addClickHandlers('.code', true);
   addClickHandlers('.regions', true);
 }
 
 void writeNavigationSubtree(
-    Element parentElement, List<NavigationTreeNode> tree) {
+    Element parentElement, List<NavigationTreeNode> tree,
+    {bool enablePartialMigration = false}) {
   Element ul = document.createElement('ul');
   parentElement.append(ul);
   for (var entity in tree) {
     Element li = document.createElement('li');
     ul.append(li);
-    if (entity.type == NavigationTreeNodeType.directory) {
+    if (entity is NavigationTreeDirectoryNode) {
       li.classes.add('dir');
+      li.dataset['name'] = entity.path;
       Element arrow = document.createElement('span');
       li.append(arrow);
       arrow.classes.add('arrow');
       arrow.innerHtml = '&#x25BC;';
-      Element icon = document.createElement('span');
-      li.append(icon);
-      icon.innerHtml = '<span class="material-icons">folder_open</span>';
+      var folderIcon = createIcon('folder_open');
+      li.append(folderIcon);
       li.append(Text(entity.name));
-      writeNavigationSubtree(li, entity.subtree);
+      writeNavigationSubtree(li, entity.subtree,
+          enablePartialMigration: enablePartialMigration);
+      if (enablePartialMigration) {
+        var statusIcon = createIcon('indeterminate_check_box')
+          ..classes.add('status-icon');
+        updateIconsForNode(statusIcon, entity);
+        statusIcon.onClick.listen((MouseEvent event) {
+          toggleDirectoryMigrationStatus(entity);
+          updateSubtreeIcons(li, entity);
+          updateIconsForNode(statusIcon, entity);
+          updateParentIcons(li, entity);
+        });
+        li.insertBefore(statusIcon, folderIcon);
+      }
       addArrowClickHandler(arrow);
-    } else {
-      li.innerHtml = '<span class="material-icons">insert_drive_file</span>';
+    } else if (entity is NavigationTreeFileNode) {
+      if (enablePartialMigration) {
+        var statusIcon = createIcon()..classes.add('status-icon');
+        updateIconsForNode(statusIcon, entity);
+        statusIcon.onClick.listen((MouseEvent event) {
+          toggleFileMigrationStatus(entity);
+          updateIconsForNode(statusIcon, entity);
+          updateParentIcons(li, entity);
+        });
+        li.append(statusIcon);
+      }
+      li.append(createIcon('insert_drive_file'));
       Element a = document.createElement('a');
       li.append(a);
       a.classes.add('nav-link');
@@ -725,7 +896,7 @@
         li.append(editsBadge);
         editsBadge.classes.add('edit-count');
         editsBadge.setAttribute(
-            'title', '$editCount ${pluralize(editCount, 'edit')}');
+            'title', '$editCount ${pluralize(editCount, 'proposed edit')}');
         editsBadge.append(Text(editCount.toString()));
       }
     }
@@ -857,3 +1028,19 @@
     }
   }
 }
+
+extension on List<NavigationTreeNode> {
+  /// Finds the node with path equal to [path], recursively, or `null`.
+  NavigationTreeNode find(String path) {
+    for (var node in this) {
+      if (node is NavigationTreeDirectoryNode) {
+        var foundInSubtree = node.subtree.find(path);
+        if (foundInSubtree != null) return foundInSubtree;
+      } else {
+        assert(node is NavigationTreeFileNode);
+        if (node.path == path) return node;
+      }
+    }
+    return null;
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart b/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
index de29189..ca96d0b 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/navigation_tree.dart
@@ -4,21 +4,107 @@
 
 import 'package:meta/meta.dart';
 
-/// Information about a node in the migration tool's navigation tree.
-class NavigationTreeNode {
-  /// Type of the node.
-  final NavigationTreeNodeType type;
-
-  /// Name of the node.
-  final String name;
-
+class NavigationTreeDirectoryNode extends NavigationTreeNode {
   /// If this is a directory node, list of nodes nested under this one.
   /// Otherwise `null`.
   final List<NavigationTreeNode> subtree;
 
-  /// If this is a file node, full path to the file.  Otherwise `null`.
-  final String path;
+  /// Creates a navigation tree node representing a directory.
+  NavigationTreeDirectoryNode(
+      {@required String name, @required String path, @required this.subtree})
+      : super._(name: name, path: path);
 
+  /// Returns the status by examining [subtree]:
+  ///
+  /// * If all children nodes have the same status, then that status is returned.
+  /// * Otherwise, if all children nodes are either 'alreadyMigrated' or
+  ///   'migrating', then [UnitMigrationStatus.migrating] is returned.
+  /// * Otherwise, if all children nodes are either 'alreadyMigrated' or
+  ///   'opting out', then [UnitMigrationStatus.optingOut] is returned.
+  /// * Otherwise, [UnitMigrationStatus.indeterminate] is returned.
+  UnitMigrationStatus get migrationStatus {
+    if (subtree.isEmpty) return UnitMigrationStatus.alreadyMigrated;
+    var sharedStatus = subtree.first.migrationStatus;
+    var allAreMigratedOrMigrating = true;
+    var allAreMigratedOrOptingOut = true;
+    for (var child in subtree) {
+      var childMigrationStatus = child.migrationStatus;
+
+      if (childMigrationStatus != sharedStatus) {
+        sharedStatus = null;
+      }
+      if (childMigrationStatus != UnitMigrationStatus.alreadyMigrated &&
+          childMigrationStatus != UnitMigrationStatus.migrating) {
+        allAreMigratedOrMigrating = false;
+      }
+      if (childMigrationStatus != UnitMigrationStatus.alreadyMigrated &&
+          childMigrationStatus != UnitMigrationStatus.optingOut) {
+        allAreMigratedOrOptingOut = false;
+      }
+    }
+    if (sharedStatus != null) {
+      return sharedStatus;
+    }
+    if (allAreMigratedOrMigrating) {
+      return UnitMigrationStatus.migrating;
+    }
+    if (allAreMigratedOrOptingOut) {
+      // TODO(srawlins): Is this confusing? Should there be an 'optingOutStar'
+      // which indicates that all opted out files will remain opted out, though
+      // some files exist in the subtree which are already migrated.
+      return UnitMigrationStatus.optingOut;
+    }
+    return UnitMigrationStatus.indeterminate;
+  }
+
+  NavigationTreeNodeType get type => NavigationTreeNodeType.directory;
+
+  void setSubtreeParents() {
+    if (subtree != null) {
+      for (var child in subtree) {
+        child.parent = this;
+      }
+    }
+  }
+
+  /// Toggle child nodes (recursively) to migrate to null safety.
+  ///
+  /// Only child nodes with 'opting out' or 'keep opted out' status are changed.
+  void toggleChildrenToMigrate() {
+    //assert(type == NavigationTreeNodeType.directory);
+    for (var child in subtree) {
+      if (child is NavigationTreeDirectoryNode) {
+        child.toggleChildrenToMigrate();
+      } else if (child is NavigationTreeFileNode &&
+          child.migrationStatus == UnitMigrationStatus.optingOut) {
+        child.migrationStatus = UnitMigrationStatus.migrating;
+      }
+    }
+  }
+
+  /// Toggle child nodes (recursively) to opt out of null safety.
+  ///
+  /// Only child nodes with 'migrating' status are changed.
+  void toggleChildrenToOptOut() {
+    for (var child in subtree) {
+      if (child is NavigationTreeDirectoryNode) {
+        child.toggleChildrenToOptOut();
+      } else if (child is NavigationTreeFileNode &&
+          child.migrationStatus == UnitMigrationStatus.migrating) {
+        child.migrationStatus = UnitMigrationStatus.optingOut;
+      }
+    }
+  }
+
+  Map<String, Object> toJson() => {
+        'type': 'directory',
+        'name': name,
+        'subtree': NavigationTreeNode.listToJson(subtree),
+        if (path != null) 'path': path,
+      };
+}
+
+class NavigationTreeFileNode extends NavigationTreeNode {
   /// If this is a file node, href that should be used if the file is clicked
   /// on, otherwise `null`.
   final String href;
@@ -27,38 +113,73 @@
   /// otherwise `null`.
   final int editCount;
 
-  /// Creates a navigation tree node representing a directory.
-  NavigationTreeNode.directory({@required this.name, @required this.subtree})
-      : type = NavigationTreeNodeType.directory,
-        path = null,
-        href = null,
-        editCount = null;
+  final bool wasExplicitlyOptedOut;
+
+  UnitMigrationStatus migrationStatus;
 
   /// Creates a navigation tree node representing a file.
-  NavigationTreeNode.file(
-      {@required this.name,
-      @required this.path,
+  NavigationTreeFileNode(
+      {@required String name,
+      @required String path,
       @required this.href,
-      @required this.editCount})
-      : type = NavigationTreeNodeType.file,
-        subtree = null;
+      @required this.editCount,
+      @required this.wasExplicitlyOptedOut,
+      @required this.migrationStatus})
+      : super._(name: name, path: path);
 
-  NavigationTreeNode.fromJson(dynamic json)
-      : type = _decodeType(json['type'] as String),
-        name = json['name'] as String,
-        subtree = listFromJsonOrNull(json['subtree']),
-        path = json['path'] as String,
-        href = json['href'] as String,
-        editCount = json['editCount'] as int;
+  NavigationTreeNodeType get type => NavigationTreeNodeType.file;
 
   Map<String, Object> toJson() => {
-        'type': _encodeType(type),
+        'type': 'file',
         'name': name,
-        if (subtree != null) 'subtree': listToJson(subtree),
         if (path != null) 'path': path,
         if (href != null) 'href': href,
-        if (editCount != null) 'editCount': editCount
+        if (editCount != null) 'editCount': editCount,
+        if (wasExplicitlyOptedOut != null)
+          'wasExplicitlyOptedOut': wasExplicitlyOptedOut,
+        if (migrationStatus != null) 'migrationStatus': migrationStatus.index,
       };
+}
+
+/// Information about a node in the migration tool's navigation tree.
+abstract class NavigationTreeNode {
+  /// Name of the node.
+  final String name;
+
+  /// Parent of this node, or `null` if this is a top-level node.
+  /*late final*/ NavigationTreeNode parent;
+
+  /// Relative path to the file or directory from the package root.
+  final String path;
+
+  factory NavigationTreeNode.fromJson(dynamic json) {
+    var type = _decodeType(json['type'] as String);
+    if (type == NavigationTreeNodeType.directory) {
+      return NavigationTreeDirectoryNode(
+          name: json['name'] as String,
+          path: json['path'] as String,
+          subtree: listFromJsonOrNull(json['subtree']))
+        ..setSubtreeParents();
+    } else {
+      return NavigationTreeFileNode(
+          name: json['name'] as String,
+          path: json['path'] as String,
+          href: json['href'] as String,
+          editCount: json['editCount'] as int,
+          wasExplicitlyOptedOut: json['wasExplicitlyOptedOut'] as bool,
+          migrationStatus:
+              _decodeMigrationStatus(json['migrationStatus'] as int));
+    }
+  }
+
+  NavigationTreeNode._({@required this.name, @required this.path});
+
+  /// The migration status of the file or directory.
+  UnitMigrationStatus get migrationStatus;
+
+  NavigationTreeNodeType get type;
+
+  Map<String, Object> toJson();
 
   /// Deserializes a list of navigation tree nodes from a JSON list.
   static List<NavigationTreeNode> listFromJson(dynamic json) =>
@@ -73,6 +194,11 @@
   static List<Map<String, Object>> listToJson(List<NavigationTreeNode> nodes) =>
       [for (var node in nodes) node.toJson()];
 
+  static UnitMigrationStatus _decodeMigrationStatus(int migrationStatus) {
+    if (migrationStatus == null) return null;
+    return UnitMigrationStatus.values[migrationStatus];
+  }
+
   static NavigationTreeNodeType _decodeType(String json) {
     switch (json) {
       case 'directory':
@@ -83,16 +209,6 @@
         throw StateError('Unrecognized navigation tree node type: $json');
     }
   }
-
-  static String _encodeType(NavigationTreeNodeType type) {
-    switch (type) {
-      case NavigationTreeNodeType.directory:
-        return 'directory';
-      case NavigationTreeNodeType.file:
-        return 'file';
-    }
-    throw StateError('Unrecognized navigation tree node type: $type');
-  }
 }
 
 /// Enum representing the different types of [NavigationTreeNode]s.
@@ -100,3 +216,27 @@
   directory,
   file,
 }
+
+/// Enum representing the different statuses a compilation unit can have.
+enum UnitMigrationStatus {
+  /// Indicates that a library was already migrated to null safety at the start
+  /// of the current migration.
+  alreadyMigrated,
+
+  /// Indicates that a directory's status is indeterminate, because the statuses
+  /// of it's children libraries (recursive) are mixed.
+  indeterminate,
+
+  /// Indicates that a library was not migrated to null safety at the start of
+  /// the current migration (either the package was not opted in, or the library
+  /// was explicitly opted out), and that the current migration does migrate the
+  /// library.
+  migrating,
+
+  /// Indicates that the current migration opts the library out of null safety.
+  ///
+  /// This may mean that the library is explicitly opted out with a Dart
+  /// language version comment, or that the package is currently opted out of
+  /// null safety.
+  optingOut,
+}
diff --git a/pkg/nnbd_migration/lib/src/messages.dart b/pkg/nnbd_migration/lib/src/messages.dart
index 6898c3f..4202a47 100644
--- a/pkg/nnbd_migration/lib/src/messages.dart
+++ b/pkg/nnbd_migration/lib/src/messages.dart
@@ -12,8 +12,6 @@
 const String sdkPathEnvironmentVariableSet =
     r'Note: $SDK_PATH environment variable is set and may point to outdated '
     'dart:core sources';
-const String _skipImportCheckFlag =
-    '--${CommandLineOptions.skipImportCheckFlag}';
 const String unmigratedDependenciesWarning = '''
 Warning: package has unmigrated dependencies.
 
@@ -21,6 +19,8 @@
 list of the unmigrated dependencies, re-run without the `$_skipImportCheckFlag`
 flag.
 ''';
+const String _skipImportCheckFlag =
+    '--${CommandLineOptions.skipImportCheckFlag}';
 
 String unmigratedDependenciesError(List<String> uris) => '''
 Error: package has unmigrated dependencies.
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index f3a9fac..69bde9d 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -23,6 +23,7 @@
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/postmortem_file.dart';
 import 'package:nnbd_migration/src/variables.dart';
+import 'package:pub_semver/pub_semver.dart';
 
 /// Implementation of the [NullabilityMigration] public API.
 class NullabilityMigrationImpl implements NullabilityMigration {
@@ -60,10 +61,6 @@
 
   final LineInfo Function(String) _getLineInfo;
 
-  /// Indicates whether we should transform iterable methods taking an "orElse"
-  /// parameter into their "OrNull" equivalents if possible.
-  final bool transformWhereOrNull;
-
   /// Map from [Source] object to a boolean indicating whether the source is
   /// opted in to null safety.
   final Map<Source, bool> _libraryOptInStatus = {};
@@ -71,6 +68,11 @@
   /// Indicates whether the client has used the [unmigratedDependencies] getter.
   bool _queriedUnmigratedDependencies = false;
 
+  /// Map of additional package dependencies that will be required by the
+  /// migrated code.  Keys are package names; values indicate the minimum
+  /// required version of each package.
+  final Map<String, Version> _neededPackages = {};
+
   /// Prepares to perform nullability migration.
   ///
   /// If [permissive] is `true`, exception handling logic will try to proceed
@@ -84,18 +86,12 @@
   /// Optional parameter [warnOnWeakCode] indicates whether weak-only code
   /// should be warned about or removed (in the way specified by
   /// [removeViaComments]).
-  ///
-  /// Optional parameter [transformWhereOrNull] indicates whether Iterable
-  /// methods should be transformed to their "OrNull" equivalents when possible.
-  /// This feature is a work in progress, so by default they are not
-  /// transformed.
   NullabilityMigrationImpl(NullabilityMigrationListener listener,
       LineInfo Function(String) getLineInfo,
       {bool permissive = false,
       NullabilityMigrationInstrumentation instrumentation,
       bool removeViaComments = false,
-      bool warnOnWeakCode = true,
-      bool transformWhereOrNull = true})
+      bool warnOnWeakCode = true})
       : this._(
             listener,
             NullabilityGraph(instrumentation: instrumentation),
@@ -103,8 +99,7 @@
             instrumentation,
             removeViaComments,
             warnOnWeakCode,
-            getLineInfo,
-            transformWhereOrNull);
+            getLineInfo);
 
   NullabilityMigrationImpl._(
       this.listener,
@@ -113,8 +108,7 @@
       this._instrumentation,
       this.removeViaComments,
       this.warnOnWeakCode,
-      this._getLineInfo,
-      this.transformWhereOrNull) {
+      this._getLineInfo) {
     _instrumentation?.immutableNodes(_graph.never, _graph.always);
     _postmortemFileWriter?.graph = _graph;
   }
@@ -169,7 +163,7 @@
         unit,
         warnOnWeakCode,
         _graph,
-        transformWhereOrNull);
+        _neededPackages);
     try {
       DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
       fixBuilder.visitAll();
@@ -196,9 +190,10 @@
     }
   }
 
-  void finish() {
+  Map<String, Version> finish() {
     _postmortemFileWriter?.write();
     _instrumentation?.finished();
+    return _neededPackages;
   }
 
   void prepareInput(ResolvedUnitResult result) {
@@ -254,7 +249,6 @@
           unit.declaredElement.source,
           _permissive ? listener : null,
           _decoratedClassHierarchy,
-          transformWhereOrNull,
           instrumentation: _instrumentation));
     } finally {
       DecoratedTypeParameterBounds.current = null;
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index f433446..4fabe98 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -364,7 +364,9 @@
 
   Future<void> rerunMigration() async {
     migrationState = await rerunFunction();
-    reset();
+    if (!migrationState.hasErrors) {
+      reset();
+    }
   }
 
   void reset() {
diff --git a/pkg/nnbd_migration/pubspec.yaml b/pkg/nnbd_migration/pubspec.yaml
index 5f57739..0a382de 100644
--- a/pkg/nnbd_migration/pubspec.yaml
+++ b/pkg/nnbd_migration/pubspec.yaml
@@ -7,20 +7,26 @@
   sdk: '>=2.6.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^4.0.0
-  analyzer: ^0.40.4
-  analyzer_plugin: ^0.2.4
+  _fe_analyzer_shared:
+    path: ../_fe_analyzer_shared
+  analyzer:
+    path: ../analyzer
+  analyzer_plugin:
+    path: ../analyzer_plugin
   args: ^1.4.4
   cli_util: ^0.2.0
   collection: ^1.14.11
   crypto: ^2.0.6
-  meta: ^1.1.6
+  meta:
+    path: ../meta
   path: ^1.6.2
   pub_semver: ^1.4.2
   source_span: ^1.4.1
-  yaml: ^2.1.15
+  yaml: any
 
 dev_dependencies:
+  analyzer_utilities:
+    path: ../analyzer_utilities
   http: '>=0.11.3+17 <0.13.0'
   pedantic: ^1.9.0
   test: ^1.6.4
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 1e86235..8e1285fa 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -60,8 +60,7 @@
     var migration = NullabilityMigration(listener, getLineInfo,
         permissive: _usePermissiveMode,
         removeViaComments: removeViaComments,
-        warnOnWeakCode: warnOnWeakCode,
-        transformWhereOrNull: true);
+        warnOnWeakCode: warnOnWeakCode);
     for (var path in input.keys) {
       if (!(session.getFile(path)).isPart) {
         for (var unit in (await session.getResolvedLibrary(path)).units) {
@@ -248,6 +247,28 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_ambiguous_closure_parameter_in_local_variable() async {
+    var content = '''
+Object f<T>(Object Function(T) callback, Object obj) => 0;
+g() {
+  var y = f<Map<String, int>>(
+      (x) => x.keys,
+      f<List<bool>>(
+          (x) => x.last, 0));
+}
+''';
+    var expected = '''
+Object f<T>(Object Function(T) callback, Object obj) => 0;
+g() {
+  var y = f<Map<String, int>>(
+      (x) => x.keys,
+      f<List<bool>>(
+          (x) => x.last, 0));
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_argumentError_checkNotNull_implies_non_null_intent() async {
     var content = '''
 void f(int i) {
@@ -2218,6 +2239,28 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_extension_on_generic_type() async {
+    var content = '''
+class C<T> {
+  final T value;
+  C(this.value);
+}
+extension E<T> on Future<C<T/*?*/>> {
+  Future<T> get asyncValue async => (await this).value;
+}
+''';
+    var expected = '''
+class C<T> {
+  final T value;
+  C(this.value);
+}
+extension E<T> on Future<C<T?>> {
+  Future<T?> get asyncValue async => (await this).value;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_extension_on_type_param_implementation() async {
     var content = '''
 abstract class C {
@@ -4045,6 +4088,24 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_isExpression_with_function_type() async {
+    var content = '''
+void test(Function f) {
+  if (f is void Function()) {
+    f();
+  }
+}
+''';
+    var expected = '''
+void test(Function f) {
+  if (f is void Function()) {
+    f();
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_issue_40181() async {
     // This contrived example created an "exact nullable" type parameter bound
     // which propagated back to *all* instantiations of that parameter.
@@ -4617,6 +4678,54 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_loop_var_is_field() async {
+    var content = '''
+class C {
+  int x;
+  C(this.x);
+  f(List<int/*?*/> y) {
+    for (x in y) {}
+  }
+}
+''';
+    var expected = '''
+class C {
+  int? x;
+  C(this.x);
+  f(List<int?> y) {
+    for (x in y) {}
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_loop_var_is_inherited_field_with_substitution() async {
+    var content = '''
+class B<T> {
+  T x;
+  B(this.x);
+}
+abstract class C implements B<int> {
+  f(List<int/*?*/> y) {
+    for (x in y) {}
+  }
+}
+''';
+    var expected = '''
+class B<T> {
+  T x;
+  B(this.x);
+}
+abstract class C implements B<int?> {
+  f(List<int?> y) {
+    for (x in y) {}
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_make_downcast_explicit() async {
     var content = 'int f(num n) => n;';
     var expected = 'int f(num n) => n as int;';
@@ -6409,11 +6518,11 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39387')
   Future<void> test_this_inside_extension() async {
     var content = '''
 class C<T> {
   T field;
+  C(this.field);
 }
 extension on C<int> {
   f() {
@@ -6422,14 +6531,14 @@
 }
 extension on C<List<int>> {
   f() {
-    this.field = null;
+    this.field = [null];
   }
 }
 ''';
     var expected = '''
-
 class C<T> {
   T field;
+  C(this.field);
 }
 extension on C<int?> {
   f() {
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 001a94b..1885167 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2929,7 +2929,6 @@
     // metadata was visited.
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39387')
   Future<void> test_extension_on_class_with_generic_type_arguments() async {
     await analyze('''
 class C<T> {}
@@ -2942,7 +2941,6 @@
     // adding assertion(s).
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39387')
   Future<void> test_extension_on_function_type() async {
     await analyze('''
 extension CurryFunction<R, S, T> on R Function(S, T) {
@@ -4433,7 +4431,6 @@
         hard: false);
   }
 
-  @failingTest
   Future<void> test_isExpression_genericFunctionType() async {
     await analyze('''
 bool f(a) => a is int Function(String);
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 29e39622..7989905 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -3538,8 +3538,7 @@
         null,
         scope.thisOrAncestorOfType<CompilationUnit>(),
         warnOnWeakCode,
-        graph,
-        true);
+        graph, {});
   }
 
   bool _isInScope(AstNode node, AstNode scope) {
diff --git a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
index 2781783..9aa39c1 100644
--- a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
@@ -17,7 +17,10 @@
   });
 }
 
-const isNavigationTreeNode = TypeMatcher<NavigationTreeNode>();
+const isNavigationTreeDirectoryNode =
+    TypeMatcher<NavigationTreeDirectoryNode>();
+
+const isNavigationTreeFileNode = TypeMatcher<NavigationTreeFileNode>();
 
 @reflectiveTest
 class NavigationTreeRendererTest extends NnbdMigrationTestBase {
@@ -40,13 +43,13 @@
       convertPath('$projectPath/lib/c.dart'): 'int c = null;\nint d = null;',
     });
 
-    var libNode = response[0];
+    var libNode = response[0] as NavigationTreeDirectoryNode;
     expect(
         libNode,
-        isNavigationTreeNode.havingSubtree([
-          isNavigationTreeNode.havingEditCount(0),
-          isNavigationTreeNode.havingEditCount(1),
-          isNavigationTreeNode.havingEditCount(2)
+        isNavigationTreeDirectoryNode.havingSubtree([
+          isNavigationTreeFileNode.havingEditCount(0),
+          isNavigationTreeFileNode.havingEditCount(1),
+          isNavigationTreeFileNode.havingEditCount(2)
         ]));
   }
 
@@ -60,15 +63,16 @@
     var libNode = response[0];
     expect(
         libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode.named('src').havingSubtree([
-            isNavigationTreeNode.havingHref(
+        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
+          isNavigationTreeDirectoryNode.named('src').havingSubtree([
+            isNavigationTreeFileNode.havingHref(
                 '$projectPath/lib/src/b.dart', pathMapper)
           ]),
-          isNavigationTreeNode.havingHref('$projectPath/lib/a.dart', pathMapper)
+          isNavigationTreeFileNode.havingHref(
+              '$projectPath/lib/a.dart', pathMapper)
         ]));
 
-    var toolNode = response[1];
+    var toolNode = response[1] as NavigationTreeFileNode;
     expect(
         toolNode.href, pathMapper.map(convertPath('$projectPath/tool.dart')));
   }
@@ -84,11 +88,11 @@
     var libNode = response[0];
     expect(
         libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode
+        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
+          isNavigationTreeDirectoryNode
               .named('src')
-              .havingSubtree([isNavigationTreeNode.named('b.dart')]),
-          isNavigationTreeNode.named('a.dart')
+              .havingSubtree([isNavigationTreeFileNode.named('b.dart')]),
+          isNavigationTreeFileNode.named('a.dart')
         ]));
 
     var toolNode = response[1];
@@ -102,12 +106,12 @@
     });
     expect(response, hasLength(2));
 
-    var binNode = response[0];
+    var binNode = response[0] as NavigationTreeDirectoryNode;
     expect(binNode.type, equals(NavigationTreeNodeType.directory));
     expect(binNode.name, equals('bin'));
     expect(binNode.subtree, hasLength(1));
 
-    var libNode = response[1];
+    var libNode = response[1] as NavigationTreeDirectoryNode;
     expect(libNode.type, equals(NavigationTreeNodeType.directory));
     expect(libNode.name, equals('lib'));
     expect(libNode.subtree, hasLength(1));
@@ -123,12 +127,12 @@
     var libNode = response[0];
     expect(
         libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode
+        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
+          isNavigationTreeFileNode
               .named('a.dart')
               .havingPath(convertPath('lib/a.dart'))
               .havingHref('$projectPath/lib/a.dart', pathMapper),
-          isNavigationTreeNode
+          isNavigationTreeFileNode
               .named('b.dart')
               .havingPath(convertPath('lib/b.dart'))
               .havingHref('$projectPath/lib/b.dart', pathMapper)
@@ -145,10 +149,11 @@
     var libNode = response[0];
     expect(
         libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode.named('src').havingSubtree(
-              [isNavigationTreeNode.havingPath(convertPath('lib/src/b.dart'))]),
-          isNavigationTreeNode.havingPath(convertPath('lib/a.dart'))
+        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
+          isNavigationTreeDirectoryNode.named('src').havingSubtree([
+            isNavigationTreeFileNode.havingPath(convertPath('lib/src/b.dart'))
+          ]),
+          isNavigationTreeFileNode.havingPath(convertPath('lib/a.dart'))
         ]));
 
     var toolNode = response[1];
@@ -164,9 +169,9 @@
     var libNode = response[0];
     expect(
         libNode,
-        isNavigationTreeNode.named('lib').havingSubtree([
-          isNavigationTreeNode.named('src').havingSubtree([
-            isNavigationTreeNode
+        isNavigationTreeDirectoryNode.named('lib').havingSubtree([
+          isNavigationTreeDirectoryNode.named('src').havingSubtree([
+            isNavigationTreeFileNode
                 .named('a.dart')
                 .havingPath(convertPath('lib/src/a.dart'))
                 .havingHref('$projectPath/lib/src/a.dart', pathMapper)
@@ -180,27 +185,174 @@
     });
     expect(response, hasLength(1));
 
-    var aNode = response[0];
+    var aNode = response[0] as NavigationTreeFileNode;
     expect(aNode.name, 'a.dart');
     expect(aNode.path, 'a.dart');
     expect(aNode.href, pathMapper.map(convertPath('$projectPath/a.dart')));
   }
+
+  Future<void> test_migrationStatus_directory_allMigrated() async {
+    var response = await renderNavigationTree({
+      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
+      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
+    });
+
+    var libNode = response[0] as NavigationTreeDirectoryNode;
+    ((libNode.subtree[0] as NavigationTreeDirectoryNode).subtree[0]
+            as NavigationTreeFileNode)
+        .migrationStatus = UnitMigrationStatus.alreadyMigrated;
+    (libNode.subtree[1] as NavigationTreeFileNode).migrationStatus =
+        UnitMigrationStatus.alreadyMigrated;
+    expect(
+        libNode,
+        isNavigationTreeDirectoryNode
+            .named('lib')
+            .havingMigrationStatus(UnitMigrationStatus.alreadyMigrated)
+            .havingSubtree([
+          isNavigationTreeDirectoryNode
+              .named('src')
+              .havingMigrationStatus(UnitMigrationStatus.alreadyMigrated),
+          isNavigationTreeFileNode
+        ]));
+  }
+
+  Future<void> test_migrationStatus_directory_allMigrating() async {
+    var response = await renderNavigationTree({
+      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
+      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
+    });
+
+    var libNode = response[0];
+    expect(
+        libNode,
+        isNavigationTreeDirectoryNode
+            .named('lib')
+            .havingMigrationStatus(UnitMigrationStatus.migrating)
+            .havingSubtree([
+          isNavigationTreeDirectoryNode
+              .named('src')
+              .havingMigrationStatus(UnitMigrationStatus.migrating),
+          isNavigationTreeFileNode
+        ]));
+  }
+
+  Future<void> test_migrationStatus_directory_allOptingOut() async {
+    var response = await renderNavigationTree({
+      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
+      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
+    });
+
+    var libNode = response[0] as NavigationTreeDirectoryNode;
+    ((libNode.subtree[0] as NavigationTreeDirectoryNode).subtree[0]
+            as NavigationTreeFileNode)
+        .migrationStatus = UnitMigrationStatus.optingOut;
+    (libNode.subtree[1] as NavigationTreeFileNode).migrationStatus =
+        UnitMigrationStatus.optingOut;
+    expect(
+        libNode,
+        isNavigationTreeDirectoryNode
+            .named('lib')
+            .havingMigrationStatus(UnitMigrationStatus.optingOut)
+            .havingSubtree([
+          isNavigationTreeDirectoryNode
+              .named('src')
+              .havingMigrationStatus(UnitMigrationStatus.optingOut),
+          isNavigationTreeFileNode
+        ]));
+  }
+
+  Future<void> test_migrationStatus_directory_mixedInAndOut() async {
+    var response = await renderNavigationTree({
+      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
+      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
+      convertPath('$projectPath/lib/src/c.dart'): 'int b = null;',
+    });
+
+    var libNode = response[0] as NavigationTreeDirectoryNode;
+    var libSrcNode = libNode.subtree[0] as NavigationTreeDirectoryNode;
+    (libSrcNode.subtree[0] as NavigationTreeFileNode).migrationStatus =
+        UnitMigrationStatus.optingOut;
+    expect(
+        libNode,
+        isNavigationTreeDirectoryNode
+            .named('lib')
+            .havingMigrationStatus(UnitMigrationStatus.indeterminate)
+            .havingSubtree([
+          isNavigationTreeDirectoryNode
+              .named('src')
+              .havingMigrationStatus(UnitMigrationStatus.indeterminate),
+          isNavigationTreeFileNode
+        ]));
+  }
+
+  Future<void> test_migrationStatus_directory_mixedInAndOutAndMigrated() async {
+    var response = await renderNavigationTree({
+      convertPath('$projectPath/lib/a.dart'): 'int a = null;',
+      convertPath('$projectPath/lib/src/b.dart'): 'int b = null;',
+      convertPath('$projectPath/lib/src/c.dart'): 'int b = null;',
+    });
+
+    var libNode = response[0] as NavigationTreeDirectoryNode;
+    var libSrcNode = libNode.subtree[0] as NavigationTreeDirectoryNode;
+    (libSrcNode.subtree[0] as NavigationTreeFileNode).migrationStatus =
+        UnitMigrationStatus.optingOut;
+    (libSrcNode.subtree[1] as NavigationTreeFileNode).migrationStatus =
+        UnitMigrationStatus.alreadyMigrated;
+    expect(
+        libNode,
+        isNavigationTreeDirectoryNode
+            .named('lib')
+            .havingMigrationStatus(UnitMigrationStatus.indeterminate)
+            .havingSubtree([
+          isNavigationTreeDirectoryNode
+              .named('src')
+              .havingMigrationStatus(UnitMigrationStatus.optingOut),
+          isNavigationTreeFileNode
+        ]));
+  }
+
+  Future<void> test_migrationStatus_file() async {
+    var response = await renderNavigationTree({
+      convertPath('$projectPath/lib/a.dart'): 'int a = 1;',
+      convertPath('$projectPath/lib/b.dart'): '// @dart=2.9\nint b = null;',
+    });
+
+    var libNode = response[0] as NavigationTreeDirectoryNode;
+    expect(
+        libNode,
+        isNavigationTreeDirectoryNode.havingSubtree([
+          isNavigationTreeFileNode
+              .havingMigrationStatus(UnitMigrationStatus.migrating),
+          isNavigationTreeFileNode
+              .havingMigrationStatus(UnitMigrationStatus.migrating),
+        ]));
+  }
 }
 
-extension on TypeMatcher<NavigationTreeNode> {
-  TypeMatcher<NavigationTreeNode> havingSubtree(dynamic matcher) =>
-      having((node) => node.subtree, 'subtree', matcher);
-
-  TypeMatcher<NavigationTreeNode> havingEditCount(dynamic matcher) =>
-      having((node) => node.editCount, 'editCount', matcher);
-
-  TypeMatcher<NavigationTreeNode> named(dynamic matcher) =>
+extension<T extends NavigationTreeNode> on TypeMatcher<T> {
+  TypeMatcher<T> named(dynamic matcher) =>
       having((node) => node.name, 'name', matcher);
 
-  TypeMatcher<NavigationTreeNode> havingHref(
+  TypeMatcher<T> havingMigrationStatus(dynamic matcher) =>
+      having((node) => node.migrationStatus, 'migrationStatus', matcher);
+}
+
+extension on TypeMatcher<NavigationTreeDirectoryNode> {
+  TypeMatcher<NavigationTreeDirectoryNode> havingSubtree(dynamic matcher) =>
+      having((node) => node.subtree, 'subtree', matcher);
+}
+
+extension on TypeMatcher<NavigationTreeFileNode> {
+  TypeMatcher<NavigationTreeFileNode> havingEditCount(dynamic matcher) =>
+      having((node) => node.editCount, 'editCount', matcher);
+
+  //TypeMatcher<NavigationTreeFileNode> named(dynamic matcher) =>
+  //    having((node) => node.name, 'name', matcher);
+
+  TypeMatcher<NavigationTreeFileNode> havingHref(
           String path, PathMapper pathMapper) =>
       having((node) => node.href, 'href', pathMapper.map(path));
 
-  TypeMatcher<NavigationTreeNode> havingPath(dynamic matcher) =>
+  TypeMatcher<NavigationTreeFileNode> havingPath(dynamic matcher) =>
       having((node) => node.path, 'path', matcher);
 }
diff --git a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
index 6f87f89..b941ca3 100644
--- a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
+++ b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
@@ -17,8 +17,25 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'analysis_abstract.dart';
 import '../utilities/test_logger.dart';
+import 'analysis_abstract.dart';
+
+class ListenerClient implements DartFixListenerClient {
+  @override
+  void onException(String detail) {
+    fail('Unexpected call to onException($detail)');
+  }
+
+  @override
+  void onFatalError(String detail) {
+    fail('Unexpected call to onFatalError($detail)');
+  }
+
+  @override
+  void onMessage(String detail) {
+    fail('Unexpected call to onMessage($detail)');
+  }
+}
 
 @reflectiveTest
 class NnbdMigrationTestBase extends AbstractAnalysisTest {
@@ -201,15 +218,14 @@
     // Compute the analysis results.
     var server = DriverProviderImpl(resourceProvider, driver.analysisContext);
     // Run the migration engine.
-    var listener = DartFixListener(server, _exceptionReported);
+    var listener = DartFixListener(server, ListenerClient());
     var instrumentationListener = InstrumentationListener();
     var adapter = NullabilityMigrationAdapter(listener);
     var migration = NullabilityMigration(adapter, getLineInfo,
         permissive: false,
         instrumentation: instrumentationListener,
         removeViaComments: removeViaComments,
-        warnOnWeakCode: warnOnWeakCode,
-        transformWhereOrNull: true);
+        warnOnWeakCode: warnOnWeakCode);
     Future<void> _forEachPath(
         void Function(ResolvedUnitResult) callback) async {
       for (var testPath in testPaths) {
@@ -230,8 +246,4 @@
         migration, nodeMapper, logger);
     infos = await builder.explainMigration();
   }
-
-  void _exceptionReported(String detail) {
-    fail('Unexpected error during migration: $detail');
-  }
 }
diff --git a/pkg/nnbd_migration/test/front_end/test_all.dart b/pkg/nnbd_migration/test/front_end/test_all.dart
index 9a81148..7c88db8 100644
--- a/pkg/nnbd_migration/test/front_end/test_all.dart
+++ b/pkg/nnbd_migration/test/front_end/test_all.dart
@@ -7,6 +7,7 @@
 import 'info_builder_test.dart' as info_builder;
 import 'instrumentation_renderer_test.dart' as instrumentation_renderer;
 import 'migration_info_test.dart' as migration_info;
+import 'migration_summary_test.dart' as migration_summary;
 import 'navigation_tree_renderer_test.dart' as navigation_tree_renderer;
 import 'offset_mapper_test.dart' as offset_mapper;
 import 'region_renderer_test.dart' as region_renderer;
@@ -17,6 +18,7 @@
     info_builder.main();
     instrumentation_renderer.main();
     migration_info.main();
+    migration_summary.main();
     navigation_tree_renderer.main();
     offset_mapper.main();
     region_renderer.main();
diff --git a/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart b/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
index 79a0fbf..9ea346f 100644
--- a/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/unit_renderer_test.dart
@@ -161,6 +161,26 @@
             ['1 late final hint converted to late and final keywords']));
   }
 
+  Future<void> test_editList_countsWhereOrNullSingly() async {
+    await buildInfoForSingleTestFile(
+        '''
+import 'package:collection/collection.dart';
+
+int firstEven(Iterable<int> x)
+    => x.firstWhere((x) => x.isEven, orElse: () => null);
+''',
+        removeViaComments: false,
+        migratedContent: '''
+import 'package:collection/collection.dart';
+
+int? firstEven(Iterable<int >  x)
+    => x.firstWherefirstWhereOrNull((x) => x.isEven, orElse: () => null);
+''');
+    var output = renderUnits()[0];
+    expect(output.edits.keys,
+        unorderedEquals(['1 method name changed', '1 type made nullable']));
+  }
+
   Future<void> test_editList_pluralHeader() async {
     await buildInfoForSingleTestFile('''
 int a = null;
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index f1352f3..d746ac6 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -144,7 +144,8 @@
 
   @override
   Set<String> computePathsToProcess(DriverBasedAnalysisContext context) =>
-      cli._test.overridePathsToProcess ?? super.computePathsToProcess(context);
+      cli._test.overridePathsToProcess ??
+      _sortPaths(super.computePathsToProcess(context));
 
   @override
   NonNullableFix createNonNullableFix(
@@ -185,6 +186,13 @@
   bool shouldBeMigrated(DriverBasedAnalysisContext context, String path) =>
       cli._test.overrideShouldBeMigrated?.call(path) ??
       super.shouldBeMigrated(context, path);
+
+  /// Sorts the paths in [paths] for repeatability of migration tests.
+  Set<String> _sortPaths(Set<String> paths) {
+    var pathList = paths.toList();
+    pathList.sort();
+    return pathList.toSet();
+  }
 }
 
 abstract class _MigrationCliTestBase {
@@ -676,10 +684,20 @@
     expect(
         errorOutput, isNot(contains('try to fix errors in the source code')));
     expect(errorOutput, contains('re-run with\n--ignore-exceptions'));
+    expect(errorOutput, contains('consider filing a bug report'));
+    expect(
+        errorOutput,
+        contains(
+            RegExp(r'Please include the SDK version \([0-9]+\.[0-9]+\..*\)')));
   }
 
   test_lifecycle_exception_handling_ignore() async {
-    var projectContents = simpleProject(sourceText: 'main() { print(0); }');
+    var projectContents = simpleProject(sourceText: '''
+main() {
+  print(0);
+  int x = null;
+}
+''');
     var projectDir = createProjectDir(projectContents);
     injectArtificialException = true;
     var cli = _createCli();
@@ -694,6 +712,14 @@
               ' of --ignore-exceptions.'));
       expect(output, contains('re-run without --ignore-exceptions'));
       await assertPreviewServerResponsive(url);
+      await _tellPreviewToApplyChanges(url);
+      assertProjectContents(
+          projectDir, simpleProject(migrated: true, sourceText: '''
+main() {
+  print(0);
+  int? x = null;
+}
+'''));
     });
     expect(logger.stderrBuffer.toString(), isEmpty);
   }
@@ -804,6 +830,30 @@
     expect(output, isNot(contains('package:bar/bar.dart')));
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44118')
+  test_lifecycle_issue_44118() async {
+    var projectContents = simpleProject(sourceText: '''
+int f() => null
+''');
+    projectContents['lib/foo.dart'] = '''
+import 'test.dart';
+''';
+    var projectDir = createProjectDir(projectContents);
+    await assertRunFailure([projectDir]);
+    var output = logger.stdoutBuffer.toString();
+    expect(output, contains('1 analysis issue found'));
+    var sep = resourceProvider.pathContext.separator;
+    expect(
+        output,
+        contains("error • Expected to find ';' at lib${sep}test.dart:1:12 • "
+            '(expected_token)'));
+    expect(
+        output,
+        contains(
+            'analysis errors will result in erroneous migration suggestions'));
+    expect(output, contains('Please fix the analysis issues'));
+  }
+
   test_lifecycle_migration_already_performed() async {
     var projectContents = simpleProject(migrated: true);
     var projectDir = createProjectDir(projectContents);
@@ -945,14 +995,7 @@
       expect(
           logger.stdoutBuffer.toString(), contains('No analysis issues found'));
       await assertPreviewServerResponsive(url);
-      var uri = Uri.parse(url);
-      var authToken = uri.queryParameters['authToken'];
-      var response = await httpPost(
-          uri.replace(
-              path: PreviewSite.applyMigrationPath,
-              queryParameters: {'authToken': authToken}),
-          headers: {'Content-Type': 'application/json; charset=UTF-8'});
-      assertHttpSuccess(response);
+      await _tellPreviewToApplyChanges(url);
       expect(applyHookCalled, true);
     });
   }
@@ -1018,9 +1061,10 @@
           headers: {'Content-Type': 'application/json; charset=UTF-8'});
       var navRoots = jsonDecode(treeResponse.body);
       for (final root in navRoots) {
-        var navTree = NavigationTreeNode.fromJson(root);
+        var navTree =
+            NavigationTreeNode.fromJson(root) as NavigationTreeDirectoryNode;
         for (final file in navTree.subtree) {
-          if (file.href != null) {
+          if (file is NavigationTreeFileNode) {
             final contentsResponse = await httpGet(
                 uri
                     .resolve(file.href)
@@ -1671,6 +1715,101 @@
     }
   }
 
+  test_pubspec_add_collection_dependency() async {
+    var projectContents = simpleProject(sourceText: '''
+int firstEven(Iterable<int> x)
+    => x.firstWhere((x) => x.isEven, orElse: () => null);
+''', pubspecText: '''
+name: test
+environment:
+  sdk: '>=2.6.0 <3.0.0'
+dependencies:
+  foo: ^1.2.3
+''');
+    var projectDir = createProjectDir(projectContents);
+    var cliRunner = _createCli()
+        .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]));
+    await cliRunner.run();
+    expect(
+        logger.stdoutBuffer.toString(), contains('Please run `dart pub get`'));
+    // The Dart source code should still be migrated.
+    assertProjectContents(
+        projectDir, simpleProject(migrated: true, sourceText: '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+int? firstEven(Iterable<int> x)
+    => x.firstWhereOrNull((x) => x.isEven);
+''', pubspecText: '''
+name: test
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+dependencies:
+  foo: ^1.2.3
+  collection: ^1.15.0-nullsafety.4
+'''));
+  }
+
+  test_pubspec_add_dependency_and_environment_sections() async {
+    var projectContents = simpleProject(sourceText: '''
+int firstEven(Iterable<int> x)
+    => x.firstWhere((x) => x.isEven, orElse: () => null);
+''', pubspecText: '''
+name: test
+''');
+    var projectDir = createProjectDir(projectContents);
+    var cliRunner = _createCli()
+        .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]));
+    await cliRunner.run();
+    expect(
+        logger.stdoutBuffer.toString(), contains('Please run `dart pub get`'));
+    // The Dart source code should still be migrated.
+    assertProjectContents(
+        projectDir, simpleProject(migrated: true, sourceText: '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+int? firstEven(Iterable<int> x)
+    => x.firstWhereOrNull((x) => x.isEven);
+''',
+            // Note: section order is weird, but it's valid and this is a rare use
+            // case.
+            pubspecText: '''
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+dependencies:
+  collection: ^1.15.0-nullsafety.4
+name: test
+'''));
+  }
+
+  test_pubspec_add_dependency_section() async {
+    var projectContents = simpleProject(sourceText: '''
+int firstEven(Iterable<int> x)
+    => x.firstWhere((x) => x.isEven, orElse: () => null);
+''');
+    var projectDir = createProjectDir(projectContents);
+    var cliRunner = _createCli()
+        .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]));
+    await cliRunner.run();
+    expect(
+        logger.stdoutBuffer.toString(), contains('Please run `dart pub get`'));
+    // The Dart source code should still be migrated.
+    assertProjectContents(projectDir, simpleProject(migrated: true, sourceText: '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+int? firstEven(Iterable<int> x)
+    => x.firstWhereOrNull((x) => x.isEven);
+''',
+        // Note: `dependencies` section is in a weird place, but it's valid and
+        // this is a rare use case.
+        pubspecText: '''
+dependencies:
+  collection: ^1.15.0-nullsafety.4
+name: test
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+'''));
+  }
+
   test_pubspec_does_not_exist() async {
     var projectContents = simpleProject()..remove('pubspec.yaml');
     var projectDir = createProjectDir(projectContents);
@@ -1778,7 +1917,6 @@
         '''
 environment:
   sdk: '>=2.12.0 <3.0.0'
-
 name: test
 '''));
   }
@@ -1788,7 +1926,76 @@
     var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli()
         .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]));
-    expect(() async => await cliRunner.run(), throwsUnsupportedError);
+    var message = await assertErrorExit(
+        cliRunner, () async => await cliRunner.run(),
+        withUsage: false);
+    expect(message, contains('Failed to parse pubspec file'));
+  }
+
+  test_pubspec_preserve_collection_dependency() async {
+    var projectContents = simpleProject(sourceText: '''
+int firstEven(Iterable<int> x)
+    => x.firstWhere((x) => x.isEven, orElse: () => null);
+''', pubspecText: '''
+name: test
+environment:
+  sdk: '>=2.6.0 <3.0.0'
+dependencies:
+  collection: ^1.16.0
+''');
+    var projectDir = createProjectDir(projectContents);
+    var cliRunner = _createCli()
+        .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]));
+    await cliRunner.run();
+    expect(logger.stdoutBuffer.toString(),
+        isNot(contains('Please run `dart pub get`')));
+    // The Dart source code should still be migrated.
+    assertProjectContents(
+        projectDir, simpleProject(migrated: true, sourceText: '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+int? firstEven(Iterable<int> x)
+    => x.firstWhereOrNull((x) => x.isEven);
+''', pubspecText: '''
+name: test
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+dependencies:
+  collection: ^1.16.0
+'''));
+  }
+
+  test_pubspec_update_collection_dependency() async {
+    var projectContents = simpleProject(sourceText: '''
+int firstEven(Iterable<int> x)
+    => x.firstWhere((x) => x.isEven, orElse: () => null);
+''', pubspecText: '''
+name: test
+environment:
+  sdk: '>=2.6.0 <3.0.0'
+dependencies:
+  collection: ^1.14.0
+''');
+    var projectDir = createProjectDir(projectContents);
+    var cliRunner = _createCli()
+        .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]));
+    await cliRunner.run();
+    expect(
+        logger.stdoutBuffer.toString(), contains('Please run `dart pub get`'));
+    // The Dart source code should still be migrated.
+    assertProjectContents(
+        projectDir, simpleProject(migrated: true, sourceText: '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+int? firstEven(Iterable<int> x)
+    => x.firstWhereOrNull((x) => x.isEven);
+''', pubspecText: '''
+name: test
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+dependencies:
+  collection: ^1.15.0-nullsafety.4
+'''));
   }
 
   test_pubspec_with_sdk_version_beta() async {
@@ -1912,6 +2119,17 @@
   ArgResults _parseArgs(List<String> args) {
     return MigrationCli.createParser().parse(args);
   }
+
+  Future<void> _tellPreviewToApplyChanges(String url) async {
+    var uri = Uri.parse(url);
+    var authToken = uri.queryParameters['authToken'];
+    var response = await httpPost(
+        uri.replace(
+            path: PreviewSite.applyMigrationPath,
+            queryParameters: {'authToken': authToken}),
+        headers: {'Content-Type': 'application/json; charset=UTF-8'});
+    assertHttpSuccess(response);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index f853f96..5ed5feb 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -149,7 +149,7 @@
     var unit = await super.analyze(code);
     decoratedClassHierarchy = DecoratedClassHierarchy(variables, graph);
     unit.accept(EdgeBuilder(typeProvider, typeSystem, variables, graph,
-        testSource, null, decoratedClassHierarchy, true));
+        testSource, null, decoratedClassHierarchy));
     return unit;
   }
 }
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index f32b003..3f9ce89 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -36,10 +36,10 @@
   }
 
   void setUp() {
-    dartfixListener = DartFixListener(null, _exceptionReported);
+    dartfixListener = DartFixListener(null, ListenerClient());
     resourceProvider = MemoryResourceProvider();
     final migrationInfo = MigrationInfo({}, {}, null, null);
-    state = MigrationState(null, null, dartfixListener, null);
+    state = MigrationState(null, null, dartfixListener, null, {});
     state.pathMapper = PathMapper(resourceProvider);
     state.migrationInfo = migrationInfo;
     site = PreviewSite(state, () async {
@@ -165,10 +165,6 @@
     expect(file.readAsStringSync(), currentContent);
     expect(state.hasBeenApplied, false);
   }
-
-  void _exceptionReported(String detail) {
-    fail('Unexpected error during migration: $detail');
-  }
 }
 
 mixin PreviewSiteTestMixin {
@@ -190,9 +186,9 @@
   @override
   void setUp() {
     super.setUp();
-    dartfixListener = DartFixListener(null, _exceptionReported);
+    dartfixListener = DartFixListener(null, ListenerClient());
     final migrationInfo = MigrationInfo({}, {}, null, null);
-    state = MigrationState(null, null, dartfixListener, null);
+    state = MigrationState(null, null, dartfixListener, null, {});
     nodeMapper = state.nodeMapper;
     state.pathMapper = PathMapper(resourceProvider);
     state.migrationInfo = migrationInfo;
@@ -337,8 +333,4 @@
     expect(state.hasBeenApplied, false);
     expect(state.needsRerun, true);
   }
-
-  void _exceptionReported(String detail) {
-    fail('Unexpected error during migration: $detail');
-  }
 }
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index b82bafb..c2f9b7f 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -26,6 +26,7 @@
 import 'preview/test_all.dart' as preview;
 import 'utilities/test_all.dart' as utilities;
 import 'variables_test.dart' as variables;
+import 'verify_tests_test.dart' as verify_tests;
 
 main() {
   defineReflectiveSuite(() {
@@ -48,5 +49,6 @@
     preview.main();
     utilities.main();
     variables.main();
+    verify_tests.main();
   });
 }
diff --git a/pkg/nnbd_migration/test/utilities/test_logger.dart b/pkg/nnbd_migration/test/utilities/test_logger.dart
index 5d997c3..67f73f9 100644
--- a/pkg/nnbd_migration/test/utilities/test_logger.dart
+++ b/pkg/nnbd_migration/test/utilities/test_logger.dart
@@ -18,9 +18,7 @@
   Ansi get ansi => Ansi(false);
 
   @override
-  void flush() {
-    throw UnimplementedError('TODO(paulberry)');
-  }
+  void flush() {}
 
   @override
   Progress progress(String message) {
@@ -39,7 +37,9 @@
 
   @override
   void trace(String message) {
-    throw UnimplementedError('TODO(paulberry)');
+    if (isVerbose) {
+      stdoutBuffer.writeln(message);
+    }
   }
 
   @override
diff --git a/pkg/nnbd_migration/test/verify_tests_test.dart b/pkg/nnbd_migration/test/verify_tests_test.dart
new file mode 100644
index 0000000..654c634
--- /dev/null
+++ b/pkg/nnbd_migration/test/verify_tests_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:analyzer_utilities/verify_tests.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+
+void main() {
+  var provider = PhysicalResourceProvider.INSTANCE;
+  var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
+  var pathToAnalyze = provider.pathContext.join(packageRoot, 'nnbd_migration');
+  var testDirPath = provider.pathContext.join(pathToAnalyze, 'test');
+  VerifyTests(testDirPath).build();
+}
diff --git a/pkg/nnbd_migration/tool/steamroll_ecosystem.sh b/pkg/nnbd_migration/tool/steamroll_ecosystem.sh
index 9af3926..0c6374b 100755
--- a/pkg/nnbd_migration/tool/steamroll_ecosystem.sh
+++ b/pkg/nnbd_migration/tool/steamroll_ecosystem.sh
@@ -276,8 +276,8 @@
   case "${package_name}" in
     _fe_analyzer_shared) repo=sdk
       make_clone_from_package _fe_analyzer_shared "${repo}" master pkg/_fe_analyzer_shared ;;
-    analysis_tool) repo=sdk
-      make_clone_from_package analysis_tool "${repo}" master pkg/analysis_tool ;;
+    analyzer_utilities) repo=sdk
+      make_clone_from_package analyzer_utilities "${repo}" master pkg/analyzer_utilities ;;
     analyzer) repo=sdk
       make_clone_from_package analyzer "${repo}" master pkg/analyzer ;;
     build) repo=build
@@ -379,7 +379,7 @@
     # those here.
     case "${package_name}" in
       analyzer)
-        add_package_to_workspace "analysis_tool"
+        add_package_to_workspace "analyzer_utilities"
         ;;
     esac
     if [ -n "${NO_UPDATE}" ] || repo_changed_this_run "${repo}" ; then
@@ -447,4 +447,4 @@
 }
 
 
-main "$@"
\ No newline at end of file
+main "$@"
diff --git a/pkg/nnbd_migration/tool/summary_stats.dart b/pkg/nnbd_migration/tool/summary_stats.dart
new file mode 100644
index 0000000..79afca0
--- /dev/null
+++ b/pkg/nnbd_migration/tool/summary_stats.dart
@@ -0,0 +1,54 @@
+import 'dart:convert' show jsonDecode;
+import 'dart:io';
+
+void main(List<String> args) {
+  var jsonPath = args[0];
+  var json =
+      jsonDecode(File(jsonPath).readAsStringSync()) as Map<String, Object>;
+  var changes = json['changes'] as Map<String, Object>;
+  var byPath = changes['byPath'] as Map<String, Object>;
+  if (args.isEmpty) {
+    print('''
+Usage: summary_stats.dart <summary_file> [category_name]
+
+Prints statistics of `dart migrate` suggestions summary, created with the
+`--summary` flag of `dart migrate`.
+
+If [category_name] is not given, this prints the total number of suggestions
+which the tool made, per category.
+
+If [category_name] is given, this prints the file names and suggestion counts of
+each file with one or more suggestions categorized as [category_name].
+''');
+  } else if (args.length == 1) {
+    _printTotals(byPath);
+  } else {
+    var category = args[1];
+    _printCategory(byPath, category);
+  }
+}
+
+/// Prints the file names and counts of files with suggestions of [category].
+void _printCategory(Map<String, Object> byPath, String category) {
+  byPath.forEach((String path, Object value) {
+    var counts = value as Map<String, Object>;
+    if (counts.containsKey(category)) {
+      print('$path: ${counts[category]}');
+    }
+  });
+}
+
+/// Prints the total number of suggestions for each category.
+void _printTotals(Map<String, Object> byPath) {
+  var summary = <String, int>{};
+  for (var file in byPath.values.cast<Map<Object, Object>>()) {
+    file.forEach((category, count) {
+      summary.putIfAbsent(category as String, () => 0);
+      summary[category as String] += count as int;
+    });
+  }
+  var categories = summary.keys.toList()..sort();
+  for (var category in categories) {
+    print('$category:  ${summary[category]}');
+  }
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 6391890..6b93319 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -114,7 +114,6 @@
 build_integration/test/*: SkipByDesign # Only meant to run on vm, most use dart:mirrors and dart:io
 compiler/tool/*: SkipByDesign # Only meant to run on vm
 dartdev/test/*: SkipByDesign # Only meant to run on vm
-dartfix/test/*: SkipByDesign # Only meant to run on vm
 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, Pass
diff --git a/pkg/scrape/lib/scrape.dart b/pkg/scrape/lib/scrape.dart
index 6359494..32ab6715 100644
--- a/pkg/scrape/lib/scrape.dart
+++ b/pkg/scrape/lib/scrape.dart
@@ -50,6 +50,10 @@
   int get scrapedLineCount => _scrapedLineCount;
   int _scrapedLineCount = 0;
 
+  /// The number of files that could not be parsed.
+  int get errorFileCount => _errorFileCount;
+  int _errorFileCount = 0;
+
   final Map<String, Histogram> _histograms = {};
 
   /// Whether we're in the middle of writing the running file count and need a
@@ -151,10 +155,22 @@
       histogram.printCounts(name);
     });
 
+    String count(int n, String unit) {
+      if (n == 1) return '1 $unit';
+      return '$n ${unit}s';
+    }
+
     var elapsed = _formatDuration(watch.elapsed);
-    var lines = _scrapedLineCount != 1 ? '$_scrapedLineCount lines' : '1 line';
-    var files = _scrapedFileCount != 1 ? '$_scrapedFileCount files' : '1 file';
-    print('Took $elapsed to scrape $lines in $files.');
+    var lines = count(_scrapedLineCount, 'line');
+    var files = count(_scrapedFileCount, 'file');
+    var message = 'Took $elapsed to scrape $lines in $files.';
+
+    if (_errorFileCount > 0) {
+      var errors = count(_errorFileCount, 'file');
+      message += ' ($errors could not be parsed.)';
+    }
+
+    print(message);
   }
 
   /// Display [message], clearing the line if necessary.
@@ -242,16 +258,18 @@
     var source = file.readAsStringSync();
 
     var errorListener = ErrorListener(this, _printErrors);
+    var featureSet = FeatureSet.latestLanguageVersion();
 
     // Tokenize the source.
     var reader = CharSequenceReader(source);
     var stringSource = StringSource(source, file.path);
     var scanner = Scanner(stringSource, reader, errorListener);
+    scanner.configureFeatures(
+        featureSet: featureSet, featureSetForOverriding: featureSet);
     var startToken = scanner.tokenize();
 
     // Parse it.
-    var parser = Parser(stringSource, errorListener,
-        featureSet: FeatureSet.latestLanguageVersion());
+    var parser = Parser(stringSource, errorListener, featureSet: featureSet);
     parser.enableOptionalNewAndConst = true;
     parser.enableSetLiterals = true;
 
@@ -277,6 +295,12 @@
       return;
     }
 
+    // Don't process files with syntax errors.
+    if (errorListener.hadError) {
+      _errorFileCount++;
+      return;
+    }
+
     var lineInfo = LineInfo(scanner.lineStarts);
 
     _scrapedFileCount++;
diff --git a/pkg/scrape/lib/src/error_listener.dart b/pkg/scrape/lib/src/error_listener.dart
index 69c9118..655959c 100644
--- a/pkg/scrape/lib/src/error_listener.dart
+++ b/pkg/scrape/lib/src/error_listener.dart
@@ -9,11 +9,16 @@
 class ErrorListener implements AnalysisErrorListener {
   final Scrape _scrape;
   final bool _printErrors;
+  bool _hadError = false;
 
   ErrorListener(this._scrape, this._printErrors);
 
+  bool get hadError => _hadError;
+
   @override
   void onError(AnalysisError error) {
+    _hadError = true;
+
     if (_printErrors) {
       _scrape.log(error);
     }
diff --git a/pkg/scrape/pubspec.yaml b/pkg/scrape/pubspec.yaml
index a011644..ffdaff1 100644
--- a/pkg/scrape/pubspec.yaml
+++ b/pkg/scrape/pubspec.yaml
@@ -2,11 +2,15 @@
 description: Helper package for analyzing the syntax of Dart programs.
 # This package is not intended for consumption on pub.dev. DO NOT publish.
 publish_to: none
+
 environment:
   sdk: ^2.10.0
+
 dependencies:
   args: ^1.6.0
-  analyzer: ^0.40.4
+  analyzer:
+    path: ../analyzer
   path: ^1.7.0
+
 dev_dependencies:
   pedantic: ^1.9.2
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index b2c8c47..5468af7 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -248,7 +248,7 @@
   }
 
   List<String> sideBySide(List<String> a, List<String> b, int columns) {
-    List<String> result = new List<String>(a.length);
+    List<String> result = new List<String>.filled(a.length, null);
     for (int i = 0; i < a.length; ++i) {
       String left = a[i].padRight(columns).substring(0, columns);
       String right = b[i].padRight(columns).substring(0, columns);
diff --git a/pkg/status_file/lib/src/disjunctive.dart b/pkg/status_file/lib/src/disjunctive.dart
index 4c461b2..b94f17d 100644
--- a/pkg/status_file/lib/src/disjunctive.dart
+++ b/pkg/status_file/lib/src/disjunctive.dart
@@ -174,7 +174,7 @@
 /// finished the function returns all combined min sets.
 List<List<Expression>> _combineMinSets(
     List<List<Expression>> minSets, List<List<Expression>> primeImplicants) {
-  List<List<LogicExpression>> combined = new List<List<LogicExpression>>();
+  List<List<LogicExpression>> combined = <List<LogicExpression>>[];
   var addedInThisIteration = new Set<List<Expression>>();
   for (var i = 0; i < minSets.length; i++) {
     var minSet = minSets[i];
@@ -317,7 +317,7 @@
 // Computes the difference between two sets of expressions in disjunctive normal
 // form. if the difference is a negation, the difference is only counted once.
 List<Expression> _difference(List<Expression> As, List<Expression> Bs) {
-  var difference = new List<Expression>()
+  var difference = <Expression>[]
     ..addAll(As.where((a) => _findFirst(a, Bs) == null))
     ..addAll(Bs.where((b) => _findFirst(b, As) == null));
   for (var expression in difference.toList()) {
@@ -351,7 +351,7 @@
 /// were combined.
 List<List<LogicExpression>> _uniqueMinSets(
     List<List<LogicExpression>> minSets) {
-  var uniqueMinSets = new List<List<LogicExpression>>();
+  var uniqueMinSets = <List<LogicExpression>>[];
   for (int i = 0; i < minSets.length; i++) {
     bool foundEqual = false;
     for (var j = i - 1; j >= 0; j--) {
diff --git a/pkg/telemetry/pubspec.yaml b/pkg/telemetry/pubspec.yaml
index c3ba85f..ca646aa 100644
--- a/pkg/telemetry/pubspec.yaml
+++ b/pkg/telemetry/pubspec.yaml
@@ -9,7 +9,8 @@
 
 dependencies:
   http: ^0.12.0
-  meta: ^1.0.2
+  meta:
+    path: ../meta
   path: ^1.4.0
   stack_trace: ^1.7.0
   usage: ^3.2.0+1
diff --git a/pkg/test_runner/bin/test_runner.dart b/pkg/test_runner/bin/test_runner.dart
index 3f5e048..7cb77ae 100644
--- a/pkg/test_runner/bin/test_runner.dart
+++ b/pkg/test_runner/bin/test_runner.dart
@@ -23,22 +23,22 @@
 /// The default test directory layout is documented in "test_suite.dart", above
 /// `factory StandardTestSuite.forDirectory`.
 import "package:test_runner/src/options.dart";
+import "package:test_runner/src/build_configurations.dart";
 import "package:test_runner/src/test_configurations.dart";
 
 /// Runs all of the tests specified by the given command line [arguments].
-void main(List<String> arguments) {
+void main(List<String> arguments) async {
   // Parse the command line arguments to a configuration.
   var parser = OptionsParser();
+  var configurations = <TestConfiguration>[];
   try {
-    var configurations = parser.parse(arguments);
-    if (configurations == null || configurations.isEmpty) return;
-
-    // Run all of the configured tests.
-    // TODO(26372): Ensure that all tasks complete and return a future from this
-    // function.
-    testConfigurations(configurations);
+    configurations = parser.parse(arguments);
   } on OptionParseException catch (exception) {
     print(exception.message);
     exit(1);
   }
+  if (configurations.isEmpty) return;
+  await buildConfigurations(configurations);
+  // Run all of the configured tests.
+  await testConfigurations(configurations);
 }
diff --git a/pkg/test_runner/lib/bot_results.dart b/pkg/test_runner/lib/bot_results.dart
index 88b2eb1..b5032f6 100644
--- a/pkg/test_runner/lib/bot_results.dart
+++ b/pkg/test_runner/lib/bot_results.dart
@@ -26,10 +26,8 @@
   final String outcome;
   final bool changed;
   final String commitHash;
-  // TODO(karlklose): this field is unnecessary with extended results and
-  // should be removed.
-  final bool flaked;
-  final bool isFlaky;
+  final bool flaked; // From optional flakiness_data argument to constructor.
+  final bool isFlaky; // From results.json after it is extended.
   final String previousOutcome;
 
   Result(
@@ -55,6 +53,7 @@
         isFlaky = map["flaky"] as bool,
         previousOutcome = map["previous_result"] as String,
         flaked = flakinessData != null &&
+            (flakinessData["active"] ?? true) == true &&
             (flakinessData["outcomes"] as List).contains(map["result"]);
 
   String get key => "$configuration:$name";
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 521e3c9..6625a5a 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -147,9 +147,16 @@
 /// [testJSDir] is the relative path to the build directory where the
 /// dartdevc-generated JS file is stored. [nonNullAsserts] enables non-null
 /// assertions for non-nullable method parameters when running with weak null
-/// safety.
-String dartdevcHtml(String testName, String testNameAlias, String testJSDir,
-    Compiler compiler, NnbdMode mode, bool nonNullAsserts) {
+/// safety. [weakNullSafetyErrors] enables null safety type violations to throw
+/// when running in weak mode.
+String dartdevcHtml(
+    String testName,
+    String testNameAlias,
+    String testJSDir,
+    Compiler compiler,
+    NnbdMode mode,
+    bool nonNullAsserts,
+    bool weakNullSafetyErrors) {
   var testId = pathToJSIdentifier(testName);
   var testIdAlias = pathToJSIdentifier(testNameAlias);
   var isNnbd = mode != NnbdMode.legacy;
@@ -233,7 +240,8 @@
   };
 
   if ($isNnbd) {
-    sdk.dart.weakNullSafetyWarnings(!$isNnbdStrong);
+    sdk.dart.weakNullSafetyWarnings(!($weakNullSafetyErrors || $isNnbdStrong));
+    sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
     sdk.dart.nonNullAsserts($nonNullAsserts);
   }
 
diff --git a/pkg/test_runner/lib/src/browser_controller.dart b/pkg/test_runner/lib/src/browser_controller.dart
index 708d185..fce0fca 100644
--- a/pkg/test_runner/lib/src/browser_controller.dart
+++ b/pkg/test_runner/lib/src/browser_controller.dart
@@ -298,8 +298,8 @@
     // We run killAndResetSafari in a Zone as opposed to running an external
     // process. The Zone allows us to collect its output, and protect the rest
     // of the test infrastructure against errors in it.
-    runZoned(zoneWrapper,
-        zoneSpecification: specification, onError: handleUncaughtError);
+    runZonedGuarded(zoneWrapper, handleUncaughtError,
+        zoneSpecification: specification);
 
     try {
       await completer.future;
diff --git a/pkg/test_runner/lib/src/build_configurations.dart b/pkg/test_runner/lib/src/build_configurations.dart
new file mode 100644
index 0000000..6179997
--- /dev/null
+++ b/pkg/test_runner/lib/src/build_configurations.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'configuration.dart';
+import 'utils.dart';
+
+Future buildConfigurations(List<TestConfiguration> configurations) async {
+  var startTime = DateTime.now();
+  if (!configurations.first.build) return;
+  final buildTargets = <String>{};
+  final modes = <Mode>{};
+  final architectures = <Architecture>{};
+  final systems = <System>{};
+  for (final configuration in configurations) {
+    final inner = configuration.configuration;
+    buildTargets.addAll(_selectBuildTargets(inner));
+    modes.add(inner.mode);
+    architectures.add(inner.architecture);
+    systems.add(inner.system);
+  }
+  if (buildTargets.isEmpty) return;
+  if (systems.length > 1) {
+    print('Unimplemented: building for multiple systems ${systems.join(',')}');
+    exit(1);
+  }
+  final system = systems.single;
+  final osFlags = <String>[];
+  if (system == System.android) {
+    osFlags.addAll(['--os', 'android']);
+  } else if (system == System.fuchsia) {
+    osFlags.addAll(['--os', 'fuchsia']);
+  } else {
+    final host = System.find(Platform.operatingSystem);
+    if (system != host) {
+      print('Unimplemented: running tests for $system on $host');
+      exit(1);
+    }
+  }
+  final command = [
+    'tools/build.py',
+    '-m',
+    modes.join(','),
+    '-a',
+    architectures.join(','),
+    ...osFlags,
+    ...buildTargets
+  ];
+  print('Running command: python ${command.join(' ')}');
+  final process = await Process.start('python', command);
+  stdout.nonBlocking.addStream(process.stdout);
+  stderr.nonBlocking.addStream(process.stderr);
+  final exitCode = await process.exitCode;
+  if (exitCode != 0) {
+    print('exit code: $exitCode');
+  }
+  var buildTime = niceTime(DateTime.now().difference(startTime));
+  print('--- Build time: $buildTime ---');
+}
+
+List<String> _selectBuildTargets(Configuration inner) {
+  final result = <String>[];
+  final compiler = inner.compiler;
+  const targetsForCompilers = {
+    Compiler.dartk: ['runtime'],
+    Compiler.dartkp: ['runtime', 'dart_precompiled_runtime'],
+    Compiler.appJitk: ['runtime'],
+    Compiler.fasta: ['create_sdk', 'dartdevc_test', 'kernel_platform_files'],
+    Compiler.dartdevk: ['dartdevc_test'],
+    Compiler.dart2js: ['create_sdk'],
+    Compiler.dart2analyzer: ['create_sdk'],
+    Compiler.specParser: <String>[],
+  };
+  result.addAll(targetsForCompilers[compiler]);
+
+  if (compiler == Compiler.dartkp &&
+      [Architecture.arm, Architecture.arm64, Architecture.arm_x64]
+          .contains(inner.architecture)) {
+    result.add('gen_snapshot');
+  }
+
+  if (compiler == Compiler.dartdevk && !inner.useSdk) {
+    result
+      ..remove('dartdevc_test')
+      ..add('dartdevc_test_local');
+  }
+
+  return result;
+}
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 6ea866c..d92797d 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -1085,8 +1085,6 @@
 }
 
 abstract class VMKernelCompilerMixin {
-  static final causalAsyncStacksRegExp = RegExp('--causal[_-]async[_-]stacks');
-
   TestConfiguration get _configuration;
 
   bool get _useSdk;
@@ -1116,8 +1114,6 @@
 
     var isProductMode = _configuration.configuration.mode == Mode.product;
 
-    var causalAsyncStacks = arguments.any(causalAsyncStacksRegExp.hasMatch);
-
     var args = [
       _isAot ? '--aot' : '--no-aot',
       '--platform=$vmPlatform',
@@ -1129,7 +1125,6 @@
           name.startsWith('--packages=') ||
           name.startsWith('--enable-experiment=')),
       '-Ddart.vm.product=$isProductMode',
-      '-Ddart.developer.causal_async_stacks=$causalAsyncStacks',
       if (_enableAsserts ||
           arguments.contains('--enable-asserts') ||
           arguments.contains('--enable_asserts'))
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index a0bafae..12af614 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -27,6 +27,7 @@
       {this.configuration,
       this.progress,
       this.selectors,
+      this.build,
       this.testList,
       this.repeat,
       this.batch,
@@ -82,6 +83,7 @@
 
   final bool batch;
   final bool batchDart2JS;
+  final bool build;
   final bool copyCoreDumps;
   final bool rr;
   final bool fastTestsOnly;
diff --git a/pkg/test_runner/lib/src/fuchsia.dart b/pkg/test_runner/lib/src/fuchsia.dart
index 182fe4b..a3880c5 100644
--- a/pkg/test_runner/lib/src/fuchsia.dart
+++ b/pkg/test_runner/lib/src/fuchsia.dart
@@ -147,6 +147,9 @@
 
   Future<void> _publishPackage(String buildDir, String mode) async {
     var packageFile = '$buildDir/gen/dart_test_$mode/dart_test_$mode.far';
+    if (!File(packageFile).existsSync()) {
+      throw 'File $packageFile does not exist. Please build fuchsia_test_package.';
+    }
     DebugLogger.info('Publishing package: $packageFile');
     var result = await Process.run(fpubTool, [packageFile]);
     if (result.exitCode != 0) {
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 231dd81..6d682de 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -15,7 +15,7 @@
 import 'utils.dart';
 
 const _defaultTestSelectors = [
-  'samples',
+  'samples_2',
   'standalone_2',
   'corelib_2',
   'language_2',
@@ -164,6 +164,8 @@
 test options, specifying how tests should be run.''',
         abbr: 'n',
         hide: true),
+    _Option.bool(
+        'build', 'Build the necessary targets to test this configuration'),
     // TODO(sigmund): rename flag once we migrate all dart2js bots to the test
     // matrix.
     _Option.bool('host_checked', 'Run compiler with assertions enabled.',
@@ -355,6 +357,7 @@
   /// For printing out reproducing command lines, we don't want to add these
   /// options.
   static final _denylistedOptions = {
+    'build',
     'build_directory',
     'chrome',
     'clean_exit',
@@ -749,6 +752,7 @@
           configuration: innerConfiguration,
           progress: progress,
           selectors: selectors,
+          build: data["build"] as bool,
           testList: data["test_list_contents"] as List<String>,
           repeat: data["repeat"] as int,
           batch: !(data["noBatch"] as bool),
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 947666f..7b29ea8 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -778,7 +778,7 @@
     // Start batch processes if needed.
     var runners = _batchProcesses[identifier];
     if (runners == null) {
-      runners = List<BatchRunnerProcess>(maxProcesses);
+      runners = List<BatchRunnerProcess>.filled(maxProcesses, null);
       for (var i = 0; i < maxProcesses; i++) {
         runners[i] = BatchRunnerProcess(useJson: identifier == "fasta");
       }
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 1aa0891..342810a 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -412,6 +412,7 @@
     if (isCrashExpected) {
       runtimeArgs.insert(0, '--suppress-core-dump');
     }
+    runtimeArgs.insert(runtimeArgs.length - 1, '--disable-dart-dev');
     return [
       VMCommand(FuchsiaEmulator.fsshTool, runtimeArgs, environmentOverrides)
     ];
diff --git a/pkg/test_runner/lib/src/test_configurations.dart b/pkg/test_runner/lib/src/test_configurations.dart
index 0b3fb76..4487429 100644
--- a/pkg/test_runner/lib/src/test_configurations.dart
+++ b/pkg/test_runner/lib/src/test_configurations.dart
@@ -18,6 +18,8 @@
 import 'test_suite.dart';
 import 'utils.dart';
 
+export 'configuration.dart' show TestConfiguration;
+
 /// The directories that contain test suites which follow the conventions
 /// required by [StandardTestSuite]'s forDirectory constructor.
 ///
@@ -34,6 +36,7 @@
   Path('runtime/observatory_2/tests/service_2'),
   Path('runtime/observatory_2/tests/observatory_ui_2'),
   Path('samples'),
+  Path('samples_2'),
   Path('samples-dev'),
   Path('tests/corelib'),
   Path('tests/corelib_2'),
@@ -41,7 +44,6 @@
   Path('tests/dart2js_2'),
   Path('tests/dartdevc'),
   Path('tests/dartdevc_2'),
-  Path('tests/kernel'),
   Path('tests/language'),
   Path('tests/language_2'),
   Path('tests/lib'),
@@ -53,6 +55,7 @@
   Path('utils/tests/peg'),
 ];
 
+// TODO(26372): Ensure that the returned future awaits on all started tasks.
 Future testConfigurations(List<TestConfiguration> configurations) async {
   var startTime = DateTime.now();
 
@@ -147,6 +150,12 @@
           // vm tests contain both cc tests (added here) and dart tests (added
           // in [TEST_SUITE_DIRECTORIES]).
           testSuites.add(VMTestSuite(configuration));
+        } else if (key == 'ffi_unit') {
+          // 'ffi_unit' contains cc non-DartVM unit tests.
+          //
+          // This is a separate suite from 'ffi', because we want to run the
+          // 'ffi' suite on many architectures, but 'ffi_unit' only on one.
+          testSuites.add(FfiTestSuite(configuration));
         } else if (configuration.compiler == Compiler.dart2analyzer) {
           if (key == 'analyze_library') {
             testSuites.add(AnalyzeLibraryTestSuite(configuration));
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index e788744..6f5d5f2 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -364,6 +364,128 @@
   VMUnitTest(this.name, this.expectation);
 }
 
+/// A specialized [TestSuite] that runs tests written in C to unit test
+/// the standalone (non-DartVM) C/C++ code.
+///
+/// The tests are compiled into an executable for all [targetAbis] by the
+/// build step.
+/// An executable lists its tests when run with the --list command line flag.
+/// Individual tests are run by specifying them on the command line.
+class FfiTestSuite extends TestSuite {
+  Map<String, String> runnerPaths;
+  final String dartDir;
+
+  static const targetAbis = [
+    "arm64_android",
+    "arm64_ios",
+    "arm64_linux",
+    "arm64_macos",
+    "arm_android",
+    "arm_ios",
+    "arm_linux",
+    "ia32_android",
+    "ia32_linux",
+    "ia32_win",
+    "x64_ios",
+    "x64_linux",
+    "x64_macos",
+    "x64_win",
+  ];
+
+  FfiTestSuite(TestConfiguration configuration)
+      : dartDir = Repository.dir.toNativePath(),
+        super(configuration, "ffi_unit", []) {
+    final binarySuffix = Platform.operatingSystem == 'windows' ? '.exe' : '';
+
+    // For running the tests we use multiple binaries, one for each target ABI.
+    runnerPaths = Map.fromIterables(
+        targetAbis,
+        targetAbis.map((String config) =>
+            '$buildDir/run_ffi_unit_tests_$config$binarySuffix'));
+  }
+
+  void findTestCases(TestCaseEvent onTest, Map testCache) {
+    final statusFiles =
+        statusFilePaths.map((statusFile) => "$dartDir/$statusFile").toList();
+    final expectations = ExpectationSet.read(statusFiles, configuration);
+
+    runnerPaths.forEach((runnerName, runnerPath) {
+      try {
+        for (final test in _listTests(runnerName, runnerPath)) {
+          _addTest(expectations, test, onTest);
+        }
+      } catch (error, s) {
+        print(
+            "Fatal error occurred while parsing tests from $runnerName: $error");
+        print(s);
+        exit(1);
+      }
+    });
+  }
+
+  void _addTest(
+      ExpectationSet testExpectations, FfiUnitTest test, TestCaseEvent onTest) {
+    final fullName = '${test.runnerName}/${test.name}';
+    var expectations = testExpectations.expectations(fullName);
+
+    // Get the expectation from the test itself.
+    final testExpectation = Expectation.find(test.expectation);
+
+    // Update the legacy status-file based expectations to include
+    // [testExpectation].
+    if (testExpectation != Expectation.pass) {
+      expectations = {...expectations, testExpectation};
+      expectations.remove(Expectation.pass);
+    }
+
+    // Update the new workflow based expectations to include [testExpectation].
+    final testFile = TestFile.vmUnitTest(
+        hasSyntaxError: false,
+        hasCompileError: testExpectation == Expectation.compileTimeError,
+        hasRuntimeError: testExpectation == Expectation.runtimeError,
+        hasStaticWarning: false,
+        hasCrash: testExpectation == Expectation.crash);
+
+    final args = [
+      // This test has no VM, but pipe through vmOptions as test options.
+      // Passing `--vm-options=--update` will update all test expectations.
+      ...configuration.vmOptions,
+      test.name,
+    ];
+    final command = ProcessCommand(
+        'run_ffi_unit_test', test.runnerPath, args, environmentOverrides);
+
+    _addTestCase(testFile, fullName, [command], expectations, onTest);
+  }
+
+  Iterable<FfiUnitTest> _listTests(String runnerName, String runnerPath) {
+    final result = Process.runSync(runnerPath, ["--list"]);
+    if (result.exitCode != 0) {
+      throw "Failed to list tests: '$runnerPath --list'. "
+          "Process exited with ${result.exitCode}";
+    }
+
+    return (result.stdout as String)
+        .split('\n')
+        .map((line) => line.trim())
+        .where((name) => name.isNotEmpty)
+        .map((String line) {
+      final parts = line.split(' ');
+      assert(parts.length == 2);
+      return FfiUnitTest(runnerName, runnerPath, parts[0], parts[1]);
+    });
+  }
+}
+
+class FfiUnitTest {
+  final String runnerName;
+  final String runnerPath;
+  final String name;
+  final String expectation;
+
+  FfiUnitTest(this.runnerName, this.runnerPath, this.name, this.expectation);
+}
+
 /// A standard [TestSuite] implementation that searches for tests in a
 /// directory, and creates [TestCase]s that compile and/or run them.
 class StandardTestSuite extends TestSuite {
@@ -740,7 +862,6 @@
 
     print("Cannot create URL for path $file. Not in build or dart directory.");
     exit(1);
-    throw "unreachable";
   }
 
   String _uriForBrowserTest(String pathComponent) {
@@ -803,8 +924,16 @@
             Path(compilationTempDir).relativeTo(Repository.dir).toString();
         var nullAssertions =
             testFile.sharedOptions.contains('--null-assertions');
-        content = dartdevcHtml(nameNoExt, nameFromModuleRootNoExt, jsDir,
-            configuration.compiler, configuration.nnbdMode, nullAssertions);
+        var weakNullSafetyErrors =
+            testFile.ddcOptions.contains('--weak-null-safety-errors');
+        content = dartdevcHtml(
+            nameNoExt,
+            nameFromModuleRootNoExt,
+            jsDir,
+            configuration.compiler,
+            configuration.nnbdMode,
+            nullAssertions,
+            weakNullSafetyErrors);
       }
     }
 
diff --git a/pkg/test_runner/lib/test_runner.dart b/pkg/test_runner/lib/test_runner.dart
index e0843da..c02d3e7 100644
--- a/pkg/test_runner/lib/test_runner.dart
+++ b/pkg/test_runner/lib/test_runner.dart
@@ -176,10 +176,10 @@
 }
 
 /// Exception thrown when looking up the build for a commit failed.
-class CommitNotBuiltException implements Exception {
+class NoResultsForCommitException implements Exception {
   final String reason;
 
-  CommitNotBuiltException(this.reason);
+  NoResultsForCommitException(this.reason);
 
   String toString() => reason;
 }
@@ -212,7 +212,7 @@
   client.close();
   var builds = object["builds"] as List<dynamic>;
   if (builds == null || builds.isEmpty) {
-    throw CommitNotBuiltException(
+    throw NoResultsForCommitException(
         "Builder $builder hasn't built commit $commit");
   }
   var build = builds.last;
@@ -220,17 +220,26 @@
   var buildAddressTag =
       tags.firstWhere((tag) => tag.startsWith("build_address:"));
   var buildAddress = buildAddressTag.substring("build_address:".length);
+  var buildNumber = int.parse(buildAddress.split("/").last);
   if (build["status"] != "COMPLETED") {
-    throw CommitNotBuiltException("Build $buildAddress isn't completed yet");
+    throw NoResultsForCommitException(
+        "Build $buildAddress isn't completed yet");
   }
-  return BuildSearchResult(int.parse(buildAddress.split("/").last), commit);
+  var resultsPath = buildFileCloudPath(builder, "$buildNumber", "results.json");
+  var flakyPath = buildFileCloudPath(builder, "$buildNumber", "flaky.json");
+  if (await lsGsutil(resultsPath) == null ||
+      await lsGsutil(flakyPath) == null) {
+    throw NoResultsForCommitException(
+        "Build $buildAddress did not upload results");
+  }
+  return BuildSearchResult(buildNumber, commit);
 }
 
 Future<BuildSearchResult> searchForApproximateBuild(
     String builder, String commit) async {
   try {
     return await searchForBuild(builder, commit);
-  } on CommitNotBuiltException catch (e) {
+  } on NoResultsForCommitException catch (e) {
     print("Warning: $e, searching for an inexact previous build...");
     var limit = 25;
     var arguments = [
@@ -255,7 +264,7 @@
             "Warning: Searching for inexact baseline build: $e, continuing...");
       }
     }
-    throw CommitNotBuiltException(
+    throw NoResultsForCommitException(
         "Failed to locate approximate baseline results for "
         "$commit in past $limit commits");
   }
diff --git a/pkg/test_runner/pubspec.yaml b/pkg/test_runner/pubspec.yaml
index be9765a..9fad3c1 100644
--- a/pkg/test_runner/pubspec.yaml
+++ b/pkg/test_runner/pubspec.yaml
@@ -22,10 +22,14 @@
 dev_dependencies:
   expect:
     path: ../expect
-  glob:
-    path: ../../third_party/pkg/glob    
+  file: any
+  glob: any
 dependency_overrides:
   # Other packages in the dependency graph have normal hosted dependencies on
   # this, so just override it to force the local one.
   args:
     path: ../../third_party/pkg/args
+  file:
+    path: ../../third_party/pkg/file/packages/file
+  glob:
+    path: ../../third_party/pkg/glob
diff --git a/pkg/test_runner/tool/update_static_error_tests.dart b/pkg/test_runner/tool/update_static_error_tests.dart
index 5364fc2..add8fe5 100644
--- a/pkg/test_runner/tool/update_static_error_tests.dart
+++ b/pkg/test_runner/tool/update_static_error_tests.dart
@@ -7,7 +7,9 @@
 import 'dart:io';
 
 import 'package:args/args.dart';
+import 'package:file/file.dart' as pkg_file;
 import 'package:glob/glob.dart';
+import 'package:glob/list_local_fs.dart';
 import 'package:path/path.dart' as p;
 
 import 'package:test_runner/src/command_output.dart';
@@ -130,7 +132,7 @@
   for (var entry in glob.listSync(root: root)) {
     if (!entry.path.endsWith(".dart")) continue;
 
-    if (entry is File) {
+    if (entry is pkg_file.File) {
       await _processFile(entry,
           dryRun: dryRun,
           remove: removeSources,
@@ -301,7 +303,7 @@
   return errors;
 }
 
-/// Find the most recently-built [binary] in any of the build directories.
+/// Find the most recently-built binary [name] in any of the build directories.
 String _findBinary(String name, String windowsExtension) {
   var binary = Platform.isWindows ? "$name.$windowsExtension" : name;
 
diff --git a/pkg/testing/lib/src/analyze.dart b/pkg/testing/lib/src/analyze.dart
index 0faf99f..099d020 100644
--- a/pkg/testing/lib/src/analyze.dart
+++ b/pkg/testing/lib/src/analyze.dart
@@ -235,11 +235,7 @@
   }
   Stopwatch sw = new Stopwatch()..start();
   Process process = await startDart(
-      analyzer,
-      const <String>["--batch"],
-      dartArguments
-        ..remove("-c")
-        ..add("-DuseFastaScanner=true"));
+      analyzer, const <String>["--batch"], dartArguments..remove("-c"));
   process.stdin.writeln(arguments.join(" "));
   process.stdin.close();
 
diff --git a/pkg/testing/lib/src/test_dart/path.dart b/pkg/testing/lib/src/test_dart/path.dart
index 5d22c0e..3c5fbea 100644
--- a/pkg/testing/lib/src/test_dart/path.dart
+++ b/pkg/testing/lib/src/test_dart/path.dart
@@ -121,7 +121,7 @@
     while (common < length && pathSegments[common] == baseSegments[common]) {
       common++;
     }
-    final segments = new List<String>();
+    final segments = <String>[];
 
     if (common < baseSegments.length && baseSegments[common] == '..') {
       throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
diff --git a/pkg/testing/lib/src/test_dart/status_expression.dart b/pkg/testing/lib/src/test_dart/status_expression.dart
index d1af0ba..200d241 100644
--- a/pkg/testing/lib/src/test_dart/status_expression.dart
+++ b/pkg/testing/lib/src/test_dart/status_expression.dart
@@ -53,7 +53,7 @@
   String expression;
   List<String> tokens;
 
-  Tokenizer(String this.expression) : tokens = new List<String>();
+  Tokenizer(String this.expression) : tokens = <String>[];
 
   // Tokens are : "(", ")", "$", ",", "&&", "||", "==", "!=", and (maximal) \w+.
   static final testRegexp =
diff --git a/pkg/testing/lib/src/test_dart/status_file_parser.dart b/pkg/testing/lib/src/test_dart/status_file_parser.dart
index 60c39f8..1ce711f 100644
--- a/pkg/testing/lib/src/test_dart/status_file_parser.dart
+++ b/pkg/testing/lib/src/test_dart/status_file_parser.dart
@@ -35,9 +35,9 @@
 
   Section.always(this.statusFile, this.lineNumber)
       : condition = null,
-        testRules = new List<TestRule>();
+        testRules = <TestRule>[];
   Section(this.statusFile, this.condition, this.lineNumber)
-      : testRules = new List<TestRule>();
+      : testRules = <TestRule>[];
 
   bool isEnabled(Map<String, String> environment) =>
       condition == null || condition.evaluate(environment);
@@ -58,7 +58,7 @@
 Future<void> ReadTestExpectationsInto(TestExpectations expectations,
     String statusFilePath, Map<String, String> environment) {
   var completer = new Completer();
-  List<Section> sections = new List<Section>();
+  List<Section> sections = <Section>[];
 
   void sectionsRead() {
     for (Section section in sections) {
@@ -233,7 +233,7 @@
     _map.forEach((key, expectations) {
       if (_keyToRegExps[key] != null) return;
       var splitKey = key.split('/');
-      var regExps = new List<RegExp>(splitKey.length);
+      var regExps = new List<RegExp>.filled(splitKey.length, null);
       for (var i = 0; i < splitKey.length; i++) {
         var component = splitKey[i];
         var regExp = _regExpCache[component];
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index fb5d3f1..13aa646 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -155,7 +155,7 @@
   final bool supportCodeCoverage;
   final bool supportHotReload;
 
-  final List<String> errors = new List<String>();
+  final List<String> errors = <String>[];
 
   CompilerOptions options;
 
@@ -621,7 +621,7 @@
 
 void _recordDependencies(
     int isolateId, Component component, Uri packageConfig) {
-  final dependencies = isolateDependencies[isolateId] ??= new List<Uri>();
+  final dependencies = isolateDependencies[isolateId] ??= <Uri>[];
 
   if (component != null) {
     for (var lib in component.libraries) {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index c123f75..eb8f045 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -627,7 +627,7 @@
 /// The list of package names is written into a file '[outputFileName]-packages'.
 Future writeOutputSplitByPackages(Uri source, CompilerOptions compilerOptions,
     KernelCompilationResults compilationResults, String outputFileName) async {
-  final packages = new List<String>();
+  final packages = <String>[];
   await runWithFrontEndCompilerContext(
       source, compilerOptions, compilationResults.component, () async {
     // When loading a kernel file list, flutter_runner and dart_runner expect
@@ -692,11 +692,10 @@
   sortComponent(component);
 
   final packages = new Map<String, List<Library>>();
-  packages['main'] = new List<Library>(); // Always create 'main'.
+  packages['main'] = <Library>[]; // Always create 'main'.
   for (Library lib in component.libraries) {
     packages
-        .putIfAbsent(
-            packageFor(lib, loadedLibraries), () => new List<Library>())
+        .putIfAbsent(packageFor(lib, loadedLibraries), () => <Library>[])
         .add(lib);
   }
   packages.remove(null); // Ignore external libraries.
diff --git a/pkg/vm/lib/metadata/loading_units.dart b/pkg/vm/lib/metadata/loading_units.dart
index 410e0d5..3136fee 100644
--- a/pkg/vm/lib/metadata/loading_units.dart
+++ b/pkg/vm/lib/metadata/loading_units.dart
@@ -68,13 +68,13 @@
 
   @override
   LoadingUnitsMetadata readFromBinary(Node node, BinarySource source) {
-    int length = source.readUInt();
+    int length = source.readUInt30();
     var units = <LoadingUnit>[];
     for (int i = 0; i < length; i++) {
-      int id = source.readUInt();
-      int parentId = source.readUInt();
+      int id = source.readUInt30();
+      int parentId = source.readUInt30();
       var libraryUris = <String>[];
-      int length = source.readUInt();
+      int length = source.readUInt30();
       for (int i = 0; i < length; i++) {
         libraryUris.add(source.readStringReference());
       }
diff --git a/pkg/vm/lib/metadata/procedure_attributes.dart b/pkg/vm/lib/metadata/procedure_attributes.dart
index d6840f2..da78cab 100644
--- a/pkg/vm/lib/metadata/procedure_attributes.dart
+++ b/pkg/vm/lib/metadata/procedure_attributes.dart
@@ -110,8 +110,8 @@
     final bool hasNonThisUses = (flags & kNonThisUsesBit) != 0;
     final bool hasTearOffUses = (flags & kTearOffUsesBit) != 0;
 
-    final int methodOrSetterSelectorId = source.readUInt();
-    final int getterSelectorId = source.readUInt();
+    final int methodOrSetterSelectorId = source.readUInt30();
+    final int getterSelectorId = source.readUInt30();
 
     return new ProcedureAttributesMetadata(
         methodOrSetterCalledDynamically: methodOrSetterCalledDynamically,
diff --git a/pkg/vm/lib/metadata/table_selector.dart b/pkg/vm/lib/metadata/table_selector.dart
index e692529..6784fcc 100644
--- a/pkg/vm/lib/metadata/table_selector.dart
+++ b/pkg/vm/lib/metadata/table_selector.dart
@@ -29,7 +29,7 @@
         flags = 0;
 
   TableSelectorInfo.readFromBinary(BinarySource source)
-      : callCount = source.readUInt(),
+      : callCount = source.readUInt30(),
         flags = source.readByte();
 
   void writeToBinary(BinarySink sink) {
@@ -79,7 +79,7 @@
 
   @override
   TableSelectorMetadata readFromBinary(Node node, BinarySource source) {
-    final int length = source.readUInt();
+    final int length = source.readUInt30();
     final List<TableSelectorInfo> selectors = List<TableSelectorInfo>.generate(
         length, (_) => TableSelectorInfo.readFromBinary(source));
     return TableSelectorMetadata.fromSelectors(selectors);
diff --git a/pkg/vm/lib/metadata/unboxing_info.dart b/pkg/vm/lib/metadata/unboxing_info.dart
index 289819b..7069c05 100644
--- a/pkg/vm/lib/metadata/unboxing_info.dart
+++ b/pkg/vm/lib/metadata/unboxing_info.dart
@@ -23,7 +23,7 @@
 
   UnboxingInfoMetadata.readFromBinary(BinarySource source)
       : unboxedArgsInfo = List<int>.generate(
-            source.readUInt(), (_) => source.readByte(),
+            source.readUInt30(), (_) => source.readByte(),
             growable: true),
         returnInfo = source.readByte();
 
diff --git a/pkg/vm/lib/target/dart_runner.dart b/pkg/vm/lib/target/dart_runner.dart
index fc814ac..928863c 100644
--- a/pkg/vm/lib/target/dart_runner.dart
+++ b/pkg/vm/lib/target/dart_runner.dart
@@ -35,7 +35,6 @@
         'dart:typed_data',
         'dart:nativewrappers',
         'dart:io',
-        'dart:wasm',
 
         // Required for dart_runner.
         'dart:fuchsia.builtin',
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index dc3b107..7746e98 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -41,7 +41,6 @@
         'dart:typed_data',
         'dart:nativewrappers',
         'dart:io',
-        'dart:wasm',
 
         // Required for flutter.
         'dart:ui',
diff --git a/pkg/vm/lib/target/flutter_runner.dart b/pkg/vm/lib/target/flutter_runner.dart
index 816c030..9a2b477 100644
--- a/pkg/vm/lib/target/flutter_runner.dart
+++ b/pkg/vm/lib/target/flutter_runner.dart
@@ -35,7 +35,6 @@
         'dart:typed_data',
         'dart:nativewrappers',
         'dart:io',
-        'dart:wasm',
 
         // Required for flutter_runner.
         'dart:fuchsia.builtin',
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 97cf03a..c117efa 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -50,7 +50,7 @@
   bool get supportsSetLiterals => false;
 
   @override
-  bool get supportsLateFields => !flags.forceLateLoweringForTesting;
+  int get enabledLateLowerings => flags.forceLateLoweringsForTesting;
 
   @override
   bool get supportsLateLoweringSentinel =>
@@ -90,7 +90,6 @@
         'dart:nativewrappers',
         'dart:io',
         'dart:cli',
-        'dart:wasm',
       ];
 
   @override
@@ -465,9 +464,6 @@
     // TODO(alexmarkov): Call this from the front-end in order to have
     //  the same defines when compiling platform.
     assert(map != null);
-    if (map['dart.vm.product'] == 'true') {
-      map['dart.developer.causal_async_stacks'] = 'false';
-    }
     map['dart.isVM'] = 'true';
     // TODO(dartbug.com/36460): Derive dart.library.* definitions from platform.
     for (String library in extraRequiredLibraries) {
diff --git a/pkg/vm/lib/transformations/late_var_init_transformer.dart b/pkg/vm/lib/transformations/late_var_init_transformer.dart
index 1dc1a87..4acb7e4 100644
--- a/pkg/vm/lib/transformations/late_var_init_transformer.dart
+++ b/pkg/vm/lib/transformations/late_var_init_transformer.dart
@@ -49,7 +49,7 @@
 
   List<Statement> _transformStatements(List<Statement> statements) {
     if (!statements.any((s) => _shouldApplyTransform(s))) return null;
-    final List<Statement> newStatements = List<Statement>();
+    final List<Statement> newStatements = <Statement>[];
     for (Statement s in statements) {
       if (_shouldApplyTransform(s)) {
         newStatements.addAll(_transformVariableDeclaration(s));
diff --git a/pkg/vm/lib/transformations/pragma.dart b/pkg/vm/lib/transformations/pragma.dart
index ce3055b..d27f3d8 100644
--- a/pkg/vm/lib/transformations/pragma.dart
+++ b/pkg/vm/lib/transformations/pragma.dart
@@ -12,11 +12,14 @@
 const kNonNullableResultType = "vm:non-nullable-result-type";
 const kResultTypeUsesPassedTypeArguments =
     "result-type-uses-passed-type-arguments";
+const kRecognizedPragmaName = "vm:recognized";
 
 abstract class ParsedPragma {}
 
 enum PragmaEntryPointType { Default, GetterOnly, SetterOnly, CallOnly }
 
+enum PragmaRecognizedType { AsmIntrinsic, GraphIntrinsic, Other }
+
 class ParsedEntryPointPragma extends ParsedPragma {
   final PragmaEntryPointType type;
   ParsedEntryPointPragma(this.type);
@@ -38,6 +41,11 @@
   ParsedNonNullableResultType();
 }
 
+class ParsedRecognized extends ParsedPragma {
+  final PragmaRecognizedType type;
+  ParsedRecognized(this.type);
+}
+
 abstract class PragmaAnnotationParser {
   /// May return 'null' if the annotation does not represent a recognized
   /// @pragma.
@@ -118,6 +126,22 @@
             "pragma: $options";
       case kNonNullableResultType:
         return new ParsedNonNullableResultType();
+      case kRecognizedPragmaName:
+        PragmaRecognizedType type;
+        if (options is StringConstant) {
+          if (options.value == "asm-intrinsic") {
+            type = PragmaRecognizedType.AsmIntrinsic;
+          } else if (options.value == "graph-intrinsic") {
+            type = PragmaRecognizedType.GraphIntrinsic;
+          } else if (options.value == "other") {
+            type = PragmaRecognizedType.Other;
+          }
+        }
+        if (type == null) {
+          throw "ERROR: Unsupported option to '$kRecognizedPragmaName' "
+              "pragma: $options";
+        }
+        return new ParsedRecognized(type);
       default:
         return null;
     }
diff --git a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
index 245d77d..e216685 100644
--- a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
+++ b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
@@ -50,6 +50,16 @@
   component.metadata.clear();
 }
 
+/// Called by the signature shaker to exclude the positional parameters of
+/// certain members whose first few parameters are depended upon by the
+/// protobuf-aware tree shaker.
+bool excludePositionalParametersFromSignatureShaking(Member member) {
+  return member.enclosingClass?.name == 'BuilderInfo' &&
+      member.enclosingLibrary.importUri ==
+          Uri.parse('package:protobuf/protobuf.dart') &&
+      _UnusedFieldMetadataPruner.fieldAddingMethods.contains(member.name.name);
+}
+
 InfoCollector removeUnusedProtoReferences(
     Component component, CoreTypes coreTypes, TransformationInfo info) {
   final protobufUri = Uri.parse('package:protobuf/protobuf.dart');
@@ -213,6 +223,17 @@
     node.body.accept(this);
   }
 
+  String _extractFieldName(Expression expression) {
+    if (expression is StringLiteral) {
+      return expression.value;
+    }
+    if (expression is ConditionalExpression) {
+      return _extractFieldName(expression.otherwise);
+    }
+    throw ArgumentError.value(
+        expression, 'expression', 'Unsupported  expression');
+  }
+
   void _changeCascadeEntry(Expression initializer) {
     if (initializer is MethodInvocation &&
         initializer.interfaceTarget?.enclosingClass == builderInfoClass &&
@@ -222,7 +243,7 @@
       if (!usedTagNumbers.contains(tagNumber)) {
         if (info != null) {
           final fieldName =
-              (initializer.arguments.positional[1] as StringLiteral).value;
+              _extractFieldName(initializer.arguments.positional[1]);
           info.removedMessageFields.add("${visitedClass.name}.$fieldName");
         }
 
diff --git a/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart b/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart
index 38e5913..672d618 100644
--- a/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart
+++ b/pkg/vm/lib/transformations/specializer/list_factory_specializer.dart
@@ -13,6 +13,9 @@
 ///
 /// new List() => new _GrowableList(0)
 /// new List(n) => new _List(n)
+/// new List.empty() => new _List.empty()
+/// new List.empty(growable: false) => new _List.empty()
+/// new List.empty(growable: true) => new _GrowableList.empty()
 /// new List.filled(n, null, growable: true) => new _GrowableList(n)
 /// new List.filled(n, x, growable: true) => new _GrowableList.filled(n, x)
 /// new List.filled(n, null) => new _List(n)
@@ -22,44 +25,57 @@
 ///
 class ListFactorySpecializer extends BaseSpecializer {
   final Procedure _defaultListFactory;
+  final Procedure _listEmptyFactory;
   final Procedure _listFilledFactory;
   final Procedure _listGenerateFactory;
   final Procedure _growableListFactory;
+  final Procedure _growableListEmptyFactory;
   final Procedure _growableListFilledFactory;
   final Procedure _growableListGenerateFactory;
   final Procedure _fixedListFactory;
+  final Procedure _fixedListEmptyFactory;
   final Procedure _fixedListFilledFactory;
   final Procedure _fixedListGenerateFactory;
 
   ListFactorySpecializer(CoreTypes coreTypes)
       : _defaultListFactory =
             coreTypes.index.getMember('dart:core', 'List', ''),
+        _listEmptyFactory =
+            coreTypes.index.getMember('dart:core', 'List', 'empty'),
         _listFilledFactory =
             coreTypes.index.getMember('dart:core', 'List', 'filled'),
         _listGenerateFactory =
             coreTypes.index.getMember('dart:core', 'List', 'generate'),
         _growableListFactory =
             coreTypes.index.getMember('dart:core', '_GrowableList', ''),
+        _growableListEmptyFactory =
+            coreTypes.index.getMember('dart:core', '_GrowableList', 'empty'),
         _growableListFilledFactory =
             coreTypes.index.getMember('dart:core', '_GrowableList', 'filled'),
         _growableListGenerateFactory =
             coreTypes.index.getMember('dart:core', '_GrowableList', 'generate'),
         _fixedListFactory = coreTypes.index.getMember('dart:core', '_List', ''),
+        _fixedListEmptyFactory =
+            coreTypes.index.getMember('dart:core', '_List', 'empty'),
         _fixedListFilledFactory =
             coreTypes.index.getMember('dart:core', '_List', 'filled'),
         _fixedListGenerateFactory =
             coreTypes.index.getMember('dart:core', '_List', 'generate') {
     assert(_defaultListFactory.isFactory);
+    assert(_listEmptyFactory.isFactory);
     assert(_listFilledFactory.isFactory);
     assert(_listGenerateFactory.isFactory);
     assert(_growableListFactory.isFactory);
+    assert(_growableListEmptyFactory.isFactory);
     assert(_growableListFilledFactory.isFactory);
     assert(_growableListGenerateFactory.isFactory);
     assert(_fixedListFactory.isFactory);
+    assert(_fixedListEmptyFactory.isFactory);
     assert(_fixedListFilledFactory.isFactory);
     assert(_fixedListGenerateFactory.isFactory);
     transformers.addAll({
       _defaultListFactory: transformDefaultFactory,
+      _listEmptyFactory: transformListEmptyFactory,
       _listFilledFactory: transformListFilledFactory,
       _listGenerateFactory: transformListGeneratorFactory,
     });
@@ -77,6 +93,24 @@
     }
   }
 
+  TreeNode transformListEmptyFactory(StaticInvocation node) {
+    final args = node.arguments;
+    assert(args.positional.length == 0);
+    final bool growable = _getConstantOptionalArgument(args, 'growable', false);
+    if (growable == null) {
+      return node;
+    }
+    if (growable) {
+      return StaticInvocation(
+          _growableListEmptyFactory, Arguments([], types: args.types))
+        ..fileOffset = node.fileOffset;
+    } else {
+      return StaticInvocation(
+          _fixedListEmptyFactory, Arguments([], types: args.types))
+        ..fileOffset = node.fileOffset;
+    }
+  }
+
   TreeNode transformListFilledFactory(StaticInvocation node) {
     final args = node.arguments;
     assert(args.positional.length == 2);
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 36da3b6..b5c33f7 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -696,7 +696,7 @@
       assert(_type is ConcreteType);
       assert(_type != type);
 
-      _list = new List<ConcreteType>();
+      _list = <ConcreteType>[];
       _list.add(_type);
 
       _type = null;
@@ -828,6 +828,10 @@
   }
 
   bool _isDefaultValueOfFieldObservable() {
+    if (field.isLate) {
+      return false;
+    }
+
     if (field.isStatic) {
       return true;
     }
@@ -962,7 +966,7 @@
     } else if (numSubTypes == 1) {
       return _allocatedSubtypes.single.concreteType;
     } else {
-      List<ConcreteType> types = new List<ConcreteType>();
+      List<ConcreteType> types = <ConcreteType>[];
       for (var sub in _allocatedSubtypes) {
         types.add(sub.concreteType);
       }
@@ -1048,7 +1052,7 @@
 
     List<DartType> flattenedTypeArgs =
         flattenedTypeArgumentsFor(klass, useCache: false);
-    result = new List<Type>(flattenedTypeArgs.length);
+    result = new List<Type>.filled(flattenedTypeArgs.length, null);
     for (int i = 0; i < flattenedTypeArgs.length; ++i) {
       final translated = closedTypeTranslator.translate(flattenedTypeArgs[i]);
       assert(translated is RuntimeType || translated is UnknownType);
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index ba8a56d..2a67d18 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -217,6 +217,22 @@
   bool isMemberReferencedFromNativeCode(Member member) =>
       _membersReferencedFromNativeCode.contains(member);
 
+  PragmaRecognizedType recognizedType(Member member) {
+    for (var annotation in member.annotations) {
+      ParsedPragma pragma = _matcher.parsePragma(annotation);
+      if (pragma is ParsedRecognized) {
+        return pragma.type;
+      }
+    }
+    return null;
+  }
+
+  bool isRecognized(Member member, [List<PragmaRecognizedType> expectedTypes]) {
+    PragmaRecognizedType type = recognizedType(member);
+    return type != null &&
+        (expectedTypes == null || expectedTypes.contains(type));
+  }
+
   /// Simulate the execution of a native method by adding its entry points
   /// using [entryPointsListener]. Returns result type of the native method.
   TypeExpr handleNativeProcedure(
diff --git a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
index e1a947c..8be7d86 100644
--- a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
+++ b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
@@ -10,6 +10,8 @@
 import 'table_selector_assigner.dart';
 import 'types.dart';
 import 'utils.dart';
+import '../protobuf_aware_treeshaker/transformer.dart'
+    show excludePositionalParametersFromSignatureShaking;
 import '../../metadata/procedure_attributes.dart';
 
 /// Transform parameters from optional to required when they are always passed,
@@ -19,23 +21,32 @@
 /// are grouped by table selector ID and thus can cover several implementations.
 ///
 /// Definitions:
+/// - A parameter is checked if it requires a runtime check, either because it
+///   is covariant or it is non-nullable and sound null safety is not enabled.
+///   If sound null safety is not enabled, the analysis currently conservatively
+///   assumes that null assertions are enabled. If we add a flag for null
+///   assertions to gen_kernel, this flag can form part of the definition.
 /// - A parameter is used if it is mentioned in the body (or, for constructors,
-///   an initializer) of any implementation.
+///   an initializer) of any implementation, or it is checked. An occurrence as
+///   an argument to a call (a use dependency) is only considered a use if the
+///   corresponding target parameter is used.
 /// - A parameter can be eliminated if either:
-///   1. it is not used; or
-///   2. it is never passed and is not written to in any implementation.
+///   1. it is not used,
+///   2. it is never passed and is not written to in any implementation, or
+///   3. it is a constant (though not necessarily the same constant) in every
+///      implementation and is neither written to nor checked.
 /// - A function is eligible if it is not external and is guaranteed to not be
 ///   called with an unknown call signature.
 ///
 /// All eligible signatures are transformed such that they contain, in order:
-/// 1. All used positional parameters that are always passed, as required
-///    positional parameters.
-/// 2. All used named parameters that are always passed, as required positional
-///    parameters, alphabetically by name.
-/// 3. All used positional parameters that are not always passed and can't be
+/// 1. All positional parameters that are always passed and can't be
+///    eliminated, as required positional parameters.
+/// 2. All named parameters that are always passed and can't be eliminated,
+///    as required positional parameters, alphabetically by name.
+/// 3. All positional parameters that are not always passed and can't be
 ///    eliminated, as positional parameters, each one required iff it was
 ///    originally required.
-/// 4. All used named parameters that are not always passed and can't be
+/// 4. All named parameters that are not always passed and can't be
 ///    eliminated, as named parameters in alphabetical order.
 class SignatureShaker {
   final TypeFlowAnalysis typeFlowAnalysis;
@@ -64,8 +75,48 @@
 
   void transformComponent(Component component) {
     _Collect(this).visitComponent(component);
+    _resolveUseDependencies();
     _Transform(this).visitComponent(component);
   }
+
+  void _resolveUseDependencies() {
+    List<_ParameterInfo> worklist = [];
+    for (_ProcedureInfo info in _memberInfo.values) {
+      _addUseDependenciesForProcedure(info, worklist);
+    }
+    for (_ProcedureInfo info in _selectorInfo.values) {
+      _addUseDependenciesForProcedure(info, worklist);
+    }
+    while (worklist.isNotEmpty) {
+      _ParameterInfo param = worklist.removeLast();
+      for (_ParameterInfo dependencyParam in param.useDependencies) {
+        if (!dependencyParam.isRead) {
+          dependencyParam.isRead = true;
+          if (dependencyParam.useDependencies != null) {
+            worklist.add(dependencyParam);
+          }
+        }
+      }
+    }
+  }
+
+  void _addUseDependenciesForProcedure(
+      _ProcedureInfo info, List<_ParameterInfo> worklist) {
+    for (_ParameterInfo param in info.positional) {
+      _addUseDependenciesForParameter(param, worklist);
+    }
+    for (_ParameterInfo param in info.named.values) {
+      _addUseDependenciesForParameter(param, worklist);
+    }
+  }
+
+  void _addUseDependenciesForParameter(
+      _ParameterInfo param, List<_ParameterInfo> worklist) {
+    if ((param.isUsed || !param.info.eligible) &&
+        param.useDependencies != null) {
+      worklist.add(param);
+    }
+  }
 }
 
 class _ProcedureInfo {
@@ -74,6 +125,11 @@
   int callCount = 0;
   bool eligible = true;
 
+  /// Whether positional parameters can be eliminated from this member. Some
+  /// protobuf methods require these parameters to be preserved for the
+  /// protobuf-aware tree shaker to function.
+  bool canEliminatePositional = true;
+
   _ParameterInfo ensurePositional(int i) {
     if (positional.length <= i) {
       assert(positional.length == i);
@@ -103,32 +159,49 @@
   int passCount = 0;
   bool isRead = false;
   bool isWritten = false;
+  bool isChecked = false;
+  bool isConstant = true;
+
+  /// List of parameter variables which were passed as arguments via this
+  /// parameter. When this parameter is considered used, all [useDependencies]
+  /// parameters should be transitively marked as read.
+  List<_ParameterInfo> useDependencies = null;
 
   _ParameterInfo(this.info, this.index);
 
   bool get isNamed => index == null;
 
-  bool get isUsed => isRead || isWritten;
+  bool get isUsed => isRead || isWritten || isChecked;
 
   bool get isAlwaysPassed => passCount == info.callCount;
 
   bool get isNeverPassed => passCount == 0;
 
-  bool get canBeEliminated => !isUsed || isNeverPassed && !isWritten;
+  bool get canBeEliminated =>
+      (!isUsed || (isNeverPassed || isConstant && !isChecked) && !isWritten) &&
+      (isNamed || info.canEliminatePositional);
 
-  void observeImplicitChecks(
+  void observeParameter(
       Member member, VariableDeclaration param, SignatureShaker shaker) {
-    if (param.isCovariant || param.isGenericCovariantImpl) {
-      // Covariant parameters have implicit type checks, which count as reads.
-      isRead = true;
-    } else if (param.type.nullability == Nullability.nonNullable) {
-      // When run in weak mode with null assertions enabled, parameters with
-      // non-nullable types have implicit null checks, which count as reads.
-      Type type = shaker.typeFlowAnalysis.argumentType(member, param);
-      if (type == null || type is NullableType) {
-        // TFA can't guarantee that the value isn't null. Preserve check.
-        isRead = true;
-      }
+    final Type type = shaker.typeFlowAnalysis.argumentType(member, param);
+
+    // A parameter is considered constant if the TFA has inferred it to have a
+    // constant value in every implementation. The constant value inferred does
+    // not have to be the same across implementations, as it is specialized in
+    // each implementation individually.
+    if (!(type is ConcreteType && type.constant != null ||
+        type is NullableType && type.baseType is EmptyType)) {
+      isConstant = false;
+    }
+
+    // Covariant parameters have implicit type checks, which count as reads.
+    // When run in weak mode with null assertions enabled, parameters with
+    // non-nullable types have implicit null checks, which count as reads.
+    if ((param.isCovariant || param.isGenericCovariantImpl) ||
+        (!shaker.typeFlowAnalysis.target.flags.enableNullSafety &&
+            param.type.nullability == Nullability.nonNullable &&
+            (type == null || type is NullableType))) {
+      isChecked = true;
     }
   }
 }
@@ -136,8 +209,14 @@
 class _Collect extends RecursiveVisitor<void> {
   final SignatureShaker shaker;
 
+  /// Parameters of the current function.
   final Map<VariableDeclaration, _ParameterInfo> localParameters = {};
 
+  /// Set of [VariableGet] nodes corresponding to parameters in the current
+  /// function which are passed as arguments to eligible calls. They are tracked
+  /// via [_ParameterInfo.useDependencies] and not marked as read immediately.
+  final Set<VariableGet> useDependencies = {};
+
   _Collect(this.shaker);
 
   void enterFunction(Member member) {
@@ -145,24 +224,30 @@
     if (info == null) return;
 
     localParameters.clear();
+    useDependencies.clear();
     final FunctionNode fun = member.function;
     for (int i = 0; i < fun.positionalParameters.length; i++) {
       final VariableDeclaration param = fun.positionalParameters[i];
       localParameters[param] = info.ensurePositional(i)
-        ..observeImplicitChecks(member, param, shaker);
+        ..observeParameter(member, param, shaker);
     }
     for (VariableDeclaration param in fun.namedParameters) {
       localParameters[param] = info.ensureNamed(param.name)
-        ..observeImplicitChecks(member, param, shaker);
+        ..observeParameter(member, param, shaker);
     }
 
     if (shaker.typeFlowAnalysis.isCalledDynamically(member) ||
         shaker.typeFlowAnalysis.isTearOffTaken(member) ||
         shaker.typeFlowAnalysis.nativeCodeOracle
             .isMemberReferencedFromNativeCode(member) ||
+        shaker.typeFlowAnalysis.nativeCodeOracle.isRecognized(member) ||
         getExternalName(member) != null) {
       info.eligible = false;
     }
+
+    if (excludePositionalParametersFromSignatureShaking(member)) {
+      info.canEliminatePositional = false;
+    }
   }
 
   @override
@@ -179,7 +264,10 @@
 
   @override
   void visitVariableGet(VariableGet node) {
-    localParameters[node.variable]?.isRead = true;
+    // Variable reads marked as use dependencies are not considered reads
+    // immediately. Their status as a read or not will be computed after all use
+    // dependencies have been collected.
+    localParameters[node.variable]?.isRead |= !useDependencies.contains(node);
     super.visitVariableGet(node);
   }
 
@@ -189,15 +277,32 @@
     super.visitVariableSet(node);
   }
 
+  void addUseDependency(Expression arg, _ParameterInfo param) {
+    if (arg is VariableGet) {
+      _ParameterInfo localParam = localParameters[arg.variable];
+      if (localParam != null && !localParam.isUsed) {
+        // This is a parameter passed as an argument. Mark it as a use
+        // dependency.
+        param.useDependencies ??= [];
+        param.useDependencies.add(localParam);
+        useDependencies.add(arg);
+      }
+    }
+  }
+
   void collectCall(Member member, Arguments args) {
     final _ProcedureInfo info = shaker._infoForMember(member);
     if (info == null) return;
 
     for (int i = 0; i < args.positional.length; i++) {
-      info.ensurePositional(i).passCount++;
+      _ParameterInfo param = info.ensurePositional(i);
+      param.passCount++;
+      addUseDependency(args.positional[i], param);
     }
     for (NamedExpression named in args.named) {
-      info.ensureNamed(named.name).passCount++;
+      _ParameterInfo param = info.ensureNamed(named.name);
+      param.passCount++;
+      addUseDependency(named.value, param);
     }
     info.callCount++;
   }
@@ -243,15 +348,36 @@
   final SignatureShaker shaker;
 
   StaticTypeContext typeContext;
-  final Set<VariableDeclaration> eliminatedParams = {};
+  final Map<VariableDeclaration, Constant> eliminatedParams = {};
+  final Set<VariableDeclaration> unusedParams = {};
   final List<LocalInitializer> addedInitializers = [];
 
   _Transform(this.shaker);
 
+  void eliminateUsedParameter(
+      Member member, _ParameterInfo param, VariableDeclaration variable) {
+    Constant value;
+    if (param.isConstant) {
+      Type type = shaker.typeFlowAnalysis.argumentType(member, variable);
+      if (type is ConcreteType) {
+        assert(type.constant != null);
+        value = type.constant;
+      } else {
+        assert(type is NullableType && type.baseType is EmptyType);
+        value = NullConstant();
+      }
+    } else {
+      value = (variable.initializer as ConstantExpression)?.constant ??
+          NullConstant();
+    }
+    eliminatedParams[variable] = value;
+  }
+
   void transformMemberSignature(Member member) {
     typeContext =
         StaticTypeContext(member, shaker.typeFlowAnalysis.environment);
     eliminatedParams.clear();
+    unusedParams.clear();
 
     final _ProcedureInfo info = shaker._infoForMember(member);
     if (info == null || !info.eligible || info.callCount == 0) return;
@@ -262,42 +388,61 @@
 
     final List<VariableDeclaration> positional = [];
     final List<VariableDeclaration> named = [];
-    // 1. All used positional parameters that are always passed, as required
-    //    positional parameters.
+    // 1. All positional parameters that are always passed and can't be
+    //    eliminated, as required positional parameters.
+    int firstNotAlwaysPassed = function.positionalParameters.length;
     for (int i = 0; i < function.positionalParameters.length; i++) {
       final _ParameterInfo param = info.positional[i];
-      if (!param.isAlwaysPassed) break;
+      if (!param.isAlwaysPassed) {
+        firstNotAlwaysPassed = i;
+        break;
+      }
+      final VariableDeclaration variable = function.positionalParameters[i];
       if (param.isUsed) {
-        final VariableDeclaration variable = function.positionalParameters[i];
-        positional.add(variable);
-        variable.initializer = null;
+        if (param.canBeEliminated) {
+          eliminateUsedParameter(member, param, variable);
+        } else {
+          positional.add(variable);
+          variable.initializer = null;
+        }
+      } else {
+        unusedParams.add(variable);
       }
     }
-    // 2. All used named parameters that are always passed, as required
-    //    positional parameters, alphabetically by name.
+    // 2. All named parameters that are always passed and can't be eliminated,
+    //    as required positional parameters, alphabetically by name.
     final List<VariableDeclaration> sortedNamed = function.namedParameters
         .toList()
           ..sort((var1, var2) => var1.name.compareTo(var2.name));
     for (VariableDeclaration variable in sortedNamed) {
       final _ParameterInfo param = info.named[variable.name];
-      if (param.isUsed && param.isAlwaysPassed) {
-        variable.initializer = null;
-        variable.isRequired = false;
-        positional.add(variable);
+      if (param.isAlwaysPassed) {
+        if (param.isUsed) {
+          if (param.canBeEliminated) {
+            eliminateUsedParameter(member, param, variable);
+          } else {
+            variable.initializer = null;
+            variable.isRequired = false;
+            positional.add(variable);
+          }
+        } else {
+          unusedParams.add(variable);
+        }
       }
     }
     int requiredParameterCount = positional.length;
-    // 3. All used positional parameters that are not always passed and can't be
+    // 3. All positional parameters that are not always passed and can't be
     //    eliminated, as positional parameters, each one required iff it was
     //    originally required.
-    for (int i = 0; i < function.positionalParameters.length; i++) {
+    for (int i = firstNotAlwaysPassed;
+        i < function.positionalParameters.length;
+        i++) {
       final _ParameterInfo param = info.positional[i];
+      assert(!param.isAlwaysPassed);
+      final VariableDeclaration variable = function.positionalParameters[i];
       if (param.isUsed) {
-        final VariableDeclaration variable = function.positionalParameters[i];
         if (param.canBeEliminated) {
-          assert(variable.initializer == null ||
-              variable.initializer is ConstantExpression);
-          eliminatedParams.add(variable);
+          eliminateUsedParameter(member, param, variable);
         } else if (!param.isAlwaysPassed) {
           positional.add(variable);
           if (i < function.requiredParameterCount) {
@@ -308,19 +453,23 @@
             requiredParameterCount++;
           }
         }
+      } else {
+        unusedParams.add(variable);
       }
     }
-    // 4. All used named parameters that are not always passed and can't be
+    // 4. All named parameters that are not always passed and can't be
     //    eliminated, as named parameters in alphabetical order.
     for (VariableDeclaration variable in sortedNamed) {
       final _ParameterInfo param = info.named[variable.name];
-      if (param.isUsed) {
-        if (param.canBeEliminated) {
-          assert(variable.initializer == null ||
-              variable.initializer is ConstantExpression);
-          eliminatedParams.add(variable);
-        } else if (!param.isAlwaysPassed) {
-          named.add(variable);
+      if (!param.isAlwaysPassed) {
+        if (param.isUsed) {
+          if (param.canBeEliminated) {
+            eliminateUsedParameter(member, param, variable);
+          } else {
+            named.add(variable);
+          }
+        } else {
+          unusedParams.add(variable);
         }
       }
     }
@@ -335,10 +484,9 @@
 
   @override
   void visitVariableGet(VariableGet node) {
-    if (eliminatedParams.contains(node.variable)) {
-      final ConstantExpression initializer = node.variable.initializer;
-      node.replaceWith(
-          ConstantExpression(initializer?.constant ?? NullConstant()));
+    Constant constantValue = eliminatedParams[node.variable];
+    if (constantValue != null) {
+      node.replaceWith(ConstantExpression(constantValue));
     }
   }
 
@@ -382,7 +530,7 @@
     bool hoistingNeeded = false;
     forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
       assert(!param.isNeverPassed);
-      if (!param.isUsed || param.isNamed && param.isAlwaysPassed) {
+      if (param.canBeEliminated || param.isNamed && param.isAlwaysPassed) {
         transformNeeded = true;
         if (mayHaveSideEffects(arg)) {
           hoistingNeeded = true;
@@ -392,12 +540,16 @@
 
     if (!transformNeeded) return;
 
+    bool isUnusedParam(Expression exp) {
+      return exp is VariableGet && unusedParams.contains(exp.variable);
+    }
+
     Map<Expression, VariableDeclaration> hoisted = {};
     if (hoistingNeeded) {
       if (call is Initializer) {
         final Constructor constructor = call.parent;
         forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
-          if (mayHaveOrSeeSideEffects(arg)) {
+          if (mayHaveOrSeeSideEffects(arg) && !isUnusedParam(arg)) {
             VariableDeclaration argVar = VariableDeclaration(null,
                 initializer: arg,
                 type: arg.getStaticType(typeContext),
@@ -411,7 +563,7 @@
         final TreeNode parent = call.parent;
         Expression current = call;
         forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
-          if (mayHaveOrSeeSideEffects(arg)) {
+          if (mayHaveOrSeeSideEffects(arg) && !isUnusedParam(arg)) {
             VariableDeclaration argVar = VariableDeclaration(null,
                 initializer: arg,
                 type: arg.getStaticType(typeContext),
@@ -421,6 +573,7 @@
           }
         });
         if (receiver != null && mayHaveOrSeeSideEffects(receiver)) {
+          assert(!isUnusedParam(receiver));
           assert(receiver.parent == call);
           final VariableDeclaration receiverVar = VariableDeclaration(null,
               initializer: receiver,
@@ -442,41 +595,41 @@
 
     final List<Expression> positional = [];
     final List<NamedExpression> named = [];
-    // 1. All used positional parameters that are always passed, as required
-    //    positional parameters.
+    // 1. All positional parameters that are always passed and can't be
+    //    eliminated, as required positional parameters.
     for (int i = 0; i < args.positional.length; i++) {
       final _ParameterInfo param = info.positional[i];
       final Expression arg = args.positional[i];
-      if (param.isUsed && param.isAlwaysPassed) {
+      if (param.isAlwaysPassed && !param.canBeEliminated) {
         positional.add(getMaybeHoistedArg(arg));
       }
     }
-    // 2. All used named parameters that are always passed, as required
-    //    positional parameters, alphabetically by name.
+    // 2. All named parameters that are always passed and can't be eliminated,
+    //    as required positional parameters, alphabetically by name.
     final List<NamedExpression> sortedNamed = args.named.toList()
       ..sort((var1, var2) => var1.name.compareTo(var2.name));
     for (NamedExpression arg in sortedNamed) {
       final _ParameterInfo param = info.named[arg.name];
-      if (param.isUsed && param.isAlwaysPassed) {
+      if (param.isAlwaysPassed && !param.canBeEliminated) {
         positional.add(getMaybeHoistedArg(arg.value));
       }
     }
-    // 3. All used positional parameters that are not always passed and can't be
+    // 3. All positional parameters that are not always passed and can't be
     //    eliminated, as positional parameters, each one required iff it was
     //    originally required.
     for (int i = 0; i < args.positional.length; i++) {
       final _ParameterInfo param = info.positional[i];
       final Expression arg = args.positional[i];
-      if (param.isUsed && !param.isAlwaysPassed) {
+      if (!param.isAlwaysPassed && !param.canBeEliminated) {
         positional.add(getMaybeHoistedArg(arg));
       }
     }
-    // 4. All used named parameters that are not always passed and can't be
+    // 4. All named parameters that are not always passed and can't be
     //    eliminated, as named parameters in alphabetical order.
     //    (Arguments are kept in original order.)
     for (NamedExpression arg in args.named) {
       final _ParameterInfo param = info.named[arg.name];
-      if (param.isUsed && !param.isAlwaysPassed) {
+      if (!param.isAlwaysPassed && !param.canBeEliminated) {
         arg.value = getMaybeHoistedArg(arg.value)..parent = arg;
         named.add(arg);
       }
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index d529e68..b009b27 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -245,7 +245,7 @@
   @override
   Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
       CallHandler callHandler) {
-    final List<Type> argTypes = new List<Type>(args.values.length);
+    final List<Type> argTypes = new List<Type>.filled(args.values.length, null);
     for (int i = 0; i < args.values.length; i++) {
       final Type type = args.values[i].getComputedType(computedTypes);
       if (type == const EmptyType()) {
@@ -451,7 +451,7 @@
   Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
       CallHandler callHandler) {
     bool hasRuntimeType = false;
-    final types = new List<Type>(flattenedTypeArgs.length);
+    final types = new List<Type>.filled(flattenedTypeArgs.length, null);
     for (int i = 0; i < types.length; ++i) {
       final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
       assert(computed is RuntimeType || computed is UnknownType);
@@ -483,7 +483,7 @@
   @override
   Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
       CallHandler callHandler) {
-    final types = new List<RuntimeType>(flattenedTypeArgs.length);
+    final types = new List<RuntimeType>.filled(flattenedTypeArgs.length, null);
     for (int i = 0; i < types.length; ++i) {
       final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
       assert(computed is RuntimeType || computed is UnknownType);
@@ -637,7 +637,7 @@
     //
     // The first `parameterCount` statements are Parameters.
 
-    List<Type> types = new List<Type>(_statements.length);
+    List<Type> types = new List<Type>.filled(_statements.length, null);
 
     for (int i = 0; i < positionalArgCount; i++) {
       final Parameter param = _statements[i] as Parameter;
@@ -703,9 +703,9 @@
   }
 
   Args<Type> get argumentTypes {
-    final argTypes = new List<Type>(parameterCount);
-    final argNames =
-        new List<String>(parameterCount - positionalParameterCount);
+    final argTypes = new List<Type>.filled(parameterCount, null);
+    final argNames = new List<String>.filled(
+        parameterCount - positionalParameterCount, null);
     for (int i = 0; i < parameterCount; i++) {
       Parameter param = _statements[i] as Parameter;
       argTypes[i] = param.argumentType;
@@ -737,7 +737,7 @@
   }
 
   List<VariableDeclaration> get uncheckedParameters {
-    final params = List<VariableDeclaration>();
+    final params = <VariableDeclaration>[];
     for (Statement statement in _statements) {
       if (statement is TypeCheck &&
           statement.canAlwaysSkip &&
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 68162e7..51daa89 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -605,8 +605,9 @@
 
     _staticTypeContext = new StaticTypeContext(member, _environment);
     _variablesInfo = new _VariablesInfoCollector(member);
-    _variableValues = new List<TypeExpr>(_variablesInfo.numVariables);
-    _variableCells = new List<Join>(_variablesInfo.numVariables);
+    _variableValues =
+        new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
+    _variableCells = new List<Join>.filled(_variablesInfo.numVariables, null);
     _variableVersions = new List<int>.filled(_variablesInfo.numVariables, 0);
     _variableValuesAfterLabeledStatements = null;
     _joinsAtSwitchCases = null;
@@ -943,7 +944,7 @@
       new List<TypeExpr>.from(values);
 
   List<TypeExpr> _makeEmptyVariableValues() {
-    final values = new List<TypeExpr>(_variablesInfo.numVariables);
+    final values = new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
     for (int i = 0; i < values.length; ++i) {
       if (_variableCells[i] != null) {
         values[i] = _variableValues[i];
@@ -1008,7 +1009,8 @@
   }
 
   List<Join> _insertJoinsForModifiedVariables(TreeNode node, bool isTry) {
-    final List<Join> joins = new List<Join>(_variablesInfo.numVariables);
+    final List<Join> joins =
+        new List<Join>.filled(_variablesInfo.numVariables, null);
     for (var i in _variablesInfo.getModifiedVariables(node)) {
       if (_variableCells[i] != null) {
         assert(_variableCells[i] == _variableValues[i]);
@@ -2198,7 +2200,8 @@
     final substitution = Substitution.fromPairs(klass.typeParameters, typeArgs);
     final flattenedTypeArgs =
         genericInterfacesInfo.flattenedTypeArgumentsFor(klass);
-    final flattenedTypeExprs = new List<TypeExpr>(flattenedTypeArgs.length);
+    final flattenedTypeExprs =
+        new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
 
     bool createConcreteType = true;
     bool allUnknown = true;
@@ -2269,7 +2272,8 @@
         type.classNode.typeParameters, type.typeArguments);
     final flattenedTypeArgs =
         genericInterfacesInfo.flattenedTypeArgumentsFor(type.classNode);
-    final flattenedTypeExprs = new List<TypeExpr>(flattenedTypeArgs.length);
+    final flattenedTypeExprs =
+        new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
 
     bool createRuntimeType = true;
     for (var i = 0; i < flattenedTypeArgs.length; ++i) {
diff --git a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
index 1d78d39..2cfe329 100644
--- a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
+++ b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
@@ -25,7 +25,7 @@
         _memberIdsForClass(cls, getter: true);
       }
     }
-    _selectorIdForMemberId = List(_unionFind.size);
+    _selectorIdForMemberId = List.filled(_unionFind.size, null);
     // Assign all selector IDs eagerly to make them independent of how they are
     // queried in later phases. This makes TFA test expectation files (which
     // contain selector IDs) more stable under changes to how selector IDs are
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 68688fd..2ea1325 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -593,19 +593,19 @@
       } else if (m is Procedure) {
         func = m.function;
         if (m.forwardingStubSuperTarget != null) {
-          m.forwardingStubSuperTarget = fieldMorpher.adjustInstanceCallTarget(
+          m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
               m.forwardingStubSuperTarget,
               isSetter: m.isSetter);
           addUsedMember(m.forwardingStubSuperTarget);
         }
         if (m.forwardingStubInterfaceTarget != null) {
-          m.forwardingStubInterfaceTarget = fieldMorpher
-              .adjustInstanceCallTarget(m.forwardingStubInterfaceTarget,
-                  isSetter: m.isSetter);
+          m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
+              m.forwardingStubInterfaceTarget,
+              isSetter: m.isSetter);
           addUsedMember(m.forwardingStubInterfaceTarget);
         }
         if (m.memberSignatureOrigin != null) {
-          m.memberSignatureOrigin = fieldMorpher.adjustInstanceCallTarget(
+          m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
               m.memberSignatureOrigin,
               isSetter: m.isSetter);
           addUsedMember(m.memberSignatureOrigin);
@@ -1230,6 +1230,12 @@
 
   void transform(Component component) {
     component.transformChildren(this);
+    for (Source source in component.uriToSource.values) {
+      source?.constantCoverageConstructors?.removeWhere((Reference reference) {
+        Member node = reference.asMember;
+        return !shaker.isMemberUsed(node) && !_preserveSpecialMember(node);
+      });
+    }
   }
 
   @override
@@ -1322,8 +1328,10 @@
           _makeUnreachableBody(node.function);
         }
         node.function.asyncMarker = AsyncMarker.Sync;
-        node.forwardingStubSuperTargetReference = null;
-        node.forwardingStubInterfaceTargetReference = null;
+        if (node.forwardingStubSuperTarget != null ||
+            node.forwardingStubInterfaceTarget != null) {
+          node.stubTarget = null;
+        }
         Statistics.methodBodiesDropped++;
       } else if (node is Field) {
         node.initializer = null;
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index c5754ed..4392865 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -858,7 +858,7 @@
       } else if (other.typeArgs == null) {
         mergedTypeArgs = typeArgs;
       } else {
-        mergedTypeArgs = new List<Type>(typeArgs.length);
+        mergedTypeArgs = new List<Type>.filled(typeArgs.length, null);
         bool hasRuntimeType = false;
         for (int i = 0; i < typeArgs.length; ++i) {
           final merged =
diff --git a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
index f105c4f..792dc99 100644
--- a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
+++ b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
@@ -6,6 +6,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/external_name.dart' show getExternalName;
 import 'package:vm/metadata/procedure_attributes.dart';
+import 'package:vm/transformations/pragma.dart';
 import 'package:vm/transformations/type_flow/analysis.dart';
 import 'package:vm/transformations/type_flow/calls.dart';
 import 'package:vm/transformations/type_flow/native_code.dart';
@@ -199,18 +200,11 @@
     // have boxed parameters and return values.
     return _isNative(member) ||
         _nativeCodeOracle.isMemberReferencedFromNativeCode(member) ||
-        _isEnclosingClassSubtypeOfNum(member);
+        _nativeCodeOracle.isRecognized(member, const [
+          PragmaRecognizedType.AsmIntrinsic,
+          PragmaRecognizedType.Other
+        ]);
   }
 
   bool _isNative(Member member) => getExternalName(member) != null;
-
-  // TODO(dartbug.com/33549): Calls to these methods could be replaced by
-  // CheckedSmiOpInstr, so in order to allow the parameters and return
-  // value to be unboxed, the slow path for such instructions should be
-  // updated to be consistent with the representations from the target interface.
-  bool _isEnclosingClassSubtypeOfNum(Member member) {
-    return (member.enclosingClass != null &&
-        ConeType(_typeHierarchy.getTFClass(member.enclosingClass))
-            .isSubtypeOf(_typeHierarchy, _coreTypes.numClass));
-  }
 }
diff --git a/pkg/vm/pubspec.yaml b/pkg/vm/pubspec.yaml
index 9a2d487..95341eb 100644
--- a/pkg/vm/pubspec.yaml
+++ b/pkg/vm/pubspec.yaml
@@ -11,9 +11,12 @@
   build_integration:
     path: ../build_integration
   crypto: any
-  front_end: any
-  kernel: ^0.3.6
-  meta: any
+  front_end:
+    path: ../front_end
+  kernel:
+    path: ../kernel
+  meta:
+    path: ../meta
   package_config: any
 
 dev_dependencies:
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 52a98e6..179c37b 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -134,7 +134,9 @@
   /// If [getAllSources] is false it will ask specifically for report
   /// (and thus hits) for "lib1.dart" only.
   Future<Set<int>> collectAndCheckCoverageData(int port, bool getAllSources,
-      {bool resume: true}) async {
+      {bool resume: true,
+      bool onGetAllVerifyCount: true,
+      Set<int> coverageForLines}) async {
     RemoteVm remoteVm = new RemoteVm(port);
 
     // Wait for the script to have finished.
@@ -145,7 +147,7 @@
     }
 
     // Collect coverage for the two user scripts.
-    List<Map> sourceReports = new List<Map>();
+    List<Map> sourceReports = <Map>[];
     if (getAllSources) {
       Map sourceReport = await remoteVm.getSourceReport();
       sourceReports.add(sourceReport);
@@ -167,7 +169,7 @@
       }
     }
 
-    List<String> errorMessages = new List<String>();
+    List<String> errorMessages = <String>[];
     Set<int> hits = new Set<int>();
 
     // Ensure that we can get a line and column number for all reported
@@ -189,7 +191,7 @@
         }
         i++;
       }
-      if (getAllSources) {
+      if (getAllSources && onGetAllVerifyCount) {
         expect(scriptIdToIndex.length >= 2, isTrue);
       }
 
@@ -226,12 +228,16 @@
             }
           }
           for (int pos in coverage["misses"]) positions.add(pos);
-          for (int pos in range["possibleBreakpoints"]) positions.add(pos);
+          if (range["possibleBreakpoints"] != null) {
+            for (int pos in range["possibleBreakpoints"]) positions.add(pos);
+          }
           Map script = scriptIndexToScript[range["scriptIndex"]];
           Set<int> knownPositions = new Set<int>();
+          Map<int, int> tokenPosToLine = {};
           if (script["tokenPosTable"] != null) {
             for (List tokenPosTableLine in script["tokenPosTable"]) {
               for (int i = 1; i < tokenPosTableLine.length; i += 2) {
+                tokenPosToLine[tokenPosTableLine[i]] = tokenPosTableLine[0];
                 knownPositions.add(tokenPosTableLine[i]);
               }
             }
@@ -244,6 +250,14 @@
                   "line and column.");
             }
           }
+
+          if (coverageForLines != null) {
+            for (int pos in coverage["hits"]) {
+              if (lib1scriptIndices.contains(range["scriptIndex"])) {
+                coverageForLines.add(tokenPosToLine[pos]);
+              }
+            }
+          }
         }
       }
     }
@@ -486,6 +500,243 @@
     });
   });
 
+  group('multiple kernels constant coverage', () {
+    Directory mytest;
+    File main;
+    File lib1;
+    int lineForUnnamedConstructor;
+    int lineForNamedConstructor;
+    Process vm;
+    setUpAll(() {
+      mytest = Directory.systemTemp.createTempSync('incremental');
+      main = new File('${mytest.path}/main.dart')..createSync();
+      main.writeAsStringSync("""
+        // This file - combined with the lib - should have coverage for both
+        // constructors of Foo.
+        import 'lib1.dart' as lib1;
+
+        void testFunction() {
+          const foo = lib1.Foo.named();
+          const foo2 = lib1.Foo.named();
+          if (!identical(foo, foo2)) throw "what?";
+        }
+
+        main() {
+          lib1.testFunction();
+          testFunction();
+          print("main");
+        }
+      """);
+      lib1 = new File('${mytest.path}/lib1.dart')..createSync();
+      lib1.writeAsStringSync("""
+        // Compiling this file should mark the default constructor - but not the
+        // named constructor - as having coverage.
+        class Foo {
+          final int x;
+          const Foo([int? x]) : this.x = x ?? 42;
+          const Foo.named([int? x]) : this.x = x ?? 42;
+        }
+
+        void testFunction() {
+          const foo = Foo();
+          const foo2 = Foo();
+          if (!identical(foo, foo2)) throw "what?";
+        }
+
+        main() {
+          testFunction();
+          print("lib1");
+        }
+      """);
+      lineForUnnamedConstructor = 5;
+      lineForNamedConstructor = 6;
+    });
+
+    tearDownAll(() {
+      try {
+        mytest.deleteSync(recursive: true);
+      } catch (_) {
+        // Ignore errors;
+      }
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+    });
+
+    Future<Set<int>> runAndGetLineCoverage(
+        File list, String expectStdoutContains) async {
+      vm = await Process.start(Platform.resolvedExecutable, <String>[
+        "--pause-isolates-on-exit",
+        "--enable-vm-service:0",
+        "--disable-service-auth-codes",
+        "--disable-dart-dev",
+        list.path
+      ]);
+
+      const kObservatoryListening = 'Observatory listening on ';
+      final RegExp observatoryPortRegExp =
+          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
+      int port;
+      final splitter = new LineSplitter();
+      Completer<String> portLineCompleter = new Completer<String>();
+      Set<int> coverageLines = {};
+      bool foundExpectedString = false;
+      vm.stdout
+          .transform(utf8.decoder)
+          .transform(splitter)
+          .listen((String s) async {
+        if (s == expectStdoutContains) {
+          foundExpectedString = true;
+        }
+        if (s.startsWith(kObservatoryListening)) {
+          expect(observatoryPortRegExp.hasMatch(s), isTrue);
+          final match = observatoryPortRegExp.firstMatch(s);
+          port = int.parse(match.group(1));
+          await collectAndCheckCoverageData(port, true,
+              onGetAllVerifyCount: false, coverageForLines: coverageLines);
+          if (!portLineCompleter.isCompleted) {
+            portLineCompleter.complete("done");
+          }
+        }
+        print("vm stdout: $s");
+      });
+      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
+        print("vm stderr: $s");
+      });
+      await portLineCompleter.future;
+      print("Compiler terminated with ${await vm.exitCode} exit code");
+      expect(foundExpectedString, isTrue);
+      return coverageLines;
+    }
+
+    test('compile seperatly, check coverage', () async {
+      Directory dir = mytest.createTempSync();
+
+      // First compile lib, run and verify coverage (un-named constructor
+      // covered, but not the named constructor).
+      // Note that it's called 'lib1' to match with expectations from coverage
+      // collector helper in this file.
+      File libDill = File(p.join(dir.path, p.basename(lib1.path + ".dill")));
+      IncrementalCompiler compiler = new IncrementalCompiler(options, lib1.uri);
+      Component component = await compiler.compile();
+      expect(component.libraries.length, equals(1));
+      expect(component.libraries.single.fileUri, equals(lib1.uri));
+      IOSink sink = libDill.openWrite();
+      BinaryPrinter printer = new BinaryPrinter(sink);
+      printer.writeComponentFile(component);
+      await sink.flush();
+      await sink.close();
+      File list = new File(p.join(dir.path, 'dill.list'))..createSync();
+      list.writeAsStringSync("#@dill\n${libDill.path}\n");
+      Set<int> lineCoverage = await runAndGetLineCoverage(list, "lib1");
+      // Expect coverage for unnamed constructor but not for the named one.
+      expect(
+          lineCoverage.intersection(
+              {lineForUnnamedConstructor, lineForNamedConstructor}),
+          equals({lineForUnnamedConstructor}));
+
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+      // Accept the compile to not include the lib again.
+      compiler.accept();
+
+      // Then compile lib, run and verify coverage (un-named constructor
+      // covered, and the named constructor coveraged too).
+      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
+      component = await compiler.compile(entryPoint: main.uri);
+      expect(component.libraries.length, equals(1));
+      expect(component.libraries.single.fileUri, equals(main.uri));
+      sink = mainDill.openWrite();
+      printer = new BinaryPrinter(sink);
+      printer.writeComponentFile(component);
+      await sink.flush();
+      await sink.close();
+      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
+      lineCoverage = await runAndGetLineCoverage(list, "main");
+
+      // Expect coverage for both unnamed constructor and for the named one.
+      expect(
+          lineCoverage.intersection(
+              {lineForUnnamedConstructor, lineForNamedConstructor}),
+          equals({lineForUnnamedConstructor, lineForNamedConstructor}));
+
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+      // Accept the compile to not include the lib again.
+      compiler.accept();
+
+      // Finally, change lib to shift the constructors so the old line numbers
+      // doesn't match. Compile lib by itself, compile lib, run with the old
+      // main and verify coverage is still correct (both un-named constructor
+      // and named constructor (at new line numbers) are covered, and the old
+      // line numbers are not coverage.
+
+      lib1.writeAsStringSync("""
+        //
+        // Shift lines down by five
+        // lines so the original
+        // lines can't be coverred
+        //
+        class Foo {
+          final int x;
+          const Foo([int? x]) : this.x = x ?? 42;
+          const Foo.named([int? x]) : this.x = x ?? 42;
+        }
+
+        void testFunction() {
+          const foo = Foo();
+          const foo2 = Foo();
+          if (!identical(foo, foo2)) throw "what?";
+        }
+
+        main() {
+          testFunction();
+          print("lib1");
+        }
+      """);
+      int newLineForUnnamedConstructor = 8;
+      int newLineForNamedConstructor = 9;
+      compiler.invalidate(lib1.uri);
+      component = await compiler.compile(entryPoint: lib1.uri);
+      expect(component.libraries.length, equals(1));
+      expect(component.libraries.single.fileUri, equals(lib1.uri));
+      sink = libDill.openWrite();
+      printer = new BinaryPrinter(sink);
+      printer.writeComponentFile(component);
+      await sink.flush();
+      await sink.close();
+      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
+      lineCoverage = await runAndGetLineCoverage(list, "main");
+
+      // Expect coverage for both unnamed constructor and for the named one on
+      // the new positions, but no coverage on the old positions.
+      expect(
+          lineCoverage.intersection({
+            lineForUnnamedConstructor,
+            lineForNamedConstructor,
+            newLineForUnnamedConstructor,
+            newLineForNamedConstructor
+          }),
+          equals({newLineForUnnamedConstructor, newLineForNamedConstructor}));
+
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+      // Accept the compile to not include the lib again.
+      compiler.accept();
+    });
+  });
+
   group('multiple kernels 2', () {
     Directory mytest;
     File main;
diff --git a/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart b/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart
index 707b1fd..4a29089 100644
--- a/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart
+++ b/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart
@@ -12,6 +12,8 @@
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
+import 'package:vm/kernel_front_end.dart'
+    show runGlobalTransformations, ErrorDetector;
 import 'package:vm/transformations/protobuf_aware_treeshaker/transformer.dart'
     as treeshaker;
 
@@ -20,7 +22,12 @@
 final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
 
 runTestCase(Uri source) async {
-  final target = new TestingVmTarget(new TargetFlags());
+  await shakeAndRun(source);
+  await compileAOT(source);
+}
+
+Future<void> shakeAndRun(Uri source) async {
+  final target = TestingVmTarget(TargetFlags());
   Component component =
       await compileTestCaseToKernelProgram(source, target: target);
 
@@ -42,8 +49,7 @@
   }
 
   final systemTempDir = Directory.systemTemp;
-  final file =
-      new File('${systemTempDir.path}/${source.pathSegments.last}.dill');
+  final file = File('${systemTempDir.path}/${source.pathSegments.last}.dill');
   try {
     final sink = file.openWrite();
     final printer = BinaryPrinter(sink, includeSources: false);
@@ -61,6 +67,30 @@
   }
 }
 
+Future<void> compileAOT(Uri source) async {
+  final target = TestingVmTarget(TargetFlags());
+  Component component =
+      await compileTestCaseToKernelProgram(source, target: target);
+
+  // Imitate the global transformations as run by the protobuf-aware tree shaker
+  // in AOT mode.
+  // Copied verbatim from pkg/vm/bin/protobuf_aware_treeshaker.dart.
+  const bool useGlobalTypeFlowAnalysis = true;
+  const bool enableAsserts = false;
+  const bool useProtobufAwareTreeShaker = true;
+  const bool useProtobufAwareTreeShakerV2 = false;
+  final nopErrorDetector = ErrorDetector();
+  runGlobalTransformations(
+    target,
+    component,
+    useGlobalTypeFlowAnalysis,
+    enableAsserts,
+    useProtobufAwareTreeShaker,
+    useProtobufAwareTreeShakerV2,
+    nopErrorDetector,
+  );
+}
+
 main() async {
   final testCases = Directory(path.join(
     pkgVmDir,
diff --git a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
index e069735..7d95c30 100644
--- a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
+++ b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
@@ -4,7 +4,6 @@
   #lib
   dart:_http
   dart:core
-  dart:wasm
   dart:cli
   dart:io
   dart:nativewrappers
@@ -50,7 +49,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -67,7 +65,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -83,7 +80,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -100,7 +96,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -117,7 +112,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -139,7 +133,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -155,7 +148,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -172,7 +164,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -189,7 +180,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -215,7 +205,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -231,7 +220,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -253,7 +241,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -270,7 +257,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -292,7 +278,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -308,7 +293,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -327,7 +311,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -343,7 +326,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -362,7 +344,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -378,7 +359,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -400,7 +380,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -417,7 +396,6 @@
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (dart.core::Object*, dart.core::StackTrace*) →* dynamic :async_op_error;
     dart.core::int* :await_jump_var = 0;
@@ -438,7 +416,6 @@
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
         dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
diff --git a/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/foo.pb.dart b/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/foo.pb.dart
index cab7883..19c9bac5 100644
--- a/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/foo.pb.dart
+++ b/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/foo.pb.dart
@@ -2,38 +2,40 @@
 //  Generated code. Do not modify.
 //  source: foo.proto
 //
-// @dart = 2.3
-// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
 
 import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class FooKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('FooKeep', createEmptyInstance: create)
-        ..aOM<BarKeep>(1, 'barKeep',
-            protoName: 'barKeep', subBuilder: BarKeep.create)
-        ..aOM<BarKeep>(2, 'barDrop',
-            protoName: 'barDrop', subBuilder: BarKeep.create)
-        ..m<$core.String, BarKeep>(3, 'mapKeep',
-            protoName: 'mapKeep',
-            entryClassName: 'FooKeep.MapKeepEntry',
-            keyFieldType: $pb.PbFieldType.OS,
-            valueFieldType: $pb.PbFieldType.OM,
-            valueCreator: BarKeep.create)
-        ..m<$core.String, ZopDrop>(4, 'mapDrop',
-            protoName: 'mapDrop',
-            entryClassName: 'FooKeep.MapDropEntry',
-            keyFieldType: $pb.PbFieldType.OS,
-            valueFieldType: $pb.PbFieldType.OM,
-            valueCreator: ZopDrop.create)
-        ..a<$core.int>(5, 'aKeep', $pb.PbFieldType.O3, protoName: 'aKeep')
-        ..aOM<HasKeep>(6, 'hasKeep',
-            protoName: 'hasKeep', subBuilder: HasKeep.create)
-        ..aOM<ClearKeep>(7, 'clearKeep',
-            protoName: 'clearKeep', subBuilder: ClearKeep.create)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FooKeep',
+      createEmptyInstance: create)
+    ..aOM<BarKeep>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'barKeep',
+        protoName: 'barKeep', subBuilder: BarKeep.create)
+    ..aOM<BarKeep>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'barDrop',
+        protoName: 'barDrop', subBuilder: BarKeep.create)
+    ..m<$core.String, BarKeep>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'mapKeep',
+        protoName: 'mapKeep',
+        entryClassName: 'FooKeep.MapKeepEntry',
+        keyFieldType: $pb.PbFieldType.OS,
+        valueFieldType: $pb.PbFieldType.OM,
+        valueCreator: BarKeep.create)
+    ..m<$core.String, ZopDrop>(
+        4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'mapDrop',
+        protoName: 'mapDrop',
+        entryClassName: 'FooKeep.MapDropEntry',
+        keyFieldType: $pb.PbFieldType.OS,
+        valueFieldType: $pb.PbFieldType.OM,
+        valueCreator: ZopDrop.create)
+    ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'aKeep', $pb.PbFieldType.O3,
+        protoName: 'aKeep')
+    ..aOM<HasKeep>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'hasKeep',
+        protoName: 'hasKeep', subBuilder: HasKeep.create)
+    ..aOM<ClearKeep>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clearKeep',
+        protoName: 'clearKeep', subBuilder: ClearKeep.create)
+    ..hasRequiredFields = false;
 
   FooKeep._() : super();
   factory FooKeep() => create();
@@ -43,9 +45,16 @@
   factory FooKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   FooKeep clone() => FooKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   FooKeep copyWith(void Function(FooKeep) updates) =>
-      super.copyWith((message) => updates(message as FooKeep));
+      super.copyWith((message) => updates(message as FooKeep))
+          as FooKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static FooKeep create() => FooKeep._();
@@ -54,7 +63,7 @@
   @$core.pragma('dart2js:noInline')
   static FooKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FooKeep>(create);
-  static FooKeep _defaultInstance;
+  static FooKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   BarKeep get barKeep => $_getN(0);
@@ -132,11 +141,26 @@
 }
 
 class BarKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('BarKeep', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aKeep', $pb.PbFieldType.O3, protoName: 'aKeep')
-        ..a<$core.int>(2, 'bDrop', $pb.PbFieldType.O3, protoName: 'bDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'BarKeep',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aKeep',
+        $pb.PbFieldType.O3,
+        protoName: 'aKeep')
+    ..a<$core.int>(
+        2,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'bDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'bDrop')
+    ..hasRequiredFields = false;
 
   BarKeep._() : super();
   factory BarKeep() => create();
@@ -146,9 +170,16 @@
   factory BarKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   BarKeep clone() => BarKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   BarKeep copyWith(void Function(BarKeep) updates) =>
-      super.copyWith((message) => updates(message as BarKeep));
+      super.copyWith((message) => updates(message as BarKeep))
+          as BarKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static BarKeep create() => BarKeep._();
@@ -157,7 +188,7 @@
   @$core.pragma('dart2js:noInline')
   static BarKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BarKeep>(create);
-  static BarKeep _defaultInstance;
+  static BarKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aKeep => $_getIZ(0);
@@ -185,10 +216,19 @@
 }
 
 class HasKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('HasKeep', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'HasKeep',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   HasKeep._() : super();
   factory HasKeep() => create();
@@ -198,9 +238,16 @@
   factory HasKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   HasKeep clone() => HasKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   HasKeep copyWith(void Function(HasKeep) updates) =>
-      super.copyWith((message) => updates(message as HasKeep));
+      super.copyWith((message) => updates(message as HasKeep))
+          as HasKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static HasKeep create() => HasKeep._();
@@ -209,7 +256,7 @@
   @$core.pragma('dart2js:noInline')
   static HasKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<HasKeep>(create);
-  static HasKeep _defaultInstance;
+  static HasKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
@@ -225,10 +272,19 @@
 }
 
 class ClearKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('ClearKeep', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'ClearKeep',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   ClearKeep._() : super();
   factory ClearKeep() => create();
@@ -238,9 +294,16 @@
   factory ClearKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   ClearKeep clone() => ClearKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   ClearKeep copyWith(void Function(ClearKeep) updates) =>
-      super.copyWith((message) => updates(message as ClearKeep));
+      super.copyWith((message) => updates(message as ClearKeep))
+          as ClearKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static ClearKeep create() => ClearKeep._();
@@ -249,7 +312,7 @@
   @$core.pragma('dart2js:noInline')
   static ClearKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClearKeep>(create);
-  static ClearKeep _defaultInstance;
+  static ClearKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
@@ -265,10 +328,19 @@
 }
 
 class ZopDrop extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('ZopDrop', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'ZopDrop',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   ZopDrop._() : super();
   factory ZopDrop() => create();
@@ -278,9 +350,16 @@
   factory ZopDrop.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   ZopDrop clone() => ZopDrop()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   ZopDrop copyWith(void Function(ZopDrop) updates) =>
-      super.copyWith((message) => updates(message as ZopDrop));
+      super.copyWith((message) => updates(message as ZopDrop))
+          as ZopDrop; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static ZopDrop create() => ZopDrop._();
@@ -289,7 +368,7 @@
   @$core.pragma('dart2js:noInline')
   static ZopDrop getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ZopDrop>(create);
-  static ZopDrop _defaultInstance;
+  static ZopDrop? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
@@ -305,10 +384,19 @@
 }
 
 class MobDrop extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('MobDrop', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'MobDrop',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   MobDrop._() : super();
   factory MobDrop() => create();
@@ -318,9 +406,16 @@
   factory MobDrop.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   MobDrop clone() => MobDrop()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   MobDrop copyWith(void Function(MobDrop) updates) =>
-      super.copyWith((message) => updates(message as MobDrop));
+      super.copyWith((message) => updates(message as MobDrop))
+          as MobDrop; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static MobDrop create() => MobDrop._();
@@ -329,7 +424,7 @@
   @$core.pragma('dart2js:noInline')
   static MobDrop getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MobDrop>(create);
-  static MobDrop _defaultInstance;
+  static MobDrop? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
diff --git a/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/name_mangling.pb.dart b/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/name_mangling.pb.dart
index bc76b27..c42141a 100644
--- a/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/name_mangling.pb.dart
+++ b/pkg/vm/testcases/transformations/protobuf_aware_treeshaker/lib/generated/name_mangling.pb.dart
@@ -2,17 +2,20 @@
 //  Generated code. Do not modify.
 //  source: name_mangling.proto
 //
-// @dart = 2.3
-// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
 
 import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class AKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('AKeep', createEmptyInstance: create)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'AKeep',
+      createEmptyInstance: create)
+    ..hasRequiredFields = false;
 
   AKeep._() : super();
   factory AKeep() => create();
@@ -22,9 +25,16 @@
   factory AKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   AKeep clone() => AKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   AKeep copyWith(void Function(AKeep) updates) =>
-      super.copyWith((message) => updates(message as AKeep));
+      super.copyWith((message) => updates(message as AKeep))
+          as AKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static AKeep create() => AKeep._();
@@ -33,14 +43,22 @@
   @$core.pragma('dart2js:noInline')
   static AKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AKeep>(create);
-  static AKeep _defaultInstance;
+  static AKeep? _defaultInstance;
 }
 
 class NameManglingKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('NameManglingKeep', createEmptyInstance: create)
-        ..aOM<AKeep>(10, 'clone', subBuilder: AKeep.create)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'NameManglingKeep',
+      createEmptyInstance: create)
+    ..aOM<AKeep>(
+        10,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'clone',
+        subBuilder: AKeep.create)
+    ..hasRequiredFields = false;
 
   NameManglingKeep._() : super();
   factory NameManglingKeep() => create();
@@ -50,9 +68,16 @@
   factory NameManglingKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   NameManglingKeep clone() => NameManglingKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   NameManglingKeep copyWith(void Function(NameManglingKeep) updates) =>
-      super.copyWith((message) => updates(message as NameManglingKeep));
+      super.copyWith((message) => updates(message as NameManglingKeep))
+          as NameManglingKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static NameManglingKeep create() => NameManglingKeep._();
@@ -62,7 +87,7 @@
   @$core.pragma('dart2js:noInline')
   static NameManglingKeep getDefault() => _defaultInstance ??=
       $pb.GeneratedMessage.$_defaultFor<NameManglingKeep>(create);
-  static NameManglingKeep _defaultInstance;
+  static NameManglingKeep? _defaultInstance;
 
   @$pb.TagNumber(10)
   AKeep get clone_10 => $_getN(0);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
index f1dfad8..ee9f237 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
@@ -12,7 +12,6 @@
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
-    dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
     (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
     core::int* :await_jump_var = 0;
@@ -30,7 +29,6 @@
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
         asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
-    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
     [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -49,7 +47,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -67,7 +64,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
@@ -78,7 +74,6 @@
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
-  dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
   (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
   core::int* :await_jump_var = 0;
@@ -100,7 +95,6 @@
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
       asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
-  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
   [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
index d9f0804..173e18b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
@@ -12,19 +12,19 @@
   }
   return true;
 }
-[@vm.unboxing-info.metadata=(i)->b]static method nThPrimeNumber([@vm.inferred-type.metadata=dart.core::_Smi (value: 50000)] core::int* n) → core::int* {
+static method nThPrimeNumber() → core::int* {
   core::int* counter = 0;
   for (core::int* i = 1; ; i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
     if([@vm.inferred-type.metadata=dart.core::bool] self::isPrime(i))
       counter = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] counter.{core::num::+}(1);
-    if([@vm.inferred-type.metadata=dart.core::bool] counter.{core::num::==}(n)) {
+    if([@vm.inferred-type.metadata=dart.core::bool] counter.{core::num::==}(#C1)) {
       return i;
     }
   }
 }
 static method run() → void {
   core::int* e = 611953;
-  core::int* p = [@vm.inferred-type.metadata=int?] self::nThPrimeNumber(50000);
+  core::int* p = [@vm.inferred-type.metadata=int?] self::nThPrimeNumber();
   if(![@vm.inferred-type.metadata=dart.core::bool] p.{core::num::==}(e)) {
     throw core::Exception::•("Unexpected result: ${p} != ${e}");
   }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
index f30eaeb..71bb393 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -9,8 +9,8 @@
 [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] [@vm.unboxing-info.metadata=()->i]  final field core::int* _offset;
 [@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i]  final field core::int* _length;
 [@vm.inferred-type.metadata=dart.typed_data::_Float64List] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  final field core::List<core::double*>* _elements;
-[@vm.unboxing-info.metadata=(i)->b]  constructor •([@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] core::int* size) → self::_Vector*
-    : self::_Vector::_offset = 0, self::_Vector::_length = size, self::_Vector::_elements = [@vm.inferred-type.metadata=dart.typed_data::_Float64List] typ::Float64List::•(size), super core::Object::•()
+  constructor •() → self::_Vector*
+    : self::_Vector::_offset = 0, self::_Vector::_length = #C1, self::_Vector::_elements = [@vm.inferred-type.metadata=dart.typed_data::_Float64List] typ::Float64List::•(#C1), super core::Object::•()
     ;
 [@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:4] [@vm.unboxing-info.metadata=(b)->d]  operator []([@vm.inferred-type.metadata=!] core::int* i) → core::double*
     return [@vm.direct-call.metadata=dart.typed_data::_Float64List.[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=#lib::_Vector._elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector._offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset}));
@@ -24,7 +24,7 @@
     return result;
   }
 }
-[@vm.inferred-type.metadata=#lib::_Vector?]static field self::_Vector* v = new self::_Vector::•(10);
+[@vm.inferred-type.metadata=#lib::_Vector?]static field self::_Vector* v = new self::_Vector::•();
 [@vm.inferred-type.metadata=dart.core::_Double?]static field core::double* x = 0.0;
 static method main(core::List<core::String*>* args) → dynamic {
   core::Stopwatch* timer = let final core::Stopwatch* #t3 = new core::Stopwatch::•() in block {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
index 8d122c1..29abf49 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
@@ -17,44 +17,44 @@
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7]  method toString() → core::String*
     return [@vm.direct-call.metadata=#lib::B._name] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "B.b2")] this.{self::B::_name};
 }
-[@vm.unboxing-info.metadata=(i)->b]static method test0([@vm.inferred-type.metadata=dart.core::_Smi (value: 40)] core::int* arg) → void {
-  core::print(arg);
-}
-static method test1() → void {
+static method test0() → void {
   core::print(#C1);
 }
-static method test2() → void {
+static method test1() → void {
   core::print(#C2);
 }
+static method test2() → void {
+  core::print(#C3);
+}
 [@vm.unboxing-info.metadata=()->d]static get getD() → dynamic
   return 100.0;
-[@vm.unboxing-info.metadata=(d)->b]static method testDouble([@vm.inferred-type.metadata=dart.core::_Double (value: 3.14)] core::double* arg) → void {
-  core::print(arg);
+static method testDouble() → void {
+  core::print(#C4);
   core::print([@vm.inferred-type.metadata=dart.core::_Double (value: 100.0)] self::getD);
 }
-static method testStrings([@vm.inferred-type.metadata=#lib::A] self::A* a0, [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "bazz")] core::String* a1) → void {
+static method testStrings([@vm.inferred-type.metadata=#lib::A] self::A* a0) → void {
   core::print([@vm.direct-call.metadata=#lib::A.foo] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "foo")] a0.{self::A::foo});
   core::print([@vm.direct-call.metadata=#lib::A.getBar] [@vm.inferred-type.metadata=dart.core::_OneByteString (skip check) (value: "bar")] a0.{self::A::getBar}());
-  core::print(a1);
+  core::print(#C5);
 }
-static method testPassEnum([@vm.inferred-type.metadata=#lib::B (value: const #lib::B{#lib::B.index: 1, #lib::B._name: "B.b2"})] self::B* arg) → void {
-  self::testPassEnum2(arg);
+static method testPassEnum() → void {
+  self::testPassEnum2();
 }
-static method testPassEnum2([@vm.inferred-type.metadata=#lib::B (value: const #lib::B{#lib::B.index: 1, #lib::B._name: "B.b2"})] self::B* arg) → void {
-  core::print(arg);
+static method testPassEnum2() → void {
+  core::print(#C8);
 }
 static method getList() → dynamic
-  return #C6;
-static method testList([@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2, 3])] dynamic arg1) → void {
-  core::print(arg1);
-  core::print(#C9);
+  return #C11;
+static method testList() → void {
+  core::print(#C11);
+  core::print(#C14);
 }
 static method main() → dynamic {
-  self::test0(40);
+  self::test0();
   self::test1();
   self::test2();
-  self::testDouble(3.14);
-  self::testStrings(new self::A::•(), "bazz");
-  self::testPassEnum(#C11);
-  self::testList([@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2, 3])] self::getList());
+  self::testDouble();
+  self::testStrings(new self::A::•());
+  self::testPassEnum();
+  let final dynamic #t1 = [@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2, 3])] self::getList() in self::testList();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index 79e29be..cb18067 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -48,8 +48,8 @@
 static method callerA4([@vm.inferred-type.metadata=#lib::D?] self::A* aa) → void {
   [@vm.direct-call.metadata=#lib::C.foo??] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
 }
-static method callerE1([@vm.inferred-type.metadata=dart.core::_OneByteString (value: "abc")] dynamic x) → void {
-  [@vm.direct-call.metadata=dart.core::_StringBase.toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] x.{core::Object::toString}();
+static method callerE1() → void {
+  [@vm.direct-call.metadata=dart.core::_StringBase.toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)](#C1).{core::Object::toString}();
 }
 static method callerE2([@vm.inferred-type.metadata=#lib::E?] dynamic x) → void {
   [@vm.inferred-type.metadata=!? (receiver not int)] x.{core::Object::toString}();
@@ -61,6 +61,6 @@
   let final self::C* #t1 = new self::C::•() in self::callerA3(#t1);
   self::callerA4([@vm.inferred-type.metadata=#lib::D?] self::dd);
   self::dd = new self::D::•();
-  self::callerE1("abc");
+  self::callerE1();
   self::callerE2([@vm.inferred-type.metadata=#lib::E?] self::ee);
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
index 560aabe..5f51fa3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
@@ -1,4 +1,4 @@
 main() {
-  dynamic x = List<int>(10);
+  dynamic x = List<int>.filled(10, null);
   x[0] + 10;
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
index 387080e..59e2b69 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
@@ -21,14 +21,14 @@
   synthetic constructor •() → self::Stream*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  abstract method foobar((dynamic) →* void onData, {core::Function* onError = #C1}) → self::StreamSubscription*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  abstract method foobar() → self::StreamSubscription*;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3]  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
 }
 abstract class _StreamImpl extends self::Stream {
   synthetic constructor •() → self::_StreamImpl*
     : super self::Stream::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method foobar([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method foobar() → self::StreamSubscription* {
     return [@vm.inferred-type.metadata=! (skip check)] this.{self::_StreamImpl::_createSubscription}();
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5]  method _createSubscription() → self::StreamSubscription* {
@@ -53,22 +53,22 @@
   constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::StreamView*
     : self::StreamView::_stream = stream, super self::Stream::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method foobar([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → self::StreamSubscription* {
-    return [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}(onData, onError: onError);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method foobar() → self::StreamSubscription* {
+    return [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}();
   }
 }
 class ByteStream extends self::StreamView {
   constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::ByteStream*
     : super self::StreamView::•(stream)
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  method super_foobar1([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
-    super.{self::StreamView::foobar}(onData);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  method super_foobar1() → dynamic {
+    super.{self::StreamView::foobar}();
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method super_foobar2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
-    super.{self::StreamView::foobar}(onData);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method super_foobar2() → dynamic {
+    super.{self::StreamView::foobar}();
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method super_foobar3() → dynamic {
-    super.{self::StreamView::foobar}(#C1, onError: #C1);
+    super.{self::StreamView::foobar}();
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13]  get super_stream() → self::Stream*
     return [@vm.inferred-type.metadata=!] super.{self::StreamView::_stream};
@@ -83,26 +83,26 @@
 }
 static method round1() → void {
   self::ByteStream* x = new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
-  [@vm.direct-call.metadata=#lib::ByteStream.super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(#C1);
+  [@vm.direct-call.metadata=#lib::ByteStream.super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}();
 }
 static method round2() → void {
   new self::_ControllerStream::•();
   self::Stream* x = new self::_GeneratedStreamImpl::•();
   x = new self::ByteStream::•(x);
-  [@vm.direct-call.metadata=#lib::StreamView.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(#C1, onError: #C1);
+  [@vm.direct-call.metadata=#lib::StreamView.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}();
 }
 static method round3() → void {
   self::Stream* x = new self::_GeneratedStreamImpl::•();
   x = new self::ByteStream::•(x);
   x = new self::_ControllerStream::•();
-  [@vm.direct-call.metadata=#lib::_StreamImpl.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(#C1, onError: #C1);
+  [@vm.direct-call.metadata=#lib::_StreamImpl.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}();
 }
 static method round4() → void {
   self::ByteStream* x = new self::ByteStream::•(new self::_ControllerStream::•());
   self::Stream* y = [@vm.direct-call.metadata=#lib::ByteStream.super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream};
   self::Stream* z = [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream};
   if([@vm.direct-call.metadata=dart.core::Object.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] y.{self::Stream::==}(z)) {
-    [@vm.direct-call.metadata=#lib::ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(#C1);
+    [@vm.direct-call.metadata=#lib::ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}();
   }
 }
 static method round5() → void {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
index 0fd6e10..c02e36d 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
@@ -11,7 +11,7 @@
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  final field core::List<core::int*>* defaultConstructor1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::•<core::int*>(0);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6]  final field core::List<core::int*>* defaultConstructor2 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::•<core::int*>(3);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7]  final field core::List<core::int*>* filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::filled<core::int*>(2, 0);
-[@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:8]  final field core::List<core::int*>* filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::filled<core::int*>(2, 0);
+[@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:8]  final field core::List<core::int*>* filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::filled<core::int*>();
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:9]  final field core::List<core::int*>* filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::filled<core::int*>(2, 0);
 [@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:10]  final field core::List<core::int*>* filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int*>(2, 0, #t1);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11]  final field core::List<core::int*>* filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::•<core::int*>(2);
@@ -20,8 +20,8 @@
 [@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:14]  final field core::List<core::int*>* filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int*>(2, null, #t2);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:15]  final field core::List<core::int*>* generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::generate<core::int*>(2, (core::int* i) → core::int* => i);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:16]  final field core::List<core::int*>* generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::generate<core::int*>(2, (core::int* i) → core::int* => i);
-[@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:17]  final field core::List<core::int*>* generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::generate<core::int*>(2, (core::int* i) → core::int* => i);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:18]  final field core::List<core::int*>* generateFactory4 = let final (core::int*) →* core::int* #t3 = (core::int* i) → core::int* => i in let final core::bool #t4 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int*>(2, #t3, #t4);
+[@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:17]  final field core::List<core::int*>* generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::generate<core::int*>((core::int* i) → core::int* => i);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:18]  final field core::List<core::int*>* generateFactory4 = let final (core::int*) →* core::int* #t3 = (core::int* i) → core::int* => i in let final core::bool #t4 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int*>(#t3, #t4);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int*>*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:19]  final field core::List<core::List<core::int*>*>* generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int*>*>] core::_GrowableList::generate<core::List<core::int*>*>(2, (core::int* _) → core::List<core::int*>* => <core::int*>[]);
   synthetic constructor •() → self::A*
     : super core::Object::•()
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect
index 8a54bb1..8d53437 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect
@@ -9,7 +9,7 @@
 [@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[])] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  final field core::List<core::int> constLiteral1 = #C1;
 [@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2])] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  final field core::List<core::int> constLiteral2 = #C4;
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  final field core::List<core::int> filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0);
-[@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6]  final field core::List<core::int> filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>(2, 0);
+[@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6]  final field core::List<core::int> filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>();
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7]  final field core::List<core::int> filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0);
 [@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:8]  final field core::List<core::int> filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(2, 0, #t1);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:9]  final field core::List<core::int?> filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2);
@@ -18,8 +18,8 @@
 [@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:12]  final field core::List<core::int?> filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(2, null, #t2);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13]  final field core::List<core::int> generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:14]  final field core::List<core::int> generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i);
-[@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:15]  final field core::List<core::int> generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>(2, (core::int i) → core::int => i);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:16]  final field core::List<core::int> generateFactory4 = let final (core::int) → core::int #t3 = (core::int i) → core::int => i in let final core::bool #t4 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(2, #t3, #t4);
+[@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:15]  final field core::List<core::int> generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>((core::int i) → core::int => i);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:16]  final field core::List<core::int> generateFactory4 = let final (core::int) → core::int #t3 = (core::int i) → core::int => i in let final core::bool #t4 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(#t3, #t4);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:17]  final field core::List<core::List<core::int>> generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] core::_GrowableList::generate<core::List<core::int>>(2, (core::int _) → core::List<core::int> => <core::int>[]);
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
index d80f88a..1b24ebc 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
@@ -7,8 +7,8 @@
 [@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::String? nonNullable;
 [@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::String? nullable;
 [@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::String? alwaysNull;
-  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String? nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String? nullable, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::String? alwaysNull = #C1}) → self::A
-    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String? nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String? nullable) → self::A
+    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = #C1, super core::Object::•()
     ;
 }
 [@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = new self::A::•("hi", "bye");
@@ -19,7 +19,7 @@
 static method testAlwaysNull([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
   return [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}!;
 static method main() → void {
-  final core::List<self::A> list = <self::A>[new self::A::•("foo", null, alwaysNull: null), self::staticField];
+  final core::List<self::A> list = <self::A>[new self::A::•("foo", null), self::staticField];
   {
     core::Iterator<self::A> :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A>] list.{core::Iterable::iterator};
     for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
index 615c0d7..17ed46c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
@@ -7,8 +7,8 @@
 [@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::String* nonNullable;
 [@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::String* nullable;
 [@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::String* alwaysNull;
-  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String* nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String* nullable, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::String* alwaysNull = #C1}) → self::A*
-    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String* nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String* nullable) → self::A*
+    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = #C1, super core::Object::•()
     ;
 }
 [@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = new self::A::•("hi", "bye");
@@ -51,7 +51,7 @@
 static method someCondition() → dynamic
   return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1);
 static method main() → void {
-  final core::List<self::A*>* list = <self::A*>[new self::A::•("foo", null, alwaysNull: null), self::staticField];
+  final core::List<self::A*>* list = <self::A*>[new self::A::•("foo", null), self::staticField];
   {
     core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A*>] list.{core::Iterable::iterator};
     for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
index 8726004..a697cdd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
@@ -13,12 +13,12 @@
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.barKeep] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pb::FooKeep::barKeep} = let final pb::BarKeep* #t2 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pb::BarKeep::aKeep} = 5;
     } =>#t2;
-    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String*, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep*>*] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapKeep}.{core::Map::[]=}("foo", let final pb::BarKeep* #t3 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
+    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep>] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapKeep}.{core::Map::[]=}("foo", let final pb::BarKeep* #t3 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pb::BarKeep::aKeep} = 2;
     } =>#t3);
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pb::FooKeep::aKeep} = 43;
   } =>#t1;
-  tes::test("retrieving values", () → Null {
+  tes::test(() → Null {
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep??] [@vm.inferred-type.metadata=int] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.barKeep] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep?] foo.{pb::FooKeep::barKeep}.{pb::BarKeep::aKeep}, 5);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep??] [@vm.inferred-type.metadata=int] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep?] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] foo.{pb::FooKeep::mapKeep}.{core::Map::[]}("foo").{pb::BarKeep::aKeep}, 2);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.hasHasKeep] [@vm.inferred-type.metadata=dart.core::bool (skip check)] foo.{pb::FooKeep::hasHasKeep}(), false);
@@ -26,7 +26,7 @@
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.clearClearKeep] [@vm.inferred-type.metadata=!? (skip check)] foo.{pb::FooKeep::clearClearKeep}();
   });
 }
-library foo.pb.dart;
+library foo.pb.dart /*isNonNullableByDefault*/;
 import self as self;
 import "package:protobuf/protobuf.dart" as pro;
 import "dart:core" as core;
@@ -35,99 +35,99 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C2);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, (#C1) ?{core::String} "" : "mapKeep", #C2);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C4);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C5);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C6);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep", #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C5);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
-  constructor _() → self::FooKeep*
+  constructor _() → self::FooKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::FooKeep*
+  static factory •() → self::FooKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C9
-  static method create() → self::FooKeep*
+  @#C8
+  static method create() → self::FooKeep
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
-  get barKeep() → self::BarKeep*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
-  set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
-    [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C10
+  get barKeep() → self::BarKeep
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep>();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C10
+  set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep v) → void {
+    [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C13
-  get mapKeep() → core::Map<core::String*, self::BarKeep*>*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C15
-  get aKeep() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C12
+  get mapKeep() → core::Map<core::String, self::BarKeep>
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String, self::BarKeep>();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C14
+  get aKeep() → core::int
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C15
-  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C14
+  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C17
-  method hasHasKeep() → core::bool*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(5);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C19
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C16
+  method hasHasKeep() → core::bool
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C18
   method clearClearKeep() → void
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}(7);
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}();
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C4);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep", #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
-  constructor _() → self::BarKeep*
+  constructor _() → self::BarKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::BarKeep*
+  static factory •() → self::BarKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C9
-  static method create() → self::BarKeep*
+  @#C8
+  static method create() → self::BarKeep
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C11
-  get aKeep() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C10
+  get aKeep() → core::int
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C11
-  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C10
+  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
-  constructor _() → self::HasKeep*
+  constructor _() → self::HasKeep
     : super pro::GeneratedMessage::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C9
-  static method create() → self::HasKeep*
+  @#C8
+  static method create() → self::HasKeep
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
-  constructor _() → self::ClearKeep*
+  constructor _() → self::ClearKeep
     : super pro::GeneratedMessage::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C9
-  static method create() → self::ClearKeep*
+  @#C8
+  static method create() → self::ClearKeep
     return new self::ClearKeep::_();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
index f59d5b9..14a4689 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
@@ -11,7 +11,7 @@
 [@vm.inferred-type.metadata=dart.core::_GrowableList?<dart.core::int*>]static field core::List<core::int*>* buffer = <core::int*>[10, 4, 8, 5, 16, 4, 26, 9, 10, 3, 102, 111, 111, 18, 2, 8, 42, 34, 9, 10, 3, 122, 111, 112, 18, 2, 8, 3, 40, 43, 50, 0, 58, 0];
 static method main() → dynamic {
   pb::FooKeep* foo = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep] pb::FooKeep::fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList?<dart.core::int*>] self::buffer);
-  tes::test("Kept values are restored correctly", () → Null {
+  tes::test(() → Null {
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep??] [@vm.inferred-type.metadata=int] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep?] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] foo.{pb::FooKeep::mapKeep}.{core::Map::[]}("foo").{pb::BarKeep::aKeep}, 42);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep??] [@vm.inferred-type.metadata=int] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.barKeep] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep?] foo.{pb::FooKeep::barKeep}.{pb::BarKeep::aKeep}, 5);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.aKeep] [@vm.inferred-type.metadata=int] foo.{pb::FooKeep::aKeep}, 43);
@@ -19,7 +19,7 @@
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.clearClearKeep] [@vm.inferred-type.metadata=!? (skip check)] foo.{pb::FooKeep::clearClearKeep}();
   });
 }
-library foo.pb.dart;
+library foo.pb.dart /*isNonNullableByDefault*/;
 import self as self;
 import "package:protobuf/protobuf.dart" as pro;
 import "dart:core" as core;
@@ -28,111 +28,87 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep", createEmptyInstance: #C2) in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, (#C1) ?{core::String} "" : "mapKeep", #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C4);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C5);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C6);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C6);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
-  constructor _() → self::FooKeep*
+  constructor _() → self::FooKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::FooKeep*
-    return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
-  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList?<dart.core::int*>] core::List<core::int*>* i) → self::FooKeep*
-    return let final self::FooKeep* #t2 = [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::GeneratedMessage::mergeFromBuffer}(i, #C7);
+  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList?<dart.core::int*>] core::List<core::int> i) → self::FooKeep
+    return let final self::FooKeep #t2 = [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create() in block {
+      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::GeneratedMessage::mergeFromBuffer}(i);
     } =>#t2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::FooKeep*
-    return let final self::FooKeep* #t3 = [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C10
-  static method create() → self::FooKeep*
+  @#C9
+  static method create() → self::FooKeep
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C12
-  get barKeep() → self::BarKeep*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  @#C14
-  get mapKeep() → core::Map<core::String*, self::BarKeep*>*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C16
-  get aKeep() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]  @#C11
+  get barKeep() → self::BarKeep
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep>();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  @#C13
+  get mapKeep() → core::Map<core::String, self::BarKeep>
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String, self::BarKeep>();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i]  @#C15
+  get aKeep() → core::int
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C18
-  method hasHasKeep() → core::bool*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(5);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C20
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  @#C17
+  method hasHasKeep() → core::bool
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C19
   method clearClearKeep() → void
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}(7);
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}();
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("BarKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C4);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
-  } =>#t4;
-  constructor _() → self::BarKeep*
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep", createEmptyInstance: #C3) in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
+  } =>#t3;
+  constructor _() → self::BarKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::BarKeep*
-    return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::BarKeep*
-    return let final self::BarKeep* #t5 = [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t5;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C10
-  static method create() → self::BarKeep*
+  @#C9
+  static method create() → self::BarKeep
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11] [@vm.unboxing-info.metadata=()->i]  @#C12
-  get aKeep() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:9] [@vm.unboxing-info.metadata=()->i]  @#C11
+  get aKeep() → core::int
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t6 = new pro::BuilderInfo::•("HasKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t6.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t6.{pro::BuilderInfo::hasRequiredFields} = false;
-  } =>#t6;
-  constructor _() → self::HasKeep*
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep", createEmptyInstance: #C5) in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
+  } =>#t4;
+  constructor _() → self::HasKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::HasKeep*
-    return [@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::HasKeep*
-    return let final self::HasKeep* #t7 = [@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t7.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t7;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C10
-  static method create() → self::HasKeep*
+  @#C9
+  static method create() → self::HasKeep
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t8 = new pro::BuilderInfo::•("ClearKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t8.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t8.{pro::BuilderInfo::hasRequiredFields} = false;
-  } =>#t8;
-  constructor _() → self::ClearKeep*
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t5 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep", createEmptyInstance: #C6) in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::hasRequiredFields} = false;
+  } =>#t5;
+  constructor _() → self::ClearKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::ClearKeep*
-    return [@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::ClearKeep*
-    return let final self::ClearKeep* #t9 = [@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t9.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t9;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C10
-  static method create() → self::ClearKeep*
+  @#C9
+  static method create() → self::ClearKeep
     return new self::ClearKeep::_();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
index 66a360a..4980123 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
@@ -15,10 +15,10 @@
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pb::BarKeep::aKeep} = 5;
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.bDrop] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pb::BarKeep::bDrop} = 4;
     } =>#t2;
-    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String*, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep*>*] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapKeep}.{core::Map::[]=}("foo", let final pb::BarKeep* #t3 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
+    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep>] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapKeep}.{core::Map::[]=}("foo", let final pb::BarKeep* #t3 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pb::BarKeep::aKeep} = 42;
     } =>#t3);
-    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String*, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::ZopDrop*>*] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapDrop] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapDrop}.{core::Map::[]=}("zop", let final pb::ZopDrop* #t4 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::ZopDrop] pb::ZopDrop::•() in block {
+    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::ZopDrop>] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapDrop] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapDrop}.{core::Map::[]=}("zop", let final pb::ZopDrop* #t4 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::ZopDrop] pb::ZopDrop::•() in block {
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::ZopDrop.aDrop] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pb::ZopDrop::aDrop} = 3;
     } =>#t4);
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pb::FooKeep::aKeep} = 43;
@@ -33,7 +33,7 @@
   }
   core::print("];");
 }
-library foo.pb.dart;
+library foo.pb.dart /*isNonNullableByDefault*/;
 import self as self;
 import "package:protobuf/protobuf.dart" as pro;
 import "dart:core" as core;
@@ -42,123 +42,123 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C2);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::ZopDrop*>(4, "mapDrop", "FooKeep.MapDropEntry", #C2, "mapDrop", #C4, #C3);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C5);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C6);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C7);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, (#C1) ?{core::String} "" : "mapKeep", "FooKeep.MapKeepEntry", "mapKeep", #C2);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::ZopDrop>(4, (#C1) ?{core::String} "" : "mapDrop", "FooKeep.MapDropEntry", "mapDrop", #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep", #C4, "aKeep");
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C6);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
-  constructor _() → self::FooKeep*
+  constructor _() → self::FooKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::FooKeep*
+  static factory •() → self::FooKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C10
-  static method create() → self::FooKeep*
+  @#C9
+  static method create() → self::FooKeep
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2]  @#C12
-  set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2]  @#C11
+  set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  @#C14
-  get mapKeep() → core::Map<core::String*, self::BarKeep*>*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C16
-  get mapDrop() → core::Map<core::String*, self::ZopDrop*>*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::ZopDrop*>(3);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5] [@vm.unboxing-info.metadata=(i)->b]  @#C18
-  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  @#C13
+  get mapKeep() → core::Map<core::String, self::BarKeep>
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String, self::BarKeep>(2);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C15
+  get mapDrop() → core::Map<core::String, self::ZopDrop>
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String, self::ZopDrop>(3);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5] [@vm.unboxing-info.metadata=(i)->b]  @#C17
+  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6]  @#C20
-  set hasKeep([@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6]  @#C19
+  set hasKeep([@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(6, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7]  @#C22
-  set clearKeep([@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7]  @#C21
+  set clearKeep([@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(7, v);
   }
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C5);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(2, "bDrop", #C5);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep", #C4, "aKeep");
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int>(2, (#C1) ?{core::String} "" : "bDrop", #C4, "bDrop");
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
-  constructor _() → self::BarKeep*
+  constructor _() → self::BarKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::BarKeep*
+  static factory •() → self::BarKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C10
-  static method create() → self::BarKeep*
+  @#C9
+  static method create() → self::BarKeep
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] [@vm.unboxing-info.metadata=(i)->b]  @#C12
-  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] [@vm.unboxing-info.metadata=(i)->b]  @#C11
+  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9] [@vm.unboxing-info.metadata=(i)->b]  @#C24
-  set bDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9] [@vm.unboxing-info.metadata=(i)->b]  @#C23
+  set bDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(1, v);
   }
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
-  constructor _() → self::HasKeep*
+  constructor _() → self::HasKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::HasKeep*
+  static factory •() → self::HasKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C10
-  static method create() → self::HasKeep*
+  @#C9
+  static method create() → self::HasKeep
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
-  constructor _() → self::ClearKeep*
+  constructor _() → self::ClearKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::ClearKeep*
+  static factory •() → self::ClearKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C10
-  static method create() → self::ClearKeep*
+  @#C9
+  static method create() → self::ClearKeep
     return new self::ClearKeep::_();
 }
 class ZopDrop extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t5 = new pro::BuilderInfo::•("ZopDrop") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::a}<core::int*>(1, "aDrop", #C5);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t5 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ZopDrop") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aDrop", #C4, "aDrop");
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t5;
-  constructor _() → self::ZopDrop*
+  constructor _() → self::ZopDrop
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::ZopDrop*
+  static factory •() → self::ZopDrop
     return [@vm.inferred-type.metadata=foo.pb.dart::ZopDrop] self::ZopDrop::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ZopDrop::_i;
-  @#C10
-  static method create() → self::ZopDrop*
+  @#C9
+  static method create() → self::ZopDrop
     return new self::ZopDrop::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10] [@vm.unboxing-info.metadata=(i)->b]  @#C12
-  set aDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10] [@vm.unboxing-info.metadata=(i)->b]  @#C11
+  set aDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
index 6423786..15a7ebf 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
@@ -6,7 +6,6 @@
 import "package:protobuf/protobuf.dart" as pro;
 import "package:test_api/src/frontend/expect.dart" as exp;
 import "package:test_api/src/frontend/throws_matcher.dart" as thr;
-import "package:matcher/src/type_matcher.dart" as typ;
 
 import "package:test/test.dart";
 import "file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart";
@@ -16,21 +15,21 @@
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.barKeep] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pb::FooKeep::barKeep} = let final pb::BarKeep* #t2 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pb::BarKeep::aKeep} = 5;
     } =>#t2;
-    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String*, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep*>*] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapKeep}.{core::Map::[]=}("foo", let final pb::BarKeep* #t3 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
+    [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<dart.core::String, library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep>] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] #t1.{pb::FooKeep::mapKeep}.{core::Map::[]=}("foo", let final pb::BarKeep* #t3 = [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep] pb::BarKeep::•() in block {
       [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pb::BarKeep::aKeep} = 2;
     } =>#t3);
     [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.aKeep] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pb::FooKeep::aKeep} = 43;
   } =>#t1;
-  tes::test("Freezing a message works", () → Null {
+  tes::test(() → Null {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.freeze] [@vm.inferred-type.metadata=!? (skip check)] foo.{pro::GeneratedMessage::freeze}();
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep??] [@vm.inferred-type.metadata=int] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.barKeep] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep?] foo.{pb::FooKeep::barKeep}.{pb::BarKeep::aKeep}, 5);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep.aKeep??] [@vm.inferred-type.metadata=int] [@vm.inferred-type.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::BarKeep?] [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.mapKeep] [@vm.inferred-type.metadata=!] foo.{pb::FooKeep::mapKeep}.{core::Map::[]}("foo").{pb::BarKeep::aKeep}, 2);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.hasHasKeep] [@vm.inferred-type.metadata=dart.core::bool (skip check)] foo.{pb::FooKeep::hasHasKeep}(), false);
     exp::expect([@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.aKeep] [@vm.inferred-type.metadata=int] foo.{pb::FooKeep::aKeep}, 43);
-    exp::expect(() → void => [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.clearClearKeep] [@vm.inferred-type.metadata=!? (skip check)] foo.{pb::FooKeep::clearClearKeep}(), [@vm.inferred-type.metadata=library package:test_api/src/frontend/throws_matcher.dart::Throws] thr::throwsA(#C2));
+    exp::expect(() → void => [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart::FooKeep.clearClearKeep] [@vm.inferred-type.metadata=!? (skip check)] foo.{pb::FooKeep::clearClearKeep}(), [@vm.inferred-type.metadata=library package:test_api/src/frontend/throws_matcher.dart::Throws] thr::throwsA());
   });
 }
-library foo.pb.dart;
+library foo.pb.dart /*isNonNullableByDefault*/;
 import self as self;
 import "package:protobuf/protobuf.dart" as pro;
 import "dart:core" as core;
@@ -39,99 +38,99 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, (#C1) ?{core::String} "" : "barKeep", "barKeep", #C2);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, (#C1) ?{core::String} "" : "mapKeep", #C2);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C4);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C5);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C6);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, (#C1) ?{core::String} "" : "aKeep", #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, (#C1) ?{core::String} "" : "hasKeep", "hasKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, (#C1) ?{core::String} "" : "clearKeep", "clearKeep", #C5);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
-  constructor _() → self::FooKeep*
+  constructor _() → self::FooKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::FooKeep*
+  static factory •() → self::FooKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C9
-  static method create() → self::FooKeep*
+  @#C8
+  static method create() → self::FooKeep
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
-  get barKeep() → self::BarKeep*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
-  set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
-    [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C10
+  get barKeep() → self::BarKeep
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep>();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C10
+  set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep v) → void {
+    [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C13
-  get mapKeep() → core::Map<core::String*, self::BarKeep*>*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C15
-  get aKeep() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C12
+  get mapKeep() → core::Map<core::String, self::BarKeep>
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String, self::BarKeep>();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C14
+  get aKeep() → core::int
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C15
-  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C14
+  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C17
-  method hasHasKeep() → core::bool*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(5);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C19
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C16
+  method hasHasKeep() → core::bool
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}();
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C18
   method clearClearKeep() → void
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}(7);
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}();
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C4);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int>(1, (#C1) ?{core::String} "" : "aKeep", #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
-  constructor _() → self::BarKeep*
+  constructor _() → self::BarKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::BarKeep*
+  static factory •() → self::BarKeep
     return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C9
-  static method create() → self::BarKeep*
+  @#C8
+  static method create() → self::BarKeep
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C11
-  get aKeep() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C10
+  get aKeep() → core::int
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C11
-  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C10
+  set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t3 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
-  constructor _() → self::HasKeep*
+  constructor _() → self::HasKeep
     : super pro::GeneratedMessage::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C9
-  static method create() → self::HasKeep*
+  @#C8
+  static method create() → self::HasKeep
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t4 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<Null>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
-  constructor _() → self::ClearKeep*
+  constructor _() → self::ClearKeep
     : super pro::GeneratedMessage::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C9
-  static method create() → self::ClearKeep*
+  @#C8
+  static method create() → self::ClearKeep
     return new self::ClearKeep::_();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart
index cab7883..19c9bac5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/foo.pb.dart
@@ -2,38 +2,40 @@
 //  Generated code. Do not modify.
 //  source: foo.proto
 //
-// @dart = 2.3
-// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
 
 import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class FooKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('FooKeep', createEmptyInstance: create)
-        ..aOM<BarKeep>(1, 'barKeep',
-            protoName: 'barKeep', subBuilder: BarKeep.create)
-        ..aOM<BarKeep>(2, 'barDrop',
-            protoName: 'barDrop', subBuilder: BarKeep.create)
-        ..m<$core.String, BarKeep>(3, 'mapKeep',
-            protoName: 'mapKeep',
-            entryClassName: 'FooKeep.MapKeepEntry',
-            keyFieldType: $pb.PbFieldType.OS,
-            valueFieldType: $pb.PbFieldType.OM,
-            valueCreator: BarKeep.create)
-        ..m<$core.String, ZopDrop>(4, 'mapDrop',
-            protoName: 'mapDrop',
-            entryClassName: 'FooKeep.MapDropEntry',
-            keyFieldType: $pb.PbFieldType.OS,
-            valueFieldType: $pb.PbFieldType.OM,
-            valueCreator: ZopDrop.create)
-        ..a<$core.int>(5, 'aKeep', $pb.PbFieldType.O3, protoName: 'aKeep')
-        ..aOM<HasKeep>(6, 'hasKeep',
-            protoName: 'hasKeep', subBuilder: HasKeep.create)
-        ..aOM<ClearKeep>(7, 'clearKeep',
-            protoName: 'clearKeep', subBuilder: ClearKeep.create)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FooKeep',
+      createEmptyInstance: create)
+    ..aOM<BarKeep>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'barKeep',
+        protoName: 'barKeep', subBuilder: BarKeep.create)
+    ..aOM<BarKeep>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'barDrop',
+        protoName: 'barDrop', subBuilder: BarKeep.create)
+    ..m<$core.String, BarKeep>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'mapKeep',
+        protoName: 'mapKeep',
+        entryClassName: 'FooKeep.MapKeepEntry',
+        keyFieldType: $pb.PbFieldType.OS,
+        valueFieldType: $pb.PbFieldType.OM,
+        valueCreator: BarKeep.create)
+    ..m<$core.String, ZopDrop>(
+        4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'mapDrop',
+        protoName: 'mapDrop',
+        entryClassName: 'FooKeep.MapDropEntry',
+        keyFieldType: $pb.PbFieldType.OS,
+        valueFieldType: $pb.PbFieldType.OM,
+        valueCreator: ZopDrop.create)
+    ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'aKeep', $pb.PbFieldType.O3,
+        protoName: 'aKeep')
+    ..aOM<HasKeep>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'hasKeep',
+        protoName: 'hasKeep', subBuilder: HasKeep.create)
+    ..aOM<ClearKeep>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clearKeep',
+        protoName: 'clearKeep', subBuilder: ClearKeep.create)
+    ..hasRequiredFields = false;
 
   FooKeep._() : super();
   factory FooKeep() => create();
@@ -43,9 +45,16 @@
   factory FooKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   FooKeep clone() => FooKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   FooKeep copyWith(void Function(FooKeep) updates) =>
-      super.copyWith((message) => updates(message as FooKeep));
+      super.copyWith((message) => updates(message as FooKeep))
+          as FooKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static FooKeep create() => FooKeep._();
@@ -54,7 +63,7 @@
   @$core.pragma('dart2js:noInline')
   static FooKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FooKeep>(create);
-  static FooKeep _defaultInstance;
+  static FooKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   BarKeep get barKeep => $_getN(0);
@@ -132,11 +141,26 @@
 }
 
 class BarKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('BarKeep', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aKeep', $pb.PbFieldType.O3, protoName: 'aKeep')
-        ..a<$core.int>(2, 'bDrop', $pb.PbFieldType.O3, protoName: 'bDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'BarKeep',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aKeep',
+        $pb.PbFieldType.O3,
+        protoName: 'aKeep')
+    ..a<$core.int>(
+        2,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'bDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'bDrop')
+    ..hasRequiredFields = false;
 
   BarKeep._() : super();
   factory BarKeep() => create();
@@ -146,9 +170,16 @@
   factory BarKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   BarKeep clone() => BarKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   BarKeep copyWith(void Function(BarKeep) updates) =>
-      super.copyWith((message) => updates(message as BarKeep));
+      super.copyWith((message) => updates(message as BarKeep))
+          as BarKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static BarKeep create() => BarKeep._();
@@ -157,7 +188,7 @@
   @$core.pragma('dart2js:noInline')
   static BarKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BarKeep>(create);
-  static BarKeep _defaultInstance;
+  static BarKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aKeep => $_getIZ(0);
@@ -185,10 +216,19 @@
 }
 
 class HasKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('HasKeep', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'HasKeep',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   HasKeep._() : super();
   factory HasKeep() => create();
@@ -198,9 +238,16 @@
   factory HasKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   HasKeep clone() => HasKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   HasKeep copyWith(void Function(HasKeep) updates) =>
-      super.copyWith((message) => updates(message as HasKeep));
+      super.copyWith((message) => updates(message as HasKeep))
+          as HasKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static HasKeep create() => HasKeep._();
@@ -209,7 +256,7 @@
   @$core.pragma('dart2js:noInline')
   static HasKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<HasKeep>(create);
-  static HasKeep _defaultInstance;
+  static HasKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
@@ -225,10 +272,19 @@
 }
 
 class ClearKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('ClearKeep', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'ClearKeep',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   ClearKeep._() : super();
   factory ClearKeep() => create();
@@ -238,9 +294,16 @@
   factory ClearKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   ClearKeep clone() => ClearKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   ClearKeep copyWith(void Function(ClearKeep) updates) =>
-      super.copyWith((message) => updates(message as ClearKeep));
+      super.copyWith((message) => updates(message as ClearKeep))
+          as ClearKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static ClearKeep create() => ClearKeep._();
@@ -249,7 +312,7 @@
   @$core.pragma('dart2js:noInline')
   static ClearKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClearKeep>(create);
-  static ClearKeep _defaultInstance;
+  static ClearKeep? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
@@ -265,10 +328,19 @@
 }
 
 class ZopDrop extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('ZopDrop', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'ZopDrop',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   ZopDrop._() : super();
   factory ZopDrop() => create();
@@ -278,9 +350,16 @@
   factory ZopDrop.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   ZopDrop clone() => ZopDrop()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   ZopDrop copyWith(void Function(ZopDrop) updates) =>
-      super.copyWith((message) => updates(message as ZopDrop));
+      super.copyWith((message) => updates(message as ZopDrop))
+          as ZopDrop; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static ZopDrop create() => ZopDrop._();
@@ -289,7 +368,7 @@
   @$core.pragma('dart2js:noInline')
   static ZopDrop getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ZopDrop>(create);
-  static ZopDrop _defaultInstance;
+  static ZopDrop? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
@@ -305,10 +384,19 @@
 }
 
 class MobDrop extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('MobDrop', createEmptyInstance: create)
-        ..a<$core.int>(1, 'aDrop', $pb.PbFieldType.O3, protoName: 'aDrop')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'MobDrop',
+      createEmptyInstance: create)
+    ..a<$core.int>(
+        1,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'aDrop',
+        $pb.PbFieldType.O3,
+        protoName: 'aDrop')
+    ..hasRequiredFields = false;
 
   MobDrop._() : super();
   factory MobDrop() => create();
@@ -318,9 +406,16 @@
   factory MobDrop.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   MobDrop clone() => MobDrop()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   MobDrop copyWith(void Function(MobDrop) updates) =>
-      super.copyWith((message) => updates(message as MobDrop));
+      super.copyWith((message) => updates(message as MobDrop))
+          as MobDrop; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static MobDrop create() => MobDrop._();
@@ -329,7 +424,7 @@
   @$core.pragma('dart2js:noInline')
   static MobDrop getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MobDrop>(create);
-  static MobDrop _defaultInstance;
+  static MobDrop? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.int get aDrop => $_getIZ(0);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/name_mangling.pb.dart b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/name_mangling.pb.dart
index bc76b27..c42141a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/name_mangling.pb.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/generated/name_mangling.pb.dart
@@ -2,17 +2,20 @@
 //  Generated code. Do not modify.
 //  source: name_mangling.proto
 //
-// @dart = 2.3
-// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
 
 import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class AKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('AKeep', createEmptyInstance: create)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'AKeep',
+      createEmptyInstance: create)
+    ..hasRequiredFields = false;
 
   AKeep._() : super();
   factory AKeep() => create();
@@ -22,9 +25,16 @@
   factory AKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   AKeep clone() => AKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   AKeep copyWith(void Function(AKeep) updates) =>
-      super.copyWith((message) => updates(message as AKeep));
+      super.copyWith((message) => updates(message as AKeep))
+          as AKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static AKeep create() => AKeep._();
@@ -33,14 +43,22 @@
   @$core.pragma('dart2js:noInline')
   static AKeep getDefault() =>
       _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AKeep>(create);
-  static AKeep _defaultInstance;
+  static AKeep? _defaultInstance;
 }
 
 class NameManglingKeep extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      $pb.BuilderInfo('NameManglingKeep', createEmptyInstance: create)
-        ..aOM<AKeep>(10, 'clone', subBuilder: AKeep.create)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+      const $core.bool.fromEnvironment('protobuf.omit_message_names')
+          ? ''
+          : 'NameManglingKeep',
+      createEmptyInstance: create)
+    ..aOM<AKeep>(
+        10,
+        const $core.bool.fromEnvironment('protobuf.omit_field_names')
+            ? ''
+            : 'clone',
+        subBuilder: AKeep.create)
+    ..hasRequiredFields = false;
 
   NameManglingKeep._() : super();
   factory NameManglingKeep() => create();
@@ -50,9 +68,16 @@
   factory NameManglingKeep.fromJson($core.String i,
           [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
       create()..mergeFromJson(i, r);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+      'Will be removed in next major version')
   NameManglingKeep clone() => NameManglingKeep()..mergeFromMessage(this);
+  @$core.Deprecated('Using this can add significant overhead to your binary. '
+      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+      'Will be removed in next major version')
   NameManglingKeep copyWith(void Function(NameManglingKeep) updates) =>
-      super.copyWith((message) => updates(message as NameManglingKeep));
+      super.copyWith((message) => updates(message as NameManglingKeep))
+          as NameManglingKeep; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
   static NameManglingKeep create() => NameManglingKeep._();
@@ -62,7 +87,7 @@
   @$core.pragma('dart2js:noInline')
   static NameManglingKeep getDefault() => _defaultInstance ??=
       $pb.GeneratedMessage.$_defaultFor<NameManglingKeep>(create);
-  static NameManglingKeep _defaultInstance;
+  static NameManglingKeep? _defaultInstance;
 
   @$pb.TagNumber(10)
   AKeep get clone_10 => $_getN(0);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
index 599d0eb..6f760ed 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
@@ -12,7 +12,7 @@
     core::print("Has clone field");
   }
 }
-library name_mangling.pb.dart;
+library name_mangling.pb.dart /*isNonNullableByDefault*/;
 import self as self;
 import "package:protobuf/protobuf.dart" as pro;
 import "dart:core" as core;
@@ -21,48 +21,36 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class AKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("AKeep") in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "AKeep", #C2) in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
-  constructor _() → self::AKeep*
+  constructor _() → self::AKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::AKeep*
-    return [@vm.inferred-type.metadata=name_mangling.pb.dart::AKeep] self::AKeep::create();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::AKeep*
-    return let final self::AKeep* #t2 = [@vm.inferred-type.metadata=name_mangling.pb.dart::AKeep] self::AKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::AKeep::_i;
-  @#C3
-  static method create() → self::AKeep*
+  @#C5
+  static method create() → self::AKeep
     return new self::AKeep::_();
 }
 class NameManglingKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("NameManglingKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::aOM}<self::AKeep*>(10, "clone", #C4);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
-  } =>#t3;
-  constructor _() → self::NameManglingKeep*
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•((#C1) ?{core::String} "" : "NameManglingKeep", #C6) in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::aOM}<self::AKeep>(10, (#C1) ?{core::String} "" : "clone", #C2);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
+  } =>#t2;
+  constructor _() → self::NameManglingKeep
     : super pro::GeneratedMessage::•()
     ;
-  static factory •() → self::NameManglingKeep*
-    return [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::create();
-  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::List<core::int*>* i) → self::NameManglingKeep*
-    return let final self::NameManglingKeep* #t4 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::create() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::GeneratedMessage::mergeFromBuffer}(i, #C5);
-    } =>#t4;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::NameManglingKeep*
-    return let final self::NameManglingKeep* #t5 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t5;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
+  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::List<core::int> i) → self::NameManglingKeep
+    return let final self::NameManglingKeep #t3 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::create() in block {
+      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::GeneratedMessage::mergeFromBuffer}(i);
+    } =>#t3;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::NameManglingKeep::_i;
-  @#C3
-  static method create() → self::NameManglingKeep*
+  @#C5
+  static method create() → self::NameManglingKeep
     return new self::NameManglingKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5]  @#C7
-  method hasClone_10() → core::bool*
-    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(0);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C8
+  method hasClone_10() → core::bool
+    return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
index 7f5cdd6..61cf1bbd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
@@ -23,7 +23,7 @@
       return;
     core::print([@vm.direct-call.metadata=#lib::_SplayTreeNode.left] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] root{self::_SplayTree::Node}.{self::_SplayTreeNode::left});
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  abstract get /*isNullableByDefault*/ _root() → self::_SplayTree::Node?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  abstract get /*isLegacy*/ _root() → self::_SplayTree::Node?;
 }
 class SplayTreeMap<V extends core::Object? = dynamic> extends self::_SplayTree<self::_SplayTreeMapNode<self::SplayTreeMap::V%>> {
 [@vm.inferred-type.metadata=#lib::_SplayTreeMapNode] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:5]  generic-covariant-impl field self::_SplayTreeMapNode<self::SplayTreeMap::V%>? _root = new self::_SplayTreeMapNode::•<self::SplayTreeMap::V%>();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect
index 101cd55..72a2ae0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect
@@ -12,8 +12,8 @@
   synthetic constructor •() → self::B<self::B::T*>*
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i]  method testT1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T*>(x);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i]  method testT1() → dynamic
+    return _in::unsafeCast<self::B::T*>(#C1);
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method testT2negative([@vm.inferred-type.metadata=#lib::A<dart.core::String*>] dynamic x) → dynamic
     return x as self::B::T*;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  method testAOfT1([@vm.inferred-type.metadata=#lib::A<#lib::A<dart.core::int*>*>] dynamic x) → dynamic
@@ -21,14 +21,14 @@
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  method testAOfT2negative([@vm.inferred-type.metadata=#lib::A<#lib::A<dart.core::num*>*>] dynamic x) → dynamic
     return x as self::A<self::B::T*>*;
 }
-[@vm.unboxing-info.metadata=(i)->i]static method testInt1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int*>(x);
-static method testInt2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int*>(x);
-static method testDynamic([@vm.inferred-type.metadata=dart.core::_OneByteString (value: "hi")] dynamic x) → dynamic
-  return _in::unsafeCast<dynamic>(x);
-static method testObject([@vm.inferred-type.metadata=dart.core::_OneByteString (value: "bye")] dynamic x) → dynamic
-  return x;
+[@vm.unboxing-info.metadata=()->i]static method testInt1() → dynamic
+  return _in::unsafeCast<core::int*>(#C1);
+static method testInt2() → dynamic
+  return _in::unsafeCast<core::int*>(#C2);
+static method testDynamic() → dynamic
+  return _in::unsafeCast<dynamic>(#C3);
+static method testObject() → dynamic
+  return #C4;
 static method testBOfInt([@vm.inferred-type.metadata=#lib::B<dart.core::int*>] dynamic x) → dynamic
   return _in::unsafeCast<self::B<core::int*>*>(x);
 static method testAOfInt([@vm.inferred-type.metadata=#lib::B<dart.core::int*>] dynamic x) → dynamic
@@ -40,16 +40,16 @@
 static method testAOfAOfB2negative([@vm.inferred-type.metadata=#lib::A<#lib::A<#lib::A<dynamic>*>*>] dynamic x) → dynamic
   return x as self::A<self::A<self::B<dynamic>*>*>*;
 static method main() → void {
-  self::testInt1(42);
-  self::testInt2(null);
-  self::testDynamic("hi");
-  self::testObject("bye");
+  self::testInt1();
+  self::testInt2();
+  self::testDynamic();
+  self::testObject();
   self::testBOfInt(new self::B::•<core::int*>());
   self::testAOfInt(new self::B::•<core::int*>());
   self::testAOfNum(new self::B::•<core::int*>());
   self::testAOfAOfB1(new self::A::•<self::A<self::B<dynamic>*>*>());
   self::testAOfAOfB2negative(new self::A::•<self::A<self::A<dynamic>*>*>());
-  [@vm.direct-call.metadata=#lib::B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int*>().{self::B::testT1}(42);
+  [@vm.direct-call.metadata=#lib::B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int*>().{self::B::testT1}();
   [@vm.direct-call.metadata=#lib::B.testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testT2negative}(new self::A::•<core::String*>());
   [@vm.direct-call.metadata=#lib::B.testAOfT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testAOfT1}(new self::A::•<self::A<core::int*>*>());
   [@vm.direct-call.metadata=#lib::B.testAOfT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testAOfT2negative}(new self::A::•<self::A<core::num*>*>());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect
index 11d1e0b..95e736c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect
@@ -12,60 +12,60 @@
   synthetic constructor •() → self::B<self::B::T%>
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i]  method testT1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T%>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method testT2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T%>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  method testT3([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T%>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(i)->i]  method testNullableT1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T?>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method testNullableT2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T?>(x);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i]  method testT1() → dynamic
+    return _in::unsafeCast<self::B::T%>(#C1);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method testT2() → dynamic
+    return _in::unsafeCast<self::B::T%>(#C2);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  method testT3() → dynamic
+    return _in::unsafeCast<self::B::T%>(#C2);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=()->i]  method testNullableT1() → dynamic
+    return _in::unsafeCast<self::B::T?>(#C1);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method testNullableT2() → dynamic
+    return _in::unsafeCast<self::B::T?>(#C2);
 }
-[@vm.unboxing-info.metadata=(i)->i]static method testInt1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int>(x);
-static method testInt2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int>(x);
-[@vm.unboxing-info.metadata=(i)->i]static method testNullableInt1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int?>(x);
-static method testNullableInt2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int?>(x);
-static method testDynamic([@vm.inferred-type.metadata=dart.core::_OneByteString (value: "hi")] dynamic x) → dynamic
-  return _in::unsafeCast<dynamic>(x);
-static method testObject([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return x;
-static method testNullableObject([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return x;
+[@vm.unboxing-info.metadata=()->i]static method testInt1() → dynamic
+  return _in::unsafeCast<core::int>(#C1);
+static method testInt2() → dynamic
+  return _in::unsafeCast<core::int>(#C2);
+[@vm.unboxing-info.metadata=()->i]static method testNullableInt1() → dynamic
+  return _in::unsafeCast<core::int?>(#C1);
+static method testNullableInt2() → dynamic
+  return _in::unsafeCast<core::int?>(#C2);
+static method testDynamic() → dynamic
+  return _in::unsafeCast<dynamic>(#C3);
+static method testObject() → dynamic
+  return #C2;
+static method testNullableObject() → dynamic
+  return #C2;
 static method testAOfNum1([@vm.inferred-type.metadata=#lib::B<dart.core::int>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num>>(x);
 static method testAOfNum2([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num>>(x);
-static method testAOfNum3([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<self::A<core::num>>(x);
+static method testAOfNum3() → dynamic
+  return _in::unsafeCast<self::A<core::num>>(#C2);
 static method testAOfNullableNum([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num?>>(x);
-static method testNullableAOfNum([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<self::A<core::num>?>(x);
+static method testNullableAOfNum() → dynamic
+  return _in::unsafeCast<self::A<core::num>?>(#C2);
 static method testNullableAOfNullableNum([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num?>?>(x);
 static method main() → void {
-  self::testInt1(42);
-  self::testInt2(null);
-  self::testNullableInt1(42);
-  self::testNullableInt2(null);
-  self::testDynamic("hi");
-  self::testObject(null);
-  self::testNullableObject(null);
+  self::testInt1();
+  self::testInt2();
+  self::testNullableInt1();
+  self::testNullableInt2();
+  self::testDynamic();
+  self::testObject();
+  self::testNullableObject();
   self::testAOfNum1(new self::B::•<core::int>());
   self::testAOfNum2(new self::B::•<core::int?>());
-  self::testAOfNum3(null);
+  self::testAOfNum3();
   self::testAOfNullableNum(new self::B::•<core::int?>());
-  self::testNullableAOfNum(null);
+  self::testNullableAOfNum();
   self::testNullableAOfNullableNum(new self::B::•<core::int?>());
-  [@vm.direct-call.metadata=#lib::B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}(42);
-  [@vm.direct-call.metadata=#lib::B.testT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2}(null);
-  [@vm.direct-call.metadata=#lib::B.testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}(null);
-  [@vm.direct-call.metadata=#lib::B.testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}(42);
-  [@vm.direct-call.metadata=#lib::B.testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}(null);
+  [@vm.direct-call.metadata=#lib::B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}();
+  [@vm.direct-call.metadata=#lib::B.testT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2}();
+  [@vm.direct-call.metadata=#lib::B.testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}();
+  [@vm.direct-call.metadata=#lib::B.testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}();
+  [@vm.direct-call.metadata=#lib::B.testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect
index 10ac8a6..8ad5b44 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect
@@ -12,63 +12,63 @@
   synthetic constructor •() → self::B<self::B::T%>
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i]  method testT1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T%>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method testT2negative([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-    return x as{ForNonNullableByDefault} self::B::T%;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  method testT3([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T%>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(i)->i]  method testNullableT1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T?>(x);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method testNullableT2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-    return _in::unsafeCast<self::B::T?>(x);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=()->i]  method testT1() → dynamic
+    return _in::unsafeCast<self::B::T%>(#C1);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method testT2negative() → dynamic
+    return (#C2) as{ForNonNullableByDefault} self::B::T%;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  method testT3() → dynamic
+    return _in::unsafeCast<self::B::T%>(#C2);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=()->i]  method testNullableT1() → dynamic
+    return _in::unsafeCast<self::B::T?>(#C1);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method testNullableT2() → dynamic
+    return _in::unsafeCast<self::B::T?>(#C2);
 }
-[@vm.unboxing-info.metadata=(i)->i]static method testInt1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int>(x);
-static method testInt2negative([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return x as{ForNonNullableByDefault} core::int;
-[@vm.unboxing-info.metadata=(i)->i]static method testNullableInt1([@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int?>(x);
-static method testNullableInt2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<core::int?>(x);
-static method testDynamic([@vm.inferred-type.metadata=dart.core::_OneByteString (value: "hi")] dynamic x) → dynamic
-  return _in::unsafeCast<dynamic>(x);
-static method testObjectNegative([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return let dynamic #t1 = x in true ?{core::Object} #t1 as{ForNonNullableByDefault} core::Object : #t1{core::Object};
-static method testNullableObject([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return x;
+[@vm.unboxing-info.metadata=()->i]static method testInt1() → dynamic
+  return _in::unsafeCast<core::int>(#C1);
+static method testInt2negative() → dynamic
+  return (#C2) as{ForNonNullableByDefault} core::int;
+[@vm.unboxing-info.metadata=()->i]static method testNullableInt1() → dynamic
+  return _in::unsafeCast<core::int?>(#C1);
+static method testNullableInt2() → dynamic
+  return _in::unsafeCast<core::int?>(#C2);
+static method testDynamic() → dynamic
+  return _in::unsafeCast<dynamic>(#C3);
+static method testObjectNegative() → dynamic
+  return let dynamic #t1 = #C2 in true ?{core::Object} #t1 as{ForNonNullableByDefault} core::Object : #t1{core::Object};
+static method testNullableObject() → dynamic
+  return #C2;
 static method testAOfNum1([@vm.inferred-type.metadata=#lib::B<dart.core::int>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num>>(x);
 static method testAOfNum2negative([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return x as{ForNonNullableByDefault} self::A<core::num>;
-static method testAOfNum3negative([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return x as{ForNonNullableByDefault} self::A<core::num>;
+static method testAOfNum3negative() → dynamic
+  return (#C2) as{ForNonNullableByDefault} self::A<core::num>;
 static method testAOfNullableNum([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num?>>(x);
-static method testNullableAOfNum([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
-  return _in::unsafeCast<self::A<core::num>?>(x);
+static method testNullableAOfNum() → dynamic
+  return _in::unsafeCast<self::A<core::num>?>(#C2);
 static method testNullableAOfNumNegative([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return x as{ForNonNullableByDefault} self::A<core::num>?;
 static method testNullableAOfNullableNum([@vm.inferred-type.metadata=#lib::B<dart.core::int?>] dynamic x) → dynamic
   return _in::unsafeCast<self::A<core::num?>?>(x);
 static method main() → void {
-  self::testInt1(42);
-  self::testInt2negative(null);
-  self::testNullableInt1(42);
-  self::testNullableInt2(null);
-  self::testDynamic("hi");
-  self::testObjectNegative(null);
-  self::testNullableObject(null);
+  self::testInt1();
+  self::testInt2negative();
+  self::testNullableInt1();
+  self::testNullableInt2();
+  self::testDynamic();
+  self::testObjectNegative();
+  self::testNullableObject();
   self::testAOfNum1(new self::B::•<core::int>());
   self::testAOfNum2negative(new self::B::•<core::int?>());
-  self::testAOfNum3negative(null);
+  self::testAOfNum3negative();
   self::testAOfNullableNum(new self::B::•<core::int?>());
-  self::testNullableAOfNum(null);
+  self::testNullableAOfNum();
   self::testNullableAOfNumNegative(new self::B::•<core::int?>());
   self::testNullableAOfNullableNum(new self::B::•<core::int?>());
-  [@vm.direct-call.metadata=#lib::B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}(42);
-  [@vm.direct-call.metadata=#lib::B.testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2negative}(null);
-  [@vm.direct-call.metadata=#lib::B.testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}(null);
-  [@vm.direct-call.metadata=#lib::B.testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}(42);
-  [@vm.direct-call.metadata=#lib::B.testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}(null);
+  [@vm.direct-call.metadata=#lib::B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}();
+  [@vm.direct-call.metadata=#lib::B.testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2negative}();
+  [@vm.direct-call.metadata=#lib::B.testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}();
+  [@vm.direct-call.metadata=#lib::B.testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}();
+  [@vm.direct-call.metadata=#lib::B.testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
index 4dbd258..2109c6a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
@@ -23,8 +23,8 @@
 }
 class BI2A extends core::Object implements self::BI2 {
 [@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]  final field core::int* value;
-  constructor •([@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::int* value) → self::BI2A*
-    : self::BI2A::value = value, super core::Object::•()
+  constructor •() → self::BI2A*
+    : self::BI2A::value = #C1, super core::Object::•()
     ;
 }
 class BI2B extends core::Object implements self::BI2 {
@@ -81,7 +81,7 @@
   final self::BI1A* bi1a = new self::BI1A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
   final self::BI1B* bi1b = new self::BI1B::•();
   self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI1*} bi1a : bi1b).{self::BI1::value});
-  final self::BI2A* bi2a = new self::BI2A::•(null);
+  final self::BI2A* bi2a = new self::BI2A::•();
   final self::BI2B* bi2b = new self::BI2B::•();
   self::use([@vm.inferred-type.metadata=int?]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::BI2*} bi2a : bi2b).{self::BI2::value});
   final self::BI3A* bi3a = new self::BI3A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
index c2f2f87..664dad2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
@@ -61,7 +61,7 @@
     [@vm.call-site-attributes.metadata=receiverType:#lib::C<dart.core::num*>*] [@vm.direct-call.metadata=#lib::D.bar] c.{self::C::bar} = 3.14;
   });
   self::E* e = new self::F::•();
-  exp::Expect::equals(42, [@vm.direct-call.metadata=#lib::F.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar});
+  let final core::int* #t2 = [@vm.direct-call.metadata=#lib::F.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar} in exp::Expect::equals();
   exp::Expect::isTrue(![@vm.inferred-type.metadata=dart.core::bool] core::identical(#C2, #C4));
   [@vm.direct-call.metadata=#lib::I.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::I::•().{self::I::foo}();
   5;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
index b363f58..001ee63 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
@@ -9,10 +9,10 @@
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method use() → dynamic {
     [@vm.direct-call.metadata=#lib::A.x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A::x} = 3;
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3]  set /*isNullableByDefault*/ x(core::int value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3]  set /*isLegacy*/ x(core::int value) → void;
 }
 class B extends core::Object {
-[@vm.inferred-type.metadata=dart.core::_Smi?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5]  late final [setter] field core::int x;
+[@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i)->i]  late final [setter] field core::int x;
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
@@ -20,7 +20,7 @@
     [@vm.direct-call.metadata=#lib::B.x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::B::x} = 3;
   }
 }
-[@vm.inferred-type.metadata=dart.core::_Smi?]late static final field core::int staticLateB;
+[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] [@vm.unboxing-info.metadata=(i)->i]late static final field core::int staticLateB;
 static method main() → void {
   [@vm.direct-call.metadata=#lib::A.use] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::use}();
   [@vm.direct-call.metadata=#lib::B.use] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::use}();
diff --git a/pkg/vm_service/test/async_single_step_exception_test.dart b/pkg/vm_service/test/async_single_step_exception_test.dart
index 189196e..b616326 100644
--- a/pkg/vm_service/test/async_single_step_exception_test.dart
+++ b/pkg/vm_service/test/async_single_step_exception_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:developer';
 import 'common/service_test_common.dart';
diff --git a/pkg/vm_service/test/async_single_step_into_test.dart b/pkg/vm_service/test/async_single_step_into_test.dart
index 90be6df..36dd15b 100644
--- a/pkg/vm_service/test/async_single_step_into_test.dart
+++ b/pkg/vm_service/test/async_single_step_into_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:developer';
 import 'common/service_test_common.dart';
diff --git a/pkg/vm_service/test/async_single_step_out_test.dart b/pkg/vm_service/test/async_single_step_out_test.dart
index fe8baed..a0a3d83 100644
--- a/pkg/vm_service/test/async_single_step_out_test.dart
+++ b/pkg/vm_service/test/async_single_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:developer';
 import 'common/service_test_common.dart';
diff --git a/pkg/vm_service/test/async_star_single_step_into_test.dart b/pkg/vm_service/test/async_star_single_step_into_test.dart
index 061c2fd..d2d730e 100644
--- a/pkg/vm_service/test/async_star_single_step_into_test.dart
+++ b/pkg/vm_service/test/async_star_single_step_into_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:developer';
 import 'common/service_test_common.dart';
diff --git a/pkg/vm_service/test/async_star_step_out_test.dart b/pkg/vm_service/test/async_star_step_out_test.dart
index 6e4cde9..5bb8dde 100644
--- a/pkg/vm_service/test/async_star_step_out_test.dart
+++ b/pkg/vm_service/test/async_star_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:developer';
 import 'common/service_test_common.dart';
diff --git a/pkg/vm_service/test/async_step_out_test.dart b/pkg/vm_service/test/async_step_out_test.dart
index 3ccfb1d..8e46584 100644
--- a/pkg/vm_service/test/async_step_out_test.dart
+++ b/pkg/vm_service/test/async_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:developer';
 import 'common/service_test_common.dart';
diff --git a/pkg/vm_service/test/common/test_helper.dart b/pkg/vm_service/test/common/test_helper.dart
index 836e323..48d5941 100644
--- a/pkg/vm_service/test/common/test_helper.dart
+++ b/pkg/vm_service/test/common/test_helper.dart
@@ -13,14 +13,8 @@
 import 'service_test_common.dart';
 export 'service_test_common.dart' show IsolateTest, VMTest;
 
-/// Whether to use causal async stacks (if not we use lazy async stacks).
-const bool useCausalAsyncStacks =
-    bool.fromEnvironment('dart.developer.causal_async_stacks');
-
 /// The extra arguments to use
-const List<String> extraDebuggingArgs = useCausalAsyncStacks
-    ? ['--causal-async-stacks', '--no-lazy-async-stacks']
-    : ['--no-causal-async-stacks', '--lazy-async-stacks'];
+const List<String> extraDebuggingArgs = ['--lazy-async-stacks'];
 
 /// Will be set to the http address of the VM's service protocol before
 /// any tests are invoked.
diff --git a/pkg/vm_service/test/get_isolate_rpc_test.dart b/pkg/vm_service/test/get_isolate_rpc_test.dart
index ed901a3..6df4ec0 100644
--- a/pkg/vm_service/test/get_isolate_rpc_test.dart
+++ b/pkg/vm_service/test/get_isolate_rpc_test.dart
@@ -22,8 +22,6 @@
     expect(result.pauseOnExit, isFalse);
     expect(result.pauseEvent.type, 'Event');
     expect(result.error, isNull);
-    expect(result.json['_numZoneHandles'], isPositive);
-    expect(result.json['_numScopedHandles'], isPositive);
     expect(result.rootLib, isNotNull);
     expect(result.libraries.length, isPositive);
     expect(result.libraries[0], isNotNull);
diff --git a/pkg/vm_service/test/get_stack_test.dart b/pkg/vm_service/test/get_stack_test.dart
new file mode 100644
index 0000000..5889996
--- /dev/null
+++ b/pkg/vm_service/test/get_stack_test.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--lazy-async-stacks --verbose_debug
+
+import 'dart:developer';
+
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+const LINE_A = 33;
+const LINE_B = 35;
+
+Future<void> testMain() async {
+  await func1();
+}
+
+Future func1() async => await func2();
+Future func2() async => await func3();
+Future func3() async => await func4();
+Future func4() async => await func5();
+Future func5() async => await func6();
+Future func6() async => await func7();
+Future func7() async => await func8();
+Future func8() async => await func9();
+Future func9() async => await func10();
+Future func10() async {
+  debugger(); // LINE_A
+  await 0;
+  debugger(); // LINE_B
+  print("Hello, world!");
+}
+
+void expectFrame(
+    final frame, final kindExpectation, final codeNameExpectation) {
+  expect(frame.kind, kindExpectation);
+  expect(frame.code?.name, codeNameExpectation);
+}
+
+void expectFrames(final frames, final expectKindAndCodeName) {
+  for (int i = 0; i < expectKindAndCodeName.length; i++) {
+    expectFrame(
+        frames[i], expectKindAndCodeName[i][0], expectKindAndCodeName[i][1]);
+  }
+}
+
+final tests = <IsolateTest>[
+  // Before the first await.
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_A),
+  (VmService service, IsolateRef isolateRef) async {
+    final result = await service.getStack(isolateRef.id);
+
+    expect(result.frames, hasLength(16));
+    expect(result.asyncCausalFrames, hasLength(16));
+    expect(result.awaiterFrames, hasLength(16));
+
+    expectFrames(result.frames, [
+      [equals('Regular'), endsWith(' func10')],
+      [equals('Regular'), endsWith(' func9')],
+      [equals('Regular'), endsWith(' func8')],
+      [equals('Regular'), endsWith(' func7')],
+      [equals('Regular'), endsWith(' func6')],
+      [equals('Regular'), endsWith(' func5')],
+      [equals('Regular'), endsWith(' func4')],
+      [equals('Regular'), endsWith(' func3')],
+      [equals('Regular'), endsWith(' func2')],
+      [equals('Regular'), endsWith(' func1')],
+      [equals('Regular'), endsWith(' testMain')],
+    ]);
+
+    expectFrames(result.asyncCausalFrames, [
+      [equals('Regular'), endsWith(' func10')],
+      [equals('Regular'), endsWith(' func9')],
+      [equals('Regular'), endsWith(' func8')],
+      [equals('Regular'), endsWith(' func7')],
+      [equals('Regular'), endsWith(' func6')],
+      [equals('Regular'), endsWith(' func5')],
+      [equals('Regular'), endsWith(' func4')],
+      [equals('Regular'), endsWith(' func3')],
+      [equals('Regular'), endsWith(' func2')],
+      [equals('Regular'), endsWith(' func1')],
+      [equals('Regular'), endsWith(' testMain')],
+    ]);
+
+    expectFrames(result.awaiterFrames, [
+      [equals('AsyncActivation'), endsWith(' func10')],
+      [equals('AsyncActivation'), endsWith(' func9')],
+      [equals('AsyncActivation'), endsWith(' func8')],
+      [equals('AsyncActivation'), endsWith(' func7')],
+      [equals('AsyncActivation'), endsWith(' func6')],
+      [equals('AsyncActivation'), endsWith(' func5')],
+      [equals('AsyncActivation'), endsWith(' func4')],
+      [equals('AsyncActivation'), endsWith(' func3')],
+      [equals('AsyncActivation'), endsWith(' func2')],
+      [equals('AsyncActivation'), endsWith(' func1')],
+      [equals('AsyncActivation'), endsWith(' testMain')],
+    ]);
+  },
+  // After resuming the continuation - i.e. running async.
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_B),
+  (VmService service, IsolateRef isolateRef) async {
+    final result = await service.getStack(isolateRef.id);
+
+    expect(result.frames, hasLength(10));
+    expect(result.asyncCausalFrames, hasLength(26));
+    expect(result.awaiterFrames, hasLength(2));
+
+    expectFrames(result.frames, [
+      [equals('Regular'), endsWith(' func10')],
+      [equals('Regular'), endsWith(' _RootZone.runUnary')],
+      [equals('Regular'), anything], // Internal mech. ..
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), endsWith(' _RawReceivePortImpl._handleMessage')],
+    ]);
+
+    expectFrames(result.asyncCausalFrames, [
+      [equals('Regular'), endsWith(' func10')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func9')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func8')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func7')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func6')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func5')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func4')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func3')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func2')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func1')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' testMain')],
+      [equals('AsyncSuspensionMarker'), isNull],
+    ]);
+
+    expectFrames(result.awaiterFrames, [
+      [equals('AsyncActivation'), endsWith(' func10')],
+      [equals('AsyncActivation'), endsWith(' func9')],
+    ]);
+  },
+];
+
+main([args = const <String>[]]) =>
+    runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/pkg/vm_service/test/heap_snapshot_graph_test.dart b/pkg/vm_service/test/heap_snapshot_graph_test.dart
index 7bd4418..7b035cc 100644
--- a/pkg/vm_service/test/heap_snapshot_graph_test.dart
+++ b/pkg/vm_service/test/heap_snapshot_graph_test.dart
@@ -27,10 +27,10 @@
   r.right = b;
   a.left = b;
 
-  lst = List(2);
+  lst = List.filled(2, null);
   lst[0] = lst; // Self-loop.
   // Larger than any other fixed-size list in a fresh heap.
-  lst[1] = List(1234569);
+  lst[1] = List.filled(1234569, null);
 }
 
 var tests = <IsolateTest>[
diff --git a/pkg/vm_snapshot_analysis/lib/program_info.dart b/pkg/vm_snapshot_analysis/lib/program_info.dart
index c139f02..e243048 100644
--- a/pkg/vm_snapshot_analysis/lib/program_info.dart
+++ b/pkg/vm_snapshot_analysis/lib/program_info.dart
@@ -62,7 +62,7 @@
       void Function(
               String pkg, String lib, String cls, String fun, ProgramInfoNode n)
           callback) {
-    final context = List<String>(NodeType.values.length);
+    final context = List<String>.filled(NodeType.values.length, null);
 
     void recurse(ProgramInfoNode node) {
       final prevContext = context[node._type];
diff --git a/pkg/vm_snapshot_analysis/lib/treemap.dart b/pkg/vm_snapshot_analysis/lib/treemap.dart
index 36ce891..c0535e7 100644
--- a/pkg/vm_snapshot_analysis/lib/treemap.dart
+++ b/pkg/vm_snapshot_analysis/lib/treemap.dart
@@ -163,7 +163,8 @@
     return;
   }
 
-  final ownerPathCache = List<String>(info.snapshotInfo.infoNodes.length);
+  final ownerPathCache =
+      List<String>.filled(info.snapshotInfo.infoNodes.length, null);
   ownerPathCache[info.root.id] = info.root.name;
 
   String ownerPath(ProgramInfoNode n) {
diff --git a/pkg/wasm/lib/src/module.dart b/pkg/wasm/lib/src/module.dart
index d60f9e8..62723d5 100644
--- a/pkg/wasm/lib/src/module.dart
+++ b/pkg/wasm/lib/src/module.dart
@@ -11,12 +11,14 @@
 
 /// WasmModule is a compiled module that can be instantiated.
 class WasmModule {
-  Pointer<WasmerStore> _store;
+  late Pointer<WasmerStore> _store;
   late Pointer<WasmerModule> _module;
 
   /// Compile a module.
-  WasmModule(Uint8List data) : _store = WasmRuntime().newStore() {
-    _module = WasmRuntime().compile(_store, data);
+  WasmModule(Uint8List data) {
+    var runtime = WasmRuntime();
+    _store = runtime.newStore(this);
+    _module = runtime.compile(this, _store, data);
   }
 
   /// Returns a WasmInstanceBuilder that is used to add all the imports that the
@@ -115,6 +117,7 @@
   Map<String, int> _importIndex;
   Pointer<WasmerExternVec> _imports = allocate<WasmerExternVec>();
   Pointer<WasmerWasiEnv> _wasiEnv = nullptr;
+  Object _importOwner = Object();
 
   WasmInstanceBuilder(this._module) : _importIndex = {} {
     _importDescs = WasmRuntime().importDescriptors(_module._module);
@@ -168,6 +171,7 @@
     wasmFnImport.ref.store = _module._store;
     _wasmFnImportToFn[wasmFnImport.address] = fn;
     var fnImp = runtime.newFunc(
+        _importOwner,
         _module._store,
         imp.funcType,
         _wasmFnImportTrampolineNative,
@@ -199,24 +203,26 @@
         throw Exception("Missing import: ${_importDescs[i]}");
       }
     }
-    return WasmInstance(_module, _imports, _wasiEnv);
+    return WasmInstance(_module, _imports, _wasiEnv, _importOwner);
   }
 }
 
 /// WasmInstance is an instantiated WasmModule.
 class WasmInstance {
   WasmModule _module;
-  Pointer<WasmerInstance> _instance;
+  late Pointer<WasmerInstance> _instance;
   Pointer<WasmerMemory>? _exportedMemory;
   Pointer<WasmerWasiEnv> _wasiEnv;
   Stream<List<int>>? _stdout;
   Stream<List<int>>? _stderr;
   Map<String, WasmFunction> _functions = {};
+  Object _importOwner;
 
-  WasmInstance(this._module, Pointer<WasmerExternVec> imports, this._wasiEnv)
-      : _instance = WasmRuntime()
-            .instantiate(_module._store, _module._module, imports) {
+  WasmInstance(this._module, Pointer<WasmerExternVec> imports, this._wasiEnv,
+      this._importOwner) {
     var runtime = WasmRuntime();
+    _instance =
+        runtime.instantiate(this, _module._store, _module._module, imports);
     var exports = runtime.exports(_instance);
     var exportDescs = runtime.exportDescriptors(_module._module);
     assert(exports.ref.length == exportDescs.length);
@@ -275,7 +281,7 @@
 
 /// WasmMemory contains the memory of a WasmInstance.
 class WasmMemory {
-  Pointer<WasmerMemory> _mem;
+  late Pointer<WasmerMemory> _mem;
   late Uint8List _view;
 
   WasmMemory._fromExport(this._mem) {
@@ -284,8 +290,8 @@
 
   /// Create a new memory with the given number of initial pages, and optional
   /// maximum number of pages.
-  WasmMemory._create(Pointer<WasmerStore> store, int pages, int? maxPages)
-      : _mem = WasmRuntime().newMemory(store, pages, maxPages) {
+  WasmMemory._create(Pointer<WasmerStore> store, int pages, int? maxPages) {
+    _mem = WasmRuntime().newMemory(this, store, pages, maxPages);
     _view = WasmRuntime().memoryView(_mem);
   }
 
diff --git a/pkg/wasm/lib/src/runtime.dart b/pkg/wasm/lib/src/runtime.dart
index ee83580..777c6dc 100644
--- a/pkg/wasm/lib/src/runtime.dart
+++ b/pkg/wasm/lib/src/runtime.dart
@@ -54,12 +54,26 @@
   }
 }
 
+class _WasmTrapsEntry {
+  dynamic exception;
+  _WasmTrapsEntry(this.exception);
+}
+
 class WasmRuntime {
   static WasmRuntime? _inst;
 
   DynamicLibrary _lib;
   late Pointer<WasmerEngine> _engine;
-  Map<int, dynamic> traps = {};
+  Map<int, _WasmTrapsEntry> traps = {};
+  late WasmerDartInitializeApiDLFn _Dart_InitializeApiDL;
+  late WasmerSetFinalizerForEngineFn _set_finalizer_for_engine;
+  late WasmerSetFinalizerForFuncFn _set_finalizer_for_func;
+  late WasmerSetFinalizerForInstanceFn _set_finalizer_for_instance;
+  late WasmerSetFinalizerForMemoryFn _set_finalizer_for_memory;
+  late WasmerSetFinalizerForMemorytypeFn _set_finalizer_for_memorytype;
+  late WasmerSetFinalizerForModuleFn _set_finalizer_for_module;
+  late WasmerSetFinalizerForStoreFn _set_finalizer_for_store;
+  late WasmerSetFinalizerForTrapFn _set_finalizer_for_trap;
   late WasmerWasiConfigInheritStderrFn _wasi_config_inherit_stderr;
   late WasmerWasiConfigInheritStdoutFn _wasi_config_inherit_stdout;
   late WasmerWasiConfigNewFn _wasi_config_new;
@@ -178,6 +192,33 @@
 
   WasmRuntime._init()
       : _lib = DynamicLibrary.open(path.join(_getLibDir(), _getLibName())) {
+    _Dart_InitializeApiDL = _lib.lookupFunction<
+        NativeWasmerDartInitializeApiDLFn,
+        WasmerDartInitializeApiDLFn>('Dart_InitializeApiDL');
+    _set_finalizer_for_engine = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForEngineFn,
+        WasmerSetFinalizerForEngineFn>('set_finalizer_for_engine');
+    _set_finalizer_for_func = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForFuncFn,
+        WasmerSetFinalizerForFuncFn>('set_finalizer_for_func');
+    _set_finalizer_for_instance = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForInstanceFn,
+        WasmerSetFinalizerForInstanceFn>('set_finalizer_for_instance');
+    _set_finalizer_for_memory = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForMemoryFn,
+        WasmerSetFinalizerForMemoryFn>('set_finalizer_for_memory');
+    _set_finalizer_for_memorytype = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForMemorytypeFn,
+        WasmerSetFinalizerForMemorytypeFn>('set_finalizer_for_memorytype');
+    _set_finalizer_for_module = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForModuleFn,
+        WasmerSetFinalizerForModuleFn>('set_finalizer_for_module');
+    _set_finalizer_for_store = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForStoreFn,
+        WasmerSetFinalizerForStoreFn>('set_finalizer_for_store');
+    _set_finalizer_for_trap = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForTrapFn,
+        WasmerSetFinalizerForTrapFn>('set_finalizer_for_trap');
     _wasi_config_inherit_stderr = _lib.lookupFunction<
         NativeWasmerWasiConfigInheritStderrFn,
         WasmerWasiConfigInheritStderrFn>('wasi_config_inherit_stderr');
@@ -377,14 +418,23 @@
         NativeWasmerWasmerLastErrorMessageFn,
         WasmerWasmerLastErrorMessageFn>('wasmer_last_error_message');
 
+    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
+      throw Exception("Failed to initialize Dart API");
+    }
     _engine = _engine_new();
+    _checkNotEqual(_engine, nullptr, "Failed to initialize Wasm engine.");
+    _set_finalizer_for_engine(this, _engine);
   }
 
-  Pointer<WasmerStore> newStore() {
-    return _store_new(_engine);
+  Pointer<WasmerStore> newStore(Object owner) {
+    Pointer<WasmerStore> store = _checkNotEqual(
+        _store_new(_engine), nullptr, "Failed to create Wasm store.");
+    _set_finalizer_for_store(owner, store);
+    return store;
   }
 
-  Pointer<WasmerModule> compile(Pointer<WasmerStore> store, Uint8List data) {
+  Pointer<WasmerModule> compile(
+      Object owner, Pointer<WasmerStore> store, Uint8List data) {
     var dataPtr = allocate<Uint8>(count: data.length);
     for (int i = 0; i < data.length; ++i) {
       dataPtr[i] = data[i];
@@ -398,7 +448,9 @@
     free(dataPtr);
     free(dataVec);
 
-    return _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
+    _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
+    _set_finalizer_for_module(owner, modulePtr);
+    return modulePtr;
   }
 
   List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
@@ -442,37 +494,51 @@
 
   void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
     if (trap != nullptr) {
-      var stashedException = traps[trap.address];
-      if (stashedException != null) {
-        traps.remove(stashedException);
-        throw stashedException;
+      // There are 2 kinds of trap, and their memory is managed differently.
+      // Traps created in the newTrap method below are stored in the traps map
+      // with a corresponding exception, and their memory is managed using a
+      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
+      // code, and in that case we delete them in this function.
+      var entry = traps[trap.address];
+      if (entry != null) {
+        traps.remove(entry);
+        throw entry.exception;
       } else {
         var trapMessage = allocate<WasmerByteVec>();
         _trap_message(trap, trapMessage);
         var message = "Wasm trap when calling $source: ${trapMessage.ref}";
-        free(trapMessage.ref.data);
+        _byte_vec_delete(trapMessage);
         free(trapMessage);
+        _trap_delete(trap);
         throw Exception(message);
       }
     }
   }
 
-  Pointer<WasmerInstance> instantiate(Pointer<WasmerStore> store,
+  Pointer<WasmerInstance> instantiate(Object owner, Pointer<WasmerStore> store,
       Pointer<WasmerModule> module, Pointer<WasmerExternVec> imports) {
     var trap = allocate<Pointer<WasmerTrap>>();
     trap.value = nullptr;
     var inst = _instance_new(store, module, imports, trap);
     maybeThrowTrap(trap.value, "module initialization function");
     free(trap);
-    return _checkNotEqual(inst, nullptr, "Wasm module instantiation failed.");
+    _checkNotEqual(inst, nullptr, "Wasm module instantiation failed.");
+    _set_finalizer_for_instance(owner, inst);
+    return inst;
   }
 
+  // Clean up the exports after use, with deleteExports.
   Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
     var exports = allocate<WasmerExternVec>();
     _instance_exports(instancePtr, exports);
     return exports;
   }
 
+  void deleteExports(Pointer<WasmerExternVec> exports) {
+    _extern_vec_delete(exports);
+    free(exports);
+  }
+
   int externKind(Pointer<WasmerExtern> extern) {
     return _extern_kind(extern);
   }
@@ -518,14 +584,18 @@
   }
 
   Pointer<WasmerMemory> newMemory(
-      Pointer<WasmerStore> store, int pages, int? maxPages) {
+      Object owner, Pointer<WasmerStore> store, int pages, int? maxPages) {
     var limPtr = allocate<WasmerLimits>();
     limPtr.ref.min = pages;
     limPtr.ref.max = maxPages ?? wasm_limits_max_default;
     var memType = _memorytype_new(limPtr);
     free(limPtr);
-    return _checkNotEqual(
+    _checkNotEqual(memType, nullptr, "Failed to create memory type.");
+    _set_finalizer_for_memorytype(owner, memType);
+    var memory = _checkNotEqual(
         _memory_new(store, memType), nullptr, "Failed to create memory.");
+    _set_finalizer_for_memory(owner, memory);
+    return memory;
   }
 
   void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
@@ -542,13 +612,17 @@
   }
 
   Pointer<WasmerFunc> newFunc(
+      Object owner,
       Pointer<WasmerStore> store,
       Pointer<WasmerFunctype> funcType,
       Pointer func,
       Pointer env,
       Pointer finalizer) {
-    return _func_new_with_env(
+    var f = _func_new_with_env(
         store, funcType, func.cast(), env.cast(), finalizer.cast());
+    _checkNotEqual(f, nullptr, "Failed to create function.");
+    _set_finalizer_for_func(owner, f);
+    return f;
   }
 
   Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, dynamic exception) {
@@ -557,10 +631,13 @@
     msg.ref.data[0] = 0;
     msg.ref.length = 0;
     var trap = _trap_new(store, msg);
-    traps[trap.address] = exception;
     free(msg.ref.data);
     free(msg);
-    return _checkNotEqual(trap, nullptr, "Failed to create trap.");
+    _checkNotEqual(trap, nullptr, "Failed to create trap.");
+    var entry = _WasmTrapsEntry(exception);
+    _set_finalizer_for_trap(entry, trap);
+    traps[trap.address] = entry;
+    return trap;
   }
 
   Pointer<WasmerWasiConfig> newWasiConfig() {
diff --git a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py b/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
index 6251ee9..4feda0e 100755
--- a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
+++ b/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
@@ -35,12 +35,14 @@
 
 def removePrefix(t):
     assert (t.startswith('wasm_') or t.startswith('wasi_') or
-            t.startswith('wasmer_'))
+            t.startswith('wasmer_') or t.startswith('Dart_') or
+            t.startswith('set_finalizer_'))
     return t[(5 if t.startswith('wasm_') else 0):]
 
 
 def addPrefix(t):
-    if t.startswith('wasi_') or t.startswith('wasmer_'):
+    if t.startswith('wasi_') or t.startswith('wasmer_') or t.startswith(
+            'Dart_') or t.startswith('set_finalizer_'):
         return t
     return 'wasm_' + t
 
@@ -251,6 +253,7 @@
 predefinedType('float64_t', 'Float64', 'double')
 predefinedType('wasm_limits_t', 'WasmerLimits', 'WasmerLimits')
 predefinedType('wasm_val_t', 'WasmerVal', 'WasmerVal')
+predefinedType('Dart_Handle', 'Handle', 'Object')
 
 declareOwn('engine')
 declareOwn('store')
@@ -310,6 +313,7 @@
 WASM_API_EXTERN own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*);
 WASM_API_EXTERN void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out);
 WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
+
 wasi_config_t* wasi_config_new(const uint8_t* program_name);
 wasi_env_t* wasi_env_new(wasi_config_t* config);
 bool wasi_get_imports(const wasm_store_t* store, const wasm_module_t* module, const wasi_env_t* wasi_env, wasm_extern_vec_t* imports);
@@ -320,6 +324,16 @@
 void wasi_config_inherit_stderr(wasi_config_t* config);
 intptr_t wasi_env_read_stderr(wasi_env_t* env, uint8_t* buffer, uintptr_t buffer_len);
 intptr_t wasi_env_read_stdout(wasi_env_t* env, uint8_t* buffer, uintptr_t buffer_len);
+
+intptr_t Dart_InitializeApiDL(void* data);
+void set_finalizer_for_engine(Dart_Handle, wasm_engine_t*);
+void set_finalizer_for_store(Dart_Handle, wasm_store_t*);
+void set_finalizer_for_module(Dart_Handle, wasm_module_t*);
+void set_finalizer_for_instance(Dart_Handle, wasm_instance_t*);
+void set_finalizer_for_trap(Dart_Handle, wasm_trap_t*);
+void set_finalizer_for_memorytype(Dart_Handle, wasm_memorytype_t*);
+void set_finalizer_for_memory(Dart_Handle, wasm_memory_t*);
+void set_finalizer_for_func(Dart_Handle, wasm_func_t*);
 '''
 for f in rawFns.split('\n'):
     if len(f.strip()) > 0:
diff --git a/pkg/wasm/lib/src/tools/runtime_template.dart b/pkg/wasm/lib/src/tools/runtime_template.dart
index 1f53a43..385004f 100644
--- a/pkg/wasm/lib/src/tools/runtime_template.dart
+++ b/pkg/wasm/lib/src/tools/runtime_template.dart
@@ -52,12 +52,17 @@
   }
 }
 
+class _WasmTrapsEntry {
+  dynamic exception;
+  _WasmTrapsEntry(this.exception);
+}
+
 class WasmRuntime {
   static WasmRuntime? _inst;
 
   DynamicLibrary _lib;
   late Pointer<WasmerEngine> _engine;
-  Map<int, dynamic> traps = {};
+  Map<int, _WasmTrapsEntry> traps = {};
 /* <RUNTIME_MEMB> */
 
   factory WasmRuntime() {
@@ -104,14 +109,23 @@
       : _lib = DynamicLibrary.open(path.join(_getLibDir(), _getLibName())) {
 /* <RUNTIME_LOAD> */
 
+    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
+      throw Exception("Failed to initialize Dart API");
+    }
     _engine = _engine_new();
+    _checkNotEqual(_engine, nullptr, "Failed to initialize Wasm engine.");
+    _set_finalizer_for_engine(this, _engine);
   }
 
-  Pointer<WasmerStore> newStore() {
-    return _store_new(_engine);
+  Pointer<WasmerStore> newStore(Object owner) {
+    Pointer<WasmerStore> store = _checkNotEqual(
+        _store_new(_engine), nullptr, "Failed to create Wasm store.");
+    _set_finalizer_for_store(owner, store);
+    return store;
   }
 
-  Pointer<WasmerModule> compile(Pointer<WasmerStore> store, Uint8List data) {
+  Pointer<WasmerModule> compile(
+      Object owner, Pointer<WasmerStore> store, Uint8List data) {
     var dataPtr = allocate<Uint8>(count: data.length);
     for (int i = 0; i < data.length; ++i) {
       dataPtr[i] = data[i];
@@ -125,7 +139,9 @@
     free(dataPtr);
     free(dataVec);
 
-    return _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
+    _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
+    _set_finalizer_for_module(owner, modulePtr);
+    return modulePtr;
   }
 
   List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
@@ -169,37 +185,51 @@
 
   void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
     if (trap != nullptr) {
-      var stashedException = traps[trap.address];
-      if (stashedException != null) {
-        traps.remove(stashedException);
-        throw stashedException;
+      // There are 2 kinds of trap, and their memory is managed differently.
+      // Traps created in the newTrap method below are stored in the traps map
+      // with a corresponding exception, and their memory is managed using a
+      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
+      // code, and in that case we delete them in this function.
+      var entry = traps[trap.address];
+      if (entry != null) {
+        traps.remove(entry);
+        throw entry.exception;
       } else {
         var trapMessage = allocate<WasmerByteVec>();
         _trap_message(trap, trapMessage);
         var message = "Wasm trap when calling $source: ${trapMessage.ref}";
-        free(trapMessage.ref.data);
+        _byte_vec_delete(trapMessage);
         free(trapMessage);
+        _trap_delete(trap);
         throw Exception(message);
       }
     }
   }
 
-  Pointer<WasmerInstance> instantiate(Pointer<WasmerStore> store,
+  Pointer<WasmerInstance> instantiate(Object owner, Pointer<WasmerStore> store,
       Pointer<WasmerModule> module, Pointer<WasmerExternVec> imports) {
     var trap = allocate<Pointer<WasmerTrap>>();
     trap.value = nullptr;
     var inst = _instance_new(store, module, imports, trap);
     maybeThrowTrap(trap.value, "module initialization function");
     free(trap);
-    return _checkNotEqual(inst, nullptr, "Wasm module instantiation failed.");
+    _checkNotEqual(inst, nullptr, "Wasm module instantiation failed.");
+    _set_finalizer_for_instance(owner, inst);
+    return inst;
   }
 
+  // Clean up the exports after use, with deleteExports.
   Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
     var exports = allocate<WasmerExternVec>();
     _instance_exports(instancePtr, exports);
     return exports;
   }
 
+  void deleteExports(Pointer<WasmerExternVec> exports) {
+    _extern_vec_delete(exports);
+    free(exports);
+  }
+
   int externKind(Pointer<WasmerExtern> extern) {
     return _extern_kind(extern);
   }
@@ -245,14 +275,18 @@
   }
 
   Pointer<WasmerMemory> newMemory(
-      Pointer<WasmerStore> store, int pages, int? maxPages) {
+      Object owner, Pointer<WasmerStore> store, int pages, int? maxPages) {
     var limPtr = allocate<WasmerLimits>();
     limPtr.ref.min = pages;
     limPtr.ref.max = maxPages ?? wasm_limits_max_default;
     var memType = _memorytype_new(limPtr);
     free(limPtr);
-    return _checkNotEqual(
+    _checkNotEqual(memType, nullptr, "Failed to create memory type.");
+    _set_finalizer_for_memorytype(owner, memType);
+    var memory = _checkNotEqual(
         _memory_new(store, memType), nullptr, "Failed to create memory.");
+    _set_finalizer_for_memory(owner, memory);
+    return memory;
   }
 
   void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
@@ -269,13 +303,17 @@
   }
 
   Pointer<WasmerFunc> newFunc(
+      Object owner,
       Pointer<WasmerStore> store,
       Pointer<WasmerFunctype> funcType,
       Pointer func,
       Pointer env,
       Pointer finalizer) {
-    return _func_new_with_env(
+    var f = _func_new_with_env(
         store, funcType, func.cast(), env.cast(), finalizer.cast());
+    _checkNotEqual(f, nullptr, "Failed to create function.");
+    _set_finalizer_for_func(owner, f);
+    return f;
   }
 
   Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, dynamic exception) {
@@ -284,10 +322,13 @@
     msg.ref.data[0] = 0;
     msg.ref.length = 0;
     var trap = _trap_new(store, msg);
-    traps[trap.address] = exception;
     free(msg.ref.data);
     free(msg);
-    return _checkNotEqual(trap, nullptr, "Failed to create trap.");
+    _checkNotEqual(trap, nullptr, "Failed to create trap.");
+    var entry = _WasmTrapsEntry(exception);
+    _set_finalizer_for_trap(entry, trap);
+    traps[trap.address] = entry;
+    return trap;
   }
 
   Pointer<WasmerWasiConfig> newWasiConfig() {
diff --git a/pkg/wasm/lib/src/wasmer_api.dart b/pkg/wasm/lib/src/wasmer_api.dart
index ce9057e..b95cf9a 100644
--- a/pkg/wasm/lib/src/wasmer_api.dart
+++ b/pkg/wasm/lib/src/wasmer_api.dart
@@ -214,6 +214,58 @@
   external Pointer<Pointer<WasmerValtype>> data;
 }
 
+// Dart_InitializeApiDL
+typedef NativeWasmerDartInitializeApiDLFn = Int64 Function(Pointer<Void>);
+typedef WasmerDartInitializeApiDLFn = int Function(Pointer<Void>);
+
+// set_finalizer_for_engine
+typedef NativeWasmerSetFinalizerForEngineFn = Void Function(
+    Handle, Pointer<WasmerEngine>);
+typedef WasmerSetFinalizerForEngineFn = void Function(
+    Object, Pointer<WasmerEngine>);
+
+// set_finalizer_for_func
+typedef NativeWasmerSetFinalizerForFuncFn = Void Function(
+    Handle, Pointer<WasmerFunc>);
+typedef WasmerSetFinalizerForFuncFn = void Function(
+    Object, Pointer<WasmerFunc>);
+
+// set_finalizer_for_instance
+typedef NativeWasmerSetFinalizerForInstanceFn = Void Function(
+    Handle, Pointer<WasmerInstance>);
+typedef WasmerSetFinalizerForInstanceFn = void Function(
+    Object, Pointer<WasmerInstance>);
+
+// set_finalizer_for_memory
+typedef NativeWasmerSetFinalizerForMemoryFn = Void Function(
+    Handle, Pointer<WasmerMemory>);
+typedef WasmerSetFinalizerForMemoryFn = void Function(
+    Object, Pointer<WasmerMemory>);
+
+// set_finalizer_for_memorytype
+typedef NativeWasmerSetFinalizerForMemorytypeFn = Void Function(
+    Handle, Pointer<WasmerMemorytype>);
+typedef WasmerSetFinalizerForMemorytypeFn = void Function(
+    Object, Pointer<WasmerMemorytype>);
+
+// set_finalizer_for_module
+typedef NativeWasmerSetFinalizerForModuleFn = Void Function(
+    Handle, Pointer<WasmerModule>);
+typedef WasmerSetFinalizerForModuleFn = void Function(
+    Object, Pointer<WasmerModule>);
+
+// set_finalizer_for_store
+typedef NativeWasmerSetFinalizerForStoreFn = Void Function(
+    Handle, Pointer<WasmerStore>);
+typedef WasmerSetFinalizerForStoreFn = void Function(
+    Object, Pointer<WasmerStore>);
+
+// set_finalizer_for_trap
+typedef NativeWasmerSetFinalizerForTrapFn = Void Function(
+    Handle, Pointer<WasmerTrap>);
+typedef WasmerSetFinalizerForTrapFn = void Function(
+    Object, Pointer<WasmerTrap>);
+
 // wasi_config_inherit_stderr
 typedef NativeWasmerWasiConfigInheritStderrFn = Void Function(
     Pointer<WasmerWasiConfig>);
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 1d06186..9a3074b 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -83,6 +83,11 @@
     defines += [ "TARGET_OS_MACOS" ]
   } else if (target_os == "win") {
     defines += [ "TARGET_OS_WINDOWS" ]
+  } else if (target_os == "winuwp") {
+    defines += [
+      "TARGET_OS_WINDOWS",
+      "TARGET_OS_WINDOWS_UWP",
+    ]
   } else {
     print("Unknown target_os: $target_os")
     assert(false)
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 906eb34..40ff303 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -210,12 +210,14 @@
     if (is_win) {
       libs = [
         "iphlpapi.lib",
-        "psapi.lib",
         "ws2_32.lib",
         "Rpcrt4.lib",
         "shlwapi.lib",
         "winmm.lib",
       ]
+      if (target_os != "winuwp") {
+        libs += [ "psapi.lib" ]
+      }
     }
   }
 }
diff --git a/runtime/bin/dart_io_api_impl.cc b/runtime/bin/dart_io_api_impl.cc
index 18be4c8..a890132 100644
--- a/runtime/bin/dart_io_api_impl.cc
+++ b/runtime/bin/dart_io_api_impl.cc
@@ -10,7 +10,9 @@
 #include "bin/io_natives.h"
 #include "bin/platform.h"
 #include "bin/process.h"
-#include "bin/secure_socket_filter.h"
+#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
+  #include "bin/secure_socket_filter.h"
+#endif
 #include "bin/thread.h"
 #include "bin/utils.h"
 
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
index 0153f2f..df01614 100644
--- a/runtime/bin/dartdev_isolate.cc
+++ b/runtime/bin/dartdev_isolate.cc
@@ -40,6 +40,7 @@
 DartDevIsolate::DartDev_Result DartDevIsolate::DartDevRunner::result_ =
     DartDevIsolate::DartDev_Result_Unknown;
 char** DartDevIsolate::DartDevRunner::script_ = nullptr;
+char** DartDevIsolate::DartDevRunner::package_config_override_ = nullptr;
 std::unique_ptr<char*[], void (*)(char*[])>
     DartDevIsolate::DartDevRunner::argv_ =
         std::unique_ptr<char*[], void (*)(char**)>(nullptr, [](char**) {});
@@ -62,14 +63,14 @@
 
   // First assume we're in dart-sdk/bin.
   char* snapshot_path =
-      Utils::SCreate("%s../lib/_internal/dartdev.dill", dir_prefix.get());
+      Utils::SCreate("%ssnapshots/dartdev.dill", dir_prefix.get());
   if (File::Exists(nullptr, snapshot_path)) {
     return Utils::CreateCStringUniquePtr(snapshot_path);
   }
   free(snapshot_path);
 
   // If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
-  // directories. Try to use a snapshot rom a previously built SDK.
+  // directories. Try to use a snapshot from a previously built SDK.
   snapshot_path = Utils::SCreate("%sdartdev.dill", dir_prefix.get());
   if (File::Exists(nullptr, snapshot_path)) {
     return Utils::CreateCStringUniquePtr(snapshot_path);
@@ -80,12 +81,12 @@
 
 void DartDevIsolate::DartDevRunner::Run(
     Dart_IsolateGroupCreateCallback create_isolate,
-    const char* packages_file,
+    char** packages_file,
     char** script,
     CommandLineOptions* dart_options) {
   create_isolate_ = create_isolate;
   dart_options_ = dart_options;
-  packages_file_ = packages_file;
+  package_config_override_ = packages_file;
   script_ = script;
 
   MonitorLocker locker(monitor_);
@@ -111,18 +112,33 @@
 void DartDevIsolate::DartDevRunner::DartDevResultCallback(
     Dart_Port dest_port_id,
     Dart_CObject* message) {
+  // These messages are produced in pkg/dartdev/lib/src/vm_interop_handler.dart.
   ASSERT(message->type == Dart_CObject_kArray);
   int32_t type = GetArrayItem(message, 0)->value.as_int32;
   switch (type) {
     case DartDevIsolate::DartDev_Result_Run: {
       result_ = DartDevIsolate::DartDev_Result_Run;
       ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
+      auto item2 = GetArrayItem(message, 2);
+
+      ASSERT(item2->type == Dart_CObject_kString ||
+             item2->type == Dart_CObject_kNull);
+
       if (*script_ != nullptr) {
         free(*script_);
       }
+      if (*package_config_override_ != nullptr) {
+        free(*package_config_override_);
+        *package_config_override_ = nullptr;
+      }
       *script_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
-      ASSERT(GetArrayItem(message, 2)->type == Dart_CObject_kArray);
-      Dart_CObject* args = GetArrayItem(message, 2);
+
+      if (item2->type == Dart_CObject_kString) {
+        *package_config_override_ = Utils::StrDup(item2->value.as_string);
+      }
+
+      ASSERT(GetArrayItem(message, 3)->type == Dart_CObject_kArray);
+      Dart_CObject* args = GetArrayItem(message, 3);
       argc_ = args->value.as_array.length;
       Dart_CObject** dart_args = args->value.as_array.values;
 
@@ -213,15 +229,12 @@
   Dart_Handle send_port = Dart_NewSendPort(send_port_id);
   CHECK_RESULT(send_port);
 
-  const intptr_t kNumIsolateArgs = 7;
+  const intptr_t kNumIsolateArgs = 4;
   Dart_Handle isolate_args[kNumIsolateArgs];
-  isolate_args[0] = Dart_Null();   // parentPort
-  isolate_args[1] = main_closure;  // entryPoint
-  isolate_args[2] = runner->dart_options_->CreateRuntimeOptions();  // args
-  isolate_args[3] = send_port;                                      // message
-  isolate_args[4] = Dart_True();  // isSpawnUri
-  isolate_args[5] = Dart_Null();  // controlPort
-  isolate_args[6] = Dart_Null();  // capabilities
+  isolate_args[0] = main_closure;  // entryPoint
+  isolate_args[1] = runner->dart_options_->CreateRuntimeOptions();  // args
+  isolate_args[2] = send_port;                                      // message
+  isolate_args[3] = Dart_True();  // isSpawnUri
 
   Dart_Handle isolate_lib =
       Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
@@ -247,7 +260,7 @@
 
 DartDevIsolate::DartDev_Result DartDevIsolate::RunDartDev(
     Dart_IsolateGroupCreateCallback create_isolate,
-    const char* packages_file,
+    char** packages_file,
     char** script,
     CommandLineOptions* dart_options) {
   runner_.Run(create_isolate, packages_file, script, dart_options);
diff --git a/runtime/bin/dartdev_isolate.h b/runtime/bin/dartdev_isolate.h
index 7145c9b..8fd0bd9 100644
--- a/runtime/bin/dartdev_isolate.h
+++ b/runtime/bin/dartdev_isolate.h
@@ -52,7 +52,7 @@
   // values.
   static DartDev_Result RunDartDev(
       Dart_IsolateGroupCreateCallback create_isolate,
-      const char* packages_file,
+      char** packages_file,
       char** script,
       CommandLineOptions* dart_options);
 
@@ -62,7 +62,7 @@
     DartDevRunner() {}
 
     void Run(Dart_IsolateGroupCreateCallback create_isolate,
-             const char* packages_file,
+             char** package_config_override_,
              char** script,
              CommandLineOptions* dart_options);
 
@@ -76,6 +76,7 @@
 
     static DartDev_Result result_;
     static char** script_;
+    static char** package_config_override_;
     static std::unique_ptr<char*[], void (*)(char**)> argv_;
     static intptr_t argc_;
 
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 4e0f338..50283d3 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -294,9 +294,6 @@
   }
   *len = static_cast<intptr_t>(file_len);
   *data = reinterpret_cast<uint8_t*>(malloc(*len));
-  if (*data == NULL) {
-    OUT_OF_MEMORY();
-  }
   if (!file_stream->ReadFully(*data, *len)) {
     free(*data);
     *data = NULL;
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 755ef82..f0aa87a 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -312,9 +312,6 @@
     }
 
     *p_bytes = reinterpret_cast<uint8_t*>(malloc(size));
-    if (*p_bytes == nullptr) {
-      OUT_OF_MEMORY();
-    }
     uint8_t* p = *p_bytes;
     KernelIRNode* node = head;
     while (node != nullptr) {
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 3304154..57d6a01 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -610,8 +610,8 @@
 }
 
 // A struct designed to exercise all kinds of alignment rules.
-// Note that offset32A (System V ia32) aligns doubles on 4 bytes while offset32B
-// (Arm 32 bit and MSVC ia32) aligns on 8 bytes.
+// Note that offset32A (System V ia32, iOS arm) aligns doubles on 4 bytes while
+// offset32B (Arm 32 bit and MSVC ia32) aligns on 8 bytes.
 // TODO(37271): Support nested structs.
 // TODO(37470): Add uncommon primitive data types when we want to support them.
 struct VeryLargeStruct {
diff --git a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
index ace3747..e642819 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
@@ -10,6 +10,7 @@
 #include <csignal>
 
 #include "platform/globals.h"
+#include "platform/memory_sanitizer.h"
 #if defined(HOST_OS_WINDOWS)
 #include <psapi.h>
 #include <windows.h>
@@ -47,6 +48,12 @@
 
 #define CHECK_EQ(X, Y) CHECK((X) == (Y))
 
+#define ENSURE(X)                                                              \
+  if (!(X)) {                                                                  \
+    fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, "Check failed: " #X);   \
+    exit(1);                                                                   \
+  }
+
 ////////////////////////////////////////////////////////////////////////////////
 // Functions for stress-testing.
 
@@ -271,6 +278,89 @@
 
 #endif  // defined(TARGET_OS_LINUX)
 
+DART_EXPORT void IGH_MsanUnpoison(void* start, intptr_t length) {
+  MSAN_UNPOISON(start, length);
+}
+
+DART_EXPORT Dart_Isolate IGH_CreateIsolate(const char* name, void* peer) {
+  struct Helper {
+    static void ShutdownCallback(void* ig_data, void* isolate_data) {
+      char* string = reinterpret_cast<char*>(isolate_data);
+      ENSURE(string[0] == 'a');
+      string[0] = 'x';
+    }
+    static void CleanupCallback(void* ig_data, void* isolate_data) {
+      char* string = reinterpret_cast<char*>(isolate_data);
+      ENSURE(string[2] == 'c');
+      string[2] = 'z';
+    }
+  };
+
+  Dart_Isolate parent = Dart_CurrentIsolate();
+  Dart_ExitIsolate();
+
+  char* error = nullptr;
+  Dart_Isolate child =
+      Dart_CreateIsolateInGroup(parent, name, &Helper::ShutdownCallback,
+                                &Helper::CleanupCallback, peer, &error);
+  if (child == nullptr) {
+    Dart_EnterIsolate(parent);
+    Dart_Handle error_obj = Dart_NewStringFromCString(error);
+    free(error);
+    Dart_ThrowException(error_obj);
+    return nullptr;
+  }
+  Dart_ExitIsolate();
+  Dart_EnterIsolate(parent);
+  return child;
+}
+
+DART_EXPORT void IGH_StartIsolate(Dart_Isolate child_isolate,
+                                  int64_t main_isolate_port,
+                                  const char* library_uri,
+                                  const char* function_name,
+                                  bool errors_are_fatal,
+                                  Dart_Port on_error_port,
+                                  Dart_Port on_exit_port) {
+  Dart_Isolate parent = Dart_CurrentIsolate();
+  Dart_ExitIsolate();
+  Dart_EnterIsolate(child_isolate);
+  {
+    Dart_EnterScope();
+
+    Dart_Handle library_name = Dart_NewStringFromCString(library_uri);
+    ENSURE(!Dart_IsError(library_name));
+
+    Dart_Handle library = Dart_LookupLibrary(library_name);
+    ENSURE(!Dart_IsError(library));
+
+    Dart_Handle fun = Dart_NewStringFromCString(function_name);
+    ENSURE(!Dart_IsError(fun));
+
+    Dart_Handle port = Dart_NewInteger(main_isolate_port);
+    ENSURE(!Dart_IsError(port));
+
+    Dart_Handle args[] = {
+        port,
+    };
+
+    Dart_Handle result = Dart_Invoke(library, fun, 1, args);
+    if (Dart_IsError(result)) {
+      fprintf(stderr, "Failed to invoke %s/%s in child isolate: %s\n",
+              library_uri, function_name, Dart_GetError(result));
+    }
+    ENSURE(!Dart_IsError(result));
+
+    Dart_ExitScope();
+  }
+
+  char* error = nullptr;
+  ENSURE(
+      Dart_RunLoopAsync(errors_are_fatal, on_error_port, on_exit_port, &error));
+
+  Dart_EnterIsolate(parent);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Initialize `dart_api_dl.h`
 DART_EXPORT intptr_t InitDartApiDL(void* data) {
diff --git a/runtime/bin/ffi_unit_test/BUILD.gn b/runtime/bin/ffi_unit_test/BUILD.gn
new file mode 100644
index 0000000..2a7b371
--- /dev/null
+++ b/runtime/bin/ffi_unit_test/BUILD.gn
@@ -0,0 +1,189 @@
+# Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import("../../platform/platform_sources.gni")
+import("../../vm/compiler/compiler_sources.gni")
+import("../../vm/vm_sources.gni")
+
+template("build_run_ffi_unit_tests") {
+  extra_configs = []
+  if (defined(invoker.extra_configs)) {
+    extra_configs += invoker.extra_configs
+  }
+
+  executable(target_name) {
+    configs += [] + extra_configs
+
+    defines = [
+      "TESTING",
+      "FFI_UNIT_TESTS",
+    ]
+
+    include_dirs = [
+      "../..",
+      "//third_party",
+    ]
+
+    constants = rebase_path(constants_sources, ".", "../../vm")
+    ffi_tests = rebase_path(ffi_sources_tests, ".", "../../vm/compiler")
+    platform = rebase_path(platform_sources, ".", "../../platform")
+
+    sources = [ "run_ffi_unit_tests.cc" ] + constants + ffi_tests + platform
+  }
+}
+
+config("define_target_arch_arm") {
+  defines = [ "TARGET_ARCH_ARM" ]
+}
+
+config("define_target_arch_arm64") {
+  defines = [ "TARGET_ARCH_ARM64" ]
+}
+
+config("define_target_arch_ia32") {
+  defines = [ "TARGET_ARCH_IA32" ]
+}
+
+config("define_target_arch_x64") {
+  defines = [ "TARGET_ARCH_X64" ]
+}
+
+config("define_target_os_android") {
+  defines = [ "TARGET_OS_ANDROID" ]
+}
+
+config("define_target_os_ios") {
+  # This is TARGET_OS_MACOS_IOS instead of TARGET_OS_IOS because the latter is
+  # defined by Xcode already. See https://dartbug.com/24453.
+  defines = [ "TARGET_OS_MACOS_IOS" ]
+}
+
+config("define_target_os_linux") {
+  defines = [ "TARGET_OS_LINUX" ]
+}
+
+config("define_target_os_macos") {
+  defines = [ "TARGET_OS_MACOS" ]
+}
+
+config("define_target_os_windows") {
+  defines = [ "TARGET_OS_WINDOWS" ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm_android") {
+  extra_configs = [
+    ":define_target_arch_arm",
+    ":define_target_os_android",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm_ios") {
+  extra_configs = [
+    ":define_target_arch_arm",
+    ":define_target_os_ios",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm_linux") {
+  extra_configs = [
+    ":define_target_arch_arm",
+    ":define_target_os_linux",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_android") {
+  extra_configs = [
+    ":define_target_arch_arm64",
+    ":define_target_os_android",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_ios") {
+  extra_configs = [
+    ":define_target_arch_arm64",
+    ":define_target_os_ios",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_macos") {
+  extra_configs = [
+    ":define_target_arch_arm64",
+    ":define_target_os_macos",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_linux") {
+  extra_configs = [
+    ":define_target_arch_arm64",
+    ":define_target_os_linux",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_ia32_android") {
+  extra_configs = [
+    ":define_target_arch_ia32",
+    ":define_target_os_android",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_ia32_linux") {
+  extra_configs = [
+    ":define_target_arch_ia32",
+    ":define_target_os_linux",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_ia32_win") {
+  extra_configs = [
+    ":define_target_arch_ia32",
+    ":define_target_os_windows",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_x64_ios") {
+  extra_configs = [
+    ":define_target_arch_x64",
+    ":define_target_os_ios",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_x64_linux") {
+  extra_configs = [
+    ":define_target_arch_x64",
+    ":define_target_os_linux",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_x64_macos") {
+  extra_configs = [
+    ":define_target_arch_x64",
+    ":define_target_os_macos",
+  ]
+}
+
+build_run_ffi_unit_tests("run_ffi_unit_tests_x64_win") {
+  extra_configs = [
+    ":define_target_arch_x64",
+    ":define_target_os_windows",
+  ]
+}
+
+group("run_ffi_unit_tests") {
+  deps = [
+    ":run_ffi_unit_tests_arm64_android",
+    ":run_ffi_unit_tests_arm64_ios",  # No other test coverage.
+    ":run_ffi_unit_tests_arm64_linux",
+    ":run_ffi_unit_tests_arm64_macos",
+    ":run_ffi_unit_tests_arm_android",  # SoftFP
+    ":run_ffi_unit_tests_arm_ios",  # No other test coverage.
+    ":run_ffi_unit_tests_arm_linux",  # HardFP
+    ":run_ffi_unit_tests_ia32_android",  # Emulator, no other test coverage.
+    ":run_ffi_unit_tests_ia32_linux",
+    ":run_ffi_unit_tests_ia32_win",
+    ":run_ffi_unit_tests_x64_ios",  # Simulator, no other test coverage.
+    ":run_ffi_unit_tests_x64_linux",
+    ":run_ffi_unit_tests_x64_macos",
+    ":run_ffi_unit_tests_x64_win",
+  ]
+}
diff --git a/runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc b/runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc
new file mode 100644
index 0000000..8fe8784
--- /dev/null
+++ b/runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A slimmed down version of bin/run_vm_tests.cc that only runs C++ non-DartVM
+// unit tests.
+//
+// By slimming it down to non-VM, we can run with the defines for all target
+// architectures and operating systems.
+
+#include "vm/compiler/ffi/unit_test.h"
+
+#include "platform/assert.h"
+#include "platform/syslog.h"
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+static const char* const kNone = "No Test";
+static const char* const kList = "List all Tests";
+static const char* const kAll = "Run all Tests";
+static const char* run_filter = kNone;
+
+static const char* kCommandAll = "--all";
+static const char* kCommandList = "--list";
+static const char* kCommandUpdate = "--update";
+
+static int run_matches = 0;
+
+TestCaseBase* TestCaseBase::first_ = nullptr;
+TestCaseBase* TestCaseBase::tail_ = nullptr;
+bool TestCaseBase::update_expectations = false;
+
+TestCaseBase::TestCaseBase(const char* name, const char* expectation)
+    : next_(nullptr), name_(name), expectation_(expectation) {
+  ASSERT(strlen(expectation) > 0);
+  if (first_ == nullptr) {
+    first_ = this;
+  } else {
+    tail_->next_ = this;
+  }
+  tail_ = this;
+}
+
+void TestCaseBase::RunAll() {
+  TestCaseBase* test = first_;
+  while (test != nullptr) {
+    test->RunTest();
+    test = test->next_;
+  }
+}
+
+void TestCaseBase::RunTest() {
+  if (run_filter == kList) {
+    Syslog::Print("%s %s\n", this->name(), this->expectation());
+    run_matches++;
+  } else if (run_filter == kAll) {
+    this->Run();
+    run_matches++;
+  } else if (strcmp(run_filter, this->name()) == 0) {
+    this->Run();
+    run_matches++;
+  }
+}
+
+void RawTestCase::Run() {
+  Syslog::Print("Running test: %s\n", name());
+  (*run_)();
+  Syslog::Print("Done: %s\n", name());
+}
+
+static int Main(int argc, const char** argv) {
+  if (argc == 2 && strcmp(argv[1], kCommandList) == 0) {
+    run_filter = kList;
+    // List all tests and benchmarks and exit.
+    TestCaseBase::RunAll();
+    fflush(stdout);
+    return 0;
+  }
+  if (argc > 1 && strcmp(argv[1], kCommandUpdate) == 0) {
+    TestCaseBase::update_expectations = true;
+  }
+  if (strcmp(argv[argc - 1], kCommandAll) == 0) {
+    // Run all tests.
+    run_filter = kAll;
+  } else if (argc > 1) {
+    // Run only test with specific name.
+    run_filter = argv[argc - 1];
+  }
+
+  TestCaseBase::RunAll();
+
+  // Print a warning message if no tests or benchmarks were matched.
+  if (run_matches == 0) {
+    Syslog::PrintErr("No tests matched: %s\n", run_filter);
+    return 1;
+  }
+  if (Expect::failed()) {
+    Syslog::PrintErr(
+        "Some tests failed. Run the following command to update "
+        "expectations.\ntools/test.py --vm-options=--update ffi_unit");
+    return 255;
+  }
+
+  return 0;
+}
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
+
+int main(int argc, const char** argv) {
+  return dart::compiler::ffi::Main(argc, argv);
+}
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 72e10c8..cb53b76 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -209,15 +209,11 @@
                           char** argv,
                           CommandLineOptions* vm_options,
                           CommandLineOptions* inputs) {
-  const char* kPrefix = "-";
-  const intptr_t kPrefixLen = strlen(kPrefix);
-
   // Skip the binary name.
   int i = 1;
 
   // Parse out the vm options.
-  while ((i < argc) &&
-         OptionProcessor::IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
+  while ((i < argc) && OptionProcessor::IsValidShortFlag(argv[i])) {
     if (OptionProcessor::TryProcess(argv[i], vm_options)) {
       i += 1;
       continue;
diff --git a/runtime/bin/gzip.cc b/runtime/bin/gzip.cc
index 5494537..c80396c 100644
--- a/runtime/bin/gzip.cc
+++ b/runtime/bin/gzip.cc
@@ -4,6 +4,7 @@
 
 #include "bin/gzip.h"
 
+#include "platform/allocation.h"
 #include "platform/assert.h"
 #include "platform/globals.h"
 #include "zlib/zlib.h"
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 4b51532..7299ade 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -245,12 +245,8 @@
     if (Dart_IsError(result)) goto failed;
   }
 
-  // Make the isolate runnable so that it is ready to handle messages.
   Dart_ExitScope();
-  Dart_ExitIsolate();
-  *error = Dart_IsolateMakeRunnable(isolate);
-  Dart_EnterIsolate(isolate);
-  return *error == nullptr;
+  return true;
 
 failed:
   *error = Utils::StrDup(Dart_GetError(result));
@@ -903,7 +899,9 @@
   file->Release();
 }
 
-bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
+void RunMainIsolate(const char* script_name,
+                    const char* package_config_override,
+                    CommandLineOptions* dart_options) {
   // Call CreateIsolateGroupAndSetup which creates an isolate and loads up
   // the specified application script.
   char* error = NULL;
@@ -912,7 +910,9 @@
   Dart_IsolateFlagsInitialize(&flags);
 
   Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
-      /* is_main_isolate */ true, script_name, "main", Options::packages_file(),
+      /* is_main_isolate */ true, script_name, "main",
+      Options::packages_file() == nullptr ? package_config_override
+                                          : Options::packages_file(),
       &flags, NULL /* callback_data */, &error, &exit_code);
 
   if (isolate == NULL) {
@@ -1039,9 +1039,6 @@
 
   // Shutdown the isolate.
   Dart_ShutdownIsolate();
-
-  // No restart.
-  return false;
 }
 
 #undef CHECK_RESULT
@@ -1080,6 +1077,8 @@
 
 void main(int argc, char** argv) {
   char* script_name = nullptr;
+  // Allows the dartdev process to point to the desired package_config.
+  char* package_config_override = nullptr;
   const int EXTRA_VM_ARGUMENTS = 10;
   CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
   CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);
@@ -1141,10 +1140,10 @@
 
   // Parse command line arguments.
   if (app_snapshot == nullptr) {
-    int result = Options::ParseArguments(
+    bool success = Options::ParseArguments(
         argc, argv, vm_run_app_snapshot, &vm_options, &script_name,
         &dart_options, &print_flags_seen, &verbose_debug_seen);
-    if (result < 0) {
+    if (!success) {
       if (Options::help_option()) {
         Options::PrintUsage();
         Platform::Exit(0);
@@ -1294,7 +1293,7 @@
   if (DartDevIsolate::should_run_dart_dev() && !Options::disable_dart_dev() &&
       Options::gen_snapshot_kind() == SnapshotKind::kNone) {
     DartDevIsolate::DartDev_Result dartdev_result = DartDevIsolate::RunDartDev(
-        CreateIsolateGroupAndSetup, Options::packages_file(), &script_name,
+        CreateIsolateGroupAndSetup, &package_config_override, &script_name,
         &dart_options);
     ASSERT(dartdev_result != DartDevIsolate::DartDev_Result_Unknown);
     ran_dart_dev = true;
@@ -1314,9 +1313,7 @@
       Platform::Exit(kErrorExitCode);
     } else {
       // Run the main isolate until we aren't told to restart.
-      while (RunMainIsolate(script_name, &dart_options)) {
-        Syslog::PrintErr("Restarting VM\n");
-      }
+      RunMainIsolate(script_name, package_config_override, &dart_options);
     }
   }
 
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 452346f..d019ce4 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -282,6 +282,26 @@
   return true;
 }
 
+// Returns true if arg starts with the characters "--" followed by option, but
+// all '_' in the option name are treated as '-'.
+static bool IsOption(const char* arg, const char* option) {
+  if (arg[0] != '-' || arg[1] != '-') {
+    // Special case first two characters to avoid recognizing __flag.
+    return false;
+  }
+  for (int i = 0; option[i] != '\0'; i++) {
+    auto c = arg[i + 2];
+    if (c == '\0') {
+      // Not long enough.
+      return false;
+    }
+    if ((c == '_' ? '-' : c) != option[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
 const char* Options::vm_service_server_ip_ = DEFAULT_VM_SERVICE_SERVER_IP;
 int Options::vm_service_server_port_ = INVALID_VM_SERVICE_SERVER_PORT;
 bool Options::ProcessEnableVmServiceOption(const char* arg,
@@ -366,17 +386,14 @@
   return false;
 }
 
-int Options::ParseArguments(int argc,
-                            char** argv,
-                            bool vm_run_app_snapshot,
-                            CommandLineOptions* vm_options,
-                            char** script_name,
-                            CommandLineOptions* dart_options,
-                            bool* print_flags_seen,
-                            bool* verbose_debug_seen) {
-  const char* kPrefix = "--";
-  const intptr_t kPrefixLen = strlen(kPrefix);
-
+bool Options::ParseArguments(int argc,
+                             char** argv,
+                             bool vm_run_app_snapshot,
+                             CommandLineOptions* vm_options,
+                             char** script_name,
+                             CommandLineOptions* dart_options,
+                             bool* print_flags_seen,
+                             bool* verbose_debug_seen) {
   // Store the executable name.
   Platform::SetExecutableName(argv[0]);
 
@@ -395,43 +412,26 @@
       i++;
     } else {
       // Check if this flag is a potentially valid VM flag.
-      if (!OptionProcessor::IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
+      if (!OptionProcessor::IsValidFlag(argv[i])) {
         break;
       }
-      // The following two flags are processed by both the embedder and
-      // the VM.
-      const char* kPrintFlags1 = "--print-flags";
-      const char* kPrintFlags2 = "--print_flags";
-      const char* kVerboseDebug1 = "--verbose_debug";
-      const char* kVerboseDebug2 = "--verbose-debug";
-
-      // The following two flags are processed as DartDev flags and are not to
+      // The following flags are processed as DartDev flags and are not to
       // be treated as if they are VM flags.
-      const char* kEnableDartDevAnalytics1 = "--enable-analytics";
-      const char* kEnableDartDevAnalytics2 = "--enable_analytics";
-      const char* kDisableDartDevAnalytics1 = "--disable-analytics";
-      const char* kDisableDartDevAnalytics2 = "--disable_analytics";
-
-      if ((strncmp(argv[i], kPrintFlags1, strlen(kPrintFlags1)) == 0) ||
-          (strncmp(argv[i], kPrintFlags2, strlen(kPrintFlags2)) == 0)) {
+      if (IsOption(argv[i], "print-flags")) {
         *print_flags_seen = true;
-      } else if ((strncmp(argv[i], kVerboseDebug1, strlen(kVerboseDebug1)) ==
-                  0) ||
-                 (strncmp(argv[i], kVerboseDebug2, strlen(kVerboseDebug2)) ==
-                  0)) {
+      } else if (IsOption(argv[i], "verbose-debug")) {
         *verbose_debug_seen = true;
-      } else if ((strncmp(argv[i], kEnableDartDevAnalytics1,
-                          strlen(kEnableDartDevAnalytics1)) == 0) ||
-                 (strncmp(argv[i], kEnableDartDevAnalytics2,
-                          strlen(kEnableDartDevAnalytics2)) == 0)) {
+      } else if (IsOption(argv[i], "enable-analytics")) {
         enable_dartdev_analytics = true;
         skipVmOption = true;
-      } else if ((strncmp(argv[i], kDisableDartDevAnalytics1,
-                          strlen(kDisableDartDevAnalytics1)) == 0) ||
-                 (strncmp(argv[i], kDisableDartDevAnalytics2,
-                          strlen(kDisableDartDevAnalytics2)) == 0)) {
+      } else if (IsOption(argv[i], "disable-analytics")) {
         disable_dartdev_analytics = true;
         skipVmOption = true;
+      } else if (IsOption(argv[i], "no-analytics")) {
+        // Just add this option even if we don't go to dartdev.
+        // It is irelevant for the vm.
+        dart_options->AddArgument("--no-analytics");
+        skipVmOption = true;
       }
       if (!skipVmOption) {
         temp_vm_options.AddArgument(argv[i]);
@@ -465,7 +465,6 @@
 
   bool implicitly_use_dart_dev = false;
   bool run_script = false;
-
   // Get the script name.
   if (i < argc) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -478,6 +477,7 @@
     bool is_potential_file_path = true;
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
     if (Options::disable_dart_dev() ||
+        (Options::snapshot_filename() != nullptr) ||
         (is_potential_file_path && !enable_vm_service_)) {
       *script_name = Utils::StrDup(argv[i]);
       run_script = true;
@@ -505,25 +505,19 @@
     DartDevIsolate::set_should_run_dart_dev(true);
     // Let DartDev handle the default help message.
     dart_options->AddArgument("help");
-    return 0;
+    return true;
   } else if (!Options::disable_dart_dev() &&
              (enable_dartdev_analytics || disable_dartdev_analytics)) {
     // The analytics flags are a special case as we don't have a target script
     // or DartDev command but we still want to launch DartDev.
     DartDevIsolate::set_should_run_dart_dev(true);
 
-    if (enable_dartdev_analytics) {
-      dart_options->AddArgument("--enable-analytics");
-    }
-    if (disable_dartdev_analytics) {
-      dart_options->AddArgument("--disable-analytics");
-    }
-    return 0;
+    return true;
   }
 
 #endif    // !defined(DART_PRECOMPILED_RUNTIME)
   else {  // NOLINT
-    return -1;
+    return false;
   }
   USE(enable_dartdev_analytics);
   USE(disable_dartdev_analytics);
@@ -546,7 +540,7 @@
     while (tmp_i < argc) {
       // Check if this flag is a potentially valid VM flag. If not, we've likely
       // hit a script name and are done parsing VM flags.
-      if (!OptionProcessor::IsValidFlag(argv[tmp_i], kPrefix, kPrefixLen)) {
+      if (!OptionProcessor::IsValidFlag(argv[tmp_i])) {
         break;
       }
       OptionProcessor::TryProcess(argv[tmp_i], vm_options);
@@ -595,14 +589,12 @@
       first_option = false;
     }
   }
-
-
   // Verify consistency of arguments.
 
   // snapshot_depfile is an alias for depfile. Passing them both is an error.
   if ((snapshot_deps_filename_ != NULL) && (depfile_ != NULL)) {
     Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
-    return -1;
+    return false;
   }
   if (snapshot_deps_filename_ != NULL) {
     depfile_ = snapshot_deps_filename_;
@@ -611,25 +603,25 @@
 
   if ((packages_file_ != NULL) && (strlen(packages_file_) == 0)) {
     Syslog::PrintErr("Empty package file name specified.\n");
-    return -1;
+    return false;
   }
   if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == NULL)) {
     Syslog::PrintErr(
         "Generating a snapshot requires a filename (--snapshot).\n");
-    return -1;
+    return false;
   }
   if ((gen_snapshot_kind_ == kNone) && (depfile_ != NULL) &&
       (snapshot_filename_ == NULL) && (depfile_output_filename_ == NULL)) {
     Syslog::PrintErr(
         "Generating a depfile requires an output filename"
         " (--depfile-output-filename or --snapshot).\n");
-    return -1;
+    return false;
   }
   if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
     Syslog::PrintErr(
         "Specifying an option to generate a snapshot and"
         " run using a snapshot is invalid.\n");
-    return -1;
+    return false;
   }
 
   // If --snapshot is given without --snapshot-kind, default to script snapshot.
@@ -637,7 +629,7 @@
     gen_snapshot_kind_ = kKernel;
   }
 
-  return 0;
+  return true;
 }
 
 }  // namespace bin
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index f900a3c..2ab8598 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -85,14 +85,15 @@
 
 class Options {
  public:
-  static int ParseArguments(int argc,
-                            char** argv,
-                            bool vm_run_app_shapshot,
-                            CommandLineOptions* vm_options,
-                            char** script_name,
-                            CommandLineOptions* dart_options,
-                            bool* print_flags_seen,
-                            bool* verbose_debug_seen);
+  // Returns true if argument parsing succeeded. False otherwise.
+  static bool ParseArguments(int argc,
+                             char** argv,
+                             bool vm_run_app_shapshot,
+                             CommandLineOptions* vm_options,
+                             char** script_name,
+                             CommandLineOptions* dart_options,
+                             bool* print_flags_seen,
+                             bool* verbose_debug_seen);
 
 #define STRING_OPTION_GETTER(flag, variable)                                   \
   static const char* variable() { return variable##_; }
diff --git a/runtime/bin/options.cc b/runtime/bin/options.cc
index 1eed113..7ad5d20 100644
--- a/runtime/bin/options.cc
+++ b/runtime/bin/options.cc
@@ -9,12 +9,12 @@
 
 OptionProcessor* OptionProcessor::first_ = NULL;
 
-bool OptionProcessor::IsValidFlag(const char* name,
-                                  const char* prefix,
-                                  intptr_t prefix_length) {
-  const intptr_t name_length = strlen(name);
-  return ((name_length > prefix_length) &&
-          (strncmp(name, prefix, prefix_length) == 0));
+bool OptionProcessor::IsValidFlag(const char* name) {
+  return name[0] == '-' && name[1] == '-' && name[2] != '\0';
+}
+
+bool OptionProcessor::IsValidShortFlag(const char* name) {
+  return name[0] == '-' && name[1] != '\0';
 }
 
 const char* OptionProcessor::ProcessOption(const char* option,
diff --git a/runtime/bin/options.h b/runtime/bin/options.h
index 4bcd7de..bb5f5ee 100644
--- a/runtime/bin/options.h
+++ b/runtime/bin/options.h
@@ -22,9 +22,11 @@
 
   virtual ~OptionProcessor() {}
 
-  static bool IsValidFlag(const char* name,
-                          const char* prefix,
-                          intptr_t prefix_length);
+  // Returns true if name starts with "--".
+  static bool IsValidFlag(const char* name);
+
+  // Returns true if name starts with "-".
+  static bool IsValidShortFlag(const char* name);
 
   virtual bool Process(const char* option, CommandLineOptions* options) = 0;
 
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index dd11341..26d7d0b 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -932,19 +932,31 @@
 }
 
 int64_t Process::CurrentRSS() {
+// Although the documentation at
+// https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getprocessmemoryinfo
+// claims that GetProcessMemoryInfo is UWP compatible, it is actually not
+// hence this function cannot work when compiled in UWP mode.
+#ifdef TARGET_OS_WINDOWS_UWP
+  return -1;
+#else
   PROCESS_MEMORY_COUNTERS pmc;
   if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
     return -1;
   }
   return pmc.WorkingSetSize;
+#endif
 }
 
 int64_t Process::MaxRSS() {
+#ifdef TARGET_OS_WINDOWS_UWP
+  return -1;
+#else
   PROCESS_MEMORY_COUNTERS pmc;
   if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
     return -1;
   }
   return pmc.PeakWorkingSetSize;
+#endif
 }
 
 static SignalInfo* signal_handlers = NULL;
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index c934fc5..927e139 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -106,6 +106,8 @@
                                                            uint8_t* out_alert) {
   SSLFilter* filter = static_cast<SSLFilter*>(
       SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
+  SSLCertContext* context = static_cast<SSLCertContext*>(
+      SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));
 
   const X509TrustState* certificate_trust_state =
       filter->certificate_trust_state();
@@ -125,9 +127,90 @@
     }
   }
 
-  Dart_CObject dart_cobject_ssl;
-  dart_cobject_ssl.type = Dart_CObject_kInt64;
-  dart_cobject_ssl.value.as_int64 = reinterpret_cast<intptr_t>(ssl);
+  STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
+
+  // Convert BoringSSL formatted certificates to SecCertificate certificates.
+  ScopedCFMutableArrayRef cert_chain(NULL);
+  X509* root_cert = NULL;
+  int num_certs = sk_X509_num(unverified);
+  int current_cert = 0;
+  cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
+  X509* ca;
+  while ((ca = sk_X509_shift(unverified)) != NULL) {
+    ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
+    if (cert == NULL) {
+      return ssl_verify_invalid;
+    }
+    CFArrayAppendValue(cert_chain.get(), cert.release());
+    ++current_cert;
+
+    if (current_cert == num_certs) {
+      root_cert = ca;
+    }
+  }
+
+  SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
+  X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
+  // Convert all trusted certificates provided by the user via
+  // setTrustedCertificatesBytes or the command line into SecCertificates.
+  ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
+  ASSERT(store != NULL);
+
+  if (store->objs != NULL) {
+    for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
+      X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
+      ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
+      if (cert == NULL) {
+        return ssl_verify_invalid;
+      }
+      CFArrayAppendValue(trusted_certs.get(), cert.release());
+    }
+  }
+
+  // Generate a policy for validating chains for SSL.
+  CFStringRef cfhostname = NULL;
+  if (filter->hostname() != NULL) {
+    cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
+                                           kCFStringEncodingUTF8);
+  }
+  ScopedCFStringRef hostname(cfhostname);
+  ScopedSecPolicyRef policy(
+      SecPolicyCreateSSL(filter->is_client(), hostname.get()));
+
+  // Create the trust object with the certificates provided by the user.
+  ScopedSecTrustRef trust(NULL);
+  OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
+                                                   policy.get(), trust.ptr());
+  if (status != noErr) {
+    return ssl_verify_invalid;
+  }
+
+  // If the user provided any additional CA certificates, add them to the trust
+  // object.
+  if (CFArrayGetCount(trusted_certs.get()) > 0) {
+    status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
+    if (status != noErr) {
+      return ssl_verify_invalid;
+    }
+  }
+
+  // Specify whether or not to use the built-in CA certificates for
+  // verification.
+  status =
+      SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
+  if (status != noErr) {
+    return ssl_verify_invalid;
+  }
+
+  // Handler should release trust and root_cert.
+  Dart_CObject dart_cobject_trust;
+  dart_cobject_trust.type = Dart_CObject_kInt64;
+  dart_cobject_trust.value.as_int64 =
+      reinterpret_cast<intptr_t>(CFRetain(trust.get()));
+
+  Dart_CObject dart_cobject_root_cert;
+  dart_cobject_root_cert.type = Dart_CObject_kInt64;
+  dart_cobject_root_cert.value.as_int64 = reinterpret_cast<intptr_t>(root_cert);
 
   Dart_CObject reply_send_port;
   reply_send_port.type = Dart_CObject_kSendPort;
@@ -135,8 +218,9 @@
 
   Dart_CObject array;
   array.type = Dart_CObject_kArray;
-  array.value.as_array.length = 2;
-  Dart_CObject* values[] = {&dart_cobject_ssl, &reply_send_port};
+  array.value.as_array.length = 3;
+  Dart_CObject* values[] = {&dart_cobject_trust, &dart_cobject_root_cert,
+                            &reply_send_port};
   array.value.as_array.values = values;
 
   Dart_PostCObject(filter->trust_evaluate_reply_port(), &array);
@@ -166,104 +250,28 @@
 
 static void TrustEvaluateHandler(Dart_Port dest_port_id,
                                  Dart_CObject* message) {
-  CObjectArray request(message);
-  ASSERT(request.Length() == 2);
-
-  CObjectIntptr ssl_cobject(request[0]);
-  SSL* ssl = reinterpret_cast<SSL*>(ssl_cobject.Value());
-  SSLFilter* filter = static_cast<SSLFilter*>(
-      SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
-  SSLCertContext* context = static_cast<SSLCertContext*>(
-      SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));
-  CObjectSendPort reply_port(request[1]);
-  Dart_Port reply_port_id = reply_port.Value();
-
-  STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
-
-  // Convert BoringSSL formatted certificates to SecCertificate certificates.
-  ScopedCFMutableArrayRef cert_chain(NULL);
-  X509* root_cert = NULL;
-  int num_certs = sk_X509_num(unverified);
-  int current_cert = 0;
-  cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
-  X509* ca;
-  while ((ca = sk_X509_shift(unverified)) != NULL) {
-    ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
-    if (cert == NULL) {
-      postReply(reply_port_id, /*success=*/false);
-      return;
-    }
-    CFArrayAppendValue(cert_chain.get(), cert.release());
-    ++current_cert;
-
-    if (current_cert == num_certs) {
-      root_cert = ca;
-    }
-  }
-
-  SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
-  X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
-  // Convert all trusted certificates provided by the user via
-  // setTrustedCertificatesBytes or the command line into SecCertificates.
-  ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
-  ASSERT(store != NULL);
-
-  if (store->objs != NULL) {
-    for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
-      X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
-      ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
-      if (cert == NULL) {
-        postReply(reply_port_id, /*success=*/false);
-        return;
-      }
-      CFArrayAppendValue(trusted_certs.get(), cert.release());
-    }
-  }
-
-  // Generate a policy for validating chains for SSL.
-  CFStringRef cfhostname = NULL;
-  if (filter->hostname() != NULL) {
-    cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
-                                           kCFStringEncodingUTF8);
-  }
-  ScopedCFStringRef hostname(cfhostname);
-  ScopedSecPolicyRef policy(
-      SecPolicyCreateSSL(filter->is_client(), hostname.get()));
-
-  // Create the trust object with the certificates provided by the user.
-  ScopedSecTrustRef trust(NULL);
-  OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
-                                                   policy.get(), trust.ptr());
-  if (status != noErr) {
-    postReply(reply_port_id, /*success=*/false);
-    return;
-  }
-
-  // If the user provided any additional CA certificates, add them to the trust
-  // object.
-  if (CFArrayGetCount(trusted_certs.get()) > 0) {
-    status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
-    if (status != noErr) {
-      postReply(reply_port_id, /*success=*/false);
-      return;
-    }
-  }
-
-  // Specify whether or not to use the built-in CA certificates for
-  // verification.
-  status =
-      SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
-  if (status != noErr) {
-    postReply(reply_port_id, /*success=*/false);
-    return;
-  }
-
-  SecTrustResultType trust_result;
-
   // This is used for testing to confirm that trust evaluation doesn't block
   // dart isolate.
+  // First sleep exposes problem where ssl data structures are released/freed
+  // by main isolate before this handler had a chance to access them.
+  // Second sleep(below) is there to maintain same long delay of certificate
+  // verification.
   if (SSLCertContext::long_ssl_cert_evaluation()) {
-    usleep(1000 * 1000 /*1 s*/);
+    usleep(2000 * 1000 /* 2 s*/);
+  }
+
+  CObjectArray request(message);
+  ASSERT(request.Length() == 3);
+  CObjectIntptr trust_cobject(request[0]);
+  ScopedSecTrustRef trust(reinterpret_cast<SecTrustRef>(trust_cobject.Value()));
+  CObjectIntptr root_cert_cobject(request[1]);
+  X509* root_cert = reinterpret_cast<X509*>(root_cert_cobject.Value());
+  CObjectSendPort reply_port(request[2]);
+  Dart_Port reply_port_id = reply_port.Value();
+
+  SecTrustResultType trust_result;
+  if (SSLCertContext::long_ssl_cert_evaluation()) {
+    usleep(3000 * 1000 /* 3 s*/);
   }
 
   // Perform the certificate verification.
@@ -277,11 +285,11 @@
   // from calling SecTrustEvaluate.
   bool res = SecTrustEvaluateWithError(trust.get(), NULL);
   USE(res);
-  status = SecTrustGetTrustResult(trust.get(), &trust_result);
+  OSStatus status = SecTrustGetTrustResult(trust.get(), &trust_result);
 #else
 
   // SecTrustEvaluate is deprecated as of OSX 10.15 and iOS 13.
-  status = SecTrustEvaluate(trust.get(), &trust_result);
+  OSStatus status = SecTrustEvaluate(trust.get(), &trust_result);
 #endif
 
   postReply(reply_port_id,
diff --git a/runtime/bin/security_context_win.cc b/runtime/bin/security_context_win.cc
index 1b49292..effdc5e 100644
--- a/runtime/bin/security_context_win.cc
+++ b/runtime/bin/security_context_win.cc
@@ -20,7 +20,9 @@
 #include "bin/secure_socket_utils.h"
 #include "platform/syslog.h"
 
+#ifndef TARGET_OS_WINDOWS_UWP
 #pragma comment(lib, "crypt32.lib")
+#endif
 
 namespace dart {
 namespace bin {
@@ -42,6 +44,11 @@
 
 // Add certificates from Windows trusted root store.
 static bool AddCertificatesFromRootStore(X509_STORE* store) {
+// The UWP platform doesn't support CertEnumCertificatesInStore hence
+// this function cannot work when compiled in UWP mode.
+#ifdef TARGET_OS_WINDOWS_UWP
+  return false;
+#else
   // Open root system store.
   // Note that only current user certificates are accessible using this method,
   // not the local machine store.
@@ -98,6 +105,7 @@
     return false;
   }
   return true;
+#endif  // ifdef TARGET_OS_WINDOWS_UWP
 }
 
 void SSLCertContext::TrustBuiltinRoots() {
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 6881e59..6769a93 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -431,7 +431,8 @@
   RawAddr sourceAddr;
   address = Dart_GetNativeArgument(args, 2);
   if (Dart_IsNull(address)) {
-    Dart_SetReturnValue(args,
+    return Dart_SetReturnValue(
+        args,
         DartUtils::NewDartArgumentError("expect address to be of type String"));
   }
   result = SocketAddress::GetUnixDomainSockAddr(
@@ -462,7 +463,8 @@
   RawAddr addr;
   Dart_Handle address = Dart_GetNativeArgument(args, 1);
   if (Dart_IsNull(address)) {
-    Dart_SetReturnValue(args,
+    return Dart_SetReturnValue(
+        args,
         DartUtils::NewDartArgumentError("expect address to be of type String"));
   }
   Dart_Handle result = SocketAddress::GetUnixDomainSockAddr(
diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h
index 0e4fae9..3d4cfe3 100644
--- a/runtime/bin/utils_win.h
+++ b/runtime/bin/utils_win.h
@@ -9,6 +9,8 @@
 
 #include "platform/utils.h"
 
+#include "platform/allocation.h"
+
 #define MAX_LONG_PATH 32767
 
 namespace dart {
diff --git a/runtime/docs/compiler/pragmas_recognized_by_compiler.md b/runtime/docs/compiler/pragmas_recognized_by_compiler.md
index 3fded63..8c910f8 100644
--- a/runtime/docs/compiler/pragmas_recognized_by_compiler.md
+++ b/runtime/docs/compiler/pragmas_recognized_by_compiler.md
@@ -135,3 +135,18 @@
   final int value;
 }
 ```
+
+### Marking recognized methods
+
+```dart
+@pragma("vm:recognized", <kind>)
+```
+
+Marks the method as one of the methods specially recognized by the VM. Here,
+<kind> is one of `"asm-intrinsic"`, `"graph-intrinsic"` or `"other"`,
+corresponding to the category the recognized method belongs to, as defined in
+[`recognized_methods_list.h`](../../vm/compiler/recognized_methods_list.h).
+
+The pragmas must match exactly the set of recognized methods.  This enables
+kernel-level analyses and optimizations to query whether a method is recognized
+by the VM. The correspondence is checked when running in debug mode.
diff --git a/runtime/docs/pragmas.md b/runtime/docs/pragmas.md
index ad3b987..3f7d23b 100644
--- a/runtime/docs/pragmas.md
+++ b/runtime/docs/pragmas.md
@@ -17,6 +17,7 @@
 | Pragma | Meaning |
 | --- | --- |
 | `vm:exact-result-type` | [Declaring an exact result type of a method](compiler/pragmas_recognized_by_compiler.md#providing-an-exact-result-type) |
+| `vm:recognized` | [Marking this as a recognized method](compiler/pragmas_recognized_by_compiler.md#marking-recognized-methods) |
 
 ## Pragmas for internal testing
 
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index db0e630..189a6b7 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1007,6 +1007,37 @@
                         void* isolate_group_data,
                         void* isolate_data,
                         char** error);
+/**
+ * Creates a new isolate inside the isolate group of [group_member].
+ *
+ * Requires there to be no current isolate.
+ *
+ * \param group_member An isolate from the same group into which the newly created
+ *   isolate should be born into. Other threads may not have entered / enter this
+ *   member isolate.
+ * \param name A short name for the isolate for debugging purposes.
+ * \param shutdown_callback A callback to be called when the isolate is being
+ *   shutdown (may be NULL).
+ * \param cleanup_callback A callback to be called when the isolate is being
+ *   cleaned up (may be NULL).
+ * \param isolate_data The embedder-specific data associated with this isolate.
+ * \param error Set to NULL if creation is successful, set to an error
+ *   message otherwise. The caller is responsible for calling free() on the
+ *   error message.
+ *
+ * \return The newly created isolate on success, or NULL if isolate creation
+ *   failed.
+ *
+ * If successful, the newly created isolate will become the current isolate.
+ */
+DART_EXPORT Dart_Isolate
+Dart_CreateIsolateInGroup(Dart_Isolate group_member,
+                          const char* name,
+                          Dart_IsolateShutdownCallback shutdown_callback,
+                          Dart_IsolateCleanupCallback cleanup_callback,
+                          void* child_isolate_data,
+                          char** error);
+
 /* TODO(turnidge): Document behavior when there is already a current
  * isolate. */
 
@@ -1483,6 +1514,31 @@
  *   error handle is returned.
  */
 DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_RunLoop();
+
+/**
+ * Lets the VM run message processing for the isolate.
+ *
+ * This function expects there to a current isolate and the current isolate
+ * must not have an active api scope. The VM will take care of making the
+ * isolate runnable (if not already), handles its message loop and will take
+ * care of shutting the isolate down once it's done.
+ *
+ * \param errors_are_fatal Whether uncaught errors should be fatal.
+ * \param on_error_port A port to notify on uncaught errors (or ILLEGAL_PORT).
+ * \param on_exit_port A port to notify on exit (or ILLEGAL_PORT).
+ * \param error A non-NULL pointer which will hold an error message if the call
+ *   fails. The error has to be free()ed by the caller.
+ *
+ * \return If successfull the VM takes owernship of the isolate and takes care
+ *   of its message loop. If not successful the caller retains owernship of the
+ *   isolate.
+ */
+DART_EXPORT DART_WARN_UNUSED_RESULT bool Dart_RunLoopAsync(
+    bool errors_are_fatal,
+    Dart_Port on_error_port,
+    Dart_Port on_exit_port,
+    char** error);
+
 /* TODO(turnidge): Should this be removed from the public api? */
 
 /**
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index bb85a96..2144be8 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -224,7 +224,7 @@
   const auto& typed_data_class =
       Class::Handle(zone, isolate->class_table()->At(cid));
   const auto& error =
-      Error::Handle(zone, typed_data_class.EnsureIsFinalized(thread));
+      Error::Handle(zone, typed_data_class.EnsureIsAllocateFinalized(thread));
   if (!error.IsNull()) {
     Exceptions::PropagateError(error);
   }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 905cb26..3a41006 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -76,6 +76,15 @@
   return Integer::New(id);
 }
 
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_setActive, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Bool, active, arguments->NativeArgAt(1));
+  Dart_Port id = port.Id();
+  PortMap::SetPortState(
+      id, active.value() ? PortMap::kLivePort : PortMap::kInactivePort);
+  return Object::null();
+}
+
 DEFINE_NATIVE_ENTRY(SendPortImpl_get_id, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   return Integer::New(port.Id());
@@ -284,6 +293,272 @@
   return Object::null();
 }
 
+class IsolateSpawnState {
+ public:
+  IsolateSpawnState(Dart_Port parent_port,
+                    Dart_Port origin_id,
+                    const char* script_url,
+                    const Function& func,
+                    SerializedObjectBuffer* message_buffer,
+                    const char* package_config,
+                    bool paused,
+                    bool errorsAreFatal,
+                    Dart_Port onExit,
+                    Dart_Port onError,
+                    const char* debug_name,
+                    IsolateGroup* group);
+  IsolateSpawnState(Dart_Port parent_port,
+                    const char* script_url,
+                    const char* package_config,
+                    SerializedObjectBuffer* args_buffer,
+                    SerializedObjectBuffer* message_buffer,
+                    bool paused,
+                    bool errorsAreFatal,
+                    Dart_Port onExit,
+                    Dart_Port onError,
+                    const char* debug_name,
+                    IsolateGroup* group);
+  ~IsolateSpawnState();
+
+  Isolate* isolate() const { return isolate_; }
+  void set_isolate(Isolate* value) { isolate_ = value; }
+
+  Dart_Port parent_port() const { return parent_port_; }
+  Dart_Port origin_id() const { return origin_id_; }
+  Dart_Port on_exit_port() const { return on_exit_port_; }
+  Dart_Port on_error_port() const { return on_error_port_; }
+  const char* script_url() const { return script_url_; }
+  const char* package_config() const { return package_config_; }
+  const char* library_url() const { return library_url_; }
+  const char* class_name() const { return class_name_; }
+  const char* function_name() const { return function_name_; }
+  const char* debug_name() const { return debug_name_; }
+  bool is_spawn_uri() const { return library_url_ == nullptr; }
+  bool paused() const { return paused_; }
+  bool errors_are_fatal() const { return errors_are_fatal_; }
+  Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
+
+  ObjectPtr ResolveFunction();
+  InstancePtr BuildArgs(Thread* thread);
+  InstancePtr BuildMessage(Thread* thread);
+
+  IsolateGroup* isolate_group() const { return isolate_group_; }
+
+ private:
+  Isolate* isolate_ = nullptr;
+  Dart_Port parent_port_;
+  Dart_Port origin_id_ = ILLEGAL_PORT;
+  Dart_Port on_exit_port_;
+  Dart_Port on_error_port_;
+  const char* script_url_;
+  const char* package_config_;
+  const char* library_url_ = nullptr;
+  const char* class_name_ = nullptr;
+  const char* function_name_ = nullptr;
+  const char* debug_name_;
+  IsolateGroup* isolate_group_;
+  std::unique_ptr<Message> serialized_args_;
+  std::unique_ptr<Message> serialized_message_;
+
+  Dart_IsolateFlags isolate_flags_;
+  bool paused_;
+  bool errors_are_fatal_;
+};
+
+static const char* NewConstChar(const char* chars) {
+  size_t len = strlen(chars);
+  char* mem = new char[len + 1];
+  memmove(mem, chars, len + 1);
+  return mem;
+}
+
+IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
+                                     Dart_Port origin_id,
+                                     const char* script_url,
+                                     const Function& func,
+                                     SerializedObjectBuffer* message_buffer,
+                                     const char* package_config,
+                                     bool paused,
+                                     bool errors_are_fatal,
+                                     Dart_Port on_exit_port,
+                                     Dart_Port on_error_port,
+                                     const char* debug_name,
+                                     IsolateGroup* isolate_group)
+    : parent_port_(parent_port),
+      origin_id_(origin_id),
+      on_exit_port_(on_exit_port),
+      on_error_port_(on_error_port),
+      script_url_(script_url),
+      package_config_(package_config),
+      debug_name_(debug_name),
+      isolate_group_(isolate_group),
+      serialized_args_(nullptr),
+      serialized_message_(message_buffer->StealMessage()),
+      paused_(paused),
+      errors_are_fatal_(errors_are_fatal) {
+  auto thread = Thread::Current();
+  auto isolate = thread->isolate();
+  auto zone = thread->zone();
+  const auto& cls = Class::Handle(zone, func.Owner());
+  const auto& lib = Library::Handle(zone, cls.library());
+  const auto& lib_url = String::Handle(zone, lib.url());
+  library_url_ = NewConstChar(lib_url.ToCString());
+
+  String& func_name = String::Handle(zone);
+  func_name = func.name();
+  function_name_ = NewConstChar(String::ScrubName(func_name));
+  if (!cls.IsTopLevel()) {
+    const auto& class_name = String::Handle(zone, cls.Name());
+    class_name_ = NewConstChar(class_name.ToCString());
+  }
+
+  // Inherit flags from spawning isolate.
+  isolate->FlagsCopyTo(isolate_flags());
+}
+
+IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
+                                     const char* script_url,
+                                     const char* package_config,
+                                     SerializedObjectBuffer* args_buffer,
+                                     SerializedObjectBuffer* message_buffer,
+                                     bool paused,
+                                     bool errors_are_fatal,
+                                     Dart_Port on_exit_port,
+                                     Dart_Port on_error_port,
+                                     const char* debug_name,
+                                     IsolateGroup* group)
+    : parent_port_(parent_port),
+      on_exit_port_(on_exit_port),
+      on_error_port_(on_error_port),
+      script_url_(script_url),
+      package_config_(package_config),
+      debug_name_(debug_name),
+      isolate_group_(group),
+      serialized_args_(args_buffer->StealMessage()),
+      serialized_message_(message_buffer->StealMessage()),
+      isolate_flags_(),
+      paused_(paused),
+      errors_are_fatal_(errors_are_fatal) {
+  function_name_ = NewConstChar("main");
+
+  // By default inherit flags from spawning isolate. These can be overridden
+  // from the calling code.
+  Isolate::Current()->FlagsCopyTo(isolate_flags());
+}
+
+IsolateSpawnState::~IsolateSpawnState() {
+  delete[] script_url_;
+  delete[] package_config_;
+  delete[] library_url_;
+  delete[] class_name_;
+  delete[] function_name_;
+  delete[] debug_name_;
+}
+
+ObjectPtr IsolateSpawnState::ResolveFunction() {
+  Thread* thread = Thread::Current();
+  Isolate* I = thread->isolate();
+  Zone* zone = thread->zone();
+
+  const String& func_name = String::Handle(zone, String::New(function_name()));
+
+  if (library_url() == nullptr) {
+    // Handle spawnUri lookup rules.
+    // Check whether the root library defines a main function.
+    const Library& lib =
+        Library::Handle(zone, I->object_store()->root_library());
+    Function& func = Function::Handle(zone, lib.LookupLocalFunction(func_name));
+    if (func.IsNull()) {
+      // Check whether main is reexported from the root library.
+      const Object& obj = Object::Handle(zone, lib.LookupReExport(func_name));
+      if (obj.IsFunction()) {
+        func ^= obj.raw();
+      }
+    }
+    if (func.IsNull()) {
+      const String& msg = String::Handle(
+          zone, String::NewFormatted(
+                    "Unable to resolve function '%s' in script '%s'.",
+                    function_name(), script_url()));
+      return LanguageError::New(msg);
+    }
+    return func.raw();
+  }
+
+  // Lookup the to be spawned function for the Isolate.spawn implementation.
+  // Resolve the library.
+  const String& lib_url = String::Handle(zone, String::New(library_url()));
+  const Library& lib =
+      Library::Handle(zone, Library::LookupLibrary(thread, lib_url));
+  if (lib.IsNull() || lib.IsError()) {
+    const String& msg = String::Handle(
+        zone,
+        String::NewFormatted("Unable to find library '%s'.", library_url()));
+    return LanguageError::New(msg);
+  }
+
+  // Resolve the function.
+  if (class_name() == nullptr) {
+    const Function& func =
+        Function::Handle(zone, lib.LookupLocalFunction(func_name));
+    if (func.IsNull()) {
+      const String& msg = String::Handle(
+          zone, String::NewFormatted(
+                    "Unable to resolve function '%s' in library '%s'.",
+                    function_name(), library_url()));
+      return LanguageError::New(msg);
+    }
+    return func.raw();
+  }
+
+  const String& cls_name = String::Handle(zone, String::New(class_name()));
+  const Class& cls = Class::Handle(zone, lib.LookupLocalClass(cls_name));
+  if (cls.IsNull()) {
+    const String& msg = String::Handle(
+        zone, String::NewFormatted(
+                  "Unable to resolve class '%s' in library '%s'.", class_name(),
+                  (library_url() != nullptr ? library_url() : script_url())));
+    return LanguageError::New(msg);
+  }
+  Function& func = Function::Handle(zone);
+  const auto& error = cls.EnsureIsFinalized(thread);
+  if (error == Error::null()) {
+    func = cls.LookupStaticFunctionAllowPrivate(func_name);
+  }
+  if (func.IsNull()) {
+    const String& msg = String::Handle(
+        zone, String::NewFormatted(
+                  "Unable to resolve static method '%s.%s' in library '%s'.",
+                  class_name(), function_name(),
+                  (library_url() != nullptr ? library_url() : script_url())));
+    return LanguageError::New(msg);
+  }
+  return func.raw();
+}
+
+static InstancePtr DeserializeMessage(Thread* thread, Message* message) {
+  if (message == NULL) {
+    return Instance::null();
+  }
+  Zone* zone = thread->zone();
+  if (message->IsRaw()) {
+    return Instance::RawCast(message->raw_obj());
+  } else {
+    MessageSnapshotReader reader(message, thread);
+    const Object& obj = Object::Handle(zone, reader.ReadObject());
+    ASSERT(!obj.IsError());
+    return Instance::RawCast(obj.raw());
+  }
+}
+
+InstancePtr IsolateSpawnState::BuildArgs(Thread* thread) {
+  return DeserializeMessage(thread, serialized_args_.get());
+}
+
+InstancePtr IsolateSpawnState::BuildMessage(Thread* thread) {
+  return DeserializeMessage(thread, serialized_message_.get());
+}
+
 static void ThrowIsolateSpawnException(const String& message) {
   const Array& args = Array::Handle(Array::New(1));
   args.SetAt(0, message);
@@ -293,11 +568,8 @@
 class SpawnIsolateTask : public ThreadPool::Task {
  public:
   SpawnIsolateTask(Isolate* parent_isolate,
-                   std::unique_ptr<IsolateSpawnState> state,
-                   bool in_new_isolate_group)
-      : parent_isolate_(parent_isolate),
-        state_(std::move(state)),
-        in_new_isolate_group_(in_new_isolate_group) {
+                   std::unique_ptr<IsolateSpawnState> state)
+      : parent_isolate_(parent_isolate), state_(std::move(state)) {
     parent_isolate->IncrementSpawnCount();
   }
 
@@ -308,68 +580,67 @@
   }
 
   void Run() override {
-    auto group = state_->isolate_group();
+    const char* name = (state_->debug_name() == nullptr)
+                           ? state_->function_name()
+                           : state_->debug_name();
+    ASSERT(name != nullptr);
 
-    // The create isolate group call back is mandatory.  If not provided we
+    auto group = state_->isolate_group();
+    if (!FLAG_enable_isolate_groups || group == nullptr) {
+      RunHeavyweight(name);
+    } else {
+      RunLightweight(name);
+    }
+  }
+
+  void RunHeavyweight(const char* name) {
+    // The create isolate group callback is mandatory.  If not provided we
     // cannot spawn isolates.
-    Dart_IsolateGroupCreateCallback create_group_callback =
-        Isolate::CreateGroupCallback();
+    auto create_group_callback = Isolate::CreateGroupCallback();
     if (create_group_callback == nullptr) {
       FailedSpawn("Isolate spawn is not supported by this Dart embedder\n");
       return;
     }
 
-    // The initialize callback is optional atm, we fall back to creating isolate
-    // groups if it was not provided.
-    Dart_InitializeIsolateCallback initialize_callback =
-        Isolate::InitializeCallback();
-
-    const char* name = (state_->debug_name() == NULL) ? state_->function_name()
-                                                      : state_->debug_name();
-    ASSERT(name != NULL);
-
-    // Create a new isolate.
     char* error = nullptr;
-    Isolate* isolate = nullptr;
-    if (!FLAG_enable_isolate_groups || group == nullptr ||
-        initialize_callback == nullptr || in_new_isolate_group_) {
-      // Make a copy of the state's isolate flags and hand it to the callback.
-      Dart_IsolateFlags api_flags = *(state_->isolate_flags());
-      isolate = reinterpret_cast<Isolate*>((create_group_callback)(
-          state_->script_url(), name, nullptr, state_->package_config(),
-          &api_flags, parent_isolate_->init_callback_data(), &error));
-      parent_isolate_->DecrementSpawnCount();
-      parent_isolate_ = nullptr;
-    } else {
-      if (initialize_callback == nullptr) {
-        FailedSpawn("Isolate spawn is not supported by this embedder.");
-        return;
-      }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
-      isolate = CreateWithinExistingIsolateGroupAOT(group, name, &error);
-#else
-      isolate = CreateWithinExistingIsolateGroup(group, name, &error);
-#endif
-      parent_isolate_->DecrementSpawnCount();
-      parent_isolate_ = nullptr;
-      if (isolate == nullptr) {
-        FailedSpawn(error);
-        free(error);
-        return;
-      }
+    // Make a copy of the state's isolate flags and hand it to the callback.
+    Dart_IsolateFlags api_flags = *(state_->isolate_flags());
+    Dart_Isolate isolate = (create_group_callback)(
+        state_->script_url(), name, nullptr, state_->package_config(),
+        &api_flags, parent_isolate_->init_callback_data(), &error);
+    parent_isolate_->DecrementSpawnCount();
+    parent_isolate_ = nullptr;
 
-      void* child_isolate_data = nullptr;
-      bool success = initialize_callback(&child_isolate_data, &error);
-      isolate->set_init_callback_data(child_isolate_data);
-      if (!success) {
-        Dart_ShutdownIsolate();
-        FailedSpawn(error);
-        free(error);
-        return;
-      }
-      Dart_ExitIsolate();
+    if (isolate == nullptr) {
+      FailedSpawn(error);
+      free(error);
+      return;
     }
+    Dart_EnterIsolate(isolate);
+    Run(reinterpret_cast<Isolate*>(isolate));
+  }
+
+  void RunLightweight(const char* name) {
+    // The create isolate initialize callback is mandatory if
+    // --enable-isolate-groups was passed.
+    auto initialize_callback = Isolate::InitializeCallback();
+    if (initialize_callback == nullptr) {
+      FailedSpawn(
+          "Lightweight isolate spawn is not supported by this Dart embedder\n");
+      return;
+    }
+
+    char* error = nullptr;
+
+    auto group = state_->isolate_group();
+#if defined(DART_PRECOMPILED_RUNTIME)
+    Isolate* isolate = CreateWithinExistingIsolateGroupAOT(group, name, &error);
+#else
+    Isolate* isolate = CreateWithinExistingIsolateGroup(group, name, &error);
+#endif
+    parent_isolate_->DecrementSpawnCount();
+    parent_isolate_ = nullptr;
 
     if (isolate == nullptr) {
       FailedSpawn(error);
@@ -377,20 +648,134 @@
       return;
     }
 
-    if (state_->origin_id() != ILLEGAL_PORT) {
-      // For isolates spawned using spawnFunction we set the origin_id
-      // to the origin_id of the parent isolate.
-      isolate->set_origin_id(state_->origin_id());
+    void* child_isolate_data = nullptr;
+    const bool success = initialize_callback(&child_isolate_data, &error);
+    if (!success) {
+      Dart_ShutdownIsolate();
+      FailedSpawn(error);
+      free(error);
+      return;
     }
-    MutexLocker ml(isolate->mutex());
-    state_->set_isolate(isolate);
-    isolate->set_spawn_state(std::move(state_));
-    if (isolate->is_runnable()) {
-      isolate->Run();
-    }
+
+    isolate->set_init_callback_data(child_isolate_data);
+    Run(isolate);
   }
 
  private:
+  void Run(Isolate* child) {
+    if (!EnsureIsRunnable(child)) {
+      Dart_ShutdownIsolate();
+      return;
+    }
+
+    state_->set_isolate(child);
+    child->set_origin_id(state_->origin_id());
+
+    bool success = true;
+    {
+      auto thread = Thread::Current();
+      TransitionNativeToVM transition(thread);
+      StackZone zone(thread);
+      HandleScope hs(thread);
+
+      success = EnqueueEntrypointInvocationAndNotifySpawner(thread);
+    }
+
+    if (!success) {
+      Dart_ShutdownIsolate();
+      return;
+    }
+
+    // All preconditions are met for this to always succeed.
+    char* error = nullptr;
+    if (!Dart_RunLoopAsync(state_->errors_are_fatal(), state_->on_error_port(),
+                           state_->on_exit_port(), &error)) {
+      FATAL("Dart_RunLoopAsync() failed: %s. Please file a Dart VM bug report.",
+            error);
+    }
+  }
+
+  bool EnsureIsRunnable(Isolate* child) {
+    // We called out to the embedder to create/initialize a new isolate. The
+    // embedder callback sucessfully did so. It is now our responsibility to
+    // run the isolate.
+    // If the isolate was not marked as runnable, we'll do so here and run it.
+    if (!child->is_runnable()) {
+      const char* error = child->MakeRunnable();
+      if (error != nullptr) {
+        FailedSpawn(error);
+        return false;
+      }
+    }
+    ASSERT(child->is_runnable());
+    return true;
+  }
+
+  bool EnqueueEntrypointInvocationAndNotifySpawner(Thread* thread) {
+    auto isolate = thread->isolate();
+    auto zone = thread->zone();
+
+    // Step 1) Resolve the entrypoint function.
+    auto& result = Object::Handle(zone, state_->ResolveFunction());
+    const bool is_spawn_uri = state_->is_spawn_uri();
+    if (result.IsError()) {
+      ASSERT(is_spawn_uri);
+      ReportError("Failed to resolve entrypoint function.");
+      return false;
+    }
+    ASSERT(result.IsFunction());
+    auto& func = Function::Handle(zone, Function::Cast(result).raw());
+    func = func.ImplicitClosureFunction();
+    const auto& entrypoint_closure =
+        Object::Handle(zone, func.ImplicitStaticClosure());
+
+    // Step 2) Enqueue delayed invocation of entrypoint callback.
+    const Array& args = Array::Handle(zone, Array::New(4));
+    args.SetAt(0, entrypoint_closure);
+    args.SetAt(1, Instance::Handle(zone, state_->BuildArgs(thread)));
+    args.SetAt(2, Instance::Handle(zone, state_->BuildMessage(thread)));
+    args.SetAt(3, is_spawn_uri ? Bool::True() : Bool::False());
+
+    const auto& lib = Library::Handle(zone, Library::IsolateLibrary());
+    const auto& entry_name = String::Handle(zone, String::New("_startIsolate"));
+    const auto& entry_point =
+        Function::Handle(zone, lib.LookupLocalFunction(entry_name));
+    ASSERT(entry_point.IsFunction() && !entry_point.IsNull());
+    result = DartEntry::InvokeFunction(entry_point, args);
+    if (result.IsError()) {
+      ReportError("Failed to enqueue delayed entrypoint invocation.");
+      return false;
+    }
+
+    // Step 3) Pause the isolate if required & Notify parent isolate about
+    // isolate creation.
+    const auto& capabilities = Array::Handle(zone, Array::New(2));
+    auto& capability = Capability::Handle(zone);
+    capability = Capability::New(isolate->pause_capability());
+    capabilities.SetAt(0, capability);
+    capability = Capability::New(isolate->terminate_capability());
+    capabilities.SetAt(1, capability);
+    const auto& send_port =
+        SendPort::Handle(zone, SendPort::New(isolate->main_port()));
+    const auto& message = Array::Handle(zone, Array::New(2));
+    message.SetAt(0, send_port);
+    message.SetAt(1, capabilities);
+    if (state_->paused()) {
+      capability ^= capabilities.At(0);
+      const bool added = isolate->AddResumeCapability(capability);
+      ASSERT(added);
+      isolate->message_handler()->increment_paused();
+    }
+    {
+      MessageWriter writer(/*can_send_any_object=*/false);
+      // If parent isolate died, we ignore the fact that we cannot notify it.
+      PortMap::PostMessage(writer.WriteMessage(message, state_->parent_port(),
+                                               Message::kNormalPriority));
+    }
+
+    return true;
+  }
+
   void FailedSpawn(const char* error) {
     ReportError(error != nullptr
                     ? error
@@ -410,7 +795,6 @@
 
   Isolate* parent_isolate_;
   std::unique_ptr<IsolateSpawnState> state_;
-  bool in_new_isolate_group_;
 
   DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
 };
@@ -466,18 +850,19 @@
           packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
       const char* utf8_debug_name =
           debugName.IsNull() ? NULL : String2UTF8(debugName);
+      const bool in_new_isolate_group = newIsolateGroup.value();
 
       std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
           port.Id(), isolate->origin_id(), String2UTF8(script_uri), func,
           &message_buffer, utf8_package_config, paused.value(), fatal_errors,
-          on_exit_port, on_error_port, utf8_debug_name, isolate->group()));
+          on_exit_port, on_error_port, utf8_debug_name,
+          in_new_isolate_group ? nullptr : isolate->group()));
 
       // Since this is a call to Isolate.spawn, copy the parent isolate's code.
       state->isolate_flags()->copy_parent_code = true;
 
-      const bool in_new_isolate_group = newIsolateGroup.value();
-      isolate->group()->thread_pool()->Run<SpawnIsolateTask>(
-          isolate, std::move(state), in_new_isolate_group);
+      isolate->group()->thread_pool()->Run<SpawnIsolateTask>(isolate,
+                                                             std::move(state));
       return Object::null();
     }
   }
@@ -581,9 +966,8 @@
   // Since this is a call to Isolate.spawnUri, don't copy the parent's code.
   state->isolate_flags()->copy_parent_code = false;
 
-  const bool in_new_isolate_group = false;
-  isolate->group()->thread_pool()->Run<SpawnIsolateTask>(
-      isolate, std::move(state), in_new_isolate_group);
+  isolate->group()->thread_pool()->Run<SpawnIsolateTask>(isolate,
+                                                         std::move(state));
   return Object::null();
 }
 
@@ -689,7 +1073,7 @@
     }
   }
 
-  uint8_t* data = reinterpret_cast<uint8_t*>(malloc(total_bytes));
+  uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(total_bytes));
   if (data == nullptr) {
     const Instance& exception =
         Instance::Handle(thread->isolate()->object_store()->out_of_memory());
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index e1ab140..eddf299 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -269,8 +269,7 @@
   kind_flags |=
       (static_cast<intptr_t>(is_ctor && func.IsGenerativeConstructor())
        << Mirrors::kGenerativeCtor);
-  kind_flags |= (static_cast<intptr_t>(is_ctor && func.is_redirecting())
-                 << Mirrors::kRedirectingCtor);
+  kind_flags |= (static_cast<intptr_t>(false) << Mirrors::kRedirectingCtor);
   kind_flags |= (static_cast<intptr_t>(is_ctor && func.IsFactory())
                  << Mirrors::kFactoryCtor);
   kind_flags |=
@@ -436,11 +435,12 @@
                                                  const LibraryPrefix& prefix,
                                                  const bool is_import,
                                                  const bool is_deferred) {
-  const Library& importee = Library::Handle(ns.library());
+  const Library& importee = Library::Handle(ns.target());
   const Array& show_names = Array::Handle(ns.show_names());
   const Array& hide_names = Array::Handle(ns.hide_names());
 
-  Object& metadata = Object::Handle(ns.GetMetadata());
+  const Library& owner = Library::Handle(ns.owner());
+  Object& metadata = Object::Handle(owner.GetMetadata(ns));
   if (metadata.IsError()) {
     Exceptions::PropagateError(Error::Cast(metadata));
     UNREACHABLE();
@@ -1402,29 +1402,6 @@
   }
 
   Class& redirected_klass = Class::Handle(klass.raw());
-  Function& redirected_constructor = Function::Handle(lookup_constructor.raw());
-  if (lookup_constructor.IsRedirectingFactory()) {
-    // Redirecting factory must be resolved.
-    ASSERT(lookup_constructor.RedirectionTarget() != Function::null());
-    Type& redirect_type = Type::Handle(lookup_constructor.RedirectionType());
-
-    if (!redirect_type.IsInstantiated()) {
-      // The type arguments of the redirection type are instantiated from the
-      // type arguments of the type reflected by the class mirror.
-      ASSERT(redirect_type.IsInstantiated(kFunctions));
-      redirect_type ^= redirect_type.InstantiateFrom(
-          type_arguments, Object::null_type_arguments(), kNoneFree, Heap::kOld);
-      redirect_type ^= redirect_type.Canonicalize(thread, nullptr);
-    }
-
-    type = redirect_type.raw();
-    type_arguments = redirect_type.arguments();
-
-    redirected_constructor = lookup_constructor.RedirectionTarget();
-    ASSERT(!redirected_constructor.IsNull());
-    redirected_klass = type.type_class();
-  }
-
   const intptr_t num_explicit_args = explicit_args.Length();
   const intptr_t num_implicit_args = 1;
   const Array& args =
@@ -1442,8 +1419,8 @@
       ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(), arg_names));
 
   ArgumentsDescriptor args_descriptor(args_descriptor_array);
-  if (!redirected_constructor.AreValidArguments(args_descriptor, NULL)) {
-    external_constructor_name = redirected_constructor.name();
+  if (!lookup_constructor.AreValidArguments(args_descriptor, NULL)) {
+    external_constructor_name = lookup_constructor.name();
     ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
                       external_constructor_name, explicit_args, arg_names,
                       InvocationMirror::kConstructor,
@@ -1457,7 +1434,7 @@
   ASSERT(explicit_argument.IsNull());
 #endif
   const Object& type_error =
-      Object::Handle(redirected_constructor.DoArgumentTypesMatch(
+      Object::Handle(lookup_constructor.DoArgumentTypesMatch(
           args, args_descriptor, type_arguments));
   if (!type_error.IsNull()) {
     Exceptions::PropagateError(Error::Cast(type_error));
@@ -1465,7 +1442,7 @@
   }
 
   Instance& new_object = Instance::Handle();
-  if (redirected_constructor.IsGenerativeConstructor()) {
+  if (lookup_constructor.IsGenerativeConstructor()) {
     // Constructors get the uninitialized object.
     // Note we have delayed allocation until after the function
     // type and argument matching checks.
@@ -1484,7 +1461,7 @@
 
   // Invoke the constructor and return the new object.
   const Object& result = Object::Handle(DartEntry::InvokeFunction(
-      redirected_constructor, args, args_descriptor_array));
+      lookup_constructor, args, args_descriptor_array));
   if (result.IsError()) {
     Exceptions::PropagateError(Error::Cast(result));
     UNREACHABLE();
@@ -1493,7 +1470,7 @@
   // Factories may return null.
   ASSERT(result.IsInstance() || result.IsNull());
 
-  if (redirected_constructor.IsGenerativeConstructor()) {
+  if (lookup_constructor.IsGenerativeConstructor()) {
     return new_object.raw();
   } else {
     return result.raw();
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index eaa287c..2c75f02 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -66,79 +66,17 @@
 // Gets current stack trace for `thread`.
 // This functions itself handles the --causel-async-stacks case.
 // For --lazy-async-stacks see `CurrentSyncStackTraceLazy`.
-// For --no-causel-async-stacks see `CurrentSyncStackTrace`.
+// For fallback see `CurrentSyncStackTrace`.
 // Extracts the causal async stack from the thread if any set, then prepends
 // the current sync. stack up until the current async function (if any).
-static StackTracePtr CurrentStackTrace(
-    Thread* thread,
-    bool for_async_function,
-    intptr_t skip_frames = 1,
-    bool causal_async_stacks = FLAG_causal_async_stacks) {
+static StackTracePtr CurrentStackTrace(Thread* thread,
+                                       bool for_async_function,
+                                       intptr_t skip_frames = 1) {
   if (FLAG_lazy_async_stacks) {
     return CurrentSyncStackTraceLazy(thread, skip_frames);
   }
-  if (!causal_async_stacks) {
-    // Return the synchronous stack trace.
-    return CurrentSyncStackTrace(thread, skip_frames);
-  }
-
-  Zone* zone = thread->zone();
-  Code& code = Code::ZoneHandle(zone);
-  Smi& offset = Smi::ZoneHandle(zone);
-  Function& async_function = Function::ZoneHandle(zone);
-  StackTrace& async_stack_trace = StackTrace::ZoneHandle(zone);
-  Array& async_code_array = Array::ZoneHandle(zone);
-  Array& async_pc_offset_array = Array::ZoneHandle(zone);
-
-  StackTraceUtils::ExtractAsyncStackTraceInfo(
-      thread, &async_function, &async_stack_trace, &async_code_array,
-      &async_pc_offset_array);
-
-  // Determine the size of the stack trace.
-  const intptr_t extra_frames = for_async_function ? 1 : 0;
-  bool sync_async_end = false;
-  // Count frames until `async_function` and set whether the async function is
-  // running synchronously (i.e. hasn't yielded yet).
-  const intptr_t synchronous_stack_trace_length = StackTraceUtils::CountFrames(
-      thread, skip_frames, async_function, &sync_async_end);
-
-  ASSERT(synchronous_stack_trace_length > 0);
-
-  const intptr_t capacity = synchronous_stack_trace_length +
-                            extra_frames;  // For the asynchronous gap.
-
-  // Allocate memory for the stack trace.
-  const Array& code_array = Array::ZoneHandle(zone, Array::New(capacity));
-  const Array& pc_offset_array = Array::ZoneHandle(zone, Array::New(capacity));
-
-  intptr_t write_cursor = 0;
-  if (for_async_function) {
-    // Place the asynchronous gap marker at the top of the stack trace.
-    code = StubCode::AsynchronousGapMarker().raw();
-    ASSERT(!code.IsNull());
-    offset = Smi::New(0);
-    code_array.SetAt(write_cursor, code);
-    pc_offset_array.SetAt(write_cursor, offset);
-    write_cursor++;
-  }
-
-  // Prepend: synchronous stack trace + (cached) async stack trace.
-
-  write_cursor +=
-      StackTraceUtils::CollectFrames(thread, code_array, pc_offset_array,
-                                     /*array_offset=*/write_cursor,
-                                     /*count=*/synchronous_stack_trace_length,
-                                     /*skip_frames=*/skip_frames);
-
-  ASSERT(write_cursor == capacity);
-
-  const StackTrace& result = StackTrace::Handle(
-      zone,
-      StackTrace::New(code_array, pc_offset_array,
-                      /*async_link=*/async_stack_trace,
-                      /*skip_sync_start_in_parent_stack=*/sync_async_end));
-
-  return result.raw();
+  // Return the synchronous stack trace.
+  return CurrentSyncStackTrace(thread, skip_frames);
 }
 
 StackTracePtr GetStackTraceForException() {
@@ -150,39 +88,6 @@
   return CurrentStackTrace(thread, false);
 }
 
-DEFINE_NATIVE_ENTRY(StackTrace_asyncStackTraceHelper, 0, 1) {
-  if (!FLAG_causal_async_stacks) {
-    // If causal async stacks are not enabled we should recognize this method
-    // and never call to the NOP runtime.
-    // See kernel_to_il.cc.
-    UNREACHABLE();
-  }
-#if !defined(PRODUCT)
-  GET_NATIVE_ARGUMENT(Closure, async_op, arguments->NativeArgAt(0));
-  Debugger* debugger = isolate->debugger();
-  if (debugger != NULL) {
-    debugger->MaybeAsyncStepInto(async_op);
-  }
-#endif
-  return CurrentStackTrace(thread, true);
-}
-
-DEFINE_NATIVE_ENTRY(StackTrace_clearAsyncThreadStackTrace, 0, 0) {
-  thread->clear_async_stack_trace();
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(StackTrace_setAsyncThreadStackTrace, 0, 1) {
-  if (!FLAG_causal_async_stacks) {
-    return Object::null();
-  }
-
-  GET_NON_NULL_NATIVE_ARGUMENT(StackTrace, stack_trace,
-                               arguments->NativeArgAt(0));
-  thread->set_async_stack_trace(stack_trace);
-  return Object::null();
-}
-
 static void AppendFrames(const GrowableObjectArray& code_list,
                          const GrowableObjectArray& pc_offset_list,
                          int skip_frames) {
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
deleted file mode 100644
index 639c72a..0000000
--- a/runtime/lib/wasm.cc
+++ /dev/null
@@ -1,1045 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifdef DART_ENABLE_WASM
-
-#include <memory>
-#include <sstream>
-
-#include "platform/unicode.h"
-#include "third_party/wasmer/wasmer.hh"
-#include "vm/bootstrap_natives.h"
-#include "vm/dart_api_state.h"
-#include "vm/dart_entry.h"
-#include "vm/exceptions.h"
-
-namespace dart {
-
-static void ThrowWasmerError() {
-  String& error = String::Handle();
-  {
-    int len = wasmer_last_error_length();
-    auto raw_error = std::unique_ptr<char[]>(new char[len]);
-    int read_len = wasmer_last_error_message(raw_error.get(), len);
-    ASSERT(read_len == len);
-    error = String::NewFormatted("Wasmer error: %s", raw_error.get());
-  }
-  Exceptions::ThrowArgumentError(error);
-  UNREACHABLE();
-}
-
-template <typename T>
-static void Finalize(void* isolate_callback_data,
-                     Dart_WeakPersistentHandle handle,
-                     void* peer) {
-  delete reinterpret_cast<T*>(peer);
-}
-
-static void FinalizeWasmModule(void* isolate_callback_data,
-                               Dart_WeakPersistentHandle handle,
-                               void* module) {
-  wasmer_module_destroy(reinterpret_cast<wasmer_module_t*>(module));
-}
-
-static void FinalizeWasmMemory(void* isolate_callback_data,
-                               Dart_WeakPersistentHandle handle,
-                               void* memory) {
-  wasmer_memory_destroy(reinterpret_cast<wasmer_memory_t*>(memory));
-}
-
-static std::unique_ptr<char[]> ToUTF8(const String& str) {
-  const intptr_t str_size = Utf8::Length(str);
-  auto str_raw = std::unique_ptr<char[]>(new char[str_size + 1]);
-  str.ToUTF8(reinterpret_cast<uint8_t*>(str_raw.get()), str_size);
-  str_raw[str_size] = '\0';
-  return str_raw;
-}
-
-static bool ToWasmValue(const Number& value,
-                        classid_t type,
-                        wasmer_value_t* out) {
-  switch (type) {
-    case kWasmInt32Cid:
-      if (!value.IsInteger()) return false;
-      out->tag = wasmer_value_tag::WASM_I32;
-      out->value.I32 = Integer::Cast(value).AsInt64Value();
-      return true;
-    case kWasmInt64Cid:
-      if (!value.IsInteger()) return false;
-      out->tag = wasmer_value_tag::WASM_I64;
-      out->value.I64 = Integer::Cast(value).AsInt64Value();
-      return true;
-    case kWasmFloatCid:
-      if (!value.IsDouble()) return false;
-      out->tag = wasmer_value_tag::WASM_F32;
-      out->value.F32 = Double::Cast(value).value();
-      return true;
-    case kWasmDoubleCid:
-      if (!value.IsDouble()) return false;
-      out->tag = wasmer_value_tag::WASM_F64;
-      out->value.F64 = Double::Cast(value).value();
-      return true;
-    default:
-      return false;
-  }
-}
-
-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 ObjectPtr ToDartObject(wasmer_value_t ret) {
-  switch (ret.tag) {
-    case wasmer_value_tag::WASM_I32:
-      return Integer::New(ret.value.I32);
-    case wasmer_value_tag::WASM_I64:
-      return Integer::New(ret.value.I64);
-    case wasmer_value_tag::WASM_F32:
-      return Double::New(ret.value.F32);
-    case wasmer_value_tag::WASM_F64:
-      return Double::New(ret.value.F64);
-    default:
-      FATAL("Unknown WASM type");
-      return nullptr;
-  }
-}
-
-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;
-  }
-}
-
-ExternalTypedDataPtr WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
-  uint8_t* data = wasmer_memory_data(memory);
-  uint32_t size = wasmer_memory_data_length(memory);
-  return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, size);
-}
-
-std::ostream& operator<<(std::ostream& o, const wasmer_byte_array& str) {
-  for (uint32_t i = 0; i < str.bytes_len; ++i) {
-    o << str.bytes[i];
-  }
-  return o;
-}
-
-std::ostream& operator<<(std::ostream& o, const wasmer_import_export_kind& io) {
-  switch (io) {
-    case wasmer_import_export_kind::WASM_FUNCTION:
-      return o << "WASM_FUNCTION";
-    case wasmer_import_export_kind::WASM_GLOBAL:
-      return o << "WASM_GLOBAL";
-    case wasmer_import_export_kind::WASM_MEMORY:
-      return o << "WASM_MEMORY";
-    case wasmer_import_export_kind::WASM_TABLE:
-      return o << "WASM_TABLE";
-  }
-}
-
-StringPtr DescribeModule(const wasmer_module_t* module) {
-  std::stringstream desc;
-
-  desc << "Imports:\n";
-  wasmer_import_descriptors_t* imports;
-  wasmer_import_descriptors(module, &imports);
-  unsigned num_imports = wasmer_import_descriptors_len(imports);
-  for (unsigned i = 0; i < num_imports; ++i) {
-    wasmer_import_descriptor_t* imp = wasmer_import_descriptors_get(imports, i);
-    desc << "\t" << wasmer_import_descriptor_module_name(imp);
-    desc << "\t" << wasmer_import_descriptor_name(imp);
-    desc << "\t" << wasmer_import_descriptor_kind(imp);
-    desc << "\n";
-  }
-  wasmer_import_descriptors_destroy(imports);
-
-  desc << "\nExports:\n";
-  wasmer_export_descriptors_t* exports;
-  wasmer_export_descriptors(module, &exports);
-  unsigned num_exports = wasmer_export_descriptors_len(exports);
-  for (unsigned i = 0; i < num_exports; ++i) {
-    wasmer_export_descriptor_t* exp = wasmer_export_descriptors_get(exports, i);
-    desc << "\t" << wasmer_export_descriptor_name(exp);
-    desc << "\t" << wasmer_export_descriptor_kind(exp);
-    desc << "\n";
-  }
-  wasmer_export_descriptors_destroy(exports);
-
-  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:
-  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[]> 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[]> 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(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:
-  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[]> 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());
-    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;
-  }
-
-  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,
-               classid_t ret,
-               const wasmer_export_func_t* fn)
-      : _args(std::move(args)), _ret(ret), _fn(fn) {}
-  bool IsVoid() const { return _ret == kWasmVoidCid; }
-  const MallocGrowableArray<classid_t>& args() const { return _args; }
-
-  bool SignatureMatches(const MallocGrowableArray<classid_t>& dart_args,
-                        classid_t dart_ret) {
-    if (dart_args.length() != _args.length()) {
-      return false;
-    }
-    for (intptr_t i = 0; i < dart_args.length(); ++i) {
-      if (dart_args[i] != _args[i]) {
-        return false;
-      }
-    }
-    return dart_ret == _ret;
-  }
-
-  wasmer_result_t Call(const wasmer_value_t* params, wasmer_value_t* result) {
-    return wasmer_export_func_call(_fn, params, _args.length(), result,
-                                   IsVoid() ? 0 : 1);
-  }
-
-  void Print(std::ostream& o, const char* name) const {
-    PrintDartType(o, _ret);
-    o << ' ' << name << '(';
-    for (intptr_t i = 0; i < _args.length(); ++i) {
-      if (i > 0) o << ", ";
-      PrintDartType(o, _args[i]);
-    }
-    o << ')';
-  }
-
- private:
-  MallocGrowableArray<classid_t> _args;
-  const classid_t _ret;
-  const wasmer_export_func_t* _fn;
-
-  static void PrintDartType(std::ostream& o, classid_t type) {
-    switch (type) {
-      case kWasmInt32Cid:
-        o << "i32";
-        break;
-      case kWasmInt64Cid:
-        o << "i64";
-        break;
-      case kWasmFloatCid:
-        o << "f32";
-        break;
-      case kWasmDoubleCid:
-        o << "f64";
-        break;
-      case kWasmVoidCid:
-        o << "void";
-        break;
-    }
-  }
-};
-
-class WasmInstance {
- public:
-  WasmInstance() : _instance(nullptr), _exports(nullptr), _memory(nullptr) {}
-
-  bool Instantiate(wasmer_module_t* module, WasmImports* imports) {
-    ASSERT(_instance == nullptr);
-
-    // Instantiate module.
-    if (wasmer_module_instantiate(module, &_instance, imports->RawImports(),
-                                  imports->NumImports()) !=
-        wasmer_result_t::WASMER_OK) {
-      return false;
-    }
-
-    // Load all exports.
-    wasmer_instance_exports(_instance, &_exports);
-    intptr_t num_exports = wasmer_exports_len(_exports);
-    for (intptr_t i = 0; i < num_exports; ++i) {
-      wasmer_export_t* exp = wasmer_exports_get(_exports, i);
-      wasmer_import_export_kind kind = wasmer_export_kind(exp);
-      if (kind == wasmer_import_export_kind::WASM_FUNCTION) {
-        if (!AddFunction(exp)) {
-          return false;
-        }
-      } else if (kind == wasmer_import_export_kind::WASM_MEMORY) {
-        ASSERT(_memory == nullptr);
-        if (wasmer_export_to_memory(exp, &_memory) !=
-            wasmer_result_t::WASMER_OK) {
-          return false;
-        }
-      }
-    }
-
-    return true;
-  }
-
-  ~WasmInstance() {
-    auto it = _functions.GetIterator();
-    for (auto* kv = it.Next(); kv; kv = it.Next()) {
-      delete[] kv->key;
-      delete kv->value;
-    }
-    if (_exports != nullptr) {
-      wasmer_exports_destroy(_exports);
-    }
-    if (_instance != nullptr) {
-      wasmer_instance_destroy(_instance);
-    }
-  }
-
-  WasmFunction* GetFunction(const char* name,
-                            const MallocGrowableArray<classid_t>& dart_args,
-                            classid_t dart_ret,
-                            String* error) {
-    WasmFunction* fn = _functions.LookupValue(name);
-    if (fn == nullptr) {
-      *error = String::NewFormatted(
-          "Couldn't find a function called %s in the WASM module's exports",
-          name);
-      return nullptr;
-    }
-    if (!fn->SignatureMatches(dart_args, dart_ret)) {
-      std::stringstream sig;
-      fn->Print(sig, name);
-      *error = String::NewFormatted("Function signature doesn't match: %s",
-                                    sig.str().c_str());
-      return nullptr;
-    }
-    return fn;
-  }
-
-  void PrintFunctions(std::ostream& o) const {
-    o << '{' << std::endl;
-    auto it = _functions.GetIterator();
-    for (auto* kv = it.Next(); kv; kv = it.Next()) {
-      kv->value->Print(o, kv->key);
-      o << std::endl;
-    }
-    o << '}' << std::endl;
-  }
-
-  wasmer_memory_t* memory() { return _memory; }
-
- private:
-  wasmer_instance_t* _instance;
-  wasmer_exports_t* _exports;
-  MallocDirectChainedHashMap<CStringKeyValueTrait<WasmFunction*>> _functions;
-  wasmer_memory_t* _memory;
-
-  static classid_t ToDartType(wasmer_value_tag wasm_type) {
-    switch (wasm_type) {
-      case wasmer_value_tag::WASM_I32:
-        return kWasmInt32Cid;
-      case wasmer_value_tag::WASM_I64:
-        return kWasmInt64Cid;
-      case wasmer_value_tag::WASM_F32:
-        return kWasmFloatCid;
-      case wasmer_value_tag::WASM_F64:
-        return kWasmDoubleCid;
-    }
-    FATAL("Unknown WASM type");
-    return 0;
-  }
-
-  bool AddFunction(wasmer_export_t* exp) {
-    const wasmer_export_func_t* fn = wasmer_export_to_func(exp);
-
-    uint32_t num_rets;
-    if (wasmer_export_func_returns_arity(fn, &num_rets) !=
-        wasmer_result_t::WASMER_OK) {
-      return false;
-    }
-    ASSERT(num_rets <= 1);
-    wasmer_value_tag wasm_ret;
-    if (wasmer_export_func_returns(fn, &wasm_ret, num_rets) !=
-        wasmer_result_t::WASMER_OK) {
-      return false;
-    }
-    classid_t ret = num_rets == 0 ? kWasmVoidCid : ToDartType(wasm_ret);
-
-    uint32_t num_args;
-    if (wasmer_export_func_params_arity(fn, &num_args) !=
-        wasmer_result_t::WASMER_OK) {
-      return false;
-    }
-    auto wasm_args =
-        std::unique_ptr<wasmer_value_tag[]>(new wasmer_value_tag[num_args]);
-    if (wasmer_export_func_params(fn, wasm_args.get(), num_args) !=
-        wasmer_result_t::WASMER_OK) {
-      return false;
-    }
-    MallocGrowableArray<classid_t> args;
-    for (intptr_t i = 0; i < num_args; ++i) {
-      args.Add(ToDartType(wasm_args[i]));
-    }
-
-    wasmer_byte_array name_bytes = wasmer_export_name(exp);
-    char* name = new char[name_bytes.bytes_len + 1];
-    for (size_t i = 0; i < name_bytes.bytes_len; ++i) {
-      name[i] = name_bytes.bytes[i];
-    }
-    name[name_bytes.bytes_len] = '\0';
-
-    _functions.Insert({name, new WasmFunction(std::move(args), ret, fn)});
-    return true;
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(WasmInstance);
-};
-
-DEFINE_NATIVE_ENTRY(Wasm_initModule, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mod_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(TypedDataBase, data, arguments->NativeArgAt(1));
-
-  ASSERT(mod_wrap.NumNativeFields() == 1);
-
-  std::unique_ptr<uint8_t[]> data_copy;
-  intptr_t len;
-  {
-    NoSafepointScope scope(thread);
-    len = data.LengthInBytes();
-    data_copy = std::unique_ptr<uint8_t[]>(new uint8_t[len]);
-    // The memory does not overlap.
-    memcpy(data_copy.get(), data.DataAddr(0), len);  // NOLINT
-  }
-
-  wasmer_module_t* module;
-  wasmer_result_t result;
-  {
-    TransitionVMToNative transition(thread);
-    result = wasmer_compile(&module, data_copy.get(), len);
-  }
-  if (result != wasmer_result_t::WASMER_OK) {
-    data_copy.reset();
-    ThrowWasmerError();
-    UNREACHABLE();
-  }
-
-  mod_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(module));
-  FinalizablePersistentHandle::New(thread->isolate(), mod_wrap, module,
-                                   FinalizeWasmModule, len);
-
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_describeModule, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mod_wrap, arguments->NativeArgAt(0));
-
-  ASSERT(mod_wrap.NumNativeFields() == 1);
-
-  wasmer_module_t* module =
-      reinterpret_cast<wasmer_module_t*>(mod_wrap.GetNativeField(0));
-
-  return DescribeModule(module);
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
-
-  ASSERT(imp_wrap.NumNativeFields() == 1);
-
-  WasmImports* imports = new WasmImports();
-
-  imp_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(imports));
-  imports->SetHandle(FinalizablePersistentHandle::New(
-      thread->isolate(), imp_wrap, imports, Finalize<WasmImports>,
-      sizeof(WasmImports)));
-
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 4) {
-  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(Instance, mem_wrap, arguments->NativeArgAt(3));
-
-  ASSERT(imp_wrap.NumNativeFields() == 1);
-  ASSERT(mem_wrap.NumNativeFields() == 1);
-
-  WasmImports* imports =
-      reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
-  wasmer_memory_t* memory =
-      reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
-
-  imports->AddMemory(ToUTF8(module_name), ToUTF8(name), memory);
-
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 6) {
-  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(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);
-
-  WasmImports* imports =
-      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(
-        zone, String::NewFormatted(
-                  "Can't convert dart value to WASM global variable")));
-    UNREACHABLE();
-  }
-
-  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();
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initMemory, 0, 3) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Integer, init, arguments->NativeArgAt(1));
-  GET_NATIVE_ARGUMENT(Integer, max, arguments->NativeArgAt(2));
-
-  ASSERT(mem_wrap.NumNativeFields() == 1);
-  const int64_t init_size = init.AsInt64Value();
-
-  wasmer_memory_t* memory;
-  wasmer_limits_t descriptor;
-  descriptor.min = init_size;
-  if (max.IsNull()) {
-    descriptor.max.has_some = false;
-  } else {
-    descriptor.max.has_some = true;
-    descriptor.max.some = max.AsInt64Value();
-  }
-  if (wasmer_memory_new(&memory, descriptor) != wasmer_result_t::WASMER_OK) {
-    ThrowWasmerError();
-    UNREACHABLE();
-  }
-  mem_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(memory));
-  FinalizablePersistentHandle::New(thread->isolate(), mem_wrap, memory,
-                                   FinalizeWasmMemory, init_size);
-  return WasmMemoryToExternalTypedData(memory);
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_growMemory, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Integer, delta, arguments->NativeArgAt(1));
-
-  ASSERT(mem_wrap.NumNativeFields() == 1);
-
-  wasmer_memory_t* memory =
-      reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
-  if (wasmer_memory_grow(memory, delta.AsInt64Value()) !=
-      wasmer_result_t::WASMER_OK) {
-    ThrowWasmerError();
-    UNREACHABLE();
-  }
-  return WasmMemoryToExternalTypedData(memory);
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initInstance, 0, 3) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mod_wrap, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(2));
-
-  ASSERT(inst_wrap.NumNativeFields() == 1);
-  ASSERT(mod_wrap.NumNativeFields() == 1);
-  ASSERT(imp_wrap.NumNativeFields() == 1);
-
-  wasmer_module_t* module =
-      reinterpret_cast<wasmer_module_t*>(mod_wrap.GetNativeField(0));
-  WasmImports* imports =
-      reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
-
-  WasmInstance* inst = nullptr;
-  {
-    TransitionVMToNative transition(thread);
-    inst = new WasmInstance();
-    if (!inst->Instantiate(module, imports)) {
-      delete inst;
-      inst = nullptr;
-    }
-  }
-  if (inst == nullptr) {
-    ThrowWasmerError();
-    UNREACHABLE();
-  }
-
-  inst_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(inst));
-  FinalizablePersistentHandle::New(thread->isolate(), inst_wrap, inst,
-                                   Finalize<WasmInstance>,
-                                   sizeof(WasmInstance));
-
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initMemoryFromInstance, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(1));
-
-  ASSERT(mem_wrap.NumNativeFields() == 1);
-  ASSERT(inst_wrap.NumNativeFields() == 1);
-
-  WasmInstance* inst =
-      reinterpret_cast<WasmInstance*>(inst_wrap.GetNativeField(0));
-
-  wasmer_memory_t* memory = inst->memory();
-
-  mem_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(memory));
-  FinalizablePersistentHandle::New(thread->isolate(), mem_wrap, memory,
-                                   FinalizeWasmMemory,
-                                   wasmer_memory_length(memory));
-  return WasmMemoryToExternalTypedData(memory);
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_getMemoryPages, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
-
-  ASSERT(mem_wrap.NumNativeFields() == 1);
-
-  wasmer_memory_t* memory =
-      reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
-
-  return Integer::New(wasmer_memory_length(memory));
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, fn_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
-  GET_NON_NULL_NATIVE_ARGUMENT(Type, fn_type, arguments->NativeArgAt(3));
-
-  ASSERT(fn_wrap.NumNativeFields() == 1);
-  ASSERT(inst_wrap.NumNativeFields() == 1);
-
-  WasmInstance* inst =
-      reinterpret_cast<WasmInstance*>(inst_wrap.GetNativeField(0));
-
-  WasmFunction* fn;
-  String& error = String::Handle(zone);
-
-  {
-    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) {
-      arg_type ^= args.At(i);
-      dart_args.Add(arg_type.type_class_id());
-    }
-    classid_t dart_ret =
-        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);
-  }
-
-  if (fn == nullptr) {
-    Exceptions::ThrowArgumentError(error);
-    UNREACHABLE();
-  }
-
-  fn_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(fn));
-  // Don't need a finalizer because WasmFunctions are owned their WasmInstance.
-
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_callFunction, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, fn_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1));
-
-  ASSERT(fn_wrap.NumNativeFields() == 1);
-  WasmFunction* fn = reinterpret_cast<WasmFunction*>(fn_wrap.GetNativeField(0));
-
-  if (args.Length() != fn->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) {
-    arg_num ^= args.At(i);
-    if (!ToWasmValue(arg_num, fn->args()[i], &params[i])) {
-      params.reset();
-      Exceptions::ThrowArgumentError(String::Handle(
-          zone, String::NewFormatted("Arg %" Pd " is the wrong type.", i)));
-      UNREACHABLE();
-    }
-  }
-
-  wasmer_value_t ret;
-  wasmer_result_t result;
-  {
-    TransitionVMToNative transition(thread);
-    result = fn->Call(params.get(), &ret);
-  }
-  if (result != wasmer_result_t::WASMER_OK) {
-    params.reset();
-    ThrowWasmerError();
-    UNREACHABLE();
-  }
-  return fn->IsVoid() ? Object::null() : ToDartObject(ret);
-}
-
-}  // namespace dart
-
-#else  // DART_ENABLE_WASM
-
-#include "vm/bootstrap_natives.h"
-#include "vm/dart_entry.h"
-#include "vm/exceptions.h"
-
-namespace dart {
-
-DEFINE_NATIVE_ENTRY(Wasm_initModule, 0, 2) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_describeModule, 0, 1) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 1) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 4) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-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;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initMemory, 0, 3) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_growMemory, 0, 3) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initInstance, 0, 3) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initMemoryFromInstance, 0, 2) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_getMemoryPages, 0, 1) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-DEFINE_NATIVE_ENTRY(Wasm_callFunction, 0, 2) {
-  Exceptions::ThrowUnsupportedError("WASM is disabled");
-  return nullptr;
-}
-
-}  // namespace dart
-
-#endif  // DART_ENABLE_WASM
diff --git a/runtime/lib/wasm_sources.gni b/runtime/lib/wasm_sources.gni
deleted file mode 100644
index 2e7faff..0000000
--- a/runtime/lib/wasm_sources.gni
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-wasm_runtime_cc_files = [ "wasm.cc" ]
diff --git a/runtime/lib/weak_property.cc b/runtime/lib/weak_property.cc
index 8715b6d..16eb41c 100644
--- a/runtime/lib/weak_property.cc
+++ b/runtime/lib/weak_property.cc
@@ -10,21 +10,20 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(WeakProperty_new, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, key, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(1));
-  const WeakProperty& weak_property = WeakProperty::Handle(WeakProperty::New());
-  weak_property.set_key(key);
-  weak_property.set_value(value);
-  return weak_property.raw();
-}
-
 DEFINE_NATIVE_ENTRY(WeakProperty_getKey, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
                                arguments->NativeArgAt(0));
   return weak_property.key();
 }
 
+DEFINE_NATIVE_ENTRY(WeakProperty_setKey, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
+                               arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, key, arguments->NativeArgAt(1));
+  weak_property.set_key(key);
+  return Object::null();
+}
+
 DEFINE_NATIVE_ENTRY(WeakProperty_getValue, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
                                arguments->NativeArgAt(0));
diff --git a/runtime/observatory/analysis_options.yaml b/runtime/observatory/analysis_options.yaml
index 13bad8a..f9cf4b3 100644
--- a/runtime/observatory/analysis_options.yaml
+++ b/runtime/observatory/analysis_options.yaml
@@ -1,10 +1,13 @@
 analyzer:
   enable-experiment:
     - non-nullable
+
   errors:
-    dead_code: ignore
-    unused_local_variable: ignore
-    getter_not_subtype_setter_types: ignore
+    dead_code: info
+    getter_not_subtype_setter_types: info
+    missing_enum_constant_in_switch: info
+    unused_local_variable: info
+
   exclude:
     - tests/service/bad_reload/v2/main.dart
     - tests/service/complex_reload/v2/main.dart
@@ -14,7 +17,7 @@
     - tests/service/get_user_level_retaining_path_rpc_test.dart
     - tests/service/pause_on_unhandled_async_exceptions_test.dart
 
-linter:
-  rules:
-    - prefer_final_fields
-    - prefer_final_locals
+# linter:
+#   rules:
+#     - prefer_final_fields
+#     - prefer_final_locals
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
index 7282dd1..e907c62 100644
--- a/runtime/observatory/lib/models.dart
+++ b/runtime/observatory/lib/models.dart
@@ -50,14 +50,12 @@
 part 'src/models/objects/source_location.dart';
 part 'src/models/objects/subtype_test_cache.dart';
 part 'src/models/objects/target.dart';
-part 'src/models/objects/thread.dart';
 part 'src/models/objects/timeline.dart';
 part 'src/models/objects/timeline_event.dart';
 part 'src/models/objects/type_arguments.dart';
 part 'src/models/objects/unknown.dart';
 part 'src/models/objects/unlinked_call.dart';
 part 'src/models/objects/vm.dart';
-part 'src/models/objects/zone.dart';
 
 part 'src/models/repositories/allocation_profile.dart';
 part 'src/models/repositories/breakpoint.dart';
diff --git a/runtime/observatory/lib/src/elements/isolate_view.dart b/runtime/observatory/lib/src/elements/isolate_view.dart
index 73377da..d792d03 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.dart
+++ b/runtime/observatory/lib/src/elements/isolate_view.dart
@@ -116,7 +116,6 @@
   void render() {
     final uptime = new DateTime.now().difference(_isolate.startTime!);
     final libraries = _isolate.libraries!.toList();
-    final List<M.Thread> threads = _isolate.threads!.toList();
     children = <Element>[
       navBar(<Element>[
         new NavTopMenuElement(queue: _r.queue).element,
@@ -261,26 +260,6 @@
                 ..children = <Element>[
                   new DivElement()
                     ..classes = ['memberName']
-                    ..text = 'allocated zone handle count',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..text = '${_isolate.numZoneHandles}'
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'allocated scoped handle count',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..text = '${_isolate.numScopedHandles}'
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
                     ..text = 'object store',
                   new DivElement()
                     ..classes = ['memberValue']
@@ -289,19 +268,6 @@
                         ..text = 'object store'
                     ]
                 ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'zone capacity high watermark'
-                    ..title = '''The maximum amount of native zone memory
-                    allocated by the isolate over it\'s life.''',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..text = Utils.formatSize(_isolate.zoneHighWatermark)
-                    ..title = '${_isolate.zoneHighWatermark}B'
-                ],
               new BRElement(),
               new DivElement()
                 ..classes = ['memberItem']
@@ -324,21 +290,6 @@
                           .element
                     ]
                 ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'threads (${threads.length})',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..children = <Element>[
-                      (new CurlyBlockElement(queue: _r.queue)
-                            ..content =
-                                threads.map<Element>(_populateThreadInfo))
-                          .element
-                    ]
-                ]
             ],
           new HRElement(),
           new EvalBoxElement(_isolate, _isolate.rootLibrary!, _objects, _eval,
@@ -360,31 +311,6 @@
     ];
   }
 
-  DivElement _populateThreadInfo(M.Thread t) {
-    return new DivElement()
-      ..classes = ['indent']
-      ..children = <Element>[
-        new SpanElement()..text = '${t.id} ',
-        (new CurlyBlockElement(queue: _r.queue)
-              ..content = <Element>[
-                new DivElement()
-                  ..classes = ['indent']
-                  ..text = 'kind ${t.kindString}',
-                new DivElement()
-                  ..classes = ['indent']
-                  ..title = '${t.zoneHighWatermark}B'
-                  ..text = 'zone capacity high watermark '
-                      '${Utils.formatSize(t.zoneHighWatermark)}',
-                new DivElement()
-                  ..classes = ['indent']
-                  ..title = '${t.zoneCapacity}B'
-                  ..text = 'current zone capacity ' +
-                      '${Utils.formatSize(t.zoneCapacity)}',
-              ])
-            .element
-      ];
-  }
-
   Future _loadExtraData() async {
     _function = null;
     _rootScript = null;
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
index 3f83455..c39fccf 100644
--- a/runtime/observatory/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate.dart
@@ -57,20 +57,6 @@
   /// [optional] The error that is causing this isolate to exit, if applicable.
   Error? get error;
 
-  /// The list of threads associated with this isolate.
-  Iterable<Thread>? get threads;
-
-  /// The maximum amount of zone memory in bytes allocated by the isolate in
-  /// all threads at a given time. Calculated using the high watermarks of each
-  /// thread alive when a thread is unscheduled.
-  int? get zoneHighWatermark;
-
-  /// The number of zone handles currently held by this isolate.
-  int? get numZoneHandles;
-
-  /// The number of scoped handles currently held by this isolate.
-  int? get numScopedHandles;
-
   /// The current pause on exception mode for this isolate.
   //ExceptionPauseMode get exceptionPauseMode;
 
diff --git a/runtime/observatory/lib/src/models/objects/thread.dart b/runtime/observatory/lib/src/models/objects/thread.dart
deleted file mode 100644
index b29d3e6..0000000
--- a/runtime/observatory/lib/src/models/objects/thread.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of models;
-
-enum ThreadKind {
-  unknownTask,
-  mutatorTask,
-  compilerTask,
-  sweeperTask,
-  markerTask,
-  finalizerTask
-}
-
-abstract class Thread {
-  /// The id associated with the thread on creation.
-  String? get id;
-
-  /// The task type associated with the thread.
-  ThreadKind? get kind;
-
-  String? get kindString;
-
-  /// The maximum amount of zone memory in bytes allocated by a thread at a
-  /// given time throughout the entire life of the thread.
-  int? get zoneHighWatermark;
-
-  /// The current Zone capacity available to this thread.
-  int? get zoneCapacity;
-}
diff --git a/runtime/observatory/lib/src/models/objects/zone.dart b/runtime/observatory/lib/src/models/objects/zone.dart
deleted file mode 100644
index 51840cb..0000000
--- a/runtime/observatory/lib/src/models/objects/zone.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of models;
-
-abstract class Zone {
-  /// The total amount of memory in bytes allocated in the zone, including
-  /// memory that is not actually being used.
-  int get capacity;
-
-  /// The total amount of memory in bytes actually used in the zone.
-  int get used;
-}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 2d9a331..63ec9c4 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -238,9 +238,6 @@
       case 'SourceLocation':
         obj = new SourceLocation._empty(owner);
         break;
-      case '_Thread':
-        obj = new Thread._empty(owner);
-        break;
       case 'UnresolvedSourceLocation':
         obj = new UnresolvedSourceLocation._empty(owner);
         break;
@@ -1617,18 +1614,6 @@
   DartError? error;
   SnapshotReader? _snapshotFetch;
 
-  List<Thread> get threads => _threads;
-  final List<Thread> _threads = <Thread>[];
-
-  int get zoneHighWatermark => _zoneHighWatermark;
-  int _zoneHighWatermark = 0;
-
-  int get numZoneHandles => _numZoneHandles;
-  int _numZoneHandles = 0;
-
-  int get numScopedHandles => _numScopedHandles;
-  int _numScopedHandles = 0;
-
   bool? isSystemIsolate;
 
   void _loadHeapSnapshot(ServiceEvent event) {
@@ -1731,23 +1716,6 @@
     if (map['extensionRPCs'] != null) {
       for (String e in map['extensionRPCs']) extensionRPCs.add(e);
     }
-
-    threads.clear();
-    if (map['_threads'] != null) {
-      for (Thread t in map['_threads']) threads.add(t);
-    }
-
-    int currentZoneHighWatermark = 0;
-    for (var i = 0; i < threads.length; i++) {
-      currentZoneHighWatermark += threads[i].zoneHighWatermark!;
-    }
-
-    if (currentZoneHighWatermark > _zoneHighWatermark) {
-      _zoneHighWatermark = currentZoneHighWatermark;
-    }
-
-    _numZoneHandles = map['_numZoneHandles'];
-    _numScopedHandles = map['_numScopedHandles'];
   }
 
   Future<TagProfile> updateTagProfile() {
@@ -3285,60 +3253,6 @@
   String get shortName => valueAsString;
 }
 
-class Thread extends ServiceObject implements M.Thread {
-  M.ThreadKind? get kind => _kind;
-  M.ThreadKind? _kind;
-  String? get kindString => _kindString;
-  String? _kindString;
-  int? get zoneHighWatermark => _zoneHighWatermark;
-  int? _zoneHighWatermark;
-  int? get zoneCapacity => _zoneCapacity;
-  int? _zoneCapacity;
-
-  Thread._empty(ServiceObjectOwner? owner) : super._empty(owner);
-
-  void _update(Map map, bool mapIsRef) {
-    String rawKind = map['kind'];
-
-    switch (rawKind) {
-      case "kUnknownTask":
-        _kind = M.ThreadKind.unknownTask;
-        _kindString = 'unknown';
-        break;
-      case "kMutatorTask":
-        _kind = M.ThreadKind.mutatorTask;
-        _kindString = 'mutator';
-        break;
-      case "kCompilerTask":
-        _kind = M.ThreadKind.compilerTask;
-        _kindString = 'compiler';
-        break;
-      case "kSweeperTask":
-        _kind = M.ThreadKind.sweeperTask;
-        _kindString = 'sweeper';
-        break;
-      case "kMarkerTask":
-        _kind = M.ThreadKind.markerTask;
-        _kindString = 'marker';
-        break;
-      default:
-        assert(false);
-    }
-
-    _zoneHighWatermark = int.parse(map['_zoneHighWatermark']);
-    _zoneCapacity = int.parse(map['_zoneCapacity']);
-  }
-}
-
-class Zone implements M.Zone {
-  int get capacity => _capacity;
-  int _capacity;
-  int get used => _used;
-  int _used;
-
-  Zone(this._capacity, this._used);
-}
-
 class Field extends HeapObject implements M.Field {
   // Library or Class.
   HeapObject? dartOwner;
diff --git a/runtime/observatory/observatory_sources.gni b/runtime/observatory/observatory_sources.gni
index e78a449..9ad1b96 100644
--- a/runtime/observatory/observatory_sources.gni
+++ b/runtime/observatory/observatory_sources.gni
@@ -183,14 +183,12 @@
   "lib/src/models/objects/source_location.dart",
   "lib/src/models/objects/subtype_test_cache.dart",
   "lib/src/models/objects/target.dart",
-  "lib/src/models/objects/thread.dart",
   "lib/src/models/objects/timeline.dart",
   "lib/src/models/objects/timeline_event.dart",
   "lib/src/models/objects/type_arguments.dart",
   "lib/src/models/objects/unknown.dart",
   "lib/src/models/objects/unlinked_call.dart",
   "lib/src/models/objects/vm.dart",
-  "lib/src/models/objects/zone.dart",
   "lib/src/models/repositories/allocation_profile.dart",
   "lib/src/models/repositories/breakpoint.dart",
   "lib/src/models/repositories/class.dart",
diff --git a/runtime/observatory/tests/service/async_single_step_exception_test.dart b/runtime/observatory/tests/service/async_single_step_exception_test.dart
index 55bd063..0fdc183 100644
--- a/runtime/observatory/tests/service/async_single_step_exception_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_exception_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/async_single_step_into_test.dart b/runtime/observatory/tests/service/async_single_step_into_test.dart
index 8d8417f..7477840 100644
--- a/runtime/observatory/tests/service/async_single_step_into_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_into_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/async_single_step_out_test.dart b/runtime/observatory/tests/service/async_single_step_out_test.dart
index 2b51e24..cfeac6c 100644
--- a/runtime/observatory/tests/service/async_single_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/async_star_single_step_into_test.dart b/runtime/observatory/tests/service/async_star_single_step_into_test.dart
index 65a784d..0d99fd5 100644
--- a/runtime/observatory/tests/service/async_star_single_step_into_test.dart
+++ b/runtime/observatory/tests/service/async_star_single_step_into_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/async_star_step_out_test.dart b/runtime/observatory/tests/service/async_star_step_out_test.dart
index fca9d16..95ca280 100644
--- a/runtime/observatory/tests/service/async_star_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_star_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/async_step_out_test.dart b/runtime/observatory/tests/service/async_step_out_test.dart
index f22f8d8..4cce826 100644
--- a/runtime/observatory/tests/service/async_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/awaiter_async_stack_contents_2_test.dart b/runtime/observatory/tests/service/awaiter_async_stack_contents_2_test.dart
index e9b971c..b2d2165 100644
--- a/runtime/observatory/tests/service/awaiter_async_stack_contents_2_test.dart
+++ b/runtime/observatory/tests/service/awaiter_async_stack_contents_2_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'package:observatory/models.dart' as M;
@@ -50,28 +50,13 @@
       print(v);
     }
 
-    if (useCausalAsyncStacks) {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(4));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:${LINE_A}']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:${LINE_B}']));
-      // Suspension point.
-      expect(awaiterFrames[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      // Causal frame.
-      expect(await awaiterFrames[3].toUserString(),
-          stringContainsInOrder(['testMain', '.dart:${LINE_C}']));
-    } else {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(2));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:${LINE_A}']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:${LINE_B}']));
-    }
+    expect(awaiterFrames.length, greaterThanOrEqualTo(2));
+    // Awaiter frame.
+    expect(await awaiterFrames[0].toUserString(),
+        stringContainsInOrder(['foobar', '.dart:${LINE_A}']));
+    // Awaiter frame.
+    expect(await awaiterFrames[1].toUserString(),
+        stringContainsInOrder(['helper', '.dart:${LINE_B}']));
   },
 ];
 
diff --git a/runtime/observatory/tests/service/awaiter_async_stack_contents_test.dart b/runtime/observatory/tests/service/awaiter_async_stack_contents_test.dart
index 0aef00e..77eeed2 100644
--- a/runtime/observatory/tests/service/awaiter_async_stack_contents_test.dart
+++ b/runtime/observatory/tests/service/awaiter_async_stack_contents_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'package:observatory/models.dart' as M;
@@ -53,29 +53,15 @@
     ServiceMap stack = await isolate.getStack();
     expect(stack['awaiterFrames'], isNotNull);
     List awaiterFrames = stack['awaiterFrames'];
-    if (useCausalAsyncStacks) {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(4));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:$LINE_C']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:$LINE_D']));
-      // Suspension point.
-      expect(awaiterFrames[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      // Causal frame.
-      expect(await awaiterFrames[3].toUserString(),
-          stringContainsInOrder(['testMain', '.dart:$LINE_B']));
-    } else {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(2));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:$LINE_C']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:$LINE_D']));
-      // "helper" is not await'ed.
-    }
+
+    expect(awaiterFrames.length, greaterThanOrEqualTo(2));
+    // Awaiter frame.
+    expect(await awaiterFrames[0].toUserString(),
+        stringContainsInOrder(['foobar', '.dart:$LINE_C']));
+    // Awaiter frame.
+    expect(await awaiterFrames[1].toUserString(),
+        stringContainsInOrder(['helper', '.dart:$LINE_D']));
+    // "helper" is not await'ed.
   },
 ];
 
diff --git a/runtime/observatory/tests/service/causal_async_stack_contents_test.dart b/runtime/observatory/tests/service/causal_async_stack_contents_test.dart
index ed77ae6..3e4a8eb 100644
--- a/runtime/observatory/tests/service/causal_async_stack_contents_test.dart
+++ b/runtime/observatory/tests/service/causal_async_stack_contents_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory/models.dart' as M;
@@ -48,14 +48,8 @@
     // Has causal frames (we are inside an async function)
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack[0].toString(), contains('helper'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[2].toString(), contains('testMain'));
-    } else {
-      expect(asyncStack[0].toString(), contains('helper'));
-      // "helper" is not await'ed.
-    }
+    expect(asyncStack[0].toString(), contains('helper'));
+    // "helper" is not await'ed.
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
@@ -65,19 +59,9 @@
     // Has causal frames (we are inside a function called by an async function)
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].toString(), contains('helper'));
-      expect(asyncStack[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[3].toString(), contains('testMain'));
-      expect(await asyncStack[0].location.toUserString(), contains('.dart:20'));
-      expect(await asyncStack[1].location.toUserString(), contains('.dart:27'));
-      expect(await asyncStack[3].location.toUserString(), contains('.dart:32'));
-    } else {
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].toString(), contains('helper'));
-      // "helper" is not await'ed.
-    }
+    expect(asyncStack[0].toString(), contains('foobar'));
+    expect(asyncStack[1].toString(), contains('helper'));
+    // "helper" is not await'ed.
   },
 ];
 
diff --git a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
index 0e57f47..3a90e4a 100644
--- a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
+++ b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
diff --git a/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart b/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart
index 8efcecc..8d66a17a 100644
--- a/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart
+++ b/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory/models.dart' as M;
@@ -44,16 +44,9 @@
     // No causal frames because we are in a completely synchronous stack.
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack.length, greaterThanOrEqualTo(3));
-      expect(asyncStack[0].toString(), contains('helper'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[2].toString(), contains('testMain'));
-    } else {
-      expect(asyncStack.length, greaterThanOrEqualTo(1));
-      expect(asyncStack[0].toString(), contains('helper'));
-      // helper isn't awaited.
-    }
+    expect(asyncStack.length, greaterThanOrEqualTo(1));
+    expect(asyncStack[0].toString(), contains('helper'));
+    // helper isn't awaited.
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
@@ -68,10 +61,6 @@
     expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
     expect(asyncStack[2].toString(), contains('helper'));
     expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
-    if (useCausalAsyncStacks) {
-      // helper isn't awaited.
-      expect(asyncStack[4].toString(), contains('testMain'));
-    }
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
@@ -93,12 +82,6 @@
     expect(asyncStack[2].toString(), contains('helper'));
     expect(await asyncStack[2].location.toUserString(), contains('.dart:30'));
     expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
-    if (useCausalAsyncStacks) {
-      // helper isn't awaited.
-      expect(asyncStack.length, greaterThanOrEqualTo(5));
-      expect(asyncStack[4].toString(), contains('testMain'));
-      expect(await asyncStack[4].location.toUserString(), contains('.dart:36'));
-    }
   },
 ];
 
diff --git a/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
index df29834..4d3e448 100644
--- a/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
+++ b/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
diff --git a/runtime/observatory/tests/service/get_isolate_rpc_test.dart b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
index 14a1f09..e1a60ba 100644
--- a/runtime/observatory/tests/service/get_isolate_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
@@ -25,8 +25,6 @@
     expect(result['pauseOnExit'], isFalse);
     expect(result['pauseEvent']['type'], equals('Event'));
     expect(result['error'], isNull);
-    expect(result['_numZoneHandles'], isPositive);
-    expect(result['_numScopedHandles'], isPositive);
     expect(result['rootLib']['type'], equals('@Library'));
     expect(result['libraries'].length, isPositive);
     expect(result['libraries'][0]['type'], equals('@Library'));
diff --git a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
index 05950a1..c2abb01 100644
--- a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
@@ -21,6 +21,8 @@
 dynamic target3 = new _TestClass();
 dynamic target4 = new _TestClass();
 dynamic target5 = new _TestClass();
+dynamic target6 = new _TestClass();
+Expando<_TestClass> expando = Expando<_TestClass>();
 @pragma("vm:entry-point") // Prevent obfuscation
 dynamic globalObject = new _TestClass();
 @pragma("vm:entry-point") // Prevent obfuscation
@@ -77,6 +79,15 @@
 }
 
 @pragma("vm:entry-point")
+takeExpandoTarget() {
+  var tmp = target6;
+  target6 = null;
+  var tmp2 = _TestClass();
+  expando[tmp] = tmp2;
+  return tmp2;
+}
+
+@pragma("vm:entry-point")
 getTrue() => true;
 
 invoke(Isolate isolate, String selector) async {
@@ -192,6 +203,23 @@
     expect(result['elements'][2]['value']['name'], equals('globalMap2'));
   },
 
+  (Isolate isolate) async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/44016
+    var target6 = await invoke(isolate, 'takeExpandoTarget');
+    var params = {
+      'targetId': target6['id'],
+      'limit': 100,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getRetainingPath', params);
+    expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(5));
+    expect(result['elements'][1]['parentMapKey']['class']['name'],
+        equals('_TestClass'));
+    expect(result['elements'][2]['parentListIndex'], isNotNull);
+    expect(result['elements'][3]['value']['class']['name'], 'Expando');
+    expect(result['elements'][4]['value']['name'], 'expando');
+  },
+
   // object store
   (Isolate isolate) async {
     var obj = await invoke(isolate, 'getTrue');
diff --git a/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart b/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart
new file mode 100644
index 0000000..b0f078d
--- /dev/null
+++ b/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "get_source_report_const_coverage_test.dart";
+
+void testFunction() {
+  const namedFoo = Foo.named3();
+  const namedFoo2 = Foo.named3();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print("namedIdentical: $namedIdentical");
+}
diff --git a/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart b/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart
new file mode 100644
index 0000000..32cb035
--- /dev/null
+++ b/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+import 'dart:developer';
+
+import 'get_source_report_const_coverage_lib.dart' as lib;
+
+const String filename = "get_source_report_const_coverage_test";
+const Set<int> expectedLinesHit = {20, 22, 26};
+const Set<int> expectedLinesNotHit = {24};
+
+class Foo {
+  final int x;
+  // Expect this constructor to be coverage by coverage.
+  const Foo([int? x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too.
+  const Foo.named1([int? x]) : this.x = x ?? 42;
+  // Expect this constructor to *NOT* be coverage by coverage.
+  const Foo.named2([int? x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too (from lib).
+  const Foo.named3([int? x]) : this.x = x ?? 42;
+}
+
+void testFunction() {
+  const foo = Foo();
+  const foo2 = Foo();
+  const fooIdentical = identical(foo, foo2);
+  print(fooIdentical);
+
+  const namedFoo = Foo.named1();
+  const namedFoo2 = Foo.named1();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print(fooIdentical);
+
+  debugger();
+
+  // That this is called after (or at all) is not relevent for the code
+  // coverage of constants.
+  lib.testFunction();
+
+  print("Done");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    final stack = await isolate.getStack();
+
+    // Make sure we are in the right place.
+    expect(stack.type, equals('Stack'));
+    expect(stack['frames'].length, greaterThanOrEqualTo(1));
+    expect(stack['frames'][0].function.name, equals('testFunction'));
+
+    final List<Script> scripts = await isolate.getScripts();
+    Script? foundScript;
+    for (Script script in scripts) {
+      if (script.uri.contains(filename)) {
+        foundScript = script;
+        break;
+      }
+    }
+
+    Set<int> hits;
+    {
+      // Get report for everything; then collect for this library.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      hits = getHitsFor(coverage, filename);
+      await foundScript!.load();
+      final Set<int> lines = {};
+      for (int hit in hits) {
+        // We expect every hit to be translatable to line
+        // (i.e. tokenToLine to return non-null).
+        lines.add(foundScript.tokenToLine(hit)!);
+      }
+      print("Token position hits: $hits --- line hits: $lines");
+      expect(lines.intersection(expectedLinesHit), equals(expectedLinesHit));
+      expect(lines.intersection(expectedLinesNotHit), isEmpty);
+    }
+    {
+      // Now get report for the this file only.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+        'scriptId': foundScript.id!
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      final Set<int> localHits = getHitsFor(coverage, filename);
+      expect(localHits.length, equals(hits.length));
+      expect(hits.toList()..sort(), equals(localHits.toList()..sort()));
+      print(localHits);
+    }
+  },
+];
+
+Set<int> getHitsFor(Map coverage, String uriContains) {
+  final List scripts = coverage["scripts"];
+  final Set<int> scriptIdsWanted = {};
+  for (int i = 0; i < scripts.length; i++) {
+    final Map script = scripts[i];
+    final String scriptUri = script["uri"];
+    if (scriptUri.contains(uriContains)) {
+      scriptIdsWanted.add(i);
+    }
+  }
+  final List ranges = coverage["ranges"];
+  final Set<int> hits = {};
+  for (int i = 0; i < ranges.length; i++) {
+    final Map range = ranges[i];
+    if (scriptIdsWanted.contains(range["scriptIndex"])) {
+      if (range["coverage"] != null) {
+        for (int hit in range["coverage"]["hits"]) {
+          hits.add(hit);
+        }
+      }
+    }
+  }
+  return hits;
+}
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index adea481..a1d5206 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -91,7 +91,7 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    expect(numRanges, equals(10));
+    expect(numRanges, equals(11));
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -106,7 +106,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, 11);
+    expect(coverage['ranges'].length, 12);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart b/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
index 99a8bf1..b1ccb4f 100644
--- a/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+// VMOptions=--lazy-async-stacks
 
 import 'dart:async';
 import 'dart:developer';
@@ -13,31 +13,29 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
-bar(int depth) {
+bar(int depth) async {
   if (depth == 21) {
     debugger();
     return;
   }
-  foo(depth + 1);
+  await foo(depth + 1);
 }
 
-foo(int depth) {
-  bar(depth + 1);
+foo(int depth) async {
+  if (depth == 10) {
+    // Yield once to force the rest to run async.
+    await 0;
+  }
+  await bar(depth + 1);
 }
 
-testMain() {
-  foo(0);
+testMain() async {
+  await foo(0);
 }
 
-verifyStack(List frames, int numFrames) {
-  for (int i = 0; i < frames.length && i < numFrames; ++i) {
-    final frame = frames[i];
-    if (i < 22) {
-      expect(frame.function!.qualifiedName, (i % 2) == 0 ? 'bar' : 'foo');
-    } else if (i == 22) {
-      expect(frame.function!.qualifiedName, 'testMain');
-      break;
-    }
+verifyStack(List frames, List<String> expectedNames) {
+  for (int i = 0; i < frames.length && i < expectedNames.length; ++i) {
+    expect(frames[i].function!.qualifiedName, expectedNames[i]);
   }
 }
 
@@ -57,10 +55,14 @@
     var awaiterFrames = stack['awaiterFrames'];
     expect(frames.length, greaterThanOrEqualTo(20));
     expect(asyncFrames.length, greaterThan(frames.length));
-    expect(awaiterFrames.length, greaterThan(frames.length));
+    expect(awaiterFrames.length, 13);
     expect(stack['truncated'], false);
-
-    verifyStack(frames, frames.length);
+    verifyStack(frames, [
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      '_RootZone.runUnary', // Internal async. mech. ..
+    ]);
 
     final fullStackLength = frames.length;
 
@@ -75,7 +77,12 @@
     expect(asyncFrames.length, fullStackLength + 1);
     expect(asyncFrames.length, fullStackLength + 1);
     expect(stack['truncated'], true);
-    verifyStack(frames, fullStackLength);
+    verifyStack(frames, [
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      '_RootZone.runUnary', // Internal async. mech. ..
+    ]);
 
     // Try a limit < actual stack depth and expect to get a stack of depth
     // 'limit'.
@@ -88,7 +95,18 @@
     expect(asyncFrames.length, 10);
     expect(awaiterFrames.length, 10);
     expect(stack['truncated'], true);
-    verifyStack(frames, 10);
+    verifyStack(frames, [
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+    ]);
   },
 // Invalid limit
   (Isolate isolate) async {
diff --git a/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart b/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
deleted file mode 100644
index 3de0b1d..0000000
--- a/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-
-import 'test_helper.dart';
-
-var tests = <VMTest>[
-  (VM vm) async {
-    // Just iterate over all the isolates to confirm they have
-    // the correct fields needed to examine zone memory usage.
-    for (Isolate isolate in new List.from(vm.isolates)) {
-      await isolate.reload();
-      expect(isolate.zoneHighWatermark, isA<int>());
-      expect(isolate.threads, isNotNull);
-      List<Thread> threads = isolate.threads;
-
-      for (Thread thread in threads) {
-        expect(thread.type, equals('_Thread'));
-        expect(thread.id, isNotNull);
-        expect(thread.kind, isNotNull);
-        expect(thread.zoneHighWatermark, isA<int>());
-        expect(thread.zoneCapacity, isA<int>());
-      }
-    }
-  },
-];
-
-main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart b/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
index 3bbc12e..8aae0aa 100644
--- a/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
@@ -70,8 +70,6 @@
     Expect.isFalse(result['pauseOnExit']);
     Expect.equals(result['pauseEvent']['type'], 'Event');
     Expect.isNull(result['error']);
-    Expect.isTrue(result['_numZoneHandles'] > 0);
-    Expect.isTrue(result['_numScopedHandles'] > 0);
     Expect.equals(result['rootLib']['type'], '@Library');
     Expect.isTrue(result['libraries'].length > 0);
     Expect.equals(result['libraries'][0]['type'], '@Library');
diff --git a/runtime/observatory/tests/service/next_through_simple_async_test.dart b/runtime/observatory/tests/service/next_through_simple_async_test.dart
index 5a3ac87..bc2c3d5 100644
--- a/runtime/observatory/tests/service/next_through_simple_async_test.dart
+++ b/runtime/observatory/tests/service/next_through_simple_async_test.dart
@@ -1,19 +1,17 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'test_helper.dart';
 import 'service_test_common.dart';
 import 'dart:io';
 
-const int LINE_A = 16;
+const int LINE_A = 14;
 const String file = "next_through_simple_async_test.dart";
 
-// line A is at the "code() async" line
-code() async {
+code() async {  // LINE_A
   File f = new File(Platform.script.toFilePath());
   DateTime modified = await f.lastModified();
   bool exists = await f.exists();
diff --git a/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart b/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
index 68dca68..9a3f234 100644
--- a/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
+++ b/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
@@ -1,19 +1,17 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'test_helper.dart';
 import 'service_test_common.dart';
 import 'dart:io';
 
-const int LINE_A = 16;
+const int LINE_A = 14;
 const String file = "next_through_simple_async_with_returns_test.dart";
 
-// line A is at the "code() async" line
-code() async {
+code() async {  // LINE_A
   File f = new File(Platform.script.toFilePath());
   bool exists = await f.exists();
   if (exists) {
diff --git a/runtime/observatory/tests/service/pause_on_exception_from_slow_path_test.dart b/runtime/observatory/tests/service/pause_on_exception_from_slow_path_test.dart
new file mode 100644
index 0000000..4b64380
--- /dev/null
+++ b/runtime/observatory/tests/service/pause_on_exception_from_slow_path_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--deterministic --optimization-counter-threshold=1000
+
+import 'dart:convert';
+
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+class X {
+  late String _y;
+
+  @pragma('vm:never-inline')
+  String get y => _y;
+}
+
+testeeMain() async {
+  final x = X();
+  x._y = "";
+  for (var i = 0; i < 2000; i++) x.y;
+
+  X().y;
+}
+
+var tests = <IsolateTest>[
+  hasStoppedWithUnhandledException,
+  (Isolate isolate) async {
+    print("We stopped!");
+    var stack = await isolate.getStack();
+  }
+];
+
+main(args) => runIsolateTests(args, tests,
+    pause_on_unhandled_exceptions: true,
+    testeeConcurrent: testeeMain,
+    extraArgs: extraDebuggingArgs);
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart
index e922a19..67f6901 100644
--- a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart
+++ b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart
@@ -1,10 +1,9 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async_debugger --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async_debugger --causal-async-stacks --no-lazy-async-stacks
-// VMOptions=--async_debugger --no-causal-async-stacks --lazy-async-stacks --optimization-counter-threshold=5
-// VMOptions=--async_debugger --causal-async-stacks --no-lazy-async-stacks --optimization-counter-threshold=5
+//
+// VMOptions=--async_debugger --lazy-async-stacks
+// VMOptions=--async_debugger --lazy-async-stacks --optimization-counter-threshold=5
 
 import 'package:observatory/service_io.dart';
 import 'package:observatory/models.dart' as M;
@@ -12,12 +11,12 @@
 import 'test_helper.dart';
 import 'service_test_common.dart';
 
-const LINE_A = 37;
+const LINE_A = 36;
 
 class Foo {}
 
 doThrow() {
-  throw "TheException"; // Line 13.
+  throw "TheException";
   return "end of doThrow";
 }
 
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions_test.dart
index 05cf750..fe636dd 100644
--- a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions_test.dart
+++ b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async_debugger --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async_debugger --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async_debugger --lazy-async-stacks
 
 import 'package:observatory/service_io.dart';
 import 'package:observatory/models.dart' as M;
@@ -15,7 +15,7 @@
 class Foo {}
 
 doThrow() {
-  throw "TheException"; // Line 13.
+  throw "TheException";
   return "end of doThrow";
 }
 
@@ -45,21 +45,10 @@
     var stack = await isolate.getStack();
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack.length, greaterThanOrEqualTo(4));
-      expect(asyncStack[0].toString(), contains('doThrow'));
-      expect(asyncStack[1].toString(), contains('asyncThrower'));
-      expect(asyncStack[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[3].toString(), contains('testeeMain'));
-      // We've stopped at LINE_A.
-      expect(await asyncStack[3].location.toUserString(),
-          contains('.dart:$LINE_A'));
-    } else {
-      expect(asyncStack.length, greaterThanOrEqualTo(2));
-      expect(asyncStack[0].toString(), contains('doThrow'));
-      expect(asyncStack[1].toString(), contains('asyncThrower'));
-      // There was no await'er for "doThrow()".
-    }
+    expect(asyncStack.length, greaterThanOrEqualTo(2));
+    expect(asyncStack[0].toString(), contains('doThrow'));
+    expect(asyncStack[1].toString(), contains('asyncThrower'));
+    // There was no await'er for "doThrow()".
   }
 ];
 
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 8c09f06..59145d2 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -39,157 +39,160 @@
 pause_on_unhandled_async_exceptions2_test: Pass, Slow
 
 [ $compiler == dartkp ]
-add_breakpoint_rpc_kernel_test: SkipByDesign
-async_generator_breakpoint_test: SkipByDesign
-async_next_regession_18877_test: Skip, Timeout
-async_next_test: Skip, Timeout
-async_scope_test: Skip, Timeout
-async_single_step_exception_test: Skip, Timeout
-async_single_step_into_test: Skip, Timeout
-async_single_step_out_test: Skip, Timeout
-async_star_single_step_into_test: Skip, Timeout
-async_star_step_out_test: Skip, Timeout
-async_step_out_test: Skip, Timeout
-awaiter_async_stack_contents_2_test: Skip, Timeout
-awaiter_async_stack_contents_test: Skip, Timeout
-bad_reload_test: SkipByDesign
-break_on_activation_test: SkipByDesign
-break_on_async_function_test: Skip, Timeout
-break_on_default_constructor_test: SkipByDesign
-break_on_function_test: Skip, Timeout
-breakpoint_async_break_test: SkipByDesign
-breakpoint_in_package_parts_class_file_uri_test: SkipByDesign
-breakpoint_in_package_parts_class_test: SkipByDesign
-breakpoint_in_parts_class_test: SkipByDesign
-breakpoint_non_debuggable_library_test: SkipByDesign
-breakpoint_on_if_null_1_test: SkipByDesign
-breakpoint_on_if_null_2_test: SkipByDesign
-breakpoint_on_if_null_3_test: SkipByDesign
-breakpoint_on_if_null_4_test: SkipByDesign
-breakpoint_partfile_test: SkipByDesign
-breakpoint_two_args_checked_test: Skip, Timeout
+add_breakpoint_rpc_kernel_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_generator_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_next_regession_18877_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_next_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_single_step_exception_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_single_step_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_star_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_star_step_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_step_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+awaiter_async_stack_contents_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+awaiter_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode.
+bad_reload_test: SkipByDesign # Hot reload is disabled in AOT mode.
+break_on_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_async_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_default_constructor_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_async_break_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_in_package_parts_class_file_uri_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_in_package_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_in_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_non_debuggable_library_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_1_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_3_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_4_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_partfile_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_two_args_checked_test: SkipByDesign # Debugger is disabled in AOT mode.
 breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
-capture_stdio_test: Skip, Timeout
-causal_async_stack_contents_test: Skip, Timeout
-causal_async_stack_presence_test: Skip, Timeout
-causal_async_star_stack_contents_test: Skip, Timeout
-causal_async_star_stack_presence_test: Skip, Timeout
-client_resume_approvals_reload_test: SkipByDesign # Compiler is disabled in AOT mode.
-code_test: SkipByDesign
-column_breakpoint_test: SkipByDesign
-complex_reload_test: SkipByDesign
-coverage_const_field_async_closure_test: Skip, Timeout
-coverage_leaf_function_test: Skip, Timeout
-coverage_optimized_function_test: Skip, Timeout
-dds_log_history_size_*: Skip, Timeout
-debugger_inspect_test: SkipByDesign
-debugger_location_second_test: Skip, Timeout
-debugger_location_test: Skip, Timeout
-debugging_inlined_finally_test: Skip, Timeout
-debugging_test: SkipByDesign
-dev_fs_spawn_test: SkipByDesign
-developer_extension_test: Skip, Timeout
-developer_service_get_isolate_id_test: Skip, Timeout
-eval_internal_class_test: SkipByDesign
-eval_regression_flutter20255_test: Skip, Timeout
-eval_test: Skip, Timeout
-evaluate_activation_in_method_class_test: Skip, Timeout
+capture_stdio_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_star_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_star_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode.
+client_resume_approvals_reload_test: SkipByDesign # Debugger is disabled in AOT mode.
+code_test: SkipByDesign # Debugger is disabled in AOT mode.
+column_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode.
+complex_reload_test: SkipByDesign # Debugger is disabled in AOT mode.
+coverage_const_field_async_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
+coverage_leaf_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+coverage_optimized_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+dds_log_history_size_*: SkipByDesign # Debugger is disabled in AOT mode.
+debugger_inspect_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugger_location_second_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugger_location_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugging_inlined_finally_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugging_test: SkipByDesign # Debugger is disabled in AOT mode.
+dev_fs_spawn_test: SkipByDesign # Debugger is disabled in AOT mode.
+developer_extension_test: SkipByDesign # Debugger is disabled in AOT mode.
+developer_service_get_isolate_id_test: SkipByDesign # Debugger is disabled in AOT mode.
+eval_internal_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+eval_regression_flutter20255_test: SkipByDesign # Debugger is disabled in AOT mode.
+eval_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_activation_in_method_class_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_activation_test: SkipByDesign
 evaluate_async_closure_test: SkipByDesign
-evaluate_class_type_parameters_test: Skip, Timeout
-evaluate_function_type_parameters_test: Skip, Timeout
-evaluate_in_async_activation_test: Skip, Timeout
-evaluate_in_async_star_activation_test: Skip, Timeout
-evaluate_in_frame_rpc_test: Skip, Timeout
-evaluate_in_frame_with_scope_test: Skip, Timeout
-evaluate_in_sync_star_activation_test: Skip, Timeout
-evaluate_with_escaping_closure_test: SkipByDesign
-evaluate_with_scope_test: SkipByDesign
-field_script_test: SkipByDesign
-get_allocation_samples_test: Skip, Timeout
+evaluate_class_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_function_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_async_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_async_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_frame_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_frame_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_sync_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_with_escaping_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
+field_script_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_allocation_samples_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_isolate_after_language_error_test: CompileTimeError
-get_object_rpc_test: SkipByDesign
-get_source_report_test: Skip, Timeout
-get_source_report_with_mixin_test: Skip, Timeout
-get_stack_limit_rpc_test: Skip, Timeout
-get_stack_rpc_test: Skip, Timeout
-implicit_getter_setter_test: SkipByDesign
-invoke_test: Skip, Timeout
-isolate_lifecycle_test: SkipByDesign
-issue_25465_test: SkipByDesign
-issue_27238_test: Skip, Timeout
-issue_27287_test: Skip, Timeout
-issue_30555_test: SkipByDesign
-kill_paused_test: Skip, Timeout
+get_object_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_const_coverage_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_stack_limit_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_stack_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+implicit_getter_setter_test: SkipByDesign # Debugger is disabled in AOT mode.
+invoke_test: SkipByDesign # Debugger is disabled in AOT mode.
+isolate_lifecycle_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_25465_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_27238_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_27287_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_30555_test: SkipByDesign # Debugger is disabled in AOT mode.
+kill_paused_test: SkipByDesign # Debugger is disabled in AOT mode.
 library_dependency_test: CompileTimeError
-local_variable_declaration_test: Skip, Timeout
-local_variable_in_awaiter_async_frame_test: Skip, Timeout
-logging_test: Skip, Timeout
+local_variable_declaration_test: SkipByDesign # Debugger is disabled in AOT mode.
+local_variable_in_awaiter_async_frame_test: SkipByDesign # Debugger is disabled in AOT mode.
+logging_test: SkipByDesign # Debugger is disabled in AOT mode.
 mirror_references_test: CompileTimeError
-mixin_break_test: Skip, Timeout
-network_profiling_test: Skip, Timeout
-next_through_assign_call_test: SkipByDesign
-next_through_assign_int_test: SkipByDesign
-next_through_await_for_test: SkipByDesign
-next_through_call_on_field_in_class_test: SkipByDesign
-next_through_call_on_field_test: SkipByDesign
-next_through_call_on_static_field_in_class_test: SkipByDesign
-next_through_catch_test: SkipByDesign
-next_through_closure_test: SkipByDesign
-next_through_create_list_and_map_test: SkipByDesign
-next_through_for_each_loop_test: SkipByDesign
-next_through_for_loop_with_break_and_continue_test: SkipByDesign
-next_through_function_expression_test: SkipByDesign
-next_through_implicit_call_test: SkipByDesign
-next_through_is_and_as_test: SkipByDesign
-next_through_multi_catch_test: SkipByDesign
-next_through_new_test: SkipByDesign
-next_through_operator_bracket_on_super_test: SkipByDesign
-next_through_operator_bracket_on_this_test: SkipByDesign
-next_through_operator_bracket_test: SkipByDesign
-next_through_simple_async_test: SkipByDesign
-next_through_simple_async_with_returns_test: SkipByDesign
-next_through_simple_linear_2_test: SkipByDesign
-next_through_simple_linear_test: SkipByDesign
-parameters_in_scope_at_entry_test: Skip, Timeout
-pause_idle_isolate_test: Skip, Timeout
-pause_on_exceptions_test: SkipByDesign
-pause_on_start_then_step_test: SkipByDesign
-pause_on_unhandled_async_exceptions2_test: SkipByDesign
-pause_on_unhandled_async_exceptions3_test: SkipByDesign
-pause_on_unhandled_async_exceptions_test: SkipByDesign
-pause_on_unhandled_exceptions_test: SkipByDesign
-positive_token_pos_test: Skip, Timeout
-regress_28443_test: SkipByDesign
-regress_28980_test: SkipByDesign
-regress_34841_test: Skip, Timeout
-reload_sources_test: Skip, Timeout
-rewind_optimized_out_test: Skip, Timeout
-rewind_test: Skip, Timeout
-set_library_debuggable_test: Skip, Timeout
-simple_reload_test: SkipByDesign
-steal_breakpoint_test: SkipByDesign
-step_into_async_no_await_test: Skip, Timeout
-step_over_await_test: Skip, Timeout
-step_test: SkipByDesign
-step_through_arithmetic_test: SkipByDesign
-step_through_constructor_calls_test: SkipByDesign
-step_through_constructor_test: SkipByDesign
-step_through_for_each_sync_star_2_test: SkipByDesign
-step_through_for_each_sync_star_test: SkipByDesign
-step_through_function_2_test: SkipByDesign
-step_through_function_test: SkipByDesign
-step_through_getter_test: SkipByDesign
-step_through_mixin_from_sdk_test: SkipByDesign
-step_through_property_get_test: SkipByDesign
-step_through_property_set_test: SkipByDesign
-step_through_setter_test: SkipByDesign
-step_through_switch_test: SkipByDesign
-step_through_switch_with_continue_test: SkipByDesign
-valid_source_locations_test: Skip, Timeout
-vm_timeline_flags_test: Skip, Timeout
+mixin_break_test: SkipByDesign # Debugger is disabled in AOT mode.
+network_profiling_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_assign_call_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_assign_int_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_await_for_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_call_on_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_call_on_field_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_call_on_static_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_catch_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_create_list_and_map_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_for_each_loop_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_for_loop_with_break_and_continue_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_function_expression_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_implicit_call_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_is_and_as_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_multi_catch_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_new_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_operator_bracket_on_super_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_operator_bracket_on_this_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_operator_bracket_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_async_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_async_with_returns_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_linear_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_linear_test: SkipByDesign # Debugger is disabled in AOT mode.
+parameters_in_scope_at_entry_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_idle_isolate_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_exception_from_slow_path_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_start_then_step_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_async_exceptions2_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_async_exceptions3_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_async_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode.
+positive_token_pos_test: SkipByDesign # Debugger is disabled in AOT mode.
+regress_28443_test: SkipByDesign # Debugger is disabled in AOT mode.
+regress_28980_test: SkipByDesign # Debugger is disabled in AOT mode.
+regress_34841_test: SkipByDesign # Debugger is disabled in AOT mode.
+reload_sources_test: SkipByDesign # Debugger is disabled in AOT mode.
+rewind_optimized_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+rewind_test: SkipByDesign # Debugger is disabled in AOT mode.
+set_library_debuggable_test: SkipByDesign # Debugger is disabled in AOT mode.
+simple_reload_test: SkipByDesign # Hot reload is disabled in AOT mode.
+steal_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_into_async_no_await_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_over_await_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_arithmetic_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_constructor_calls_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_constructor_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_for_each_sync_star_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_for_each_sync_star_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_function_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_getter_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_mixin_from_sdk_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_property_get_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_property_set_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_setter_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_switch_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_switch_with_continue_test: SkipByDesign # Debugger is disabled in AOT mode.
+valid_source_locations_test: SkipByDesign # Debugger is disabled in AOT mode.
+validate_timer_port_behavior_test: SkipByDesign # Debugger is disabled in AOT mode.
+vm_timeline_flags_test: SkipByDesign # Debugger is disabled in AOT mode.
 weak_properties_test: CompileTimeError
-yield_positions_with_finally_test: SkipByDesign
+yield_positions_with_finally_test: SkipByDesign # Debugger is disabled in AOT mode.
 
 [ $fasta ]
 get_isolate_after_language_error_test: CompileTimeError
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 805e7fe..3143df6d 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -13,17 +13,11 @@
 import 'service_test_common.dart';
 export 'service_test_common.dart' show DDSTest, IsolateTest, VMTest;
 
-/// Whether to use causal async stacks (if not we use lazy async stacks).
-const bool useCausalAsyncStacks =
-    const bool.fromEnvironment('dart.developer.causal_async_stacks');
-
 /// Determines whether DDS is enabled for this test run.
 const bool useDds = const bool.fromEnvironment('USE_DDS');
 
 /// The extra arguments to use
-const List<String> extraDebuggingArgs = useCausalAsyncStacks
-    ? const ['--causal-async-stacks', '--no-lazy-async-stacks']
-    : const ['--no-causal-async-stacks', '--lazy-async-stacks'];
+const List<String> extraDebuggingArgs = ['--lazy-async-stacks'];
 
 /// Will be set to the http address of the VM's service protocol before
 /// any tests are invoked.
diff --git a/runtime/observatory/tests/service/validate_timer_port_behavior_test.dart b/runtime/observatory/tests/service/validate_timer_port_behavior_test.dart
new file mode 100644
index 0000000..ae40cb2
--- /dev/null
+++ b/runtime/observatory/tests/service/validate_timer_port_behavior_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:developer';
+import 'dart:isolate' hide Isolate;
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+void warmup() {
+  Timer timer = Timer(const Duration(days: 30), () => null);
+  debugger();
+  timer.cancel();
+  debugger();
+  timer = Timer(const Duration(days: 30), () => null);
+  debugger();
+  timer.cancel();
+}
+
+late Set<int> originalPortIds;
+late int timerPortId;
+
+final tests = <IsolateTest>[
+  hasPausedAtStart,
+  (Isolate isolate) async {
+    final originalPorts =
+        (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    originalPortIds = {
+      for (int i = 0; i < originalPorts.length; ++i) originalPorts[i]['portId'],
+    };
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Determine the ID of the timer port.
+    final ports = (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    timerPortId = ports
+        .firstWhere((p) => !originalPortIds.contains(p['portId']))['portId'];
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // After cancelling the timer, there should be no active timers left.
+    // The timer port should be inactive and not reported.
+    final ports = (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    for (final port in ports) {
+      if (port['portId'] == timerPortId) {
+        fail('Timer port should no longer be active');
+      }
+    }
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // After setting a new timer, the timer port should be active and have the same
+    // port ID as before as the original port is still being used.
+    final ports = (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    bool foundTimerPort = false;
+    for (final port in ports) {
+      if (port['portId'] == timerPortId) {
+        foundTimerPort = true;
+        break;
+      }
+    }
+    expect(foundTimerPort, true);
+  },
+];
+
+main(args) async => runIsolateTests(args, tests,
+    pause_on_start: true, testeeConcurrent: warmup);
diff --git a/runtime/observatory_2/lib/models.dart b/runtime/observatory_2/lib/models.dart
index 9ea69d9..101d0c7 100644
--- a/runtime/observatory_2/lib/models.dart
+++ b/runtime/observatory_2/lib/models.dart
@@ -50,14 +50,12 @@
 part 'src/models/objects/source_location.dart';
 part 'src/models/objects/subtype_test_cache.dart';
 part 'src/models/objects/target.dart';
-part 'src/models/objects/thread.dart';
 part 'src/models/objects/timeline.dart';
 part 'src/models/objects/timeline_event.dart';
 part 'src/models/objects/type_arguments.dart';
 part 'src/models/objects/unknown.dart';
 part 'src/models/objects/unlinked_call.dart';
 part 'src/models/objects/vm.dart';
-part 'src/models/objects/zone.dart';
 
 part 'src/models/repositories/allocation_profile.dart';
 part 'src/models/repositories/breakpoint.dart';
diff --git a/runtime/observatory_2/lib/src/elements/isolate_view.dart b/runtime/observatory_2/lib/src/elements/isolate_view.dart
index 269f207..59104c9 100644
--- a/runtime/observatory_2/lib/src/elements/isolate_view.dart
+++ b/runtime/observatory_2/lib/src/elements/isolate_view.dart
@@ -116,7 +116,6 @@
   void render() {
     final uptime = new DateTime.now().difference(_isolate.startTime);
     final libraries = _isolate.libraries.toList();
-    final List<M.Thread> threads = _isolate.threads;
     children = <Element>[
       navBar(<Element>[
         new NavTopMenuElement(queue: _r.queue).element,
@@ -261,26 +260,6 @@
                 ..children = <Element>[
                   new DivElement()
                     ..classes = ['memberName']
-                    ..text = 'allocated zone handle count',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..text = '${_isolate.numZoneHandles}'
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'allocated scoped handle count',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..text = '${_isolate.numScopedHandles}'
-                ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
                     ..text = 'object store',
                   new DivElement()
                     ..classes = ['memberValue']
@@ -289,19 +268,6 @@
                         ..text = 'object store'
                     ]
                 ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'zone capacity high watermark'
-                    ..title = '''The maximum amount of native zone memory
-                    allocated by the isolate over it\'s life.''',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..text = Utils.formatSize(_isolate.zoneHighWatermark)
-                    ..title = '${_isolate.zoneHighWatermark}B'
-                ],
               new BRElement(),
               new DivElement()
                 ..classes = ['memberItem']
@@ -324,21 +290,6 @@
                           .element
                     ]
                 ],
-              new DivElement()
-                ..classes = ['memberItem']
-                ..children = <Element>[
-                  new DivElement()
-                    ..classes = ['memberName']
-                    ..text = 'threads (${threads.length})',
-                  new DivElement()
-                    ..classes = ['memberValue']
-                    ..children = <Element>[
-                      (new CurlyBlockElement(queue: _r.queue)
-                            ..content =
-                                threads.map<Element>(_populateThreadInfo))
-                          .element
-                    ]
-                ]
             ],
           new HRElement(),
           new EvalBoxElement(_isolate, _isolate.rootLibrary, _objects, _eval,
@@ -360,31 +311,6 @@
     ];
   }
 
-  DivElement _populateThreadInfo(M.Thread t) {
-    return new DivElement()
-      ..classes = ['indent']
-      ..children = <Element>[
-        new SpanElement()..text = '${t.id} ',
-        (new CurlyBlockElement(queue: _r.queue)
-              ..content = <Element>[
-                new DivElement()
-                  ..classes = ['indent']
-                  ..text = 'kind ${t.kindString}',
-                new DivElement()
-                  ..classes = ['indent']
-                  ..title = '${t.zoneHighWatermark}B'
-                  ..text = 'zone capacity high watermark '
-                      '${Utils.formatSize(t.zoneHighWatermark)}',
-                new DivElement()
-                  ..classes = ['indent']
-                  ..title = '${t.zoneCapacity}B'
-                  ..text = 'current zone capacity ' +
-                      '${Utils.formatSize(t.zoneCapacity)}',
-              ])
-            .element
-      ];
-  }
-
   Future _loadExtraData() async {
     _function = null;
     _rootScript = null;
diff --git a/runtime/observatory_2/lib/src/models/objects/isolate.dart b/runtime/observatory_2/lib/src/models/objects/isolate.dart
index a3c063a..e87a62d 100644
--- a/runtime/observatory_2/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory_2/lib/src/models/objects/isolate.dart
@@ -57,20 +57,6 @@
   /// [optional] The error that is causing this isolate to exit, if applicable.
   Error get error;
 
-  /// The list of threads associated with this isolate.
-  Iterable<Thread> get threads;
-
-  /// The maximum amount of zone memory in bytes allocated by the isolate in
-  /// all threads at a given time. Calculated using the high watermarks of each
-  /// thread alive when a thread is unscheduled.
-  int get zoneHighWatermark;
-
-  /// The number of zone handles currently held by this isolate.
-  int get numZoneHandles;
-
-  /// The number of scoped handles currently held by this isolate.
-  int get numScopedHandles;
-
   /// The current pause on exception mode for this isolate.
   //ExceptionPauseMode get exceptionPauseMode;
 
diff --git a/runtime/observatory_2/lib/src/models/objects/thread.dart b/runtime/observatory_2/lib/src/models/objects/thread.dart
deleted file mode 100644
index 8d16a8c..0000000
--- a/runtime/observatory_2/lib/src/models/objects/thread.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of models;
-
-enum ThreadKind {
-  unknownTask,
-  mutatorTask,
-  compilerTask,
-  sweeperTask,
-  markerTask,
-  finalizerTask
-}
-
-abstract class Thread {
-  /// The id associated with the thread on creation.
-  String get id;
-
-  /// The task type associated with the thread.
-  ThreadKind get kind;
-
-  String get kindString;
-
-  /// The maximum amount of zone memory in bytes allocated by a thread at a
-  /// given time throughout the entire life of the thread.
-  int get zoneHighWatermark;
-
-  /// The current Zone capacity available to this thread.
-  int get zoneCapacity;
-}
diff --git a/runtime/observatory_2/lib/src/models/objects/zone.dart b/runtime/observatory_2/lib/src/models/objects/zone.dart
deleted file mode 100644
index 51840cb..0000000
--- a/runtime/observatory_2/lib/src/models/objects/zone.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of models;
-
-abstract class Zone {
-  /// The total amount of memory in bytes allocated in the zone, including
-  /// memory that is not actually being used.
-  int get capacity;
-
-  /// The total amount of memory in bytes actually used in the zone.
-  int get used;
-}
diff --git a/runtime/observatory_2/lib/src/service/object.dart b/runtime/observatory_2/lib/src/service/object.dart
index 3f61be6..981215d 100644
--- a/runtime/observatory_2/lib/src/service/object.dart
+++ b/runtime/observatory_2/lib/src/service/object.dart
@@ -241,9 +241,6 @@
       case 'SourceLocation':
         obj = new SourceLocation._empty(owner);
         break;
-      case '_Thread':
-        obj = new Thread._empty(owner);
-        break;
       case 'UnresolvedSourceLocation':
         obj = new UnresolvedSourceLocation._empty(owner);
         break;
@@ -1628,18 +1625,6 @@
   DartError error;
   SnapshotReader _snapshotFetch;
 
-  List<Thread> get threads => _threads;
-  final List<Thread> _threads = <Thread>[];
-
-  int get zoneHighWatermark => _zoneHighWatermark;
-  int _zoneHighWatermark = 0;
-
-  int get numZoneHandles => _numZoneHandles;
-  int _numZoneHandles;
-
-  int get numScopedHandles => _numScopedHandles;
-  int _numScopedHandles;
-
   bool isSystemIsolate;
 
   void _loadHeapSnapshot(ServiceEvent event) {
@@ -1742,23 +1727,6 @@
     if (map['extensionRPCs'] != null) {
       for (String e in map['extensionRPCs']) extensionRPCs.add(e);
     }
-
-    threads.clear();
-    if (map['_threads'] != null) {
-      for (Thread t in map['_threads']) threads.add(t);
-    }
-
-    int currentZoneHighWatermark = 0;
-    for (var i = 0; i < threads.length; i++) {
-      currentZoneHighWatermark += threads[i].zoneHighWatermark;
-    }
-
-    if (currentZoneHighWatermark > _zoneHighWatermark) {
-      _zoneHighWatermark = currentZoneHighWatermark;
-    }
-
-    _numZoneHandles = map['_numZoneHandles'];
-    _numScopedHandles = map['_numScopedHandles'];
   }
 
   Future<TagProfile> updateTagProfile() {
@@ -3298,60 +3266,6 @@
   String get shortName => valueAsString;
 }
 
-class Thread extends ServiceObject implements M.Thread {
-  M.ThreadKind get kind => _kind;
-  M.ThreadKind _kind;
-  String get kindString => _kindString;
-  String _kindString;
-  int get zoneHighWatermark => _zoneHighWatermark;
-  int _zoneHighWatermark;
-  int get zoneCapacity => _zoneCapacity;
-  int _zoneCapacity;
-
-  Thread._empty(ServiceObjectOwner owner) : super._empty(owner);
-
-  void _update(Map map, bool mapIsRef) {
-    String rawKind = map['kind'];
-
-    switch (rawKind) {
-      case "kUnknownTask":
-        _kind = M.ThreadKind.unknownTask;
-        _kindString = 'unknown';
-        break;
-      case "kMutatorTask":
-        _kind = M.ThreadKind.mutatorTask;
-        _kindString = 'mutator';
-        break;
-      case "kCompilerTask":
-        _kind = M.ThreadKind.compilerTask;
-        _kindString = 'compiler';
-        break;
-      case "kSweeperTask":
-        _kind = M.ThreadKind.sweeperTask;
-        _kindString = 'sweeper';
-        break;
-      case "kMarkerTask":
-        _kind = M.ThreadKind.markerTask;
-        _kindString = 'marker';
-        break;
-      default:
-        assert(false);
-    }
-
-    _zoneHighWatermark = int.parse(map['_zoneHighWatermark']);
-    _zoneCapacity = int.parse(map['_zoneCapacity']);
-  }
-}
-
-class Zone implements M.Zone {
-  int get capacity => _capacity;
-  int _capacity;
-  int get used => _used;
-  int _used;
-
-  Zone(this._capacity, this._used);
-}
-
 class Field extends HeapObject implements M.Field {
   // Library or Class.
   HeapObject dartOwner;
diff --git a/runtime/observatory_2/observatory_sources.gni b/runtime/observatory_2/observatory_sources.gni
index e78a449..9ad1b96 100644
--- a/runtime/observatory_2/observatory_sources.gni
+++ b/runtime/observatory_2/observatory_sources.gni
@@ -183,14 +183,12 @@
   "lib/src/models/objects/source_location.dart",
   "lib/src/models/objects/subtype_test_cache.dart",
   "lib/src/models/objects/target.dart",
-  "lib/src/models/objects/thread.dart",
   "lib/src/models/objects/timeline.dart",
   "lib/src/models/objects/timeline_event.dart",
   "lib/src/models/objects/type_arguments.dart",
   "lib/src/models/objects/unknown.dart",
   "lib/src/models/objects/unlinked_call.dart",
   "lib/src/models/objects/vm.dart",
-  "lib/src/models/objects/zone.dart",
   "lib/src/models/repositories/allocation_profile.dart",
   "lib/src/models/repositories/breakpoint.dart",
   "lib/src/models/repositories/class.dart",
diff --git a/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart b/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart
index fdc490e..841afab 100644
--- a/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_single_step_exception_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory_2/tests/service_2/async_single_step_into_test.dart b/runtime/observatory_2/tests/service_2/async_single_step_into_test.dart
index 8d8417f..7477840 100644
--- a/runtime/observatory_2/tests/service_2/async_single_step_into_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_single_step_into_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart b/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart
index 2b51e24..cfeac6c 100644
--- a/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_single_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart b/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart
index 65a784d..0d99fd5 100644
--- a/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_star_single_step_into_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart b/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart
index fca9d16..95ca280 100644
--- a/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_star_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory_2/tests/service_2/async_step_out_test.dart b/runtime/observatory_2/tests/service_2/async_step_out_test.dart
index f22f8d8..4cce826 100644
--- a/runtime/observatory_2/tests/service_2/async_step_out_test.dart
+++ b/runtime/observatory_2/tests/service_2/async_step_out_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_2_test.dart b/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_2_test.dart
index be22e8b..0df05fd 100644
--- a/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_2_test.dart
+++ b/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_2_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'package:observatory_2/models.dart' as M;
@@ -50,28 +50,13 @@
       print(v);
     }
 
-    if (useCausalAsyncStacks) {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(4));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:${LINE_A}']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:${LINE_B}']));
-      // Suspension point.
-      expect(awaiterFrames[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      // Causal frame.
-      expect(await awaiterFrames[3].toUserString(),
-          stringContainsInOrder(['testMain', '.dart:${LINE_C}']));
-    } else {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(2));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:${LINE_A}']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:${LINE_B}']));
-    }
+    expect(awaiterFrames.length, greaterThanOrEqualTo(2));
+    // Awaiter frame.
+    expect(await awaiterFrames[0].toUserString(),
+        stringContainsInOrder(['foobar', '.dart:${LINE_A}']));
+    // Awaiter frame.
+    expect(await awaiterFrames[1].toUserString(),
+        stringContainsInOrder(['helper', '.dart:${LINE_B}']));
   },
 ];
 
diff --git a/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_test.dart b/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_test.dart
index 5f18945..9e0f8f3 100644
--- a/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_test.dart
+++ b/runtime/observatory_2/tests/service_2/awaiter_async_stack_contents_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async-debugger --verbose-debug --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async-debugger --verbose-debug --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async-debugger --verbose-debug --lazy-async-stacks
 
 import 'dart:developer';
 import 'package:observatory_2/models.dart' as M;
@@ -53,29 +53,14 @@
     ServiceMap stack = await isolate.getStack();
     expect(stack['awaiterFrames'], isNotNull);
     List awaiterFrames = stack['awaiterFrames'];
-    if (useCausalAsyncStacks) {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(4));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:$LINE_C']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:$LINE_D']));
-      // Suspension point.
-      expect(awaiterFrames[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      // Causal frame.
-      expect(await awaiterFrames[3].toUserString(),
-          stringContainsInOrder(['testMain', '.dart:$LINE_B']));
-    } else {
-      expect(awaiterFrames.length, greaterThanOrEqualTo(2));
-      // Awaiter frame.
-      expect(await awaiterFrames[0].toUserString(),
-          stringContainsInOrder(['foobar', '.dart:$LINE_C']));
-      // Awaiter frame.
-      expect(await awaiterFrames[1].toUserString(),
-          stringContainsInOrder(['helper', '.dart:$LINE_D']));
-      // "helper" is not await'ed.
-    }
+    expect(awaiterFrames.length, greaterThanOrEqualTo(2));
+    // Awaiter frame.
+    expect(await awaiterFrames[0].toUserString(),
+        stringContainsInOrder(['foobar', '.dart:$LINE_C']));
+    // Awaiter frame.
+    expect(await awaiterFrames[1].toUserString(),
+        stringContainsInOrder(['helper', '.dart:$LINE_D']));
+    // "helper" is not await'ed.
   },
 ];
 
diff --git a/runtime/observatory_2/tests/service_2/causal_async_stack_contents_test.dart b/runtime/observatory_2/tests/service_2/causal_async_stack_contents_test.dart
index 067887d..7523c0f 100644
--- a/runtime/observatory_2/tests/service_2/causal_async_stack_contents_test.dart
+++ b/runtime/observatory_2/tests/service_2/causal_async_stack_contents_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory_2/models.dart' as M;
@@ -48,14 +48,8 @@
     // Has causal frames (we are inside an async function)
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack[0].toString(), contains('helper'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[2].toString(), contains('testMain'));
-    } else {
-      expect(asyncStack[0].toString(), contains('helper'));
-      // "helper" is not await'ed.
-    }
+    expect(asyncStack[0].toString(), contains('helper'));
+    // "helper" is not await'ed.
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
@@ -65,19 +59,9 @@
     // Has causal frames (we are inside a function called by an async function)
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].toString(), contains('helper'));
-      expect(asyncStack[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[3].toString(), contains('testMain'));
-      expect(await asyncStack[0].location.toUserString(), contains('.dart:20'));
-      expect(await asyncStack[1].location.toUserString(), contains('.dart:27'));
-      expect(await asyncStack[3].location.toUserString(), contains('.dart:32'));
-    } else {
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].toString(), contains('helper'));
-      // "helper" is not await'ed.
-    }
+    expect(asyncStack[0].toString(), contains('foobar'));
+    expect(asyncStack[1].toString(), contains('helper'));
+    // "helper" is not await'ed.
   },
 ];
 
diff --git a/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart b/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
index c37359e..f52f4a1 100644
--- a/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
+++ b/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory_2/service_io.dart';
diff --git a/runtime/observatory_2/tests/service_2/causal_async_star_stack_contents_test.dart b/runtime/observatory_2/tests/service_2/causal_async_star_stack_contents_test.dart
index 4474624..5044d57 100644
--- a/runtime/observatory_2/tests/service_2/causal_async_star_stack_contents_test.dart
+++ b/runtime/observatory_2/tests/service_2/causal_async_star_stack_contents_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory_2/models.dart' as M;
@@ -44,16 +44,9 @@
     // No causal frames because we are in a completely synchronous stack.
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack.length, greaterThanOrEqualTo(3));
-      expect(asyncStack[0].toString(), contains('helper'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[2].toString(), contains('testMain'));
-    } else {
-      expect(asyncStack.length, greaterThanOrEqualTo(1));
-      expect(asyncStack[0].toString(), contains('helper'));
-      // helper isn't awaited.
-    }
+    expect(asyncStack.length, greaterThanOrEqualTo(1));
+    expect(asyncStack[0].toString(), contains('helper'));
+    // helper isn't awaited.
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
@@ -68,10 +61,7 @@
     expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
     expect(asyncStack[2].toString(), contains('helper'));
     expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
-    if (useCausalAsyncStacks) {
-      // helper isn't awaited.
-      expect(asyncStack[4].toString(), contains('testMain'));
-    }
+    // helper isn't awaited.
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
@@ -93,12 +83,7 @@
     expect(asyncStack[2].toString(), contains('helper'));
     expect(await asyncStack[2].location.toUserString(), contains('.dart:30'));
     expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
-    if (useCausalAsyncStacks) {
-      // helper isn't awaited.
-      expect(asyncStack.length, greaterThanOrEqualTo(5));
-      expect(asyncStack[4].toString(), contains('testMain'));
-      expect(await asyncStack[4].location.toUserString(), contains('.dart:36'));
-    }
+    // helper isn't awaited.
   },
 ];
 
diff --git a/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart b/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
index db19b2c..7fb385a 100644
--- a/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
+++ b/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks --verbose_debug
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks --verbose_debug
+//
+// VMOptions=--lazy-async-stacks --verbose_debug
 
 import 'dart:developer';
 import 'package:observatory_2/service_io.dart';
diff --git a/runtime/observatory_2/tests/service_2/get_isolate_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_isolate_rpc_test.dart
index f09eb04..40cb013 100644
--- a/runtime/observatory_2/tests/service_2/get_isolate_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_isolate_rpc_test.dart
@@ -23,8 +23,6 @@
     expect(result['pauseOnExit'], isFalse);
     expect(result['pauseEvent']['type'], equals('Event'));
     expect(result['error'], isNull);
-    expect(result['_numZoneHandles'], isPositive);
-    expect(result['_numScopedHandles'], isPositive);
     expect(result['rootLib']['type'], equals('@Library'));
     expect(result['libraries'].length, isPositive);
     expect(result['libraries'][0]['type'], equals('@Library'));
diff --git a/runtime/observatory_2/tests/service_2/get_retaining_path_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_retaining_path_rpc_test.dart
index 2bbc008..43f02e5 100644
--- a/runtime/observatory_2/tests/service_2/get_retaining_path_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_retaining_path_rpc_test.dart
@@ -21,6 +21,8 @@
 var target3 = new _TestClass();
 var target4 = new _TestClass();
 var target5 = new _TestClass();
+var target6 = new _TestClass();
+Expando<_TestClass> expando = Expando<_TestClass>();
 @pragma("vm:entry-point") // Prevent obfuscation
 var globalObject = new _TestClass();
 @pragma("vm:entry-point") // Prevent obfuscation
@@ -77,6 +79,15 @@
 }
 
 @pragma("vm:entry-point")
+takeExpandoTarget() {
+  var tmp = target6;
+  target6 = null;
+  var tmp2 = _TestClass();
+  expando[tmp] = tmp2;
+  return tmp2;
+}
+
+@pragma("vm:entry-point")
 getTrue() => true;
 
 invoke(Isolate isolate, String selector) async {
@@ -192,6 +203,23 @@
     expect(result['elements'][2]['value']['name'], equals('globalMap2'));
   },
 
+  (Isolate isolate) async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/44016
+    var target6 = await invoke(isolate, 'takeExpandoTarget');
+    var params = {
+      'targetId': target6['id'],
+      'limit': 100,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getRetainingPath', params);
+    expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(5));
+    expect(result['elements'][1]['parentMapKey']['class']['name'],
+        equals('_TestClass'));
+    expect(result['elements'][2]['parentListIndex'], isNotNull);
+    expect(result['elements'][3]['value']['class']['name'], 'Expando');
+    expect(result['elements'][4]['value']['name'], 'expando');
+  },
+
   // object store
   (Isolate isolate) async {
     var obj = await invoke(isolate, 'getTrue');
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart
new file mode 100644
index 0000000..b0f078d
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "get_source_report_const_coverage_test.dart";
+
+void testFunction() {
+  const namedFoo = Foo.named3();
+  const namedFoo2 = Foo.named3();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print("namedIdentical: $namedIdentical");
+}
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart
new file mode 100644
index 0000000..7c6af16
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+import 'dart:developer';
+
+import 'get_source_report_const_coverage_lib.dart' as lib;
+
+const String filename = "get_source_report_const_coverage_test";
+const Set<int> expectedLinesHit = {20, 22, 26};
+const Set<int> expectedLinesNotHit = {24};
+
+class Foo {
+  final int x;
+  // Expect this constructor to be coverage by coverage.
+  const Foo([int x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too.
+  const Foo.named1([int x]) : this.x = x ?? 42;
+  // Expect this constructor to *NOT* be coverage by coverage.
+  const Foo.named2([int x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too (from lib).
+  const Foo.named3([int x]) : this.x = x ?? 42;
+}
+
+void testFunction() {
+  const foo = Foo();
+  const foo2 = Foo();
+  const fooIdentical = identical(foo, foo2);
+  print(fooIdentical);
+
+  const namedFoo = Foo.named1();
+  const namedFoo2 = Foo.named1();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print(fooIdentical);
+
+  debugger();
+
+  // That this is called after (or at all) is not relevent for the code
+  // coverage of constants.
+  lib.testFunction();
+
+  print("Done");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    final stack = await isolate.getStack();
+
+    // Make sure we are in the right place.
+    expect(stack.type, equals('Stack'));
+    expect(stack['frames'].length, greaterThanOrEqualTo(1));
+    expect(stack['frames'][0].function.name, equals('testFunction'));
+
+    final List<Script> scripts = await isolate.getScripts();
+    Script foundScript;
+    for (Script script in scripts) {
+      if (script.uri.contains(filename)) {
+        foundScript = script;
+        break;
+      }
+    }
+
+    Set<int> hits;
+    {
+      // Get report for everything; then collect for this library.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      hits = getHitsFor(coverage, filename);
+      await foundScript.load();
+      final Set<int> lines = {};
+      for (int hit in hits) {
+        // We expect every hit to be translatable to line
+        // (i.e. tokenToLine to return non-null).
+        lines.add(foundScript.tokenToLine(hit));
+      }
+      print("Token position hits: $hits --- line hits: $lines");
+      expect(lines.intersection(expectedLinesHit), equals(expectedLinesHit));
+      expect(lines.intersection(expectedLinesNotHit), isEmpty);
+    }
+    {
+      // Now get report for the this file only.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+        'scriptId': foundScript.id
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      final Set<int> localHits = getHitsFor(coverage, filename);
+      expect(localHits.length, equals(hits.length));
+      expect(hits.toList()..sort(), equals(localHits.toList()..sort()));
+      print(localHits);
+    }
+  },
+];
+
+Set<int> getHitsFor(Map coverage, String uriContains) {
+  final List scripts = coverage["scripts"];
+  final Set<int> scriptIdsWanted = {};
+  for (int i = 0; i < scripts.length; i++) {
+    final Map script = scripts[i];
+    final String scriptUri = script["uri"];
+    if (scriptUri.contains(uriContains)) {
+      scriptIdsWanted.add(i);
+    }
+  }
+  final List ranges = coverage["ranges"];
+  final Set<int> hits = {};
+  for (int i = 0; i < ranges.length; i++) {
+    final Map range = ranges[i];
+    if (scriptIdsWanted.contains(range["scriptIndex"])) {
+      if (range["coverage"] != null) {
+        for (int hit in range["coverage"]["hits"]) {
+          hits.add(hit);
+        }
+      }
+    }
+  }
+  return hits;
+}
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
index 97606de..78ea471 100644
--- a/runtime/observatory_2/tests/service_2/get_source_report_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
@@ -91,7 +91,7 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    expect(numRanges, equals(10));
+    expect(numRanges, equals(11));
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -106,7 +106,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, 11);
+    expect(coverage['ranges'].length, 12);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
index 5248ebc..33766da 100644
--- a/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+// VMOptions=--lazy-async-stacks
 
 import 'dart:async';
 import 'dart:developer';
@@ -13,31 +13,29 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
-bar(int depth) {
+bar(int depth) async {
   if (depth == 21) {
     debugger();
     return;
   }
-  foo(depth + 1);
+  await foo(depth + 1);
 }
 
-foo(int depth) {
-  bar(depth + 1);
+foo(int depth) async {
+  if (depth == 10) {
+    // Yield once to force the rest to run async.
+    await 0;
+  }
+  await bar(depth + 1);
 }
 
-testMain() {
-  foo(0);
+testMain() async {
+  await foo(0);
 }
 
-verifyStack(List frames, int numFrames) {
-  for (int i = 0; i < frames.length && i < numFrames; ++i) {
-    final frame = frames[i];
-    if (i < 22) {
-      expect(frame.function.qualifiedName, (i % 2) == 0 ? 'bar' : 'foo');
-    } else if (i == 22) {
-      expect(frame.function.qualifiedName, 'testMain');
-      break;
-    }
+verifyStack(List frames, List<String> expectedNames) {
+  for (int i = 0; i < frames.length && i < expectedNames.length; ++i) {
+    expect(frames[i].function.qualifiedName, expectedNames[i]);
   }
 }
 
@@ -57,10 +55,14 @@
     var awaiterFrames = stack['awaiterFrames'];
     expect(frames.length, greaterThanOrEqualTo(20));
     expect(asyncFrames.length, greaterThan(frames.length));
-    expect(awaiterFrames.length, greaterThan(frames.length));
+    expect(awaiterFrames.length, 13);
     expect(stack['truncated'], false);
-
-    verifyStack(frames, frames.length);
+    verifyStack(frames, [
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      '_RootZone.runUnary', // Internal async. mech. ..
+    ]);
 
     final fullStackLength = frames.length;
 
@@ -75,7 +77,12 @@
     expect(asyncFrames.length, fullStackLength + 1);
     expect(asyncFrames.length, fullStackLength + 1);
     expect(stack['truncated'], true);
-    verifyStack(frames, fullStackLength);
+    verifyStack(frames, [
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      'bar.async_op', 'foo.async_op', 'bar.async_op', 'foo.async_op',
+      '_RootZone.runUnary', // Internal async. mech. ..
+    ]);
 
     // Try a limit < actual stack depth and expect to get a stack of depth
     // 'limit'.
@@ -88,7 +95,18 @@
     expect(asyncFrames.length, 10);
     expect(awaiterFrames.length, 10);
     expect(stack['truncated'], true);
-    verifyStack(frames, 10);
+    verifyStack(frames, [
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+      'bar.async_op',
+      'foo.async_op',
+    ]);
   },
 // Invalid limit
   (Isolate isolate) async {
diff --git a/runtime/observatory_2/tests/service_2/get_zone_memory_info_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_zone_memory_info_rpc_test.dart
deleted file mode 100644
index dd1d671..0000000
--- a/runtime/observatory_2/tests/service_2/get_zone_memory_info_rpc_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:observatory_2/service_io.dart';
-import 'package:test/test.dart';
-
-import 'test_helper.dart';
-
-var tests = <VMTest>[
-  (VM vm) async {
-    // Just iterate over all the isolates to confirm they have
-    // the correct fields needed to examine zone memory usage.
-    for (Isolate isolate in new List.from(vm.isolates)) {
-      await isolate.reload();
-      expect(isolate.zoneHighWatermark, isA<int>());
-      expect(isolate.threads, isNotNull);
-      List<Thread> threads = isolate.threads;
-
-      for (Thread thread in threads) {
-        expect(thread.type, equals('_Thread'));
-        expect(thread.id, isNotNull);
-        expect(thread.kind, isNotNull);
-        expect(thread.zoneHighWatermark, isA<int>());
-        expect(thread.zoneCapacity, isA<int>());
-      }
-    }
-  },
-];
-
-main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory_2/tests/service_2/http_get_isolate_rpc_common.dart b/runtime/observatory_2/tests/service_2/http_get_isolate_rpc_common.dart
index 7f5c869..ae80158 100644
--- a/runtime/observatory_2/tests/service_2/http_get_isolate_rpc_common.dart
+++ b/runtime/observatory_2/tests/service_2/http_get_isolate_rpc_common.dart
@@ -70,8 +70,6 @@
     Expect.isFalse(result['pauseOnExit']);
     Expect.equals(result['pauseEvent']['type'], 'Event');
     Expect.isNull(result['error']);
-    Expect.isTrue(result['_numZoneHandles'] > 0);
-    Expect.isTrue(result['_numScopedHandles'] > 0);
     Expect.equals(result['rootLib']['type'], '@Library');
     Expect.isTrue(result['libraries'].length > 0);
     Expect.equals(result['libraries'][0]['type'], '@Library');
diff --git a/runtime/observatory_2/tests/service_2/next_through_simple_async_test.dart b/runtime/observatory_2/tests/service_2/next_through_simple_async_test.dart
index 5a3ac87..bc2c3d5 100644
--- a/runtime/observatory_2/tests/service_2/next_through_simple_async_test.dart
+++ b/runtime/observatory_2/tests/service_2/next_through_simple_async_test.dart
@@ -1,19 +1,17 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'test_helper.dart';
 import 'service_test_common.dart';
 import 'dart:io';
 
-const int LINE_A = 16;
+const int LINE_A = 14;
 const String file = "next_through_simple_async_test.dart";
 
-// line A is at the "code() async" line
-code() async {
+code() async {  // LINE_A
   File f = new File(Platform.script.toFilePath());
   DateTime modified = await f.lastModified();
   bool exists = await f.exists();
diff --git a/runtime/observatory_2/tests/service_2/next_through_simple_async_with_returns_test.dart b/runtime/observatory_2/tests/service_2/next_through_simple_async_with_returns_test.dart
index 68dca68..9a3f234 100644
--- a/runtime/observatory_2/tests/service_2/next_through_simple_async_with_returns_test.dart
+++ b/runtime/observatory_2/tests/service_2/next_through_simple_async_with_returns_test.dart
@@ -1,19 +1,17 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'test_helper.dart';
 import 'service_test_common.dart';
 import 'dart:io';
 
-const int LINE_A = 16;
+const int LINE_A = 14;
 const String file = "next_through_simple_async_with_returns_test.dart";
 
-// line A is at the "code() async" line
-code() async {
+code() async {  // LINE_A
   File f = new File(Platform.script.toFilePath());
   bool exists = await f.exists();
   if (exists) {
diff --git a/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions2_test.dart b/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions2_test.dart
index fa4bf52..50d9537 100644
--- a/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions2_test.dart
+++ b/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions2_test.dart
@@ -1,10 +1,9 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async_debugger --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async_debugger --causal-async-stacks --no-lazy-async-stacks
-// VMOptions=--async_debugger --no-causal-async-stacks --lazy-async-stacks --optimization-counter-threshold=5
-// VMOptions=--async_debugger --causal-async-stacks --no-lazy-async-stacks --optimization-counter-threshold=5
+//
+// VMOptions=--async_debugger --lazy-async-stacks
+// VMOptions=--async_debugger --lazy-async-stacks --optimization-counter-threshold=5
 
 import 'package:observatory_2/service_io.dart';
 import 'package:observatory_2/models.dart' as M;
@@ -12,12 +11,12 @@
 import 'test_helper.dart';
 import 'service_test_common.dart';
 
-const LINE_A = 37;
+const LINE_A = 36;
 
 class Foo {}
 
 doThrow() {
-  throw "TheException"; // Line 13.
+  throw "TheException";
   return "end of doThrow";
 }
 
diff --git a/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions_test.dart b/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions_test.dart
index da16126..d179cb6 100644
--- a/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions_test.dart
+++ b/runtime/observatory_2/tests/service_2/pause_on_unhandled_async_exceptions_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--async_debugger --no-causal-async-stacks --lazy-async-stacks
-// VMOptions=--async_debugger --causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--async_debugger --lazy-async-stacks
 
 import 'package:observatory_2/service_io.dart';
 import 'package:observatory_2/models.dart' as M;
@@ -15,7 +15,7 @@
 class Foo {}
 
 doThrow() {
-  throw "TheException"; // Line 13.
+  throw "TheException";
   return "end of doThrow";
 }
 
@@ -45,21 +45,10 @@
     var stack = await isolate.getStack();
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
-    if (useCausalAsyncStacks) {
-      expect(asyncStack.length, greaterThanOrEqualTo(4));
-      expect(asyncStack[0].toString(), contains('doThrow'));
-      expect(asyncStack[1].toString(), contains('asyncThrower'));
-      expect(asyncStack[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[3].toString(), contains('testeeMain'));
-      // We've stopped at LINE_A.
-      expect(await asyncStack[3].location.toUserString(),
-          contains('.dart:$LINE_A'));
-    } else {
-      expect(asyncStack.length, greaterThanOrEqualTo(2));
-      expect(asyncStack[0].toString(), contains('doThrow'));
-      expect(asyncStack[1].toString(), contains('asyncThrower'));
-      // There was no await'er for "doThrow()".
-    }
+    expect(asyncStack.length, greaterThanOrEqualTo(2));
+    expect(asyncStack[0].toString(), contains('doThrow'));
+    expect(asyncStack[1].toString(), contains('asyncThrower'));
+    // There was no await'er for "doThrow()".
   }
 ];
 
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 8c09f06..5522831 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -39,157 +39,159 @@
 pause_on_unhandled_async_exceptions2_test: Pass, Slow
 
 [ $compiler == dartkp ]
-add_breakpoint_rpc_kernel_test: SkipByDesign
-async_generator_breakpoint_test: SkipByDesign
-async_next_regession_18877_test: Skip, Timeout
-async_next_test: Skip, Timeout
-async_scope_test: Skip, Timeout
-async_single_step_exception_test: Skip, Timeout
-async_single_step_into_test: Skip, Timeout
-async_single_step_out_test: Skip, Timeout
-async_star_single_step_into_test: Skip, Timeout
-async_star_step_out_test: Skip, Timeout
-async_step_out_test: Skip, Timeout
-awaiter_async_stack_contents_2_test: Skip, Timeout
-awaiter_async_stack_contents_test: Skip, Timeout
-bad_reload_test: SkipByDesign
-break_on_activation_test: SkipByDesign
-break_on_async_function_test: Skip, Timeout
-break_on_default_constructor_test: SkipByDesign
-break_on_function_test: Skip, Timeout
-breakpoint_async_break_test: SkipByDesign
-breakpoint_in_package_parts_class_file_uri_test: SkipByDesign
-breakpoint_in_package_parts_class_test: SkipByDesign
-breakpoint_in_parts_class_test: SkipByDesign
-breakpoint_non_debuggable_library_test: SkipByDesign
-breakpoint_on_if_null_1_test: SkipByDesign
-breakpoint_on_if_null_2_test: SkipByDesign
-breakpoint_on_if_null_3_test: SkipByDesign
-breakpoint_on_if_null_4_test: SkipByDesign
-breakpoint_partfile_test: SkipByDesign
-breakpoint_two_args_checked_test: Skip, Timeout
+add_breakpoint_rpc_kernel_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_generator_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_next_regession_18877_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_next_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_single_step_exception_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_single_step_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_star_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_star_step_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+async_step_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+awaiter_async_stack_contents_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+awaiter_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode.
+bad_reload_test: SkipByDesign # Hot reload is disabled in AOT mode.
+break_on_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_async_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_default_constructor_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_async_break_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_in_package_parts_class_file_uri_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_in_package_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_in_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_non_debuggable_library_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_1_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_3_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_if_null_4_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_partfile_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_two_args_checked_test: SkipByDesign # Debugger is disabled in AOT mode.
 breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
-capture_stdio_test: Skip, Timeout
-causal_async_stack_contents_test: Skip, Timeout
-causal_async_stack_presence_test: Skip, Timeout
-causal_async_star_stack_contents_test: Skip, Timeout
-causal_async_star_stack_presence_test: Skip, Timeout
-client_resume_approvals_reload_test: SkipByDesign # Compiler is disabled in AOT mode.
-code_test: SkipByDesign
-column_breakpoint_test: SkipByDesign
-complex_reload_test: SkipByDesign
-coverage_const_field_async_closure_test: Skip, Timeout
-coverage_leaf_function_test: Skip, Timeout
-coverage_optimized_function_test: Skip, Timeout
-dds_log_history_size_*: Skip, Timeout
-debugger_inspect_test: SkipByDesign
-debugger_location_second_test: Skip, Timeout
-debugger_location_test: Skip, Timeout
-debugging_inlined_finally_test: Skip, Timeout
-debugging_test: SkipByDesign
-dev_fs_spawn_test: SkipByDesign
-developer_extension_test: Skip, Timeout
-developer_service_get_isolate_id_test: Skip, Timeout
-eval_internal_class_test: SkipByDesign
-eval_regression_flutter20255_test: Skip, Timeout
-eval_test: Skip, Timeout
-evaluate_activation_in_method_class_test: Skip, Timeout
+capture_stdio_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_star_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode.
+causal_async_star_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode.
+client_resume_approvals_reload_test: SkipByDesign # Debugger is disabled in AOT mode.
+code_test: SkipByDesign # Debugger is disabled in AOT mode.
+column_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode.
+complex_reload_test: SkipByDesign # Debugger is disabled in AOT mode.
+coverage_const_field_async_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
+coverage_leaf_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+coverage_optimized_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+dds_log_history_size_*: SkipByDesign # Debugger is disabled in AOT mode.
+debugger_inspect_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugger_location_second_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugger_location_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugging_inlined_finally_test: SkipByDesign # Debugger is disabled in AOT mode.
+debugging_test: SkipByDesign # Debugger is disabled in AOT mode.
+dev_fs_spawn_test: SkipByDesign # Debugger is disabled in AOT mode.
+developer_extension_test: SkipByDesign # Debugger is disabled in AOT mode.
+developer_service_get_isolate_id_test: SkipByDesign # Debugger is disabled in AOT mode.
+eval_internal_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+eval_regression_flutter20255_test: SkipByDesign # Debugger is disabled in AOT mode.
+eval_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_activation_in_method_class_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_activation_test: SkipByDesign
 evaluate_async_closure_test: SkipByDesign
-evaluate_class_type_parameters_test: Skip, Timeout
-evaluate_function_type_parameters_test: Skip, Timeout
-evaluate_in_async_activation_test: Skip, Timeout
-evaluate_in_async_star_activation_test: Skip, Timeout
-evaluate_in_frame_rpc_test: Skip, Timeout
-evaluate_in_frame_with_scope_test: Skip, Timeout
-evaluate_in_sync_star_activation_test: Skip, Timeout
-evaluate_with_escaping_closure_test: SkipByDesign
-evaluate_with_scope_test: SkipByDesign
-field_script_test: SkipByDesign
-get_allocation_samples_test: Skip, Timeout
+evaluate_class_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_function_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_async_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_async_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_frame_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_frame_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_in_sync_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_with_escaping_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
+field_script_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_allocation_samples_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_isolate_after_language_error_test: CompileTimeError
-get_object_rpc_test: SkipByDesign
-get_source_report_test: Skip, Timeout
-get_source_report_with_mixin_test: Skip, Timeout
-get_stack_limit_rpc_test: Skip, Timeout
-get_stack_rpc_test: Skip, Timeout
-implicit_getter_setter_test: SkipByDesign
-invoke_test: Skip, Timeout
-isolate_lifecycle_test: SkipByDesign
-issue_25465_test: SkipByDesign
-issue_27238_test: Skip, Timeout
-issue_27287_test: Skip, Timeout
-issue_30555_test: SkipByDesign
-kill_paused_test: Skip, Timeout
+get_object_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_const_coverage_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_stack_limit_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_stack_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+implicit_getter_setter_test: SkipByDesign # Debugger is disabled in AOT mode.
+invoke_test: SkipByDesign # Debugger is disabled in AOT mode.
+isolate_lifecycle_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_25465_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_27238_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_27287_test: SkipByDesign # Debugger is disabled in AOT mode.
+issue_30555_test: SkipByDesign # Debugger is disabled in AOT mode.
+kill_paused_test: SkipByDesign # Debugger is disabled in AOT mode.
 library_dependency_test: CompileTimeError
-local_variable_declaration_test: Skip, Timeout
-local_variable_in_awaiter_async_frame_test: Skip, Timeout
-logging_test: Skip, Timeout
+local_variable_declaration_test: SkipByDesign # Debugger is disabled in AOT mode.
+local_variable_in_awaiter_async_frame_test: SkipByDesign # Debugger is disabled in AOT mode.
+logging_test: SkipByDesign # Debugger is disabled in AOT mode.
 mirror_references_test: CompileTimeError
-mixin_break_test: Skip, Timeout
-network_profiling_test: Skip, Timeout
-next_through_assign_call_test: SkipByDesign
-next_through_assign_int_test: SkipByDesign
-next_through_await_for_test: SkipByDesign
-next_through_call_on_field_in_class_test: SkipByDesign
-next_through_call_on_field_test: SkipByDesign
-next_through_call_on_static_field_in_class_test: SkipByDesign
-next_through_catch_test: SkipByDesign
-next_through_closure_test: SkipByDesign
-next_through_create_list_and_map_test: SkipByDesign
-next_through_for_each_loop_test: SkipByDesign
-next_through_for_loop_with_break_and_continue_test: SkipByDesign
-next_through_function_expression_test: SkipByDesign
-next_through_implicit_call_test: SkipByDesign
-next_through_is_and_as_test: SkipByDesign
-next_through_multi_catch_test: SkipByDesign
-next_through_new_test: SkipByDesign
-next_through_operator_bracket_on_super_test: SkipByDesign
-next_through_operator_bracket_on_this_test: SkipByDesign
-next_through_operator_bracket_test: SkipByDesign
-next_through_simple_async_test: SkipByDesign
-next_through_simple_async_with_returns_test: SkipByDesign
-next_through_simple_linear_2_test: SkipByDesign
-next_through_simple_linear_test: SkipByDesign
-parameters_in_scope_at_entry_test: Skip, Timeout
-pause_idle_isolate_test: Skip, Timeout
-pause_on_exceptions_test: SkipByDesign
-pause_on_start_then_step_test: SkipByDesign
-pause_on_unhandled_async_exceptions2_test: SkipByDesign
-pause_on_unhandled_async_exceptions3_test: SkipByDesign
-pause_on_unhandled_async_exceptions_test: SkipByDesign
-pause_on_unhandled_exceptions_test: SkipByDesign
-positive_token_pos_test: Skip, Timeout
-regress_28443_test: SkipByDesign
-regress_28980_test: SkipByDesign
-regress_34841_test: Skip, Timeout
-reload_sources_test: Skip, Timeout
-rewind_optimized_out_test: Skip, Timeout
-rewind_test: Skip, Timeout
-set_library_debuggable_test: Skip, Timeout
-simple_reload_test: SkipByDesign
-steal_breakpoint_test: SkipByDesign
-step_into_async_no_await_test: Skip, Timeout
-step_over_await_test: Skip, Timeout
-step_test: SkipByDesign
-step_through_arithmetic_test: SkipByDesign
-step_through_constructor_calls_test: SkipByDesign
-step_through_constructor_test: SkipByDesign
-step_through_for_each_sync_star_2_test: SkipByDesign
-step_through_for_each_sync_star_test: SkipByDesign
-step_through_function_2_test: SkipByDesign
-step_through_function_test: SkipByDesign
-step_through_getter_test: SkipByDesign
-step_through_mixin_from_sdk_test: SkipByDesign
-step_through_property_get_test: SkipByDesign
-step_through_property_set_test: SkipByDesign
-step_through_setter_test: SkipByDesign
-step_through_switch_test: SkipByDesign
-step_through_switch_with_continue_test: SkipByDesign
-valid_source_locations_test: Skip, Timeout
-vm_timeline_flags_test: Skip, Timeout
+mixin_break_test: SkipByDesign # Debugger is disabled in AOT mode.
+network_profiling_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_assign_call_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_assign_int_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_await_for_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_call_on_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_call_on_field_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_call_on_static_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_catch_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_create_list_and_map_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_for_each_loop_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_for_loop_with_break_and_continue_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_function_expression_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_implicit_call_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_is_and_as_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_multi_catch_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_new_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_operator_bracket_on_super_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_operator_bracket_on_this_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_operator_bracket_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_async_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_async_with_returns_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_linear_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+next_through_simple_linear_test: SkipByDesign # Debugger is disabled in AOT mode.
+parameters_in_scope_at_entry_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_idle_isolate_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_start_then_step_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_async_exceptions2_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_async_exceptions3_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_async_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode.
+pause_on_unhandled_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode.
+positive_token_pos_test: SkipByDesign # Debugger is disabled in AOT mode.
+regress_28443_test: SkipByDesign # Debugger is disabled in AOT mode.
+regress_28980_test: SkipByDesign # Debugger is disabled in AOT mode.
+regress_34841_test: SkipByDesign # Debugger is disabled in AOT mode.
+reload_sources_test: SkipByDesign # Debugger is disabled in AOT mode.
+rewind_optimized_out_test: SkipByDesign # Debugger is disabled in AOT mode.
+rewind_test: SkipByDesign # Debugger is disabled in AOT mode.
+set_library_debuggable_test: SkipByDesign # Debugger is disabled in AOT mode.
+simple_reload_test: SkipByDesign # Hot reload is disabled in AOT mode.
+steal_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_into_async_no_await_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_over_await_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_arithmetic_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_constructor_calls_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_constructor_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_for_each_sync_star_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_for_each_sync_star_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_function_2_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_function_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_getter_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_mixin_from_sdk_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_property_get_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_property_set_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_setter_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_switch_test: SkipByDesign # Debugger is disabled in AOT mode.
+step_through_switch_with_continue_test: SkipByDesign # Debugger is disabled in AOT mode.
+valid_source_locations_test: SkipByDesign # Debugger is disabled in AOT mode.
+validate_timer_port_behavior_test: SkipByDesign # Debugger is disabled in AOT mode.
+vm_timeline_flags_test: SkipByDesign # Debugger is disabled in AOT mode.
 weak_properties_test: CompileTimeError
-yield_positions_with_finally_test: SkipByDesign
+yield_positions_with_finally_test: SkipByDesign # Debugger is disabled in AOT mode.
 
 [ $fasta ]
 get_isolate_after_language_error_test: CompileTimeError
diff --git a/runtime/observatory_2/tests/service_2/test_helper.dart b/runtime/observatory_2/tests/service_2/test_helper.dart
index 18f345e..0a352fe 100644
--- a/runtime/observatory_2/tests/service_2/test_helper.dart
+++ b/runtime/observatory_2/tests/service_2/test_helper.dart
@@ -13,17 +13,11 @@
 import 'service_test_common.dart';
 export 'service_test_common.dart' show DDSTest, IsolateTest, VMTest;
 
-/// Whether to use causal async stacks (if not we use lazy async stacks).
-const bool useCausalAsyncStacks =
-    const bool.fromEnvironment('dart.developer.causal_async_stacks');
-
 /// Determines whether DDS is enabled for this test run.
 const bool useDds = const bool.fromEnvironment('USE_DDS');
 
 /// The extra arguments to use
-const List<String> extraDebuggingArgs = useCausalAsyncStacks
-    ? const ['--causal-async-stacks', '--no-lazy-async-stacks']
-    : const ['--no-causal-async-stacks', '--lazy-async-stacks'];
+const List<String> extraDebuggingArgs = ['--lazy-async-stacks'];
 
 /// Will be set to the http address of the VM's service protocol before
 /// any tests are invoked.
diff --git a/runtime/observatory_2/tests/service_2/validate_timer_port_behavior_test.dart b/runtime/observatory_2/tests/service_2/validate_timer_port_behavior_test.dart
new file mode 100644
index 0000000..fd91428
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/validate_timer_port_behavior_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:developer';
+import 'dart:isolate' hide Isolate;
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+void warmup() {
+  Timer timer = Timer(const Duration(days: 30), () => null);
+  debugger();
+  timer.cancel();
+  debugger();
+  timer = Timer(const Duration(days: 30), () => null);
+  debugger();
+  timer.cancel();
+}
+
+Set<int> originalPortIds;
+int timerPortId;
+
+final tests = <IsolateTest>[
+  hasPausedAtStart,
+  (Isolate isolate) async {
+    final originalPorts =
+        (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    originalPortIds = {
+      for (int i = 0; i < originalPorts.length; ++i) originalPorts[i]['portId'],
+    };
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Determine the ID of the timer port.
+    final ports = (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    timerPortId = ports
+        .firstWhere((p) => !originalPortIds.contains(p['portId']))['portId'];
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // After cancelling the timer, there should be no active timers left.
+    // The timer port should be inactive and not reported.
+    final ports = (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    for (final port in ports) {
+      if (port['portId'] == timerPortId) {
+        fail('Timer port should no longer be active');
+      }
+    }
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // After setting a new timer, the timer port should be active and have the same
+    // port ID as before as the original port is still being used.
+    final ports = (await isolate.invokeRpcNoUpgrade('getPorts', {}))['ports'];
+    bool foundTimerPort = false;
+    for (final port in ports) {
+      if (port['portId'] == timerPortId) {
+        foundTimerPort = true;
+        break;
+      }
+    }
+    expect(foundTimerPort, true);
+  },
+];
+
+main(args) async => runIsolateTests(args, tests,
+    pause_on_start: true, testeeConcurrent: warmup);
diff --git a/runtime/platform/allocation.cc b/runtime/platform/allocation.cc
new file mode 100644
index 0000000..6f8ae01
--- /dev/null
+++ b/runtime/platform/allocation.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "platform/allocation.h"
+
+#include "platform/assert.h"
+
+namespace dart {
+
+void* malloc(size_t size) {
+  void* result = ::malloc(size);
+  if (result == nullptr) {
+    OUT_OF_MEMORY();
+  }
+  return result;
+}
+
+void* realloc(void* ptr, size_t size) {
+  void* result = ::realloc(ptr, size);
+  if (result == nullptr) {
+    OUT_OF_MEMORY();
+  }
+  return result;
+}
+
+}  // namespace dart
diff --git a/runtime/platform/allocation.h b/runtime/platform/allocation.h
index 2e3b76b..4458f55 100644
--- a/runtime/platform/allocation.h
+++ b/runtime/platform/allocation.h
@@ -5,6 +5,7 @@
 #ifndef RUNTIME_PLATFORM_ALLOCATION_H_
 #define RUNTIME_PLATFORM_ALLOCATION_H_
 
+#include "platform/address_sanitizer.h"
 #include "platform/assert.h"
 
 namespace dart {
@@ -31,6 +32,39 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(AllStatic);
 };
 
+class MallocAllocated {
+ public:
+  MallocAllocated() {}
+
+  // Intercept operator new to produce clearer error messages when we run out
+  // of memory. Don't do this when running under ASAN so it can continue to
+  // check malloc/new/new[] are paired with free/delete/delete[] respectively.
+#if !defined(USING_ADDRESS_SANITIZER)
+  void* operator new(size_t size) {
+    void* result = ::malloc(size);
+    if (result == nullptr) {
+      OUT_OF_MEMORY();
+    }
+    return result;
+  }
+
+  void* operator new[](size_t size) {
+    void* result = ::malloc(size);
+    if (result == nullptr) {
+      OUT_OF_MEMORY();
+    }
+    return result;
+  }
+
+  void operator delete(void* pointer) { ::free(pointer); }
+
+  void operator delete[](void* pointer) { ::free(pointer); }
+#endif
+};
+
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+
 }  // namespace dart
 
 #endif  // RUNTIME_PLATFORM_ALLOCATION_H_
diff --git a/runtime/platform/atomic.h b/runtime/platform/atomic.h
index 7a966f5..98bc900 100644
--- a/runtime/platform/atomic.h
+++ b/runtime/platform/atomic.h
@@ -100,14 +100,18 @@
   bool compare_exchange_weak(
       T& expected,  // NOLINT
       T desired,
-      std::memory_order order = std::memory_order_acq_rel) {
-    return value_.compare_exchange_weak(expected, desired, order, order);
+      std::memory_order success_order = std::memory_order_acq_rel,
+      std::memory_order failure_order = std::memory_order_seq_cst) {
+    return value_.compare_exchange_weak(expected, desired, success_order,
+                                        failure_order);
   }
   bool compare_exchange_strong(
       T& expected,  // NOLINT
       T desired,
-      std::memory_order order = std::memory_order_acq_rel) {
-    return value_.compare_exchange_strong(expected, desired, order, order);
+      std::memory_order success_order = std::memory_order_acq_rel,
+      std::memory_order failure_order = std::memory_order_seq_cst) {
+    return value_.compare_exchange_strong(expected, desired, success_order,
+                                          failure_order);
   }
 
   // Require explicit loads and stores.
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 1796c33..79b6a6b 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -339,17 +339,17 @@
 // Verify that host and target architectures match, we cannot
 // have a 64 bit Dart VM generating 32 bit code or vice-versa.
 #if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)
-#if !defined(ARCH_IS_64_BIT)
+#if !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
 #error Mismatched Host/Target architectures.
-#endif  // !defined(ARCH_IS_64_BIT)
+#endif  // !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
 #elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
 #if defined(HOST_ARCH_X64) && defined(TARGET_ARCH_ARM)
 // This is simarm_x64, which is the only case where host/target architecture
-// mismatch is allowed.
+// mismatch is allowed. Unless, we're running FFI unit tests.
 #define IS_SIMARM_X64 1
-#elif !defined(ARCH_IS_32_BIT)
+#elif !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
 #error Mismatched Host/Target architectures.
-#endif  // !defined(ARCH_IS_32_BIT)
+#endif  // !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
 #endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
 
 // Determine whether we will be using the simulator.
@@ -374,12 +374,6 @@
 #error Unknown architecture.
 #endif
 
-#if defined(ARCH_IS_32_BIT) || defined(IS_SIMARM_X64)
-#define TARGET_ARCH_IS_32_BIT 1
-#elif defined(ARCH_IS_64_BIT)
-#define TARGET_ARCH_IS_64_BIT 1
-#endif
-
 #if !defined(TARGET_OS_ANDROID) && !defined(TARGET_OS_FUCHSIA) &&              \
     !defined(TARGET_OS_MACOS_IOS) && !defined(TARGET_OS_LINUX) &&              \
     !defined(TARGET_OS_MACOS) && !defined(TARGET_OS_WINDOWS)
diff --git a/runtime/platform/growable_array.h b/runtime/platform/growable_array.h
index b604ea4..9c906f6 100644
--- a/runtime/platform/growable_array.h
+++ b/runtime/platform/growable_array.h
@@ -240,12 +240,12 @@
  public:
   template <class T>
   static inline T* Alloc(intptr_t len) {
-    return reinterpret_cast<T*>(malloc(len * sizeof(T)));
+    return reinterpret_cast<T*>(dart::malloc(len * sizeof(T)));
   }
 
   template <class T>
   static inline T* Realloc(T* old_array, intptr_t old_len, intptr_t new_len) {
-    return reinterpret_cast<T*>(realloc(old_array, new_len * sizeof(T)));
+    return reinterpret_cast<T*>(dart::realloc(old_array, new_len * sizeof(T)));
   }
 
   template <class T>
@@ -254,14 +254,13 @@
   }
 };
 
-class EmptyBase {};
-
 template <typename T>
-class MallocGrowableArray : public BaseGrowableArray<T, EmptyBase, Malloc> {
+class MallocGrowableArray
+    : public BaseGrowableArray<T, MallocAllocated, Malloc> {
  public:
   explicit MallocGrowableArray(intptr_t initial_capacity)
-      : BaseGrowableArray<T, EmptyBase, Malloc>(initial_capacity, NULL) {}
-  MallocGrowableArray() : BaseGrowableArray<T, EmptyBase, Malloc>(NULL) {}
+      : BaseGrowableArray<T, MallocAllocated, Malloc>(initial_capacity, NULL) {}
+  MallocGrowableArray() : BaseGrowableArray<T, MallocAllocated, Malloc>(NULL) {}
 };
 
 }  // namespace dart
diff --git a/runtime/platform/hashmap.cc b/runtime/platform/hashmap.cc
index 88c521e..730b94e 100644
--- a/runtime/platform/hashmap.cc
+++ b/runtime/platform/hashmap.cc
@@ -157,9 +157,6 @@
 void SimpleHashMap::Initialize(uint32_t capacity) {
   ASSERT(dart::Utils::IsPowerOfTwo(capacity));
   map_ = new Entry[capacity];
-  if (map_ == NULL) {
-    OUT_OF_MEMORY();
-  }
   capacity_ = capacity;
   occupancy_ = 0;
 }
diff --git a/runtime/platform/platform_sources.gni b/runtime/platform/platform_sources.gni
index 02f23fb..bef56fe 100644
--- a/runtime/platform/platform_sources.gni
+++ b/runtime/platform/platform_sources.gni
@@ -6,6 +6,7 @@
 # components.
 platform_sources = [
   "address_sanitizer.h",
+  "allocation.cc",
   "allocation.h",
   "assert.cc",
   "assert.h",
diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc
index 5d08892..104fe76 100644
--- a/runtime/platform/text_buffer.cc
+++ b/runtime/platform/text_buffer.cc
@@ -114,9 +114,6 @@
 TextBuffer::TextBuffer(intptr_t buf_size) {
   ASSERT(buf_size > 0);
   buffer_ = reinterpret_cast<char*>(malloc(buf_size));
-  if (buffer_ == nullptr) {
-    OUT_OF_MEMORY();
-  }
   capacity_ = buf_size;
   Clear();
 }
@@ -139,9 +136,6 @@
   if (remaining <= len) {
     intptr_t new_size = capacity_ + Utils::Maximum(capacity_, len + 1);
     char* new_buf = reinterpret_cast<char*>(realloc(buffer_, new_size));
-    if (new_buf == nullptr) {
-      OUT_OF_MEMORY();
-    }
     buffer_ = new_buf;
     capacity_ = new_size;
   }
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index 6314265..dc10160 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -4,6 +4,8 @@
 
 #include "platform/utils.h"
 
+#include "platform/allocation.h"
+
 namespace dart {
 
 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
diff --git a/runtime/platform/utils_macos.cc b/runtime/platform/utils_macos.cc
index f0ccf53f..a801746 100644
--- a/runtime/platform/utils_macos.cc
+++ b/runtime/platform/utils_macos.cc
@@ -25,9 +25,6 @@
     len = n;
   }
   char* result = reinterpret_cast<char*>(malloc(len + 1));
-  if (result == NULL) {
-    return NULL;
-  }
   result[len] = '\0';
   return reinterpret_cast<char*>(memmove(result, s, len));
 #else   // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ...
diff --git a/runtime/platform/utils_win.cc b/runtime/platform/utils_win.cc
index 6cfe4e0..7ba2ec8 100644
--- a/runtime/platform/utils_win.cc
+++ b/runtime/platform/utils_win.cc
@@ -6,6 +6,7 @@
 #if defined(HOST_OS_WINDOWS)
 
 #include <io.h>  // NOLINT
+#include "platform/allocation.h"
 #include "platform/utils.h"
 
 namespace dart {
@@ -19,9 +20,6 @@
     len = n;
   }
   char* result = reinterpret_cast<char*>(malloc(len + 1));
-  if (result == NULL) {
-    return NULL;
-  }
   result[len] = '\0';
   return reinterpret_cast<char*>(memmove(result, s, len));
 }
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
index 11c1a33..5f18af8 100644
--- a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--dwarf-stack-traces --save-debugging-info=async_lazy_debug.so --lazy-async-stacks --no-causal-async-stacks
+//
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_lazy_debug.so --lazy-async-stacks --no-use-bare-instructions
 
 import 'dart:async';
 import 'dart:io';
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_test.dart
index 3155257..26805f1 100644
--- a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_test.dart
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_lazy_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--lazy-async-stacks --no-causal-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:async';
 
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
index f65de84..c9dbb09 100644
--- a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--dwarf-stack-traces --save-debugging-info=async_no_causal_debug.so --no-causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_no_causal_debug.so --no-lazy-async-stacks
 
 import 'dart:async';
 import 'dart:io';
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_test.dart
index 7cc8cf0..84848c9 100644
--- a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_test.dart
+++ b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_no_causal_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--no-lazy-async-stacks
 
 import 'dart:async';
 
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart
deleted file mode 100644
index cdb783a..0000000
--- a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_non_symbolic_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--dwarf-stack-traces --save-debugging-info=async_causal_debug.so --causal-async-stacks --no-lazy-async-stacks
-
-import 'dart:async';
-import 'dart:io';
-
-import 'utils.dart';
-
-Future<void> main(List<String> args) async {
-  // We won't have access to the debugging info file on Android.
-  if (Platform.isAndroid) return;
-
-  await doTestsCausal('async_causal_debug.so');
-}
diff --git a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_test.dart b/runtime/tests/vm/dart/causal_stacks/async_throws_stack_test.dart
deleted file mode 100644
index 6d25d36..0000000
--- a/runtime/tests/vm/dart/causal_stacks/async_throws_stack_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
-
-import 'dart:async';
-
-import 'utils.dart';
-
-Future<void> main(List<String> args) async => await doTestsCausal();
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 6b3b6e6..73ffe1d 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -13,12 +13,12 @@
 // Test functions:
 
 Future<void> throwSync() {
-  throw '';
+  throw 'throw from throwSync';
 }
 
 Future<void> throwAsync() async {
   await 0;
-  throw '';
+  throw 'throw from throwAsync';
 }
 
 // ----
@@ -170,6 +170,14 @@
   ]);
 }
 
+// ----
+// Scenario: Future.whenComplete:
+// ----
+
+Future futureSyncWhenComplete() {
+  return Future.sync(throwAsync).whenComplete(() => 'nop');
+}
+
 // Helpers:
 
 // We want lines that either start with a frame index or an async gap marker.
@@ -277,477 +285,7 @@
 // Test "Suites":
 // ----
 
-// For: --causal-async-stacks
-Future<void> doTestsCausal([String? debugInfoFilename]) async {
-  final allYieldExpected = const <String>[
-    r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'^#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      allYield2 \(.*/utils.dart:34(:9)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#3      allYield \(.*/utils.dart:29(:9)?\)$',
-    r'^<asynchronous suspension>$',
-  ];
-  await doTestAwait(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final noYieldsExpected = const <String>[
-    r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'^#1      noYields3 \(.*/utils.dart:54(:3)?\)$',
-    r'^#2      noYields2 \(.*/utils.dart:50(:9)?\)$',
-    r'^#3      noYields \(.*/utils.dart:46(:9)?\)$',
-  ];
-  await doTestAwait(
-      noYields,
-      noYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      noYields,
-      noYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      noYields,
-      noYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final mixedYieldsExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      mixedYields3 \(.*/utils.dart:70(:10)?\)$',
-    r'^#2      mixedYields2 \(.*/utils.dart:66(:9)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#3      mixedYields \(.*/utils.dart:61(:9)?\)$',
-  ];
-  await doTestAwait(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final syncSuffixExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      syncSuffix3 \(.*/utils.dart:86(:10)?\)$',
-    r'^#2      syncSuffix2 \(.*/utils.dart:82(:9)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#3      syncSuffix \(.*/utils.dart:77(:9)?\)$',
-  ];
-  await doTestAwait(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final nonAsyncNoStackExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      nonAsyncNoStack2.<anonymous closure> ',
-    r'^#2      _RootZone.runUnary ',
-    r'^#3      _FutureListener.handleValue ',
-    r'^#4      Future._propagateToListeners.handleValueCallback ',
-    r'^#5      Future._propagateToListeners ',
-    r'^#6      Future._completeWithValue ',
-    r'^#7      Future._asyncCompleteWithValue.<anonymous closure> ',
-    r'^#8      _microtaskLoop ',
-    r'^#9      _startMicrotaskLoop ',
-    r'^#10     _runPendingImmediateCallback ',
-    r'^#11     _RawReceivePortImpl._handleMessage ',
-  ];
-  await doTestAwait(
-      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-  await doTestAwaitThen(
-      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-  await doTestAwaitCatchError(
-      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-
-  final asyncStarThrowSyncExpected = const <String>[
-    r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'^#1      asyncStarThrowSync \(.*/utils.dart:112(:11)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      awaitEveryAsyncStarThrowSync \(.+\)$',
-  ];
-  await doTestAwait(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^#3      doTestAwait \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitThen \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitCatchError \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-
-  final asyncStarThrowAsyncExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:11)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      awaitEveryAsyncStarThrowAsync \(.+\)$',
-  ];
-  await doTestAwait(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^#3      doTestAwait \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitThen \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitCatchError \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-
-  final listenAsyncStartExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:11)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      listenAsyncStarThrowAsync \(.+/utils.dart:132(:27)?\)$',
-  ];
-  await doTestAwait(
-      listenAsyncStarThrowAsync,
-      listenAsyncStartExpected +
-          const <String>[
-            r'^#3      doTestAwait \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      listenAsyncStarThrowAsync,
-      listenAsyncStartExpected +
-          const <String>[
-            r'^#3      doTestAwaitThen \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      listenAsyncStarThrowAsync,
-      listenAsyncStartExpected +
-          const <String>[
-            r'^#3      doTestAwaitCatchError \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-
-  final customErrorZoneExpected = const <String>[
-    r'#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
-    r'<asynchronous suspension>$',
-    r'#2      allYield2 \(.*/utils.dart:34(:9)?\)$',
-    r'<asynchronous suspension>$',
-    r'#3      allYield \(.*/utils.dart:29(:9)?\)$',
-    r'<asynchronous suspension>$',
-    r'#4      customErrorZone.<anonymous closure> \(.*/utils.dart:144(:11)?\)$',
-    r'#5      _rootRun ',
-    r'#6      _CustomZone.run ',
-    r'#7      _runZoned ',
-    r'#8      runZonedGuarded ',
-    r'#9      customErrorZone \(.*/utils.dart:143(:3)?\)$',
-  ];
-  await doTestAwait(
-      customErrorZone,
-      customErrorZoneExpected +
-          const <String>[
-            r'#10     doTestAwait ',
-            r'#11     doTestsCausal ',
-            r'<asynchronous suspension>$',
-            r'#12     main \(.+\)$',
-            r'#13     _startIsolate.<anonymous closure> ',
-            r'#14     _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      customErrorZone,
-      customErrorZoneExpected +
-          const <String>[
-            r'#10     doTestAwaitThen ',
-            r'#11     doTestsCausal ',
-            r'<asynchronous suspension>$',
-            r'#12     main \(.+\)$',
-            r'#13     _startIsolate.<anonymous closure> ',
-            r'#14     _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      customErrorZone,
-      customErrorZoneExpected +
-          const <String>[
-            r'#10     doTestAwaitCatchError ',
-            r'#11     doTestsCausal ',
-            r'<asynchronous suspension>$',
-            r'#12     main \(.+\)$',
-            r'#13     _startIsolate.<anonymous closure> ',
-            r'#14     _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final awaitTimeoutExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^^<asynchronous suspension>$',
-    r'^#1      awaitTimeout ',
-  ];
-  await doTestAwait(
-      awaitTimeout,
-      awaitTimeoutExpected +
-          const <String>[
-            r'^#2      doTestAwait ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitTimeout,
-      awaitTimeoutExpected +
-          const <String>[
-            r'^#2      doTestAwaitThen ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitTimeout,
-      awaitTimeoutExpected +
-          const <String>[
-            r'^#2      doTestAwaitCatchError ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final awaitWaitExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^^<asynchronous suspension>$',
-    r'^#1      awaitWait ',
-  ];
-  await doTestAwait(
-      awaitWait,
-      awaitWaitExpected +
-          const <String>[
-            r'^#2      doTestAwait ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitWait,
-      awaitWaitExpected +
-          const <String>[
-            r'^#2      doTestAwaitThen ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitWait,
-      awaitWaitExpected +
-          const <String>[
-            r'^#2      doTestAwaitCatchError ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-}
-
-// For: --no-causal-async-stacks --no-lazy-async-stacks
+// For: --no-lazy-async-stacks
 Future<void> doTestsNoCausalNoLazy([String? debugInfoFilename]) async {
   final allYieldExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -1065,12 +603,10 @@
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
   ];
-  await doTestAwait(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
-  await doTestAwaitThen(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+  await doTestAwait(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
+  await doTestAwaitThen(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
   await doTestAwaitCatchError(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+      awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
 
   final awaitWaitExpected = const <String>[
     r'#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1084,12 +620,28 @@
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
   ];
-  await doTestAwait(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
-  await doTestAwaitThen(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+  await doTestAwait(awaitWait, awaitWaitExpected, debugInfoFilename);
+  await doTestAwaitThen(awaitWait, awaitWaitExpected, debugInfoFilename);
+  await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+  {
+    final expected = const <String>[
+      r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+      r'^#1      _RootZone.runUnary ',
+      r'^#2      _FutureListener.handleValue ',
+      r'^#3      Future._propagateToListeners.handleValueCallback ',
+      r'^#4      Future._propagateToListeners ',
+      r'^#5      Future.(_addListener|_prependListeners).<anonymous closure> ',
+      r'^#6      _microtaskLoop ',
+      r'^#7      _startMicrotaskLoop ',
+      r'^#8      _runPendingImmediateCallback ',
+      r'^#9      _RawReceivePortImpl._handleMessage ',
+    ];
+    await doTestAwait(futureSyncWhenComplete, expected, debugInfoFilename);
+    await doTestAwaitThen(futureSyncWhenComplete, expected, debugInfoFilename);
+    await doTestAwaitCatchError(
+        futureSyncWhenComplete, expected, debugInfoFilename);
+  }
 }
 
 // For: --lazy-async-stacks
@@ -1355,7 +907,7 @@
   final awaitTimeoutExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
     r'^<asynchronous suspension>$',
-    r'^#1      Future.timeout.<anonymous closure> \(dart:async/future_impl.dart\)$',
+    r'^#1      Future.timeout.<anonymous closure> \(dart:async/future_impl.dart',
     r'^<asynchronous suspension>$',
     r'^#2      awaitTimeout ',
     r'^<asynchronous suspension>$',
@@ -1381,12 +933,12 @@
           ],
       debugInfoFilename);
   await doTestAwaitCatchError(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+      awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
 
   final awaitWaitExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
     r'^<asynchronous suspension>$',
-    r'^#1      Future.wait.<anonymous closure> \(dart:async/future.dart\)$',
+    r'^#1      Future.wait.<anonymous closure> \(dart:async/future.dart',
     r'^<asynchronous suspension>$',
     r'^#2      awaitWait ',
     r'^<asynchronous suspension>$',
@@ -1411,6 +963,34 @@
             r'^<asynchronous suspension>$',
           ],
       debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+  await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+  {
+    final expected = const <String>[
+      r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+      r'^<asynchronous suspension>$',
+    ];
+    await doTestAwait(
+        futureSyncWhenComplete,
+        expected +
+            const <String>[
+              r'^#1      doTestAwait ',
+              r'^<asynchronous suspension>$',
+              r'^#2      doTestsLazy ',
+              r'^<asynchronous suspension>$',
+              r'^#3      main ',
+              r'^<asynchronous suspension>$',
+            ],
+        debugInfoFilename);
+    await doTestAwaitThen(
+        futureSyncWhenComplete,
+        expected +
+            const <String>[
+              r'^#1      doTestAwaitThen.<anonymous closure> ',
+              r'^<asynchronous suspension>$',
+            ],
+        debugInfoFilename);
+    await doTestAwaitCatchError(
+        futureSyncWhenComplete, expected, debugInfoFilename);
+  }
 }
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_prologue_test.dart b/runtime/tests/vm/dart/entrypoints/tearoff_prologue_test.dart
deleted file mode 100644
index 2cf7278..0000000
--- a/runtime/tests/vm/dart/entrypoints/tearoff_prologue_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// No type checks are removed here, but we can skip the argument count check.
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
-
-import "package:expect/expect.dart";
-import "common.dart";
-
-class C<T> {
-  @NeverInline
-  @pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
-  @pragma("vm:entry-point")
-  void samir1(T x) {
-    if (x == -1) {
-      throw "oh no";
-    }
-  }
-}
-
-void run(void Function(int) test, int i) {
-  test(i);
-}
-
-main(List<String> args) {
-  var c = new C<int>();
-  var f = c.samir1;
-
-  const int iterations = benchmarkMode ? 100000000 : 100;
-  for (int i = 0; i < iterations; ++i) {
-    run(f, i);
-  }
-
-  entryPoint.expectChecked(iterations);
-  tearoffEntryPoint.expectUnchecked(iterations);
-}
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_test.dart b/runtime/tests/vm/dart/entrypoints/tearoff_test.dart
deleted file mode 100644
index d0bd88a..0000000
--- a/runtime/tests/vm/dart/entrypoints/tearoff_test.dart
+++ /dev/null
@@ -1,38 +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.
-//
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
-
-// Test that typed calls against tearoffs go into the unchecked entrypoint.
-
-import "package:expect/expect.dart";
-import "common.dart";
-
-class C<T> {
-  @NeverInline
-  @pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
-  @pragma("vm:entry-point")
-  void target1(T x, String y) {
-    Expect.notEquals(x, -1);
-    Expect.equals(y, "foo");
-  }
-}
-
-void run(void Function(int, String) fn, int i) {
-  fn(i, "foo");
-}
-
-main(List<String> args) {
-  var f = (new C<int>()).target1;
-
-  const int iterations = benchmarkMode ? 100000000 : 100;
-  for (int i = 0; i < iterations; ++i) {
-    run(f, i);
-  }
-
-  entryPoint.expectChecked(iterations);
-  tearoffEntryPoint.expectUnchecked(iterations);
-}
diff --git a/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart b/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
new file mode 100644
index 0000000..f2e8a70
--- /dev/null
+++ b/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--enable-isolate-groups --disable-heap-verification
+
+import 'dart:async';
+import 'dart:ffi';
+import 'dart:io';
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
+import '../../../../../tests/ffi/dylib_utils.dart';
+
+final bool isAOT = Platform.executable.contains('dart_precompiled_runtime');
+final bool isolateGropusEnabled =
+    Platform.executableArguments.contains('--enable-isolate-groups');
+final sdkRoot = Platform.script.resolve('../../../../../');
+
+class Isolate extends Struct {}
+
+abstract class FfiBindings {
+  static final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+  static final IGH_MsanUnpoison = ffiTestFunctions.lookupFunction<
+      Pointer<Isolate> Function(Pointer<Void>, IntPtr),
+      Pointer<Isolate> Function(Pointer<Void>, int)>('IGH_MsanUnpoison');
+
+  static final IGH_CreateIsolate = ffiTestFunctions.lookupFunction<
+      Pointer<Isolate> Function(Pointer<Utf8>, Pointer<Void>),
+      Pointer<Isolate> Function(
+          Pointer<Utf8>, Pointer<Void>)>('IGH_CreateIsolate');
+
+  static final IGH_StartIsolate = ffiTestFunctions.lookupFunction<
+      Pointer<Void> Function(Pointer<Isolate>, Int64, Pointer<Utf8>,
+          Pointer<Utf8>, IntPtr, Int64, Int64),
+      Pointer<Void> Function(Pointer<Isolate>, int, Pointer<Utf8>,
+          Pointer<Utf8>, int, int, int)>('IGH_StartIsolate');
+
+  static final Dart_CurrentIsolate = DynamicLibrary.executable()
+      .lookupFunction<Pointer<Isolate> Function(), Pointer<Isolate> Function()>(
+          "Dart_CurrentIsolate");
+
+  static final Dart_IsolateData = DynamicLibrary.executable().lookupFunction<
+      Pointer<Isolate> Function(Pointer<Isolate>),
+      Pointer<Isolate> Function(Pointer<Isolate>)>("Dart_IsolateData");
+
+  static final Dart_PostInteger = DynamicLibrary.executable()
+      .lookupFunction<IntPtr Function(Int64, Int64), int Function(int, int)>(
+          "Dart_PostInteger");
+
+  static Pointer<Isolate> createLightweightIsolate(
+      String name, Pointer<Void> peer) {
+    final cname = Utf8.toUtf8(name);
+    IGH_MsanUnpoison(cname.cast(), name.length + 10);
+    try {
+      final isolate = IGH_CreateIsolate(cname, peer);
+      Expect.isTrue(isolate.address != 0);
+      return isolate;
+    } finally {
+      free(cname);
+    }
+  }
+
+  static void invokeTopLevelAndRunLoopAsync(
+      Pointer<Isolate> isolate, SendPort sendPort, String name,
+      {bool? errorsAreFatal, SendPort? onError, SendPort? onExit}) {
+    final dartScriptUri = sdkRoot.resolve(
+        'runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart');
+    final dartScript = dartScriptUri.toString();
+    final libraryUri = Utf8.toUtf8(dartScript);
+    IGH_MsanUnpoison(libraryUri.cast(), dartScript.length + 1);
+    final functionName = Utf8.toUtf8(name);
+    IGH_MsanUnpoison(functionName.cast(), name.length + 1);
+
+    IGH_StartIsolate(
+        isolate,
+        sendPort.nativePort,
+        libraryUri,
+        functionName,
+        errorsAreFatal == false ? 0 : 1,
+        onError != null ? onError.nativePort : 0,
+        onExit != null ? onExit.nativePort : 0);
+
+    free(libraryUri);
+    free(functionName);
+  }
+}
+
+void scheduleAsyncInvocation(void fun()) {
+  final rp = RawReceivePort();
+  rp.handler = (_) {
+    try {
+      fun();
+    } finally {
+      rp.close();
+    }
+  };
+  rp.sendPort.send(null);
+}
+
+Future withPeerPointer(fun(Pointer<Void> peer)) async {
+  final Pointer<Void> peer = Utf8.toUtf8('abc').cast();
+  FfiBindings.IGH_MsanUnpoison(peer.cast(), 'abc'.length + 1);
+  try {
+    await fun(peer);
+  } catch (e, s) {
+    print('Exception: $e\nStack:$s');
+    rethrow;
+  } finally {
+    // The shutdown callback is called before the exit listeners are notified, so
+    // we can validate that a->x has been changed.
+    Expect.isTrue(Utf8.fromUtf8(peer.cast()).startsWith('xb'));
+
+    // The cleanup callback is called after after notifying exit listeners. So we
+    // wait a little here to ensure the write of the callback has arrived.
+    await Future.delayed(const Duration(milliseconds: 100));
+    Expect.equals('xbz', Utf8.fromUtf8(peer.cast()));
+    free(peer);
+  }
+}
+
+@pragma('vm:entry-point')
+void childTestIsolateData(int mainPort) {
+  final peerIsolateData =
+      FfiBindings.Dart_IsolateData(FfiBindings.Dart_CurrentIsolate());
+  FfiBindings.Dart_PostInteger(mainPort, peerIsolateData.address);
+}
+
+Future testIsolateData() async {
+  await withPeerPointer((Pointer<Void> peer) async {
+    final rp = ReceivePort();
+    final exit = ReceivePort();
+    final isolate = FfiBindings.createLightweightIsolate('debug-name', peer);
+    FfiBindings.invokeTopLevelAndRunLoopAsync(
+        isolate, rp.sendPort, 'childTestIsolateData',
+        onExit: exit.sendPort);
+
+    Expect.equals(peer.address, await rp.first);
+    await exit.first;
+
+    exit.close();
+    rp.close();
+  });
+}
+
+@pragma('vm:entry-point')
+void childTestMultipleErrors(int mainPort) {
+  scheduleAsyncInvocation(() {
+    for (int i = 0; i < 10; ++i) {
+      scheduleAsyncInvocation(() => throw 'error-$i');
+    }
+  });
+}
+
+Future testMultipleErrors() async {
+  await withPeerPointer((Pointer<Void> peer) async {
+    final rp = ReceivePort();
+    final accumulatedErrors = <dynamic>[];
+    final errors = ReceivePort()..listen(accumulatedErrors.add);
+    final exit = ReceivePort();
+    final isolate = FfiBindings.createLightweightIsolate('debug-name', peer);
+    FfiBindings.invokeTopLevelAndRunLoopAsync(
+        isolate, rp.sendPort, 'childTestMultipleErrors',
+        errorsAreFatal: false, onError: errors.sendPort, onExit: exit.sendPort);
+    await exit.first;
+    Expect.equals(10, accumulatedErrors.length);
+    for (int i = 0; i < 10; ++i) {
+      Expect.equals('error-$i', accumulatedErrors[i][0]);
+      Expect.isTrue(
+          accumulatedErrors[i][1].contains('childTestMultipleErrors'));
+    }
+
+    exit.close();
+    errors.close();
+    rp.close();
+  });
+}
+
+@pragma('vm:entry-point')
+void childTestFatalError(int mainPort) {
+  scheduleAsyncInvocation(() {
+    scheduleAsyncInvocation(() => throw 'error-0');
+    scheduleAsyncInvocation(() => throw 'error-1');
+  });
+}
+
+Future testFatalError() async {
+  await withPeerPointer((Pointer<Void> peer) async {
+    final rp = ReceivePort();
+    final accumulatedErrors = <dynamic>[];
+    final errors = ReceivePort()..listen(accumulatedErrors.add);
+    final exit = ReceivePort();
+    final isolate = FfiBindings.createLightweightIsolate('debug-name', peer);
+    FfiBindings.invokeTopLevelAndRunLoopAsync(
+        isolate, rp.sendPort, 'childTestFatalError',
+        errorsAreFatal: true, onError: errors.sendPort, onExit: exit.sendPort);
+    await exit.first;
+    Expect.equals(1, accumulatedErrors.length);
+    Expect.equals('error-0', accumulatedErrors[0][0]);
+    Expect.contains('childTestFatalError', accumulatedErrors[0][1]);
+
+    exit.close();
+    errors.close();
+    rp.close();
+  });
+}
+
+Future testAot() async {
+  await testIsolateData();
+  await testMultipleErrors();
+  await testFatalError();
+}
+
+Future testNotSupported() async {
+  dynamic exception;
+  try {
+    FfiBindings.createLightweightIsolate('debug-name', Pointer.fromAddress(0));
+  } catch (e) {
+    exception = e;
+  }
+  Expect.contains(
+      'Lightweight isolates are only implemented in AOT mode and need to be '
+      'explicitly enabled by passing --enable-isolate-groups.',
+      exception.toString());
+}
+
+Future testJit() async {
+  dynamic exception;
+  try {
+    FfiBindings.createLightweightIsolate('debug-name', Pointer.fromAddress(0));
+  } catch (e) {
+    exception = e;
+  }
+  Expect.contains(
+      'Lightweight isolates are not yet ready in JIT mode', exception);
+}
+
+Future main(args) async {
+  if (!isolateGropusEnabled) {
+    await testNotSupported();
+    return;
+  }
+  if (isAOT) {
+    await testAot();
+  } else {
+    await testJit();
+  }
+}
diff --git a/runtime/tests/vm/dart/regress40189_test.dart b/runtime/tests/vm/dart/regress40189_test.dart
index 9f30e0c..f857e5b 100644
--- a/runtime/tests/vm/dart/regress40189_test.dart
+++ b/runtime/tests/vm/dart/regress40189_test.dart
@@ -1,7 +1,8 @@
 // Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--lazy-async-stacks --no-causal-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import "package:expect/expect.dart";
 
diff --git a/runtime/tests/vm/dart/regress_44342_test.dart b/runtime/tests/vm/dart/regress_44342_test.dart
new file mode 100644
index 0000000..98514fc
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44342_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--deterministic --optimization_counter_threshold=100
+
+// Verifies that class of a constant participates in CHA decisions.
+// Regression test for https://github.com/dart-lang/sdk/issues/44342.
+
+import 'package:expect/expect.dart';
+
+class A {
+  const A();
+
+  int foo() => 3;
+
+  @pragma("vm:never-inline")
+  int bar() => foo();
+}
+
+class B extends A {}
+
+class C extends A {
+  const C();
+
+  int foo() => 4;
+}
+
+A x = B();
+A y = const C();
+
+main() {
+  for (int i = 0; i < 200; ++i) {
+    // Optimize A.bar() with inlined A.foo().
+    int result = x.bar();
+    Expect.equals(3, result);
+  }
+  int result = y.bar();
+  Expect.equals(4, result);
+}
diff --git a/runtime/tests/vm/dart/scavenger_abort_2_test.dart b/runtime/tests/vm/dart/scavenger_abort_2_test.dart
new file mode 100644
index 0000000..e3183da
--- /dev/null
+++ b/runtime/tests/vm/dart/scavenger_abort_2_test.dart
@@ -0,0 +1,288 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:expect/expect.dart";
+
+// The sizes of these classes are co-prime multiples of the allocation unit to
+// increase the likelihood that scavenging fails from fragmentation.
+
+// header + 13 fields = 7 allocation units
+class A {
+  dynamic field1;
+  dynamic field2;
+  dynamic field3;
+  dynamic field4;
+  dynamic field5;
+  dynamic field6;
+  dynamic field7;
+  dynamic field8;
+  dynamic field9;
+  dynamic field10;
+  dynamic field11;
+  dynamic field12;
+  dynamic field13;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return field1 +
+        field2 +
+        field3 +
+        field4 +
+        field5 +
+        field6 +
+        field7 +
+        field8 +
+        field9 +
+        field10 +
+        field11 +
+        field12 +
+        field13;
+  }
+}
+
+// header + 17 fields = 9 allocation units
+class B {
+  dynamic field1;
+  dynamic field2;
+  dynamic field3;
+  dynamic field4;
+  dynamic field5;
+  dynamic field6;
+  dynamic field7;
+  dynamic field8;
+  dynamic field9;
+  dynamic field10;
+  dynamic field11;
+  dynamic field12;
+  dynamic field13;
+  dynamic field14;
+  dynamic field15;
+  dynamic field16;
+  dynamic field17;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return field1 +
+        field2 +
+        field3 +
+        field4 +
+        field5 +
+        field6 +
+        field7 +
+        field8 +
+        field9 +
+        field10 +
+        field11 +
+        field12 +
+        field13 +
+        field14 +
+        field15 +
+        field16 +
+        field17;
+  }
+}
+
+// header + 19 fields = 10 allocation units
+class C {
+  dynamic field1;
+  dynamic field2;
+  dynamic field3;
+  dynamic field4;
+  dynamic field5;
+  dynamic field6;
+  dynamic field7;
+  dynamic field8;
+  dynamic field9;
+  dynamic field10;
+  dynamic field11;
+  dynamic field12;
+  dynamic field13;
+  dynamic field14;
+  dynamic field15;
+  dynamic field16;
+  dynamic field17;
+  dynamic field18;
+  dynamic field19;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return field1 +
+        field2 +
+        field3 +
+        field4 +
+        field5 +
+        field6 +
+        field7 +
+        field8 +
+        field9 +
+        field10 +
+        field11 +
+        field12 +
+        field13 +
+        field14 +
+        field15 +
+        field16 +
+        field17 +
+        field18 +
+        field19;
+  }
+}
+
+class Old {
+  dynamic next;
+  dynamic new1;
+  dynamic new2;
+  dynamic new3;
+  dynamic new4;
+  dynamic new5;
+  dynamic new6;
+  dynamic new7;
+  dynamic new8;
+  dynamic new9;
+  dynamic new10;
+  dynamic new11;
+  dynamic new12;
+  dynamic new13;
+  dynamic new14;
+  dynamic new15;
+  dynamic new16;
+  dynamic new17;
+  dynamic new18;
+  dynamic new19;
+  dynamic new20;
+  dynamic new21;
+  dynamic new22;
+  dynamic new23;
+  dynamic new24;
+  dynamic new25;
+  dynamic new26;
+  dynamic new27;
+  dynamic new28;
+  dynamic new29;
+  dynamic new30;
+  dynamic new31;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return new1 +
+        new2 +
+        new3 +
+        new4 +
+        new5 +
+        new6 +
+        new7 +
+        new8 +
+        new9 +
+        new10 +
+        new11 +
+        new12 +
+        new13 +
+        new14 +
+        new15 +
+        new16 +
+        new17 +
+        new18 +
+        new19 +
+        new20 +
+        new21 +
+        new22 +
+        new23 +
+        new24 +
+        new25 +
+        new26 +
+        new27 +
+        new28 +
+        new29 +
+        new30 +
+        new31;
+  }
+}
+
+fill(old) {
+  // Note the allocation order is different from the field order. The objects
+  // will be scavenged in field order, causing the objects to be rearranged to
+  // produce new-space fragmentation.
+  old.new1 = new C();
+  old.new4 = new C();
+  old.new7 = new C();
+  old.new10 = new C();
+  old.new13 = new C();
+  old.new16 = new C();
+
+  old.new2 = new B();
+  old.new5 = new B();
+  old.new8 = new B();
+  old.new11 = new B();
+  old.new14 = new B();
+  old.new17 = new B();
+
+  old.new3 = new A();
+  old.new6 = new A();
+  old.new9 = new A();
+  old.new12 = new A();
+  old.new15 = new A();
+  old.new18 = new A();
+}
+
+makeOld() {
+  // 2/4 MB worth of Old.
+  print("PHASE1");
+  var head;
+  for (var i = 0; i < 16384; i++) {
+    var old = new Old();
+    old.next = head;
+    head = old;
+  }
+
+  // 32/64 MB worth of new objects, all directly reachable from the
+  // remembered set.
+  print("PHASE2");
+  for (var old = head; old != null; old = old.next) {
+    fill(old);
+  }
+
+  print("PHASE3");
+  return head;
+}
+
+main(List<String> argsIn) async {
+  if (argsIn.contains("--testee")) {
+    // Trigger OOM.
+    // Must read the fields to prevent the writes from being optimized away. If
+    // the writes are optimized away, most of the tree is collectible right away
+    // and we timeout instead of triggering OOM.
+    print(makeOld());
+    return;
+  }
+
+  var exec = Platform.executable;
+  var args = Platform.executableArguments +
+      [
+        "--new_gen_semi_max_size=4" /*MB*/,
+        "--old_gen_heap_size=15" /*MB*/,
+        "--verbose_gc",
+        "--verify_store_buffer",
+        Platform.script.toFilePath(),
+        "--testee"
+      ];
+  print("+ $exec ${args.join(' ')}");
+
+  var result = await Process.run(exec, args);
+  print("Command stdout:");
+  print(result.stdout);
+  print("Command stderr:");
+  print(result.stderr);
+
+  Expect.equals(255, result.exitCode,
+      "Should see runtime exception error code, not SEGV");
+
+  Expect.isTrue(
+      result.stderr.contains("Unhandled exception:\nOut of Memory") ||
+          result.stderr.contains("Unhandled exception:\r\nOut of Memory"),
+      "Should see the Dart OutOfMemoryError");
+
+  Expect.isFalse(result.stderr.contains("error: Out of memory"),
+      "Should not see the C++ OUT_OF_MEMORY()");
+}
diff --git a/runtime/tests/vm/dart/strict_null_safety_checks_in_weak_mode_test.dart b/runtime/tests/vm/dart/strict_null_safety_checks_in_weak_mode_test.dart
new file mode 100644
index 0000000..b70a3d4
--- /dev/null
+++ b/runtime/tests/vm/dart/strict_null_safety_checks_in_weak_mode_test.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test verifies that with --strict_null_safety_checks runtime casts and
+// required parameters have strong mode semantics in weak mode.
+// Derived from tests/language/nnbd/subtyping/type_casts_strong_test.dart
+// and tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart.
+
+// VMOptions=--strict_null_safety_checks --optimization_counter_threshold=10 --deterministic
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+
+class C {}
+
+class W<T> {
+  @pragma('vm:never-inline')
+  asT(arg) => arg as T;
+
+  @pragma('vm:never-inline')
+  asNullableT(arg) => arg as T?;
+
+  @pragma('vm:never-inline')
+  asXT(arg) => arg as X<T>;
+
+  @pragma('vm:never-inline')
+  asNullableXT(arg) => arg as X<T>?;
+
+  @pragma('vm:never-inline')
+  asXNullableT(arg) => arg as X<T?>;
+}
+
+class X<T> {}
+
+class Y {}
+
+class Z extends Y {}
+
+testCasts() {
+  // Testing 'arg as T', T = Y
+  final wy = new W<Y>();
+  wy.asT(new Y());
+  wy.asT(new Z());
+  Expect.throwsTypeError(() {
+    wy.asT(null);
+  });
+  Expect.throwsTypeError(() {
+    wy.asT(new C());
+  });
+
+  // Testing 'arg as T?', T = Y
+  wy.asNullableT(new Y());
+  wy.asNullableT(new Z());
+  wy.asNullableT(null);
+  Expect.throwsTypeError(() {
+    wy.asNullableT(new C());
+  });
+
+  // Testing 'arg as X<T>', T = Y
+  wy.asXT(new X<Y>());
+  wy.asXT(new X<Z>());
+  Expect.throwsTypeError(() {
+    wy.asXT(null);
+  });
+  Expect.throwsTypeError(() {
+    wy.asXT(new X<dynamic>());
+  });
+  Expect.throwsTypeError(() {
+    wy.asXT(new X<Y?>());
+  });
+
+  // Testing 'arg as X<T>?', T = Y
+  wy.asNullableXT(new X<Y>());
+  wy.asNullableXT(new X<Z>());
+  wy.asNullableXT(null);
+  Expect.throwsTypeError(() {
+    wy.asNullableXT(new X<dynamic>());
+  });
+  Expect.throwsTypeError(() {
+    wy.asNullableXT(new X<Y?>());
+  });
+
+  // Testing 'arg as X<T?>', T = Y
+  wy.asXNullableT(new X<Y>());
+  wy.asXNullableT(new X<Z>());
+  wy.asXNullableT(new X<Y?>());
+  Expect.throwsTypeError(() {
+    wy.asXNullableT(null);
+  });
+  Expect.throwsTypeError(() {
+    wy.asXNullableT(new X<dynamic>());
+  });
+
+  // Testing 'arg as X<T>', T = Y?
+  final wny = new W<Y?>();
+  wny.asXT(new X<Y>());
+  wny.asXT(new X<Z>());
+  wny.asXT(new X<Y?>());
+  Expect.throwsTypeError(() {
+    wny.asXT(null);
+  });
+  Expect.throwsTypeError(() {
+    wny.asXT(new X<dynamic>());
+  });
+}
+
+func(String q0, {bool p3 = false, required int p1, required String p2}) => "";
+
+testRequiredParameters() {
+  dynamic f = func;
+
+  // Invalid: Subtype may not redeclare optional parameters as required.
+  Expect.throwsTypeError(() {
+    Function(
+      String p0, {
+      required int p1,
+      String p2,
+    }) t2 = f;
+  });
+
+  // Invalid: Subtype may not declare new required named parameters.
+  Expect.throwsTypeError(() {
+    Function(
+      String p0, {
+      required int p1,
+    }) t3 = f;
+  });
+
+  // Invalid: Invocation with explicit null required named argument.
+  Expect.throwsTypeError(() {
+    f("", p1: null, p2: null);
+  });
+  Expect.throwsTypeError(() {
+    Function.apply(f, [""], {#p1: null, #p2: null});
+  });
+
+  // Invalid: Invocation that omits a required named argument.
+  Expect.throwsNoSuchMethodError(() {
+    f("", p1: 100);
+  });
+  Expect.throwsNoSuchMethodError(() {
+    Function.apply(f, [""], {#p1: 100});
+  });
+}
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    testCasts();
+    testRequiredParameters();
+  }
+}
diff --git a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
index 11c1a33..5f18af8 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_non_symbolic_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--dwarf-stack-traces --save-debugging-info=async_lazy_debug.so --lazy-async-stacks --no-causal-async-stacks
+//
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_lazy_debug.so --lazy-async-stacks --no-use-bare-instructions
 
 import 'dart:async';
 import 'dart:io';
diff --git a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_test.dart b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_test.dart
index 3155257..26805f1 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_test.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_lazy_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--lazy-async-stacks --no-causal-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'dart:async';
 
diff --git a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
index f65de84..c9dbb09 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_non_symbolic_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--dwarf-stack-traces --save-debugging-info=async_no_causal_debug.so --no-causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--dwarf-stack-traces --save-debugging-info=async_no_causal_debug.so --no-lazy-async-stacks
 
 import 'dart:async';
 import 'dart:io';
diff --git a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_test.dart b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_test.dart
index 7cc8cf0..84848c9 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_test.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_no_causal_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-causal-async-stacks --no-lazy-async-stacks
+//
+// VMOptions=--no-lazy-async-stacks
 
 import 'dart:async';
 
diff --git a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_non_symbolic_test.dart b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_non_symbolic_test.dart
deleted file mode 100644
index cdb783a..0000000
--- a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_non_symbolic_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--dwarf-stack-traces --save-debugging-info=async_causal_debug.so --causal-async-stacks --no-lazy-async-stacks
-
-import 'dart:async';
-import 'dart:io';
-
-import 'utils.dart';
-
-Future<void> main(List<String> args) async {
-  // We won't have access to the debugging info file on Android.
-  if (Platform.isAndroid) return;
-
-  await doTestsCausal('async_causal_debug.so');
-}
diff --git a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_test.dart b/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_test.dart
deleted file mode 100644
index 6d25d36..0000000
--- a/runtime/tests/vm/dart_2/causal_stacks/async_throws_stack_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
-
-import 'dart:async';
-
-import 'utils.dart';
-
-Future<void> main(List<String> args) async => await doTestsCausal();
diff --git a/runtime/tests/vm/dart_2/causal_stacks/utils.dart b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
index 743986d..192984f 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -13,12 +13,12 @@
 // Test functions:
 
 Future<void> throwSync() {
-  throw '';
+  throw 'throw from throwSync';
 }
 
 Future<void> throwAsync() async {
   await 0;
-  throw '';
+  throw 'throw from throwAsync';
 }
 
 // ----
@@ -170,6 +170,14 @@
   ]);
 }
 
+// ----
+// Scenario: Future.whenComplete:
+// ----
+
+Future futureSyncWhenComplete() {
+  return Future.sync(throwAsync).whenComplete(() => 'nop');
+}
+
 // Helpers:
 
 // We want lines that either start with a frame index or an async gap marker.
@@ -277,477 +285,7 @@
 // Test "Suites":
 // ----
 
-// For: --causal-async-stacks
-Future<void> doTestsCausal([String debugInfoFilename]) async {
-  final allYieldExpected = const <String>[
-    r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'^#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      allYield2 \(.*/utils.dart:34(:9)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#3      allYield \(.*/utils.dart:29(:9)?\)$',
-    r'^<asynchronous suspension>$',
-  ];
-  await doTestAwait(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      allYield,
-      allYieldExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final noYieldsExpected = const <String>[
-    r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'^#1      noYields3 \(.*/utils.dart:54(:3)?\)$',
-    r'^#2      noYields2 \(.*/utils.dart:50(:9)?\)$',
-    r'^#3      noYields \(.*/utils.dart:46(:9)?\)$',
-  ];
-  await doTestAwait(
-      noYields,
-      noYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      noYields,
-      noYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      noYields,
-      noYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final mixedYieldsExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      mixedYields3 \(.*/utils.dart:70(:10)?\)$',
-    r'^#2      mixedYields2 \(.*/utils.dart:66(:9)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#3      mixedYields \(.*/utils.dart:61(:9)?\)$',
-  ];
-  await doTestAwait(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      mixedYields,
-      mixedYieldsExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final syncSuffixExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      syncSuffix3 \(.*/utils.dart:86(:10)?\)$',
-    r'^#2      syncSuffix2 \(.*/utils.dart:82(:9)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#3      syncSuffix \(.*/utils.dart:77(:9)?\)$',
-  ];
-  await doTestAwait(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^#4      doTestAwait ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^#4      doTestAwaitThen ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      syncSuffix,
-      syncSuffixExpected +
-          const <String>[
-            r'^#4      doTestAwaitCatchError ',
-            r'^#5      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#6      main ',
-            r'^#7      _startIsolate.<anonymous closure> ',
-            r'^#8      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final nonAsyncNoStackExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      nonAsyncNoStack2.<anonymous closure> ',
-    r'^#2      _RootZone.runUnary ',
-    r'^#3      _FutureListener.handleValue ',
-    r'^#4      Future._propagateToListeners.handleValueCallback ',
-    r'^#5      Future._propagateToListeners ',
-    r'^#6      Future._completeWithValue ',
-    r'^#7      Future._asyncCompleteWithValue.<anonymous closure> ',
-    r'^#8      _microtaskLoop ',
-    r'^#9      _startMicrotaskLoop ',
-    r'^#10     _runPendingImmediateCallback ',
-    r'^#11     _RawReceivePortImpl._handleMessage ',
-  ];
-  await doTestAwait(
-      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-  await doTestAwaitThen(
-      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-  await doTestAwaitCatchError(
-      nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-
-  final asyncStarThrowSyncExpected = const <String>[
-    r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'^#1      asyncStarThrowSync \(.*/utils.dart:112(:11)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      awaitEveryAsyncStarThrowSync \(.+\)$',
-  ];
-  await doTestAwait(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^#3      doTestAwait \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitThen \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowSync,
-      asyncStarThrowSyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitCatchError \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-
-  final asyncStarThrowAsyncExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:11)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      awaitEveryAsyncStarThrowAsync \(.+\)$',
-  ];
-  await doTestAwait(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^#3      doTestAwait \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitThen \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowAsync,
-      asyncStarThrowAsyncExpected +
-          const <String>[
-            r'^#3      doTestAwaitCatchError \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-
-  final listenAsyncStartExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:11)?\)$',
-    r'^<asynchronous suspension>$',
-    r'^#2      listenAsyncStarThrowAsync \(.+/utils.dart:132(:27)?\)$',
-  ];
-  await doTestAwait(
-      listenAsyncStarThrowAsync,
-      listenAsyncStartExpected +
-          const <String>[
-            r'^#3      doTestAwait \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      listenAsyncStarThrowAsync,
-      listenAsyncStartExpected +
-          const <String>[
-            r'^#3      doTestAwaitThen \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      listenAsyncStarThrowAsync,
-      listenAsyncStartExpected +
-          const <String>[
-            r'^#3      doTestAwaitCatchError \(.+\)$',
-            r'^#4      doTestsCausal \(.+\)$',
-            r'^<asynchronous suspension>$',
-            r'^#5      main \(.+\)$',
-            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
-            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
-          ],
-      debugInfoFilename);
-
-  final customErrorZoneExpected = const <String>[
-    r'#0      throwSync \(.*/utils.dart:16(:3)?\)$',
-    r'#1      allYield3 \(.*/utils.dart:39(:3)?\)$',
-    r'<asynchronous suspension>$',
-    r'#2      allYield2 \(.*/utils.dart:34(:9)?\)$',
-    r'<asynchronous suspension>$',
-    r'#3      allYield \(.*/utils.dart:29(:9)?\)$',
-    r'<asynchronous suspension>$',
-    r'#4      customErrorZone.<anonymous closure> \(.*/utils.dart:144(:11)?\)$',
-    r'#5      _rootRun ',
-    r'#6      _CustomZone.run ',
-    r'#7      _runZoned ',
-    r'#8      runZonedGuarded ',
-    r'#9      customErrorZone \(.*/utils.dart:143(:3)?\)$',
-  ];
-  await doTestAwait(
-      customErrorZone,
-      customErrorZoneExpected +
-          const <String>[
-            r'#10     doTestAwait ',
-            r'#11     doTestsCausal ',
-            r'<asynchronous suspension>$',
-            r'#12     main \(.+\)$',
-            r'#13     _startIsolate.<anonymous closure> ',
-            r'#14     _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      customErrorZone,
-      customErrorZoneExpected +
-          const <String>[
-            r'#10     doTestAwaitThen ',
-            r'#11     doTestsCausal ',
-            r'<asynchronous suspension>$',
-            r'#12     main \(.+\)$',
-            r'#13     _startIsolate.<anonymous closure> ',
-            r'#14     _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      customErrorZone,
-      customErrorZoneExpected +
-          const <String>[
-            r'#10     doTestAwaitCatchError ',
-            r'#11     doTestsCausal ',
-            r'<asynchronous suspension>$',
-            r'#12     main \(.+\)$',
-            r'#13     _startIsolate.<anonymous closure> ',
-            r'#14     _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final awaitTimeoutExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^^<asynchronous suspension>$',
-    r'^#1      awaitTimeout ',
-  ];
-  await doTestAwait(
-      awaitTimeout,
-      awaitTimeoutExpected +
-          const <String>[
-            r'^#2      doTestAwait ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitTimeout,
-      awaitTimeoutExpected +
-          const <String>[
-            r'^#2      doTestAwaitThen ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitTimeout,
-      awaitTimeoutExpected +
-          const <String>[
-            r'^#2      doTestAwaitCatchError ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-
-  final awaitWaitExpected = const <String>[
-    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
-    r'^^<asynchronous suspension>$',
-    r'^#1      awaitWait ',
-  ];
-  await doTestAwait(
-      awaitWait,
-      awaitWaitExpected +
-          const <String>[
-            r'^#2      doTestAwait ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitThen(
-      awaitWait,
-      awaitWaitExpected +
-          const <String>[
-            r'^#2      doTestAwaitThen ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitWait,
-      awaitWaitExpected +
-          const <String>[
-            r'^#2      doTestAwaitCatchError ',
-            r'^#3      doTestsCausal ',
-            r'^<asynchronous suspension>$',
-            r'^#4      main \(.+\)$',
-            r'^#5      _startIsolate.<anonymous closure> ',
-            r'^#6      _RawReceivePortImpl._handleMessage ',
-          ],
-      debugInfoFilename);
-}
-
-// For: --no-causal-async-stacks --no-lazy-async-stacks
+// For: --no-lazy-async-stacks
 Future<void> doTestsNoCausalNoLazy([String debugInfoFilename]) async {
   final allYieldExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
@@ -1065,12 +603,10 @@
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
   ];
-  await doTestAwait(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
-  await doTestAwaitThen(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+  await doTestAwait(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
+  await doTestAwaitThen(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
   await doTestAwaitCatchError(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+      awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
 
   final awaitWaitExpected = const <String>[
     r'#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1084,12 +620,28 @@
     r'^#8      _runPendingImmediateCallback ',
     r'^#9      _RawReceivePortImpl._handleMessage ',
   ];
-  await doTestAwait(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
-  await doTestAwaitThen(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+  await doTestAwait(awaitWait, awaitWaitExpected, debugInfoFilename);
+  await doTestAwaitThen(awaitWait, awaitWaitExpected, debugInfoFilename);
+  await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+  {
+    final expected = const <String>[
+      r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+      r'^#1      _RootZone.runUnary ',
+      r'^#2      _FutureListener.handleValue ',
+      r'^#3      Future._propagateToListeners.handleValueCallback ',
+      r'^#4      Future._propagateToListeners ',
+      r'^#5      Future.(_addListener|_prependListeners).<anonymous closure> ',
+      r'^#6      _microtaskLoop ',
+      r'^#7      _startMicrotaskLoop ',
+      r'^#8      _runPendingImmediateCallback ',
+      r'^#9      _RawReceivePortImpl._handleMessage ',
+    ];
+    await doTestAwait(futureSyncWhenComplete, expected, debugInfoFilename);
+    await doTestAwaitThen(futureSyncWhenComplete, expected, debugInfoFilename);
+    await doTestAwaitCatchError(
+        futureSyncWhenComplete, expected, debugInfoFilename);
+  }
 }
 
 // For: --lazy-async-stacks
@@ -1355,7 +907,7 @@
   final awaitTimeoutExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
     r'^<asynchronous suspension>$',
-    r'^#1      Future.timeout.<anonymous closure> \(dart:async/future_impl.dart\)$',
+    r'^#1      Future.timeout.<anonymous closure> \(dart:async/future_impl.dart',
     r'^<asynchronous suspension>$',
     r'^#2      awaitTimeout ',
     r'^<asynchronous suspension>$',
@@ -1381,12 +933,12 @@
           ],
       debugInfoFilename);
   await doTestAwaitCatchError(
-      awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+      awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
 
   final awaitWaitExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
     r'^<asynchronous suspension>$',
-    r'^#1      Future.wait.<anonymous closure> \(dart:async/future.dart\)$',
+    r'^#1      Future.wait.<anonymous closure> \(dart:async/future.dart',
     r'^<asynchronous suspension>$',
     r'^#2      awaitWait ',
     r'^<asynchronous suspension>$',
@@ -1411,6 +963,34 @@
             r'^<asynchronous suspension>$',
           ],
       debugInfoFilename);
-  await doTestAwaitCatchError(
-      awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+  await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+  {
+    final expect = const <String>[
+      r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+      r'^<asynchronous suspension>$',
+    ];
+    await doTestAwait(
+        futureSyncWhenComplete,
+        expect +
+            const <String>[
+              r'^#1      doTestAwait ',
+              r'^<asynchronous suspension>$',
+              r'^#2      doTestsLazy ',
+              r'^<asynchronous suspension>$',
+              r'^#3      main ',
+              r'^<asynchronous suspension>$',
+            ],
+        debugInfoFilename);
+    await doTestAwaitThen(
+        futureSyncWhenComplete,
+        expect +
+            const <String>[
+              r'^#1      doTestAwaitThen.<anonymous closure> ',
+              r'^<asynchronous suspension>$',
+            ],
+        debugInfoFilename);
+    await doTestAwaitCatchError(
+        futureSyncWhenComplete, expect, debugInfoFilename);
+  }
 }
diff --git a/runtime/tests/vm/dart_2/entrypoints/tearoff_prologue_test.dart b/runtime/tests/vm/dart_2/entrypoints/tearoff_prologue_test.dart
deleted file mode 100644
index 2cf7278..0000000
--- a/runtime/tests/vm/dart_2/entrypoints/tearoff_prologue_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// No type checks are removed here, but we can skip the argument count check.
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
-
-import "package:expect/expect.dart";
-import "common.dart";
-
-class C<T> {
-  @NeverInline
-  @pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
-  @pragma("vm:entry-point")
-  void samir1(T x) {
-    if (x == -1) {
-      throw "oh no";
-    }
-  }
-}
-
-void run(void Function(int) test, int i) {
-  test(i);
-}
-
-main(List<String> args) {
-  var c = new C<int>();
-  var f = c.samir1;
-
-  const int iterations = benchmarkMode ? 100000000 : 100;
-  for (int i = 0; i < iterations; ++i) {
-    run(f, i);
-  }
-
-  entryPoint.expectChecked(iterations);
-  tearoffEntryPoint.expectUnchecked(iterations);
-}
diff --git a/runtime/tests/vm/dart_2/entrypoints/tearoff_test.dart b/runtime/tests/vm/dart_2/entrypoints/tearoff_test.dart
deleted file mode 100644
index d0bd88a..0000000
--- a/runtime/tests/vm/dart_2/entrypoints/tearoff_test.dart
+++ /dev/null
@@ -1,38 +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.
-//
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
-// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
-
-// Test that typed calls against tearoffs go into the unchecked entrypoint.
-
-import "package:expect/expect.dart";
-import "common.dart";
-
-class C<T> {
-  @NeverInline
-  @pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
-  @pragma("vm:entry-point")
-  void target1(T x, String y) {
-    Expect.notEquals(x, -1);
-    Expect.equals(y, "foo");
-  }
-}
-
-void run(void Function(int, String) fn, int i) {
-  fn(i, "foo");
-}
-
-main(List<String> args) {
-  var f = (new C<int>()).target1;
-
-  const int iterations = benchmarkMode ? 100000000 : 100;
-  for (int i = 0; i < iterations; ++i) {
-    run(f, i);
-  }
-
-  entryPoint.expectChecked(iterations);
-  tearoffEntryPoint.expectUnchecked(iterations);
-}
diff --git a/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart b/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
new file mode 100644
index 0000000..0daead0
--- /dev/null
+++ b/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--enable-isolate-groups --disable-heap-verification
+
+import 'dart:async';
+import 'dart:ffi';
+import 'dart:io';
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
+import '../../../../../tests/ffi/dylib_utils.dart';
+
+final bool isAOT = Platform.executable.contains('dart_precompiled_runtime');
+final bool isolateGropusEnabled =
+    Platform.executableArguments.contains('--enable-isolate-groups');
+final sdkRoot = Platform.script.resolve('../../../../../');
+
+class Isolate extends Struct {}
+
+abstract class FfiBindings {
+  static final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+  static final IGH_MsanUnpoison = ffiTestFunctions.lookupFunction<
+      Pointer<Isolate> Function(Pointer<Void>, IntPtr),
+      Pointer<Isolate> Function(Pointer<Void>, int)>('IGH_MsanUnpoison');
+
+  static final IGH_CreateIsolate = ffiTestFunctions.lookupFunction<
+      Pointer<Isolate> Function(Pointer<Utf8>, Pointer<Void>),
+      Pointer<Isolate> Function(
+          Pointer<Utf8>, Pointer<Void>)>('IGH_CreateIsolate');
+
+  static final IGH_StartIsolate = ffiTestFunctions.lookupFunction<
+      Pointer<Void> Function(Pointer<Isolate>, Int64, Pointer<Utf8>,
+          Pointer<Utf8>, IntPtr, Int64, Int64),
+      Pointer<Void> Function(Pointer<Isolate>, int, Pointer<Utf8>,
+          Pointer<Utf8>, int, int, int)>('IGH_StartIsolate');
+
+  static final Dart_CurrentIsolate = DynamicLibrary.executable()
+      .lookupFunction<Pointer<Isolate> Function(), Pointer<Isolate> Function()>(
+          "Dart_CurrentIsolate");
+
+  static final Dart_IsolateData = DynamicLibrary.executable().lookupFunction<
+      Pointer<Isolate> Function(Pointer<Isolate>),
+      Pointer<Isolate> Function(Pointer<Isolate>)>("Dart_IsolateData");
+
+  static final Dart_PostInteger = DynamicLibrary.executable()
+      .lookupFunction<IntPtr Function(Int64, Int64), int Function(int, int)>(
+          "Dart_PostInteger");
+
+  static Pointer<Isolate> createLightweightIsolate(
+      String name, Pointer<Void> peer) {
+    final cname = Utf8.toUtf8(name);
+    IGH_MsanUnpoison(cname.cast(), name.length + 10);
+    try {
+      final isolate = IGH_CreateIsolate(cname, peer);
+      Expect.isTrue(isolate.address != 0);
+      return isolate;
+    } finally {
+      free(cname);
+    }
+  }
+
+  static void invokeTopLevelAndRunLoopAsync(
+      Pointer<Isolate> isolate, SendPort sendPort, String name,
+      {bool errorsAreFatal, SendPort onError, SendPort onExit}) {
+    final dartScriptUri = sdkRoot.resolve(
+        'runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart');
+    final dartScript = dartScriptUri.toString();
+    final libraryUri = Utf8.toUtf8(dartScript);
+    IGH_MsanUnpoison(libraryUri.cast(), dartScript.length + 1);
+    final functionName = Utf8.toUtf8(name);
+    IGH_MsanUnpoison(functionName.cast(), name.length + 1);
+
+    IGH_StartIsolate(
+        isolate,
+        sendPort.nativePort,
+        libraryUri,
+        functionName,
+        errorsAreFatal == false ? 0 : 1,
+        onError != null ? onError.nativePort : 0,
+        onExit != null ? onExit.nativePort : 0);
+
+    free(libraryUri);
+    free(functionName);
+  }
+}
+
+void scheduleAsyncInvocation(void fun()) {
+  final rp = RawReceivePort();
+  rp.handler = (_) {
+    try {
+      fun();
+    } finally {
+      rp.close();
+    }
+  };
+  rp.sendPort.send(null);
+}
+
+Future withPeerPointer(fun(Pointer<Void> peer)) async {
+  final Pointer<Void> peer = Utf8.toUtf8('abc').cast();
+  FfiBindings.IGH_MsanUnpoison(peer.cast(), 'abc'.length + 1);
+  try {
+    await fun(peer);
+  } catch (e, s) {
+    print('Exception: $e\nStack:$s');
+    rethrow;
+  } finally {
+    // The shutdown callback is called before the exit listeners are notified, so
+    // we can validate that a->x has been changed.
+    Expect.isTrue(Utf8.fromUtf8(peer.cast()).startsWith('xb'));
+
+    // The cleanup callback is called after after notifying exit listeners. So we
+    // wait a little here to ensure the write of the callback has arrived.
+    await Future.delayed(const Duration(milliseconds: 100));
+    Expect.equals('xbz', Utf8.fromUtf8(peer.cast()));
+    free(peer);
+  }
+}
+
+@pragma('vm:entry-point')
+void childTestIsolateData(int mainPort) {
+  final peerIsolateData =
+      FfiBindings.Dart_IsolateData(FfiBindings.Dart_CurrentIsolate());
+  FfiBindings.Dart_PostInteger(mainPort, peerIsolateData.address);
+}
+
+Future testIsolateData() async {
+  await withPeerPointer((Pointer<Void> peer) async {
+    final rp = ReceivePort();
+    final exit = ReceivePort();
+    final isolate = FfiBindings.createLightweightIsolate('debug-name', peer);
+    FfiBindings.invokeTopLevelAndRunLoopAsync(
+        isolate, rp.sendPort, 'childTestIsolateData',
+        onExit: exit.sendPort);
+
+    Expect.equals(peer.address, await rp.first);
+    await exit.first;
+
+    exit.close();
+    rp.close();
+  });
+}
+
+@pragma('vm:entry-point')
+void childTestMultipleErrors(int mainPort) {
+  scheduleAsyncInvocation(() {
+    for (int i = 0; i < 10; ++i) {
+      scheduleAsyncInvocation(() => throw 'error-$i');
+    }
+  });
+}
+
+Future testMultipleErrors() async {
+  await withPeerPointer((Pointer<Void> peer) async {
+    final rp = ReceivePort();
+    final accumulatedErrors = <dynamic>[];
+    final errors = ReceivePort()..listen(accumulatedErrors.add);
+    final exit = ReceivePort();
+    final isolate = FfiBindings.createLightweightIsolate('debug-name', peer);
+    FfiBindings.invokeTopLevelAndRunLoopAsync(
+        isolate, rp.sendPort, 'childTestMultipleErrors',
+        errorsAreFatal: false, onError: errors.sendPort, onExit: exit.sendPort);
+    await exit.first;
+    Expect.equals(10, accumulatedErrors.length);
+    for (int i = 0; i < 10; ++i) {
+      Expect.equals('error-$i', accumulatedErrors[i][0]);
+      Expect.isTrue(
+          accumulatedErrors[i][1].contains('childTestMultipleErrors'));
+    }
+
+    exit.close();
+    errors.close();
+    rp.close();
+  });
+}
+
+@pragma('vm:entry-point')
+void childTestFatalError(int mainPort) {
+  scheduleAsyncInvocation(() {
+    scheduleAsyncInvocation(() => throw 'error-0');
+    scheduleAsyncInvocation(() => throw 'error-1');
+  });
+}
+
+Future testFatalError() async {
+  await withPeerPointer((Pointer<Void> peer) async {
+    final rp = ReceivePort();
+    final accumulatedErrors = <dynamic>[];
+    final errors = ReceivePort()..listen(accumulatedErrors.add);
+    final exit = ReceivePort();
+    final isolate = FfiBindings.createLightweightIsolate('debug-name', peer);
+    FfiBindings.invokeTopLevelAndRunLoopAsync(
+        isolate, rp.sendPort, 'childTestFatalError',
+        errorsAreFatal: true, onError: errors.sendPort, onExit: exit.sendPort);
+    await exit.first;
+    Expect.equals(1, accumulatedErrors.length);
+    Expect.equals('error-0', accumulatedErrors[0][0]);
+    Expect.contains('childTestFatalError', accumulatedErrors[0][1]);
+
+    exit.close();
+    errors.close();
+    rp.close();
+  });
+}
+
+Future testAot() async {
+  await testIsolateData();
+  await testMultipleErrors();
+  await testFatalError();
+}
+
+Future testNotSupported() async {
+  dynamic exception;
+  try {
+    FfiBindings.createLightweightIsolate('debug-name', Pointer.fromAddress(0));
+  } catch (e) {
+    exception = e;
+  }
+  Expect.contains(
+      'Lightweight isolates are only implemented in AOT mode and need to be '
+      'explicitly enabled by passing --enable-isolate-groups.',
+      exception.toString());
+}
+
+Future testJit() async {
+  dynamic exception;
+  try {
+    FfiBindings.createLightweightIsolate('debug-name', Pointer.fromAddress(0));
+  } catch (e) {
+    exception = e;
+  }
+  Expect.contains(
+      'Lightweight isolates are not yet ready in JIT mode', exception);
+}
+
+Future main(args) async {
+  if (!isolateGropusEnabled) {
+    await testNotSupported();
+    return;
+  }
+  if (isAOT) {
+    await testAot();
+  } else {
+    await testJit();
+  }
+}
diff --git a/runtime/tests/vm/dart_2/regress40189_test.dart b/runtime/tests/vm/dart_2/regress40189_test.dart
index 9f30e0c..f857e5b 100644
--- a/runtime/tests/vm/dart_2/regress40189_test.dart
+++ b/runtime/tests/vm/dart_2/regress40189_test.dart
@@ -1,7 +1,8 @@
 // Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--lazy-async-stacks --no-causal-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import "package:expect/expect.dart";
 
diff --git a/runtime/tests/vm/dart_2/regress_44342_test.dart b/runtime/tests/vm/dart_2/regress_44342_test.dart
new file mode 100644
index 0000000..98514fc
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_44342_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--deterministic --optimization_counter_threshold=100
+
+// Verifies that class of a constant participates in CHA decisions.
+// Regression test for https://github.com/dart-lang/sdk/issues/44342.
+
+import 'package:expect/expect.dart';
+
+class A {
+  const A();
+
+  int foo() => 3;
+
+  @pragma("vm:never-inline")
+  int bar() => foo();
+}
+
+class B extends A {}
+
+class C extends A {
+  const C();
+
+  int foo() => 4;
+}
+
+A x = B();
+A y = const C();
+
+main() {
+  for (int i = 0; i < 200; ++i) {
+    // Optimize A.bar() with inlined A.foo().
+    int result = x.bar();
+    Expect.equals(3, result);
+  }
+  int result = y.bar();
+  Expect.equals(4, result);
+}
diff --git a/runtime/tests/vm/dart_2/scavenger_abort_2_test.dart b/runtime/tests/vm/dart_2/scavenger_abort_2_test.dart
new file mode 100644
index 0000000..e3183da
--- /dev/null
+++ b/runtime/tests/vm/dart_2/scavenger_abort_2_test.dart
@@ -0,0 +1,288 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:expect/expect.dart";
+
+// The sizes of these classes are co-prime multiples of the allocation unit to
+// increase the likelihood that scavenging fails from fragmentation.
+
+// header + 13 fields = 7 allocation units
+class A {
+  dynamic field1;
+  dynamic field2;
+  dynamic field3;
+  dynamic field4;
+  dynamic field5;
+  dynamic field6;
+  dynamic field7;
+  dynamic field8;
+  dynamic field9;
+  dynamic field10;
+  dynamic field11;
+  dynamic field12;
+  dynamic field13;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return field1 +
+        field2 +
+        field3 +
+        field4 +
+        field5 +
+        field6 +
+        field7 +
+        field8 +
+        field9 +
+        field10 +
+        field11 +
+        field12 +
+        field13;
+  }
+}
+
+// header + 17 fields = 9 allocation units
+class B {
+  dynamic field1;
+  dynamic field2;
+  dynamic field3;
+  dynamic field4;
+  dynamic field5;
+  dynamic field6;
+  dynamic field7;
+  dynamic field8;
+  dynamic field9;
+  dynamic field10;
+  dynamic field11;
+  dynamic field12;
+  dynamic field13;
+  dynamic field14;
+  dynamic field15;
+  dynamic field16;
+  dynamic field17;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return field1 +
+        field2 +
+        field3 +
+        field4 +
+        field5 +
+        field6 +
+        field7 +
+        field8 +
+        field9 +
+        field10 +
+        field11 +
+        field12 +
+        field13 +
+        field14 +
+        field15 +
+        field16 +
+        field17;
+  }
+}
+
+// header + 19 fields = 10 allocation units
+class C {
+  dynamic field1;
+  dynamic field2;
+  dynamic field3;
+  dynamic field4;
+  dynamic field5;
+  dynamic field6;
+  dynamic field7;
+  dynamic field8;
+  dynamic field9;
+  dynamic field10;
+  dynamic field11;
+  dynamic field12;
+  dynamic field13;
+  dynamic field14;
+  dynamic field15;
+  dynamic field16;
+  dynamic field17;
+  dynamic field18;
+  dynamic field19;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return field1 +
+        field2 +
+        field3 +
+        field4 +
+        field5 +
+        field6 +
+        field7 +
+        field8 +
+        field9 +
+        field10 +
+        field11 +
+        field12 +
+        field13 +
+        field14 +
+        field15 +
+        field16 +
+        field17 +
+        field18 +
+        field19;
+  }
+}
+
+class Old {
+  dynamic next;
+  dynamic new1;
+  dynamic new2;
+  dynamic new3;
+  dynamic new4;
+  dynamic new5;
+  dynamic new6;
+  dynamic new7;
+  dynamic new8;
+  dynamic new9;
+  dynamic new10;
+  dynamic new11;
+  dynamic new12;
+  dynamic new13;
+  dynamic new14;
+  dynamic new15;
+  dynamic new16;
+  dynamic new17;
+  dynamic new18;
+  dynamic new19;
+  dynamic new20;
+  dynamic new21;
+  dynamic new22;
+  dynamic new23;
+  dynamic new24;
+  dynamic new25;
+  dynamic new26;
+  dynamic new27;
+  dynamic new28;
+  dynamic new29;
+  dynamic new30;
+  dynamic new31;
+
+  // Prevent fields from being optimized away as write-only.
+  String toString() {
+    return new1 +
+        new2 +
+        new3 +
+        new4 +
+        new5 +
+        new6 +
+        new7 +
+        new8 +
+        new9 +
+        new10 +
+        new11 +
+        new12 +
+        new13 +
+        new14 +
+        new15 +
+        new16 +
+        new17 +
+        new18 +
+        new19 +
+        new20 +
+        new21 +
+        new22 +
+        new23 +
+        new24 +
+        new25 +
+        new26 +
+        new27 +
+        new28 +
+        new29 +
+        new30 +
+        new31;
+  }
+}
+
+fill(old) {
+  // Note the allocation order is different from the field order. The objects
+  // will be scavenged in field order, causing the objects to be rearranged to
+  // produce new-space fragmentation.
+  old.new1 = new C();
+  old.new4 = new C();
+  old.new7 = new C();
+  old.new10 = new C();
+  old.new13 = new C();
+  old.new16 = new C();
+
+  old.new2 = new B();
+  old.new5 = new B();
+  old.new8 = new B();
+  old.new11 = new B();
+  old.new14 = new B();
+  old.new17 = new B();
+
+  old.new3 = new A();
+  old.new6 = new A();
+  old.new9 = new A();
+  old.new12 = new A();
+  old.new15 = new A();
+  old.new18 = new A();
+}
+
+makeOld() {
+  // 2/4 MB worth of Old.
+  print("PHASE1");
+  var head;
+  for (var i = 0; i < 16384; i++) {
+    var old = new Old();
+    old.next = head;
+    head = old;
+  }
+
+  // 32/64 MB worth of new objects, all directly reachable from the
+  // remembered set.
+  print("PHASE2");
+  for (var old = head; old != null; old = old.next) {
+    fill(old);
+  }
+
+  print("PHASE3");
+  return head;
+}
+
+main(List<String> argsIn) async {
+  if (argsIn.contains("--testee")) {
+    // Trigger OOM.
+    // Must read the fields to prevent the writes from being optimized away. If
+    // the writes are optimized away, most of the tree is collectible right away
+    // and we timeout instead of triggering OOM.
+    print(makeOld());
+    return;
+  }
+
+  var exec = Platform.executable;
+  var args = Platform.executableArguments +
+      [
+        "--new_gen_semi_max_size=4" /*MB*/,
+        "--old_gen_heap_size=15" /*MB*/,
+        "--verbose_gc",
+        "--verify_store_buffer",
+        Platform.script.toFilePath(),
+        "--testee"
+      ];
+  print("+ $exec ${args.join(' ')}");
+
+  var result = await Process.run(exec, args);
+  print("Command stdout:");
+  print(result.stdout);
+  print("Command stderr:");
+  print(result.stderr);
+
+  Expect.equals(255, result.exitCode,
+      "Should see runtime exception error code, not SEGV");
+
+  Expect.isTrue(
+      result.stderr.contains("Unhandled exception:\nOut of Memory") ||
+          result.stderr.contains("Unhandled exception:\r\nOut of Memory"),
+      "Should see the Dart OutOfMemoryError");
+
+  Expect.isFalse(result.stderr.contains("error: Out of memory"),
+      "Should not see the C++ OUT_OF_MEMORY()");
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 16ee403..802cc8b 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -115,6 +115,7 @@
 
 [ $mode == debug ]
 cc/CorelibIsolateStartup: SkipByDesign # This is a benchmark that is not informative in debug mode.
+cc/SixtyThousandDartClasses: SkipSlow # Finalization of 64K classes is too slow in debug mode.
 cc/VerifyExplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
 cc/VerifyImplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
 dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
@@ -139,8 +140,24 @@
 [ $nnbd == legacy ]
 dart/*: SkipByDesign # Migrated tests are not supposed to run on non-NNBD bots.
 
+[ $runtime == vm ]
+dart/isolates/*: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart/issue_31959_31960_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart/sendandexit_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart/spawn_infinite_loop_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart/transferable_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart/transferable_throws_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart_2/isolates/*: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart_2/issue_31959_31960_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart_2/sendandexit_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart_2/spawn_infinite_loop_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart_2/transferable_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+dart_2/transferable_throws_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+
 [ $system == android ]
+dart/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # On android this test does not work due to not being able to identify library uri.
 dart/sdk_hash_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
+dart_2/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # On android this test does not work due to not being able to identify library uri.
 dart_2/sdk_hash_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
 
 [ $system == fuchsia ]
@@ -158,7 +175,9 @@
 [ $system == windows ]
 cc/CorelibCompilerStats: Skip
 dart/disassemble_determinism_test: Slow, Pass # Times out on slower bots.
+dart/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # https://dartbug.com/40579: Dart C API symbols not available.
 dart_2/disassemble_determinism_test: Slow, Pass # Times out on slower bots.
+dart_2/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # https://dartbug.com/40579: Dart C API symbols not available.
 
 [ $arch == ia32 && $mode == debug && $system == windows ]
 dart/transferable_test: Skip # This is performance test and somehow debug win ia32 bot's performance is unpredictable
@@ -181,11 +200,13 @@
 [ $builder_tag == obfuscated && $compiler == dartkp ]
 dart/extension_names_test: SkipByDesign # No demangling (obfuscated).
 dart/extension_unnamed_names_test: SkipByDesign # No demangling (obfuscated).
+dart/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # https://dartbug.com/44215: This test relies on non-obfuscated library uris.
 dart/optimized_stacktrace_line_and_column_test: SkipByDesign # Looks for filenames in stacktrace output
 dart/optimized_stacktrace_line_test: SkipByDesign # Looks for filenames in stacktrace output
 dart/regress_37382_test: SkipByDesign # Matches the type arguments names
 dart_2/extension_names_test: SkipByDesign # No demangling (obfuscated).
 dart_2/extension_unnamed_names_test: SkipByDesign # No demangling (obfuscated).
+dart_2/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # https://dartbug.com/44215: This test relies on non-obfuscated library uris.
 dart_2/optimized_stacktrace_line_and_column_test: SkipByDesign # Looks for filenames in stacktrace output
 dart_2/optimized_stacktrace_line_test: SkipByDesign # Looks for filenames in stacktrace output
 dart_2/regress_37382_test: SkipByDesign # Matches the type arguments names
@@ -327,12 +348,14 @@
 cc/Profiler_TrivialRecordAllocation: SkipByDesign
 cc/Profiler_TypedArrayAllocation: SkipByDesign
 cc/Service_Profile: SkipByDesign
+dart/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
 dart/isolates/thread_pool_test: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
 dart/regress_41971_test: SkipByDesign # dart:ffi is not supported on simulator
 dart/sdk_hash_test: SkipSlow # gen_kernel is slow to run on simarm
 dart/unboxed_param_args_descriptor_test: SkipByDesign # FFI helper not supported on simulator
 dart/unboxed_param_tear_off_test: SkipByDesign # FFI helper not supported on simulator
 dart/unboxed_param_test: SkipByDesign # FFI helper not supported on simulator
+dart_2/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
 dart_2/isolates/thread_pool_test: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
 dart_2/regress_41971_test: SkipByDesign # dart:ffi is not supported on simulator
 dart_2/sdk_hash_test: SkipSlow # gen_kernel is slow to run on simarm
diff --git a/runtime/tools/embedder_layering_check.py b/runtime/tools/embedder_layering_check.py
index d49b705..8e33bf0 100644
--- a/runtime/tools/embedder_layering_check.py
+++ b/runtime/tools/embedder_layering_check.py
@@ -20,7 +20,9 @@
 
 # Tests that don't match the simple case of *_test.cc.
 EXTRA_TEST_FILES = [
-    'runtime/bin/run_vm_tests.cc', 'runtime/vm/libfuzzer/dart_libfuzzer.cc'
+    'runtime/bin/run_vm_tests.cc',
+    'runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc',
+    'runtime/vm/libfuzzer/dart_libfuzzer.cc'
 ]
 
 
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 714de1b..6fca249 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -15,7 +15,6 @@
 import("../../sdk/lib/mirrors/mirrors_sources.gni")
 import("../../sdk/lib/typed_data/typed_data_sources.gni")
 import("../../sdk/lib/vmservice/vmservice_sources.gni")
-import("../../sdk/lib/wasm/wasm_sources.gni")
 import("../../sdk_args.gni")
 import("../../utils/compile_platform.gni")
 import("../bin/cli_sources.gni")
@@ -34,7 +33,6 @@
 import("../lib/profiler_sources.gni")
 import("../lib/typed_data_sources.gni")
 import("../lib/vmservice_sources.gni")
-import("../lib/wasm_sources.gni")
 import("../runtime_args.gni")
 import("compiler/compiler_sources.gni")
 import("heap/heap_sources.gni")
@@ -51,8 +49,10 @@
     libs = [
       "advapi32.lib",
       "shell32.lib",
-      "dbghelp.lib",
     ]
+    if (target_os != "winuwp") {
+      libs += [ "dbghelp.lib" ]
+    }
   } else {
     libs = [ "dl" ]
     if (!is_android) {
@@ -154,7 +154,7 @@
                internal_runtime_cc_files + isolate_runtime_cc_files +
                math_runtime_cc_files + mirrors_runtime_cc_files +
                typed_data_runtime_cc_files + vmservice_runtime_cc_files +
-               ffi_runtime_cc_files + wasm_runtime_cc_files
+               ffi_runtime_cc_files
   sources = [ "bootstrap.cc" ] + rebase_path(allsources, ".", "../lib")
   snapshot_sources = []
 }
@@ -180,10 +180,8 @@
       "$root_out_dir/vm_outline" + output_postfix + ".dill",
     ]
     args = [ "dart:core" ]
-    allow_causal_async_stacks = false
     args += [
       "-Ddart.vm.product=$is_product_flag",
-      "-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks",
       "-Ddart.isVM=true",
       "--enable-experiment=non-nullable",
       "--nnbd-agnostic",
diff --git a/runtime/vm/allocation.h b/runtime/vm/allocation.h
index 834b28b..fc4be72 100644
--- a/runtime/vm/allocation.h
+++ b/runtime/vm/allocation.h
@@ -54,10 +54,10 @@
   ZoneAllocated() {}
 
   // Implicitly allocate the object in the current zone.
-  void* operator new(uword size);
+  void* operator new(size_t size);
 
   // Allocate the object in the given zone, which must be the current zone.
-  void* operator new(uword size, Zone* zone);
+  void* operator new(size_t size, Zone* zone);
 
   // Ideally, the delete operator should be protected instead of
   // public, but unfortunately the compiler sometimes synthesizes
diff --git a/runtime/vm/base64.cc b/runtime/vm/base64.cc
index ec003ae..54e1ddc 100644
--- a/runtime/vm/base64.cc
+++ b/runtime/vm/base64.cc
@@ -4,6 +4,7 @@
 
 #include "vm/base64.h"
 
+#include "platform/allocation.h"
 #include "vm/os.h"
 
 namespace dart {
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index be59b16..a8c09ee 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -46,8 +46,6 @@
   // zones/handles in the API scope :
   // - Dart_RunLoop()
   // - IsolateSaver in Dart_NewNativePort
-  // Similarly, tracking async_stack_trace requires that we always reschedule
-  // on the same thread.
   // We probably need a mechanism to return to the specific thread only
   // for these specific cases. We should also determine if the embedder
   // should allow exiting an isolate with live state in zones/handles in
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index a1ca4cd..cf5a69a 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -270,7 +270,6 @@
   intptr_t kernel_buffer_size = file->Length();
   uint8_t* kernel_buffer =
       reinterpret_cast<uint8_t*>(malloc(kernel_buffer_size));
-  EXPECT(kernel_buffer != NULL);
   bool read_fully = file->ReadFully(kernel_buffer, kernel_buffer_size);
   EXPECT(read_fully);
   Dart_Handle result =
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index a6b8a6b..5d9d84b 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -134,11 +134,6 @@
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
   library.set_native_entry_symbol_resolver(symbol_resolver);
-
-  library = Library::WasmLibrary();
-  ASSERT(!library.IsNull());
-  library.set_native_entry_resolver(resolver);
-  library.set_native_entry_symbol_resolver(symbol_resolver);
 }
 
 bool Bootstrap::IsBootstrapResolver(Dart_NativeEntryResolver resolver) {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 8b15f7b..df3b7ec 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -58,6 +58,7 @@
   V(RawReceivePortImpl_get_id, 1)                                              \
   V(RawReceivePortImpl_get_sendport, 1)                                        \
   V(RawReceivePortImpl_closeInternal, 1)                                       \
+  V(RawReceivePortImpl_setActive, 2)                                           \
   V(SendPortImpl_get_id, 1)                                                    \
   V(SendPortImpl_get_hashcode, 1)                                              \
   V(SendPortImpl_sendInternal_, 2)                                             \
@@ -161,9 +162,6 @@
   V(AssertionError_throwNew, 3)                                                \
   V(AssertionError_throwNewSource, 4)                                          \
   V(Async_rethrow, 2)                                                          \
-  V(StackTrace_asyncStackTraceHelper, 1)                                       \
-  V(StackTrace_clearAsyncThreadStackTrace, 0)                                  \
-  V(StackTrace_setAsyncThreadStackTrace, 1)                                    \
   V(StackTrace_current, 0)                                                     \
   V(TypeError_throwNew, 4)                                                     \
   V(FallThroughError_throwNew, 1)                                              \
@@ -357,8 +355,8 @@
   V(LinkedHashMap_setUsedData, 2)                                              \
   V(LinkedHashMap_getDeletedKeys, 1)                                           \
   V(LinkedHashMap_setDeletedKeys, 2)                                           \
-  V(WeakProperty_new, 2)                                                       \
   V(WeakProperty_getKey, 1)                                                    \
+  V(WeakProperty_setKey, 2)                                                    \
   V(WeakProperty_getValue, 1)                                                  \
   V(WeakProperty_setValue, 2)                                                  \
   V(Uri_isWindowsPlatform, 0)                                                  \
@@ -420,20 +418,7 @@
   V(DartApiDLMinorVersion, 0)                                                  \
   V(DartNativeApiFunctionPointer, 1)                                           \
   V(TransferableTypedData_factory, 2)                                          \
-  V(TransferableTypedData_materialize, 1)                                      \
-  V(Wasm_initModule, 2)                                                        \
-  V(Wasm_describeModule, 1)                                                    \
-  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)                                                      \
-  V(Wasm_initMemoryFromInstance, 2)                                            \
-  V(Wasm_getMemoryPages, 1)                                                    \
-  V(Wasm_initFunction, 4)                                                      \
-  V(Wasm_callFunction, 2)
+  V(TransferableTypedData_materialize, 1)
 
 // List of bootstrap native entry points used in the dart:mirror library.
 #define MIRRORS_BOOTSTRAP_NATIVE_LIST(V)                                       \
diff --git a/runtime/vm/canonical_tables.cc b/runtime/vm/canonical_tables.cc
new file mode 100644
index 0000000..d5ab2ff
--- /dev/null
+++ b/runtime/vm/canonical_tables.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/canonical_tables.h"
+
+namespace dart {
+
+bool MetadataMapTraits::IsMatch(const Object& a, const Object& b) {
+  // In the absence of hot reload, this can just be an identity check. With
+  // reload, some old program elements may be retained by the stack, closures
+  // or mirrors, which are absent from the new version of the library's
+  // metadata table. This name-based matching fuzzy maps the old program
+  // elements to corresponding new elements, preserving the behavior of the old
+  // metaname+fields scheme.
+  if (a.IsLibrary() && b.IsLibrary()) {
+    const String& url_a = String::Handle(Library::Cast(a).url());
+    const String& url_b = String::Handle(Library::Cast(b).url());
+    return url_a.Equals(url_b);
+  } else if (a.IsClass() && b.IsClass()) {
+    const String& name_a = String::Handle(Class::Cast(a).Name());
+    const String& name_b = String::Handle(Class::Cast(b).Name());
+    return name_a.Equals(name_b);
+  } else if (a.IsFunction() && b.IsFunction()) {
+    const String& name_a = String::Handle(Function::Cast(a).name());
+    const String& name_b = String::Handle(Function::Cast(b).name());
+    if (!name_a.Equals(name_b)) {
+      return false;
+    }
+    const Object& owner_a = Object::Handle(Function::Cast(a).Owner());
+    const Object& owner_b = Object::Handle(Function::Cast(b).Owner());
+    return IsMatch(owner_a, owner_b);
+  } else if (a.IsField() && b.IsField()) {
+    const String& name_a = String::Handle(Field::Cast(a).name());
+    const String& name_b = String::Handle(Field::Cast(b).name());
+    if (!name_a.Equals(name_b)) {
+      return false;
+    }
+    const Object& owner_a = Object::Handle(Field::Cast(a).Owner());
+    const Object& owner_b = Object::Handle(Field::Cast(b).Owner());
+    return IsMatch(owner_a, owner_b);
+  } else if (a.IsTypeParameter() && b.IsTypeParameter()) {
+    const String& name_a = String::Handle(TypeParameter::Cast(a).name());
+    const String& name_b = String::Handle(TypeParameter::Cast(b).name());
+    if (!name_a.Equals(name_b)) {
+      return false;
+    }
+    const Object& owner_a = Object::Handle(TypeParameter::Cast(a).Owner());
+    const Object& owner_b = Object::Handle(TypeParameter::Cast(b).Owner());
+    return IsMatch(owner_a, owner_b);
+  }
+  return a.raw() == b.raw();
+}
+
+uword MetadataMapTraits::Hash(const Object& key) {
+  if (key.IsLibrary()) {
+    return String::Hash(Library::Cast(key).url());
+  } else if (key.IsClass()) {
+    return String::Hash(Class::Cast(key).Name());
+  } else if (key.IsFunction()) {
+    return CombineHashes(String::Hash(Function::Cast(key).name()),
+                         Hash(Object::Handle(Function::Cast(key).Owner())));
+  } else if (key.IsField()) {
+    return CombineHashes(String::Hash(Field::Cast(key).name()),
+                         Hash(Object::Handle(Field::Cast(key).Owner())));
+  } else if (key.IsTypeParameter()) {
+    return TypeParameter::Cast(key).Hash();
+  } else if (key.IsNamespace()) {
+    return Hash(Library::Handle(Namespace::Cast(key).target()));
+  }
+  UNREACHABLE();
+}
+
+}  // namespace dart
diff --git a/runtime/vm/canonical_tables.h b/runtime/vm/canonical_tables.h
index 69b79eb..f0c3d2b 100644
--- a/runtime/vm/canonical_tables.h
+++ b/runtime/vm/canonical_tables.h
@@ -254,6 +254,15 @@
 typedef UnorderedHashSet<CanonicalTypeArgumentsTraits>
     CanonicalTypeArgumentsSet;
 
+class MetadataMapTraits {
+ public:
+  static const char* Name() { return "MetadataMapTraits"; }
+  static bool ReportStats() { return false; }
+  static bool IsMatch(const Object& a, const Object& b);
+  static uword Hash(const Object& key);
+};
+typedef UnorderedHashMap<MetadataMapTraits> MetadataMap;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CANONICAL_TABLES_H_
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 556b548..175f985 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -303,8 +303,11 @@
     for (intptr_t i = 0; i < num_types; i++) {
       type_parameter ^= type_parameters.TypeAt(i);
       if (!type_parameter.IsFinalized()) {
-        type_parameter.set_index(type_parameter.index() + offset);
+        ASSERT(type_parameter.index() == i);
+        type_parameter.set_index(offset + i);
         type_parameter.SetIsFinalized();
+      } else {
+        ASSERT(type_parameter.index() == offset + i);
       }
       // The declaration of a type parameter is canonical.
       ASSERT(type_parameter.IsDeclaration());
@@ -821,8 +824,11 @@
     for (intptr_t i = 0; i < num_type_params; i++) {
       type_param ^= type_params.TypeAt(i);
       if (!type_param.IsFinalized()) {
+        ASSERT(type_param.index() == i);
         type_param.set_index(num_parent_type_params + i);
         type_param.SetIsFinalized();
+      } else {
+        ASSERT(type_param.index() == num_parent_type_params + i);
       }
       // The declaration of a type parameter is canonical.
       ASSERT(type_param.IsDeclaration());
@@ -956,13 +962,6 @@
     if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) {
       continue;
     }
-    if (function.is_static()) {
-      if (function.IsRedirectingFactory()) {
-        Type& type = Type::Handle(zone, function.RedirectionType());
-        type ^= FinalizeType(type);
-        function.SetRedirectionType(type);
-      }
-    }
   }
 }
 
@@ -1149,10 +1148,9 @@
 }
 
 ErrorPtr ClassFinalizer::AllocateFinalizeClass(const Class& cls) {
+  ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
   ASSERT(cls.is_finalized());
-  if (cls.is_allocate_finalized()) {
-    return Error::null();
-  }
+  ASSERT(!cls.is_allocate_finalized());
 
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
@@ -1201,7 +1199,10 @@
 }
 
 ErrorPtr ClassFinalizer::LoadClassMembers(const Class& cls) {
+  ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
   ASSERT(Thread::Current()->IsMutatorThread());
+  ASSERT(!cls.is_finalized());
+
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1502,7 +1503,7 @@
       if (old_cid != new_cid) {
         // Don't touch objects that are unchanged. In particular, Instructions,
         // which are write-protected.
-        obj->ptr()->SetClassId(new_cid);
+        obj->ptr()->SetClassIdUnsynchronized(new_cid);
       }
     }
   }
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 92faca0..8421944 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -23,7 +23,6 @@
   V(Function)                                                                  \
   V(ClosureData)                                                               \
   V(SignatureData)                                                             \
-  V(RedirectionData)                                                           \
   V(FfiTrampolineData)                                                         \
   V(Field)                                                                     \
   V(Script)                                                                    \
@@ -144,13 +143,6 @@
   V(DynamicLibrary)                                                            \
   V(Struct)
 
-#define CLASS_LIST_WASM(V)                                                     \
-  V(WasmInt32)                                                                 \
-  V(WasmInt64)                                                                 \
-  V(WasmFloat)                                                                 \
-  V(WasmDouble)                                                                \
-  V(WasmVoid)
-
 #define DART_CLASS_LIST_TYPED_DATA(V)                                          \
   V(Int8)                                                                      \
   V(Uint8)                                                                     \
@@ -202,10 +194,6 @@
   CLASS_LIST_FFI(DEFINE_OBJECT_KIND)
 #undef DEFINE_OBJECT_KIND
 
-#define DEFINE_OBJECT_KIND(clazz) k##clazz##Cid,
-  CLASS_LIST_WASM(DEFINE_OBJECT_KIND)
-#undef DEFINE_OBJECT_KIND
-
 #define DEFINE_OBJECT_KIND(clazz)                                              \
   kTypedData##clazz##Cid,                                                      \
   kTypedData##clazz##ViewCid,                                                  \
@@ -364,21 +352,29 @@
 }
 
 inline bool IsFfiTypeClassId(intptr_t index) {
-  // Make sure this is updated when new Ffi types are added.
-  COMPILE_ASSERT(kFfiNativeFunctionCid == kFfiPointerCid + 1 &&
-                 kFfiInt8Cid == kFfiPointerCid + 2 &&
-                 kFfiInt16Cid == kFfiPointerCid + 3 &&
-                 kFfiInt32Cid == kFfiPointerCid + 4 &&
-                 kFfiInt64Cid == kFfiPointerCid + 5 &&
-                 kFfiUint8Cid == kFfiPointerCid + 6 &&
-                 kFfiUint16Cid == kFfiPointerCid + 7 &&
-                 kFfiUint32Cid == kFfiPointerCid + 8 &&
-                 kFfiUint64Cid == kFfiPointerCid + 9 &&
-                 kFfiIntPtrCid == kFfiPointerCid + 10 &&
-                 kFfiFloatCid == kFfiPointerCid + 11 &&
-                 kFfiDoubleCid == kFfiPointerCid + 12 &&
-                 kFfiVoidCid == kFfiPointerCid + 13);
-  return (index >= kFfiPointerCid && index <= kFfiVoidCid);
+  switch (index) {
+    case kFfiPointerCid:
+    case kFfiNativeFunctionCid:
+#define CASE_FFI_CID(name) case kFfi##name##Cid:
+      CLASS_LIST_FFI_TYPE_MARKER(CASE_FFI_CID)
+#undef CASE_FFI_CID
+      return true;
+    default:
+      return false;
+  }
+  UNREACHABLE();
+}
+
+inline bool IsFfiPredefinedClassId(classid_t class_id) {
+  switch (class_id) {
+#define CASE_FFI_CID(name) case kFfi##name##Cid:
+    CLASS_LIST_FFI(CASE_FFI_CID)
+#undef CASE_FFI_CID
+    return true;
+    default:
+      return false;
+  }
+  UNREACHABLE();
 }
 
 inline bool IsFfiTypeIntClassId(intptr_t index) {
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 8068db1..529040e 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "platform/allocation.h"
 #include "platform/assert.h"
 #include "platform/atomic.h"
 #include "platform/utils.h"
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 7913553..895f537 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -99,7 +99,7 @@
                                     intptr_t size,
                                     bool is_canonical) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
-  uint32_t tags = 0;
+  uword tags = 0;
   tags = ObjectLayout::ClassIdTag::update(class_id, tags);
   tags = ObjectLayout::SizeTag::update(size, tags);
   tags = ObjectLayout::CanonicalBit::update(is_canonical, tags);
@@ -108,9 +108,6 @@
   tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
   tags = ObjectLayout::NewBit::update(false, tags);
   raw->ptr()->tags_ = tags;
-#if defined(HASH_IN_OBJECT_HEADER)
-  raw->ptr()->hash_ = 0;
-#endif
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -988,69 +985,6 @@
   }
 };
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-class RedirectionDataSerializationCluster : public SerializationCluster {
- public:
-  RedirectionDataSerializationCluster()
-      : SerializationCluster("RedirectionData") {}
-  ~RedirectionDataSerializationCluster() {}
-
-  void Trace(Serializer* s, ObjectPtr object) {
-    RedirectionDataPtr data = RedirectionData::RawCast(object);
-    objects_.Add(data);
-    PushFromTo(data);
-  }
-
-  void WriteAlloc(Serializer* s) {
-    s->WriteCid(kRedirectionDataCid);
-    const intptr_t count = objects_.length();
-    s->WriteUnsigned(count);
-    for (intptr_t i = 0; i < count; i++) {
-      RedirectionDataPtr data = objects_[i];
-      s->AssignRef(data);
-    }
-  }
-
-  void WriteFill(Serializer* s) {
-    const intptr_t count = objects_.length();
-    for (intptr_t i = 0; i < count; i++) {
-      RedirectionDataPtr data = objects_[i];
-      AutoTraceObject(data);
-      WriteFromTo(data);
-    }
-  }
-
- private:
-  GrowableArray<RedirectionDataPtr> objects_;
-};
-#endif  // !DART_PRECOMPILED_RUNTIME
-
-class RedirectionDataDeserializationCluster : public DeserializationCluster {
- public:
-  RedirectionDataDeserializationCluster()
-      : DeserializationCluster("RedirectionData") {}
-  ~RedirectionDataDeserializationCluster() {}
-
-  void ReadAlloc(Deserializer* d, bool is_canonical) {
-    start_index_ = d->next_index();
-    PageSpace* old_space = d->heap()->old_space();
-    const intptr_t count = d->ReadUnsigned();
-    for (intptr_t i = 0; i < count; i++) {
-      d->AssignRef(
-          AllocateUninitialized(old_space, RedirectionData::InstanceSize()));
-    }
-    stop_index_ = d->next_index();
-  }
-
-  void ReadFill(Deserializer* d, bool is_canonical) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RedirectionDataPtr data = static_cast<RedirectionDataPtr>(d->Ref(id));
-      Deserializer::InitializeHeader(data, kRedirectionDataCid,
-                                     RedirectionData::InstanceSize());
-      ReadFromTo(data);
-    }
-  }
-};
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class FieldSerializationCluster : public SerializationCluster {
@@ -1071,26 +1005,16 @@
     s->Push(field->ptr()->initializer_function_);
 
     if (kind != Snapshot::kFullAOT) {
-      s->Push(field->ptr()->saved_initial_value_);
       s->Push(field->ptr()->guarded_list_length_);
     }
     if (kind == Snapshot::kFullJIT) {
       s->Push(field->ptr()->dependent_code_);
     }
-    // Write out either static value, initial value or field offset.
+    // Write out either the initial static value or field offset.
     if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
-      if (
-          // For precompiled static fields, the value was already reset and
-          // initializer_ now contains a Function.
-          kind == Snapshot::kFullAOT ||
-          // Do not reset const fields.
-          Field::ConstBit::decode(field->ptr()->kind_bits_)) {
-        s->Push(s->field_table()->At(
-            Smi::Value(field->ptr()->host_offset_or_field_id_)));
-      } else {
-        // Otherwise, for static fields we write out the initial static value.
-        s->Push(field->ptr()->saved_initial_value_);
-      }
+      const intptr_t field_id =
+          Smi::Value(field->ptr()->host_offset_or_field_id_);
+      s->Push(s->initial_field_table()->At(field_id));
     } else {
       s->Push(Smi::New(Field::TargetOffsetOf(field)));
     }
@@ -1119,7 +1043,6 @@
       // Write out the initializer function and initial value if not in AOT.
       WriteField(field, initializer_function_);
       if (kind != Snapshot::kFullAOT) {
-        WriteField(field, saved_initial_value_);
         WriteField(field, guarded_list_length_);
       }
       if (kind == Snapshot::kFullJIT) {
@@ -1136,22 +1059,12 @@
       }
       s->Write<uint16_t>(field->ptr()->kind_bits_);
 
-      // Write out the initial static value or field offset.
+      // Write out either the initial static value or field offset.
       if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
-        if (
-            // For precompiled static fields, the value was already reset and
-            // initializer_ now contains a Function.
-            kind == Snapshot::kFullAOT ||
-            // Do not reset const fields.
-            Field::ConstBit::decode(field->ptr()->kind_bits_)) {
-          WriteFieldValue("static value",
-                          s->field_table()->At(Smi::Value(
-                              field->ptr()->host_offset_or_field_id_)));
-        } else {
-          // Otherwise, for static fields we write out the initial static value.
-          WriteFieldValue("static value", field->ptr()->saved_initial_value_);
-        }
-        s->WriteUnsigned(Smi::Value(field->ptr()->host_offset_or_field_id_));
+        const intptr_t field_id =
+            Smi::Value(field->ptr()->host_offset_or_field_id_);
+        WriteFieldValue("static value", s->initial_field_table()->At(field_id));
+        s->WriteUnsigned(field_id);
       } else {
         WriteFieldValue("offset", Smi::New(Field::TargetOffsetOf(field)));
       }
@@ -1186,10 +1099,6 @@
       Deserializer::InitializeHeader(field, kFieldCid, Field::InstanceSize());
       ReadFromTo(field);
       if (kind != Snapshot::kFullAOT) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-        field->ptr()->saved_initial_value_ =
-            static_cast<InstancePtr>(d->ReadRef());
-#endif
         field->ptr()->guarded_list_length_ = static_cast<SmiPtr>(d->ReadRef());
       }
       if (kind == Snapshot::kFullJIT) {
@@ -1209,9 +1118,9 @@
 
       ObjectPtr value_or_offset = d->ReadRef();
       if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
-        intptr_t field_id = d->ReadUnsigned();
-        d->field_table()->SetAt(field_id,
-                                static_cast<InstancePtr>(value_or_offset));
+        const intptr_t field_id = d->ReadUnsigned();
+        d->initial_field_table()->SetAt(
+            field_id, static_cast<InstancePtr>(value_or_offset));
         field->ptr()->host_offset_or_field_id_ = Smi::New(field_id);
       } else {
         field->ptr()->host_offset_or_field_id_ = Smi::RawCast(value_or_offset);
@@ -1228,10 +1137,10 @@
     if (!Isolate::Current()->use_field_guards()) {
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         field ^= refs.At(i);
-        field.set_guarded_cid(kDynamicCid);
-        field.set_is_nullable(true);
-        field.set_guarded_list_length(Field::kNoFixedLength);
-        field.set_guarded_list_length_in_object_offset(
+        field.set_guarded_cid_unsafe(kDynamicCid);
+        field.set_is_nullable_unsafe(true);
+        field.set_guarded_list_length_unsafe(Field::kNoFixedLength);
+        field.set_guarded_list_length_in_object_offset_unsafe(
             Field::kUnknownLengthOffset);
         field.set_static_type_exactness_state(
             StaticTypeExactnessState::NotTracking());
@@ -1239,7 +1148,7 @@
     } else {
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         field ^= refs.At(i);
-        field.InitializeGuardedListLengthInObjectOffset();
+        field.InitializeGuardedListLengthInObjectOffset(/*unsafe=*/true);
       }
     }
   }
@@ -4413,6 +4322,7 @@
       Deserializer::InitializeHeader(property, kWeakPropertyCid,
                                      WeakProperty::InstanceSize());
       ReadFromTo(property);
+      property->ptr()->next_ = WeakProperty::null();
     }
   }
 };
@@ -5302,7 +5212,7 @@
       num_written_objects_(0),
       next_ref_index_(kFirstReference),
       previous_text_offset_(0),
-      field_table_(thread->isolate()->field_table()),
+      initial_field_table_(thread->isolate_group()->initial_field_table()),
       vm_(vm),
       profile_writer_(profile_writer)
 #if defined(SNAPSHOT_BACKTRACE)
@@ -5573,8 +5483,6 @@
       return new (Z) ClosureDataSerializationCluster();
     case kSignatureDataCid:
       return new (Z) SignatureDataSerializationCluster();
-    case kRedirectionDataCid:
-      return new (Z) RedirectionDataSerializationCluster();
     case kFfiTrampolineDataCid:
       return new (Z) FfiTrampolineDataSerializationCluster();
     case kFieldCid:
@@ -5929,7 +5837,12 @@
   WriteUnsigned(num_objects);
   WriteUnsigned(canonical_clusters.length());
   WriteUnsigned(clusters.length());
-  WriteUnsigned(field_table_->NumFieldIds());
+  // TODO(dartbug.com/36097): Not every snapshot carries the field table.
+  if (current_loading_unit_id_ <= LoadingUnit::kRootId) {
+    WriteUnsigned(initial_field_table_->NumFieldIds());
+  } else {
+    WriteUnsigned(0);
+  }
 
   for (SerializationCluster* cluster : canonical_clusters) {
     cluster->WriteAndMeasureAlloc(this);
@@ -6210,7 +6123,7 @@
       previous_text_offset_(0),
       canonical_clusters_(nullptr),
       clusters_(nullptr),
-      field_table_(thread->isolate()->field_table()),
+      initial_field_table_(thread->isolate_group()->initial_field_table()),
       is_non_root_unit_(is_non_root_unit) {
   if (Snapshot::IncludesCode(kind)) {
     ASSERT(instructions_buffer != nullptr);
@@ -6269,8 +6182,6 @@
       return new (Z) ClosureDataDeserializationCluster();
     case kSignatureDataCid:
       return new (Z) SignatureDataDeserializationCluster();
-    case kRedirectionDataCid:
-      return new (Z) RedirectionDataDeserializationCluster();
     case kFfiTrampolineDataCid:
       return new (Z) FfiTrampolineDataDeserializationCluster();
     case kFieldCid:
@@ -6660,15 +6571,15 @@
   num_objects_ = ReadUnsigned();
   num_canonical_clusters_ = ReadUnsigned();
   num_clusters_ = ReadUnsigned();
-  const intptr_t field_table_len = ReadUnsigned();
+  const intptr_t initial_field_table_len = ReadUnsigned();
 
   canonical_clusters_ = new DeserializationCluster*[num_canonical_clusters_];
   clusters_ = new DeserializationCluster*[num_clusters_];
   refs_ = Array::New(num_objects_ + kFirstReference, Heap::kOld);
-  if (field_table_len > 0) {
-    field_table_->AllocateIndex(field_table_len - 1);
+  if (initial_field_table_len > 0) {
+    initial_field_table_->AllocateIndex(initial_field_table_len - 1);
+    ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len);
   }
-  ASSERT_EQUAL(field_table_->NumFieldIds(), field_table_len);
 
   {
     NoSafepointScope no_safepoint;
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index 2632693..031ab05 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -221,7 +221,7 @@
   ZoneGrowableArray<Object*>* Serialize(SerializationRoots* roots);
   void PrintSnapshotSizes();
 
-  FieldTable* field_table() { return field_table_; }
+  FieldTable* initial_field_table() const { return initial_field_table_; }
 
   NonStreamingWriteStream* stream() { return stream_; }
   intptr_t bytes_written() { return stream_->bytes_written(); }
@@ -433,7 +433,7 @@
   intptr_t num_written_objects_;
   intptr_t next_ref_index_;
   intptr_t previous_text_offset_;
-  FieldTable* field_table_;
+  FieldTable* initial_field_table_;
 
   intptr_t dispatch_table_size_ = 0;
 
@@ -641,7 +641,7 @@
   Heap* heap() const { return heap_; }
   Zone* zone() const { return zone_; }
   Snapshot::Kind kind() const { return kind_; }
-  FieldTable* field_table() const { return field_table_; }
+  FieldTable* initial_field_table() const { return initial_field_table_; }
 
  private:
   Heap* heap_;
@@ -658,7 +658,7 @@
   intptr_t previous_text_offset_;
   DeserializationCluster** canonical_clusters_;
   DeserializationCluster** clusters_;
-  FieldTable* field_table_;
+  FieldTable* initial_field_table_;
   const bool is_non_root_unit_;
 };
 
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index 7d50a23..8590013 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -43,9 +43,6 @@
   observers_length_++;
   observers_ = reinterpret_cast<CodeObserver**>(
       realloc(observers_, sizeof(observer) * observers_length_));
-  if (observers_ == NULL) {
-    FATAL("failed to grow code observers array");
-  }
   observers_[observers_length_ - 1] = observer;
 }
 
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index 0db337d..d2f88ed 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -448,7 +448,6 @@
   ADD_FLAG(enable_asserts);
   ADD_FLAG(use_field_guards);
   ADD_FLAG(use_osr);
-  ADD_FLAG(causal_async_stacks);
   ADD_FLAG(fields_may_be_reset);
 #undef ADD_FLAG
 
@@ -744,6 +743,8 @@
       fields_ = cls_.fields();
     }
 
+    SafepointWriteRwLocker ml(thread_,
+                              thread_->isolate_group()->program_lock());
     for (intptr_t i = 0; i < num_fields; i++) {
       field_name_ = ReadString();
       intptr_t guarded_cid = cid_map_[ReadInt()];
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 0b503e5..d7f198e 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -416,7 +416,6 @@
       I->object_store()->set_simple_instance_of_function(null_function);
       I->object_store()->set_simple_instance_of_true_function(null_function);
       I->object_store()->set_simple_instance_of_false_function(null_function);
-      I->object_store()->set_async_set_thread_stack_trace(null_function);
       I->object_store()->set_async_star_move_next_helper(null_function);
       I->object_store()->set_complete_on_async_return(null_function);
       I->object_store()->set_async_star_stream_controller(null_class);
@@ -633,7 +632,6 @@
   }
 
   ASSERT(!function.is_abstract());
-  ASSERT(!function.IsRedirectingFactory());
 
   error_ = CompileFunction(this, thread_, zone_, function);
   if (!error_.IsNull()) {
@@ -781,9 +779,6 @@
 void Precompiler::AddTypesOf(const Function& function) {
   if (function.IsNull()) return;
   if (functions_to_retain_.ContainsKey(function)) return;
-  // We don't expect to see a reference to a redirecting factory. Only its
-  // target should remain.
-  ASSERT(!function.IsRedirectingFactory());
   functions_to_retain_.Insert(function);
 
   AddTypeArguments(TypeArguments::Handle(Z, function.type_parameters()));
@@ -1127,7 +1122,7 @@
 
   class_count_++;
   cls.set_is_allocated(true);
-  error_ = cls.EnsureIsFinalized(T);
+  error_ = cls.EnsureIsAllocateFinalized(T);
   if (!error_.IsNull()) {
     Jump(error_);
   }
@@ -2121,48 +2116,12 @@
 }
 
 void Precompiler::DropMetadata() {
-  Library& lib = Library::Handle(Z);
-  const GrowableObjectArray& null_growable_list =
-      GrowableObjectArray::Handle(Z);
-  Array& dependencies = Array::Handle(Z);
-  Namespace& ns = Namespace::Handle(Z);
-  const Field& null_field = Field::Handle(Z);
-  GrowableObjectArray& metadata = GrowableObjectArray::Handle(Z);
-  Field& metadata_field = Field::Handle(Z);
+  SafepointWriteRwLocker ml(T, T->isolate_group()->program_lock());
 
+  Library& lib = Library::Handle(Z);
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
     lib ^= libraries_.At(i);
-    metadata ^= lib.metadata();
-    for (intptr_t j = 0; j < metadata.Length(); j++) {
-      metadata_field ^= metadata.At(j);
-      if (metadata_field.is_static()) {
-        // Although this field will become garbage after clearing the list
-        // below, we also need to clear its value from the field table.
-        // The value may be an instance of an otherwise dead class, and if
-        // it remains in the field table we can get an instance on the heap
-        // with a deleted class.
-        metadata_field.SetStaticValue(Object::null_instance(),
-                                      /*save_initial_value=*/true);
-      }
-    }
-
-    lib.set_metadata(null_growable_list);
-
-    dependencies = lib.imports();
-    for (intptr_t j = 0; j < dependencies.Length(); j++) {
-      ns ^= dependencies.At(j);
-      if (!ns.IsNull()) {
-        ns.set_metadata_field(null_field);
-      }
-    }
-
-    dependencies = lib.exports();
-    for (intptr_t j = 0; j < dependencies.Length(); j++) {
-      ns ^= dependencies.At(j);
-      if (!ns.IsNull()) {
-        ns.set_metadata_field(null_field);
-      }
-    }
+    lib.set_metadata(Array::null_array());
   }
 }
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 22eff5a..fd9c7c7 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -28,14 +28,10 @@
   return -1;
 }
 
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
-}
-
 void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CODE_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(ARGS_DESC_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP));
 
   // Save LR by moving it to a callee saved temporary register.
   assembler->Comment("IntrinsicCallPrologue");
@@ -1213,8 +1209,8 @@
   if (TargetCPUFeatures::vfp_supported()) {
     __ ldr(R0, Address(SP, 0 * target::kWordSize));
     // R1 <- value[0:31], R2 <- value[32:63]
-    __ LoadFieldFromOffset(kWord, R1, R0, target::Double::value_offset());
-    __ LoadFieldFromOffset(kWord, R2, R0,
+    __ LoadFieldFromOffset(R1, R0, target::Double::value_offset());
+    __ LoadFieldFromOffset(R2, R0,
                            target::Double::value_offset() + target::kWordSize);
 
     // If the low word isn't 0, then it isn't infinity.
@@ -1382,13 +1378,13 @@
       disp_0 + target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
 
   __ LoadImmediate(R0, a_int32_value);
-  __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
-  __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
+  __ LoadFieldFromOffset(R2, R1, disp_0);
+  __ LoadFieldFromOffset(R3, R1, disp_1);
   __ mov(R8, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
   // Unsigned 32-bit multiply and 64-bit accumulate into R8:R3.
   __ umlal(R3, R8, R0, R2);  // R8:R3 <- R8:R3 + R0 * R2.
-  __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
-  __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
+  __ StoreFieldToOffset(R3, R1, disp_0);
+  __ StoreFieldToOffset(R8, R1, disp_1);
   ASSERT(target::ToRawSmi(0) == 0);
   __ eor(R0, R0, Operand(R0));
   __ Ret();
@@ -1466,25 +1462,22 @@
   __ b(&not_double, NE);
 
   __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0,
-                    target::Isolate::cached_object_store_offset());
-  __ LoadFromOffset(kWord, R0, R0, target::ObjectStore::double_type_offset());
+  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadFromOffset(R0, R0, target::ObjectStore::double_type_offset());
   __ Ret();
 
   __ Bind(&not_double);
   JumpIfNotInteger(assembler, R1, R0, &not_integer);
   __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0,
-                    target::Isolate::cached_object_store_offset());
-  __ LoadFromOffset(kWord, R0, R0, target::ObjectStore::int_type_offset());
+  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadFromOffset(R0, R0, target::ObjectStore::int_type_offset());
   __ Ret();
 
   __ Bind(&not_integer);
   JumpIfNotString(assembler, R1, R0, &use_declaration_type);
   __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0,
-                    target::Isolate::cached_object_store_offset());
-  __ LoadFromOffset(kWord, R0, R0, target::ObjectStore::string_type_offset());
+  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadFromOffset(R0, R0, target::ObjectStore::string_type_offset());
   __ Ret();
 
   __ Bind(&use_declaration_type);
@@ -1957,7 +1950,7 @@
 
     // Get the class index and insert it into the tags.
     // R3: size and bit tags.
-    const uint32_t tags =
+    const uword tags =
         target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ LoadImmediate(TMP, tags);
     __ orr(R3, R3, Operand(TMP));
@@ -2242,20 +2235,6 @@
 #endif
 }
 
-void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                                 Label* normal_ir_body) {
-  __ LoadObject(R0, NullObject());
-  __ str(R0, Address(THR, target::Thread::async_stack_trace_offset()));
-  __ Ret();
-}
-
-void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                               Label* normal_ir_body) {
-  __ ldr(R0, Address(THR, target::Thread::async_stack_trace_offset()));
-  __ LoadObject(R0, NullObject());
-  __ Ret();
-}
-
 #undef __
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index a54be20..1c1271d 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -28,19 +28,15 @@
   return -1;
 }
 
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
-}
-
 void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
-  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
-  ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
+  COMPILE_ASSERT(IsAbiPreservedRegister(CODE_REG));
+  COMPILE_ASSERT(!IsAbiPreservedRegister(ARGS_DESC_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP2));
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
 
   assembler->Comment("IntrinsicCallPrologue");
   assembler->mov(CALLEE_SAVED_TEMP, LR);
@@ -1556,8 +1552,8 @@
   __ LoadClassById(R2, R1);
   __ ldr(
       R3,
-      FieldAddress(R2, target::Class::num_type_arguments_offset(), kHalfword),
-      kHalfword);
+      FieldAddress(R2, target::Class::num_type_arguments_offset(), kTwoBytes),
+      kTwoBytes);
   __ CompareImmediate(R3, 0);
   __ b(normal_ir_body, NE);
 
@@ -1597,8 +1593,8 @@
   __ LoadClassById(scratch, cid1);
   __ ldr(scratch,
          FieldAddress(scratch, target::Class::num_type_arguments_offset(),
-                      kHalfword),
-         kHalfword);
+                      kTwoBytes),
+         kTwoBytes);
   __ cbnz(normal_ir_body, scratch);
   __ b(equal);
 
@@ -1654,7 +1650,8 @@
 void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
                                          Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ ldr(R0, FieldAddress(R0, target::String::hash_offset()), kUnsignedWord);
+  __ ldr(R0, FieldAddress(R0, target::String::hash_offset()),
+         kUnsignedFourBytes);
   __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
   __ b(normal_ir_body, EQ);
   __ ret();
@@ -1729,8 +1726,8 @@
 void AsmIntrinsifier::Object_getHash(Assembler* assembler,
                                      Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ ldr(R0, FieldAddress(R0, target::String::hash_offset(), kWord),
-         kUnsignedWord);
+  __ ldr(R0, FieldAddress(R0, target::String::hash_offset(), kFourBytes),
+         kUnsignedFourBytes);
   __ SmiTag(R0);
   __ ret();
 }
@@ -1739,9 +1736,16 @@
                                      Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 1 * target::kWordSize));  // Object.
   __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Value.
+  // R0: Untagged address of header word (ldxr/stxr do not support offsets).
+  __ sub(R0, R0, Operand(kHeapObjectTag));
   __ SmiUntag(R1);
-  __ str(R1, FieldAddress(R0, target::String::hash_offset(), kWord),
-         kUnsignedWord);
+  __ LslImmediate(R1, R1, target::ObjectLayout::kHashTagPos);
+  Label retry;
+  __ Bind(&retry);
+  __ ldxr(R2, R0, kEightBytes);
+  __ orr(R2, R2, Operand(R1));
+  __ stxr(R4, R2, R0, kEightBytes);
+  __ cbnz(&retry, R4);
   __ ret();
 }
 
@@ -1795,10 +1799,10 @@
 
   // this.codeUnitAt(i + start)
   __ ldr(R10, Address(R0, 0),
-         receiver_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+         receiver_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedTwoBytes);
   // other.codeUnitAt(i)
   __ ldr(R11, Address(R2, 0),
-         other_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+         other_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedTwoBytes);
   __ cmp(R10, Operand(R11));
   __ b(return_false, NE);
 
@@ -1883,7 +1887,7 @@
   __ b(normal_ir_body, NE);
   ASSERT(kSmiTagShift == 1);
   __ AddImmediate(R0, target::TwoByteString::data_offset() - kHeapObjectTag);
-  __ ldr(R1, Address(R0, R1), kUnsignedHalfword);
+  __ ldr(R1, Address(R0, R1), kUnsignedTwoBytes);
   __ CompareImmediate(R1, target::Symbols::kNumberOfOneCharCodeSymbols);
   __ b(normal_ir_body, GE);
   __ ldr(R0, Address(THR, target::Thread::predefined_symbols_address_offset()));
@@ -1910,7 +1914,8 @@
                                                 Label* normal_ir_body) {
   Label compute_hash;
   __ ldr(R1, Address(SP, 0 * target::kWordSize));  // OneByteString object.
-  __ ldr(R0, FieldAddress(R1, target::String::hash_offset()), kUnsignedWord);
+  __ ldr(R0, FieldAddress(R1, target::String::hash_offset()),
+         kUnsignedFourBytes);
   __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
   __ b(&compute_hash, EQ);
   __ ret();  // Return if already computed.
@@ -1963,7 +1968,18 @@
   // return hash_ == 0 ? 1 : hash_;
   __ Bind(&done);
   __ csinc(R0, R0, ZR, NE);  // R0 <- (R0 != 0) ? R0 : (ZR + 1).
-  __ str(R0, FieldAddress(R1, target::String::hash_offset()), kUnsignedWord);
+
+  // R1: Untagged address of header word (ldxr/stxr do not support offsets).
+  __ sub(R1, R1, Operand(kHeapObjectTag));
+  __ LslImmediate(R0, R0, target::ObjectLayout::kHashTagPos);
+  Label retry;
+  __ Bind(&retry);
+  __ ldxr(R2, R1, kEightBytes);
+  __ orr(R2, R2, Operand(R0));
+  __ stxr(R4, R2, R1, kEightBytes);
+  __ cbnz(&retry, R4);
+
+  __ LsrImmediate(R0, R0, target::ObjectLayout::kHashTagPos);
   __ SmiTag(R0);
   __ ret();
 }
@@ -2032,7 +2048,7 @@
     // Get the class index and insert it into the tags.
     // R2: size and bit tags.
     // This also clears the hash, which is in the high word of the tags.
-    const uint32_t tags =
+    const uword tags =
         target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ LoadImmediate(TMP, tags);
     __ orr(R2, R2, Operand(TMP));
@@ -2127,7 +2143,7 @@
   __ SmiUntag(R2);
   __ AddImmediate(R3, R0,
                   target::TwoByteString::data_offset() - kHeapObjectTag);
-  __ str(R2, Address(R3, R1), kUnsignedHalfword);
+  __ str(R2, Address(R3, R1), kUnsignedTwoBytes);
   __ ret();
 }
 
@@ -2200,8 +2216,8 @@
     __ AddImmediate(R0, 1);
     __ AddImmediate(R1, 1);
   } else if (string_cid == kTwoByteStringCid) {
-    __ ldr(R3, Address(R0), kUnsignedHalfword);
-    __ ldr(R4, Address(R1), kUnsignedHalfword);
+    __ ldr(R3, Address(R0), kUnsignedTwoBytes);
+    __ ldr(R4, Address(R1), kUnsignedTwoBytes);
     __ AddImmediate(R0, 2);
     __ AddImmediate(R1, 2);
   } else {
@@ -2316,20 +2332,6 @@
 #endif
 }
 
-void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                                 Label* normal_ir_body) {
-  __ LoadObject(R0, NullObject());
-  __ str(R0, Address(THR, target::Thread::async_stack_trace_offset()));
-  __ ret();
-}
-
-void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                               Label* normal_ir_body) {
-  __ ldr(R0, Address(THR, target::Thread::async_stack_trace_offset()));
-  __ LoadObject(R0, NullObject());
-  __ ret();
-}
-
 #undef __
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index c1e0863..ec97c64 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1910,7 +1910,8 @@
   __ cmpl(length_reg, Immediate(0));
   __ j(LESS, failure);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, EAX, failure, false));
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(cid, EAX, failure, Assembler::kFarJump));
   if (length_reg != EDI) {
     __ movl(EDI, length_reg);
   }
@@ -1964,7 +1965,7 @@
     __ Bind(&done);
 
     // Get the class index and insert it into the tags.
-    const uint32_t tags =
+    const uword tags =
         target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ orl(EDI, Immediate(tags));
     __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI);  // Tags.
@@ -2239,20 +2240,6 @@
 #endif
 }
 
-void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                                 Label* normal_ir_body) {
-  __ LoadObject(EAX, NullObject());
-  __ movl(Address(THR, target::Thread::async_stack_trace_offset()), EAX);
-  __ ret();
-}
-
-void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                               Label* normal_ir_body) {
-  __ movl(Address(THR, target::Thread::async_stack_trace_offset()), EAX);
-  __ LoadObject(EAX, NullObject());
-  __ ret();
-}
-
 #undef __
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 816f2fc..8a424dd 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -28,16 +28,12 @@
   return 0;
 }
 
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
-}
-
 void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  COMPILE_ASSERT(IsAbiPreservedRegister(CODE_REG));
+  COMPILE_ASSERT(!IsAbiPreservedRegister(ARGS_DESC_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP));
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
 
   assembler->Comment("IntrinsicCallPrologue");
   assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
@@ -1680,7 +1676,10 @@
   __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Object.
   __ movq(RDX, Address(RSP, +1 * target::kWordSize));  // Value.
   __ SmiUntag(RDX);
-  __ movl(FieldAddress(RAX, target::String::hash_offset()), RDX);
+  __ shlq(RDX, Immediate(target::ObjectLayout::kHashTagPos));
+  // lock+orq is an atomic read-modify-write.
+  __ lock();
+  __ orq(FieldAddress(RAX, target::Object::tags_offset()), RDX);
   __ ret();
 }
 
@@ -1915,7 +1914,11 @@
   __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
   __ incq(RAX);
   __ Bind(&set_hash_code);
-  __ movl(FieldAddress(RBX, target::String::hash_offset()), RAX);
+  __ shlq(RAX, Immediate(target::ObjectLayout::kHashTagPos));
+  // lock+orq is an atomic read-modify-write.
+  __ lock();
+  __ orq(FieldAddress(RBX, target::Object::tags_offset()), RAX);
+  __ sarq(RAX, Immediate(target::ObjectLayout::kHashTagPos));
   __ SmiTag(RAX);
   __ ret();
 }
@@ -1935,7 +1938,7 @@
   __ cmpq(length_reg, Immediate(0));
   __ j(LESS, failure);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, false));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, Assembler::kFarJump));
   if (length_reg != RDI) {
     __ movq(RDI, length_reg);
   }
@@ -1990,7 +1993,7 @@
 
     // Get the class index and insert it into the tags.
     // This also clears the hash, which is in the high bits of the tags.
-    const uint32_t tags =
+    const uword tags =
         target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ orq(RDI, Immediate(tags));
     __ movq(FieldAddress(RAX, target::Object::tags_offset()), RDI);  // Tags.
@@ -2265,20 +2268,6 @@
 #endif
 }
 
-void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                                 Label* normal_ir_body) {
-  __ LoadObject(RAX, NullObject());
-  __ movq(Address(THR, target::Thread::async_stack_trace_offset()), RAX);
-  __ ret();
-}
-
-void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                               Label* normal_ir_body) {
-  __ movq(Address(THR, target::Thread::async_stack_trace_offset()), RAX);
-  __ LoadObject(RAX, NullObject());
-  __ ret();
-}
-
 #undef __
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 8417f7c..bcab63b 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -567,18 +567,17 @@
                                             Register tmp1,
                                             bool enter_safepoint) {
   // Save exit frame information to enable stack walking.
-  StoreToOffset(kWord, exit_frame_fp, THR,
+  StoreToOffset(exit_frame_fp, THR,
                 target::Thread::top_exit_frame_info_offset());
 
-  StoreToOffset(kWord, exit_through_ffi, THR,
+  StoreToOffset(exit_through_ffi, THR,
                 target::Thread::exit_through_ffi_offset());
   Register tmp2 = exit_through_ffi;
 
   // Mark that the thread is executing native code.
-  StoreToOffset(kWord, destination_address, THR,
-                target::Thread::vm_tag_offset());
+  StoreToOffset(destination_address, THR, target::Thread::vm_tag_offset());
   LoadImmediate(tmp1, target::Thread::native_execution_state());
-  StoreToOffset(kWord, tmp1, THR, target::Thread::execution_state_offset());
+  StoreToOffset(tmp1, THR, target::Thread::execution_state_offset());
 
   if (enter_safepoint) {
     EnterSafepoint(tmp1, tmp2);
@@ -640,15 +639,14 @@
 
   // Mark that the thread is executing Dart code.
   LoadImmediate(state, target::Thread::vm_tag_dart_id());
-  StoreToOffset(kWord, state, THR, target::Thread::vm_tag_offset());
+  StoreToOffset(state, THR, target::Thread::vm_tag_offset());
   LoadImmediate(state, target::Thread::generated_execution_state());
-  StoreToOffset(kWord, state, THR, target::Thread::execution_state_offset());
+  StoreToOffset(state, THR, target::Thread::execution_state_offset());
 
   // Reset exit frame information in Isolate's mutator thread structure.
   LoadImmediate(state, 0);
-  StoreToOffset(kWord, state, THR,
-                target::Thread::top_exit_frame_info_offset());
-  StoreToOffset(kWord, state, THR, target::Thread::exit_through_ffi_offset());
+  StoreToOffset(state, THR, target::Thread::top_exit_frame_info_offset());
+  StoreToOffset(state, THR, target::Thread::exit_through_ffi_offset());
 }
 
 void Assembler::clrex() {
@@ -1214,11 +1212,11 @@
     case kByte:
     case kUnsignedByte:
       return 0;
-    case kHalfword:
-    case kUnsignedHalfword:
+    case kTwoBytes:
+    case kUnsignedTwoBytes:
       return 1;
-    case kWord:
-    case kUnsignedWord:
+    case kFourBytes:
+    case kUnsignedFourBytes:
       return 2;
     case kWordPair:
       return 3;
@@ -1388,14 +1386,14 @@
       code = 1 | (idx << 1);
       break;
     }
-    case kHalfword:
-    case kUnsignedHalfword: {
+    case kTwoBytes:
+    case kUnsignedTwoBytes: {
       ASSERT((idx >= 0) && (idx < 4));
       code = 2 | (idx << 2);
       break;
     }
-    case kWord:
-    case kUnsignedWord: {
+    case kFourBytes:
+    case kUnsignedFourBytes: {
       ASSERT((idx >= 0) && (idx < 2));
       code = 4 | (idx << 3);
       break;
@@ -1524,7 +1522,7 @@
   const int32_t offset =
       target::ObjectPool::element_offset(index) - kHeapObjectTag;
   int32_t offset_mask = 0;
-  if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) {
+  if (Address::CanHoldLoadOffset(kFourBytes, offset, &offset_mask)) {
     ldr(rd, Address(pp, offset), cond);
   } else {
     int32_t offset_hi = offset & ~offset_mask;  // signed
@@ -1839,7 +1837,8 @@
                                       CanBeSmi can_value_be_smi,
                                       bool lr_reserved) {
   int32_t ignored = 0;
-  if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
+  if (Address::CanHoldStoreOffset(kFourBytes, offset - kHeapObjectTag,
+                                  &ignored)) {
     StoreIntoObject(object, FieldAddress(object, offset), value,
                     can_value_be_smi, lr_reserved);
   } else {
@@ -1880,7 +1879,8 @@
                                                int32_t offset,
                                                Register value) {
   int32_t ignored = 0;
-  if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
+  if (Address::CanHoldStoreOffset(kFourBytes, offset - kHeapObjectTag,
+                                  &ignored)) {
     StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
   } else {
     Register base = object == R9 ? R8 : R9;
@@ -1896,7 +1896,8 @@
                                                const Object& value) {
   ASSERT(IsOriginalObject(value));
   int32_t ignored = 0;
-  if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
+  if (Address::CanHoldStoreOffset(kFourBytes, offset - kHeapObjectTag,
+                                  &ignored)) {
     StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
   } else {
     Register base = object == R9 ? R8 : R9;
@@ -2011,7 +2012,7 @@
       target::Isolate::cached_class_table_table_offset();
 
   LoadIsolate(result);
-  LoadFromOffset(kWord, result, result, table_offset);
+  LoadFromOffset(result, result, table_offset);
   ldr(result, Address(result, class_id, LSL, target::kWordSizeLog2));
 }
 
@@ -2210,13 +2211,13 @@
     case kArrayCid:
     case kImmutableArrayCid:
     case kTypeArgumentsCid:
-      return kWord;
+      return kFourBytes;
     case kOneByteStringCid:
     case kExternalOneByteStringCid:
       return kByte;
     case kTwoByteStringCid:
     case kExternalTwoByteStringCid:
-      return kHalfword;
+      return kTwoBytes;
     case kTypedDataInt8ArrayCid:
       return kByte;
     case kTypedDataUint8ArrayCid:
@@ -2225,13 +2226,13 @@
     case kExternalTypedDataUint8ClampedArrayCid:
       return kUnsignedByte;
     case kTypedDataInt16ArrayCid:
-      return kHalfword;
+      return kTwoBytes;
     case kTypedDataUint16ArrayCid:
-      return kUnsignedHalfword;
+      return kUnsignedTwoBytes;
     case kTypedDataInt32ArrayCid:
-      return kWord;
+      return kFourBytes;
     case kTypedDataUint32ArrayCid:
-      return kUnsignedWord;
+      return kUnsignedFourBytes;
     case kTypedDataInt64ArrayCid:
     case kTypedDataUint64ArrayCid:
       return kDWord;
@@ -2257,15 +2258,15 @@
                                 int32_t* offset_mask) {
   switch (size) {
     case kByte:
-    case kHalfword:
-    case kUnsignedHalfword:
+    case kTwoBytes:
+    case kUnsignedTwoBytes:
     case kWordPair: {
       *offset_mask = 0xff;
       return Utils::IsAbsoluteUint(8, offset);  // Addressing mode 3.
     }
     case kUnsignedByte:
-    case kWord:
-    case kUnsignedWord: {
+    case kFourBytes:
+    case kUnsignedFourBytes: {
       *offset_mask = 0xfff;
       return Utils::IsAbsoluteUint(12, offset);  // Addressing mode 2.
     }
@@ -2290,16 +2291,16 @@
                                  int32_t offset,
                                  int32_t* offset_mask) {
   switch (size) {
-    case kHalfword:
-    case kUnsignedHalfword:
+    case kTwoBytes:
+    case kUnsignedTwoBytes:
     case kWordPair: {
       *offset_mask = 0xff;
       return Utils::IsAbsoluteUint(8, offset);  // Addressing mode 3.
     }
     case kByte:
     case kUnsignedByte:
-    case kWord:
-    case kUnsignedWord: {
+    case kFourBytes:
+    case kUnsignedFourBytes: {
       *offset_mask = 0xfff;
       return Utils::IsAbsoluteUint(12, offset);  // Addressing mode 2.
     }
@@ -2639,7 +2640,7 @@
 void Assembler::BranchLinkOffset(Register base, int32_t offset) {
   ASSERT(base != PC);
   ASSERT(base != IP);
-  LoadFromOffset(kWord, IP, base, offset);
+  LoadFromOffset(IP, base, offset);
   blx(IP);  // Use blx instruction so that the return branch prediction works.
 }
 
@@ -2698,10 +2699,10 @@
   }
 }
 
-void Assembler::LoadFromOffset(OperandSize size,
-                               Register reg,
+void Assembler::LoadFromOffset(Register reg,
                                Register base,
                                int32_t offset,
+                               OperandSize size,
                                Condition cond) {
   ASSERT(size != kWordPair);
   int32_t offset_mask = 0;
@@ -2718,13 +2719,13 @@
     case kUnsignedByte:
       ldrb(reg, Address(base, offset), cond);
       break;
-    case kHalfword:
+    case kTwoBytes:
       ldrsh(reg, Address(base, offset), cond);
       break;
-    case kUnsignedHalfword:
+    case kUnsignedTwoBytes:
       ldrh(reg, Address(base, offset), cond);
       break;
-    case kWord:
+    case kFourBytes:
       ldr(reg, Address(base, offset), cond);
       break;
     default:
@@ -2732,10 +2733,25 @@
   }
 }
 
-void Assembler::StoreToOffset(OperandSize size,
-                              Register reg,
+void Assembler::LoadFromStack(Register dst, intptr_t depth) {
+  ASSERT(depth >= 0);
+  LoadFromOffset(dst, SPREG, depth * target::kWordSize);
+}
+
+void Assembler::StoreToStack(Register src, intptr_t depth) {
+  ASSERT(depth >= 0);
+  StoreToOffset(src, SPREG, depth * target::kWordSize);
+}
+
+void Assembler::CompareToStack(Register src, intptr_t depth) {
+  LoadFromStack(TMP, depth);
+  CompareRegisters(src, TMP);
+}
+
+void Assembler::StoreToOffset(Register reg,
                               Register base,
                               int32_t offset,
+                              OperandSize size,
                               Condition cond) {
   ASSERT(size != kWordPair);
   int32_t offset_mask = 0;
@@ -2750,10 +2766,10 @@
     case kByte:
       strb(reg, Address(base, offset), cond);
       break;
-    case kHalfword:
+    case kTwoBytes:
       strh(reg, Address(base, offset), cond);
       break;
-    case kWord:
+    case kFourBytes:
       str(reg, Address(base, offset), cond);
       break;
     default:
@@ -2844,16 +2860,12 @@
     LoadDFromOffset(dtmp, src, target::Double::value_offset() - kHeapObjectTag);
     StoreDToOffset(dtmp, dst, target::Double::value_offset() - kHeapObjectTag);
   } else {
-    LoadFromOffset(kWord, tmp1, src,
-                   target::Double::value_offset() - kHeapObjectTag);
-    LoadFromOffset(
-        kWord, tmp2, src,
-        target::Double::value_offset() + target::kWordSize - kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  target::Double::value_offset() - kHeapObjectTag);
-    StoreToOffset(
-        kWord, tmp2, dst,
-        target::Double::value_offset() + target::kWordSize - kHeapObjectTag);
+    LoadFieldFromOffset(tmp1, src, target::Double::value_offset());
+    LoadFieldFromOffset(tmp2, src,
+                        target::Double::value_offset() + target::kWordSize);
+    StoreFieldToOffset(tmp1, dst, target::Double::value_offset());
+    StoreFieldToOffset(tmp2, dst,
+                       target::Double::value_offset() + target::kWordSize);
   }
 }
 
@@ -2868,31 +2880,23 @@
     StoreMultipleDToOffset(dtmp, 2, dst,
                            target::Float32x4::value_offset() - kHeapObjectTag);
   } else {
-    LoadFromOffset(kWord, tmp1, src,
-                   (target::Float32x4::value_offset() + 0 * target::kWordSize) -
-                       kHeapObjectTag);
-    LoadFromOffset(kWord, tmp2, src,
-                   (target::Float32x4::value_offset() + 1 * target::kWordSize) -
-                       kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (target::Float32x4::value_offset() + 0 * target::kWordSize) -
-                      kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (target::Float32x4::value_offset() + 1 * target::kWordSize) -
-                      kHeapObjectTag);
+    LoadFieldFromOffset(
+        tmp1, src, target::Float32x4::value_offset() + 0 * target::kWordSize);
+    LoadFieldFromOffset(
+        tmp2, src, target::Float32x4::value_offset() + 1 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp1, dst, target::Float32x4::value_offset() + 0 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp2, dst, target::Float32x4::value_offset() + 1 * target::kWordSize);
 
-    LoadFromOffset(kWord, tmp1, src,
-                   (target::Float32x4::value_offset() + 2 * target::kWordSize) -
-                       kHeapObjectTag);
-    LoadFromOffset(kWord, tmp2, src,
-                   (target::Float32x4::value_offset() + 3 * target::kWordSize) -
-                       kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (target::Float32x4::value_offset() + 2 * target::kWordSize) -
-                      kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (target::Float32x4::value_offset() + 3 * target::kWordSize) -
-                      kHeapObjectTag);
+    LoadFieldFromOffset(
+        tmp1, src, target::Float32x4::value_offset() + 2 * target::kWordSize);
+    LoadFieldFromOffset(
+        tmp2, src, target::Float32x4::value_offset() + 3 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp1, dst, target::Float32x4::value_offset() + 2 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp2, dst, target::Float32x4::value_offset() + 3 * target::kWordSize);
   }
 }
 
@@ -2907,31 +2911,23 @@
     StoreMultipleDToOffset(dtmp, 2, dst,
                            target::Float64x2::value_offset() - kHeapObjectTag);
   } else {
-    LoadFromOffset(kWord, tmp1, src,
-                   (target::Float64x2::value_offset() + 0 * target::kWordSize) -
-                       kHeapObjectTag);
-    LoadFromOffset(kWord, tmp2, src,
-                   (target::Float64x2::value_offset() + 1 * target::kWordSize) -
-                       kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (target::Float64x2::value_offset() + 0 * target::kWordSize) -
-                      kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (target::Float64x2::value_offset() + 1 * target::kWordSize) -
-                      kHeapObjectTag);
+    LoadFieldFromOffset(
+        tmp1, src, target::Float64x2::value_offset() + 0 * target::kWordSize);
+    LoadFieldFromOffset(
+        tmp2, src, target::Float64x2::value_offset() + 1 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp1, dst, target::Float64x2::value_offset() + 0 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp2, dst, target::Float64x2::value_offset() + 1 * target::kWordSize);
 
-    LoadFromOffset(kWord, tmp1, src,
-                   (target::Float64x2::value_offset() + 2 * target::kWordSize) -
-                       kHeapObjectTag);
-    LoadFromOffset(kWord, tmp2, src,
-                   (target::Float64x2::value_offset() + 3 * target::kWordSize) -
-                       kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (target::Float64x2::value_offset() + 2 * target::kWordSize) -
-                      kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (target::Float64x2::value_offset() + 3 * target::kWordSize) -
-                      kHeapObjectTag);
+    LoadFieldFromOffset(
+        tmp1, src, target::Float64x2::value_offset() + 2 * target::kWordSize);
+    LoadFieldFromOffset(
+        tmp2, src, target::Float64x2::value_offset() + 3 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp1, dst, target::Float64x2::value_offset() + 2 * target::kWordSize);
+    StoreFieldToOffset(
+        tmp2, dst, target::Float64x2::value_offset() + 3 * target::kWordSize);
   }
 }
 
@@ -3424,8 +3420,7 @@
     ASSERT(instance_size >= kHeapObjectTag);
     AddImmediate(instance_reg, -instance_size + kHeapObjectTag);
 
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     LoadImmediate(IP, tags);
     str(IP, FieldAddress(instance_reg, target::Object::tags_offset()));
   } else {
@@ -3467,8 +3462,7 @@
 
     // Initialize the tags.
     // instance: new object start as a tagged pointer.
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     LoadImmediate(temp2, tags);
     str(temp2,
         FieldAddress(instance, target::Object::tags_offset()));  // Store tags.
@@ -3553,8 +3547,8 @@
   ASSERT(array != IP);
   ASSERT(index != IP);
   const Register base = is_load ? IP : index;
-  if ((offset != 0) || (is_load && (size == kByte)) || (size == kHalfword) ||
-      (size == kUnsignedHalfword) || (size == kSWord) || (size == kDWord) ||
+  if ((offset != 0) || (is_load && (size == kByte)) || (size == kTwoBytes) ||
+      (size == kUnsignedTwoBytes) || (size == kSWord) || (size == kDWord) ||
       (size == kRegList)) {
     if (shift < 0) {
       ASSERT(shift == -1);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 1e9d2ff..f853da7 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -32,21 +32,6 @@
 class RegisterSet;
 class RuntimeEntry;
 
-// TODO(vegorov) these enumerations are temporarily moved out of compiler
-// namespace to make refactoring easier.
-enum OperandSize {
-  kByte,
-  kUnsignedByte,
-  kHalfword,
-  kUnsignedHalfword,
-  kWord,
-  kUnsignedWord,
-  kWordPair,
-  kSWord,
-  kDWord,
-  kRegList,
-};
-
 // Load/store multiple addressing mode.
 enum BlockAddressMode {
   // bit encoding P U W
@@ -398,14 +383,17 @@
   }
 
   void Bind(Label* label);
-  void Jump(Label* label) { b(label); }
+  // Unconditional jump to a given label. [distance] is ignored on ARM.
+  void Jump(Label* label, JumpDistance distance = kFarJump) { b(label); }
+  // Unconditional jump to a given address in memory.
+  void Jump(const Address& address) { Branch(address); }
 
   void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
-    LoadFromOffset(kWord, dst, base, offset, AL);
+    LoadFromOffset(dst, base, offset);
   }
   void StoreMemoryValue(Register src, Register base, int32_t offset) {
-    StoreToOffset(kWord, src, base, offset, AL);
+    StoreToOffset(src, base, offset);
   }
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     ldr(dst, Address(address, offset));
@@ -768,6 +756,7 @@
     ldr(LR, target);
     blx(LR);
   }
+  void Call(const Code& code) { BranchLink(code); }
 
   void CallCFunction(Address target) { Call(target); }
 
@@ -833,7 +822,7 @@
 
   void LoadIsolate(Register rd);
 
-  // Load word from pool from the given offset using encoding that
+  // Load word from pool from the given index using encoding that
   // InstructionPattern::DecodeLoadWordFromPool can decode.
   void LoadWordFromPoolIndex(Register rd,
                              intptr_t index,
@@ -929,29 +918,45 @@
 
   intptr_t FindImmediate(int32_t imm);
   bool CanLoadFromObjectPool(const Object& object) const;
-  void LoadFromOffset(OperandSize type,
-                      Register reg,
+  void LoadFromOffset(Register reg,
                       Register base,
                       int32_t offset,
+                      OperandSize type = kFourBytes,
                       Condition cond = AL);
-  void LoadFieldFromOffset(OperandSize type,
-                           Register reg,
+  void LoadFieldFromOffset(Register reg,
                            Register base,
                            int32_t offset,
+                           OperandSize type = kFourBytes,
                            Condition cond = AL) {
-    LoadFromOffset(type, reg, base, offset - kHeapObjectTag, cond);
+    LoadFromOffset(reg, base, offset - kHeapObjectTag, type, cond);
   }
-  void StoreToOffset(OperandSize type,
-                     Register reg,
+  // For loading indexed payloads out of tagged objects like Arrays. If the
+  // payload objects are word-sized, use TIMES_HALF_WORD_SIZE if the contents of
+  // [index] is a Smi, otherwise TIMES_WORD_SIZE if unboxed.
+  void LoadIndexedPayload(Register reg,
+                          Register base,
+                          int32_t payload_start,
+                          Register index,
+                          ScaleFactor scale,
+                          OperandSize type = kFourBytes) {
+    add(reg, base, Operand(index, LSL, scale));
+    LoadFromOffset(reg, reg, payload_start - kHeapObjectTag, type);
+  }
+  void LoadFromStack(Register dst, intptr_t depth);
+  void StoreToStack(Register src, intptr_t depth);
+  void CompareToStack(Register src, intptr_t depth);
+
+  void StoreToOffset(Register reg,
                      Register base,
                      int32_t offset,
+                     OperandSize type = kFourBytes,
                      Condition cond = AL);
-  void StoreFieldToOffset(OperandSize type,
-                          Register reg,
+  void StoreFieldToOffset(Register reg,
                           Register base,
                           int32_t offset,
+                          OperandSize type = kFourBytes,
                           Condition cond = AL) {
-    StoreToOffset(type, reg, base, offset - kHeapObjectTag, cond);
+    StoreToOffset(reg, base, offset - kHeapObjectTag, type, cond);
   }
   void LoadSFromOffset(SRegister reg,
                        Register base,
@@ -1011,7 +1016,19 @@
   void PopNativeCalleeSavedRegisters();
 
   void CompareRegisters(Register rn, Register rm) { cmp(rn, Operand(rm)); }
-  void BranchIf(Condition condition, Label* label) { b(label, condition); }
+  // Branches to the given label if the condition holds.
+  // [distance] is ignored on ARM.
+  void BranchIf(Condition condition,
+                Label* label,
+                JumpDistance distance = kFarJump) {
+    b(label, condition);
+  }
+  void BranchIfZero(Register rn,
+                    Label* label,
+                    JumpDistance distance = kFarJump) {
+    cmp(rn, Operand(0));
+    b(label, ZERO);
+  }
 
   void MoveRegister(Register rd, Register rm, Condition cond = AL);
 
@@ -1078,12 +1095,18 @@
     b(is_smi, CC);
   }
 
-  void BranchIfNotSmi(Register reg, Label* label) {
+  // For ARM, the near argument is ignored.
+  void BranchIfNotSmi(Register reg,
+                      Label* label,
+                      JumpDistance distance = kFarJump) {
     tst(reg, Operand(kSmiTagMask));
     b(label, NE);
   }
 
-  void BranchIfSmi(Register reg, Label* label) {
+  // For ARM, the near argument is ignored.
+  void BranchIfSmi(Register reg,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
     tst(reg, Operand(kSmiTagMask));
     b(label, EQ);
   }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 67d07c8..00b02db 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -508,6 +508,21 @@
   LoadObjectHelper(dst, object, true);
 }
 
+void Assembler::LoadFromStack(Register dst, intptr_t depth) {
+  ASSERT(depth >= 0);
+  LoadFromOffset(dst, SPREG, depth * target::kWordSize);
+}
+
+void Assembler::StoreToStack(Register src, intptr_t depth) {
+  ASSERT(depth >= 0);
+  StoreToOffset(src, SPREG, depth * target::kWordSize);
+}
+
+void Assembler::CompareToStack(Register src, intptr_t depth) {
+  LoadFromStack(TMP, depth);
+  CompareRegisters(src, TMP);
+}
+
 void Assembler::CompareObject(Register reg, const Object& object) {
   ASSERT(IsOriginalObject(object));
   word offset = 0;
@@ -680,11 +695,11 @@
                                      Register rn,
                                      int64_t imm,
                                      OperandSize sz) {
-  ASSERT(sz == kDoubleWord || sz == kWord);
+  ASSERT(sz == kEightBytes || sz == kFourBytes);
   Operand op;
   if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
     // Handles imm == kMinInt64.
-    if (sz == kDoubleWord) {
+    if (sz == kEightBytes) {
       adds(dest, rn, op);
     } else {
       addsw(dest, rn, op);
@@ -692,7 +707,7 @@
   } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
              Operand::Immediate) {
     ASSERT(imm != kMinInt64);  // Would cause erroneous overflow detection.
-    if (sz == kDoubleWord) {
+    if (sz == kEightBytes) {
       subs(dest, rn, op);
     } else {
       subsw(dest, rn, op);
@@ -701,7 +716,7 @@
     // TODO(zra): Try adding top 12 bits, then bottom 12 bits.
     ASSERT(rn != TMP2);
     LoadImmediate(TMP2, imm);
-    if (sz == kDoubleWord) {
+    if (sz == kEightBytes) {
       adds(dest, rn, Operand(TMP2));
     } else {
       addsw(dest, rn, Operand(TMP2));
@@ -714,10 +729,10 @@
                                      int64_t imm,
                                      OperandSize sz) {
   Operand op;
-  ASSERT(sz == kDoubleWord || sz == kWord);
+  ASSERT(sz == kEightBytes || sz == kFourBytes);
   if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
     // Handles imm == kMinInt64.
-    if (sz == kDoubleWord) {
+    if (sz == kEightBytes) {
       subs(dest, rn, op);
     } else {
       subsw(dest, rn, op);
@@ -725,7 +740,7 @@
   } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
              Operand::Immediate) {
     ASSERT(imm != kMinInt64);  // Would cause erroneous overflow detection.
-    if (sz == kDoubleWord) {
+    if (sz == kEightBytes) {
       adds(dest, rn, op);
     } else {
       addsw(dest, rn, op);
@@ -734,7 +749,7 @@
     // TODO(zra): Try subtracting top 12 bits, then bottom 12 bits.
     ASSERT(rn != TMP2);
     LoadImmediate(TMP2, imm);
-    if (sz == kDoubleWord) {
+    if (sz == kEightBytes) {
       subs(dest, rn, Operand(TMP2));
     } else {
       subsw(dest, rn, Operand(TMP2));
@@ -1141,7 +1156,7 @@
 void Assembler::ExtractClassIdFromTags(Register result, Register tags) {
   ASSERT(target::ObjectLayout::kClassIdTagPos == 16);
   ASSERT(target::ObjectLayout::kClassIdTagSize == 16);
-  LsrImmediate(result, tags, target::ObjectLayout::kClassIdTagPos, kWord);
+  LsrImmediate(result, tags, target::ObjectLayout::kClassIdTagPos, kFourBytes);
 }
 
 void Assembler::ExtractInstanceSizeFromTags(Register result, Register tags) {
@@ -1159,7 +1174,7 @@
       target::Object::tags_offset() +
       target::ObjectLayout::kClassIdTagPos / kBitsPerByte;
   LoadFromOffset(result, object, class_id_offset - kHeapObjectTag,
-                 kUnsignedHalfword);
+                 kUnsignedTwoBytes);
 }
 
 void Assembler::LoadClassById(Register result, Register class_id) {
@@ -1176,7 +1191,6 @@
 void Assembler::CompareClassId(Register object,
                                intptr_t class_id,
                                Register scratch) {
-  ASSERT(scratch == kNoRegister);
   LoadClassId(TMP, object);
   CompareImmediate(TMP, class_id);
 }
@@ -1744,10 +1758,7 @@
     // next object start and store the class in the class field of object.
     str(top_reg, Address(THR, target::Thread::top_offset()));
 
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
-    // Extends the 32 bit tags with zeros, which is the uninitialized
-    // hash code.
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     LoadImmediate(TMP, tags);
     StoreToOffset(TMP, instance_reg, target::Object::tags_offset());
 
@@ -1792,10 +1803,7 @@
 
     // Initialize the tags.
     // instance: new object start as a tagged pointer.
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
-    // Extends the 32 bit tags with zeros, which is the uninitialized
-    // hash code.
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     LoadImmediate(temp2, tags);
     str(temp2, FieldAddress(instance, target::Object::tags_offset()));
   } else {
@@ -2033,7 +2041,7 @@
 
 void Assembler::GenerateXCbzTbz(Register rn, Condition cond, Label* label) {
   constexpr int32_t bit_no = 63;
-  constexpr OperandSize sz = kDoubleWord;
+  constexpr OperandSize sz = kEightBytes;
   ASSERT(rn != CSP);
   switch (cond) {
     case EQ:  // equal
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index b74553e..3290499 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -32,6 +32,50 @@
 
 namespace compiler {
 
+static inline int Log2OperandSizeBytes(OperandSize os) {
+  switch (os) {
+    case kByte:
+    case kUnsignedByte:
+      return 0;
+    case kTwoBytes:
+    case kUnsignedTwoBytes:
+      return 1;
+    case kFourBytes:
+    case kUnsignedFourBytes:
+    case kSWord:
+      return 2;
+    case kEightBytes:
+    case kDWord:
+      return 3;
+    case kQWord:
+      return 4;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  return -1;
+}
+
+static inline bool IsSignedOperand(OperandSize os) {
+  switch (os) {
+    case kByte:
+    case kTwoBytes:
+    case kFourBytes:
+      return true;
+    case kUnsignedByte:
+    case kUnsignedTwoBytes:
+    case kUnsignedFourBytes:
+    case kEightBytes:
+    case kSWord:
+    case kDWord:
+    case kQWord:
+      return false;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  return false;
+}
 class Immediate : public ValueObject {
  public:
   explicit Immediate(int64_t value) : value_(value) {}
@@ -135,7 +179,7 @@
   Address(Register rn,
           int32_t offset = 0,
           AddressType at = Offset,
-          OperandSize sz = kDoubleWord) {
+          OperandSize sz = kEightBytes) {
     ASSERT((rn != kNoRegister) && (rn != R31) && (rn != ZR));
     ASSERT(CanHoldOffset(offset, at, sz));
     log2sz_ = -1;
@@ -190,11 +234,11 @@
   Address(Register rn,
           Register offset,
           AddressType at,
-          OperandSize sz = kDoubleWord);
+          OperandSize sz = kEightBytes);
 
   static bool CanHoldOffset(int32_t offset,
                             AddressType at = Offset,
-                            OperandSize sz = kDoubleWord) {
+                            OperandSize sz = kEightBytes) {
     if (at == Offset) {
       // Offset fits in 12 bit unsigned and has right alignment for sz,
       // or fits in 9 bit signed offset with no alignment restriction.
@@ -230,7 +274,7 @@
   static Address Pair(Register rn,
                       int32_t offset = 0,
                       AddressType at = PairOffset,
-                      OperandSize sz = kDoubleWord) {
+                      OperandSize sz = kEightBytes) {
     return Address(rn, offset, at, sz);
   }
 
@@ -267,13 +311,13 @@
       case kArrayCid:
       case kImmutableArrayCid:
       case kTypeArgumentsCid:
-        return kWord;
+        return kFourBytes;
       case kOneByteStringCid:
       case kExternalOneByteStringCid:
         return kByte;
       case kTwoByteStringCid:
       case kExternalTwoByteStringCid:
-        return kHalfword;
+        return kTwoBytes;
       case kTypedDataInt8ArrayCid:
         return kByte;
       case kTypedDataUint8ArrayCid:
@@ -282,13 +326,13 @@
       case kExternalTypedDataUint8ClampedArrayCid:
         return kUnsignedByte;
       case kTypedDataInt16ArrayCid:
-        return kHalfword;
+        return kTwoBytes;
       case kTypedDataUint16ArrayCid:
-        return kUnsignedHalfword;
+        return kUnsignedTwoBytes;
       case kTypedDataInt32ArrayCid:
-        return kWord;
+        return kFourBytes;
       case kTypedDataUint32ArrayCid:
-        return kUnsignedWord;
+        return kUnsignedFourBytes;
       case kTypedDataInt64ArrayCid:
       case kTypedDataUint64ArrayCid:
         return kDWord;
@@ -326,11 +370,11 @@
 
 class FieldAddress : public Address {
  public:
-  FieldAddress(Register base, int32_t disp, OperandSize sz = kDoubleWord)
+  FieldAddress(Register base, int32_t disp, OperandSize sz = kEightBytes)
       : Address(base, disp - kHeapObjectTag, Offset, sz) {}
 
   // This addressing mode does not exist.
-  FieldAddress(Register base, Register disp, OperandSize sz = kDoubleWord);
+  FieldAddress(Register base, Register disp, OperandSize sz = kEightBytes);
 
   FieldAddress(const FieldAddress& other) : Address(other) {}
 
@@ -494,14 +538,20 @@
   }
 
   void Bind(Label* label);
-  void Jump(Label* label) { b(label); }
+  // Unconditional jump to a given label. [distance] is ignored on ARM.
+  void Jump(Label* label, JumpDistance distance = kFarJump) { b(label); }
+  // Unconditional jump to a given address in memory. Clobbers TMP.
+  void Jump(const Address& address) {
+    ldr(TMP, address);
+    br(TMP);
+  }
 
   void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
-    LoadFromOffset(dst, base, offset, kDoubleWord);
+    LoadFromOffset(dst, base, offset, kEightBytes);
   }
   void StoreMemoryValue(Register src, Register base, int32_t offset) {
-    StoreToOffset(src, base, offset, kDoubleWord);
+    StoreToOffset(src, base, offset, kEightBytes);
   }
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     if (offset != 0) {
@@ -579,54 +629,54 @@
   // For add and sub, to use CSP for rn, o must be of type Operand::Extend.
   // For an unmodified rm in this case, use Operand(rm, UXTX, 0);
   void add(Register rd, Register rn, Operand o) {
-    AddSubHelper(kDoubleWord, false, false, rd, rn, o);
+    AddSubHelper(kEightBytes, false, false, rd, rn, o);
   }
   void adds(Register rd, Register rn, Operand o) {
-    AddSubHelper(kDoubleWord, true, false, rd, rn, o);
+    AddSubHelper(kEightBytes, true, false, rd, rn, o);
   }
   void addw(Register rd, Register rn, Operand o) {
-    AddSubHelper(kWord, false, false, rd, rn, o);
+    AddSubHelper(kFourBytes, false, false, rd, rn, o);
   }
   void addsw(Register rd, Register rn, Operand o) {
-    AddSubHelper(kWord, true, false, rd, rn, o);
+    AddSubHelper(kFourBytes, true, false, rd, rn, o);
   }
   void sub(Register rd, Register rn, Operand o) {
-    AddSubHelper(kDoubleWord, false, true, rd, rn, o);
+    AddSubHelper(kEightBytes, false, true, rd, rn, o);
   }
   void subs(Register rd, Register rn, Operand o) {
-    AddSubHelper(kDoubleWord, true, true, rd, rn, o);
+    AddSubHelper(kEightBytes, true, true, rd, rn, o);
   }
   void subw(Register rd, Register rn, Operand o) {
-    AddSubHelper(kWord, false, true, rd, rn, o);
+    AddSubHelper(kFourBytes, false, true, rd, rn, o);
   }
   void subsw(Register rd, Register rn, Operand o) {
-    AddSubHelper(kWord, true, true, rd, rn, o);
+    AddSubHelper(kFourBytes, true, true, rd, rn, o);
   }
 
   // Addition and subtraction with carry.
   void adc(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kDoubleWord, false, false, rd, rn, rm);
+    AddSubWithCarryHelper(kEightBytes, false, false, rd, rn, rm);
   }
   void adcs(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kDoubleWord, true, false, rd, rn, rm);
+    AddSubWithCarryHelper(kEightBytes, true, false, rd, rn, rm);
   }
   void adcw(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kWord, false, false, rd, rn, rm);
+    AddSubWithCarryHelper(kFourBytes, false, false, rd, rn, rm);
   }
   void adcsw(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kWord, true, false, rd, rn, rm);
+    AddSubWithCarryHelper(kFourBytes, true, false, rd, rn, rm);
   }
   void sbc(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kDoubleWord, false, true, rd, rn, rm);
+    AddSubWithCarryHelper(kEightBytes, false, true, rd, rn, rm);
   }
   void sbcs(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kDoubleWord, true, true, rd, rn, rm);
+    AddSubWithCarryHelper(kEightBytes, true, true, rd, rn, rm);
   }
   void sbcw(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kWord, false, true, rd, rn, rm);
+    AddSubWithCarryHelper(kFourBytes, false, true, rd, rn, rm);
   }
   void sbcsw(Register rd, Register rn, Register rm) {
-    AddSubWithCarryHelper(kWord, true, true, rd, rn, rm);
+    AddSubWithCarryHelper(kFourBytes, true, true, rd, rn, rm);
   }
 
   // PC relative immediate add. imm is in bytes.
@@ -640,7 +690,7 @@
            Register rn,
            int r_imm,
            int s_imm,
-           OperandSize size = kDoubleWord) {
+           OperandSize size = kEightBytes) {
     EmitBitfieldOp(BFM, rd, rn, r_imm, s_imm, size);
   }
 
@@ -649,7 +699,7 @@
             Register rn,
             int r_imm,
             int s_imm,
-            OperandSize size = kDoubleWord) {
+            OperandSize size = kEightBytes) {
     EmitBitfieldOp(SBFM, rd, rn, r_imm, s_imm, size);
   }
 
@@ -658,7 +708,7 @@
             Register rn,
             int r_imm,
             int s_imm,
-            OperandSize size = kDoubleWord) {
+            OperandSize size = kEightBytes) {
     EmitBitfieldOp(UBFM, rd, rn, r_imm, s_imm, size);
   }
 
@@ -668,8 +718,8 @@
            Register rn,
            int low_bit,
            int width,
-           OperandSize size = kDoubleWord) {
-    int wordsize = size == kDoubleWord ? 64 : 32;
+           OperandSize size = kEightBytes) {
+    int wordsize = size == kEightBytes ? 64 : 32;
     EmitBitfieldOp(BFM, rd, rn, -low_bit & (wordsize - 1), width - 1, size);
   }
 
@@ -679,7 +729,7 @@
              Register rn,
              int low_bit,
              int width,
-             OperandSize size = kDoubleWord) {
+             OperandSize size = kEightBytes) {
     EmitBitfieldOp(BFM, rd, rn, low_bit, low_bit + width - 1, size);
   }
 
@@ -690,8 +740,8 @@
              Register rn,
              int low_bit,
              int width,
-             OperandSize size = kDoubleWord) {
-    int wordsize = size == kDoubleWord ? 64 : 32;
+             OperandSize size = kEightBytes) {
+    int wordsize = size == kEightBytes ? 64 : 32;
     EmitBitfieldOp(SBFM, rd, rn, (wordsize - low_bit) & (wordsize - 1),
                    width - 1, size);
   }
@@ -702,7 +752,7 @@
             Register rn,
             int low_bit,
             int width,
-            OperandSize size = kDoubleWord) {
+            OperandSize size = kEightBytes) {
     EmitBitfieldOp(SBFM, rd, rn, low_bit, low_bit + width - 1, size);
   }
 
@@ -712,8 +762,8 @@
              Register rn,
              int low_bit,
              int width,
-             OperandSize size = kDoubleWord) {
-    int wordsize = size == kDoubleWord ? 64 : 32;
+             OperandSize size = kEightBytes) {
+    int wordsize = size == kEightBytes ? 64 : 32;
     ASSERT(width > 0);
     ASSERT(low_bit < wordsize);
     EmitBitfieldOp(UBFM, rd, rn, (-low_bit) & (wordsize - 1), width - 1, size);
@@ -725,38 +775,38 @@
             Register rn,
             int low_bit,
             int width,
-            OperandSize size = kDoubleWord) {
+            OperandSize size = kEightBytes) {
     EmitBitfieldOp(UBFM, rd, rn, low_bit, low_bit + width - 1, size);
   }
 
   // Sign extend byte->64 bit.
   void sxtb(Register rd, Register rn) {
-    EmitBitfieldOp(SBFM, rd, rn, 0, 7, kDoubleWord);
+    EmitBitfieldOp(SBFM, rd, rn, 0, 7, kEightBytes);
   }
 
   // Sign extend halfword->64 bit.
   void sxth(Register rd, Register rn) {
-    EmitBitfieldOp(SBFM, rd, rn, 0, 15, kDoubleWord);
+    EmitBitfieldOp(SBFM, rd, rn, 0, 15, kEightBytes);
   }
 
   // Sign extend word->64 bit.
   void sxtw(Register rd, Register rn) {
-    EmitBitfieldOp(SBFM, rd, rn, 0, 31, kDoubleWord);
+    EmitBitfieldOp(SBFM, rd, rn, 0, 31, kEightBytes);
   }
 
   // Zero/unsigned extend byte->64 bit.
   void uxtb(Register rd, Register rn) {
-    EmitBitfieldOp(UBFM, rd, rn, 0, 7, kDoubleWord);
+    EmitBitfieldOp(UBFM, rd, rn, 0, 7, kEightBytes);
   }
 
   // Zero/unsigned extend halfword->64 bit.
   void uxth(Register rd, Register rn) {
-    EmitBitfieldOp(UBFM, rd, rn, 0, 15, kDoubleWord);
+    EmitBitfieldOp(UBFM, rd, rn, 0, 15, kEightBytes);
   }
 
   // Zero/unsigned extend word->64 bit.
   void uxtw(Register rd, Register rn) {
-    EmitBitfieldOp(UBFM, rd, rn, 0, 31, kDoubleWord);
+    EmitBitfieldOp(UBFM, rd, rn, 0, 31, kEightBytes);
   }
 
   // Logical immediate operations.
@@ -765,153 +815,153 @@
     const bool immok =
         Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
     ASSERT(immok);
-    EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord);
+    EmitLogicalImmOp(ANDI, rd, rn, imm_op, kEightBytes);
   }
   void orri(Register rd, Register rn, const Immediate& imm) {
     Operand imm_op;
     const bool immok =
         Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
     ASSERT(immok);
-    EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord);
+    EmitLogicalImmOp(ORRI, rd, rn, imm_op, kEightBytes);
   }
   void eori(Register rd, Register rn, const Immediate& imm) {
     Operand imm_op;
     const bool immok =
         Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
     ASSERT(immok);
-    EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord);
+    EmitLogicalImmOp(EORI, rd, rn, imm_op, kEightBytes);
   }
   void andis(Register rd, Register rn, const Immediate& imm) {
     Operand imm_op;
     const bool immok =
         Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
     ASSERT(immok);
-    EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord);
+    EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kEightBytes);
   }
 
   // Logical (shifted) register operations.
   void and_(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(AND, rd, rn, o, kEightBytes);
   }
   void andw_(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(AND, rd, rn, o, kWord);
+    EmitLogicalShiftOp(AND, rd, rn, o, kFourBytes);
   }
   void bic(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(BIC, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(BIC, rd, rn, o, kEightBytes);
   }
   void orr(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(ORR, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(ORR, rd, rn, o, kEightBytes);
   }
   void orrw(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(ORR, rd, rn, o, kWord);
+    EmitLogicalShiftOp(ORR, rd, rn, o, kFourBytes);
   }
   void orn(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(ORN, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(ORN, rd, rn, o, kEightBytes);
   }
   void ornw(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(ORN, rd, rn, o, kWord);
+    EmitLogicalShiftOp(ORN, rd, rn, o, kFourBytes);
   }
   void eor(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(EOR, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(EOR, rd, rn, o, kEightBytes);
   }
   void eorw(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(EOR, rd, rn, o, kWord);
+    EmitLogicalShiftOp(EOR, rd, rn, o, kFourBytes);
   }
   void eon(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(EON, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(EON, rd, rn, o, kEightBytes);
   }
   void ands(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(ANDS, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(ANDS, rd, rn, o, kEightBytes);
   }
   void bics(Register rd, Register rn, Operand o) {
-    EmitLogicalShiftOp(BICS, rd, rn, o, kDoubleWord);
+    EmitLogicalShiftOp(BICS, rd, rn, o, kEightBytes);
   }
 
   // Count leading zero bits.
   void clz(Register rd, Register rn) {
-    EmitMiscDP1Source(CLZ, rd, rn, kDoubleWord);
+    EmitMiscDP1Source(CLZ, rd, rn, kEightBytes);
   }
 
   // Reverse bits.
   void rbit(Register rd, Register rn) {
-    EmitMiscDP1Source(RBIT, rd, rn, kDoubleWord);
+    EmitMiscDP1Source(RBIT, rd, rn, kEightBytes);
   }
 
   // Misc. arithmetic.
   void udiv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(UDIV, rd, rn, rm, kDoubleWord);
+    EmitMiscDP2Source(UDIV, rd, rn, rm, kEightBytes);
   }
   void sdiv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(SDIV, rd, rn, rm, kDoubleWord);
+    EmitMiscDP2Source(SDIV, rd, rn, rm, kEightBytes);
   }
   void lslv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSLV, rd, rn, rm, kDoubleWord);
+    EmitMiscDP2Source(LSLV, rd, rn, rm, kEightBytes);
   }
   void lsrv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSRV, rd, rn, rm, kDoubleWord);
+    EmitMiscDP2Source(LSRV, rd, rn, rm, kEightBytes);
   }
   void asrv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(ASRV, rd, rn, rm, kDoubleWord);
+    EmitMiscDP2Source(ASRV, rd, rn, rm, kEightBytes);
   }
   void lslvw(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSLV, rd, rn, rm, kWord);
+    EmitMiscDP2Source(LSLV, rd, rn, rm, kFourBytes);
   }
   void lsrvw(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSRV, rd, rn, rm, kWord);
+    EmitMiscDP2Source(LSRV, rd, rn, rm, kFourBytes);
   }
   void asrvw(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(ASRV, rd, rn, rm, kWord);
+    EmitMiscDP2Source(ASRV, rd, rn, rm, kFourBytes);
   }
   void madd(Register rd,
             Register rn,
             Register rm,
             Register ra,
-            OperandSize sz = kDoubleWord) {
+            OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(MADD, rd, rn, rm, ra, sz);
   }
   void msub(Register rd,
             Register rn,
             Register rm,
             Register ra,
-            OperandSize sz = kDoubleWord) {
+            OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(MSUB, rd, rn, rm, ra, sz);
   }
   void smulh(Register rd,
              Register rn,
              Register rm,
-             OperandSize sz = kDoubleWord) {
+             OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(SMULH, rd, rn, rm, R31, sz);
   }
   void umulh(Register rd,
              Register rn,
              Register rm,
-             OperandSize sz = kDoubleWord) {
+             OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(UMULH, rd, rn, rm, R31, sz);
   }
   void umaddl(Register rd,
               Register rn,
               Register rm,
               Register ra,
-              OperandSize sz = kDoubleWord) {
+              OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(UMADDL, rd, rn, rm, ra, sz);
   }
   void umull(Register rd,
              Register rn,
              Register rm,
-             OperandSize sz = kDoubleWord) {
+             OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(UMADDL, rd, rn, rm, ZR, sz);
   }
   void smaddl(Register rd,
               Register rn,
               Register rm,
               Register ra,
-              OperandSize sz = kDoubleWord) {
+              OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(SMADDL, rd, rn, rm, ra, sz);
   }
   void smull(Register rd,
              Register rn,
              Register rm,
-             OperandSize sz = kDoubleWord) {
+             OperandSize sz = kEightBytes) {
     EmitMiscDP3Source(SMADDL, rd, rn, rm, ZR, sz);
   }
 
@@ -919,26 +969,26 @@
   void movk(Register rd, const Immediate& imm, int hw_idx) {
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
-    EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord);
+    EmitMoveWideOp(MOVK, crd, imm, hw_idx, kEightBytes);
   }
   void movn(Register rd, const Immediate& imm, int hw_idx) {
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
-    EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord);
+    EmitMoveWideOp(MOVN, crd, imm, hw_idx, kEightBytes);
   }
   void movz(Register rd, const Immediate& imm, int hw_idx) {
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
-    EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord);
+    EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kEightBytes);
   }
 
   // Loads and Stores.
-  void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) {
+  void ldr(Register rt, Address a, OperandSize sz = kEightBytes) {
     ASSERT((a.type() != Address::PairOffset) &&
            (a.type() != Address::PairPostIndex) &&
            (a.type() != Address::PairPreIndex));
     if (a.type() == Address::PCOffset) {
-      ASSERT(sz == kDoubleWord);
+      ASSERT(sz == kEightBytes);
       EmitLoadRegLiteral(LDRpc, rt, a, sz);
     } else {
       if (IsSignedOperand(sz)) {
@@ -948,27 +998,27 @@
       }
     }
   }
-  void str(Register rt, Address a, OperandSize sz = kDoubleWord) {
+  void str(Register rt, Address a, OperandSize sz = kEightBytes) {
     ASSERT((a.type() != Address::PairOffset) &&
            (a.type() != Address::PairPostIndex) &&
            (a.type() != Address::PairPreIndex));
     EmitLoadStoreReg(STR, rt, a, sz);
   }
 
-  void ldp(Register rt, Register rt2, Address a, OperandSize sz = kDoubleWord) {
+  void ldp(Register rt, Register rt2, Address a, OperandSize sz = kEightBytes) {
     ASSERT((a.type() == Address::PairOffset) ||
            (a.type() == Address::PairPostIndex) ||
            (a.type() == Address::PairPreIndex));
     EmitLoadStoreRegPair(LDP, rt, rt2, a, sz);
   }
-  void stp(Register rt, Register rt2, Address a, OperandSize sz = kDoubleWord) {
+  void stp(Register rt, Register rt2, Address a, OperandSize sz = kEightBytes) {
     ASSERT((a.type() == Address::PairOffset) ||
            (a.type() == Address::PairPostIndex) ||
            (a.type() == Address::PairPreIndex));
     EmitLoadStoreRegPair(STP, rt, rt2, a, sz);
   }
 
-  void ldxr(Register rt, Register rn, OperandSize size = kDoubleWord) {
+  void ldxr(Register rt, Register rn, OperandSize size = kEightBytes) {
     // rt = value
     // rn = address
     EmitLoadStoreExclusive(LDXR, R31, rn, rt, size);
@@ -976,7 +1026,7 @@
   void stxr(Register rs,
             Register rt,
             Register rn,
-            OperandSize size = kDoubleWord) {
+            OperandSize size = kEightBytes) {
     // rs = status (1 = failure, 0 = success)
     // rt = value
     // rn = address
@@ -987,20 +1037,20 @@
     Emit(encoding);
   }
 
-  void ldar(Register rt, Register rn, OperandSize sz = kDoubleWord) {
+  void ldar(Register rt, Register rn, OperandSize sz = kEightBytes) {
     EmitLoadStoreExclusive(LDAR, R31, rn, rt, sz);
   }
 
-  void stlr(Register rt, Register rn, OperandSize sz = kDoubleWord) {
+  void stlr(Register rt, Register rn, OperandSize sz = kEightBytes) {
     EmitLoadStoreExclusive(STLR, R31, rn, rt, sz);
   }
 
   // Conditional select.
   void csel(Register rd, Register rn, Register rm, Condition cond) {
-    EmitConditionalSelect(CSEL, rd, rn, rm, cond, kDoubleWord);
+    EmitConditionalSelect(CSEL, rd, rn, rm, cond, kEightBytes);
   }
   void csinc(Register rd, Register rn, Register rm, Condition cond) {
-    EmitConditionalSelect(CSINC, rd, rn, rm, cond, kDoubleWord);
+    EmitConditionalSelect(CSINC, rd, rn, rm, cond, kEightBytes);
   }
   void cinc(Register rd, Register rn, Condition cond) {
     csinc(rd, rn, rn, InvertCondition(cond));
@@ -1009,7 +1059,7 @@
     csinc(rd, ZR, ZR, InvertCondition(cond));
   }
   void csinv(Register rd, Register rn, Register rm, Condition cond) {
-    EmitConditionalSelect(CSINV, rd, rn, rm, cond, kDoubleWord);
+    EmitConditionalSelect(CSINV, rd, rn, rm, cond, kEightBytes);
   }
   void cinv(Register rd, Register rn, Condition cond) {
     csinv(rd, rn, rn, InvertCondition(cond));
@@ -1018,11 +1068,11 @@
     csinv(rd, ZR, ZR, InvertCondition(cond));
   }
   void csneg(Register rd, Register rn, Register rm, Condition cond) {
-    EmitConditionalSelect(CSNEG, rd, rn, rm, cond, kDoubleWord);
+    EmitConditionalSelect(CSNEG, rd, rn, rm, cond, kEightBytes);
   }
   void cneg(Register rd, Register rn, Condition cond) {
     EmitConditionalSelect(CSNEG, rd, rn, rn, InvertCondition(cond),
-                          kDoubleWord);
+                          kEightBytes);
   }
 
   // Comparison.
@@ -1052,13 +1102,24 @@
   void b(int32_t offset) { EmitUnconditionalBranchOp(B, offset); }
   void bl(int32_t offset) { EmitUnconditionalBranchOp(BL, offset); }
 
-  void BranchIf(Condition condition, Label* label) { b(label, condition); }
+  // Branches to the given label if the condition holds.
+  // [distance] is ignored on ARM.
+  void BranchIf(Condition condition,
+                Label* label,
+                JumpDistance distance = kFarJump) {
+    b(label, condition);
+  }
+  void BranchIfZero(Register rn,
+                    Label* label,
+                    JumpDistance distance = kFarJump) {
+    cbz(label, rn);
+  }
 
-  void cbz(Label* label, Register rt, OperandSize sz = kDoubleWord) {
+  void cbz(Label* label, Register rt, OperandSize sz = kEightBytes) {
     EmitCompareAndBranch(CBZ, rt, label, sz);
   }
 
-  void cbnz(Label* label, Register rt, OperandSize sz = kDoubleWord) {
+  void cbnz(Label* label, Register rt, OperandSize sz = kEightBytes) {
     EmitCompareAndBranch(CBNZ, rt, label, sz);
   }
 
@@ -1102,13 +1163,13 @@
     ASSERT(rn != R31);
     ASSERT(rn != CSP);
     const Register crn = ConcreteRegister(rn);
-    EmitFPIntCvtOp(FMOVSR, static_cast<Register>(vd), crn, kWord);
+    EmitFPIntCvtOp(FMOVSR, static_cast<Register>(vd), crn, kFourBytes);
   }
   void fmovrs(Register rd, VRegister vn) {
     ASSERT(rd != R31);
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
-    EmitFPIntCvtOp(FMOVRS, crd, static_cast<Register>(vn), kWord);
+    EmitFPIntCvtOp(FMOVRS, crd, static_cast<Register>(vn), kFourBytes);
   }
   void fmovdr(VRegister vd, Register rn) {
     ASSERT(rn != R31);
@@ -1132,7 +1193,7 @@
     ASSERT(rn != R31);
     ASSERT(rn != CSP);
     const Register crn = ConcreteRegister(rn);
-    EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn, kWord);
+    EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn, kFourBytes);
   }
   void fcvtzds(Register rd, VRegister vn) {
     ASSERT(rd != R31);
@@ -1282,11 +1343,11 @@
   }
   void vdupw(VRegister vd, Register rn) {
     const VRegister vn = static_cast<VRegister>(rn);
-    EmitSIMDCopyOp(VDUPI, vd, vn, kWord, 0, 0);
+    EmitSIMDCopyOp(VDUPI, vd, vn, kFourBytes, 0, 0);
   }
   void vdupx(VRegister vd, Register rn) {
     const VRegister vn = static_cast<VRegister>(rn);
-    EmitSIMDCopyOp(VDUPI, vd, vn, kDoubleWord, 0, 0);
+    EmitSIMDCopyOp(VDUPI, vd, vn, kEightBytes, 0, 0);
   }
   void vdups(VRegister vd, VRegister vn, int32_t idx) {
     EmitSIMDCopyOp(VDUP, vd, vn, kSWord, 0, idx);
@@ -1296,11 +1357,11 @@
   }
   void vinsw(VRegister vd, int32_t didx, Register rn) {
     const VRegister vn = static_cast<VRegister>(rn);
-    EmitSIMDCopyOp(VINSI, vd, vn, kWord, 0, didx);
+    EmitSIMDCopyOp(VINSI, vd, vn, kFourBytes, 0, didx);
   }
   void vinsx(VRegister vd, int32_t didx, Register rn) {
     const VRegister vn = static_cast<VRegister>(rn);
-    EmitSIMDCopyOp(VINSI, vd, vn, kDoubleWord, 0, didx);
+    EmitSIMDCopyOp(VINSI, vd, vn, kEightBytes, 0, didx);
   }
   void vinss(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) {
     EmitSIMDCopyOp(VINS, vd, vn, kSWord, sidx, didx);
@@ -1310,11 +1371,11 @@
   }
   void vmovrs(Register rd, VRegister vn, int32_t sidx) {
     const VRegister vd = static_cast<VRegister>(rd);
-    EmitSIMDCopyOp(VMOVW, vd, vn, kWord, 0, sidx);
+    EmitSIMDCopyOp(VMOVW, vd, vn, kFourBytes, 0, sidx);
   }
   void vmovrd(Register rd, VRegister vn, int32_t sidx) {
     const VRegister vd = static_cast<VRegister>(rd);
-    EmitSIMDCopyOp(VMOVX, vd, vn, kDoubleWord, 0, sidx);
+    EmitSIMDCopyOp(VMOVX, vd, vn, kEightBytes, 0, sidx);
   }
 
   // Aliases.
@@ -1339,10 +1400,10 @@
   void negs(Register rd, Register rm) { subs(rd, ZR, Operand(rm)); }
   void negsw(Register rd, Register rm) { subsw(rd, ZR, Operand(rm)); }
   void mul(Register rd, Register rn, Register rm) {
-    madd(rd, rn, rm, ZR, kDoubleWord);
+    madd(rd, rn, rm, ZR, kEightBytes);
   }
   void mulw(Register rd, Register rn, Register rm) {
-    madd(rd, rn, rm, ZR, kWord);
+    madd(rd, rn, rm, ZR, kFourBytes);
   }
   void Push(Register reg) {
     ASSERT(reg != PP);  // Only push PP with TagAndPushPP().
@@ -1400,17 +1461,17 @@
   void LslImmediate(Register rd,
                     Register rn,
                     int shift,
-                    OperandSize sz = kDoubleWord) {
+                    OperandSize sz = kEightBytes) {
     const int reg_size =
-        (sz == kDoubleWord) ? kXRegSizeInBits : kWRegSizeInBits;
+        (sz == kEightBytes) ? kXRegSizeInBits : kWRegSizeInBits;
     ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1, sz);
   }
   void LsrImmediate(Register rd,
                     Register rn,
                     int shift,
-                    OperandSize sz = kDoubleWord) {
+                    OperandSize sz = kEightBytes) {
     const int reg_size =
-        (sz == kDoubleWord) ? kXRegSizeInBits : kWRegSizeInBits;
+        (sz == kEightBytes) ? kXRegSizeInBits : kWRegSizeInBits;
     ubfm(rd, rn, shift, reg_size - 1, sz);
   }
   void AsrImmediate(Register rd, Register rn, int shift) {
@@ -1430,9 +1491,19 @@
     LslImmediate(dst, src, kSmiTagSize);
   }
 
-  void BranchIfNotSmi(Register reg, Label* label) { tbnz(label, reg, kSmiTag); }
+  // For ARM, the near argument is ignored.
+  void BranchIfNotSmi(Register reg,
+                      Label* label,
+                      JumpDistance distance = kFarJump) {
+    tbnz(label, reg, kSmiTag);
+  }
 
-  void BranchIfSmi(Register reg, Label* label) { tbz(label, reg, kSmiTag); }
+  // For ARM, the near argument is ignored.
+  void BranchIfSmi(Register reg,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
+    tbz(label, reg, kSmiTag);
+  }
 
   void Branch(const Code& code,
               Register pp,
@@ -1461,6 +1532,7 @@
     ldr(LR, target);
     blr(LR);
   }
+  void Call(const Code& code) { BranchLink(code); }
 
   void CallCFunction(Address target) { Call(target); }
 
@@ -1476,11 +1548,11 @@
   void AddImmediateSetFlags(Register dest,
                             Register rn,
                             int64_t imm,
-                            OperandSize sz = kDoubleWord);
+                            OperandSize sz = kEightBytes);
   void SubImmediateSetFlags(Register dest,
                             Register rn,
                             int64_t imm,
-                            OperandSize sz = kDoubleWord);
+                            OperandSize sz = kEightBytes);
   void AndImmediate(Register rd, Register rn, int64_t imm);
   void OrImmediate(Register rd, Register rn, int64_t imm);
   void XorImmediate(Register rd, Register rn, int64_t imm);
@@ -1488,15 +1560,30 @@
   void CompareImmediate(Register rn, int64_t imm);
 
   void LoadFromOffset(Register dest,
+                      const Address& address,
+                      OperandSize sz = kEightBytes);
+  void LoadFromOffset(Register dest,
                       Register base,
                       int32_t offset,
-                      OperandSize sz = kDoubleWord);
+                      OperandSize sz = kEightBytes);
   void LoadFieldFromOffset(Register dest,
                            Register base,
                            int32_t offset,
-                           OperandSize sz = kDoubleWord) {
+                           OperandSize sz = kEightBytes) {
     LoadFromOffset(dest, base, offset - kHeapObjectTag, sz);
   }
+  // For loading indexed payloads out of tagged objects like Arrays. If the
+  // payload objects are word-sized, use TIMES_HALF_WORD_SIZE if the contents of
+  // [index] is a Smi, otherwise TIMES_WORD_SIZE if unboxed.
+  void LoadIndexedPayload(Register dest,
+                          Register base,
+                          int32_t payload_offset,
+                          Register index,
+                          ScaleFactor scale,
+                          OperandSize sz = kEightBytes) {
+    add(dest, base, Operand(index, LSL, scale));
+    LoadFromOffset(dest, dest, payload_offset - kHeapObjectTag, sz);
+  }
   void LoadSFromOffset(VRegister dest, Register base, int32_t offset);
   void LoadDFromOffset(VRegister dest, Register base, int32_t offset);
   void LoadDFieldFromOffset(VRegister dest, Register base, int32_t offset) {
@@ -1507,14 +1594,18 @@
     LoadQFromOffset(dest, base, offset - kHeapObjectTag);
   }
 
+  void LoadFromStack(Register dst, intptr_t depth);
+  void StoreToStack(Register src, intptr_t depth);
+  void CompareToStack(Register src, intptr_t depth);
+
   void StoreToOffset(Register src,
                      Register base,
                      int32_t offset,
-                     OperandSize sz = kDoubleWord);
+                     OperandSize sz = kEightBytes);
   void StoreFieldToOffset(Register src,
                           Register base,
                           int32_t offset,
-                          OperandSize sz = kDoubleWord) {
+                          OperandSize sz = kEightBytes) {
     StoreToOffset(src, base, offset - kHeapObjectTag, sz);
   }
 
@@ -1875,7 +1966,7 @@
                              Register rm) {
     ASSERT((rd != R31) && (rn != R31) && (rm != R31));
     ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t s = set_flags ? B29 : 0;
     const int32_t op = subtract ? SBC : ADC;
     const int32_t encoding = op | size | s | Arm64Encode::Rd(rd) |
@@ -1889,8 +1980,9 @@
                        Operand o,
                        OperandSize sz,
                        bool set_flags) {
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t s = set_flags ? B29 : 0;
     const int32_t encoding = op | size | s | Arm64Encode::Rd(rd) |
                              Arm64Encode::Rn(rn) | o.encoding();
@@ -1905,13 +1997,13 @@
                       int r_imm,
                       int s_imm,
                       OperandSize size) {
-    if (size != kDoubleWord) {
-      ASSERT(size == kWord);
+    if (size != kEightBytes) {
+      ASSERT(size == kFourBytes);
       ASSERT(r_imm < 32 && s_imm < 32);
     } else {
       ASSERT(r_imm < 64 && s_imm < 64);
     }
-    const int32_t instr = op | (size == kDoubleWord ? Bitfield64 : 0);
+    const int32_t instr = op | (size == kEightBytes ? Bitfield64 : 0);
     const int32_t encoding = instr | Operand(0, s_imm, r_imm).encoding() |
                              Arm64Encode::Rd(rd) | Arm64Encode::Rn(rn);
     Emit(encoding);
@@ -1922,13 +2014,14 @@
                         Register rn,
                         Operand o,
                         OperandSize sz) {
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
     ASSERT((rd != R31) && (rn != R31));
     ASSERT(rn != CSP);
     ASSERT((op == ANDIS) || (rd != ZR));   // op != ANDIS => rd != ZR.
     ASSERT((op != ANDIS) || (rd != CSP));  // op == ANDIS => rd != CSP.
     ASSERT(o.type() == Operand::BitfieldImm);
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding =
         op | size | Arm64Encode::Rd(rd) | Arm64Encode::Rn(rn) | o.encoding();
     Emit(encoding);
@@ -1939,11 +2032,12 @@
                           Register rn,
                           Operand o,
                           OperandSize sz) {
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
     ASSERT((rd != R31) && (rn != R31));
     ASSERT((rd != CSP) && (rn != CSP));
     ASSERT(o.type() == Operand::Shifted);
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding =
         op | size | Arm64Encode::Rd(rd) | Arm64Encode::Rn(rn) | o.encoding();
     Emit(encoding);
@@ -1955,8 +2049,9 @@
                             Operand o,
                             OperandSize sz,
                             bool set_flags) {
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t s = set_flags ? B29 : 0;
     const int32_t encoding = op | size | s | Arm64Encode::Rd(rd) |
                              Arm64Encode::Rn(rn) | o.encoding();
@@ -2049,10 +2144,11 @@
     // EncodeImm19BranchOffset will longjump out if the offset does not fit in
     // 19 bits.
     const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0);
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
     ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
     ASSERT((rt != CSP) && (rt != R31));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding = op | size | Arm64Encode::Rt(rt) | encoded_offset;
     Emit(encoding);
   }
@@ -2222,8 +2318,9 @@
                       int hw_idx,
                       OperandSize sz) {
     ASSERT((hw_idx >= 0) && (hw_idx <= 3));
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding =
         op | size | Arm64Encode::Rd(rd) |
         (static_cast<int32_t>(hw_idx) << kHWShift) |
@@ -2235,9 +2332,9 @@
                               Register rs,
                               Register rn,
                               Register rt,
-                              OperandSize sz = kDoubleWord) {
-    ASSERT(sz == kDoubleWord || sz == kWord);
-    const int32_t size = B31 | (sz == kDoubleWord ? B30 : 0);
+                              OperandSize sz = kEightBytes) {
+    ASSERT(sz == kEightBytes || sz == kFourBytes);
+    const int32_t size = B31 | (sz == kEightBytes ? B30 : 0);
 
     ASSERT((rs != kNoRegister) && (rs != ZR));
     ASSERT((rn != kNoRegister) && (rn != ZR));
@@ -2268,10 +2365,11 @@
                           Register rt,
                           Address a,
                           OperandSize sz) {
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
     ASSERT(a.log2sz_ == -1 || a.log2sz_ == Log2OperandSizeBytes(sz));
     ASSERT((rt != CSP) && (rt != R31));
-    const int32_t size = (sz == kDoubleWord) ? B30 : 0;
+    const int32_t size = (sz == kEightBytes) ? B30 : 0;
     const int32_t encoding = op | size | Arm64Encode::Rt(rt) | a.encoding();
     Emit(encoding);
   }
@@ -2285,19 +2383,20 @@
     ASSERT(a.can_writeback_to(rt) && a.can_writeback_to(rt2));
     ASSERT(op != LDP || rt != rt2);
 
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
     ASSERT(a.log2sz_ == -1 || a.log2sz_ == Log2OperandSizeBytes(sz));
     ASSERT((rt != CSP) && (rt != R31));
     ASSERT((rt2 != CSP) && (rt2 != R31));
     int32_t opc = 0;
     switch (sz) {
-      case kDoubleWord:
+      case kEightBytes:
         opc = B31;
         break;
-      case kWord:
+      case kFourBytes:
         opc = B30;
         break;
-      case kUnsignedWord:
+      case kUnsignedFourBytes:
         opc = 0;
         break;
       default:
@@ -2324,8 +2423,9 @@
                          Register rn,
                          OperandSize sz) {
     ASSERT((rd != CSP) && (rn != CSP));
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding =
         op | size | Arm64Encode::Rd(rd) | Arm64Encode::Rn(rn);
     Emit(encoding);
@@ -2337,8 +2437,9 @@
                          Register rm,
                          OperandSize sz) {
     ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding = op | size | Arm64Encode::Rd(rd) |
                              Arm64Encode::Rn(rn) | Arm64Encode::Rm(rm);
     Emit(encoding);
@@ -2351,8 +2452,9 @@
                          Register ra,
                          OperandSize sz) {
     ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP) && (ra != CSP));
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding = op | size | Arm64Encode::Rd(rd) |
                              Arm64Encode::Rn(rn) | Arm64Encode::Rm(rm) |
                              Arm64Encode::Ra(ra);
@@ -2366,8 +2468,9 @@
                              Condition cond,
                              OperandSize sz) {
     ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
-    ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
+           (sz == kUnsignedFourBytes));
+    const int32_t size = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding = op | size | Arm64Encode::Rd(rd) |
                              Arm64Encode::Rn(rn) | Arm64Encode::Rm(rm) |
                              (static_cast<int32_t>(cond) << kSelCondShift);
@@ -2383,9 +2486,9 @@
   void EmitFPIntCvtOp(FPIntCvtOp op,
                       Register rd,
                       Register rn,
-                      OperandSize sz = kDoubleWord) {
-    ASSERT((sz == kDoubleWord) || (sz == kWord));
-    const int32_t sfield = (sz == kDoubleWord) ? B31 : 0;
+                      OperandSize sz = kEightBytes) {
+    ASSERT((sz == kEightBytes) || (sz == kFourBytes));
+    const int32_t sfield = (sz == kEightBytes) ? B31 : 0;
     const int32_t encoding =
         op | Arm64Encode::Rd(rd) | Arm64Encode::Rn(rn) | sfield;
     Emit(encoding);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index ce1ba92..8cf9ac2 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -461,9 +461,9 @@
          Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadImmediate(R1, 0xffffffff);
-  __ str(R1, Address(SP, -4, Address::PreIndex, kWord), kWord);
-  __ ldr(R0, Address(SP), kWord);
-  __ ldr(R1, Address(SP, 4, Address::PostIndex, kWord), kWord);
+  __ str(R1, Address(SP, -4, Address::PreIndex, kFourBytes), kFourBytes);
+  __ ldr(R0, Address(SP), kFourBytes);
+  __ ldr(R1, Address(SP, 4, Address::PostIndex, kFourBytes), kFourBytes);
   __ RestoreCSP();
   __ ret();
 }
@@ -635,10 +635,10 @@
 
   Label retry;
   __ Bind(&retry);
-  __ ldxr(R0, SP, kWord);
+  __ ldxr(R0, SP, kFourBytes);
   // 32 bit operation should ignore the high word of R0 that was pushed on the
   // stack.
-  __ stxr(TMP, R1, SP, kWord);  // IP == 0, success
+  __ stxr(TMP, R1, SP, kFourBytes);  // IP == 0, success
   __ cmp(TMP, Operand(0));
   __ b(&retry, NE);  // NE if context switch occurred between ldrex and strex.
   __ Pop(R0);        // 42 + 42 * 2**32
@@ -664,9 +664,9 @@
   __ movz(R0, Immediate(40), 0);
   __ movz(R1, Immediate(42), 0);
 
-  __ ldxr(R0, SP, kWord);
+  __ ldxr(R0, SP, kFourBytes);
   __ clrex();                   // Simulate a context switch.
-  __ stxr(TMP, R1, SP, kWord);  // IP == 1, failure
+  __ stxr(TMP, R1, SP, kFourBytes);  // IP == 1, failure
   __ Pop(R0);                   // 40
   __ add(R0, R0, Operand(TMP));
   __ RestoreCSP();
@@ -692,14 +692,14 @@
 
   // Test 64-bit ladr.
   __ PushImmediate(0x1122334455667788);
-  __ ldar(R1, SP, kDoubleWord);
+  __ ldar(R1, SP, kEightBytes);
   __ CompareImmediate(R1, 0x1122334455667788);
   __ BranchIf(NOT_EQUAL, &failed);
   __ Drop(1);
 
   // Test 32-bit ladr - must zero extend.
   __ PushImmediate(0x1122334455667788);
-  __ ldar(R1, SP, kWord);
+  __ ldar(R1, SP, kFourBytes);
   __ CompareImmediate(R1, 0x55667788);
   __ BranchIf(NOT_EQUAL, &failed);
   __ Drop(1);
@@ -707,7 +707,7 @@
   // Test 64-bit stlr.
   __ PushImmediate(0);
   __ LoadImmediate(R1, 0x1122334455667788);
-  __ stlr(R1, SP, kDoubleWord);
+  __ stlr(R1, SP, kEightBytes);
   __ Pop(R1);
   __ CompareImmediate(R1, 0x1122334455667788);
   __ BranchIf(NOT_EQUAL, &failed);
@@ -715,7 +715,7 @@
   // Test 32-bit stlr.
   __ PushImmediate(0);
   __ LoadImmediate(R1, 0x1122334455667788);
-  __ stlr(R1, SP, kWord);
+  __ stlr(R1, SP, kFourBytes);
   __ Pop(R1);
   __ CompareImmediate(R1, 0x55667788);
   __ BranchIf(NOT_EQUAL, &failed);
@@ -1048,7 +1048,7 @@
 #define SHIFT_32_IMMEDIATE_TEST(macro_op, val, shift, expected)                \
   ASSEMBLER_TEST_GENERATE(macro_op##a_##val##_##shift, assembler) {            \
     __ LoadImmediate(R1, bit_cast<int32_t>(val));                              \
-    __ macro_op(R0, R1, (shift), kWord);                                       \
+    __ macro_op(R0, R1, (shift), kFourBytes);                                  \
     __ ret();                                                                  \
   }                                                                            \
                                                                                \
@@ -2373,7 +2373,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnaligned, assembler) {
-  __ ldr(R1, R0, kHalfword);
+  __ ldr(R1, R0, kTwoBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -2396,7 +2396,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) {
-  __ ldr(R1, R0, kUnsignedHalfword);
+  __ ldr(R1, R0, kUnsignedTwoBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -2418,7 +2418,7 @@
 
 ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) {
   __ LoadImmediate(R1, 0xABCD);
-  __ str(R1, R0, kHalfword);
+  __ str(R1, R0, kTwoBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -2446,7 +2446,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) {
-  __ ldr(R1, R0, kUnsignedWord);
+  __ ldr(R1, R0, kUnsignedFourBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -2476,7 +2476,7 @@
 
 ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) {
   __ LoadImmediate(R1, 0x12345678);
-  __ str(R1, R0, kUnsignedWord);
+  __ str(R1, R0, kUnsignedFourBytes);
   __ mov(R0, R1);
   __ ret();
 }
diff --git a/runtime/vm/compiler/assembler/assembler_arm_test.cc b/runtime/vm/compiler/assembler/assembler_arm_test.cc
index 558895e..9199d5a 100644
--- a/runtime/vm/compiler/assembler/assembler_arm_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm_test.cc
@@ -2024,7 +2024,7 @@
     __ mov(R0, Operand(8));
     __ vmovsr(S7, R0);
 
-    __ vaddqi(kHalfword, Q2, Q0, Q1);
+    __ vaddqi(kTwoBytes, Q2, Q0, Q1);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -2065,7 +2065,7 @@
     __ mov(R0, Operand(8));
     __ vmovsr(S7, R0);
 
-    __ vaddqi(kWord, Q2, Q0, Q1);
+    __ vaddqi(kFourBytes, Q2, Q0, Q1);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -2214,7 +2214,7 @@
     __ rsb(shift, shift, Operand(0));
     __ vmovsr(stemp0, shift);
     __ vshlqi(kWordPair, temp, out, temp);
-    __ vceqqi(kWord, out, temp, value);
+    __ vceqqi(kFourBytes, out, temp, value);
     // Low 64 bits of temp should be all 1's, otherwise temp != value and
     // we deopt.
     __ vmovrs(shift, sout0);
@@ -2269,7 +2269,7 @@
     __ rsb(shift, shift, Operand(0));
     __ vmovsr(stemp0, shift);
     __ vshlqi(kWordPair, temp, out, temp);
-    __ vceqqi(kWord, out, temp, value);
+    __ vceqqi(kFourBytes, out, temp, value);
     // Low 64 bits of temp should be all 1's, otherwise temp != value and
     // we deopt.
     __ vmovrs(shift, sout0);
@@ -2356,7 +2356,7 @@
     __ mov(R0, Operand(8));
     __ vmovsr(S7, R0);
 
-    __ vsubqi(kHalfword, Q2, Q1, Q0);
+    __ vsubqi(kTwoBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -2397,7 +2397,7 @@
     __ mov(R0, Operand(8));
     __ vmovsr(S7, R0);
 
-    __ vsubqi(kWord, Q2, Q1, Q0);
+    __ vsubqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -2508,7 +2508,7 @@
     __ mov(R0, Operand(8));
     __ vmovsr(S7, R0);
 
-    __ vmulqi(kHalfword, Q2, Q1, Q0);
+    __ vmulqi(kTwoBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -2549,7 +2549,7 @@
     __ mov(R0, Operand(8));
     __ vmovsr(S7, R0);
 
-    __ vmulqi(kWord, Q2, Q1, Q0);
+    __ vmulqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -3071,7 +3071,7 @@
     __ vmovsr(S5, R1);
 
     // Should copy 0xff to each byte of Q0.
-    __ vdup(kHalfword, Q0, D2, 1);
+    __ vdup(kTwoBytes, Q0, D2, 1);
 
     __ vmovrs(R0, S0);
     __ vmovrs(R1, S1);
@@ -3101,7 +3101,7 @@
     __ vmovsr(S5, R1);
 
     // Should copy 0xff to each byte of Q0.
-    __ vdup(kWord, Q0, D2, 1);
+    __ vdup(kFourBytes, Q0, D2, 1);
 
     __ vmovrs(R0, S0);
     __ vmovrs(R1, S1);
@@ -3173,7 +3173,7 @@
     __ mov(R0, Operand(40));
     __ vmovsr(S7, R0);
 
-    __ vceqqi(kWord, Q2, Q1, Q0);
+    __ vceqqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -3247,7 +3247,7 @@
     __ mov(R0, Operand(1));
     __ vmovsr(S7, R0);
 
-    __ vcgeqi(kWord, Q2, Q1, Q0);
+    __ vcgeqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -3288,7 +3288,7 @@
     __ mov(R0, Operand(1));
     __ vmovsr(S7, R0);
 
-    __ vcugeqi(kWord, Q2, Q1, Q0);
+    __ vcugeqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -3362,7 +3362,7 @@
     __ mov(R0, Operand(1));
     __ vmovsr(S7, R0);
 
-    __ vcgtqi(kWord, Q2, Q1, Q0);
+    __ vcgtqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
@@ -3403,7 +3403,7 @@
     __ mov(R0, Operand(1));
     __ vmovsr(S7, R0);
 
-    __ vcugtqi(kWord, Q2, Q1, Q0);
+    __ vcugtqi(kFourBytes, Q2, Q1, Q0);
 
     __ vmovrs(R0, S8);
     __ vmovrs(R1, S9);
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index 03f0cfc..d240da5 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -28,6 +28,25 @@
 
 namespace compiler {
 
+enum OperandSize {
+  // Architecture-independent constants.
+  kByte,
+  kUnsignedByte,
+  kTwoBytes,  // Halfword (ARM), w(ord) (Intel)
+  kUnsignedTwoBytes,
+  kFourBytes,  // Word (ARM), l(ong) (Intel)
+  kUnsignedFourBytes,
+  kEightBytes,  // DoubleWord (ARM), q(uadword) (Intel)
+  // ARM-specific constants.
+  kSWord,
+  kDWord,
+  // 32-bit ARM specific constants.
+  kWordPair,
+  kRegList,
+  // 64-bit ARM specific constants.
+  kQWord,
+};
+
 // Forward declarations.
 class Assembler;
 class AssemblerFixup;
@@ -330,6 +349,12 @@
         object_pool_builder_(object_pool_builder) {}
   virtual ~AssemblerBase();
 
+  // Used for near/far jumps on IA32/X64, ignored for ARM.
+  enum JumpDistance : bool {
+    kFarJump = false,
+    kNearJump = true,
+  };
+
   intptr_t CodeSize() const { return buffer_.Size(); }
 
   uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 06f27c2..de9ce35 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1665,7 +1665,7 @@
   EmitUint8(0xF4);
 }
 
-void Assembler::j(Condition condition, Label* label, bool near) {
+void Assembler::j(Condition condition, Label* label, JumpDistance distance) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   if (label->IsBound()) {
     static const int kShortSize = 2;
@@ -1680,7 +1680,7 @@
       EmitUint8(0x80 + condition);
       EmitInt32(offset - kLongSize);
     }
-  } else if (near) {
+  } else if (distance == kNearJump) {
     EmitUint8(0x70 + condition);
     EmitNearLabelLink(label);
   } else {
@@ -1710,7 +1710,7 @@
   EmitOperand(4, address);
 }
 
-void Assembler::jmp(Label* label, bool near) {
+void Assembler::jmp(Label* label, JumpDistance distance) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   if (label->IsBound()) {
     static const int kShortSize = 2;
@@ -1724,7 +1724,7 @@
       EmitUint8(0xE9);
       EmitInt32(offset - kLongSize);
     }
-  } else if (near) {
+  } else if (distance == kNearJump) {
     EmitUint8(0xEB);
     EmitNearLabelLink(label);
   } else {
@@ -1762,6 +1762,41 @@
   cmpl(a, b);
 }
 
+void Assembler::LoadFromOffset(Register reg,
+                               Register base,
+                               int32_t offset,
+                               OperandSize type) {
+  switch (type) {
+    case kByte:
+      return movsxb(reg, Address(base, offset));
+    case kUnsignedByte:
+      return movzxb(reg, Address(base, offset));
+    case kTwoBytes:
+      return movsxw(reg, Address(base, offset));
+    case kUnsignedTwoBytes:
+      return movzxw(reg, Address(base, offset));
+    case kFourBytes:
+      return movl(reg, Address(base, offset));
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+void Assembler::LoadFromStack(Register dst, intptr_t depth) {
+  ASSERT(depth >= 0);
+  movl(dst, Address(ESP, depth * target::kWordSize));
+}
+
+void Assembler::StoreToStack(Register src, intptr_t depth) {
+  ASSERT(depth >= 0);
+  movl(Address(ESP, depth * target::kWordSize), src);
+}
+
+void Assembler::CompareToStack(Register src, intptr_t depth) {
+  cmpl(src, Address(ESP, depth * target::kWordSize));
+}
+
 void Assembler::MoveRegister(Register to, Register from) {
   if (to != from) {
     movl(to, from);
@@ -1917,7 +1952,7 @@
     testl(value, Immediate(0xf));
   }
   Condition condition = how_to_jump == kJumpToNoUpdate ? NOT_ZERO : ZERO;
-  bool distance = how_to_jump == kJumpToNoUpdate ? kNearJump : kFarJump;
+  auto const distance = how_to_jump == kJumpToNoUpdate ? kNearJump : kFarJump;
   j(condition, label, distance);
 }
 
@@ -2429,7 +2464,7 @@
 void Assembler::MaybeTraceAllocation(intptr_t cid,
                                      Register temp_reg,
                                      Label* trace,
-                                     bool near_jump) {
+                                     JumpDistance distance) {
   ASSERT(cid > 0);
   Address state_address(kNoRegister, 0);
 
@@ -2446,13 +2481,13 @@
   cmpb(Address(temp_reg, class_offset), Immediate(0));
   // We are tracing for this class, jump to the trace label which will use
   // the allocation stub.
-  j(NOT_ZERO, trace, near_jump);
+  j(NOT_ZERO, trace, distance);
 }
 #endif  // !PRODUCT
 
 void Assembler::TryAllocate(const Class& cls,
                             Label* failure,
-                            bool near_jump,
+                            JumpDistance distance,
                             Register instance_reg,
                             Register temp_reg) {
   ASSERT(failure != NULL);
@@ -2464,19 +2499,18 @@
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
     const classid_t cid = target::Class::GetId(cls);
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, near_jump));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, distance));
     movl(instance_reg, Address(THR, target::Thread::top_offset()));
     addl(instance_reg, Immediate(instance_size));
     // instance_reg: potential next object start.
     cmpl(instance_reg, Address(THR, target::Thread::end_offset()));
-    j(ABOVE_EQUAL, failure, near_jump);
+    j(ABOVE_EQUAL, failure, distance);
     // Successfully allocated the object, now update top to point to
     // next object start and store the class in the class field of object.
     movl(Address(THR, target::Thread::top_offset()), instance_reg);
     ASSERT(instance_size >= kHeapObjectTag);
     subl(instance_reg, Immediate(instance_size - kHeapObjectTag));
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     movl(FieldAddress(instance_reg, target::Object::tags_offset()),
          Immediate(tags));
   } else {
@@ -2487,7 +2521,7 @@
 void Assembler::TryAllocateArray(intptr_t cid,
                                  intptr_t instance_size,
                                  Label* failure,
-                                 bool near_jump,
+                                 JumpDistance distance,
                                  Register instance,
                                  Register end_address,
                                  Register temp_reg) {
@@ -2498,7 +2532,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, near_jump));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, distance));
     movl(instance, Address(THR, target::Thread::top_offset()));
     movl(end_address, instance);
 
@@ -2517,8 +2551,7 @@
     addl(instance, Immediate(kHeapObjectTag));
 
     // Initialize the tags.
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     movl(FieldAddress(instance, target::Object::tags_offset()),
          Immediate(tags));
   } else {
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 25bdf4b..dfa7f35 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -238,9 +238,6 @@
   }
   ~Assembler() {}
 
-  static const bool kNearJump = true;
-  static const bool kFarJump = false;
-
   /*
    * Emit Machine Instructions.
    */
@@ -556,12 +553,12 @@
   void int3();
   void hlt();
 
-  void j(Condition condition, Label* label, bool near = kFarJump);
+  void j(Condition condition, Label* label, JumpDistance distance = kFarJump);
   void j(Condition condition, const ExternalLabel* label);
 
   void jmp(Register reg);
   void jmp(const Address& address);
-  void jmp(Label* label, bool near = kFarJump);
+  void jmp(Label* label, JumpDistance distance = kFarJump);
   void jmp(const ExternalLabel* label);
 
   void lock();
@@ -575,9 +572,39 @@
 
   void Ret() { ret(); }
   void CompareRegisters(Register a, Register b);
-  void BranchIf(Condition condition, Label* label) { j(condition, label); }
+  void BranchIf(Condition condition,
+                Label* label,
+                JumpDistance distance = kFarJump) {
+    j(condition, label, distance);
+  }
+  void BranchIfZero(Register src,
+                    Label* label,
+                    JumpDistance distance = kFarJump) {
+    cmpl(src, Immediate(0));
+    j(ZERO, label, distance);
+  }
 
+  void LoadFromOffset(Register reg,
+                      Register base,
+                      int32_t offset,
+                      OperandSize type = kFourBytes);
   void LoadField(Register dst, FieldAddress address) { movl(dst, address); }
+  void LoadFieldFromOffset(Register reg,
+                           Register base,
+                           int32_t offset,
+                           OperandSize type = kFourBytes) {
+    LoadFromOffset(reg, base, offset - kHeapObjectTag, type);
+  }
+  void LoadIndexedFieldFromOffset(Register reg,
+                                  Register base,
+                                  int32_t offset,
+                                  Register index,
+                                  ScaleFactor scale) {
+    LoadField(reg, FieldAddress(base, index, scale, offset));
+  }
+  void LoadFromStack(Register dst, intptr_t depth);
+  void StoreToStack(Register src, intptr_t depth);
+  void CompareToStack(Register src, intptr_t depth);
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     movl(dst, Address(base, offset));
   }
@@ -695,6 +722,11 @@
     cmpxchgl(address, reg);
   }
 
+  void CompareTypeNullabilityWith(Register type, int8_t value) {
+    cmpb(FieldAddress(type, compiler::target::Type::nullability_offset()),
+         Immediate(value));
+  }
+
   void EnterFrame(intptr_t frame_space);
   void LeaveFrame();
   void ReserveAlignedFrameSpace(intptr_t frame_space);
@@ -795,19 +827,25 @@
 
   void SmiUntag(Register reg) { sarl(reg, Immediate(kSmiTagSize)); }
 
-  void BranchIfNotSmi(Register reg, Label* label) {
+  void BranchIfNotSmi(Register reg,
+                      Label* label,
+                      JumpDistance distance = kFarJump) {
     testl(reg, Immediate(kSmiTagMask));
-    j(NOT_ZERO, label);
+    j(NOT_ZERO, label, distance);
   }
 
-  void BranchIfSmi(Register reg, Label* label) {
+  void BranchIfSmi(Register reg,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
     testl(reg, Immediate(kSmiTagMask));
-    j(ZERO, label);
+    j(ZERO, label, distance);
   }
 
   void Align(intptr_t alignment, intptr_t offset);
   void Bind(Label* label);
-  void Jump(Label* label) { jmp(label); }
+  void Jump(Label* label, JumpDistance distance = kFarJump) {
+    jmp(label, distance);
+  }
 
   // Moves one word from the memory at [from] to the memory at [to].
   // Needs a temporary register.
@@ -878,7 +916,7 @@
   void MaybeTraceAllocation(intptr_t cid,
                             Register temp_reg,
                             Label* trace,
-                            bool near_jump);
+                            JumpDistance distance);
 
   // Inlined allocation of an instance of class 'cls', code has no runtime
   // calls. Jump to 'failure' if the instance cannot be allocated here.
@@ -886,14 +924,14 @@
   // Only the tags field of the object is initialized.
   void TryAllocate(const Class& cls,
                    Label* failure,
-                   bool near_jump,
+                   JumpDistance distance,
                    Register instance_reg,
                    Register temp_reg);
 
   void TryAllocateArray(intptr_t cid,
                         intptr_t instance_size,
                         Label* failure,
-                        bool near_jump,
+                        JumpDistance distance,
                         Register instance,
                         Register end_address,
                         Register temp);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 4310ef2..0bc1761 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -808,16 +808,17 @@
 
 void Assembler::MulImmediate(Register reg,
                              const Immediate& imm,
-                             OperandWidth width) {
+                             OperandSize width) {
+  ASSERT(width == kFourBytes || width == kEightBytes);
   if (imm.is_int32()) {
-    if (width == k32Bit) {
+    if (width == kFourBytes) {
       imull(reg, imm);
     } else {
       imulq(reg, imm);
     }
   } else {
     ASSERT(reg != TMP);
-    ASSERT(width != k32Bit);
+    ASSERT(width == kEightBytes);
     movq(TMP, imm);
     imulq(reg, TMP);
   }
@@ -967,7 +968,7 @@
   }
 }
 
-void Assembler::j(Condition condition, Label* label, bool near) {
+void Assembler::j(Condition condition, Label* label, JumpDistance distance) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   if (label->IsBound()) {
     static const int kShortSize = 2;
@@ -982,7 +983,7 @@
       EmitUint8(0x80 + condition);
       EmitInt32(offset - kLongSize);
     }
-  } else if (near) {
+  } else if (distance == kNearJump) {
     EmitUint8(0x70 + condition);
     EmitNearLabelLink(label);
   } else {
@@ -1000,7 +1001,7 @@
   Bind(&no_jump);
 }
 
-void Assembler::jmp(Label* label, bool near) {
+void Assembler::jmp(Label* label, JumpDistance distance) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   if (label->IsBound()) {
     static const int kShortSize = 2;
@@ -1014,7 +1015,7 @@
       EmitUint8(0xE9);
       EmitInt32(offset - kLongSize);
     }
-  } else if (near) {
+  } else if (distance == kNearJump) {
     EmitUint8(0xEB);
     EmitNearLabelLink(label);
   } else {
@@ -1056,6 +1057,20 @@
   cmpq(a, b);
 }
 
+void Assembler::LoadFromStack(Register dst, intptr_t depth) {
+  ASSERT(depth >= 0);
+  movq(dst, Address(SPREG, depth * target::kWordSize));
+}
+
+void Assembler::StoreToStack(Register src, intptr_t depth) {
+  ASSERT(depth >= 0);
+  movq(Address(SPREG, depth * target::kWordSize), src);
+}
+
+void Assembler::CompareToStack(Register src, intptr_t depth) {
+  cmpq(Address(SPREG, depth * target::kWordSize), src);
+}
+
 void Assembler::MoveRegister(Register to, Register from) {
   if (to != from) {
     movq(to, from);
@@ -1072,28 +1087,29 @@
 
 void Assembler::AddImmediate(Register reg,
                              const Immediate& imm,
-                             OperandWidth width) {
+                             OperandSize width) {
+  ASSERT(width == kFourBytes || width == kEightBytes);
   const int64_t value = imm.value();
   if (value == 0) {
     return;
   }
   if ((value > 0) || (value == kMinInt64)) {
     if (value == 1) {
-      if (width == k32Bit) {
+      if (width == kFourBytes) {
         incl(reg);
       } else {
         incq(reg);
       }
     } else {
-      if (imm.is_int32() || (width == k32Bit && imm.is_uint32())) {
-        if (width == k32Bit) {
+      if (imm.is_int32() || (width == kFourBytes && imm.is_uint32())) {
+        if (width == kFourBytes) {
           addl(reg, imm);
         } else {
           addq(reg, imm);
         }
       } else {
         ASSERT(reg != TMP);
-        ASSERT(width != k32Bit);
+        ASSERT(width == kEightBytes);
         LoadImmediate(TMP, imm);
         addq(reg, TMP);
       }
@@ -1126,29 +1142,30 @@
 
 void Assembler::SubImmediate(Register reg,
                              const Immediate& imm,
-                             OperandWidth width) {
+                             OperandSize width) {
+  ASSERT(width == kFourBytes || width == kEightBytes);
   const int64_t value = imm.value();
   if (value == 0) {
     return;
   }
   if ((value > 0) || (value == kMinInt64) ||
-      (value == kMinInt32 && width == k32Bit)) {
+      (value == kMinInt32 && width == kFourBytes)) {
     if (value == 1) {
-      if (width == k32Bit) {
+      if (width == kFourBytes) {
         decl(reg);
       } else {
         decq(reg);
       }
     } else {
       if (imm.is_int32()) {
-        if (width == k32Bit) {
+        if (width == kFourBytes) {
           subl(reg, imm);
         } else {
           subq(reg, imm);
         }
       } else {
         ASSERT(reg != TMP);
-        ASSERT(width != k32Bit);
+        ASSERT(width == kEightBytes);
         LoadImmediate(TMP, imm);
         subq(reg, TMP);
       }
@@ -1361,7 +1378,7 @@
     testl(value, Immediate(0x1f));
   }
   Condition condition = how_to_jump == kJumpToNoUpdate ? NOT_ZERO : ZERO;
-  bool distance = how_to_jump == kJumpToNoUpdate ? kNearJump : kFarJump;
+  JumpDistance distance = how_to_jump == kJumpToNoUpdate ? kNearJump : kFarJump;
   j(condition, label, distance);
 }
 
@@ -1532,6 +1549,28 @@
   label->BindTo(bound);
 }
 
+void Assembler::LoadFromOffset(Register reg,
+                               const Address& address,
+                               OperandSize sz) {
+  switch (sz) {
+    case kByte:
+      return movsxb(reg, address);
+    case kUnsignedByte:
+      return movzxb(reg, address);
+    case kTwoBytes:
+      return movsxw(reg, address);
+    case kUnsignedTwoBytes:
+      return movzxw(reg, address);
+    case kFourBytes:
+      return movl(reg, address);
+    case kEightBytes:
+      return movq(reg, address);
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
 void Assembler::EnterFrame(intptr_t frame_size) {
   if (prologue_offset_ == -1) {
     prologue_offset_ = CodeSize();
@@ -1580,9 +1619,8 @@
 #endif
 }
 
-void Assembler::PushRegisters(intptr_t cpu_register_set,
-                              intptr_t xmm_register_set) {
-  const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
+void Assembler::PushRegisters(const RegisterSet& register_set) {
+  const intptr_t xmm_regs_count = register_set.FpuRegisterCount();
   if (xmm_regs_count > 0) {
     AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize));
     // Store XMM registers with the lowest register number at the lowest
@@ -1590,7 +1628,7 @@
     intptr_t offset = 0;
     for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) {
       XmmRegister xmm_reg = static_cast<XmmRegister>(i);
-      if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
+      if (register_set.ContainsFpuRegister(xmm_reg)) {
         movups(Address(RSP, offset), xmm_reg);
         offset += kFpuRegisterSize;
       }
@@ -1602,28 +1640,27 @@
   // in which the registers are encoded in the safe point's stack map.
   for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
     Register reg = static_cast<Register>(i);
-    if (RegisterSet::Contains(cpu_register_set, reg)) {
+    if (register_set.ContainsRegister(reg)) {
       pushq(reg);
     }
   }
 }
 
-void Assembler::PopRegisters(intptr_t cpu_register_set,
-                             intptr_t xmm_register_set) {
+void Assembler::PopRegisters(const RegisterSet& register_set) {
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
     Register reg = static_cast<Register>(i);
-    if (RegisterSet::Contains(cpu_register_set, reg)) {
+    if (register_set.ContainsRegister(reg)) {
       popq(reg);
     }
   }
 
-  const intptr_t xmm_regs_count = RegisterSet::RegisterCount(xmm_register_set);
+  const intptr_t xmm_regs_count = register_set.FpuRegisterCount();
   if (xmm_regs_count > 0) {
     // XMM registers have the lowest register number at the lowest address.
     intptr_t offset = 0;
     for (intptr_t i = 0; i < kNumberOfXmmRegisters; ++i) {
       XmmRegister xmm_reg = static_cast<XmmRegister>(i);
-      if (RegisterSet::Contains(xmm_register_set, xmm_reg)) {
+      if (register_set.ContainsFpuRegister(xmm_reg)) {
         movups(xmm_reg, Address(RSP, offset));
         offset += kFpuRegisterSize;
       }
@@ -1633,6 +1670,10 @@
   }
 }
 
+static const RegisterSet kVolatileRegisterSet(
+    CallingConventions::kVolatileCpuRegisters,
+    CallingConventions::kVolatileXmmRegisters);
+
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
   Comment("EnterCallRuntimeFrame");
   EnterFrame(0);
@@ -1642,8 +1683,7 @@
   }
 
   // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
-  PushRegisters(CallingConventions::kVolatileCpuRegisters,
-                CallingConventions::kVolatileXmmRegisters);
+  PushRegisters(kVolatileRegisterSet);
 
   ReserveAlignedFrameSpace(frame_space);
 }
@@ -1665,8 +1705,7 @@
   leaq(RSP, Address(RBP, -kPushedRegistersSize));
 
   // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
-  PopRegisters(CallingConventions::kVolatileCpuRegisters,
-               CallingConventions::kVolatileXmmRegisters);
+  PopRegisters(kVolatileRegisterSet);
 
   LeaveStubFrame();
 }
@@ -1889,7 +1928,7 @@
 #ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
                                      Label* trace,
-                                     bool near_jump) {
+                                     JumpDistance distance) {
   ASSERT(cid > 0);
   const intptr_t shared_table_offset =
       target::Isolate::shared_class_table_offset();
@@ -1904,13 +1943,13 @@
   cmpb(Address(temp_reg, class_offset), Immediate(0));
   // We are tracing for this class, jump to the trace label which will use
   // the allocation stub.
-  j(NOT_ZERO, trace, near_jump);
+  j(NOT_ZERO, trace, distance);
 }
 #endif  // !PRODUCT
 
 void Assembler::TryAllocate(const Class& cls,
                             Label* failure,
-                            bool near_jump,
+                            JumpDistance distance,
                             Register instance_reg,
                             Register temp) {
   ASSERT(failure != NULL);
@@ -1921,21 +1960,18 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, near_jump));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, distance));
     movq(instance_reg, Address(THR, target::Thread::top_offset()));
     addq(instance_reg, Immediate(instance_size));
     // instance_reg: potential next object start.
     cmpq(instance_reg, Address(THR, target::Thread::end_offset()));
-    j(ABOVE_EQUAL, failure, near_jump);
+    j(ABOVE_EQUAL, failure, distance);
     // Successfully allocated the object, now update top to point to
     // next object start and store the class in the class field of object.
     movq(Address(THR, target::Thread::top_offset()), instance_reg);
     ASSERT(instance_size >= kHeapObjectTag);
     AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size));
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
-    // Extends the 32 bit tags with zeros, which is the uninitialized
-    // hash code.
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     MoveImmediate(FieldAddress(instance_reg, target::Object::tags_offset()),
                   Immediate(tags));
   } else {
@@ -1946,7 +1982,7 @@
 void Assembler::TryAllocateArray(intptr_t cid,
                                  intptr_t instance_size,
                                  Label* failure,
-                                 bool near_jump,
+                                 JumpDistance distance,
                                  Register instance,
                                  Register end_address,
                                  Register temp) {
@@ -1956,7 +1992,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, near_jump));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, distance));
     movq(instance, Address(THR, target::Thread::top_offset()));
     movq(end_address, instance);
 
@@ -1976,10 +2012,7 @@
 
     // Initialize the tags.
     // instance: new object start as a tagged pointer.
-    const uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, instance_size);
-    // Extends the 32 bit tags with zeros, which is the uninitialized
-    // hash code.
+    const uword tags = target::MakeTagWordForNewSpaceObject(cid, instance_size);
     movq(FieldAddress(instance, target::Object::tags_offset()),
          Immediate(tags));
   } else {
@@ -2175,7 +2208,6 @@
 void Assembler::CompareClassId(Register object,
                                intptr_t class_id,
                                Register scratch) {
-  ASSERT(scratch == kNoRegister);
   LoadClassId(TMP, object);
   cmpl(TMP, Immediate(class_id));
 }
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index f6576ff..3b5fa5c 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -27,6 +27,7 @@
 
 // Forward declarations.
 class FlowGraphCompiler;
+class RegisterSet;
 
 namespace compiler {
 
@@ -292,9 +293,6 @@
 
   ~Assembler() {}
 
-  static const bool kNearJump = true;
-  static const bool kFarJump = false;
-
   /*
    * Emit Machine Instructions.
    */
@@ -307,6 +305,7 @@
   void pushq(const Address& address) { EmitUnaryL(address, 0xFF, 6); }
   void pushq(const Immediate& imm);
   void PushImmediate(const Immediate& imm);
+  void PushImmediate(int64_t value) { PushImmediate(Immediate(value)); }
 
   void popq(Register reg);
   void popq(const Address& address) { EmitUnaryL(address, 0x8F, 0); }
@@ -614,16 +613,12 @@
   REGULAR_UNARY(dec, 0xFF, 1)
 #undef REGULAR_UNARY
 
-  // We could use kWord, kDoubleWord, and kQuadWord here, but it is rather
-  // confusing since the same sizes mean something different on ARM.
-  enum OperandWidth { k32Bit, k64Bit };
-
   void imull(Register reg, const Immediate& imm);
 
   void imulq(Register dst, const Immediate& imm);
   void MulImmediate(Register reg,
                     const Immediate& imm,
-                    OperandWidth width = k64Bit);
+                    OperandSize width = kEightBytes);
 
   void shll(Register reg, const Immediate& imm);
   void shll(Register operand, Register shifter);
@@ -653,10 +648,10 @@
   // 'size' indicates size in bytes and must be in the range 1..8.
   void nop(int size = 1);
 
-  void j(Condition condition, Label* label, bool near = kFarJump);
+  void j(Condition condition, Label* label, JumpDistance distance = kFarJump);
   void jmp(Register reg) { EmitUnaryL(reg, 0xFF, 4); }
   void jmp(const Address& address) { EmitUnaryL(address, 0xFF, 4); }
-  void jmp(Label* label, bool near = kFarJump);
+  void jmp(Label* label, JumpDistance distance = kFarJump);
   void jmp(const ExternalLabel* label);
   void jmp(const Code& code);
 
@@ -683,7 +678,17 @@
   // Methods for High-level operations and implemented on all architectures.
   void Ret() { ret(); }
   void CompareRegisters(Register a, Register b);
-  void BranchIf(Condition condition, Label* label) { j(condition, label); }
+  void BranchIf(Condition condition,
+                Label* label,
+                JumpDistance distance = kFarJump) {
+    j(condition, label, distance);
+  }
+  void BranchIfZero(Register src,
+                    Label* label,
+                    JumpDistance distance = kFarJump) {
+    cmpq(src, Immediate(0));
+    j(ZERO, label, distance);
+  }
 
   // Issues a move instruction if 'to' is not the same as 'from'.
   void MoveRegister(Register to, Register from);
@@ -704,14 +709,16 @@
   // TODO(koda): Assert that these are not used for heap objects.
   void AddImmediate(Register reg,
                     const Immediate& imm,
-                    OperandWidth width = k64Bit);
-  void AddImmediate(Register reg, int32_t value, OperandWidth width = k64Bit) {
+                    OperandSize width = kEightBytes);
+  void AddImmediate(Register reg,
+                    int32_t value,
+                    OperandSize width = kEightBytes) {
     AddImmediate(reg, Immediate(value), width);
   }
   void AddImmediate(const Address& address, const Immediate& imm);
   void SubImmediate(Register reg,
                     const Immediate& imm,
-                    OperandWidth width = k64Bit);
+                    OperandSize width = kEightBytes);
   void SubImmediate(const Address& address, const Immediate& imm);
 
   void Drop(intptr_t stack_elements, Register tmp = TMP);
@@ -804,8 +811,8 @@
     cmpxchgl(address, reg);
   }
 
-  void PushRegisters(intptr_t cpu_register_set, intptr_t xmm_register_set);
-  void PopRegisters(intptr_t cpu_register_set, intptr_t xmm_register_set);
+  void PushRegisters(const RegisterSet& registers);
+  void PopRegisters(const RegisterSet& registers);
 
   void CheckCodePointer();
 
@@ -856,21 +863,61 @@
 
   void SmiUntag(Register reg) { sarq(reg, Immediate(kSmiTagSize)); }
 
-  void BranchIfNotSmi(Register reg, Label* label) {
+  void BranchIfNotSmi(Register reg,
+                      Label* label,
+                      JumpDistance distance = kFarJump) {
     testq(reg, Immediate(kSmiTagMask));
-    j(NOT_ZERO, label);
+    j(NOT_ZERO, label, distance);
   }
 
-  void BranchIfSmi(Register reg, Label* label) {
+  void BranchIfSmi(Register reg,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
     testq(reg, Immediate(kSmiTagMask));
-    j(ZERO, label);
+    j(ZERO, label, distance);
   }
 
   void Align(int alignment, intptr_t offset);
   void Bind(Label* label);
-  void Jump(Label* label) { jmp(label); }
+  // Unconditional jump to a given label.
+  void Jump(Label* label, JumpDistance distance = kFarJump) {
+    jmp(label, distance);
+  }
+  // Unconditional jump to a given address in memory.
+  void Jump(const Address& address) { jmp(address); }
 
-  void LoadField(Register dst, FieldAddress address) { movq(dst, address); }
+  // Arch-specific LoadFromOffset to choose the right operation for [sz].
+  void LoadFromOffset(Register dst,
+                      const Address& address,
+                      OperandSize sz = kEightBytes);
+  void LoadFromOffset(Register dst,
+                      Register base,
+                      int32_t offset,
+                      OperandSize sz = kEightBytes) {
+    LoadFromOffset(dst, Address(base, offset), sz);
+  }
+  void LoadField(Register dst,
+                 FieldAddress address,
+                 OperandSize sz = kEightBytes) {
+    LoadFromOffset(dst, address, sz);
+  }
+  void LoadFieldFromOffset(Register dst,
+                           Register base,
+                           int32_t offset,
+                           OperandSize sz = kEightBytes) {
+    LoadFromOffset(dst, FieldAddress(base, offset), sz);
+  }
+  void LoadIndexedPayload(Register dst,
+                          Register base,
+                          int32_t payload_offset,
+                          Register index,
+                          ScaleFactor scale,
+                          OperandSize sz = kEightBytes) {
+    LoadFromOffset(dst, FieldAddress(base, index, scale, payload_offset), sz);
+  }
+  void LoadFromStack(Register dst, intptr_t depth);
+  void StoreToStack(Register src, intptr_t depth);
+  void CompareToStack(Register src, intptr_t depth);
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     movq(dst, Address(base, offset));
   }
@@ -956,7 +1003,7 @@
 
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
-  void MaybeTraceAllocation(intptr_t cid, Label* trace, bool near_jump);
+  void MaybeTraceAllocation(intptr_t cid, Label* trace, JumpDistance distance);
 
   // Inlined allocation of an instance of class 'cls', code has no runtime
   // calls. Jump to 'failure' if the instance cannot be allocated here.
@@ -964,14 +1011,14 @@
   // Only the tags field of the object is initialized.
   void TryAllocate(const Class& cls,
                    Label* failure,
-                   bool near_jump,
+                   JumpDistance distance,
                    Register instance_reg,
                    Register temp);
 
   void TryAllocateArray(intptr_t cid,
                         intptr_t instance_size,
                         Label* failure,
-                        bool near_jump,
+                        JumpDistance distance,
                         Register instance,
                         Register end_address,
                         Register temp);
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index 8c416ab..7a21b97 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/locations.h"
 #include "vm/cpu.h"
 #include "vm/os.h"
 #include "vm/unit_test.h"
@@ -3765,7 +3766,8 @@
   const intptr_t cpu_register_set = 0;
   const intptr_t fpu_register_set =
       ((1 << XMM10) | (1 << XMM11)) & CallingConventions::kVolatileXmmRegisters;
-  __ PushRegisters(cpu_register_set, fpu_register_set);
+  const RegisterSet register_set(cpu_register_set, fpu_register_set);
+  __ PushRegisters(register_set);
   __ movl(RAX, Immediate(0x2));
   __ movd(XMM10, RAX);
   __ shufps(XMM10, XMM10, Immediate(0x0));
@@ -3778,7 +3780,7 @@
   __ pushq(RAX);
   __ movss(Address(RSP, 0), XMM10);
   __ popq(RAX);
-  __ PopRegisters(cpu_register_set, fpu_register_set);
+  __ PopRegisters(register_set);
   __ ret();
 }
 
@@ -5878,7 +5880,7 @@
   }
   {
     __ LoadImmediate(RAX, Immediate(42));
-    __ MulImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
+    __ MulImmediate(RAX, Immediate(kBillion), kFourBytes);
     Label ok;
     __ CompareImmediate(RAX, Immediate((42 * kBillion) & 0xffffffffll));
     __ j(EQUAL, &ok);
@@ -5896,9 +5898,9 @@
   }
   {
     __ LoadImmediate(RAX, Immediate(kBillion));
-    __ AddImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
-    __ AddImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
-    __ AddImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
+    __ AddImmediate(RAX, Immediate(kBillion), kFourBytes);
+    __ AddImmediate(RAX, Immediate(kBillion), kFourBytes);
+    __ AddImmediate(RAX, Immediate(kBillion), kFourBytes);
     Label ok;
     __ CompareImmediate(RAX, Immediate((4 * kBillion) & 0xffffffffll));
     __ j(EQUAL, &ok);
@@ -5908,9 +5910,9 @@
   {
     __ LoadImmediate(RAX, Immediate(kBillion));
     __ AddImmediate(RAX, Immediate(static_cast<int32_t>(3 * kBillion)),
-                    Assembler::k32Bit);
-    __ AddImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
-    __ AddImmediate(RAX, Immediate(-kBillion), Assembler::k32Bit);
+                    kFourBytes);
+    __ AddImmediate(RAX, Immediate(kBillion), kFourBytes);
+    __ AddImmediate(RAX, Immediate(-kBillion), kFourBytes);
     Label ok;
     __ CompareImmediate(RAX, Immediate((4 * kBillion) & 0xffffffffll));
     __ j(EQUAL, &ok);
@@ -5928,9 +5930,9 @@
   }
   {
     __ LoadImmediate(RAX, Immediate(-kBillion));
-    __ SubImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
-    __ SubImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
-    __ SubImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
+    __ SubImmediate(RAX, Immediate(kBillion), kFourBytes);
+    __ SubImmediate(RAX, Immediate(kBillion), kFourBytes);
+    __ SubImmediate(RAX, Immediate(kBillion), kFourBytes);
     Label ok;
     __ CompareImmediate(RAX, Immediate((-4 * kBillion) & 0xffffffffll));
     __ j(EQUAL, &ok);
@@ -5939,10 +5941,9 @@
   }
   {
     __ LoadImmediate(RAX, Immediate(kBillion));
-    __ SubImmediate(RAX, Immediate((-3 * kBillion) & 0xffffffffll),
-                    Assembler::k32Bit);
-    __ SubImmediate(RAX, Immediate(kBillion), Assembler::k32Bit);
-    __ SubImmediate(RAX, Immediate(-kBillion), Assembler::k32Bit);
+    __ SubImmediate(RAX, Immediate((-3 * kBillion) & 0xffffffffll), kFourBytes);
+    __ SubImmediate(RAX, Immediate(kBillion), kFourBytes);
+    __ SubImmediate(RAX, Immediate(-kBillion), kFourBytes);
     Label ok;
     __ CompareImmediate(RAX, Immediate((4 * kBillion) & 0xffffffffll));
     __ j(EQUAL, &ok);
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index dc5b713..0b7acfc 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -2382,10 +2382,9 @@
           int num_args_checked =
               MethodRecognizer::NumArgsCheckedForStaticCall(target);
           const ICData& ic_data = ICData::ZoneHandle(
-              zone, ICData::New(function, String::Handle(zone, target.name()),
-                                arguments_descriptor, call->deopt_id(),
-                                num_args_checked, ICData::kStatic));
-          ic_data.AddTarget(target);
+              zone, ICData::NewForStaticCall(
+                        function, target, arguments_descriptor,
+                        call->deopt_id(), num_args_checked, ICData::kStatic));
           call->set_ic_data(&ic_data);
         }
       }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index e943f75..213bb7a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -174,11 +174,13 @@
   // The `field.is_non_nullable_integer()` is set in the kernel loader and can
   // only be set if we consume a AOT kernel (annotated with inferred types).
   ASSERT(!field.is_non_nullable_integer() || FLAG_precompiled_mode);
+  // Unboxed fields in JIT lightweight isolates mode are not supported yet.
   const bool valid_class =
-      (SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) ||
-      (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) ||
-      (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)) ||
-      field.is_non_nullable_integer();
+      (FLAG_precompiled_mode || !FLAG_enable_isolate_groups) &&
+      ((SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) ||
+       (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) ||
+       (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)) ||
+       field.is_non_nullable_integer());
   return field.is_unboxing_candidate() && !field.is_nullable() && valid_class;
 }
 
@@ -189,7 +191,8 @@
     // proven to be correct.
     return IsUnboxedField(field);
   }
-  return field.is_unboxing_candidate() &&
+  // Unboxed fields in JIT lightweight isolates mode are not supported yet.
+  return !FLAG_enable_isolate_groups && field.is_unboxing_candidate() &&
          (FlowGraphCompiler::IsUnboxedField(field) ||
           (field.guarded_cid() == kIllegalCid));
 }
@@ -846,6 +849,7 @@
 CompilerDeoptInfo* FlowGraphCompiler::AddSlowPathDeoptInfo(intptr_t deopt_id,
                                                            Environment* env) {
   ASSERT(deopt_id != DeoptId::kNone);
+  deopt_id = DeoptId::ToDeoptAfter(deopt_id);
   CompilerDeoptInfo* info =
       new (zone()) CompilerDeoptInfo(deopt_id, ICData::kDeoptUnknown, 0, env);
   info->set_pc_offset(assembler()->CodeSize());
@@ -1886,7 +1890,8 @@
     const String& target_name,
     const Array& arguments_descriptor,
     intptr_t num_args_tested,
-    const AbstractType& receiver_type) {
+    const AbstractType& receiver_type,
+    const Function& binary_smi_target) {
   if ((deopt_id_to_ic_data_ != NULL) &&
       ((*deopt_id_to_ic_data_)[deopt_id] != NULL)) {
     const ICData* res = (*deopt_id_to_ic_data_)[deopt_id];
@@ -1899,10 +1904,24 @@
     ASSERT(res->receivers_static_type() == receiver_type.raw());
     return res;
   }
-  const ICData& ic_data = ICData::ZoneHandle(
-      zone(), ICData::New(parsed_function().function(), target_name,
+
+  auto& ic_data = ICData::ZoneHandle(zone());
+  if (!binary_smi_target.IsNull()) {
+    ASSERT(num_args_tested == 2);
+    ASSERT(!binary_smi_target.IsNull());
+    GrowableArray<intptr_t> cids(num_args_tested);
+    cids.Add(kSmiCid);
+    cids.Add(kSmiCid);
+    ic_data = ICData::NewWithCheck(parsed_function().function(), target_name,
+                                   arguments_descriptor, deopt_id,
+                                   num_args_tested, ICData::kInstance, &cids,
+                                   binary_smi_target, receiver_type);
+  } else {
+    ic_data = ICData::New(parsed_function().function(), target_name,
                           arguments_descriptor, deopt_id, num_args_tested,
-                          ICData::kInstance, receiver_type));
+                          ICData::kInstance, receiver_type);
+  }
+
   if (deopt_id_to_ic_data_ != NULL) {
     (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
   }
@@ -1928,12 +1947,10 @@
     return res;
   }
 
-  const ICData& ic_data = ICData::ZoneHandle(
-      zone(),
-      ICData::New(parsed_function().function(),
-                  String::Handle(zone(), target.name()), arguments_descriptor,
-                  deopt_id, num_args_tested, rebind_rule));
-  ic_data.AddTarget(target);
+  const auto& ic_data = ICData::ZoneHandle(
+      zone(), ICData::NewForStaticCall(parsed_function().function(), target,
+                                       arguments_descriptor, deopt_id,
+                                       num_args_tested, rebind_rule));
   if (deopt_id_to_ic_data_ != NULL) {
     (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
   }
@@ -2092,6 +2109,18 @@
 }
 
 #define __ assembler()->
+
+void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
+                                      const GrowableArray<intptr_t>& class_ids,
+                                      compiler::Label* is_equal_lbl,
+                                      compiler::Label* is_not_equal_lbl) {
+  for (const auto& id : class_ids) {
+    __ CompareImmediate(class_id_reg, id);
+    __ BranchIf(EQUAL, is_equal_lbl);
+  }
+  __ Jump(is_not_equal_lbl);
+}
+
 void FlowGraphCompiler::EmitTestAndCall(const CallTargets& targets,
                                         const String& function_name,
                                         ArgumentsInfo args_info,
@@ -2274,36 +2303,465 @@
 
 bool FlowGraphCompiler::CheckAssertAssignableTypeTestingABILocations(
     const LocationSummary& locs) {
-  ASSERT(locs.in(0).IsRegister() &&
-         locs.in(0).reg() == TypeTestABI::kInstanceReg);
-  ASSERT((locs.in(1).IsConstant() && locs.in(1).constant().IsAbstractType()) ||
-         (locs.in(1).IsRegister() &&
-          locs.in(1).reg() == TypeTestABI::kDstTypeReg));
-  ASSERT(locs.in(2).IsRegister() &&
-         locs.in(2).reg() == TypeTestABI::kInstantiatorTypeArgumentsReg);
-  ASSERT(locs.in(3).IsRegister() &&
-         locs.in(3).reg() == TypeTestABI::kFunctionTypeArgumentsReg);
+  ASSERT(locs.in(AssertAssignableInstr::kInstancePos).IsRegister() &&
+         locs.in(AssertAssignableInstr::kInstancePos).reg() ==
+             TypeTestABI::kInstanceReg);
+  ASSERT((locs.in(AssertAssignableInstr::kDstTypePos).IsConstant() &&
+          locs.in(AssertAssignableInstr::kDstTypePos)
+              .constant()
+              .IsAbstractType()) ||
+         (locs.in(AssertAssignableInstr::kDstTypePos).IsRegister() &&
+          locs.in(AssertAssignableInstr::kDstTypePos).reg() ==
+              TypeTestABI::kDstTypeReg));
+  ASSERT(locs.in(AssertAssignableInstr::kInstantiatorTAVPos).IsRegister() &&
+         locs.in(AssertAssignableInstr::kInstantiatorTAVPos).reg() ==
+             TypeTestABI::kInstantiatorTypeArgumentsReg);
+  ASSERT(locs.in(AssertAssignableInstr::kFunctionTAVPos).IsRegister() &&
+         locs.in(AssertAssignableInstr::kFunctionTAVPos).reg() ==
+             TypeTestABI::kFunctionTypeArgumentsReg);
   ASSERT(locs.out(0).IsRegister() &&
          locs.out(0).reg() == TypeTestABI::kInstanceReg);
   return true;
 }
 
+// Generates function type check.
+//
+// See [GenerateInlineInstanceof] for calling convention.
+SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
+    TokenPosition token_pos,
+    const AbstractType& type,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  __ Comment("FunctionTypeTest");
+
+  __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
+  // Load the type into the right register for the subtype test cache check.
+  __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+  // Uninstantiated type class is known at compile time, but the type
+  // arguments are determined at runtime by the instantiator(s).
+  return GenerateCallSubtypeTestStub(kTestTypeSevenArgs, is_instance_lbl,
+                                     is_not_instance_lbl);
+}
+
+// Inputs (from TypeTestABI):
+//   - kInstanceReg : instance to test against.
+//   - kInstantiatorTypeArgumentsReg : instantiator type arguments (if needed).
+//   - kFunctionTypeArgumentsReg : function type arguments (if needed).
+//
+// Preserves all input registers.
+//
+// Clobbers kDstTypeReg, kSubtypeTestCacheReg and kSubtypeTestCacheResultReg at
+// a minimum, may clobber additional registers depending on architecture. See
+// GenerateSubtypeNTestCacheStub for architecture-specific registers that should
+// be saved across a subtype test cache stub call.
+//
+// Note that this inlined code must be followed by the runtime_call code, as it
+// may fall through to it. Otherwise, this inline code will jump to the label
+// is_instance or to the label is_not_instance.
+SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
+    TokenPosition token_pos,
+    const AbstractType& type,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  __ Comment("InlineInstanceof");
+
+  if (type.IsFunctionType()) {
+    return GenerateFunctionTypeTest(token_pos, type, is_instance_lbl,
+                                    is_not_instance_lbl);
+  }
+
+  if (type.IsInstantiated()) {
+    const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
+    // A class equality check is only applicable with a dst type (not a
+    // function type) of a non-parameterized class or with a raw dst type of
+    // a parameterized class.
+    if (type_class.NumTypeArguments() > 0) {
+      return GenerateInstantiatedTypeWithArgumentsTest(
+          token_pos, type, is_instance_lbl, is_not_instance_lbl);
+      // Fall through to runtime call.
+    }
+    const bool has_fall_through = GenerateInstantiatedTypeNoArgumentsTest(
+        token_pos, type, is_instance_lbl, is_not_instance_lbl);
+    if (has_fall_through) {
+      // If test non-conclusive so far, try the inlined type-test cache.
+      // 'type' is known at compile time.
+      return GenerateSubtype1TestCacheLookup(
+          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+    } else {
+      return SubtypeTestCache::null();
+    }
+  }
+  return GenerateUninstantiatedTypeTest(token_pos, type, is_instance_lbl,
+                                        is_not_instance_lbl);
+}
+
 FlowGraphCompiler::TypeTestStubKind
 FlowGraphCompiler::GetTypeTestStubKindForTypeParameter(
     const TypeParameter& type_param) {
   // If it's guaranteed, by type-parameter bound, that the type parameter will
-  // never have a value of a function type, then we can safely do a 4-type
-  // test instead of a 6-type test.
+  // never have a value of a function type, then we can safely do a 5-type
+  // test instead of a 7-type test.
   AbstractType& bound = AbstractType::Handle(zone(), type_param.bound());
   bound = bound.UnwrapFutureOr();
   return !bound.IsTopTypeForSubtyping() && !bound.IsObjectType() &&
                  !bound.IsFunctionType() && !bound.IsDartFunctionType() &&
                  bound.IsType()
-             ? kTestTypeFourArgs
-             : kTestTypeSixArgs;
+             ? kTestTypeFiveArgs
+             : kTestTypeSevenArgs;
+}
+
+// Generates quick and subtype cache tests when only the instance need be
+// checked. Jumps to 'is_instance' or 'is_not_instance' respectively, if any
+// generated check is conclusive, otherwise falls through if further checking is
+// required.
+//
+// See [GenerateInlineInstanceof] for calling convention.
+SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
+    TokenPosition token_pos,
+    const Class& type_class,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  __ Comment("Subtype1TestCacheLookup");
+#if defined(DEBUG)
+  compiler::Label ok;
+  __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &ok);
+  __ Breakpoint();
+  __ Bind(&ok);
+#endif
+  // Check immediate superclass equality. If type_class is Object, then testing
+  // supertype may yield a wrong result for Null in NNBD strong mode (because
+  // Null also extends Object).
+  if (!type_class.IsObjectClass() ||
+      !Isolate::Current()->use_strict_null_safety_checks()) {
+    // We don't use TypeTestABI::kScratchReg for the first scratch register as
+    // it is not defined on IA32. Instead, we use the subtype test cache
+    // register, as it is clobbered by the subtype test cache stub call anyway.
+    const Register kScratch1Reg = TypeTestABI::kSubtypeTestCacheReg;
+#if defined(TARGET_ARCH_IA32)
+    // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
+    // Instead, we pick another TypeTestABI register and push/pop it around
+    // the uses of the second scratch register.
+    const Register kScratch2Reg = TypeTestABI::kDstTypeReg;
+    __ PushRegister(kScratch2Reg);
+#else
+    // We can use TypeTestABI::kScratchReg for the second scratch register, as
+    // IA32 is handled separately.
+    const Register kScratch2Reg = TypeTestABI::kScratchReg;
+#endif
+    static_assert(kScratch1Reg != kScratch2Reg,
+                  "Scratch registers must be distinct");
+    __ LoadClassId(kScratch2Reg, TypeTestABI::kInstanceReg);
+    __ LoadClassById(kScratch1Reg, kScratch2Reg);
+#if defined(TARGET_ARCH_IA32)
+    // kScratch2 is no longer used, so restore it.
+    __ PopRegister(kScratch2Reg);
+#endif
+    __ LoadFieldFromOffset(kScratch1Reg, kScratch1Reg,
+                           compiler::target::Class::super_type_offset());
+    __ LoadFieldFromOffset(kScratch1Reg, kScratch1Reg,
+                           compiler::target::Type::type_class_id_offset());
+    __ CompareImmediate(kScratch1Reg, Smi::RawValue(type_class.id()));
+    __ BranchIf(EQUAL, is_instance_lbl);
+  }
+
+  return GenerateCallSubtypeTestStub(kTestTypeOneArg, is_instance_lbl,
+                                     is_not_instance_lbl);
+}
+
+// Generates quick and subtype cache tests for an instantiated generic type.
+// Jumps to 'is_instance' or 'is_not_instance' respectively, if any generated
+// check is conclusive, otherwise falls through if further checking is required.
+//
+// See [GenerateInlineInstanceof] for calling convention.
+SubtypeTestCachePtr
+FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
+    TokenPosition token_pos,
+    const AbstractType& type,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  __ Comment("InstantiatedTypeWithArgumentsTest");
+  ASSERT(type.IsInstantiated());
+  ASSERT(!type.IsFunctionType());
+  const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
+  ASSERT(type_class.NumTypeArguments() > 0);
+  const Type& smi_type = Type::Handle(zone(), Type::SmiType());
+  const bool smi_is_ok = smi_type.IsSubtypeOf(type, Heap::kOld);
+  __ BranchIfSmi(TypeTestABI::kInstanceReg,
+                 smi_is_ok ? is_instance_lbl : is_not_instance_lbl);
+
+  const intptr_t num_type_args = type_class.NumTypeArguments();
+  const intptr_t num_type_params = type_class.NumTypeParameters();
+  const intptr_t from_index = num_type_args - num_type_params;
+  const TypeArguments& type_arguments =
+      TypeArguments::ZoneHandle(zone(), type.arguments());
+  const bool is_raw_type = type_arguments.IsNull() ||
+                           type_arguments.IsRaw(from_index, num_type_params);
+  // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
+  // Instead, we use the subtype test cache register, as it is clobbered by the
+  // subtype test cache stub call anyway.
+  const Register kScratchReg = TypeTestABI::kSubtypeTestCacheReg;
+  if (is_raw_type) {
+    // dynamic type argument, check only classes.
+    __ LoadClassId(kScratchReg, TypeTestABI::kInstanceReg);
+    __ CompareImmediate(kScratchReg, type_class.id());
+    __ BranchIf(EQUAL, is_instance_lbl);
+    // List is a very common case.
+    if (IsListClass(type_class)) {
+      GenerateListTypeCheck(kScratchReg, is_instance_lbl);
+    }
+    return GenerateSubtype1TestCacheLookup(
+        token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+  }
+  // If one type argument only, check if type argument is a top type.
+  if (type_arguments.Length() == 1) {
+    const AbstractType& tp_argument =
+        AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
+    if (tp_argument.IsTopTypeForSubtyping()) {
+      // Instance class test only necessary.
+      return GenerateSubtype1TestCacheLookup(
+          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+    }
+  }
+
+  // Load the type into the right register for the subtype test cache check.
+  __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+  // Regular subtype test cache involving instance's type arguments.
+  return GenerateCallSubtypeTestStub(kTestTypeThreeArgs, is_instance_lbl,
+                                     is_not_instance_lbl);
+}
+
+// Generates quick and subtype cache tests for an instantiated non-generic type.
+// Jumps to 'is_instance' or 'is_not_instance' respectively, if any generated
+// check is conclusive. Returns whether the code will fall through for further
+// type checking because the checks are not exhaustive.
+//
+// See [GenerateInlineInstanceof] for calling convention.
+//
+// Uses kScratchReg, so this implementation cannot be shared with IA32.
+bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
+    TokenPosition token_pos,
+    const AbstractType& type,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  __ Comment("InstantiatedTypeNoArgumentsTest");
+  ASSERT(type.IsInstantiated());
+  ASSERT(!type.IsFunctionType());
+  const Class& type_class = Class::Handle(zone(), type.type_class());
+  ASSERT(type_class.NumTypeArguments() == 0);
+
+  // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
+  // Instead, we use the subtype test cache register, as it is clobbered by the
+  // subtype test cache stub call anyway.
+  const Register kScratchReg = TypeTestABI::kSubtypeTestCacheReg;
+
+  const Class& smi_class = Class::Handle(zone(), Smi::Class());
+  const bool smi_is_ok =
+      Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
+                         Nullability::kNonNullable, type, Heap::kOld);
+  __ BranchIfSmi(TypeTestABI::kInstanceReg,
+                 smi_is_ok ? is_instance_lbl : is_not_instance_lbl);
+  __ LoadClassId(kScratchReg, TypeTestABI::kInstanceReg);
+  // Bool interface can be implemented only by core class Bool.
+  if (type.IsBoolType()) {
+    __ CompareImmediate(kScratchReg, kBoolCid);
+    __ BranchIf(EQUAL, is_instance_lbl);
+    __ Jump(is_not_instance_lbl);
+    return false;
+  }
+  // Custom checking for numbers (Smi, Mint and Double).
+  // Note that instance is not Smi (checked above).
+  if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType()) {
+    GenerateNumberTypeCheck(kScratchReg, type, is_instance_lbl,
+                            is_not_instance_lbl);
+    return false;
+  }
+  if (type.IsStringType()) {
+    GenerateStringTypeCheck(kScratchReg, is_instance_lbl, is_not_instance_lbl);
+    return false;
+  }
+  if (type.IsDartFunctionType()) {
+    // Check if instance is a closure.
+    __ CompareImmediate(kScratchReg, kClosureCid);
+    __ BranchIf(EQUAL, is_instance_lbl);
+    return true;
+  }
+
+  // Fast case for cid-range based checks.
+  // Warning: This code destroys the contents of [kScratchReg], so this should
+  // be the last check in this method. It returns whether the checks were
+  // exhaustive, so we negate it to indicate whether we'll fall through.
+  return !GenerateSubtypeRangeCheck(kScratchReg, type_class, is_instance_lbl);
+}
+
+// Generates inlined check if 'type' is a type parameter or type itself.
+//
+// See [GenerateInlineInstanceof] for calling convention.
+SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
+    TokenPosition token_pos,
+    const AbstractType& type,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  __ Comment("UninstantiatedTypeTest");
+  ASSERT(!type.IsInstantiated());
+  ASSERT(!type.IsFunctionType());
+  // Skip check if destination is a dynamic type.
+  if (type.IsTypeParameter()) {
+    // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
+    // Instead, we use the subtype test cache register, as it is clobbered by
+    // the subtype test cache stub call anyway.
+    const Register kScratchReg = TypeTestABI::kSubtypeTestCacheReg;
+
+    const TypeParameter& type_param = TypeParameter::Cast(type);
+
+    const Register kTypeArgumentsReg =
+        type_param.IsClassTypeParameter()
+            ? TypeTestABI::kInstantiatorTypeArgumentsReg
+            : TypeTestABI::kFunctionTypeArgumentsReg;
+    // Check if type arguments are null, i.e. equivalent to vector of dynamic.
+    __ CompareObject(kTypeArgumentsReg, Object::null_object());
+    __ BranchIf(EQUAL, is_instance_lbl);
+    __ LoadFieldFromOffset(kScratchReg, kTypeArgumentsReg,
+                           TypeArguments::type_at_offset(type_param.index()));
+    // kScratchReg: Concrete type of type.
+    // Check if type argument is dynamic, Object?, or void.
+    __ CompareObject(kScratchReg, Object::dynamic_type());
+    __ BranchIf(EQUAL, is_instance_lbl);
+    __ CompareObject(
+        kScratchReg,
+        Type::ZoneHandle(zone(),
+                         isolate()->object_store()->nullable_object_type()));
+    __ BranchIf(EQUAL, is_instance_lbl);
+    __ CompareObject(kScratchReg, Object::void_type());
+    __ BranchIf(EQUAL, is_instance_lbl);
+
+    // For Smi check quickly against int and num interfaces.
+    compiler::Label not_smi;
+    __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &not_smi,
+                      compiler::Assembler::kNearJump);
+    __ CompareObject(kScratchReg, Type::ZoneHandle(zone(), Type::IntType()));
+    __ BranchIf(EQUAL, is_instance_lbl);
+    __ CompareObject(kScratchReg, Type::ZoneHandle(zone(), Type::Number()));
+    __ BranchIf(EQUAL, is_instance_lbl);
+    // Smi can be handled by type test cache.
+    __ Bind(&not_smi);
+
+    // Load the type into the right register for the subtype test cache check.
+    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+    const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
+    return GenerateCallSubtypeTestStub(test_kind, is_instance_lbl,
+                                       is_not_instance_lbl);
+  }
+  if (type.IsType()) {
+    // The only uninstantiated type to which a Smi is assignable is FutureOr<T>,
+    // as T might be a top type or int or num when instantiated
+    if (!type.IsFutureOrType()) {
+      __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
+    }
+    // Load the type into the right register for the subtype test cache check.
+    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+    // Uninstantiated type class is known at compile time, but the type
+    // arguments are determined at runtime by the instantiator(s).
+    return GenerateCallSubtypeTestStub(kTestTypeFiveArgs, is_instance_lbl,
+                                       is_not_instance_lbl);
+  }
+  return SubtypeTestCache::null();
 }
 
 #if !defined(TARGET_ARCH_IA32)
+// If instanceof type test cannot be performed successfully at compile time and
+// therefore eliminated, optimize it by adding inlined tests for:
+// - Null -> see comment below.
+// - Smi -> compile time subtype check (only if dst class is not parameterized).
+// - Class equality (only if class is not parameterized).
+// Inputs (from TypeTestABI):
+// - kInstanceReg: object.
+// - kInstantiatorTypeArgumentsReg: instantiator type arguments or raw_null.
+// - kFunctionTypeArgumentsReg: function type arguments or raw_null.
+// Returns:
+// - true or false in kInstanceOfResultReg.
+void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
+                                           intptr_t deopt_id,
+                                           const AbstractType& type,
+                                           LocationSummary* locs) {
+  ASSERT(type.IsFinalized());
+  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
+
+  compiler::Label is_instance, is_not_instance;
+  // 'null' is an instance of Null, Object*, Never*, void, and dynamic.
+  // In addition, 'null' is an instance of any nullable type.
+  // It is also an instance of FutureOr<T> if it is an instance of T.
+  const AbstractType& unwrapped_type =
+      AbstractType::Handle(type.UnwrapFutureOr());
+  if (!unwrapped_type.IsTypeParameter() || unwrapped_type.IsNullable()) {
+    // Only nullable type parameter remains nullable after instantiation.
+    // See NullIsInstanceOf().
+    __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
+    __ BranchIf(EQUAL,
+                (unwrapped_type.IsNullable() ||
+                 (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType()))
+                    ? &is_instance
+                    : &is_not_instance);
+  }
+
+  // Generate inline instanceof test.
+  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+  // kInstanceReg, kInstantiatorTypeArgumentsReg, and kFunctionTypeArgumentsReg
+  // are preserved across the call.
+  test_cache =
+      GenerateInlineInstanceof(token_pos, type, &is_instance, &is_not_instance);
+
+  // test_cache is null if there is no fall-through.
+  compiler::Label done;
+  if (!test_cache.IsNull()) {
+    // Generate Runtime call.
+    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
+    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
+    GenerateStubCall(token_pos, StubCode::InstanceOf(),
+                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
+    __ Jump(&done, compiler::Assembler::kNearJump);
+  }
+  __ Bind(&is_not_instance);
+  __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(false));
+  __ Jump(&done, compiler::Assembler::kNearJump);
+
+  __ Bind(&is_instance);
+  __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(true));
+  __ Bind(&done);
+}
+
+// Expected inputs (from TypeTestABI):
+// - kInstanceReg: instance (preserved).
+// - kDstTypeReg: destination type (for test_kind != kTestTypeOneArg).
+// - kInstantiatorTypeArgumentsReg: instantiator type arguments
+//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+// - kFunctionTypeArgumentsReg: function type arguments
+//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+//
+// See the arch-specific GenerateSubtypeNTestCacheStub method to see which
+// registers may need saving across this call.
+SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
+    TypeTestStubKind test_kind,
+    compiler::Label* is_instance_lbl,
+    compiler::Label* is_not_instance_lbl) {
+  const SubtypeTestCache& type_test_cache =
+      SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
+  __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, type_test_cache);
+  if (test_kind == kTestTypeOneArg) {
+    __ Call(StubCode::Subtype1TestCache());
+  } else if (test_kind == kTestTypeThreeArgs) {
+    __ Call(StubCode::Subtype3TestCache());
+  } else if (test_kind == kTestTypeFiveArgs) {
+    __ Call(StubCode::Subtype5TestCache());
+  } else if (test_kind == kTestTypeSevenArgs) {
+    __ Call(StubCode::Subtype7TestCache());
+  } else {
+    UNREACHABLE();
+  }
+  GenerateBoolToJump(TypeTestABI::kSubtypeTestCacheResultReg, is_instance_lbl,
+                     is_not_instance_lbl);
+  return type_test_cache.raw();
+}
+
 // Generates an assignable check for a given object. Emits no code if the
 // destination type is known at compile time and is a top type. See
 // GenerateCallerChecksForAssertAssignable for other optimized cases.
@@ -2327,23 +2785,34 @@
   ASSERT(!token_pos.IsClassifying());
   ASSERT(CheckAssertAssignableTypeTestingABILocations(*locs));
 
-  if (!locs->in(1).IsConstant()) {
-    // TODO(dartbug.com/40813): Handle setting up the non-constant case.
-    UNREACHABLE();
-  }
-  const auto& dst_type = AbstractType::Cast(locs->in(1).constant());
-  ASSERT(dst_type.IsFinalized());
+  // Non-null if we have a constant destination type.
+  const auto& dst_type =
+      locs->in(AssertAssignableInstr::kDstTypePos).IsConstant()
+          ? AbstractType::Cast(
+                locs->in(AssertAssignableInstr::kDstTypePos).constant())
+          : Object::null_abstract_type();
 
-  if (dst_type.IsTopTypeForSubtyping()) return;  // No code needed.
+  if (!dst_type.IsNull()) {
+    ASSERT(dst_type.IsFinalized());
+    if (dst_type.IsTopTypeForSubtyping()) return;  // No code needed.
+  }
 
   compiler::Label done;
+  Register type_reg = TypeTestABI::kDstTypeReg;
+  // Generate caller-side checks to perform prior to calling the TTS.
+  if (dst_type.IsNull()) {
+    __ Comment("AssertAssignable for runtime type");
+    // kDstTypeReg should already contain the destination type.
+  } else {
+    __ Comment("AssertAssignable for compile-time type");
+    GenerateCallerChecksForAssertAssignable(receiver_type, dst_type, &done);
+    if (dst_type.IsTypeParameter()) {
+      // The resolved type parameter is in the scratch register.
+      type_reg = TypeTestABI::kScratchReg;
+    }
+  }
 
-  GenerateCallerChecksForAssertAssignable(receiver_type, dst_type, &done);
-
-  GenerateTTSCall(token_pos, deopt_id,
-                  dst_type.IsTypeParameter() ? TypeTestABI::kScratchReg
-                                             : TypeTestABI::kDstTypeReg,
-                  dst_type, dst_name, locs);
+  GenerateTTSCall(token_pos, deopt_id, type_reg, dst_type, dst_name, locs);
   __ Bind(&done);
 }
 
@@ -2356,8 +2825,7 @@
                                         const AbstractType& dst_type,
                                         const String& dst_name,
                                         LocationSummary* locs) {
-  // For now, we don't allow dynamic (non-compile-time) dst_type/dst_name.
-  ASSERT(!dst_type.IsNull() && !dst_name.IsNull());
+  ASSERT(!dst_name.IsNull());
   // We use 2 consecutive entries in the pool for the subtype cache and the
   // destination name.  The second entry, namely [dst_name] seems to be unused,
   // but it will be used by the code throwing a TypeError if the type test fails
@@ -2371,9 +2839,11 @@
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
+  __ Comment("TTSCall");
   // If the dst_type is known at compile time and instantiated, we know the
   // target TTS stub and so can use a PC-relative call when available.
-  if (dst_type.IsInstantiated() && CanPcRelativeCall(dst_type)) {
+  if (!dst_type.IsNull() && dst_type.IsInstantiated() &&
+      CanPcRelativeCall(dst_type)) {
     __ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
                              sub_type_cache_index);
     __ GenerateUnRelocatedPcRelativeCall();
@@ -2439,7 +2909,8 @@
 
   if (dst_type.IsObjectType()) {
     // Special case: non-nullable Object.
-    ASSERT(dst_type.IsNonNullable() && isolate()->null_safety());
+    ASSERT(dst_type.IsNonNullable() &&
+           isolate()->use_strict_null_safety_checks());
     __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
     __ BranchIf(NOT_EQUAL, done);
     // Fall back to type testing stub in caller to throw the exception.
@@ -2461,7 +2932,8 @@
     // Special case: Instantiate the type parameter on the caller side, invoking
     // the TTS of the corresponding type parameter in the caller.
     const TypeParameter& type_param = TypeParameter::Cast(dst_type);
-    if (isolate()->null_safety() && !type_param.IsNonNullable()) {
+    if (isolate()->use_strict_null_safety_checks() &&
+        !type_param.IsNonNullable()) {
       // If the type parameter is nullable when running in strong mode, we need
       // to handle null before calling the TTS because the type parameter may be
       // instantiated with a non-nullable type, where the TTS rejects null.
@@ -2625,7 +3097,7 @@
                           instruction()->token_pos(), try_index_);
   AddMetadataForRuntimeCall(compiler);
   compiler->RecordSafepoint(locs, num_args);
-  if ((try_index_ != kInvalidTryIndex) ||
+  if (!FLAG_precompiled_mode || (try_index_ != kInvalidTryIndex) ||
       (compiler->CurrentTryIndex() != kInvalidTryIndex)) {
     Environment* env =
         compiler->SlowPathEnvironmentFor(instruction(), num_args);
@@ -2800,8 +3272,10 @@
       !destination.IsFpuRegisters()) {
     // TODO(40209): If this is stack to stack, we could use FpuTMP.
     // Test the impact on code size and speed.
-    EmitNativeMove(destination.Split(zone_, 0), source.Split(zone_, 0), temp);
-    EmitNativeMove(destination.Split(zone_, 1), source.Split(zone_, 1), temp);
+    EmitNativeMove(destination.Split(zone_, 2, 0), source.Split(zone_, 2, 0),
+                   temp);
+    EmitNativeMove(destination.Split(zone_, 2, 1), source.Split(zone_, 2, 1),
+                   temp);
     return;
   }
 
@@ -2814,7 +3288,7 @@
     }
     const auto& intermediate =
         *new (zone_) compiler::ffi::NativeRegistersLocation(
-            dst_payload_type, dst_container_type, scratch);
+            zone_, dst_payload_type, dst_container_type, scratch);
     EmitNativeMove(intermediate, source, temp);
     EmitNativeMove(destination, intermediate, temp);
     if (TMP == kNoRegister) {
@@ -2876,7 +3350,7 @@
     for (intptr_t i : {0, 1}) {
       const auto& src_split = compiler::ffi::NativeLocation::FromPairLocation(
           zone_, src_loc, src_type, i);
-      EmitNativeMove(dst.Split(zone_, i), src_split, temp);
+      EmitNativeMove(dst.Split(zone_, 2, i), src_split, temp);
     }
   } else {
     const auto& src =
@@ -2896,7 +3370,7 @@
     for (intptr_t i : {0, 1}) {
       const auto& dest_split = compiler::ffi::NativeLocation::FromPairLocation(
           zone_, dst_loc, dst_type, i);
-      EmitNativeMove(dest_split, src.Split(zone_, i), temp);
+      EmitNativeMove(dest_split, src.Split(zone_, 2, i), temp);
     }
   } else {
     const auto& dest =
@@ -2943,7 +3417,7 @@
             compiler::ffi::NativeLocation::FromLocation(zone_, intermediate,
                                                         src_type_split);
         EmitMove(intermediate, src.AsPairLocation()->At(i), temp);
-        EmitNativeMove(dst.Split(zone_, i), intermediate_native, temp);
+        EmitNativeMove(dst.Split(zone_, 2, i), intermediate_native, temp);
       }
     } else {
       const auto& intermediate_native =
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 1965d97..ca9a298 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -364,7 +364,7 @@
   LateInitializationErrorSlowPath(LoadFieldInstr* instruction,
                                   intptr_t try_index)
       : ThrowErrorSlowPathCode(instruction,
-                               kLateInitializationErrorRuntimeEntry,
+                               kLateFieldNotInitializedErrorRuntimeEntry,
                                try_index) {}
   virtual const char* name() { return "late initialization error"; }
 
@@ -911,11 +911,15 @@
   bool may_reoptimize() const { return may_reoptimize_; }
 
   // Use in unoptimized compilation to preserve/reuse ICData.
+  //
+  // If [binary_smi_target] is non-null and we have to create the ICData, the
+  // ICData will get an (kSmiCid, kSmiCid, binary_smi_target) entry.
   const ICData* GetOrAddInstanceCallICData(intptr_t deopt_id,
                                            const String& target_name,
                                            const Array& arguments_descriptor,
                                            intptr_t num_args_tested,
-                                           const AbstractType& receiver_type);
+                                           const AbstractType& receiver_type,
+                                           const Function& binary_smi_target);
 
   const ICData* GetOrAddStaticCallICData(intptr_t deopt_id,
                                          const Function& target,
@@ -1076,21 +1080,19 @@
 
   enum TypeTestStubKind {
     kTestTypeOneArg,
-    kTestTypeTwoArgs,
-    kTestTypeFourArgs,
-    kTestTypeSixArgs,
+    kTestTypeThreeArgs,
+    kTestTypeFiveArgs,
+    kTestTypeSevenArgs,
   };
 
   // Returns type test stub kind for a type test against type parameter type.
   TypeTestStubKind GetTypeTestStubKindForTypeParameter(
       const TypeParameter& type_param);
 
+  // Takes input from TypeTestABI registers (or stack on IA32), see
+  // StubCodeCompiler::GenerateSubtypeNTestCacheStub for caller-save registers.
   SubtypeTestCachePtr GenerateCallSubtypeTestStub(
       TypeTestStubKind test_kind,
-      Register instance_reg,
-      Register instantiator_type_arguments_reg,
-      Register function_type_arguments_reg,
-      Register temp_reg,
       compiler::Label* is_instance_lbl,
       compiler::Label* is_not_instance_lbl);
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 66f966d..1d85187 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -224,464 +224,6 @@
   __ Bind(&fall_through);
 }
 
-// R0: instance (must be preserved).
-// R2: instantiator type arguments (if used).
-// R1: function type arguments (if used).
-// R3: type test cache.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
-    TypeTestStubKind test_kind,
-    Register instance_reg,
-    Register instantiator_type_arguments_reg,
-    Register function_type_arguments_reg,
-    Register temp_reg,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  ASSERT(instance_reg == R0);
-  ASSERT(temp_reg == kNoRegister);  // Unused on ARM.
-  const SubtypeTestCache& type_test_cache =
-      SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
-  __ LoadUniqueObject(R3, type_test_cache);
-  if (test_kind == kTestTypeOneArg) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ BranchLink(StubCode::Subtype1TestCache());
-  } else if (test_kind == kTestTypeTwoArgs) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ BranchLink(StubCode::Subtype2TestCache());
-  } else if (test_kind == kTestTypeFourArgs) {
-    ASSERT(instantiator_type_arguments_reg ==
-           TypeTestABI::kInstantiatorTypeArgumentsReg);
-    ASSERT(function_type_arguments_reg ==
-           TypeTestABI::kFunctionTypeArgumentsReg);
-    __ BranchLink(StubCode::Subtype4TestCache());
-  } else if (test_kind == kTestTypeSixArgs) {
-    ASSERT(instantiator_type_arguments_reg ==
-           TypeTestABI::kInstantiatorTypeArgumentsReg);
-    ASSERT(function_type_arguments_reg ==
-           TypeTestABI::kFunctionTypeArgumentsReg);
-    __ BranchLink(StubCode::Subtype6TestCache());
-  } else {
-    UNREACHABLE();
-  }
-  // Result is in R1: null -> not found, otherwise Bool::True or Bool::False.
-  GenerateBoolToJump(R1, is_instance_lbl, is_not_instance_lbl);
-  return type_test_cache.raw();
-}
-
-// Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
-// type test is conclusive, otherwise fallthrough if a type test could not
-// be completed.
-// R0: instance being type checked (preserved).
-// Clobbers R1, R2.
-SubtypeTestCachePtr
-FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeWithArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() > 0);
-  const Type& smi_type = Type::Handle(zone(), Type::SmiType());
-  const bool smi_is_ok = smi_type.IsSubtypeOf(type, Heap::kOld);
-  __ tst(TypeTestABI::kInstanceReg, compiler::Operand(kSmiTagMask));
-  if (smi_is_ok) {
-    // Fast case for type = FutureOr<int/num/top-type>.
-    __ b(is_instance_lbl, EQ);
-  } else {
-    __ b(is_not_instance_lbl, EQ);
-  }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-                           type_arguments.IsRaw(from_index, num_type_params);
-  if (is_raw_type) {
-    const Register kClassIdReg = R2;
-    // dynamic type argument, check only classes.
-    __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-    __ CompareImmediate(kClassIdReg, type_class.id());
-    __ b(is_instance_lbl, EQ);
-    // List is a very common case.
-    if (IsListClass(type_class)) {
-      GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
-    }
-    return GenerateSubtype1TestCacheLookup(
-        token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-  }
-  // If one type argument only, check if type argument is a top type.
-  if (type_arguments.Length() == 1) {
-    const AbstractType& tp_argument =
-        AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopTypeForSubtyping()) {
-      // Instance class test only necessary.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    }
-  }
-
-  // Regular subtype test cache involving instance's type arguments.
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = kNoRegister;
-  // R0: instance (must be preserved).
-  return GenerateCallSubtypeTestStub(
-      kTestTypeTwoArgs, TypeTestABI::kInstanceReg,
-      kInstantiatorTypeArgumentsReg, kFunctionTypeArgumentsReg, kTempReg,
-      is_instance_lbl, is_not_instance_lbl);
-}
-
-void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
-                                      const GrowableArray<intptr_t>& class_ids,
-                                      compiler::Label* is_equal_lbl,
-                                      compiler::Label* is_not_equal_lbl) {
-  for (intptr_t i = 0; i < class_ids.length(); i++) {
-    __ CompareImmediate(class_id_reg, class_ids[i]);
-    __ b(is_equal_lbl, EQ);
-  }
-  __ b(is_not_equal_lbl);
-}
-
-// Testing against an instantiated type with no arguments, without
-// SubtypeTestCache.
-// R0: instance being type checked (preserved).
-// Clobbers R2, R3.
-// Returns true if there is a fallthrough.
-bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeNoArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::Handle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() == 0);
-
-  __ tst(TypeTestABI::kInstanceReg, compiler::Operand(kSmiTagMask));
-  // If instance is Smi, check directly.
-  const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
-                         Nullability::kNonNullable, type, Heap::kOld)) {
-    // Fast case for type = int/num/top-type.
-    __ b(is_instance_lbl, EQ);
-  } else {
-    __ b(is_not_instance_lbl, EQ);
-  }
-  const Register kClassIdReg = R2;
-  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-  // Bool interface can be implemented only by core class Bool.
-  if (type.IsBoolType()) {
-    __ CompareImmediate(kClassIdReg, kBoolCid);
-    __ b(is_instance_lbl, EQ);
-    __ b(is_not_instance_lbl);
-    return false;
-  }
-  // Custom checking for numbers (Smi, Mint and Double).
-  // Note that instance is not Smi (checked above).
-  if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType()) {
-    GenerateNumberTypeCheck(kClassIdReg, type, is_instance_lbl,
-                            is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsStringType()) {
-    GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsDartFunctionType()) {
-    // Check if instance is a closure.
-    __ CompareImmediate(kClassIdReg, kClosureCid);
-    __ b(is_instance_lbl, EQ);
-    return true;  // Fall through
-  }
-
-  // Fast case for cid-range based checks.
-  // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
-    return false;
-  }
-
-  // Otherwise fallthrough, result non-conclusive.
-  return true;
-}
-
-// Uses SubtypeTestCache to store instance class and result.
-// R0: instance to test.
-// Clobbers R1-R4, R8, R9.
-// Immediate class test already done.
-// TODO(srdjan): Implement a quicker subtype check, as type test
-// arrays can grow too high, but they may be useful when optimizing
-// code (type-feedback).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    TokenPosition token_pos,
-    const Class& type_class,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("Subtype1TestCacheLookup");
-#if defined(DEBUG)
-  compiler::Label ok;
-  __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &ok);
-  __ Breakpoint();
-  __ Bind(&ok);
-#endif
-  __ LoadClassId(R2, TypeTestABI::kInstanceReg);
-  __ LoadClassById(R1, R2);
-  // R1: instance class.
-  // Check immediate superclass equality. If type_class is Object, then testing
-  // supertype may yield a wrong result for Null in NNBD strong mode (because
-  // Null also extends Object).
-  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
-    __ ldr(R2, compiler::FieldAddress(
-                   R1, compiler::target::Class::super_type_offset()));
-    __ ldr(R2, compiler::FieldAddress(
-                   R2, compiler::target::Type::type_class_id_offset()));
-    __ CompareImmediate(R2, Smi::RawValue(type_class.id()));
-    __ b(is_instance_lbl, EQ);
-  }
-
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = kNoRegister;
-  return GenerateCallSubtypeTestStub(kTestTypeOneArg, TypeTestABI::kInstanceReg,
-                                     kInstantiatorTypeArgumentsReg,
-                                     kFunctionTypeArgumentsReg, kTempReg,
-                                     is_instance_lbl, is_not_instance_lbl);
-}
-
-// Generates inlined check if 'type' is a type parameter or type itself
-// R0: instance (preserved).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("UninstantiatedTypeTest");
-  const Register kTempReg = kNoRegister;
-  ASSERT(!type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  // Skip check if destination is a dynamic type.
-  if (type.IsTypeParameter()) {
-    const TypeParameter& type_param = TypeParameter::Cast(type);
-    static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
-                      TypeTestABI::kInstantiatorTypeArgumentsReg,
-                  "Should be ordered to load arguments with one instruction");
-    __ ldm(IA, SP,
-           (1 << TypeTestABI::kFunctionTypeArgumentsReg) |
-               (1 << TypeTestABI::kInstantiatorTypeArgumentsReg));
-    const Register kTypeArgumentsReg =
-        type_param.IsClassTypeParameter()
-            ? TypeTestABI::kInstantiatorTypeArgumentsReg
-            : TypeTestABI::kFunctionTypeArgumentsReg;
-    // Check if type arguments are null, i.e. equivalent to vector of dynamic.
-    __ CompareObject(kTypeArgumentsReg, Object::null_object());
-    __ b(is_instance_lbl, EQ);
-    __ ldr(R3, compiler::FieldAddress(
-                   kTypeArgumentsReg,
-                   compiler::target::TypeArguments::type_at_offset(
-                       type_param.index())));
-    // R3: concrete type of type.
-    // Check if type argument is dynamic, Object?, or void.
-    __ CompareObject(R3, Object::dynamic_type());
-    __ b(is_instance_lbl, EQ);
-    __ CompareObject(
-        R3, Type::ZoneHandle(
-                zone(), isolate()->object_store()->nullable_object_type()));
-    __ b(is_instance_lbl, EQ);
-    __ CompareObject(R3, Object::void_type());
-    __ b(is_instance_lbl, EQ);
-
-    // For Smi check quickly against int and num interfaces.
-    compiler::Label not_smi;
-    __ tst(R0, compiler::Operand(kSmiTagMask));  // Value is Smi?
-    __ b(&not_smi, NE);
-    __ CompareObject(R3, Type::ZoneHandle(zone(), Type::IntType()));
-    __ b(is_instance_lbl, EQ);
-    __ CompareObject(R3, Type::ZoneHandle(zone(), Type::Number()));
-    __ b(is_instance_lbl, EQ);
-    // Smi can be handled by type test cache.
-    __ Bind(&not_smi);
-
-    const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
-    const SubtypeTestCache& type_test_cache = SubtypeTestCache::ZoneHandle(
-        zone(), GenerateCallSubtypeTestStub(
-                    test_kind, TypeTestABI::kInstanceReg,
-                    TypeTestABI::kInstantiatorTypeArgumentsReg,
-                    TypeTestABI::kFunctionTypeArgumentsReg, kTempReg,
-                    is_instance_lbl, is_not_instance_lbl));
-    return type_test_cache.raw();
-  }
-  if (type.IsType()) {
-    // Smi is FutureOr<T>, when T is a top type or int or num.
-    if (!type.IsFutureOrType()) {
-      __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
-    }
-    static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
-                      TypeTestABI::kInstantiatorTypeArgumentsReg,
-                  "Should be ordered to load arguments with one instruction");
-    __ ldm(IA, SP,
-           (1 << TypeTestABI::kFunctionTypeArgumentsReg) |
-               (1 << TypeTestABI::kInstantiatorTypeArgumentsReg));
-    // Uninstantiated type class is known at compile time, but the type
-    // arguments are determined at runtime by the instantiator(s).
-    return GenerateCallSubtypeTestStub(
-        kTestTypeFourArgs, TypeTestABI::kInstanceReg,
-        TypeTestABI::kInstantiatorTypeArgumentsReg,
-        TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-        is_not_instance_lbl);
-  }
-  return SubtypeTestCache::null();
-}
-
-// Generates function type check.
-//
-// See [GenerateUninstantiatedTypeTest] for calling convention.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
-  static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
-                    TypeTestABI::kInstantiatorTypeArgumentsReg,
-                "Should be ordered to load arguments with one instruction");
-  __ ldm(IA, SP,
-         (1 << TypeTestABI::kFunctionTypeArgumentsReg) |
-             (1 << TypeTestABI::kInstantiatorTypeArgumentsReg));
-  // Uninstantiated type class is known at compile time, but the type
-  // arguments are determined at runtime by the instantiator(s).
-  const Register kTempReg = kNoRegister;
-  return GenerateCallSubtypeTestStub(
-      kTestTypeSixArgs, TypeTestABI::kInstanceReg,
-      TypeTestABI::kInstantiatorTypeArgumentsReg,
-      TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-      is_not_instance_lbl);
-}
-
-// Inputs:
-// - R0: instance being type checked (preserved).
-// - R2: optional instantiator type arguments (preserved).
-// - R1: optional function type arguments (preserved).
-// Clobbers R3, R4, R8, R9.
-// Returns:
-// - preserved instance in R0, optional instantiator type arguments in R2, and
-//   optional function type arguments in R1.
-// Note that this inlined code must be followed by the runtime_call code, as it
-// may fall through to it. Otherwise, this inline code will jump to the label
-// is_instance or to the label is_not_instance.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InlineInstanceof");
-
-  if (type.IsFunctionType()) {
-    return GenerateFunctionTypeTest(token_pos, type, is_instance_lbl,
-                                    is_not_instance_lbl);
-  }
-
-  if (type.IsInstantiated()) {
-    const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type (not a
-    // function type) of a non-parameterized class or with a raw dst type of
-    // a parameterized class.
-    if (type_class.NumTypeArguments() > 0) {
-      return GenerateInstantiatedTypeWithArgumentsTest(
-          token_pos, type, is_instance_lbl, is_not_instance_lbl);
-      // Fall through to runtime call.
-    }
-    const bool has_fall_through = GenerateInstantiatedTypeNoArgumentsTest(
-        token_pos, type, is_instance_lbl, is_not_instance_lbl);
-    if (has_fall_through) {
-      // If test non-conclusive so far, try the inlined type-test cache.
-      // 'type' is known at compile time.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    } else {
-      return SubtypeTestCache::null();
-    }
-  }
-  return GenerateUninstantiatedTypeTest(token_pos, type, is_instance_lbl,
-                                        is_not_instance_lbl);
-}
-
-// If instanceof type test cannot be performed successfully at compile time and
-// therefore eliminated, optimize it by adding inlined tests for:
-// - Null -> see comment below.
-// - Smi -> compile time subtype check (only if dst class is not parameterized).
-// - Class equality (only if class is not parameterized).
-// Inputs:
-// - R0: object.
-// - R2: instantiator type arguments or raw_null.
-// - R1: function type arguments or raw_null.
-// Returns:
-// - true or false in R0.
-void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
-                                           intptr_t deopt_id,
-                                           const AbstractType& type,
-                                           LocationSummary* locs) {
-  ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
-  static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
-                    TypeTestABI::kInstantiatorTypeArgumentsReg,
-                "Should be ordered to push arguments with one instruction");
-  __ PushList((1 << TypeTestABI::kInstantiatorTypeArgumentsReg) |
-              (1 << TypeTestABI::kFunctionTypeArgumentsReg));
-
-  compiler::Label is_instance, is_not_instance;
-  // 'null' is an instance of Null, Object*, Never*, void, and dynamic.
-  // In addition, 'null' is an instance of any nullable type.
-  // It is also an instance of FutureOr<T> if it is an instance of T.
-  const AbstractType& unwrapped_type =
-      AbstractType::Handle(type.UnwrapFutureOr());
-  if (!unwrapped_type.IsTypeParameter() || unwrapped_type.IsNullable()) {
-    // Only nullable type parameter remains nullable after instantiation.
-    // See NullIsInstanceOf().
-    __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
-    __ b((unwrapped_type.IsNullable() ||
-          (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType()))
-             ? &is_instance
-             : &is_not_instance,
-         EQ);
-  }
-
-  // Generate inline instanceof test.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  test_cache =
-      GenerateInlineInstanceof(token_pos, type, &is_instance, &is_not_instance);
-
-  // test_cache is null if there is no fall-through.
-  compiler::Label done;
-  if (!test_cache.IsNull()) {
-    // Generate runtime call.
-    static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
-                      TypeTestABI::kInstantiatorTypeArgumentsReg,
-                  "Should be ordered to load arguments with one instruction");
-    __ ldm(IA, SP,
-           (1 << TypeTestABI::kFunctionTypeArgumentsReg) |
-               (1 << TypeTestABI::kInstantiatorTypeArgumentsReg));
-    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
-    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
-    GenerateStubCall(token_pos, StubCode::InstanceOf(),
-                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
-    __ b(&done);
-  }
-  __ Bind(&is_not_instance);
-  __ LoadObject(R0, Bool::Get(false));
-  __ b(&done);
-
-  __ Bind(&is_instance);
-  __ LoadObject(R0, Bool::Get(true));
-  __ Bind(&done);
-  // Remove instantiator type arguments and function type arguments.
-  __ Drop(2);
-}
-
 void FlowGraphCompiler::GenerateIndirectTTSCall(Register reg_to_call,
                                                 intptr_t sub_type_cache_index) {
   __ LoadField(
@@ -727,15 +269,15 @@
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     kPoolReg = PP;
   } else {
-    __ LoadFieldFromOffset(kWord, kPoolReg, CODE_REG,
+    __ LoadFieldFromOffset(kPoolReg, CODE_REG,
                            compiler::target::Code::object_pool_offset());
   }
   __ LoadImmediate(R4, type_arguments_field_offset);
   __ LoadFieldFromOffset(
-      kWord, R1, kPoolReg,
+      R1, kPoolReg,
       compiler::target::ObjectPool::element_offset(function_index));
   __ LoadFieldFromOffset(
-      kWord, CODE_REG, kPoolReg,
+      CODE_REG, kPoolReg,
       compiler::target::ObjectPool::element_offset(stub_index));
   __ Branch(compiler::FieldAddress(
       CODE_REG,
@@ -800,8 +342,7 @@
       const intptr_t slot_index =
           compiler::target::frame_layout.FrameSlotForVariableIndex(-i);
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : R0;
-      __ StoreToOffset(kWord, value_reg, FP,
-                       slot_index * compiler::target::kWordSize);
+      __ StoreToOffset(value_reg, FP, slot_index * compiler::target::kWordSize);
     }
   }
 
@@ -935,7 +476,7 @@
   bool old_use_far_branches = assembler_->use_far_branches();
   assembler_->set_use_far_branches(true);
 #endif  // DEBUG
-  __ LoadFieldFromOffset(kWord, R1, R0,
+  __ LoadFieldFromOffset(R1, R0,
                          compiler::target::Array::element_offset(edge_id));
   __ add(R1, R1, compiler::Operand(Smi::RawValue(1)));
   __ StoreIntoObjectNoBarrierOffset(
@@ -961,8 +502,7 @@
   // Pass the function explicitly, it is used in IC stub.
 
   __ LoadObject(R8, parsed_function().function());
-  __ LoadFromOffset(kWord, R0, SP,
-                    (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
+  __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
   __ LoadUniqueObject(R9, ic_data);
   GenerateDartCall(deopt_id, token_pos, stub, PcDescriptorsLayout::kIcCall,
                    locs, entry_kind);
@@ -979,8 +519,7 @@
   ASSERT(entry_kind == Code::EntryKind::kNormal ||
          entry_kind == Code::EntryKind::kUnchecked);
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
-  __ LoadFromOffset(kWord, R0, SP,
-                    (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
+  __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
   __ LoadUniqueObject(R9, ic_data);
   __ LoadUniqueObject(CODE_REG, stub);
   const intptr_t entry_point_offset =
@@ -1010,7 +549,7 @@
 
   __ Comment("MegamorphicCall");
   // Load receiver into R0.
-  __ LoadFromOffset(kWord, R0, SP,
+  __ LoadFromOffset(R0, SP,
                     (args_desc.Count() - 1) * compiler::target::kWordSize);
   // Use same code pattern as instance call so it can be parsed by code patcher.
   if (FLAG_precompiled_mode) {
@@ -1083,7 +622,7 @@
 
   __ Comment("InstanceCallAOT (%s)", switchable_call_mode);
   __ LoadFromOffset(
-      kWord, R0, SP,
+      R0, SP,
       (ic_data.SizeWithoutTypeArgs() - 1) * compiler::target::kWordSize);
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     // The AOT runtime will replace the slot in the object pool with the
@@ -1271,8 +810,7 @@
   __ Comment("EmitTestAndCall");
   // Load receiver into R0.
   __ LoadFromOffset(
-      kWord, R0, SP,
-      (count_without_type_args - 1) * compiler::target::kWordSize);
+      R0, SP, (count_without_type_args - 1) * compiler::target::kWordSize);
   __ LoadObject(R4, arguments_descriptor);
 }
 
@@ -1325,14 +863,12 @@
     } else {
       ASSERT(destination.IsStackSlot());
       const intptr_t dest_offset = destination.ToStackSlotOffset();
-      __ StoreToOffset(kWord, source.reg(), destination.base_reg(),
-                       dest_offset);
+      __ StoreToOffset(source.reg(), destination.base_reg(), dest_offset);
     }
   } else if (source.IsStackSlot()) {
     if (destination.IsRegister()) {
       const intptr_t source_offset = source.ToStackSlotOffset();
-      __ LoadFromOffset(kWord, destination.reg(), source.base_reg(),
-                        source_offset);
+      __ LoadFromOffset(destination.reg(), source.base_reg(), source_offset);
     } else {
       ASSERT(destination.IsStackSlot());
       const intptr_t source_offset = source.ToStackSlotOffset();
@@ -1346,8 +882,8 @@
       // temporary as we know we're in a ParallelMove.
       const Register temp_reg = LR;
 
-      __ LoadFromOffset(kWord, temp_reg, source.base_reg(), source_offset);
-      __ StoreToOffset(kWord, temp_reg, destination.base_reg(), dest_offset);
+      __ LoadFromOffset(temp_reg, source.base_reg(), source_offset);
+      __ StoreToOffset(temp_reg, destination.base_reg(), dest_offset);
     }
   } else if (source.IsFpuRegister()) {
     if (destination.IsFpuRegister()) {
@@ -1423,14 +959,14 @@
   }
 }
 
-static OperandSize BytesToOperandSize(intptr_t bytes) {
+static compiler::OperandSize BytesToOperandSize(intptr_t bytes) {
   switch (bytes) {
     case 4:
-      return OperandSize::kWord;
+      return compiler::OperandSize::kFourBytes;
     case 2:
-      return OperandSize::kHalfword;
+      return compiler::OperandSize::kTwoBytes;
     case 1:
-      return OperandSize::kByte;
+      return compiler::OperandSize::kByte;
     default:
       UNIMPLEMENTED();
   }
@@ -1489,9 +1025,9 @@
       const auto& dst = destination.AsStack();
       ASSERT(!sign_or_zero_extend);
       ASSERT(dst_size <= 4);
-      const OperandSize op_size = BytesToOperandSize(dst_size);
-      __ StoreToOffset(op_size, src.reg_at(0), dst.base_register(),
-                       dst.offset_in_bytes());
+      auto const op_size = BytesToOperandSize(dst_size);
+      __ StoreToOffset(src.reg_at(0), dst.base_register(),
+                       dst.offset_in_bytes(), op_size);
     }
 
   } else if (source.IsFpuRegisters()) {
@@ -1549,9 +1085,9 @@
       const auto dst_reg = dst.reg_at(0);
       ASSERT(!sign_or_zero_extend);
       ASSERT(dst_size <= 4);
-      const OperandSize op_size = BytesToOperandSize(dst_size);
-      __ LoadFromOffset(op_size, dst_reg, src.base_register(),
-                        src.offset_in_bytes());
+      auto const op_size = BytesToOperandSize(dst_size);
+      __ LoadFromOffset(dst_reg, src.base_register(), src.offset_in_bytes(),
+                        op_size);
 
     } else if (destination.IsFpuRegisters()) {
       ASSERT(src_payload_type.Equals(dst_payload_type));
@@ -1729,8 +1265,8 @@
                                     intptr_t stack_offset) {
   ScratchRegisterScope tmp(this, reg);
   __ mov(tmp.reg(), compiler::Operand(reg));
-  __ LoadFromOffset(kWord, reg, base_reg, stack_offset);
-  __ StoreToOffset(kWord, tmp.reg(), base_reg, stack_offset);
+  __ LoadFromOffset(reg, base_reg, stack_offset);
+  __ StoreToOffset(tmp.reg(), base_reg, stack_offset);
 }
 
 void ParallelMoveResolver::Exchange(Register base_reg1,
@@ -1739,10 +1275,10 @@
                                     intptr_t stack_offset2) {
   ScratchRegisterScope tmp1(this, kNoRegister);
   ScratchRegisterScope tmp2(this, tmp1.reg());
-  __ LoadFromOffset(kWord, tmp1.reg(), base_reg1, stack_offset1);
-  __ LoadFromOffset(kWord, tmp2.reg(), base_reg2, stack_offset2);
-  __ StoreToOffset(kWord, tmp1.reg(), base_reg2, stack_offset2);
-  __ StoreToOffset(kWord, tmp2.reg(), base_reg1, stack_offset1);
+  __ LoadFromOffset(tmp1.reg(), base_reg1, stack_offset1);
+  __ LoadFromOffset(tmp2.reg(), base_reg2, stack_offset2);
+  __ StoreToOffset(tmp1.reg(), base_reg2, stack_offset2);
+  __ StoreToOffset(tmp2.reg(), base_reg1, stack_offset1);
 }
 
 void ParallelMoveResolver::SpillScratch(Register reg) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 14cb38c..d841daf 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -214,440 +214,6 @@
   __ Bind(&fall_through);
 }
 
-// R0: instance (must be preserved).
-// R2: instantiator type arguments (if used).
-// R1: function type arguments (if used).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
-    TypeTestStubKind test_kind,
-    Register instance_reg,
-    Register instantiator_type_arguments_reg,
-    Register function_type_arguments_reg,
-    Register temp_reg,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  ASSERT(instance_reg == R0);
-  ASSERT(temp_reg == kNoRegister);  // Unused on ARM64.
-  const SubtypeTestCache& type_test_cache =
-      SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
-  __ LoadUniqueObject(R3, type_test_cache);
-  if (test_kind == kTestTypeOneArg) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ BranchLink(StubCode::Subtype1TestCache());
-  } else if (test_kind == kTestTypeTwoArgs) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ BranchLink(StubCode::Subtype2TestCache());
-  } else if (test_kind == kTestTypeFourArgs) {
-    ASSERT(instantiator_type_arguments_reg ==
-           TypeTestABI::kInstantiatorTypeArgumentsReg);
-    ASSERT(function_type_arguments_reg ==
-           TypeTestABI::kFunctionTypeArgumentsReg);
-    __ BranchLink(StubCode::Subtype4TestCache());
-  } else if (test_kind == kTestTypeSixArgs) {
-    ASSERT(instantiator_type_arguments_reg ==
-           TypeTestABI::kInstantiatorTypeArgumentsReg);
-    ASSERT(function_type_arguments_reg ==
-           TypeTestABI::kFunctionTypeArgumentsReg);
-    __ BranchLink(StubCode::Subtype6TestCache());
-  } else {
-    UNREACHABLE();
-  }
-  // Result is in R1: null -> not found, otherwise Bool::True or Bool::False.
-  GenerateBoolToJump(R1, is_instance_lbl, is_not_instance_lbl);
-  return type_test_cache.raw();
-}
-
-// Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
-// type test is conclusive, otherwise fallthrough if a type test could not
-// be completed.
-// R0: instance being type checked (preserved).
-// Clobbers R1, R2.
-SubtypeTestCachePtr
-FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeWithArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() > 0);
-  const Type& smi_type = Type::Handle(zone(), Type::SmiType());
-  const bool smi_is_ok = smi_type.IsSubtypeOf(type, Heap::kOld);
-  // Fast case for type = FutureOr<int/num/top-type>.
-  __ BranchIfSmi(TypeTestABI::kInstanceReg,
-                 smi_is_ok ? is_instance_lbl : is_not_instance_lbl);
-
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-                           type_arguments.IsRaw(from_index, num_type_params);
-  if (is_raw_type) {
-    const Register kClassIdReg = R2;
-    // dynamic type argument, check only classes.
-    __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-    __ CompareImmediate(kClassIdReg, type_class.id());
-    __ b(is_instance_lbl, EQ);
-    // List is a very common case.
-    if (IsListClass(type_class)) {
-      GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
-    }
-    return GenerateSubtype1TestCacheLookup(
-        token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-  }
-  // If one type argument only, check if type argument is a top type.
-  if (type_arguments.Length() == 1) {
-    const AbstractType& tp_argument =
-        AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopTypeForSubtyping()) {
-      // Instance class test only necessary.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    }
-  }
-  // Regular subtype test cache involving instance's type arguments.
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = kNoRegister;
-  // R0: instance (must be preserved).
-  return GenerateCallSubtypeTestStub(
-      kTestTypeTwoArgs, TypeTestABI::kInstanceReg,
-      kInstantiatorTypeArgumentsReg, kFunctionTypeArgumentsReg, kTempReg,
-      is_instance_lbl, is_not_instance_lbl);
-}
-
-void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
-                                      const GrowableArray<intptr_t>& class_ids,
-                                      compiler::Label* is_equal_lbl,
-                                      compiler::Label* is_not_equal_lbl) {
-  for (intptr_t i = 0; i < class_ids.length(); i++) {
-    __ CompareImmediate(class_id_reg, class_ids[i]);
-    __ b(is_equal_lbl, EQ);
-  }
-  __ b(is_not_equal_lbl);
-}
-
-// Testing against an instantiated type with no arguments, without
-// SubtypeTestCache.
-// R0: instance being type checked (preserved).
-// Clobbers R2, R3.
-// Returns true if there is a fallthrough.
-bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeNoArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::Handle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() == 0);
-
-  // If instance is Smi, check directly.
-  const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
-                         Nullability::kNonNullable, type, Heap::kOld)) {
-    // Fast case for type = int/num/top-type.
-    __ BranchIfSmi(TypeTestABI::kInstanceReg, is_instance_lbl);
-  } else {
-    __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
-  }
-  const Register kClassIdReg = R2;
-  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-  // Bool interface can be implemented only by core class Bool.
-  if (type.IsBoolType()) {
-    __ CompareImmediate(kClassIdReg, kBoolCid);
-    __ b(is_instance_lbl, EQ);
-    __ b(is_not_instance_lbl);
-    return false;
-  }
-  // Custom checking for numbers (Smi, Mint and Double).
-  // Note that instance is not Smi (checked above).
-  if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType()) {
-    GenerateNumberTypeCheck(kClassIdReg, type, is_instance_lbl,
-                            is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsStringType()) {
-    GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsDartFunctionType()) {
-    // Check if instance is a closure.
-    __ CompareImmediate(kClassIdReg, kClosureCid);
-    __ b(is_instance_lbl, EQ);
-    return true;  // Fall through
-  }
-
-  // Fast case for cid-range based checks.
-  // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
-    return false;
-  }
-
-  // Otherwise fallthrough, result non-conclusive.
-  return true;
-}
-
-// Uses SubtypeTestCache to store instance class and result.
-// R0: instance to test.
-// Clobbers R1-R5.
-// Immediate class test already done.
-// TODO(srdjan): Implement a quicker subtype check, as type test
-// arrays can grow too high, but they may be useful when optimizing
-// code (type-feedback).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    TokenPosition token_pos,
-    const Class& type_class,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("Subtype1TestCacheLookup");
-#if defined(DEBUG)
-  compiler::Label ok;
-  __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &ok);
-  __ Breakpoint();
-  __ Bind(&ok);
-#endif
-  __ LoadClassId(TMP, TypeTestABI::kInstanceReg);
-  __ LoadClassById(R1, TMP);
-  // R1: instance class.
-  // Check immediate superclass equality. If type_class is Object, then testing
-  // supertype may yield a wrong result for Null in NNBD strong mode (because
-  // Null also extends Object).
-  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
-    __ LoadFieldFromOffset(R2, R1, Class::super_type_offset());
-    __ LoadFieldFromOffset(R2, R2, Type::type_class_id_offset());
-    __ CompareImmediate(R2, Smi::RawValue(type_class.id()));
-    __ b(is_instance_lbl, EQ);
-  }
-
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = kNoRegister;
-  return GenerateCallSubtypeTestStub(kTestTypeOneArg, TypeTestABI::kInstanceReg,
-                                     kInstantiatorTypeArgumentsReg,
-                                     kFunctionTypeArgumentsReg, kTempReg,
-                                     is_instance_lbl, is_not_instance_lbl);
-}
-
-// Generates inlined check if 'type' is a type parameter or type itself
-// R0: instance (preserved).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("UninstantiatedTypeTest");
-  const Register kTempReg = kNoRegister;
-  ASSERT(!type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  // Skip check if destination is a dynamic type.
-  if (type.IsTypeParameter()) {
-    const TypeParameter& type_param = TypeParameter::Cast(type);
-
-    // Get instantiator type args (high) and function type args (low).
-    __ ldp(TypeTestABI::kFunctionTypeArgumentsReg,
-           TypeTestABI::kInstantiatorTypeArgumentsReg,
-           compiler::Address(SP, 0 * kWordSize, compiler::Address::PairOffset));
-    const Register kTypeArgumentsReg =
-        type_param.IsClassTypeParameter()
-            ? TypeTestABI::kInstantiatorTypeArgumentsReg
-            : TypeTestABI::kFunctionTypeArgumentsReg;
-    // Check if type arguments are null, i.e. equivalent to vector of dynamic.
-    __ CompareObject(kTypeArgumentsReg, Object::null_object());
-    __ b(is_instance_lbl, EQ);
-    __ LoadFieldFromOffset(R3, kTypeArgumentsReg,
-                           TypeArguments::type_at_offset(type_param.index()));
-    // R3: concrete type of type.
-    // Check if type argument is dynamic, Object?, or void.
-    __ CompareObject(R3, Object::dynamic_type());
-    __ b(is_instance_lbl, EQ);
-    __ CompareObject(
-        R3, Type::ZoneHandle(
-                zone(), isolate()->object_store()->nullable_object_type()));
-    __ b(is_instance_lbl, EQ);
-    __ CompareObject(R3, Object::void_type());
-    __ b(is_instance_lbl, EQ);
-
-    // For Smi check quickly against int and num interfaces.
-    compiler::Label not_smi;
-    __ BranchIfNotSmi(R0, &not_smi);
-    __ CompareObject(R3, Type::ZoneHandle(zone(), Type::IntType()));
-    __ b(is_instance_lbl, EQ);
-    __ CompareObject(R3, Type::ZoneHandle(zone(), Type::Number()));
-    __ b(is_instance_lbl, EQ);
-    // Smi can be handled by type test cache.
-    __ Bind(&not_smi);
-
-    const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
-    const SubtypeTestCache& type_test_cache = SubtypeTestCache::ZoneHandle(
-        zone(), GenerateCallSubtypeTestStub(
-                    test_kind, TypeTestABI::kInstanceReg,
-                    TypeTestABI::kInstantiatorTypeArgumentsReg,
-                    TypeTestABI::kFunctionTypeArgumentsReg, kTempReg,
-                    is_instance_lbl, is_not_instance_lbl));
-    return type_test_cache.raw();
-  }
-  if (type.IsType()) {
-    // Smi is FutureOr<T>, when T is a top type or int or num.
-    if (!type.IsFutureOrType()) {
-      __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
-    }
-    __ ldp(TypeTestABI::kFunctionTypeArgumentsReg,
-           TypeTestABI::kInstantiatorTypeArgumentsReg,
-           compiler::Address(SP, 0 * kWordSize, compiler::Address::PairOffset));
-    // Uninstantiated type class is known at compile time, but the type
-    // arguments are determined at runtime by the instantiator.
-    return GenerateCallSubtypeTestStub(
-        kTestTypeFourArgs, TypeTestABI::kInstanceReg,
-        TypeTestABI::kInstantiatorTypeArgumentsReg,
-        TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-        is_not_instance_lbl);
-  }
-  return SubtypeTestCache::null();
-}
-
-// Generates function type check.
-//
-// See [GenerateUninstantiatedTypeTest] for calling convention.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
-  __ ldp(TypeTestABI::kFunctionTypeArgumentsReg,
-         TypeTestABI::kInstantiatorTypeArgumentsReg,
-         compiler::Address(SP, 0 * kWordSize, compiler::Address::PairOffset));
-  // Uninstantiated type class is known at compile time, but the type
-  // arguments are determined at runtime by the instantiator(s).
-  const Register kTempReg = kNoRegister;
-  return GenerateCallSubtypeTestStub(
-      kTestTypeSixArgs, TypeTestABI::kInstanceReg,
-      TypeTestABI::kInstantiatorTypeArgumentsReg,
-      TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-      is_not_instance_lbl);
-}
-
-// Inputs:
-// - R0: instance being type checked (preserved).
-// - R2: optional instantiator type arguments (preserved).
-// - R1: optional function type arguments (preserved).
-// Clobbers R3, R4, R8, R9.
-// Returns:
-// - preserved instance in R0, optional instantiator type arguments in R2, and
-//   optional function type arguments in R1.
-// Note that this inlined code must be followed by the runtime_call code, as it
-// may fall through to it. Otherwise, this inline code will jump to the label
-// is_instance or to the label is_not_instance.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InlineInstanceof");
-
-  if (type.IsFunctionType()) {
-    return GenerateFunctionTypeTest(token_pos, type, is_instance_lbl,
-                                    is_not_instance_lbl);
-  }
-
-  if (type.IsInstantiated()) {
-    const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type (not a
-    // function type) of a non-parameterized class or with a raw dst type of
-    // a parameterized class.
-    if (type_class.NumTypeArguments() > 0) {
-      return GenerateInstantiatedTypeWithArgumentsTest(
-          token_pos, type, is_instance_lbl, is_not_instance_lbl);
-      // Fall through to runtime call.
-    }
-    const bool has_fall_through = GenerateInstantiatedTypeNoArgumentsTest(
-        token_pos, type, is_instance_lbl, is_not_instance_lbl);
-    if (has_fall_through) {
-      // If test non-conclusive so far, try the inlined type-test cache.
-      // 'type' is known at compile time.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    } else {
-      return SubtypeTestCache::null();
-    }
-  }
-  return GenerateUninstantiatedTypeTest(token_pos, type, is_instance_lbl,
-                                        is_not_instance_lbl);
-}
-
-// If instanceof type test cannot be performed successfully at compile time and
-// therefore eliminated, optimize it by adding inlined tests for:
-// - Null -> see comment below.
-// - Smi -> compile time subtype check (only if dst class is not parameterized).
-// - Class equality (only if class is not parameterized).
-// Inputs:
-// - R0: object.
-// - R2: instantiator type arguments or raw_null.
-// - R1: function type arguments or raw_null.
-// Returns:
-// - true or false in R0.
-void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
-                                           intptr_t deopt_id,
-                                           const AbstractType& type,
-                                           LocationSummary* locs) {
-  ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
-  __ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
-              TypeTestABI::kInstantiatorTypeArgumentsReg);
-
-  compiler::Label is_instance, is_not_instance;
-  // 'null' is an instance of Null, Object*, Never*, void, and dynamic.
-  // In addition, 'null' is an instance of any nullable type.
-  // It is also an instance of FutureOr<T> if it is an instance of T.
-  const AbstractType& unwrapped_type =
-      AbstractType::Handle(type.UnwrapFutureOr());
-  if (!unwrapped_type.IsTypeParameter() || unwrapped_type.IsNullable()) {
-    // Only nullable type parameter remains nullable after instantiation.
-    // See NullIsInstanceOf().
-    __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
-    __ b((unwrapped_type.IsNullable() ||
-          (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType()))
-             ? &is_instance
-             : &is_not_instance,
-         EQ);
-  }
-
-  // Generate inline instanceof test.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  test_cache =
-      GenerateInlineInstanceof(token_pos, type, &is_instance, &is_not_instance);
-
-  // test_cache is null if there is no fall-through.
-  compiler::Label done;
-  if (!test_cache.IsNull()) {
-    // Generate runtime call.
-    __ ldp(TypeTestABI::kFunctionTypeArgumentsReg,
-           TypeTestABI::kInstantiatorTypeArgumentsReg,
-           compiler::Address(SP, 0 * kWordSize, compiler::Address::PairOffset));
-    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
-    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
-    GenerateStubCall(token_pos, StubCode::InstanceOf(),
-                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
-    __ b(&done);
-  }
-  __ Bind(&is_not_instance);
-  __ LoadObject(R0, Bool::Get(false));
-  __ b(&done);
-
-  __ Bind(&is_instance);
-  __ LoadObject(R0, Bool::Get(true));
-  __ Bind(&done);
-  // Remove instantiator type arguments and function type arguments.
-  __ Drop(2);
-}
-
 void FlowGraphCompiler::GenerateIndirectTTSCall(Register reg_to_call,
                                                 intptr_t sub_type_cache_index) {
   __ LoadField(
@@ -718,13 +284,13 @@
            compiler::FieldAddress(CODE_REG, Code::owner_offset()));
 
     __ LoadFieldFromOffset(R7, function_reg, Function::usage_counter_offset(),
-                           kWord);
+                           compiler::kFourBytes);
     // Reoptimization of an optimized function is triggered by counting in
     // IC stubs, but not at the entry of the function.
     if (!is_optimizing()) {
       __ add(R7, R7, compiler::Operand(1));
       __ StoreFieldToOffset(R7, function_reg, Function::usage_counter_offset(),
-                            kWord);
+                            compiler::kFourBytes);
     }
     __ CompareImmediate(R7, GetOptimizationThreshold());
     ASSERT(function_reg == R6);
@@ -1370,16 +936,16 @@
   }
 }
 
-static OperandSize BytesToOperandSize(intptr_t bytes) {
+static compiler::OperandSize BytesToOperandSize(intptr_t bytes) {
   switch (bytes) {
     case 8:
-      return OperandSize::kDoubleWord;
+      return compiler::OperandSize::kEightBytes;
     case 4:
-      return OperandSize::kWord;
+      return compiler::OperandSize::kFourBytes;
     case 2:
-      return OperandSize::kHalfword;
+      return compiler::OperandSize::kTwoBytes;
     case 1:
-      return OperandSize::kByte;
+      return compiler::OperandSize::kByte;
     default:
       UNIMPLEMENTED();
   }
@@ -1447,7 +1013,7 @@
       ASSERT(destination.IsStack());
       const auto& dst = destination.AsStack();
       ASSERT(!sign_or_zero_extend);
-      const OperandSize op_size = BytesToOperandSize(dst_size);
+      auto const op_size = BytesToOperandSize(dst_size);
       __ StoreToOffset(src.reg_at(0), dst.base_register(),
                        dst.offset_in_bytes(), op_size);
     }
@@ -1491,7 +1057,7 @@
       ASSERT(dst.num_regs() == 1);
       const auto dst_reg = dst.reg_at(0);
       ASSERT(!sign_or_zero_extend);
-      const OperandSize op_size = BytesToOperandSize(dst_size);
+      auto const op_size = BytesToOperandSize(dst_size);
       __ LoadFromOffset(dst_reg, src.base_register(), src.offset_in_bytes(),
                         op_size);
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 83f47d6..e0cb95a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -195,392 +195,63 @@
   __ Bind(&fall_through);
 }
 
-// Clobbers ECX.
+// Input registers (from TypeTestABI):
+// - kInstanceReg: instance.
+// - kDstTypeReg: destination type (for test_kind != kTestTypeOneArg).
+// - kInstantiatorTypeArgumentsReg: instantiator type arguments
+//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+// - kFunctionTypeArgumentsReg: function type arguments
+//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+//
+// Only preserves kInstanceReg from TypeTestABI, all other TypeTestABI
+// registers may be used and thus must be saved by the caller.
 SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
     TypeTestStubKind test_kind,
-    Register instance_reg,
-    Register instantiator_type_arguments_reg,
-    Register function_type_arguments_reg,
-    Register temp_reg,
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
   const SubtypeTestCache& type_test_cache =
       SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
-  const compiler::Immediate& raw_null =
-      compiler::Immediate(static_cast<intptr_t>(Object::null()));
-  __ LoadObject(temp_reg, type_test_cache);
-  __ pushl(temp_reg);      // Subtype test cache.
-  __ pushl(instance_reg);  // Instance.
+  __ LoadObject(TypeTestABI::kSubtypeTestCacheReg, type_test_cache);
+  __ pushl(TypeTestABI::kSubtypeTestCacheReg);
+  __ pushl(TypeTestABI::kInstanceReg);
   if (test_kind == kTestTypeOneArg) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ pushl(raw_null);
-    __ pushl(raw_null);
+    __ PushObject(Object::null_object());
+    __ PushObject(Object::null_object());
+    __ PushObject(Object::null_object());
     __ Call(StubCode::Subtype1TestCache());
-  } else if (test_kind == kTestTypeTwoArgs) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ pushl(raw_null);
-    __ pushl(raw_null);
-    __ Call(StubCode::Subtype2TestCache());
-  } else if (test_kind == kTestTypeFourArgs) {
-    __ pushl(instantiator_type_arguments_reg);
-    __ pushl(function_type_arguments_reg);
-    __ Call(StubCode::Subtype4TestCache());
-  } else if (test_kind == kTestTypeSixArgs) {
-    __ pushl(instantiator_type_arguments_reg);
-    __ pushl(function_type_arguments_reg);
-    __ Call(StubCode::Subtype6TestCache());
+  } else if (test_kind == kTestTypeThreeArgs) {
+    __ pushl(TypeTestABI::kDstTypeReg);
+    __ PushObject(Object::null_object());
+    __ PushObject(Object::null_object());
+    __ Call(StubCode::Subtype3TestCache());
+  } else if (test_kind == kTestTypeFiveArgs) {
+    __ pushl(TypeTestABI::kDstTypeReg);
+    __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+    __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
+    __ Call(StubCode::Subtype5TestCache());
+  } else if (test_kind == kTestTypeSevenArgs) {
+    __ pushl(TypeTestABI::kDstTypeReg);
+    __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+    __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
+    __ Call(StubCode::Subtype7TestCache());
   } else {
     UNREACHABLE();
   }
-  // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
-  ASSERT(instance_reg != ECX);
-  ASSERT(temp_reg != ECX);
-  __ Drop(2);
-  __ popl(instance_reg);  // Restore receiver.
-  __ popl(temp_reg);      // Discard.
-  GenerateBoolToJump(ECX, is_instance_lbl, is_not_instance_lbl);
+  // Restore all but kSubtypeTestCacheReg (since it is the same as
+  // kSubtypeTestCacheResultReg).
+  static_assert(TypeTestABI::kSubtypeTestCacheReg ==
+                    TypeTestABI::kSubtypeTestCacheResultReg,
+                "Code assumes cache and result register are the same");
+  __ popl(TypeTestABI::kFunctionTypeArgumentsReg);
+  __ popl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ popl(TypeTestABI::kDstTypeReg);
+  __ popl(TypeTestABI::kInstanceReg);  // Restore receiver.
+  __ Drop(1);
+  GenerateBoolToJump(TypeTestABI::kSubtypeTestCacheResultReg, is_instance_lbl,
+                     is_not_instance_lbl);
   return type_test_cache.raw();
 }
 
-// Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
-// type test is conclusive, otherwise fallthrough if a type test could not
-// be completed.
-// EAX: instance (must survive).
-// Clobbers ECX, EDI.
-SubtypeTestCachePtr
-FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeWithArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() > 0);
-  const Type& smi_type = Type::Handle(zone(), Type::SmiType());
-  const bool smi_is_ok = smi_type.IsSubtypeOf(type, Heap::kOld);
-  __ testl(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
-  if (smi_is_ok) {
-    // Fast case for type = FutureOr<int/num/top-type>.
-    __ j(ZERO, is_instance_lbl);
-  } else {
-    __ j(ZERO, is_not_instance_lbl);
-  }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-                           type_arguments.IsRaw(from_index, num_type_params);
-  if (is_raw_type) {
-    const Register kClassIdReg = ECX;
-    // dynamic type argument, check only classes.
-    __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-    __ cmpl(kClassIdReg, compiler::Immediate(type_class.id()));
-    __ j(EQUAL, is_instance_lbl);
-    // List is a very common case.
-    if (IsListClass(type_class)) {
-      GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
-    }
-    return GenerateSubtype1TestCacheLookup(
-        token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-  }
-  // If one type argument only, check if type argument is a top type.
-  if (type_arguments.Length() == 1) {
-    const AbstractType& tp_argument =
-        AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopTypeForSubtyping()) {
-      // Instance class test only necessary.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    }
-  }
-  // Regular subtype test cache involving instance's type arguments.
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = EDI;
-  return GenerateCallSubtypeTestStub(
-      kTestTypeTwoArgs, TypeTestABI::kInstanceReg,
-      kInstantiatorTypeArgumentsReg, kFunctionTypeArgumentsReg, kTempReg,
-      is_instance_lbl, is_not_instance_lbl);
-}
-
-void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
-                                      const GrowableArray<intptr_t>& class_ids,
-                                      compiler::Label* is_equal_lbl,
-                                      compiler::Label* is_not_equal_lbl) {
-  for (intptr_t i = 0; i < class_ids.length(); i++) {
-    __ cmpl(class_id_reg, compiler::Immediate(class_ids[i]));
-    __ j(EQUAL, is_equal_lbl);
-  }
-  __ jmp(is_not_equal_lbl);
-}
-
-// Testing against an instantiated type with no arguments, without
-// SubtypeTestCache.
-// EAX: instance to test against (preserved).
-// Clobbers ECX, EDI.
-// Returns true if there is a fallthrough.
-bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeNoArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::Handle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() == 0);
-
-  __ testl(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
-  // If instance is Smi, check directly.
-  const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
-                         Nullability::kNonNullable, type, Heap::kOld)) {
-    // Fast case for type = int/num/top-type.
-    __ j(ZERO, is_instance_lbl);
-  } else {
-    __ j(ZERO, is_not_instance_lbl);
-  }
-  const Register kClassIdReg = ECX;
-  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-  // Bool interface can be implemented only by core class Bool.
-  if (type.IsBoolType()) {
-    __ cmpl(kClassIdReg, compiler::Immediate(kBoolCid));
-    __ j(EQUAL, is_instance_lbl);
-    __ jmp(is_not_instance_lbl);
-    return false;
-  }
-  // Custom checking for numbers (Smi, Mint and Double).
-  // Note that instance is not Smi (checked above).
-  if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType()) {
-    GenerateNumberTypeCheck(kClassIdReg, type, is_instance_lbl,
-                            is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsStringType()) {
-    GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsDartFunctionType()) {
-    // Check if instance is a closure.
-    __ cmpl(kClassIdReg, compiler::Immediate(kClosureCid));
-    __ j(EQUAL, is_instance_lbl);
-    return true;  // Fall through
-  }
-
-  // Fast case for cid-range based checks.
-  // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
-    return false;
-  }
-
-  // Otherwise fallthrough, result non-conclusive.
-  return true;
-}
-
-// Uses SubtypeTestCache to store instance class and result.
-// EAX: instance to test.
-// Clobbers EDI, ECX.
-// Immediate class test already done.
-// TODO(srdjan): Implement a quicker subtype check, as type test
-// arrays can grow too high, but they may be useful when optimizing
-// code (type-feedback).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    TokenPosition token_pos,
-    const Class& type_class,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("Subtype1TestCacheLookup");
-#if defined(DEBUG)
-  compiler::Label ok;
-  __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &ok);
-  __ Breakpoint();
-  __ Bind(&ok);
-#endif
-  __ LoadClassId(EDI, TypeTestABI::kInstanceReg);
-  __ LoadClassById(ECX, EDI);
-  // ECX: instance class.
-  // Check immediate superclass equality. If type_class is Object, then testing
-  // supertype may yield a wrong result for Null in NNBD strong mode (because
-  // Null also extends Object).
-  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
-    __ movl(EDI, compiler::FieldAddress(ECX, Class::super_type_offset()));
-    __ movl(EDI, compiler::FieldAddress(EDI, Type::type_class_id_offset()));
-    __ cmpl(EDI, compiler::Immediate(Smi::RawValue(type_class.id())));
-    __ j(EQUAL, is_instance_lbl);
-  }
-
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = EDI;
-  return GenerateCallSubtypeTestStub(kTestTypeOneArg, TypeTestABI::kInstanceReg,
-                                     kInstantiatorTypeArgumentsReg,
-                                     kFunctionTypeArgumentsReg, kTempReg,
-                                     is_instance_lbl, is_not_instance_lbl);
-}
-
-// Generates inlined check if 'type' is a type parameter or type itself
-// EAX: instance (preserved).
-// Clobbers EDX, EDI, ECX.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("UninstantiatedTypeTest");
-  const Register kTempReg = EDI;
-  ASSERT(!type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  // Skip check if destination is a dynamic type.
-  const compiler::Immediate& raw_null =
-      compiler::Immediate(static_cast<intptr_t>(Object::null()));
-  if (type.IsTypeParameter()) {
-    const TypeParameter& type_param = TypeParameter::Cast(type);
-
-    __ movl(EDX, compiler::Address(
-                     ESP, 1 * kWordSize));  // Get instantiator type args.
-    __ movl(ECX,
-            compiler::Address(ESP, 0 * kWordSize));  // Get function type args.
-    // EDX: instantiator type arguments.
-    // ECX: function type arguments.
-    const Register kTypeArgumentsReg =
-        type_param.IsClassTypeParameter()
-            ? TypeTestABI::kInstantiatorTypeArgumentsReg
-            : TypeTestABI::kFunctionTypeArgumentsReg;
-    // Check if type arguments are null, i.e. equivalent to vector of dynamic.
-    __ cmpl(kTypeArgumentsReg, raw_null);
-    __ j(EQUAL, is_instance_lbl);
-    __ movl(EDI, compiler::FieldAddress(
-                     kTypeArgumentsReg,
-                     TypeArguments::type_at_offset(type_param.index())));
-    // EDI: concrete type of type.
-    // Check if type argument is dynamic, Object?, or void.
-    __ CompareObject(EDI, Object::dynamic_type());
-    __ j(EQUAL, is_instance_lbl);
-    __ CompareObject(
-        EDI, Type::ZoneHandle(
-                 zone(), isolate()->object_store()->nullable_object_type()));
-    __ j(EQUAL, is_instance_lbl);
-    __ CompareObject(EDI, Object::void_type());
-    __ j(EQUAL, is_instance_lbl);
-
-    // For Smi check quickly against int and num interfaces.
-    compiler::Label not_smi;
-    __ testl(EAX, compiler::Immediate(kSmiTagMask));  // Value is Smi?
-    __ j(NOT_ZERO, &not_smi, compiler::Assembler::kNearJump);
-    __ CompareObject(EDI, Type::ZoneHandle(zone(), Type::IntType()));
-    __ j(EQUAL, is_instance_lbl);
-    __ CompareObject(EDI, Type::ZoneHandle(zone(), Type::Number()));
-    __ j(EQUAL, is_instance_lbl);
-    // Smi can be handled by type test cache.
-    __ Bind(&not_smi);
-
-    const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
-    const SubtypeTestCache& type_test_cache = SubtypeTestCache::ZoneHandle(
-        zone(), GenerateCallSubtypeTestStub(
-                    test_kind, TypeTestABI::kInstanceReg,
-                    TypeTestABI::kInstantiatorTypeArgumentsReg,
-                    TypeTestABI::kFunctionTypeArgumentsReg, kTempReg,
-                    is_instance_lbl, is_not_instance_lbl));
-    return type_test_cache.raw();
-  }
-  if (type.IsType()) {
-    // Smi is FutureOr<T>, when T is a top type or int or num.
-    if (!type.IsFutureOrType()) {
-      __ testl(TypeTestABI::kInstanceReg,
-               compiler::Immediate(kSmiTagMask));  // Is instance Smi?
-      __ j(ZERO, is_not_instance_lbl);
-    }
-    __ movl(TypeTestABI::kInstantiatorTypeArgumentsReg,
-            compiler::Address(ESP, 1 * kWordSize));
-    __ movl(TypeTestABI::kFunctionTypeArgumentsReg,
-            compiler::Address(ESP, 0 * kWordSize));
-    // Uninstantiated type class is known at compile time, but the type
-    // arguments are determined at runtime by the instantiator(s).
-    return GenerateCallSubtypeTestStub(
-        kTestTypeFourArgs, TypeTestABI::kInstanceReg,
-        TypeTestABI::kInstantiatorTypeArgumentsReg,
-        TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-        is_not_instance_lbl);
-  }
-  return SubtypeTestCache::null();
-}
-
-// Generates function type check.
-//
-// See [GenerateUninstantiatedTypeTest] for calling convention.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("FunctionTypeTest");
-
-  __ testl(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
-  __ j(ZERO, is_not_instance_lbl);
-  // Uninstantiated type class is known at compile time, but the type
-  // arguments are determined at runtime by the instantiator(s).
-  const Register kTempReg = EDI;
-  return GenerateCallSubtypeTestStub(
-      kTestTypeSixArgs, TypeTestABI::kInstanceReg,
-      TypeTestABI::kInstantiatorTypeArgumentsReg,
-      TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-      is_not_instance_lbl);
-}
-
-// Inputs:
-// - EAX: instance to test against (preserved).
-// - EDX: optional instantiator type arguments (preserved).
-// - ECX: optional function type arguments (preserved).
-// Clobbers EDI.
-// Returns:
-// - preserved instance in EAX, optional instantiator type arguments in EDX, and
-//   optional function type arguments in RCX.
-// Note that this inlined code must be followed by the runtime_call code, as it
-// may fall through to it. Otherwise, this inline code will jump to the label
-// is_instance or to the label is_not_instance.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InlineInstanceof");
-
-  if (type.IsFunctionType()) {
-    return GenerateFunctionTypeTest(token_pos, type, is_instance_lbl,
-                                    is_not_instance_lbl);
-  }
-
-  if (type.IsInstantiated()) {
-    const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type (not a
-    // function type) of a non-parameterized class or with a raw dst type of
-    // a parameterized class.
-    if (type_class.NumTypeArguments() > 0) {
-      return GenerateInstantiatedTypeWithArgumentsTest(
-          token_pos, type, is_instance_lbl, is_not_instance_lbl);
-      // Fall through to runtime call.
-    }
-    const bool has_fall_through = GenerateInstantiatedTypeNoArgumentsTest(
-        token_pos, type, is_instance_lbl, is_not_instance_lbl);
-    if (has_fall_through) {
-      // If test non-conclusive so far, try the inlined type-test cache.
-      // 'type' is known at compile time.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    } else {
-      return SubtypeTestCache::null();
-    }
-  }
-  return GenerateUninstantiatedTypeTest(token_pos, type, is_instance_lbl,
-                                        is_not_instance_lbl);
-}
-
 // If instanceof type test cannot be performed successfully at compile time and
 // therefore eliminated, optimize it by adding inlined tests for:
 // - Null -> see comment below.
@@ -599,9 +270,6 @@
   ASSERT(type.IsFinalized());
   ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
 
-  __ pushl(EDX);  // Store instantiator type arguments.
-  __ pushl(ECX);  // Store function type arguments.
-
   const compiler::Immediate& raw_null =
       compiler::Immediate(static_cast<intptr_t>(Object::null()));
   compiler::Label is_instance, is_not_instance;
@@ -629,33 +297,28 @@
   compiler::Label done;
   if (!test_cache.IsNull()) {
     // Generate runtime call.
-    __ movl(EDX, compiler::Address(
-                     ESP, 1 * kWordSize));  // Get instantiator type args.
-    __ movl(ECX,
-            compiler::Address(ESP, 0 * kWordSize));  // Get function type args.
     __ PushObject(Object::null_object());  // Make room for the result.
-    __ pushl(EAX);                         // Push the instance.
+    __ pushl(TypeTestABI::kInstanceReg);   // Push the instance.
     __ PushObject(type);                   // Push the type.
     __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
     __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
-    __ LoadObject(EAX, test_cache);
-    __ pushl(EAX);
+    // Can reuse kInstanceReg as scratch here since it was pushed above.
+    __ LoadObject(TypeTestABI::kInstanceReg, test_cache);
+    __ pushl(TypeTestABI::kInstanceReg);
     GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
     __ Drop(5);
-    __ popl(EAX);
+    __ popl(TypeTestABI::kInstanceOfResultReg);
     __ jmp(&done, compiler::Assembler::kNearJump);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(EAX, Bool::Get(false));
+  __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(false));
   __ jmp(&done, compiler::Assembler::kNearJump);
 
   __ Bind(&is_instance);
-  __ LoadObject(EAX, Bool::Get(true));
+  __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(true));
   __ Bind(&done);
-  __ popl(ECX);  // Remove pushed function type arguments.
-  __ popl(EDX);  // Remove pushed instantiator type arguments.
 }
 
 // Optimize assignable type check by adding inlined tests for:
@@ -679,52 +342,72 @@
   ASSERT(!token_pos.IsClassifying());
   ASSERT(CheckAssertAssignableTypeTestingABILocations(*locs));
 
-  if (!locs->in(1).IsConstant()) {
-    // TODO(dartbug.com/40813): Handle setting up the non-constant case.
-    UNREACHABLE();
+  const auto& dst_type =
+      locs->in(AssertAssignableInstr::kDstTypePos).IsConstant()
+          ? AbstractType::Cast(
+                locs->in(AssertAssignableInstr::kDstTypePos).constant())
+          : Object::null_abstract_type();
+
+  if (!dst_type.IsNull()) {
+    ASSERT(dst_type.IsFinalized());
+    if (dst_type.IsTopTypeForSubtyping()) return;  // No code needed.
   }
 
-  ASSERT(locs->in(1).constant().IsAbstractType());
-  const auto& dst_type = AbstractType::Cast(locs->in(1).constant());
-  ASSERT(dst_type.IsFinalized());
-
-  if (dst_type.IsTopTypeForSubtyping()) return;  // No code needed.
-
-  __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
-
   compiler::Label is_assignable, runtime_call;
-  if (Instance::NullIsAssignableTo(dst_type)) {
-    const compiler::Immediate& raw_null =
-        compiler::Immediate(static_cast<intptr_t>(Object::null()));
-    __ cmpl(TypeTestABI::kInstanceReg, raw_null);
-    __ j(EQUAL, &is_assignable);
+  auto& test_cache = SubtypeTestCache::ZoneHandle(zone());
+  if (dst_type.IsNull()) {
+    __ Comment("AssertAssignable for runtime type");
+    // kDstTypeReg should already contain the destination type.
+    const bool null_safety =
+        Isolate::Current()->use_strict_null_safety_checks();
+    GenerateStubCall(token_pos,
+                     null_safety ? StubCode::TypeIsTopTypeForSubtypingNullSafe()
+                                 : StubCode::TypeIsTopTypeForSubtyping(),
+                     PcDescriptorsLayout::kOther, locs, deopt_id);
+    // TypeTestABI::kSubtypeTestCacheReg is 0 if the type is a top type.
+    __ BranchIfZero(TypeTestABI::kSubtypeTestCacheReg, &is_assignable,
+                    compiler::Assembler::kNearJump);
+
+    GenerateStubCall(token_pos,
+                     null_safety ? StubCode::NullIsAssignableToTypeNullSafe()
+                                 : StubCode::NullIsAssignableToType(),
+                     PcDescriptorsLayout::kOther, locs, deopt_id);
+    // TypeTestABI::kSubtypeTestCacheReg is 0 if the object is null and is
+    // assignable.
+    __ BranchIfZero(TypeTestABI::kSubtypeTestCacheReg, &is_assignable,
+                    compiler::Assembler::kNearJump);
+
+    // Use the full-arg version of the cache.
+    test_cache = GenerateCallSubtypeTestStub(kTestTypeSevenArgs, &is_assignable,
+                                             &runtime_call);
+  } else {
+    __ Comment("AssertAssignable for compile-time type");
+
+    if (Instance::NullIsAssignableTo(dst_type)) {
+      __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
+      __ BranchIf(EQUAL, &is_assignable);
+    }
+
+    // Generate inline type check, linking to runtime call if not assignable.
+    test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+                                          &runtime_call);
   }
 
-  // Generate inline type check, linking to runtime call if not assignable.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
-                                        &runtime_call);
-
   __ Bind(&runtime_call);
-  __ movl(
-      TypeTestABI::kInstantiatorTypeArgumentsReg,
-      compiler::Address(ESP, 1 * kWordSize));  // Get instantiator type args.
-  __ movl(TypeTestABI::kFunctionTypeArgumentsReg,
-          compiler::Address(ESP, 0 * kWordSize));  // Get function type args.
   __ PushObject(Object::null_object());            // Make room for the result.
   __ pushl(TypeTestABI::kInstanceReg);             // Push the source object.
-  if (locs->in(1).IsConstant()) {
-    __ PushObject(locs->in(1).constant());  // Push the type of the destination.
+  // Push the type of the destination.
+  if (!dst_type.IsNull()) {
+    __ PushObject(dst_type);
   } else {
-    // TODO(dartbug.com/40813): Handle setting up the non-constant case.
-    UNREACHABLE();
+    __ pushl(TypeTestABI::kDstTypeReg);
   }
   __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
   __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
   __ PushObject(dst_name);  // Push the name of the destination.
-  __ LoadObject(EAX, test_cache);
-  __ pushl(EAX);
+  // Can reuse kInstanceReg as scratch here since it was pushed above.
+  __ LoadObject(TypeTestABI::kInstanceReg, test_cache);
+  __ pushl(TypeTestABI::kInstanceReg);
   __ PushObject(Smi::ZoneHandle(zone(), Smi::New(kTypeCheckFromInline)));
   GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 7, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
@@ -733,8 +416,6 @@
   __ popl(TypeTestABI::kInstanceReg);
 
   __ Bind(&is_assignable);
-  __ popl(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ popl(TypeTestABI::kInstantiatorTypeArgumentsReg);
 }
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 41e5961..aad34de 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -217,452 +217,6 @@
   __ Bind(&fall_through);
 }
 
-// Call stub to perform subtype test using a cache (see
-// stub_code_x64.cc:GenerateSubtypeNTestCacheStub)
-//
-// Inputs:
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments (if necessary).
-//   - RCX : function type arguments (if necessary).
-//
-// Preserves RAX/RCX/RDX.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateCallSubtypeTestStub(
-    TypeTestStubKind test_kind,
-    Register instance_reg,
-    Register instantiator_type_arguments_reg,
-    Register function_type_arguments_reg,
-    Register temp_reg,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  ASSERT(temp_reg == kNoRegister);
-  const SubtypeTestCache& type_test_cache =
-      SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
-  __ LoadUniqueObject(R9, type_test_cache);
-  if (test_kind == kTestTypeOneArg) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ Call(StubCode::Subtype1TestCache());
-  } else if (test_kind == kTestTypeTwoArgs) {
-    ASSERT(instantiator_type_arguments_reg == kNoRegister);
-    ASSERT(function_type_arguments_reg == kNoRegister);
-    __ Call(StubCode::Subtype2TestCache());
-  } else if (test_kind == kTestTypeFourArgs) {
-    ASSERT(instantiator_type_arguments_reg ==
-           TypeTestABI::kInstantiatorTypeArgumentsReg);
-    ASSERT(function_type_arguments_reg ==
-           TypeTestABI::kFunctionTypeArgumentsReg);
-    __ Call(StubCode::Subtype4TestCache());
-  } else if (test_kind == kTestTypeSixArgs) {
-    ASSERT(instantiator_type_arguments_reg ==
-           TypeTestABI::kInstantiatorTypeArgumentsReg);
-    ASSERT(function_type_arguments_reg ==
-           TypeTestABI::kFunctionTypeArgumentsReg);
-    __ Call(StubCode::Subtype6TestCache());
-  } else {
-    UNREACHABLE();
-  }
-  // Result is in R8: null -> not found, otherwise Bool::True or Bool::False.
-  GenerateBoolToJump(R8, is_instance_lbl, is_not_instance_lbl);
-  return type_test_cache.raw();
-}
-
-// Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
-// type test is conclusive, otherwise fallthrough if a type test could not
-// be completed.
-// RAX: instance (must survive).
-// Clobbers R10.
-SubtypeTestCachePtr
-FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeWithArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() > 0);
-  const Type& smi_type = Type::Handle(zone(), Type::SmiType());
-  const bool smi_is_ok = smi_type.IsSubtypeOf(type, Heap::kOld);
-  __ testq(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
-  if (smi_is_ok) {
-    // Fast case for type = FutureOr<int/num/top-type>.
-    __ j(ZERO, is_instance_lbl);
-  } else {
-    __ j(ZERO, is_not_instance_lbl);
-  }
-
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-                           type_arguments.IsRaw(from_index, num_type_params);
-  if (is_raw_type) {
-    const Register kClassIdReg = R10;
-    // dynamic type argument, check only classes.
-    __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-    __ cmpl(kClassIdReg, compiler::Immediate(type_class.id()));
-    __ j(EQUAL, is_instance_lbl);
-    // List is a very common case.
-    if (IsListClass(type_class)) {
-      GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
-    }
-    return GenerateSubtype1TestCacheLookup(
-        token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-  }
-  // If one type argument only, check if type argument is a top type.
-  if (type_arguments.Length() == 1) {
-    const AbstractType& tp_argument =
-        AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
-    if (tp_argument.IsTopTypeForSubtyping()) {
-      // Instance class test only necessary.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    }
-  }
-
-  // Regular subtype test cache involving instance's type arguments.
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = kNoRegister;
-  return GenerateCallSubtypeTestStub(
-      kTestTypeTwoArgs, TypeTestABI::kInstanceReg,
-      kInstantiatorTypeArgumentsReg, kFunctionTypeArgumentsReg, kTempReg,
-      is_instance_lbl, is_not_instance_lbl);
-}
-
-void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
-                                      const GrowableArray<intptr_t>& class_ids,
-                                      compiler::Label* is_equal_lbl,
-                                      compiler::Label* is_not_equal_lbl) {
-  for (intptr_t i = 0; i < class_ids.length(); i++) {
-    __ cmpl(class_id_reg, compiler::Immediate(class_ids[i]));
-    __ j(EQUAL, is_equal_lbl);
-  }
-  __ jmp(is_not_equal_lbl);
-}
-
-// Testing against an instantiated type with no arguments, without
-// SubtypeTestCache
-//
-// Inputs:
-//   - RAX : instance to test against
-//
-// Preserves RAX/RCX/RDX.
-//
-// Returns true if there is a fallthrough.
-bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InstantiatedTypeNoArgumentsTest");
-  ASSERT(type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  const Class& type_class = Class::Handle(zone(), type.type_class());
-  ASSERT(type_class.NumTypeArguments() == 0);
-
-  __ testq(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
-  // If instance is Smi, check directly.
-  const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
-                         Nullability::kNonNullable, type, Heap::kOld)) {
-    // Fast case for type = int/num/top-type.
-    __ j(ZERO, is_instance_lbl);
-  } else {
-    __ j(ZERO, is_not_instance_lbl);
-  }
-  const Register kClassIdReg = R10;
-  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
-  // Bool interface can be implemented only by core class Bool.
-  if (type.IsBoolType()) {
-    __ cmpl(kClassIdReg, compiler::Immediate(kBoolCid));
-    __ j(EQUAL, is_instance_lbl);
-    __ jmp(is_not_instance_lbl);
-    return false;
-  }
-  // Custom checking for numbers (Smi, Mint and Double).
-  // Note that instance is not Smi (checked above).
-  if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType()) {
-    GenerateNumberTypeCheck(kClassIdReg, type, is_instance_lbl,
-                            is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsStringType()) {
-    GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
-    return false;
-  }
-  if (type.IsDartFunctionType()) {
-    // Check if instance is a closure.
-    __ cmpq(kClassIdReg, compiler::Immediate(kClosureCid));
-    __ j(EQUAL, is_instance_lbl);
-    return true;
-  }
-
-  // Fast case for cid-range based checks.
-  // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
-    return false;
-  }
-
-  // Otherwise fallthrough, result non-conclusive.
-  return true;
-}
-
-// Uses SubtypeTestCache to store instance class and result.
-// Immediate class test already done.
-//
-// Inputs:
-//   RAX : instance to test against.
-//
-// Preserves RAX/RCX/RDX.
-//
-// TODO(srdjan): Implement a quicker subtype check, as type test
-// arrays can grow too high, but they may be useful when optimizing
-// code (type-feedback).
-SubtypeTestCachePtr FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    TokenPosition token_pos,
-    const Class& type_class,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("Subtype1TestCacheLookup");
-#if defined(DEBUG)
-  compiler::Label ok;
-  __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &ok);
-  __ Breakpoint();
-  __ Bind(&ok);
-#endif
-  __ LoadClassId(TMP, TypeTestABI::kInstanceReg);
-  __ LoadClassById(R10, TMP);
-  // R10: instance class.
-  // Check immediate superclass equality. If type_class is Object, then testing
-  // supertype may yield a wrong result for Null in NNBD strong mode (because
-  // Null also extends Object).
-  if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
-    __ movq(R13, compiler::FieldAddress(R10, Class::super_type_offset()));
-    __ movq(R13, compiler::FieldAddress(R13, Type::type_class_id_offset()));
-    __ CompareImmediate(R13,
-                        compiler::Immediate(Smi::RawValue(type_class.id())));
-    __ j(EQUAL, is_instance_lbl);
-  }
-
-  const Register kInstantiatorTypeArgumentsReg = kNoRegister;
-  const Register kFunctionTypeArgumentsReg = kNoRegister;
-  const Register kTempReg = kNoRegister;
-  return GenerateCallSubtypeTestStub(kTestTypeOneArg, TypeTestABI::kInstanceReg,
-                                     kInstantiatorTypeArgumentsReg,
-                                     kFunctionTypeArgumentsReg, kTempReg,
-                                     is_instance_lbl, is_not_instance_lbl);
-}
-
-// Generates inlined check if 'type' is a type parameter or type itself
-//
-// Inputs:
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments (if necessary).
-//   - RCX : function type arguments (if necessary).
-//
-// Preserves RAX/RCX/RDX.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  const Register kTempReg = kNoRegister;
-  __ Comment("UninstantiatedTypeTest");
-  ASSERT(!type.IsInstantiated());
-  ASSERT(!type.IsFunctionType());
-  // Skip check if destination is a dynamic type.
-  if (type.IsTypeParameter()) {
-    const TypeParameter& type_param = TypeParameter::Cast(type);
-
-    const Register kTypeArgumentsReg =
-        type_param.IsClassTypeParameter()
-            ? TypeTestABI::kInstantiatorTypeArgumentsReg
-            : TypeTestABI::kFunctionTypeArgumentsReg;
-    // Check if type arguments are null, i.e. equivalent to vector of dynamic.
-    __ CompareObject(kTypeArgumentsReg, Object::null_object());
-    __ j(EQUAL, is_instance_lbl);
-    __ movq(RDI, compiler::FieldAddress(
-                     kTypeArgumentsReg,
-                     TypeArguments::type_at_offset(type_param.index())));
-    // RDI: Concrete type of type.
-    // Check if type argument is dynamic, Object?, or void.
-    __ CompareObject(RDI, Object::dynamic_type());
-    __ j(EQUAL, is_instance_lbl);
-    __ CompareObject(
-        RDI, Type::ZoneHandle(
-                 zone(), isolate()->object_store()->nullable_object_type()));
-    __ j(EQUAL, is_instance_lbl);
-    __ CompareObject(RDI, Object::void_type());
-    __ j(EQUAL, is_instance_lbl);
-
-    // For Smi check quickly against int and num interfaces.
-    compiler::Label not_smi;
-    __ testq(RAX, compiler::Immediate(kSmiTagMask));  // Value is Smi?
-    __ j(NOT_ZERO, &not_smi, compiler::Assembler::kNearJump);
-    __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::IntType()));
-    __ j(EQUAL, is_instance_lbl);
-    __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::Number()));
-    __ j(EQUAL, is_instance_lbl);
-    // Smi can be handled by type test cache.
-    __ Bind(&not_smi);
-
-    const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
-    const SubtypeTestCache& type_test_cache = SubtypeTestCache::ZoneHandle(
-        zone(), GenerateCallSubtypeTestStub(
-                    test_kind, TypeTestABI::kInstanceReg,
-                    TypeTestABI::kInstantiatorTypeArgumentsReg,
-                    TypeTestABI::kFunctionTypeArgumentsReg, kTempReg,
-                    is_instance_lbl, is_not_instance_lbl));
-    return type_test_cache.raw();
-  }
-  if (type.IsType()) {
-    // Smi is FutureOr<T>, when T is a top type or int or num.
-    if (!type.IsFutureOrType()) {
-      __ testq(TypeTestABI::kInstanceReg,
-               compiler::Immediate(kSmiTagMask));  // Is instance Smi?
-      __ j(ZERO, is_not_instance_lbl);
-    }
-    // Uninstantiated type class is known at compile time, but the type
-    // arguments are determined at runtime by the instantiator(s).
-    return GenerateCallSubtypeTestStub(
-        kTestTypeFourArgs, TypeTestABI::kInstanceReg,
-        TypeTestABI::kInstantiatorTypeArgumentsReg,
-        TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-        is_not_instance_lbl);
-  }
-  return SubtypeTestCache::null();
-}
-
-// Generates function type check.
-//
-// See [GenerateUninstantiatedTypeTest] for calling convention.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateFunctionTypeTest(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  const Register kTempReg = kNoRegister;
-  __ Comment("FunctionTypeTest");
-
-  __ testq(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
-  __ j(ZERO, is_not_instance_lbl);
-  return GenerateCallSubtypeTestStub(
-      kTestTypeSixArgs, TypeTestABI::kInstanceReg,
-      TypeTestABI::kInstantiatorTypeArgumentsReg,
-      TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-      is_not_instance_lbl);
-}
-
-// Inputs:
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments.
-//   - RCX : function type arguments.
-//
-// Preserves RAX/RCX/RDX.
-//
-// Note that this inlined code must be followed by the runtime_call code, as it
-// may fall through to it. Otherwise, this inline code will jump to the label
-// is_instance or to the label is_not_instance.
-SubtypeTestCachePtr FlowGraphCompiler::GenerateInlineInstanceof(
-    TokenPosition token_pos,
-    const AbstractType& type,
-    compiler::Label* is_instance_lbl,
-    compiler::Label* is_not_instance_lbl) {
-  __ Comment("InlineInstanceof");
-
-  if (type.IsFunctionType()) {
-    return GenerateFunctionTypeTest(token_pos, type, is_instance_lbl,
-                                    is_not_instance_lbl);
-  }
-
-  if (type.IsInstantiated()) {
-    const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type (not a
-    // function type) of a non-parameterized class or with a raw dst type of
-    // a parameterized class.
-    if (type_class.NumTypeArguments() > 0) {
-      return GenerateInstantiatedTypeWithArgumentsTest(
-          token_pos, type, is_instance_lbl, is_not_instance_lbl);
-      // Fall through to runtime call.
-    }
-    const bool has_fall_through = GenerateInstantiatedTypeNoArgumentsTest(
-        token_pos, type, is_instance_lbl, is_not_instance_lbl);
-    if (has_fall_through) {
-      // If test non-conclusive so far, try the inlined type-test cache.
-      // 'type' is known at compile time.
-      return GenerateSubtype1TestCacheLookup(
-          token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
-    } else {
-      return SubtypeTestCache::null();
-    }
-  }
-  return GenerateUninstantiatedTypeTest(token_pos, type, is_instance_lbl,
-                                        is_not_instance_lbl);
-}
-
-// If instanceof type test cannot be performed successfully at compile time and
-// therefore eliminated, optimize it by adding inlined tests for:
-// - Null -> see comment below.
-// - Smi -> compile time subtype check (only if dst class is not parameterized).
-// - Class equality (only if class is not parameterized).
-// Inputs:
-// - RAX: object.
-// - RDX: instantiator type arguments or raw_null.
-// - RCX: function type arguments or raw_null.
-// Returns:
-// - true or false in RAX.
-void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
-                                           intptr_t deopt_id,
-                                           const AbstractType& type,
-                                           LocationSummary* locs) {
-  ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
-
-  compiler::Label is_instance, is_not_instance;
-  // 'null' is an instance of Null, Object*, Never*, void, and dynamic.
-  // In addition, 'null' is an instance of any nullable type.
-  // It is also an instance of FutureOr<T> if it is an instance of T.
-  const AbstractType& unwrapped_type =
-      AbstractType::Handle(type.UnwrapFutureOr());
-  if (!unwrapped_type.IsTypeParameter() || unwrapped_type.IsNullable()) {
-    // Only nullable type parameter remains nullable after instantiation.
-    // See NullIsInstanceOf().
-    __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
-    __ j(EQUAL, (unwrapped_type.IsNullable() ||
-                 (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType()))
-                    ? &is_instance
-                    : &is_not_instance);
-  }
-
-  // Generate inline instanceof test.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  // The registers RAX, RCX, RDX are preserved across the call.
-  test_cache =
-      GenerateInlineInstanceof(token_pos, type, &is_instance, &is_not_instance);
-
-  // test_cache is null if there is no fall-through.
-  compiler::Label done;
-  if (!test_cache.IsNull()) {
-    // Generate Runtime call.
-    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
-    __ LoadUniqueObject(TypeTestABI::kSubtypeTestCacheReg, test_cache);
-    GenerateStubCall(token_pos, StubCode::InstanceOf(),
-                     /*kind=*/PcDescriptorsLayout::kOther, locs, deopt_id);
-    __ jmp(&done, compiler::Assembler::kNearJump);
-  }
-  __ Bind(&is_not_instance);
-  __ LoadObject(RAX, Bool::Get(false));
-  __ jmp(&done, compiler::Assembler::kNearJump);
-
-  __ Bind(&is_instance);
-  __ LoadObject(RAX, Bool::Get(true));
-  __ Bind(&done);
-}
-
 void FlowGraphCompiler::GenerateIndirectTTSCall(Register reg_to_call,
                                                 intptr_t sub_type_cache_index) {
   __ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
@@ -1201,13 +755,11 @@
 #endif
 
   // TODO(vegorov): avoid saving non-volatile registers.
-  __ PushRegisters(locs->live_registers()->cpu_registers(),
-                   locs->live_registers()->fpu_registers());
+  __ PushRegisters(*locs->live_registers());
 }
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
-  __ PopRegisters(locs->live_registers()->cpu_registers(),
-                  locs->live_registers()->fpu_registers());
+  __ PopRegisters(*locs->live_registers());
 }
 
 #if defined(DEBUG)
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 8d8abf9..7ae73e4 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -820,23 +820,26 @@
     const Array& descriptor =
         Array::Handle(zone, ic_data.arguments_descriptor());
     Thread* thread = Thread::Current();
-    const MegamorphicCache& cache = MegamorphicCache::Handle(
+
+    const auto& cache = MegamorphicCache::Handle(
         zone, MegamorphicCacheTable::Lookup(thread, name, descriptor));
-    SafepointMutexLocker ml(thread->isolate()->megamorphic_mutex());
-    MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
-    for (intptr_t i = 0, n = entries.Length(); i < n; i++) {
-      const intptr_t id =
-          Smi::Value(entries[i].Get<MegamorphicCache::kClassIdIndex>());
-      if (id == kIllegalCid) {
-        continue;
+    {
+      SafepointMutexLocker ml(thread->isolate_group()->type_feedback_mutex());
+      MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
+      for (intptr_t i = 0, n = entries.Length(); i < n; i++) {
+        const intptr_t id =
+            Smi::Value(entries[i].Get<MegamorphicCache::kClassIdIndex>());
+        if (id == kIllegalCid) {
+          continue;
+        }
+        Function& function = Function::ZoneHandle(zone);
+        function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
+        const intptr_t filled_entry_count = cache.filled_entry_count();
+        ASSERT(filled_entry_count > 0);
+        cid_ranges_.Add(new (zone) TargetInfo(
+            id, id, &function, Usage(function) / filled_entry_count,
+            StaticTypeExactnessState::NotTracking()));
       }
-      Function& function = Function::ZoneHandle(zone);
-      function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
-      const intptr_t filled_entry_count = cache.filled_entry_count();
-      ASSERT(filled_entry_count > 0);
-      cid_ranges_.Add(new (zone) TargetInfo(
-          id, id, &function, Usage(function) / filled_entry_count,
-          StaticTypeExactnessState::NotTracking()));
     }
   }
 }
@@ -1070,8 +1073,8 @@
 }
 
 Instruction* AssertSubtypeInstr::Canonicalize(FlowGraph* flow_graph) {
-  // If all inputs are constant, we can instantiate the sub and super type and
-  // remove this instruction if the subtype test succeeds.
+  // If all inputs needed to check instantation are constant, instantiate the
+  // sub and super type and remove the instruction if the subtype test succeeds.
   if (super_type()->BindsToConstant() && sub_type()->BindsToConstant() &&
       instantiator_type_arguments()->BindsToConstant() &&
       function_type_arguments()->BindsToConstant()) {
@@ -2752,6 +2755,8 @@
     case Slot::Kind::kTypeParameter_name:
     case Slot::Kind::kUnhandledException_exception:
     case Slot::Kind::kUnhandledException_stacktrace:
+    case Slot::Kind::kWeakProperty_key:
+    case Slot::Kind::kWeakProperty_value:
       return false;
   }
   UNREACHABLE();
@@ -4815,8 +4820,36 @@
   }
 }
 
+static FunctionPtr FindBinarySmiOp(Zone* zone, const String& name) {
+  const auto& smi_class = Class::Handle(zone, Smi::Class());
+  auto& smi_op_target = Function::Handle(
+      zone, Resolver::ResolveDynamicAnyArgs(zone, smi_class, name));
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (smi_op_target.IsNull() &&
+      Function::IsDynamicInvocationForwarderName(name)) {
+    const String& demangled = String::Handle(
+        zone, Function::DemangleDynamicInvocationForwarderName(name));
+    smi_op_target = Resolver::ResolveDynamicAnyArgs(zone, smi_class, demangled);
+  }
+#endif
+  return smi_op_target.raw();
+}
+
 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Zone* zone = compiler->zone();
+
+  UpdateReceiverSminess(zone);
+
+  auto& specialized_binary_smi_ic_stub = Code::ZoneHandle(zone);
+  auto& binary_smi_op_target = Function::Handle(zone);
+  if (!receiver_is_not_smi()) {
+    specialized_binary_smi_ic_stub = TwoArgsSmiOpInlineCacheEntry(token_kind());
+    if (!specialized_binary_smi_ic_stub.IsNull()) {
+      binary_smi_op_target = FindBinarySmiOp(zone, function_name());
+    }
+  }
+
   const ICData* call_ic_data = NULL;
   if (!FLAG_propagate_ic_data || !compiler->is_optimizing() ||
       (ic_data() == NULL)) {
@@ -4830,13 +4863,11 @@
 
     call_ic_data = compiler->GetOrAddInstanceCallICData(
         deopt_id(), function_name(), arguments_descriptor,
-        checked_argument_count(), receivers_static_type);
+        checked_argument_count(), receivers_static_type, binary_smi_op_target);
   } else {
     call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw());
   }
 
-  UpdateReceiverSminess(zone);
-
   if (compiler->is_optimizing() && HasICData()) {
     if (ic_data()->NumberOfUsedChecks() > 0) {
       const ICData& unary_ic_data =
@@ -4854,18 +4885,27 @@
     // Unoptimized code.
     compiler->AddCurrentDescriptor(PcDescriptorsLayout::kRewind, deopt_id(),
                                    token_pos());
-    bool is_smi_two_args_op = false;
-    const Code& stub =
-        Code::ZoneHandle(TwoArgsSmiOpInlineCacheEntry(token_kind()));
-    if (!stub.IsNull()) {
-      // We have a dedicated inline cache stub for this operation, add an
-      // an initial Smi/Smi check with count 0.
-      is_smi_two_args_op = call_ic_data->AddSmiSmiCheckForFastSmiStubs();
+
+    // If the ICData contains a (Smi, Smi, <binary-smi-op-target>) stub already
+    // we will call the specialized IC Stub that works as a normal IC Stub but
+    // has inlined fast path for the specific Smi operation.
+    bool use_specialized_smi_ic_stub = false;
+    if (!specialized_binary_smi_ic_stub.IsNull() &&
+        call_ic_data->NumberOfChecksIs(1)) {
+      GrowableArray<intptr_t> class_ids(2);
+      auto& target = Function::Handle();
+      call_ic_data->GetCheckAt(0, &class_ids, &target);
+      if (class_ids[0] == kSmiCid && class_ids[1] == kSmiCid &&
+          target.raw() == binary_smi_op_target.raw()) {
+        use_specialized_smi_ic_stub = true;
+      }
     }
-    if (is_smi_two_args_op) {
+
+    if (use_specialized_smi_ic_stub) {
       ASSERT(ArgumentCount() == 2);
-      compiler->EmitInstanceCallJIT(stub, *call_ic_data, deopt_id(),
-                                    token_pos(), locs(), entry_kind());
+      compiler->EmitInstanceCallJIT(specialized_binary_smi_ic_stub,
+                                    *call_ic_data, deopt_id(), token_pos(),
+                                    locs(), entry_kind());
     } else {
       compiler->GenerateInstanceCall(deopt_id(), token_pos(), locs(),
                                      *call_ic_data, entry_kind(),
@@ -5286,7 +5326,7 @@
 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->GenerateAssertAssignable(value()->Type(), token_pos(), deopt_id(),
                                      dst_name(), locs());
-  ASSERT(locs()->in(0).reg() == locs()->out(0).reg());
+  ASSERT(locs()->in(kInstancePos).reg() == locs()->out(0).reg());
 }
 
 LocationSummary* AssertSubtypeInstr::MakeLocationSummary(Zone* zone,
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 6e4fe72..c1a0446 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -3620,6 +3620,13 @@
   static const char* KindToCString(Kind kind);
   static bool ParseKind(const char* str, Kind* out);
 
+  enum {
+    kInstancePos = 0,
+    kDstTypePos = 1,
+    kInstantiatorTAVPos = 2,
+    kFunctionTAVPos = 3,
+  };
+
   AssertAssignableInstr(TokenPosition token_pos,
                         Value* value,
                         Value* dst_type,
@@ -3633,10 +3640,10 @@
         dst_name_(dst_name),
         kind_(kind) {
     ASSERT(!dst_name.IsNull());
-    SetInputAt(0, value);
-    SetInputAt(1, dst_type);
-    SetInputAt(2, instantiator_type_arguments);
-    SetInputAt(3, function_type_arguments);
+    SetInputAt(kInstancePos, value);
+    SetInputAt(kDstTypePos, dst_type);
+    SetInputAt(kInstantiatorTAVPos, instantiator_type_arguments);
+    SetInputAt(kFunctionTAVPos, function_type_arguments);
   }
 
   virtual intptr_t statistics_tag() const;
@@ -3645,10 +3652,12 @@
   virtual CompileType ComputeType() const;
   virtual bool RecomputeType();
 
-  Value* value() const { return inputs_[0]; }
-  Value* dst_type() const { return inputs_[1]; }
-  Value* instantiator_type_arguments() const { return inputs_[2]; }
-  Value* function_type_arguments() const { return inputs_[3]; }
+  Value* value() const { return inputs_[kInstancePos]; }
+  Value* dst_type() const { return inputs_[kDstTypePos]; }
+  Value* instantiator_type_arguments() const {
+    return inputs_[kInstantiatorTAVPos];
+  }
+  Value* function_type_arguments() const { return inputs_[kFunctionTAVPos]; }
 
   virtual TokenPosition token_pos() const { return token_pos_; }
   const String& dst_name() const { return dst_name_; }
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index cbedc5b..04b1857 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -104,7 +104,7 @@
     case kTagged: {
       const auto out = locs()->out(0).reg();
       __ add(out, base_reg(), compiler::Operand(index, LSL, 1));
-      __ LoadFromOffset(kWord, out, out, offset());
+      __ LoadFromOffset(out, out, offset());
       break;
     }
     case kUnboxedInt64: {
@@ -112,9 +112,8 @@
       const auto out_hi = locs()->out(0).AsPairLocation()->At(1).reg();
 
       __ add(out_hi, base_reg(), compiler::Operand(index, LSL, 1));
-      __ LoadFromOffset(kWord, out_lo, out_hi, offset());
-      __ LoadFromOffset(kWord, out_hi, out_hi,
-                        offset() + compiler::target::kWordSize);
+      __ LoadFromOffset(out_lo, out_hi, offset());
+      __ LoadFromOffset(out_hi, out_hi, offset() + compiler::target::kWordSize);
       break;
     }
     case kUnboxedDouble: {
@@ -428,7 +427,7 @@
         } else {
           ASSERT(value.IsStackSlot());
           const intptr_t value_offset = value.ToStackSlotOffset();
-          __ LoadFromOffset(kWord, reg, value.base_reg(), value_offset);
+          __ LoadFromOffset(reg, value.base_reg(), value_offset);
         }
         pusher.PushRegister(compiler, reg);
       }
@@ -637,7 +636,7 @@
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register result = locs()->out(0).reg();
-  __ LoadFromOffset(kWord, result, FP,
+  __ LoadFromOffset(result, FP,
                     compiler::target::FrameOffsetInBytesForVariable(&local()));
 }
 
@@ -651,7 +650,7 @@
   const Register value = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
   ASSERT(result == value);  // Assert that register assignment is correct.
-  __ StoreToOffset(kWord, value, FP,
+  __ StoreToOffset(value, FP,
                    compiler::target::FrameOffsetInBytesForVariable(&local()));
 }
 
@@ -719,7 +718,7 @@
     } else {
       __ LoadObject(tmp, value_);
     }
-    __ StoreToOffset(kWord, tmp, destination.base_reg(), dest_offset);
+    __ StoreToOffset(tmp, destination.base_reg(), dest_offset);
   }
 }
 
@@ -791,12 +790,14 @@
 
   LocationSummary* summary = new (zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCallCalleeSafe);
-  summary->set_in(0, Location::RegisterLocation(TypeTestABI::kInstanceReg));
-  summary->set_in(1, dst_type_loc);
-  summary->set_in(2, Location::RegisterLocation(
-                         TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kInstancePos,
+                  Location::RegisterLocation(TypeTestABI::kInstanceReg));
+  summary->set_in(kDstTypePos, dst_type_loc);
   summary->set_in(
-      3, Location::RegisterLocation(TypeTestABI::kFunctionTypeArgumentsReg));
+      kInstantiatorTAVPos,
+      Location::RegisterLocation(TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kFunctionTAVPos, Location::RegisterLocation(
+                                       TypeTestABI::kFunctionTypeArgumentsReg));
   summary->set_out(0, Location::SameAsFirstInput());
 
   // Let's reserve all registers except for the input ones.
@@ -1377,8 +1378,7 @@
 
   // Restore top_resource.
   __ Pop(tmp);
-  __ StoreToOffset(kWord, tmp, THR,
-                   compiler::target::Thread::top_resource_offset());
+  __ StoreToOffset(tmp, THR, compiler::target::Thread::top_resource_offset());
 
   __ Pop(vm_tag_reg);
 
@@ -1466,24 +1466,24 @@
   }
 
   // Save the current VMTag on the stack.
-  __ LoadFromOffset(kWord, R0, THR, compiler::target::Thread::vm_tag_offset());
+  __ LoadFromOffset(R0, THR, compiler::target::Thread::vm_tag_offset());
   __ Push(R0);
 
   // Save top resource.
   const intptr_t top_resource_offset =
       compiler::target::Thread::top_resource_offset();
-  __ LoadFromOffset(kWord, R0, THR, top_resource_offset);
+  __ LoadFromOffset(R0, THR, top_resource_offset);
   __ Push(R0);
   __ LoadImmediate(R0, 0);
-  __ StoreToOffset(kWord, R0, THR, top_resource_offset);
+  __ StoreToOffset(R0, THR, top_resource_offset);
 
-  __ LoadFromOffset(kWord, R0, THR,
+  __ LoadFromOffset(R0, THR,
                     compiler::target::Thread::exit_through_ffi_offset());
   __ Push(R0);
 
   // Save top exit frame info. Don't set it to 0 yet,
   // TransitionNativeToGenerated will handle that.
-  __ LoadFromOffset(kWord, R0, THR,
+  __ LoadFromOffset(R0, THR,
                     compiler::target::Thread::top_exit_frame_info_offset());
   __ Push(R0);
 
@@ -1498,16 +1498,15 @@
   // handles.
 
   // Load the code object.
-  __ LoadFromOffset(kWord, R0, THR,
-                    compiler::target::Thread::callback_code_offset());
-  __ LoadFieldFromOffset(kWord, R0, R0,
+  __ LoadFromOffset(R0, THR, compiler::target::Thread::callback_code_offset());
+  __ LoadFieldFromOffset(R0, R0,
                          compiler::target::GrowableObjectArray::data_offset());
-  __ LoadFieldFromOffset(kWord, CODE_REG, R0,
+  __ LoadFieldFromOffset(CODE_REG, R0,
                          compiler::target::Array::data_offset() +
                              callback_id_ * compiler::target::kWordSize);
 
   // Put the code object in the reserved slot.
-  __ StoreToOffset(kWord, CODE_REG, FPREG,
+  __ StoreToOffset(CODE_REG, FPREG,
                    kPcMarkerSlotFromFp * compiler::target::kWordSize);
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
     __ SetupGlobalPoolAndDispatchTable();
@@ -1520,10 +1519,9 @@
 
   // Load a dummy return address which suggests that we are inside of
   // InvokeDartCodeStub. This is how the stack walker detects an entry frame.
-  __ LoadFromOffset(kWord, LR, THR,
+  __ LoadFromOffset(LR, THR,
                     compiler::target::Thread::invoke_dart_code_stub_offset());
-  __ LoadFieldFromOffset(kWord, LR, LR,
-                         compiler::target::Code::entry_point_offset());
+  __ LoadFieldFromOffset(LR, LR, compiler::target::Code::entry_point_offset());
 
   FunctionEntryInstr::EmitNativeCode(compiler);
 }
@@ -1636,7 +1634,7 @@
   compiler::Label loop, loop_in;
 
   // Address of input bytes.
-  __ LoadFieldFromOffset(kWord, bytes_reg, bytes_reg,
+  __ LoadFieldFromOffset(bytes_reg, bytes_reg,
                          compiler::target::TypedDataBase::data_field_offset());
 
   // Table.
@@ -1684,11 +1682,9 @@
     decoder_reg = decoder_location.reg();
   }
   const auto scan_flags_field_offset = scan_flags_field_.offset_in_bytes();
-  __ LoadFieldFromOffset(kWord, flags_temp_reg, decoder_reg,
-                         scan_flags_field_offset);
+  __ LoadFieldFromOffset(flags_temp_reg, decoder_reg, scan_flags_field_offset);
   __ orr(flags_temp_reg, flags_temp_reg, compiler::Operand(flags_reg));
-  __ StoreFieldToOffset(kWord, flags_temp_reg, decoder_reg,
-                        scan_flags_field_offset);
+  __ StoreFieldToOffset(flags_temp_reg, decoder_reg, scan_flags_field_offset);
 }
 
 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(Zone* zone,
@@ -1702,15 +1698,15 @@
   const Register obj = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
   if (object()->definition()->representation() == kUntagged) {
-    __ LoadFromOffset(kWord, result, obj, offset());
+    __ LoadFromOffset(result, obj, offset());
   } else {
     ASSERT(object()->definition()->representation() == kTagged);
-    __ LoadFieldFromOffset(kWord, result, obj, offset());
+    __ LoadFieldFromOffset(result, obj, offset());
   }
 }
 
 DEFINE_BACKEND(StoreUntagged, (NoLocation, Register obj, Register value)) {
-  __ StoreToOffset(kWord, value, obj, instr->offset_from_tagged());
+  __ StoreToOffset(value, obj, instr->offset_from_tagged());
 }
 
 Representation LoadIndexedInstr::representation() const {
@@ -2767,11 +2763,11 @@
       BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
                                       result, temp);
       __ eor(temp, temp, compiler::Operand(temp));
-      __ StoreToOffset(kWord, value, result,
-                       compiler::target::Mint::value_offset() - kHeapObjectTag);
-      __ StoreToOffset(kWord, temp, result,
-                       compiler::target::Mint::value_offset() - kHeapObjectTag +
-                           compiler::target::kWordSize);
+      __ StoreFieldToOffset(value, result,
+                            compiler::target::Mint::value_offset());
+      __ StoreFieldToOffset(
+          temp, result,
+          compiler::target::Mint::value_offset() + compiler::target::kWordSize);
       __ Bind(&done);
     }
   }
@@ -2856,11 +2852,9 @@
       const Register value_lo = value_pair->At(0).reg();
       const Register value_hi = value_pair->At(1).reg();
       __ Comment("UnboxedIntegerStoreInstanceFieldInstr");
-      __ StoreToOffset(kWord, value_lo, instance_reg,
-                       offset_in_bytes - kHeapObjectTag);
-      __ StoreToOffset(
-          kWord, value_hi, instance_reg,
-          offset_in_bytes - kHeapObjectTag + compiler::target::kWordSize);
+      __ StoreFieldToOffset(value_lo, instance_reg, offset_in_bytes);
+      __ StoreFieldToOffset(value_hi, instance_reg,
+                            offset_in_bytes + compiler::target::kWordSize);
       return;
     }
 
@@ -3059,10 +3053,10 @@
 
   compiler->used_static_fields().Add(&field());
 
-  __ LoadFromOffset(kWord, temp, THR,
+  __ LoadFromOffset(temp, THR,
                     compiler::target::Thread::field_table_values_offset());
   // Note: static fields ids won't be changed by hot-reload.
-  __ StoreToOffset(kWord, value, temp,
+  __ StoreToOffset(value, temp,
                    compiler::target::FieldTable::OffsetOf(field()));
 }
 
@@ -3292,21 +3286,21 @@
         const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
         const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
         __ Comment("UnboxedInt64LoadFieldInstr");
-        __ LoadFromOffset(kWord, out_lo, instance_reg, offset_lo);
-        __ LoadFromOffset(kWord, out_hi, instance_reg, offset_hi);
+        __ LoadFromOffset(out_lo, instance_reg, offset_lo);
+        __ LoadFromOffset(out_hi, instance_reg, offset_hi);
         break;
       }
       case kUnboxedUint32: {
         const Register result = locs()->out(0).reg();
         __ Comment("UnboxedUint32LoadFieldInstr");
-        __ LoadFieldFromOffset(kWord, result, instance_reg, OffsetInBytes());
+        __ LoadFieldFromOffset(result, instance_reg, OffsetInBytes());
         break;
       }
       case kUnboxedUint8: {
         const Register result = locs()->out(0).reg();
         __ Comment("UnboxedUint8LoadFieldInstr");
-        __ LoadFieldFromOffset(kUnsignedByte, result, instance_reg,
-                               OffsetInBytes());
+        __ LoadFieldFromOffset(result, instance_reg, OffsetInBytes(),
+                               compiler::kUnsignedByte);
         break;
       }
       default:
@@ -3346,7 +3340,7 @@
     }
 
     const Register temp = locs()->temp(0).reg();
-    __ LoadFieldFromOffset(kWord, temp, instance_reg, OffsetInBytes());
+    __ LoadFieldFromOffset(temp, instance_reg, OffsetInBytes());
     switch (cid) {
       case kDoubleCid:
         __ Comment("UnboxedDoubleLoadFieldInstr");
@@ -3446,7 +3440,7 @@
     __ Bind(&load_pointer);
   }
 
-  __ LoadFieldFromOffset(kWord, result_reg, instance_reg, OffsetInBytes());
+  __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
 
   if (calls_initializer()) {
     EmitNativeCodeForInitializerCall(compiler);
@@ -3704,12 +3698,12 @@
   if (!compiler->is_optimizing()) {
     if (raw_exception_var_ != nullptr) {
       __ StoreToOffset(
-          kWord, kExceptionObjectReg, FP,
+          kExceptionObjectReg, FP,
           compiler::target::FrameOffsetInBytesForVariable(raw_exception_var_));
     }
     if (raw_stacktrace_var_ != nullptr) {
       __ StoreToOffset(
-          kWord, kStackTraceObjectReg, FP,
+          kStackTraceObjectReg, FP,
           compiler::target::FrameOffsetInBytesForVariable(raw_stacktrace_var_));
     }
   }
@@ -4860,8 +4854,8 @@
     case kUnboxedInt64: {
       PairLocation* result = locs()->out(0).AsPairLocation();
       ASSERT(result->At(0).reg() != box);
-      __ LoadFieldFromOffset(kWord, result->At(0).reg(), box, ValueOffset());
-      __ LoadFieldFromOffset(kWord, result->At(1).reg(), box,
+      __ LoadFieldFromOffset(result->At(0).reg(), box, ValueOffset());
+      __ LoadFieldFromOffset(result->At(1).reg(), box,
                              ValueOffset() + compiler::target::kWordSize);
       break;
     }
@@ -4925,8 +4919,7 @@
   const Register result = locs()->out(0).reg();
   compiler::Label done;
   __ SmiUntag(result, value, &done);
-  __ LoadFieldFromOffset(kWord, result, value,
-                         compiler::target::Mint::value_offset());
+  __ LoadFieldFromOffset(result, value, compiler::target::Mint::value_offset());
   __ Bind(&done);
 }
 
@@ -5007,11 +5000,10 @@
       ASSERT(from_representation() == kUnboxedUint32);
       __ eor(temp, temp, compiler::Operand(temp));
     }
-    __ StoreToOffset(kWord, value, out,
-                     compiler::target::Mint::value_offset() - kHeapObjectTag);
-    __ StoreToOffset(kWord, temp, out,
-                     compiler::target::Mint::value_offset() - kHeapObjectTag +
-                         compiler::target::kWordSize);
+    __ StoreFieldToOffset(value, out, compiler::target::Mint::value_offset());
+    __ StoreFieldToOffset(
+        temp, out,
+        compiler::target::Mint::value_offset() + compiler::target::kWordSize);
     __ Bind(&done);
   }
 }
@@ -5097,11 +5089,11 @@
                                     out_reg, tmp);
   }
 
-  __ StoreToOffset(kWord, value_lo, out_reg,
-                   compiler::target::Mint::value_offset() - kHeapObjectTag);
-  __ StoreToOffset(kWord, value_hi, out_reg,
-                   compiler::target::Mint::value_offset() - kHeapObjectTag +
-                       compiler::target::kWordSize);
+  __ StoreFieldToOffset(value_lo, out_reg,
+                        compiler::target::Mint::value_offset());
+  __ StoreFieldToOffset(
+      value_hi, out_reg,
+      compiler::target::Mint::value_offset() + compiler::target::kWordSize);
   __ Bind(&done);
 }
 
@@ -5110,11 +5102,10 @@
                               Register result,
                               Register temp,
                               compiler::Label* deopt) {
-  __ LoadFieldFromOffset(kWord, result, mint,
-                         compiler::target::Mint::value_offset());
+  __ LoadFieldFromOffset(result, mint, compiler::target::Mint::value_offset());
   if (deopt != NULL) {
     __ LoadFieldFromOffset(
-        kWord, temp, mint,
+        temp, mint,
         compiler::target::Mint::value_offset() + compiler::target::kWordSize);
     __ cmp(temp,
            compiler::Operand(result, ASR, compiler::target::kBitsPerWord - 1));
@@ -5293,7 +5284,7 @@
       break;
     case SimdOpInstr::kFloat32x4Scale:
       __ vcvtsd(STMP, EvenDRegisterOf(left));
-      __ vdup(kWord, result, DTMP, 0);
+      __ vdup(compiler::kFourBytes, result, DTMP, 0);
       __ vmulqs(result, result, right);
       break;
     case SimdOpInstr::kInt32x4BitAnd:
@@ -5306,10 +5297,10 @@
       __ veorq(result, left, right);
       break;
     case SimdOpInstr::kInt32x4Add:
-      __ vaddqi(kWord, result, left, right);
+      __ vaddqi(compiler::kFourBytes, result, left, right);
       break;
     case SimdOpInstr::kInt32x4Sub:
-      __ vsubqi(kWord, result, left, right);
+      __ vsubqi(compiler::kFourBytes, result, left, right);
       break;
     default:
       UNREACHABLE();
@@ -5363,13 +5354,13 @@
     case SimdOpInstr::kInt32x4Shuffle:
     case SimdOpInstr::kFloat32x4Shuffle: {
       if (instr->mask() == 0x00) {
-        __ vdup(kWord, result, value.d(0), 0);
+        __ vdup(compiler::kFourBytes, result, value.d(0), 0);
       } else if (instr->mask() == 0x55) {
-        __ vdup(kWord, result, value.d(0), 1);
+        __ vdup(compiler::kFourBytes, result, value.d(0), 1);
       } else if (instr->mask() == 0xAA) {
-        __ vdup(kWord, result, value.d(1), 0);
+        __ vdup(compiler::kFourBytes, result, value.d(1), 0);
       } else if (instr->mask() == 0xFF) {
-        __ vdup(kWord, result, value.d(1), 1);
+        __ vdup(compiler::kFourBytes, result, value.d(1), 1);
       } else {
         // TODO(zra): Investigate better instruction sequences for other
         // shuffle masks.
@@ -5442,7 +5433,7 @@
   __ vcvtsd(STMP, value.d(0));
 
   // Splat across all lanes.
-  __ vdup(kWord, result, DTMP, 0);
+  __ vdup(compiler::kFourBytes, result, DTMP, 0);
 }
 
 DEFINE_EMIT(Float32x4Sqrt,
@@ -6985,10 +6976,10 @@
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
     __ StoreToOffset(
-        kWord, right_lo, THR,
+        right_lo, THR,
         compiler::target::Thread::unboxed_int64_runtime_arg_offset());
     __ StoreToOffset(
-        kWord, right_hi, THR,
+        right_hi, THR,
         compiler::target::Thread::unboxed_int64_runtime_arg_offset() +
             compiler::target::kWordSize);
   }
@@ -7126,10 +7117,10 @@
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
     __ StoreToOffset(
-        kWord, right_lo, THR,
+        right_lo, THR,
         compiler::target::Thread::unboxed_int64_runtime_arg_offset());
     __ StoreToOffset(
-        kWord, right_hi, THR,
+        right_hi, THR,
         compiler::target::Thread::unboxed_int64_runtime_arg_offset() +
             compiler::target::kWordSize);
   }
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 7cb909a..50100ea 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -188,24 +188,24 @@
   __ Bind(&loop);
   switch (element_size_) {
     case 1:
-      __ ldr(temp_reg, src_address, kUnsignedByte);
-      __ str(temp_reg, dest_address, kUnsignedByte);
+      __ ldr(temp_reg, src_address, compiler::kUnsignedByte);
+      __ str(temp_reg, dest_address, compiler::kUnsignedByte);
       break;
     case 2:
-      __ ldr(temp_reg, src_address, kUnsignedHalfword);
-      __ str(temp_reg, dest_address, kUnsignedHalfword);
+      __ ldr(temp_reg, src_address, compiler::kUnsignedTwoBytes);
+      __ str(temp_reg, dest_address, compiler::kUnsignedTwoBytes);
       break;
     case 4:
-      __ ldr(temp_reg, src_address, kUnsignedWord);
-      __ str(temp_reg, dest_address, kUnsignedWord);
+      __ ldr(temp_reg, src_address, compiler::kUnsignedFourBytes);
+      __ str(temp_reg, dest_address, compiler::kUnsignedFourBytes);
       break;
     case 8:
-      __ ldr(temp_reg, src_address, kDoubleWord);
-      __ str(temp_reg, dest_address, kDoubleWord);
+      __ ldr(temp_reg, src_address, compiler::kEightBytes);
+      __ str(temp_reg, dest_address, compiler::kEightBytes);
       break;
     case 16:
-      __ ldp(temp_reg, temp_reg2, src_address, kDoubleWord);
-      __ stp(temp_reg, temp_reg2, dest_address, kDoubleWord);
+      __ ldp(temp_reg, temp_reg2, src_address, compiler::kEightBytes);
+      __ stp(temp_reg, temp_reg2, dest_address, compiler::kEightBytes);
       break;
   }
   __ subs(length_reg, length_reg, compiler::Operand(1));
@@ -688,12 +688,14 @@
 
   LocationSummary* summary = new (zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCallCalleeSafe);
-  summary->set_in(0, Location::RegisterLocation(TypeTestABI::kInstanceReg));
-  summary->set_in(1, dst_type_loc);
-  summary->set_in(2, Location::RegisterLocation(
-                         TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kInstancePos,
+                  Location::RegisterLocation(TypeTestABI::kInstanceReg));
+  summary->set_in(kDstTypePos, dst_type_loc);
   summary->set_in(
-      3, Location::RegisterLocation(TypeTestABI::kFunctionTypeArgumentsReg));
+      kInstantiatorTAVPos,
+      Location::RegisterLocation(TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kFunctionTAVPos, Location::RegisterLocation(
+                                       TypeTestABI::kFunctionTypeArgumentsReg));
   summary->set_out(0, Location::SameAsFirstInput());
 
   // Let's reserve all registers except for the input ones.
@@ -1407,8 +1409,10 @@
   const Register str = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
   __ LoadFieldFromOffset(result, str, String::length_offset());
-  __ ldr(TMP, compiler::FieldAddress(str, OneByteString::data_offset(), kByte),
-         kUnsignedByte);
+  __ ldr(TMP,
+         compiler::FieldAddress(str, OneByteString::data_offset(),
+                                compiler::kByte),
+         compiler::kUnsignedByte);
   __ CompareImmediate(result, Smi::RawValue(1));
   __ LoadImmediate(result, -1);
   __ csel(result, TMP, result, EQ);
@@ -1498,10 +1502,11 @@
   // Read byte and increment pointer.
   __ ldr(temp_reg,
          compiler::Address(bytes_ptr_reg, 1, compiler::Address::PostIndex),
-         kUnsignedByte);
+         compiler::kUnsignedByte);
 
   // Update size and flags based on byte value.
-  __ ldr(temp_reg, compiler::Address(table_reg, temp_reg), kUnsignedByte);
+  __ ldr(temp_reg, compiler::Address(table_reg, temp_reg),
+         compiler::kUnsignedByte);
   __ orr(flags_reg, flags_reg, compiler::Operand(temp_reg));
   __ andi(temp_reg, temp_reg, compiler::Immediate(kSizeMask));
   __ add(size_reg, size_reg, compiler::Operand(temp_reg));
@@ -1675,21 +1680,21 @@
   switch (class_id()) {
     case kTypedDataInt32ArrayCid:
       ASSERT(representation() == kUnboxedInt32);
-      __ ldr(result, element_address, kWord);
+      __ ldr(result, element_address, compiler::kFourBytes);
       break;
     case kTypedDataUint32ArrayCid:
       ASSERT(representation() == kUnboxedUint32);
-      __ ldr(result, element_address, kUnsignedWord);
+      __ ldr(result, element_address, compiler::kUnsignedFourBytes);
       break;
     case kTypedDataInt64ArrayCid:
     case kTypedDataUint64ArrayCid:
       ASSERT(representation() == kUnboxedInt64);
-      __ ldr(result, element_address, kDoubleWord);
+      __ ldr(result, element_address, compiler::kEightBytes);
       break;
     case kTypedDataInt8ArrayCid:
       ASSERT(representation() == kUnboxedIntPtr);
       ASSERT(index_scale() == 1);
-      __ ldr(result, element_address, kByte);
+      __ ldr(result, element_address, compiler::kByte);
       break;
     case kTypedDataUint8ArrayCid:
     case kTypedDataUint8ClampedArrayCid:
@@ -1699,17 +1704,17 @@
     case kExternalOneByteStringCid:
       ASSERT(representation() == kUnboxedIntPtr);
       ASSERT(index_scale() == 1);
-      __ ldr(result, element_address, kUnsignedByte);
+      __ ldr(result, element_address, compiler::kUnsignedByte);
       break;
     case kTypedDataInt16ArrayCid:
       ASSERT(representation() == kUnboxedIntPtr);
-      __ ldr(result, element_address, kHalfword);
+      __ ldr(result, element_address, compiler::kTwoBytes);
       break;
     case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
     case kExternalTwoByteStringCid:
       ASSERT(representation() == kUnboxedIntPtr);
-      __ ldr(result, element_address, kUnsignedHalfword);
+      __ ldr(result, element_address, compiler::kUnsignedTwoBytes);
       break;
     default:
       ASSERT(representation() == kTagged);
@@ -1736,7 +1741,7 @@
   // The string register points to the backing store for external strings.
   const Register str = locs()->in(0).reg();
   const Location index = locs()->in(1);
-  OperandSize sz = OperandSize::kByte;
+  compiler::OperandSize sz = compiler::kByte;
 
   Register result = locs()->out(0).reg();
   switch (class_id()) {
@@ -1744,13 +1749,13 @@
     case kExternalOneByteStringCid:
       switch (element_count()) {
         case 1:
-          sz = kUnsignedByte;
+          sz = compiler::kUnsignedByte;
           break;
         case 2:
-          sz = kUnsignedHalfword;
+          sz = compiler::kUnsignedTwoBytes;
           break;
         case 4:
-          sz = kUnsignedWord;
+          sz = compiler::kUnsignedFourBytes;
           break;
         default:
           UNREACHABLE();
@@ -1760,10 +1765,10 @@
     case kExternalTwoByteStringCid:
       switch (element_count()) {
         case 1:
-          sz = kUnsignedHalfword;
+          sz = compiler::kUnsignedTwoBytes;
           break;
         case 2:
-          sz = kUnsignedWord;
+          sz = compiler::kUnsignedFourBytes;
           break;
         default:
           UNREACHABLE();
@@ -1935,10 +1940,10 @@
       if (locs()->in(2).IsConstant()) {
         const Smi& constant = Smi::Cast(locs()->in(2).constant());
         __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()));
-        __ str(TMP, element_address, kUnsignedByte);
+        __ str(TMP, element_address, compiler::kUnsignedByte);
       } else {
         const Register value = locs()->in(2).reg();
-        __ str(value, element_address, kUnsignedByte);
+        __ str(value, element_address, compiler::kUnsignedByte);
       }
       break;
     }
@@ -1955,14 +1960,14 @@
           value = 0;
         }
         __ LoadImmediate(TMP, static_cast<int8_t>(value));
-        __ str(TMP, element_address, kUnsignedByte);
+        __ str(TMP, element_address, compiler::kUnsignedByte);
       } else {
         const Register value = locs()->in(2).reg();
         // Clamp to 0x00 or 0xFF respectively.
         __ CompareImmediate(value, 0xFF);
         __ csetm(TMP, GT);             // TMP = value > 0xFF ? -1 : 0.
         __ csel(TMP, value, TMP, LS);  // TMP = value in range ? value : TMP.
-        __ str(TMP, element_address, kUnsignedByte);
+        __ str(TMP, element_address, compiler::kUnsignedByte);
       }
       break;
     }
@@ -1971,19 +1976,19 @@
     case kTypedDataUint16ArrayCid: {
       ASSERT(RequiredInputRepresentation(2) == kUnboxedIntPtr);
       const Register value = locs()->in(2).reg();
-      __ str(value, element_address, kUnsignedHalfword);
+      __ str(value, element_address, compiler::kUnsignedTwoBytes);
       break;
     }
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid: {
       const Register value = locs()->in(2).reg();
-      __ str(value, element_address, kUnsignedWord);
+      __ str(value, element_address, compiler::kUnsignedFourBytes);
       break;
     }
     case kTypedDataInt64ArrayCid:
     case kTypedDataUint64ArrayCid: {
       const Register value = locs()->in(2).reg();
-      __ str(value, element_address, kDoubleWord);
+      __ str(value, element_address, compiler::kEightBytes);
       break;
     }
     case kTypedDataFloat32ArrayCid: {
@@ -2100,24 +2105,25 @@
     __ LoadObject(field_reg, Field::ZoneHandle((field().Original())));
 
     compiler::FieldAddress field_cid_operand(
-        field_reg, Field::guarded_cid_offset(), kUnsignedHalfword);
+        field_reg, Field::guarded_cid_offset(), compiler::kUnsignedTwoBytes);
     compiler::FieldAddress field_nullability_operand(
-        field_reg, Field::is_nullable_offset(), kUnsignedHalfword);
+        field_reg, Field::is_nullable_offset(), compiler::kUnsignedTwoBytes);
 
     if (value_cid == kDynamicCid) {
       LoadValueCid(compiler, value_cid_reg, value_reg);
       compiler::Label skip_length_check;
-      __ ldr(TMP, field_cid_operand, kUnsignedHalfword);
+      __ ldr(TMP, field_cid_operand, compiler::kUnsignedTwoBytes);
       __ CompareRegisters(value_cid_reg, TMP);
       __ b(&ok, EQ);
-      __ ldr(TMP, field_nullability_operand, kUnsignedHalfword);
+      __ ldr(TMP, field_nullability_operand, compiler::kUnsignedTwoBytes);
       __ CompareRegisters(value_cid_reg, TMP);
     } else if (value_cid == kNullCid) {
-      __ ldr(value_cid_reg, field_nullability_operand, kUnsignedHalfword);
+      __ ldr(value_cid_reg, field_nullability_operand,
+             compiler::kUnsignedTwoBytes);
       __ CompareImmediate(value_cid_reg, value_cid);
     } else {
       compiler::Label skip_length_check;
-      __ ldr(value_cid_reg, field_cid_operand, kUnsignedHalfword);
+      __ ldr(value_cid_reg, field_cid_operand, compiler::kUnsignedTwoBytes);
       __ CompareImmediate(value_cid_reg, value_cid);
     }
     __ b(&ok, EQ);
@@ -2131,17 +2137,18 @@
     if (!field().needs_length_check()) {
       // Uninitialized field can be handled inline. Check if the
       // field is still unitialized.
-      __ ldr(TMP, field_cid_operand, kUnsignedHalfword);
+      __ ldr(TMP, field_cid_operand, compiler::kUnsignedTwoBytes);
       __ CompareImmediate(TMP, kIllegalCid);
       __ b(fail, NE);
 
       if (value_cid == kDynamicCid) {
-        __ str(value_cid_reg, field_cid_operand, kUnsignedHalfword);
-        __ str(value_cid_reg, field_nullability_operand, kUnsignedHalfword);
+        __ str(value_cid_reg, field_cid_operand, compiler::kUnsignedTwoBytes);
+        __ str(value_cid_reg, field_nullability_operand,
+               compiler::kUnsignedTwoBytes);
       } else {
         __ LoadImmediate(TMP, value_cid);
-        __ str(TMP, field_cid_operand, kUnsignedHalfword);
-        __ str(TMP, field_nullability_operand, kUnsignedHalfword);
+        __ str(TMP, field_cid_operand, compiler::kUnsignedTwoBytes);
+        __ str(TMP, field_nullability_operand, compiler::kUnsignedTwoBytes);
       }
 
       __ b(&ok);
@@ -2152,7 +2159,7 @@
       __ Bind(fail);
 
       __ LoadFieldFromOffset(TMP, field_reg, Field::guarded_cid_offset(),
-                             kUnsignedHalfword);
+                             compiler::kUnsignedTwoBytes);
       __ CompareImmediate(TMP, kDynamicCid);
       __ b(&ok, EQ);
 
@@ -2242,7 +2249,7 @@
     __ ldr(offset_reg,
            compiler::FieldAddress(
                field_reg, Field::guarded_list_length_in_object_offset_offset()),
-           kByte);
+           compiler::kByte);
     __ ldr(length_reg, compiler::FieldAddress(
                            field_reg, Field::guarded_list_length_offset()));
 
@@ -2495,27 +2502,27 @@
     __ LoadObject(temp, Field::ZoneHandle(Z, slot().field().Original()));
 
     __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(),
-                           kUnsignedHalfword);
+                           compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp2, kNullCid);
     __ b(&store_pointer, EQ);
 
     __ LoadFromOffset(temp2, temp, Field::kind_bits_offset() - kHeapObjectTag,
-                      kUnsignedByte);
+                      compiler::kUnsignedByte);
     __ tsti(temp2, compiler::Immediate(1 << Field::kUnboxingCandidateBit));
     __ b(&store_pointer, EQ);
 
     __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           kUnsignedHalfword);
+                           compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp2, kDoubleCid);
     __ b(&store_double, EQ);
 
     __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           kUnsignedHalfword);
+                           compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp2, kFloat32x4Cid);
     __ b(&store_float32x4, EQ);
 
     __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           kUnsignedHalfword);
+                           compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp2, kFloat64x2Cid);
     __ b(&store_float64x2, EQ);
 
@@ -2819,12 +2826,12 @@
       case kUnboxedUint32:
         __ Comment("UnboxedUint32LoadFieldInstr");
         __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes(),
-                               kUnsignedWord);
+                               compiler::kUnsignedFourBytes);
         break;
       case kUnboxedUint8:
         __ Comment("UnboxedUint8LoadFieldInstr");
         __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes(),
-                               kUnsignedByte);
+                               compiler::kUnsignedByte);
         break;
       default:
         UNIMPLEMENTED();
@@ -2889,23 +2896,23 @@
     __ LoadObject(result_reg, Field::ZoneHandle(slot().field().Original()));
 
     compiler::FieldAddress field_cid_operand(
-        result_reg, Field::guarded_cid_offset(), kUnsignedHalfword);
+        result_reg, Field::guarded_cid_offset(), compiler::kUnsignedTwoBytes);
     compiler::FieldAddress field_nullability_operand(
-        result_reg, Field::is_nullable_offset(), kUnsignedHalfword);
+        result_reg, Field::is_nullable_offset(), compiler::kUnsignedTwoBytes);
 
-    __ ldr(temp, field_nullability_operand, kUnsignedHalfword);
+    __ ldr(temp, field_nullability_operand, compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp, kNullCid);
     __ b(&load_pointer, EQ);
 
-    __ ldr(temp, field_cid_operand, kUnsignedHalfword);
+    __ ldr(temp, field_cid_operand, compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp, kDoubleCid);
     __ b(&load_double, EQ);
 
-    __ ldr(temp, field_cid_operand, kUnsignedHalfword);
+    __ ldr(temp, field_cid_operand, compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp, kFloat32x4Cid);
     __ b(&load_float32x4, EQ);
 
-    __ ldr(temp, field_cid_operand, kUnsignedHalfword);
+    __ ldr(temp, field_cid_operand, compiler::kUnsignedTwoBytes);
     __ CompareImmediate(temp, kFloat64x2Cid);
     __ b(&load_float64x2, EQ);
 
@@ -3334,10 +3341,10 @@
     intptr_t threshold =
         FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ LoadFieldFromOffset(TMP, function, Function::usage_counter_offset(),
-                           kWord);
+                           compiler::kFourBytes);
     __ add(TMP, TMP, compiler::Operand(1));
     __ StoreFieldToOffset(TMP, function, Function::usage_counter_offset(),
-                          kWord);
+                          compiler::kFourBytes);
     __ CompareImmediate(TMP, threshold);
     __ b(slow_path->osr_entry_label(), GE);
   }
@@ -4157,8 +4164,10 @@
   compiler::Label done;
   __ SmiUntag(result, value);
   __ BranchIfSmi(value, &done);
-  __ ldr(result, compiler::FieldAddress(value, Mint::value_offset(), kWord),
-         kWord);
+  __ ldr(
+      result,
+      compiler::FieldAddress(value, Mint::value_offset(), compiler::kFourBytes),
+      compiler::kFourBytes);
   __ LoadFieldFromOffset(result, value, Mint::value_offset());
   __ Bind(&done);
 }
@@ -6017,10 +6026,10 @@
   } else {
     switch (op_kind) {
       case Token::kSHR:
-        __ LsrImmediate(out, left, shift, kWord);
+        __ LsrImmediate(out, left, shift, compiler::kFourBytes);
         break;
       case Token::kSHL:
-        __ LslImmediate(out, left, shift, kWord);
+        __ LslImmediate(out, left, shift, compiler::kFourBytes);
         break;
       default:
         UNREACHABLE();
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
index dcc40c0..6c30d95 100644
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ b/runtime/vm/compiler/backend/il_deserializer.cc
@@ -2327,7 +2327,7 @@
   }
 
   ASSERT(parsed_function_ != nullptr);
-  const auto& ic_data = ICData::ZoneHandle(
+  auto& ic_data = ICData::ZoneHandle(
       zone(), ICData::New(parsed_function_->function(), *function_name,
                           arguments_descriptor, inst->deopt_id(),
                           num_args_checked, rebind_rule, *type_ptr));
@@ -2360,7 +2360,9 @@
         StoreError(entry, "expected a zero count for no checked args");
         return false;
       }
-      ic_data.AddTarget(target);
+      ic_data = ICData::NewForStaticCall(parsed_function_->function(), target,
+                                         arguments_descriptor, inst->deopt_id(),
+                                         num_args_checked, rebind_rule);
       continue;
     }
 
@@ -2386,7 +2388,7 @@
   }
 
   if (auto const call = inst->AsInstanceCall()) {
-    call->set_ic_data(&ic_data);
+    call->set_ic_data(const_cast<const ICData*>(&ic_data));
   } else if (auto const call = inst->AsStaticCall()) {
     call->set_ic_data(&ic_data);
   }
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 54356ba..985299e 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -496,13 +496,15 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(TypeTestABI::kInstanceReg));
+  summary->set_in(kInstancePos,
+                  Location::RegisterLocation(TypeTestABI::kInstanceReg));
+  summary->set_in(kDstTypePos, LocationFixedRegisterOrConstant(
+                                   dst_type(), TypeTestABI::kDstTypeReg));
   summary->set_in(
-      1, LocationFixedRegisterOrConstant(dst_type(), TypeTestABI::kDstTypeReg));
-  summary->set_in(2, Location::RegisterLocation(
-                         TypeTestABI::kInstantiatorTypeArgumentsReg));
-  summary->set_in(
-      3, Location::RegisterLocation(TypeTestABI::kFunctionTypeArgumentsReg));
+      kInstantiatorTAVPos,
+      Location::RegisterLocation(TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kFunctionTAVPos, Location::RegisterLocation(
+                                       TypeTestABI::kFunctionTypeArgumentsReg));
   summary->set_out(0, Location::SameAsFirstInput());
   return summary;
 }
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 50b1287..34af406 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -337,6 +337,10 @@
   __ set_constant_pool_allowed(true);
 }
 
+static const RegisterSet kCalleeSaveRegistersSet(
+    CallingConventions::kCalleeSaveCpuRegisters,
+    CallingConventions::kCalleeSaveXmmRegisters);
+
 void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   EmitReturnMoves(compiler);
 
@@ -369,8 +373,7 @@
       /*enter_safepoint=*/!NativeCallbackTrampolines::Enabled());
 
   // Restore C++ ABI callee-saved registers.
-  __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                  CallingConventions::kCalleeSaveXmmRegisters);
+  __ PopRegisters(kCalleeSaveRegistersSet);
 
 #if defined(TARGET_OS_FUCHSIA)
   UNREACHABLE();  // Fuchsia does not allow dart:ffi.
@@ -624,12 +627,14 @@
 
   LocationSummary* summary = new (zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCallCalleeSafe);
-  summary->set_in(0, Location::RegisterLocation(TypeTestABI::kInstanceReg));
-  summary->set_in(1, dst_type_loc);
-  summary->set_in(2, Location::RegisterLocation(
-                         TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kInstancePos,
+                  Location::RegisterLocation(TypeTestABI::kInstanceReg));
+  summary->set_in(kDstTypePos, dst_type_loc);
   summary->set_in(
-      3, Location::RegisterLocation(TypeTestABI::kFunctionTypeArgumentsReg));
+      kInstantiatorTAVPos,
+      Location::RegisterLocation(TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(kFunctionTAVPos, Location::RegisterLocation(
+                                       TypeTestABI::kFunctionTypeArgumentsReg));
   summary->set_out(0, Location::SameAsFirstInput());
 
   // Let's reserve all registers except for the input ones.
@@ -1148,8 +1153,7 @@
   __ PushImmediate(compiler::Immediate(0));
 
   // Save ABI callee-saved registers.
-  __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                   CallingConventions::kCalleeSaveXmmRegisters);
+  __ PushRegisters(kCalleeSaveRegistersSet);
 
   // Load the address of DLRT_GetThreadForNativeCallback without using Thread.
   if (FLAG_precompiled_mode) {
@@ -4553,7 +4557,7 @@
   if (compiler->intrinsic_mode()) {
     __ TryAllocate(compiler->mint_class(),
                    compiler->intrinsic_slow_path_label(),
-                   /*near_jump=*/true, out, temp);
+                   compiler::Assembler::kNearJump, out, temp);
   } else if (locs()->call_on_shared_slow_path()) {
     auto object_store = compiler->isolate()->object_store();
     const bool live_fpu_regs = locs()->live_registers()->FpuRegisterCount() > 0;
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index 1d29a39..942e10a 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -538,6 +538,12 @@
     ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte));
   }
 
+  explicit RegisterSet(intptr_t cpu_register_mask,
+                       intptr_t fpu_register_mask = 0)
+      : RegisterSet() {
+    AddTaggedRegisters(cpu_register_mask, fpu_register_mask);
+  }
+
   void AddAllNonReservedRegisters(bool include_fpu_registers) {
     for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
       if ((kReservedCpuRegisters & (1 << i)) != 0u) continue;
@@ -594,6 +600,22 @@
 #endif
   }
 
+  void AddTaggedRegisters(intptr_t cpu_register_mask,
+                          intptr_t fpu_register_mask) {
+    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+      if (Utils::TestBit(cpu_register_mask, i)) {
+        const Register reg = static_cast<Register>(i);
+        Add(Location::RegisterLocation(reg));
+      }
+    }
+    for (intptr_t i = 0; i < kNumberOfFpuRegisters; ++i) {
+      if (Utils::TestBit(fpu_register_mask, i)) {
+        const FpuRegister reg = static_cast<FpuRegister>(i);
+        Add(Location::FpuRegisterLocation(reg));
+      }
+    }
+  }
+
   void Add(Location loc, Representation rep = kTagged) {
     if (loc.IsRegister()) {
       cpu_registers_.Add(loc.reg());
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 4018099..8a60a63 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2736,6 +2736,8 @@
     case Slot::Kind::kTypeParameter_name:
     case Slot::Kind::kUnhandledException_exception:
     case Slot::Kind::kUnhandledException_stacktrace:
+    case Slot::Kind::kWeakProperty_key:
+    case Slot::Kind::kWeakProperty_value:
       // Not an integer valued field.
       UNREACHABLE();
       break;
@@ -2766,10 +2768,7 @@
       break;
 
     case Slot::Kind::kClosureData_default_type_arguments_info:
-      *range = Range(
-          RangeBoundary::FromConstant(0),
-          RangeBoundary::FromConstant(
-              (1 << Function::NumParentTypeParametersField::kNextBit) - 1));
+      *range = Range(RangeBoundary::FromConstant(0), RangeBoundary::MaxSmi());
   }
 }
 
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 8118b63..269a793 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3694,7 +3694,7 @@
                                                    alloc_object->cls()));
     }
   }
-  if (auto create_array = alloc->AsCreateArray()) {
+  if (alloc->IsCreateArray()) {
     AddSlot(slots,
             Slot::GetTypeArgumentsSlotFor(
                 flow_graph_->thread(),
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 1c348aa..f0a4f2c 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -110,10 +110,18 @@
   return kIllegalCid;
 }
 
+AcqRelAtomic<Slot*> Slot::native_fields_(nullptr);
+
+enum NativeSlotsEnumeration {
+#define DECLARE_KIND(CN, __, FN, ___, ____) k##CN##_##FN,
+  NATIVE_SLOTS_LIST(DECLARE_KIND)
+#undef DECLARE_KIND
+      kNativeSlotsCount
+};
+
 const Slot& Slot::GetNativeSlot(Kind kind) {
-  // There is a fixed statically known number of native slots so we cache
-  // them statically.
-  static const Slot fields[] = {
+  if (native_fields_.load() == nullptr) {
+    Slot* new_value = new Slot[kNativeSlotsCount]{
 #define NULLABLE_FIELD_FINAL                                                   \
   (IsNullableBit::encode(true) | IsImmutableBit::encode(true))
 #define NULLABLE_FIELD_VAR (IsNullableBit::encode(true))
@@ -123,7 +131,7 @@
        k##cid##Cid, compiler::target::ClassName::FieldName##_offset(),         \
        #ClassName "." #FieldName, nullptr, kTagged),
 
-      NULLABLE_BOXED_NATIVE_SLOTS_LIST(DEFINE_NULLABLE_BOXED_NATIVE_FIELD)
+        NULLABLE_BOXED_NATIVE_SLOTS_LIST(DEFINE_NULLABLE_BOXED_NATIVE_FIELD)
 
 #undef DEFINE_NULLABLE_BOXED_NATIVE_FIELD
 #undef NULLABLE_FIELD_FINAL
@@ -137,8 +145,8 @@
        k##cid##Cid, compiler::target::ClassName::FieldName##_offset(),         \
        #ClassName "." #FieldName, nullptr, kTagged),
 
-          NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(
-              DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD)
+            NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(
+                DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD)
 
 #undef DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD
 #define DEFINE_UNBOXED_NATIVE_FIELD(ClassName, UnderlyingType, FieldName,      \
@@ -148,15 +156,20 @@
        compiler::target::ClassName::FieldName##_offset(),                      \
        #ClassName "." #FieldName, nullptr, kUnboxed##representation),
 
-              UNBOXED_NATIVE_SLOTS_LIST(DEFINE_UNBOXED_NATIVE_FIELD)
+                UNBOXED_NATIVE_SLOTS_LIST(DEFINE_UNBOXED_NATIVE_FIELD)
 
 #undef DEFINE_UNBOXED_NATIVE_FIELD
 #undef NONNULLABLE_FIELD_VAR
 #undef NONNULLABLE_FIELD_FINAL
-  };
+    };
+    Slot* old_value = nullptr;
+    if (!native_fields_.compare_exchange_strong(old_value, new_value)) {
+      delete[] new_value;
+    }
+  }
 
-  ASSERT(static_cast<uint8_t>(kind) < ARRAY_SIZE(fields));
-  return fields[static_cast<uint8_t>(kind)];
+  ASSERT(static_cast<uint8_t>(kind) < kNativeSlotsCount);
+  return native_fields_.load()[static_cast<uint8_t>(kind)];
 }
 
 // Note: should only be called with cids of array-like classes.
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 8c24078..4e2414f 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -59,7 +59,9 @@
   V(ClosureData, ClosureDataLayout, default_type_arguments, TypeArguments,     \
     FINAL)                                                                     \
   V(Function, FunctionLayout, type_parameters, TypeArguments, FINAL)           \
-  V(Type, TypeLayout, arguments, TypeArguments, FINAL)
+  V(Type, TypeLayout, arguments, TypeArguments, FINAL)                         \
+  V(WeakProperty, WeakPropertyLayout, key, Dynamic, VAR)                       \
+  V(WeakProperty, WeakPropertyLayout, value, Dynamic, VAR)
 
 // The list of slots that correspond to non-nullable boxed fields of native
 // objects in the following format:
@@ -295,6 +297,9 @@
     return static_cast<const T*>(data_);
   }
 
+  // There is a fixed statically known number of native slots so we cache
+  // them statically.
+  static AcqRelAtomic<Slot*> native_fields_;
   static const Slot& GetNativeSlot(Kind kind);
 
   const Kind kind_;
diff --git a/runtime/vm/compiler/backend/slot_test.cc b/runtime/vm/compiler/backend/slot_test.cc
index a506698..8c4b620 100644
--- a/runtime/vm/compiler/backend/slot_test.cc
+++ b/runtime/vm/compiler/backend/slot_test.cc
@@ -59,8 +59,8 @@
                  TokenPosition::kMinSource));
 
   // Set non-trivial guarded state on the field.
-  field.set_guarded_cid(kSmiCid);
-  field.set_is_nullable(false);
+  field.set_guarded_cid_unsafe(kSmiCid);
+  field.set_is_nullable_unsafe(false);
 
   // Enter compiler state.
   CompilerState compiler_state(thread, /*is_aot=*/false);
@@ -87,8 +87,8 @@
   // Change the guarded state of the field to "unknown" - emulating concurrent
   // modification of the guarded state in mutator) and create a new clone of
   // the field.
-  field.set_guarded_cid(kDynamicCid);
-  field.set_is_nullable(true);
+  field.set_guarded_cid_unsafe(kDynamicCid);
+  field.set_is_nullable_unsafe(true);
   const Field& field_clone_3 = Field::ZoneHandle(field.CloneFromOriginal());
 
   // Slot::Get must return the same slot and add the field from which it
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index 73d4014..852a885 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -187,6 +187,11 @@
                  /*is_reflectable=*/true,
                  /*is_late=*/false, object_class, Object::dynamic_type(),
                  TokenPosition::kNoSource, TokenPosition::kNoSource));
+  {
+    SafepointWriteRwLocker locker(thread,
+                                  thread->isolate_group()->program_lock());
+    thread->isolate_group()->RegisterStaticField(field, Instance::Handle());
+  }
 
   FlowGraphBuilderHelper H;
 
diff --git a/runtime/vm/compiler/backend/typed_data_aot_test.cc b/runtime/vm/compiler/backend/typed_data_aot_test.cc
index 30d58db..72f41e3 100644
--- a/runtime/vm/compiler/backend/typed_data_aot_test.cc
+++ b/runtime/vm/compiler/backend/typed_data_aot_test.cc
@@ -491,10 +491,6 @@
   ILMatcher cursor(flow_graph, entry, /*trace=*/true);
   RELEASE_ASSERT(cursor.TryMatch(
       {
-          kMatchAndMoveGoto,
-          kMatchAndMoveBranchFalse,
-          kMatchAndMoveAssertAssignable,
-          kMatchAndMoveGoto,
           kMatchAndMoveLoadField,
           kMatchAndMoveGenericCheckBound,
           kMatchAndMoveLoadUntagged,
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index dd1d2fa..1496c09 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -179,8 +179,8 @@
   "backend/typed_data_aot_test.cc",
   "backend/yield_position_test.cc",
   "cha_test.cc",
+  "ffi/native_type_vm_test.cc",
   "frontend/kernel_binary_flowgraph_test.cc",
-  "frontend/multiple_entrypoints_test.cc",
   "write_barrier_elimination_test.cc",
 ]
 
@@ -204,3 +204,11 @@
   "assembler/disassembler_arm64.cc",
   "assembler/disassembler_x86.cc",
 ]
+
+ffi_sources_tests = [
+  "ffi/native_calling_convention_test.cc",
+  "ffi/native_location_test.cc",
+  "ffi/native_type_test.cc",
+  "ffi/unit_test_custom_zone.cc",
+  "ffi/unit_test.cc",
+]
diff --git a/runtime/vm/compiler/ffi/abi.cc b/runtime/vm/compiler/ffi/abi.cc
index f3ea956..1d3bd8b 100644
--- a/runtime/vm/compiler/ffi/abi.cc
+++ b/runtime/vm/compiler/ffi/abi.cc
@@ -51,7 +51,7 @@
 #elif (defined(TARGET_ARCH_IA32) && /* NOLINT(whitespace/parens) */            \
        (defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) ||                \
         defined(TARGET_OS_ANDROID))) ||                                        \
-    (defined(TARGET_ARCH_ARM) && defined(TARGET_OS_IOS))
+    (defined(TARGET_ARCH_ARM) && defined(TARGET_OS_MACOS_IOS))
   return Abi::kWordSize32Align32;
 #elif defined(TARGET_ARCH_IA32) && defined(TARGET_OS_WINDOWS) ||               \
     defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/ffi/marshaller.cc b/runtime/vm/compiler/ffi/marshaller.cc
index c095e9e..6620468 100644
--- a/runtime/vm/compiler/ffi/marshaller.cc
+++ b/runtime/vm/compiler/ffi/marshaller.cc
@@ -4,9 +4,13 @@
 
 #include "vm/compiler/ffi/marshaller.h"
 
+#include "platform/assert.h"
+#include "platform/globals.h"
 #include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/compiler/ffi/native_location.h"
 #include "vm/compiler/ffi/native_type.h"
+#include "vm/log.h"
 #include "vm/raw_object.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
@@ -17,6 +21,56 @@
 
 namespace ffi {
 
+// Argument #0 is the function pointer.
+const intptr_t kNativeParamsStartAt = 1;
+
+// Representations of the arguments and return value of a C signature function.
+static const NativeFunctionType& NativeFunctionSignature(
+    Zone* zone,
+    const Function& c_signature) {
+  ASSERT(c_signature.NumOptionalParameters() == 0);
+  ASSERT(c_signature.NumOptionalPositionalParameters() == 0);
+
+  const intptr_t num_arguments =
+      c_signature.num_fixed_parameters() - kNativeParamsStartAt;
+  auto& argument_representations =
+      *new ZoneGrowableArray<const NativeType*>(zone, num_arguments);
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    AbstractType& arg_type = AbstractType::Handle(
+        zone, c_signature.ParameterTypeAt(i + kNativeParamsStartAt));
+    const auto& rep = NativeType::FromAbstractType(zone, arg_type);
+    argument_representations.Add(&rep);
+  }
+
+  const auto& result_type =
+      AbstractType::Handle(zone, c_signature.result_type());
+  const auto& result_representation =
+      NativeType::FromAbstractType(zone, result_type);
+
+  const auto& result = *new (zone) NativeFunctionType(argument_representations,
+                                                      result_representation);
+  return result;
+}
+
+BaseMarshaller::BaseMarshaller(Zone* zone, const Function& dart_signature)
+    : zone_(zone),
+      dart_signature_(dart_signature),
+      c_signature_(Function::ZoneHandle(zone, dart_signature.FfiCSignature())),
+      native_calling_convention_(NativeCallingConvention::FromSignature(
+          zone,
+          NativeFunctionSignature(zone_, c_signature_))) {
+  ASSERT(dart_signature_.IsZoneHandle());
+}
+
+AbstractTypePtr BaseMarshaller::CType(intptr_t arg_index) const {
+  if (arg_index == kResultIndex) {
+    return c_signature_.result_type();
+  }
+
+  // Skip #0 argument, the function pointer.
+  return c_signature_.ParameterTypeAt(arg_index + kNativeParamsStartAt);
+}
+
 bool BaseMarshaller::ContainsHandles() const {
   return dart_signature_.FfiCSignatureContainsHandles();
 }
@@ -80,14 +134,14 @@
   static NativeLocations& TranslateArgumentLocations(
       Zone* zone,
       const NativeLocations& arg_locs) {
-    auto& pushed_locs = *(new NativeLocations(arg_locs.length()));
+    auto& pushed_locs = *(new (zone) NativeLocations(arg_locs.length()));
 
     CallbackArgumentTranslator translator;
     for (intptr_t i = 0, n = arg_locs.length(); i < n; i++) {
       translator.AllocateArgument(*arg_locs[i]);
     }
     for (intptr_t i = 0, n = arg_locs.length(); i < n; ++i) {
-      pushed_locs.Add(&translator.TranslateArgument(*arg_locs[i], zone));
+      pushed_locs.Add(&translator.TranslateArgument(zone, *arg_locs[i]));
     }
 
     return pushed_locs;
@@ -97,16 +151,17 @@
   void AllocateArgument(const NativeLocation& arg) {
     if (arg.IsStack()) return;
 
-    ASSERT(arg.IsRegisters() || arg.IsFpuRegisters());
     if (arg.IsRegisters()) {
       argument_slots_required_ += arg.AsRegisters().num_regs();
-    } else {
+    } else if (arg.IsFpuRegisters()) {
       argument_slots_required_ += 8 / target::kWordSize;
+    } else {
+      UNREACHABLE();
     }
   }
 
-  const NativeLocation& TranslateArgument(const NativeLocation& arg,
-                                          Zone* zone) {
+  const NativeLocation& TranslateArgument(Zone* zone,
+                                          const NativeLocation& arg) {
     if (arg.IsStack()) {
       // Add extra slots after the saved arguments for the return address and
       // frame pointer of the dummy arguments frame, which will be between the
@@ -152,10 +207,9 @@
 CallbackMarshaller::CallbackMarshaller(Zone* zone,
                                        const Function& dart_signature)
     : BaseMarshaller(zone, dart_signature),
-      callback_locs_(
-          CallbackArgumentTranslator::TranslateArgumentLocations(zone_,
-                                                                 arg_locs_)) {}
-
+      callback_locs_(CallbackArgumentTranslator::TranslateArgumentLocations(
+          zone_,
+          native_calling_convention_.argument_locations())) {}
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/marshaller.h b/runtime/vm/compiler/ffi/marshaller.h
index d175ddc..be567b6 100644
--- a/runtime/vm/compiler/ffi/marshaller.h
+++ b/runtime/vm/compiler/ffi/marshaller.h
@@ -11,6 +11,7 @@
 
 #include <platform/globals.h>
 
+#include "platform/assert.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/ffi/callback.h"
 #include "vm/compiler/ffi/native_calling_convention.h"
@@ -24,16 +25,32 @@
 
 namespace ffi {
 
+// Values below 0 index result (result might be multiple if composite).
+const intptr_t kResultIndex = -1;
+
 // Provides the mapping from the native calling convention to the Dart calling
 // convention.
 //
 // This class is set up in a query-able way so that it's underlying logic can
 // be extended to support more native ABI features and calling conventions.
-//
-// TODO(36730): Add a way to query arguments that are broken into multiple
-// parts.
-class BaseMarshaller : public NativeCallingConvention {
+class BaseMarshaller : public ZoneAllocated {
  public:
+  intptr_t num_args() const {
+    return native_calling_convention_.argument_locations().length();
+  }
+
+  intptr_t StackTopInBytes() const {
+    return native_calling_convention_.StackTopInBytes();
+  }
+
+  // The location of the argument at `arg_index`.
+  const NativeLocation& Location(intptr_t arg_index) const {
+    if (arg_index == kResultIndex) {
+      return native_calling_convention_.return_location();
+    }
+    return *native_calling_convention_.argument_locations().At(arg_index);
+  }
+
   // Unboxed representation on how the value is passed or received from regular
   // Dart code.
   Representation RepInDart(intptr_t arg_index) const {
@@ -62,6 +79,11 @@
     return Location(arg_index).payload_type();
   }
 
+  // The C Type (expressed in a Dart Type) of the argument at `arg_index`.
+  //
+  // Excluding the #0 argument which is the function pointer.
+  AbstractTypePtr CType(intptr_t arg_index) const;
+
   // Requires boxing or unboxing.
   bool IsPointer(intptr_t arg_index) const {
     return AbstractType::Handle(zone_, CType(arg_index)).type_class_id() ==
@@ -83,18 +105,16 @@
   StringPtr function_name() const { return dart_signature_.name(); }
 
  protected:
-  BaseMarshaller(Zone* zone, const Function& dart_signature)
-      : NativeCallingConvention(
-            zone,
-            Function::ZoneHandle(zone, dart_signature.FfiCSignature())),
-        dart_signature_(dart_signature) {
-    ASSERT(dart_signature_.IsZoneHandle());
-  }
+  BaseMarshaller(Zone* zone, const Function& dart_signature);
 
- private:
+  ~BaseMarshaller() {}
+
+  Zone* zone_;
   // Contains the function pointer as argument #0.
   // The Dart signature is used for the function and argument names.
   const Function& dart_signature_;
+  const Function& c_signature_;
+  const NativeCallingConvention& native_calling_convention_;
 };
 
 class CallMarshaller : public BaseMarshaller {
@@ -103,6 +123,9 @@
       : BaseMarshaller(zone, dart_signature) {}
 
   dart::Location LocInFfiCall(intptr_t arg_index) const;
+
+ protected:
+  ~CallMarshaller() {}
 };
 
 class CallbackMarshaller : public BaseMarshaller {
@@ -125,6 +148,8 @@
   }
 
  protected:
+  ~CallbackMarshaller() {}
+
   const NativeLocations& callback_locs_;
 };
 
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc
index 84081aa..e53a1e8 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.cc
+++ b/runtime/vm/compiler/ffi/native_calling_convention.cc
@@ -4,11 +4,13 @@
 
 #include "vm/compiler/ffi/native_calling_convention.h"
 
-#include "vm/compiler/ffi/marshaller.h"
 #include "vm/compiler/ffi/native_location.h"
 #include "vm/compiler/ffi/native_type.h"
-#include "vm/log.h"
-#include "vm/symbols.h"
+#include "vm/zone_text_buffer.h"
+
+#if !defined(FFI_UNIT_TESTS)
+#include "vm/cpu.h"
+#endif
 
 namespace dart {
 
@@ -16,11 +18,9 @@
 
 namespace ffi {
 
-// Argument #0 is the function pointer.
-const intptr_t kNativeParamsStartAt = 1;
-
 const intptr_t kNoFpuRegister = -1;
 
+#if !defined(FFI_UNIT_TESTS)
 // In Soft FP, floats and doubles get passed in integer registers.
 static bool SoftFpAbi() {
 #if defined(TARGET_ARCH_ARM)
@@ -29,6 +29,15 @@
   return false;
 #endif
 }
+#else  // !defined(FFI_UNIT_TESTS)
+static bool SoftFpAbi() {
+#if defined(TARGET_ARCH_ARM) && defined(TARGET_OS_ANDROID)
+  return true;
+#else
+  return false;
+#endif
+}
+#endif  // !defined(FFI_UNIT_TESTS)
 
 // In Soft FP, floats are treated as 4 byte ints, and doubles as 8 byte ints.
 static const NativeType& ConvertIfSoftFp(Zone* zone, const NativeType& rep) {
@@ -44,28 +53,12 @@
   return rep;
 }
 
-// Representations of the arguments to a C signature function.
-static ZoneGrowableArray<const NativeType*>& ArgumentRepresentations(
-    Zone* zone,
-    const Function& signature) {
-  const intptr_t num_arguments =
-      signature.num_fixed_parameters() - kNativeParamsStartAt;
-  auto& result = *new ZoneGrowableArray<const NativeType*>(zone, num_arguments);
-  for (intptr_t i = 0; i < num_arguments; i++) {
-    AbstractType& arg_type = AbstractType::Handle(
-        zone, signature.ParameterTypeAt(i + kNativeParamsStartAt));
-    const auto& rep = NativeType::FromAbstractType(zone, arg_type);
-    result.Add(&rep);
-  }
-  return result;
-}
-
-// Representation of the result of a C signature function.
-static NativeType& ResultRepresentation(Zone* zone, const Function& signature) {
-  AbstractType& result_type =
-      AbstractType::Handle(zone, signature.result_type());
-  return NativeType::FromAbstractType(zone, result_type);
-}
+// The native dual of `kUnboxedFfiIntPtr`.
+//
+// It has the same signedness as `kUnboxedFfiIntPtr` to avoid sign conversions
+// when converting between both.
+const PrimitiveType kFfiIntPtr =
+    compiler::target::kWordSize == 8 ? kInt64 : kUint32;
 
 // Represents the state of a stack frame going into a call, between allocations
 // of argument locations.
@@ -76,53 +69,287 @@
   const NativeLocation& AllocateArgument(const NativeType& payload_type) {
     const auto& payload_type_converted = ConvertIfSoftFp(zone_, payload_type);
     if (payload_type_converted.IsFloat()) {
-      const auto kind = FpuRegKind(payload_type);
-      const intptr_t reg_index = FirstFreeFpuRegisterIndex(kind);
-      if (reg_index != kNoFpuRegister) {
-        AllocateFpuRegisterAtIndex(kind, reg_index);
-        if (CallingConventions::kArgumentIntRegXorFpuReg) {
-          cpu_regs_used++;
-        }
-        return *new (zone_) NativeFpuRegistersLocation(
-            payload_type, payload_type, kind, reg_index);
-      } else {
-        BlockAllFpuRegisters();
-        if (CallingConventions::kArgumentIntRegXorFpuReg) {
-          ASSERT(cpu_regs_used == CallingConventions::kNumArgRegs);
-        }
+      return AllocateFloat(payload_type);
+    }
+    if (payload_type_converted.IsInt()) {
+      return AllocateInt(payload_type);
+    }
+
+    // Compounds are laid out differently per ABI, so they are implemented
+    // per ABI.
+    //
+    // Compounds always have a PointerToMemory, Stack, or Multiple location,
+    // even if the parts of a compound fit in 1 cpu or fpu register it will
+    // be nested in a MultipleNativeLocations.
+    const NativeCompoundType& compound_type = payload_type.AsCompound();
+    return AllocateCompound(compound_type);
+  }
+
+ private:
+  const NativeLocation& AllocateFloat(const NativeType& payload_type) {
+    const auto kind = FpuRegKind(payload_type);
+    const intptr_t reg_index = FirstFreeFpuRegisterIndex(kind);
+    if (reg_index != kNoFpuRegister) {
+      AllocateFpuRegisterAtIndex(kind, reg_index);
+      if (CallingConventions::kArgumentIntRegXorFpuReg) {
+        cpu_regs_used++;
+      }
+      return *new (zone_) NativeFpuRegistersLocation(payload_type, payload_type,
+                                                     kind, reg_index);
+    }
+
+    BlockAllFpuRegisters();
+    if (CallingConventions::kArgumentIntRegXorFpuReg) {
+      ASSERT(cpu_regs_used == CallingConventions::kNumArgRegs);
+    }
+    return AllocateStack(payload_type);
+  }
+
+  const NativeLocation& AllocateInt(const NativeType& payload_type) {
+    const auto& payload_type_converted = ConvertIfSoftFp(zone_, payload_type);
+
+    // Some calling conventions require the callee to make the lowest 32 bits
+    // in registers non-garbage.
+    const auto& container_type =
+        CallingConventions::kArgumentRegisterExtension == kExtendedTo4
+            ? payload_type_converted.WidenTo4Bytes(zone_)
+            : payload_type_converted;
+    if (target::kWordSize == 4 && payload_type.SizeInBytes() == 8) {
+      if (CallingConventions::kArgumentRegisterAlignment ==
+          kAlignedToWordSizeBut8AlignedTo8) {
+        cpu_regs_used += cpu_regs_used % 2;
+      }
+      if (cpu_regs_used + 2 <= CallingConventions::kNumArgRegs) {
+        const Register register_1 = AllocateCpuRegister();
+        const Register register_2 = AllocateCpuRegister();
+        return *new (zone_) NativeRegistersLocation(
+            zone_, payload_type, container_type, register_1, register_2);
       }
     } else {
-      ASSERT(payload_type_converted.IsInt());
-      // Some calling conventions require the callee to make the lowest 32 bits
-      // in registers non-garbage.
-      const auto& container_type =
-          CallingConventions::kArgumentRegisterExtension == kExtendedTo4
-              ? payload_type_converted.WidenTo4Bytes(zone_)
-              : payload_type_converted;
-      if (target::kWordSize == 4 && payload_type.SizeInBytes() == 8) {
-        if (CallingConventions::kArgumentRegisterAlignment ==
-            kAlignedToWordSizeBut8AlignedTo8) {
-          cpu_regs_used += cpu_regs_used % 2;
-        }
-        if (cpu_regs_used + 2 <= CallingConventions::kNumArgRegs) {
-          const Register register_1 = AllocateCpuRegister();
-          const Register register_2 = AllocateCpuRegister();
-          return *new (zone_) NativeRegistersLocation(
-              payload_type, container_type, register_1, register_2);
-        }
-      } else {
-        ASSERT(payload_type.SizeInBytes() <= target::kWordSize);
-        if (cpu_regs_used + 1 <= CallingConventions::kNumArgRegs) {
-          return *new (zone_) NativeRegistersLocation(
-              payload_type, container_type, AllocateCpuRegister());
-        }
+      ASSERT(payload_type.SizeInBytes() <= target::kWordSize);
+      if (cpu_regs_used + 1 <= CallingConventions::kNumArgRegs) {
+        return *new (zone_) NativeRegistersLocation(
+            zone_, payload_type, container_type, AllocateCpuRegister());
       }
     }
+    return AllocateStack(payload_type);
+  }
+
+#if defined(TARGET_ARCH_X64) && !defined(TARGET_OS_WINDOWS)
+  // If fits in two fpu and/or cpu registers, transfer in those. Otherwise,
+  // transfer on stack.
+  const NativeLocation& AllocateCompound(
+      const NativeCompoundType& payload_type) {
+    const intptr_t size = payload_type.SizeInBytes();
+    if (size <= 16 && size > 0) {
+      intptr_t required_regs =
+          payload_type.NumberOfWordSizeChunksNotOnlyFloat();
+      intptr_t required_xmm_regs =
+          payload_type.NumberOfWordSizeChunksOnlyFloat();
+      const bool regs_available =
+          cpu_regs_used + required_regs <= CallingConventions::kNumArgRegs;
+      const bool fpu_regs_available =
+          FirstFreeFpuRegisterIndex(kQuadFpuReg) != kNoFpuRegister &&
+          FirstFreeFpuRegisterIndex(kQuadFpuReg) + required_xmm_regs <=
+              CallingConventions::kNumFpuArgRegs;
+      if (regs_available && fpu_regs_available) {
+        // Transfer in registers.
+        NativeLocations& multiple_locations = *new (zone_) NativeLocations(
+            zone_, required_regs + required_xmm_regs);
+        for (intptr_t offset = 0; offset < size;
+             offset += compiler::target::kWordSize) {
+          if (payload_type.ContainsOnlyFloats(
+                  offset, Utils::Minimum<intptr_t>(size - offset, 8))) {
+            const intptr_t reg_index = FirstFreeFpuRegisterIndex(kQuadFpuReg);
+            AllocateFpuRegisterAtIndex(kQuadFpuReg, reg_index);
+            const auto& type = *new (zone_) NativePrimitiveType(kDouble);
+            multiple_locations.Add(new (zone_) NativeFpuRegistersLocation(
+                type, type, kQuadFpuReg, reg_index));
+          } else {
+            const auto& type = *new (zone_) NativePrimitiveType(kInt64);
+            multiple_locations.Add(new (zone_) NativeRegistersLocation(
+                zone_, type, type, AllocateCpuRegister()));
+          }
+        }
+        return *new (zone_)
+            MultipleNativeLocations(payload_type, multiple_locations);
+      }
+    }
+    return AllocateStack(payload_type);
+  }
+#endif  // defined(TARGET_ARCH_X64) && !defined(TARGET_OS_WINDOWS)
+
+#if defined(TARGET_ARCH_X64) && defined(TARGET_OS_WINDOWS)
+  // If struct fits in a single register and size is a power of two, then
+  // use a single register and sign extend.
+  // Otherwise, pass a pointer to a copy.
+  const NativeLocation& AllocateCompound(
+      const NativeCompoundType& payload_type) {
+    const NativeCompoundType& compound_type = payload_type.AsCompound();
+    const intptr_t size = compound_type.SizeInBytes();
+    if (size <= 8 && Utils::IsPowerOfTwo(size)) {
+      if (cpu_regs_used < CallingConventions::kNumArgRegs) {
+        NativeLocations& multiple_locations =
+            *new (zone_) NativeLocations(zone_, 1);
+        const auto& type = *new (zone_) NativePrimitiveType(
+            PrimitiveTypeFromSizeInBytes(size));
+        multiple_locations.Add(new (zone_) NativeRegistersLocation(
+            zone_, type, type, AllocateCpuRegister()));
+        return *new (zone_)
+            MultipleNativeLocations(compound_type, multiple_locations);
+      }
+
+    } else if (size > 0) {
+      // Pointer in register if available, else pointer on stack.
+      const auto& pointer_type = *new (zone_) NativePrimitiveType(kFfiIntPtr);
+      const auto& pointer_location = AllocateArgument(pointer_type);
+      return *new (zone_)
+          PointerToMemoryLocation(pointer_location, compound_type);
+    }
 
     return AllocateStack(payload_type);
   }
+#endif  // defined(TARGET_ARCH_X64) && defined(TARGET_OS_WINDOWS)
 
- private:
+#if defined(TARGET_ARCH_IA32)
+  const NativeLocation& AllocateCompound(
+      const NativeCompoundType& payload_type) {
+    return AllocateStack(payload_type);
+  }
+#endif  // defined(TARGET_ARCH_IA32)
+
+#if defined(TARGET_ARCH_ARM)
+  // Transfer homogenuous floats in FPU registers, and allocate the rest
+  // in 4 or 8 size chunks in registers and stack.
+  const NativeLocation& AllocateCompound(
+      const NativeCompoundType& payload_type) {
+    const auto& compound_type = payload_type.AsCompound();
+    if (compound_type.ContainsHomogenuousFloats() && !SoftFpAbi() &&
+        compound_type.members().length() <= 4) {
+      const auto& elem_type = *(compound_type.members().At(0));
+      const intptr_t size = compound_type.SizeInBytes();
+      const intptr_t elem_size = compound_type.members().At(0)->SizeInBytes();
+      const auto reg_kind = FpuRegisterKindFromSize(elem_size);
+      ASSERT(size % elem_size == 0);
+      const intptr_t num_registers = size / elem_size;
+      const intptr_t first_reg =
+          FirstFreeFpuRegisterIndex(reg_kind, num_registers);
+      if (first_reg != kNoFpuRegister) {
+        AllocateFpuRegisterAtIndex(reg_kind, first_reg, num_registers);
+
+        NativeLocations& multiple_locations =
+            *new (zone_) NativeLocations(zone_, num_registers);
+        for (int i = 0; i < num_registers; i++) {
+          const intptr_t reg_index = first_reg + i;
+          multiple_locations.Add(new (zone_) NativeFpuRegistersLocation(
+              elem_type, elem_type, reg_kind, reg_index));
+        }
+        return *new (zone_)
+            MultipleNativeLocations(compound_type, multiple_locations);
+
+      } else {
+        BlockAllFpuRegisters();
+        return AllocateStack(payload_type);
+      }
+    } else {
+      const intptr_t chunck_size = payload_type.AlignmentInBytesStack();
+      ASSERT(chunck_size == 4 || chunck_size == 8);
+      const intptr_t size_rounded =
+          Utils::RoundUp(payload_type.SizeInBytes(), chunck_size);
+      const intptr_t num_chuncks = size_rounded / chunck_size;
+      const auto& chuck_type =
+          *new (zone_) NativePrimitiveType(chunck_size == 4 ? kInt32 : kInt64);
+
+      NativeLocations& multiple_locations =
+          *new (zone_) NativeLocations(zone_, num_chuncks);
+      for (int i = 0; i < num_chuncks; i++) {
+        const auto& allocated_chunk = &AllocateArgument(chuck_type);
+        // The last chunk should not be 8 bytes, if the struct only has 4
+        // remaining bytes to be allocated.
+        if (i == num_chuncks - 1 && chunck_size == 8 &&
+            Utils::RoundUp(payload_type.SizeInBytes(), 4) % 8 == 4) {
+          const auto& small_chuck_type = *new (zone_) NativePrimitiveType(
+              chunck_size == 4 ? kInt32 : kInt64);
+          multiple_locations.Add(&allocated_chunk->WithOtherNativeType(
+              zone_, small_chuck_type, small_chuck_type));
+        } else {
+          multiple_locations.Add(allocated_chunk);
+        }
+      }
+      return *new (zone_)
+          MultipleNativeLocations(compound_type, multiple_locations);
+    }
+  }
+#endif  // defined(TARGET_ARCH_ARM)
+
+#if defined(TARGET_ARCH_ARM64)
+  // Slightly different from Arm32. FPU registers don't alias the same way,
+  // structs up to 16 bytes block remaining registers if they do not fit in
+  // registers, and larger structs go on stack always.
+  const NativeLocation& AllocateCompound(
+      const NativeCompoundType& payload_type) {
+    const auto& compound_type = payload_type.AsCompound();
+    const intptr_t size = compound_type.SizeInBytes();
+    if (compound_type.ContainsHomogenuousFloats() &&
+        compound_type.members().length() <= 4) {
+      const auto& elem_type = *(compound_type.members().At(0));
+      const intptr_t elem_size = compound_type.members().At(0)->SizeInBytes();
+      const auto reg_kind = kQuadFpuReg;
+      ASSERT(size % elem_size == 0);
+      const intptr_t num_registers = size / elem_size;
+      const intptr_t first_reg =
+          FirstFreeFpuRegisterIndex(reg_kind, num_registers);
+      if (first_reg != kNoFpuRegister) {
+        AllocateFpuRegisterAtIndex(reg_kind, first_reg, num_registers);
+
+        NativeLocations& multiple_locations =
+            *new (zone_) NativeLocations(zone_, num_registers);
+        for (int i = 0; i < num_registers; i++) {
+          const intptr_t reg_index = first_reg + i;
+          multiple_locations.Add(new (zone_) NativeFpuRegistersLocation(
+              elem_type, elem_type, reg_kind, reg_index));
+        }
+        return *new (zone_)
+            MultipleNativeLocations(compound_type, multiple_locations);
+      }
+      BlockAllFpuRegisters();
+      return AllocateStack(payload_type);
+    }
+
+    if (size <= 16) {
+      const intptr_t required_regs = size / 8;
+      const bool regs_available =
+          cpu_regs_used + required_regs <= CallingConventions::kNumArgRegs;
+
+      if (regs_available) {
+        const intptr_t size_rounded =
+            Utils::RoundUp(payload_type.SizeInBytes(), 8);
+        const intptr_t num_chuncks = size_rounded / 8;
+        const auto& chuck_type = *new (zone_) NativePrimitiveType(kInt64);
+
+        NativeLocations& multiple_locations =
+            *new (zone_) NativeLocations(zone_, num_chuncks);
+        for (int i = 0; i < num_chuncks; i++) {
+          const auto& allocated_chunk = &AllocateArgument(chuck_type);
+          multiple_locations.Add(allocated_chunk);
+        }
+        return *new (zone_)
+            MultipleNativeLocations(compound_type, multiple_locations);
+
+      } else {
+        // Block all CPU registers.
+        cpu_regs_used = CallingConventions::kNumArgRegs;
+        return AllocateStack(payload_type);
+      }
+    }
+
+    const auto& pointer_location =
+        AllocateArgument(*new (zone_) NativePrimitiveType(kInt64));
+    return *new (zone_)
+        PointerToMemoryLocation(pointer_location, compound_type);
+  }
+#endif  // defined(TARGET_ARCH_ARM64)
+
   static FpuRegisterKind FpuRegKind(const NativeType& payload_type) {
 #if defined(TARGET_ARCH_ARM)
     return FpuRegisterKindFromSize(payload_type.SizeInBytes());
@@ -174,13 +401,13 @@
   }
 
   // If no register is free, returns -1.
-  int FirstFreeFpuRegisterIndex(FpuRegisterKind kind) {
+  int FirstFreeFpuRegisterIndex(FpuRegisterKind kind, int amount = 1) {
     const intptr_t size = SizeFromFpuRegisterKind(kind) / 4;
     ASSERT(size == 1 || size == 2 || size == 4);
     if (fpu_reg_parts_used == -1) return kNoFpuRegister;
-    const intptr_t mask = (1 << size) - 1;
+    const intptr_t mask = (1 << (size * amount)) - 1;
     intptr_t index = 0;
-    while (index < NumFpuRegisters(kind)) {
+    while (index + amount <= NumFpuRegisters(kind)) {
       const intptr_t mask_shifted = mask << (index * size);
       if ((fpu_reg_parts_used & mask_shifted) == 0) {
         return index;
@@ -190,10 +417,12 @@
     return kNoFpuRegister;
   }
 
-  void AllocateFpuRegisterAtIndex(FpuRegisterKind kind, int index) {
+  void AllocateFpuRegisterAtIndex(FpuRegisterKind kind,
+                                  int index,
+                                  int amount = 1) {
     const intptr_t size = SizeFromFpuRegisterKind(kind) / 4;
     ASSERT(size == 1 || size == 2 || size == 4);
-    const intptr_t mask = (1 << size) - 1;
+    const intptr_t mask = (1 << size * amount) - 1;
     const intptr_t mask_shifted = (mask << (index * size));
     ASSERT((mask_shifted & fpu_reg_parts_used) == 0);
     fpu_reg_parts_used |= mask_shifted;
@@ -225,12 +454,24 @@
 // Location for the arguments of a C signature function.
 static NativeLocations& ArgumentLocations(
     Zone* zone,
-    const ZoneGrowableArray<const NativeType*>& arg_reps) {
+    const ZoneGrowableArray<const NativeType*>& arg_reps,
+    const NativeLocation& return_location) {
   intptr_t num_arguments = arg_reps.length();
-  auto& result = *new NativeLocations(zone, num_arguments);
+  auto& result = *new (zone) NativeLocations(zone, num_arguments);
 
   // Loop through all arguments and assign a register or a stack location.
+  // Allocate result pointer for composite returns first.
   ArgumentAllocator frame_state(zone);
+#if !defined(TARGET_ARCH_ARM64)
+  // Arm64 allocates the pointer in R8, which is not an argument location.
+  if (return_location.IsPointerToMemory()) {
+    const auto& pointer_location =
+        return_location.AsPointerToMemory().pointer_location();
+    const auto& pointer_location_allocated =
+        frame_state.AllocateArgument(pointer_location.payload_type());
+    ASSERT(pointer_location.Equals(pointer_location_allocated));
+  }
+#endif
   for (intptr_t i = 0; i < num_arguments; i++) {
     const NativeType& rep = *arg_reps[i];
     result.Add(&frame_state.AllocateArgument(rep));
@@ -238,71 +479,285 @@
   return result;
 }
 
+#if !defined(TARGET_ARCH_IA32)
+static const NativeLocation& PointerToMemoryResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  const auto& pointer_type = *new (zone) NativePrimitiveType(kFfiIntPtr);
+  const auto& pointer_location = *new (zone) NativeRegistersLocation(
+      zone, pointer_type, pointer_type,
+      CallingConventions::kPointerToReturnStructRegisterCall);
+  const auto& pointer_return_location = *new (zone) NativeRegistersLocation(
+      zone, pointer_type, pointer_type,
+      CallingConventions::kPointerToReturnStructRegisterReturn);
+  return *new (zone) PointerToMemoryLocation(
+      pointer_location, pointer_return_location, payload_type);
+}
+#endif  // !defined(TARGET_ARCH_IA32)
+
+#if defined(TARGET_ARCH_IA32)
+// ia32 Passes pointers to result locations on the stack.
+static const NativeLocation& PointerToMemoryResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  const auto& pointer_type = *new (zone) NativePrimitiveType(kFfiIntPtr);
+  const auto& pointer_location = *new (zone) NativeStackLocation(
+      pointer_type, pointer_type, CallingConventions::kStackPointerRegister, 0);
+  const auto& pointer_return_location = *new (zone) NativeRegistersLocation(
+      zone, pointer_type, pointer_type,
+      CallingConventions::kPointerToReturnStructRegisterReturn);
+  return *new (zone) PointerToMemoryLocation(
+      pointer_location, pointer_return_location, payload_type);
+}
+#endif  // defined(TARGET_ARCH_IA32)
+
+#if defined(TARGET_ARCH_X64) && !defined(TARGET_OS_WINDOWS)
+static const NativeLocation& CompoundResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  const intptr_t size = payload_type.SizeInBytes();
+  if (size <= 16 && size > 0) {
+    // Allocate the same as argument, but use return registers instead of
+    // argument registers.
+    NativeLocations& multiple_locations =
+        *new (zone) NativeLocations(zone, size > 8 ? 2 : 1);
+    intptr_t used_regs = 0;
+    intptr_t used_xmm_regs = 0;
+
+    const auto& double_type = *new (zone) NativePrimitiveType(kDouble);
+    const auto& int64_type = *new (zone) NativePrimitiveType(kInt64);
+
+    const bool first_half_in_xmm =
+        payload_type.ContainsOnlyFloats(0, Utils::Minimum<intptr_t>(size, 8));
+    if (first_half_in_xmm) {
+      multiple_locations.Add(new (zone) NativeFpuRegistersLocation(
+          double_type, double_type, kQuadFpuReg,
+          CallingConventions::kReturnFpuReg));
+      used_xmm_regs++;
+    } else {
+      multiple_locations.Add(new (zone) NativeRegistersLocation(
+          zone, int64_type, int64_type, CallingConventions::kReturnReg));
+      used_regs++;
+    }
+    if (size > 8) {
+      const bool second_half_in_xmm = payload_type.ContainsOnlyFloats(
+          8, Utils::Minimum<intptr_t>(size - 8, 8));
+      if (second_half_in_xmm) {
+        const FpuRegister reg = used_xmm_regs == 0
+                                    ? CallingConventions::kReturnFpuReg
+                                    : CallingConventions::kSecondReturnFpuReg;
+        multiple_locations.Add(new (zone) NativeFpuRegistersLocation(
+            double_type, double_type, kQuadFpuReg, reg));
+        used_xmm_regs++;
+      } else {
+        const Register reg = used_regs == 0
+                                 ? CallingConventions::kReturnReg
+                                 : CallingConventions::kSecondReturnReg;
+        multiple_locations.Add(new (zone) NativeRegistersLocation(
+            zone, int64_type, int64_type, reg));
+        used_regs++;
+      }
+    }
+    return *new (zone)
+        MultipleNativeLocations(payload_type, multiple_locations);
+  }
+  return PointerToMemoryResultLocation(zone, payload_type);
+}
+#endif  // defined(TARGET_ARCH_X64) && !defined(TARGET_OS_WINDOWS)
+
+#if defined(TARGET_ARCH_X64) && defined(TARGET_OS_WINDOWS)
+// If struct fits in a single register do that, and sign extend.
+// Otherwise, pass a pointer to memory.
+static const NativeLocation& CompoundResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  const intptr_t size = payload_type.SizeInBytes();
+  if (size <= 8 && size > 0 && Utils::IsPowerOfTwo(size)) {
+    NativeLocations& multiple_locations = *new (zone) NativeLocations(zone, 1);
+    const auto& type =
+        *new (zone) NativePrimitiveType(PrimitiveTypeFromSizeInBytes(size));
+    multiple_locations.Add(new (zone) NativeRegistersLocation(
+        zone, type, type, CallingConventions::kReturnReg));
+    return *new (zone)
+        MultipleNativeLocations(payload_type, multiple_locations);
+  }
+  return PointerToMemoryResultLocation(zone, payload_type);
+}
+#endif  // defined(TARGET_ARCH_X64) && defined(TARGET_OS_WINDOWS)
+
+#if defined(TARGET_ARCH_IA32) && !defined(TARGET_OS_WINDOWS)
+static const NativeLocation& CompoundResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  return PointerToMemoryResultLocation(zone, payload_type);
+}
+#endif  // defined(TARGET_ARCH_IA32) && !defined(TARGET_OS_WINDOWS)
+
+#if defined(TARGET_ARCH_IA32) && defined(TARGET_OS_WINDOWS)
+// Windows uses up to two return registers, while Linux does not.
+static const NativeLocation& CompoundResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  const intptr_t size = payload_type.SizeInBytes();
+  if (size <= 8 && Utils::IsPowerOfTwo(size)) {
+    NativeLocations& multiple_locations =
+        *new (zone) NativeLocations(zone, size > 4 ? 2 : 1);
+    const auto& type = *new (zone) NativePrimitiveType(kUint32);
+    multiple_locations.Add(new (zone) NativeRegistersLocation(
+        zone, type, type, CallingConventions::kReturnReg));
+    if (size > 4) {
+      multiple_locations.Add(new (zone) NativeRegistersLocation(
+          zone, type, type, CallingConventions::kSecondReturnReg));
+    }
+    return *new (zone)
+        MultipleNativeLocations(payload_type, multiple_locations);
+  }
+  return PointerToMemoryResultLocation(zone, payload_type);
+}
+#endif  // defined(TARGET_ARCH_IA32) && defined(TARGET_OS_WINDOWS)
+
+#if defined(TARGET_ARCH_ARM)
+// Arm passes homogenous float return values in FPU registers and small
+// composities in a single integer register. The rest is stored into the
+// location passed in by pointer.
+static const NativeLocation& CompoundResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  const intptr_t num_members = payload_type.members().length();
+  if (payload_type.ContainsHomogenuousFloats() && !SoftFpAbi() &&
+      num_members <= 4) {
+    NativeLocations& multiple_locations =
+        *new (zone) NativeLocations(zone, num_members);
+    for (int i = 0; i < num_members; i++) {
+      const auto& member = payload_type.members().At(0)->AsPrimitive();
+      multiple_locations.Add(new (zone) NativeFpuRegistersLocation(
+          member, member, FpuRegisterKindFromSize(member.SizeInBytes()), i));
+    }
+    return *new (zone)
+        MultipleNativeLocations(payload_type, multiple_locations);
+  }
+  const intptr_t size = payload_type.SizeInBytes();
+  if (size <= 4) {
+    NativeLocations& multiple_locations = *new (zone) NativeLocations(zone, 1);
+    const auto& type = *new (zone) NativePrimitiveType(kUint32);
+    multiple_locations.Add(new (zone)
+                               NativeRegistersLocation(zone, type, type, R0));
+    return *new (zone)
+        MultipleNativeLocations(payload_type, multiple_locations);
+  }
+  return PointerToMemoryResultLocation(zone, payload_type);
+}
+#endif  // defined(TARGET_ARCH_ARM)
+
+#if defined(TARGET_ARCH_ARM64)
+// If allocated to integer or fpu registers as argument, same for return,
+// otherwise a pointer to the result location is passed in.
+static const NativeLocation& CompoundResultLocation(
+    Zone* zone,
+    const NativeCompoundType& payload_type) {
+  ArgumentAllocator frame_state(zone);
+  const auto& location_as_argument = frame_state.AllocateArgument(payload_type);
+  if (!location_as_argument.IsStack() &&
+      !location_as_argument.IsPointerToMemory()) {
+    return location_as_argument;
+  }
+  return PointerToMemoryResultLocation(zone, payload_type);
+}
+#endif  // defined(TARGET_ARCH_ARM64)
+
 // Location for the result of a C signature function.
-static NativeLocation& ResultLocation(Zone* zone,
-                                      const NativeType& payload_type) {
+static const NativeLocation& ResultLocation(Zone* zone,
+                                            const NativeType& payload_type) {
   const auto& payload_type_converted = ConvertIfSoftFp(zone, payload_type);
   const auto& container_type =
       CallingConventions::kReturnRegisterExtension == kExtendedTo4
           ? payload_type_converted.WidenTo4Bytes(zone)
           : payload_type_converted;
+
   if (container_type.IsFloat()) {
     return *new (zone) NativeFpuRegistersLocation(
         payload_type, container_type, CallingConventions::kReturnFpuReg);
   }
 
-  ASSERT(container_type.IsInt() || container_type.IsVoid());
-  if (container_type.SizeInBytes() == 8 && target::kWordSize == 4) {
+  if (container_type.IsInt() || container_type.IsVoid()) {
+    if (container_type.SizeInBytes() == 8 && target::kWordSize == 4) {
+      return *new (zone) NativeRegistersLocation(
+          zone, payload_type, container_type, CallingConventions::kReturnReg,
+          CallingConventions::kSecondReturnReg);
+    }
+
+    ASSERT(container_type.SizeInBytes() <= target::kWordSize);
     return *new (zone) NativeRegistersLocation(
-        payload_type, container_type, CallingConventions::kReturnReg,
-        CallingConventions::kSecondReturnReg);
+        zone, payload_type, container_type, CallingConventions::kReturnReg);
   }
 
-  ASSERT(container_type.SizeInBytes() <= target::kWordSize);
-  return *new (zone) NativeRegistersLocation(payload_type, container_type,
-                                             CallingConventions::kReturnReg);
+  // Compounds are laid out differently per ABI, so they are implemented
+  // per ABI.
+  const auto& compound_type = payload_type.AsCompound();
+  return CompoundResultLocation(zone, compound_type);
 }
 
-NativeCallingConvention::NativeCallingConvention(Zone* zone,
-                                                 const Function& c_signature)
-    : zone_(ASSERT_NOTNULL(zone)),
-      c_signature_(c_signature),
-      arg_locs_(
-          ArgumentLocations(zone_,
-                            ArgumentRepresentations(zone_, c_signature_))),
-      result_loc_(
-          ResultLocation(zone_, ResultRepresentation(zone_, c_signature_))) {}
-
-intptr_t NativeCallingConvention::num_args() const {
-  ASSERT(c_signature_.NumOptionalParameters() == 0);
-  ASSERT(c_signature_.NumOptionalPositionalParameters() == 0);
-
-  // Subtract the #0 argument, the function pointer.
-  return c_signature_.num_fixed_parameters() - kNativeParamsStartAt;
-}
-
-AbstractTypePtr NativeCallingConvention::CType(intptr_t arg_index) const {
-  if (arg_index == kResultIndex) {
-    return c_signature_.result_type();
-  }
-
-  // Skip #0 argument, the function pointer.
-  return c_signature_.ParameterTypeAt(arg_index + kNativeParamsStartAt);
+const NativeCallingConvention& NativeCallingConvention::FromSignature(
+    Zone* zone,
+    const NativeFunctionType& signature) {
+  // With struct return values, a possible pointer to a return value can
+  // occupy an argument position. Hence, allocate return value first.
+  const auto& return_location = ResultLocation(zone, signature.return_type());
+  const auto& argument_locations =
+      ArgumentLocations(zone, signature.argument_types(), return_location);
+  return *new (zone)
+      NativeCallingConvention(argument_locations, return_location);
 }
 
 intptr_t NativeCallingConvention::StackTopInBytes() const {
-  const intptr_t num_arguments = arg_locs_.length();
+  const intptr_t num_arguments = argument_locations_.length();
   intptr_t max_height_in_bytes = 0;
   for (intptr_t i = 0; i < num_arguments; i++) {
-    if (Location(i).IsStack()) {
-      const intptr_t height = Location(i).AsStack().offset_in_bytes() +
-                              Location(i).container_type().SizeInBytes();
-      max_height_in_bytes = Utils::Maximum(height, max_height_in_bytes);
-    }
+    max_height_in_bytes = Utils::Maximum(
+        max_height_in_bytes, argument_locations_[i]->StackTopInBytes());
   }
   return Utils::RoundUp(max_height_in_bytes, compiler::target::kWordSize);
 }
 
+void NativeCallingConvention::PrintTo(BaseTextBuffer* f,
+                                      bool multi_line) const {
+  if (!multi_line) {
+    f->AddString("(");
+  }
+  for (intptr_t i = 0; i < argument_locations_.length(); i++) {
+    if (i > 0) {
+      if (multi_line) {
+        f->AddString("\n");
+      } else {
+        f->AddString(", ");
+      }
+    }
+    argument_locations_[i]->PrintTo(f);
+  }
+  if (multi_line) {
+    f->AddString("\n=>\n");
+  } else {
+    f->AddString(") => ");
+  }
+  return_location_.PrintTo(f);
+  if (multi_line) {
+    f->AddString("\n");
+  }
+}
+
+const char* NativeCallingConvention::ToCString(Zone* zone,
+                                               bool multi_line) const {
+  ZoneTextBuffer textBuffer(zone);
+  PrintTo(&textBuffer, multi_line);
+  return textBuffer.buffer();
+}
+
+#if !defined(FFI_UNIT_TESTS)
+const char* NativeCallingConvention::ToCString(bool multi_line) const {
+  return ToCString(Thread::Current()->zone(), multi_line);
+}
+#endif
+
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.h b/runtime/vm/compiler/ffi/native_calling_convention.h
index 5eae152..9faf620 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.h
+++ b/runtime/vm/compiler/ffi/native_calling_convention.h
@@ -9,9 +9,7 @@
 #error "AOT runtime should not use compiler sources (including header files)"
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-#include <platform/globals.h>
-
-#include "vm/compiler/backend/locations.h"
+#include "platform/globals.h"
 #include "vm/compiler/ffi/native_location.h"
 #include "vm/compiler/ffi/native_type.h"
 
@@ -23,43 +21,39 @@
 
 using NativeLocations = ZoneGrowableArray<const NativeLocation*>;
 
-
-// Values below 0 index result (result might be multiple if composite).
-const intptr_t kResultIndex = -1;
-
 // Calculates native calling convention, is not aware of Dart calling
 // convention constraints.
 //
-// This class is meant to be extended or embedded in a class that is aware
-// of Dart calling convention constraints.
+// This class is meant to beembedded in a class that is aware of Dart calling
+// convention constraints.
 class NativeCallingConvention : public ZoneAllocated {
  public:
-  NativeCallingConvention(Zone* zone, const Function& c_signature);
+  static const NativeCallingConvention& FromSignature(
+      Zone* zone,
+      const NativeFunctionType& signature);
 
-  // Excluding the #0 argument which is the function pointer.
-  intptr_t num_args() const;
-
-  // The C Type (expressed in a Dart Type) of the argument at `arg_index`.
-  //
-  // Excluding the #0 argument which is the function pointer.
-  AbstractTypePtr CType(intptr_t arg_index) const;
-
-  // The location of the argument at `arg_index`.
-  const NativeLocation& Location(intptr_t arg_index) const {
-    if (arg_index == kResultIndex) {
-      return result_loc_;
-    }
-    return *arg_locs_.At(arg_index);
+  const NativeLocations& argument_locations() const {
+    return argument_locations_;
   }
+  const NativeLocation& return_location() const { return return_location_; }
 
   intptr_t StackTopInBytes() const;
 
- protected:
-  Zone* const zone_;
-  // Contains the function pointer as argument #0.
-  const Function& c_signature_;
-  const NativeLocations& arg_locs_;
-  const NativeLocation& result_loc_;
+  void PrintTo(BaseTextBuffer* f, bool multi_line = false) const;
+  void PrintToMultiLine(BaseTextBuffer* f) const;
+  const char* ToCString(Zone* zone, bool multi_line = false) const;
+#if !defined(FFI_UNIT_TESTS)
+  const char* ToCString(bool multi_line = false) const;
+#endif
+
+ private:
+  NativeCallingConvention(const NativeLocations& argument_locations,
+                          const NativeLocation& return_location)
+      : argument_locations_(argument_locations),
+        return_location_(return_location) {}
+
+  const NativeLocations& argument_locations_;
+  const NativeLocation& return_location_;
 };
 
 }  // namespace ffi
diff --git a/runtime/vm/compiler/ffi/native_calling_convention_test.cc b/runtime/vm/compiler/ffi/native_calling_convention_test.cc
new file mode 100644
index 0000000..8b27760
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_calling_convention_test.cc
@@ -0,0 +1,300 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/ffi/unit_test.h"
+
+#include "platform/syslog.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+void RunSignatureTest(dart::Zone* zone,
+                      const char* name,
+                      const NativeTypes& argument_types,
+                      const NativeType& return_type) {
+  const auto& native_signature =
+      *new (zone) NativeFunctionType(argument_types, return_type);
+
+  const auto& native_calling_convention =
+      NativeCallingConvention::FromSignature(zone, native_signature);
+
+  const char* test_result =
+      native_calling_convention.ToCString(zone, /*multi_line=*/true);
+
+  const int kFilePathLength = 100;
+  char expectation_file_path[kFilePathLength];
+  Utils::SNPrint(expectation_file_path, kFilePathLength,
+                 "runtime/vm/compiler/ffi/unit_tests/%s/%s_%s.expect", name,
+                 kArch, kOs);
+
+  if (TestCaseBase::update_expectations) {
+    Syslog::Print("Updating %s\n", expectation_file_path);
+    WriteToFile(expectation_file_path, test_result);
+  }
+
+  char* expectation_file_contents = nullptr;
+  ReadFromFile(expectation_file_path, &expectation_file_contents);
+  EXPECT_NOTNULL(expectation_file_contents);
+  if (expectation_file_contents != nullptr) {
+    EXPECT_STREQ(expectation_file_contents, test_result);
+    free(expectation_file_contents);
+  }
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_int8x10) {
+  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 10);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+  arguments.Add(&int8type);
+
+  RunSignatureTest(Z, "int8x10", arguments, int8type);
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_floatx10) {
+  const auto& floatType = *new (Z) NativePrimitiveType(kFloat);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 10);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+  arguments.Add(&floatType);
+
+  RunSignatureTest(Z, "floatx10", arguments, floatType);
+}
+
+// Test with 3-byte struct.
+//
+// On ia32, result pointer is passed on stack and passed back in eax.
+//
+// On x64, is passed and returned in registers, except for on Windows where it
+// is passed on stack because of its size not being a power of two.
+//
+// See the *.expect in ./unit_tests for this behavior.
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct3bytesx10) {
+  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
+
+  auto& member_types = *new (Z) NativeTypes(Z, 3);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(Z, member_types);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 10);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+
+  RunSignatureTest(Z, "struct3bytesx10", arguments, struct_type);
+}
+
+// Test with homogenous struct.
+//
+// On arm softfp, the return pointer is passed in the first int register, and
+// the first struct is passed in the next 3 registers and 1 stack slot.
+//
+// On arm hardfp, arm64, and x64 non-Windows the structs are passed in FPU
+// registers until exhausted, the rest is passed on the stack, and struct is
+// returned in FPU registers.
+//
+// On ia32 a return pointer and all arguments are passed on the stack.
+//
+// On x64 on Windows the structs are passed by pointer and pointer to the
+// return value is passed in.
+//
+// See the *.expect in ./unit_tests for this behavior.
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct16bytesHomogenousx10) {
+  const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
+  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
+
+  // If passed in FPU registers, uses an even amount of them.
+  auto& member_types = *new (Z) NativeTypes(Z, 4);
+  member_types.Add(&float_type);
+  member_types.Add(&float_type);
+  member_types.Add(&float_type);
+  member_types.Add(&float_type);
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(Z, member_types);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 13);
+  arguments.Add(&struct_type);
+  arguments.Add(&float_type);  // Claim a single FPU register.
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&float_type);   // Check float register back filling, if any.
+  arguments.Add(&int8type);     // Check integer register back filling, if any.
+  arguments.Add(&struct_type);  // Check stack alignment of struct.
+
+  RunSignatureTest(Z, "struct16bytesHomogenousx10", arguments, struct_type);
+}
+
+// A fairly big struct.
+//
+// On arm, split up in 8-byte chunks. The first chunk goes into two registers,
+// the rest on the stack. Note that r1 goes unused and is not backfilled.
+//
+// On arm64 and Windows x64 passed by a pointer to copy.
+//
+// On ia32, wholly passed on stack.
+//
+// On non-Windows x64, wholly passed on stack, and the integer argument
+// backfills a still unoccupied integer register.
+//
+// See the *.expect in ./unit_tests for this behavior.
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct128bytesx1) {
+  const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
+  const auto& int64_type = *new (Z) NativePrimitiveType(kInt64);
+
+  auto& member_types = *new (Z) NativeTypes(Z, 16);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  member_types.Add(&int64_type);
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(Z, member_types);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 2);
+  arguments.Add(&struct_type);
+  arguments.Add(&int32_type);  // Check integer register backfilling, if any.
+
+  RunSignatureTest(Z, "struct128bytesx1", arguments, struct_type);
+}
+
+#if defined(TARGET_ARCH_X64)
+// On x64 non-Windows a struct can be spread over an FPU and int register.
+//
+// See the *.expect in ./unit_tests for this behavior.
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct16bytesMixedx10) {
+  const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
+  const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
+
+  auto& member_types = *new (Z) NativeTypes(Z, 4);
+  member_types.Add(&float_type);
+  member_types.Add(&float_type);
+  member_types.Add(&int32_type);
+  member_types.Add(&int32_type);
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(Z, member_types);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 11);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);  // Integer registers exhausted, on stack.
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&float_type);  // Use remaining FPU register.
+
+  RunSignatureTest(Z, "struct16bytesMixedx10", arguments, struct_type);
+}
+
+// On x64 non-Windows a struct can be spread over an FPU and int register.
+//
+// See the *.expect in ./unit_tests for this behavior.
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct16bytesMixedx10_2) {
+  const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
+  const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
+
+  auto& member_types = *new (Z) NativeTypes(Z, 4);
+  member_types.Add(&float_type);
+  member_types.Add(&float_type);
+  member_types.Add(&int32_type);
+  member_types.Add(&int32_type);
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(Z, member_types);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 15);
+  arguments.Add(&float_type);
+  arguments.Add(&float_type);
+  arguments.Add(&float_type);
+  arguments.Add(&float_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);  // FPU registers exhausted, on stack.
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&struct_type);
+  arguments.Add(&int32_type);  // Use remaining integer register.
+
+  RunSignatureTest(Z, "struct16bytesMixedx10_2", arguments, struct_type);
+}
+#endif  // defined(TARGET_ARCH_X64)
+
+// On ia32 Windows a struct can be returned in registers, on non-Windows not.
+//
+// See the *.expect in ./unit_tests for this behavior.
+UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct8bytesx1) {
+  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
+
+  auto& member_types = *new (Z) NativeTypes(Z, 4);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  member_types.Add(&int8type);
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(Z, member_types);
+
+  auto& arguments = *new (Z) NativeTypes(Z, 1);
+  arguments.Add(&struct_type);
+
+  RunSignatureTest(Z, "struct8bytesx1", arguments, struct_type);
+}
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/native_location.cc b/runtime/vm/compiler/ffi/native_location.cc
index f954e9f..f757a31 100644
--- a/runtime/vm/compiler/ffi/native_location.cc
+++ b/runtime/vm/compiler/ffi/native_location.cc
@@ -4,7 +4,7 @@
 
 #include "vm/compiler/ffi/native_location.h"
 
-#include "vm/compiler/backend/il_printer.h"
+#include "vm/zone_text_buffer.h"
 
 namespace dart {
 
@@ -12,6 +12,7 @@
 
 namespace ffi {
 
+#if !defined(FFI_UNIT_TESTS)
 bool NativeLocation::LocationCanBeExpressed(Location loc, Representation rep) {
   switch (loc.kind()) {
     case Location::Kind::kRegister:
@@ -23,7 +24,6 @@
       break;
   }
   if (loc.IsPairLocation()) {
-    // TODO(36730): We could possibly consume a pair location as struct.
     return false;
   }
   return false;
@@ -32,7 +32,6 @@
 NativeLocation& NativeLocation::FromLocation(Zone* zone,
                                              Location loc,
                                              Representation rep) {
-  // TODO(36730): We could possibly consume a pair location as struct.
   ASSERT(LocationCanBeExpressed(loc, rep));
 
   const NativeType& native_rep =
@@ -41,7 +40,7 @@
   switch (loc.kind()) {
     case Location::Kind::kRegister:
       return *new (zone)
-          NativeRegistersLocation(native_rep, native_rep, loc.reg());
+          NativeRegistersLocation(zone, native_rep, native_rep, loc.reg());
     case Location::Kind::kFpuRegister:
       return *new (zone)
           NativeFpuRegistersLocation(native_rep, native_rep, loc.fpu_reg());
@@ -60,7 +59,6 @@
   UNREACHABLE();
 }
 
-// TODO(36730): Remove when being able to consume as struct.
 NativeLocation& NativeLocation::FromPairLocation(Zone* zone,
                                                  Location pair_loc,
                                                  Representation pair_rep,
@@ -74,6 +72,7 @@
   const Location loc = pair_loc.AsPairLocation()->At(index);
   return FromLocation(zone, loc, rep);
 }
+#endif
 
 const NativeRegistersLocation& NativeLocation::AsRegisters() const {
   ASSERT(IsRegisters());
@@ -90,6 +89,17 @@
   return static_cast<const NativeStackLocation&>(*this);
 }
 
+const MultipleNativeLocations& NativeLocation::AsMultiple() const {
+  ASSERT(IsMultiple());
+  return static_cast<const MultipleNativeLocations&>(*this);
+}
+
+const PointerToMemoryLocation& NativeLocation::AsPointerToMemory() const {
+  ASSERT(IsPointerToMemory());
+  return static_cast<const PointerToMemoryLocation&>(*this);
+}
+
+#if !defined(FFI_UNIT_TESTS)
 Location NativeRegistersLocation::AsLocation() const {
   ASSERT(IsExpressibleAsLocation());
   switch (num_regs()) {
@@ -126,22 +136,49 @@
   }
   UNREACHABLE();
 }
+#endif
+
 NativeRegistersLocation& NativeRegistersLocation::Split(Zone* zone,
+                                                        intptr_t num_parts,
                                                         intptr_t index) const {
-  ASSERT(num_regs() == 2);
+  ASSERT(num_parts == 2);
+  ASSERT(num_regs() == num_parts);
   return *new (zone) NativeRegistersLocation(
-      payload_type().Split(zone, index), container_type().Split(zone, index),
-      reg_at(index));
+      zone, payload_type().Split(zone, index),
+      container_type().Split(zone, index), reg_at(index));
 }
 
 NativeStackLocation& NativeStackLocation::Split(Zone* zone,
+                                                intptr_t num_parts,
                                                 intptr_t index) const {
-  ASSERT(index == 0 || index == 1);
   const intptr_t size = payload_type().SizeInBytes();
 
-  return *new (zone) NativeStackLocation(
-      payload_type().Split(zone, index), container_type().Split(zone, index),
-      base_register_, offset_in_bytes_ + size / 2 * index);
+  if (payload_type().IsPrimitive()) {
+    ASSERT(num_parts == 2);
+    return *new (zone) NativeStackLocation(
+        payload_type().Split(zone, index), container_type().Split(zone, index),
+        base_register_, offset_in_bytes_ + size / num_parts * index);
+  } else {
+    const intptr_t size_rounded_up =
+        Utils::RoundUp(size, compiler::target::kWordSize);
+    ASSERT(size_rounded_up / compiler::target::kWordSize == num_parts);
+
+    // Blocks of compiler::target::kWordSize.
+    return *new (zone) NativeStackLocation(
+        *new (zone) NativePrimitiveType(
+            compiler::target::kWordSize == 8 ? kInt64 : kInt32),
+        *new (zone) NativePrimitiveType(
+            compiler::target::kWordSize == 8 ? kInt64 : kInt32),
+        base_register_, offset_in_bytes_ + compiler::target::kWordSize * index);
+  }
+}
+
+intptr_t MultipleNativeLocations::StackTopInBytes() const {
+  intptr_t height = 0;
+  for (int i = 0; i < locations_.length(); i++) {
+    height = Utils::Maximum(height, locations_[i]->StackTopInBytes());
+  }
+  return height;
 }
 
 NativeLocation& NativeLocation::WidenTo4Bytes(Zone* zone) const {
@@ -205,17 +242,30 @@
   return other_stack.offset_in_bytes_ == offset_in_bytes_;
 }
 
+bool PointerToMemoryLocation::Equals(const NativeLocation& other) const {
+  if (!other.IsPointerToMemory()) {
+    return false;
+  }
+  const auto& other_pointer = other.AsPointerToMemory();
+  if (!other_pointer.pointer_location_.Equals(pointer_location_)) {
+    return false;
+  }
+  return other_pointer.payload_type().Equals(payload_type());
+}
+
+#if !defined(FFI_UNIT_TESTS)
 compiler::Address NativeLocationToStackSlotAddress(
     const NativeStackLocation& loc) {
   return compiler::Address(loc.base_register(), loc.offset_in_bytes());
 }
+#endif
 
 static void PrintRepresentations(BaseTextBuffer* f, const NativeLocation& loc) {
   f->AddString(" ");
-  loc.container_type().PrintTo(f);
+  loc.container_type().PrintTo(f, /*multi_line=*/false, /*verbose=*/false);
   if (!loc.container_type().Equals(loc.payload_type())) {
     f->AddString("[");
-    loc.payload_type().PrintTo(f);
+    loc.payload_type().PrintTo(f, /*multi_line=*/false, /*verbose=*/false);
     f->AddString("]");
   }
 }
@@ -231,7 +281,9 @@
   } else {
     f->AddString("(");
     for (intptr_t i = 0; i < num_regs(); i++) {
-      if (i != 0) f->Printf(", ");
+      if (i != 0) {
+        f->Printf(", ");
+      }
       f->Printf("%s", RegisterNames::RegisterName(regs_->At(i)));
     }
     f->AddString(")");
@@ -264,13 +316,39 @@
   PrintRepresentations(f, *this);
 }
 
-const char* NativeLocation::ToCString() const {
-  char buffer[1024];
-  BufferFormatter bf(buffer, 1024);
-  PrintTo(&bf);
-  return Thread::Current()->zone()->MakeCopyOfString(buffer);
+const char* NativeLocation::ToCString(Zone* zone) const {
+  ZoneTextBuffer textBuffer(zone);
+  PrintTo(&textBuffer);
+  return textBuffer.buffer();
 }
 
+void PointerToMemoryLocation::PrintTo(BaseTextBuffer* f) const {
+  f->Printf("P(");
+  pointer_location().PrintTo(f);
+  if (!pointer_location().Equals(pointer_return_location())) {
+    f->Printf(", ret:");
+    pointer_return_location().PrintTo(f);
+  }
+  f->Printf(")");
+  PrintRepresentations(f, *this);
+}
+
+void MultipleNativeLocations::PrintTo(BaseTextBuffer* f) const {
+  f->Printf("M(");
+  for (intptr_t i = 0; i < locations_.length(); i++) {
+    if (i != 0) f->Printf(", ");
+    locations_[i]->PrintTo(f);
+  }
+  f->Printf(")");
+  PrintRepresentations(f, *this);
+}
+
+#if !defined(FFI_UNIT_TESTS)
+const char* NativeLocation::ToCString() const {
+  return ToCString(Thread::Current()->zone());
+}
+#endif
+
 intptr_t SizeFromFpuRegisterKind(enum FpuRegisterKind kind) {
   switch (kind) {
     case kQuadFpuReg:
diff --git a/runtime/vm/compiler/ffi/native_location.h b/runtime/vm/compiler/ffi/native_location.h
index 78caa24..9108b21 100644
--- a/runtime/vm/compiler/ffi/native_location.h
+++ b/runtime/vm/compiler/ffi/native_location.h
@@ -9,10 +9,15 @@
 #error "AOT runtime should not use compiler sources (including header files)"
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-#include "vm/compiler/backend/locations.h"
+#include "platform/assert.h"
 #include "vm/compiler/ffi/native_type.h"
+#include "vm/compiler/runtime_api.h"
+#include "vm/constants.h"
 #include "vm/growable_array.h"
-#include "vm/thread.h"
+
+#if !defined(FFI_UNIT_TESTS)
+#include "vm/compiler/backend/locations.h"
+#endif
 
 namespace dart {
 
@@ -25,6 +30,8 @@
 class NativeRegistersLocation;
 class NativeFpuRegistersLocation;
 class NativeStackLocation;
+class MultipleNativeLocations;
+class PointerToMemoryLocation;
 
 // NativeLocation objects are used in the FFI to describe argument and return
 // value locations in all native ABIs that the FFI supports.
@@ -34,14 +41,15 @@
 // * The container type, equal to or larger than the payload. If the
 //   container is larger than the payload, the upper bits are defined by sign
 //   or zero extension.
+//   Container type is also used to denote an integer container when floating
+//   point values are passed in integer registers.
 //
 // NativeLocations can express things that dart::Locations cannot express:
 // * Multiple consecutive registers.
 // * Multiple sizes of FPU registers (e.g. S, D, and Q on Arm32).
 // * Arbitrary byte-size stack locations, at byte-size offsets.
 //   (The Location class uses word-size offsets.)
-// * Pointers including a backing location on the stack.
-// * No location.
+// * Pointers to a memory location.
 // * Split between multiple registers and stack.
 //
 // NativeLocations cannot express the following dart::Locations:
@@ -53,6 +61,7 @@
 // inequality cannot be used to determine disjointness.
 class NativeLocation : public ZoneAllocated {
  public:
+#if !defined(FFI_UNIT_TESTS)
   static bool LocationCanBeExpressed(Location loc, Representation rep);
   static NativeLocation& FromLocation(Zone* zone,
                                       Location loc,
@@ -61,6 +70,7 @@
                                           Location loc,
                                           Representation rep,
                                           intptr_t index);
+#endif
 
   // The type of the data at this location.
   const NativeType& payload_type() const { return payload_type_; }
@@ -87,25 +97,40 @@
   virtual bool IsRegisters() const { return false; }
   virtual bool IsFpuRegisters() const { return false; }
   virtual bool IsStack() const { return false; }
+  virtual bool IsMultiple() const { return false; }
+  virtual bool IsPointerToMemory() const { return false; }
 
   virtual bool IsExpressibleAsLocation() const { return false; }
+#if !defined(FFI_UNIT_TESTS)
   virtual Location AsLocation() const {
     ASSERT(IsExpressibleAsLocation());
     UNREACHABLE();
   }
+#endif
 
   virtual void PrintTo(BaseTextBuffer* f) const;
+  const char* ToCString(Zone* zone) const;
+#if !defined(FFI_UNIT_TESTS)
   const char* ToCString() const;
+#endif
 
   const NativeRegistersLocation& AsRegisters() const;
   const NativeFpuRegistersLocation& AsFpuRegisters() const;
   const NativeStackLocation& AsStack() const;
+  const MultipleNativeLocations& AsMultiple() const;
+  const PointerToMemoryLocation& AsPointerToMemory() const;
 
-  virtual NativeLocation& Split(Zone* zone, intptr_t index) const {
-    ASSERT(index == 0 || index == 1);
+  // Retrieve one part from this location when it is split into multiple parts.
+  virtual NativeLocation& Split(Zone* zone,
+                                intptr_t num_parts,
+                                intptr_t index) const {
     UNREACHABLE();
   }
 
+  // Return the top of the stack in bytes. Recurses over its constituents when
+  // MultipleNativeLocations.
+  virtual intptr_t StackTopInBytes() const { return 0; }
+
   // Equality of location, ignores the payload and container native types.
   virtual bool Equals(const NativeLocation& other) const { UNREACHABLE(); }
 
@@ -133,19 +158,21 @@
                           const NativeType& container_type,
                           ZoneGrowableArray<Register>* registers)
       : NativeLocation(payload_type, container_type), regs_(registers) {}
-  NativeRegistersLocation(const NativeType& payload_type,
+  NativeRegistersLocation(Zone* zone,
+                          const NativeType& payload_type,
                           const NativeType& container_type,
                           Register reg)
       : NativeLocation(payload_type, container_type) {
-    regs_ = new ZoneGrowableArray<Register>();
+    regs_ = new (zone) ZoneGrowableArray<Register>(zone, 1);
     regs_->Add(reg);
   }
-  NativeRegistersLocation(const NativeType& payload_type,
+  NativeRegistersLocation(Zone* zone,
+                          const NativeType& payload_type,
                           const NativeType& container_type,
                           Register register1,
                           Register register2)
       : NativeLocation(payload_type, container_type) {
-    regs_ = new ZoneGrowableArray<Register>();
+    regs_ = new (zone) ZoneGrowableArray<Register>(zone, 2);
     regs_->Add(register1);
     regs_->Add(register2);
   }
@@ -163,11 +190,15 @@
   virtual bool IsExpressibleAsLocation() const {
     return num_regs() == 1 || num_regs() == 2;
   }
+#if !defined(FFI_UNIT_TESTS)
   virtual Location AsLocation() const;
+#endif
   intptr_t num_regs() const { return regs_->length(); }
   Register reg_at(intptr_t index) const { return regs_->At(index); }
 
-  virtual NativeRegistersLocation& Split(Zone* zone, intptr_t index) const;
+  virtual NativeRegistersLocation& Split(Zone* zone,
+                                         intptr_t num_parts,
+                                         intptr_t index) const;
 
   virtual void PrintTo(BaseTextBuffer* f) const;
 
@@ -230,10 +261,12 @@
   virtual bool IsExpressibleAsLocation() const {
     return fpu_reg_kind_ == kQuadFpuReg;
   }
+#if !defined(FFI_UNIT_TESTS)
   virtual Location AsLocation() const {
     ASSERT(IsExpressibleAsLocation());
     return Location::FpuRegisterLocation(fpu_reg());
   }
+#endif
   FpuRegisterKind fpu_reg_kind() const { return fpu_reg_kind_; }
   FpuRegister fpu_reg() const {
     ASSERT(fpu_reg_kind_ == kQuadFpuReg);
@@ -291,6 +324,8 @@
            size % compiler::target::kWordSize == 0 &&
            (size_slots == 1 || size_slots == 2);
   }
+
+#if !defined(FFI_UNIT_TESTS)
   virtual Location AsLocation() const;
 
   // ConstantInstr expects DoubleStackSlot for doubles, even on 64-bit systems.
@@ -300,8 +335,15 @@
     ASSERT(compiler::target::kWordSize == 8);
     return Location::DoubleStackSlot(offset_in_words(), base_register_);
   }
+#endif
 
-  virtual NativeStackLocation& Split(Zone* zone, intptr_t index) const;
+  virtual NativeStackLocation& Split(Zone* zone,
+                                     intptr_t num_parts,
+                                     intptr_t index) const;
+
+  virtual intptr_t StackTopInBytes() const {
+    return offset_in_bytes() + container_type().SizeInBytes();
+  }
 
   virtual void PrintTo(BaseTextBuffer* f) const;
 
@@ -322,9 +364,101 @@
   DISALLOW_COPY_AND_ASSIGN(NativeStackLocation);
 };
 
+// The location of a pointer pointing to a compound.
+//
+// For arguments a pointer to a copy of an object. The backing copy of the
+// object typically resides on the stack.
+//
+// For return values a pointer to empty space that should hold the object. This
+// space also typically resides on the stack.
+class PointerToMemoryLocation : public NativeLocation {
+ public:
+  PointerToMemoryLocation(const NativeLocation& pointer_location,
+                          const NativeCompoundType& object_pointed_to)
+      : NativeLocation(object_pointed_to, object_pointed_to),
+        pointer_location_(pointer_location),
+        pointer_return_location_(pointer_location) {
+    ASSERT(pointer_location.IsRegisters() || pointer_location.IsStack());
+  }
+  PointerToMemoryLocation(const NativeLocation& pointer_location,
+                          const NativeLocation& pointer_return_location,
+                          const NativeCompoundType& object_pointed_to)
+      : NativeLocation(object_pointed_to, object_pointed_to),
+        pointer_location_(pointer_location),
+        pointer_return_location_(pointer_return_location) {
+    ASSERT(pointer_location.IsRegisters() || pointer_location.IsStack());
+  }
+
+  virtual ~PointerToMemoryLocation() {}
+
+  virtual bool IsPointerToMemory() const { return true; }
+
+  virtual void PrintTo(BaseTextBuffer* f) const;
+
+  virtual bool Equals(const NativeLocation& other) const;
+
+  virtual NativeLocation& WithOtherNativeType(
+      Zone* zone,
+      const NativeType& new_payload_type,
+      const NativeType& new_container_type) const {
+    UNREACHABLE();
+  }
+
+  virtual intptr_t StackTopInBytes() const {
+    return pointer_location().StackTopInBytes();
+  }
+
+  // The location where the pointer is passed to the function.
+  const NativeLocation& pointer_location() const { return pointer_location_; }
+
+  // The location where the pointer is returned from the function.
+  const NativeLocation& pointer_return_location() const {
+    return pointer_return_location_;
+  }
+
+ private:
+  const NativeLocation& pointer_location_;
+  // The return location is only in use for return values, not for arguments.
+  const NativeLocation& pointer_return_location_;
+
+  DISALLOW_COPY_AND_ASSIGN(PointerToMemoryLocation);
+};
+
+using NativeLocations = ZoneGrowableArray<const NativeLocation*>;
+
+// A struct broken up over multiple native locations.
+class MultipleNativeLocations : public NativeLocation {
+ public:
+  MultipleNativeLocations(const NativeCompoundType& payload_type,
+                          const NativeLocations& locations)
+      : NativeLocation(payload_type, payload_type), locations_(locations) {}
+  virtual ~MultipleNativeLocations() {}
+
+  virtual bool IsMultiple() const { return true; }
+
+  virtual void PrintTo(BaseTextBuffer* f) const;
+
+  virtual NativeLocation& WithOtherNativeType(
+      Zone* zone,
+      const NativeType& new_payload_type,
+      const NativeType& new_container_type) const {
+    UNREACHABLE();
+  }
+
+  virtual intptr_t StackTopInBytes() const;
+
+  const NativeLocations& locations() const { return locations_; }
+
+ private:
+  const NativeLocations& locations_;
+  DISALLOW_COPY_AND_ASSIGN(MultipleNativeLocations);
+};
+
+#if !defined(FFI_UNIT_TESTS)
 // Return a memory operand for stack slot locations.
 compiler::Address NativeLocationToStackSlotAddress(
     const NativeStackLocation& loc);
+#endif
 
 }  // namespace ffi
 
diff --git a/runtime/vm/compiler/ffi/native_location_test.cc b/runtime/vm/compiler/ffi/native_location_test.cc
new file mode 100644
index 0000000..8ba10d9
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_location_test.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/ffi/unit_test.h"
+
+#include "vm/compiler/ffi/native_location.h"
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+UNIT_TEST_CASE_WITH_ZONE(NativeStackLocation) {
+  const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
+
+  const int kUnalignedStackLocation = 17;
+
+  const auto& native_location = *new (Z) NativeStackLocation(
+      native_type, native_type, SPREG, kUnalignedStackLocation);
+
+  EXPECT_EQ(kUnalignedStackLocation + native_type.SizeInBytes(),
+            native_location.StackTopInBytes());
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeStackLocation_Split) {
+  const auto& native_type = *new (Z) NativePrimitiveType(kInt64);
+
+  const auto& native_location =
+      *new (Z) NativeStackLocation(native_type, native_type, SPREG, 0);
+
+  const auto& half_0 = native_location.Split(Z, 2, 0);
+  const auto& half_1 = native_location.Split(Z, 2, 1);
+
+  EXPECT_EQ(0, half_0.offset_in_bytes());
+  EXPECT_EQ(4, half_1.offset_in_bytes());
+}
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc
index 5bb9f4c..1ffb1a2e 100644
--- a/runtime/vm/compiler/ffi/native_type.cc
+++ b/runtime/vm/compiler/ffi/native_type.cc
@@ -6,12 +6,17 @@
 
 #include "platform/assert.h"
 #include "platform/globals.h"
-#include "vm/compiler/runtime_api.h"
-#include "vm/object.h"
+#include "vm/class_id.h"
+#include "vm/constants.h"
+#include "vm/zone_text_buffer.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 #include "vm/compiler/backend/locations.h"
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
+
+#if !defined(FFI_UNIT_TESTS)
+#include "vm/symbols.h"
+#endif
 
 namespace dart {
 
@@ -19,11 +24,33 @@
 
 namespace ffi {
 
+PrimitiveType PrimitiveTypeFromSizeInBytes(intptr_t size) {
+  ASSERT(size <= 8);
+  ASSERT(size > 0);
+  switch (size) {
+    case 1:
+      return kUint8;
+    case 2:
+      return kUint16;
+    case 4:
+      return kUint32;
+    case 8:
+      // Dart unboxed Representation for unsigned and signed is equal.
+      return kInt64;
+  }
+  UNREACHABLE();
+}
+
 const NativePrimitiveType& NativeType::AsPrimitive() const {
   ASSERT(IsPrimitive());
   return static_cast<const NativePrimitiveType&>(*this);
 }
 
+const NativeCompoundType& NativeType::AsCompound() const {
+  ASSERT(IsCompound());
+  return static_cast<const NativeCompoundType&>(*this);
+}
+
 bool NativePrimitiveType::IsInt() const {
   switch (representation_) {
     case kInt8:
@@ -126,7 +153,58 @@
   }
 }
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+static bool ContainsHomogenuousFloatsInternal(const NativeTypes& types);
+
+// Keep consistent with
+// pkg/vm/lib/transformations/ffi_definitions.dart:_calculateSizeAndOffsets.
+NativeCompoundType& NativeCompoundType::FromNativeTypes(
+    Zone* zone,
+    const NativeTypes& members) {
+  intptr_t offset = 0;
+
+  const intptr_t kAtLeast1ByteAligned = 1;
+  // If this struct is nested in another struct, it should be aligned to the
+  // largest alignment of its members.
+  intptr_t alignment_field = kAtLeast1ByteAligned;
+  // If this struct is passed on the stack, it should be aligned to the largest
+  // alignment of its members when passing those members on the stack.
+  intptr_t alignment_stack = kAtLeast1ByteAligned;
+#if defined(TARGET_OS_MACOS_IOS) && defined(TARGET_ARCH_ARM64)
+  // On iOS64 stack values can be less aligned than wordSize, which deviates
+  // from the arm64 ABI.
+  ASSERT(CallingConventions::kArgumentStackAlignment == kAlignedToValueSize);
+  // Because the arm64 ABI aligns primitives to word size on the stack, every
+  // struct will be automatically aligned to word size. iOS64 does not align
+  // the primitives to word size, so we set structs to align to word size for
+  // iOS64.
+  // However, homogenous structs are treated differently. They are aligned to
+  // their member alignment. (Which is 4 in case of a homogenous float).
+  // Source: manual testing.
+  if (!ContainsHomogenuousFloatsInternal(members)) {
+    alignment_stack = compiler::target::kWordSize;
+  }
+#endif
+
+  auto& member_offsets =
+      *new (zone) ZoneGrowableArray<intptr_t>(zone, members.length());
+  for (intptr_t i = 0; i < members.length(); i++) {
+    const NativeType& member = *members[i];
+    const intptr_t member_size = member.SizeInBytes();
+    const intptr_t member_align_field = member.AlignmentInBytesField();
+    const intptr_t member_align_stack = member.AlignmentInBytesStack();
+    offset = Utils::RoundUp(offset, member_align_field);
+    member_offsets.Add(offset);
+    offset += member_size;
+    alignment_field = Utils::Maximum(alignment_field, member_align_field);
+    alignment_stack = Utils::Maximum(alignment_stack, member_align_stack);
+  }
+  const intptr_t size = Utils::RoundUp(offset, alignment_field);
+
+  return *new (zone) NativeCompoundType(members, member_offsets, size,
+                                        alignment_field, alignment_stack);
+}
+
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 bool NativePrimitiveType::IsExpressibleAsRepresentation() const {
   switch (representation_) {
     case kInt8:
@@ -138,7 +216,7 @@
     case kInt32:
     case kUint32:
     case kInt64:
-    case kUint64:
+    case kUint64:  // We don't actually have a kUnboxedUint64.
     case kFloat:
     case kDouble:
       return true;
@@ -169,7 +247,7 @@
       UNREACHABLE();
   }
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 
 bool NativePrimitiveType::Equals(const NativeType& other) const {
   if (!other.IsPrimitive()) {
@@ -178,6 +256,23 @@
   return other.AsPrimitive().representation_ == representation_;
 }
 
+bool NativeCompoundType::Equals(const NativeType& other) const {
+  if (!other.IsCompound()) {
+    return false;
+  }
+  const auto& other_compound = other.AsCompound();
+  const auto& other_members = other_compound.members_;
+  if (other_members.length() != members_.length()) {
+    return false;
+  }
+  for (intptr_t i = 0; i < members_.length(); i++) {
+    if (!members_[i]->Equals(*other_members[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
 static PrimitiveType split_fundamental(PrimitiveType in) {
   switch (in) {
     case kInt16:
@@ -243,17 +338,43 @@
 }
 
 NativeType& NativeType::FromTypedDataClassId(Zone* zone, classid_t class_id) {
-  // TODO(36730): Support composites.
+  ASSERT(IsFfiPredefinedClassId(class_id));
   const auto fundamental_rep = TypeRepresentation(class_id);
   return *new (zone) NativePrimitiveType(fundamental_rep);
 }
 
+#if !defined(FFI_UNIT_TESTS)
 NativeType& NativeType::FromAbstractType(Zone* zone, const AbstractType& type) {
-  // TODO(36730): Support composites.
-  return NativeType::FromTypedDataClassId(zone, type.type_class_id());
-}
+  const classid_t class_id = type.type_class_id();
+  if (IsFfiPredefinedClassId(class_id)) {
+    return NativeType::FromTypedDataClassId(zone, class_id);
+  }
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+  // User-defined structs.
+  const auto& cls = Class::Handle(zone, type.type_class());
+
+  auto& options = Object::Handle(zone);
+  Library::FindPragma(dart::Thread::Current(), /*only_core=*/false, cls,
+                      Symbols::vm_ffi_struct_fields(), &options);
+  ASSERT(!options.IsNull());
+  ASSERT(options.IsArray());
+
+  const auto& field_types = Array::Cast(options);
+  auto& field_type = AbstractType::Handle(zone);
+  auto& field_native_types = *new (zone) ZoneGrowableArray<const NativeType*>(
+      zone, field_types.Length());
+  for (intptr_t i = 0; i < field_types.Length(); i++) {
+    field_type ^= field_types.At(i);
+    const NativeType& field_native_type =
+        NativeType::FromAbstractType(zone, field_type);
+    field_native_types.Add(&field_native_type);
+  }
+
+  return NativeCompoundType::FromNativeTypes(zone, field_native_types);
+}
+#endif
+
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 static PrimitiveType fundamental_rep(Representation rep) {
   switch (rep) {
     case kUnboxedDouble:
@@ -276,15 +397,22 @@
                                                            Representation rep) {
   return *new (zone) NativePrimitiveType(fundamental_rep(rep));
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 
-const char* NativeType::ToCString() const {
-  char buffer[1024];
-  BufferFormatter bf(buffer, 1024);
-  PrintTo(&bf);
-  return Thread::Current()->zone()->MakeCopyOfString(buffer);
+const char* NativeType::ToCString(Zone* zone,
+                                  bool multi_line,
+                                  bool verbose) const {
+  ZoneTextBuffer textBuffer(zone);
+  PrintTo(&textBuffer, multi_line, verbose);
+  return textBuffer.buffer();
 }
 
+#if !defined(FFI_UNIT_TESTS)
+const char* NativeType::ToCString() const {
+  return ToCString(Thread::Current()->zone());
+}
+#endif
+
 static const char* PrimitiveTypeToCString(PrimitiveType rep) {
   switch (rep) {
     case kInt8:
@@ -316,14 +444,158 @@
   }
 }
 
-void NativeType::PrintTo(BaseTextBuffer* f) const {
+void NativeType::PrintTo(BaseTextBuffer* f,
+                         bool multi_line,
+                         bool verbose) const {
   f->AddString("I");
 }
 
-void NativePrimitiveType::PrintTo(BaseTextBuffer* f) const {
+void NativePrimitiveType::PrintTo(BaseTextBuffer* f,
+                                  bool multi_line,
+                                  bool verbose) const {
   f->Printf("%s", PrimitiveTypeToCString(representation_));
 }
 
+const char* NativeFunctionType::ToCString(Zone* zone) const {
+  ZoneTextBuffer textBuffer(zone);
+  PrintTo(&textBuffer);
+  return textBuffer.buffer();
+}
+
+void NativeCompoundType::PrintTo(BaseTextBuffer* f,
+                                 bool multi_line,
+                                 bool verbose) const {
+  f->AddString("Compound(");
+  f->Printf("size: %" Pd "", SizeInBytes());
+  if (verbose) {
+    f->Printf(", field alignment: %" Pd ", ", AlignmentInBytesField());
+    f->Printf("stack alignment: %" Pd ", ", AlignmentInBytesStack());
+    f->AddString("members: {");
+    if (multi_line) {
+      f->AddString("\n  ");
+    }
+    for (intptr_t i = 0; i < members_.length(); i++) {
+      if (i > 0) {
+        if (multi_line) {
+          f->AddString(",\n  ");
+        } else {
+          f->AddString(", ");
+        }
+      }
+      f->Printf("%" Pd ": ", member_offsets_[i]);
+      members_[i]->PrintTo(f);
+    }
+    if (multi_line) {
+      f->AddString("\n");
+    }
+    f->AddString("}");
+  }
+  f->AddString(")");
+  if (multi_line) {
+    f->AddString("\n");
+  }
+}
+
+#if !defined(FFI_UNIT_TESTS)
+const char* NativeFunctionType::ToCString() const {
+  return ToCString(Thread::Current()->zone());
+}
+#endif
+
+void NativeFunctionType::PrintTo(BaseTextBuffer* f) const {
+  f->AddString("(");
+  for (intptr_t i = 0; i < argument_types_.length(); i++) {
+    if (i > 0) {
+      f->AddString(", ");
+    }
+    argument_types_[i]->PrintTo(f);
+  }
+  f->AddString(") => ");
+  return_type_.PrintTo(f);
+}
+
+bool NativeCompoundType::ContainsOnlyFloats(intptr_t offset_in_bytes,
+                                            intptr_t size_in_bytes) const {
+  ASSERT(size_in_bytes >= 0);
+  const intptr_t first_byte = offset_in_bytes;
+  const intptr_t last_byte = offset_in_bytes + size_in_bytes - 1;
+  for (intptr_t i = 0; i < members_.length(); i++) {
+    const intptr_t member_first_byte = member_offsets_[i];
+    const intptr_t member_last_byte =
+        member_first_byte + members_[i]->SizeInBytes() - 1;
+    if ((first_byte <= member_first_byte && member_first_byte <= last_byte) ||
+        (first_byte <= member_last_byte && member_last_byte <= last_byte)) {
+      if (members_[i]->IsPrimitive() && !members_[i]->IsFloat()) {
+        return false;
+      }
+      if (members_[i]->IsCompound()) {
+        const auto& nested = members_[i]->AsCompound();
+        const bool nested_only_floats = nested.ContainsOnlyFloats(
+            offset_in_bytes - member_first_byte, size_in_bytes);
+        if (!nested_only_floats) {
+          return false;
+        }
+      }
+    }
+    if (member_first_byte > last_byte) {
+      // None of the remaining members fits the range.
+      break;
+    }
+  }
+  return true;
+}
+
+intptr_t NativeCompoundType::NumberOfWordSizeChunksOnlyFloat() const {
+  // O(n^2) implementation, but only invoked for small structs.
+  ASSERT(SizeInBytes() <= 16);
+  const intptr_t size = SizeInBytes();
+  intptr_t float_only_chunks = 0;
+  for (intptr_t offset = 0; offset < size;
+       offset += compiler::target::kWordSize) {
+    if (ContainsOnlyFloats(
+            offset, Utils::Minimum<intptr_t>(size - offset,
+                                             compiler::target::kWordSize))) {
+      float_only_chunks++;
+    }
+  }
+  return float_only_chunks;
+}
+
+intptr_t NativeCompoundType::NumberOfWordSizeChunksNotOnlyFloat() const {
+  const intptr_t total_chunks =
+      Utils::RoundUp(SizeInBytes(), compiler::target::kWordSize) /
+      compiler::target::kWordSize;
+  return total_chunks - NumberOfWordSizeChunksOnlyFloat();
+}
+
+static void ContainsHomogenuousFloatsRecursive(const NativeTypes& types,
+                                               bool* only_float,
+                                               bool* only_double) {
+  for (intptr_t i = 0; i < types.length(); i++) {
+    const auto& member_type = types.At(i);
+    if (member_type->IsPrimitive()) {
+      PrimitiveType type = member_type->AsPrimitive().representation();
+      *only_float = *only_float && (type == kFloat);
+      *only_double = *only_double && (type == kDouble);
+    }
+    if (member_type->IsCompound()) {
+      ContainsHomogenuousFloatsRecursive(member_type->AsCompound().members(),
+                                         only_float, only_double);
+    }
+  }
+}
+
+static bool ContainsHomogenuousFloatsInternal(const NativeTypes& types) {
+  bool only_float = true;
+  bool only_double = true;
+  ContainsHomogenuousFloatsRecursive(types, &only_float, &only_double);
+  return (only_double || only_float) && types.length() > 0;
+}
+
+bool NativeCompoundType::ContainsHomogenuousFloats() const {
+  return ContainsHomogenuousFloatsInternal(this->members());
+}
+
 const NativeType& NativeType::WidenTo4Bytes(Zone* zone) const {
   if (IsInt() && SizeInBytes() <= 2) {
     if (IsSigned()) {
diff --git a/runtime/vm/compiler/ffi/native_type.h b/runtime/vm/compiler/ffi/native_type.h
index 66d5f31..140c54f 100644
--- a/runtime/vm/compiler/ffi/native_type.h
+++ b/runtime/vm/compiler/ffi/native_type.h
@@ -5,15 +5,17 @@
 #ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_TYPE_H_
 #define RUNTIME_VM_COMPILER_FFI_NATIVE_TYPE_H_
 
-#include <platform/globals.h>
-
 #include "platform/assert.h"
+#include "platform/globals.h"
 #include "vm/allocation.h"
-#include "vm/compiler/runtime_api.h"
+#include "vm/growable_array.h"
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 #include "vm/compiler/backend/locations.h"
 #endif
+#if !defined(FFI_UNIT_TESTS)
+#include "vm/object.h"
+#endif
 
 namespace dart {
 
@@ -24,6 +26,7 @@
 namespace ffi {
 
 class NativePrimitiveType;
+class NativeCompoundType;
 
 // NativeTypes are the types used in calling convention specifications:
 // integers, floats, and composites.
@@ -38,35 +41,37 @@
 //
 // Instead, NativeTypes support representations not supported in Dart's unboxed
 // Representations, such as:
-// * Primitive types:
+// * Primitive types (https://en.cppreference.com/w/cpp/language/types):
 //   * int8_t
 //   * int16_t
 //   * uint8_t
 //   * uint16t
 //   * void
-// * Compound types:
+// * Compound types (https://en.cppreference.com/w/cpp/language/type):
 //   * Struct
 //   * Union
-//
-// TODO(36730): Add composites.
 class NativeType : public ZoneAllocated {
  public:
+#if !defined(FFI_UNIT_TESTS)
   static NativeType& FromAbstractType(Zone* zone, const AbstractType& type);
+#endif
   static NativeType& FromTypedDataClassId(Zone* zone, classid_t class_id);
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
   static NativePrimitiveType& FromUnboxedRepresentation(Zone* zone,
                                                         Representation rep);
-#endif
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 
   virtual bool IsPrimitive() const { return false; }
   const NativePrimitiveType& AsPrimitive() const;
+  virtual bool IsCompound() const { return false; }
+  const NativeCompoundType& AsCompound() const;
 
   virtual bool IsInt() const { return false; }
   virtual bool IsFloat() const { return false; }
   virtual bool IsVoid() const { return false; }
 
-  virtual bool IsSigned() const = 0;
+  virtual bool IsSigned() const { return false; }
 
   // The size in bytes of this representation.
   //
@@ -79,19 +84,19 @@
   // The alignment in bytes of this representation as member of a composite.
   virtual intptr_t AlignmentInBytesField() const = 0;
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
   // NativeTypes which are available as unboxed Representations.
   virtual bool IsExpressibleAsRepresentation() const { return false; }
 
   // Unboxed Representation if it exists.
-  virtual Representation AsRepresentation() const = 0;
+  virtual Representation AsRepresentation() const { UNREACHABLE(); }
 
   // Unboxed Representation, over approximates if needed.
   Representation AsRepresentationOverApprox(Zone* zone_) const {
     const auto& widened = WidenTo4Bytes(zone_);
     return widened.AsRepresentation();
   }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 
   virtual bool Equals(const NativeType& other) const { UNREACHABLE(); }
 
@@ -102,8 +107,15 @@
   // Otherwise, return original representation.
   const NativeType& WidenTo4Bytes(Zone* zone) const;
 
-  virtual void PrintTo(BaseTextBuffer* f) const;
+  virtual void PrintTo(BaseTextBuffer* f,
+                       bool multi_line = false,
+                       bool verbose = true) const;
+  const char* ToCString(Zone* zone,
+                        bool multi_line = false,
+                        bool verbose = true) const;
+#if !defined(FFI_UNIT_TESTS)
   const char* ToCString() const;
+#endif
 
   virtual ~NativeType() {}
 
@@ -127,6 +139,8 @@
   // TODO(37470): Add packed data structures.
 };
 
+PrimitiveType PrimitiveTypeFromSizeInBytes(intptr_t size);
+
 // Represents a primitive native type.
 //
 // These are called object types in the C standard (ISO/IEC 9899:2011) and
@@ -151,15 +165,17 @@
   virtual intptr_t AlignmentInBytesStack() const;
   virtual intptr_t AlignmentInBytesField() const;
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
   virtual bool IsExpressibleAsRepresentation() const;
   virtual Representation AsRepresentation() const;
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
 
   virtual bool Equals(const NativeType& other) const;
   virtual NativePrimitiveType& Split(Zone* zone, intptr_t part) const;
 
-  virtual void PrintTo(BaseTextBuffer* f) const;
+  virtual void PrintTo(BaseTextBuffer* f,
+                       bool multi_line = false,
+                       bool verbose = true) const;
 
   virtual ~NativePrimitiveType() {}
 
@@ -167,6 +183,96 @@
   const PrimitiveType representation_;
 };
 
+using NativeTypes = ZoneGrowableArray<const NativeType*>;
+
+// Struct
+//
+// TODO(dartbug.com/38491): Support unions.
+// TODO(dartbug.com/37271): Support nested compound types.
+// TODO(dartbug.com/35763): Support inline fixed-length arrays.
+class NativeCompoundType : public NativeType {
+ public:
+  static NativeCompoundType& FromNativeTypes(Zone* zone,
+                                             const NativeTypes& members);
+
+  const NativeTypes& members() const { return members_; }
+  const ZoneGrowableArray<intptr_t>& member_offsets() const {
+    return member_offsets_;
+  }
+
+  virtual bool IsCompound() const { return true; }
+
+  virtual intptr_t SizeInBytes() const { return size_; }
+  virtual intptr_t AlignmentInBytesField() const { return alignment_field_; }
+  virtual intptr_t AlignmentInBytesStack() const { return alignment_stack_; }
+
+  virtual bool Equals(const NativeType& other) const;
+
+  virtual void PrintTo(BaseTextBuffer* f,
+                       bool multi_line = false,
+                       bool verbose = true) const;
+
+  // Whether a range within a struct contains only floats.
+  //
+  // Useful for determining whether struct is passed in FP registers on x64.
+  bool ContainsOnlyFloats(intptr_t offset_in_bytes,
+                          intptr_t size_in_bytes) const;
+
+  // Returns how many word-sized chuncks _only_ contain floats.
+  //
+  // Useful for determining whether struct is passed in FP registers on x64.
+  intptr_t NumberOfWordSizeChunksOnlyFloat() const;
+
+  // Returns how many word-sized chunks do not _only_ contain floats.
+  //
+  // Useful for determining whether struct is passed in FP registers on x64.
+  intptr_t NumberOfWordSizeChunksNotOnlyFloat() const;
+
+  // Whether this type has only same-size floating point members.
+  //
+  // Useful for determining whether struct is passed in FP registers in hardfp
+  // and arm64.
+  bool ContainsHomogenuousFloats() const;
+
+ private:
+  NativeCompoundType(const NativeTypes& members,
+                     const ZoneGrowableArray<intptr_t>& member_offsets,
+                     intptr_t size,
+                     intptr_t alignment_field,
+                     intptr_t alignment_stack)
+      : members_(members),
+        member_offsets_(member_offsets),
+        size_(size),
+        alignment_field_(alignment_field),
+        alignment_stack_(alignment_stack) {}
+
+  const NativeTypes& members_;
+  const ZoneGrowableArray<intptr_t>& member_offsets_;
+  const intptr_t size_;
+  const intptr_t alignment_field_;
+  const intptr_t alignment_stack_;
+};
+
+class NativeFunctionType : public ZoneAllocated {
+ public:
+  NativeFunctionType(const NativeTypes& argument_types,
+                     const NativeType& return_type)
+      : argument_types_(argument_types), return_type_(return_type) {}
+
+  const NativeTypes& argument_types() const { return argument_types_; }
+  const NativeType& return_type() const { return return_type_; }
+
+  void PrintTo(BaseTextBuffer* f) const;
+  const char* ToCString(Zone* zone) const;
+#if !defined(FFI_UNIT_TESTS)
+  const char* ToCString() const;
+#endif
+
+ private:
+  const NativeTypes& argument_types_;
+  const NativeType& return_type_;
+};
+
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi/native_type_test.cc b/runtime/vm/compiler/ffi/native_type_test.cc
new file mode 100644
index 0000000..66fa987
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_type_test.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/ffi/unit_test.h"
+
+#include "platform/syslog.h"
+#include "vm/compiler/ffi/native_type.h"
+#include "vm/compiler/runtime_api.h"
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+const NativeCompoundType& RunStructTest(dart::Zone* zone,
+                                        const char* name,
+                                        const NativeTypes& member_types) {
+  const auto& struct_type =
+      NativeCompoundType::FromNativeTypes(zone, member_types);
+
+  const char* test_result = struct_type.ToCString(zone, /*multi_line=*/true);
+
+  const int kFilePathLength = 100;
+  char expectation_file_path[kFilePathLength];
+  Utils::SNPrint(expectation_file_path, kFilePathLength,
+                 "runtime/vm/compiler/ffi/unit_tests/%s/%s_%s.expect", name,
+                 kArch, kOs);
+
+  if (TestCaseBase::update_expectations) {
+    Syslog::Print("Updating %s\n", expectation_file_path);
+    WriteToFile(expectation_file_path, test_result);
+  }
+
+  char* expectation_file_contents = nullptr;
+  ReadFromFile(expectation_file_path, &expectation_file_contents);
+  EXPECT_NOTNULL(expectation_file_contents);
+  if (expectation_file_contents != nullptr) {
+    EXPECT_STREQ(expectation_file_contents, test_result);
+    free(expectation_file_contents);
+  }
+
+  return struct_type;
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeType) {
+  const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
+
+  EXPECT_EQ(1, native_type.SizeInBytes());
+  EXPECT(native_type.IsInt());
+  EXPECT(native_type.IsPrimitive());
+
+  EXPECT_STREQ("int8", native_type.ToCString(Z));
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_int8x10) {
+  const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
+
+  auto& members = *new (Z) NativeTypes(Z, 10);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+  members.Add(&int8type);
+
+  const auto& struct_type = RunStructTest(Z, "struct_int8x10", members);
+
+  EXPECT(!struct_type.ContainsHomogenuousFloats());
+  EXPECT(!struct_type.ContainsOnlyFloats(0, 8));
+  EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksOnlyFloat());
+  EXPECT_EQ(
+      Utils::RoundUp(struct_type.SizeInBytes(), compiler::target::kWordSize) /
+          compiler::target::kWordSize,
+      struct_type.NumberOfWordSizeChunksNotOnlyFloat());
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_floatx4) {
+  const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
+
+  auto& members = *new (Z) NativeTypes(Z, 4);
+  members.Add(&float_type);
+  members.Add(&float_type);
+  members.Add(&float_type);
+  members.Add(&float_type);
+
+  const auto& struct_type = RunStructTest(Z, "struct_floatx4", members);
+
+  // This is a homogenous float in the arm and arm64 ABIs.
+  //
+  // On Arm64 iOS stack alignment of homogenous floats is not word size see
+  // runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_ios.expect.
+  EXPECT(struct_type.ContainsHomogenuousFloats());
+
+  // On x64, 8-byte parts of the chunks contain only floats and will be passed
+  // in FPU registers.
+  EXPECT(struct_type.ContainsOnlyFloats(0, 8));
+  EXPECT(struct_type.ContainsOnlyFloats(8, 8));
+  EXPECT_EQ(struct_type.SizeInBytes() / compiler::target::kWordSize,
+            struct_type.NumberOfWordSizeChunksOnlyFloat());
+  EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksNotOnlyFloat());
+}
+
+// A struct designed to exercise all kinds of alignment rules.
+// Note that offset32A (System V ia32, iOS arm) aligns doubles on 4 bytes while
+// offset32B (Arm 32 bit and MSVC ia32) aligns on 8 bytes.
+// TODO(37271): Support nested structs.
+// TODO(37470): Add uncommon primitive data types when we want to support them.
+struct VeryLargeStruct {
+  //                             size32 size64 offset32A offset32B offset64
+  int8_t a;                   // 1              0         0         0
+  int16_t b;                  // 2              2         2         2
+  int32_t c;                  // 4              4         4         4
+  int64_t d;                  // 8              8         8         8
+  uint8_t e;                  // 1             16        16        16
+  uint16_t f;                 // 2             18        18        18
+  uint32_t g;                 // 4             20        20        20
+  uint64_t h;                 // 8             24        24        24
+  intptr_t i;                 // 4      8      32        32        32
+  double j;                   // 8             36        40        40
+  float k;                    // 4             44        48        48
+  VeryLargeStruct* parent;    // 4      8      48        52        56
+  intptr_t numChildren;       // 4      8      52        56        64
+  VeryLargeStruct* children;  // 4      8      56        60        72
+  int8_t smallLastField;      // 1             60        64        80
+                              // sizeof        64        72        88
+};
+
+UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_VeryLargeStruct) {
+  const auto& intptr_type = *new (Z) NativePrimitiveType(
+      compiler::target::kWordSize == 4 ? kInt32 : kInt64);
+
+  auto& members = *new (Z) NativeTypes(Z, 15);
+  members.Add(new (Z) NativePrimitiveType(kInt8));
+  members.Add(new (Z) NativePrimitiveType(kInt16));
+  members.Add(new (Z) NativePrimitiveType(kInt32));
+  members.Add(new (Z) NativePrimitiveType(kInt64));
+  members.Add(new (Z) NativePrimitiveType(kUint8));
+  members.Add(new (Z) NativePrimitiveType(kUint16));
+  members.Add(new (Z) NativePrimitiveType(kUint32));
+  members.Add(new (Z) NativePrimitiveType(kUint64));
+  members.Add(&intptr_type);
+  members.Add(new (Z) NativePrimitiveType(kDouble));
+  members.Add(new (Z) NativePrimitiveType(kFloat));
+  members.Add(&intptr_type);
+  members.Add(&intptr_type);
+  members.Add(&intptr_type);
+  members.Add(new (Z) NativePrimitiveType(kInt8));
+
+  RunStructTest(Z, "struct_VeryLargeStruct", members);
+}
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/native_type_vm_test.cc b/runtime/vm/compiler/ffi/native_type_vm_test.cc
new file mode 100644
index 0000000..52f0835
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_type_vm_test.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/ffi/native_type.h"
+
+#include "vm/compiler/backend/il_test_helper.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+ISOLATE_UNIT_TEST_CASE(Ffi_NativeType_Primitive_FromAbstractType) {
+  Zone* Z = thread->zone();
+
+  const auto& ffi_library = Library::Handle(Library::FfiLibrary());
+  const auto& int8_class = Class::Handle(GetClass(ffi_library, "Int8"));
+  const auto& int8_type = Type::Handle(int8_class.DeclarationType());
+  const auto& native_type = NativeType::FromAbstractType(Z, int8_type);
+
+  EXPECT_EQ(1, native_type.SizeInBytes());
+  EXPECT_STREQ("int8", native_type.ToCString());
+  EXPECT(native_type.IsInt());
+  EXPECT(native_type.IsPrimitive());
+}
+
+// Test that we construct `NativeType` correctly from `Type`.
+ISOLATE_UNIT_TEST_CASE(Ffi_NativeType_Struct_FromAbstractType) {
+  Zone* Z = thread->zone();
+
+  const char* kScript =
+      R"(
+      import 'dart:ffi';
+
+      class MyStruct extends Struct {
+        @Int8()
+        external int a0;
+
+        external Pointer<Int8> a1;
+      }
+      )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  const auto& struct_class = Class::Handle(GetClass(root_library, "MyStruct"));
+  const auto& struct_type = Type::Handle(struct_class.DeclarationType());
+
+  const auto& native_type =
+      NativeType::FromAbstractType(Z, struct_type).AsCompound();
+
+  EXPECT_EQ(2, native_type.members().length());
+
+  const auto& int8_type = *new (Z) NativePrimitiveType(kInt8);
+  EXPECT(int8_type.Equals(*native_type.members()[0]));
+
+  EXPECT_EQ(compiler::target::kWordSize,
+            native_type.members()[1]->SizeInBytes());
+}
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/unit_test.cc b/runtime/vm/compiler/ffi/unit_test.cc
new file mode 100644
index 0000000..044b398
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_test.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/ffi/unit_test.h"
+
+#include "platform/syslog.h"
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+#if defined(TARGET_ARCH_ARM)
+const char* kArch = "arm";
+#elif defined(TARGET_ARCH_ARM64)
+const char* kArch = "arm64";
+#elif defined(TARGET_ARCH_IA32)
+const char* kArch = "ia32";
+#elif defined(TARGET_ARCH_X64)
+const char* kArch = "x64";
+#endif
+
+#if defined(TARGET_OS_ANDROID)
+const char* kOs = "android";
+#elif defined(TARGET_OS_MACOS_IOS)
+const char* kOs = "ios";
+#elif defined(TARGET_OS_LINUX)
+const char* kOs = "linux";
+#elif defined(TARGET_OS_MACOS)
+const char* kOs = "macos";
+#elif defined(TARGET_OS_WINDOWS)
+const char* kOs = "win";
+#endif
+
+void WriteToFile(char* path, const char* contents) {
+  FILE* file;
+  file = fopen(path, "w");
+  if (file != nullptr) {
+    fprintf(file, "%s", contents);
+  } else {
+    Syslog::Print("Error %d \n", errno);
+  }
+  fclose(file);
+}
+
+void ReadFromFile(char* path, char** buffer_pointer) {
+  FILE* file = fopen(path, "rb");
+  if (file == nullptr) {
+    Syslog::Print("Error %d \n", errno);
+    return;
+  }
+
+  fseek(file, 0, SEEK_END);
+  size_t size = ftell(file);
+  rewind(file);
+
+  char* buffer = reinterpret_cast<char*>(malloc(sizeof(char) * (size + 1)));
+
+  fread(buffer, 1, size, file);
+  buffer[size] = 0;
+
+  fclose(file);
+  *buffer_pointer = buffer;
+}
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/unit_test.h b/runtime/vm/compiler/ffi/unit_test.h
new file mode 100644
index 0000000..5cb4da0
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_test.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A slimmed down version of runtime/vm/unit_test.h that only runs C++
+// non-DartVM unit tests.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_UNIT_TEST_H_
+#define RUNTIME_VM_COMPILER_FFI_UNIT_TEST_H_
+
+// Don't use the DartVM zone, so include this first.
+#include "vm/compiler/ffi/unit_test_custom_zone.h"
+
+#include "platform/globals.h"
+
+// The UNIT_TEST_CASE macro is used for tests.
+#define UNIT_TEST_CASE_WITH_EXPECTATION(name, expectation)                     \
+  void Dart_Test##name();                                                      \
+  static const dart::compiler::ffi::RawTestCase kRegister##name(               \
+      Dart_Test##name, #name, expectation);                                    \
+  void Dart_Test##name()
+
+#define UNIT_TEST_CASE(name) UNIT_TEST_CASE_WITH_EXPECTATION(name, "Pass")
+
+// The UNIT_TEST_CASE_WITH_ZONE macro is used for tests that need a custom
+// dart::Zone.
+#define UNIT_TEST_CASE_WITH_ZONE_WITH_EXPECTATION(name, expectation)           \
+  static void Dart_TestHelper##name(dart::Zone* Z);                            \
+  UNIT_TEST_CASE_WITH_EXPECTATION(name, expectation) {                         \
+    dart::Zone zone;                                                           \
+    Dart_TestHelper##name(&zone);                                              \
+  }                                                                            \
+  static void Dart_TestHelper##name(dart::Zone* Z)
+
+#define UNIT_TEST_CASE_WITH_ZONE(name)                                         \
+  UNIT_TEST_CASE_WITH_ZONE_WITH_EXPECTATION(name, "Pass")
+
+namespace dart {
+namespace compiler {
+namespace ffi {
+
+extern const char* kArch;
+extern const char* kOs;
+
+void WriteToFile(char* path, const char* contents);
+
+void ReadFromFile(char* path, char** buffer_pointer);
+
+class TestCaseBase {
+ public:
+  explicit TestCaseBase(const char* name, const char* expectation);
+  virtual ~TestCaseBase() {}
+
+  const char* name() const { return name_; }
+  const char* expectation() const { return expectation_; }
+
+  virtual void Run() = 0;
+  void RunTest();
+
+  static void RunAll();
+  static void RunAllRaw();
+
+  static bool update_expectations;
+
+ private:
+  static TestCaseBase* first_;
+  static TestCaseBase* tail_;
+
+  TestCaseBase* next_;
+  const char* name_;
+  const char* expectation_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestCaseBase);
+};
+
+class RawTestCase : TestCaseBase {
+ public:
+  typedef void(RunEntry)();
+
+  RawTestCase(RunEntry* run, const char* name, const char* expectation)
+      : TestCaseBase(name, expectation), run_(run) {}
+  virtual void Run();
+
+ private:
+  RunEntry* const run_;
+};
+
+}  // namespace ffi
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_UNIT_TEST_H_
diff --git a/runtime/vm/compiler/ffi/unit_test_custom_zone.cc b/runtime/vm/compiler/ffi/unit_test_custom_zone.cc
new file mode 100644
index 0000000..90f01cf
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_test_custom_zone.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/ffi/unit_test_custom_zone.h"
+
+#include "vm/compiler/runtime_api.h"
+
+// Directly compile cc files into the custom zone, so that we do not get linker
+// errors from object files compiled against the DartVM Zone.
+#include "vm/compiler/ffi/native_calling_convention.cc"  // NOLINT
+#include "vm/compiler/ffi/native_location.cc"            // NOLINT
+#include "vm/compiler/ffi/native_type.cc"                // NOLINT
+#include "vm/zone_text_buffer.cc"                        // NOLINT
+
+namespace dart {
+
+void* ZoneAllocated::operator new(uintptr_t size, dart::Zone* zone) {
+  return reinterpret_cast<void*>(zone->AllocUnsafe(size));
+}
+
+Zone::~Zone() {
+  while (buffers_.size() > 0) {
+    free(buffers_.back());
+    buffers_.pop_back();
+  }
+}
+
+void* Zone::AllocUnsafe(intptr_t size) {
+  void* memory = malloc(size);
+  buffers_.push_back(memory);
+  return memory;
+}
+
+DART_EXPORT void Dart_PrepareToAbort() {
+  fprintf(stderr, "Dart_PrepareToAbort() not implemented!\n");
+  exit(1);
+}
+
+DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
+  fprintf(stderr, "Dart_DumpNativeStackTrace() not implemented!\n");
+  exit(1);
+}
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/unit_test_custom_zone.h b/runtime/vm/compiler/ffi/unit_test_custom_zone.h
new file mode 100644
index 0000000..ac305a1
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_test_custom_zone.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_UNIT_TEST_CUSTOM_ZONE_H_
+#define RUNTIME_VM_COMPILER_FFI_UNIT_TEST_CUSTOM_ZONE_H_
+
+#include <vector>
+
+// We use a custom zone here which doesn't depend on VM internals (e.g. handles,
+// thread, ...)
+#if defined(RUNTIME_VM_ZONE_H_)
+#error "We want our own zone implementation"
+#endif
+#define RUNTIME_VM_ZONE_H_
+
+namespace dart {
+
+class Zone {
+ public:
+  Zone() {}
+  ~Zone();
+
+  template <class ElementType>
+  inline ElementType* Alloc(intptr_t length) {
+    return static_cast<ElementType*>(AllocUnsafe(sizeof(ElementType) * length));
+  }
+
+  template <class ElementType>
+  inline ElementType* Realloc(ElementType* old_array,
+                              intptr_t old_length,
+                              intptr_t new_length) {
+    void* memory = AllocUnsafe(sizeof(ElementType) * new_length);
+    memmove(memory, old_array, sizeof(ElementType) * old_length);
+    return static_cast<ElementType*>(memory);
+  }
+
+  template <class ElementType>
+  void Free(ElementType* old_array, intptr_t len) {}
+
+  void* AllocUnsafe(intptr_t size);
+
+ private:
+  Zone(const Zone&) = delete;
+  void operator=(const Zone&) = delete;
+  std::vector<void*> buffers_;
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_UNIT_TEST_CUSTOM_ZONE_H_
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_android.expect
new file mode 100644
index 0000000..8f237e3
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_android.expect
@@ -0,0 +1,12 @@
+v0 float
+v1 float
+v2 float
+v3 float
+v4 float
+v5 float
+v6 float
+v7 float
+S+0 float
+S+8 float
+=>
+v0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_ios.expect
new file mode 100644
index 0000000..0a25996
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_ios.expect
@@ -0,0 +1,12 @@
+v0 float
+v1 float
+v2 float
+v3 float
+v4 float
+v5 float
+v6 float
+v7 float
+S+0 float
+S+4 float
+=>
+v0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_linux.expect
new file mode 100644
index 0000000..8f237e3
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_linux.expect
@@ -0,0 +1,12 @@
+v0 float
+v1 float
+v2 float
+v3 float
+v4 float
+v5 float
+v6 float
+v7 float
+S+0 float
+S+8 float
+=>
+v0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_macos.expect
new file mode 100644
index 0000000..8f237e3
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_macos.expect
@@ -0,0 +1,12 @@
+v0 float
+v1 float
+v2 float
+v3 float
+v4 float
+v5 float
+v6 float
+v7 float
+S+0 float
+S+8 float
+=>
+v0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_android.expect
new file mode 100644
index 0000000..f563dbd
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_android.expect
@@ -0,0 +1,12 @@
+r0 int32[float]
+r1 int32[float]
+r2 int32[float]
+r3 int32[float]
+S+0 float
+S+4 float
+S+8 float
+S+12 float
+S+16 float
+S+20 float
+=>
+r0 int32[float]
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_ios.expect
new file mode 100644
index 0000000..9ff44a7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_ios.expect
@@ -0,0 +1,12 @@
+s0 float
+s1 float
+s2 float
+s3 float
+s4 float
+s5 float
+s6 float
+s7 float
+s8 float
+s9 float
+=>
+q0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_linux.expect
new file mode 100644
index 0000000..9ff44a7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/arm_linux.expect
@@ -0,0 +1,12 @@
+s0 float
+s1 float
+s2 float
+s3 float
+s4 float
+s5 float
+s6 float
+s7 float
+s8 float
+s9 float
+=>
+q0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_android.expect
new file mode 100644
index 0000000..c4390e7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_android.expect
@@ -0,0 +1,12 @@
+S+0 float
+S+4 float
+S+8 float
+S+12 float
+S+16 float
+S+20 float
+S+24 float
+S+28 float
+S+32 float
+S+36 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_linux.expect
new file mode 100644
index 0000000..c4390e7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_linux.expect
@@ -0,0 +1,12 @@
+S+0 float
+S+4 float
+S+8 float
+S+12 float
+S+16 float
+S+20 float
+S+24 float
+S+28 float
+S+32 float
+S+36 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_win.expect
new file mode 100644
index 0000000..c4390e7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_win.expect
@@ -0,0 +1,12 @@
+S+0 float
+S+4 float
+S+8 float
+S+12 float
+S+16 float
+S+20 float
+S+24 float
+S+28 float
+S+32 float
+S+36 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_ios.expect
new file mode 100644
index 0000000..b650130
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_ios.expect
@@ -0,0 +1,12 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+xmm4 float
+xmm5 float
+xmm6 float
+xmm7 float
+S+0 float
+S+8 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_linux.expect
new file mode 100644
index 0000000..b650130
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_linux.expect
@@ -0,0 +1,12 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+xmm4 float
+xmm5 float
+xmm6 float
+xmm7 float
+S+0 float
+S+8 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_macos.expect
new file mode 100644
index 0000000..b650130
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_macos.expect
@@ -0,0 +1,12 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+xmm4 float
+xmm5 float
+xmm6 float
+xmm7 float
+S+0 float
+S+8 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_win.expect
new file mode 100644
index 0000000..1244587
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/floatx10/x64_win.expect
@@ -0,0 +1,12 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+S+0 float
+S+8 float
+S+16 float
+S+24 float
+S+32 float
+S+40 float
+=>
+xmm0 float
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_android.expect
new file mode 100644
index 0000000..04f72e5f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_android.expect
@@ -0,0 +1,12 @@
+r0 int8
+r1 int8
+r2 int8
+r3 int8
+r4 int8
+r5 int8
+r6 int8
+r7 int8
+S+0 int8
+S+8 int8
+=>
+r0 int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_ios.expect
new file mode 100644
index 0000000..f8d22bc
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_ios.expect
@@ -0,0 +1,12 @@
+r0 int32[int8]
+r1 int32[int8]
+r2 int32[int8]
+r3 int32[int8]
+r4 int32[int8]
+r5 int32[int8]
+r6 int32[int8]
+r7 int32[int8]
+S+0 int8
+S+1 int8
+=>
+r0 int32[int8]
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_linux.expect
new file mode 100644
index 0000000..04f72e5f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_linux.expect
@@ -0,0 +1,12 @@
+r0 int8
+r1 int8
+r2 int8
+r3 int8
+r4 int8
+r5 int8
+r6 int8
+r7 int8
+S+0 int8
+S+8 int8
+=>
+r0 int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_macos.expect
new file mode 100644
index 0000000..04f72e5f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_macos.expect
@@ -0,0 +1,12 @@
+r0 int8
+r1 int8
+r2 int8
+r3 int8
+r4 int8
+r5 int8
+r6 int8
+r7 int8
+S+0 int8
+S+8 int8
+=>
+r0 int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_android.expect
new file mode 100644
index 0000000..9307d2f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_android.expect
@@ -0,0 +1,12 @@
+r0 int32[int8]
+r1 int32[int8]
+r2 int32[int8]
+r3 int32[int8]
+S+0 int32[int8]
+S+4 int32[int8]
+S+8 int32[int8]
+S+12 int32[int8]
+S+16 int32[int8]
+S+20 int32[int8]
+=>
+r0 int32[int8]
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_ios.expect
new file mode 100644
index 0000000..9307d2f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_ios.expect
@@ -0,0 +1,12 @@
+r0 int32[int8]
+r1 int32[int8]
+r2 int32[int8]
+r3 int32[int8]
+S+0 int32[int8]
+S+4 int32[int8]
+S+8 int32[int8]
+S+12 int32[int8]
+S+16 int32[int8]
+S+20 int32[int8]
+=>
+r0 int32[int8]
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_linux.expect
new file mode 100644
index 0000000..9307d2f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/arm_linux.expect
@@ -0,0 +1,12 @@
+r0 int32[int8]
+r1 int32[int8]
+r2 int32[int8]
+r3 int32[int8]
+S+0 int32[int8]
+S+4 int32[int8]
+S+8 int32[int8]
+S+12 int32[int8]
+S+16 int32[int8]
+S+20 int32[int8]
+=>
+r0 int32[int8]
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_android.expect
new file mode 100644
index 0000000..bf5f6c4
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_android.expect
@@ -0,0 +1,12 @@
+S+0 int32[int8]
+S+4 int32[int8]
+S+8 int32[int8]
+S+12 int32[int8]
+S+16 int32[int8]
+S+20 int32[int8]
+S+24 int32[int8]
+S+28 int32[int8]
+S+32 int32[int8]
+S+36 int32[int8]
+=>
+eax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_linux.expect
new file mode 100644
index 0000000..bf5f6c4
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_linux.expect
@@ -0,0 +1,12 @@
+S+0 int32[int8]
+S+4 int32[int8]
+S+8 int32[int8]
+S+12 int32[int8]
+S+16 int32[int8]
+S+20 int32[int8]
+S+24 int32[int8]
+S+28 int32[int8]
+S+32 int32[int8]
+S+36 int32[int8]
+=>
+eax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_win.expect
new file mode 100644
index 0000000..bf5f6c4
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_win.expect
@@ -0,0 +1,12 @@
+S+0 int32[int8]
+S+4 int32[int8]
+S+8 int32[int8]
+S+12 int32[int8]
+S+16 int32[int8]
+S+20 int32[int8]
+S+24 int32[int8]
+S+28 int32[int8]
+S+32 int32[int8]
+S+36 int32[int8]
+=>
+eax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_ios.expect
new file mode 100644
index 0000000..0bcad4b
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_ios.expect
@@ -0,0 +1,12 @@
+rdi int32[int8]
+rsi int32[int8]
+rdx int32[int8]
+rcx int32[int8]
+r8 int32[int8]
+r9 int32[int8]
+S+0 int32[int8]
+S+8 int32[int8]
+S+16 int32[int8]
+S+24 int32[int8]
+=>
+rax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_linux.expect
new file mode 100644
index 0000000..0bcad4b
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_linux.expect
@@ -0,0 +1,12 @@
+rdi int32[int8]
+rsi int32[int8]
+rdx int32[int8]
+rcx int32[int8]
+r8 int32[int8]
+r9 int32[int8]
+S+0 int32[int8]
+S+8 int32[int8]
+S+16 int32[int8]
+S+24 int32[int8]
+=>
+rax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_macos.expect
new file mode 100644
index 0000000..0bcad4b
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_macos.expect
@@ -0,0 +1,12 @@
+rdi int32[int8]
+rsi int32[int8]
+rdx int32[int8]
+rcx int32[int8]
+r8 int32[int8]
+r9 int32[int8]
+S+0 int32[int8]
+S+8 int32[int8]
+S+16 int32[int8]
+S+24 int32[int8]
+=>
+rax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_win.expect
new file mode 100644
index 0000000..94704e5
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/int8x10/x64_win.expect
@@ -0,0 +1,12 @@
+rcx int8
+rdx int8
+r8 int8
+r9 int8
+S+0 int8
+S+8 int8
+S+16 int8
+S+24 int8
+S+32 int8
+S+40 int8
+=>
+rax int8
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_android.expect
new file mode 100644
index 0000000..1170c02
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_android.expect
@@ -0,0 +1,4 @@
+P(r0 int64) Compound(size: 128)
+r1 int32
+=>
+P(r8 int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_ios.expect
new file mode 100644
index 0000000..1170c02
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_ios.expect
@@ -0,0 +1,4 @@
+P(r0 int64) Compound(size: 128)
+r1 int32
+=>
+P(r8 int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_linux.expect
new file mode 100644
index 0000000..1170c02
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_linux.expect
@@ -0,0 +1,4 @@
+P(r0 int64) Compound(size: 128)
+r1 int32
+=>
+P(r8 int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_macos.expect
new file mode 100644
index 0000000..1170c02
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm64_macos.expect
@@ -0,0 +1,4 @@
+P(r0 int64) Compound(size: 128)
+r1 int32
+=>
+P(r8 int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_android.expect
new file mode 100644
index 0000000..230a6ab
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_android.expect
@@ -0,0 +1,4 @@
+M((r2, r3) int64, S+0 int64, S+8 int64, S+16 int64, S+24 int64, S+32 int64, S+40 int64, S+48 int64, S+56 int64, S+64 int64, S+72 int64, S+80 int64, S+88 int64, S+96 int64, S+104 int64, S+112 int64) Compound(size: 128)
+S+120 int32
+=>
+P(r0 uint32) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_ios.expect
new file mode 100644
index 0000000..230a6ab
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_ios.expect
@@ -0,0 +1,4 @@
+M((r2, r3) int64, S+0 int64, S+8 int64, S+16 int64, S+24 int64, S+32 int64, S+40 int64, S+48 int64, S+56 int64, S+64 int64, S+72 int64, S+80 int64, S+88 int64, S+96 int64, S+104 int64, S+112 int64) Compound(size: 128)
+S+120 int32
+=>
+P(r0 uint32) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_linux.expect
new file mode 100644
index 0000000..230a6ab
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/arm_linux.expect
@@ -0,0 +1,4 @@
+M((r2, r3) int64, S+0 int64, S+8 int64, S+16 int64, S+24 int64, S+32 int64, S+40 int64, S+48 int64, S+56 int64, S+64 int64, S+72 int64, S+80 int64, S+88 int64, S+96 int64, S+104 int64, S+112 int64) Compound(size: 128)
+S+120 int32
+=>
+P(r0 uint32) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_android.expect
new file mode 100644
index 0000000..c765e39
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_android.expect
@@ -0,0 +1,4 @@
+S+4 Compound(size: 128)
+S+132 int32
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_linux.expect
new file mode 100644
index 0000000..c765e39
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_linux.expect
@@ -0,0 +1,4 @@
+S+4 Compound(size: 128)
+S+132 int32
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_win.expect
new file mode 100644
index 0000000..c765e39
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/ia32_win.expect
@@ -0,0 +1,4 @@
+S+4 Compound(size: 128)
+S+132 int32
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_ios.expect
new file mode 100644
index 0000000..f5ce3da
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_ios.expect
@@ -0,0 +1,4 @@
+S+0 Compound(size: 128)
+rsi int32
+=>
+P(rdi int64, ret:rax int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_linux.expect
new file mode 100644
index 0000000..f5ce3da
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_linux.expect
@@ -0,0 +1,4 @@
+S+0 Compound(size: 128)
+rsi int32
+=>
+P(rdi int64, ret:rax int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_macos.expect
new file mode 100644
index 0000000..f5ce3da
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_macos.expect
@@ -0,0 +1,4 @@
+S+0 Compound(size: 128)
+rsi int32
+=>
+P(rdi int64, ret:rax int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_win.expect
new file mode 100644
index 0000000..ff78425
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct128bytesx1/x64_win.expect
@@ -0,0 +1,4 @@
+P(rdx int64) Compound(size: 128)
+r8 int32
+=>
+P(rcx int64, ret:rax int64) Compound(size: 128)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_android.expect
new file mode 100644
index 0000000..f4b87ed
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_android.expect
@@ -0,0 +1,15 @@
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
+v4 float
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+S+96 Compound(size: 16)
+S+112 Compound(size: 16)
+S+128 float
+r0 int8
+S+136 Compound(size: 16)
+=>
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_ios.expect
new file mode 100644
index 0000000..70977c2
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_ios.expect
@@ -0,0 +1,15 @@
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
+v4 float
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+S+96 Compound(size: 16)
+S+112 Compound(size: 16)
+S+128 float
+r0 int32[int8]
+S+132 Compound(size: 16)
+=>
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_linux.expect
new file mode 100644
index 0000000..f4b87ed
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_linux.expect
@@ -0,0 +1,15 @@
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
+v4 float
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+S+96 Compound(size: 16)
+S+112 Compound(size: 16)
+S+128 float
+r0 int8
+S+136 Compound(size: 16)
+=>
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_macos.expect
new file mode 100644
index 0000000..f4b87ed
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm64_macos.expect
@@ -0,0 +1,15 @@
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
+v4 float
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+S+96 Compound(size: 16)
+S+112 Compound(size: 16)
+S+128 float
+r0 int8
+S+136 Compound(size: 16)
+=>
+M(v0 float, v1 float, v2 float, v3 float) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_android.expect
new file mode 100644
index 0000000..24fce41
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_android.expect
@@ -0,0 +1,15 @@
+M(r1 int32, r2 int32, r3 int32, S+0 int32) Compound(size: 16)
+S+4 float
+M(S+8 int32, S+12 int32, S+16 int32, S+20 int32) Compound(size: 16)
+M(S+24 int32, S+28 int32, S+32 int32, S+36 int32) Compound(size: 16)
+M(S+40 int32, S+44 int32, S+48 int32, S+52 int32) Compound(size: 16)
+M(S+56 int32, S+60 int32, S+64 int32, S+68 int32) Compound(size: 16)
+M(S+72 int32, S+76 int32, S+80 int32, S+84 int32) Compound(size: 16)
+M(S+88 int32, S+92 int32, S+96 int32, S+100 int32) Compound(size: 16)
+M(S+104 int32, S+108 int32, S+112 int32, S+116 int32) Compound(size: 16)
+M(S+120 int32, S+124 int32, S+128 int32, S+132 int32) Compound(size: 16)
+S+136 float
+S+140 int32[int8]
+M(S+144 int32, S+148 int32, S+152 int32, S+156 int32) Compound(size: 16)
+=>
+P(r0 uint32) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_ios.expect
new file mode 100644
index 0000000..124f1cd
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_ios.expect
@@ -0,0 +1,15 @@
+M(s0 float, s1 float, s2 float, s3 float) Compound(size: 16)
+s4 float
+M(s5 float, s6 float, s7 float, s8 float) Compound(size: 16)
+M(s9 float, s10 float, s11 float, s12 float) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+S+96 float
+r0 int32[int8]
+S+100 Compound(size: 16)
+=>
+M(s0 float, s1 float, s2 float, s3 float) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_linux.expect
new file mode 100644
index 0000000..124f1cd
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/arm_linux.expect
@@ -0,0 +1,15 @@
+M(s0 float, s1 float, s2 float, s3 float) Compound(size: 16)
+s4 float
+M(s5 float, s6 float, s7 float, s8 float) Compound(size: 16)
+M(s9 float, s10 float, s11 float, s12 float) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+S+96 float
+r0 int32[int8]
+S+100 Compound(size: 16)
+=>
+M(s0 float, s1 float, s2 float, s3 float) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_android.expect
new file mode 100644
index 0000000..3c127f9
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_android.expect
@@ -0,0 +1,15 @@
+S+4 Compound(size: 16)
+S+20 float
+S+24 Compound(size: 16)
+S+40 Compound(size: 16)
+S+56 Compound(size: 16)
+S+72 Compound(size: 16)
+S+88 Compound(size: 16)
+S+104 Compound(size: 16)
+S+120 Compound(size: 16)
+S+136 Compound(size: 16)
+S+152 float
+S+156 int32[int8]
+S+160 Compound(size: 16)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_linux.expect
new file mode 100644
index 0000000..3c127f9
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_linux.expect
@@ -0,0 +1,15 @@
+S+4 Compound(size: 16)
+S+20 float
+S+24 Compound(size: 16)
+S+40 Compound(size: 16)
+S+56 Compound(size: 16)
+S+72 Compound(size: 16)
+S+88 Compound(size: 16)
+S+104 Compound(size: 16)
+S+120 Compound(size: 16)
+S+136 Compound(size: 16)
+S+152 float
+S+156 int32[int8]
+S+160 Compound(size: 16)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_win.expect
new file mode 100644
index 0000000..3c127f9
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/ia32_win.expect
@@ -0,0 +1,15 @@
+S+4 Compound(size: 16)
+S+20 float
+S+24 Compound(size: 16)
+S+40 Compound(size: 16)
+S+56 Compound(size: 16)
+S+72 Compound(size: 16)
+S+88 Compound(size: 16)
+S+104 Compound(size: 16)
+S+120 Compound(size: 16)
+S+136 Compound(size: 16)
+S+152 float
+S+156 int32[int8]
+S+160 Compound(size: 16)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_ios.expect
new file mode 100644
index 0000000..991a252
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_ios.expect
@@ -0,0 +1,15 @@
+M(xmm0 double, xmm1 double) Compound(size: 16)
+xmm2 float
+M(xmm3 double, xmm4 double) Compound(size: 16)
+M(xmm5 double, xmm6 double) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+xmm7 float
+rdi int32[int8]
+S+96 Compound(size: 16)
+=>
+M(xmm0 double, xmm1 double) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_linux.expect
new file mode 100644
index 0000000..991a252
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_linux.expect
@@ -0,0 +1,15 @@
+M(xmm0 double, xmm1 double) Compound(size: 16)
+xmm2 float
+M(xmm3 double, xmm4 double) Compound(size: 16)
+M(xmm5 double, xmm6 double) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+xmm7 float
+rdi int32[int8]
+S+96 Compound(size: 16)
+=>
+M(xmm0 double, xmm1 double) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_macos.expect
new file mode 100644
index 0000000..991a252
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_macos.expect
@@ -0,0 +1,15 @@
+M(xmm0 double, xmm1 double) Compound(size: 16)
+xmm2 float
+M(xmm3 double, xmm4 double) Compound(size: 16)
+M(xmm5 double, xmm6 double) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+xmm7 float
+rdi int32[int8]
+S+96 Compound(size: 16)
+=>
+M(xmm0 double, xmm1 double) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_win.expect
new file mode 100644
index 0000000..8e31945
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesHomogenousx10/x64_win.expect
@@ -0,0 +1,15 @@
+P(rdx int64) Compound(size: 16)
+xmm2 float
+P(r9 int64) Compound(size: 16)
+P(S+0 int64) Compound(size: 16)
+P(S+8 int64) Compound(size: 16)
+P(S+16 int64) Compound(size: 16)
+P(S+24 int64) Compound(size: 16)
+P(S+32 int64) Compound(size: 16)
+P(S+40 int64) Compound(size: 16)
+P(S+48 int64) Compound(size: 16)
+S+56 float
+S+64 int8
+P(S+72 int64) Compound(size: 16)
+=>
+P(rcx int64, ret:rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_ios.expect
new file mode 100644
index 0000000..2b50280
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_ios.expect
@@ -0,0 +1,13 @@
+M(xmm0 double, rdi int64) Compound(size: 16)
+M(xmm1 double, rsi int64) Compound(size: 16)
+M(xmm2 double, rdx int64) Compound(size: 16)
+M(xmm3 double, rcx int64) Compound(size: 16)
+M(xmm4 double, r8 int64) Compound(size: 16)
+M(xmm5 double, r9 int64) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+xmm6 float
+=>
+M(xmm0 double, rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_linux.expect
new file mode 100644
index 0000000..2b50280
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_linux.expect
@@ -0,0 +1,13 @@
+M(xmm0 double, rdi int64) Compound(size: 16)
+M(xmm1 double, rsi int64) Compound(size: 16)
+M(xmm2 double, rdx int64) Compound(size: 16)
+M(xmm3 double, rcx int64) Compound(size: 16)
+M(xmm4 double, r8 int64) Compound(size: 16)
+M(xmm5 double, r9 int64) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+xmm6 float
+=>
+M(xmm0 double, rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_macos.expect
new file mode 100644
index 0000000..2b50280
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_macos.expect
@@ -0,0 +1,13 @@
+M(xmm0 double, rdi int64) Compound(size: 16)
+M(xmm1 double, rsi int64) Compound(size: 16)
+M(xmm2 double, rdx int64) Compound(size: 16)
+M(xmm3 double, rcx int64) Compound(size: 16)
+M(xmm4 double, r8 int64) Compound(size: 16)
+M(xmm5 double, r9 int64) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+xmm6 float
+=>
+M(xmm0 double, rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_win.expect
new file mode 100644
index 0000000..d21ee2b
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10/x64_win.expect
@@ -0,0 +1,13 @@
+P(rdx int64) Compound(size: 16)
+P(r8 int64) Compound(size: 16)
+P(r9 int64) Compound(size: 16)
+P(S+0 int64) Compound(size: 16)
+P(S+8 int64) Compound(size: 16)
+P(S+16 int64) Compound(size: 16)
+P(S+24 int64) Compound(size: 16)
+P(S+32 int64) Compound(size: 16)
+P(S+40 int64) Compound(size: 16)
+P(S+48 int64) Compound(size: 16)
+S+56 float
+=>
+P(rcx int64, ret:rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_ios.expect
new file mode 100644
index 0000000..bcdf3b5
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_ios.expect
@@ -0,0 +1,17 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+M(xmm4 double, rdi int64) Compound(size: 16)
+M(xmm5 double, rsi int64) Compound(size: 16)
+M(xmm6 double, rdx int64) Compound(size: 16)
+M(xmm7 double, rcx int64) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+r8 int32
+=>
+M(xmm0 double, rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_linux.expect
new file mode 100644
index 0000000..bcdf3b5
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_linux.expect
@@ -0,0 +1,17 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+M(xmm4 double, rdi int64) Compound(size: 16)
+M(xmm5 double, rsi int64) Compound(size: 16)
+M(xmm6 double, rdx int64) Compound(size: 16)
+M(xmm7 double, rcx int64) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+r8 int32
+=>
+M(xmm0 double, rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_macos.expect
new file mode 100644
index 0000000..bcdf3b5
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_macos.expect
@@ -0,0 +1,17 @@
+xmm0 float
+xmm1 float
+xmm2 float
+xmm3 float
+M(xmm4 double, rdi int64) Compound(size: 16)
+M(xmm5 double, rsi int64) Compound(size: 16)
+M(xmm6 double, rdx int64) Compound(size: 16)
+M(xmm7 double, rcx int64) Compound(size: 16)
+S+0 Compound(size: 16)
+S+16 Compound(size: 16)
+S+32 Compound(size: 16)
+S+48 Compound(size: 16)
+S+64 Compound(size: 16)
+S+80 Compound(size: 16)
+r8 int32
+=>
+M(xmm0 double, rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_win.expect
new file mode 100644
index 0000000..bb695c2
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct16bytesMixedx10_2/x64_win.expect
@@ -0,0 +1,17 @@
+xmm1 float
+xmm2 float
+xmm3 float
+S+0 float
+P(S+8 int64) Compound(size: 16)
+P(S+16 int64) Compound(size: 16)
+P(S+24 int64) Compound(size: 16)
+P(S+32 int64) Compound(size: 16)
+P(S+40 int64) Compound(size: 16)
+P(S+48 int64) Compound(size: 16)
+P(S+56 int64) Compound(size: 16)
+P(S+64 int64) Compound(size: 16)
+P(S+72 int64) Compound(size: 16)
+P(S+80 int64) Compound(size: 16)
+S+88 int32
+=>
+P(rcx int64, ret:rax int64) Compound(size: 16)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_android.expect
new file mode 100644
index 0000000..121dccb
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_android.expect
@@ -0,0 +1,12 @@
+M(r0 int64) Compound(size: 3)
+M(r1 int64) Compound(size: 3)
+M(r2 int64) Compound(size: 3)
+M(r3 int64) Compound(size: 3)
+M(r4 int64) Compound(size: 3)
+M(r5 int64) Compound(size: 3)
+M(r6 int64) Compound(size: 3)
+M(r7 int64) Compound(size: 3)
+M(S+0 int64) Compound(size: 3)
+M(S+8 int64) Compound(size: 3)
+=>
+M(r0 int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_ios.expect
new file mode 100644
index 0000000..121dccb
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_ios.expect
@@ -0,0 +1,12 @@
+M(r0 int64) Compound(size: 3)
+M(r1 int64) Compound(size: 3)
+M(r2 int64) Compound(size: 3)
+M(r3 int64) Compound(size: 3)
+M(r4 int64) Compound(size: 3)
+M(r5 int64) Compound(size: 3)
+M(r6 int64) Compound(size: 3)
+M(r7 int64) Compound(size: 3)
+M(S+0 int64) Compound(size: 3)
+M(S+8 int64) Compound(size: 3)
+=>
+M(r0 int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_linux.expect
new file mode 100644
index 0000000..121dccb
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_linux.expect
@@ -0,0 +1,12 @@
+M(r0 int64) Compound(size: 3)
+M(r1 int64) Compound(size: 3)
+M(r2 int64) Compound(size: 3)
+M(r3 int64) Compound(size: 3)
+M(r4 int64) Compound(size: 3)
+M(r5 int64) Compound(size: 3)
+M(r6 int64) Compound(size: 3)
+M(r7 int64) Compound(size: 3)
+M(S+0 int64) Compound(size: 3)
+M(S+8 int64) Compound(size: 3)
+=>
+M(r0 int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_macos.expect
new file mode 100644
index 0000000..121dccb
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm64_macos.expect
@@ -0,0 +1,12 @@
+M(r0 int64) Compound(size: 3)
+M(r1 int64) Compound(size: 3)
+M(r2 int64) Compound(size: 3)
+M(r3 int64) Compound(size: 3)
+M(r4 int64) Compound(size: 3)
+M(r5 int64) Compound(size: 3)
+M(r6 int64) Compound(size: 3)
+M(r7 int64) Compound(size: 3)
+M(S+0 int64) Compound(size: 3)
+M(S+8 int64) Compound(size: 3)
+=>
+M(r0 int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_android.expect
new file mode 100644
index 0000000..572a779
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_android.expect
@@ -0,0 +1,12 @@
+M(r0 int32) Compound(size: 3)
+M(r1 int32) Compound(size: 3)
+M(r2 int32) Compound(size: 3)
+M(r3 int32) Compound(size: 3)
+M(S+0 int32) Compound(size: 3)
+M(S+4 int32) Compound(size: 3)
+M(S+8 int32) Compound(size: 3)
+M(S+12 int32) Compound(size: 3)
+M(S+16 int32) Compound(size: 3)
+M(S+20 int32) Compound(size: 3)
+=>
+M(r0 uint32) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_ios.expect
new file mode 100644
index 0000000..572a779
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_ios.expect
@@ -0,0 +1,12 @@
+M(r0 int32) Compound(size: 3)
+M(r1 int32) Compound(size: 3)
+M(r2 int32) Compound(size: 3)
+M(r3 int32) Compound(size: 3)
+M(S+0 int32) Compound(size: 3)
+M(S+4 int32) Compound(size: 3)
+M(S+8 int32) Compound(size: 3)
+M(S+12 int32) Compound(size: 3)
+M(S+16 int32) Compound(size: 3)
+M(S+20 int32) Compound(size: 3)
+=>
+M(r0 uint32) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_linux.expect
new file mode 100644
index 0000000..572a779
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/arm_linux.expect
@@ -0,0 +1,12 @@
+M(r0 int32) Compound(size: 3)
+M(r1 int32) Compound(size: 3)
+M(r2 int32) Compound(size: 3)
+M(r3 int32) Compound(size: 3)
+M(S+0 int32) Compound(size: 3)
+M(S+4 int32) Compound(size: 3)
+M(S+8 int32) Compound(size: 3)
+M(S+12 int32) Compound(size: 3)
+M(S+16 int32) Compound(size: 3)
+M(S+20 int32) Compound(size: 3)
+=>
+M(r0 uint32) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_android.expect
new file mode 100644
index 0000000..91c0595
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_android.expect
@@ -0,0 +1,12 @@
+S+4 Compound(size: 3)
+S+8 Compound(size: 3)
+S+12 Compound(size: 3)
+S+16 Compound(size: 3)
+S+20 Compound(size: 3)
+S+24 Compound(size: 3)
+S+28 Compound(size: 3)
+S+32 Compound(size: 3)
+S+36 Compound(size: 3)
+S+40 Compound(size: 3)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_linux.expect
new file mode 100644
index 0000000..91c0595
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_linux.expect
@@ -0,0 +1,12 @@
+S+4 Compound(size: 3)
+S+8 Compound(size: 3)
+S+12 Compound(size: 3)
+S+16 Compound(size: 3)
+S+20 Compound(size: 3)
+S+24 Compound(size: 3)
+S+28 Compound(size: 3)
+S+32 Compound(size: 3)
+S+36 Compound(size: 3)
+S+40 Compound(size: 3)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_win.expect
new file mode 100644
index 0000000..91c0595
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/ia32_win.expect
@@ -0,0 +1,12 @@
+S+4 Compound(size: 3)
+S+8 Compound(size: 3)
+S+12 Compound(size: 3)
+S+16 Compound(size: 3)
+S+20 Compound(size: 3)
+S+24 Compound(size: 3)
+S+28 Compound(size: 3)
+S+32 Compound(size: 3)
+S+36 Compound(size: 3)
+S+40 Compound(size: 3)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_ios.expect
new file mode 100644
index 0000000..7f90b7a
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_ios.expect
@@ -0,0 +1,12 @@
+M(rdi int64) Compound(size: 3)
+M(rsi int64) Compound(size: 3)
+M(rdx int64) Compound(size: 3)
+M(rcx int64) Compound(size: 3)
+M(r8 int64) Compound(size: 3)
+M(r9 int64) Compound(size: 3)
+S+0 Compound(size: 3)
+S+8 Compound(size: 3)
+S+16 Compound(size: 3)
+S+24 Compound(size: 3)
+=>
+M(rax int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_linux.expect
new file mode 100644
index 0000000..7f90b7a
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_linux.expect
@@ -0,0 +1,12 @@
+M(rdi int64) Compound(size: 3)
+M(rsi int64) Compound(size: 3)
+M(rdx int64) Compound(size: 3)
+M(rcx int64) Compound(size: 3)
+M(r8 int64) Compound(size: 3)
+M(r9 int64) Compound(size: 3)
+S+0 Compound(size: 3)
+S+8 Compound(size: 3)
+S+16 Compound(size: 3)
+S+24 Compound(size: 3)
+=>
+M(rax int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_macos.expect
new file mode 100644
index 0000000..7f90b7a
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_macos.expect
@@ -0,0 +1,12 @@
+M(rdi int64) Compound(size: 3)
+M(rsi int64) Compound(size: 3)
+M(rdx int64) Compound(size: 3)
+M(rcx int64) Compound(size: 3)
+M(r8 int64) Compound(size: 3)
+M(r9 int64) Compound(size: 3)
+S+0 Compound(size: 3)
+S+8 Compound(size: 3)
+S+16 Compound(size: 3)
+S+24 Compound(size: 3)
+=>
+M(rax int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_win.expect
new file mode 100644
index 0000000..4b80330
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct3bytesx10/x64_win.expect
@@ -0,0 +1,12 @@
+P(rdx int64) Compound(size: 3)
+P(r8 int64) Compound(size: 3)
+P(r9 int64) Compound(size: 3)
+P(S+0 int64) Compound(size: 3)
+P(S+8 int64) Compound(size: 3)
+P(S+16 int64) Compound(size: 3)
+P(S+24 int64) Compound(size: 3)
+P(S+32 int64) Compound(size: 3)
+P(S+40 int64) Compound(size: 3)
+P(S+48 int64) Compound(size: 3)
+=>
+P(rcx int64, ret:rax int64) Compound(size: 3)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_android.expect
new file mode 100644
index 0000000..aae2f45
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_android.expect
@@ -0,0 +1,3 @@
+M(r0 int64) Compound(size: 8)
+=>
+M(r0 int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_ios.expect
new file mode 100644
index 0000000..aae2f45
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_ios.expect
@@ -0,0 +1,3 @@
+M(r0 int64) Compound(size: 8)
+=>
+M(r0 int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_linux.expect
new file mode 100644
index 0000000..aae2f45
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_linux.expect
@@ -0,0 +1,3 @@
+M(r0 int64) Compound(size: 8)
+=>
+M(r0 int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_macos.expect
new file mode 100644
index 0000000..aae2f45
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm64_macos.expect
@@ -0,0 +1,3 @@
+M(r0 int64) Compound(size: 8)
+=>
+M(r0 int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_android.expect
new file mode 100644
index 0000000..0dac74d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_android.expect
@@ -0,0 +1,3 @@
+M(r1 int32, r2 int32) Compound(size: 8)
+=>
+P(r0 uint32) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_ios.expect
new file mode 100644
index 0000000..0dac74d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_ios.expect
@@ -0,0 +1,3 @@
+M(r1 int32, r2 int32) Compound(size: 8)
+=>
+P(r0 uint32) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_linux.expect
new file mode 100644
index 0000000..0dac74d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/arm_linux.expect
@@ -0,0 +1,3 @@
+M(r1 int32, r2 int32) Compound(size: 8)
+=>
+P(r0 uint32) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_android.expect
new file mode 100644
index 0000000..b6e748c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_android.expect
@@ -0,0 +1,3 @@
+S+4 Compound(size: 8)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_linux.expect
new file mode 100644
index 0000000..b6e748c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_linux.expect
@@ -0,0 +1,3 @@
+S+4 Compound(size: 8)
+=>
+P(S+0 uint32, ret:eax uint32) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_win.expect
new file mode 100644
index 0000000..3778ea7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/ia32_win.expect
@@ -0,0 +1,3 @@
+S+0 Compound(size: 8)
+=>
+M(eax uint32, edx uint32) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_ios.expect
new file mode 100644
index 0000000..80d98b3
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_ios.expect
@@ -0,0 +1,3 @@
+M(rdi int64) Compound(size: 8)
+=>
+M(rax int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_linux.expect
new file mode 100644
index 0000000..80d98b3
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_linux.expect
@@ -0,0 +1,3 @@
+M(rdi int64) Compound(size: 8)
+=>
+M(rax int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_macos.expect
new file mode 100644
index 0000000..80d98b3
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_macos.expect
@@ -0,0 +1,3 @@
+M(rdi int64) Compound(size: 8)
+=>
+M(rax int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_win.expect
new file mode 100644
index 0000000..5610272
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesx1/x64_win.expect
@@ -0,0 +1,3 @@
+M(rcx int64) Compound(size: 8)
+=>
+M(rax int64) Compound(size: 8)
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_android.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_android.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_ios.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_ios.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_linux.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_linux.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_macos.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm64_macos.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_android.expect
new file mode 100644
index 0000000..124e769
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_android.expect
@@ -0,0 +1,17 @@
+Compound(size: 72, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int32,
+  40: double,
+  48: float,
+  52: int32,
+  56: int32,
+  60: int32,
+  64: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_ios.expect
new file mode 100644
index 0000000..44136f8
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_ios.expect
@@ -0,0 +1,17 @@
+Compound(size: 64, field alignment: 4, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int32,
+  36: double,
+  44: float,
+  48: int32,
+  52: int32,
+  56: int32,
+  60: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_linux.expect
new file mode 100644
index 0000000..124e769
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/arm_linux.expect
@@ -0,0 +1,17 @@
+Compound(size: 72, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int32,
+  40: double,
+  48: float,
+  52: int32,
+  56: int32,
+  60: int32,
+  64: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_android.expect
new file mode 100644
index 0000000..24fa174
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_android.expect
@@ -0,0 +1,17 @@
+Compound(size: 64, field alignment: 4, stack alignment: 4, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int32,
+  36: double,
+  44: float,
+  48: int32,
+  52: int32,
+  56: int32,
+  60: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_linux.expect
new file mode 100644
index 0000000..24fa174
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_linux.expect
@@ -0,0 +1,17 @@
+Compound(size: 64, field alignment: 4, stack alignment: 4, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int32,
+  36: double,
+  44: float,
+  48: int32,
+  52: int32,
+  56: int32,
+  60: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_win.expect
new file mode 100644
index 0000000..e0bd22c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/ia32_win.expect
@@ -0,0 +1,17 @@
+Compound(size: 72, field alignment: 8, stack alignment: 4, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int32,
+  40: double,
+  48: float,
+  52: int32,
+  56: int32,
+  60: int32,
+  64: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_ios.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_ios.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_linux.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_linux.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_macos.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_macos.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_win.expect
new file mode 100644
index 0000000..ca69b6c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_VeryLargeStruct/x64_win.expect
@@ -0,0 +1,17 @@
+Compound(size: 88, field alignment: 8, stack alignment: 8, members: {
+  0: int8,
+  2: int16,
+  4: int32,
+  8: int64,
+  16: uint8,
+  18: uint16,
+  20: uint32,
+  24: uint64,
+  32: int64,
+  40: double,
+  48: float,
+  56: int64,
+  64: int64,
+  72: int64,
+  80: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_android.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_android.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_ios.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_ios.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_linux.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_linux.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_macos.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_macos.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_android.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_android.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_ios.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_ios.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_linux.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm_linux.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_android.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_android.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_linux.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_linux.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_win.expect
new file mode 100644
index 0000000..db47a46
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/ia32_win.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 4, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_ios.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_ios.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_linux.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_linux.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_macos.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_macos.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_win.expect
new file mode 100644
index 0000000..025609f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_floatx4/x64_win.expect
@@ -0,0 +1,6 @@
+Compound(size: 16, field alignment: 4, stack alignment: 8, members: {
+  0: float,
+  4: float,
+  8: float,
+  12: float
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_android.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_android.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_ios.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_ios.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_linux.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_linux.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_macos.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm64_macos.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_android.expect
new file mode 100644
index 0000000..c7c2467
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_android.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 4, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_ios.expect
new file mode 100644
index 0000000..c7c2467
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_ios.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 4, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_linux.expect
new file mode 100644
index 0000000..c7c2467
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/arm_linux.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 4, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_android.expect
new file mode 100644
index 0000000..c7c2467
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_android.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 4, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_linux.expect
new file mode 100644
index 0000000..c7c2467
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_linux.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 4, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_win.expect
new file mode 100644
index 0000000..c7c2467
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/ia32_win.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 4, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_ios.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_ios.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_linux.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_linux.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_macos.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_macos.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_win.expect
new file mode 100644
index 0000000..146893d
--- /dev/null
+++ b/runtime/vm/compiler/ffi/unit_tests/struct_int8x10/x64_win.expect
@@ -0,0 +1,12 @@
+Compound(size: 10, field alignment: 1, stack alignment: 8, members: {
+  0: int8,
+  1: int8,
+  2: int8,
+  3: int8,
+  4: int8,
+  5: int8,
+  6: int8,
+  7: int8,
+  8: int8,
+  9: int8
+})
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index 6f66e9c..a8cb442 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -59,15 +59,15 @@
 
 ObjectPtr ConstantReader::ReadAnnotations() {
   intptr_t list_length = helper_->ReadListLength();  // read list length.
-  const Array& metadata_values =
-      Array::Handle(Z, Array::New(list_length, H.allocation_space()));
+  const auto& metadata_values =
+      Array::Handle(Z, ImmutableArray::New(list_length, H.allocation_space()));
   Instance& value = Instance::Handle(Z);
   for (intptr_t i = 0; i < list_length; ++i) {
     // This will read the expression.
     value = ReadConstantExpression();
     metadata_values.SetAt(i, value);
   }
-  return metadata_values.raw();
+  return H.Canonicalize(metadata_values);
 }
 
 InstancePtr ConstantReader::ReadConstant(intptr_t constant_offset) {
@@ -81,7 +81,8 @@
   // must be locked since mutator and background compiler can
   // access the array at the same time.
   {
-    SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+    SafepointMutexLocker ml(
+        H.thread()->isolate_group()->kernel_constants_mutex());
     KernelConstantsMap constant_map(H.info().constants());
     result_ ^= constant_map.GetOrNull(constant_offset);
     ASSERT(constant_map.Release().raw() == H.info().constants());
@@ -90,7 +91,8 @@
   // On miss, evaluate, and insert value.
   if (result_.IsNull()) {
     result_ = ReadConstantInternal(constant_offset);
-    SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+    SafepointMutexLocker ml(
+        H.thread()->isolate_group()->kernel_constants_mutex());
     KernelConstantsMap constant_map(H.info().constants());
     auto insert = constant_map.InsertNewOrGetValue(constant_offset, result_);
     ASSERT(insert == result_.raw());
@@ -231,7 +233,8 @@
             "%s is not loaded yet.",
             klass.ToCString());
       }
-      const auto& obj = Object::Handle(Z, klass.EnsureIsFinalized(H.thread()));
+      const auto& obj =
+          Object::Handle(Z, klass.EnsureIsAllocateFinalized(H.thread()));
       ASSERT(obj.IsNull());
       ASSERT(klass.is_enum_class() || klass.is_const());
       instance = Instance::New(klass, Heap::kOld);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index c5a05cd..54435dc 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -482,40 +482,6 @@
   return DebugStepCheck(check_pos);
 }
 
-Fragment StreamingFlowGraphBuilder::SetAsyncStackTrace(
-    const Function& dart_function) {
-  if (!FLAG_causal_async_stacks ||
-      !(dart_function.IsAsyncClosure() || dart_function.IsAsyncGenClosure())) {
-    return {};
-  }
-
-  // The code we are building will be executed right after we enter
-  // the function and before any nested contexts are allocated.
-  ASSERT(B->context_depth_ ==
-         scopes()->yield_jump_variable->owner()->context_level());
-
-  Fragment instructions;
-  LocalScope* scope = parsed_function()->scope();
-
-  const Function& target = Function::ZoneHandle(
-      Z, I->object_store()->async_set_thread_stack_trace());
-  ASSERT(!target.IsNull());
-
-  // Fetch and load :async_stack_trace
-  LocalVariable* async_stack_trace_var =
-      scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
-  ASSERT((async_stack_trace_var != NULL) &&
-         async_stack_trace_var->is_captured());
-
-  Fragment code;
-  code += LoadLocal(async_stack_trace_var);
-  // Call _setAsyncThreadStackTrace
-  code += StaticCall(TokenPosition::kNoSource, target,
-                     /* argument_count = */ 1, ICData::kStatic);
-  code += Drop();
-  return code;
-}
-
 Fragment StreamingFlowGraphBuilder::TypeArgumentsHandling(
     const Function& dart_function) {
   Fragment prologue = B->BuildDefaultTypeHandling(dart_function);
@@ -722,31 +688,6 @@
   return body;
 }
 
-// If we run in checked mode or strong mode, we have to check the type of the
-// passed arguments.
-//
-// TODO(#34162): If we're building an extra entry-point to skip
-// type checks, we should substitute Redefinition nodes for the AssertAssignable
-// instructions to ensure that the argument types are known.
-void StreamingFlowGraphBuilder::CheckArgumentTypesAsNecessary(
-    const Function& dart_function,
-    intptr_t type_parameters_offset,
-    Fragment* explicit_checks,
-    Fragment* implicit_checks,
-    Fragment* implicit_redefinitions) {
-  if (dart_function.NeedsTypeArgumentTypeChecks()) {
-    B->BuildTypeArgumentTypeChecks(
-        MethodCanSkipTypeChecksForNonCovariantTypeArguments(dart_function)
-            ? TypeChecksToBuild::kCheckCovariantTypeParameterBounds
-            : TypeChecksToBuild::kCheckAllTypeParameterBounds,
-        implicit_checks);
-  }
-  if (dart_function.NeedsArgumentTypeChecks()) {
-    B->BuildArgumentTypeChecks(explicit_checks, implicit_checks,
-                               implicit_redefinitions);
-  }
-}
-
 Fragment StreamingFlowGraphBuilder::ShortcutForUserDefinedEquals(
     const Function& dart_function,
     LocalVariable* first_parameter) {
@@ -826,7 +767,6 @@
   Fragment F;
   F += CheckStackOverflowInPrologue(dart_function);
   F += DebugStepCheckInPrologue(dart_function, token_position);
-  F += SetAsyncStackTrace(dart_function);
   F += B->InitConstantParameters();
   return F;
 }
@@ -948,12 +888,19 @@
   // regular methods.
   const Fragment type_args_handling = TypeArgumentsHandling(dart_function);
 
-  Fragment explicit_type_checks;
   Fragment implicit_type_checks;
+  if (dart_function.NeedsTypeArgumentTypeChecks()) {
+    B->BuildTypeArgumentTypeChecks(
+        TypeChecksToBuild::kCheckCovariantTypeParameterBounds,
+        &implicit_type_checks);
+  }
+
+  Fragment explicit_type_checks;
   Fragment implicit_redefinitions;
-  CheckArgumentTypesAsNecessary(dart_function, type_parameters_offset,
-                                &explicit_type_checks, &implicit_type_checks,
-                                &implicit_redefinitions);
+  if (dart_function.NeedsArgumentTypeChecks()) {
+    B->BuildArgumentTypeChecks(&explicit_type_checks, &implicit_type_checks,
+                               &implicit_redefinitions);
+  }
 
   // The RawParameter variables should be set to null to avoid retaining more
   // objects than necessary during GC.
@@ -2110,14 +2057,42 @@
       // If the variable isn't initialized, call the initializer and set it.
       Fragment initialize(is_uninitialized);
       initialize += BuildExpression();
-      initialize += StoreLocal(position, variable);
-      initialize += Drop();
-      initialize += Goto(join);
+      if (variable->is_final()) {
+        // Late final variable, so check whether it has been assigned
+        // during initialization.
+        initialize += LoadLocal(variable);
+        TargetEntryInstr *is_uninitialized_after_init,
+            *is_initialized_after_init;
+        initialize += Constant(Object::sentinel());
+        initialize += flow_graph_builder_->BranchIfStrictEqual(
+            &is_uninitialized_after_init, &is_initialized_after_init);
+        {
+          // The variable is uninitialized, so store the initializer result.
+          Fragment store_result(is_uninitialized_after_init);
+          store_result += StoreLocal(position, variable);
+          store_result += Drop();
+          store_result += Goto(join);
+        }
+
+        {
+          // Already initialized, so throw a LateInitializationError.
+          Fragment already_assigned(is_initialized_after_init);
+          already_assigned += flow_graph_builder_->ThrowLateInitializationError(
+              position, "_throwLocalAssignedDuringInitialization",
+              variable->name());
+          already_assigned += Goto(join);
+        }
+      } else {
+        // Late non-final variable. Store the initializer result.
+        initialize += StoreLocal(position, variable);
+        initialize += Drop();
+        initialize += Goto(join);
+      }
     } else {
       // The variable has no initializer, so throw a LateInitializationError.
       Fragment initialize(is_uninitialized);
       initialize += flow_graph_builder_->ThrowLateInitializationError(
-          position, variable->name());
+          position, "_throwLocalNotInitialized", variable->name());
       initialize += Goto(join);
     }
   }
@@ -2183,7 +2158,7 @@
       // Already initialized, so throw a LateInitializationError.
       Fragment already_initialized(is_initialized);
       already_initialized += flow_graph_builder_->ThrowLateInitializationError(
-          position, variable->name());
+          position, "_throwLocalAlreadyInitialized", variable->name());
       already_initialized += Goto(join);
     }
 
@@ -3058,10 +3033,6 @@
   Fragment instructions;
   LocalVariable* instance_variable = NULL;
 
-  const bool special_case_nop_async_stack_trace_helper =
-      !FLAG_causal_async_stacks &&
-      recognized_kind == MethodRecognizer::kAsyncStackTraceHelper;
-
   const bool special_case_unchecked_cast =
       klass.IsTopLevel() && (klass.library() == Library::InternalLibrary()) &&
       (target.name() == Symbols::UnsafeCast().raw());
@@ -3070,9 +3041,8 @@
       klass.IsTopLevel() && (klass.library() == Library::CoreLibrary()) &&
       (target.name() == Symbols::Identical().raw());
 
-  const bool special_case = special_case_identical ||
-                            special_case_unchecked_cast ||
-                            special_case_nop_async_stack_trace_helper;
+  const bool special_case =
+      special_case_identical || special_case_unchecked_cast;
 
   // If we cross the Kernel -> VM core library boundary, a [StaticInvocation]
   // can appear, but the thing we're calling is not a static method, but a
@@ -3132,10 +3102,6 @@
     ASSERT(argument_count == 2);
     instructions +=
         StrictCompare(position, Token::kEQ_STRICT, /*number_check=*/true);
-  } else if (special_case_nop_async_stack_trace_helper) {
-    ASSERT(argument_count == 1);
-    instructions += Drop();
-    instructions += NullConstant();
   } else if (special_case_unchecked_cast) {
     // Simply do nothing: the result value is already pushed on the stack.
   } else {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index ef94bf3..0718d9d 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -94,11 +94,6 @@
   Fragment ShortcutForUserDefinedEquals(const Function& dart_function,
                                         LocalVariable* first_parameter);
   Fragment TypeArgumentsHandling(const Function& dart_function);
-  void CheckArgumentTypesAsNecessary(const Function& dart_function,
-                                     intptr_t type_parameters_offset,
-                                     Fragment* explicit_checks,
-                                     Fragment* implicit_checks,
-                                     Fragment* implicit_redefinitions);
   Fragment CompleteBodyWithYieldContinuations(Fragment body);
 
   static UncheckedEntryPointStyle ChooseEntryPointStyle(
@@ -222,8 +217,6 @@
   Fragment StringInterpolate(TokenPosition position);
   Fragment StringInterpolateSingle(TokenPosition position);
   Fragment ThrowTypeError();
-  Fragment ThrowLateInitializationError(TokenPosition position,
-                                        const String& name);
   Fragment LoadInstantiatorTypeArguments();
   Fragment LoadFunctionTypeArguments();
   Fragment InstantiateType(const AbstractType& type);
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 0a40040..6b6a2d55 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -784,6 +784,7 @@
   BuildHash(procedure_helper.kind_);
   BuildHash(procedure_helper.flags_);
   BuildHash(procedure_helper.annotation_count_);
+  BuildHash(procedure_helper.stub_kind_);
   BuildHash(name.Hash());
   return hash_;
 }
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 48aae11..fa468cc 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -440,22 +440,24 @@
   }
 }
 
-Fragment FlowGraphBuilder::ThrowLateInitializationError(TokenPosition position,
-                                                        const String& name) {
-  const Class& klass = Class::ZoneHandle(
-      Z, Library::LookupCoreClass(Symbols::LateInitializationError()));
+Fragment FlowGraphBuilder::ThrowLateInitializationError(
+    TokenPosition position,
+    const char* throw_method_name,
+    const String& name) {
+  const Class& klass =
+      Class::ZoneHandle(Z, Library::LookupCoreClass(Symbols::LateError()));
   ASSERT(!klass.IsNull());
 
   const auto& error = klass.EnsureIsFinalized(thread_);
   ASSERT(error == Error::null());
   const Function& throw_new =
       Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate(
-                                  H.DartSymbolObfuscate("_throwNew")));
+                                  H.DartSymbolObfuscate(throw_method_name)));
   ASSERT(!throw_new.IsNull());
 
   Fragment instructions;
 
-  // Call _LateInitializationError._throwNew.
+  // Call LateError._throwFoo.
   instructions += Constant(name);
   instructions += StaticCall(position, throw_new,
                              /* argument_count = */ 1, ICData::kStatic);
@@ -495,7 +497,8 @@
       // If the field is already initialized, throw a LateInitializationError.
       Fragment already_initialized(is_initialized);
       already_initialized += ThrowLateInitializationError(
-          position, String::ZoneHandle(Z, field.name()));
+          position, "_throwFieldAlreadyInitialized",
+          String::ZoneHandle(Z, field.name()));
       already_initialized += Goto(join);
     }
 
@@ -546,18 +549,6 @@
     instructions += DebugStepCheck(position);
   }
 
-  if (FLAG_causal_async_stacks &&
-      (function.IsAsyncClosure() || function.IsAsyncGenClosure())) {
-    // We are returning from an asynchronous closure. Before we do that, be
-    // sure to clear the thread's asynchronous stack trace.
-    const Function& target = Function::ZoneHandle(
-        Z, I->object_store()->async_clear_thread_stack_trace());
-    ASSERT(!target.IsNull());
-    instructions += StaticCall(TokenPosition::kNoSource, target,
-                               /* argument_count = */ 0, ICData::kStatic);
-    instructions += Drop();
-  }
-
   instructions += BaseFlowGraphBuilder::Return(position, yield_index);
 
   return instructions;
@@ -741,6 +732,23 @@
       KernelProgramInfo::Handle(script.kernel_program_info());
   ASSERT(info.IsNull() ||
          info.potential_natives() == GrowableObjectArray::null());
+
+  // Check that all functions that are explicitly marked as recognized with the
+  // vm:recognized annotation are in fact recognized. The check can't be done on
+  // function creation, since the recognized status isn't set until later.
+  if ((function.IsRecognized() !=
+       MethodRecognizer::IsMarkedAsRecognized(function)) &&
+      !function.IsDynamicInvocationForwarder()) {
+    if (function.IsRecognized()) {
+      FATAL1(
+          "Recognized method %s is not marked with the vm:recognized pragma.",
+          function.ToQualifiedCString());
+    } else {
+      FATAL1(
+          "Non-recognized method %s is marked with the vm:recognized pragma.",
+          function.ToQualifiedCString());
+    }
+  }
 #endif
 
   auto& kernel_data = ExternalTypedData::Handle(Z, function.KernelData());
@@ -859,12 +867,14 @@
     case MethodRecognizer::kLinkedHashMap_setUsedData:
     case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
     case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+    case MethodRecognizer::kWeakProperty_getKey:
+    case MethodRecognizer::kWeakProperty_setKey:
+    case MethodRecognizer::kWeakProperty_getValue:
+    case MethodRecognizer::kWeakProperty_setValue:
     case MethodRecognizer::kFfiAbi:
     case MethodRecognizer::kReachabilityFence:
     case MethodRecognizer::kUtf8DecoderScan:
       return true;
-    case MethodRecognizer::kAsyncStackTraceHelper:
-      return !FLAG_causal_async_stacks;
     default:
       return false;
   }
@@ -1208,8 +1218,30 @@
           StoreInstanceFieldInstr::Kind::kOther, kNoStoreBarrier);
       body += NullConstant();
       break;
-    case MethodRecognizer::kAsyncStackTraceHelper:
-      ASSERT(!FLAG_causal_async_stacks);
+    case MethodRecognizer::kWeakProperty_getKey:
+      ASSERT(function.NumParameters() == 1);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadNativeField(Slot::WeakProperty_key());
+      break;
+    case MethodRecognizer::kWeakProperty_setKey:
+      ASSERT(function.NumParameters() == 2);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
+      body += StoreInstanceField(TokenPosition::kNoSource,
+                                 Slot::WeakProperty_key());
+      body += NullConstant();
+      break;
+    case MethodRecognizer::kWeakProperty_getValue:
+      ASSERT(function.NumParameters() == 1);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadNativeField(Slot::WeakProperty_value());
+      break;
+    case MethodRecognizer::kWeakProperty_setValue:
+      ASSERT(function.NumParameters() == 2);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
+      body += StoreInstanceField(TokenPosition::kNoSource,
+                                 Slot::WeakProperty_value());
       body += NullConstant();
       break;
     case MethodRecognizer::kUtf8DecoderScan:
@@ -1981,11 +2013,11 @@
   }
   String& name = String::Handle(Z);
   for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
-    intptr_t parameter_index = descriptor.PositionalCount() + i;
+    const intptr_t parameter_index = descriptor.PositionAt(i);
     name = descriptor.NameAt(i);
     name = Symbols::New(H.thread(), name);
     body += LoadLocal(array);
-    body += IntConstant(receiver_index + descriptor.PositionAt(i));
+    body += IntConstant(receiver_index + parameter_index);
     body += LoadLocal(parsed_function_->ParameterVariable(parameter_index));
     body += StoreIndexed(kArrayCid);
   }
@@ -2052,6 +2084,7 @@
   LocalVariable* num_max_params = nullptr;
   LocalVariable* has_named_params = nullptr;
   LocalVariable* parameter_names = nullptr;
+  LocalVariable* parameter_types = nullptr;
   LocalVariable* type_parameters = nullptr;
   LocalVariable* closure_data = nullptr;
   LocalVariable* default_tav_info = nullptr;
@@ -2084,7 +2117,7 @@
     Fragment set,
     Fragment not_set) {
   // Required named arguments only exist if null_safety is enabled.
-  if (!I->null_safety()) return not_set;
+  if (!I->use_strict_null_safety_checks()) return not_set;
 
   Fragment check_required;
   // First, we convert the index to be in terms of the number of optional
@@ -2259,7 +2292,7 @@
   // required named arguments.
   if (info.descriptor.NamedCount() == 0) {
     // No work to do if there are no possible required named parameters.
-    if (!I->null_safety()) {
+    if (!I->use_strict_null_safety_checks()) {
       return Fragment();
     }
     // If the below changes, we can no longer assume that flag slots existing
@@ -2332,10 +2365,13 @@
     loop_body += BranchIfEqual(&match, &mismatch);
     loop_body.current = mismatch;
 
-    // We have a match, so go to the next name after incrementing the number
-    // of matched arguments. (No need to check for the required bit, as this
-    // parameter was provided.)
+    // We have a match, so go to the next name after storing the corresponding
+    // parameter index on the stack and incrementing the number of matched
+    // arguments. (No need to check the required bit for provided parameters.)
     Fragment matched(match);
+    matched += LoadLocal(info.vars->current_param_index);
+    matched += StoreLocal(info.vars->named_argument_parameter_indices.At(i));
+    matched += Drop();
     matched += LoadLocal(info.vars->current_num_processed);
     matched += IntConstant(1);
     matched += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);
@@ -2549,6 +2585,60 @@
   return Fragment(loop_init.entry, done);
 }
 
+Fragment FlowGraphBuilder::BuildClosureCallArgumentTypeCheck(
+    const ClosureCallInfo& info,
+    LocalVariable* param_index,
+    intptr_t arg_index,
+    const String& arg_name) {
+  Fragment instructions;
+
+  // Load value.
+  instructions += LoadLocal(parsed_function_->ParameterVariable(arg_index));
+  // Load destination type.
+  instructions += LoadLocal(info.parameter_types);
+  instructions += LoadLocal(param_index);
+  instructions += LoadIndexed(kArrayCid);
+  // Load instantiator type arguments.
+  instructions += LoadLocal(info.instantiator_type_args);
+  // Load the full set of function type arguments.
+  instructions += LoadLocal(info.vars->function_type_args);
+  // Check that the value has the right type.
+  instructions += AssertAssignable(TokenPosition::kNoSource, arg_name,
+                                   AssertAssignableInstr::kParameterCheck);
+  // Make sure to store the result to keep data dependencies accurate.
+  instructions += StoreLocal(parsed_function_->ParameterVariable(arg_index));
+  instructions += Drop();
+
+  return instructions;
+}
+
+Fragment FlowGraphBuilder::BuildClosureCallArgumentTypeChecks(
+    const ClosureCallInfo& info) {
+  Fragment instructions;
+
+  // Only check explicit arguments (i.e., skip the receiver), as the receiver
+  // is always assignable to its type (stored as dynamic).
+  for (intptr_t i = 1; i < info.descriptor.PositionalCount(); i++) {
+    instructions += IntConstant(i);
+    LocalVariable* param_index = MakeTemporary("param_index");
+    // We don't have a compile-time name, so this symbol signals the runtime
+    // that it should recreate the type check using info from the stack.
+    instructions += BuildClosureCallArgumentTypeCheck(
+        info, param_index, i, Symbols::dynamic_assert_assignable_stc_check());
+    instructions += DropTemporary(&param_index);
+  }
+
+  for (intptr_t i = 0; i < info.descriptor.NamedCount(); i++) {
+    const intptr_t arg_index = info.descriptor.PositionAt(i);
+    const auto& arg_name = String::ZoneHandle(Z, info.descriptor.NameAt(i));
+    auto const param_index = info.vars->named_argument_parameter_indices.At(i);
+    instructions += BuildClosureCallArgumentTypeCheck(info, param_index,
+                                                      arg_index, arg_name);
+  }
+
+  return instructions;
+}
+
 Fragment FlowGraphBuilder::BuildDynamicClosureCallChecks(
     LocalVariable* closure) {
   ClosureCallInfo info(closure, BuildThrowNoSuchMethod(),
@@ -2584,11 +2674,13 @@
   body += StrictCompare(Token::kNE_STRICT);
   info.has_named_params = MakeTemporary("has_named_params");
 
-  if (I->null_safety() || info.descriptor.NamedCount() > 0) {
-    body += LoadLocal(info.function);
-    body += LoadNativeField(Slot::Function_parameter_names());
-    info.parameter_names = MakeTemporary("parameter_names");
-  }
+  body += LoadLocal(info.function);
+  body += LoadNativeField(Slot::Function_parameter_names());
+  info.parameter_names = MakeTemporary("parameter_names");
+
+  body += LoadLocal(info.function);
+  body += LoadNativeField(Slot::Function_parameter_types());
+  info.parameter_types = MakeTemporary("parameter_types");
 
   body += LoadLocal(info.function);
   body += LoadNativeField(Slot::Function_type_parameters());
@@ -2671,18 +2763,16 @@
   // and performing any needed type argument checking.
   body += TestClosureFunctionGeneric(info, generic, not_generic);
 
-  // TODO(dartbug.com/40813): Move checks that are currently compiled
-  // in the closure body to here, using the dynamic versions of
-  // AssertAssignable to typecheck the parameters using the runtime types
-  // available in the closure object.
+  // Check that the values provided as arguments are assignable to the types
+  // of the corresponding closure function parameters.
+  body += BuildClosureCallArgumentTypeChecks(info);
 
   // Drop all the read-only temporaries at the end of the fragment.
   body += DropTemporary(&info.parent_function_type_args);
   body += DropTemporary(&info.instantiator_type_args);
   body += DropTemporary(&info.type_parameters);
-  if (info.parameter_names != nullptr) {
-    body += DropTemporary(&info.parameter_names);
-  }
+  body += DropTemporary(&info.parameter_types);
+  body += DropTemporary(&info.parameter_names);
   body += DropTemporary(&info.has_named_params);
   body += DropTemporary(&info.num_max_params);
   body += DropTemporary(&info.num_opt_params);
@@ -2776,8 +2866,10 @@
         Array::ZoneHandle(Z, Array::New(descriptor.NamedCount(), Heap::kNew));
     String& string_handle = String::Handle(Z);
     for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
+      const intptr_t named_arg_index =
+          descriptor.PositionAt(i) - descriptor.PositionalCount();
       string_handle = descriptor.NameAt(i);
-      array_handle.SetAt(i, string_handle);
+      array_handle.SetAt(named_arg_index, string_handle);
     }
     argument_names = &array_handle;
   }
@@ -3199,49 +3291,38 @@
   BlockEntryInstr* instruction_cursor =
       BuildPrologue(normal_entry, &prologue_info);
 
-  const Fragment prologue = CheckStackOverflowInPrologue(function.token_pos());
+  Fragment closure(instruction_cursor);
+  closure += CheckStackOverflowInPrologue(function.token_pos());
+  closure += BuildDefaultTypeHandling(function);
 
-  const Fragment default_type_handling = BuildDefaultTypeHandling(function);
-
-  Fragment implicit_checks;
-  if (function.NeedsTypeArgumentTypeChecks() &&
-      (target.is_static() ||
-       MethodCanSkipTypeChecksForNonCovariantTypeArguments(parent))) {
-    BuildTypeArgumentTypeChecks(
-        target.is_static()
-            ? TypeChecksToBuild::kCheckAllTypeParameterBounds
-            : TypeChecksToBuild::kCheckNonCovariantTypeParameterBounds,
-        &implicit_checks);
-  }
-  if (function.NeedsArgumentTypeChecks() &&
-      (target.is_static() ||
-       MethodCanSkipTypeChecksForNonCovariantArguments(parent))) {
-    // We're going to throw away the explicit checks because the target will
-    // always check them.
-    Fragment explicit_checks_unused;
-    BuildArgumentTypeChecks(&explicit_checks_unused, &implicit_checks, nullptr);
-  }
-
-  Fragment body;
+  // For implicit closure functions, any non-covariant checks are either
+  // performed by the type system or a dynamic invocation layer (dynamic closure
+  // call dispatcher, mirror, etc.). Static targets never have covariant
+  // arguments, and for non-static targets, they already perform the covariant
+  // checks internally. Thus, no checks are needed and we just need to invoke
+  // the target with the right receiver (unless static).
+  //
+  // TODO(dartbug.com/44195): Consider replacing the argument pushes + static
+  // call with stack manipulation and a tail call instead.
 
   intptr_t type_args_len = 0;
   if (function.IsGeneric()) {
     type_args_len = function.NumTypeParameters();
     ASSERT(parsed_function_->function_type_arguments() != NULL);
-    body += LoadLocal(parsed_function_->function_type_arguments());
+    closure += LoadLocal(parsed_function_->function_type_arguments());
   }
 
   // Push receiver.
   if (!target.is_static()) {
     // The context has a fixed shape: a single variable which is the
     // closed-over receiver.
-    body += LoadLocal(parsed_function_->ParameterVariable(0));
-    body += LoadNativeField(Slot::Closure_context());
-    body += LoadNativeField(Slot::GetContextVariableSlotFor(
+    closure += LoadLocal(parsed_function_->ParameterVariable(0));
+    closure += LoadNativeField(Slot::Closure_context());
+    closure += LoadNativeField(Slot::GetContextVariableSlotFor(
         thread_, *parsed_function_->receiver_var()));
   }
 
-  body += PushExplicitParameters(function);
+  closure += PushExplicitParameters(function);
 
   // Forward parameters to the target.
   intptr_t argument_count = function.NumParameters() -
@@ -3252,48 +3333,12 @@
   Array& argument_names =
       Array::ZoneHandle(Z, GetOptionalParameterNames(function));
 
-  body += StaticCall(TokenPosition::kNoSource, target, argument_count,
-                     argument_names, ICData::kNoRebind,
-                     /* result_type = */ NULL, type_args_len);
+  closure += StaticCall(TokenPosition::kNoSource, target, argument_count,
+                        argument_names, ICData::kNoRebind,
+                        /* result_type = */ NULL, type_args_len);
 
   // Return the result.
-  body += Return(function.end_token_pos());
-
-  // Setup multiple entrypoints if useful.
-  FunctionEntryInstr* extra_entry = nullptr;
-  if (function.MayHaveUncheckedEntryPoint()) {
-    // The prologue for a closure will always have context handling (e.g.
-    // setting up the receiver variable), but we don't need it on the unchecked
-    // entry because the only time we reference this is for loading the
-    // receiver, which we fetch directly from the context.
-    if (PrologueBuilder::PrologueSkippableOnUncheckedEntry(function)) {
-      // Use separate entry points since we can skip almost everything on the
-      // static entry.
-      extra_entry = BuildSeparateUncheckedEntryPoint(
-          /*normal_entry=*/instruction_cursor,
-          /*normal_prologue=*/prologue + default_type_handling +
-              implicit_checks,
-          /*extra_prologue=*/
-          CheckStackOverflowInPrologue(function.token_pos()),
-          /*shared_prologue=*/Fragment(),
-          /*body=*/body);
-    } else {
-      Fragment shared_prologue(normal_entry, instruction_cursor);
-      shared_prologue += prologue;
-      extra_entry = BuildSharedUncheckedEntryPoint(
-          /*shared_prologue_linked_in=*/shared_prologue,
-          /*skippable_checks=*/default_type_handling + implicit_checks,
-          /*redefinitions_if_skipped=*/Fragment(),
-          /*body=*/body);
-    }
-    RecordUncheckedEntryPoint(graph_entry_, extra_entry);
-  } else {
-    Fragment function(instruction_cursor);
-    function += prologue;
-    function += default_type_handling;
-    function += implicit_checks;
-    function += body;
-  }
+  closure += Return(function.end_token_pos());
 
   return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                            prologue_info);
@@ -3737,10 +3782,9 @@
 
   const bool signature_contains_handles = marshaller.ContainsHandles();
 
-  ASSERT(function.CanReceiveDynamicInvocation());
-  BuildTypeArgumentTypeChecks(TypeChecksToBuild::kCheckAllTypeParameterBounds,
-                              &function_body);
-  BuildArgumentTypeChecks(&function_body, &function_body, &function_body);
+  // FFI trampolines are accessed via closures, so non-covariant argument types
+  // and type arguments are either statically checked by the type system or
+  // dynamically checked via dynamic closure call dispatchers.
 
   // Null check arguments before we go into the try catch, so that we don't
   // catch our own null errors.
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index cd23744..1041f9c 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -120,6 +120,20 @@
   // function is generic.
   Fragment BuildClosureCallTypeArgumentsTypeCheck(const ClosureCallInfo& info);
 
+  // Builds checks for type checking a given argument of the closure call using
+  // parameter information from the closure function retrieved at runtime.
+  //
+  // For named arguments, arg_name is a compile-time constant retrieved from
+  // the saved arguments descriptor. For positional arguments, null is passed.
+  Fragment BuildClosureCallArgumentTypeCheck(const ClosureCallInfo& info,
+                                             LocalVariable* param_index,
+                                             intptr_t arg_index,
+                                             const String& arg_name);
+
+  // Builds checks for type checking the arguments of a call using parameter
+  // information for the function retrieved at runtime from the closure.
+  Fragment BuildClosureCallArgumentTypeChecks(const ClosureCallInfo& info);
+
   // Main entry point for building checks.
   Fragment BuildDynamicClosureCallChecks(LocalVariable* closure);
 
@@ -210,6 +224,7 @@
   Fragment ThrowTypeError();
   Fragment ThrowNoSuchMethodError(const Function& target);
   Fragment ThrowLateInitializationError(TokenPosition position,
+                                        const char* throw_method_name,
                                         const String& name);
   Fragment BuildImplicitClosureCreation(const Function& target);
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 5c28b56..794f917 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -626,9 +626,6 @@
     Function& function = Function::ZoneHandle(
         Z, klass.LookupFunctionAllowPrivate(procedure_name));
     CheckStaticLookup(function);
-    // Redirecting factory must be resolved.
-    ASSERT(!function.IsRedirectingFactory() ||
-           function.RedirectionTarget() != Function::null());
     return function.raw();
   }
 }
@@ -1084,6 +1081,10 @@
       kind_ = static_cast<Kind>(helper_->ReadByte());
       if (++next_read_ == field) return;
       FALL_THROUGH;
+    case kStubKind:
+      stub_kind_ = static_cast<StubKind>(helper_->ReadByte());
+      if (++next_read_ == field) return;
+      FALL_THROUGH;
     case kFlags:
       flags_ = helper_->ReadUInt();
       if (++next_read_ == field) return;
@@ -1100,16 +1101,12 @@
       if (++next_read_ == field) return;
     }
       FALL_THROUGH;
-    case kForwardingStubSuperTarget:
-      forwarding_stub_super_target_ = helper_->ReadCanonicalNameReference();
-      if (++next_read_ == field) return;
-      FALL_THROUGH;
-    case kForwardingStubInterfaceTarget:
-      helper_->ReadCanonicalNameReference();
-      if (++next_read_ == field) return;
-      FALL_THROUGH;
-    case kMemberSignatureTarget:
-      helper_->ReadCanonicalNameReference();
+    case kStubTarget:
+      if (stub_kind_ == kForwardingSuperStubKind) {
+        forwarding_stub_super_target_ = helper_->ReadCanonicalNameReference();
+      } else {
+        helper_->ReadCanonicalNameReference();
+      }
       if (++next_read_ == field) return;
       FALL_THROUGH;
     case kFunction:
@@ -2810,6 +2807,33 @@
   return H.DartString(reader_.BufferAt(ReaderOffset()), size, Heap::kOld);
 }
 
+ExternalTypedDataPtr KernelReaderHelper::GetConstantCoverageFor(
+    intptr_t index) {
+  AlternativeReadingScope alt(&reader_);
+  SetOffset(GetOffsetForSourceInfo(index));
+  SkipBytes(ReadUInt());                         // skip uri.
+  SkipBytes(ReadUInt());                         // skip source.
+  const intptr_t line_start_count = ReadUInt();  // read number of line start
+                                                 // entries.
+  for (intptr_t i = 0; i < line_start_count; ++i) {
+    ReadUInt();
+  }
+
+  SkipBytes(ReadUInt());  // skip import uri.
+
+  intptr_t start_offset = ReaderOffset();
+
+  // Read past "constant coverage constructors".
+  const intptr_t constant_coverage_constructors = ReadUInt();
+  for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
+    ReadUInt();
+  }
+
+  intptr_t end_offset = ReaderOffset();
+
+  return reader_.ExternalDataFromTo(start_offset, end_offset);
+}
+
 intptr_t ActiveClass::MemberTypeParameterCount(Zone* zone) {
   ASSERT(member != NULL);
   if (member->IsFactory()) {
@@ -3338,20 +3362,9 @@
     TypeParameterHelper helper(helper_);
     helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
 
-    // TODO(github.com/dart-lang/kernel/issues/42): This should be handled
-    // by the frontend.
     parameter ^= type_parameters.TypeAt(i);
-    const Tag tag = helper_->PeekTag();  // peek ith bound type.
-    if (tag == kDynamicType) {
-      helper_->SkipDartType();  // read ith bound.
-      parameter.set_bound(
-          Type::Handle(Z, nnbd_mode == NNBDMode::kOptedInLib
-                              ? I->object_store()->nullable_object_type()
-                              : I->object_store()->legacy_object_type()));
-    } else {
-      AbstractType& bound = BuildTypeWithoutFinalization();  // read ith bound.
-      parameter.set_bound(bound);
-    }
+    AbstractType& bound = BuildTypeWithoutFinalization();  // read ith bound.
+    parameter.set_bound(bound);
     helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kDefaultType);
     const AbstractType* default_arg = &Object::dynamic_type();
     if (helper_->ReadTag() == kSomething) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index d725cf7..36c8a5e 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -387,9 +387,10 @@
     kFinal = 1 << 0,
     kConst = 1 << 1,
     kCovariant = 1 << 3,
-    kIsGenericCovariantImpl = 1 << 5,
-    kLate = 1 << 6,
-    kRequired = 1 << 7,
+    kIsGenericCovariantImpl = 1 << 4,
+    kLate = 1 << 5,
+    kRequired = 1 << 6,
+    kLowered = 1 << 7,
   };
 
   explicit VariableDeclarationHelper(KernelReaderHelper* helper)
@@ -517,12 +518,11 @@
     kPosition,
     kEndPosition,
     kKind,
+    kStubKind,
     kFlags,
     kName,
     kAnnotations,
-    kForwardingStubSuperTarget,
-    kForwardingStubInterfaceTarget,
-    kMemberSignatureTarget,
+    kStubTarget,
     kFunction,
     kEnd,
   };
@@ -535,18 +535,26 @@
     kFactory,
   };
 
+  enum StubKind {
+    kRegularStubKind,
+    kForwardingStubKind,
+    kForwardingSuperStubKind,
+    kNoSuchMethodForwarderStubKind,
+    kMemberSignatureStubKind,
+    kMixinStubKind,
+    kMixinSuperStubKind,
+  };
+
   enum Flag {
     kStatic = 1 << 0,
     kAbstract = 1 << 1,
     kExternal = 1 << 2,
     kConst = 1 << 3,  // Only for external const factories.
-    kForwardingStub = 1 << 4,
 
     // TODO(29841): Remove this line after the issue is resolved.
-    kRedirectingFactoryConstructor = 1 << 6,
-    kNoSuchMethodForwarder = 1 << 7,
-    kExtensionMember = 1 << 8,
-    kMemberSignature = 1 << 9,
+    kRedirectingFactoryConstructor = 1 << 4,
+    kExtensionMember = 1 << 5,
+    kSyntheticProcedure = 1 << 7,
   };
 
   explicit ProcedureHelper(KernelReaderHelper* helper)
@@ -565,15 +573,20 @@
   bool IsAbstract() const { return (flags_ & kAbstract) != 0; }
   bool IsExternal() const { return (flags_ & kExternal) != 0; }
   bool IsConst() const { return (flags_ & kConst) != 0; }
-  bool IsForwardingStub() const { return (flags_ & kForwardingStub) != 0; }
+  bool IsForwardingStub() const {
+    return stub_kind_ == kForwardingStubKind ||
+           stub_kind_ == kForwardingSuperStubKind;
+  }
   bool IsRedirectingFactoryConstructor() const {
     return (flags_ & kRedirectingFactoryConstructor) != 0;
   }
   bool IsNoSuchMethodForwarder() const {
-    return (flags_ & kNoSuchMethodForwarder) != 0;
+    return stub_kind_ == kNoSuchMethodForwarderStubKind;
   }
   bool IsExtensionMember() const { return (flags_ & kExtensionMember) != 0; }
-  bool IsMemberSignature() const { return (flags_ & kMemberSignature) != 0; }
+  bool IsMemberSignature() const {
+    return stub_kind_ == kMemberSignatureStubKind;
+  }
 
   NameIndex canonical_name_;
   TokenPosition start_position_;
@@ -583,6 +596,7 @@
   uint32_t flags_ = 0;
   intptr_t source_uri_index_ = 0;
   intptr_t annotation_count_ = 0;
+  StubKind stub_kind_;
 
   // Only valid if the 'isForwardingStub' flag is set.
   NameIndex forwarding_stub_super_target_;
@@ -1244,6 +1258,7 @@
   const String& GetSourceFor(intptr_t index);
   TypedDataPtr GetLineStartsFor(intptr_t index);
   String& SourceTableImportUriFor(intptr_t index, uint32_t binaryVersion);
+  ExternalTypedDataPtr GetConstantCoverageFor(intptr_t index);
 
   Zone* zone_;
   TranslationHelper& translation_helper_;
@@ -1282,6 +1297,8 @@
   friend class ObfuscationProhibitionsMetadataHelper;
   friend class LoadingUnitsMetadataHelper;
   friend bool NeedsDynamicInvocationForwarder(const Function& function);
+  friend ArrayPtr CollectConstConstructorCoverageFrom(
+      const Script& interesting_script);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(KernelReaderHelper);
diff --git a/runtime/vm/compiler/frontend/multiple_entrypoints_test.cc b/runtime/vm/compiler/frontend/multiple_entrypoints_test.cc
deleted file mode 100644
index 9ae1679..0000000
--- a/runtime/vm/compiler/frontend/multiple_entrypoints_test.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/compiler/backend/il_test_helper.h"
-#include "vm/compiler/compiler_pass.h"
-#include "vm/object.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-#if defined(DART_PRECOMPILER)
-
-ISOLATE_UNIT_TEST_CASE(IRTest_MultilpeEntryPoints_Regress43534) {
-  const char* kScript =
-      R"(
-      import 'dart:typed_data';
-
-      @pragma('vm:never-inline')
-      void callWith<T>(void Function(T arg) fun, T arg) {
-        fun(arg);
-      }
-
-      @pragma('vm:never-inline')
-      void use(dynamic arg) {}
-
-      void test() {
-        callWith<Uint8List>((Uint8List list) {
-          use(list);
-        }, Uint8List(10));
-      }
-      )";
-
-  const auto& root_library = Library::Handle(LoadTestScript(kScript));
-  Invoke(root_library, "test");
-  const auto& test_function =
-      Function::Handle(GetFunction(root_library, "test"));
-  const auto& closures = GrowableObjectArray::Handle(
-      Isolate::Current()->object_store()->closure_functions());
-  auto& function = Function::Handle();
-  for (intptr_t i = closures.Length() - 1; 0 <= i; ++i) {
-    function ^= closures.At(i);
-    if (function.parent_function() == test_function.raw()) {
-      break;
-    }
-    function = Function::null();
-  }
-  RELEASE_ASSERT(!function.IsNull());
-  TestPipeline pipeline(function, CompilerPass::kAOT);
-  FlowGraph* flow_graph = pipeline.RunPasses({CompilerPass::kComputeSSA});
-
-  auto entry = flow_graph->graph_entry()->normal_entry();
-  EXPECT(entry != nullptr);
-
-  auto unchecked_entry = flow_graph->graph_entry()->unchecked_entry();
-  EXPECT(unchecked_entry != nullptr);
-
-  AssertAssignableInstr* assert_assignable = nullptr;
-  StaticCallInstr* static_call = nullptr;
-
-  // Normal entry
-  ILMatcher cursor(flow_graph, entry, /*trace=*/true);
-  RELEASE_ASSERT(cursor.TryMatch(
-      {
-          kMatchAndMoveGoto,
-          kMatchAndMoveBranchFalse,
-          {kMatchAndMoveAssertAssignable, &assert_assignable},
-          kMatchAndMoveGoto,
-          {kMatchAndMoveStaticCall, &static_call},
-          kMatchReturn,
-      },
-      kMoveGlob));
-
-  RedefinitionInstr* redefinition = nullptr;
-  StaticCallInstr* static_call2 = nullptr;
-
-  // Unchecked entry
-  ILMatcher cursor2(flow_graph, entry, /*trace=*/true);
-  RELEASE_ASSERT(cursor2.TryMatch(
-      {
-          kMatchAndMoveGoto,
-          kMatchAndMoveBranchTrue,
-          {kMatchAndMoveRedefinition, &redefinition},
-          kMatchAndMoveGoto,
-          {kMatchAndMoveStaticCall, &static_call2},
-          kMatchReturn,
-      },
-      kMoveGlob));
-
-  // Ensure the value the static call uses is a Phi node with 2 inputs:
-  //   a) Normal entry: AssertAssignable
-  //   b) Unchecked entry: Redefinition
-  RELEASE_ASSERT(static_call->ArgumentAt(0)->IsPhi());
-  auto phi = static_call->ArgumentAt(0)->AsPhi();
-  auto input_a = phi->InputAt(0)->definition();
-  auto input_b = phi->InputAt(1)->definition();
-  RELEASE_ASSERT(input_a->IsRedefinition());
-  RELEASE_ASSERT(input_b->IsAssertAssignable());
-  RELEASE_ASSERT(input_a == redefinition);
-  RELEASE_ASSERT(input_b == assert_assignable);
-  RELEASE_ASSERT(static_call == static_call2);
-}
-
-#endif  // defined(DART_PRECOMPILER)
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 7fd8c35..64fb780 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -40,7 +40,6 @@
 
 bool PrologueBuilder::HasEmptyPrologue(const Function& function) {
   return !function.HasOptionalParameters() && !function.IsGeneric() &&
-         !function.CanReceiveDynamicInvocation() &&
          !function.IsClosureFunction();
 }
 
@@ -53,26 +52,12 @@
 
   const bool load_optional_arguments = function_.HasOptionalParameters();
   const bool expect_type_args = function_.IsGeneric();
-  const bool check_shapes = function_.CanReceiveDynamicInvocation();
 
   Fragment prologue = Fragment(entry);
 
-  // We only check for bad argument shapes and throw NSM in functions that
-  // can receive dynamic invocation. Otherwise, the NSM block is never used
-  // and so there's no need to create it. The helper methods can only throw
-  // NSM in appropriate spots if one was created.
-  JoinEntryInstr* nsm = nullptr;
-  if (check_shapes) {
-    nsm = BuildThrowNoSuchMethod();
-    Fragment f = BuildTypeArgumentsLengthCheck(nsm, expect_type_args);
-    if (link) prologue += f;
-  }
   if (load_optional_arguments) {
-    Fragment f = BuildOptionalParameterHandling(
-        nsm, parsed_function_->expression_temp_var());
-    if (link) prologue += f;
-  } else if (check_shapes) {
-    Fragment f = BuildFixedParameterLengthChecks(nsm);
+    Fragment f =
+        BuildOptionalParameterHandling(parsed_function_->expression_temp_var());
     if (link) prologue += f;
   }
   if (function_.IsClosureFunction()) {
@@ -80,7 +65,7 @@
     if (!compiling_for_osr_) prologue += f;
   }
   if (expect_type_args) {
-    Fragment f = BuildTypeArgumentsHandling(nsm);
+    Fragment f = BuildTypeArgumentsHandling();
     if (link) prologue += f;
   }
 
@@ -103,57 +88,8 @@
   }
 }
 
-Fragment PrologueBuilder::BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
-                                                        bool expect_type_args) {
-  ASSERT(nsm != nullptr);
-  Fragment check_type_args;
-  JoinEntryInstr* done = BuildJoinEntry();
-
-  // Type args are always optional, so length can always be zero.
-  // If expect_type_args, a non-zero length must match the declaration length.
-  TargetEntryInstr *then, *fail;
-  check_type_args += LoadArgDescriptor();
-  check_type_args += LoadNativeField(Slot::ArgumentsDescriptor_type_args_len());
-  if (expect_type_args) {
-    JoinEntryInstr* join2 = BuildJoinEntry();
-
-    LocalVariable* len = MakeTemporary();
-
-    TargetEntryInstr* otherwise;
-    check_type_args += LoadLocal(len);
-    check_type_args += IntConstant(0);
-    check_type_args += BranchIfEqual(&then, &otherwise);
-
-    TargetEntryInstr* then2;
-    Fragment check_len(otherwise);
-    check_len += LoadLocal(len);
-    check_len += IntConstant(function_.NumTypeParameters());
-    check_len += BranchIfEqual(&then2, &fail);
-
-    Fragment(then) + Goto(join2);
-    Fragment(then2) + Goto(join2);
-
-    Fragment(join2) + Drop() + Goto(done);
-    Fragment(fail) + Goto(nsm);
-  } else {
-    check_type_args += IntConstant(0);
-    check_type_args += BranchIfEqual(&then, &fail);
-    Fragment(then) + Goto(done);
-    Fragment(fail) + Goto(nsm);
-  }
-
-  return Fragment(check_type_args.entry, done);
-}
-
 Fragment PrologueBuilder::BuildOptionalParameterHandling(
-    JoinEntryInstr* nsm,
     LocalVariable* temp_var) {
-  // We only need to check the shape of the arguments (correct parameter count
-  // and correct names/provided required arguments) when the function can be
-  // invoked dynamically. The caller only provides a non-nullptr nsm block if
-  // dynamic invocation is possible.
-  const bool check_arguments_shape = nsm != nullptr;
-
   Fragment copy_args_prologue;
   const int num_fixed_params = function_.num_fixed_parameters();
   const int num_opt_pos_params = function_.NumOptionalPositionalParameters();
@@ -168,39 +104,15 @@
   // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
   // where num_pos_args is the number of positional arguments passed in.
   const int min_num_pos_args = num_fixed_params;
-  const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
 
   copy_args_prologue += LoadArgDescriptor();
   copy_args_prologue +=
       LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
-  LocalVariable* positional_count_var = MakeTemporary();
 
   copy_args_prologue += LoadArgDescriptor();
   copy_args_prologue += LoadNativeField(Slot::ArgumentsDescriptor_count());
   LocalVariable* count_var = MakeTemporary();
 
-  if (check_arguments_shape) {
-    // Ensure the caller provided at least [min_num_pos_args] arguments.
-    copy_args_prologue += IntConstant(min_num_pos_args);
-    copy_args_prologue += LoadLocal(positional_count_var);
-    copy_args_prologue += SmiRelationalOp(Token::kLTE);
-    TargetEntryInstr *success1, *fail1;
-    copy_args_prologue += BranchIfTrue(&success1, &fail1);
-    copy_args_prologue = Fragment(copy_args_prologue.entry, success1);
-
-    // Ensure the caller provided at most [max_num_pos_args] arguments.
-    copy_args_prologue += LoadLocal(positional_count_var);
-    copy_args_prologue += IntConstant(max_num_pos_args);
-    copy_args_prologue += SmiRelationalOp(Token::kLTE);
-    TargetEntryInstr *success2, *fail2;
-    copy_args_prologue += BranchIfTrue(&success2, &fail2);
-    copy_args_prologue = Fragment(copy_args_prologue.entry, success2);
-
-    // Link up the argument check failing code.
-    Fragment(fail1) + Goto(nsm);
-    Fragment(fail2) + Goto(nsm);
-  }
-
   copy_args_prologue += LoadLocal(count_var);
   copy_args_prologue += IntConstant(min_num_pos_args);
   copy_args_prologue += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
@@ -290,23 +202,11 @@
     }
     copy_args_prologue += Goto(next_missing /* join good/not_good flows */);
     copy_args_prologue.current = next_missing;
-
-    if (check_arguments_shape) {
-      // Check for unprocessed arguments and throw NSM if there are any.
-      TargetEntryInstr *done, *unknown_named_arg_passed;
-      copy_args_prologue += LoadLocal(positional_count_var);
-      copy_args_prologue += LoadLocal(count_var);
-      copy_args_prologue += BranchIfEqual(&done, &unknown_named_arg_passed);
-      copy_args_prologue.current = done;
-      {
-        Fragment f(unknown_named_arg_passed);
-        f += Goto(nsm);
-      }
-    }
   } else {
     ASSERT(num_opt_named_params > 0);
 
-    bool null_safety = Isolate::Current()->null_safety();
+    bool check_required_params =
+        Isolate::Current()->use_strict_null_safety_checks();
     const intptr_t first_name_offset =
         compiler::target::ArgumentsDescriptor::first_named_entry_offset() -
         compiler::target::Array::data_offset();
@@ -371,13 +271,10 @@
         good += Drop();
       }
 
-      const bool required =
-          null_safety && function_.IsRequiredAt(opt_param_position[i]);
+      const bool required = check_required_params &&
+                            function_.IsRequiredAt(opt_param_position[i]);
 
-      // If this function cannot be invoked dynamically and this is a required
-      // named argument, then we can just add this fragment directly without
-      // checking the name to ensure it was provided.
-      if (required && !check_arguments_shape) {
+      if (required) {
         copy_args_prologue += good;
       } else {
         // name = arg_desc[names_offset + arg_desc_name_index + nameOffset]
@@ -409,42 +306,22 @@
         good.Prepend(supplied);
         good += Goto(join);
 
-        // We had no match. If the param is required, throw a NoSuchMethod
-        // error. Otherwise just load the default constant.
+        // We had no match, so load the default constant.
         Fragment not_good(missing);
-        if (required) {
-          ASSERT(nsm != nullptr);
-          not_good += Goto(nsm);
-        } else {
-          not_good += Constant(DefaultParameterValueAt(opt_param_position[i] -
-                                                       num_fixed_params));
+        not_good += Constant(
+            DefaultParameterValueAt(opt_param_position[i] - num_fixed_params));
 
-          // Copy down with default value.
-          not_good += StoreLocalRaw(TokenPosition::kNoSource,
-                                    ParameterVariable(opt_param_position[i]));
-          not_good += Drop();
-          not_good += Goto(join);
-        }
+        // Copy down with default value.
+        not_good += StoreLocalRaw(TokenPosition::kNoSource,
+                                  ParameterVariable(opt_param_position[i]));
+        not_good += Drop();
+        not_good += Goto(join);
 
         copy_args_prologue.current = join;
       }
 
       copy_args_prologue += Drop();  // tuple_diff
     }
-
-    if (check_arguments_shape) {
-      // Check for unprocessed arguments and throw NSM if there are any.
-      TargetEntryInstr *done, *unknown_named_arg_passed;
-      copy_args_prologue += LoadLocal(optional_count_var);
-      copy_args_prologue += LoadLocal(optional_count_vars_processed);
-      copy_args_prologue += BranchIfEqual(&done, &unknown_named_arg_passed);
-      copy_args_prologue.current = done;
-
-      {
-        Fragment f(unknown_named_arg_passed);
-        f += Goto(nsm);
-      }
-    }
   }
 
   copy_args_prologue += Drop();  // optional_count_var
@@ -454,32 +331,6 @@
   return copy_args_prologue;
 }
 
-Fragment PrologueBuilder::BuildFixedParameterLengthChecks(JoinEntryInstr* nsm) {
-  Fragment check_args;
-  JoinEntryInstr* done = BuildJoinEntry();
-
-  check_args += LoadArgDescriptor();
-  check_args += LoadNativeField(Slot::ArgumentsDescriptor_count());
-  LocalVariable* count = MakeTemporary();
-
-  TargetEntryInstr *then, *fail;
-  check_args += LoadLocal(count);
-  check_args += IntConstant(function_.num_fixed_parameters());
-  check_args += BranchIfEqual(&then, &fail);
-
-  TargetEntryInstr *then2, *fail2;
-  Fragment check_len(then);
-  check_len += LoadArgDescriptor();
-  check_len += LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
-  check_len += BranchIfEqual(&then2, &fail2);
-
-  Fragment(fail) + Goto(nsm);
-  Fragment(fail2) + Goto(nsm);
-  Fragment(then2) + Goto(done);
-
-  return Fragment(check_args.entry, done);
-}
-
 Fragment PrologueBuilder::BuildClosureContextHandling() {
   LocalVariable* closure_parameter = parsed_function_->ParameterVariable(0);
   LocalVariable* context = parsed_function_->current_context_var();
@@ -494,13 +345,7 @@
   return populate_context;
 }
 
-Fragment PrologueBuilder::BuildTypeArgumentsHandling(JoinEntryInstr* nsm) {
-  // We only need to check the shape of the arguments (correct parameter count
-  // and correct names/provided required arguments) when the function can be
-  // invoked dynamically. The caller only provides a non-nullptr nsm block if
-  // dynamic invocation is possible.
-  const bool check_argument_shapes = nsm != nullptr;
-
+Fragment PrologueBuilder::BuildTypeArgumentsHandling() {
   LocalVariable* type_args_var = parsed_function_->RawTypeArgumentsVariable();
   ASSERT(type_args_var != nullptr);
 
@@ -538,15 +383,9 @@
         StoreLocal(TokenPosition::kNoSource, type_args_var);
     use_delayed_type_args += Drop();
 
-    handling += TestDelayedTypeArgs(
-        closure,
-        /*present=*/
-        // No need to check the type arguments length if this function cannot
-        // be invoked dynamically, and thus we are not checking argument shapes.
-        check_argument_shapes
-            ? TestTypeArgsLen(use_delayed_type_args, Goto(nsm), 0)
-            : use_delayed_type_args,
-        /*absent=*/Fragment());
+    handling += TestDelayedTypeArgs(closure,
+                                    /*present=*/use_delayed_type_args,
+                                    /*absent=*/Fragment());
   }
 
   return handling;
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index 58923f9..c8d629d 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -49,8 +49,7 @@
   BlockEntryInstr* BuildPrologue(BlockEntryInstr* entry,
                                  PrologueInfo* prologue_info);
 
-  Fragment BuildOptionalParameterHandling(JoinEntryInstr* nsm,
-                                          LocalVariable* temp_var);
+  Fragment BuildOptionalParameterHandling(LocalVariable* temp_var);
 
   static bool HasEmptyPrologue(const Function& function);
   static bool PrologueSkippableOnUncheckedEntry(const Function& function);
@@ -58,14 +57,9 @@
   intptr_t last_used_block_id() const { return last_used_block_id_; }
 
  private:
-  Fragment BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
-                                         bool expect_type_args);
-
-  Fragment BuildFixedParameterLengthChecks(JoinEntryInstr* nsm);
-
   Fragment BuildClosureContextHandling();
 
-  Fragment BuildTypeArgumentsHandling(JoinEntryInstr* nsm);
+  Fragment BuildTypeArgumentsHandling();
 
   LocalVariable* ParameterVariable(intptr_t index) {
     return parsed_function_->RawParameterVariable(index);
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 4470cee..ba75d00 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -15,44 +15,6 @@
 #define T (type_translator_)
 #define I Isolate::Current()
 
-// Returns true if the given method can skip type checks for all type arguments
-// that are not covariant or generic covariant in its implementation.
-bool MethodCanSkipTypeChecksForNonCovariantTypeArguments(
-    const Function& method) {
-  // Dart 2 type system at non-dynamic call sites statically guarantees that
-  // argument values match declared parameter types for all non-covariant
-  // and non-generic-covariant parameters. The same applies to type parameters
-  // bounds for type parameters of generic functions.
-  //
-  // Normally dynamic call sites will call dyn:* forwarders which perform type
-  // checks.
-  //
-  // Though for some kinds of methods (e.g. ffi trampolines called from native
-  // code) we do have to perform type checks for all parameters.
-  return !method.CanReceiveDynamicInvocation();
-}
-
-// Returns true if the given method can skip type checks for all arguments
-// that are not covariant or generic covariant in its implementation.
-bool MethodCanSkipTypeChecksForNonCovariantArguments(const Function& method) {
-  // Dart 2 type system at non-dynamic call sites statically guarantees that
-  // argument values match declarated parameter types for all non-covariant
-  // and non-generic-covariant parameters. The same applies to type parameters
-  // bounds for type parameters of generic functions.
-  //
-  // Normally dynamic call sites will call dyn:* forwarders which perform type
-  // checks.
-  //
-  // Though for some kinds of methods (e.g. ffi trampolines called from native
-  // code) we do have to perform type checks for all parameters.
-  //
-  // TODO(dartbug.com/40813): Remove the closure case when argument checks have
-  // been fully moved out of closures.
-  return !method.CanReceiveDynamicInvocation() &&
-         !(method.IsClosureFunction() &&
-           Function::ClosureBodiesContainNonCovariantArgumentChecks());
-}
-
 ScopeBuilder::ScopeBuilder(ParsedFunction* parsed_function)
     : result_(NULL),
       parsed_function_(parsed_function),
@@ -134,7 +96,6 @@
   }
 
   if (parsed_function_->has_arg_desc_var()) {
-    needs_expr_temp_ = true;
     scope_->AddVariable(parsed_function_->arg_desc_var());
   }
 
@@ -230,47 +191,28 @@
         result_->type_arguments_variable = variable;
       }
 
-      ParameterTypeCheckMode type_check_mode = kTypeCheckAllParameters;
+      ParameterTypeCheckMode type_check_mode =
+          kTypeCheckForNonDynamicallyInvokedMethod;
       if (function.IsSyncGenClosure()) {
         // Don't type check the parameter of sync-yielding since these calls are
         // all synthetic and types should always match.
-        ASSERT((function.NumParameters() - function.NumImplicitParameters()) ==
-               3);
+        ASSERT_EQUAL(
+            function.NumParameters() - function.NumImplicitParameters(), 3);
         ASSERT(
             Class::Handle(
                 AbstractType::Handle(function.ParameterTypeAt(1)).type_class())
                 .ScrubbedName() == Symbols::_SyncIterator().raw());
         type_check_mode = kTypeCheckForStaticFunction;
-      } else if (function.IsNonImplicitClosureFunction()) {
-        type_check_mode = kTypeCheckAllParameters;
+      } else if (function.is_static()) {
+        // In static functions we don't check anything.
+        type_check_mode = kTypeCheckForStaticFunction;
       } else if (function.IsImplicitClosureFunction()) {
-        if (MethodCanSkipTypeChecksForNonCovariantTypeArguments(
-                Function::Handle(Z, function.parent_function())) &&
-            MethodCanSkipTypeChecksForNonCovariantArguments(
-                Function::Handle(Z, function.parent_function()))) {
-          // This is a tear-off of an instance method that can not be reached
-          // from any dynamic invocation. The method would not check any
-          // parameters except covariant ones and those annotated with
-          // generic-covariant-impl. Which means that we have to check
-          // the rest in the tear-off itself.
-          type_check_mode =
-              kTypeCheckEverythingNotCheckedInNonDynamicallyInvokedMethod;
-        }
-      } else {
-        if (function.is_static()) {
-          // In static functions we don't check anything.
-          type_check_mode = kTypeCheckForStaticFunction;
-        } else if (MethodCanSkipTypeChecksForNonCovariantTypeArguments(
-                       function) &&
-                   MethodCanSkipTypeChecksForNonCovariantArguments(function)) {
-          // If the current function is never a target of a dynamic invocation
-          // and this parameter is not marked with generic-covariant-impl
-          // (which means that among all super-interfaces no type parameters
-          // ever occur at the position of this parameter) then we don't need
-          // to check this parameter on the callee side, because strong mode
-          // guarantees that it was checked at the caller side.
-          type_check_mode = kTypeCheckForNonDynamicallyInvokedMethod;
-        }
+        // All non-covariant checks are either performed by the type system,
+        // or by a dynamic closure call dispatcher/mirror if dynamically
+        // invoked. For covariant checks, static targets never have covariant
+        // arguments and dynamic targets do their own covariant checking.
+        // Thus, implicit closure functions perform no checking internally.
+        type_check_mode = kTypeCheckForImplicitClosureFunction;
       }
 
       // Continue reading FunctionNode:
@@ -336,9 +278,7 @@
         }
         scope_->InsertParameterAt(pos++, result_->setter_value);
 
-        if (is_method &&
-            MethodCanSkipTypeChecksForNonCovariantTypeArguments(function) &&
-            MethodCanSkipTypeChecksForNonCovariantArguments(function)) {
+        if (is_method) {
           if (field.is_covariant()) {
             result_->setter_value->set_is_explicit_covariant_parameter();
           } else if (!field.is_generic_covariant_impl() ||
@@ -460,6 +400,9 @@
 #define ADD_VAR(Name, _, __) scope_->AddVariable(vars->Name);
         FOR_EACH_DYNAMIC_CLOSURE_CALL_VARIABLE(ADD_VAR);
 #undef ADD_VAR
+        for (auto const& v : vars->named_argument_parameter_indices) {
+          scope_->AddVariable(v);
+        }
       }
     }
       FALL_THROUGH;
@@ -480,7 +423,10 @@
       UNREACHABLE();
   }
   if (needs_expr_temp_) {
-    scope_->AddVariable(parsed_function_->EnsureExpressionTemp());
+    parsed_function_->EnsureExpressionTemp();
+  }
+  if (parsed_function_->has_expression_temp_var()) {
+    scope_->AddVariable(parsed_function_->expression_temp_var());
   }
   if (parsed_function_->function().MayHaveUncheckedEntryPoint()) {
     scope_->AddVariable(parsed_function_->EnsureEntryPointsTemp());
@@ -598,16 +544,6 @@
   }
   function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
 
-  if (FLAG_causal_async_stacks &&
-      (function_node_helper.dart_async_marker_ == FunctionNodeHelper::kAsync ||
-       function_node_helper.dart_async_marker_ ==
-           FunctionNodeHelper::kAsyncStar)) {
-    LocalVariable* asyncStackTraceVar = MakeVariable(
-        TokenPosition::kNoSource, TokenPosition::kNoSource,
-        Symbols::AsyncStackTraceVar(), AbstractType::dynamic_type());
-    scope_->AddVariable(asyncStackTraceVar);
-  }
-
   // The :sync_op and :async_op continuations are called multiple times. So we
   // don't want the parameters from the first invocation to get stored in the
   // context and reused on later invocations with different parameters.
@@ -627,8 +563,8 @@
     first_body_token_position_ = helper_.reader_.min_position();
   }
 
-  // Ensure that :await_jump_var, :await_ctx_var, :async_op, :is_sync,
-  // :async_future and :async_stack_trace are captured.
+  // Ensure that :await_jump_var, :await_ctx_var, :async_op, :is_sync and
+  // :async_future are captured.
   if (function_node_helper.async_marker_ == FunctionNodeHelper::kSyncYielding) {
     {
       LocalVariable* temp = nullptr;
@@ -669,13 +605,6 @@
         scope_->CaptureVariable(temp);
       }
     }
-    if (FLAG_causal_async_stacks) {
-      LocalVariable* temp =
-          scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true);
-      if (temp != nullptr) {
-        scope_->CaptureVariable(temp);
-      }
-    }
   }
 
   // Mark known chained futures such as _Future::timeout()'s _future.
@@ -1345,7 +1274,7 @@
   // debuggable position in the initializer.
   TokenPosition end_position = helper_.reader_.max_position();
   if (end_position.IsReal()) {
-    end_position.Next();
+    end_position = end_position.Next();
   }
   LocalVariable* variable =
       MakeVariable(helper.position_, end_position, name, type);
@@ -1539,7 +1468,8 @@
       FunctionNodeHelper::kPositionalParameters);
 
   ProcedureAttributesMetadata default_attrs;
-  AddPositionalAndNamedParameters(0, kTypeCheckAllParameters, default_attrs);
+  AddPositionalAndNamedParameters(0, kTypeCheckForNonDynamicallyInvokedMethod,
+                                  default_attrs);
 
   // "Peek" is now done.
   helper_.SetOffset(offset);
@@ -1639,6 +1569,17 @@
         variable->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
       }
       break;
+    case kTypeCheckForImplicitClosureFunction:
+      if (needs_covariant_check_in_method) {
+        // Don't type check covariant parameters - they will be checked by
+        // a function we forward to. Their types however are not known.
+        variable->set_type_check_mode(LocalVariable::kSkipTypeCheck);
+      } else {
+        // All non-covariant checks are either checked by the type system or
+        // by a dynamic closure call dispatcher.
+        variable->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
+      }
+      break;
     case kTypeCheckForStaticFunction:
       variable->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
       break;
diff --git a/runtime/vm/compiler/frontend/scope_builder.h b/runtime/vm/compiler/frontend/scope_builder.h
index 33e24b3..c8680c3 100644
--- a/runtime/vm/compiler/frontend/scope_builder.h
+++ b/runtime/vm/compiler/frontend/scope_builder.h
@@ -73,6 +73,10 @@
 
     // No parameters will be checked.
     kTypeCheckForStaticFunction,
+
+    // No non-covariant checks are performed, and any covariant checks are
+    // performed by the target.
+    kTypeCheckForImplicitClosureFunction,
   };
 
   // This assumes that the reader is at a FunctionNode,
@@ -230,15 +234,6 @@
   DISALLOW_COPY_AND_ASSIGN(ScopeBuildingResult);
 };
 
-// Returns true if the given method can skip type checks for all type arguments
-// that are not covariant or generic covariant in its implementation.
-bool MethodCanSkipTypeChecksForNonCovariantTypeArguments(
-    const Function& method);
-
-// Returns true if the given method can skip type checks for all arguments
-// that are not covariant or generic covariant in its implementation.
-bool MethodCanSkipTypeChecksForNonCovariantArguments(const Function& method);
-
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/graph_intrinsifier_arm.cc b/runtime/vm/compiler/graph_intrinsifier_arm.cc
index cc8dc4c..1cebb33 100644
--- a/runtime/vm/compiler/graph_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_arm.cc
@@ -17,14 +17,10 @@
   return -1;
 }
 
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
-}
-
 void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CODE_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(ARGS_DESC_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP));
 
   // Save LR by moving it to a callee saved temporary register.
   assembler->Comment("IntrinsicCallPrologue");
diff --git a/runtime/vm/compiler/graph_intrinsifier_arm64.cc b/runtime/vm/compiler/graph_intrinsifier_arm64.cc
index 9bd2ae5..99d33b4 100644
--- a/runtime/vm/compiler/graph_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_arm64.cc
@@ -17,19 +17,15 @@
   return -1;
 }
 
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
-}
-
 void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
-  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
-  ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
+  COMPILE_ASSERT(IsAbiPreservedRegister(CODE_REG));
+  COMPILE_ASSERT(!IsAbiPreservedRegister(ARGS_DESC_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP2));
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
 
   assembler->Comment("IntrinsicCallPrologue");
   assembler->mov(CALLEE_SAVED_TEMP, LR);
diff --git a/runtime/vm/compiler/graph_intrinsifier_x64.cc b/runtime/vm/compiler/graph_intrinsifier_x64.cc
index 58c02b2..e1479a8 100644
--- a/runtime/vm/compiler/graph_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/graph_intrinsifier_x64.cc
@@ -17,16 +17,12 @@
   return 0;
 }
 
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
-}
-
 void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  COMPILE_ASSERT(IsAbiPreservedRegister(CODE_REG));
+  COMPILE_ASSERT(!IsAbiPreservedRegister(ARGS_DESC_REG));
+  COMPILE_ASSERT(IsAbiPreservedRegister(CALLEE_SAVED_TEMP));
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
 
   assembler->Comment("IntrinsicCallPrologue");
   assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 1c7f122..9931e91 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -130,8 +130,6 @@
     //
     // Normally we have to check the parameter type.
     ASSERT(function.NeedsArgumentTypeChecks());
-    // Dynamic call sites will go to dyn:set:* instead.
-    ASSERT(!function.CanReceiveDynamicInvocation());
     // Covariant parameter types have to be checked, which we don't support.
     if (field.is_covariant() || field.is_generic_covariant_impl()) return false;
 
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index cd282c3..3e142f4 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -104,7 +104,6 @@
     FLAG_reorder_basic_blocks = true;
     FLAG_use_field_guards = false;
     FLAG_use_cha_deopt = false;
-    FLAG_causal_async_stacks = false;
     FLAG_lazy_async_stacks = true;
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
@@ -212,17 +211,15 @@
 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
   ASSERT(thread->IsMutatorThread());
   const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0));
-  Object& result = Object::Handle(zone);
-  ASSERT(!function.HasCode());
 
-  result = Compiler::CompileFunction(thread, function);
-  if (result.IsError()) {
-    if (result.IsLanguageError()) {
-      Exceptions::ThrowCompileTimeError(LanguageError::Cast(result));
-      UNREACHABLE();
-    }
-    Exceptions::PropagateError(Error::Cast(result));
-  }
+  // In single-isolate scenarios the lazy compile stub is only invoked if
+  // there's no existing code. In multi-isolate scenarios with shared JITed code
+  // we can end up in the lazy compile runtime entry here with code being
+  // installed.
+  ASSERT(!function.HasCode() || FLAG_enable_isolate_groups);
+
+  // Will throw if compilation failed (e.g. with compile-time error).
+  function.EnsureHasCode();
 }
 
 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
@@ -620,10 +617,13 @@
           CheckIfBackgroundCompilerIsBeingStopped(optimized());
         }
 
-        // Grab read program_lock outside of potential safepoint, that lock
+        // Grab write program_lock outside of potential safepoint, that lock
         // can't be waited for inside the safepoint.
-        SafepointReadRwLocker ml(thread(),
-                                 thread()->isolate_group()->program_lock());
+        // Initially read lock was added to guard direct_subclasses field
+        // access.
+        // Read lock was upgraded to write lock to guard dependent code updates.
+        SafepointWriteRwLocker ml(thread(),
+                                  thread()->isolate_group()->program_lock());
         // We have to ensure no mutators are running, because:
         //
         //   a) We allocate an instructions object, which might cause us to
@@ -975,8 +975,7 @@
   for (int i = 0; i < functions.Length(); i++) {
     func ^= functions.At(i);
     ASSERT(!func.IsNull());
-    if (!func.HasCode() && !func.is_abstract() &&
-        !func.IsRedirectingFactory()) {
+    if (!func.HasCode() && !func.is_abstract()) {
       result = CompileFunction(thread, func);
       if (result.IsError()) {
         return Error::Cast(result).raw();
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc
index 6ce72c4..05ce2af 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.cc
+++ b/runtime/vm/compiler/jit/jit_call_specializer.cc
@@ -205,6 +205,9 @@
       }
       ASSERT(field.IsOriginal());
       field.set_is_unboxing_candidate(false);
+      Thread* thread = Thread::Current();
+      SafepointWriteRwLocker ml(thread,
+                                thread->isolate_group()->program_lock());
       field.DeoptimizeDependentCode();
     } else {
       flow_graph()->parsed_function().AddToGuardedFields(&field);
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 2d4d7d6..ecd99a1 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -195,6 +195,27 @@
   return "?";
 }
 
+// Is this method marked with the vm:recognized pragma?
+bool MethodRecognizer::IsMarkedAsRecognized(const Function& function,
+                                            const char* kind) {
+  const Function* functionp =
+      function.IsDynamicInvocationForwarder()
+          ? &Function::Handle(function.ForwardingTarget())
+          : &function;
+  Object& options = Object::Handle();
+  bool is_recognized =
+      Library::FindPragma(Thread::Current(), /*only_core=*/true, *functionp,
+                          Symbols::vm_recognized(), &options);
+  if (!is_recognized) return false;
+  if (kind == nullptr) return true;
+
+  ASSERT(options.IsString());
+  ASSERT(String::Cast(options).Equals("asm-intrinsic") ||
+         String::Cast(options).Equals("graph-intrinsic") ||
+         String::Cast(options).Equals("other"));
+  return String::Cast(options).Equals(kind);
+}
+
 void MethodRecognizer::InitializeState() {
   GrowableArray<Library*> libs(3);
   Libraries(&libs);
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index 949e031..e9a1067 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -53,6 +53,8 @@
   static intptr_t MethodKindToReceiverCid(Kind kind);
   static const char* KindToCString(Kind kind);
 
+  static bool IsMarkedAsRecognized(const Function& function,
+                                   const char* kind = nullptr);
   static void InitializeState();
 
  private:
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index d725d4e..6c80aa5 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -12,365 +12,368 @@
 // When adding a new function, add a 0 as the fingerprint and run the build in
 // debug mode to get the correct fingerprint from the mismatch error.
 #define OTHER_RECOGNIZED_LIST(V)                                               \
-  V(::, identical, ObjectIdentical, 0x8fd6ea58)                                \
-  V(ClassID, getID, ClassIDgetID, 0x0401ffad)                                  \
-  V(Object, Object., ObjectConstructor, 0x256e7170)                            \
-  V(List, ., ListFactory, 0xbec87d33)                                          \
-  V(_List, ., ObjectArrayAllocate, 0x6de199a1)                                 \
-  V(_List, []=, ObjectArraySetIndexed, 0xba15978f)                             \
-  V(_GrowableList, []=, GrowableArraySetIndexed, 0xba15978f)                   \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0xc28aff37)                    \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0xc3e7212d)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0xdaa7b952)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0xdc2919bc)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0xc57f53af)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0xc5c49520)                \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0xa2c7e6a4)                  \
-  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0xd8c29ffe)                \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0xaf15f28a)              \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0xbe4987b7)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x76c82c28)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x29abed4e)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0xfc13ad87)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 0xc9e4212d)                  \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0xd570aa0c)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 0xe8acb234)                \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0xd8651525)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0xd3f10d97)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0xe357b95f)                  \
-  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0xf4d19bea)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0xd6272645)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0xca4af137)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x71767f7f)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0xf0483280)              \
-  V(ByteData, ., ByteDataFactory, 0x63fefa4b)                                  \
-  V(_ByteDataView, get:offsetInBytes, ByteDataViewOffsetInBytes, 0xe51b926b)   \
-  V(_ByteDataView, get:_typedData, ByteDataViewTypedData, 0x3c781fb9)          \
-  V(_TypedListView, get:offsetInBytes, TypedDataViewOffsetInBytes, 0xe51b926b) \
-  V(_TypedListView, get:_typedData, TypedDataViewTypedData, 0x3c781fb9)        \
-  V(_ByteDataView, ._, TypedData_ByteDataView_factory, 0xe9e9dad9)             \
-  V(_Int8ArrayView, ._, TypedData_Int8ArrayView_factory, 0x016014a7)           \
-  V(_Uint8ArrayView, ._, TypedData_Uint8ArrayView_factory, 0x8c3fc232)         \
+  V(::, identical, ObjectIdentical, 0x19eb7f33)                                \
+  V(ClassID, getID, ClassIDgetID, 0x4d140cb3)                                  \
+  V(Object, Object., ObjectConstructor, 0x89c467da)                            \
+  V(List, ., ListFactory, 0x1892cc51)                                          \
+  V(_List, ., ObjectArrayAllocate, 0x4c9d39e2)                                 \
+  V(_List, []=, ObjectArraySetIndexed, 0xa06ee8ae)                             \
+  V(_GrowableList, []=, GrowableArraySetIndexed, 0xa06ee8ae)                   \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x30688af4)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x31c4acea)                  \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x4885450f)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x4a06a579)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x335cdbca)                  \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x33a21d3b)                \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x10a56ebf)                  \
+  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x46a02819)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0xe425bcd3)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0xf3595200)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0xb3cc1803)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0xbe4aee59)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x89b17e2a)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 0x5781f1d0)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x630e7aaf)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 0x764a82d7)                \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x6602e5c8)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x618ede3a)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x70f58a02)                  \
+  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x826f6c8d)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x2761c274)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x1b858d66)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x9e2320c0)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0xfa1f5cf1)              \
+  V(ByteData, ., ByteDataFactory, 0x1a2bee78)                                  \
+  V(_ByteDataView, get:offsetInBytes, ByteDataViewOffsetInBytes, 0x3915c92a)   \
+  V(_ByteDataView, get:_typedData, ByteDataViewTypedData, 0x487f857c)          \
+  V(_TypedListView, get:offsetInBytes, TypedDataViewOffsetInBytes, 0x3915c92a) \
+  V(_TypedListView, get:_typedData, TypedDataViewTypedData, 0x487f857c)        \
+  V(_ByteDataView, ._, TypedData_ByteDataView_factory, 0xbdff93f4)             \
+  V(_Int8ArrayView, ._, TypedData_Int8ArrayView_factory, 0x955093e6)           \
+  V(_Uint8ArrayView, ._, TypedData_Uint8ArrayView_factory, 0x666697bb)         \
   V(_Uint8ClampedArrayView, ._, TypedData_Uint8ClampedArrayView_factory,       \
-    0x36da9706)                                                                \
-  V(_Int16ArrayView, ._, TypedData_Int16ArrayView_factory, 0x09a366f8)         \
-  V(_Uint16ArrayView, ._, TypedData_Uint16ArrayView_factory, 0x8f74c30f)       \
-  V(_Int32ArrayView, ._, TypedData_Int32ArrayView_factory, 0x8c100d16)         \
-  V(_Uint32ArrayView, ._, TypedData_Uint32ArrayView_factory, 0x4f7f073e)       \
-  V(_Int64ArrayView, ._, TypedData_Int64ArrayView_factory, 0xb85546cc)         \
-  V(_Uint64ArrayView, ._, TypedData_Uint64ArrayView_factory, 0x019c229a)       \
-  V(_Float32ArrayView, ._, TypedData_Float32ArrayView_factory, 0x2290e5a1)     \
-  V(_Float64ArrayView, ._, TypedData_Float64ArrayView_factory, 0xbe62c734)     \
-  V(_Float32x4ArrayView, ._, TypedData_Float32x4ArrayView_factory, 0x5bb7771d) \
-  V(_Int32x4ArrayView, ._, TypedData_Int32x4ArrayView_factory, 0x30b9f2a2)     \
-  V(_Float64x2ArrayView, ._, TypedData_Float64x2ArrayView_factory, 0x96490d01) \
-  V(Int8List, ., TypedData_Int8Array_factory, 0x80ad83e1)                      \
-  V(Uint8List, ., TypedData_Uint8Array_factory, 0x252e6768)                    \
-  V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 0x1ed931ee)      \
-  V(Int16List, ., TypedData_Int16Array_factory, 0x7ea8630c)                    \
-  V(Uint16List, ., TypedData_Uint16Array_factory, 0x2764f743)                  \
-  V(Int32List, ., TypedData_Int32Array_factory, 0x54a56479)                    \
-  V(Uint32List, ., TypedData_Uint32Array_factory, 0xac4deaa4)                  \
-  V(Int64List, ., TypedData_Int64Array_factory, 0x02d4c748)                    \
-  V(Uint64List, ., TypedData_Uint64Array_factory, 0x08669751)                  \
-  V(Float32List, ., TypedData_Float32Array_factory, 0x8b65b9d7)                \
-  V(Float64List, ., TypedData_Float64Array_factory, 0x09ede82a)                \
-  V(Float32x4List, ., TypedData_Float32x4Array_factory, 0xb2a9e6e1)            \
-  V(Int32x4List, ., TypedData_Int32x4Array_factory, 0xa5292147)                \
-  V(Float64x2List, ., TypedData_Float64x2Array_factory, 0x20eafb43)            \
-  V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x143ed675)                 \
+    0x0f265d67)                                                                \
+  V(_Int16ArrayView, ._, TypedData_Int16ArrayView_factory, 0x95778bb5)         \
+  V(_Uint16ArrayView, ._, TypedData_Uint16ArrayView_factory, 0xc9d1b27e)       \
+  V(_Int32ArrayView, ._, TypedData_Int32ArrayView_factory, 0x609fa957)         \
+  V(_Uint32ArrayView, ._, TypedData_Uint32ArrayView_factory, 0x0b0ff42f)       \
+  V(_Int64ArrayView, ._, TypedData_Int64ArrayView_factory, 0xbd01a661)         \
+  V(_Uint64ArrayView, ._, TypedData_Uint64ArrayView_factory, 0x9c964453)       \
+  V(_Float32ArrayView, ._, TypedData_Float32ArrayView_factory, 0x9a39e22c)     \
+  V(_Float64ArrayView, ._, TypedData_Float64ArrayView_factory, 0x78a432f9)     \
+  V(_Float32x4ArrayView, ._, TypedData_Float32x4ArrayView_factory, 0x85e58030) \
+  V(_Int32x4ArrayView, ._, TypedData_Int32x4ArrayView_factory, 0x5132754b)     \
+  V(_Float64x2ArrayView, ._, TypedData_Float64x2ArrayView_factory, 0x9d86a6cc) \
+  V(Int8List, ., TypedData_Int8Array_factory, 0x934e97a2)                      \
+  V(Uint8List, ., TypedData_Uint8Array_factory, 0x7eea24fb)                    \
+  V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 0xba98ab35)      \
+  V(Int16List, ., TypedData_Int16Array_factory, 0x54af9dd7)                    \
+  V(Uint16List, ., TypedData_Uint16Array_factory, 0xc3859080)                  \
+  V(Int32List, ., TypedData_Int32Array_factory, 0x3e52ca0a)                    \
+  V(Uint32List, ., TypedData_Uint32Array_factory, 0xdbbb093f)                  \
+  V(Int64List, ., TypedData_Int64Array_factory, 0x560fc11b)                    \
+  V(Uint64List, ., TypedData_Uint64Array_factory, 0x02b7f232)                  \
+  V(Float32List, ., TypedData_Float32Array_factory, 0xdf9d206c)                \
+  V(Float64List, ., TypedData_Float64Array_factory, 0x321abc79)                \
+  V(Float32x4List, ., TypedData_Float32x4Array_factory, 0xa0de94a2)            \
+  V(Int32x4List, ., TypedData_Int32x4Array_factory, 0xfe46a6fc)                \
+  V(Float64x2List, ., TypedData_Float64x2Array_factory, 0xfac00c80)            \
+  V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x84e4b390)                 \
   V(::, copyRangeFromUint8ListToOneByteString,                                 \
-    CopyRangeFromUint8ListToOneByteString, 0x89d6a60a)                         \
-  V(_StringBase, _interpolate, StringBaseInterpolate, 0xd5a58efc)              \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 0x5f8db5f5)             \
-  V(_Double, _add, DoubleAdd, 0x4326962a)                                      \
-  V(_Double, _sub, DoubleSub, 0x81077f31)                                      \
-  V(_Double, _mul, DoubleMul, 0x7858fa6f)                                      \
-  V(_Double, _div, DoubleDiv, 0x813d6a94)                                      \
-  V(::, min, MathMin, 0xe6a2f504)                                              \
-  V(::, max, MathMax, 0x4cfa6f6b)                                              \
-  V(::, _doublePow, MathDoublePow, 0x973546e3)                                 \
-  V(::, _intPow, MathIntPow, 0x5449a6fb)                                       \
-  V(Float32x4, _Float32x4FromDoubles, Float32x4FromDoubles, 0x4ddbf1d0)        \
-  V(Float32x4, Float32x4.zero, Float32x4Zero, 0x730d827d)                      \
-  V(Float32x4, _Float32x4Splat, Float32x4Splat, 0x36ae87e8)                    \
-  V(Float32x4, Float32x4.fromInt32x4Bits, Int32x4ToFloat32x4, 0x8704457d)      \
-  V(Float32x4, Float32x4.fromFloat64x2, Float64x2ToFloat32x4, 0x71ab7a48)      \
-  V(_Float32x4, shuffle, Float32x4Shuffle, 0x6f8cd72e)                         \
-  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 0xd9fe42cf)                   \
-  V(_Float32x4, get:signMask, Float32x4GetSignMask, 0x00b7b96d)                \
-  V(_Float32x4, equal, Float32x4Equal, 0x77b31279)                             \
-  V(_Float32x4, greaterThan, Float32x4GreaterThan, 0x85a5a282)                 \
-  V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, 0x81c686ba)   \
-  V(_Float32x4, lessThan, Float32x4LessThan, 0x7d709620)                       \
-  V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, 0x79cf7843)         \
-  V(_Float32x4, notEqual, Float32x4NotEqual, 0x97a75a46)                       \
-  V(_Float32x4, min, Float32x4Min, 0x0ad96995)                                 \
-  V(_Float32x4, max, Float32x4Max, 0xed08eb66)                                 \
-  V(_Float32x4, scale, Float32x4Scale, 0xfdf348c5)                             \
-  V(_Float32x4, sqrt, Float32x4Sqrt, 0x84853df5)                               \
-  V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, 0x7d66357b)           \
-  V(_Float32x4, reciprocal, Float32x4Reciprocal, 0x73e065b5)                   \
-  V(_Float32x4, unary-, Float32x4Negate, 0x86111def)                           \
-  V(_Float32x4, abs, Float32x4Abs, 0x8ad4c18b)                                 \
-  V(_Float32x4, clamp, Float32x4Clamp, 0x374a9da0)                             \
-  V(_Float32x4, _withX, Float32x4WithX, 0xfd53a072)                            \
-  V(_Float32x4, _withY, Float32x4WithY, 0xf5f5b506)                            \
-  V(_Float32x4, _withZ, Float32x4WithZ, 0xf2122f63)                            \
-  V(_Float32x4, _withW, Float32x4WithW, 0xef6f231e)                            \
-  V(Float64x2, _Float64x2FromDoubles, Float64x2FromDoubles, 0x9688f476)        \
-  V(Float64x2, Float64x2.zero, Float64x2Zero, 0x35f71913)                      \
-  V(Float64x2, _Float64x2Splat, Float64x2Splat, 0xf2e6bce9)                    \
-  V(Float64x2, Float64x2.fromFloat32x4, Float32x4ToFloat64x2, 0xa936b421)      \
-  V(_Float64x2, get:x, Float64x2GetX, 0xd83e5791)                              \
-  V(_Float64x2, get:y, Float64x2GetY, 0xc5cfb2b4)                              \
-  V(_Float64x2, unary-, Float64x2Negate, 0x48fab485)                           \
-  V(_Float64x2, abs, Float64x2Abs, 0x4dbe5821)                                 \
-  V(_Float64x2, sqrt, Float64x2Sqrt, 0x476ed48b)                               \
-  V(_Float64x2, get:signMask, Float64x2GetSignMask, 0x00b7b96d)                \
-  V(_Float64x2, scale, Float64x2Scale, 0xc0dcdf5b)                             \
-  V(_Float64x2, _withX, Float64x2WithX, 0xc03d3708)                            \
-  V(_Float64x2, _withY, Float64x2WithY, 0xb8df4b9c)                            \
-  V(_Float64x2, min, Float64x2Min,  0x6b5e1755)                                \
-  V(_Float64x2, max, Float64x2Max,  0x4d8d9926)                                \
-  V(Int32x4, _Int32x4FromInts, Int32x4FromInts, 0xa646ec55)                    \
-  V(Int32x4, _Int32x4FromBools, Int32x4FromBools, 0x5e05beed)                  \
-  V(Int32x4, Int32x4.fromFloat32x4Bits, Float32x4ToInt32x4, 0x7893999c)        \
-  V(_Int32x4, get:flagX, Int32x4GetFlagX, 0x7713cbb9)                          \
-  V(_Int32x4, get:flagY, Int32x4GetFlagY, 0x92840299)                          \
-  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 0xa02d9dec)                          \
-  V(_Int32x4, get:flagW, Int32x4GetFlagW, 0xa94db02d)                          \
-  V(_Int32x4, get:signMask, Int32x4GetSignMask, 0x00b7b96d)                    \
-  V(_Int32x4, shuffle, Int32x4Shuffle, 0x149a8b16)                             \
-  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 0xd017e89f)                       \
-  V(_Int32x4, select, Int32x4Select, 0x2847cb63)                               \
-  V(_Int32x4, _withFlagX, Int32x4WithFlagX, 0xa365d5a6)                        \
-  V(_Int32x4, _withFlagY, Int32x4WithFlagY, 0x945670e9)                        \
-  V(_Int32x4, _withFlagZ, Int32x4WithFlagZ, 0x938c5d97)                        \
-  V(_Int32x4, _withFlagW, Int32x4WithFlagW, 0x9ebace9b)                        \
-  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0xe161439b)               \
-  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x8c899997)               \
-  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0xb1d039ec)                 \
-  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x7c713c68)                 \
-  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0xcb55342c)         \
-  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x4b6bbba8)         \
-  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0xd35b67db)         \
-  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x5371ef57)         \
-  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0xd55a64df)   \
-  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x5570ec5b)   \
-  V(::, _classRangeCheck, ClassRangeCheck, 0x44ba948a)                         \
-  V(::, _asyncStackTraceHelper, AsyncStackTraceHelper, 0x92cea920)             \
-  V(::, _abi, FfiAbi, 0x00a48dda)                                              \
-  V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x4ea3f661)                \
-  V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0xe7a60ce3)        \
-  V(::, _loadInt8, FfiLoadInt8, 0x7b779ed3)                                    \
-  V(::, _loadInt16, FfiLoadInt16, 0x58b6f02a)                                  \
-  V(::, _loadInt32, FfiLoadInt32, 0x5a94fec0)                                  \
-  V(::, _loadInt64, FfiLoadInt64, 0x4b627ea0)                                  \
-  V(::, _loadUint8, FfiLoadUint8, 0x4dc0dbce)                                  \
-  V(::, _loadUint16, FfiLoadUint16, 0x79491be7)                                \
-  V(::, _loadUint32, FfiLoadUint32, 0x62e14f52)                                \
-  V(::, _loadUint64, FfiLoadUint64, 0x7178bcc9)                                \
-  V(::, _loadIntPtr, FfiLoadIntPtr, 0x584c733b)                                \
-  V(::, _loadFloat, FfiLoadFloat, 0x7f0471da)                                  \
-  V(::, _loadDouble, FfiLoadDouble, 0x7d37b396)                                \
-  V(::, _loadPointer, FfiLoadPointer, 0x3691c04d)                              \
-  V(::, _storeInt8, FfiStoreInt8, 0x118e5bc9)                                  \
-  V(::, _storeInt16, FfiStoreInt16, 0x0a8b9fef)                                \
-  V(::, _storeInt32, FfiStoreInt32, 0x2e23d91a)                                \
-  V(::, _storeInt64, FfiStoreInt64, 0x2411ba37)                                \
-  V(::, _storeUint8, FfiStoreUint8, 0x37ab7fb3)                                \
-  V(::, _storeUint16, FfiStoreUint16, 0x153b579b)                              \
-  V(::, _storeUint32, FfiStoreUint32, 0x18159582)                              \
-  V(::, _storeUint64, FfiStoreUint64, 0x1516def6)                              \
-  V(::, _storeIntPtr, FfiStoreIntPtr, 0x3a401365)                              \
-  V(::, _storeFloat, FfiStoreFloat, 0x23292bbb)                                \
-  V(::, _storeDouble, FfiStoreDouble, 0x013dc7a1)                              \
-  V(::, _storePointer, FfiStorePointer, 0x43c38f62)                            \
-  V(::, _fromAddress, FfiFromAddress, 0xab4ae553)                              \
-  V(Pointer, get:address, FfiGetAddress, 0x012b2b9f)                           \
-  V(::, reachabilityFence, ReachabilityFence, 0xad39d0a6)                      \
-  V(_Utf8Decoder, _scan, Utf8DecoderScan, 0x78f44c3c)                          \
-  V(_Future, timeout, FutureTimeout, 0xdea67258)                               \
-  V(Future, wait, FutureWait, 0x6c0c3295)                                      \
+    CopyRangeFromUint8ListToOneByteString, 0xeb5abaa9)                         \
+  V(_StringBase, _interpolate, StringBaseInterpolate, 0xe8ece5a1)              \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 0x33d887fc)             \
+  V(_Double, _add, DoubleAdd, 0x1ba15967)                                      \
+  V(_Double, _sub, DoubleSub, 0x5982426e)                                      \
+  V(_Double, _mul, DoubleMul, 0x50d3bdac)                                      \
+  V(_Double, _div, DoubleDiv, 0x59b82dd1)                                      \
+  V(::, min, MathMin, 0xa24c3a83)                                              \
+  V(::, max, MathMax, 0x8552d67e)                                              \
+  V(::, _doublePow, MathDoublePow, 0x9441cc3a)                                 \
+  V(::, _intPow, MathIntPow, 0x409dd978)                                       \
+  V(Float32x4, _Float32x4FromDoubles, Float32x4FromDoubles, 0x790497df)        \
+  V(Float32x4, Float32x4.zero, Float32x4Zero, 0x9657735e)                      \
+  V(Float32x4, _Float32x4Splat, Float32x4Splat, 0xb0d7702d)                    \
+  V(Float32x4, Float32x4.fromInt32x4Bits, Int32x4ToFloat32x4, 0xda38dd92)      \
+  V(Float32x4, Float32x4.fromFloat64x2, Float64x2ToFloat32x4, 0xe41a2079)      \
+  V(_Float32x4, shuffle, Float32x4Shuffle, 0xac90c309)                         \
+  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 0x3d6d7e46)                   \
+  V(_Float32x4, get:signMask, Float32x4GetSignMask, 0x54b1e8e8)                \
+  V(_Float32x4, equal, Float32x4Equal, 0xc9591626)                             \
+  V(_Float32x4, greaterThan, Float32x4GreaterThan, 0xd74ba62f)                 \
+  V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, 0xd36c8a67)   \
+  V(_Float32x4, lessThan, Float32x4LessThan, 0xcf1699cd)                       \
+  V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, 0xcb757bf0)         \
+  V(_Float32x4, notEqual, Float32x4NotEqual, 0xe94d5df3)                       \
+  V(_Float32x4, min, Float32x4Min, 0x04e45812)                                 \
+  V(_Float32x4, max, Float32x4Max, 0xe713d9e3)                                 \
+  V(_Float32x4, scale, Float32x4Scale, 0xde622d94)                             \
+  V(_Float32x4, sqrt, Float32x4Sqrt, 0xa7982e0e)                               \
+  V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, 0xa0792594)           \
+  V(_Float32x4, reciprocal, Float32x4Reciprocal, 0x96f355ce)                   \
+  V(_Float32x4, unary-, Float32x4Negate, 0xa94cf76e)                           \
+  V(_Float32x4, abs, Float32x4Abs, 0xade7b1a4)                                 \
+  V(_Float32x4, clamp, Float32x4Clamp, 0x57c0dbb9)                             \
+  V(_Float32x4, _withX, Float32x4WithX, 0xddc28541)                            \
+  V(_Float32x4, _withY, Float32x4WithY, 0xd66499d5)                            \
+  V(_Float32x4, _withZ, Float32x4WithZ, 0xd2811432)                            \
+  V(_Float32x4, _withW, Float32x4WithW, 0xcfde07ed)                            \
+  V(Float64x2, _Float64x2FromDoubles, Float64x2FromDoubles, 0x9f0a0865)        \
+  V(Float64x2, Float64x2.zero, Float64x2Zero, 0x30a0af88)                      \
+  V(Float64x2, _Float64x2Splat, Float64x2Splat, 0xe169544e)                    \
+  V(Float64x2, Float64x2.fromFloat32x4, Float32x4ToFloat64x2, 0x7ad848fa)      \
+  V(_Float64x2, get:x, Float64x2GetX, 0xf36ac93a)                              \
+  V(_Float64x2, get:y, Float64x2GetY, 0xe0fc245d)                              \
+  V(_Float64x2, unary-, Float64x2Negate, 0x43963398)                           \
+  V(_Float64x2, abs, Float64x2Abs, 0x4830edce)                                 \
+  V(_Float64x2, sqrt, Float64x2Sqrt, 0x41e16a38)                               \
+  V(_Float64x2, get:signMask, Float64x2GetSignMask, 0x54b1e8e8)                \
+  V(_Float64x2, scale, Float64x2Scale, 0x78ab69be)                             \
+  V(_Float64x2, _withX, Float64x2WithX, 0x780bc16b)                            \
+  V(_Float64x2, _withY, Float64x2WithY, 0x70add5ff)                            \
+  V(_Float64x2, min, Float64x2Min,  0xb4f56252)                                \
+  V(_Float64x2, max, Float64x2Max,  0x9724e423)                                \
+  V(Int32x4, _Int32x4FromInts, Int32x4FromInts, 0x533214b0)                    \
+  V(Int32x4, _Int32x4FromBools, Int32x4FromBools, 0x17964f48)                  \
+  V(Int32x4, Int32x4.fromFloat32x4Bits, Float32x4ToInt32x4, 0xca709e11)        \
+  V(_Int32x4, get:flagX, Int32x4GetFlagX, 0x998cbdb6)                          \
+  V(_Int32x4, get:flagY, Int32x4GetFlagY, 0xb4fcf496)                          \
+  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 0xc2a68fe9)                          \
+  V(_Int32x4, get:flagW, Int32x4GetFlagW, 0xcbc6a22a)                          \
+  V(_Int32x4, get:signMask, Int32x4GetSignMask, 0x54b1e8e8)                    \
+  V(_Int32x4, shuffle, Int32x4Shuffle, 0xa9398c21)                             \
+  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 0x0a889276)                       \
+  V(_Int32x4, select, Int32x4Select, 0x48be097c)                               \
+  V(_Int32x4, _withFlagX, Int32x4WithFlagX, 0x7f4a63d1)                        \
+  V(_Int32x4, _withFlagY, Int32x4WithFlagY, 0x703aff14)                        \
+  V(_Int32x4, _withFlagZ, Int32x4WithFlagZ, 0x6f70ebc2)                        \
+  V(_Int32x4, _withFlagW, Int32x4WithFlagW, 0x7a9f5cc6)                        \
+  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0xf6b408ce)               \
+  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0xb0967252)               \
+  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0xe81ec483)                 \
+  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x719e1187)                 \
+  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x1f4f6aeb)         \
+  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0xa209d2ef)         \
+  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x27559e9a)         \
+  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0xaa10069e)         \
+  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x29549b9e)   \
+  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0xac0f03a2)   \
+  V(_WeakProperty, get:key, WeakProperty_getKey, 0x16b8624c)                   \
+  V(_WeakProperty, set:key, WeakProperty_setKey, 0x8b5df091)                   \
+  V(_WeakProperty, get:value, WeakProperty_getValue, 0x0baa0898)               \
+  V(_WeakProperty, set:value, WeakProperty_setValue, 0x804f96dd)               \
+  V(::, _classRangeCheck, ClassRangeCheck, 0x071d2ec8)                         \
+  V(::, _abi, FfiAbi, 0x54918e73)                                              \
+  V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x2d4e5e32)                \
+  V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x68db1afc)        \
+  V(::, _loadInt8, FfiLoadInt8, 0x3b38d254)                                    \
+  V(::, _loadInt16, FfiLoadInt16, 0x187823ab)                                  \
+  V(::, _loadInt32, FfiLoadInt32, 0x1a563241)                                  \
+  V(::, _loadInt64, FfiLoadInt64, 0x0b23b221)                                  \
+  V(::, _loadUint8, FfiLoadUint8, 0x0d820f4f)                                  \
+  V(::, _loadUint16, FfiLoadUint16, 0x390a4f68)                                \
+  V(::, _loadUint32, FfiLoadUint32, 0x22a282d3)                                \
+  V(::, _loadUint64, FfiLoadUint64, 0x3139f04a)                                \
+  V(::, _loadIntPtr, FfiLoadIntPtr, 0x180da6bc)                                \
+  V(::, _loadFloat, FfiLoadFloat, 0x05f7e3e7)                                  \
+  V(::, _loadDouble, FfiLoadDouble, 0x042b25a3)                                \
+  V(::, _loadPointer, FfiLoadPointer, 0x117833fa)                              \
+  V(::, _storeInt8, FfiStoreInt8, 0xdaa635d2)                                  \
+  V(::, _storeInt16, FfiStoreInt16, 0xd3a379f8)                                \
+  V(::, _storeInt32, FfiStoreInt32, 0xf73bb323)                                \
+  V(::, _storeInt64, FfiStoreInt64, 0xed299440)                                \
+  V(::, _storeUint8, FfiStoreUint8, 0x00c359bc)                                \
+  V(::, _storeUint16, FfiStoreUint16, 0xde5331a4)                              \
+  V(::, _storeUint32, FfiStoreUint32, 0xe12d6f8b)                              \
+  V(::, _storeUint64, FfiStoreUint64, 0xde2eb8ff)                              \
+  V(::, _storeIntPtr, FfiStoreIntPtr, 0x0357ed6e)                              \
+  V(::, _storeFloat, FfiStoreFloat, 0xafddd150)                                \
+  V(::, _storeDouble, FfiStoreDouble, 0x8df26d36)                              \
+  V(::, _storePointer, FfiStorePointer, 0xf3b14e97)                            \
+  V(::, _fromAddress, FfiFromAddress, 0x811e2220)                              \
+  V(Pointer, get:address, FfiGetAddress, 0x55255ebc)                           \
+  V(::, reachabilityFence, ReachabilityFence, 0xde1dc5bd)                      \
+  V(_Utf8Decoder, _scan, Utf8DecoderScan, 0xb35ced99)                          \
+  V(_Future, timeout, FutureTimeout, 0x6ad7d1ef)                               \
+  V(Future, wait, FutureWait, 0xb4396ca1)                                      \
 
 // List of intrinsics:
 // (class-name, function-name, intrinsification method, fingerprint).
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 0x068652b8)                                        \
-  V(_Smi, get:bitLength, Smi_bitLength, 0xff01b0cc)                            \
-  V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, 0xa483e093)                       \
-  V(_BigIntImpl, _lsh, Bigint_lsh, 0x772fb5fd)                                 \
-  V(_BigIntImpl, _rsh, Bigint_rsh, 0xb52a24b8)                                 \
-  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x90dc61a8)                           \
-  V(_BigIntImpl, _absSub, Bigint_absSub, 0x76887330)                           \
-  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0xb2741296)                           \
-  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0xcee0facc)                           \
+  V(_Smi, ~, Smi_bitNegate, 0x5a9bcc19)                                        \
+  V(_Smi, get:bitLength, Smi_bitLength, 0x52fbe3e9)                            \
+  V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, 0x7818c386)                       \
+  V(_BigIntImpl, _lsh, Bigint_lsh, 0xb7f65896)                                 \
+  V(_BigIntImpl, _rsh, Bigint_rsh, 0x3922f42b)                                 \
+  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x295e93f3)                           \
+  V(_BigIntImpl, _absSub, Bigint_absSub, 0x273f7af1)                           \
+  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0xba45f6ad)                           \
+  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x2db11c6b)                           \
   V(_BigIntImpl, _estimateQuotientDigit, Bigint_estimateQuotientDigit,         \
-    0x14527ed9)                                                                \
-  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x08df2795)        \
-  V(_Double, >, Double_greaterThan, 0xe88b6ffc)                                \
-  V(_Double, >=, Double_greaterEqualThan, 0x1fb70bae)                          \
-  V(_Double, <, Double_lessThan, 0xae875025)                                   \
-  V(_Double, <=, Double_lessEqualThan, 0xc87a5050)                             \
-  V(_Double, ==, Double_equal, 0x5299f1d2)                                     \
-  V(_Double, +, Double_add, 0x783a47d4)                                        \
-  V(_Double, -, Double_sub, 0x493f1465)                                        \
-  V(_Double, *, Double_mul, 0xae0df2e2)                                        \
-  V(_Double, /, Double_div, 0xed535dde)                                        \
-  V(_Double, get:hashCode, Double_hashCode, 0xfa2d7816)                        \
-  V(_Double, get:_identityHashCode, Double_identityHash, 0xcbf20cd4)           \
-  V(_Double, get:isNaN, Double_getIsNaN, 0x88fdcef4)                           \
-  V(_Double, get:isInfinite, Double_getIsInfinite, 0x796f93b3)                 \
-  V(_Double, get:isNegative, Double_getIsNegative, 0x88e61872)                 \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 0xc5afaa28)               \
-  V(_Double, .fromInteger, DoubleFromInteger, 0x9d1ad7f6)                      \
-  V(_GrowableList, ._withData, GrowableArray_Allocate, 0x00be5928)             \
-  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0x6817556e)                   \
-  V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0x60e30834)       \
-  V(Object, ==, ObjectEquals, 0xbc3cad49)                                      \
-  V(Object, get:runtimeType, ObjectRuntimeType, 0x6461c691)                    \
-  V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, 0xa66bfc58)       \
-  V(_StringBase, get:hashCode, String_getHashCode, 0xfa2d7835)                 \
-  V(_StringBase, get:_identityHashCode, String_identityHash, 0xcbf20cf3)       \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 0xbdfe9c92)                   \
-  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 0xf5c3c873)    \
-  V(_StringBase, [], StringBaseCharAt, 0xfa3bf7be)                             \
-  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 0xfa2d7835)       \
+    0x3c62c74c)                                                                \
+  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x091127d0)        \
+  V(_Double, >, Double_greaterThan, 0xc4a96c0f)                                \
+  V(_Double, >=, Double_greaterEqualThan, 0x335a31b3)                          \
+  V(_Double, <, Double_lessThan, 0x059b1fd8)                                   \
+  V(_Double, <=, Double_lessEqualThan, 0xeb04cf95)                             \
+  V(_Double, ==, Double_equal, 0x094145f1)                                     \
+  V(_Double, +, Double_add, 0x74e922bb)                                        \
+  V(_Double, -, Double_sub, 0x67d62f0c)                                        \
+  V(_Double, *, Double_mul, 0xa95d3909)                                        \
+  V(_Double, /, Double_div, 0x9f8bc745)                                        \
+  V(_Double, get:hashCode, Double_hashCode, 0x4e27a791)                        \
+  V(_Double, get:_identityHashCode, Double_identityHash, 0x1fec3c4f)           \
+  V(_Double, get:isNaN, Double_getIsNaN, 0xab76c0f1)                           \
+  V(_Double, get:isInfinite, Double_getIsInfinite, 0x9be885b0)                 \
+  V(_Double, get:isNegative, Double_getIsNegative, 0xab5f0a6f)                 \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 0x88ace077)               \
+  V(_Double, .fromInteger, DoubleFromInteger, 0x0f908a15)                      \
+  V(_GrowableList, ._withData, GrowableArray_Allocate, 0x1947d8a1)             \
+  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0xd8114d5f)                   \
+  V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0xd0dd0025)       \
+  V(Object, ==, ObjectEquals, 0xd3f5f95a)                                      \
+  V(Object, get:runtimeType, ObjectRuntimeType, 0x8177627e)                    \
+  V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, 0xe61da79f)       \
+  V(_StringBase, get:hashCode, String_getHashCode, 0x4e27ab52)                 \
+  V(_StringBase, get:_identityHashCode, String_identityHash, 0x1fec4010)       \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 0xfda61c55)                   \
+  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 0xf07e5912)    \
+  V(_StringBase, [], StringBaseCharAt, 0x6c55f9a1)                             \
+  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 0x4e27ab52)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
-    OneByteString_substringUnchecked,  0x0d39e4a1)                             \
-  V(_OneByteString, ==, OneByteString_equality, 0x3399ded1)                    \
-  V(_TwoByteString, ==, TwoByteString_equality, 0x3399ded1)                    \
-  V(_Type, get:hashCode, Type_getHashCode, 0xfa2d7835)                         \
-  V(_Type, ==, Type_equality, 0xbc3cad0b)                                      \
-  V(::, _getHash, Object_getHash, 0x87e0c73d)                                  \
-  V(::, _setHash, Object_setHash, 0xcb4f51d2)                                  \
+    OneByteString_substringUnchecked,  0xd81afdbe)                             \
+  V(_OneByteString, ==, OneByteString_equality, 0x483ef8d2)                    \
+  V(_TwoByteString, ==, TwoByteString_equality, 0x483ef8d2)                    \
+  V(_Type, get:hashCode, Type_getHashCode, 0x4e27ab52)                         \
+  V(_Type, ==, Type_equality, 0xd3f5f1d8)                                      \
+  V(::, _getHash, Object_getHash, 0x1d1372ac)                                  \
+  V(::, _setHash, Object_setHash, 0x77e0bb27)                                  \
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
-    0xdb88076e)                                                                \
-  V(_IntegerImplementation, +, Integer_add, 0x9b2718c0)                        \
+    0x4965932b)                                                                \
+  V(_IntegerImplementation, +, Integer_add, 0xaf966f4f)                        \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
-    0xa1d87562)                                                                \
-  V(_IntegerImplementation, -, Integer_sub, 0x6c350eb1)                        \
+    0x0fb6011f)                                                                \
+  V(_IntegerImplementation, -, Integer_sub, 0xa39f7e40)                        \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
-    0xa93fad01)                                                                \
-  V(_IntegerImplementation, *, Integer_mul, 0x4197ce8e)                        \
+    0x171d38be)                                                                \
+  V(_IntegerImplementation, *, Integer_mul, 0x870ed2dd)                        \
   V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
-    0xd040918e)                                                                \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 0x79adb402)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 0xf07a7709)                \
+    0x3e1e1d4b)                                                                \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 0xaade713f)               \
+  V(_IntegerImplementation, unary-, Integer_negate, 0x8c0ec194)                \
   V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger,     \
-    0xcbb1b792)                                                                \
-  V(_IntegerImplementation, &, Integer_bitAnd, 0x2b385f64)                     \
+    0x398f434f)                                                                \
+  V(_IntegerImplementation, &, Integer_bitAnd, 0xd8a76af3)                     \
   V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger,       \
-    0xbd3f946a)                                                                \
-  V(_IntegerImplementation, |, Integer_bitOr, 0x19dc9b1c)                      \
+    0x2b1d2027)                                                                \
+  V(_IntegerImplementation, |, Integer_bitOr, 0xdc51e4ab)                      \
   V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger,     \
-    0xae7f642e)                                                                \
-  V(_IntegerImplementation, ^, Integer_bitXor, 0x139d6723)                     \
+    0x1c5cefeb)                                                                \
+  V(_IntegerImplementation, ^, Integer_bitXor, 0x2542adb2)                     \
   V(_IntegerImplementation, _greaterThanFromInteger,                           \
-    Integer_greaterThanFromInt, 0x47319226)                                    \
-  V(_IntegerImplementation, >, Integer_greaterThan, 0xc9d374cc)                \
-  V(_IntegerImplementation, ==, Integer_equal, 0xca4e7087)                     \
+    Integer_greaterThanFromInt, 0x838ddcc3)                                    \
+  V(_IntegerImplementation, >, Integer_greaterThan, 0x0c62013f)                \
+  V(_IntegerImplementation, ==, Integer_equal, 0x881c9ddc)                     \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
-    0x4d9e5fc5)                                                                \
-  V(_IntegerImplementation, <, Integer_lessThan, 0xae875025)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0xc87a5050)             \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x1fb70bae)          \
-  V(_IntegerImplementation, <<, Integer_shl, 0xe8da5296)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 0x4fb2013b)                       \
-  V(_Double, toInt, DoubleToInteger, 0xebc963eb)                               \
+    0x89faaa62)                                                                \
+  V(_IntegerImplementation, <, Integer_lessThan, 0x059b1fd8)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0xeb04cf95)             \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x335a31b3)          \
+  V(_IntegerImplementation, <<, Integer_shl, 0xc378efa5)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 0xe029aa4a)                       \
+  V(_Double, toInt, DoubleToInteger, 0x3fb5f3e6)                               \
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
-  V(::, sqrt, MathSqrt, 0x98d7cb39)                                            \
-  V(_Random, _nextState, Random_nextState, 0x3077323d)                         \
+  V(::, sqrt, MathSqrt, 0x1d97494a)                                            \
+  V(_Random, _nextState, Random_nextState, 0x7e5ba345)                         \
 
 #define GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                       \
-  V(::, sin, MathSin, 0x859e6680)                                              \
-  V(::, cos, MathCos, 0xd2dae38e)                                              \
-  V(::, tan, MathTan, 0xa23c1122)                                              \
-  V(::, asin, MathAsin, 0x1cdb139f)                                            \
-  V(::, acos, MathAcos, 0x830d84ba)                                            \
-  V(::, atan, MathAtan, 0x35d5ecd7)                                            \
-  V(::, atan2, MathAtan2, 0xb4e03ae8)                                          \
+  V(::, sin, MathSin, 0xb89b1cb1)                                              \
+  V(::, cos, MathCos, 0x82a25065)                                              \
+  V(::, tan, MathTan, 0x65b9839b)                                              \
+  V(::, asin, MathAsin, 0x7e24237c)                                            \
+  V(::, acos, MathAcos, 0xc484d233)                                            \
+  V(::, atan, MathAtan, 0xb6c154e6)                                            \
+  V(::, atan2, MathAtan2, 0x8e6e8a7b)                                          \
 
 #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
-  V(_Int8List, [], Int8ArrayGetIndexed, 0xd61e79bd)                            \
-  V(_Int8List, []=, Int8ArraySetIndexed, 0x6e0b2e72)                           \
-  V(_Uint8List, [], Uint8ArrayGetIndexed, 0xe1a67dfd)                          \
-  V(_Uint8List, []=, Uint8ArraySetIndexed, 0x89499a2e)                         \
-  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0xe1a67dfd)         \
-  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0x89499a2e)        \
-  V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0xe1a67dfd)            \
-  V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x5facb08e)           \
+  V(_Int8List, [], Int8ArrayGetIndexed, 0x0cc3b782)                            \
+  V(_Int8List, []=, Int8ArraySetIndexed, 0xbbb0b00b)                           \
+  V(_Uint8List, [], Uint8ArrayGetIndexed, 0x723c3b42)                          \
+  V(_Uint8List, []=, Uint8ArraySetIndexed, 0x083fbbcf)                         \
+  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0x723c3b42)         \
+  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0x083fbbcf)        \
+  V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0x723c3b42)            \
+  V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0xfe3f716f)           \
   V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
-    0xe1a67dfd)                                                                \
+    0x723c3b42)                                                                \
   V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
-    0x5facb08e)                                                                \
-  V(_Int16List, [], Int16ArrayGetIndexed, 0x1726ae5d)                          \
-  V(_Int16List, []=, Int16ArraySetIndexed, 0xde0f4d87)                         \
-  V(_Uint16List, [], Uint16ArrayGetIndexed, 0x26c2525d)                        \
-  V(_Uint16List, []=, Uint16ArraySetIndexed, 0x69ae5b30)                       \
-  V(_Int32List, [], Int32ArrayGetIndexed, 0x407e58de)                          \
-  V(_Int32List, []=, Int32ArraySetIndexed, 0x61194108)                         \
-  V(_Uint32List, [], Uint32ArrayGetIndexed, 0xf078bf3e)                        \
-  V(_Uint32List, []=, Uint32ArraySetIndexed, 0x70f53c88)                       \
-  V(_Int64List, [], Int64ArrayGetIndexed, 0x7c21b69e)                          \
-  V(_Int64List, []=, Int64ArraySetIndexed, 0xcaa7c6ca)                         \
-  V(_Uint64List, [], Uint64ArrayGetIndexed, 0x0a7aa11e)                        \
-  V(_Uint64List, []=, Uint64ArraySetIndexed, 0xd1374e92)                       \
-  V(_Float64List, [], Float64ArrayGetIndexed, 0x9e4b2403)                      \
-  V(_Float64List, []=, Float64ArraySetIndexed, 0x0a43d538)                     \
-  V(_Float32List, [], Float32ArrayGetIndexed, 0xbdf87ee3)                      \
-  V(_Float32List, []=, Float32ArraySetIndexed, 0x2e3e1a4a)                     \
-  V(_Float32x4List, [], Float32x4ArrayGetIndexed, 0xa90520bc)                  \
-  V(_Float32x4List, []=, Float32x4ArraySetIndexed, 0xb9c7400f)                 \
-  V(_Int32x4List, [], Int32x4ArrayGetIndexed, 0xfbcc0e74)                      \
-  V(_Int32x4List, []=, Int32x4ArraySetIndexed, 0x79152aaf)                     \
-  V(_Float64x2List, [], Float64x2ArrayGetIndexed, 0xd90a31e6)                  \
-  V(_Float64x2List, []=, Float64x2ArraySetIndexed, 0x4fd191fb)                 \
-  V(_TypedList, get:length, TypedListLength, 0xdc9d90aa)                       \
-  V(_TypedListView, get:length, TypedListViewLength, 0xdc9d90aa)               \
-  V(_ByteDataView, get:length, ByteDataViewLength, 0xdc9d90aa)                 \
-  V(_Float32x4, get:x, Float32x4ShuffleX, 0xd83e5791)                          \
-  V(_Float32x4, get:y, Float32x4ShuffleY, 0xc5cfb2b4)                          \
-  V(_Float32x4, get:z, Float32x4ShuffleZ, 0xfb9b1e4a)                          \
-  V(_Float32x4, get:w, Float32x4ShuffleW, 0xdddb62cc)                          \
-  V(_Float32x4, *, Float32x4Mul, 0x0be25e24)                                   \
-  V(_Float32x4, /, Float32x4Div, 0xe73114a1)                                   \
-  V(_Float32x4, -, Float32x4Sub, 0x03c44de7)                                   \
-  V(_Float32x4, +, Float32x4Add, 0xde8b8376)                                   \
-  V(_Float64x2, *, Float64x2Mul, 0x6c670bc5)                                   \
-  V(_Float64x2, /, Float64x2Div, 0x47b5c261)                                   \
-  V(_Float64x2, -, Float64x2Sub, 0x6448fb88)                                   \
-  V(_Float64x2, +, Float64x2Add, 0x3f103117)                                   \
+    0xfe3f716f)                                                                \
+  V(_Int16List, [], Int16ArrayGetIndexed, 0xecc216e2)                          \
+  V(_Int16List, []=, Int16ArraySetIndexed, 0x4c307396)                         \
+  V(_Uint16List, [], Uint16ArrayGetIndexed, 0xd09af2e2)                        \
+  V(_Uint16List, []=, Uint16ArraySetIndexed, 0x34731b0d)                       \
+  V(_Int32List, [], Int32ArrayGetIndexed, 0xee5fbc81)                          \
+  V(_Int32List, []=, Int32ArraySetIndexed, 0x2a64f035)                         \
+  V(_Uint32List, [], Uint32ArrayGetIndexed, 0x3db22221)                        \
+  V(_Uint32List, []=, Uint32ArraySetIndexed, 0x160864b5)                       \
+  V(_Int64List, [], Int64ArrayGetIndexed, 0x272816c1)                          \
+  V(_Int64List, []=, Int64ArraySetIndexed, 0x53c7e8d3)                         \
+  V(_Uint64List, [], Uint64ArrayGetIndexed, 0x63ec7c41)                        \
+  V(_Uint64List, []=, Uint64ArraySetIndexed, 0x1f295a0b)                       \
+  V(_Float64List, [], Float64ArrayGetIndexed, 0x4a2c55fc)                      \
+  V(_Float64List, []=, Float64ArraySetIndexed, 0x07ada825)                     \
+  V(_Float32List, [], Float32ArrayGetIndexed, 0x202a571c)                      \
+  V(_Float32List, []=, Float32ArraySetIndexed, 0x62fc0553)                     \
+  V(_Float32x4List, [], Float32x4ArrayGetIndexed, 0x96b1f063)                  \
+  V(_Float32x4List, []=, Float32x4ArraySetIndexed, 0x4897982e)                 \
+  V(_Int32x4List, [], Int32x4ArrayGetIndexed, 0x9cc8b9ab)                      \
+  V(_Int32x4List, []=, Int32x4ArraySetIndexed, 0x7307018e)                     \
+  V(_Float64x2List, [], Float64x2ArrayGetIndexed, 0x674f0479)                  \
+  V(_Float64x2List, []=, Float64x2ArraySetIndexed, 0x73d783c2)                 \
+  V(_TypedList, get:length, TypedListLength, 0x3097c769)                       \
+  V(_TypedListView, get:length, TypedListViewLength, 0x3097c769)               \
+  V(_ByteDataView, get:length, ByteDataViewLength, 0x3097c769)                 \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 0xf36ac93a)                          \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 0xe0fc245d)                          \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 0x16c78ff3)                          \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 0xf907d475)                          \
+  V(_Float32x4, *, Float32x4Mul, 0x06163607)                                   \
+  V(_Float32x4, /, Float32x4Div, 0xe164e8e2)                                   \
+  V(_Float32x4, -, Float32x4Sub, 0xfdf825ca)                                   \
+  V(_Float32x4, +, Float32x4Add, 0xd8bf5b59)                                   \
+  V(_Float64x2, *, Float64x2Mul, 0xb6273c86)                                   \
+  V(_Float64x2, /, Float64x2Div, 0x9175f322)                                   \
+  V(_Float64x2, -, Float64x2Sub, 0xae092c49)                                   \
+  V(_Float64x2, +, Float64x2Add, 0x88d061d8)                                   \
 
 #define GRAPH_CORE_INTRINSICS_LIST(V)                                          \
-  V(_List, get:length, ObjectArrayLength, 0xdc9d90aa)                          \
-  V(_List, [], ObjectArrayGetIndexed, 0xd159dece)                              \
-  V(_List, _setIndexed, ObjectArraySetIndexedUnchecked, 0xf5780f43)            \
-  V(_ImmutableList, get:length, ImmutableArrayLength, 0xdc9d90aa)              \
-  V(_ImmutableList, [], ImmutableArrayGetIndexed, 0xd159dece)                  \
-  V(_GrowableList, get:length, GrowableArrayLength, 0xdc9d90aa)                \
-  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x01ec3c31)           \
-  V(_GrowableList, _setData, GrowableArraySetData, 0x8ecf0a40)                 \
-  V(_GrowableList, _setLength, GrowableArraySetLength, 0x63da779b)             \
-  V(_GrowableList, [], GrowableArrayGetIndexed, 0xd159dece)                    \
-  V(_GrowableList, _setIndexed, GrowableArraySetIndexedUnchecked, 0x012e9e24)  \
-  V(_StringBase, get:length, StringBaseLength, 0xdc9d90aa)                     \
-  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 0xc4602c13)           \
-  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 0xc4602c13)           \
+  V(_List, get:length, ObjectArrayLength, 0x3097c769)                          \
+  V(_List, [], ObjectArrayGetIndexed, 0x78f4f491)                              \
+  V(_List, _setIndexed, ObjectArraySetIndexedUnchecked, 0xf233cfd8)            \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 0x3097c769)              \
+  V(_ImmutableList, [], ImmutableArrayGetIndexed, 0x78f4f491)                  \
+  V(_GrowableList, get:length, GrowableArrayLength, 0x3097c769)                \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x55e672f0)           \
+  V(_GrowableList, _setData, GrowableArraySetData, 0x9388253f)                 \
+  V(_GrowableList, _setLength, GrowableArraySetLength, 0xba5d44fc)             \
+  V(_GrowableList, [], GrowableArrayGetIndexed, 0x78f4f491)                    \
+  V(_GrowableList, _setIndexed, GrowableArraySetIndexedUnchecked, 0x5d4f1d17)  \
+  V(_StringBase, get:length, StringBaseLength, 0x3097c769)                     \
+  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 0x323db7d0)           \
+  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 0x323db7d0)           \
   V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt,       \
-    0xc4602c13)                                                                \
+    0x323db7d0)                                                                \
   V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt,       \
-    0xc4602c13)                                                                \
-  V(_Double, unary-, DoubleFlipSignBit, 0xdb229448)                            \
-  V(_Double, truncateToDouble, DoubleTruncate, 0x00e6f81b)                     \
-  V(_Double, roundToDouble, DoubleRound, 0xf45c3bc2)                           \
-  V(_Double, floorToDouble, DoubleFloor, 0xf2c73d0a)                           \
-  V(_Double, ceilToDouble, DoubleCeil, 0xfd2e409b)                             \
-  V(_Double, _modulo, DoubleMod, 0x5673c731)
+    0x323db7d0)                                                                \
+  V(_Double, unary-, DoubleFlipSignBit, 0xf66a4c35)                            \
+  V(_Double, truncateToDouble, DoubleTruncate, 0x1c05c6a2)                     \
+  V(_Double, roundToDouble, DoubleRound, 0x0f7b0a49)                           \
+  V(_Double, floorToDouble, DoubleFloor, 0x0de60b91)                           \
+  V(_Double, ceilToDouble, DoubleCeil, 0x184d0f22)                             \
+  V(_Double, _modulo, DoubleMod, 0x2eee8a6e)
 
 #define GRAPH_INTRINSICS_LIST(V)                                               \
   GRAPH_CORE_INTRINSICS_LIST(V)                                                \
@@ -378,23 +381,18 @@
   GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                             \
 
 #define DEVELOPER_LIB_INTRINSIC_LIST(V)                                        \
-  V(_UserTag, makeCurrent, UserTag_makeCurrent, 0x1eb344b3)                    \
-  V(::, _getDefaultTag, UserTag_defaultTag, 0x2ef2e42c)                        \
-  V(::, _getCurrentTag, Profiler_getCurrentTag, 0x33c3ec15)                    \
-  V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 0x7dfcaa18)        \
-
-#define ASYNC_LIB_INTRINSIC_LIST(V)                                            \
-  V(::, _clearAsyncThreadStackTrace, ClearAsyncThreadStackTrace, 0x20fecac6)   \
-  V(::, _setAsyncThreadStackTrace, SetAsyncThreadStackTrace, 0x39346953)       \
+  V(_UserTag, makeCurrent, UserTag_makeCurrent, 0xc0abd700)                    \
+  V(::, _getDefaultTag, UserTag_defaultTag, 0xd0ebe717)                        \
+  V(::, _getCurrentTag, Profiler_getCurrentTag, 0xd5bcef00)                    \
+  V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 0xa0686991)        \
 
 #define INTERNAL_LIB_INTRINSIC_LIST(V)                                         \
-  V(::, allocateOneByteString, AllocateOneByteString, 0xc86bebfa)              \
-  V(::, allocateTwoByteString, AllocateTwoByteString, 0xd0312797)              \
-  V(::, writeIntoOneByteString, WriteIntoOneByteString, 0xe0d28307)            \
-  V(::, writeIntoTwoByteString, WriteIntoTwoByteString, 0xd82789d0)            \
+  V(::, allocateOneByteString, AllocateOneByteString, 0x3a5d74f6)              \
+  V(::, allocateTwoByteString, AllocateTwoByteString, 0x4222b093)              \
+  V(::, writeIntoOneByteString, WriteIntoOneByteString, 0xa2337709)            \
+  V(::, writeIntoTwoByteString, WriteIntoTwoByteString, 0x99887dd2)            \
 
 #define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
-  ASYNC_LIB_INTRINSIC_LIST(V)                                                  \
   CORE_LIB_INTRINSIC_LIST(V)                                                   \
   DEVELOPER_LIB_INTRINSIC_LIST(V)                                              \
   INTERNAL_LIB_INTRINSIC_LIST(V)                                               \
@@ -411,64 +409,64 @@
 
 // A list of core functions that internally dispatch based on received id.
 #define POLYMORPHIC_TARGET_LIST(V)                                             \
-  V(_StringBase, [], StringBaseCharAt, 0xfa3bf7be)                             \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0xc28aff37)                    \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0xc3e7212d)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0xdaa7b952)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0xdc2919bc)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0xc57f53af)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0xc5c49520)                \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0xa2c7e6a4)                  \
-  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0xd8c29ffe)                \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0xaf15f28a)              \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0xbe4987b7)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x76c82c28)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x29abed4e)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0xfc13ad87)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0xc9e4212d)                   \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0xd570aa0c)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0xe8acb234)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0xd8651525)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0xd3f10d97)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0xe357b95f)                  \
-  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0xf4d19bea)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0xd6272645)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0xca4af137)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x71767f7f)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0xf0483280)              \
-  V(Object, get:runtimeType, ObjectRuntimeType, 0x6461c691)
+  V(_StringBase, [], StringBaseCharAt, 0x6c55f9a1)                             \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x30688af4)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x31c4acea)                  \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x4885450f)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x4a06a579)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x335cdbca)                  \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x33a21d3b)                \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x10a56ebf)                  \
+  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x46a02819)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0xe425bcd3)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0xf3595200)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0xb3cc1803)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0xbe4aee59)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x89b17e2a)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x5781f1d0)                   \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x630e7aaf)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x764a82d7)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x6602e5c8)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x618ede3a)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x70f58a02)                  \
+  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x826f6c8d)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x2761c274)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x1b858d66)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x9e2320c0)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0xfa1f5cf1)              \
+  V(Object, get:runtimeType, ObjectRuntimeType, 0x8177627e)
 
 // List of recognized list factories:
 // (factory-name-symbol, class-name-string, constructor-name-string,
 //  result-cid, fingerprint).
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, _List, ., kArrayCid, 0x6de199a1)                             \
-  V(_ListFilledFactory, _List, .filled, kArrayCid, 0x871c7eb6)                 \
-  V(_ListGenerateFactory, _List, .generate, kArrayCid, 0x045b9063)             \
+  V(_ListFactory, _List, ., kArrayCid, 0x4c9d39e2)                             \
+  V(_ListFilledFactory, _List, .filled, kArrayCid, 0xaf758106)                 \
+  V(_ListGenerateFactory, _List, .generate, kArrayCid, 0xff53e115)             \
   V(_GrowableListFactory, _GrowableList, ., kGrowableObjectArrayCid,           \
-    0xdc1f9e09)                                                                \
+    0xa61fbeb9)                                                                \
   V(_GrowableListFilledFactory, _GrowableList, .filled,                        \
-    kGrowableObjectArrayCid, 0xbc894d36)                                       \
+    kGrowableObjectArrayCid, 0x27a28286)                                       \
   V(_GrowableListGenerateFactory, _GrowableList, .generate,                    \
-    kGrowableObjectArrayCid, 0xf6fbbee3)                                       \
+    kGrowableObjectArrayCid, 0x60b98295)                                       \
   V(_GrowableListWithData, _GrowableList, ._withData, kGrowableObjectArrayCid, \
-    0x00be5928)                                                                \
-  V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x80ad83e1)        \
-  V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x252e6768)     \
+    0x1947d8a1)                                                                \
+  V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x934e97a2)        \
+  V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x7eea24fb)     \
   V(_Uint8ClampedArrayFactory, Uint8ClampedList, .,                            \
-    kTypedDataUint8ClampedArrayCid, 0x1ed931ee)                                \
-  V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x7ea8630c)     \
-  V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0x2764f743)  \
-  V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x54a56479)     \
-  V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0xac4deaa4)  \
-  V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0x02d4c748)     \
-  V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0x08669751)  \
+    kTypedDataUint8ClampedArrayCid, 0xba98ab35)                                \
+  V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x54af9dd7)     \
+  V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0xc3859080)  \
+  V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x3e52ca0a)     \
+  V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0xdbbb093f)  \
+  V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0x560fc11b)     \
+  V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0x02b7f232)  \
   V(_Float64ArrayFactory, Float64List, ., kTypedDataFloat64ArrayCid,           \
-    0x09ede82a)                                                                \
+    0x321abc79)                                                                \
   V(_Float32ArrayFactory, Float32List, ., kTypedDataFloat32ArrayCid,           \
-    0x8b65b9d7)                                                                \
+    0xdf9d206c)                                                                \
   V(_Float32x4ArrayFactory, Float32x4List, ., kTypedDataFloat32x4ArrayCid,     \
-    0xb2a9e6e1)
+    0xa0de94a2)
 
 // clang-format on
 
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 24bfa59..739f168 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -252,12 +252,12 @@
   return dart::StubCode::AllocateArray();
 }
 
-const Code& StubCodeSubtype2TestCache() {
-  return dart::StubCode::Subtype2TestCache();
+const Code& StubCodeSubtype3TestCache() {
+  return dart::StubCode::Subtype3TestCache();
 }
 
-const Code& StubCodeSubtype6TestCache() {
-  return dart::StubCode::Subtype6TestCache();
+const Code& StubCodeSubtype7TestCache() {
+  return dart::StubCode::Subtype7TestCache();
 }
 
 #define DEFINE_ALIAS(name)                                                     \
@@ -298,7 +298,7 @@
       TranslateOffsetInWordsToHost(instance_size));
 }
 
-uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
+uword MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
   return dart::ObjectLayout::SizeTag::encode(
              TranslateOffsetInWordsToHost(instance_size)) |
          dart::ObjectLayout::ClassIdTag::encode(cid) |
@@ -326,6 +326,10 @@
 
 const word ObjectLayout::kClassIdTagSize = dart::ObjectLayout::kClassIdTagSize;
 
+const word ObjectLayout::kHashTagPos = dart::ObjectLayout::kHashTagPos;
+
+const word ObjectLayout::kHashTagSize = dart::ObjectLayout::kHashTagSize;
+
 const word ObjectLayout::kSizeTagMaxSizeTag =
     dart::ObjectLayout::SizeTag::kMaxSizeTagInUnitsOfAlignment *
     ObjectAlignment::kObjectAlignment;
@@ -380,6 +384,8 @@
       return LinkedHashMap::InstanceSize();
     case kUnhandledExceptionCid:
       return UnhandledException::InstanceSize();
+    case kWeakPropertyCid:
+      return WeakProperty::InstanceSize();
     case kByteBufferCid:
     case kByteDataViewCid:
     case kFfiPointerCid:
@@ -978,10 +984,6 @@
   return -kWordSize;
 }
 
-word RedirectionData::NextFieldOffset() {
-  return -kWordSize;
-}
-
 word FfiTrampolineData::NextFieldOffset() {
   return -kWordSize;
 }
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 7611669..cb104ad 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -206,8 +206,8 @@
                                          intptr_t);
 
 const Code& StubCodeAllocateArray();
-const Code& StubCodeSubtype2TestCache();
-const Code& StubCodeSubtype6TestCache();
+const Code& StubCodeSubtype3TestCache();
+const Code& StubCodeSubtype7TestCache();
 
 class RuntimeEntry : public ValueObject {
  public:
@@ -288,8 +288,10 @@
 static constexpr int kWordSize = 1 << kWordSizeLog2;
 static_assert(kWordSize == sizeof(word), "kWordSize should match sizeof(word)");
 // Our compiler code currently assumes this, so formally check it.
+#if !defined(FFI_UNIT_TESTS)
 static_assert(dart::kWordSize >= kWordSize,
               "Host word size smaller than target word size");
+#endif
 
 static constexpr word kBitsPerWordLog2 = kWordSizeLog2 + kBitsPerByteLog2;
 static constexpr word kBitsPerWord = 1 << kBitsPerWordLog2;
@@ -352,7 +354,7 @@
 // size.
 //
 // Note: even on 64-bit platforms we only use lower 32-bits of the tag word.
-uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size);
+uword MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size);
 
 //
 // Target specific information about objects.
@@ -413,6 +415,8 @@
   static const word kSizeTagSize;
   static const word kClassIdTagPos;
   static const word kClassIdTagSize;
+  static const word kHashTagPos;
+  static const word kHashTagSize;
   static const word kSizeTagMaxSizeTag;
   static const word kTagBitsSizeTagPos;
   static const word kBarrierOverlapShift;
@@ -772,12 +776,6 @@
   static word NextFieldOffset();
 };
 
-class RedirectionData : public AllStatic {
- public:
-  static word InstanceSize();
-  static word NextFieldOffset();
-};
-
 class FfiTrampolineData : public AllStatic {
  public:
   static word InstanceSize();
@@ -897,6 +895,7 @@
   static word NextFieldOffset();
   static word parameterized_class_id_offset();
   static word index_offset();
+  static word nullability_offset();
 };
 
 class LibraryPrefix : public AllStatic {
@@ -949,6 +948,8 @@
 
 class WeakProperty : public AllStatic {
  public:
+  static word key_offset();
+  static word value_offset();
   static word InstanceSize();
   static word NextFieldOffset();
 };
@@ -991,7 +992,6 @@
   static uword exit_through_runtime_call();
   static uword exit_through_ffi();
   static word dart_stream_offset();
-  static word async_stack_trace_offset();
   static word predefined_symbols_address_offset();
   static word optimize_entry_offset();
   static word deoptimize_entry_offset();
@@ -1205,6 +1205,7 @@
 
   static const word kTestEntryLength;
   static const word kInstanceClassIdOrFunction;
+  static const word kDestinationType;
   static const word kInstanceTypeArguments;
   static const word kInstantiatorTypeArguments;
   static const word kFunctionTypeArguments;
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 7263afe..63c13d4 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -45,19 +45,21 @@
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
@@ -122,13 +124,13 @@
     Field_initializer_function_offset = 16;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 20;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 56;
+    Field_guarded_list_length_in_object_offset_offset = 52;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    28;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+    24;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
 static constexpr dart::compiler::target::word Function_code_offset = 44;
 static constexpr dart::compiler::target::word Function_data_offset = 36;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -217,171 +219,169 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 376;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    696;
+    692;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    696;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 272;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 288;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 196;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 728;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 332;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 112;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 324;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 268;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 136;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 736;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 44;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    308;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    312;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    228;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    348;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 344;
+static constexpr dart::compiler::target::word Thread_end_offset = 52;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    712;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 252;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 256;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 316;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 356;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    352;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 364;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     700;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 128;
+    Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    724;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    64;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 272;
+    Thread_lazy_deopt_from_return_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280;
+    Thread_lazy_deopt_from_throw_stub_offset = 236;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 188;
+    Thread_lazy_specialize_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284;
+    Thread_marking_stack_block_offset = 80;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 192;
+    Thread_megamorphic_call_checked_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 288;
+    Thread_switchable_call_miss_entry_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 196;
+    Thread_switchable_call_miss_stub_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 292;
+    Thread_no_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 200;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 144;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 296;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 140;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 204;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 732;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    96;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 340;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 148;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 332;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 276;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 740;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 48;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    316;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    320;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    236;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    356;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 352;
-static constexpr dart::compiler::target::word Thread_end_offset = 56;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 708;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     716;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 260;
+    Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 264;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 324;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 136;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 132;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 368;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 364;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    360;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 372;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    704;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    728;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    68;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 240;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 244;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 252;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 84;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 308;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 216;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 160;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 156;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 180;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 344;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 708;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 712;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    720;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
+    Thread_slow_type_test_entry_point_offset = 320;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 32;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    60;
+    56;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 64;
+    Thread_stack_overflow_flags_offset = 60;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    80;
+    76;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 76;
-static constexpr dart::compiler::target::word Thread_top_offset = 52;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 24;
+    Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word Thread_top_offset = 48;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 20;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 104;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92;
+    Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    124;
+    116;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 268;
+    Thread_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 724;
+    36;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -393,6 +393,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -419,6 +421,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 12;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
 static constexpr dart::compiler::target::word Array_element_size = 4;
 static constexpr dart::compiler::target::word
@@ -431,7 +435,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -459,7 +463,7 @@
     12;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     24;
-static constexpr dart::compiler::target::word Field_InstanceSize = 64;
+static constexpr dart::compiler::target::word Field_InstanceSize = 60;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 96;
@@ -498,9 +502,8 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 56;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 12;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -560,19 +563,21 @@
 static constexpr dart::compiler::target::word String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
@@ -637,13 +642,13 @@
     Field_initializer_function_offset = 32;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 96;
+    Field_guarded_list_length_in_object_offset_offset = 88;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    56;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
+    48;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_data_offset = 72;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -733,173 +738,171 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 736;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1400;
+    1392;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    1400;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 512;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 376;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1464;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 648;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 208;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 632;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 520;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 256;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1480;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 88;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    600;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    608;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    440;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    680;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word Thread_end_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 480;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    1432;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 488;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 496;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 616;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 696;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    688;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 712;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     1408;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 240;
+    Thread_invoke_dart_code_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1456;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 528;
+    Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 560;
+    Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 376;
+    Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 568;
+    Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 384;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 576;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 264;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 392;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1472;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    192;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 664;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 536;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 272;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 96;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    616;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    624;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    456;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    696;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word Thread_end_offset = 112;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 496;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1416;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1424;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     1440;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 504;
+    Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 512;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 632;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 256;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 720;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 712;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    704;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1416;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1464;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    136;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 464;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 472;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 488;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 600;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 608;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 416;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 656;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1432;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1448;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 480;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 640;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
+    Thread_slow_type_test_entry_point_offset = 624;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 64;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    120;
+    112;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 128;
+    Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    160;
+    152;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word Thread_top_offset = 104;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 48;
+    Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word Thread_top_offset = 96;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 40;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184;
+    Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    232;
+    216;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 520;
+    Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1456;
+    1448;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -912,6 +915,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 64;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 72;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    75;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -938,6 +943,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
 static constexpr dart::compiler::target::word Array_element_size = 8;
 static constexpr dart::compiler::target::word
@@ -950,12 +957,12 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, -1,   -1,   1344, 1352,
-        1360, 1368, 1376, -1,   1384, 1392, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
-static constexpr dart::compiler::target::word Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word Class_InstanceSize = 208;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
@@ -963,7 +970,7 @@
 static constexpr dart::compiler::target::word Code_InstanceSize = 176;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word Context_header_size = 24;
 static constexpr dart::compiler::target::word ContextScope_InstanceSize = 16;
@@ -979,7 +986,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 104;
+static constexpr dart::compiler::target::word Field_InstanceSize = 96;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 144;
@@ -989,7 +996,7 @@
 static constexpr dart::compiler::target::word ICData_InstanceSize = 56;
 static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word
     InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
@@ -1018,9 +1025,8 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 104;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -1079,19 +1085,21 @@
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
@@ -1156,13 +1164,13 @@
     Field_initializer_function_offset = 16;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 20;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 56;
+    Field_guarded_list_length_in_object_offset_offset = 52;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    28;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+    24;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
 static constexpr dart::compiler::target::word Function_code_offset = 44;
 static constexpr dart::compiler::target::word Function_data_offset = 36;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -1251,171 +1259,169 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 376;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    664;
+    660;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    664;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 272;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 288;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 196;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 696;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 332;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 112;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 324;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 268;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 136;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 44;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    308;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    312;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    228;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    348;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 344;
+static constexpr dart::compiler::target::word Thread_end_offset = 52;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    680;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 252;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 256;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 316;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 356;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    352;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 364;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     668;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 128;
+    Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    692;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    64;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 272;
+    Thread_lazy_deopt_from_return_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280;
+    Thread_lazy_deopt_from_throw_stub_offset = 236;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 188;
+    Thread_lazy_specialize_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284;
+    Thread_marking_stack_block_offset = 80;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 192;
+    Thread_megamorphic_call_checked_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 288;
+    Thread_switchable_call_miss_entry_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 196;
+    Thread_switchable_call_miss_stub_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 292;
+    Thread_no_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 200;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 144;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 296;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 140;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 204;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 700;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    96;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 340;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 148;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 332;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 276;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 708;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 48;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    316;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    320;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    236;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    356;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 352;
-static constexpr dart::compiler::target::word Thread_end_offset = 56;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 672;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 676;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     684;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 260;
+    Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 264;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 324;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 136;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 132;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 368;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 364;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    360;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 372;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    672;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    696;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    68;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 240;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 244;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 252;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 84;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 308;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 216;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 160;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 156;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 180;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 344;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 676;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 680;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    688;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
+    Thread_slow_type_test_entry_point_offset = 320;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 32;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    60;
+    56;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 64;
+    Thread_stack_overflow_flags_offset = 60;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    80;
+    76;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 76;
-static constexpr dart::compiler::target::word Thread_top_offset = 52;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 24;
+    Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word Thread_top_offset = 48;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 20;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 104;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92;
+    Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    124;
+    116;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 268;
+    Thread_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 692;
+    36;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -1427,6 +1433,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -1453,6 +1461,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 12;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
 static constexpr dart::compiler::target::word Array_element_size = 4;
 static constexpr dart::compiler::target::word
@@ -1490,7 +1500,7 @@
     12;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     24;
-static constexpr dart::compiler::target::word Field_InstanceSize = 64;
+static constexpr dart::compiler::target::word Field_InstanceSize = 60;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 96;
@@ -1529,9 +1539,8 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 56;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 12;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -1591,19 +1600,21 @@
 static constexpr dart::compiler::target::word String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
@@ -1668,13 +1679,13 @@
     Field_initializer_function_offset = 32;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 96;
+    Field_guarded_list_length_in_object_offset_offset = 88;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    56;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
+    48;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_data_offset = 72;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -1764,173 +1775,171 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 736;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1472;
+    1464;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    1472;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 512;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 376;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1536;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 648;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 208;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 632;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 520;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 256;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1552;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 88;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    600;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    608;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    440;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    680;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word Thread_end_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 480;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    1504;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 488;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 496;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 616;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 696;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    688;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 712;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     1480;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 240;
+    Thread_invoke_dart_code_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1528;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 528;
+    Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 560;
+    Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 376;
+    Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 568;
+    Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 384;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 576;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 264;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 392;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1544;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    192;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 664;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 536;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 272;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 96;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    616;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    624;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    456;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    696;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word Thread_end_offset = 112;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 496;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1496;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     1512;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 504;
+    Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 512;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 632;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 256;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 720;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 712;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    704;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1488;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1536;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    136;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 464;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 472;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 488;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 600;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 608;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 416;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 656;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1496;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1504;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1520;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 480;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 640;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
+    Thread_slow_type_test_entry_point_offset = 624;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 64;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    120;
+    112;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 128;
+    Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    160;
+    152;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word Thread_top_offset = 104;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 48;
+    Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word Thread_top_offset = 96;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 40;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184;
+    Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    232;
+    216;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 520;
+    Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1528;
+    1520;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -1943,6 +1952,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 64;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 72;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    75;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -1969,6 +1980,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
 static constexpr dart::compiler::target::word Array_element_size = 8;
 static constexpr dart::compiler::target::word
@@ -1981,13 +1994,13 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392,
-        1400, 1408, 1416, 1424, -1,   -1,   -1,   -1,   1432, 1440, -1,
-        -1,   1448, 1456, 1464, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
-static constexpr dart::compiler::target::word Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word Class_InstanceSize = 208;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
@@ -1995,7 +2008,7 @@
 static constexpr dart::compiler::target::word Code_InstanceSize = 176;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word Context_header_size = 24;
 static constexpr dart::compiler::target::word ContextScope_InstanceSize = 16;
@@ -2011,7 +2024,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 104;
+static constexpr dart::compiler::target::word Field_InstanceSize = 96;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 144;
@@ -2021,7 +2034,7 @@
 static constexpr dart::compiler::target::word ICData_InstanceSize = 56;
 static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word
     InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
@@ -2050,9 +2063,8 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 104;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -2113,19 +2125,21 @@
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
@@ -2188,13 +2202,13 @@
     Field_initializer_function_offset = 16;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 20;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 56;
+    Field_guarded_list_length_in_object_offset_offset = 52;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    28;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+    24;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
 static constexpr dart::compiler::target::word Function_code_offset = 44;
 static constexpr dart::compiler::target::word Function_data_offset = 36;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -2282,171 +2296,169 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 376;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    696;
+    692;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    696;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 272;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 288;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 196;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 728;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 332;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 112;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 324;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 268;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 136;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 736;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 44;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    308;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    312;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    228;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    348;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 344;
+static constexpr dart::compiler::target::word Thread_end_offset = 52;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    712;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 252;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 256;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 316;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 356;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    352;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 364;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     700;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 128;
+    Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    724;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    64;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 272;
+    Thread_lazy_deopt_from_return_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280;
+    Thread_lazy_deopt_from_throw_stub_offset = 236;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 188;
+    Thread_lazy_specialize_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284;
+    Thread_marking_stack_block_offset = 80;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 192;
+    Thread_megamorphic_call_checked_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 288;
+    Thread_switchable_call_miss_entry_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 196;
+    Thread_switchable_call_miss_stub_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 292;
+    Thread_no_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 200;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 144;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 296;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 140;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 204;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 732;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    96;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 340;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 148;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 332;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 276;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 740;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 48;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    316;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    320;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    236;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    356;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 352;
-static constexpr dart::compiler::target::word Thread_end_offset = 56;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 708;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     716;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 260;
+    Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 264;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 324;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 136;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 132;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 368;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 364;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    360;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 372;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    704;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    728;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    68;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 240;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 244;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 252;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 84;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 308;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 216;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 160;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 156;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 180;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 344;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 708;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 712;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    720;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
+    Thread_slow_type_test_entry_point_offset = 320;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 32;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    60;
+    56;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 64;
+    Thread_stack_overflow_flags_offset = 60;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    80;
+    76;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 76;
-static constexpr dart::compiler::target::word Thread_top_offset = 52;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 24;
+    Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word Thread_top_offset = 48;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 20;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 104;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92;
+    Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    124;
+    116;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 268;
+    Thread_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 724;
+    36;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -2458,6 +2470,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -2484,6 +2498,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 12;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
 static constexpr dart::compiler::target::word Array_element_size = 4;
 static constexpr dart::compiler::target::word
@@ -2493,7 +2509,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -2521,7 +2537,7 @@
     12;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     24;
-static constexpr dart::compiler::target::word Field_InstanceSize = 64;
+static constexpr dart::compiler::target::word Field_InstanceSize = 60;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 96;
@@ -2560,7 +2576,6 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -2622,19 +2637,21 @@
 static constexpr dart::compiler::target::word String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
@@ -2697,13 +2714,13 @@
     Field_initializer_function_offset = 32;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 96;
+    Field_guarded_list_length_in_object_offset_offset = 88;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    56;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
+    48;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_data_offset = 72;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -2792,173 +2809,171 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 736;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1400;
+    1392;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    1400;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 512;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 376;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1464;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 648;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 208;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 632;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 520;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 256;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1480;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 88;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    600;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    608;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    440;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    680;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word Thread_end_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 480;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    1432;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 488;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 496;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 616;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 696;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    688;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 712;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     1408;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 240;
+    Thread_invoke_dart_code_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1456;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 528;
+    Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 560;
+    Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 376;
+    Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 568;
+    Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 384;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 576;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 264;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 392;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1472;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    192;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 664;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 536;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 272;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 96;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    616;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    624;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    456;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    696;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word Thread_end_offset = 112;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 496;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1416;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1424;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     1440;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 504;
+    Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 512;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 632;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 256;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 720;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 712;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    704;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1416;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1464;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    136;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 464;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 472;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 488;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 600;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 608;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 416;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 656;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1432;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1448;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 480;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 640;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
+    Thread_slow_type_test_entry_point_offset = 624;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 64;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    120;
+    112;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 128;
+    Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    160;
+    152;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word Thread_top_offset = 104;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 48;
+    Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word Thread_top_offset = 96;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 40;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184;
+    Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    232;
+    216;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 520;
+    Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1456;
+    1448;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -2971,6 +2986,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 64;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 72;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    75;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -2997,6 +3014,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
 static constexpr dart::compiler::target::word Array_element_size = 8;
 static constexpr dart::compiler::target::word
@@ -3006,12 +3025,12 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, -1,   -1,   1344, 1352,
-        1360, 1368, 1376, -1,   1384, 1392, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
-static constexpr dart::compiler::target::word Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word Class_InstanceSize = 208;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
@@ -3019,7 +3038,7 @@
 static constexpr dart::compiler::target::word Code_InstanceSize = 144;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word Context_header_size = 24;
 static constexpr dart::compiler::target::word ContextScope_InstanceSize = 16;
@@ -3035,7 +3054,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 104;
+static constexpr dart::compiler::target::word Field_InstanceSize = 96;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 144;
@@ -3045,7 +3064,7 @@
 static constexpr dart::compiler::target::word ICData_InstanceSize = 56;
 static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word
     InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
@@ -3074,9 +3093,8 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -3135,19 +3153,21 @@
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
@@ -3210,13 +3230,13 @@
     Field_initializer_function_offset = 16;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 20;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 56;
+    Field_guarded_list_length_in_object_offset_offset = 52;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    28;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+    24;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
 static constexpr dart::compiler::target::word Function_code_offset = 44;
 static constexpr dart::compiler::target::word Function_data_offset = 36;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -3304,171 +3324,169 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 376;
+    Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    664;
+    660;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    664;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 272;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 180;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 288;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 196;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 696;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 332;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 112;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 324;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 268;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 136;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 44;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    308;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    312;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    228;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    348;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 344;
+static constexpr dart::compiler::target::word Thread_end_offset = 52;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    680;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 252;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 256;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 316;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 356;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    352;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 364;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     668;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 128;
+    Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    692;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    64;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 272;
+    Thread_lazy_deopt_from_return_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280;
+    Thread_lazy_deopt_from_throw_stub_offset = 236;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 188;
+    Thread_lazy_specialize_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284;
+    Thread_marking_stack_block_offset = 80;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 192;
+    Thread_megamorphic_call_checked_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 288;
+    Thread_switchable_call_miss_entry_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 196;
+    Thread_switchable_call_miss_stub_offset = 208;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 292;
+    Thread_no_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 200;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 144;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 296;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 140;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 204;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 700;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    96;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 340;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 116;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 148;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 332;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 276;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 708;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 48;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    316;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    320;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    236;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    356;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 352;
-static constexpr dart::compiler::target::word Thread_end_offset = 56;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 672;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 676;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     684;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 260;
+    Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 264;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 324;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 136;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 132;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 368;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 364;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    360;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 372;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    672;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    696;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    68;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 240;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 244;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 252;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 84;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 308;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 216;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 160;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 156;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 180;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 344;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 676;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 680;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    688;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
+    Thread_slow_type_test_entry_point_offset = 320;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 32;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    60;
+    56;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 64;
+    Thread_stack_overflow_flags_offset = 60;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    80;
+    76;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 76;
-static constexpr dart::compiler::target::word Thread_top_offset = 52;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 24;
+    Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word Thread_top_offset = 48;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 20;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 104;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92;
+    Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    124;
+    116;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 268;
+    Thread_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 692;
+    36;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -3480,6 +3498,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -3506,6 +3526,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 12;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
 static constexpr dart::compiler::target::word Array_element_size = 4;
 static constexpr dart::compiler::target::word
@@ -3540,7 +3562,7 @@
     12;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     24;
-static constexpr dart::compiler::target::word Field_InstanceSize = 64;
+static constexpr dart::compiler::target::word Field_InstanceSize = 60;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 96;
@@ -3579,7 +3601,6 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -3641,19 +3662,21 @@
 static constexpr dart::compiler::target::word String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 4;
+    SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 2;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kTestEntryLength = 7;
+    SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
@@ -3716,13 +3739,13 @@
     Field_initializer_function_offset = 32;
 static constexpr dart::compiler::target::word
     Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 96;
+    Field_guarded_list_length_in_object_offset_offset = 88;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    56;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
+    48;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
 static constexpr dart::compiler::target::word Function_code_offset = 88;
 static constexpr dart::compiler::target::word Function_data_offset = 72;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
@@ -3811,173 +3834,171 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    Thread_AllocateArray_entry_point_offset = 736;
+    Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1472;
+    1464;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    1472;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 512;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_parameterized_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    Thread_allocate_object_slow_stub_offset = 376;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1536;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 648;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 208;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 632;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 520;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 256;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1552;
+static constexpr dart::compiler::target::word
+    Thread_dispatch_table_array_offset = 88;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    600;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    608;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    440;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    680;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word Thread_end_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 480;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    1504;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 488;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 496;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 616;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 704;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 696;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    688;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 712;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
     1480;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_code_offset = 240;
+    Thread_invoke_dart_code_stub_offset = 248;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1528;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    128;
 static constexpr dart::compiler::target::word
-    Thread_array_write_barrier_entry_point_offset = 528;
+    Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_entry_point_offset = 560;
+    Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_stub_offset = 376;
+    Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_entry_point_offset = 568;
+    Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_parameterized_stub_offset = 384;
+    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_entry_point_offset = 576;
+    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 264;
 static constexpr dart::compiler::target::word
-    Thread_allocate_object_slow_stub_offset = 392;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1544;
-static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
-    192;
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    Thread_auto_scope_native_wrapper_entry_point_offset = 664;
-static constexpr dart::compiler::target::word Thread_bool_false_offset = 224;
-static constexpr dart::compiler::target::word Thread_bool_true_offset = 216;
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_entry_point_offset = 536;
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    Thread_call_to_runtime_stub_offset = 272;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560;
+    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    Thread_dispatch_table_array_offset = 96;
-static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
-    616;
-static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
-static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
-    624;
-static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
-    456;
-static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
-    696;
+    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word Thread_end_offset = 112;
+    Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    Thread_enter_safepoint_stub_offset = 496;
-static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 656;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1496;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
     1512;
 static constexpr dart::compiler::target::word
-    Thread_exit_safepoint_stub_offset = 504;
+    Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_stub_offset = 512;
-static constexpr dart::compiler::target::word
-    Thread_call_native_through_safepoint_entry_point_offset = 632;
-static constexpr dart::compiler::target::word
-    Thread_fix_allocation_stub_code_offset = 256;
-static constexpr dart::compiler::target::word
-    Thread_fix_callers_target_code_offset = 248;
-static constexpr dart::compiler::target::word
-    Thread_float_absolute_address_offset = 720;
-static constexpr dart::compiler::target::word
-    Thread_float_negate_address_offset = 712;
-static constexpr dart::compiler::target::word Thread_float_not_address_offset =
-    704;
-static constexpr dart::compiler::target::word
-    Thread_float_zerow_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1488;
-static constexpr dart::compiler::target::word
-    Thread_invoke_dart_code_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1536;
-static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
-static constexpr dart::compiler::target::word Thread_field_table_values_offset =
-    136;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_return_stub_offset = 464;
-static constexpr dart::compiler::target::word
-    Thread_lazy_deopt_from_throw_stub_offset = 472;
-static constexpr dart::compiler::target::word
-    Thread_lazy_specialize_type_test_stub_offset = 488;
-static constexpr dart::compiler::target::word
-    Thread_marking_stack_block_offset = 168;
-static constexpr dart::compiler::target::word
-    Thread_megamorphic_call_checked_entry_offset = 600;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_entry_offset = 608;
-static constexpr dart::compiler::target::word
-    Thread_switchable_call_miss_stub_offset = 416;
-static constexpr dart::compiler::target::word
-    Thread_no_scope_native_wrapper_entry_point_offset = 656;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
-static constexpr dart::compiler::target::word
-    Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
-static constexpr dart::compiler::target::word
-    Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
-static constexpr dart::compiler::target::word
-    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
-static constexpr dart::compiler::target::word
-    Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
-static constexpr dart::compiler::target::word
-    Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
-static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
-static constexpr dart::compiler::target::word
-    Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1496;
-static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1504;
-static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1520;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_stub_offset = 480;
-static constexpr dart::compiler::target::word
-    Thread_slow_type_test_entry_point_offset = 640;
-static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
+    Thread_slow_type_test_entry_point_offset = 624;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 64;
 static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
-    120;
+    112;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_flags_offset = 128;
+    Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
-    160;
+    152;
 static constexpr dart::compiler::target::word
-    Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word Thread_top_offset = 104;
-static constexpr dart::compiler::target::word Thread_top_resource_offset = 48;
+    Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word Thread_top_offset = 96;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 40;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184;
+    Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
-    232;
+    216;
 static constexpr dart::compiler::target::word
-    Thread_write_barrier_entry_point_offset = 520;
+    Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1528;
+    1520;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -3990,6 +4011,8 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 64;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 72;
+static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
+    75;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -4016,6 +4039,8 @@
     MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
 static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
 static constexpr dart::compiler::target::word Array_element_size = 8;
 static constexpr dart::compiler::target::word
@@ -4025,13 +4050,13 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392,
-        1400, 1408, 1416, 1424, -1,   -1,   -1,   -1,   1432, 1440, -1,
-        -1,   1448, 1456, 1464, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word Array_header_size = 24;
-static constexpr dart::compiler::target::word Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word Class_InstanceSize = 208;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
@@ -4039,7 +4064,7 @@
 static constexpr dart::compiler::target::word Code_InstanceSize = 144;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word Context_header_size = 24;
 static constexpr dart::compiler::target::word ContextScope_InstanceSize = 16;
@@ -4055,7 +4080,7 @@
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
     48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 104;
+static constexpr dart::compiler::target::word Field_InstanceSize = 96;
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 144;
@@ -4065,7 +4090,7 @@
 static constexpr dart::compiler::target::word ICData_InstanceSize = 56;
 static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word
     InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
@@ -4094,9 +4119,8 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
-static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -4157,19 +4181,21 @@
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
     536870911;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    AOT_SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kTestEntryLength = 7;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
@@ -4349,180 +4375,178 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 376;
+    AOT_Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 696;
+    AOT_Thread_active_exception_offset = 692;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 700;
+    AOT_Thread_active_stacktrace_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_code_offset = 128;
+    AOT_Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 272;
+    AOT_Thread_array_write_barrier_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 188;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 180;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 192;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 184;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_entry_point_offset = 288;
+    AOT_Thread_allocate_object_entry_point_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_stub_offset = 196;
+    AOT_Thread_allocate_object_stub_offset = 188;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_entry_point_offset = 292;
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_stub_offset = 200;
+    AOT_Thread_allocate_object_parameterized_stub_offset = 192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_entry_point_offset = 296;
+    AOT_Thread_allocate_object_slow_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_stub_offset = 204;
+    AOT_Thread_allocate_object_slow_stub_offset = 196;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    732;
+    728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_async_stack_trace_offset = 96;
-static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 340;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 332;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
-    120;
-static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 116;
+    112;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 108;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 332;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 276;
+    AOT_Thread_call_to_runtime_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_stub_offset = 144;
+    AOT_Thread_call_to_runtime_stub_offset = 136;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    740;
+    736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_dispatch_table_array_offset = 48;
+    AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    316;
+    308;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    232;
+    224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 320;
+    AOT_Thread_deoptimize_entry_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 236;
+    AOT_Thread_deoptimize_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 356;
+    AOT_Thread_double_abs_address_offset = 348;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 352;
-static constexpr dart::compiler::target::word AOT_Thread_end_offset = 56;
+    AOT_Thread_double_negate_address_offset = 344;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 52;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 256;
+    AOT_Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 716;
+    AOT_Thread_execution_state_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 260;
+    AOT_Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 264;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 324;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 316;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_allocation_stub_code_offset = 136;
+    AOT_Thread_fix_allocation_stub_code_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_callers_target_code_offset = 132;
+    AOT_Thread_fix_callers_target_code_offset = 124;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 368;
+    AOT_Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 364;
+    AOT_Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 360;
+    AOT_Thread_float_not_address_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 372;
+    AOT_Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 704;
+    AOT_Thread_global_object_pool_offset = 700;
 static constexpr dart::compiler::target::word
-    AOT_Thread_invoke_dart_code_stub_offset = 140;
+    AOT_Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 728;
-static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
+    AOT_Thread_exit_through_ffi_offset = 724;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_Thread_field_table_values_offset = 68;
+    AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 240;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 244;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 236;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 252;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    AOT_Thread_marking_stack_block_offset = 84;
+    AOT_Thread_marking_stack_block_offset = 80;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 308;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_entry_offset = 312;
+    AOT_Thread_switchable_call_miss_entry_offset = 304;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_stub_offset = 216;
+    AOT_Thread_switchable_call_miss_stub_offset = 208;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 336;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word
-    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152;
+    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 144;
 static constexpr dart::compiler::target::word
     AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset =
-        148;
+        140;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 160;
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 156;
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 148;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168;
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 160;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164;
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176;
+    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172;
+    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 184;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 180;
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
-    112;
+    104;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 344;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 708;
+    AOT_Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 712;
+    AOT_Thread_saved_shadow_call_stack_offset = 708;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 720;
+    AOT_Thread_safepoint_state_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 248;
+    AOT_Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_entry_point_offset = 328;
+    AOT_Thread_slow_type_test_entry_point_offset = 320;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
-    36;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_stack_limit_offset = 60;
+    AOT_Thread_saved_stack_limit_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_flags_offset = 64;
+    AOT_Thread_stack_overflow_flags_offset = 60;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_store_buffer_block_offset = 80;
+    AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_Thread_top_exit_frame_info_offset = 76;
-static constexpr dart::compiler::target::word AOT_Thread_top_offset = 52;
+    AOT_Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
-    24;
+    20;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 104;
-static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 92;
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_code_offset = 124;
+    AOT_Thread_write_barrier_code_offset = 116;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 268;
+    AOT_Thread_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_mask_offset = 40;
+    AOT_Thread_write_barrier_mask_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    724;
+    720;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4539,6 +4563,8 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     40;
 static constexpr dart::compiler::target::word
+    AOT_TypeParameter_nullability_offset = 43;
+static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     8;
@@ -4571,6 +4597,8 @@
     AOT_MonomorphicSmiableCall_entrypoint_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset = 8;
 static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
     12;
 static constexpr dart::compiler::target::word AOT_Array_element_size = 4;
@@ -4585,7 +4613,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
@@ -4660,8 +4688,6 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 20;
-static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
-    16;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -4729,19 +4755,21 @@
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    AOT_SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kTestEntryLength = 7;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
@@ -4921,181 +4949,179 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 736;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1400;
+    AOT_Thread_active_exception_offset = 1392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1408;
+    AOT_Thread_active_stacktrace_offset = 1400;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_code_offset = 240;
+    AOT_Thread_array_write_barrier_code_offset = 224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 528;
+    AOT_Thread_array_write_barrier_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_entry_point_offset = 560;
+    AOT_Thread_allocate_object_entry_point_offset = 544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_stub_offset = 376;
+    AOT_Thread_allocate_object_stub_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_entry_point_offset = 568;
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_stub_offset = 384;
+    AOT_Thread_allocate_object_parameterized_stub_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_entry_point_offset = 576;
+    AOT_Thread_allocate_object_slow_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_stub_offset = 392;
+    AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1472;
+    1464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_async_stack_trace_offset = 192;
-static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 648;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
-    224;
-static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
+    208;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 536;
+    AOT_Thread_call_to_runtime_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_stub_offset = 272;
+    AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1488;
+    1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_dispatch_table_array_offset = 96;
+    AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    616;
+    600;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    448;
+    432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 624;
+    AOT_Thread_deoptimize_entry_offset = 608;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 456;
+    AOT_Thread_deoptimize_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 696;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
+    AOT_Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 104;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 496;
+    AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1440;
+    AOT_Thread_execution_state_offset = 1432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 504;
+    AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 512;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 632;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_allocation_stub_code_offset = 256;
+    AOT_Thread_fix_allocation_stub_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_callers_target_code_offset = 248;
+    AOT_Thread_fix_callers_target_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 720;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 712;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 704;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 728;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1416;
+    AOT_Thread_global_object_pool_offset = 1408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_invoke_dart_code_stub_offset = 264;
+    AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1464;
-static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
+    AOT_Thread_exit_through_ffi_offset = 1456;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word
-    AOT_Thread_field_table_values_offset = 136;
+    AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 464;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 472;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 488;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_marking_stack_block_offset = 168;
+    AOT_Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 600;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_entry_offset = 608;
+    AOT_Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_stub_offset = 416;
+    AOT_Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
+    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset =
-        280;
+        264;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
+    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 672;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1424;
+    1416;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1432;
+    AOT_Thread_saved_shadow_call_stack_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1448;
+    AOT_Thread_safepoint_state_offset = 1440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 480;
+    AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_entry_point_offset = 640;
+    AOT_Thread_slow_type_test_entry_point_offset = 624;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
-    72;
+    64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_stack_limit_offset = 120;
+    AOT_Thread_saved_stack_limit_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_flags_offset = 128;
+    AOT_Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_store_buffer_block_offset = 160;
+    AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word AOT_Thread_top_offset = 104;
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
-    48;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184;
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_code_offset = 232;
+    AOT_Thread_write_barrier_code_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 520;
+    AOT_Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_mask_offset = 80;
+    AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1456;
+    1448;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5112,6 +5138,8 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     72;
 static constexpr dart::compiler::target::word
+    AOT_TypeParameter_nullability_offset = 75;
+static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     16;
@@ -5144,6 +5172,9 @@
     AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+    16;
 static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
     24;
 static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -5158,12 +5189,12 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, -1,   -1,   1344, 1352,
-        1360, 1368, 1376, -1,   1384, 1392, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
-static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
@@ -5171,7 +5202,7 @@
 static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 152;
 static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word
-    AOT_CompressedStackMaps_HeaderSize = 12;
+    AOT_CompressedStackMaps_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
 static constexpr dart::compiler::target::word AOT_ContextScope_InstanceSize =
@@ -5199,7 +5230,7 @@
 static constexpr dart::compiler::target::word AOT_ICData_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_Instructions_UnalignedHeaderSize = 12;
+    AOT_Instructions_UnalignedHeaderSize = 16;
 static constexpr dart::compiler::target::word
     AOT_InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
@@ -5234,10 +5265,8 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
-static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
-    32;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -5273,7 +5302,7 @@
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 12;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_X64)
 
 #if defined(TARGET_ARCH_IA32)
@@ -5306,19 +5335,21 @@
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    AOT_SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kTestEntryLength = 7;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
@@ -5498,181 +5529,179 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 736;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1472;
+    AOT_Thread_active_exception_offset = 1464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1480;
+    AOT_Thread_active_stacktrace_offset = 1472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_code_offset = 240;
+    AOT_Thread_array_write_barrier_code_offset = 224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 528;
+    AOT_Thread_array_write_barrier_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_entry_point_offset = 560;
+    AOT_Thread_allocate_object_entry_point_offset = 544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_stub_offset = 376;
+    AOT_Thread_allocate_object_stub_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_entry_point_offset = 568;
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_stub_offset = 384;
+    AOT_Thread_allocate_object_parameterized_stub_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_entry_point_offset = 576;
+    AOT_Thread_allocate_object_slow_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_stub_offset = 392;
+    AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1544;
+    1536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_async_stack_trace_offset = 192;
-static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 648;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
-    224;
-static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
+    208;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 536;
+    AOT_Thread_call_to_runtime_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_stub_offset = 272;
+    AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1560;
+    1552;
 static constexpr dart::compiler::target::word
-    AOT_Thread_dispatch_table_array_offset = 96;
+    AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    616;
+    600;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    448;
+    432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 624;
+    AOT_Thread_deoptimize_entry_offset = 608;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 456;
+    AOT_Thread_deoptimize_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 696;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
+    AOT_Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 104;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 496;
+    AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1512;
+    AOT_Thread_execution_state_offset = 1504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 504;
+    AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 512;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 632;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_allocation_stub_code_offset = 256;
+    AOT_Thread_fix_allocation_stub_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_callers_target_code_offset = 248;
+    AOT_Thread_fix_callers_target_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 720;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 712;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 704;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 728;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1488;
+    AOT_Thread_global_object_pool_offset = 1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_invoke_dart_code_stub_offset = 264;
+    AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1536;
-static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
+    AOT_Thread_exit_through_ffi_offset = 1528;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word
-    AOT_Thread_field_table_values_offset = 136;
+    AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 464;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 472;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 488;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_marking_stack_block_offset = 168;
+    AOT_Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 600;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_entry_offset = 608;
+    AOT_Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_stub_offset = 416;
+    AOT_Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
+    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset =
-        280;
+        264;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
+    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 672;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1496;
+    1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1504;
+    AOT_Thread_saved_shadow_call_stack_offset = 1496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1520;
+    AOT_Thread_safepoint_state_offset = 1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 480;
+    AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_entry_point_offset = 640;
+    AOT_Thread_slow_type_test_entry_point_offset = 624;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
-    72;
+    64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_stack_limit_offset = 120;
+    AOT_Thread_saved_stack_limit_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_flags_offset = 128;
+    AOT_Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_store_buffer_block_offset = 160;
+    AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word AOT_Thread_top_offset = 104;
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
-    48;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184;
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_code_offset = 232;
+    AOT_Thread_write_barrier_code_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 520;
+    AOT_Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_mask_offset = 80;
+    AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1528;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5689,6 +5718,8 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     72;
 static constexpr dart::compiler::target::word
+    AOT_TypeParameter_nullability_offset = 75;
+static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     16;
@@ -5721,6 +5752,9 @@
     AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+    16;
 static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
     24;
 static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -5735,13 +5769,13 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392,
-        1400, 1408, 1416, 1424, -1,   -1,   -1,   -1,   1432, 1440, -1,
-        -1,   1448, 1456, 1464, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
-static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
@@ -5749,7 +5783,7 @@
 static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 152;
 static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word
-    AOT_CompressedStackMaps_HeaderSize = 12;
+    AOT_CompressedStackMaps_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
 static constexpr dart::compiler::target::word AOT_ContextScope_InstanceSize =
@@ -5777,7 +5811,7 @@
 static constexpr dart::compiler::target::word AOT_ICData_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_Instructions_UnalignedHeaderSize = 12;
+    AOT_Instructions_UnalignedHeaderSize = 16;
 static constexpr dart::compiler::target::word
     AOT_InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
@@ -5812,10 +5846,8 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
-static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
-    32;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -5851,7 +5883,7 @@
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 12;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_ARM64)
 
 #else  // !defined(PRODUCT)
@@ -5882,19 +5914,21 @@
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
     536870911;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    AOT_SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kTestEntryLength = 7;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
@@ -6070,180 +6104,178 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 376;
+    AOT_Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 696;
+    AOT_Thread_active_exception_offset = 692;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 700;
+    AOT_Thread_active_stacktrace_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_code_offset = 128;
+    AOT_Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 272;
+    AOT_Thread_array_write_barrier_entry_point_offset = 264;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 188;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 180;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 192;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 184;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_entry_point_offset = 288;
+    AOT_Thread_allocate_object_entry_point_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_stub_offset = 196;
+    AOT_Thread_allocate_object_stub_offset = 188;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_entry_point_offset = 292;
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_stub_offset = 200;
+    AOT_Thread_allocate_object_parameterized_stub_offset = 192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_entry_point_offset = 296;
+    AOT_Thread_allocate_object_slow_entry_point_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_stub_offset = 204;
+    AOT_Thread_allocate_object_slow_stub_offset = 196;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    732;
+    728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_async_stack_trace_offset = 96;
-static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 340;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 332;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
-    120;
-static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 116;
+    112;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 108;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 332;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 276;
+    AOT_Thread_call_to_runtime_entry_point_offset = 268;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_stub_offset = 144;
+    AOT_Thread_call_to_runtime_stub_offset = 136;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    740;
+    736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_dispatch_table_array_offset = 48;
+    AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    316;
+    308;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    232;
+    224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 320;
+    AOT_Thread_deoptimize_entry_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 236;
+    AOT_Thread_deoptimize_stub_offset = 228;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 356;
+    AOT_Thread_double_abs_address_offset = 348;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 352;
-static constexpr dart::compiler::target::word AOT_Thread_end_offset = 56;
+    AOT_Thread_double_negate_address_offset = 344;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 52;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 256;
+    AOT_Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 716;
+    AOT_Thread_execution_state_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 260;
+    AOT_Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 264;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 324;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 316;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_allocation_stub_code_offset = 136;
+    AOT_Thread_fix_allocation_stub_code_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_callers_target_code_offset = 132;
+    AOT_Thread_fix_callers_target_code_offset = 124;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 368;
+    AOT_Thread_float_absolute_address_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 364;
+    AOT_Thread_float_negate_address_offset = 356;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 360;
+    AOT_Thread_float_not_address_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 372;
+    AOT_Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 704;
+    AOT_Thread_global_object_pool_offset = 700;
 static constexpr dart::compiler::target::word
-    AOT_Thread_invoke_dart_code_stub_offset = 140;
+    AOT_Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 728;
-static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
+    AOT_Thread_exit_through_ffi_offset = 724;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_Thread_field_table_values_offset = 68;
+    AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 240;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 244;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 236;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 252;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
-    AOT_Thread_marking_stack_block_offset = 84;
+    AOT_Thread_marking_stack_block_offset = 80;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 308;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 300;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_entry_offset = 312;
+    AOT_Thread_switchable_call_miss_entry_offset = 304;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_stub_offset = 216;
+    AOT_Thread_switchable_call_miss_stub_offset = 208;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 336;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 328;
 static constexpr dart::compiler::target::word
-    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152;
+    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 144;
 static constexpr dart::compiler::target::word
     AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset =
-        148;
+        140;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 160;
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 156;
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 148;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168;
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 160;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164;
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 156;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176;
+    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 168;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172;
+    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 164;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 184;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 180;
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 172;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
-    112;
+    104;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 344;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 708;
+    AOT_Thread_predefined_symbols_address_offset = 336;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 712;
+    AOT_Thread_saved_shadow_call_stack_offset = 708;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 720;
+    AOT_Thread_safepoint_state_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 248;
+    AOT_Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_entry_point_offset = 328;
+    AOT_Thread_slow_type_test_entry_point_offset = 320;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
-    36;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_stack_limit_offset = 60;
+    AOT_Thread_saved_stack_limit_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_flags_offset = 64;
+    AOT_Thread_stack_overflow_flags_offset = 60;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 204;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 292;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_store_buffer_block_offset = 80;
+    AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_Thread_top_exit_frame_info_offset = 76;
-static constexpr dart::compiler::target::word AOT_Thread_top_offset = 52;
+    AOT_Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
-    24;
+    20;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 104;
-static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 92;
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_code_offset = 124;
+    AOT_Thread_write_barrier_code_offset = 116;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 268;
+    AOT_Thread_write_barrier_entry_point_offset = 260;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_mask_offset = 40;
+    AOT_Thread_write_barrier_mask_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    724;
+    720;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6260,6 +6292,8 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     40;
 static constexpr dart::compiler::target::word
+    AOT_TypeParameter_nullability_offset = 43;
+static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     8;
@@ -6292,6 +6326,8 @@
     AOT_MonomorphicSmiableCall_entrypoint_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset = 8;
 static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
     12;
 static constexpr dart::compiler::target::word AOT_Array_element_size = 4;
@@ -6303,7 +6339,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1};
+        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
@@ -6378,8 +6414,6 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 12;
-static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
-    16;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -6447,19 +6481,21 @@
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    AOT_SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kTestEntryLength = 7;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
@@ -6635,181 +6671,179 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 736;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1400;
+    AOT_Thread_active_exception_offset = 1392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1408;
+    AOT_Thread_active_stacktrace_offset = 1400;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_code_offset = 240;
+    AOT_Thread_array_write_barrier_code_offset = 224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 528;
+    AOT_Thread_array_write_barrier_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_entry_point_offset = 560;
+    AOT_Thread_allocate_object_entry_point_offset = 544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_stub_offset = 376;
+    AOT_Thread_allocate_object_stub_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_entry_point_offset = 568;
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_stub_offset = 384;
+    AOT_Thread_allocate_object_parameterized_stub_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_entry_point_offset = 576;
+    AOT_Thread_allocate_object_slow_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_stub_offset = 392;
+    AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1472;
+    1464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_async_stack_trace_offset = 192;
-static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 648;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
-    224;
-static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
+    208;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 536;
+    AOT_Thread_call_to_runtime_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_stub_offset = 272;
+    AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1488;
+    1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_dispatch_table_array_offset = 96;
+    AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    616;
+    600;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    448;
+    432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 624;
+    AOT_Thread_deoptimize_entry_offset = 608;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 456;
+    AOT_Thread_deoptimize_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 696;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
+    AOT_Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 104;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 496;
+    AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1440;
+    AOT_Thread_execution_state_offset = 1432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 504;
+    AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 512;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 632;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_allocation_stub_code_offset = 256;
+    AOT_Thread_fix_allocation_stub_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_callers_target_code_offset = 248;
+    AOT_Thread_fix_callers_target_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 720;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 712;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 704;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 728;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1416;
+    AOT_Thread_global_object_pool_offset = 1408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_invoke_dart_code_stub_offset = 264;
+    AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1464;
-static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
+    AOT_Thread_exit_through_ffi_offset = 1456;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word
-    AOT_Thread_field_table_values_offset = 136;
+    AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 464;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 472;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 488;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_marking_stack_block_offset = 168;
+    AOT_Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 600;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_entry_offset = 608;
+    AOT_Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_stub_offset = 416;
+    AOT_Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
+    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset =
-        280;
+        264;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
+    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 672;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1424;
+    1416;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1432;
+    AOT_Thread_saved_shadow_call_stack_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1448;
+    AOT_Thread_safepoint_state_offset = 1440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 480;
+    AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_entry_point_offset = 640;
+    AOT_Thread_slow_type_test_entry_point_offset = 624;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
-    72;
+    64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_stack_limit_offset = 120;
+    AOT_Thread_saved_stack_limit_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_flags_offset = 128;
+    AOT_Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_store_buffer_block_offset = 160;
+    AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word AOT_Thread_top_offset = 104;
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
-    48;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184;
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_code_offset = 232;
+    AOT_Thread_write_barrier_code_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 520;
+    AOT_Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_mask_offset = 80;
+    AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1456;
+    1448;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6826,6 +6860,8 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     72;
 static constexpr dart::compiler::target::word
+    AOT_TypeParameter_nullability_offset = 75;
+static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     16;
@@ -6858,6 +6894,9 @@
     AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+    16;
 static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
     24;
 static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -6869,12 +6908,12 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, -1,   -1,   1344, 1352,
-        1360, 1368, 1376, -1,   1384, 1392, -1,   -1};
+        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
+        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
-static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
@@ -6882,7 +6921,7 @@
 static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word
-    AOT_CompressedStackMaps_HeaderSize = 12;
+    AOT_CompressedStackMaps_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
 static constexpr dart::compiler::target::word AOT_ContextScope_InstanceSize =
@@ -6910,7 +6949,7 @@
 static constexpr dart::compiler::target::word AOT_ICData_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_Instructions_UnalignedHeaderSize = 12;
+    AOT_Instructions_UnalignedHeaderSize = 16;
 static constexpr dart::compiler::target::word
     AOT_InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
@@ -6945,10 +6984,8 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
-    32;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -6984,7 +7021,7 @@
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 12;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_X64)
 
 #if defined(TARGET_ARCH_IA32)
@@ -7017,19 +7054,21 @@
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
     2305843009213693951;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 5;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+    AOT_SubtypeTestCache_kDestinationType = 2;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 7;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 3;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kTestEntryLength = 7;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
@@ -7205,181 +7244,179 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Thread_AllocateArray_entry_point_offset = 736;
+    AOT_Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1472;
+    AOT_Thread_active_exception_offset = 1464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1480;
+    AOT_Thread_active_stacktrace_offset = 1472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_code_offset = 240;
+    AOT_Thread_array_write_barrier_code_offset = 224;
 static constexpr dart::compiler::target::word
-    AOT_Thread_array_write_barrier_entry_point_offset = 528;
+    AOT_Thread_array_write_barrier_entry_point_offset = 512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544;
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360;
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 344;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552;
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368;
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 352;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_entry_point_offset = 560;
+    AOT_Thread_allocate_object_entry_point_offset = 544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_stub_offset = 376;
+    AOT_Thread_allocate_object_stub_offset = 360;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_entry_point_offset = 568;
+    AOT_Thread_allocate_object_parameterized_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_parameterized_stub_offset = 384;
+    AOT_Thread_allocate_object_parameterized_stub_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_entry_point_offset = 576;
+    AOT_Thread_allocate_object_slow_entry_point_offset = 560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_allocate_object_slow_stub_offset = 392;
+    AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1544;
+    1536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_async_stack_trace_offset = 192;
-static constexpr dart::compiler::target::word
-    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 648;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
-    224;
-static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216;
+    208;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 200;
 static constexpr dart::compiler::target::word
-    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648;
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 632;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_entry_point_offset = 536;
+    AOT_Thread_call_to_runtime_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_to_runtime_stub_offset = 272;
+    AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1560;
+    1552;
 static constexpr dart::compiler::target::word
-    AOT_Thread_dispatch_table_array_offset = 96;
+    AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
-    616;
+    600;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
-    448;
+    432;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_entry_offset = 624;
+    AOT_Thread_deoptimize_entry_offset = 608;
 static constexpr dart::compiler::target::word
-    AOT_Thread_deoptimize_stub_offset = 456;
+    AOT_Thread_deoptimize_stub_offset = 440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_abs_address_offset = 696;
+    AOT_Thread_double_abs_address_offset = 680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_negate_address_offset = 688;
-static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112;
+    AOT_Thread_double_negate_address_offset = 672;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 104;
 static constexpr dart::compiler::target::word
-    AOT_Thread_enter_safepoint_stub_offset = 496;
+    AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1512;
+    AOT_Thread_execution_state_offset = 1504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_safepoint_stub_offset = 504;
+    AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_stub_offset = 512;
+    AOT_Thread_call_native_through_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_call_native_through_safepoint_entry_point_offset = 632;
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_allocation_stub_code_offset = 256;
+    AOT_Thread_fix_allocation_stub_code_offset = 240;
 static constexpr dart::compiler::target::word
-    AOT_Thread_fix_callers_target_code_offset = 248;
+    AOT_Thread_fix_callers_target_code_offset = 232;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_absolute_address_offset = 720;
+    AOT_Thread_float_absolute_address_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_negate_address_offset = 712;
+    AOT_Thread_float_negate_address_offset = 696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_not_address_offset = 704;
+    AOT_Thread_float_not_address_offset = 688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_float_zerow_address_offset = 728;
+    AOT_Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1488;
+    AOT_Thread_global_object_pool_offset = 1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_invoke_dart_code_stub_offset = 264;
+    AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1536;
-static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
+    AOT_Thread_exit_through_ffi_offset = 1528;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word
-    AOT_Thread_field_table_values_offset = 136;
+    AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_return_stub_offset = 464;
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_deopt_from_throw_stub_offset = 472;
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_lazy_specialize_type_test_stub_offset = 488;
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
-    AOT_Thread_marking_stack_block_offset = 168;
+    AOT_Thread_marking_stack_block_offset = 160;
 static constexpr dart::compiler::target::word
-    AOT_Thread_megamorphic_call_checked_entry_offset = 600;
+    AOT_Thread_megamorphic_call_checked_entry_offset = 584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_entry_offset = 608;
+    AOT_Thread_switchable_call_miss_entry_offset = 592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_switchable_call_miss_stub_offset = 416;
+    AOT_Thread_switchable_call_miss_stub_offset = 400;
 static constexpr dart::compiler::target::word
-    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656;
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288;
+    AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset =
-        280;
+        264;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304;
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296;
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320;
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312;
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336;
+    AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 320;
 static constexpr dart::compiler::target::word
-    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328;
+    AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 312;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352;
+    AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 336;
 static constexpr dart::compiler::target::word
-    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344;
+    AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word
-    AOT_Thread_predefined_symbols_address_offset = 672;
+    AOT_Thread_predefined_symbols_address_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1496;
+    1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1504;
+    AOT_Thread_saved_shadow_call_stack_offset = 1496;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1520;
+    AOT_Thread_safepoint_state_offset = 1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_stub_offset = 480;
+    AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
-    AOT_Thread_slow_type_test_entry_point_offset = 640;
+    AOT_Thread_slow_type_test_entry_point_offset = 624;
 static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
-    72;
+    64;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_stack_limit_offset = 120;
+    AOT_Thread_saved_stack_limit_offset = 112;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_flags_offset = 128;
+    AOT_Thread_stack_overflow_flags_offset = 120;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408;
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 392;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 568;
 static constexpr dart::compiler::target::word
-    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400;
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 384;
 static constexpr dart::compiler::target::word
-    AOT_Thread_store_buffer_block_offset = 160;
+    AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_top_exit_frame_info_offset = 152;
-static constexpr dart::compiler::target::word AOT_Thread_top_offset = 104;
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
-    48;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 200;
-static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184;
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_code_offset = 232;
+    AOT_Thread_write_barrier_code_offset = 216;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_entry_point_offset = 520;
+    AOT_Thread_write_barrier_entry_point_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_Thread_write_barrier_mask_offset = 80;
+    AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1528;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -7396,6 +7433,8 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     72;
 static constexpr dart::compiler::target::word
+    AOT_TypeParameter_nullability_offset = 75;
+static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     16;
@@ -7428,6 +7467,9 @@
     AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+    16;
 static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
     24;
 static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -7439,13 +7481,13 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392,
-        1400, 1408, 1416, 1424, -1,   -1,   -1,   -1,   1432, 1440, -1,
-        -1,   1448, 1456, 1464, -1,   -1,   -1,   -1,   -1,   -1};
+        1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+        1392, 1400, 1408, 1416, -1,   -1,   -1,   -1,   1424, 1432, -1,
+        -1,   1440, 1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
-static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
@@ -7453,7 +7495,7 @@
 static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
 static constexpr dart::compiler::target::word
-    AOT_CompressedStackMaps_HeaderSize = 12;
+    AOT_CompressedStackMaps_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Context_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
 static constexpr dart::compiler::target::word AOT_ContextScope_InstanceSize =
@@ -7481,7 +7523,7 @@
 static constexpr dart::compiler::target::word AOT_ICData_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_Instructions_UnalignedHeaderSize = 12;
+    AOT_Instructions_UnalignedHeaderSize = 16;
 static constexpr dart::compiler::target::word
     AOT_InstructionsSection_UnalignedHeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
@@ -7516,10 +7558,8 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
-    32;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -7555,7 +7595,7 @@
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 12;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_ARM64)
 
 #endif  // !defined(PRODUCT)
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 2aa714c..bc52da9 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -54,6 +54,7 @@
   CONSTANT(String, kMaxElements)                                               \
   CONSTANT(SubtypeTestCache, kFunctionTypeArguments)                           \
   CONSTANT(SubtypeTestCache, kInstanceClassIdOrFunction)                       \
+  CONSTANT(SubtypeTestCache, kDestinationType)                                 \
   CONSTANT(SubtypeTestCache, kInstanceDelayedFunctionTypeArguments)            \
   CONSTANT(SubtypeTestCache, kInstanceParentFunctionTypeArguments)             \
   CONSTANT(SubtypeTestCache, kInstanceTypeArguments)                           \
@@ -180,7 +181,6 @@
   FIELD(Thread, allocate_object_slow_entry_point_offset)                       \
   FIELD(Thread, allocate_object_slow_stub_offset)                              \
   FIELD(Thread, api_top_scope_offset)                                          \
-  FIELD(Thread, async_stack_trace_offset)                                      \
   FIELD(Thread, auto_scope_native_wrapper_entry_point_offset)                  \
   FIELD(Thread, bool_false_offset)                                             \
   FIELD(Thread, bool_true_offset)                                              \
@@ -266,6 +266,7 @@
   FIELD(Type, nullability_offset)                                              \
   FIELD(TypeParameter, parameterized_class_id_offset)                          \
   FIELD(TypeParameter, index_offset)                                           \
+  FIELD(TypeParameter, nullability_offset)                                     \
   FIELD(TypeArguments, instantiations_offset)                                  \
   FIELD(TypeArguments, length_offset)                                          \
   FIELD(TypeArguments, nullability_offset)                                     \
@@ -284,6 +285,8 @@
   FIELD(MonomorphicSmiableCall, expected_cid_offset)                           \
   FIELD(MonomorphicSmiableCall, entrypoint_offset)                             \
   FIELD(MonomorphicSmiableCall, target_offset)                                 \
+  FIELD(WeakProperty, key_offset)                                              \
+  FIELD(WeakProperty, value_offset)                                            \
   ARRAY(Array, element_offset)                                                 \
   ARRAY(TypeArguments, type_at_offset)                                         \
   NOT_IN_PRODUCT(ARRAY(ClassTable, ClassOffsetFor))                            \
@@ -348,7 +351,6 @@
   SIZEOF(PcDescriptors, HeaderSize, PcDescriptorsLayout)                       \
   SIZEOF(Pointer, InstanceSize, PointerLayout)                                 \
   SIZEOF(ReceivePort, InstanceSize, ReceivePortLayout)                         \
-  SIZEOF(RedirectionData, InstanceSize, RedirectionDataLayout)                 \
   SIZEOF(RegExp, InstanceSize, RegExpLayout)                                   \
   SIZEOF(Script, InstanceSize, ScriptLayout)                                   \
   SIZEOF(SendPort, InstanceSize, SendPortLayout)                               \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 4376d54..8295e00 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -12,6 +12,7 @@
 
 #include "vm/compiler/stub_code_compiler.h"
 
+#include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
 
 #define __ assembler->
@@ -120,7 +121,7 @@
     __ Bind(&throw_exception);
     __ PushObject(NullObject());  // Make room for (unused) result.
     __ PushRegister(kFieldReg);
-    __ CallRuntime(kLateInitializationErrorRuntimeEntry,
+    __ CallRuntime(kLateFieldAssignedDuringInitializationErrorRuntimeEntry,
                    /*argument_count=*/1);
     __ Breakpoint();
   }
@@ -183,11 +184,487 @@
   __ PushRegister(TypeTestABI::kSubtypeTestCacheReg);
   __ CallRuntime(kInstanceofRuntimeEntry, /*argument_count=*/5);
   __ Drop(5);
-  __ PopRegister(TypeTestABI::kResultReg);
+  __ PopRegister(TypeTestABI::kInstanceOfResultReg);
   __ LeaveStubFrame();
   __ Ret();
 }
 
+// For use in GenerateTypeIsTopTypeForSubtyping and
+// GenerateNullIsAssignableToType.
+static void EnsureIsTypeOrTypeParameter(Assembler* assembler,
+                                        Register type_reg,
+                                        Register scratch_reg) {
+#if defined(DEBUG)
+  compiler::Label is_type_param_or_type;
+  __ LoadClassIdMayBeSmi(scratch_reg, type_reg);
+  __ CompareImmediate(scratch_reg, kTypeParameterCid);
+  __ BranchIf(EQUAL, &is_type_param_or_type, compiler::Assembler::kNearJump);
+  __ CompareImmediate(scratch_reg, kTypeCid);
+  __ BranchIf(EQUAL, &is_type_param_or_type, compiler::Assembler::kNearJump);
+  // Type references show up in F-bounded polymorphism, which is limited
+  // to classes. Thus, TypeRefs only appear in places like class type
+  // arguments or the bounds of uninstantiated class type parameters.
+  //
+  // Since this stub is currently used only by the dynamic versions of
+  // AssertSubtype and AssertAssignable, where kDstType is either the bound of
+  // a function type parameter or the type of a function parameter
+  // (respectively), we should never see a TypeRef here. This check is here
+  // in case this changes and we need to update this stub.
+  __ Stop("not a type or type parameter");
+  __ Bind(&is_type_param_or_type);
+#endif
+}
+
+// Version of AbstractType::IsTopTypeForSubtyping() used when the type is not
+// known at compile time. Must be kept in sync.
+//
+// Inputs:
+// - TypeTestABI::kDstTypeReg: Destination type.
+//
+// Non-preserved scratch registers:
+// - TypeTestABI::kScratchReg (only on non-IA32 architectures)
+//
+// Outputs:
+// - TypeTestABI::kSubtypeTestCacheReg: 0 if the value is guaranteed assignable,
+//   non-zero otherwise.
+//
+// All registers other than outputs and non-preserved scratches are preserved.
+static void GenerateTypeIsTopTypeForSubtyping(Assembler* assembler,
+                                              bool null_safety) {
+  // The only case where the original value of kSubtypeTestCacheReg is needed
+  // after the stub call is on IA32, where it's currently preserved on the stack
+  // before calling the stub (as it's also CODE_REG on that architecture), so we
+  // both use it as a scratch and clobber it for the return value.
+  const Register scratch1_reg = TypeTestABI::kSubtypeTestCacheReg;
+  // We reuse the first scratch register as the output register because we're
+  // always guaranteed to have a type in it (starting with kDstType), and all
+  // non-Smi ObjectPtrs are non-zero values.
+  const Register output_reg = scratch1_reg;
+#if defined(TARGET_ARCH_IA32)
+  // The remaining scratch registers are preserved and restored before exit on
+  // IA32. Because  we have few registers to choose from (which are all used in
+  // TypeTestABI), use specific TestTypeABI registers.
+  const Register scratch2_reg = TypeTestABI::kFunctionTypeArgumentsReg;
+  // Preserve non-output scratch registers.
+  __ PushRegister(scratch2_reg);
+#else
+  const Register scratch2_reg = TypeTestABI::kScratchReg;
+#endif
+  static_assert(scratch1_reg != scratch2_reg,
+                "both scratch registers are the same");
+
+  compiler::Label check_top_type, is_top_type, done;
+  // Initialize scratch1_reg with the type to check (which also sets the
+  // output register to a non-zero value). scratch1_reg (and thus the output
+  // register) will always have a type in it from here on out.
+  __ MoveRegister(scratch1_reg, TypeTestABI::kDstTypeReg);
+  __ Bind(&check_top_type);
+  // scratch1_reg: Current type to check.
+  EnsureIsTypeOrTypeParameter(assembler, scratch1_reg, scratch2_reg);
+  compiler::Label is_type_ref;
+  __ CompareClassId(scratch1_reg, kTypeParameterCid, scratch2_reg);
+  // Type parameters can't be top types themselves, though a particular
+  // instantiation may result in a top type.
+  __ BranchIf(EQUAL, &done);
+  __ LoadField(
+      scratch2_reg,
+      compiler::FieldAddress(scratch1_reg,
+                             compiler::target::Type::type_class_id_offset()));
+  __ SmiUntag(scratch2_reg);
+  __ CompareImmediate(scratch2_reg, kDynamicCid);
+  __ BranchIf(EQUAL, &is_top_type, compiler::Assembler::kNearJump);
+  __ CompareImmediate(scratch2_reg, kVoidCid);
+  __ BranchIf(EQUAL, &is_top_type, compiler::Assembler::kNearJump);
+  compiler::Label unwrap_future_or;
+  __ CompareImmediate(scratch2_reg, kFutureOrCid);
+  __ BranchIf(EQUAL, &unwrap_future_or, compiler::Assembler::kNearJump);
+  __ CompareImmediate(scratch2_reg, kInstanceCid);
+  __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
+  if (null_safety) {
+    // Instance type isn't a top type if non-nullable in null safe mode.
+    __ CompareTypeNullabilityWith(
+        scratch1_reg, static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(EQUAL, &done, compiler::Assembler::kNearJump);
+  }
+  __ Bind(&is_top_type);
+  __ LoadImmediate(output_reg, 0);
+  __ Bind(&done);
+#if defined(TARGET_ARCH_IA32)
+  // Restore preserved scratch registers.
+  __ PopRegister(scratch2_reg);
+#endif
+  __ Ret();
+  // An uncommon case, so off the main trunk of the function.
+  __ Bind(&unwrap_future_or);
+  __ LoadField(scratch2_reg,
+               compiler::FieldAddress(
+                   scratch1_reg, compiler::target::Type::arguments_offset()));
+  __ CompareObject(scratch2_reg, Object::null_object());
+  // If the arguments are null, then unwrapping gives dynamic, a top type.
+  __ BranchIf(EQUAL, &is_top_type, compiler::Assembler::kNearJump);
+  __ LoadField(
+      scratch1_reg,
+      compiler::FieldAddress(
+          scratch2_reg, compiler::target::TypeArguments::type_at_offset(0)));
+  __ Jump(&check_top_type, compiler::Assembler::kNearJump);
+}
+
+void StubCodeCompiler::GenerateTypeIsTopTypeForSubtypingStub(
+    Assembler* assembler) {
+  GenerateTypeIsTopTypeForSubtyping(assembler,
+                                    /*null_safety=*/false);
+}
+
+void StubCodeCompiler::GenerateTypeIsTopTypeForSubtypingNullSafeStub(
+    Assembler* assembler) {
+  GenerateTypeIsTopTypeForSubtyping(assembler,
+                                    /*null_safety=*/true);
+}
+
+// Version of Instance::NullIsAssignableTo() used when the destination type is
+// not known at compile time. Must be kept in sync.
+//
+// Inputs:
+// - TypeTestABI::kInstanceReg: Object to check for assignability.
+// - TypeTestABI::kDstTypeReg: Destination type.
+//
+// Non-preserved non-output scratch registers:
+// - TypeTestABI::kScratchReg (only on non-IA32 architectures)
+//
+// Outputs:
+// - TypeTestABI::kSubtypeTestCacheReg: 0 if the value is guaranteed assignable,
+//   non-zero otherwise.
+//
+// All registers other than outputs and non-preserved scratches are preserved.
+static void GenerateNullIsAssignableToType(Assembler* assembler,
+                                           bool null_safety) {
+  // The only case where the original value of kSubtypeTestCacheReg is needed
+  // after the stub call is on IA32, where it's currently preserved on the stack
+  // before calling the stub (as it's also CODE_REG on that architecture), so we
+  // both use it as a scratch and clobber it for the return value.
+  const Register scratch1_reg = TypeTestABI::kSubtypeTestCacheReg;
+  // We reuse the first scratch register as the output register because we're
+  // always guaranteed to have a type in it (starting with kDstType), and all
+  // non-Smi ObjectPtrs are non-zero values.
+  const Register output_reg = scratch1_reg;
+#if defined(TARGET_ARCH_IA32)
+  // The remaining scratch registers are preserved and restored before exit on
+  // IA32. Because  we have few registers to choose from (which are all used in
+  // TypeTestABI), use specific TestTypeABI registers.
+  const Register scratch2_reg = TypeTestABI::kFunctionTypeArgumentsReg;
+  // Preserve non-output scratch registers.
+  __ PushRegister(scratch2_reg);
+#else
+  const Register scratch2_reg = TypeTestABI::kScratchReg;
+#endif
+  static_assert(scratch1_reg != scratch2_reg,
+                "code assumes distinct scratch registers");
+
+  compiler::Label is_assignable, done;
+  // Initialize the first scratch register (and thus the output register) with
+  // the destination type. We do this before the check to ensure the output
+  // register has a non-zero value if !null_safety and kInstanceReg is not null.
+  __ MoveRegister(scratch1_reg, TypeTestABI::kDstTypeReg);
+  __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
+  if (null_safety) {
+    compiler::Label check_null_assignable;
+    // Skip checking the type if not null.
+    __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
+    __ Bind(&check_null_assignable);
+    // scratch1_reg: Current type to check.
+    EnsureIsTypeOrTypeParameter(assembler, scratch1_reg, scratch2_reg);
+    compiler::Label is_not_type;
+    __ CompareClassId(scratch1_reg, kTypeCid, scratch2_reg);
+    __ BranchIf(NOT_EQUAL, &is_not_type, compiler::Assembler::kNearJump);
+    __ CompareTypeNullabilityWith(
+        scratch1_reg, static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(NOT_EQUAL, &is_assignable, compiler::Assembler::kNearJump);
+    // FutureOr is a special case because it may have the non-nullable bit set,
+    // but FutureOr<T> functions as the union of T and Future<T>, so it must be
+    // unwrapped to see if T is nullable.
+    __ LoadField(
+        scratch2_reg,
+        compiler::FieldAddress(scratch1_reg,
+                               compiler::target::Type::type_class_id_offset()));
+    __ SmiUntag(scratch2_reg);
+    __ CompareImmediate(scratch2_reg, kFutureOrCid);
+    __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
+    __ LoadField(scratch2_reg,
+                 compiler::FieldAddress(
+                     scratch1_reg, compiler::target::Type::arguments_offset()));
+    __ CompareObject(scratch2_reg, Object::null_object());
+    // If the arguments are null, then unwrapping gives the dynamic type,
+    // which can take null.
+    __ BranchIf(EQUAL, &is_assignable, compiler::Assembler::kNearJump);
+    __ LoadField(
+        scratch1_reg,
+        compiler::FieldAddress(
+            scratch2_reg, compiler::target::TypeArguments::type_at_offset(0)));
+    __ Jump(&check_null_assignable, compiler::Assembler::kNearJump);
+    __ Bind(&is_not_type);
+    // Null is assignable to a type parameter only if it is nullable.
+    __ LoadFieldFromOffset(
+        scratch2_reg, scratch1_reg,
+        compiler::target::TypeParameter::nullability_offset(), kByte);
+    __ CompareImmediate(scratch2_reg,
+                        static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(EQUAL, &done, compiler::Assembler::kNearJump);
+  } else {
+    // Null in non-null-safe mode is always assignable.
+    __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
+  }
+  __ Bind(&is_assignable);
+  __ LoadImmediate(output_reg, 0);
+  __ Bind(&done);
+#if defined(TARGET_ARCH_IA32)
+  // Restore preserved scratch registers.
+  __ PopRegister(scratch2_reg);
+#endif
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateNullIsAssignableToTypeStub(
+    Assembler* assembler) {
+  GenerateNullIsAssignableToType(assembler,
+                                 /*null_safety=*/false);
+}
+
+void StubCodeCompiler::GenerateNullIsAssignableToTypeNullSafeStub(
+    Assembler* assembler) {
+  GenerateNullIsAssignableToType(assembler,
+                                 /*null_safety=*/true);
+}
+#if !defined(TARGET_ARCH_IA32)
+// The <X>TypeTestStubs are used to test whether a given value is of a given
+// type. All variants have the same calling convention:
+//
+// Inputs (from TypeTestABI struct):
+//   - kSubtypeTestCacheReg: RawSubtypeTestCache
+//   - kInstanceReg: instance to test against.
+//   - kInstantiatorTypeArgumentsReg : instantiator type arguments (if needed).
+//   - kFunctionTypeArgumentsReg : function type arguments (if needed).
+//
+// See GenerateSubtypeNTestCacheStub for registers that may need saving by the
+// caller.
+//
+// Output (from TypeTestABI struct):
+//   - kResultReg: checked instance.
+//
+// Throws if the check is unsuccessful.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  __ LoadFromOffset(CODE_REG, THR,
+                    target::Thread::slow_type_test_stub_offset());
+  __ Jump(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+}
+
+// Used instead of DefaultTypeTestStub when null is assignable.
+void StubCodeCompiler::GenerateDefaultNullableTypeTestStub(
+    Assembler* assembler) {
+  Label done;
+
+  // Fast case for 'null'.
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ LoadFromOffset(CODE_REG, THR,
+                    target::Thread::slow_type_test_stub_offset());
+  __ Jump(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+static void BuildTypeParameterTypeTestStub(Assembler* assembler,
+                                           bool allow_null) {
+  Label done;
+
+  if (allow_null) {
+    __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
+    __ BranchIf(EQUAL, &done, Assembler::kNearJump);
+  }
+
+  auto handle_case = [&](Register tav) {
+    // If the TAV is null, then resolving the type parameter gives the dynamic
+    // type, which is a top type.
+    __ CompareObject(tav, NullObject());
+    __ BranchIf(EQUAL, &done, Assembler::kNearJump);
+    // Resolve the type parameter to its instantiated type and tail call the
+    // instantiated type's TTS.
+    __ LoadFieldFromOffset(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg,
+                           target::TypeParameter::index_offset(), kTwoBytes);
+    __ LoadIndexedPayload(TypeTestABI::kScratchReg, tav,
+                          target::TypeArguments::types_offset(),
+                          TypeTestABI::kScratchReg, TIMES_WORD_SIZE);
+    __ Jump(FieldAddress(
+        TypeTestABI::kScratchReg,
+        target::AbstractType::type_test_stub_entry_point_offset()));
+  };
+
+  Label function_type_param;
+  __ LoadFieldFromOffset(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg,
+                         target::TypeParameter::parameterized_class_id_offset(),
+                         kUnsignedTwoBytes);
+  __ CompareImmediate(TypeTestABI::kScratchReg, kFunctionCid);
+  __ BranchIf(EQUAL, &function_type_param, Assembler::kNearJump);
+  handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ Bind(&function_type_param);
+  handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
+    Assembler* assembler) {
+  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
+}
+
+void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
+  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
+}
+
+static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
+                                            TypeCheckMode mode) {
+  __ PushObject(NullObject());  // Make room for result.
+  __ PushRegister(TypeTestABI::kInstanceReg);
+  __ PushRegister(TypeTestABI::kDstTypeReg);
+  __ PushRegister(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ PushRegister(TypeTestABI::kFunctionTypeArgumentsReg);
+  __ PushObject(NullObject());
+  __ PushRegister(TypeTestABI::kSubtypeTestCacheReg);
+  __ PushImmediate(target::ToRawSmi(mode));
+  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
+  __ Drop(1);  // mode
+  __ PopRegister(TypeTestABI::kSubtypeTestCacheReg);
+  __ Drop(1);  // dst_name
+  __ PopRegister(TypeTestABI::kFunctionTypeArgumentsReg);
+  __ PopRegister(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ PopRegister(TypeTestABI::kDstTypeReg);
+  __ PopRegister(TypeTestABI::kInstanceReg);
+  __ Drop(1);  // Discard return value.
+}
+
+void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
+    Assembler* assembler) {
+  __ LoadFromOffset(CODE_REG, THR,
+                    target::Thread::lazy_specialize_type_test_stub_offset());
+  __ EnterStubFrame();
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+// Used instead of LazySpecializeTypeTestStub when null is assignable.
+void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
+    Assembler* assembler) {
+  Label done;
+
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ LoadFromOffset(CODE_REG, THR,
+                    target::Thread::lazy_specialize_type_test_stub_offset());
+  __ EnterStubFrame();
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
+  __ LeaveStubFrame();
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ LoadFromOffset(CODE_REG, THR,
+                      target::Thread::slow_type_test_stub_offset());
+  }
+  __ EnterStubFrame();
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
+  __ BranchIf(EQUAL, &call_runtime, Assembler::kNearJump);
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple_case, is_complex_case;
+  __ LoadClassId(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg);
+  __ CompareImmediate(TypeTestABI::kScratchReg, kTypeCid);
+  __ BranchIf(NOT_EQUAL, &is_complex_case, Assembler::kNearJump);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ LoadFieldFromOffset(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg,
+                         target::Type::type_state_offset(), kByte);
+  __ CompareImmediate(
+      TypeTestABI::kScratchReg,
+      target::AbstractTypeLayout::kTypeStateFinalizedInstantiated);
+  __ BranchIf(NOT_EQUAL, &is_complex_case, Assembler::kNearJump);
+
+  // Check whether this [Type] is a function type.
+  __ LoadFieldFromOffset(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg,
+                         target::Type::signature_offset());
+  __ CompareObject(TypeTestABI::kScratchReg, NullObject());
+  __ BranchIf(NOT_EQUAL, &is_complex_case, Assembler::kNearJump);
+
+  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
+  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
+
+  // Fall through to &is_simple_case
+
+  const RegisterSet caller_saved_registers(
+      TypeTestABI::kSubtypeTestCacheStubCallerSavedRegisters);
+
+  __ Bind(&is_simple_case);
+  {
+    __ PushRegisters(caller_saved_registers);
+    __ Call(StubCodeSubtype3TestCache());
+    __ CompareObject(TypeTestABI::kSubtypeTestCacheResultReg,
+                     CastHandle<Object>(TrueObject()));
+    __ PopRegisters(caller_saved_registers);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime, Assembler::kNearJump);
+  }
+
+  __ Bind(&is_complex_case);
+  {
+    __ PushRegisters(caller_saved_registers);
+    __ Call(StubCodeSubtype7TestCache());
+    __ CompareObject(TypeTestABI::kSubtypeTestCacheResultReg,
+                     CastHandle<Object>(TrueObject()));
+    __ PopRegisters(caller_saved_registers);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
+
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+#else
+// Type testing stubs are not implemented on IA32.
+#define GENERATE_BREAKPOINT_STUB(Name)                                         \
+  void StubCodeCompiler::Generate##Name##Stub(Assembler* assembler) {          \
+    __ Breakpoint();                                                           \
+  }
+
+VM_TYPE_TESTING_STUB_CODE_LIST(GENERATE_BREAKPOINT_STUB)
+
+#undef GENERATE_BREAKPOINT_STUB
+#endif  // !defined(TARGET_ARCH_IA32)
+
 // The UnhandledException class lives in the VM isolate, so it cannot cache
 // an allocation stub for itself. Instead, we cache it in the stub code list.
 void StubCodeCompiler::GenerateAllocateUnhandledExceptionStub(
@@ -215,7 +692,8 @@
                                                        bool with_fpu_regs) {
   auto perform_runtime_call = [&]() {
     __ PushRegister(LateInitializationErrorABI::kFieldReg);
-    __ CallRuntime(kLateInitializationErrorRuntimeEntry, /*argument_count=*/1);
+    __ CallRuntime(kLateFieldNotInitializedErrorRuntimeEntry,
+                   /*argument_count=*/1);
   };
   GenerateSharedStubGeneric(
       assembler, /*save_fpu_registers=*/with_fpu_regs,
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 141f378..44b632d 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -84,18 +84,17 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ StoreToOffset(kWord, FP, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
 
   // Mark that the thread exited generated code through a runtime call.
   __ LoadImmediate(R8, target::Thread::exit_through_runtime_call());
-  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+  __ StoreToOffset(R8, THR, target::Thread::exit_through_ffi_offset());
 
 #if defined(DEBUG)
   {
     Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset());
+    __ LoadFromOffset(R8, THR, target::Thread::vm_tag_offset());
     __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -104,7 +103,7 @@
 #endif
 
   // Mark that the thread is executing VM code.
-  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R9, THR, target::Thread::vm_tag_offset());
 
   // Reserve space for arguments and align frame before entering C++ world.
   // target::NativeArguments are passed in registers.
@@ -138,15 +137,14 @@
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
 
   // Mark that the thread has not exited generated Dart code.
   __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR, target::Thread::exit_through_ffi_offset());
+  __ StoreToOffset(R2, THR, target::Thread::exit_through_ffi_offset());
 
   // Reset exit frame information in Isolate's mutator thread structure.
-  __ StoreToOffset(kWord, R2, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(R2, THR, target::Thread::top_exit_frame_info_offset());
 
   // Restore the global object pool after returning from runtime (old space is
   // moving, so the GOP could have been relocated).
@@ -352,7 +350,7 @@
 //   NOTFP, R4: clobbered, although normally callee-saved
 void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
     Assembler* assembler) {
-  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R4)) != 0);
+  COMPILE_ASSERT(IsAbiPreservedRegister(R4));
 
   // TransitionGeneratedToNative might clobber LR if it takes the slow path.
   __ mov(R4, Operand(LR));
@@ -447,9 +445,8 @@
   COMPILE_ASSERT(!IsArgumentRegister(R8));
 
   // Load the code object.
-  __ LoadFromOffset(kWord, R5, THR,
-                    compiler::target::Thread::callback_code_offset());
-  __ LoadFieldFromOffset(kWord, R5, R5,
+  __ LoadFromOffset(R5, THR, compiler::target::Thread::callback_code_offset());
+  __ LoadFieldFromOffset(R5, R5,
                          compiler::target::GrowableObjectArray::data_offset());
   __ ldr(R5, __ ElementAddressForRegIndex(
                  /*is_load=*/true,
@@ -459,8 +456,7 @@
                  /*index_unboxed=*/false,
                  /*array=*/R5,
                  /*index=*/R4));
-  __ LoadFieldFromOffset(kWord, R5, R5,
-                         compiler::target::Code::entry_point_offset());
+  __ LoadFieldFromOffset(R5, R5, compiler::target::Code::entry_point_offset());
 
   // On entry to the function, there will be four extra slots on the stack:
   // saved THR, R4, R5 and the return address. The target will know to skip
@@ -528,18 +524,17 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(kWord, FP, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
 
   // Mark that the thread exited generated code through a runtime call.
   __ LoadImmediate(R8, target::Thread::exit_through_runtime_call());
-  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+  __ StoreToOffset(R8, THR, target::Thread::exit_through_ffi_offset());
 
 #if defined(DEBUG)
   {
     Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset());
+    __ LoadFromOffset(R8, THR, target::Thread::vm_tag_offset());
     __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -548,7 +543,7 @@
 #endif
 
   // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R9, THR, target::Thread::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -588,15 +583,14 @@
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
 
   // Mark that the thread has not exited generated Dart code.
   __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR, target::Thread::exit_through_ffi_offset());
+  __ StoreToOffset(R2, THR, target::Thread::exit_through_ffi_offset());
 
   // Reset exit frame information in Isolate's mutator thread structure.
-  __ StoreToOffset(kWord, R2, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(R2, THR, target::Thread::top_exit_frame_info_offset());
 
   // Restore the global object pool after returning from runtime (old space is
   // moving, so the GOP could have been relocated).
@@ -1071,7 +1065,7 @@
 
       // Get the class index and insert it into the tags.
       // R8: size and bit tags.
-      const uint32_t tags =
+      const uword tags =
           target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
       __ LoadImmediate(TMP, tags);
       __ orr(R8, R8, Operand(TMP));
@@ -1197,25 +1191,23 @@
 #endif
 
   // Save the current VMTag on the stack.
-  __ LoadFromOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+  __ LoadFromOffset(R9, THR, target::Thread::vm_tag_offset());
   __ Push(R9);
 
   // Save top resource and top exit frame info. Use R4-6 as temporary registers.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(kWord, R4, THR, target::Thread::top_resource_offset());
+  __ LoadFromOffset(R4, THR, target::Thread::top_resource_offset());
   __ Push(R4);
   __ LoadImmediate(R8, 0);
-  __ StoreToOffset(kWord, R8, THR, target::Thread::top_resource_offset());
+  __ StoreToOffset(R8, THR, target::Thread::top_resource_offset());
 
-  __ LoadFromOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+  __ LoadFromOffset(R8, THR, target::Thread::exit_through_ffi_offset());
   __ Push(R8);
   __ LoadImmediate(R8, 0);
-  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+  __ StoreToOffset(R8, THR, target::Thread::exit_through_ffi_offset());
 
-  __ LoadFromOffset(kWord, R9, THR,
-                    target::Thread::top_exit_frame_info_offset());
-  __ StoreToOffset(kWord, R8, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ LoadFromOffset(R9, THR, target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(R8, THR, target::Thread::top_exit_frame_info_offset());
 
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
@@ -1231,7 +1223,7 @@
   // Mark that the thread is executing Dart code. Do this after initializing the
   // exit link for the profiler.
   __ LoadImmediate(R9, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R9, THR, target::Thread::vm_tag_offset());
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
   __ ldr(R4, Address(R1, target::VMHandles::kOffsetOfRawPtrInHandle));
@@ -1282,16 +1274,15 @@
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure. Uses R9 as a temporary register for this.
   __ Pop(R9);
-  __ StoreToOffset(kWord, R9, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(R9, THR, target::Thread::top_exit_frame_info_offset());
   __ Pop(R9);
-  __ StoreToOffset(kWord, R9, THR, target::Thread::exit_through_ffi_offset());
+  __ StoreToOffset(R9, THR, target::Thread::exit_through_ffi_offset());
   __ Pop(R9);
-  __ StoreToOffset(kWord, R9, THR, target::Thread::top_resource_offset());
+  __ StoreToOffset(R9, THR, target::Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
   __ Pop(R4);
-  __ StoreToOffset(kWord, R4, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R4, THR, target::Thread::vm_tag_offset());
 
 #if defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
@@ -1365,7 +1356,7 @@
 
   // Get the class index and insert it into the tags.
   // R9: size and bit tags.
-  const uint32_t tags =
+  const uword tags =
       target::MakeTagWordForNewSpaceObject(kContextCid, /*instance_size=*/0);
 
   __ LoadImmediate(IP, tags);
@@ -1884,7 +1875,7 @@
   ASSERT(instance_size > 0);
   RELEASE_ASSERT(target::Heap::IsAllocatableInNewSpace(instance_size));
 
-  const uint32_t tags =
+  const uword tags =
       target::MakeTagWordForNewSpaceObject(cls_id, instance_size);
 
   // Note: Keep in sync with helper function.
@@ -2082,7 +2073,7 @@
     // Update counter, ignore overflow.
     const intptr_t count_offset =
         target::ICData::CountIndexFor(num_args) * target::kWordSize;
-    __ LoadFromOffset(kWord, R1, R8, count_offset);
+    __ LoadFromOffset(R1, R8, count_offset);
     __ adds(R1, R1, Operand(target::ToRawSmi(1)));
     __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
@@ -2274,7 +2265,7 @@
   __ PushList(regs);
   // Push call arguments.
   for (intptr_t i = 0; i < num_args; i++) {
-    __ LoadFromOffset(kWord, TMP, R1, -i * target::kWordSize);
+    __ LoadFromOffset(TMP, R1, -i * target::kWordSize);
     __ Push(TMP);
   }
   // Pass IC data object.
@@ -2303,11 +2294,11 @@
       target::ICData::TargetIndexFor(num_args) * target::kWordSize;
   const intptr_t count_offset =
       target::ICData::CountIndexFor(num_args) * target::kWordSize;
-  __ LoadFromOffset(kWord, R0, R8, kIcDataOffset + target_offset);
+  __ LoadFromOffset(R0, R8, kIcDataOffset + target_offset);
 
   if (FLAG_optimization_counter_threshold >= 0) {
     __ Comment("Update caller's counter");
-    __ LoadFromOffset(kWord, R1, R8, kIcDataOffset + count_offset);
+    __ LoadFromOffset(R1, R8, kIcDataOffset + count_offset);
     // Ignore overflow.
     __ adds(R1, R1, Operand(target::ToRawSmi(1)));
     __ StoreIntoSmiField(Address(R8, kIcDataOffset + count_offset), R1);
@@ -2482,7 +2473,7 @@
 
   if (FLAG_optimization_counter_threshold >= 0) {
     // Increment count for this call, ignore overflow.
-    __ LoadFromOffset(kWord, R1, R8, count_offset);
+    __ LoadFromOffset(R1, R8, count_offset);
     __ adds(R1, R1, Operand(target::ToRawSmi(1)));
     __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
@@ -2492,7 +2483,7 @@
          FieldAddress(R9, target::CallSiteData::arguments_descriptor_offset()));
 
   // Get function and call it, if possible.
-  __ LoadFromOffset(kWord, R0, R8, target_offset);
+  __ LoadFromOffset(R0, R8, target_offset);
   __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
 
   __ Branch(Address(R0, R3));
@@ -2617,41 +2608,57 @@
 }
 
 // Used to check class and type arguments. Arguments passed in registers:
-// LR: return address.
-// R0: instance (must be preserved).
-// R2: instantiator type arguments (only if n >= 4, can be raw_null).
-// R1: function type arguments (only if n >= 4, can be raw_null).
-// R3: target::SubtypeTestCache.
 //
-// Preserves R0/R2.
-// Preserves NOTFP with bare instructions and CODE_REG without.
+// Inputs (mostly from TypeTestABI struct):
+//   - kSubtypeTestCacheReg: SubtypeTestCacheLayout
+//   - kInstanceReg: instance to test against.
+//   - kDstTypeReg: destination type (for n>=3).
+//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n=5).
+//   - kFunctionTypeArgumentsReg: function type arguments (for n=5).
+//   - LR: return address.
 //
-// Result in R1: null -> not found, otherwise result (true or false).
+// All TypeTestABI registers are preserved but kSubtypeTestCacheReg, which must
+// be saved by the caller if the original value is needed after the call.
+//
+// Result in SubtypeTestCacheABI::kResultReg: null -> not found, otherwise
+// result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
 
-  const Register kInstanceCidOrFunction = R8;
-  const Register kInstanceInstantiatorTypeArgumentsReg = R4;
-  const Register kInstanceDelayedFunctionTypeArgumentsReg = PP;
+  // Safe as the original value of TypeTestABI::kSubtypeTestCacheReg is only
+  // used to initialize this register.
+  const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheReg;
+  const Register kScratchReg = TypeTestABI::kScratchReg;
+  const Register kInstanceCidOrFunction = R9;
+  // Registers that are only used for n >= 3 and must be preserved if used.
+  Register kInstanceInstantiatorTypeArgumentsReg = kNoRegister;
+  // Registers that are only used for n >= 7 and must be preserved if used.
+  Register kInstanceParentFunctionTypeArgumentsReg = kNoRegister;
+  // There is no register for InstanceDelayedFunctionTypeArguments, it is
+  // instead placed on the stack and pulled into TMP for comparison against
+  // the corresponding slot in the current cache entry.
 
-  Register kInstanceParentFunctionTypeArgumentsReg;
-  Register kNullReg;
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    // NOTFP must be preserved, but CODE_REG can be freely used.
-    kInstanceParentFunctionTypeArgumentsReg = NOTFP;
-    kNullReg = CODE_REG;
-  } else {
-    // CODE_REG must be preserved, but NOTFP can be freely used.
-    kInstanceParentFunctionTypeArgumentsReg = CODE_REG;
-    kNullReg = NOTFP;
-  }
-
+  // NOTFP must be preserved for bare payloads, otherwise CODE_REG.
+  const bool use_bare_payloads =
+      FLAG_precompiled_mode && FLAG_use_bare_instructions;
+  // For this, we choose the register that need not be preserved of the pair.
+  const Register kNullReg = use_bare_payloads ? CODE_REG : NOTFP;
   __ LoadObject(kNullReg, NullObject());
 
-  // Free up these 2 registers to be used for 6-value test.
-  if (n >= 6) {
-    __ PushList(1 << kInstanceParentFunctionTypeArgumentsReg |
-                1 << kInstanceDelayedFunctionTypeArgumentsReg);
+  // Free up registers to be used if performing a 3, 5, or 7 value test.
+  RegList pushed_registers = 0;
+  if (n >= 3) {
+    kInstanceInstantiatorTypeArgumentsReg = PP;
+    pushed_registers |= 1 << kInstanceInstantiatorTypeArgumentsReg;
+  }
+  if (n >= 7) {
+    // For this, we choose the register that must be preserved of the pair.
+    kInstanceParentFunctionTypeArgumentsReg =
+        use_bare_payloads ? NOTFP : CODE_REG;
+    pushed_registers |= 1 << kInstanceParentFunctionTypeArgumentsReg;
+  }
+  if (pushed_registers != 0) {
+    __ PushList(pushed_registers);
   }
 
   // Loop initialization (moved up here to avoid having all dependent loads
@@ -2659,14 +2666,14 @@
 
   // We avoid a load-acquire barrier here by relying on the fact that all other
   // loads from the array are data-dependent loads.
-  __ ldr(TypeTestABI::kSubtypeTestCacheReg,
+  __ ldr(kCacheArrayReg,
          FieldAddress(TypeTestABI::kSubtypeTestCacheReg,
                       target::SubtypeTestCache::cache_offset()));
-  __ AddImmediate(TypeTestABI::kSubtypeTestCacheReg,
+  __ AddImmediate(kCacheArrayReg,
                   target::Array::data_offset() - kHeapObjectTag);
 
   Label loop, not_closure;
-  if (n >= 4) {
+  if (n >= 5) {
     __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
   } else {
     __ LoadClassId(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
@@ -2679,19 +2686,19 @@
     __ ldr(kInstanceCidOrFunction,
            FieldAddress(TypeTestABI::kInstanceReg,
                         target::Closure::function_offset()));
-    if (n >= 2) {
+    if (n >= 3) {
       __ ldr(
           kInstanceInstantiatorTypeArgumentsReg,
           FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        ASSERT(n == 6);
+      if (n >= 7) {
         __ ldr(kInstanceParentFunctionTypeArgumentsReg,
                FieldAddress(TypeTestABI::kInstanceReg,
                             target::Closure::function_type_arguments_offset()));
-        __ ldr(kInstanceDelayedFunctionTypeArgumentsReg,
+        __ ldr(kScratchReg,
                FieldAddress(TypeTestABI::kInstanceReg,
                             target::Closure::delayed_type_arguments_offset()));
+        __ PushRegister(kScratchReg);
       }
     }
     __ b(&loop);
@@ -2700,103 +2707,126 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n >= 2) {
+    if (n >= 3) {
       Label has_no_type_arguments;
-      __ LoadClassById(R9, kInstanceCidOrFunction);
+      __ LoadClassById(kScratchReg, kInstanceCidOrFunction);
       __ mov(kInstanceInstantiatorTypeArgumentsReg, Operand(kNullReg));
-      __ ldr(R9,
-             FieldAddress(
-                 R9, target::Class::
-                         host_type_arguments_field_offset_in_words_offset()));
-      __ CompareImmediate(R9, target::Class::kNoTypeArguments);
+      __ ldr(
+          kScratchReg,
+          FieldAddress(kScratchReg,
+                       target::Class::
+                           host_type_arguments_field_offset_in_words_offset()));
+      __ CompareImmediate(kScratchReg, target::Class::kNoTypeArguments);
       __ b(&has_no_type_arguments, EQ);
-      __ add(R9, TypeTestABI::kInstanceReg, Operand(R9, LSL, 2));
-      __ ldr(kInstanceInstantiatorTypeArgumentsReg, FieldAddress(R9, 0));
+      __ add(kScratchReg, TypeTestABI::kInstanceReg,
+             Operand(kScratchReg, LSL, 2));
+      __ ldr(kInstanceInstantiatorTypeArgumentsReg,
+             FieldAddress(kScratchReg, 0));
       __ Bind(&has_no_type_arguments);
 
-      if (n >= 6) {
+      if (n >= 7) {
         __ mov(kInstanceParentFunctionTypeArgumentsReg, Operand(kNullReg));
-        __ mov(kInstanceDelayedFunctionTypeArgumentsReg, Operand(kNullReg));
+        __ PushRegister(kNullReg);
       }
     }
     __ SmiTag(kInstanceCidOrFunction);
   }
 
+  const intptr_t kNoDepth = -1;
+  const intptr_t kInstanceDelayedFunctionTypeArgumentsDepth =
+      n >= 7 ? 0 : kNoDepth;
+
   Label found, not_found, next_iteration;
 
   // Loop header.
   __ Bind(&loop);
-  __ ldr(R9, Address(TypeTestABI::kSubtypeTestCacheReg,
-                     target::kWordSize *
-                         target::SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmp(R9, Operand(kNullReg));
+  __ ldr(kScratchReg,
+         Address(kCacheArrayReg,
+                 target::kWordSize *
+                     target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmp(kScratchReg, Operand(kNullReg));
   __ b(&not_found, EQ);
-  __ cmp(R9, Operand(kInstanceCidOrFunction));
+  __ cmp(kScratchReg, Operand(kInstanceCidOrFunction));
   if (n == 1) {
     __ b(&found, EQ);
   } else {
     __ b(&next_iteration, NE);
-    __ ldr(R9, Address(TypeTestABI::kSubtypeTestCacheReg,
-                       target::kWordSize *
-                           target::SubtypeTestCache::kInstanceTypeArguments));
-    __ cmp(R9, Operand(kInstanceInstantiatorTypeArgumentsReg));
-    if (n == 2) {
+    __ ldr(kScratchReg,
+           Address(
+               kCacheArrayReg,
+               target::kWordSize * target::SubtypeTestCache::kDestinationType));
+    __ cmp(kScratchReg, Operand(TypeTestABI::kDstTypeReg));
+    __ b(&next_iteration, NE);
+    __ ldr(kScratchReg,
+           Address(kCacheArrayReg,
+                   target::kWordSize *
+                       target::SubtypeTestCache::kInstanceTypeArguments));
+    __ cmp(kScratchReg, Operand(kInstanceInstantiatorTypeArgumentsReg));
+    if (n == 3) {
       __ b(&found, EQ);
     } else {
       __ b(&next_iteration, NE);
-      __ ldr(R9,
-             Address(TypeTestABI::kSubtypeTestCacheReg,
+      __ ldr(kScratchReg,
+             Address(kCacheArrayReg,
                      target::kWordSize *
                          target::SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmp(R9, Operand(TypeTestABI::kInstantiatorTypeArgumentsReg));
+      __ cmp(kScratchReg, Operand(TypeTestABI::kInstantiatorTypeArgumentsReg));
       __ b(&next_iteration, NE);
-      __ ldr(R9, Address(TypeTestABI::kSubtypeTestCacheReg,
-                         target::kWordSize *
-                             target::SubtypeTestCache::kFunctionTypeArguments));
-      __ cmp(R9, Operand(TypeTestABI::kFunctionTypeArgumentsReg));
-      if (n == 4) {
+      __ ldr(kScratchReg,
+             Address(kCacheArrayReg,
+                     target::kWordSize *
+                         target::SubtypeTestCache::kFunctionTypeArguments));
+      __ cmp(kScratchReg, Operand(TypeTestABI::kFunctionTypeArgumentsReg));
+      if (n == 5) {
         __ b(&found, EQ);
       } else {
-        ASSERT(n == 6);
+        ASSERT(n == 7);
         __ b(&next_iteration, NE);
 
-        __ ldr(R9, Address(TypeTestABI::kSubtypeTestCacheReg,
-                           target::kWordSize *
-                               target::SubtypeTestCache::
-                                   kInstanceParentFunctionTypeArguments));
-        __ cmp(R9, Operand(kInstanceParentFunctionTypeArgumentsReg));
+        __ ldr(kScratchReg,
+               Address(kCacheArrayReg,
+                       target::kWordSize *
+                           target::SubtypeTestCache::
+                               kInstanceParentFunctionTypeArguments));
+        __ cmp(kScratchReg, Operand(kInstanceParentFunctionTypeArgumentsReg));
         __ b(&next_iteration, NE);
 
-        __ ldr(R9, Address(TypeTestABI::kSubtypeTestCacheReg,
-                           target::kWordSize *
-                               target::SubtypeTestCache::
-                                   kInstanceDelayedFunctionTypeArguments));
-        __ cmp(R9, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
+        __ ldr(kScratchReg,
+               Address(kCacheArrayReg,
+                       target::kWordSize *
+                           target::SubtypeTestCache::
+                               kInstanceDelayedFunctionTypeArguments));
+        __ CompareToStack(kScratchReg,
+                          kInstanceDelayedFunctionTypeArgumentsDepth);
         __ b(&found, EQ);
       }
     }
   }
   __ Bind(&next_iteration);
   __ AddImmediate(
-      TypeTestABI::kSubtypeTestCacheReg,
+      kCacheArrayReg,
       target::kWordSize * target::SubtypeTestCache::kTestEntryLength);
   __ b(&loop);
 
   __ Bind(&found);
-  __ ldr(R1,
-         Address(TypeTestABI::kSubtypeTestCacheReg,
+  __ ldr(TypeTestABI::kSubtypeTestCacheResultReg,
+         Address(kCacheArrayReg,
                  target::kWordSize * target::SubtypeTestCache::kTestResult));
-  if (n >= 6) {
-    __ PopList(1 << kInstanceParentFunctionTypeArgumentsReg |
-               1 << kInstanceDelayedFunctionTypeArgumentsReg);
+  if (n >= 7) {
+    __ Drop(1);  // delayed function type args.
+  }
+  if (pushed_registers != 0) {
+    __ PopList(pushed_registers);
   }
   __ Ret();
 
   __ Bind(&not_found);
-  __ mov(R1, Operand(kNullReg));
-  if (n >= 6) {
-    __ PopList(1 << kInstanceParentFunctionTypeArgumentsReg |
-               1 << kInstanceDelayedFunctionTypeArgumentsReg);
+  __ mov(TypeTestABI::kSubtypeTestCacheResultReg, Operand(kNullReg));
+  if (n >= 7) {
+    __ Drop(1);  // delayed function type args.
+  }
+  if (pushed_registers != 0) {
+    __ PopList(pushed_registers);
   }
   __ Ret();
 }
@@ -2807,238 +2837,18 @@
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
+void StubCodeCompiler::GenerateSubtype3TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 3);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
+void StubCodeCompiler::GenerateSubtype5TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 5);
 }
 
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-// Used to test whether a given value is of a given type (different variants,
-// all have the same calling convention).
-//
-// Inputs:
-//   - R0 : instance to test against.
-//   - R2 : instantiator type arguments (if needed).
-//   - R1 : function type arguments (if needed).
-//
-//   - R3 : subtype test cache.
-//
-//   - R8 : type to test against.
-//   - R4 : name of destination variable.
-//
-// Preserves R0/R2.
-//
-// Note of warning: The caller will not populate CODE_REG and we have therefore
-// no access to the pool.
-void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
-  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-}
-
-// Used instead of DefaultTypeTestStub when null is assignable.
-void StubCodeCompiler::GenerateDefaultNullableTypeTestStub(
-    Assembler* assembler) {
-  Label done;
-
-  // Fast case for 'null'.
-  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-  __ BranchIf(EQUAL, &done);
-
-  __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
-  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
-                                            TypeCheckMode mode) {
-  __ PushObject(NullObject());  // Make room for result.
-  __ Push(TypeTestABI::kInstanceReg);
-  __ Push(TypeTestABI::kDstTypeReg);
-  __ Push(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ Push(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ PushObject(NullObject());
-  __ Push(TypeTestABI::kSubtypeTestCacheReg);
-  __ PushImmediate(target::ToRawSmi(mode));
-  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
-  __ Drop(1);  // mode
-  __ Pop(TypeTestABI::kSubtypeTestCacheReg);
-  __ Drop(1);  // dst_name
-  __ Pop(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ Pop(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ Pop(TypeTestABI::kDstTypeReg);
-  __ Pop(TypeTestABI::kInstanceReg);
-  __ Drop(1);  // Discard return value.
-}
-
-void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
-    Assembler* assembler) {
-  __ ldr(CODE_REG,
-         Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Used instead of LazySpecializeTypeTestStub when null is assignable.
-void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
-    Assembler* assembler) {
-  Label done;
-
-  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-  __ BranchIf(EQUAL, &done);
-
-  __ ldr(CODE_REG,
-         Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-static void BuildTypeParameterTypeTestStub(Assembler* assembler,
-                                           bool allow_null) {
-  Label done;
-
-  if (allow_null) {
-    __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-    __ BranchIf(EQUAL, &done);
-  }
-
-  Label function_type_param;
-  __ ldrh(TypeTestABI::kScratchReg,
-          FieldAddress(TypeTestABI::kDstTypeReg,
-                       TypeParameter::parameterized_class_id_offset()));
-  __ cmp(TypeTestABI::kScratchReg, Operand(kFunctionCid));
-  __ BranchIf(EQUAL, &function_type_param);
-
-  auto handle_case = [&](Register tav) {
-    __ CompareObject(tav, NullObject());
-    __ BranchIf(EQUAL, &done);
-    __ ldrh(
-        TypeTestABI::kScratchReg,
-        FieldAddress(TypeTestABI::kDstTypeReg, TypeParameter::index_offset()));
-    __ add(TypeTestABI::kScratchReg, tav,
-           Operand(TypeTestABI::kScratchReg, LSL, 8));
-    __ ldr(TypeTestABI::kScratchReg,
-           FieldAddress(TypeTestABI::kScratchReg,
-                        target::TypeArguments::InstanceSize()));
-    __ Branch(FieldAddress(TypeTestABI::kScratchReg,
-                           AbstractType::type_test_stub_entry_point_offset()));
-  };
-
-  // Class type parameter: If dynamic we're done, otherwise dereference type
-  // parameter and tail call.
-  handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
-
-  // Function type parameter: If dynamic we're done, otherwise dereference type
-  // parameter and tail call.
-  __ Bind(&function_type_param);
-  handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
-    Assembler* assembler) {
-  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
-}
-
-void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
-  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
-}
-
-void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
-  Label done, call_runtime;
-
-  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    __ ldr(CODE_REG,
-           Address(THR, target::Thread::slow_type_test_stub_offset()));
-  }
-  __ EnterStubFrame();
-
-  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
-  __ BranchIf(EQUAL, &call_runtime);
-
-  const Register kTmp = R9;
-
-  // If this is not a [Type] object, we'll go to the runtime.
-  Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, TypeTestABI::kDstTypeReg);
-  __ cmp(kTmp, Operand(kTypeCid));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is instantiated/uninstantiated.
-  __ ldrb(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
-                             target::Type::type_state_offset()));
-  __ cmp(kTmp,
-         Operand(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is a function type.
-  __ ldr(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
-                            target::Type::signature_offset()));
-  __ CompareObject(kTmp, NullObject());
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
-
-  // Fall through to &is_simple_case
-
-  const intptr_t kRegsToSave = (1 << TypeTestABI::kSubtypeTestCacheReg) |
-                               (1 << TypeTestABI::kDstTypeReg) |
-                               (1 << TypeTestABI::kFunctionTypeArgumentsReg);
-
-  __ Bind(&is_simple_case);
-  {
-    __ PushList(kRegsToSave);
-    __ BranchLink(StubCodeSubtype2TestCache());
-    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
-    __ PopList(kRegsToSave);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    __ Jump(&call_runtime);
-  }
-
-  __ Bind(&is_complex_case);
-  {
-    __ PushList(kRegsToSave);
-    __ BranchLink(StubCodeSubtype6TestCache());
-    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
-    __ PopList(kRegsToSave);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    // Fall through to runtime_call
-  }
-
-  __ Bind(&call_runtime);
-
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
-
-  __ Bind(&done);
-  __ LeaveStubFrame();
-  __ Ret();
+// See comment on[GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype7TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 7);
 }
 
 // Return the current stack pointer address, used to do stack alignment checks.
@@ -3057,10 +2867,13 @@
 //
 // Notice: We need to keep this in sync with `Simulator::JumpToFrame()`.
 void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
-  ASSERT(kExceptionObjectReg == R0);
-  ASSERT(kStackTraceObjectReg == R1);
+  COMPILE_ASSERT(kExceptionObjectReg == R0);
+  COMPILE_ASSERT(kStackTraceObjectReg == R1);
+  COMPILE_ASSERT(IsAbiPreservedRegister(R4));
+  COMPILE_ASSERT(IsAbiPreservedRegister(THR));
   __ mov(IP, Operand(R1));   // Copy Stack pointer into IP.
-  __ mov(LR, Operand(R0));   // Program counter.
+  // TransitionGeneratedToNative might clobber LR if it takes the slow path.
+  __ mov(R4, Operand(R0));   // Program counter.
   __ mov(THR, Operand(R3));  // Thread.
   __ mov(FP, Operand(R2));   // Frame_pointer.
   __ mov(SP, Operand(IP));   // Set Stack pointer.
@@ -3070,7 +2883,7 @@
   Label exit_through_non_ffi;
   Register tmp1 = R0, tmp2 = R1;
   // Check if we exited generated from FFI. If so do transition.
-  __ LoadFromOffset(kWord, tmp1, THR,
+  __ LoadFromOffset(tmp1, THR,
                     compiler::target::Thread::exit_through_ffi_offset());
   __ LoadImmediate(tmp2, target::Thread::exit_through_ffi());
   __ cmp(tmp1, Operand(tmp2));
@@ -3081,11 +2894,10 @@
 
   // Set the tag.
   __ LoadImmediate(R2, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
   // Clear top exit frame.
   __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR,
-                   target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(R2, THR, target::Thread::top_exit_frame_info_offset());
   // Restore the pool pointer.
   __ RestoreCodePointer();
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
@@ -3094,7 +2906,7 @@
   } else {
     __ LoadPoolPointer();
   }
-  __ bx(LR);  // Jump to continuation point.
+  __ bx(R4);  // Jump to continuation point.
 }
 
 // Run an exception handler.  Execution comes from JumpToFrame
@@ -3103,20 +2915,20 @@
 // The arguments are stored in the Thread object.
 // Does not return.
 void StubCodeCompiler::GenerateRunExceptionHandlerStub(Assembler* assembler) {
-  __ LoadFromOffset(kWord, LR, THR, target::Thread::resume_pc_offset());
+  __ LoadFromOffset(LR, THR, target::Thread::resume_pc_offset());
 
   word offset_from_thread = 0;
   bool ok = target::CanLoadFromThread(NullObject(), &offset_from_thread);
   ASSERT(ok);
-  __ LoadFromOffset(kWord, R2, THR, offset_from_thread);
+  __ LoadFromOffset(R2, THR, offset_from_thread);
 
   // Exception object.
-  __ LoadFromOffset(kWord, R0, THR, target::Thread::active_exception_offset());
-  __ StoreToOffset(kWord, R2, THR, target::Thread::active_exception_offset());
+  __ LoadFromOffset(R0, THR, target::Thread::active_exception_offset());
+  __ StoreToOffset(R2, THR, target::Thread::active_exception_offset());
 
   // StackTrace object.
-  __ LoadFromOffset(kWord, R1, THR, target::Thread::active_stacktrace_offset());
-  __ StoreToOffset(kWord, R2, THR, target::Thread::active_stacktrace_offset());
+  __ LoadFromOffset(R1, THR, target::Thread::active_stacktrace_offset());
+  __ StoreToOffset(R2, THR, target::Thread::active_stacktrace_offset());
 
   __ bx(LR);  // Jump to the exception handler code.
 }
@@ -3130,7 +2942,7 @@
   __ Push(IP);
 
   // Load the deopt pc into LR.
-  __ LoadFromOffset(kWord, LR, THR, target::Thread::resume_pc_offset());
+  __ LoadFromOffset(LR, THR, target::Thread::resume_pc_offset());
   GenerateDeoptimizationSequence(assembler, kEagerDeopt);
 
   // After we have deoptimized, jump to the correct frame.
@@ -3676,8 +3488,7 @@
     __ mov(R3, Operand(0), HI);
 
     /* Get the class index and insert it into the tags. */
-    uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    uword tags = target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ LoadImmediate(TMP, tags);
     __ orr(R3, R3, Operand(TMP));
     __ str(R3, FieldAddress(R0, target::Object::tags_offset())); /* Tags. */
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index b749ad9..7168025 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -300,7 +300,7 @@
 //   Stack: preserved, CSP == SP
 void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
     Assembler* assembler) {
-  COMPILE_ASSERT((1 << R19) & kAbiPreservedCpuRegs);
+  COMPILE_ASSERT(IsAbiPreservedRegister(R19));
 
   __ mov(R19, LR);
   __ LoadImmediate(R10, target::Thread::exit_through_ffi());
@@ -470,7 +470,7 @@
 
   // Build type_arguments vector (or null)
   Label no_type_args;
-  __ ldr(R3, Address(THR, target::Thread::object_null_offset()), kDoubleWord);
+  __ ldr(R3, Address(THR, target::Thread::object_null_offset()), kEightBytes);
   __ cmp(R4, Operand(0));
   __ b(&no_type_args, EQ);
   __ ldr(R0, Address(FP, kReceiverOffset * target::kWordSize));
@@ -1195,7 +1195,7 @@
     __ csel(R1, ZR, R1, HI);
 
     // Get the class index and insert it into the tags.
-    const uint32_t tags =
+    const uword tags =
         target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
 
     __ LoadImmediate(TMP, tags);
@@ -1502,7 +1502,7 @@
 
   // Get the class index and insert it into the tags.
   // R2: size and bit tags.
-  const uint32_t tags =
+  const uword tags =
       target::MakeTagWordForNewSpaceObject(kContextCid, /*instance_size=*/0);
 
   __ LoadImmediate(TMP, tags);
@@ -1591,8 +1591,10 @@
     Label slow_case;
 
     // Load num. variable (int32) in the existing context.
-    __ ldr(R1, FieldAddress(R5, target::Context::num_variables_offset(), kWord),
-           kWord);
+    __ ldr(
+        R1,
+        FieldAddress(R5, target::Context::num_variables_offset(), kFourBytes),
+        kFourBytes);
 
     GenerateAllocateContextSpaceStub(assembler, &slow_case);
 
@@ -1693,12 +1695,12 @@
          target::ObjectAlignment::kNewObjectBitPosition);
 
   if (cards) {
-    __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
+    __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kFourBytes);
     __ tbnz(&remember_card, TMP, target::ObjectLayout::kCardRememberedBit);
   } else {
 #if defined(DEBUG)
     Label ok;
-    __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
+    __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kFourBytes);
     __ tbz(&ok, TMP, target::ObjectLayout::kCardRememberedBit);
     __ Stop("Wrong barrier");
     __ Bind(&ok);
@@ -1714,21 +1716,19 @@
   ASSERT(target::Object::tags_offset() == 0);
   __ sub(R3, R1, Operand(kHeapObjectTag));
   // R3: Untagged address of header word (ldxr/stxr do not support offsets).
-  // Note that we use 32 bit operations here to match the size of the
-  // background sweeper which is also manipulating this 32 bit word.
   Label retry;
   __ Bind(&retry);
-  __ ldxr(R2, R3, kWord);
+  __ ldxr(R2, R3, kEightBytes);
   __ AndImmediate(R2, R2,
                   ~(1 << target::ObjectLayout::kOldAndNotRememberedBit));
-  __ stxr(R4, R2, R3, kWord);
+  __ stxr(R4, R2, R3, kEightBytes);
   __ cbnz(&retry, R4);
 
   // Load the StoreBuffer block out of the thread. Then load top_ out of the
   // StoreBufferBlock and add the address to the pointers_.
   __ LoadFromOffset(R4, THR, target::Thread::store_buffer_block_offset());
   __ LoadFromOffset(R2, R4, target::StoreBufferBlock::top_offset(),
-                    kUnsignedWord);
+                    kUnsignedFourBytes);
   __ add(R3, R4, Operand(R2, LSL, target::kWordSizeLog2));
   __ StoreToOffset(R1, R3, target::StoreBufferBlock::pointers_offset());
 
@@ -1738,7 +1738,7 @@
   Label overflow;
   __ add(R2, R2, Operand(1));
   __ StoreToOffset(R2, R4, target::StoreBufferBlock::top_offset(),
-                   kUnsignedWord);
+                   kUnsignedFourBytes);
   __ CompareImmediate(R2, target::StoreBufferBlock::kSize);
   // Restore values.
   __ Pop(R4);
@@ -1764,27 +1764,25 @@
   __ Push(R4);  // Spill.
 
   // Atomically clear kOldAndNotMarkedBit.
-  // Note that we use 32 bit operations here to match the size of the
-  // background sweeper which is also manipulating this 32 bit word.
   Label marking_retry, lost_race, marking_overflow;
   ASSERT(target::Object::tags_offset() == 0);
   __ sub(R3, R0, Operand(kHeapObjectTag));
   // R3: Untagged address of header word (ldxr/stxr do not support offsets).
   __ Bind(&marking_retry);
-  __ ldxr(R2, R3, kWord);
+  __ ldxr(R2, R3, kEightBytes);
   __ tbz(&lost_race, R2, target::ObjectLayout::kOldAndNotMarkedBit);
   __ AndImmediate(R2, R2, ~(1 << target::ObjectLayout::kOldAndNotMarkedBit));
-  __ stxr(R4, R2, R3, kWord);
+  __ stxr(R4, R2, R3, kEightBytes);
   __ cbnz(&marking_retry, R4);
 
   __ LoadFromOffset(R4, THR, target::Thread::marking_stack_block_offset());
   __ LoadFromOffset(R2, R4, target::MarkingStackBlock::top_offset(),
-                    kUnsignedWord);
+                    kUnsignedFourBytes);
   __ add(R3, R4, Operand(R2, LSL, target::kWordSizeLog2));
   __ StoreToOffset(R0, R3, target::MarkingStackBlock::pointers_offset());
   __ add(R2, R2, Operand(1));
   __ StoreToOffset(R2, R4, target::MarkingStackBlock::top_offset(),
-                   kUnsignedWord);
+                   kUnsignedFourBytes);
   __ CompareImmediate(R2, target::MarkingStackBlock::kSize);
   __ Pop(R4);  // Unspill.
   __ Pop(R3);  // Unspill.
@@ -1923,7 +1921,7 @@
           FieldAddress(kTypeOffestReg,
                        target::Class::
                            host_type_arguments_field_offset_in_words_offset()),
-          kWord);
+          kFourBytes);
 
       // Set the type arguments in the new object.
       __ StoreIntoObjectNoBarrier(
@@ -2022,7 +2020,7 @@
   ASSERT(instance_size > 0);
   RELEASE_ASSERT(target::Heap::IsAllocatableInNewSpace(instance_size));
 
-  const uint32_t tags =
+  const uword tags =
       target::MakeTagWordForNewSpaceObject(cls_id, instance_size);
 
   // Note: Keep in sync with helper function.
@@ -2141,10 +2139,10 @@
     __ LeaveStubFrame();
   }
   __ LoadFieldFromOffset(R7, func_reg, target::Function::usage_counter_offset(),
-                         kWord);
+                         kFourBytes);
   __ add(R7, R7, Operand(1));
   __ StoreFieldToOffset(R7, func_reg, target::Function::usage_counter_offset(),
-                        kWord);
+                        kFourBytes);
 }
 
 // Loads function into 'temp_reg'.
@@ -2160,11 +2158,11 @@
     ASSERT(temp_reg == R6);
     __ Comment("Increment function counter");
     __ LoadFieldFromOffset(func_reg, ic_reg, target::ICData::owner_offset());
-    __ LoadFieldFromOffset(R7, func_reg,
-                           target::Function::usage_counter_offset(), kWord);
+    __ LoadFieldFromOffset(
+        R7, func_reg, target::Function::usage_counter_offset(), kFourBytes);
     __ AddImmediate(R7, 1);
     __ StoreFieldToOffset(R7, func_reg,
-                          target::Function::usage_counter_offset(), kWord);
+                          target::Function::usage_counter_offset(), kFourBytes);
   }
 }
 
@@ -2295,7 +2293,7 @@
     // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
     __ LoadFromOffset(R6, R5,
                       target::ICData::state_bits_offset() - kHeapObjectTag,
-                      kUnsignedWord);
+                      kUnsignedFourBytes);
     ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
     __ andi(R6, R6, Immediate(target::ICData::NumArgsTestedMask()));
     __ CompareImmediate(R6, num_args);
@@ -2609,7 +2607,7 @@
     // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
     __ LoadFromOffset(R6, R5,
                       target::ICData::state_bits_offset() - kHeapObjectTag,
-                      kUnsignedWord);
+                      kUnsignedFourBytes);
     ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
     __ andi(R6, R6, Immediate(target::ICData::NumArgsTestedMask()));
     __ CompareImmediate(R6, 0);
@@ -2786,40 +2784,52 @@
 }
 
 // Used to check class and type arguments. Arguments passed in registers:
-// LR: return address.
-// R0: instance (must be preserved).
-// R2: instantiator type arguments (only if n == 4, can be raw_null).
-// R1: function type arguments (only if n == 4, can be raw_null).
-// R3: target::SubtypeTestCache.
 //
-// Preserves R0/R2/R8.
+// Inputs (mostly from TypeTestABI struct):
+//   - kSubtypeTestCacheReg: SubtypeTestCacheLayout
+//   - kInstanceReg: instance to test against.
+//   - kDstTypeReg: destination type (for n>=3).
+//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n=5).
+//   - kFunctionTypeArgumentsReg: function type arguments (for n=5).
+//   - LR: return address.
 //
-// Result in R1: null -> not found, otherwise result (true or false).
+// All input registers are preserved except for kSubtypeTestCacheReg, which
+// should be saved by the caller if needed.
+//
+// Result in SubtypeTestCacheABI::kResultReg: null -> not found, otherwise
+// result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
 
+  // Until we have the result, we use the result register to store the null
+  // value for quick access. This has the side benefit of initializing the
+  // result to null, so it only needs to be changed if found.
+  const Register kNullReg = TypeTestABI::kSubtypeTestCacheResultReg;
+  __ LoadObject(kNullReg, NullObject());
+
+  const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheReg;
+  const Register kScratchReg = TypeTestABI::kScratchReg;
   const Register kInstanceCidOrFunction = R6;
-  const Register kInstanceInstantiatorTypeArgumentsReg = R4;
+  const Register kInstanceInstantiatorTypeArgumentsReg = R5;
   const Register kInstanceParentFunctionTypeArgumentsReg = R9;
   const Register kInstanceDelayedFunctionTypeArgumentsReg = R10;
 
-  const Register kNullReg = R7;
-
-  __ LoadObject(kNullReg, NullObject());
+  // All of these must be distinct from TypeTestABI::kSubtypeTestCacheResultReg
+  // since it is used for kNullReg as well.
 
   // Loop initialization (moved up here to avoid having all dependent loads
   // after each other).
 
   // We avoid a load-acquire barrier here by relying on the fact that all other
   // loads from the array are data-dependent loads.
-  __ ldr(TypeTestABI::kSubtypeTestCacheReg,
+  __ ldr(kCacheArrayReg,
          FieldAddress(TypeTestABI::kSubtypeTestCacheReg,
                       target::SubtypeTestCache::cache_offset()));
-  __ AddImmediate(TypeTestABI::kSubtypeTestCacheReg,
+  __ AddImmediate(kCacheArrayReg,
                   target::Array::data_offset() - kHeapObjectTag);
 
   Label loop, not_closure;
-  if (n >= 4) {
+  if (n >= 5) {
     __ LoadClassIdMayBeSmi(kInstanceCidOrFunction,
                            TypeTestABI::TypeTestABI::kInstanceReg);
   } else {
@@ -2833,13 +2843,12 @@
     __ ldr(kInstanceCidOrFunction,
            FieldAddress(TypeTestABI::kInstanceReg,
                         target::Closure::function_offset()));
-    if (n >= 2) {
+    if (n >= 3) {
       __ ldr(
           kInstanceInstantiatorTypeArgumentsReg,
           FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        ASSERT(n == 6);
+      if (n >= 7) {
         __ ldr(kInstanceParentFunctionTypeArgumentsReg,
                FieldAddress(TypeTestABI::kInstanceReg,
                             target::Closure::function_type_arguments_offset()));
@@ -2854,21 +2863,23 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n >= 2) {
+    if (n >= 3) {
       Label has_no_type_arguments;
-      __ LoadClassById(R5, kInstanceCidOrFunction);
+      __ LoadClassById(kScratchReg, kInstanceCidOrFunction);
       __ mov(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
       __ LoadFieldFromOffset(
-          R5, R5,
+          kScratchReg, kScratchReg,
           target::Class::host_type_arguments_field_offset_in_words_offset(),
-          kWord);
-      __ CompareImmediate(R5, target::Class::kNoTypeArguments);
+          kFourBytes);
+      __ CompareImmediate(kScratchReg, target::Class::kNoTypeArguments);
       __ b(&has_no_type_arguments, EQ);
-      __ add(R5, TypeTestABI::kInstanceReg, Operand(R5, LSL, 3));
-      __ ldr(kInstanceInstantiatorTypeArgumentsReg, FieldAddress(R5, 0));
+      __ add(kScratchReg, TypeTestABI::kInstanceReg,
+             Operand(kScratchReg, LSL, 3));
+      __ ldr(kInstanceInstantiatorTypeArgumentsReg,
+             FieldAddress(kScratchReg, 0));
       __ Bind(&has_no_type_arguments);
 
-      if (n >= 6) {
+      if (n >= 7) {
         __ mov(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
         __ mov(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
       }
@@ -2876,74 +2887,82 @@
     __ SmiTag(kInstanceCidOrFunction);
   }
 
-  Label found, not_found, next_iteration;
+  Label found, done, next_iteration;
 
   // Loop header
   __ Bind(&loop);
-  __ ldr(R5, Address(TypeTestABI::kSubtypeTestCacheReg,
-                     target::kWordSize *
-                         target::SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmp(R5, Operand(kNullReg));
-  __ b(&not_found, EQ);
-  __ cmp(R5, Operand(kInstanceCidOrFunction));
+  __ ldr(kScratchReg,
+         Address(kCacheArrayReg,
+                 target::kWordSize *
+                     target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmp(kScratchReg, Operand(kNullReg));
+  __ b(&done, EQ);
+  __ cmp(kScratchReg, Operand(kInstanceCidOrFunction));
   if (n == 1) {
     __ b(&found, EQ);
   } else {
     __ b(&next_iteration, NE);
-    __ ldr(R5, Address(TypeTestABI::kSubtypeTestCacheReg,
-                       target::kWordSize *
-                           target::SubtypeTestCache::kInstanceTypeArguments));
-    __ cmp(R5, Operand(kInstanceInstantiatorTypeArgumentsReg));
-    if (n == 2) {
+    __ ldr(kScratchReg,
+           Address(
+               kCacheArrayReg,
+               target::kWordSize * target::SubtypeTestCache::kDestinationType));
+    __ cmp(kScratchReg, Operand(TypeTestABI::kDstTypeReg));
+    __ b(&next_iteration, NE);
+    __ ldr(kScratchReg,
+           Address(kCacheArrayReg,
+                   target::kWordSize *
+                       target::SubtypeTestCache::kInstanceTypeArguments));
+    __ cmp(kScratchReg, Operand(kInstanceInstantiatorTypeArgumentsReg));
+    if (n == 3) {
       __ b(&found, EQ);
     } else {
       __ b(&next_iteration, NE);
-      __ ldr(R5,
-             Address(TypeTestABI::kSubtypeTestCacheReg,
+      __ ldr(kScratchReg,
+             Address(kCacheArrayReg,
                      target::kWordSize *
                          target::SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmp(R5, Operand(TypeTestABI::kInstantiatorTypeArgumentsReg));
+      __ cmp(kScratchReg, Operand(TypeTestABI::kInstantiatorTypeArgumentsReg));
       __ b(&next_iteration, NE);
-      __ ldr(R5, Address(TypeTestABI::kSubtypeTestCacheReg,
-                         target::kWordSize *
-                             target::SubtypeTestCache::kFunctionTypeArguments));
-      __ cmp(R5, Operand(TypeTestABI::kFunctionTypeArgumentsReg));
-      if (n == 4) {
+      __ ldr(kScratchReg,
+             Address(kCacheArrayReg,
+                     target::kWordSize *
+                         target::SubtypeTestCache::kFunctionTypeArguments));
+      __ cmp(kScratchReg, Operand(TypeTestABI::kFunctionTypeArgumentsReg));
+      if (n == 5) {
         __ b(&found, EQ);
       } else {
-        ASSERT(n == 6);
+        ASSERT(n == 7);
         __ b(&next_iteration, NE);
 
-        __ ldr(R5, Address(TypeTestABI::kSubtypeTestCacheReg,
-                           target::kWordSize *
-                               target::SubtypeTestCache::
-                                   kInstanceParentFunctionTypeArguments));
-        __ cmp(R5, Operand(kInstanceParentFunctionTypeArgumentsReg));
+        __ ldr(kScratchReg,
+               Address(kCacheArrayReg,
+                       target::kWordSize *
+                           target::SubtypeTestCache::
+                               kInstanceParentFunctionTypeArguments));
+        __ cmp(kScratchReg, Operand(kInstanceParentFunctionTypeArgumentsReg));
         __ b(&next_iteration, NE);
 
-        __ ldr(R5, Address(TypeTestABI::kSubtypeTestCacheReg,
-                           target::kWordSize *
-                               target::SubtypeTestCache::
-                                   kInstanceDelayedFunctionTypeArguments));
-        __ cmp(R5, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
+        __ ldr(kScratchReg,
+               Address(kCacheArrayReg,
+                       target::kWordSize *
+                           target::SubtypeTestCache::
+                               kInstanceDelayedFunctionTypeArguments));
+        __ cmp(kScratchReg, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
         __ b(&found, EQ);
       }
     }
   }
   __ Bind(&next_iteration);
   __ AddImmediate(
-      TypeTestABI::kSubtypeTestCacheReg,
+      kCacheArrayReg,
       target::kWordSize * target::SubtypeTestCache::kTestEntryLength);
   __ b(&loop);
 
   __ Bind(&found);
-  __ ldr(R1,
-         Address(TypeTestABI::kSubtypeTestCacheReg,
+  __ ldr(TypeTestABI::kSubtypeTestCacheResultReg,
+         Address(kCacheArrayReg,
                  target::kWordSize * target::SubtypeTestCache::kTestResult));
-  __ ret();
-
-  __ Bind(&not_found);
-  __ mov(R1, kNullReg);
+  __ Bind(&done);
   __ ret();
 }
 
@@ -2953,248 +2972,18 @@
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
+void StubCodeCompiler::GenerateSubtype3TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 3);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
+void StubCodeCompiler::GenerateSubtype5TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 5);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-// Used to test whether a given value is of a given type (different variants,
-// all have the same calling convention).
-//
-// Inputs:
-//   - R0 : instance to test against.
-//   - R2 : instantiator type arguments (if needed).
-//   - R1 : function type arguments (if needed).
-//
-//   - R3 : subtype test cache.
-//
-//   - R8 : type to test against.
-//   - R4 : name of destination variable.
-//
-// Preserves R0/R2.
-//
-// Note of warning: The caller will not populate CODE_REG and we have therefore
-// no access to the pool.
-void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  // Tail call the [SubtypeTestCache]-based implementation.
-  __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
-  __ ldr(R9, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-  __ br(R9);
-}
-
-// Used instead of DefaultTypeTestStub when null is assignable.
-void StubCodeCompiler::GenerateDefaultNullableTypeTestStub(
-    Assembler* assembler) {
-  Label done;
-
-  // Fast case for 'null'.
-  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-  __ BranchIf(EQUAL, &done);
-
-  // Tail call the [SubtypeTestCache]-based implementation.
-  __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
-  __ ldr(R9, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-  __ br(R9);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
-                                            TypeCheckMode mode) {
-  __ PushObject(NullObject());  // Make room for result.
-  __ Push(TypeTestABI::kInstanceReg);
-  __ Push(TypeTestABI::kDstTypeReg);
-  __ Push(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ Push(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ PushObject(NullObject());
-  __ Push(TypeTestABI::kSubtypeTestCacheReg);
-  __ PushImmediate(target::ToRawSmi(mode));
-  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
-  __ Drop(1);  // mode
-  __ Pop(TypeTestABI::kSubtypeTestCacheReg);
-  __ Drop(1);  // dst_name
-  __ Pop(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ Pop(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ Pop(TypeTestABI::kDstTypeReg);
-  __ Pop(TypeTestABI::kInstanceReg);
-  __ Drop(1);  // Discard return value.
-}
-
-void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
-    Assembler* assembler) {
-  __ ldr(CODE_REG,
-         Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Used instead of LazySpecializeTypeTestStub when null is assignable.
-void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
-    Assembler* assembler) {
-  Label done;
-
-  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-  __ BranchIf(EQUAL, &done);
-
-  __ ldr(CODE_REG,
-         Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-static void BuildTypeParameterTypeTestStub(Assembler* assembler,
-                                           bool allow_null) {
-  Label done;
-
-  if (allow_null) {
-    __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-    __ BranchIf(EQUAL, &done);
-  }
-
-  Label function_type_param;
-  __ ldr(TypeTestABI::kScratchReg,
-         FieldAddress(TypeTestABI::kDstTypeReg,
-                      TypeParameter::parameterized_class_id_offset()),
-         kUnsignedHalfword);
-  __ cmp(TypeTestABI::kScratchReg, Operand(kFunctionCid));
-  __ BranchIf(EQUAL, &function_type_param);
-
-  auto handle_case = [&](Register tav) {
-    __ CompareObject(tav, NullObject());
-    __ BranchIf(EQUAL, &done);
-    __ ldr(
-        TypeTestABI::kScratchReg,
-        FieldAddress(TypeTestABI::kDstTypeReg, TypeParameter::index_offset()),
-        kUnsignedHalfword);
-    __ add(TypeTestABI::kScratchReg, tav,
-           Operand(TypeTestABI::kScratchReg, LSL, 8));
-    __ ldr(TypeTestABI::kScratchReg,
-           FieldAddress(TypeTestABI::kScratchReg,
-                        target::TypeArguments::InstanceSize()));
-    __ ldr(TypeTestABI::kScratchReg,
-           FieldAddress(TypeTestABI::kScratchReg,
-                        AbstractType::type_test_stub_entry_point_offset()));
-    __ br(TypeTestABI::kScratchReg);
-  };
-
-  // Class type parameter: If dynamic we're done, otherwise dereference type
-  // parameter and tail call.
-  handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
-
-  // Function type parameter: If dynamic we're done, otherwise dereference type
-  // parameter and tail call.
-  __ Bind(&function_type_param);
-  handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
-    Assembler* assembler) {
-  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
-}
-
-void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
-  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
-}
-
-void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
-  Label done, call_runtime;
-
-  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    __ ldr(CODE_REG,
-           Address(THR, target::Thread::slow_type_test_stub_offset()));
-  }
-  __ EnterStubFrame();
-
-  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
-  __ BranchIf(EQUAL, &call_runtime);
-
-  const Register kTmp = R9;
-
-  // If this is not a [Type] object, we'll go to the runtime.
-  Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, TypeTestABI::kDstTypeReg);
-  __ cmp(kTmp, Operand(kTypeCid));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is instantiated/uninstantiated.
-  __ ldr(kTmp,
-         FieldAddress(TypeTestABI::kDstTypeReg,
-                      target::Type::type_state_offset(), kByte),
-         kByte);
-  __ cmp(kTmp,
-         Operand(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is a function type.
-  __ ldr(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
-                            target::Type::signature_offset()));
-  __ CompareObject(kTmp, NullObject());
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
-
-  // Fall through to &is_simple_case
-
-  __ Bind(&is_simple_case);
-  {
-    __ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
-                TypeTestABI::kSubtypeTestCacheReg);
-    __ BranchLink(StubCodeSubtype2TestCache());
-    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
-    __ PopPair(TypeTestABI::kFunctionTypeArgumentsReg,
-               TypeTestABI::kSubtypeTestCacheReg);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    __ Jump(&call_runtime);
-  }
-
-  __ Bind(&is_complex_case);
-  {
-    __ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
-                TypeTestABI::kSubtypeTestCacheReg);
-    __ BranchLink(StubCodeSubtype6TestCache());
-    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
-    __ PopPair(TypeTestABI::kFunctionTypeArgumentsReg,
-               TypeTestABI::kSubtypeTestCacheReg);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    // Fall through to runtime_call
-  }
-
-  __ Bind(&call_runtime);
-
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
-
-  __ Bind(&done);
-  __ LeaveStubFrame();
-  __ Ret();
+void StubCodeCompiler::GenerateSubtype7TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 7);
 }
 
 void StubCodeCompiler::GenerateGetCStackPointerStub(Assembler* assembler) {
@@ -3214,7 +3003,8 @@
 void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
   ASSERT(kExceptionObjectReg == R0);
   ASSERT(kStackTraceObjectReg == R1);
-  __ mov(LR, R0);  // Program counter.
+  // TransitionGeneratedToNative might clobber LR if it takes the slow path.
+  __ mov(CALLEE_SAVED_TEMP, R0);  // Program counter.
   __ mov(SP, R1);  // Stack pointer.
   __ mov(FP, R2);  // Frame_pointer.
   __ mov(THR, R3);
@@ -3249,7 +3039,7 @@
   } else {
     __ LoadPoolPointer();
   }
-  __ ret();  // Jump to continuation point.
+  __ ret(CALLEE_SAVED_TEMP);  // Jump to continuation point.
 }
 
 // Run an exception handler.  Execution comes from JumpToFrame
@@ -3611,12 +3401,12 @@
   __ LoadClassIdMayBeSmi(R1, R0);
   __ ldr(R2,
          FieldAddress(R5, target::SingleTargetCache::lower_limit_offset(),
-                      kHalfword),
-         kUnsignedHalfword);
+                      kTwoBytes),
+         kUnsignedTwoBytes);
   __ ldr(R3,
          FieldAddress(R5, target::SingleTargetCache::upper_limit_offset(),
-                      kHalfword),
-         kUnsignedHalfword);
+                      kTwoBytes),
+         kUnsignedTwoBytes);
 
   __ cmp(R1, Operand(R2));
   __ b(&miss, LT);
@@ -3835,8 +3625,7 @@
     __ csel(R2, ZR, R2, HI);
 
     /* Get the class index and insert it into the tags. */
-    uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    uword tags = target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ LoadImmediate(TMP, tags);
     __ orr(R2, R2, Operand(TMP));
     __ str(R2, FieldAddress(R0, target::Object::tags_offset())); /* Tags. */
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index bc4c545..4d499af 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -833,7 +833,7 @@
       __ Bind(&done);
 
       // Get the class index and insert it into the tags.
-      uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+      uword tags = target::MakeTagWordForNewSpaceObject(cid, 0);
       __ orl(EDI, Immediate(tags));
       __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI);  // Tags.
     }
@@ -1060,9 +1060,9 @@
   // EDX: number of context variables.
   __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
 #if defined(DEBUG)
-  static const bool kJumpLength = Assembler::kFarJump;
+  static auto const kJumpLength = Assembler::kFarJump;
 #else
-  static const bool kJumpLength = Assembler::kNearJump;
+  static auto const kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
   __ j(ABOVE_EQUAL, slow_case, kJumpLength);
 
@@ -1098,7 +1098,7 @@
     // EAX: new object.
     // EDX: number of context variables.
     // EBX: size and bit tags.
-    uint32_t tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
+    uword tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
     __ orl(EBX, Immediate(tags));
     __ movl(FieldAddress(EAX, target::Object::tags_offset()), EBX);  // Tags.
   }
@@ -1453,8 +1453,8 @@
     // EDX: new object type arguments (if is_cls_parameterized).
     // Set the tags.
     ASSERT(target::Class::GetId(cls) != kIllegalCid);
-    uint32_t tags = target::MakeTagWordForNewSpaceObject(
-        target::Class::GetId(cls), instance_size);
+    uword tags = target::MakeTagWordForNewSpaceObject(target::Class::GetId(cls),
+                                                      instance_size);
     __ movl(Address(EAX, target::Object::tags_offset()), Immediate(tags));
     __ addl(EAX, Immediate(kHeapObjectTag));
 
@@ -2184,34 +2184,74 @@
 // TOS + 0: return address.
 // TOS + 1: function type arguments (only if n == 4, can be raw_null).
 // TOS + 2: instantiator type arguments (only if n == 4, can be raw_null).
-// TOS + 3: instance.
-// TOS + 4: SubtypeTestCache.
-// Result in ECX: null -> not found, otherwise result (true or false).
+// TOS + 3: destination_type (only used if n >= 3).
+// TOS + 4: instance.
+// TOS + 5: SubtypeTestCache.
+//
+// No registers are preserved by this stub.
+//
+// Result in SubtypeTestCacheReg::kResultReg: null -> not found, otherwise
+// result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
 
-  static intptr_t kFunctionTypeArgumentsInBytes = 1 * target::kWordSize;
-  static intptr_t kInstantiatorTypeArgumentsInBytes = 2 * target::kWordSize;
-  static intptr_t kInstanceOffsetInBytes = 3 * target::kWordSize;
-  static intptr_t kCacheOffsetInBytes = 4 * target::kWordSize;
+  // We represent the depth of as a depth from the top of the stack at the
+  // start of the stub. That is, depths for input values are non-negative and
+  // depths for values pushed during the stub are negative.
 
-  const Register kInstanceCidOrFunction = ECX;
-  const Register kInstanceInstantiatorTypeArgumentsReg = EBX;
+  // Used to initialize depths for conditionally-pushed values.
+  const intptr_t kNoDepth = kIntptrMin;
+  // Offset of the original top of the stack from the current top of stack.
+  intptr_t original_tos_offset = 0;
+
+  // Inputs use relative depths.
+  static constexpr intptr_t kFunctionTypeArgumentsDepth = 1;
+  static constexpr intptr_t kInstantiatorTypeArgumentsDepth = 2;
+  static constexpr intptr_t kDestinationTypeDepth = 3;
+  static constexpr intptr_t kInstanceDepth = 4;
+  static constexpr intptr_t kCacheDepth = 5;
+  // Others use absolute depths. We initialize conditionally pushed values to
+  // kNoInput for extra checking.
+  intptr_t kInstanceParentFunctionTypeArgumentsDepth = kNoDepth;
+  intptr_t kInstanceDelayedFunctionTypeArgumentsDepth = kNoDepth;
+
+  // Other values are stored in non-kInstanceReg registers from TypeTestABI.
+  const Register kCacheArrayReg = TypeTestABI::kInstantiatorTypeArgumentsReg;
+  const Register kScratchReg = TypeTestABI::kSubtypeTestCacheReg;
+  const Register kInstanceCidOrFunction =
+      TypeTestABI::kFunctionTypeArgumentsReg;
+  const Register kInstanceInstantiatorTypeArgumentsReg =
+      TypeTestABI::kDstTypeReg;
+
+  // Loads a value at the given depth from the stack into dst.
+  auto load_from_stack = [&](Register dst, intptr_t depth) {
+    ASSERT(depth != kNoDepth);
+    __ LoadFromStack(dst, original_tos_offset + depth);
+  };
+
+  // Compares a value at the given depth from the stack to the value in src.
+  auto compare_to_stack = [&](Register src, intptr_t depth) {
+    ASSERT(depth != kNoDepth);
+    __ CompareToStack(src, original_tos_offset + depth);
+  };
 
   const auto& raw_null = Immediate(target::ToRawPointer(NullObject()));
 
-  __ movl(TypeTestABI::kInstanceReg, Address(ESP, kInstanceOffsetInBytes));
+  load_from_stack(TypeTestABI::kInstanceReg, kInstanceDepth);
 
   // Loop initialization (moved up here to avoid having all dependent loads
   // after each other)
-  __ movl(EDX, Address(ESP, kCacheOffsetInBytes));
+  load_from_stack(kCacheArrayReg, kCacheDepth);
   // We avoid a load-acquire barrier here by relying on the fact that all other
   // loads from the array are data-dependent loads.
-  __ movl(EDX, FieldAddress(EDX, target::SubtypeTestCache::cache_offset()));
-  __ addl(EDX, Immediate(target::Array::data_offset() - kHeapObjectTag));
+  __ movl(
+      kCacheArrayReg,
+      FieldAddress(kCacheArrayReg, target::SubtypeTestCache::cache_offset()));
+  __ addl(kCacheArrayReg,
+          Immediate(target::Array::data_offset() - kHeapObjectTag));
 
   Label loop, not_closure;
-  if (n >= 4) {
+  if (n >= 5) {
     __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
   } else {
     __ LoadClassId(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
@@ -2224,12 +2264,12 @@
     __ movl(kInstanceCidOrFunction,
             FieldAddress(TypeTestABI::kInstanceReg,
                          target::Closure::function_offset()));
-    if (n >= 2) {
+    if (n >= 3) {
       __ movl(
           kInstanceInstantiatorTypeArgumentsReg,
           FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
+      if (n >= 7) {
         __ pushl(
             FieldAddress(TypeTestABI::kInstanceReg,
                          target::Closure::delayed_type_arguments_offset()));
@@ -2244,21 +2284,22 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n >= 2) {
+    if (n >= 3) {
       Label has_no_type_arguments;
-      __ LoadClassById(EDI, kInstanceCidOrFunction);
+      __ LoadClassById(kScratchReg, kInstanceCidOrFunction);
       __ movl(kInstanceInstantiatorTypeArgumentsReg, raw_null);
-      __ movl(EDI,
-              FieldAddress(
-                  EDI, target::Class::
+      __ movl(
+          kScratchReg,
+          FieldAddress(kScratchReg,
+                       target::Class::
                            host_type_arguments_field_offset_in_words_offset()));
-      __ cmpl(EDI, Immediate(target::Class::kNoTypeArguments));
+      __ cmpl(kScratchReg, Immediate(target::Class::kNoTypeArguments));
       __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
       __ movl(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(TypeTestABI::kInstanceReg, EDI, TIMES_4, 0));
+              FieldAddress(TypeTestABI::kInstanceReg, kScratchReg, TIMES_4, 0));
       __ Bind(&has_no_type_arguments);
 
-      if (n >= 6) {
+      if (n >= 7) {
         __ pushl(raw_null);  // delayed.
         __ pushl(raw_null);  // function.
       }
@@ -2266,84 +2307,97 @@
     __ SmiTag(kInstanceCidOrFunction);
   }
 
-  const intptr_t kInstanceParentFunctionTypeArgumentsFromSp = 0;
-  const intptr_t kInstanceDelayedFunctionTypeArgumentsFromSp =
-      target::kWordSize;
-  const intptr_t args_offset = n >= 6 ? 2 * target::kWordSize : 0;
+  if (n >= 7) {
+    // Now that instance handling is done, both the delayed and parent function
+    // type arguments stack slots have been set, so any input uses must be
+    // offset by the new values and the new values can now be accessed in
+    // the following code without issue when n >= 6.
+    original_tos_offset = 2;
+    kInstanceDelayedFunctionTypeArgumentsDepth = -1;
+    kInstanceParentFunctionTypeArgumentsDepth = -2;
+  }
 
-  Label found, not_found, next_iteration;
+  Label done, next_iteration;
 
   // Loop header.
   __ Bind(&loop);
-  __ movl(
-      EDI,
-      Address(EDX, target::kWordSize *
-                       target::SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmpl(EDI, raw_null);
-  __ j(EQUAL, &not_found, Assembler::kNearJump);
-  __ cmpl(EDI, kInstanceCidOrFunction);
+  __ movl(kScratchReg,
+          Address(kCacheArrayReg,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmpl(kScratchReg, raw_null);
+  __ j(EQUAL, &done, Assembler::kNearJump);
+  __ cmpl(kScratchReg, kInstanceCidOrFunction);
   if (n == 1) {
-    __ j(EQUAL, &found, Assembler::kNearJump);
+    __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
     __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+    __ movl(kScratchReg,
+            Address(kCacheArrayReg,
+                    target::kWordSize *
+                        target::SubtypeTestCache::kDestinationType));
+    compare_to_stack(kScratchReg, kDestinationTypeDepth);
+    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
     __ cmpl(kInstanceInstantiatorTypeArgumentsReg,
-            Address(EDX, target::kWordSize *
-                             target::SubtypeTestCache::kInstanceTypeArguments));
-    if (n == 2) {
-      __ j(EQUAL, &found, Assembler::kNearJump);
+            Address(kCacheArrayReg,
+                    target::kWordSize *
+                        target::SubtypeTestCache::kInstanceTypeArguments));
+    if (n == 3) {
+      __ j(EQUAL, &done, Assembler::kNearJump);
     } else {
       __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
       __ movl(
-          EDI,
-          Address(EDX,
+          kScratchReg,
+          Address(kCacheArrayReg,
                   target::kWordSize *
                       target::SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmpl(EDI,
-              Address(ESP, args_offset + kInstantiatorTypeArgumentsInBytes));
+      compare_to_stack(kScratchReg, kInstantiatorTypeArgumentsDepth);
       __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ movl(
-          EDI,
-          Address(EDX, target::kWordSize *
-                           target::SubtypeTestCache::kFunctionTypeArguments));
-      __ cmpl(EDI, Address(ESP, args_offset + kFunctionTypeArgumentsInBytes));
-      if (n == 4) {
-        __ j(EQUAL, &found, Assembler::kNearJump);
+      __ movl(kScratchReg,
+              Address(kCacheArrayReg,
+                      target::kWordSize *
+                          target::SubtypeTestCache::kFunctionTypeArguments));
+      compare_to_stack(kScratchReg, kFunctionTypeArgumentsDepth);
+      if (n == 5) {
+        __ j(EQUAL, &done, Assembler::kNearJump);
       } else {
-        ASSERT(n == 6);
+        ASSERT(n == 7);
         __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
 
-        __ movl(EDI,
-                Address(EDX, target::kWordSize *
-                                 target::SubtypeTestCache::
-                                     kInstanceParentFunctionTypeArguments));
-        __ cmpl(EDI, Address(ESP, kInstanceParentFunctionTypeArgumentsFromSp));
+        __ movl(kScratchReg,
+                Address(kCacheArrayReg,
+                        target::kWordSize *
+                            target::SubtypeTestCache::
+                                kInstanceParentFunctionTypeArguments));
+        compare_to_stack(kScratchReg,
+                         kInstanceParentFunctionTypeArgumentsDepth);
         __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-        __ movl(EDI,
-                Address(EDX, target::kWordSize *
-                                 target::SubtypeTestCache::
-                                     kInstanceDelayedFunctionTypeArguments));
-        __ cmpl(EDI, Address(ESP, kInstanceDelayedFunctionTypeArgumentsFromSp));
-        __ j(EQUAL, &found, Assembler::kNearJump);
+        __ movl(kScratchReg,
+                Address(kCacheArrayReg,
+                        target::kWordSize *
+                            target::SubtypeTestCache::
+                                kInstanceDelayedFunctionTypeArguments));
+        compare_to_stack(kScratchReg,
+                         kInstanceDelayedFunctionTypeArgumentsDepth);
+        __ j(EQUAL, &done, Assembler::kNearJump);
       }
     }
   }
   __ Bind(&next_iteration);
-  __ addl(EDX, Immediate(target::kWordSize *
-                         target::SubtypeTestCache::kTestEntryLength));
+  __ addl(kCacheArrayReg,
+          Immediate(target::kWordSize *
+                    target::SubtypeTestCache::kTestEntryLength));
   __ jmp(&loop, Assembler::kNearJump);
 
-  __ Bind(&found);
-  __ movl(ECX, Address(EDX, target::kWordSize *
-                                target::SubtypeTestCache::kTestResult));
-  if (n == 6) {
+  __ Bind(&done);
+  // In the not found case, the test result slot is null, so we can
+  // unconditionally load from the cache entry.
+  __ movl(TypeTestABI::kSubtypeTestCacheResultReg,
+          Address(kCacheArrayReg,
+                  target::kWordSize * target::SubtypeTestCache::kTestResult));
+  if (n >= 7) {
     __ Drop(2);
-  }
-  __ ret();
-
-  __ Bind(&not_found);
-  __ movl(ECX, raw_null);
-  if (n == 6) {
-    __ Drop(2);
+    original_tos_offset = 0;  // In case we add any input uses after this point.
   }
   __ ret();
 }
@@ -2354,67 +2408,18 @@
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
+void StubCodeCompiler::GenerateSubtype3TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 3);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
+void StubCodeCompiler::GenerateSubtype5TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 5);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateDefaultNullableTypeTestStub(
-    Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
-    Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
-    Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
-    Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
+void StubCodeCompiler::GenerateSubtype7TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 7);
 }
 
 // Return the current stack pointer address, used to do stack alignment checks.
@@ -2891,7 +2896,8 @@
   Label call_runtime;
   __ pushl(AllocateTypedDataArrayABI::kLengthReg);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, ECX, &call_runtime, false));
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(cid, ECX, &call_runtime, Assembler::kFarJump));
   __ movl(EDI, AllocateTypedDataArrayABI::kLengthReg);
   /* Check that length is a positive Smi. */
   /* EDI: requested array length argument. */
@@ -2950,8 +2956,7 @@
     __ movl(EDI, Immediate(0));
     __ Bind(&done);
     /* Get the class index and insert it into the tags. */
-    uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    uword tags = target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ orl(EDI, Immediate(tags));
     __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI); /* Tags. */
   }
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index b3c99af..08b540d 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -172,8 +172,9 @@
     std::function<void()> perform_runtime_call) {
   // We want the saved registers to appear like part of the caller's frame, so
   // we push them before calling EnterStubFrame.
-  __ PushRegisters(kDartAvailableCpuRegs,
-                   save_fpu_registers ? kAllFpuRegistersList : 0);
+  const RegisterSet saved_registers(
+      kDartAvailableCpuRegs, save_fpu_registers ? kAllFpuRegistersList : 0);
+  __ PushRegisters(saved_registers);
 
   const intptr_t kSavedCpuRegisterSlots =
       Utils::CountOneBitsWord(kDartAvailableCpuRegs);
@@ -197,8 +198,7 @@
   // Copy up the return address (in case it was changed).
   __ popq(TMP);
   __ movq(Address(RSP, kAllSavedRegistersSlots * target::kWordSize), TMP);
-  __ PopRegisters(kDartAvailableCpuRegs,
-                  save_fpu_registers ? kAllFpuRegistersList : 0);
+  __ PopRegisters(saved_registers);
   __ ret();
 }
 
@@ -230,8 +230,7 @@
 void StubCodeCompiler::GenerateEnterSafepointStub(Assembler* assembler) {
   RegisterSet all_registers;
   all_registers.AddAllGeneralRegisters();
-  __ PushRegisters(all_registers.cpu_registers(),
-                   all_registers.fpu_registers());
+  __ PushRegisters(all_registers);
 
   __ EnterFrame(0);
   __ ReserveAlignedFrameSpace(0);
@@ -239,15 +238,14 @@
   __ CallCFunction(RAX);
   __ LeaveFrame();
 
-  __ PopRegisters(all_registers.cpu_registers(), all_registers.fpu_registers());
+  __ PopRegisters(all_registers);
   __ ret();
 }
 
 void StubCodeCompiler::GenerateExitSafepointStub(Assembler* assembler) {
   RegisterSet all_registers;
   all_registers.AddAllGeneralRegisters();
-  __ PushRegisters(all_registers.cpu_registers(),
-                   all_registers.fpu_registers());
+  __ PushRegisters(all_registers);
 
   __ EnterFrame(0);
   __ ReserveAlignedFrameSpace(0);
@@ -262,7 +260,7 @@
   __ CallCFunction(RAX);
   __ LeaveFrame();
 
-  __ PopRegisters(all_registers.cpu_registers(), all_registers.fpu_registers());
+  __ PopRegisters(all_registers);
   __ ret();
 }
 
@@ -292,6 +290,10 @@
 }
 
 #if !defined(DART_PRECOMPILER)
+static const RegisterSet kArgumentRegisterSet(
+    CallingConventions::kArgumentRegisters,
+    CallingConventions::kFpuArgumentRegisters);
+
 void StubCodeCompiler::GenerateJITCallbackTrampolines(
     Assembler* assembler,
     intptr_t next_callback_id) {
@@ -324,8 +326,7 @@
   __ pushq(RAX);
 
   // Save all registers which might hold arguments.
-  __ PushRegisters(CallingConventions::kArgumentRegisters,
-                   CallingConventions::kFpuArgumentRegisters);
+  __ PushRegisters(kArgumentRegisterSet);
 
   // Load the thread, verify the callback ID and exit the safepoint.
   //
@@ -346,8 +347,7 @@
   }
 
   // Restore the arguments.
-  __ PopRegisters(CallingConventions::kArgumentRegisters,
-                  CallingConventions::kFpuArgumentRegisters);
+  __ PopRegisters(kArgumentRegisterSet);
 
   // Restore the callback ID.
   __ popq(RAX);
@@ -765,9 +765,9 @@
   // RBX: address of first argument in array.
   Label loop, loop_condition;
 #if defined(DEBUG)
-  static const bool kJumpLength = Assembler::kFarJump;
+  static auto const kJumpLength = Assembler::kFarJump;
 #else
-  static const bool kJumpLength = Assembler::kNearJump;
+  static auto const kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
   __ jmp(&loop_condition, kJumpLength);
   __ Bind(&loop);
@@ -1111,7 +1111,7 @@
       __ Bind(&done);
 
       // Get the class index and insert it into the tags.
-      uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+      uword tags = target::MakeTagWordForNewSpaceObject(cid, 0);
       __ orq(RDI, Immediate(tags));
       __ movq(FieldAddress(RAX, target::Array::tags_offset()), RDI);  // Tags.
     }
@@ -1138,9 +1138,9 @@
     __ Bind(&init_loop);
     __ cmpq(RDI, RCX);
 #if defined(DEBUG)
-    static const bool kJumpLength = Assembler::kFarJump;
+    static auto const kJumpLength = Assembler::kFarJump;
 #else
-    static const bool kJumpLength = Assembler::kNearJump;
+    static auto const kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
     __ j(ABOVE_EQUAL, &done, kJumpLength);
     // No generational barrier needed, since we are storing null.
@@ -1180,7 +1180,7 @@
   // For test purpose call allocation stub without inline allocation attempt.
   if (!FLAG_use_slow_path) {
     Label slow_case;
-    __ TryAllocate(compiler::MintClass(), &slow_case, /*near_jump=*/true,
+    __ TryAllocate(compiler::MintClass(), &slow_case, Assembler::kNearJump,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
     __ Ret();
 
@@ -1200,7 +1200,7 @@
   // For test purpose call allocation stub without inline allocation attempt.
   if (!FLAG_use_slow_path) {
     Label slow_case;
-    __ TryAllocate(compiler::MintClass(), &slow_case, /*near_jump=*/true,
+    __ TryAllocate(compiler::MintClass(), &slow_case, Assembler::kNearJump,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
     __ Ret();
 
@@ -1215,6 +1215,10 @@
       /*store_runtime_result_in_result_register=*/true);
 }
 
+static const RegisterSet kCalleeSavedRegisterSet(
+    CallingConventions::kCalleeSaveCpuRegisters,
+    CallingConventions::kCalleeSaveXmmRegisters);
+
 // Called when invoking Dart code from C++ (VM code).
 // Input parameters:
 //   RSP : points to return address.
@@ -1245,8 +1249,7 @@
   __ pushq(kArgDescReg);
 
   // Save C++ ABI callee-saved registers.
-  __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                   CallingConventions::kCalleeSaveXmmRegisters);
+  __ PushRegisters(kCalleeSavedRegisterSet);
 
   // If any additional (or fewer) values are pushed, the offsets in
   // target::frame_layout.exit_link_slot_from_entry_fp will need to be changed.
@@ -1356,8 +1359,7 @@
 #endif
 
   // Restore C++ ABI callee-saved registers.
-  __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                  CallingConventions::kCalleeSaveXmmRegisters);
+  __ PopRegisters(kCalleeSavedRegisterSet);
   __ set_constant_pool_allowed(false);
 
   // Restore the frame pointer.
@@ -1432,7 +1434,7 @@
     // RAX: new object.
     // R10: number of context variables.
     // R13: size and bit tags.
-    uint32_t tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
+    uword tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
     __ orq(R13, Immediate(tags));
     __ movq(FieldAddress(RAX, target::Object::tags_offset()), R13);  // Tags.
   }
@@ -1471,9 +1473,9 @@
       Label loop, entry;
       __ leaq(R13, FieldAddress(RAX, target::Context::variable_offset(0)));
 #if defined(DEBUG)
-      static const bool kJumpLength = Assembler::kFarJump;
+      static auto const kJumpLength = Assembler::kFarJump;
 #else
-      static const bool kJumpLength = Assembler::kNearJump;
+      static auto const kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
       __ jmp(&entry, kJumpLength);
       __ Bind(&loop);
@@ -1633,13 +1635,11 @@
   }
 
   // Update the tags that this object has been remembered.
-  // Note that we use 32 bit operations here to match the size of the
-  // background sweeper which is also manipulating this 32 bit word.
   // RDX: Address being stored
   // RAX: Current tag value
-  // lock+andl is an atomic read-modify-write.
+  // lock+andq is an atomic read-modify-write.
   __ lock();
-  __ andl(FieldAddress(RDX, target::Object::tags_offset()),
+  __ andq(FieldAddress(RDX, target::Object::tags_offset()),
           Immediate(~(1 << target::ObjectLayout::kOldAndNotRememberedBit)));
 
   // Save registers being destroyed.
@@ -1686,16 +1686,14 @@
   __ movq(TMP, RAX);  // RAX is fixed implicit operand of CAS.
 
   // Atomically clear kOldAndNotMarkedBit.
-  // Note that we use 32 bit operations here to match the size of the
-  // background marker which is also manipulating this 32 bit word.
   Label retry, lost_race, marking_overflow;
-  __ movl(RAX, FieldAddress(TMP, target::Object::tags_offset()));
+  __ movq(RAX, FieldAddress(TMP, target::Object::tags_offset()));
   __ Bind(&retry);
-  __ movl(RCX, RAX);
-  __ testl(RCX, Immediate(1 << target::ObjectLayout::kOldAndNotMarkedBit));
+  __ movq(RCX, RAX);
+  __ testq(RCX, Immediate(1 << target::ObjectLayout::kOldAndNotMarkedBit));
   __ j(ZERO, &lost_race);  // Marked by another thread.
-  __ andl(RCX, Immediate(~(1 << target::ObjectLayout::kOldAndNotMarkedBit)));
-  __ LockCmpxchgl(FieldAddress(TMP, target::Object::tags_offset()), RCX);
+  __ andq(RCX, Immediate(~(1 << target::ObjectLayout::kOldAndNotMarkedBit)));
+  __ LockCmpxchgq(FieldAddress(TMP, target::Object::tags_offset()), RCX);
   __ j(NOT_EQUAL, &retry, Assembler::kNearJump);
 
   __ movq(RAX, Address(THR, target::Thread::marking_stack_block_offset()));
@@ -1819,9 +1817,9 @@
       __ Bind(&init_loop);
       __ cmpq(kNextFieldReg, kNewTopReg);
 #if defined(DEBUG)
-      static const bool kJumpLength = Assembler::kFarJump;
+      static auto const kJumpLength = Assembler::kFarJump;
 #else
-      static const bool kJumpLength = Assembler::kNearJump;
+      static auto const kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
       __ j(ABOVE_EQUAL, &done, kJumpLength);
       __ StoreIntoObjectNoBarrier(RAX, Address(kNextFieldReg, 0), kNullReg);
@@ -1949,7 +1947,7 @@
   // User-defined classes should always be allocatable in new space.
   RELEASE_ASSERT(target::Heap::IsAllocatableInNewSpace(instance_size));
 
-  const uint32_t tags =
+  const uword tags =
       target::MakeTagWordForNewSpaceObject(cls_id, instance_size);
 
   // Note: Keep in sync with helper function.
@@ -2566,9 +2564,9 @@
   __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset()));
   __ cmpq(RAX, Immediate(0));
 #if defined(DEBUG)
-  static const bool kJumpLength = Assembler::kFarJump;
+  static auto const kJumpLength = Assembler::kFarJump;
 #else
-  static const bool kJumpLength = Assembler::kNearJump;
+  static auto const kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
   __ j(NOT_EQUAL, &stepping, kJumpLength);
   __ Bind(&done_stepping);
@@ -2732,31 +2730,42 @@
 
 // Used to check class and type arguments. Arguments passed in registers:
 //
-// Inputs:
-//   - R9  : RawSubtypeTestCache
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments (for n=4).
-//   - RCX : function type arguments (for n=4).
-//
+// Input registers (from TypeTestABI struct):
+//   - kSubtypeTestCacheReg: SubtypeTestCacheLayout
+//   - kInstanceReg: instance to test against (must be preserved).
+//   - kDstTypeReg: destination type (for n>=3).
+//   - kInstantiatorTypeArgumentsReg : instantiator type arguments (for n>=5).
+//   - kFunctionTypeArgumentsReg : function type arguments (for n>=5).
+// Inputs from stack:
 //   - TOS + 0: return address.
 //
-// Preserves R9/RAX/RCX/RDX, RBX.
+// All input registers are preserved.
 //
-// Result in R8: null -> not found, otherwise result (true or false).
+// Result in SubtypeTestCacheReg::kResultReg: null -> not found, otherwise
+// result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
 
-  const Register kInstanceCidOrFunction = R10;
-  const Register kInstanceInstantiatorTypeArgumentsReg = R13;
-  const Register kInstanceParentFunctionTypeArgumentsReg = PP;
-  const Register kInstanceDelayedFunctionTypeArgumentsReg = CODE_REG;
-
-  const Register kNullReg = R8;
-
+  // Until we have the result, we use the result register to store the null
+  // value for quick access. This has the side benefit of initializing the
+  // result to null, so it only needs to be changed if found.
+  const Register kNullReg = TypeTestABI::kSubtypeTestCacheResultReg;
   __ LoadObject(kNullReg, NullObject());
 
-  // Free up these 2 registers to be used for 6-value test.
-  if (n >= 6) {
+  // All of these must be distinct from TypeTestABI::kSubtypeTestCacheResultReg
+  // since it is used for kNullReg as well.
+  const Register kCacheArrayReg = RDI;
+  const Register kScratchReg = TypeTestABI::kScratchReg;
+  const Register kInstanceCidOrFunction = R10;
+  const Register kInstanceInstantiatorTypeArgumentsReg = R13;
+  // Only used for n >= 7, so set conditionally in that case to catch misuse.
+  Register kInstanceParentFunctionTypeArgumentsReg = kNoRegister;
+  Register kInstanceDelayedFunctionTypeArgumentsReg = kNoRegister;
+
+  // Free up these 2 registers to be used for 7-value test.
+  if (n >= 7) {
+    kInstanceParentFunctionTypeArgumentsReg = PP;
+    kInstanceDelayedFunctionTypeArgumentsReg = CODE_REG;
     __ pushq(kInstanceParentFunctionTypeArgumentsReg);
     __ pushq(kInstanceDelayedFunctionTypeArgumentsReg);
   }
@@ -2766,12 +2775,14 @@
 
   // We avoid a load-acquire barrier here by relying on the fact that all other
   // loads from the array are data-dependent loads.
-  __ movq(RSI, FieldAddress(TypeTestABI::kSubtypeTestCacheReg,
-                            target::SubtypeTestCache::cache_offset()));
-  __ addq(RSI, Immediate(target::Array::data_offset() - kHeapObjectTag));
+  __ movq(kCacheArrayReg,
+          FieldAddress(TypeTestABI::kSubtypeTestCacheReg,
+                       target::SubtypeTestCache::cache_offset()));
+  __ addq(kCacheArrayReg,
+          Immediate(target::Array::data_offset() - kHeapObjectTag));
 
   Label loop, not_closure;
-  if (n >= 4) {
+  if (n >= 5) {
     __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
   } else {
     __ LoadClassId(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
@@ -2784,13 +2795,12 @@
     __ movq(kInstanceCidOrFunction,
             FieldAddress(TypeTestABI::kInstanceReg,
                          target::Closure::function_offset()));
-    if (n >= 2) {
+    if (n >= 3) {
       __ movq(
           kInstanceInstantiatorTypeArgumentsReg,
           FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        ASSERT(n == 6);
+      if (n >= 7) {
         __ movq(
             kInstanceParentFunctionTypeArgumentsReg,
             FieldAddress(TypeTestABI::kInstanceReg,
@@ -2806,21 +2816,22 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n >= 2) {
+    if (n >= 3) {
       Label has_no_type_arguments;
-      __ LoadClassById(RDI, kInstanceCidOrFunction);
+      __ LoadClassById(kScratchReg, kInstanceCidOrFunction);
       __ movq(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
-      __ movl(RDI,
-              FieldAddress(
-                  RDI, target::Class::
+      __ movl(
+          kScratchReg,
+          FieldAddress(kScratchReg,
+                       target::Class::
                            host_type_arguments_field_offset_in_words_offset()));
-      __ cmpl(RDI, Immediate(target::Class::kNoTypeArguments));
+      __ cmpl(kScratchReg, Immediate(target::Class::kNoTypeArguments));
       __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
       __ movq(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(TypeTestABI::kInstanceReg, RDI, TIMES_8, 0));
+              FieldAddress(TypeTestABI::kInstanceReg, kScratchReg, TIMES_8, 0));
       __ Bind(&has_no_type_arguments);
 
-      if (n >= 6) {
+      if (n >= 7) {
         __ movq(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
         __ movq(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
       }
@@ -2832,71 +2843,76 @@
 
   // Loop header.
   __ Bind(&loop);
-  __ movq(
-      RDI,
-      Address(RSI, target::kWordSize *
-                       target::SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmpq(RDI, kNullReg);
+  __ movq(kScratchReg,
+          Address(kCacheArrayReg,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmpq(kScratchReg, kNullReg);
   __ j(EQUAL, &not_found, Assembler::kNearJump);
-  __ cmpq(RDI, kInstanceCidOrFunction);
+  __ cmpq(kScratchReg, kInstanceCidOrFunction);
   if (n == 1) {
     __ j(EQUAL, &found, Assembler::kNearJump);
   } else {
     __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+    __ cmpq(TypeTestABI::kDstTypeReg,
+            Address(kCacheArrayReg,
+                    target::kWordSize *
+                        target::SubtypeTestCache::kDestinationType));
+    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
     __ cmpq(kInstanceInstantiatorTypeArgumentsReg,
-            Address(RSI, target::kWordSize *
-                             target::SubtypeTestCache::kInstanceTypeArguments));
-    if (n == 2) {
+            Address(kCacheArrayReg,
+                    target::kWordSize *
+                        target::SubtypeTestCache::kInstanceTypeArguments));
+    if (n == 3) {
       __ j(EQUAL, &found, Assembler::kNearJump);
     } else {
       __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
       __ cmpq(
           TypeTestABI::kInstantiatorTypeArgumentsReg,
-          Address(RSI,
+          Address(kCacheArrayReg,
                   target::kWordSize *
                       target::SubtypeTestCache::kInstantiatorTypeArguments));
       __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ cmpq(
-          TypeTestABI::kFunctionTypeArgumentsReg,
-          Address(RSI, target::kWordSize *
-                           target::SubtypeTestCache::kFunctionTypeArguments));
+      __ cmpq(TypeTestABI::kFunctionTypeArgumentsReg,
+              Address(kCacheArrayReg,
+                      target::kWordSize *
+                          target::SubtypeTestCache::kFunctionTypeArguments));
 
-      if (n == 4) {
+      if (n == 5) {
         __ j(EQUAL, &found, Assembler::kNearJump);
       } else {
-        ASSERT(n == 6);
+        ASSERT(n == 7);
         __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
 
         __ cmpq(kInstanceParentFunctionTypeArgumentsReg,
-                Address(RSI, target::kWordSize *
-                                 target::SubtypeTestCache::
-                                     kInstanceParentFunctionTypeArguments));
+                Address(kCacheArrayReg,
+                        target::kWordSize *
+                            target::SubtypeTestCache::
+                                kInstanceParentFunctionTypeArguments));
         __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
         __ cmpq(kInstanceDelayedFunctionTypeArgumentsReg,
-                Address(RSI, target::kWordSize *
-                                 target::SubtypeTestCache::
-                                     kInstanceDelayedFunctionTypeArguments));
+                Address(kCacheArrayReg,
+                        target::kWordSize *
+                            target::SubtypeTestCache::
+                                kInstanceDelayedFunctionTypeArguments));
         __ j(EQUAL, &found, Assembler::kNearJump);
       }
     }
   }
 
   __ Bind(&next_iteration);
-  __ addq(RSI, Immediate(target::kWordSize *
-                         target::SubtypeTestCache::kTestEntryLength));
+  __ addq(kCacheArrayReg,
+          Immediate(target::kWordSize *
+                    target::SubtypeTestCache::kTestEntryLength));
   __ jmp(&loop, Assembler::kNearJump);
 
   __ Bind(&found);
-  __ movq(R8, Address(RSI, target::kWordSize *
-                               target::SubtypeTestCache::kTestResult));
-  if (n >= 6) {
-    __ popq(kInstanceDelayedFunctionTypeArgumentsReg);
-    __ popq(kInstanceParentFunctionTypeArgumentsReg);
-  }
-  __ ret();
+  __ movq(TypeTestABI::kSubtypeTestCacheResultReg,
+          Address(kCacheArrayReg,
+                  target::kWordSize * target::SubtypeTestCache::kTestResult));
 
   __ Bind(&not_found);
-  if (n >= 6) {
+  if (n >= 7) {
     __ popq(kInstanceDelayedFunctionTypeArgumentsReg);
     __ popq(kInstanceParentFunctionTypeArgumentsReg);
   }
@@ -2909,228 +2925,18 @@
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
+void StubCodeCompiler::GenerateSubtype3TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 3);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
+void StubCodeCompiler::GenerateSubtype5TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 5);
 }
 
 // See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-// Used to test whether a given value is of a given type (different variants,
-// all have the same calling convention).
-//
-// Inputs:
-//   - R9  : RawSubtypeTestCache
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments (if needed).
-//   - RCX : function type arguments (if needed).
-//
-//   - RBX : type to test against.
-//   - R10 : name of destination variable.
-//
-// Preserves R9/RAX/RCX/RDX, RBX, R10.
-//
-// Note of warning: The caller will not populate CODE_REG and we have therefore
-// no access to the pool.
-void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  __ movq(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
-  __ jmp(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-}
-
-// Used instead of DefaultTypeTestStub when null is assignable.
-void StubCodeCompiler::GenerateDefaultNullableTypeTestStub(
-    Assembler* assembler) {
-  Label done;
-
-  // Fast case for 'null'.
-  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-  __ BranchIf(EQUAL, &done);
-
-  __ movq(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
-  __ jmp(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
-                                            TypeCheckMode mode) {
-  __ PushObject(NullObject());  // Make room for result.
-  __ pushq(TypeTestABI::kInstanceReg);
-  __ pushq(TypeTestABI::kDstTypeReg);
-  __ pushq(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ pushq(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ PushObject(NullObject());
-  __ pushq(TypeTestABI::kSubtypeTestCacheReg);
-  __ PushImmediate(Immediate(target::ToRawSmi(mode)));
-  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
-  __ Drop(1);  // mode
-  __ popq(TypeTestABI::kSubtypeTestCacheReg);
-  __ Drop(1);
-  __ popq(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ popq(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ popq(TypeTestABI::kDstTypeReg);
-  __ popq(TypeTestABI::kInstanceReg);
-  __ Drop(1);  // Discard return value.
-}
-
-void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
-    Assembler* assembler) {
-  __ movq(
-      CODE_REG,
-      Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Used instead of LazySpecializeTypeTestStub when null is assignable.
-void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
-    Assembler* assembler) {
-  Label done;
-
-  // Fast case for 'null'.
-  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-  __ BranchIf(EQUAL, &done);
-
-  __ movq(
-      CODE_REG,
-      Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-static void BuildTypeParameterTypeTestStub(Assembler* assembler,
-                                           bool allow_null) {
-  Label done;
-
-  if (allow_null) {
-    __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
-    __ BranchIf(EQUAL, &done);
-  }
-
-  Label function_type_param;
-  __ cmpw(FieldAddress(TypeTestABI::kDstTypeReg,
-                       TypeParameter::parameterized_class_id_offset()),
-          Immediate(kFunctionCid));
-  __ BranchIf(EQUAL, &function_type_param);
-
-  auto handle_case = [&](Register tav) {
-    __ CompareObject(tav, NullObject());
-    __ BranchIf(EQUAL, &done);
-    __ movzxw(
-        TypeTestABI::kScratchReg,
-        FieldAddress(TypeTestABI::kDstTypeReg, TypeParameter::index_offset()));
-    __ movq(TypeTestABI::kScratchReg,
-            FieldAddress(tav, TypeTestABI::kScratchReg, TIMES_8,
-                         target::TypeArguments::InstanceSize()));
-    __ jmp(FieldAddress(TypeTestABI::kScratchReg,
-                        AbstractType::type_test_stub_entry_point_offset()));
-  };
-
-  // Class type parameter: If dynamic we're done, otherwise dereference type
-  // parameter and tail call.
-  handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
-
-  // Function type parameter: If dynamic we're done, otherwise dereference type
-  // parameter and tail call.
-  __ Bind(&function_type_param);
-  handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCodeCompiler::GenerateNullableTypeParameterTypeTestStub(
-    Assembler* assembler) {
-  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/true);
-}
-
-void StubCodeCompiler::GenerateTypeParameterTypeTestStub(Assembler* assembler) {
-  BuildTypeParameterTypeTestStub(assembler, /*allow_null=*/false);
-}
-
-void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
-  Label done, call_runtime;
-
-  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    __ movq(CODE_REG,
-            Address(THR, target::Thread::slow_type_test_stub_offset()));
-  }
-  __ EnterStubFrame();
-
-  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
-  __ BranchIf(EQUAL, &call_runtime);
-
-  const Register kTmp = RDI;
-
-  // If this is not a [Type] object, we'll go to the runtime.
-  Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, TypeTestABI::kDstTypeReg);
-  __ cmpq(kTmp, Immediate(kTypeCid));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is instantiated/uninstantiated.
-  __ cmpb(
-      FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
-      Immediate(target::AbstractTypeLayout::kTypeStateFinalizedInstantiated));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is a function type.
-  __ movq(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
-                             target::Type::signature_offset()));
-  __ CompareObject(kTmp, NullObject());
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
-
-  // Fall through to &is_simple_case
-
-  __ Bind(&is_simple_case);
-  {
-    __ Call(StubCodeSubtype2TestCache());
-    __ CompareObject(R8, CastHandle<Object>(TrueObject()));
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    __ Jump(&call_runtime);
-  }
-
-  __ Bind(&is_complex_case);
-  {
-    __ Call(StubCodeSubtype6TestCache());
-    __ CompareObject(R8, CastHandle<Object>(TrueObject()));
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    // Fall through to runtime_call
-  }
-
-  __ Bind(&call_runtime);
-
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
-
-  __ Bind(&done);
-  __ LeaveStubFrame();
-  __ Ret();
+void StubCodeCompiler::GenerateSubtype7TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 7);
 }
 
 // Return the current stack pointer address, used to stack alignment
@@ -3712,7 +3518,8 @@
   Label call_runtime;
   __ pushq(AllocateTypedDataArrayABI::kLengthReg);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &call_runtime, false));
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(cid, &call_runtime, Assembler::kFarJump));
   __ movq(RDI, AllocateTypedDataArrayABI::kLengthReg);
   /* Check that length is a positive Smi. */
   /* RDI: requested array length argument. */
@@ -3773,8 +3580,7 @@
     __ Bind(&done);
 
     /* Get the class index and insert it into the tags. */
-    uint32_t tags =
-        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    uword tags = target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
     __ orq(RDI, Immediate(tags));
     __ movq(FieldAddress(RAX, target::Object::tags_offset()), RDI); /* Tags. */
   }
diff --git a/runtime/vm/constants.h b/runtime/vm/constants.h
index f89abc6..01d9d08 100644
--- a/runtime/vm/constants.h
+++ b/runtime/vm/constants.h
@@ -53,6 +53,12 @@
   return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
 }
 
+#if !defined(TARGET_ARCH_IA32)
+constexpr bool IsAbiPreservedRegister(Register reg) {
+  return (kAbiPreservedCpuRegs & (1 << reg)) != 0;
+}
+#endif
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CONSTANTS_H_
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 016d438..5c2d42f 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -333,13 +333,20 @@
   static const Register kSubtypeTestCacheReg = R3;
   static const Register kScratchReg = R4;
 
+  // For calls to InstanceOfStub.
+  static const Register kInstanceOfResultReg = kInstanceReg;
+  // For calls to SubtypeNTestCacheStub. Must be saved by the caller if the
+  // original value is needed after the call.
+  static const Register kSubtypeTestCacheResultReg = kSubtypeTestCacheReg;
+
+  // Registers that need saving across SubtypeTestCacheStub calls.
+  static const intptr_t kSubtypeTestCacheStubCallerSavedRegisters =
+      1 << kSubtypeTestCacheReg;
+
   static const intptr_t kAbiRegisters =
       (1 << kInstanceReg) | (1 << kDstTypeReg) |
       (1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
       (1 << kSubtypeTestCacheReg) | (1 << kScratchReg);
-
-  // For call to InstanceOfStub.
-  static const Register kResultReg = R0;
 };
 
 // Calling convention when calling AssertSubtypeStub.
@@ -480,7 +487,7 @@
   static const intptr_t kArgumentRegisters = kAbiArgumentCpuRegs;
   static const Register ArgumentRegisters[];
   static const intptr_t kNumArgRegs = 4;
-  static const Register kPointerToReturnStructRegister = R0;
+  static const Register kPointerToReturnStructRegisterCall = R0;
 
   static const intptr_t kFpuArgumentRegisters = 0;
 
@@ -520,6 +527,7 @@
   static constexpr Register kReturnReg = R0;
   static constexpr Register kSecondReturnReg = R1;
   static constexpr FpuRegister kReturnFpuReg = Q0;
+  static constexpr Register kPointerToReturnStructRegisterReturn = kReturnReg;
 
   // We choose these to avoid overlap between themselves and reserved registers.
   static constexpr Register kFirstNonArgumentRegister = R8;
@@ -529,7 +537,7 @@
 
   COMPILE_ASSERT(
       ((R(kFirstNonArgumentRegister) | R(kSecondNonArgumentRegister)) &
-       (kArgumentRegisters | R(kPointerToReturnStructRegister))) == 0);
+       (kArgumentRegisters | R(kPointerToReturnStructRegisterCall))) == 0);
 };
 
 #undef R
@@ -699,6 +707,24 @@
   kBranchOffsetMask = 0x00ffffff
 };
 
+enum ScaleFactor {
+  TIMES_1 = 0,
+  TIMES_2 = 1,
+  TIMES_4 = 2,
+  TIMES_8 = 3,
+  TIMES_16 = 4,
+// Don't use (dart::)kWordSizeLog2, as this needs to work for crossword as
+// well. If this is included, we know the target is 32 bit.
+#if defined(TARGET_ARCH_IS_32_BIT)
+  // Used for Smi-boxed indices.
+  TIMES_HALF_WORD_SIZE = kInt32SizeLog2 - 1,
+  // Used for unboxed indices.
+  TIMES_WORD_SIZE = kInt32SizeLog2,
+#else
+#error "Unexpected word size"
+#endif
+};
+
 // The class Instr enables access to individual fields defined in the ARM
 // architecture instruction set encoding as described in figure A3-1.
 //
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 39225df..5e94310 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -165,13 +165,21 @@
   static const Register kSubtypeTestCacheReg = R3;
   static const Register kScratchReg = R4;
 
+  // For calls to InstanceOfStub.
+  static const Register kInstanceOfResultReg = kInstanceReg;
+  // For calls to SubtypeNTestCacheStub. Must not overlap with any other
+  // registers above, for it is also used internally as kNullReg in those stubs.
+  static const Register kSubtypeTestCacheResultReg = R7;
+
+  // Registers that need saving across SubtypeTestCacheStub calls.
+  static const intptr_t kSubtypeTestCacheStubCallerSavedRegisters =
+      1 << kSubtypeTestCacheReg;
+
   static const intptr_t kAbiRegisters =
       (1 << kInstanceReg) | (1 << kDstTypeReg) |
       (1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
-      (1 << kSubtypeTestCacheReg) | (1 << kScratchReg);
-
-  // For call to InstanceOfStub.
-  static const Register kResultReg = R0;
+      (1 << kSubtypeTestCacheReg) | (1 << kScratchReg) |
+      (1 << kSubtypeTestCacheResultReg);
 };
 
 // Calling convention when calling AssertSubtypeStub.
@@ -338,7 +346,8 @@
   // The native ABI uses R8 to pass the pointer to the memory preallocated for
   // struct return values. Arm64 is the only ABI in which this pointer is _not_
   // in ArgumentRegisters[0] or on the stack.
-  static const Register kPointerToReturnStructRegister = R8;
+  static const Register kPointerToReturnStructRegisterCall = R8;
+  static const Register kPointerToReturnStructRegisterReturn = R8;
 
   static const FpuRegister FpuArgumentRegisters[];
   static const intptr_t kFpuArgumentRegisters =
@@ -355,6 +364,9 @@
 
   // How stack arguments are aligned.
 #if defined(TARGET_OS_MACOS_IOS)
+  // > Function arguments may consume slots on the stack that are not multiples
+  // > of 8 bytes.
+  // https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms
   static constexpr AlignmentStrategy kArgumentStackAlignment =
       kAlignedToValueSize;
 #else
@@ -387,7 +399,7 @@
 
   COMPILE_ASSERT(
       ((R(kFirstNonArgumentRegister) | R(kSecondNonArgumentRegister)) &
-       (kArgumentRegisters | R(kPointerToReturnStructRegister))) == 0);
+       (kArgumentRegisters | R(kPointerToReturnStructRegisterCall))) == 0);
 };
 
 #undef R
@@ -487,64 +499,6 @@
   B31 = (1 << 31),
 };
 
-enum OperandSize {
-  kByte,
-  kUnsignedByte,
-  kHalfword,
-  kUnsignedHalfword,
-  kWord,
-  kUnsignedWord,
-  kDoubleWord,
-  kSWord,
-  kDWord,
-  kQWord,
-};
-
-static inline int Log2OperandSizeBytes(OperandSize os) {
-  switch (os) {
-    case kByte:
-    case kUnsignedByte:
-      return 0;
-    case kHalfword:
-    case kUnsignedHalfword:
-      return 1;
-    case kWord:
-    case kUnsignedWord:
-    case kSWord:
-      return 2;
-    case kDoubleWord:
-    case kDWord:
-      return 3;
-    case kQWord:
-      return 4;
-    default:
-      UNREACHABLE();
-      break;
-  }
-  return -1;
-}
-
-static inline bool IsSignedOperand(OperandSize os) {
-  switch (os) {
-    case kByte:
-    case kHalfword:
-    case kWord:
-      return true;
-    case kUnsignedByte:
-    case kUnsignedHalfword:
-    case kUnsignedWord:
-    case kDoubleWord:
-    case kSWord:
-    case kDWord:
-    case kQWord:
-      return false;
-    default:
-      UNREACHABLE();
-      break;
-  }
-  return false;
-}
-
 // Opcodes from C3
 // C3.1.
 enum MainOp {
@@ -1095,6 +1049,24 @@
   return result;
 }
 
+enum ScaleFactor {
+  TIMES_1 = 0,
+  TIMES_2 = 1,
+  TIMES_4 = 2,
+  TIMES_8 = 3,
+  TIMES_16 = 4,
+// We can't include vm/compiler/runtime_api.h, so just be explicit instead
+// of using (dart::)kWordSizeLog2.
+#if defined(TARGET_ARCH_IS_64_BIT)
+  // Used for Smi-boxed indices.
+  TIMES_HALF_WORD_SIZE = kInt64SizeLog2 - 1,
+  // Used for unboxed indices.
+  TIMES_WORD_SIZE = kInt64SizeLog2,
+#else
+#error "Unexpected word size"
+#endif
+};
+
 // The class Instr enables access to individual fields defined in the ARM
 // architecture instruction set encoding as described in figure A3-1.
 //
@@ -1110,6 +1082,8 @@
  public:
   enum { kInstrSize = 4, kInstrSizeLog2 = 2, kPCReadOffset = 8 };
 
+  enum class WideSize { k32Bits, k64Bits };
+
   static const int32_t kNopInstruction = HINT;  // hint #0 === nop.
 
   // Reserved brk and hlt instruction codes.
@@ -1153,10 +1127,9 @@
                               Register rd,
                               uint16_t imm,
                               int hw,
-                              OperandSize sz) {
+                              WideSize sz) {
     ASSERT((hw >= 0) && (hw <= 3));
-    ASSERT((sz == kDoubleWord) || (sz == kWord));
-    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const int32_t size = (sz == WideSize::k64Bits) ? B31 : 0;
     SetInstructionBits(op | size | (static_cast<int32_t>(rd) << kRdShift) |
                        (static_cast<int32_t>(hw) << kHWShift) |
                        (static_cast<int32_t>(imm) << kImm16Shift));
@@ -1396,7 +1369,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
 };
 
-const uword kBreakInstructionFiller = 0xD4200000D4200000L;  // brk #0; brk #0
+const uint64_t kBreakInstructionFiller = 0xD4200000D4200000L;  // brk #0; brk #0
 
 }  // namespace dart
 
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index a8d5b46..8e47d4d 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -118,7 +118,10 @@
       EDI;  // On ia32 we don't use CODE_REG.
 
   // For call to InstanceOfStub.
-  static const Register kResultReg = kNoRegister;
+  static const Register kInstanceOfResultReg = kInstanceReg;
+  // For call to SubtypeNTestCacheStub.
+  static const Register kSubtypeTestCacheResultReg =
+      TypeTestABI::kSubtypeTestCacheReg;
 };
 
 // Calling convention when calling kSubtypeCheckRuntimeEntry, to match other
@@ -202,7 +205,16 @@
   TIMES_4 = 2,
   TIMES_8 = 3,
   TIMES_16 = 4,
-  TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1
+// We can't include vm/compiler/runtime_api.h, so just be explicit instead
+// of using (dart::)kWordSizeLog2.
+#if defined(TARGET_ARCH_IS_32_BIT)
+  // Used for Smi-boxed indices.
+  TIMES_HALF_WORD_SIZE = kInt32SizeLog2 - 1,
+  // Used for unboxed indices.
+  TIMES_WORD_SIZE = kInt32SizeLog2,
+#else
+#error "Unexpected word size"
+#endif
 };
 
 class Instr {
@@ -239,7 +251,7 @@
   static const intptr_t kArgumentRegisters = 0;
   static const intptr_t kFpuArgumentRegisters = 0;
   static const intptr_t kNumArgRegs = 0;
-  static const Register kPointerToReturnStructRegister = kNoRegister;
+  static const Register kPointerToReturnStructRegisterCall = kNoRegister;
 
   static const XmmRegister FpuArgumentRegisters[];
   static const intptr_t kXmmArgumentRegisters = 0;
@@ -252,6 +264,7 @@
 
   static constexpr Register kReturnReg = EAX;
   static constexpr Register kSecondReturnReg = EDX;
+  static constexpr Register kPointerToReturnStructRegisterReturn = kReturnReg;
 
   // Floating point values are returned on the "FPU stack" (in "ST" registers).
   // However, we use XMM0 in our compiler pipeline as the location.
@@ -273,7 +286,7 @@
       kAlignedToWordSize;
 
   // How fields in composites are aligned.
-#if defined(_WIN32)
+#if defined(TARGET_OS_WINDOWS)
   static constexpr AlignmentStrategy kFieldAlignment = kAlignedToValueSize;
 #else
   static constexpr AlignmentStrategy kFieldAlignment =
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index c1fb6c3..480f565 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -155,13 +155,20 @@
   static const Register kSubtypeTestCacheReg = R9;
   static const Register kScratchReg = RSI;
 
+  // For calls to InstanceOfStub.
+  static const Register kInstanceOfResultReg = kInstanceReg;
+  // For calls to SubtypeNTestCacheStub. Must not overlap with any other
+  // registers above, for it is also used internally as kNullReg in those stubs.
+  static const Register kSubtypeTestCacheResultReg = R8;
+
+  // No registers need saving across SubtypeTestCacheStub calls.
+  static const intptr_t kSubtypeTestCacheStubCallerSavedRegisters = 0;
+
   static const intptr_t kAbiRegisters =
       (1 << kInstanceReg) | (1 << kDstTypeReg) |
       (1 << kInstantiatorTypeArgumentsReg) | (1 << kFunctionTypeArgumentsReg) |
-      (1 << kSubtypeTestCacheReg) | (1 << kScratchReg);
-
-  // For call to InstanceOfStub.
-  static const Register kResultReg = RAX;
+      (1 << kSubtypeTestCacheReg) | (1 << kScratchReg) |
+      (1 << kSubtypeTestCacheResultReg);
 };
 
 // Calling convention when calling AssertSubtypeStub.
@@ -277,7 +284,16 @@
   // https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4
   // 3.7.5 Specifying an Offset
   TIMES_16 = 4,
-  TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1
+// We can't include vm/compiler/runtime_api.h, so just be explicit instead
+// of using (dart::)kWordSizeLog2.
+#if defined(TARGET_ARCH_IS_64_BIT)
+  // Used for Smi-boxed indices.
+  TIMES_HALF_WORD_SIZE = kInt64SizeLog2 - 1,
+  // Used for unboxed indices.
+  TIMES_WORD_SIZE = kInt64SizeLog2,
+#else
+#error "Unexpected word size"
+#endif
 };
 
 #define R(reg) (1 << (reg))
@@ -293,12 +309,12 @@
   static const intptr_t kArgumentRegisters =
       R(kArg1Reg) | R(kArg2Reg) | R(kArg3Reg) | R(kArg4Reg);
   static const intptr_t kNumArgRegs = 4;
+  static const Register kPointerToReturnStructRegisterCall = kArg1Reg;
 
   static const XmmRegister FpuArgumentRegisters[];
   static const intptr_t kFpuArgumentRegisters =
       R(XMM0) | R(XMM1) | R(XMM2) | R(XMM3);
   static const intptr_t kNumFpuArgRegs = 4;
-  static const intptr_t kPointerToReturnStructRegister = kArg1Reg;
 
   // can ArgumentRegisters[i] and XmmArgumentRegisters[i] both be used at the
   // same time? (Windows no, rest yes)
@@ -338,6 +354,7 @@
   static constexpr Register kReturnReg = RAX;
   static constexpr Register kSecondReturnReg = kNoRegister;
   static constexpr FpuRegister kReturnFpuReg = XMM0;
+  static constexpr Register kPointerToReturnStructRegisterReturn = kReturnReg;
 
   // Whether larger than wordsize arguments are aligned to even registers.
   static constexpr AlignmentStrategy kArgumentRegisterAlignment =
@@ -368,7 +385,7 @@
                                              R(kArg3Reg) | R(kArg4Reg) |
                                              R(kArg5Reg) | R(kArg6Reg);
   static const intptr_t kNumArgRegs = 6;
-  static const Register kPointerToReturnStructRegister = kArg1Reg;
+  static const Register kPointerToReturnStructRegisterCall = kArg1Reg;
 
   static const XmmRegister FpuArgumentRegisters[];
   static const intptr_t kFpuArgumentRegisters = R(XMM0) | R(XMM1) | R(XMM2) |
@@ -399,8 +416,10 @@
   static const XmmRegister xmmFirstNonParameterReg = XMM8;
 
   static constexpr Register kReturnReg = RAX;
-  static constexpr Register kSecondReturnReg = kNoRegister;
+  static constexpr Register kSecondReturnReg = RDX;
   static constexpr FpuRegister kReturnFpuReg = XMM0;
+  static constexpr FpuRegister kSecondReturnFpuReg = XMM1;
+  static constexpr Register kPointerToReturnStructRegisterReturn = kReturnReg;
 
   // Whether larger than wordsize arguments are aligned to even registers.
   static constexpr AlignmentStrategy kArgumentRegisterAlignment =
@@ -435,9 +454,12 @@
 
   COMPILE_ASSERT(
       ((R(kFirstNonArgumentRegister) | R(kSecondNonArgumentRegister)) &
-       (kArgumentRegisters | R(kPointerToReturnStructRegister))) == 0);
+       (kArgumentRegisters | R(kPointerToReturnStructRegisterCall))) == 0);
 };
 
+constexpr intptr_t kAbiPreservedCpuRegs =
+    CallingConventions::kCalleeSaveCpuRegisters;
+
 #undef R
 
 class Instr {
@@ -469,7 +491,7 @@
 // becomes important to us.
 const int MAX_NOP_SIZE = 8;
 
-const uword kBreakInstructionFiller = 0xCCCCCCCCCCCCCCCCL;
+const uint64_t kBreakInstructionFiller = 0xCCCCCCCCCCCCCCCCL;
 
 }  // namespace dart
 
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index a541934..f5f806a 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -57,7 +57,7 @@
             "Use integer division instruction if supported");
 
 #if defined(TARGET_HOST_MISMATCH)
-#if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_IOS)
+#if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_MACOS_IOS)
 DEFINE_FLAG(bool, sim_use_hardfp, false, "Use the hardfp ABI.");
 #else
 DEFINE_FLAG(bool, sim_use_hardfp, true, "Use the hardfp ABI.");
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 5d7112a..9f63a72 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -215,6 +215,10 @@
     return Utils::StrDup(
         "To use --lazy-async-stacks, please disable --causal-async-stacks!");
   }
+  // TODO(cskau): Remove once flag deprecation has been completed.
+  if (FLAG_causal_async_stacks) {
+    return Utils::StrDup("--causal-async-stacks is deprecated!");
+  }
 
   FrameLayout::Init();
 
@@ -693,8 +697,7 @@
   }
   I->isolate_object_store()->Init();
   I->isolate_object_store()->PreallocateObjects();
-  I->set_field_table(
-      T, source_isolate_group->saved_initial_field_table()->Clone());
+  I->set_field_table(T, source_isolate_group->initial_field_table()->Clone(I));
 
   return true;
 }
@@ -739,8 +742,7 @@
       return error.raw();
     }
 
-    I->group()->set_saved_initial_field_table(
-        std::shared_ptr<FieldTable>(I->field_table()->Clone()));
+    I->set_field_table(T, I->group()->initial_field_table()->Clone(I));
 
 #if defined(SUPPORT_TIMELINE)
     if (tbes.enabled()) {
@@ -806,7 +808,7 @@
   }
 
   // If we are loading from source, figure out the mode from the source.
-  if (!KernelIsolate::GetExperimentalFlag("no-non-nullable")) {
+  if (KernelIsolate::GetExperimentalFlag(ExperimentalFeature::non_nullable)) {
     return KernelIsolate::DetectNullSafety(script_uri, package_config,
                                            original_working_directory);
   }
@@ -1068,7 +1070,7 @@
   Isolate* isolate = thread->isolate();
   void* isolate_group_data = isolate->group()->embedder_data();
   void* isolate_data = isolate->init_callback_data();
-  Dart_IsolateShutdownCallback callback = Isolate::ShutdownCallback();
+  Dart_IsolateShutdownCallback callback = isolate->on_shutdown_callback();
   if (callback != NULL) {
     TransitionVMToNative transition(thread);
     (callback)(isolate_group_data, isolate_data);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 4776fa5..2071a31 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -671,7 +671,7 @@
     memset(field_values, 0, (num_fields * sizeof(field_values[0])));
     return true;
   }
-  ASSERT(class_num_fields == Smi::Value(native_fields->ptr()->length_));
+  ASSERT(class_num_fields == Smi::Value(native_fields->ptr()->length()));
   intptr_t* native_values =
       reinterpret_cast<intptr_t*>(native_fields->ptr()->data());
   memmove(field_values, native_values, (num_fields * sizeof(field_values[0])));
@@ -1563,6 +1563,47 @@
   return isolate;
 }
 
+DART_EXPORT Dart_Isolate
+Dart_CreateIsolateInGroup(Dart_Isolate group_member,
+                          const char* name,
+                          Dart_IsolateShutdownCallback shutdown_callback,
+                          Dart_IsolateCleanupCallback cleanup_callback,
+                          void* child_isolate_data,
+                          char** error) {
+  CHECK_NO_ISOLATE(Isolate::Current());
+  auto member = reinterpret_cast<Isolate*>(group_member);
+  if (member->IsScheduled()) {
+    FATAL("The given member isolate (%s) must not have been entered.",
+          member->name());
+  }
+
+  *error = nullptr;
+
+  if (!FLAG_enable_isolate_groups) {
+    *error = Utils::StrDup(
+        "Lightweight isolates are only implemented in AOT "
+        "mode and need to be explicitly enabled by passing "
+        "--enable-isolate-groups.");
+    return nullptr;
+  }
+
+  Isolate* isolate;
+#if defined(DART_PRECOMPILED_RUNTIME)
+  isolate = CreateWithinExistingIsolateGroupAOT(member->group(), name, error);
+  if (isolate != nullptr) {
+    isolate->set_origin_id(member->origin_id());
+    isolate->set_init_callback_data(child_isolate_data);
+    isolate->set_on_shutdown_callback(shutdown_callback);
+    isolate->set_on_cleanup_callback(cleanup_callback);
+  }
+#else
+  *error = Utils::StrDup("Lightweight isolates are not yet ready in JIT mode.");
+  isolate = nullptr;
+#endif
+
+  return Api::CastIsolate(isolate);
+}
+
 DART_EXPORT void Dart_ShutdownIsolate() {
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
@@ -1590,6 +1631,9 @@
   {
     StackZone zone(T);
     HandleScope handle_scope(T);
+#if defined(DEBUG)
+    I->ValidateConstants();
+#endif
     Dart::RunShutdownCallback();
   }
   Dart::ShutdownIsolate();
@@ -1656,10 +1700,16 @@
   // TODO(http://dartbug.com/16615): Validate isolate parameter.
   Isolate* iso = reinterpret_cast<Isolate*>(isolate);
   if (!Thread::EnterIsolate(iso)) {
-    FATAL(
-        "Unable to Enter Isolate : "
-        "Multiple mutators entering an isolate / "
-        "Dart VM is shutting down");
+    if (iso->IsScheduled()) {
+      FATAL(
+          "Isolate %s is already scheduled on mutator thread %p, "
+          "failed to schedule from os thread 0x%" Px "\n",
+          iso->name(), iso->scheduled_mutator_thread(),
+          OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadId()));
+    } else {
+      FATAL("Unable to enter isolate %s as Dart VM is shutting down",
+            iso->name());
+    }
   }
   // A Thread structure has been associated to the thread, we do the
   // safepoint transition explicitly here instead of using the
@@ -1998,18 +2048,11 @@
     FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
   }
   // TODO(16615): Validate isolate parameter.
-  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
-  const char* error;
-  if (iso->object_store()->root_library() == Library::null()) {
-    // The embedder should have called Dart_LoadScriptFromKernel by now.
-    error = "Missing root library";
-  } else {
-    error = iso->MakeRunnable();
-  }
-  if (error != NULL) {
+  const char* error = reinterpret_cast<Isolate*>(isolate)->MakeRunnable();
+  if (error != nullptr) {
     return Utils::StrDup(error);
   }
-  return NULL;
+  return nullptr;
 }
 
 // --- Messages and Ports ---
@@ -2094,6 +2137,53 @@
   return Api::Success();
 }
 
+DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal,
+                                   Dart_Port on_error_port,
+                                   Dart_Port on_exit_port,
+                                   char** error) {
+  auto thread = Thread::Current();
+  auto isolate = thread->isolate();
+  CHECK_ISOLATE(isolate);
+  *error = nullptr;
+
+  if (thread->api_top_scope() != nullptr) {
+    *error = Utils::StrDup("There must not be an active api scope.");
+    return false;
+  }
+
+  if (!isolate->is_runnable()) {
+    const char* error_msg = isolate->MakeRunnable();
+    if (error_msg != nullptr) {
+      *error = Utils::StrDup(error_msg);
+      return false;
+    }
+  }
+
+  isolate->SetErrorsFatal(errors_are_fatal);
+
+  if (on_error_port != ILLEGAL_PORT || on_exit_port != ILLEGAL_PORT) {
+    auto thread = Thread::Current();
+    TransitionNativeToVM transition(thread);
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+
+    if (on_error_port != ILLEGAL_PORT) {
+      const auto& port =
+          SendPort::Handle(thread->zone(), SendPort::New(on_error_port));
+      isolate->AddErrorListener(port);
+    }
+    if (on_exit_port != ILLEGAL_PORT) {
+      const auto& port =
+          SendPort::Handle(thread->zone(), SendPort::New(on_exit_port));
+      isolate->AddExitListener(port, Instance::null_instance());
+    }
+  }
+
+  Dart_ExitIsolate();
+  isolate->Run();
+  return true;
+}
+
 DART_EXPORT Dart_Handle Dart_HandleMessage() {
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
@@ -4435,26 +4525,6 @@
   constructor ^= result.raw();
 
   Instance& new_object = Instance::Handle(Z);
-  if (constructor.IsRedirectingFactory()) {
-    Type& redirect_type = Type::Handle(constructor.RedirectionType());
-    constructor = constructor.RedirectionTarget();
-    ASSERT(!constructor.IsNull());
-
-    if (!redirect_type.IsInstantiated()) {
-      // The type arguments of the redirection type are instantiated from the
-      // type arguments of the type argument.
-      // We do not support generic constructors.
-      ASSERT(redirect_type.IsInstantiated(kFunctions));
-      redirect_type ^= redirect_type.InstantiateFrom(
-          type_arguments, Object::null_type_arguments(), kNoneFree, Heap::kNew);
-      redirect_type ^= redirect_type.Canonicalize(T, nullptr);
-    }
-
-    type_obj = redirect_type.raw();
-    type_arguments = redirect_type.arguments();
-
-    cls = type_obj.type_class();
-  }
   if (constructor.IsGenerativeConstructor()) {
     CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
 #if defined(DEBUG)
@@ -4557,7 +4627,7 @@
     return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
   }
 #endif
-  CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
+  CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
   return Api::NewHandle(T, AllocateObject(T, cls));
 }
 
@@ -4583,7 +4653,7 @@
     return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
   }
 #endif
-  CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
+  CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
   if (num_native_fields != cls.num_native_fields()) {
     return Api::NewError(
         "%s: invalid number of native fields %" Pd " passed in, expected %d",
@@ -5445,11 +5515,6 @@
     if (Symbols::DartIsVM().Equals(name)) {
       return Symbols::True().raw();
     }
-    if (FLAG_causal_async_stacks) {
-      if (Symbols::DartDeveloperCausalAsyncStacks().Equals(name)) {
-        return Symbols::True().raw();
-      }
-    }
   }
   return result.raw();
 }
@@ -5948,7 +6013,7 @@
     for (intptr_t j = 0; j < imports.Length(); j++) {
       ns ^= imports.At(j);
       if (ns.IsNull()) continue;
-      importee = ns.library();
+      importee = ns.target();
       importee_uri = importee.url();
       if (importee_uri.StartsWith(scheme_vm)) {
         result.Add(importer);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index fea59eb..785a41d 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -7364,7 +7364,9 @@
       "foo1:///main.dart",
       /* multiroot_filepaths= */ "/bar,/baz",
       /* multiroot_scheme= */ "foo");
-  EXPECT_ERROR(lib, "Compilation failed FileSystemException(uri=foo1:");
+  EXPECT_ERROR(lib,
+               "Compilation failed Invalid argument(s): Exception when reading "
+               "'foo1:///.dart_tool");
 }
 
 void NewNativePort_send123(Dart_Port dest_port_id, Dart_CObject* message) {
@@ -7866,10 +7868,10 @@
       "}\n";
 
   // Create an isolate.
-  Dart_Isolate isolate = TestCase::CreateTestIsolate();
+  auto isolate = reinterpret_cast<Isolate*>(TestCase::CreateTestIsolate());
   EXPECT(isolate != NULL);
 
-  Isolate::SetShutdownCallback(IsolateShutdownRunDartCodeTestCallback);
+  isolate->set_on_shutdown_callback(IsolateShutdownRunDartCodeTestCallback);
 
   {
     Dart_EnterScope();
@@ -7887,8 +7889,6 @@
   // The shutdown callback has not been called.
   EXPECT_EQ(0, add_result);
 
-  EXPECT(isolate != NULL);
-
   // Shutdown the isolate.
   Dart_ShutdownIsolate();
 
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index d371645..7c3e3de 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -331,7 +331,7 @@
 Dart_CObject* ApiMessageReader::CreateDartCObjectString(ObjectPtr raw) {
   ASSERT(IsOneByteStringClassId(raw->GetClassId()));
   OneByteStringPtr raw_str = static_cast<OneByteStringPtr>(raw);
-  intptr_t len = Smi::Value(raw_str->ptr()->length_);
+  intptr_t len = Smi::Value(raw_str->ptr()->length());
   Dart_CObject* object = AllocateDartCObjectString(len);
   char* p = object->value.as_string;
   memmove(p, raw_str->ptr()->data(), len);
@@ -842,11 +842,11 @@
     if (forward_list_length_ == 0) {
       forward_list_length_ = 4;
       intptr_t new_size = forward_list_length_ * sizeof(object);
-      new_list = ::malloc(new_size);
+      new_list = dart::malloc(new_size);
     } else {
       forward_list_length_ *= 2;
       intptr_t new_size = (forward_list_length_ * sizeof(object));
-      new_list = ::realloc(forward_list_, new_size);
+      new_list = dart::realloc(forward_list_, new_size);
     }
     ASSERT(new_list != NULL);
     forward_list_ = reinterpret_cast<Dart_CObject**>(new_list);
@@ -1039,7 +1039,7 @@
       WriteSmi(len);
       if (type == Utf8::kLatin1) {
         uint8_t* latin1_str =
-            reinterpret_cast<uint8_t*>(::malloc(len * sizeof(uint8_t)));
+            reinterpret_cast<uint8_t*>(dart::malloc(len * sizeof(uint8_t)));
         bool success =
             Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, len);
         ASSERT(success);
@@ -1049,7 +1049,7 @@
         ::free(latin1_str);
       } else {
         uint16_t* utf16_str =
-            reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
+            reinterpret_cast<uint16_t*>(dart::malloc(len * sizeof(uint16_t)));
         bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
         ASSERT(success);
         for (intptr_t i = 0; i < len; i++) {
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 63db37e..8761060 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -273,12 +273,10 @@
                               arguments_descriptor);
   }
 
-  if (!callable_function.CanReceiveDynamicInvocation()) {
-    const auto& result = Object::Handle(
-        zone, callable_function.DoArgumentTypesMatch(arguments, args_desc));
-    if (result.IsError()) {
-      Exceptions::PropagateError(Error::Cast(result));
-    }
+  const auto& result = Object::Handle(
+      zone, callable_function.DoArgumentTypesMatch(arguments, args_desc));
+  if (result.IsError()) {
+    Exceptions::PropagateError(Error::Cast(result));
   }
 
   return InvokeFunction(callable_function, arguments, arguments_descriptor);
@@ -438,7 +436,7 @@
         buffer->AddString(", ");
       }
       str = NameAt(i);
-      buffer->Printf("'%s'", str.ToCString());
+      buffer->Printf("'%s' (%" Pd ")", str.ToCString(), PositionAt(i));
     }
     buffer->Printf("]");
   }
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 5a146e0..d1096d7 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -731,10 +731,6 @@
   return Object::null();
 }
 
-ObjectPtr ActivationFrame::GetCausalStack() {
-  return GetAsyncContextVariable(Symbols::AsyncStackTraceVar());
-}
-
 bool ActivationFrame::HandlesException(const Instance& exc_obj) {
   if ((kind_ == kAsyncSuspensionMarker) || (kind_ == kAsyncCausal)) {
     // These frames are historical.
@@ -1555,8 +1551,6 @@
   }
 }
 
-void Debugger::OnIsolateRunnable() {}
-
 bool Debugger::SetupStepOverAsyncSuspension(const char** error) {
   ActivationFrame* top_frame = TopDartFrame();
   if (!IsAtAsyncJump(top_frame)) {
@@ -1825,97 +1819,9 @@
     return CollectAsyncLazyStackTrace();
   }
   if (!FLAG_causal_async_stacks) {
-    return NULL;
+    return nullptr;
   }
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
-  DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
-
-  Object& code_obj = Object::Handle(zone);
-  Code& code = Code::Handle(zone);
-  Smi& offset = Smi::Handle();
-  Code& inlined_code = Code::Handle(zone);
-  Array& deopt_frame = Array::Handle(zone);
-
-  Function& async_function = Function::Handle(zone);
-  class StackTrace& async_stack_trace = StackTrace::Handle(zone);
-  Array& async_code_array = Array::Handle(zone);
-  Array& async_pc_offset_array = Array::Handle(zone);
-
-  // Extract the eagerly recorded async stack from the current thread.
-  StackTraceUtils::ExtractAsyncStackTraceInfo(
-      thread, &async_function, &async_stack_trace, &async_code_array,
-      &async_pc_offset_array);
-
-  if (async_function.IsNull()) {
-    return NULL;
-  }
-
-  bool sync_async_end = false;
-  intptr_t synchronous_stack_trace_length =
-      StackTraceUtils::CountFrames(thread, 0, async_function, &sync_async_end);
-
-  // Append the top frames from the synchronous stack trace, up until the active
-  // asynchronous function. We truncate the remainder of the synchronous
-  // stack trace because it contains activations that are part of the
-  // asynchronous dispatch mechanisms.
-  StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames,
-                              Thread::Current(),
-                              StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* frame = iterator.NextFrame();
-  while (synchronous_stack_trace_length > 0) {
-    ASSERT(frame != NULL);
-    if (frame->IsDartFrame()) {
-      code = frame->LookupDartCode();
-      AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
-                       &inlined_code, &deopt_frame);
-      synchronous_stack_trace_length--;
-    }
-    frame = iterator.NextFrame();
-  }
-
-  // Now we append the asynchronous causal stack trace. These are not active
-  // frames but a historical record of how this asynchronous function was
-  // activated.
-
-  intptr_t frame_skip =
-      sync_async_end ? StackTrace::kSyncAsyncCroppedFrames : 0;
-  while (!async_stack_trace.IsNull()) {
-    for (intptr_t i = frame_skip; i < async_stack_trace.Length(); i++) {
-      code_obj = async_stack_trace.CodeAtFrame(i);
-      if (code_obj.IsNull()) {
-        break;
-      }
-      if (code_obj.raw() == StubCode::AsynchronousGapMarker().raw()) {
-        stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker);
-        // The frame immediately below the asynchronous gap marker is the
-        // identical to the frame above the marker. Skip the frame to enhance
-        // the readability of the trace.
-        i++;
-      } else {
-        offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i));
-        code ^= code_obj.raw();
-        uword pc = code.PayloadStart() + offset.Value();
-        if (code.is_optimized()) {
-          for (InlinedFunctionsIterator it(code, pc); !it.Done();
-               it.Advance()) {
-            inlined_code = it.code();
-            stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
-          }
-        } else {
-          stack_trace->AddAsyncCausalFrame(pc, code);
-        }
-      }
-    }
-    // Follow the link.
-    frame_skip = async_stack_trace.skip_sync_start_in_parent_stack()
-                     ? StackTrace::kSyncAsyncCroppedFrames
-                     : 0;
-    async_stack_trace = async_stack_trace.async_link();
-  }
-
-  return stack_trace;
+  UNREACHABLE();  //  FLAG_causal_async_stacks is deprecated.
 }
 
 DebuggerStackTrace* Debugger::CollectAsyncLazyStackTrace() {
@@ -1925,41 +1831,64 @@
 
   Code& code = Code::Handle(zone);
   Code& inlined_code = Code::Handle(zone);
-  Smi& offset = Smi::Handle();
   Array& deopt_frame = Array::Handle(zone);
+  Smi& offset = Smi::Handle(zone);
+  Function& function = Function::Handle(zone);
 
   constexpr intptr_t kDefaultStackAllocation = 8;
   auto stack_trace = new DebuggerStackTrace(kDefaultStackAllocation);
 
+  const auto& code_array = GrowableObjectArray::ZoneHandle(
+      zone, GrowableObjectArray::New(kDefaultStackAllocation));
+  const auto& pc_offset_array = GrowableObjectArray::ZoneHandle(
+      zone, GrowableObjectArray::New(kDefaultStackAllocation));
+  bool has_async = false;
+
   std::function<void(StackFrame*)> on_sync_frame = [&](StackFrame* frame) {
     code = frame->LookupDartCode();
     AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
                      &inlined_code, &deopt_frame);
   };
 
-  const auto& code_array = GrowableObjectArray::ZoneHandle(
-      zone, GrowableObjectArray::New(kDefaultStackAllocation));
-  const auto& pc_offset_array = GrowableObjectArray::ZoneHandle(
-      zone, GrowableObjectArray::New(kDefaultStackAllocation));
-  bool has_async = false;
   StackTraceUtils::CollectFramesLazy(thread, code_array, pc_offset_array,
                                      /*skip_frames=*/0, &on_sync_frame,
                                      &has_async);
 
+  // If the entire stack is sync, return no trace.
   if (!has_async) {
     return nullptr;
   }
 
   const intptr_t length = code_array.Length();
-  for (intptr_t i = stack_trace->Length(); i < length; ++i) {
+  bool async_frames = false;
+  for (intptr_t i = 0; i < length; ++i) {
     code ^= code_array.At(i);
-    offset ^= pc_offset_array.At(i);
+
     if (code.raw() == StubCode::AsynchronousGapMarker().raw()) {
       stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker);
-    } else {
-      const uword absolute_pc = code.PayloadStart() + offset.Value();
-      stack_trace->AddAsyncCausalFrame(absolute_pc, code);
+      // Once we reach a gap, the rest is async.
+      async_frames = true;
+      continue;
     }
+
+    // Skip the sync frames since they've been added (and un-inlined) above.
+    if (!async_frames) {
+      continue;
+    }
+
+    if (!code.IsFunctionCode()) {
+      continue;
+    }
+
+    // Skip invisible function frames.
+    function ^= code.function();
+    if (!function.is_visible()) {
+      continue;
+    }
+
+    offset ^= pc_offset_array.At(i);
+    const uword absolute_pc = code.PayloadStart() + offset.Value();
+    stack_trace->AddAsyncCausalFrame(absolute_pc, code);
   }
 
   return stack_trace;
@@ -1984,16 +1913,12 @@
                               Thread::Current(),
                               StackFrameIterator::kNoCrossThreadIteration);
 
-  Object& code_object = Object::Handle(zone);
   Code& code = Code::Handle(zone);
-  Smi& offset = Smi::Handle(zone);
   Function& function = Function::Handle(zone);
   Code& inlined_code = Code::Handle(zone);
   Closure& async_activation = Closure::Handle(zone);
   Object& next_async_activation = Object::Handle(zone);
   Array& deopt_frame = Array::Handle(zone);
-  // Note: 'class' since Debugger declares a method by the same name.
-  class StackTrace& async_stack_trace = StackTrace::Handle(zone);
   bool stack_has_async_function = false;
   Closure& closure = Closure::Handle();
 
@@ -2025,7 +1950,6 @@
         stack_has_async_function = true;
         // Grab the awaiter.
         async_activation ^= activation->GetAsyncAwaiter(&caller_closure_finder);
-        async_stack_trace ^= activation->GetCausalStack();
         // Bail if we've reach the end of sync execution stack.
         ObjectPtr* last_caller_obj =
             reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
@@ -2081,7 +2005,6 @@
         stack_has_async_function = true;
         // Grab the awaiter.
         async_activation ^= activation->GetAsyncAwaiter(&caller_closure_finder);
-        async_stack_trace ^= activation->GetCausalStack();
         found_async_awaiter = true;
       } else {
         stack_trace->AddActivation(CollectDartFrame(isolate, it.pc(), frame,
@@ -2108,8 +2031,6 @@
 
     if (!(activation->function().IsAsyncClosure() ||
           activation->function().IsAsyncGenClosure())) {
-      // No more awaiters. Extract the causal stack trace (if it exists).
-      async_stack_trace ^= activation->GetCausalStack();
       break;
     }
 
@@ -2124,59 +2045,12 @@
 
     next_async_activation = activation->GetAsyncAwaiter(&caller_closure_finder);
     if (next_async_activation.IsNull()) {
-      // No more awaiters. Extract the causal stack trace (if it exists).
-      async_stack_trace ^= activation->GetCausalStack();
       break;
     }
 
     async_activation = Closure::RawCast(next_async_activation.raw());
   }
 
-  // Now we append the asynchronous causal stack trace. These are not active
-  // frames but a historical record of how this asynchronous function was
-  // activated.
-  while (!async_stack_trace.IsNull()) {
-    for (intptr_t i = 0; i < async_stack_trace.Length(); i++) {
-      code_object = async_stack_trace.CodeAtFrame(i);
-
-      if (code_object.raw() == Code::null()) {
-        // Incomplete OutOfMemory/StackOverflow trace OR array padding.
-        break;
-      }
-
-      if (code_object.raw() == StubCode::AsynchronousGapMarker().raw()) {
-        stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker);
-        // The frame immediately below the asynchronous gap marker is the
-        // identical to the frame above the marker. Skip the frame to enhance
-        // the readability of the trace.
-        i++;
-        continue;
-      }
-
-      code_object = async_stack_trace.CodeAtFrame(i);
-      offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i));
-      code ^= code_object.raw();
-      if (FLAG_trace_debugger_stacktrace) {
-        OS::PrintErr(
-            "CollectAwaiterReturnStackTrace: visiting frame %" Pd
-            " in async causal stack trace:\n\t%s\n",
-            i, Function::Handle(code.function()).ToFullyQualifiedCString());
-      }
-      uword pc = code.PayloadStart() + offset.Value();
-      if (code.is_optimized()) {
-        for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) {
-          inlined_code = it.code();
-          stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
-        }
-      } else {
-        stack_trace->AddAsyncCausalFrame(pc, code);
-      }
-    }
-
-    // Follow the link.
-    async_stack_trace = async_stack_trace.async_link();
-  }
-
   return stack_trace;
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
@@ -3159,7 +3033,7 @@
   while ((loc == NULL) && (first_token_idx <= last_token_idx)) {
     loc = SetBreakpoint(script, first_token_idx, last_token_idx, line_number,
                         column_number, Function::Handle());
-    first_token_idx.Next();
+    first_token_idx = first_token_idx.Next();
   }
   if ((loc == NULL) && FLAG_verbose_debug) {
     OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
@@ -3723,9 +3597,7 @@
     }
   }
 
-  // Since lazy async stacks doesn't use the _asyncStackTraceHelper runtime
-  // entry, we need to manually set a synthetic breakpoint for async_op before
-  // we enter it.
+  // We need to manually set a synthetic breakpoint for async_op before entry.
   if (FLAG_lazy_async_stacks) {
     // async and async* functions always contain synthetic async_ops.
     if ((frame->function().IsAsyncFunction() ||
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index e5fd4ac..0312163 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -338,8 +338,6 @@
   // Get Closure that await'ed this async frame.
   ObjectPtr GetAsyncAwaiter(CallerClosureFinder* caller_closure_finder);
 
-  ObjectPtr GetCausalStack();
-
   bool HandlesException(const Instance& exc_obj);
 
  private:
@@ -470,8 +468,6 @@
   void NotifyIsolateCreated();
   void Shutdown();
 
-  void OnIsolateRunnable();
-
   void NotifyCompilation(const Function& func);
   void NotifyDoneLoading();
 
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 0c40fa9..dd896cc 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -27,7 +27,7 @@
 
 // Holds all data relevant for execution of deoptimization instructions.
 // Structure is allocated in C-heap.
-class DeoptContext {
+class DeoptContext : public MallocAllocated {
  public:
   enum DestFrameOptions {
     kDestIsOriginalFrame,  // Replace the original frame with deopt frame.
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 138d02e..b6abf76 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -1141,8 +1141,8 @@
                                     intptr_t offset2) {
     auto const address1 = RelocatedAddress(symbol1, offset1);
     auto const address2 = RelocatedAddress(symbol2, offset2);
+    RELEASE_ASSERT(address1 >= address2);
     auto const delta = address1 - address2;
-    RELEASE_ASSERT(delta >= 0);
     uleb128(delta);
   }
   void InitializeAbstractOrigins(intptr_t size) {
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index d67906f..6cc253e 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -1104,10 +1104,18 @@
   Exceptions::ThrowByType(Exceptions::kCompileTimeError, args);
 }
 
-void Exceptions::ThrowLateInitializationError(const String& name) {
+void Exceptions::ThrowLateFieldNotInitialized(const String& name) {
   const Array& args = Array::Handle(Array::New(1));
   args.SetAt(0, name);
-  Exceptions::ThrowByType(Exceptions::kLateInitializationError, args);
+  Exceptions::ThrowByType(Exceptions::kLateFieldNotInitialized, args);
+}
+
+void Exceptions::ThrowLateFieldAssignedDuringInitialization(
+    const String& name) {
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, name);
+  Exceptions::ThrowByType(Exceptions::kLateFieldAssignedDuringInitialization,
+                          args);
 }
 
 ObjectPtr Exceptions::Create(ExceptionType type, const Array& arguments) {
@@ -1197,9 +1205,15 @@
       library = Library::CoreLibrary();
       class_name = &Symbols::_CompileTimeError();
       break;
-    case kLateInitializationError:
-      library = Library::CoreLibrary();
-      class_name = &Symbols::LateInitializationError();
+    case kLateFieldAssignedDuringInitialization:
+      library = Library::InternalLibrary();
+      class_name = &Symbols::LateError();
+      constructor_name = &Symbols::DotFieldADI();
+      break;
+    case kLateFieldNotInitialized:
+      library = Library::InternalLibrary();
+      class_name = &Symbols::LateError();
+      constructor_name = &Symbols::DotFieldNI();
       break;
   }
 
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index e7b52e5..20aef13 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -67,7 +67,8 @@
     kAbstractClassInstantiation,
     kCyclicInitializationError,
     kCompileTimeError,
-    kLateInitializationError,
+    kLateFieldAssignedDuringInitialization,
+    kLateFieldNotInitialized,
   };
 
   DART_NORETURN static void ThrowByType(ExceptionType type,
@@ -83,7 +84,9 @@
                                             intptr_t expected_to);
   DART_NORETURN static void ThrowUnsupportedError(const char* msg);
   DART_NORETURN static void ThrowCompileTimeError(const LanguageError& error);
-  DART_NORETURN static void ThrowLateInitializationError(const String& name);
+  DART_NORETURN static void ThrowLateFieldAssignedDuringInitialization(
+      const String& name);
+  DART_NORETURN static void ThrowLateFieldNotInitialized(const String& name);
 
   // Returns a RawInstance if the exception is successfully created,
   // otherwise returns a RawError.
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
new file mode 100644
index 0000000..1fffd1a
--- /dev/null
+++ b/runtime/vm/experimental_features.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'tools/experimental_features.yaml' and run
+// 'dart tools/generate_experimental_flags.dart' to update.
+//
+// Current version: 2.12.0
+
+#include "vm/experimental_features.h"
+
+#include <cstring>
+#include "platform/assert.h"
+#include "vm/globals.h"
+
+namespace dart {
+
+bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
+  constexpr bool kFeatureValues[] = {
+    true,
+    true,
+    true,
+    true,
+    true,
+    true,
+  };
+  ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
+  return kFeatureValues[static_cast<int>(feature)];
+}
+
+const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
+  constexpr const char* kFeatureNames[] = {
+    "non-nullable",
+    "extension-methods",
+    "constant-update-2018",
+    "control-flow-collections",
+    "set-literals",
+    "spread-collections",
+  };
+  ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
+  return kFeatureNames[static_cast<int>(feature)];
+}
+
+}  // namespace dart
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
new file mode 100644
index 0000000..797b0d2
--- /dev/null
+++ b/runtime/vm/experimental_features.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'tools/experimental_features.yaml' and run
+// 'dart tools/generate_experimental_flags.dart' to update.
+//
+// Current version: 2.12.0
+
+#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
+#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
+
+namespace dart {
+
+enum class ExperimentalFeature {
+  non_nullable,
+  extension_methods,
+  constant_update_2018,
+  control_flow_collections,
+  set_literals,
+  spread_collections,
+};
+
+bool GetExperimentalFeatureDefault(ExperimentalFeature feature);
+const char* GetExperimentalFeatureName(ExperimentalFeature feature);
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
diff --git a/runtime/vm/field_table.cc b/runtime/vm/field_table.cc
index 495d7a0..a6358a1 100644
--- a/runtime/vm/field_table.cc
+++ b/runtime/vm/field_table.cc
@@ -73,7 +73,7 @@
     Grow(new_capacity);
   }
 
-  ASSERT(table_[index] == nullptr);
+  ASSERT(table_[index] == InstancePtr());
   if (index >= top_) {
     top_ = index + 1;
   }
@@ -98,14 +98,16 @@
   // via store to table_.
   std::atomic_thread_fence(std::memory_order_release);
   table_ = new_table;
-  Thread::Current()->field_table_values_ = table_;
+  if (isolate_ != nullptr) {
+    isolate_->mutator_thread()->field_table_values_ = table_;
+  }
 }
 
-FieldTable* FieldTable::Clone() {
-  FieldTable* clone = new FieldTable();
+FieldTable* FieldTable::Clone(Isolate* for_isolate) {
+  FieldTable* clone = new FieldTable(for_isolate);
   auto new_table = static_cast<InstancePtr*>(
       malloc(capacity_ * sizeof(InstancePtr)));  // NOLINT
-  memmove(new_table, table_, top_ * sizeof(InstancePtr));
+  memmove(new_table, table_, capacity_ * sizeof(InstancePtr));
   ASSERT(clone->table_ == nullptr);
   clone->table_ = new_table;
   clone->capacity_ = capacity_;
diff --git a/runtime/vm/field_table.h b/runtime/vm/field_table.h
index b4c8f23..4fc1ca8 100644
--- a/runtime/vm/field_table.h
+++ b/runtime/vm/field_table.h
@@ -16,16 +16,18 @@
 
 namespace dart {
 
+class Isolate;
 class Field;
 
 class FieldTable {
  public:
-  FieldTable()
+  explicit FieldTable(Isolate* isolate)
       : top_(0),
         capacity_(0),
         free_head_(-1),
         table_(nullptr),
-        old_tables_(new MallocGrowableArray<InstancePtr*>()) {}
+        old_tables_(new MallocGrowableArray<InstancePtr*>()),
+        isolate_(isolate) {}
 
   ~FieldTable();
 
@@ -55,7 +57,7 @@
   }
   void SetAt(intptr_t index, InstancePtr raw_instance);
 
-  FieldTable* Clone();
+  FieldTable* Clone(Isolate* for_isolate);
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
@@ -82,6 +84,11 @@
   // so it will get freed when its are no longer in use.
   MallocGrowableArray<InstancePtr*>* old_tables_;
 
+  // If non-NULL, it will specify the isolate this field table belongs to.
+  // Growing the field table will keep the cached field table on the isolate's
+  // mutator thread up-to-date.
+  Isolate* isolate_;
+
   DISALLOW_COPY_AND_ASSIGN(FieldTable);
 };
 
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 5e02239..36303f8 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -52,10 +52,11 @@
 //
 // The syntax used is the same as that for FLAG_LIST below, as these flags are
 // automatically included in FLAG_LIST.
+// TODO(cskau): Remove causal_async_stacks when deprecated.
 #define VM_GLOBAL_FLAG_LIST(P, R, C, D)                                        \
   P(dwarf_stack_traces_mode, bool, false,                                      \
     "Use --[no-]dwarf-stack-traces instead.")                                  \
-  P(causal_async_stacks, bool, false, "Improved async stacks")                 \
+  P(causal_async_stacks, bool, false, "DEPRECATED: Improved async stacks")     \
   P(lazy_async_stacks, bool, true, "Reconstruct async stacks from listeners")  \
   P(lazy_dispatchers, bool, true, "Generate dispatchers lazily")               \
   P(use_bare_instructions, bool, true, "Enable bare instructions mode.")       \
@@ -109,6 +110,9 @@
   R(enable_asserts, false, bool, false, "Enable assert statements.")           \
   R(null_assertions, false, bool, false,                                       \
     "Enable null assertions for parameters.")                                  \
+  R(strict_null_safety_checks, false, bool, false,                             \
+    "Enable strict type checks for non-nullable types and required "           \
+    "parameters.")                                                             \
   P(enable_kernel_expression_compilation, bool, true,                          \
     "Compile expressions with the Kernel front-end.")                          \
   P(enable_mirrors, bool, true,                                                \
@@ -116,7 +120,7 @@
   P(enable_ffi, bool, true, "Disable to make importing dart:ffi an error.")    \
   P(fields_may_be_reset, bool, false,                                          \
     "Don't optimize away static field initialization")                         \
-  C(force_clone_compiler_objects, false, false, bool, false,                   \
+  P(force_clone_compiler_objects, bool, false,                                 \
     "Force cloning of objects needed in compiler (ICData and Field).")         \
   P(getter_setter_ratio, int, 13,                                              \
     "Ratio of getter/setter usage used for double field unboxing heuristics")  \
@@ -167,8 +171,6 @@
   P(print_snapshot_sizes, bool, false, "Print sizes of generated snapshots.")  \
   P(print_snapshot_sizes_verbose, bool, false,                                 \
     "Print cluster sizes of generated snapshots.")                             \
-  P(print_benchmarking_metrics, bool, false,                                   \
-    "Print additional memory and latency metrics for benchmarking.")           \
   R(print_ssa_liveranges, false, bool, false,                                  \
     "Print live ranges after allocation.")                                     \
   R(print_stacktrace_at_api_error, false, bool, false,                         \
diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc
index 901856c..f3fc0ef 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -466,6 +466,30 @@
     PrintFlags();
   }
 
+  // TODO(dartbug.com/36097): Support for isolate groups in JIT mode is
+  // in-development. We will start with very conservative settings. As we make
+  // more of our compiler, runtime as well as generated code re-entrant we'll
+  // graudally remove those restrictions.
+
+#if !defined(DART_PRCOMPILED_RUNTIME)
+  if (!FLAG_precompiled_mode && FLAG_enable_isolate_groups) {
+    // Our compiler should not make rely on a global field being initialized at
+    // compile-time, since that compiled code might be re-used in another
+    // isolate that has not yet initialized the global field.
+    FLAG_fields_may_be_reset = true;
+
+    // We will start by only allowing compilation to unoptimized code.
+    FLAG_optimization_counter_threshold = -1;
+    FLAG_background_compilation = false;
+    FLAG_force_clone_compiler_objects = true;
+
+    // To eliminate potential flakiness, we will start by disabling field guards
+    // and CHA-based compilations.
+    FLAG_use_field_guards = false;
+    FLAG_use_cha_deopt = false;
+  }
+#endif  // !defined(DART_PRCOMPILED_RUNTIME)
+
   initialized_ = true;
   return NULL;
 }
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index 28ec9cc..ca6b5f4 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -116,7 +116,7 @@
   // is allocated from the chunk until we run out space in the chunk,
   // at this point another chunk is allocated. These chunks are chained
   // together.
-  class HandlesBlock {
+  class HandlesBlock : public MallocAllocated {
    public:
     explicit HandlesBlock(HandlesBlock* next)
         : next_handle_slot_(0), next_block_(next) {}
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index f4033dc..0697a13 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -157,9 +157,6 @@
   }
   if (scoped_blocks_->next_block() == NULL) {
     HandlesBlock* block = new HandlesBlock(NULL);
-    if (block == NULL) {
-      OUT_OF_MEMORY();
-    }
     scoped_blocks_->set_next_block(block);
   }
   scoped_blocks_ = scoped_blocks_->next_block();
@@ -207,9 +204,6 @@
                  CountScopedHandles());
   }
   zone_blocks_ = new HandlesBlock(zone_blocks_);
-  if (zone_blocks_ == NULL) {
-    OUT_OF_MEMORY();
-  }
 }
 
 #if defined(DEBUG)
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 409ab89..88d58ba 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -423,15 +423,17 @@
 
 template <typename KeyValueTrait>
 class MallocDirectChainedHashMap
-    : public BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc> {
+    : public BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc> {
  public:
   MallocDirectChainedHashMap()
-      : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(NULL) {}
+      : BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc>(NULL) {
+  }
 
   // The only use of the copy constructor seems to be in hash_map_test.cc.
   // Not disallowing it for now just in case there are other users.
   MallocDirectChainedHashMap(const MallocDirectChainedHashMap& other)
-      : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(other) {}
+      : BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc>(
+            other) {}
 
  private:
   void operator=(const MallocDirectChainedHashMap& other) = delete;
diff --git a/runtime/vm/heap/become.cc b/runtime/vm/heap/become.cc
index 8b9ac83..1a1415b 100644
--- a/runtime/vm/heap/become.cc
+++ b/runtime/vm/heap/become.cc
@@ -23,7 +23,7 @@
 
   ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr);
 
-  uint32_t tags = 0;
+  uword tags = result->tags_;  // Carry-over any identity hash.
   tags = ObjectLayout::SizeTag::update(size, tags);
   tags = ObjectLayout::ClassIdTag::update(kForwardingCorpse, tags);
   bool is_old = (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
@@ -86,25 +86,35 @@
   virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
     for (ObjectPtr* p = first; p <= last; p++) {
       ObjectPtr old_target = *p;
+      ObjectPtr new_target;
       if (IsForwardingObject(old_target)) {
-        ObjectPtr new_target = GetForwardedObject(old_target);
-        if (visiting_object_ == nullptr) {
-          *p = new_target;
-        } else if (visiting_object_->ptr()->IsCardRemembered()) {
-          visiting_object_->ptr()->StoreArrayPointer(p, new_target, thread_);
-        } else {
-          visiting_object_->ptr()->StorePointer(p, new_target, thread_);
-        }
+        new_target = GetForwardedObject(old_target);
+      } else {
+        // Though we do not need to update the slot's value when it is not
+        // forwarded, we do need to recheck the generational barrier. In
+        // particular, the remembered bit may be incorrectly false if this
+        // become was the result of aborting a scavenge while visiting the
+        // remembered set.
+        new_target = old_target;
+      }
+      if (visiting_object_ == nullptr) {
+        *p = new_target;
+      } else if (visiting_object_->ptr()->IsCardRemembered()) {
+        visiting_object_->ptr()->StoreArrayPointer(p, new_target, thread_);
+      } else {
+        visiting_object_->ptr()->StorePointer(p, new_target, thread_);
       }
     }
   }
 
   void VisitingObject(ObjectPtr obj) {
     visiting_object_ = obj;
+    // The incoming remembered bit may be unreliable. Clear it so we can
+    // consistently reapply the barrier to all slots.
     if ((obj != nullptr) && obj->IsOldObject() && obj->ptr()->IsRemembered()) {
       ASSERT(!obj->IsForwardingCorpse());
       ASSERT(!obj->IsFreeListElement());
-      thread_->StoreBufferAddObjectGC(obj);
+      obj->ptr()->ClearRememberedBit();
     }
   }
 
diff --git a/runtime/vm/heap/become.h b/runtime/vm/heap/become.h
index 3958c8d..5bcc42c 100644
--- a/runtime/vm/heap/become.h
+++ b/runtime/vm/heap/become.h
@@ -53,11 +53,8 @@
 
  private:
   // This layout mirrors the layout of RawObject.
-  RelaxedAtomic<uint32_t> tags_;
-#if defined(HASH_IN_OBJECT_HEADER)
-  uint32_t hash_;
-#endif
-  ObjectPtr target_;
+  RelaxedAtomic<uword> tags_;
+  RelaxedAtomic<ObjectPtr> target_;
 
   // Returns the address of the embedded size.
   intptr_t* SizeAddress() const {
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index a6ba604..2923aee 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -21,7 +21,7 @@
 
   FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);
 
-  uint32_t tags = 0;
+  uword tags = 0;
   tags = ObjectLayout::SizeTag::update(size, tags);
   tags = ObjectLayout::ClassIdTag::update(kFreeListElement, tags);
   ASSERT((addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset);
@@ -30,11 +30,7 @@
   tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
   tags = ObjectLayout::NewBit::update(false, tags);
   result->tags_ = tags;
-#if defined(HASH_IN_OBJECT_HEADER)
-  // Clearing this is mostly for neatness. The identityHashCode
-  // of free list entries is not used.
-  result->hash_ = 0;
-#endif
+
   if (size > ObjectLayout::SizeTag::kMaxSizeTag) {
     *result->SizeAddress() = size;
   }
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index e37ab52..677a0f2 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -57,11 +57,8 @@
 
  private:
   // This layout mirrors the layout of RawObject.
-  RelaxedAtomic<uint32_t> tags_;
-#if defined(HASH_IN_OBJECT_HEADER)
-  uint32_t hash_;
-#endif
-  FreeListElement* next_;
+  RelaxedAtomic<uword> tags_;
+  RelaxedAtomic<FreeListElement*> next_;
 
   // Returns the address of the embedded size.
   intptr_t* SizeAddress() const {
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index 4b3b061..b2c1009 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -583,6 +583,9 @@
 };
 
 VM_UNIT_TEST_CASE(CleanupBequestNeverReceived) {
+  // This test uses features from isolate groups
+  FLAG_enable_isolate_groups = true;
+
   const char* TEST_MESSAGE = "hello, world";
   Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
   EXPECT_EQ(parent, Dart_CurrentIsolate());
@@ -615,6 +618,9 @@
 }
 
 VM_UNIT_TEST_CASE(ReceivesSendAndExitMessage) {
+  // This test uses features from isolate groups
+  FLAG_enable_isolate_groups = true;
+
   const char* TEST_MESSAGE = "hello, world";
   Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
   EXPECT_EQ(parent, Dart_CurrentIsolate());
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 0e306f7..bceb31c 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -34,7 +34,7 @@
         page_space_(page_space),
         work_list_(marking_stack),
         deferred_work_list_(deferred_marking_stack),
-        delayed_weak_properties_(nullptr),
+        delayed_weak_properties_(WeakProperty::null()),
         marked_bytes_(0),
         marked_micros_(0) {
     ASSERT(thread_->isolate_group() == isolate_group);
@@ -48,12 +48,12 @@
   bool ProcessPendingWeakProperties() {
     bool marked = false;
     WeakPropertyPtr cur_weak = delayed_weak_properties_;
-    delayed_weak_properties_ = nullptr;
-    while (cur_weak != nullptr) {
-      uword next_weak = cur_weak->ptr()->next_;
+    delayed_weak_properties_ = WeakProperty::null();
+    while (cur_weak != WeakProperty::null()) {
+      WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
       ObjectPtr raw_key = cur_weak->ptr()->key_;
       // Reset the next pointer in the weak property.
-      cur_weak->ptr()->next_ = 0;
+      cur_weak->ptr()->next_ = WeakProperty::null();
       if (raw_key->ptr()->IsMarked()) {
         ObjectPtr raw_val = cur_weak->ptr()->value_;
         marked =
@@ -67,7 +67,7 @@
         EnqueueWeakProperty(cur_weak);
       }
       // Advance to next weak property in the queue.
-      cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+      cur_weak = next_weak;
     }
     return marked;
   }
@@ -133,8 +133,8 @@
     ASSERT(raw_weak->IsOldObject());
     ASSERT(raw_weak->IsWeakProperty());
     ASSERT(raw_weak->ptr()->IsMarked());
-    ASSERT(raw_weak->ptr()->next_ == 0);
-    raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
+    ASSERT(raw_weak->ptr()->next_ == WeakProperty::null());
+    raw_weak->ptr()->next_ = delayed_weak_properties_;
     delayed_weak_properties_ = raw_weak;
   }
 
@@ -185,16 +185,16 @@
     work_list_.Finalize();
     // Clear pending weak properties.
     WeakPropertyPtr cur_weak = delayed_weak_properties_;
-    delayed_weak_properties_ = nullptr;
+    delayed_weak_properties_ = WeakProperty::null();
     intptr_t weak_properties_cleared = 0;
-    while (cur_weak != nullptr) {
-      uword next_weak = cur_weak->ptr()->next_;
-      cur_weak->ptr()->next_ = 0;
+    while (cur_weak != WeakProperty::null()) {
+      WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
+      cur_weak->ptr()->next_ = WeakProperty::null();
       RELEASE_ASSERT(!cur_weak->ptr()->key_->ptr()->IsMarked());
       WeakProperty::Clear(cur_weak);
       weak_properties_cleared++;
       // Advance to next weak property in the queue.
-      cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+      cur_weak = next_weak;
     }
   }
 
@@ -240,7 +240,11 @@
     // change in the value.
     // Doing this before checking for an Instructions object avoids
     // unnecessary queueing of pre-marked objects.
-    if (raw_obj->ptr()->IsMarked()) {
+    // Race: The concurrent marker may observe a pointer into a heap page that
+    // was allocated after the concurrent marker started. It can read either a
+    // zero or the header of an object allocated black, both of which appear
+    // marked.
+    if (raw_obj->ptr()->IsMarkedIgnoreRace()) {
       return;
     }
 
diff --git a/runtime/vm/heap/pointer_block.h b/runtime/vm/heap/pointer_block.h
index 4a40cd1..5e7dde8 100644
--- a/runtime/vm/heap/pointer_block.h
+++ b/runtime/vm/heap/pointer_block.h
@@ -18,7 +18,7 @@
 
 // A set of ObjectPtr. Must be emptied before destruction (using Pop/Reset).
 template <int Size>
-class PointerBlock {
+class PointerBlock : public MallocAllocated {
  public:
   enum { kSize = Size };
 
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index e45ebd5..3f6f09d 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -118,7 +118,8 @@
         freelist_(freelist),
         bytes_promoted_(0),
         visiting_old_object_(nullptr),
-        promoted_list_(promotion_stack) {}
+        promoted_list_(promotion_stack),
+        delayed_weak_properties_(WeakProperty::null()) {}
 
   virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
                                           ObjectPtr* first,
@@ -318,7 +319,7 @@
       new_obj = ObjectLayout::FromAddr(new_addr);
       if (new_obj->IsOldObject()) {
         // Promoted: update age/barrier tags.
-        uint32_t tags = static_cast<uint32_t>(header);
+        uword tags = static_cast<uword>(header);
         tags = ObjectLayout::OldBit::update(true, tags);
         tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
         tags = ObjectLayout::NewBit::update(false, tags);
@@ -426,7 +427,7 @@
   ObjectPtr visiting_old_object_;
 
   PromotionWorkList promoted_list_;
-  WeakPropertyPtr delayed_weak_properties_ = nullptr;
+  WeakPropertyPtr delayed_weak_properties_;
 
   NewPage* head_ = nullptr;
   NewPage* tail_ = nullptr;  // Allocating from here.
@@ -762,6 +763,7 @@
 Scavenger::~Scavenger() {
   ASSERT(!scavenging_);
   delete to_;
+  ASSERT(blocks_ == nullptr);
 }
 
 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const {
@@ -830,7 +832,7 @@
       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
         if (!is_remembered_) {
           FATAL3(
-              "Old object %#" Px "references new object %#" Px
+              "Old object %#" Px " references new object %#" Px
               ", but it is not"
               " in any store buffer. Consider using rr to watch the slot %p and"
               " reverse-continue to find the store with a missing barrier.\n",
@@ -1024,9 +1026,8 @@
   // Grab the deduplication sets out of the isolate's consolidated store buffer.
   StoreBuffer* store_buffer = heap_->isolate_group()->store_buffer();
   StoreBufferBlock* pending = blocks_;
-  blocks_ = nullptr;
   intptr_t total_count = 0;
-  while (pending != NULL) {
+  while (pending != nullptr) {
     StoreBufferBlock* next = pending->next();
     // Generated code appends to store buffers; tell MemorySanitizer.
     MSAN_UNPOISON(pending, sizeof(*pending));
@@ -1045,10 +1046,10 @@
     pending->Reset();
     // Return the emptied block for recycling (no need to check threshold).
     store_buffer->PushBlock(pending, StoreBuffer::kIgnoreThreshold);
-    pending = next;
+    blocks_ = pending = next;
   }
   // Done iterating through old objects remembered in the store buffers.
-  visitor->VisitingOldObject(NULL);
+  visitor->VisitingOldObject(nullptr);
 
   heap_->RecordData(kStoreBufferEntries, total_count);
   heap_->RecordData(kDataUnused1, 0);
@@ -1181,9 +1182,9 @@
   // for which the keys have become reachable. Potentially this adds more
   // objects to the to space.
   WeakPropertyPtr cur_weak = delayed_weak_properties_;
-  delayed_weak_properties_ = nullptr;
-  while (cur_weak != nullptr) {
-    uword next_weak = cur_weak->ptr()->next_;
+  delayed_weak_properties_ = WeakProperty::null();
+  while (cur_weak != WeakProperty::null()) {
+    WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
     // Promoted weak properties are not enqueued. So we can guarantee that
     // we do not need to think about store barriers here.
     ASSERT(cur_weak->IsNewObject());
@@ -1197,14 +1198,14 @@
     ASSERT(from_->Contains(raw_addr));
     uword header = *reinterpret_cast<uword*>(raw_addr);
     // Reset the next pointer in the weak property.
-    cur_weak->ptr()->next_ = 0;
+    cur_weak->ptr()->next_ = WeakProperty::null();
     if (IsForwarding(header)) {
       cur_weak->ptr()->VisitPointersNonvirtual(this);
     } else {
       EnqueueWeakProperty(cur_weak);
     }
     // Advance to next weak property in the queue.
-    cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+    cur_weak = next_weak;
   }
 }
 
@@ -1244,8 +1245,8 @@
   uword header = *reinterpret_cast<uword*>(raw_addr);
   ASSERT(!IsForwarding(header));
 #endif  // defined(DEBUG)
-  ASSERT(raw_weak->ptr()->next_ == 0);
-  raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
+  ASSERT(raw_weak->ptr()->next_ == WeakProperty::null());
+  raw_weak->ptr()->next_ = delayed_weak_properties_;
   delayed_weak_properties_ = raw_weak;
 }
 
@@ -1330,11 +1331,11 @@
   // The queued weak properties at this point do not refer to reachable keys,
   // so we clear their key and value fields.
   WeakPropertyPtr cur_weak = delayed_weak_properties_;
-  delayed_weak_properties_ = nullptr;
-  while (cur_weak != nullptr) {
-    uword next_weak = cur_weak->ptr()->next_;
+  delayed_weak_properties_ = WeakProperty::null();
+  while (cur_weak != WeakProperty::null()) {
+    WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
     // Reset the next pointer in the weak property.
-    cur_weak->ptr()->next_ = 0;
+    cur_weak->ptr()->next_ = WeakProperty::null();
 
 #if defined(DEBUG)
     ObjectPtr raw_key = cur_weak->ptr()->key_;
@@ -1348,7 +1349,7 @@
     WeakProperty::Clear(cur_weak);
 
     // Advance to next weak property in the queue.
-    cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+    cur_weak = next_weak;
   }
 }
 
@@ -1618,15 +1619,15 @@
         intptr_t size = to_obj->ptr()->HeapSize();
 
         // Reset the ages bits in case this was a promotion.
-        uint32_t tags = static_cast<uint32_t>(to_header);
-        tags = ObjectLayout::OldBit::update(false, tags);
-        tags = ObjectLayout::OldAndNotRememberedBit::update(false, tags);
-        tags = ObjectLayout::NewBit::update(true, tags);
-        tags = ObjectLayout::OldAndNotMarkedBit::update(false, tags);
-        uword original_header =
-            (to_header & ~static_cast<uword>(0xFFFFFFFF)) | tags;
+        uword from_header = static_cast<uword>(to_header);
+        from_header = ObjectLayout::OldBit::update(false, from_header);
+        from_header =
+            ObjectLayout::OldAndNotRememberedBit::update(false, from_header);
+        from_header = ObjectLayout::NewBit::update(true, from_header);
+        from_header =
+            ObjectLayout::OldAndNotMarkedBit::update(false, from_header);
 
-        WriteHeader(from_obj, original_header);
+        WriteHeader(from_obj, from_header);
 
         ForwardingCorpse::AsForwarder(ObjectLayout::ToAddr(to_obj), size)
             ->set_target(from_obj);
@@ -1645,9 +1646,23 @@
   to_ = *from;
   *from = temp;
 
+  // Release any remaining part of the promotion worklist that wasn't completed.
   promotion_stack_.Reset();
 
-  // This also rebuilds the remembered set.
+  // Release any remaining part of the rememebred set that wasn't completed.
+  StoreBuffer* store_buffer = heap_->isolate_group()->store_buffer();
+  StoreBufferBlock* pending = blocks_;
+  while (pending != nullptr) {
+    StoreBufferBlock* next = pending->next();
+    pending->Reset();
+    // Return the emptied block for recycling (no need to check threshold).
+    store_buffer->PushBlock(pending, StoreBuffer::kIgnoreThreshold);
+    pending = next;
+  }
+  blocks_ = nullptr;
+
+  // Reverse the partial forwarding from the aborted scavenge. This also
+  // rebuilds the remembered set.
   Become::FollowForwardingPointers(thread);
 
   // Don't scavenge again until the next old-space GC has occurred. Prevents
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 9f84dcd..5e7486b 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -429,7 +429,7 @@
   bool scavenging_;
   bool early_tenure_ = false;
   RelaxedAtomic<intptr_t> root_slices_started_;
-  StoreBufferBlock* blocks_;
+  StoreBufferBlock* blocks_ = nullptr;
 
   int64_t gc_time_micros_;
   intptr_t collections_;
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index f579074..9013eba 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -27,24 +27,28 @@
   uword current = start;
 
   while (current < end) {
-    intptr_t obj_size;
     ObjectPtr raw_obj = ObjectLayout::FromAddr(current);
     ASSERT(OldPage::Of(raw_obj) == page);
-    if (raw_obj->ptr()->IsMarked()) {
+    // These acquire operations balance release operations in array
+    // truncaton, ensuring the writes creating the filler object are ordered
+    // before the writes inserting the filler object into the freelist.
+    uword tags = raw_obj->ptr()->tags_.load(std::memory_order_acquire);
+    intptr_t obj_size = raw_obj->ptr()->HeapSize(tags);
+    if (ObjectLayout::IsMarked(tags)) {
       // Found marked object. Clear the mark bit and update swept bytes.
       raw_obj->ptr()->ClearMarkBit();
-      obj_size = raw_obj->ptr()->HeapSize();
       used_in_bytes += obj_size;
     } else {
-      uword free_end = current + raw_obj->ptr()->HeapSize();
+      uword free_end = current + obj_size;
       while (free_end < end) {
         ObjectPtr next_obj = ObjectLayout::FromAddr(free_end);
-        if (next_obj->ptr()->IsMarked()) {
+        tags = next_obj->ptr()->tags_.load(std::memory_order_acquire);
+        if (ObjectLayout::IsMarked(tags)) {
           // Reached the end of the free block.
           break;
         }
         // Expand the free block by the size of this object.
-        free_end += next_obj->ptr()->HeapSize();
+        free_end += next_obj->ptr()->HeapSize(tags);
       }
       obj_size = free_end - current;
       if (is_executable) {
diff --git a/runtime/vm/heap/verifier.cc b/runtime/vm/heap/verifier.cc
index 4c2da50..4dc7da0 100644
--- a/runtime/vm/heap/verifier.cc
+++ b/runtime/vm/heap/verifier.cc
@@ -89,11 +89,22 @@
     : thread_(thread), instanceHandle_(Instance::Handle(thread->zone())) {}
 
 void VerifyCanonicalVisitor::VisitObject(ObjectPtr obj) {
+  // The caller of this function is walking heap pages using the
+  // ExclusivePageIterator - which holds the pages lock.
+  //
+  // If we allow handle verification, then any assignment to a handle will call
+  // `heap()->Contains()` for heap objects, which in return is implemented by
+  // walking pages using ExclusivePageIterator, which can cause a deadlock.
+  //
+  // Therefore we disable the handle verification here.
+  const bool old_verify_flag = FLAG_verify_handles;
+  FLAG_verify_handles = false;
+
   // TODO(dartbug.com/36097): The heap walk can encounter canonical objects of
   // other isolates. We should either scan live objects from the roots of each
   // individual isolate, or wait until we are ready to share constants across
   // isolates.
-  if (!FLAG_enable_isolate_groups) {
+  if (!FLAG_enable_isolate_groups || FLAG_precompiled_mode) {
     if ((obj->GetClassId() >= kInstanceCid) &&
         (obj->GetClassId() != kTypeArgumentsCid)) {
       if (obj->ptr()->IsCanonical()) {
@@ -107,6 +118,7 @@
       }
     }
   }
+  FLAG_verify_handles = old_verify_flag;
 }
 #endif  // defined(DEBUG)
 
diff --git a/runtime/vm/heap/weak_code.cc b/runtime/vm/heap/weak_code.cc
index c1a3d53..97f832a 100644
--- a/runtime/vm/heap/weak_code.cc
+++ b/runtime/vm/heap/weak_code.cc
@@ -69,6 +69,9 @@
   }
 
   UpdateArrayTo(Object::null_array());
+
+  // TODO(dartbug.com/36097): This has to walk all mutator threads when
+  // disabling code.
   // Disable all code on stack.
   Code& code = Code::Handle();
   {
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 197e24f..84d523c 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -514,7 +514,7 @@
     if (obj.IsCompressedStackMaps()) {
       const CompressedStackMaps& map = CompressedStackMaps::Cast(obj);
       const intptr_t payload_size = map.payload_size();
-      stream->WriteFixed<uint32_t>(map.raw()->ptr()->flags_and_size_);
+      stream->WriteTargetWord(map.raw()->ptr()->flags_and_size_);
       ASSERT_EQUAL(stream->Position() - object_start,
                    compiler::target::CompressedStackMaps::HeaderSize());
       stream->WriteBytes(map.raw()->ptr()->data(), payload_size);
@@ -589,12 +589,12 @@
 }
 
 uword ImageWriter::GetMarkedTags(const Object& obj) {
-  return
+  uword tags = GetMarkedTags(obj.raw()->GetClassId(), SizeInSnapshot(obj),
+                             obj.IsCanonical());
 #if defined(HASH_IN_OBJECT_HEADER)
-      static_cast<uword>(obj.raw()->ptr()->hash_) << kBitsPerInt32 |
+  tags = ObjectLayout::HashTag::update(obj.raw()->ptr()->GetHeaderHash(), tags);
 #endif
-      GetMarkedTags(obj.raw()->GetClassId(), SizeInSnapshot(obj),
-                    obj.IsCanonical());
+  return tags;
 }
 
 const char* ImageWriter::SectionSymbol(ProgramSection section, bool vm) const {
@@ -1208,7 +1208,7 @@
   ASSERT(compiler::target::kBitsPerWord == kBitsPerWord ||
          Utils::IsAbsoluteUint(compiler::target::kBitsPerWord, value));
   // Padding is helpful for comparing the .S with --disassemble.
-  assembly_stream_->Printf("%s 0x%0.*" Px "\n", kWordDirective,
+  assembly_stream_->Printf("%s 0x%.*" Px "\n", kWordDirective,
                            2 * compiler::target::kWordSize, value);
   return compiler::target::kWordSize;
 }
@@ -1365,7 +1365,7 @@
   if (end != end_of_words) {
     assembly_stream_->WriteString(kSizeDirectives[kInt8SizeLog2]);
     for (auto cursor = end_of_words; cursor < end; cursor++) {
-      assembly_stream_->Printf("%s 0x%0.2x", cursor != end_of_words ? "," : "",
+      assembly_stream_->Printf("%s 0x%.2x", cursor != end_of_words ? "," : "",
                                *cursor);
     }
     assembly_stream_->WriteString("\n");
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 222e5a3..4500d86 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -138,21 +138,6 @@
   return writer.WriteCMessage(obj, dest_port, Message::kNormalPriority);
 }
 
-static InstancePtr DeserializeMessage(Thread* thread, Message* message) {
-  if (message == NULL) {
-    return Instance::null();
-  }
-  Zone* zone = thread->zone();
-  if (message->IsRaw()) {
-    return Instance::RawCast(message->raw_obj());
-  } else {
-    MessageSnapshotReader reader(message, thread);
-    const Object& obj = Object::Handle(zone, reader.ReadObject());
-    ASSERT(!obj.IsError());
-    return Instance::RawCast(obj.raw());
-  }
-}
-
 void IsolateGroupSource::add_loaded_blob(
     Zone* zone,
     const ExternalTypedData& external_typed_data) {
@@ -368,11 +353,28 @@
       store_buffer_(new StoreBuffer()),
       heap_(nullptr),
       saved_unlinked_calls_(Array::null()),
+      initial_field_table_(new FieldTable(/*isolate=*/nullptr)),
       symbols_lock_(new SafepointRwLock()),
       type_canonicalization_mutex_(
           NOT_IN_PRODUCT("IsolateGroup::type_canonicalization_mutex_")),
       type_arguments_canonicalization_mutex_(NOT_IN_PRODUCT(
           "IsolateGroup::type_arguments_canonicalization_mutex_")),
+      subtype_test_cache_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::subtype_test_cache_mutex_")),
+      megamorphic_table_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::megamorphic_table_mutex_")),
+      type_feedback_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::type_feedback_mutex_")),
+      patchable_call_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::patchable_call_mutex_")),
+      constant_canonicalization_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::constant_canonicalization_mutex_")),
+      kernel_data_lib_cache_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::kernel_data_lib_cache_mutex_")),
+      kernel_data_class_cache_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::kernel_data_class_cache_mutex_")),
+      kernel_constants_mutex_(
+          NOT_IN_PRODUCT("IsolateGroup::kernel_constants_mutex_")),
       program_lock_(new SafepointRwLock()),
       active_mutators_monitor_(new Monitor()),
       max_active_mutators_(Scavenger::MaxMutatorThreadCount()) {
@@ -559,8 +561,6 @@
     // Now get a free Thread structure.
     ASSERT(thread != nullptr);
 
-    thread->ResetHighWatermark();
-
     // Set up other values and set the TLS value.
     thread->isolate_ = nullptr;
     thread->isolate_group_ = this;
@@ -903,8 +903,20 @@
 }
 #endif  // DEBUG
 
-void Isolate::RegisterStaticField(const Field& field) {
-  field_table()->Register(field);
+void IsolateGroup::RegisterStaticField(const Field& field,
+                                       const Instance& initial_value) {
+  ASSERT(program_lock()->IsCurrentThreadWriter());
+
+  ASSERT(field.is_static());
+  initial_field_table()->Register(field);
+  initial_field_table()->SetAt(field.field_id(), initial_value.raw());
+
+  // TODO(dartbug.com/36097): When we start sharing the object stores (and
+  // therefore libraries, classes, fields) we'll have to register the initial
+  // static field value in all isolates.
+  auto current = Isolate::Current();
+  current->field_table()->AllocateIndex(field.field_id());
+  current->field_table()->SetAt(field.field_id(), initial_value.raw());
 }
 
 void Isolate::RehashConstants() {
@@ -1619,7 +1631,7 @@
       default_tag_(UserTag::null()),
       ic_miss_code_(Code::null()),
       shared_class_table_(isolate_group->shared_class_table()),
-      field_table_(new FieldTable()),
+      field_table_(new FieldTable(/*isolate=*/this)),
       isolate_group_(isolate_group),
       isolate_object_store_(
           new IsolateObjectStore(isolate_group->object_store())),
@@ -1644,17 +1656,10 @@
           reload_every_n_stack_overflow_checks_(FLAG_reload_every),
 #endif  // !defined(PRODUCT)
       start_time_micros_(OS::GetCurrentMonotonicMicros()),
+      on_shutdown_callback_(Isolate::ShutdownCallback()),
+      on_cleanup_callback_(Isolate::CleanupCallback()),
       random_(),
       mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
-      constant_canonicalization_mutex_(
-          NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_")),
-      megamorphic_mutex_(NOT_IN_PRODUCT("Isolate::megamorphic_mutex_")),
-      kernel_data_lib_cache_mutex_(
-          NOT_IN_PRODUCT("Isolate::kernel_data_lib_cache_mutex_")),
-      kernel_data_class_cache_mutex_(
-          NOT_IN_PRODUCT("Isolate::kernel_data_class_cache_mutex_")),
-      kernel_constants_mutex_(
-          NOT_IN_PRODUCT("Isolate::kernel_constants_mutex_")),
       pending_deopts_(new MallocGrowableArray<PendingLazyDeopt>()),
       tag_table_(GrowableObjectArray::null()),
       deoptimized_code_array_(GrowableObjectArray::null()),
@@ -2048,30 +2053,34 @@
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
 const char* Isolate::MakeRunnable() {
-  ASSERT(Isolate::Current() == nullptr);
-
   MutexLocker ml(&mutex_);
   // Check if we are in a valid state to make the isolate runnable.
   if (is_runnable() == true) {
     return "Isolate is already runnable";
   }
+  if (object_store()->root_library() == Library::null()) {
+    return "The embedder has to ensure there is a root library (e.g. by "
+           "calling Dart_LoadScriptFromKernel ).";
+  }
+  MakeRunnableLocked();
+  return nullptr;
+}
+
+void Isolate::MakeRunnableLocked() {
+  ASSERT(mutex_.IsOwnedByCurrentThread());
+  ASSERT(!is_runnable());
+  ASSERT(object_store()->root_library() != Library::null());
+
   // Set the isolate as runnable and if we are being spawned schedule
   // isolate on thread pool for execution.
-  ASSERT(object_store()->root_library() != Library::null());
   set_is_runnable(true);
 #ifndef PRODUCT
   if (!Isolate::IsSystemIsolate(this)) {
-    debugger()->OnIsolateRunnable();
     if (FLAG_pause_isolates_on_unhandled_exceptions) {
       debugger()->SetExceptionPauseInfo(kPauseOnUnhandledExceptions);
     }
   }
 #endif  // !PRODUCT
-  IsolateSpawnState* state = spawn_state();
-  if (state != nullptr) {
-    ASSERT(this == state->isolate());
-    Run();
-  }
 #if defined(SUPPORT_TIMELINE)
   TimelineStream* stream = Timeline::GetIsolateStream();
   ASSERT(stream != nullptr);
@@ -2087,17 +2096,7 @@
     Service::HandleEvent(&runnableEvent);
   }
   GetRunnableLatencyMetric()->set_value(UptimeMicros());
-  if (FLAG_print_benchmarking_metrics) {
-    {
-      StartIsolateScope scope(this);
-      heap()->CollectAllGarbage();
-    }
-    int64_t heap_size = (heap()->UsedInWords(Heap::kNew) * kWordSize) +
-                        (heap()->UsedInWords(Heap::kOld) * kWordSize);
-    GetRunnableHeapSizeMetric()->set_value(heap_size);
-  }
 #endif  // !PRODUCT
-  return nullptr;
 }
 
 bool Isolate::VerifyPauseCapability(const Object& capability) const {
@@ -2308,124 +2307,9 @@
   return listeners.Length() > 0;
 }
 
-static MessageHandler::MessageStatus RunIsolate(uword parameter) {
-  Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
-  IsolateSpawnState* state = nullptr;
-  {
-    // TODO(turnidge): Is this locking required here at all anymore?
-    MutexLocker ml(isolate->mutex());
-    state = isolate->spawn_state();
-  }
-  {
-    StartIsolateScope start_scope(isolate);
-    Thread* thread = Thread::Current();
-    ASSERT(thread->isolate() == isolate);
-    StackZone zone(thread);
-    HandleScope handle_scope(thread);
-
-    // If particular values were requested for this newly spawned isolate, then
-    // they are set here before the isolate starts executing user code.
-    isolate->SetErrorsFatal(state->errors_are_fatal());
-    if (state->on_exit_port() != ILLEGAL_PORT) {
-      const SendPort& listener =
-          SendPort::Handle(SendPort::New(state->on_exit_port()));
-      isolate->AddExitListener(listener, Instance::null_instance());
-    }
-    if (state->on_error_port() != ILLEGAL_PORT) {
-      const SendPort& listener =
-          SendPort::Handle(SendPort::New(state->on_error_port()));
-      isolate->AddErrorListener(listener);
-    }
-
-    // Switch back to spawning isolate.
-
-    if (!ClassFinalizer::ProcessPendingClasses()) {
-// Error is in sticky error already.
-#if defined(DEBUG)
-      const Error& error = Error::Handle(thread->sticky_error());
-      ASSERT(!error.IsUnwindError());
-#endif
-      return MessageHandler::kError;
-    }
-
-    Object& result = Object::Handle();
-    result = state->ResolveFunction();
-    bool is_spawn_uri = state->is_spawn_uri();
-    if (result.IsError()) {
-      return StoreError(thread, Error::Cast(result));
-    }
-    ASSERT(result.IsFunction());
-    Function& func = Function::Handle(thread->zone());
-    func ^= result.raw();
-
-    func = func.ImplicitClosureFunction();
-
-    const Array& capabilities = Array::Handle(Array::New(2));
-    Capability& capability = Capability::Handle();
-    capability = Capability::New(isolate->pause_capability());
-    capabilities.SetAt(0, capability);
-    // Check whether this isolate should be started in paused state.
-    if (state->paused()) {
-      bool added = isolate->AddResumeCapability(capability);
-      ASSERT(added);  // There should be no pending resume capabilities.
-      isolate->message_handler()->increment_paused();
-    }
-    capability = Capability::New(isolate->terminate_capability());
-    capabilities.SetAt(1, capability);
-
-    // Instead of directly invoking the entry point we call '_startIsolate' with
-    // the entry point as argument.
-    // Since this function ("RunIsolate") is used for both Isolate.spawn and
-    // Isolate.spawnUri we also send a boolean flag as argument so that the
-    // "_startIsolate" function can act corresponding to how the isolate was
-    // created.
-    const Array& args = Array::Handle(Array::New(7));
-    args.SetAt(0, SendPort::Handle(SendPort::New(state->parent_port())));
-    args.SetAt(1, Instance::Handle(func.ImplicitStaticClosure()));
-    args.SetAt(2, Instance::Handle(state->BuildArgs(thread)));
-    args.SetAt(3, Instance::Handle(state->BuildMessage(thread)));
-    args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False());
-    args.SetAt(5, ReceivePort::Handle(
-                      ReceivePort::New(isolate->main_port(), Symbols::Empty(),
-                                       true /* control port */)));
-    args.SetAt(6, capabilities);
-
-    const Library& lib = Library::Handle(Library::IsolateLibrary());
-    const String& entry_name = String::Handle(String::New("_startIsolate"));
-    const Function& entry_point =
-        Function::Handle(lib.LookupLocalFunction(entry_name));
-    ASSERT(entry_point.IsFunction() && !entry_point.IsNull());
-
-    result = DartEntry::InvokeFunction(entry_point, args);
-    if (result.IsError()) {
-      return StoreError(thread, Error::Cast(result));
-    }
-  }
-  return MessageHandler::kOK;
-}
-
 static void ShutdownIsolate(uword parameter) {
-  Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
-  {
-    // Print the error if there is one.  This may execute dart code to
-    // print the exception object, so we need to use a StartIsolateScope.
-    StartIsolateScope start_scope(isolate);
-    Thread* thread = Thread::Current();
-    ASSERT(thread->isolate() == isolate);
-
-    // We must wait for any outstanding spawn calls to complete before
-    // running the shutdown callback.
-    isolate->WaitForOutstandingSpawns();
-
-    StackZone zone(thread);
-    HandleScope handle_scope(thread);
-#if defined(DEBUG)
-    isolate->ValidateConstants();
-#endif  // defined(DEBUG)
-    Dart::RunShutdownCallback();
-  }
-  // Shut the isolate down.
-  Dart::ShutdownIsolate(isolate);
+  Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(parameter));
+  Dart_ShutdownIsolate();
 }
 
 void Isolate::SetStickyError(ErrorPtr sticky_error) {
@@ -2436,7 +2320,7 @@
 }
 
 void Isolate::Run() {
-  message_handler()->Run(group()->thread_pool(), RunIsolate, ShutdownIsolate,
+  message_handler()->Run(group()->thread_pool(), nullptr, ShutdownIsolate,
                          reinterpret_cast<uword>(this));
 }
 
@@ -2549,7 +2433,7 @@
         "\tisolate:    %s\n",
         name());
   }
-  if (FLAG_print_metrics || FLAG_print_benchmarking_metrics) {
+  if (FLAG_print_metrics) {
     LogBlock lb;
     OS::PrintErr("Printing metrics for %s\n", name());
 #define ISOLATE_GROUP_METRIC_PRINT(type, variable, name, unit)                 \
@@ -2652,7 +2536,7 @@
   // Cache these two fields, since they are no longer available after the
   // `delete this` further down.
   IsolateGroup* isolate_group = isolate->isolate_group_;
-  Dart_IsolateCleanupCallback cleanup = Isolate::CleanupCallback();
+  Dart_IsolateCleanupCallback cleanup = isolate->on_cleanup_callback();
   auto callback_data = isolate->init_callback_data_;
 
   // From this point on the isolate is no longer visited by GC (which is ok,
@@ -2918,9 +2802,7 @@
     object_store()->VisitObjectPointers(visitor);
   }
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_unlinked_calls_));
-  if (saved_initial_field_table() != nullptr) {
-    saved_initial_field_table()->VisitObjectPointers(visitor);
-  }
+  initial_field_table()->VisitObjectPointers(visitor);
   VisitStackPointers(visitor, validate_frames);
 }
 
@@ -3165,12 +3047,6 @@
     jsobj.AddProperty("rootLib", lib);
   }
 
-  intptr_t zone_handle_count = thread_registry()->CountZoneHandles(this);
-  intptr_t scoped_handle_count = thread_registry()->CountScopedHandles(this);
-
-  jsobj.AddProperty("_numZoneHandles", zone_handle_count);
-  jsobj.AddProperty("_numScopedHandles", scoped_handle_count);
-
   if (FLAG_profiler) {
     JSONObject tagCounters(&jsobj, "_tagCounters");
     vm_tag_counters()->PrintToJSONObject(&tagCounters);
@@ -3230,8 +3106,6 @@
     }
   }
 
-  jsobj.AddProperty("_threads", thread_registry());
-
   {
     JSONObject isolate_group(&jsobj, "isolate_group");
     group()->PrintToJSONObject(&isolate_group, /*ref=*/true);
@@ -3853,188 +3727,4 @@
   }
 }
 
-static const char* NewConstChar(const char* chars) {
-  size_t len = strlen(chars);
-  char* mem = new char[len + 1];
-  memmove(mem, chars, len + 1);
-  return mem;
-}
-
-IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
-                                     Dart_Port origin_id,
-                                     const char* script_url,
-                                     const Function& func,
-                                     SerializedObjectBuffer* message_buffer,
-                                     const char* package_config,
-                                     bool paused,
-                                     bool errors_are_fatal,
-                                     Dart_Port on_exit_port,
-                                     Dart_Port on_error_port,
-                                     const char* debug_name,
-                                     IsolateGroup* isolate_group)
-    : isolate_(nullptr),
-      parent_port_(parent_port),
-      origin_id_(origin_id),
-      on_exit_port_(on_exit_port),
-      on_error_port_(on_error_port),
-      script_url_(script_url),
-      package_config_(package_config),
-      library_url_(nullptr),
-      class_name_(nullptr),
-      function_name_(nullptr),
-      debug_name_(debug_name),
-      isolate_group_(isolate_group),
-      serialized_args_(nullptr),
-      serialized_message_(message_buffer->StealMessage()),
-      paused_(paused),
-      errors_are_fatal_(errors_are_fatal) {
-  const Class& cls = Class::Handle(func.Owner());
-  const Library& lib = Library::Handle(cls.library());
-  const String& lib_url = String::Handle(lib.url());
-  library_url_ = NewConstChar(lib_url.ToCString());
-
-  String& func_name = String::Handle();
-  func_name = func.name();
-  function_name_ = NewConstChar(String::ScrubName(func_name));
-  if (!cls.IsTopLevel()) {
-    const String& class_name = String::Handle(cls.Name());
-    class_name_ = NewConstChar(class_name.ToCString());
-  }
-
-  // Inherit flags from spawning isolate.
-  Isolate::Current()->FlagsCopyTo(isolate_flags());
-}
-
-IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
-                                     const char* script_url,
-                                     const char* package_config,
-                                     SerializedObjectBuffer* args_buffer,
-                                     SerializedObjectBuffer* message_buffer,
-                                     bool paused,
-                                     bool errors_are_fatal,
-                                     Dart_Port on_exit_port,
-                                     Dart_Port on_error_port,
-                                     const char* debug_name,
-                                     IsolateGroup* group)
-    : isolate_(nullptr),
-      parent_port_(parent_port),
-      origin_id_(ILLEGAL_PORT),
-      on_exit_port_(on_exit_port),
-      on_error_port_(on_error_port),
-      script_url_(script_url),
-      package_config_(package_config),
-      library_url_(nullptr),
-      class_name_(nullptr),
-      function_name_(nullptr),
-      debug_name_(debug_name),
-      isolate_group_(group),
-      serialized_args_(args_buffer->StealMessage()),
-      serialized_message_(message_buffer->StealMessage()),
-      isolate_flags_(),
-      paused_(paused),
-      errors_are_fatal_(errors_are_fatal) {
-  function_name_ = NewConstChar("main");
-
-  // By default inherit flags from spawning isolate. These can be overridden
-  // from the calling code.
-  Isolate::Current()->FlagsCopyTo(isolate_flags());
-}
-
-IsolateSpawnState::~IsolateSpawnState() {
-  delete[] script_url_;
-  delete[] package_config_;
-  delete[] library_url_;
-  delete[] class_name_;
-  delete[] function_name_;
-  delete[] debug_name_;
-}
-
-ObjectPtr IsolateSpawnState::ResolveFunction() {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-
-  const String& func_name = String::Handle(zone, String::New(function_name()));
-
-  if (library_url() == nullptr) {
-    // Handle spawnUri lookup rules.
-    // Check whether the root library defines a main function.
-    const Library& lib =
-        Library::Handle(zone, I->object_store()->root_library());
-    Function& func = Function::Handle(zone, lib.LookupLocalFunction(func_name));
-    if (func.IsNull()) {
-      // Check whether main is reexported from the root library.
-      const Object& obj = Object::Handle(zone, lib.LookupReExport(func_name));
-      if (obj.IsFunction()) {
-        func ^= obj.raw();
-      }
-    }
-    if (func.IsNull()) {
-      const String& msg = String::Handle(
-          zone, String::NewFormatted(
-                    "Unable to resolve function '%s' in script '%s'.",
-                    function_name(), script_url()));
-      return LanguageError::New(msg);
-    }
-    return func.raw();
-  }
-
-  // Lookup the to be spawned function for the Isolate.spawn implementation.
-  // Resolve the library.
-  const String& lib_url = String::Handle(zone, String::New(library_url()));
-  const Library& lib =
-      Library::Handle(zone, Library::LookupLibrary(thread, lib_url));
-  if (lib.IsNull() || lib.IsError()) {
-    const String& msg = String::Handle(
-        zone,
-        String::NewFormatted("Unable to find library '%s'.", library_url()));
-    return LanguageError::New(msg);
-  }
-
-  // Resolve the function.
-  if (class_name() == nullptr) {
-    const Function& func =
-        Function::Handle(zone, lib.LookupLocalFunction(func_name));
-    if (func.IsNull()) {
-      const String& msg = String::Handle(
-          zone, String::NewFormatted(
-                    "Unable to resolve function '%s' in library '%s'.",
-                    function_name(), library_url()));
-      return LanguageError::New(msg);
-    }
-    return func.raw();
-  }
-
-  const String& cls_name = String::Handle(zone, String::New(class_name()));
-  const Class& cls = Class::Handle(zone, lib.LookupLocalClass(cls_name));
-  if (cls.IsNull()) {
-    const String& msg = String::Handle(
-        zone, String::NewFormatted(
-                  "Unable to resolve class '%s' in library '%s'.", class_name(),
-                  (library_url() != nullptr ? library_url() : script_url())));
-    return LanguageError::New(msg);
-  }
-  Function& func = Function::Handle(zone);
-  const auto& error = cls.EnsureIsFinalized(thread);
-  if (error == Error::null()) {
-    func = cls.LookupStaticFunctionAllowPrivate(func_name);
-  }
-  if (func.IsNull()) {
-    const String& msg = String::Handle(
-        zone, String::NewFormatted(
-                  "Unable to resolve static method '%s.%s' in library '%s'.",
-                  class_name(), function_name(),
-                  (library_url() != nullptr ? library_url() : script_url())));
-    return LanguageError::New(msg);
-  }
-  return func.raw();
-}
-
-InstancePtr IsolateSpawnState::BuildArgs(Thread* thread) {
-  return DeserializeMessage(thread, serialized_args_.get());
-}
-
-InstancePtr IsolateSpawnState::BuildMessage(Thread* thread) {
-  return DeserializeMessage(thread, serialized_message_.get());
-}
-
 }  // namespace dart
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 0d3279d..e88229a 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -58,7 +58,6 @@
 class IsolateObjectStore;
 class IsolateProfilerData;
 class IsolateReloadContext;
-class IsolateSpawnState;
 class Log;
 class Message;
 class MessageHandler;
@@ -226,7 +225,7 @@
                      const uint8_t* kernel_buffer,
                      intptr_t kernel_buffer_size,
                      Dart_IsolateFlags flags)
-      : script_uri(script_uri),
+      : script_uri(script_uri == nullptr ? nullptr : Utils::StrDup(script_uri)),
         name(Utils::StrDup(name)),
         snapshot_data(snapshot_data),
         snapshot_instructions(snapshot_instructions),
@@ -237,14 +236,17 @@
         script_kernel_size(-1),
         loaded_blobs_(nullptr),
         num_blob_loads_(0) {}
-  ~IsolateGroupSource() { free(name); }
+  ~IsolateGroupSource() {
+    free(script_uri);
+    free(name);
+  }
 
   void add_loaded_blob(Zone* zone_,
                        const ExternalTypedData& external_typed_data);
 
   // The arguments used for spawning in
   // `Dart_CreateIsolateGroupFromKernel` / `Dart_CreateIsolate`.
-  const char* script_uri;
+  char* script_uri;
   char* name;
   const uint8_t* snapshot_data;
   const uint8_t* snapshot_instructions;
@@ -422,6 +424,17 @@
     return &type_arguments_canonicalization_mutex_;
   }
   Mutex* subtype_test_cache_mutex() { return &subtype_test_cache_mutex_; }
+  Mutex* megamorphic_table_mutex() { return &megamorphic_table_mutex_; }
+  Mutex* type_feedback_mutex() { return &type_feedback_mutex_; }
+  Mutex* patchable_call_mutex() { return &patchable_call_mutex_; }
+  Mutex* constant_canonicalization_mutex() {
+    return &constant_canonicalization_mutex_;
+  }
+  Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
+  Mutex* kernel_data_class_cache_mutex() {
+    return &kernel_data_class_cache_mutex_;
+  }
+  Mutex* kernel_constants_mutex() { return &kernel_constants_mutex_; }
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   Mutex* unlinked_call_map_mutex() { return &unlinked_call_map_mutex_; }
@@ -561,10 +574,16 @@
   }
 
   void DeleteReloadContext();
-
-  bool IsReloading() const { return group_reload_context_ != nullptr; }
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
+  bool IsReloading() const {
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+    return group_reload_context_ != nullptr;
+#else
+    return false;
+#endif
+  }
+
   uint64_t id() { return id_; }
 
   static void Init();
@@ -612,18 +631,18 @@
   ArrayPtr saved_unlinked_calls() const { return saved_unlinked_calls_; }
   void set_saved_unlinked_calls(const Array& saved_unlinked_calls);
 
-  FieldTable* saved_initial_field_table() const {
-    return saved_initial_field_table_.get();
+  FieldTable* initial_field_table() const { return initial_field_table_.get(); }
+  std::shared_ptr<FieldTable> initial_field_table_shareable() {
+    return initial_field_table_;
   }
-  std::shared_ptr<FieldTable> saved_initial_field_table_shareable() {
-    return saved_initial_field_table_;
-  }
-  void set_saved_initial_field_table(std::shared_ptr<FieldTable> field_table) {
-    saved_initial_field_table_ = field_table;
+  void set_initial_field_table(std::shared_ptr<FieldTable> field_table) {
+    initial_field_table_ = field_table;
   }
 
   MutatorThreadPool* thread_pool() { return thread_pool_.get(); }
 
+  void RegisterStaticField(const Field& field, const Instance& initial_value);
+
  private:
   friend class Dart;  // For `object_store_ = ` in Dart::Init
   friend class Heap;
@@ -707,13 +726,20 @@
   const uint8_t* dispatch_table_snapshot_ = nullptr;
   intptr_t dispatch_table_snapshot_size_ = 0;
   ArrayPtr saved_unlinked_calls_;
-  std::shared_ptr<FieldTable> saved_initial_field_table_;
+  std::shared_ptr<FieldTable> initial_field_table_;
   uint32_t isolate_group_flags_ = 0;
 
   std::unique_ptr<SafepointRwLock> symbols_lock_;
   Mutex type_canonicalization_mutex_;
   Mutex type_arguments_canonicalization_mutex_;
   Mutex subtype_test_cache_mutex_;
+  Mutex megamorphic_table_mutex_;
+  Mutex type_feedback_mutex_;
+  Mutex patchable_call_mutex_;
+  Mutex constant_canonicalization_mutex_;
+  Mutex kernel_data_lib_cache_mutex_;
+  Mutex kernel_data_class_cache_mutex_;
+  Mutex kernel_constants_mutex_;
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   Mutex unlinked_call_map_mutex_;
@@ -786,13 +812,14 @@
     return thread == nullptr ? nullptr : thread->isolate();
   }
 
+  bool IsScheduled() { return scheduled_mutator_thread() != nullptr; }
+  Thread* scheduled_mutator_thread() const { return scheduled_mutator_thread_; }
+
   // Register a newly introduced class.
   void RegisterClass(const Class& cls);
 #if defined(DEBUG)
   void ValidateClassTable();
 #endif
-  // Register a newly introduced static field.
-  void RegisterStaticField(const Field& field);
 
   void RehashConstants();
 #if defined(DEBUG)
@@ -857,6 +884,19 @@
     message_notify_callback_ = value;
   }
 
+  void set_on_shutdown_callback(Dart_IsolateShutdownCallback value) {
+    on_shutdown_callback_ = value;
+  }
+  Dart_IsolateShutdownCallback on_shutdown_callback() {
+    return on_shutdown_callback_;
+  }
+  void set_on_cleanup_callback(Dart_IsolateCleanupCallback value) {
+    on_cleanup_callback_ = value;
+  }
+  Dart_IsolateCleanupCallback on_cleanup_callback() {
+    return on_cleanup_callback_;
+  }
+
   void bequeath(std::unique_ptr<Bequest> bequest) {
     bequest_ = std::move(bequest);
   }
@@ -923,6 +963,7 @@
   void ScheduleInterrupts(uword interrupt_bits);
 
   const char* MakeRunnable();
+  void MakeRunnableLocked();
   void Run();
 
   MessageHandler* message_handler() const { return message_handler_; }
@@ -938,25 +979,7 @@
 #endif
   }
 
-  IsolateSpawnState* spawn_state() const { return spawn_state_.get(); }
-  void set_spawn_state(std::unique_ptr<IsolateSpawnState> value) {
-    spawn_state_ = std::move(value);
-  }
-
   Mutex* mutex() { return &mutex_; }
-  Mutex* constant_canonicalization_mutex() {
-    return &constant_canonicalization_mutex_;
-  }
-  Mutex* megamorphic_mutex() { return &megamorphic_mutex_; }
-
-  Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
-  Mutex* kernel_data_class_cache_mutex() {
-    return &kernel_data_class_cache_mutex_;
-  }
-
-  // Any access to constants arrays must be locked since mutator and
-  // background compiler can access the arrays at the same time.
-  Mutex* kernel_constants_mutex() { return &kernel_constants_mutex_; }
 
 #if !defined(PRODUCT)
   Debugger* debugger() const { return debugger_; }
@@ -1324,6 +1347,10 @@
     isolate_flags_ = NullSafetyBit::update(null_safety, isolate_flags_);
   }
 
+  bool use_strict_null_safety_checks() const {
+    return null_safety() || FLAG_strict_null_safety_checks;
+  }
+
   bool has_attempted_stepping() const {
     return HasAttemptedSteppingBit::decode(isolate_flags_);
   }
@@ -1564,6 +1591,8 @@
   // All other fields go here.
   int64_t start_time_micros_;
   Dart_MessageNotifyCallback message_notify_callback_ = nullptr;
+  Dart_IsolateShutdownCallback on_shutdown_callback_ = nullptr;
+  Dart_IsolateCleanupCallback on_cleanup_callback_ = nullptr;
   char* name_ = nullptr;
   Dart_Port main_port_ = 0;
   // Isolates created by Isolate.spawn have the same origin id.
@@ -1576,14 +1605,7 @@
   Random random_;
   Simulator* simulator_ = nullptr;
   Mutex mutex_;                            // Protects compiler stats.
-  Mutex constant_canonicalization_mutex_;  // Protects const canonicalization.
-  Mutex megamorphic_mutex_;  // Protects the table of megamorphic caches and
-                             // their entries.
-  Mutex kernel_data_lib_cache_mutex_;
-  Mutex kernel_data_class_cache_mutex_;
-  Mutex kernel_constants_mutex_;
   MessageHandler* message_handler_ = nullptr;
-  std::unique_ptr<IsolateSpawnState> spawn_state_;
   intptr_t defer_finalization_count_ = 0;
   MallocGrowableArray<PendingLazyDeopt>* pending_deopts_;
   DeoptContext* deopt_context_ = nullptr;
@@ -1731,78 +1753,6 @@
   DISALLOW_COPY_AND_ASSIGN(EnterIsolateGroupScope);
 };
 
-class IsolateSpawnState {
- public:
-  IsolateSpawnState(Dart_Port parent_port,
-                    Dart_Port origin_id,
-                    const char* script_url,
-                    const Function& func,
-                    SerializedObjectBuffer* message_buffer,
-                    const char* package_config,
-                    bool paused,
-                    bool errorsAreFatal,
-                    Dart_Port onExit,
-                    Dart_Port onError,
-                    const char* debug_name,
-                    IsolateGroup* group);
-  IsolateSpawnState(Dart_Port parent_port,
-                    const char* script_url,
-                    const char* package_config,
-                    SerializedObjectBuffer* args_buffer,
-                    SerializedObjectBuffer* message_buffer,
-                    bool paused,
-                    bool errorsAreFatal,
-                    Dart_Port onExit,
-                    Dart_Port onError,
-                    const char* debug_name,
-                    IsolateGroup* group);
-  ~IsolateSpawnState();
-
-  Isolate* isolate() const { return isolate_; }
-  void set_isolate(Isolate* value) { isolate_ = value; }
-
-  Dart_Port parent_port() const { return parent_port_; }
-  Dart_Port origin_id() const { return origin_id_; }
-  Dart_Port on_exit_port() const { return on_exit_port_; }
-  Dart_Port on_error_port() const { return on_error_port_; }
-  const char* script_url() const { return script_url_; }
-  const char* package_config() const { return package_config_; }
-  const char* library_url() const { return library_url_; }
-  const char* class_name() const { return class_name_; }
-  const char* function_name() const { return function_name_; }
-  const char* debug_name() const { return debug_name_; }
-  bool is_spawn_uri() const { return library_url_ == nullptr; }
-  bool paused() const { return paused_; }
-  bool errors_are_fatal() const { return errors_are_fatal_; }
-  Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
-
-  ObjectPtr ResolveFunction();
-  InstancePtr BuildArgs(Thread* thread);
-  InstancePtr BuildMessage(Thread* thread);
-
-  IsolateGroup* isolate_group() const { return isolate_group_; }
-
- private:
-  Isolate* isolate_;
-  Dart_Port parent_port_;
-  Dart_Port origin_id_;
-  Dart_Port on_exit_port_;
-  Dart_Port on_error_port_;
-  const char* script_url_;
-  const char* package_config_;
-  const char* library_url_;
-  const char* class_name_;
-  const char* function_name_;
-  const char* debug_name_;
-  IsolateGroup* isolate_group_;
-  std::unique_ptr<Message> serialized_args_;
-  std::unique_ptr<Message> serialized_message_;
-
-  Dart_IsolateFlags isolate_flags_;
-  bool paused_;
-  bool errors_are_fatal_;
-};
-
 }  // namespace dart
 
 #endif  // RUNTIME_VM_ISOLATE_H_
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index f9e26a0..8e586b3 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -19,6 +19,7 @@
 #include "vm/kernel_isolate.h"
 #include "vm/kernel_loader.h"
 #include "vm/log.h"
+#include "vm/longjump.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
@@ -960,7 +961,7 @@
     for (intptr_t import_idx = 0; import_idx < ports.Length(); import_idx++) {
       ns ^= ports.At(import_idx);
       if (!ns.IsNull()) {
-        target = ns.library();
+        target = ns.target();
         target_url = target.url();
         if (!target_url.StartsWith(Symbols::DartExtensionScheme())) {
           (*imported_by)[target.index()]->Add(lib.index());
@@ -973,7 +974,7 @@
     for (intptr_t export_idx = 0; export_idx < ports.Length(); export_idx++) {
       ns ^= ports.At(export_idx);
       if (!ns.IsNull()) {
-        target = ns.library();
+        target = ns.target();
         (*imported_by)[target.index()]->Add(lib.index());
       }
     }
@@ -991,7 +992,7 @@
              import_idx++) {
           ns ^= ports.At(import_idx);
           if (!ns.IsNull()) {
-            target = ns.library();
+            target = ns.target();
             (*imported_by)[target.index()]->Add(lib.index());
           }
         }
@@ -1099,20 +1100,25 @@
     const String& root_lib_url) {
   Thread* thread = Thread::Current();
 
-  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
-  if (tmp.IsError()) {
-    return tmp.raw();
-  }
+  LongJumpScope jump;
+  if (setjmp(*jump.Set()) == 0) {
+    const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
+    if (tmp.IsError()) {
+      return tmp.raw();
+    }
 
-  // If main method disappeared or were not there to begin with then
-  // KernelLoader will return null. In this case lookup library by
-  // URL.
-  auto& lib = Library::Handle(Library::RawCast(tmp.raw()));
-  if (lib.IsNull()) {
-    lib = Library::LookupLibrary(thread, root_lib_url);
+    // If main method disappeared or were not there to begin with then
+    // KernelLoader will return null. In this case lookup library by
+    // URL.
+    auto& lib = Library::Handle(Library::RawCast(tmp.raw()));
+    if (lib.IsNull()) {
+      lib = Library::LookupLibrary(thread, root_lib_url);
+    }
+    isolate_->object_store()->set_root_library(lib);
+    return Object::null();
+  } else {
+    return thread->StealStickyError();
   }
-  isolate_->object_store()->set_root_library(lib);
-  return Object::null();
 }
 
 void IsolateReloadContext::ReloadPhase3FinalizeLoading() {
@@ -1242,6 +1248,8 @@
   Class& cls = Class::Handle();
   Array& fields = Array::Handle();
   Field& field = Field::Handle();
+  Thread* thread = Thread::Current();
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
   for (intptr_t cls_idx = bottom; cls_idx < top; cls_idx++) {
     if (!class_table->HasValidClassAt(cls_idx)) {
       // Skip.
@@ -1927,7 +1935,7 @@
     visitor->VisitPointers(class_table, saved_num_cids_);
   }
   ClassPtr* saved_tlc_class_table =
-      saved_class_table_.load(std::memory_order_relaxed);
+      saved_tlc_class_table_.load(std::memory_order_relaxed);
   if (saved_tlc_class_table != NULL) {
     auto class_table =
         reinterpret_cast<ObjectPtr*>(&(saved_tlc_class_table[0]));
@@ -2268,6 +2276,8 @@
          i += SubtypeTestCache::kTestEntryLength) {
       if ((entries_.At(i + SubtypeTestCache::kInstanceClassIdOrFunction) ==
            instance_cid_or_function_.raw()) &&
+          (entries_.At(i + SubtypeTestCache::kDestinationType) ==
+           type_.raw()) &&
           (entries_.At(i + SubtypeTestCache::kInstanceTypeArguments) ==
            instance_type_arguments_.raw()) &&
           (entries_.At(i + SubtypeTestCache::kInstantiatorTypeArguments) ==
@@ -2296,8 +2306,9 @@
         ASSERT(!FLAG_identity_reload);
         field.set_needs_load_guard(true);
       } else {
-        cache_.AddCheck(instance_cid_or_function_, instance_type_arguments_,
-                        instantiator_type_arguments_, function_type_arguments_,
+        cache_.AddCheck(instance_cid_or_function_, type_,
+                        instance_type_arguments_, instantiator_type_arguments_,
+                        function_type_arguments_,
                         parent_function_type_arguments_,
                         delayed_function_type_arguments_, Bool::True());
       }
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 30142f5..adfc624 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -348,16 +348,6 @@
   isolate_group->PrintJSON(this, ref);
 }
 
-void JSONStream::PrintValue(ThreadRegistry* reg) {
-  PrintCommaIfNeeded();
-  reg->PrintJSON(this);
-}
-
-void JSONStream::PrintValue(Thread* thread) {
-  PrintCommaIfNeeded();
-  thread->PrintJSON(this);
-}
-
 void JSONStream::PrintValue(const TimelineEvent* timeline_event) {
   PrintCommaIfNeeded();
   timeline_event->PrintJSON(this);
@@ -408,16 +398,6 @@
   PrintValue(isolate);
 }
 
-void JSONStream::PrintProperty(const char* name, ThreadRegistry* reg) {
-  PrintPropertyName(name);
-  PrintValue(reg);
-}
-
-void JSONStream::PrintProperty(const char* name, Thread* thread) {
-  PrintPropertyName(name);
-  PrintValue(thread);
-}
-
 void JSONStream::PrintProperty(const char* name,
                                const TimelineEvent* timeline_event) {
   PrintPropertyName(name);
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index b563f5f..a00f266 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -205,8 +205,6 @@
   void PrintValue(MessageQueue* queue);
   void PrintValue(Isolate* isolate, bool ref = true);
   void PrintValue(IsolateGroup* isolate, bool ref = true);
-  void PrintValue(ThreadRegistry* reg);
-  void PrintValue(Thread* thread);
   void PrintValue(const TimelineEvent* timeline_event);
   void PrintValue(const TimelineEventBlock* timeline_event_block);
   void PrintValueVM(bool ref = true);
@@ -261,8 +259,6 @@
   void PrintProperty(const char* name, Metric* metric);
   void PrintProperty(const char* name, MessageQueue* queue);
   void PrintProperty(const char* name, Isolate* isolate);
-  void PrintProperty(const char* name, ThreadRegistry* reg);
-  void PrintProperty(const char* name, Thread* thread);
   void PrintProperty(const char* name, Zone* zone);
   void PrintProperty(const char* name, const TimelineEvent* timeline_event);
   void PrintProperty(const char* name,
@@ -377,12 +373,6 @@
   void AddProperty(const char* name, Isolate* isolate) const {
     stream_->PrintProperty(name, isolate);
   }
-  void AddProperty(const char* name, ThreadRegistry* reg) const {
-    stream_->PrintProperty(name, reg);
-  }
-  void AddProperty(const char* name, Thread* thread) const {
-    stream_->PrintProperty(name, thread);
-  }
   void AddProperty(const char* name, Zone* zone) const {
     stream_->PrintProperty(name, zone);
   }
@@ -443,8 +433,6 @@
   void AddValue(IsolateGroup* isolate_group, bool ref = true) const {
     stream_->PrintValue(isolate_group, ref);
   }
-  void AddValue(ThreadRegistry* reg) const { stream_->PrintValue(reg); }
-  void AddValue(Thread* thread) const { stream_->PrintValue(thread); }
   void AddValue(Breakpoint* bpt) const { stream_->PrintValue(bpt); }
   void AddValue(TokenPosition tp) const { stream_->PrintValue(tp); }
   void AddValue(const ServiceEvent* event) const { stream_->PrintValue(event); }
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 7c53e72..ed49742 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -347,6 +347,36 @@
   script.set_debug_positions(array_object);
 }
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  interesting_script.LookupSourceAndLineStarts(zone);
+  TranslationHelper helper(thread);
+  helper.InitFromScript(interesting_script);
+
+  ExternalTypedData& data =
+      ExternalTypedData::Handle(zone, interesting_script.constant_coverage());
+
+  KernelReaderHelper kernel_reader(zone, &helper, interesting_script, data, 0);
+
+  // Read "constant coverage constructors".
+  const intptr_t constant_coverage_constructors = kernel_reader.ReadUInt();
+  const Array& constructors =
+      Array::Handle(Array::New(constant_coverage_constructors));
+  for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
+    NameIndex kernel_name = kernel_reader.ReadCanonicalNameReference();
+    Class& klass = Class::ZoneHandle(
+        zone,
+        helper.LookupClassByKernelClass(helper.EnclosingName(kernel_name)));
+    const Function& target = Function::ZoneHandle(
+        zone, helper.LookupConstructorByKernelConstructor(klass, kernel_name));
+    constructors.SetAt(i, target);
+  }
+  return constructors.raw();
+}
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field) {
   ASSERT(field.is_static() && field.is_const());
 
@@ -430,26 +460,28 @@
   DISALLOW_COPY_AND_ASSIGN(MetadataEvaluator);
 };
 
-ObjectPtr EvaluateMetadata(const Field& metadata_field,
+ObjectPtr EvaluateMetadata(const Library& library,
+                           intptr_t kernel_offset,
                            bool is_annotations_offset) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Thread* thread = Thread::Current();
     Zone* zone = thread->zone();
     TranslationHelper helper(thread);
-    Script& script = Script::Handle(zone, metadata_field.Script());
+    Script& script = Script::Handle(
+        zone, Class::Handle(zone, library.toplevel_class()).script());
     helper.InitFromScript(script);
 
-    const Class& owner_class = Class::Handle(zone, metadata_field.Owner());
+    const Class& owner_class = Class::Handle(zone, library.toplevel_class());
     ActiveClass active_class;
     ActiveClassScope active_class_scope(&active_class, &owner_class);
 
     MetadataEvaluator metadata_evaluator(
         zone, &helper, script,
-        ExternalTypedData::Handle(zone, metadata_field.KernelData()),
-        metadata_field.KernelDataProgramOffset(), &active_class);
+        ExternalTypedData::Handle(zone, library.kernel_data()),
+        library.kernel_offset(), &active_class);
 
-    return metadata_evaluator.EvaluateMetadata(metadata_field.kernel_offset(),
+    return metadata_evaluator.EvaluateMetadata(kernel_offset,
                                                is_annotations_offset);
 
   } else {
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 9b0d8de..79c5670 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -195,8 +195,13 @@
 
 void CollectTokenPositionsFor(const Script& script);
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field);
-ObjectPtr EvaluateMetadata(const Field& metadata_field,
+ObjectPtr EvaluateMetadata(const Library& library,
+                           intptr_t kernel_offset,
                            bool is_annotations_offset);
 ObjectPtr BuildParameterDescriptor(const Function& function);
 
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 7d5e9c5..f547c0b 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,8 +20,8 @@
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
 
 // Both version numbers are inclusive.
-static const uint32_t kMinSupportedKernelFormatVersion = 50;
-static const uint32_t kMaxSupportedKernelFormatVersion = 50;
+static const uint32_t kMinSupportedKernelFormatVersion = 52;
+static const uint32_t kMaxSupportedKernelFormatVersion = 52;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index f8f0d54..5190afd 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -140,17 +140,19 @@
     if (FLAG_trace_kernel) {
       OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n");
     }
-    Isolate* I = reinterpret_cast<Isolate*>(parameter);
+    KernelIsolate::SetLoadPort(ILLEGAL_PORT);
+    Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(parameter));
     {
-      // Print the error if there is one.  This may execute dart code to
-      // print the exception object, so we need to use a StartIsolateScope.
-      ASSERT(Isolate::Current() == NULL);
-      StartIsolateScope start_scope(I);
-      Thread* T = Thread::Current();
-      ASSERT(I == T->isolate());
-      I->WaitForOutstandingSpawns();
+      auto T = Thread::Current();
+      TransitionNativeToVM transition(T);
       StackZone zone(T);
       HandleScope handle_scope(T);
+
+      auto I = T->isolate();
+      ASSERT(KernelIsolate::IsKernelIsolate(I));
+
+      // Print the error if there is one.  This may execute dart code to
+      // print the exception object, so we need to use a StartIsolateScope.
       Error& error = Error::Handle(Z);
       error = T->sticky_error();
       if (!error.IsNull() && !error.IsUnwindError()) {
@@ -162,14 +164,8 @@
         OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n",
                      error.ToErrorCString());
       }
-      Dart::RunShutdownCallback();
     }
-
-    ASSERT(KernelIsolate::IsKernelIsolate(I));
-    KernelIsolate::SetLoadPort(ILLEGAL_PORT);
-
-    // Shut the isolate down.
-    Dart::ShutdownIsolate(I);
+    Dart_ShutdownIsolate();
     if (FLAG_trace_kernel) {
       OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n");
     }
@@ -417,13 +413,16 @@
   free(temp);
 }
 
-bool KernelIsolate::GetExperimentalFlag(const char* value) {
+bool KernelIsolate::GetExperimentalFlag(ExperimentalFeature feature) {
+  const char* value = GetExperimentalFeatureName(feature);
   for (const char* str : *experimental_flags_) {
     if (strcmp(str, value) == 0) {
       return true;
+    } else if (strstr(str, "no-") == str && strcmp(str + 3, value) == 0) {
+      return false;
     }
   }
-  return false;
+  return GetExperimentalFeatureDefault(feature);
 }
 
 DEFINE_OPTION_HANDLER(KernelIsolate::AddExperimentalFlag,
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index e45022d..0aa5221 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -12,6 +12,7 @@
 
 #include "vm/allocation.h"
 #include "vm/dart.h"
+#include "vm/experimental_features.h"
 #include "vm/os_thread.h"
 
 namespace dart {
@@ -78,7 +79,7 @@
   static void NotifyAboutIsolateShutdown(const Isolate* isolate);
 
   static void AddExperimentalFlag(const char* value);
-  static bool GetExperimentalFlag(const char* value);
+  static bool GetExperimentalFlag(ExperimentalFeature feature);
 
  protected:
   static void InitCallback(Isolate* I);
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index a64fef4..f6fe2fa 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -29,6 +29,7 @@
 
 #define Z (zone_)
 #define I (isolate_)
+#define IG (isolate_->group())
 #define T (type_translator_)
 #define H (translation_helper_)
 
@@ -214,6 +215,7 @@
       external_name_field_(Field::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
       potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
+      static_field_value_(Instance::Handle(Z)),
       pragma_class_(Class::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)),
       expression_evaluation_library_(Library::Handle(Z)) {
@@ -479,6 +481,7 @@
       external_name_field_(Field::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
       potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
+      static_field_value_(Instance::Handle(Z)),
       pragma_class_(Class::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)),
       expression_evaluation_library_(Library::Handle(Z)) {
@@ -691,7 +694,7 @@
       // Dart_GetImportsOfScheme('dart-ext').
       const auto& native_library = Library::Handle(Library::New(uri_path));
       library.AddImport(Namespace::Handle(Namespace::New(
-          native_library, Array::null_array(), Array::null_array())));
+          native_library, Array::null_array(), Array::null_array(), library)));
     }
   }
 }
@@ -768,6 +771,9 @@
 }
 
 void KernelLoader::LoadLibrary(const Library& library) {
+  // This will be invoked by VM bootstrapping code.
+  SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
+
   ASSERT(!library.Loaded());
 
   const auto& uri = String::Handle(Z, library.url());
@@ -1119,8 +1125,7 @@
 
   if (FLAG_enable_mirrors && annotation_count > 0) {
     ASSERT(annotations_kernel_offset > 0);
-    library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource,
-                               annotations_kernel_offset);
+    library.AddMetadata(library, annotations_kernel_offset);
   }
 
   if (register_class) {
@@ -1234,14 +1239,18 @@
     field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
     intptr_t field_initializer_offset = helper_.ReaderOffset();
     field_helper.ReadUntilExcluding(FieldHelper::kEnd);
+
     {
       // GenerateFieldAccessors reads (some of) the initializer.
       AlternativeReadingScope alt(&helper_.reader_, field_initializer_offset);
-      GenerateFieldAccessors(toplevel_class, field, &field_helper);
+      static_field_value_ =
+          GenerateFieldAccessors(toplevel_class, field, &field_helper);
     }
+    IG->RegisterStaticField(field, static_field_value_);
+
     if ((FLAG_enable_mirrors || has_pragma_annotation) &&
         annotation_count > 0) {
-      library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset);
+      library.AddMetadata(field, field_offset);
     }
     fields_.Add(&field);
   }
@@ -1359,7 +1368,7 @@
           "import of dart:ffi is not supported in the current Dart runtime");
     }
     String& prefix = H.DartSymbolPlain(dependency_helper.name_index_);
-    ns = Namespace::New(target_library, show_names, hide_names);
+    ns = Namespace::New(target_library, show_names, hide_names, *library);
     if ((dependency_helper.flags_ & LibraryDependencyHelper::Export) != 0) {
       library->AddExport(ns);
     } else {
@@ -1382,8 +1391,7 @@
 
     if (FLAG_enable_mirrors && dependency_helper.annotation_count_ > 0) {
       ASSERT(annotations_kernel_offset > 0);
-      ns.AddMetadata(toplevel_class, TokenPosition::kNoSource,
-                     annotations_kernel_offset);
+      library->AddMetadata(ns, annotations_kernel_offset);
     }
 
     if (prefix.IsNull()) {
@@ -1504,9 +1512,7 @@
   }
 
   if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) {
-    library.AddClassMetadata(*out_class, toplevel_class,
-                             TokenPosition::kNoSource,
-                             class_offset - correction_offset_);
+    library.AddMetadata(*out_class, class_offset - correction_offset_);
   }
 
   // We do not register expression evaluation classes with the VM:
@@ -1606,14 +1612,19 @@
       field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
       intptr_t field_initializer_offset = helper_.ReaderOffset();
       field_helper.ReadUntilExcluding(FieldHelper::kEnd);
+
       {
         // GenerateFieldAccessors reads (some of) the initializer.
         AlternativeReadingScope alt(&helper_.reader_, field_initializer_offset);
-        GenerateFieldAccessors(klass, field, &field_helper);
+        static_field_value_ =
+            GenerateFieldAccessors(klass, field, &field_helper);
+      }
+      if (field.is_static()) {
+        IG->RegisterStaticField(field, static_field_value_);
       }
       if ((FLAG_enable_mirrors || has_pragma_annotation) &&
           annotation_count > 0) {
-        library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset);
+        library.AddMetadata(field, field_offset);
       }
       fields_.Add(&field);
     }
@@ -1631,6 +1642,7 @@
                      /* is_reflectable = */ false,
                      /* is_late = */ false, klass, Object::dynamic_type(),
                      TokenPosition::kNoSource, TokenPosition::kNoSource);
+      IG->RegisterStaticField(deleted_enum_sentinel, Instance::Handle());
       fields_.Add(&deleted_enum_sentinel);
     }
 
@@ -1711,8 +1723,7 @@
 
     if ((FLAG_enable_mirrors || has_pragma_annotation) &&
         annotation_count > 0) {
-      library.AddFunctionMetadata(function, TokenPosition::kNoSource,
-                                  constructor_offset);
+      library.AddMetadata(function, constructor_offset);
     }
   }
 
@@ -2036,8 +2047,7 @@
   helper_.SetOffset(procedure_end);
 
   if (annotation_count > 0) {
-    library.AddFunctionMetadata(function, TokenPosition::kNoSource,
-                                procedure_offset);
+    library.AddMetadata(function, procedure_offset);
   }
 
   if (has_pragma_annotation) {
@@ -2086,6 +2096,10 @@
   const String& uri_string = helper_.SourceTableUriFor(index);
   const String& import_uri_string =
       helper_.SourceTableImportUriFor(index, program_->binary_version());
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  ExternalTypedData& constant_coverage =
+      ExternalTypedData::Handle(Z, helper_.GetConstantCoverageFor(index));
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
   String& sources = String::Handle(Z);
   TypedData& line_starts = TypedData::Handle(Z);
@@ -2131,24 +2145,26 @@
   script.set_kernel_script_index(index);
   script.set_kernel_program_info(kernel_program_info_);
   script.set_line_starts(line_starts);
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  script.set_constant_coverage(constant_coverage);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   script.set_debug_positions(Array::null_array());
   return script.raw();
 }
 
-void KernelLoader::GenerateFieldAccessors(const Class& klass,
-                                          const Field& field,
-                                          FieldHelper* field_helper) {
+InstancePtr KernelLoader::GenerateFieldAccessors(const Class& klass,
+                                                 const Field& field,
+                                                 FieldHelper* field_helper) {
   const Tag tag = helper_.PeekTag();
   const bool has_initializer = (tag == kSomething);
+
   if (has_initializer) {
     SimpleExpressionConverter converter(&H, &helper_);
     const bool has_simple_initializer =
         converter.IsSimple(helper_.ReaderOffset() + 1);  // ignore the tag.
     if (has_simple_initializer) {
       if (field_helper->IsStatic()) {
-        // We do not need a getter.
-        field.SetStaticValue(converter.SimpleValue(), true);
-        return;
+        return converter.SimpleValue().raw();
       } else {
         // Note: optimizer relies on DoubleInitialized bit in its field-unboxing
         // heuristics. See JitCallSpecializer::VisitStoreInstanceField for more
@@ -2166,12 +2182,8 @@
     if (!has_initializer && !field_helper->IsLate()) {
       // Static fields without an initializer are implicitly initialized to
       // null. We do not need a getter.
-      field.SetStaticValue(Instance::null_instance(), true);
-      return;
+      return Instance::null();
     }
-
-    // We do need a getter that evaluates the initializer if necessary.
-    field.SetStaticValue(Object::sentinel(), true);
   }
   ASSERT(field.NeedsGetter());
 
@@ -2230,6 +2242,10 @@
     T.SetupUnboxingInfoMetadataForFieldAccessors(setter,
                                                  library_kernel_offset_);
   }
+
+  // If static, we do need a getter that evaluates the initializer if necessary.
+  return field_helper->IsStatic() ? Instance::sentinel().raw()
+                                  : Instance::null();
 }
 
 LibraryPtr KernelLoader::LookupLibraryOrNull(NameIndex library) {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 1129956..5b983ea 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -331,9 +331,10 @@
     return kernel_program_info_.ScriptAt(source_uri_index);
   }
 
-  void GenerateFieldAccessors(const Class& klass,
-                              const Field& field,
-                              FieldHelper* field_helper);
+  // Returns the initial field value for a static function (if applicable).
+  InstancePtr GenerateFieldAccessors(const Class& klass,
+                                     const Field& field,
+                                     FieldHelper* field_helper);
   bool FieldNeedsSetter(FieldHelper* field_helper);
 
   void LoadLibraryImportsAndExports(Library* library,
@@ -414,6 +415,7 @@
   Field& external_name_field_;
   GrowableObjectArray& potential_natives_;
   GrowableObjectArray& potential_pragma_functions_;
+  Instance& static_field_value_;
 
   Class& pragma_class_;
 
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 7ad731d..cb04006 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -40,7 +40,8 @@
   return result;
 }
 
-SafepointMutexLocker::SafepointMutexLocker(Mutex* mutex) : mutex_(mutex) {
+SafepointMutexLocker::SafepointMutexLocker(ThreadState* thread, Mutex* mutex)
+    : StackResource(thread), mutex_(mutex) {
   ASSERT(mutex != NULL);
   if (!mutex_->TryLock()) {
     // We did not get the lock and could potentially block, so transition
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index 94a8070..d5b2576 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -226,9 +226,11 @@
  *      ...
  *    }
  */
-class SafepointMutexLocker : public ValueObject {
+class SafepointMutexLocker : public StackResource {
  public:
-  explicit SafepointMutexLocker(Mutex* mutex);
+  explicit SafepointMutexLocker(Mutex* mutex)
+      : SafepointMutexLocker(ThreadState::Current(), mutex) {}
+  SafepointMutexLocker(ThreadState* thread, Mutex* mutex);
   virtual ~SafepointMutexLocker() { mutex_->Unlock(); }
 
  private:
diff --git a/runtime/vm/malloc_hooks_arm.cc b/runtime/vm/malloc_hooks_arm.cc
index e344434..7e857e5 100644
--- a/runtime/vm/malloc_hooks_arm.cc
+++ b/runtime/vm/malloc_hooks_arm.cc
@@ -10,7 +10,7 @@
 
 namespace dart {
 
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
 
 }  // namespace dart
 
diff --git a/runtime/vm/malloc_hooks_arm64.cc b/runtime/vm/malloc_hooks_arm64.cc
index d063748..e50ea0b 100644
--- a/runtime/vm/malloc_hooks_arm64.cc
+++ b/runtime/vm/malloc_hooks_arm64.cc
@@ -10,7 +10,7 @@
 
 namespace dart {
 
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
 
 }  // namespace dart
 
diff --git a/runtime/vm/malloc_hooks_ia32.cc b/runtime/vm/malloc_hooks_ia32.cc
index b056456..2b7a371 100644
--- a/runtime/vm/malloc_hooks_ia32.cc
+++ b/runtime/vm/malloc_hooks_ia32.cc
@@ -11,9 +11,9 @@
 namespace dart {
 
 #if defined(DEBUG)
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 6;
 #elif !(defined(PRODUCT) || defined(DEBUG))
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
 #endif
 
 }  // namespace dart
diff --git a/runtime/vm/malloc_hooks_x64.cc b/runtime/vm/malloc_hooks_x64.cc
index 25e2283..2ec564b 100644
--- a/runtime/vm/malloc_hooks_x64.cc
+++ b/runtime/vm/malloc_hooks_x64.cc
@@ -11,9 +11,9 @@
 namespace dart {
 
 #if defined(DEBUG)
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 6;
 #elif !(defined(PRODUCT) || defined(DEBUG))
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
 #endif
 
 }  // namespace dart
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 04a4acd..2e7d1b3 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -17,13 +17,13 @@
                                                   const String& name,
                                                   const Array& descriptor) {
   Isolate* isolate = thread->isolate();
-  // Multiple compilation threads could access this lookup.
-  SafepointMutexLocker ml(isolate->megamorphic_mutex());
+  SafepointMutexLocker ml(thread->isolate_group()->megamorphic_table_mutex());
+
   ASSERT(name.IsSymbol());
   // TODO(rmacnak): ASSERT(descriptor.IsCanonical());
 
   // TODO(rmacnak): Make a proper hashtable a la symbol table.
-  GrowableObjectArray& table = GrowableObjectArray::Handle(
+  auto& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
   MegamorphicCache& cache = MegamorphicCache::Handle();
   if (table.IsNull()) {
@@ -45,7 +45,10 @@
 }
 
 void MegamorphicCacheTable::PrintSizes(Isolate* isolate) {
-  StackZone zone(Thread::Current());
+  auto thread = Thread::Current();
+  SafepointMutexLocker ml(thread->isolate_group()->megamorphic_table_mutex());
+
+  StackZone zone(thread);
   intptr_t size = 0;
   MegamorphicCache& cache = MegamorphicCache::Handle();
   Array& buckets = Array::Handle();
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc
index ecfda6c..f7e582b 100644
--- a/runtime/vm/metrics.cc
+++ b/runtime/vm/metrics.cc
@@ -206,7 +206,7 @@
 }
 
 void Metric::Cleanup() {
-  if (FLAG_print_metrics || FLAG_print_benchmarking_metrics) {
+  if (FLAG_print_metrics) {
     // Create a zone to allocate temporary strings in.
     StackZone sz(Thread::Current());
     OS::PrintErr("Printing metrics for VM\n");
diff --git a/runtime/vm/native_symbol_win.cc b/runtime/vm/native_symbol_win.cc
index 0f2c0ce..9ddc3a4 100644
--- a/runtime/vm/native_symbol_win.cc
+++ b/runtime/vm/native_symbol_win.cc
@@ -23,6 +23,10 @@
     lock_ = new Mutex();
   }
   running_ = true;
+
+// Symbol resolution API's used in this file are not supported
+// when compiled in UWP.
+#ifndef TARGET_OS_WINDOWS_UWP
   SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
   HANDLE hProcess = GetCurrentProcess();
   if (!SymInitialize(hProcess, NULL, TRUE)) {
@@ -32,6 +36,7 @@
                  error);
     return;
   }
+#endif
 }
 
 void NativeSymbolResolver::Cleanup() {
@@ -40,6 +45,7 @@
     return;
   }
   running_ = false;
+#ifndef TARGET_OS_WINDOWS_UWP
   HANDLE hProcess = GetCurrentProcess();
   if (!SymCleanup(hProcess)) {
     DWORD error = GetLastError();
@@ -47,9 +53,13 @@
                  ")\n",
                  error);
   }
+#endif
 }
 
 char* NativeSymbolResolver::LookupSymbolName(uword pc, uword* start) {
+#ifdef TARGET_OS_WINDOWS_UWP
+  return NULL;
+#else
   static const intptr_t kMaxNameLength = 2048;
   static const intptr_t kSymbolInfoSize = sizeof(SYMBOL_INFO);  // NOLINT.
   static char buffer[kSymbolInfoSize + kMaxNameLength];
@@ -76,6 +86,7 @@
     *start = pc - displacement;
   }
   return Utils::StrDup(pSymbol->Name);
+#endif  // ifdef TARGET_OS_WINDOWS_UWP
 }
 
 void NativeSymbolResolver::FreeSymbolName(char* name) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 82605a8..57ff8c6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -146,7 +146,6 @@
 ClassPtr Object::function_class_ = static_cast<ClassPtr>(RAW_NULL);
 ClassPtr Object::closure_data_class_ = static_cast<ClassPtr>(RAW_NULL);
 ClassPtr Object::signature_data_class_ = static_cast<ClassPtr>(RAW_NULL);
-ClassPtr Object::redirection_data_class_ = static_cast<ClassPtr>(RAW_NULL);
 ClassPtr Object::ffi_trampoline_data_class_ = static_cast<ClassPtr>(RAW_NULL);
 ClassPtr Object::field_class_ = static_cast<ClassPtr>(RAW_NULL);
 ClassPtr Object::script_class_ = static_cast<ClassPtr>(RAW_NULL);
@@ -632,14 +631,6 @@
 
 #define INIT_VTABLE(clazz)                                                     \
   {                                                                            \
-    Instance fake_handle;                                                      \
-    builtin_vtables_[k##clazz##Cid] = fake_handle.vtable();                    \
-  }
-  CLASS_LIST_WASM(INIT_VTABLE)
-#undef INIT_VTABLE
-
-#define INIT_VTABLE(clazz)                                                     \
-  {                                                                            \
     TypedData fake_internal_handle;                                            \
     builtin_vtables_[kTypedData##clazz##Cid] = fake_internal_handle.vtable();  \
     TypedDataView fake_view_handle;                                            \
@@ -796,9 +787,6 @@
   cls = Class::New<SignatureData, RTN::SignatureData>(isolate);
   signature_data_class_ = cls.raw();
 
-  cls = Class::New<RedirectionData, RTN::RedirectionData>(isolate);
-  redirection_data_class_ = cls.raw();
-
   cls = Class::New<FfiTrampolineData, RTN::FfiTrampolineData>(isolate);
   ffi_trampoline_data_class_ = cls.raw();
 
@@ -931,7 +919,7 @@
     InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0));
     Array::initializeHandle(empty_array_,
                             static_cast<ArrayPtr>(address + kHeapObjectTag));
-    empty_array_->StoreSmi(&empty_array_->raw_ptr()->length_, Smi::New(0));
+    empty_array_->raw_ptr()->set_length(Smi::New(0));
     empty_array_->SetCanonical();
   }
 
@@ -942,7 +930,7 @@
     InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1));
     Array::initializeHandle(zero_array_,
                             static_cast<ArrayPtr>(address + kHeapObjectTag));
-    zero_array_->StoreSmi(&zero_array_->raw_ptr()->length_, Smi::New(1));
+    zero_array_->raw_ptr()->set_length(Smi::New(1));
     smi = Smi::New(0);
     zero_array_->SetAt(0, smi);
     zero_array_->SetCanonical();
@@ -1038,10 +1026,8 @@
     TypeArguments::initializeHandle(
         empty_type_arguments_,
         static_cast<TypeArgumentsPtr>(address + kHeapObjectTag));
-    empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->length_,
-                                    Smi::New(0));
-    empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->hash_,
-                                    Smi::New(0));
+    empty_type_arguments_->raw_ptr()->set_length(Smi::New(0));
+    empty_type_arguments_->raw_ptr()->set_hash(Smi::New(0));
     empty_type_arguments_->ComputeHash();
     empty_type_arguments_->SetCanonical();
   }
@@ -1229,7 +1215,6 @@
   function_class_ = static_cast<ClassPtr>(RAW_NULL);
   closure_data_class_ = static_cast<ClassPtr>(RAW_NULL);
   signature_data_class_ = static_cast<ClassPtr>(RAW_NULL);
-  redirection_data_class_ = static_cast<ClassPtr>(RAW_NULL);
   ffi_trampoline_data_class_ = static_cast<ClassPtr>(RAW_NULL);
   field_class_ = static_cast<ClassPtr>(RAW_NULL);
   script_class_ = static_cast<ClassPtr>(RAW_NULL);
@@ -1330,7 +1315,6 @@
   SET_CLASS_NAME(function, Function);
   SET_CLASS_NAME(closure_data, ClosureData);
   SET_CLASS_NAME(signature_data, SignatureData);
-  SET_CLASS_NAME(redirection_data, RedirectionData);
   SET_CLASS_NAME(ffi_trampoline_data, FfiTrampolineData);
   SET_CLASS_NAME(field, Field);
   SET_CLASS_NAME(script, Script);
@@ -1483,18 +1467,11 @@
       // new array length, and so treat it as a pointer. Ensure it is a Smi so
       // the marker won't dereference it.
       ASSERT((new_tags & kSmiTagMask) == kSmiTag);
-      uint32_t tags = raw->ptr()->tags_;
-      uint32_t old_tags;
-      // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
-      do {
-        old_tags = tags;
-        // We can't use obj.CompareAndSwapTags here because we don't have a
-        // handle for the new object.
-      } while (!raw->ptr()->tags_.WeakCAS(old_tags, new_tags));
+      raw->ptr()->tags_ = new_tags;
 
       intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
       ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
-      raw->ptr()->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
+      raw->ptr()->set_length(Smi::New(leftover_len));
       raw->ptr()->RecomputeDataField();
     } else {
       // Update the leftover space as a basic object.
@@ -1512,14 +1489,7 @@
       // new array length, and so treat it as a pointer. Ensure it is a Smi so
       // the marker won't dereference it.
       ASSERT((new_tags & kSmiTagMask) == kSmiTag);
-      uint32_t tags = raw->ptr()->tags_;
-      uint32_t old_tags;
-      // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
-      do {
-        old_tags = tags;
-        // We can't use obj.CompareAndSwapTags here because we don't have a
-        // handle for the new object.
-      } while (!raw->ptr()->tags_.WeakCAS(old_tags, new_tags));
+      raw->ptr()->tags_ = new_tags;
     }
   }
 }
@@ -2299,23 +2269,6 @@
     pending_classes.Add(cls);
     RegisterClass(cls, Symbols::FfiDynamicLibrary(), lib);
 
-    lib = Library::LookupLibrary(thread, Symbols::DartWasm());
-    if (lib.IsNull()) {
-      lib = Library::NewLibraryHelper(Symbols::DartWasm(), true);
-      lib.SetLoadRequested();
-      lib.Register(thread);
-    }
-    object_store->set_bootstrap_library(ObjectStore::kWasm, lib);
-
-#define REGISTER_WASM_TYPE(clazz)                                              \
-  cls = Class::New<Instance, RTN::Instance>(k##clazz##Cid, isolate);           \
-  cls.set_num_type_arguments(0);                                               \
-  cls.set_is_prefinalized();                                                   \
-  pending_classes.Add(cls);                                                    \
-  RegisterClass(cls, Symbols::clazz(), lib);
-    CLASS_LIST_WASM(REGISTER_WASM_TYPE);
-#undef REGISTER_WASM_TYPE
-
     // Finish the initialization by compiling the bootstrap scripts containing
     // the base interfaces and the implementation of the internal classes.
     const Error& error = Error::Handle(
@@ -2331,9 +2284,6 @@
     // Set up the intrinsic state of all functions (core, math and typed data).
     compiler::Intrinsifier::InitializeState();
 
-    // Set up recognized state of all functions (core, math and typed data).
-    MethodRecognizer::InitializeState();
-
     // Adds static const fields (class ids) to the class 'ClassID');
     lib = Library::LookupLibrary(thread, Symbols::DartInternal());
     ASSERT(!lib.IsNull());
@@ -2343,6 +2293,9 @@
     ASSERT(injected);
 
     isolate->object_store()->InitKnownObjects();
+
+    // Set up recognized state of all functions (core, math and typed data).
+    MethodRecognizer::InitializeState();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
   } else {
     // Object::Init version when we are running in a version of dart that has a
@@ -2410,11 +2363,6 @@
     CLASS_LIST_FFI_TYPE_MARKER(REGISTER_FFI_CLASS);
 #undef REGISTER_FFI_CLASS
 
-#define REGISTER_WASM_CLASS(clazz)                                             \
-  cls = Class::New<Instance, RTN::Instance>(k##clazz##Cid, isolate);
-    CLASS_LIST_WASM(REGISTER_WASM_CLASS);
-#undef REGISTER_WASM_CLASS
-
     cls = Class::New<Instance, RTN::Instance>(kFfiNativeFunctionCid, isolate);
 
     cls = Class::NewPointerClass(kFfiPointerCid, isolate);
@@ -2507,10 +2455,9 @@
 }
 
 void Object::InitializeObject(uword address, intptr_t class_id, intptr_t size) {
-  // Note: we skip the header word here because it confuses TSAN. TSAN records
-  // an 8-byte write from the this loop, but doesn't overwrite that entry with
-  // the 4-byte relaxed store of the header below, then reports false data races
-  // based on the record of the 8-byte write.
+  // Note: we skip the header word here to avoid a racy read in the concurrent
+  // marker from observing the null object when it reads into a heap page
+  // allocated after marking started.
   uword cur = address + sizeof(ObjectLayout);
   uword end = address + size;
   if (class_id == kInstructionsCid) {
@@ -2549,7 +2496,7 @@
 #endif
     }
   }
-  uint32_t tags = 0;
+  uword tags = 0;
   ASSERT(class_id != kIllegalCid);
   tags = ObjectLayout::ClassIdTag::update(class_id, tags);
   tags = ObjectLayout::SizeTag::update(size, tags);
@@ -2560,9 +2507,6 @@
   tags = ObjectLayout::OldAndNotRememberedBit::update(is_old, tags);
   tags = ObjectLayout::NewBit::update(!is_old, tags);
   reinterpret_cast<ObjectLayout*>(address)->tags_ = tags;
-#if defined(HASH_IN_OBJECT_HEADER)
-  reinterpret_cast<ObjectLayout*>(address)->hash_ = 0;
-#endif
 }
 
 void Object::CheckHandle() const {
@@ -2709,7 +2653,7 @@
 }
 
 StringPtr Class::Name() const {
-  return raw_ptr()->name_;
+  return raw_ptr()->name();
 }
 
 StringPtr Class::ScrubbedName() const {
@@ -2722,8 +2666,8 @@
 
 StringPtr Class::UserVisibleName() const {
 #if !defined(PRODUCT)
-  ASSERT(raw_ptr()->user_name_ != String::null());
-  return raw_ptr()->user_name_;
+  ASSERT(raw_ptr()->user_name() != String::null());
+  return raw_ptr()->user_name();
 #endif  // !defined(PRODUCT)
   // No caching in PRODUCT, regenerate.
   return Symbols::New(Thread::Current(), GenerateUserVisibleName());
@@ -2731,8 +2675,8 @@
 
 const char* Class::UserVisibleNameCString() const {
 #if !defined(PRODUCT)
-  ASSERT(raw_ptr()->user_name_ != String::null());
-  return String::Handle(raw_ptr()->user_name_).ToCString();
+  ASSERT(raw_ptr()->user_name() != String::null());
+  return String::Handle(raw_ptr()->user_name()).ToCString();
 #endif                               // !defined(PRODUCT)
   return GenerateUserVisibleName();  // No caching in PRODUCT, regenerate.
 }
@@ -2768,7 +2712,7 @@
 bool Class::IsInFullSnapshot() const {
   NoSafepointScope no_safepoint;
   return LibraryLayout::InFullSnapshotBit::decode(
-      raw_ptr()->library_->ptr()->flags_);
+      raw_ptr()->library()->ptr()->flags_);
 }
 
 AbstractTypePtr Class::RareType() const {
@@ -2855,15 +2799,15 @@
     // The empty array has not been initialized yet.
     return;
   }
-  StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw());
-  StorePointer(&raw_ptr()->constants_, Object::null_array().raw());
+  raw_ptr()->set_interfaces(Object::empty_array().raw());
+  raw_ptr()->set_constants(Object::null_array().raw());
   set_functions(Object::empty_array());
   set_fields(Object::empty_array());
   set_invocation_dispatcher_cache(Object::empty_array());
 }
 
 ArrayPtr Class::OffsetToFieldMap(bool original_classes) const {
-  if (raw_ptr()->offset_in_words_to_field_ == Array::null()) {
+  if (raw_ptr()->offset_in_words_to_field() == Array::null()) {
     ASSERT(is_finalized());
     const intptr_t length = raw_ptr()->host_instance_size_in_words_;
     const Array& array = Array::Handle(Array::New(length, Heap::kOld));
@@ -2880,9 +2824,9 @@
       }
       cls = cls.SuperClass(original_classes);
     }
-    StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw());
+    raw_ptr()->set_offset_in_words_to_field(array.raw());
   }
-  return raw_ptr()->offset_in_words_to_field_;
+  return raw_ptr()->offset_in_words_to_field();
 }
 
 bool Class::HasInstanceFields() const {
@@ -2956,9 +2900,9 @@
       ASSERT(func.Owner() == raw());
       set.Insert(func);
     }
-    StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
+    raw_ptr()->set_functions_hash_table(set.Release().raw());
   } else {
-    StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
+    raw_ptr()->set_functions_hash_table(Array::null());
   }
 }
 
@@ -2979,9 +2923,9 @@
     // Transition to using hash table.
     SetFunctions(new_array);
   } else if (new_len > kFunctionLookupHashTreshold) {
-    ClassFunctionsSet set(raw_ptr()->functions_hash_table_);
+    ClassFunctionsSet set(raw_ptr()->functions_hash_table());
     set.Insert(function);
-    StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
+    raw_ptr()->set_functions_hash_table(set.Release().raw());
   }
 }
 
@@ -3084,7 +3028,7 @@
 
 void Class::set_signature_function(const Function& value) const {
   ASSERT(value.IsClosureFunction() || value.IsSignatureFunction());
-  StorePointer(&raw_ptr()->signature_function_, value.raw());
+  raw_ptr()->set_signature_function(value.raw());
 }
 
 void Class::set_state_bits(intptr_t bits) const {
@@ -3093,34 +3037,32 @@
 }
 
 void Class::set_library(const Library& value) const {
-  StorePointer(&raw_ptr()->library_, value.raw());
+  raw_ptr()->set_library(value.raw());
 }
 
 void Class::set_type_parameters(const TypeArguments& value) const {
   ASSERT((num_type_arguments() == kUnknownNumTypeArguments) ||
          is_prefinalized());
-  StorePointer(&raw_ptr()->type_parameters_, value.raw());
+  raw_ptr()->set_type_parameters(value.raw());
 }
 
 void Class::set_functions(const Array& value) const {
   // Ensure all writes to the [Function]s are visible by the time the array
   // is visible.
-  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->functions_,
-                                                    value.raw());
+  raw_ptr()->set_functions<std::memory_order_release>(value.raw());
 }
 
 void Class::set_fields(const Array& value) const {
   // Ensure all writes to the [Field]s are visible by the time the array
   // is visible.
-  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->fields_,
-                                                    value.raw());
+  raw_ptr()->set_fields<std::memory_order_release>(value.raw());
 }
 
 void Class::set_invocation_dispatcher_cache(const Array& cache) const {
   // Ensure all writes to the cache are visible by the time the array
   // is visible.
-  StorePointer<ArrayPtr, std::memory_order_release>(
-      &raw_ptr()->invocation_dispatcher_cache_, cache.raw());
+  raw_ptr()->set_invocation_dispatcher_cache<std::memory_order_release>(
+      cache.raw());
 }
 
 intptr_t Class::NumTypeParameters(Thread* thread) const {
@@ -3274,7 +3216,7 @@
 
 void Class::set_super_type(const AbstractType& value) const {
   ASSERT(value.IsNull() || (value.IsType() && !value.IsDynamicType()));
-  StorePointer(&raw_ptr()->super_type_, value.raw());
+  raw_ptr()->set_super_type(value.raw());
 }
 
 TypeParameterPtr Class::LookupTypeParameter(const String& type_name) const {
@@ -3549,8 +3491,7 @@
   invocation.SetParameterTypeAt(0, Object::dynamic_type());
   invocation.SetParameterNameAt(0, Symbols::This());
   // Remaining positional parameters.
-  intptr_t i = 1;
-  for (; i < desc.PositionalCount(); i++) {
+  for (intptr_t i = 1; i < desc.PositionalCount(); i++) {
     invocation.SetParameterTypeAt(i, Object::dynamic_type());
     char name[64];
     Utils::SNPrint(name, 64, ":p%" Pd, i);
@@ -3559,10 +3500,11 @@
   }
 
   // Named parameters.
-  for (; i < desc.Count(); i++) {
-    invocation.SetParameterTypeAt(i, Object::dynamic_type());
-    intptr_t index = i - desc.PositionalCount();
-    invocation.SetParameterNameAt(i, String::Handle(zone, desc.NameAt(index)));
+  for (intptr_t i = 0; i < desc.NamedCount(); i++) {
+    const intptr_t param_index = desc.PositionAt(i);
+    const auto& param_name = String::Handle(zone, desc.NameAt(i));
+    invocation.SetParameterTypeAt(param_index, Object::dynamic_type());
+    invocation.SetParameterNameAt(param_index, param_name);
   }
   invocation.TruncateUnusedParameterFlags();
   invocation.set_result_type(Object::dynamic_type());
@@ -3822,7 +3764,7 @@
 }
 
 ArrayPtr Class::invocation_dispatcher_cache() const {
-  return raw_ptr()->invocation_dispatcher_cache_;
+  return raw_ptr()->invocation_dispatcher_cache();
 }
 
 void Class::Finalize() const {
@@ -3919,7 +3861,15 @@
 }
 
 void Class::DisableCHAOptimizedCode(const Class& subclass) {
-  ASSERT(Thread::Current()->IsMutatorThread());
+  Thread* thread = Thread::Current();
+  ASSERT(thread->IsMutatorThread());
+  // TODO(dartbug.com/36097): The program_lock acquisition has to move up the
+  // call chain to ClassFinalizer::AllocateFinalizeClass() so that:
+  //   - no two threads allocate-finalize a class at the same time(we should
+  // use the logic similar to what is used in EnsureIsAllocateFinalized()).
+  //   - code is deoptimized before we violate optimization assumptions
+  // potentially done concurrently (AddDirectSubclass/AddDirectImplementor).
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
   CHACodeArray a(*this);
   if (FLAG_trace_deoptimization && a.HasCodes()) {
     if (subclass.IsNull()) {
@@ -3958,8 +3908,16 @@
 #endif
 }
 
+ArrayPtr Class::dependent_code() const {
+  DEBUG_ASSERT(
+      IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
+  return raw_ptr()->dependent_code();
+}
+
 void Class::set_dependent_code(const Array& array) const {
-  StorePointer(&raw_ptr()->dependent_code_, array.raw());
+  DEBUG_ASSERT(
+      IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+  raw_ptr()->set_dependent_code(array.raw());
 }
 
 // Conventions:
@@ -4239,12 +4197,10 @@
   }
   // This is a static function, so we pass an empty instantiator tav.
   ASSERT(function.is_static());
-  if (!function.CanReceiveDynamicInvocation()) {
-    ObjectPtr type_error = function.DoArgumentTypesMatch(
-        args, args_descriptor, Object::empty_type_arguments());
-    if (type_error != Error::null()) {
-      return type_error;
-    }
+  ObjectPtr type_error = function.DoArgumentTypesMatch(
+      args, args_descriptor, Object::empty_type_arguments());
+  if (type_error != Error::null()) {
+    return type_error;
   }
   return DartEntry::InvokeFunction(function, args, args_descriptor_array);
 }
@@ -4290,7 +4246,6 @@
 // Ensure that top level parsing of the class has been done.
 ErrorPtr Class::EnsureIsFinalized(Thread* thread) const {
   ASSERT(!IsNull());
-  // Finalized classes have already been parsed.
   if (is_finalized()) {
     return Error::null();
   }
@@ -4320,7 +4275,6 @@
 // this class is ready to be allocated.
 ErrorPtr Class::EnsureIsAllocateFinalized(Thread* thread) const {
   ASSERT(!IsNull());
-  // Finalized classes have already been parsed.
   if (is_allocate_finalized()) {
     return Error::null();
   }
@@ -4328,6 +4282,10 @@
     Compiler::AbortBackgroundCompilation(
         DeoptId::kNone, "Class allocate finalization while compiling");
   }
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+  if (is_allocate_finalized()) {
+    return Error::null();
+  }
   ASSERT(thread->IsMutatorThread());
   ASSERT(thread != NULL);
   Error& error = Error::Handle(thread->zone(), EnsureIsFinalized(thread));
@@ -4338,6 +4296,10 @@
       UNREACHABLE();
     }
   }
+  // May be allocate-finalized recursively during EnsureIsFinalized.
+  if (is_allocate_finalized()) {
+    return Error::null();
+  }
   error ^= ClassFinalizer::AllocateFinalizeClass(*this);
   return error.raw();
 }
@@ -4397,8 +4359,9 @@
     return false;
   }
 
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
+  auto thread = Thread::Current();
+  auto isolate_group = thread->isolate_group();
+  auto zone = thread->zone();
   Field& field = Field::Handle(zone);
   Smi& value = Smi::Handle(zone);
   String& field_name = String::Handle(zone);
@@ -4436,7 +4399,7 @@
                        /* is_late = */ false, *this, field_type,
                        TokenPosition::kMinSource, TokenPosition::kMinSource);
     value = Smi::New(cid_fields[i].cid);
-    field.SetStaticValue(value, true);
+    isolate_group->RegisterStaticField(field, value);
     AddField(field);
   }
 
@@ -4669,11 +4632,11 @@
 }
 
 void Class::set_name(const String& value) const {
-  ASSERT(raw_ptr()->name_ == String::null());
+  ASSERT(raw_ptr()->name() == String::null());
   ASSERT(value.IsSymbol());
-  StorePointer(&raw_ptr()->name_, value.raw());
+  raw_ptr()->set_name(value.raw());
 #if !defined(PRODUCT)
-  if (raw_ptr()->user_name_ == String::null()) {
+  if (raw_ptr()->user_name() == String::null()) {
     // TODO(johnmccutchan): Eagerly set user name for VM isolate classes,
     // lazily set user name for the other classes.
     // Generate and set user_name.
@@ -4686,7 +4649,7 @@
 
 #if !defined(PRODUCT)
 void Class::set_user_name(const String& value) const {
-  StorePointer(&raw_ptr()->user_name_, value.raw());
+  raw_ptr()->set_user_name(value.raw());
 }
 #endif  // !defined(PRODUCT)
 
@@ -4768,8 +4731,6 @@
       return Symbols::ClosureData().ToCString();
     case kSignatureDataCid:
       return Symbols::SignatureData().ToCString();
-    case kRedirectionDataCid:
-      return Symbols::RedirectionData().ToCString();
     case kFfiTrampolineDataCid:
       return Symbols::FfiTrampolineData().ToCString();
     case kFieldCid:
@@ -4851,7 +4812,7 @@
 }
 
 void Class::set_script(const Script& value) const {
-  StorePointer(&raw_ptr()->script_, value.raw());
+  raw_ptr()->set_script(value.raw());
 }
 
 void Class::set_token_pos(TokenPosition token_pos) const {
@@ -4942,7 +4903,7 @@
 
 void Class::set_interfaces(const Array& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->interfaces_, value.raw());
+  raw_ptr()->set_interfaces(value.raw());
 }
 
 void Class::AddDirectImplementor(const Class& implementor,
@@ -4951,10 +4912,10 @@
   ASSERT(is_implemented());
   ASSERT(!implementor.IsNull());
   GrowableObjectArray& direct_implementors =
-      GrowableObjectArray::Handle(raw_ptr()->direct_implementors_);
+      GrowableObjectArray::Handle(raw_ptr()->direct_implementors());
   if (direct_implementors.IsNull()) {
     direct_implementors = GrowableObjectArray::New(4, Heap::kOld);
-    StorePointer(&raw_ptr()->direct_implementors_, direct_implementors.raw());
+    raw_ptr()->set_direct_implementors(direct_implementors.raw());
   }
 #if defined(DEBUG)
   // Verify that the same class is not added twice.
@@ -4973,7 +4934,7 @@
 
 void Class::ClearDirectImplementors() const {
   ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
-  StorePointer(&raw_ptr()->direct_implementors_, GrowableObjectArray::null());
+  raw_ptr()->set_direct_implementors(GrowableObjectArray::null());
 }
 
 void Class::AddDirectSubclass(const Class& subclass) const {
@@ -4983,10 +4944,10 @@
   // Do not keep track of the direct subclasses of class Object.
   ASSERT(!IsObjectClass());
   GrowableObjectArray& direct_subclasses =
-      GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_);
+      GrowableObjectArray::Handle(raw_ptr()->direct_subclasses());
   if (direct_subclasses.IsNull()) {
     direct_subclasses = GrowableObjectArray::New(4, Heap::kOld);
-    StorePointer(&raw_ptr()->direct_subclasses_, direct_subclasses.raw());
+    raw_ptr()->set_direct_subclasses(direct_subclasses.raw());
   }
 #if defined(DEBUG)
   // Verify that the same class is not added twice.
@@ -4999,15 +4960,15 @@
 
 void Class::ClearDirectSubclasses() const {
   ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
-  StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null());
+  raw_ptr()->set_direct_subclasses(GrowableObjectArray::null());
 }
 
 ArrayPtr Class::constants() const {
-  return raw_ptr()->constants_;
+  return raw_ptr()->constants();
 }
 
 void Class::set_constants(const Array& value) const {
-  StorePointer(&raw_ptr()->constants_, value.raw());
+  raw_ptr()->set_constants(value.raw());
 }
 
 void Class::set_declaration_type(const Type& value) const {
@@ -5020,7 +4981,7 @@
   // The exception is DeclarationType of Null which is kNullable.
   ASSERT(value.type_class_id() != kNullCid || value.IsNullable());
   ASSERT(value.type_class_id() == kNullCid || value.IsNonNullable());
-  StorePointer(&raw_ptr()->declaration_type_, value.raw());
+  raw_ptr()->set_declaration_type(value.raw());
 }
 
 TypePtr Class::DeclarationType() const {
@@ -5053,8 +5014,8 @@
   // Never clear the stub as it may still be a target, but will be GC-d if
   // not referenced.
   ASSERT(!value.IsNull());
-  ASSERT(raw_ptr()->allocation_stub_ == Code::null());
-  StorePointer(&raw_ptr()->allocation_stub_, value.raw());
+  ASSERT(raw_ptr()->allocation_stub() == Code::null());
+  raw_ptr()->set_allocation_stub(value.raw());
 }
 
 void Class::DisableAllocationStub() const {
@@ -5066,7 +5027,7 @@
   // Change the stub so that the next caller will regenerate the stub.
   existing_stub.DisableStubCode();
   // Disassociate the existing stub from class.
-  StorePointer(&raw_ptr()->allocation_stub_, Code::null());
+  raw_ptr()->set_allocation_stub(Code::null());
 }
 
 bool Class::IsDartFunctionClass() const {
@@ -5105,7 +5066,7 @@
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
   // Nullability of left and right hand sides is verified in strong mode only.
-  const bool verified_nullability = !isolate->null_safety() ||
+  const bool verified_nullability = !isolate->use_strict_null_safety_checks() ||
                                     nullability != Nullability::kNullable ||
                                     !other.IsNonNullable();
 
@@ -5381,7 +5342,7 @@
     // If we want to increase resolver speed by avoiding the need for read lock,
     // we could make change this hash table to be lock-free for the reader.
     const Array& hash_table =
-        Array::Handle(thread->zone(), raw_ptr()->functions_hash_table_);
+        Array::Handle(thread->zone(), raw_ptr()->functions_hash_table());
     if (!hash_table.IsNull()) {
       ClassFunctionsSet set(hash_table.raw());
       REUSABLE_STRING_HANDLESCOPE(thread);
@@ -5890,7 +5851,7 @@
 }
 
 void TypeArguments::set_nullability(intptr_t value) const {
-  StoreSmi(&raw_ptr()->nullability_, Smi::New(value));
+  raw_ptr()->set_nullability(Smi::New(value));
 }
 
 intptr_t TypeArguments::HashForRange(intptr_t from_index, intptr_t len) const {
@@ -6014,7 +5975,7 @@
   if (IsNull()) {
     return buffer->AddString("null");
   }
-  buffer->Printf("(H%" Px ")", Smi::Value(raw_ptr()->hash_));
+  buffer->Printf("(H%" Px ")", Smi::Value(raw_ptr()->hash()));
   auto& type_at = AbstractType::Handle();
   for (intptr_t i = 0; i < Length(); i++) {
     type_at = TypeAt(i);
@@ -6115,7 +6076,7 @@
 ArrayPtr TypeArguments::instantiations() const {
   // We rely on the fact that any loads from the array are dependent loads and
   // avoid the load-acquire barrier here.
-  return raw_ptr()->instantiations_;
+  return raw_ptr()->instantiations();
 }
 
 void TypeArguments::set_instantiations(const Array& value) const {
@@ -6123,8 +6084,7 @@
   // when releasing the pointer to the array pointer.
   // => We have to use store-release here.
   ASSERT(!value.IsNull());
-  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->instantiations_,
-                                                    value.raw());
+  raw_ptr()->set_instantiations<std::memory_order_release>(value.raw());
 }
 
 bool TypeArguments::HasCount(intptr_t count) const {
@@ -6138,19 +6098,20 @@
   if (IsNull()) {
     return 0;
   }
-  return Smi::Value(raw_ptr()->length_);
+  return Smi::Value(raw_ptr()->length());
 }
 
 intptr_t TypeArguments::nullability() const {
   if (IsNull()) {
     return 0;
   }
-  return Smi::Value(raw_ptr()->nullability_);
+  return Smi::Value(raw_ptr()->nullability());
 }
 
 AbstractTypePtr TypeArguments::TypeAt(intptr_t index) const {
   ASSERT(!IsNull());
-  return *TypeAddr(index);
+  ASSERT((index >= 0) && (index < Length()));
+  return raw_ptr()->element(index);
 }
 
 AbstractTypePtr TypeArguments::TypeAtNullSafe(intptr_t index) const {
@@ -6164,7 +6125,8 @@
 
 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const {
   ASSERT(!IsCanonical());
-  StorePointer(TypeAddr(index), value.raw());
+  ASSERT((index >= 0) && (index < Length()));
+  return raw_ptr()->set_element(index, value.raw());
 }
 
 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index,
@@ -6514,16 +6476,11 @@
   return result.raw();
 }
 
-AbstractTypePtr const* TypeArguments::TypeAddr(intptr_t index) const {
-  ASSERT((index >= 0) && (index < Length()));
-  return &raw_ptr()->types()[index];
-}
-
 void TypeArguments::SetLength(intptr_t value) const {
   ASSERT(!IsCanonical());
   // This is only safe because we create a new Smi, which does not cause
   // heap allocation.
-  StoreSmi(&raw_ptr()->length_, Smi::New(value));
+  raw_ptr()->set_length(Smi::New(value));
 }
 
 TypeArgumentsPtr TypeArguments::Canonicalize(Thread* thread,
@@ -6654,19 +6611,19 @@
 }
 
 void PatchClass::set_patched_class(const Class& value) const {
-  StorePointer(&raw_ptr()->patched_class_, value.raw());
+  raw_ptr()->set_patched_class(value.raw());
 }
 
 void PatchClass::set_origin_class(const Class& value) const {
-  StorePointer(&raw_ptr()->origin_class_, value.raw());
+  raw_ptr()->set_origin_class(value.raw());
 }
 
 void PatchClass::set_script(const Script& value) const {
-  StorePointer(&raw_ptr()->script_, value.raw());
+  raw_ptr()->set_script(value.raw());
 }
 
 void PatchClass::set_library_kernel_data(const ExternalTypedData& data) const {
-  StorePointer(&raw_ptr()->library_kernel_data_, data.raw());
+  raw_ptr()->set_library_kernel_data(data.raw());
 }
 
 intptr_t Function::Hash() const {
@@ -6698,7 +6655,7 @@
 }
 
 void Function::SetInstructionsSafe(const Code& value) const {
-  StorePointer(&raw_ptr()->code_, value.raw());
+  raw_ptr()->set_code(value.raw());
   StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
   StoreNonPointer(&raw_ptr()->unchecked_entry_point_,
                   value.UncheckedEntryPoint());
@@ -6715,14 +6672,14 @@
 
 bool Function::HasCode() const {
   NoSafepointScope no_safepoint;
-  ASSERT(raw_ptr()->code_ != Code::null());
-  return raw_ptr()->code_ != StubCode::LazyCompile().raw();
+  ASSERT(raw_ptr()->code() != Code::null());
+  return raw_ptr()->code() != StubCode::LazyCompile().raw();
 }
 
 bool Function::HasCode(FunctionPtr function) {
   NoSafepointScope no_safepoint;
-  ASSERT(function->ptr()->code_ != Code::null());
-  return function->ptr()->code_ != StubCode::LazyCompile().raw();
+  ASSERT(function->ptr()->code() != Code::null());
+  return function->ptr()->code() != StubCode::LazyCompile().raw();
 }
 
 void Function::ClearCode() const {
@@ -6731,7 +6688,7 @@
 #else
   ASSERT(Thread::Current()->IsMutatorThread());
 
-  StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
+  raw_ptr()->set_unoptimized_code(Code::null());
 
   SetInstructions(StubCode::LazyCompile());
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
@@ -6813,13 +6770,13 @@
 #else
   DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(value.IsNull() || !value.is_optimized());
-  StorePointer(&raw_ptr()->unoptimized_code_, value.raw());
+  raw_ptr()->set_unoptimized_code(value.raw());
 #endif
 }
 
 ContextScopePtr Function::context_scope() const {
   if (IsClosureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
+    const Object& obj = Object::Handle(raw_ptr()->data());
     ASSERT(!obj.IsNull());
     return ClosureData::Cast(obj).context_scope();
   }
@@ -6828,7 +6785,7 @@
 
 void Function::set_context_scope(const ContextScope& value) const {
   if (IsClosureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
+    const Object& obj = Object::Handle(raw_ptr()->data());
     ASSERT(!obj.IsNull());
     ClosureData::Cast(obj).set_context_scope(value);
     return;
@@ -6838,7 +6795,7 @@
 
 InstancePtr Function::implicit_static_closure() const {
   if (IsImplicitStaticClosureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
+    const Object& obj = Object::Handle(raw_ptr()->data());
     ASSERT(!obj.IsNull());
     return ClosureData::Cast(obj).implicit_static_closure();
   }
@@ -6847,7 +6804,7 @@
 
 void Function::set_implicit_static_closure(const Instance& closure) const {
   if (IsImplicitStaticClosureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
+    const Object& obj = Object::Handle(raw_ptr()->data());
     ASSERT(!obj.IsNull());
     ClosureData::Cast(obj).set_implicit_static_closure(closure);
     return;
@@ -6856,7 +6813,7 @@
 }
 
 ScriptPtr Function::eval_script() const {
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   if (obj.IsScript()) {
     return Script::Cast(obj).raw();
   }
@@ -6865,27 +6822,27 @@
 
 void Function::set_eval_script(const Script& script) const {
   ASSERT(token_pos() == TokenPosition::kMinSource);
-  ASSERT(raw_ptr()->data_ == Object::null());
+  ASSERT(raw_ptr()->data() == Object::null());
   set_data(script);
 }
 
 FunctionPtr Function::extracted_method_closure() const {
   ASSERT(kind() == FunctionLayout::kMethodExtractor);
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(obj.IsFunction());
   return Function::Cast(obj).raw();
 }
 
 void Function::set_extracted_method_closure(const Function& value) const {
   ASSERT(kind() == FunctionLayout::kMethodExtractor);
-  ASSERT(raw_ptr()->data_ == Object::null());
+  ASSERT(raw_ptr()->data() == Object::null());
   set_data(value);
 }
 
 ArrayPtr Function::saved_args_desc() const {
   ASSERT(kind() == FunctionLayout::kNoSuchMethodDispatcher ||
          kind() == FunctionLayout::kInvokeFieldDispatcher);
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(obj.IsArray());
   return Array::Cast(obj).raw();
 }
@@ -6893,7 +6850,7 @@
 void Function::set_saved_args_desc(const Array& value) const {
   ASSERT(kind() == FunctionLayout::kNoSuchMethodDispatcher ||
          kind() == FunctionLayout::kInvokeFieldDispatcher);
-  ASSERT(raw_ptr()->data_ == Object::null());
+  ASSERT(raw_ptr()->data() == Object::null());
   set_data(value);
 }
 
@@ -6902,7 +6859,7 @@
          kind() == FunctionLayout::kImplicitSetter ||
          kind() == FunctionLayout::kImplicitStaticGetter ||
          kind() == FunctionLayout::kFieldInitializer);
-  return Field::RawCast(raw_ptr()->data_);
+  return Field::RawCast(raw_ptr()->data());
 }
 
 void Function::set_accessor_field(const Field& value) const {
@@ -6911,13 +6868,14 @@
          kind() == FunctionLayout::kImplicitStaticGetter ||
          kind() == FunctionLayout::kFieldInitializer);
   // Top level classes may be finalized multiple times.
-  ASSERT(raw_ptr()->data_ == Object::null() || raw_ptr()->data_ == value.raw());
+  ASSERT(raw_ptr()->data() == Object::null() ||
+         raw_ptr()->data() == value.raw());
   set_data(value);
 }
 
 FunctionPtr Function::parent_function() const {
   if (IsClosureFunction() || IsSignatureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
+    const Object& obj = Object::Handle(raw_ptr()->data());
     ASSERT(!obj.IsNull());
     if (IsClosureFunction()) {
       return ClosureData::Cast(obj).parent_function();
@@ -6929,7 +6887,7 @@
 }
 
 void Function::set_parent_function(const Function& value) const {
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   if (IsClosureFunction()) {
     ClosureData::Cast(obj).set_parent_function(value);
@@ -7013,7 +6971,7 @@
     UNREACHABLE();
   }
   const auto& closure_data =
-      ClosureData::Handle(ClosureData::RawCast(raw_ptr()->data_));
+      ClosureData::Handle(ClosureData::RawCast(raw_ptr()->data()));
   ASSERT(!closure_data.IsNull());
   if (kind_out != nullptr) {
     *kind_out = DefaultTypeArgumentsKindField::decode(
@@ -7027,15 +6985,15 @@
     UNREACHABLE();
   }
   const auto& closure_data =
-      ClosureData::Handle(ClosureData::RawCast(raw_ptr()->data_));
+      ClosureData::Handle(ClosureData::RawCast(raw_ptr()->data()));
   ASSERT(!closure_data.IsNull());
+  intptr_t updated_info = closure_data.default_type_arguments_info();
   auto kind = DefaultTypeArgumentsKindFor(value);
   ASSERT(kind != DefaultTypeArgumentsKind::kInvalid);
-  const intptr_t num_parent_type_params = NumParentTypeParameters();
-  const intptr_t default_type_args_info =
-      DefaultTypeArgumentsKindField::encode(kind) |
-      NumParentTypeParametersField::encode(num_parent_type_params);
-  closure_data.set_default_type_arguments_info(default_type_args_info);
+  updated_info = DefaultTypeArgumentsKindField::update(kind, updated_info);
+  updated_info = NumParentTypeParametersField::update(NumParentTypeParameters(),
+                                                      updated_info);
+  closure_data.set_default_type_arguments_info(updated_info);
   // We could just store null for the ksharesFunction/kSharesInstantiator cases,
   // assuming all clients retrieve the DefaultTypeArgumentsKind to distinguish.
   closure_data.set_default_type_arguments(value);
@@ -7111,7 +7069,7 @@
       IsDispatcherOrImplicitAccessor() || IsFieldInitializer()) {
     return Function::null();
   }
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray());
   if (obj.IsNull() || obj.IsScript()) {
     return Function::null();
@@ -7127,7 +7085,7 @@
 
 void Function::set_implicit_closure_function(const Function& value) const {
   ASSERT(!IsClosureFunction() && !IsSignatureFunction());
-  const Object& old_data = Object::Handle(raw_ptr()->data_);
+  const Object& old_data = Object::Handle(raw_ptr()->data());
   if (is_native()) {
     ASSERT(old_data.IsArray());
     ASSERT((Array::Cast(old_data).At(1) == Object::null()) || value.IsNull());
@@ -7145,7 +7103,7 @@
 }
 
 TypePtr Function::ExistingSignatureType() const {
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   if (IsSignatureFunction()) {
     return SignatureData::Cast(obj).signature_type();
@@ -7159,14 +7117,14 @@
 
 void Function::SetFfiCSignature(const Function& sig) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_c_signature(sig);
 }
 
 FunctionPtr Function::FfiCSignature() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).c_signature();
 }
@@ -7189,42 +7147,42 @@
 
 int32_t Function::FfiCallbackId() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).callback_id();
 }
 
 void Function::SetFfiCallbackId(int32_t value) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_callback_id(value);
 }
 
 FunctionPtr Function::FfiCallbackTarget() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).callback_target();
 }
 
 void Function::SetFfiCallbackTarget(const Function& target) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_callback_target(target);
 }
 
 InstancePtr Function::FfiCallbackExceptionalReturn() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).callback_exceptional_return();
 }
 
 void Function::SetFfiCallbackExceptionalReturn(const Instance& value) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_callback_exceptional_return(value);
 }
@@ -7272,7 +7230,7 @@
 }
 
 void Function::SetSignatureType(const Type& value) const {
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(!obj.IsNull());
   if (IsSignatureFunction()) {
     SignatureData::Cast(obj).set_signature_type(value);
@@ -7285,74 +7243,14 @@
   }
 }
 
-bool Function::IsRedirectingFactory() const {
-  if (!IsFactory() || !is_redirecting()) {
-    return false;
-  }
-  ASSERT(!IsClosureFunction());  // A factory cannot also be a closure.
-  return true;
-}
-
-TypePtr Function::RedirectionType() const {
-  ASSERT(IsRedirectingFactory());
-  ASSERT(!is_native());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
-  ASSERT(!obj.IsNull());
-  return RedirectionData::Cast(obj).type();
-}
-
 const char* Function::KindToCString(FunctionLayout::Kind kind) {
   return FunctionLayout::KindToCString(kind);
 }
 
-void Function::SetRedirectionType(const Type& type) const {
-  ASSERT(IsFactory());
-  Object& obj = Object::Handle(raw_ptr()->data_);
-  if (obj.IsNull()) {
-    obj = RedirectionData::New();
-    set_data(obj);
-  }
-  RedirectionData::Cast(obj).set_type(type);
-}
-
-StringPtr Function::RedirectionIdentifier() const {
-  ASSERT(IsRedirectingFactory());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
-  ASSERT(!obj.IsNull());
-  return RedirectionData::Cast(obj).identifier();
-}
-
-void Function::SetRedirectionIdentifier(const String& identifier) const {
-  ASSERT(IsFactory());
-  Object& obj = Object::Handle(raw_ptr()->data_);
-  if (obj.IsNull()) {
-    obj = RedirectionData::New();
-    set_data(obj);
-  }
-  RedirectionData::Cast(obj).set_identifier(identifier);
-}
-
-FunctionPtr Function::RedirectionTarget() const {
-  ASSERT(IsRedirectingFactory());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
-  ASSERT(!obj.IsNull());
-  return RedirectionData::Cast(obj).target();
-}
-
-void Function::SetRedirectionTarget(const Function& target) const {
-  ASSERT(IsFactory());
-  Object& obj = Object::Handle(raw_ptr()->data_);
-  if (obj.IsNull()) {
-    obj = RedirectionData::New();
-    set_data(obj);
-  }
-  RedirectionData::Cast(obj).set_target(target);
-}
-
 FunctionPtr Function::ForwardingTarget() const {
   ASSERT(kind() == FunctionLayout::kDynamicInvocationForwarder);
   Array& checks = Array::Handle();
-  checks ^= raw_ptr()->data_;
+  checks ^= raw_ptr()->data();
   return Function::RawCast(checks.At(0));
 }
 
@@ -7376,7 +7274,6 @@
 //   field initializer:       Field
 //   noSuchMethod dispatcher: Array arguments descriptor
 //   invoke-field dispatcher: Array arguments descriptor
-//   redirecting constructor: RedirectionData
 //   closure function:        ClosureData
 //   irregexp function:       Array[0] = RegExp
 //                            Array[1] = Smi string specialization cid
@@ -7387,7 +7284,7 @@
 //   dyn inv forwarder:       Array[0] = Function target
 //                            Array[1] = TypeArguments default type args
 void Function::set_data(const Object& value) const {
-  StorePointer(&raw_ptr()->data_, value.raw());
+  raw_ptr()->set_data(value.raw());
 }
 
 bool Function::IsInFactoryScope() const {
@@ -7403,17 +7300,17 @@
 
 void Function::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
-  StorePointer(&raw_ptr()->name_, value.raw());
+  raw_ptr()->set_name(value.raw());
 }
 
 void Function::set_owner(const Object& value) const {
   ASSERT(!value.IsNull() || IsSignatureFunction());
-  StorePointer(&raw_ptr()->owner_, value.raw());
+  raw_ptr()->set_owner(value.raw());
 }
 
 RegExpPtr Function::regexp() const {
   ASSERT(kind() == FunctionLayout::kIrregexpFunction);
-  const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
+  const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data()));
   return RegExp::RawCast(pair.At(0));
 }
 
@@ -7423,13 +7320,13 @@
 
 intptr_t Function::string_specialization_cid() const {
   ASSERT(kind() == FunctionLayout::kIrregexpFunction);
-  const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
+  const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data()));
   return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1))));
 }
 
 bool Function::is_sticky_specialization() const {
   ASSERT(kind() == FunctionLayout::kIrregexpFunction);
-  const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_));
+  const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data()));
   return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1))));
 }
 
@@ -7438,7 +7335,7 @@
                              bool sticky) const {
   ASSERT(kind() == FunctionLayout::kIrregexpFunction);
   ASSERT(IsStringClassId(string_specialization_cid));
-  ASSERT(raw_ptr()->data_ == Object::null());
+  ASSERT(raw_ptr()->data() == Object::null());
   const Array& pair = Array::Handle(Array::New(2, Heap::kOld));
   pair.SetAt(0, regexp);
   pair.SetAt(1, Smi::Handle(Smi::New(StickySpecialization::encode(sticky) |
@@ -7449,7 +7346,7 @@
 
 StringPtr Function::native_name() const {
   ASSERT(is_native());
-  const Object& obj = Object::Handle(raw_ptr()->data_);
+  const Object& obj = Object::Handle(raw_ptr()->data());
   ASSERT(obj.IsArray());
   return String::RawCast(Array::Cast(obj).At(0));
 }
@@ -7466,7 +7363,7 @@
   // closure function.
   //
   // We therefore handle both cases.
-  const Object& old_data = Object::Handle(zone, raw_ptr()->data_);
+  const Object& old_data = Object::Handle(zone, raw_ptr()->data());
   ASSERT(old_data.IsNull() ||
          (old_data.IsFunction() &&
           Function::Handle(zone, Function::RawCast(old_data.raw()))
@@ -7480,11 +7377,11 @@
 
 void Function::set_result_type(const AbstractType& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->result_type_, value.raw());
+  raw_ptr()->set_result_type(value.raw());
 }
 
 AbstractTypePtr Function::ParameterTypeAt(intptr_t index) const {
-  const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
+  const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types());
   return AbstractType::RawCast(parameter_types.At(index));
 }
 
@@ -7493,27 +7390,27 @@
   ASSERT(!value.IsNull());
   // Method extractor parameters are shared and are in the VM heap.
   ASSERT(kind() != FunctionLayout::kMethodExtractor);
-  const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
+  const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types());
   parameter_types.SetAt(index, value);
 }
 
 void Function::set_parameter_types(const Array& value) const {
-  StorePointer(&raw_ptr()->parameter_types_, value.raw());
+  raw_ptr()->set_parameter_types(value.raw());
 }
 
 StringPtr Function::ParameterNameAt(intptr_t index) const {
-  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
+  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names());
   return String::RawCast(parameter_names.At(index));
 }
 
 void Function::SetParameterNameAt(intptr_t index, const String& value) const {
   ASSERT(!value.IsNull() && value.IsSymbol());
-  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
+  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names());
   parameter_names.SetAt(index, value);
 }
 
 void Function::set_parameter_names(const Array& value) const {
-  StorePointer(&raw_ptr()->parameter_names_, value.raw());
+  raw_ptr()->set_parameter_names(value.raw());
 }
 
 void Function::CreateNameArrayIncludingFlags(Heap::Space space) const {
@@ -7558,7 +7455,7 @@
   }
   intptr_t flag_mask;
   const intptr_t flag_index = GetRequiredFlagIndex(index, &flag_mask);
-  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
+  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names());
   if (flag_index >= parameter_names.Length()) {
     return false;
   }
@@ -7570,7 +7467,7 @@
 void Function::SetIsRequiredAt(intptr_t index) const {
   intptr_t flag_mask;
   const intptr_t flag_index = GetRequiredFlagIndex(index, &flag_mask);
-  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
+  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names());
   ASSERT(flag_index < parameter_names.Length());
   const intptr_t flags =
       Smi::Value(Smi::RawCast(parameter_names.At(flag_index)));
@@ -7578,7 +7475,7 @@
 }
 
 void Function::TruncateUnusedParameterFlags() const {
-  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_);
+  const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names());
   const intptr_t num_params = NumParameters();
   if (parameter_names.Length() == num_params) {
     // No flag slots to truncate.
@@ -7595,7 +7492,7 @@
 }
 
 void Function::set_type_parameters(const TypeArguments& value) const {
-  StorePointer(&raw_ptr()->type_parameters_, value.raw());
+  raw_ptr()->set_type_parameters(value.raw());
 }
 
 intptr_t Function::NumTypeParameters(Thread* thread) const {
@@ -7937,7 +7834,7 @@
       return false;
     }
   }
-  if (isolate->null_safety()) {
+  if (isolate->use_strict_null_safety_checks()) {
     // Verify that all required named parameters are filled.
     for (intptr_t j = num_parameters - NumOptionalNamedParameters();
          j < num_parameters; j++) {
@@ -8165,8 +8062,8 @@
   const intptr_t arg_offset = args_desc.FirstArgIndex();
   // Only check explicit arguments.
   const intptr_t arg_start = arg_offset + NumImplicitParameters();
-  const intptr_t num_positional_args = args_desc.PositionalCount();
-  for (intptr_t arg_index = arg_start; arg_index < num_positional_args;
+  const intptr_t end_positional_args = arg_offset + args_desc.PositionalCount();
+  for (intptr_t arg_index = arg_start; arg_index < end_positional_args;
        ++arg_index) {
     argument ^= args.At(arg_index);
     // Adjust for type arguments when they're present.
@@ -8196,7 +8093,7 @@
        named_index++) {
     argument_name = args_desc.NameAt(named_index);
     ASSERT(argument_name.IsSymbol());
-    argument ^= args.At(args_desc.PositionAt(named_index));
+    argument ^= args.At(arg_offset + args_desc.PositionAt(named_index));
 
     // Try to find the named parameter that matches the provided argument.
     // Even when annotated with @required, named parameters are still stored
@@ -8326,6 +8223,7 @@
   // Note that parent pointers in newly instantiated signatures still points to
   // the original uninstantiated parent signatures. That is not a problem.
   const Function& parent = Function::Handle(zone, parent_function());
+  const intptr_t num_parent_type_params = NumParentTypeParameters();
 
   // See the comment on kCurrentAndEnclosingFree to understand why we don't
   // adjust 'num_free_fun_type_params' downward in this case.
@@ -8345,7 +8243,6 @@
     if (IsGeneric() || HasGenericParent()) {
       // We only consider the function type parameters declared by the parents
       // of this signature function as free.
-      const int num_parent_type_params = NumParentTypeParameters();
       if (num_parent_type_params < num_free_fun_type_params) {
         num_free_fun_type_params = num_parent_type_params;
       }
@@ -8354,6 +8251,8 @@
 
   Function& sig = Function::Handle(Function::NewSignatureFunction(
       owner, parent, TokenPosition::kNoSource, space));
+  const intptr_t offset =
+      sig.NumParentTypeParameters() - num_parent_type_params;
   AbstractType& type = AbstractType::Handle(zone);
 
   // Copy the type parameters and instantiate their bounds (if necessary).
@@ -8363,10 +8262,11 @@
     if (!type_params.IsNull()) {
       TypeArguments& instantiated_type_params = TypeArguments::Handle(zone);
       TypeParameter& type_param = TypeParameter::Handle(zone);
-      Class& cls = Class::Handle(zone);
+      const Class& null_class = Class::Handle(zone);
       String& param_name = String::Handle(zone);
       for (intptr_t i = 0; i < type_params.Length(); ++i) {
         type_param ^= type_params.TypeAt(i);
+        ASSERT(type_param.index() == num_parent_type_params + i);
         type = type_param.bound();
         if (!type.IsInstantiated(kAny, num_free_fun_type_params)) {
           type = type.InstantiateFrom(instantiator_type_arguments,
@@ -8377,12 +8277,14 @@
           if (type.IsNull()) {
             return Function::null();
           }
-          cls = type_param.parameterized_class();
+        }
+        if (offset > 0 || type.raw() != type_param.bound()) {
           param_name = type_param.name();
+          ASSERT(type_param.IsFunctionTypeParameter());
           ASSERT(type_param.IsFinalized());
           ASSERT(type_param.IsCanonical());
           type_param = TypeParameter::New(
-              cls, sig, type_param.index(), param_name, type,
+              null_class, sig, type_param.index() + offset, param_name, type,
               type_param.IsGenericCovariantImpl(), type_param.nullability(),
               type_param.token_pos());
           type_param.SetIsFinalized();
@@ -8581,7 +8483,7 @@
       return false;
     }
   }
-  if (isolate->null_safety()) {
+  if (isolate->use_strict_null_safety_checks()) {
     // Check that for each required named parameter in this function, there's a
     // corresponding required named parameter in the other function.
     String& param_name = other_param_name;
@@ -8659,7 +8561,6 @@
   result.set_is_visible(true);      // Will be computed later.
   result.set_is_debuggable(true);   // Will be computed later.
   result.set_is_intrinsic(false);
-  result.set_is_redirecting(false);
   result.set_is_generated_body(false);
   result.set_has_pragma(false);
   result.set_is_polymorphic_target(false);
@@ -8814,15 +8715,23 @@
   if (implicit_closure_function() != Function::null()) {
     return implicit_closure_function();
   }
+
 #if defined(DART_PRECOMPILED_RUNTIME)
   // In AOT mode all implicit closures are pre-created.
   FATAL("Cannot create implicit closure in AOT!");
   return Function::null();
 #else
   ASSERT(!IsSignatureFunction() && !IsClosureFunction());
+
   Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+
+  if (implicit_closure_function() != Function::null()) {
+    return implicit_closure_function();
+  }
+
   // Create closure function.
+  Zone* zone = thread->zone();
   const String& closure_name = String::Handle(zone, name());
   const Function& closure_function = Function::Handle(
       zone, NewImplicitClosureFunction(closure_name, *this, token_pos()));
@@ -8838,6 +8747,9 @@
 
   // Set closure function's type parameters.
   auto& type_args_handle = TypeArguments::Handle(zone, type_parameters());
+  // This function cannot be local, therefore it has no generic parent.
+  // Its implicit closure function therefore has no generic parent function
+  // either. That is why it is safe to simply copy the type parameters.
   closure_function.set_type_parameters(type_args_handle);
   closure_function.UpdateCachedDefaultTypeArguments(thread);
 
@@ -8999,15 +8911,24 @@
 
 InstancePtr Function::ImplicitStaticClosure() const {
   ASSERT(IsImplicitStaticClosureFunction());
-  if (implicit_static_closure() == Instance::null()) {
-    Zone* zone = Thread::Current()->zone();
-    const Context& context = Context::Handle(zone);
-    Instance& closure =
-        Instance::Handle(zone, Closure::New(Object::null_type_arguments(),
-                                            Object::null_type_arguments(),
-                                            *this, context, Heap::kOld));
-    set_implicit_static_closure(closure);
+  if (implicit_static_closure() != Instance::null()) {
+    return implicit_static_closure();
   }
+
+  auto thread = Thread::Current();
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+
+  if (implicit_static_closure() != Instance::null()) {
+    return implicit_static_closure();
+  }
+
+  Zone* zone = thread->zone();
+  const auto& null_context = Context::Handle(zone);
+  const auto& closure =
+      Instance::Handle(zone, Closure::New(Object::null_type_arguments(),
+                                          Object::null_type_arguments(), *this,
+                                          null_context, Heap::kOld));
+  set_implicit_static_closure(closure);
   return implicit_static_closure();
 }
 
@@ -9139,27 +9060,27 @@
 }
 
 ClassPtr Function::Owner() const {
-  if (raw_ptr()->owner_ == Object::null()) {
+  if (raw_ptr()->owner() == Object::null()) {
     ASSERT(IsSignatureFunction());
     return Class::null();
   }
-  if (raw_ptr()->owner_->IsClass()) {
-    return Class::RawCast(raw_ptr()->owner_);
+  if (raw_ptr()->owner()->IsClass()) {
+    return Class::RawCast(raw_ptr()->owner());
   }
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  const Object& obj = Object::Handle(raw_ptr()->owner());
   ASSERT(obj.IsPatchClass());
   return PatchClass::Cast(obj).patched_class();
 }
 
 ClassPtr Function::origin() const {
-  if (raw_ptr()->owner_ == Object::null()) {
+  if (raw_ptr()->owner() == Object::null()) {
     ASSERT(IsSignatureFunction());
     return Class::null();
   }
-  if (raw_ptr()->owner_->IsClass()) {
-    return Class::RawCast(raw_ptr()->owner_);
+  if (raw_ptr()->owner()->IsClass()) {
+    return Class::RawCast(raw_ptr()->owner());
   }
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  const Object& obj = Object::Handle(raw_ptr()->owner());
   ASSERT(obj.IsPatchClass());
   return PatchClass::Cast(obj).origin_class();
 }
@@ -9193,7 +9114,7 @@
 ScriptPtr Function::script() const {
   // NOTE(turnidge): If you update this function, you probably want to
   // update Class::PatchFieldsAndFunctions() at the same time.
-  const Object& data = Object::Handle(raw_ptr()->data_);
+  const Object& data = Object::Handle(raw_ptr()->data());
   if (IsDynamicInvocationForwarder()) {
     const auto& forwarding_target = Function::Handle(ForwardingTarget());
     return forwarding_target.script();
@@ -9216,7 +9137,7 @@
       return script.raw();
     }
   }
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  const Object& obj = Object::Handle(raw_ptr()->owner());
   if (obj.IsPatchClass()) {
     return PatchClass::Cast(obj).script();
   }
@@ -9232,7 +9153,7 @@
 }
 
 ExternalTypedDataPtr Function::KernelData() const {
-  Object& data = Object::Handle(raw_ptr()->data_);
+  Object& data = Object::Handle(raw_ptr()->data());
   if (data.IsArray()) {
     Object& script = Object::Handle(Array::Cast(data).At(0));
     if (script.IsScript()) {
@@ -9245,7 +9166,7 @@
     return parent.KernelData();
   }
 
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  const Object& obj = Object::Handle(raw_ptr()->owner());
   if (obj.IsClass()) {
     Library& lib = Library::Handle(Class::Cast(obj).library());
     return lib.kernel_data();
@@ -9259,7 +9180,7 @@
       IsFfiTrampoline()) {
     return 0;
   }
-  Object& data = Object::Handle(raw_ptr()->data_);
+  Object& data = Object::Handle(raw_ptr()->data());
   if (data.IsArray()) {
     Object& script = Object::Handle(Array::Cast(data).At(0));
     if (script.IsScript()) {
@@ -9272,7 +9193,7 @@
     return parent.KernelDataProgramOffset();
   }
 
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  const Object& obj = Object::Handle(raw_ptr()->owner());
   if (obj.IsClass()) {
     Library& lib = Library::Handle(Class::Cast(obj).library());
     return lib.kernel_offset();
@@ -9563,13 +9484,11 @@
 }
 
 void Function::set_ic_data_array(const Array& value) const {
-  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->ic_data_array_,
-                                                    value.raw());
+  raw_ptr()->set_ic_data_array<std::memory_order_release>(value.raw());
 }
 
 ArrayPtr Function::ic_data_array() const {
-  return LoadPointer<ArrayPtr, std::memory_order_acquire>(
-      &raw_ptr()->ic_data_array_);
+  return raw_ptr()->ic_data_array<std::memory_order_acquire>();
 }
 
 void Function::ClearICDataArray() const {
@@ -9600,11 +9519,24 @@
   }
 }
 
-bool Function::CheckSourceFingerprint(int32_t fp) const {
+bool Function::CheckSourceFingerprint(int32_t fp, const char* kind) const {
 #if !defined(DEBUG)
   return true;  // Only check on debug.
 #endif
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // Check that the function is marked as recognized via the vm:recognized
+  // pragma. This is so that optimizations that change the signature will know
+  // not to touch it.
+  if (kind != nullptr && !MethodRecognizer::IsMarkedAsRecognized(*this, kind)) {
+    OS::PrintErr(
+        "Recognized method %s should be marked with: "
+        "@pragma(\"vm:recognized\", \"%s\")\n",
+        ToQualifiedCString(), kind);
+    return false;
+  }
+#endif
+
   if (Isolate::Current()->obfuscate() || FLAG_precompiled_mode ||
       (Dart::vm_snapshot_kind() != Snapshot::kNone)) {
     return true;  // The kernel structure has been altered, skip checking.
@@ -9707,6 +9639,11 @@
 }
 
 bool Function::PrologueNeedsArgumentsDescriptor() const {
+  // These functions have a saved compile-time arguments descriptor that is
+  // used in lieu of the runtime arguments descriptor in generated IL.
+  if (IsInvokeFieldDispatcher() || IsNoSuchMethodDispatcher()) {
+    return false;
+  }
   // The prologue of those functions need to examine the arg descriptor for
   // various purposes.
   return IsGeneric() || HasOptionalParameters();
@@ -9714,8 +9651,7 @@
 
 bool Function::MayHaveUncheckedEntryPoint() const {
   return FLAG_enable_multiple_entrypoints &&
-         (NeedsTypeArgumentTypeChecks() || NeedsArgumentTypeChecks() ||
-          IsImplicitClosureFunction());
+         (NeedsTypeArgumentTypeChecks() || NeedsArgumentTypeChecks());
 }
 
 const char* Function::ToCString() const {
@@ -9792,34 +9728,41 @@
 }
 
 void ClosureData::set_context_scope(const ContextScope& value) const {
-  StorePointer(&raw_ptr()->context_scope_, value.raw());
+  raw_ptr()->set_context_scope(value.raw());
 }
 
 void ClosureData::set_implicit_static_closure(const Instance& closure) const {
   ASSERT(!closure.IsNull());
-  ASSERT(raw_ptr()->closure_ == Instance::null());
-  StorePointer(&raw_ptr()->closure_, closure.raw());
+  ASSERT(raw_ptr()->closure() == Instance::null());
+  raw_ptr()->set_closure(closure.raw());
 }
 
 void ClosureData::set_parent_function(const Function& value) const {
-  StorePointer(&raw_ptr()->parent_function_, value.raw());
+  raw_ptr()->set_parent_function(value.raw());
 }
 
 void ClosureData::set_signature_type(const Type& value) const {
-  StorePointer(&raw_ptr()->signature_type_, value.raw());
+  raw_ptr()->set_signature_type(value.raw());
 }
 
 void ClosureData::set_default_type_arguments(const TypeArguments& value) const {
-  StorePointer(&raw_ptr()->default_type_arguments_, value.raw());
+  raw_ptr()->set_default_type_arguments(value.raw());
 }
 
 intptr_t ClosureData::default_type_arguments_info() const {
-  return Smi::Value(raw_ptr()->default_type_arguments_info_);
+  const SmiPtr value = raw_ptr()->default_type_arguments_info();
+  if (value == Smi::null()) {
+    static_assert(Function::DefaultTypeArgumentsKindField::decode(0) ==
+                      Function::DefaultTypeArgumentsKind::kInvalid,
+                  "Returning valid value for null Smi");
+    return 0;
+  }
+  return Smi::Value(raw_ptr()->default_type_arguments_info());
 }
 
 void ClosureData::set_default_type_arguments_info(intptr_t value) const {
   ASSERT(Smi::IsValid(value));
-  StorePointer(&raw_ptr()->default_type_arguments_info_, Smi::New(value));
+  raw_ptr()->set_default_type_arguments_info(Smi::New(value));
 }
 
 ClosureDataPtr ClosureData::New() {
@@ -9862,11 +9805,11 @@
 }
 
 void SignatureData::set_parent_function(const Function& value) const {
-  StorePointer(&raw_ptr()->parent_function_, value.raw());
+  raw_ptr()->set_parent_function(value.raw());
 }
 
 void SignatureData::set_signature_type(const Type& value) const {
-  StorePointer(&raw_ptr()->signature_type_, value.raw());
+  raw_ptr()->set_signature_type(value.raw());
 }
 
 SignatureDataPtr SignatureData::New(Heap::Space space) {
@@ -9888,50 +9831,16 @@
                      type.IsNull() ? "null" : type.ToCString());
 }
 
-void RedirectionData::set_type(const Type& value) const {
-  ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->type_, value.raw());
-}
-
-void RedirectionData::set_identifier(const String& value) const {
-  StorePointer(&raw_ptr()->identifier_, value.raw());
-}
-
-void RedirectionData::set_target(const Function& value) const {
-  StorePointer(&raw_ptr()->target_, value.raw());
-}
-
-RedirectionDataPtr RedirectionData::New() {
-  ASSERT(Object::redirection_data_class() != Class::null());
-  ObjectPtr raw = Object::Allocate(RedirectionData::kClassId,
-                                   RedirectionData::InstanceSize(), Heap::kOld);
-  return static_cast<RedirectionDataPtr>(raw);
-}
-
-const char* RedirectionData::ToCString() const {
-  if (IsNull()) {
-    return "RedirectionData: null";
-  }
-  const Type& redir_type = Type::Handle(type());
-  const String& ident = String::Handle(identifier());
-  const Function& target_fun = Function::Handle(target());
-  return OS::SCreate(Thread::Current()->zone(),
-                     "RedirectionData: type: %s identifier: %s target: %s",
-                     redir_type.IsNull() ? "null" : redir_type.ToCString(),
-                     ident.IsNull() ? "null" : ident.ToCString(),
-                     target_fun.IsNull() ? "null" : target_fun.ToCString());
-}
-
 void FfiTrampolineData::set_signature_type(const Type& value) const {
-  StorePointer(&raw_ptr()->signature_type_, value.raw());
+  raw_ptr()->set_signature_type(value.raw());
 }
 
 void FfiTrampolineData::set_c_signature(const Function& value) const {
-  StorePointer(&raw_ptr()->c_signature_, value.raw());
+  raw_ptr()->set_c_signature(value.raw());
 }
 
 void FfiTrampolineData::set_callback_target(const Function& value) const {
-  StorePointer(&raw_ptr()->callback_target_, value.raw());
+  raw_ptr()->set_callback_target(value.raw());
 }
 
 void FfiTrampolineData::set_callback_id(int32_t callback_id) const {
@@ -9940,7 +9849,7 @@
 
 void FfiTrampolineData::set_callback_exceptional_return(
     const Instance& value) const {
-  StorePointer(&raw_ptr()->callback_exceptional_return_, value.raw());
+  raw_ptr()->set_callback_exceptional_return(value.raw());
 }
 
 FfiTrampolineDataPtr FfiTrampolineData::New() {
@@ -9975,7 +9884,7 @@
   if (IsNull()) {
     return Field::null();
   }
-  Object& obj = Object::Handle(raw_ptr()->owner_);
+  Object& obj = Object::Handle(raw_ptr()->owner());
   if (obj.IsField()) {
     return Field::RawCast(obj.raw());
   } else {
@@ -10001,7 +9910,7 @@
 void Field::SetOriginal(const Field& value) const {
   ASSERT(value.IsOriginal());
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
+  raw_ptr()->set_owner(static_cast<ObjectPtr>(value.raw()));
 }
 
 StringPtr Field::GetterName(const String& field_name) {
@@ -10058,24 +9967,24 @@
 void Field::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
   ASSERT(IsOriginal());
-  StorePointer(&raw_ptr()->name_, value.raw());
+  raw_ptr()->set_name(value.raw());
 }
 
 ObjectPtr Field::RawOwner() const {
   if (IsOriginal()) {
-    return raw_ptr()->owner_;
+    return raw_ptr()->owner();
   } else {
     const Field& field = Field::Handle(Original());
     ASSERT(field.IsOriginal());
-    ASSERT(!Object::Handle(field.raw_ptr()->owner_).IsField());
-    return field.raw_ptr()->owner_;
+    ASSERT(!Object::Handle(field.raw_ptr()->owner()).IsField());
+    return field.raw_ptr()->owner();
   }
 }
 
 ClassPtr Field::Owner() const {
   const Field& field = Field::Handle(Original());
   ASSERT(field.IsOriginal());
-  const Object& obj = Object::Handle(field.raw_ptr()->owner_);
+  const Object& obj = Object::Handle(field.raw_ptr()->owner());
   if (obj.IsClass()) {
     return Class::Cast(obj).raw();
   }
@@ -10086,7 +9995,7 @@
 ClassPtr Field::Origin() const {
   const Field& field = Field::Handle(Original());
   ASSERT(field.IsOriginal());
-  const Object& obj = Object::Handle(field.raw_ptr()->owner_);
+  const Object& obj = Object::Handle(field.raw_ptr()->owner());
   if (obj.IsClass()) {
     return Class::Cast(obj).raw();
   }
@@ -10099,7 +10008,7 @@
   // update Class::PatchFieldsAndFunctions() at the same time.
   const Field& field = Field::Handle(Original());
   ASSERT(field.IsOriginal());
-  const Object& obj = Object::Handle(field.raw_ptr()->owner_);
+  const Object& obj = Object::Handle(field.raw_ptr()->owner());
   if (obj.IsClass()) {
     return Class::Cast(obj).script();
   }
@@ -10108,7 +10017,7 @@
 }
 
 ExternalTypedDataPtr Field::KernelData() const {
-  const Object& obj = Object::Handle(this->raw_ptr()->owner_);
+  const Object& obj = Object::Handle(this->raw_ptr()->owner());
   // During background JIT compilation field objects are copied
   // and copy points to the original field via the owner field.
   if (obj.IsField()) {
@@ -10130,7 +10039,7 @@
 }
 
 intptr_t Field::KernelDataProgramOffset() const {
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  const Object& obj = Object::Handle(raw_ptr()->owner());
   // During background JIT compilation field objects are copied
   // and copy points to the original field via the owner field.
   if (obj.IsField()) {
@@ -10149,7 +10058,7 @@
   ASSERT(IsOriginal());
   ASSERT(!value.IsNull());
   if (value.raw() != type()) {
-    StorePointer(&raw_ptr()->type_, value.raw());
+    raw_ptr()->set_type(value.raw());
   }
 }
 
@@ -10173,7 +10082,9 @@
   result.set_kind_bits(0);
   result.set_name(name);
   result.set_is_static(is_static);
-  if (!is_static) {
+  if (is_static) {
+    result.set_field_id(-1);
+  } else {
     result.SetOffset(0, 0);
   }
   result.set_is_final(is_final);
@@ -10198,9 +10109,6 @@
   result.set_static_type_exactness_state(
       StaticTypeExactnessState::NotTracking());
   Isolate* isolate = Isolate::Current();
-  if (is_static) {
-    isolate->RegisterStaticField(result);
-  }
 
 // Use field guards if they are enabled and the isolate has never reloaded.
 // TODO(johnmccutchan): The reload case assumes the worst case (everything is
@@ -10213,14 +10121,15 @@
       FLAG_precompiled_mode ||
       (isolate->use_field_guards() && !isolate->HasAttemptedReload());
 #endif  // !defined(PRODUCT)
-  result.set_guarded_cid(use_guarded_cid ? kIllegalCid : kDynamicCid);
-  result.set_is_nullable(use_guarded_cid ? false : true);
-  result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
+  result.set_guarded_cid_unsafe(use_guarded_cid ? kIllegalCid : kDynamicCid);
+  result.set_is_nullable_unsafe(use_guarded_cid ? false : true);
+  result.set_guarded_list_length_in_object_offset_unsafe(
+      Field::kUnknownLengthOffset);
   // Presently, we only attempt to remember the list length for final fields.
   if (is_final && use_guarded_cid) {
-    result.set_guarded_list_length(Field::kUnknownFixedLength);
+    result.set_guarded_list_length_unsafe(Field::kUnknownFixedLength);
   } else {
-    result.set_guarded_list_length(Field::kNoFixedLength);
+    result.set_guarded_list_length_unsafe(Field::kNoFixedLength);
   }
 }
 
@@ -10301,20 +10210,20 @@
 }
 
 intptr_t Field::guarded_list_length() const {
-  return Smi::Value(raw_ptr()->guarded_list_length_);
+  return Smi::Value(raw_ptr()->guarded_list_length());
 }
 
-void Field::set_guarded_list_length(intptr_t list_length) const {
+void Field::set_guarded_list_length_unsafe(intptr_t list_length) const {
   ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(IsOriginal());
-  StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length));
+  raw_ptr()->set_guarded_list_length(Smi::New(list_length));
 }
 
 intptr_t Field::guarded_list_length_in_object_offset() const {
   return raw_ptr()->guarded_list_length_in_object_offset_ + kHeapObjectTag;
 }
 
-void Field::set_guarded_list_length_in_object_offset(
+void Field::set_guarded_list_length_in_object_offset_unsafe(
     intptr_t list_length_offset) const {
   ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(IsOriginal());
@@ -10414,12 +10323,16 @@
 }
 
 ArrayPtr Field::dependent_code() const {
-  return raw_ptr()->dependent_code_;
+  DEBUG_ASSERT(
+      IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
+  return raw_ptr()->dependent_code();
 }
 
 void Field::set_dependent_code(const Array& array) const {
   ASSERT(IsOriginal());
-  StorePointer(&raw_ptr()->dependent_code_, array.raw());
+  DEBUG_ASSERT(
+      IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+  raw_ptr()->set_dependent_code(array.raw());
 }
 
 class FieldDependentArray : public WeakCodeReferences {
@@ -10476,8 +10389,8 @@
 bool Field::IsConsistentWith(const Field& other) const {
   return (raw_ptr()->guarded_cid_ == other.raw_ptr()->guarded_cid_) &&
          (raw_ptr()->is_nullable_ == other.raw_ptr()->is_nullable_) &&
-         (raw_ptr()->guarded_list_length_ ==
-          other.raw_ptr()->guarded_list_length_) &&
+         (raw_ptr()->guarded_list_length() ==
+          other.raw_ptr()->guarded_list_length()) &&
          (is_unboxing_candidate() == other.is_unboxing_candidate()) &&
          (static_type_exactness_state().Encode() ==
           other.static_type_exactness_state().Encode());
@@ -10524,13 +10437,13 @@
   // We have to ensure that all stores into the initializer function object
   // happen before releasing the pointer to the initializer as it may be
   // accessed without grabbing the lock.
-  StorePointer<FunctionPtr, std::memory_order_release>(
-      &raw_ptr()->initializer_function_, initializer.raw());
+  raw_ptr()->set_initializer_function<std::memory_order_release>(
+      initializer.raw());
 #endif
 }
 
 bool Field::HasInitializerFunction() const {
-  return raw_ptr()->initializer_function_ != Function::null();
+  return raw_ptr()->initializer_function() != Function::null();
 }
 
 ErrorPtr Field::InitializeInstance(const Instance& instance) const {
@@ -10538,6 +10451,7 @@
   ASSERT(is_instance());
   ASSERT(instance.GetField(*this) == Object::sentinel().raw());
   Object& value = Object::Handle();
+
   if (has_nontrivial_initializer()) {
     const Function& initializer = Function::Handle(EnsureInitializerFunction());
     const Array& args = Array::Handle(Array::New(1));
@@ -10548,19 +10462,22 @@
     }
   } else {
     if (is_late() && !has_initializer()) {
-      Exceptions::ThrowLateInitializationError(String::Handle(name()));
+      Exceptions::ThrowLateFieldNotInitialized(String::Handle(name()));
       UNREACHABLE();
     }
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
 #else
-    value = saved_initial_value();
+    // Our trivial initializer is `null`. Any non-`null` initializer is
+    // non-trivial (see `KernelLoader::CheckForInitializer()`).
+    value = Object::null();
 #endif
   }
   ASSERT(value.IsNull() || value.IsInstance());
   if (is_late() && is_final() &&
       (instance.GetField(*this) != Object::sentinel().raw())) {
-    Exceptions::ThrowLateInitializationError(String::Handle(name()));
+    Exceptions::ThrowLateFieldAssignedDuringInitialization(
+        String::Handle(name()));
     UNREACHABLE();
   }
   instance.SetField(*this, value);
@@ -10574,7 +10491,7 @@
     auto& value = Object::Handle();
     if (is_late()) {
       if (!has_initializer()) {
-        Exceptions::ThrowLateInitializationError(String::Handle(name()));
+        Exceptions::ThrowLateFieldNotInitialized(String::Handle(name()));
         UNREACHABLE();
       }
       value = EvaluateInitializer();
@@ -10582,7 +10499,8 @@
         return Error::Cast(value).raw();
       }
       if (is_final() && (StaticValue() != Object::sentinel().raw())) {
-        Exceptions::ThrowLateInitializationError(String::Handle(name()));
+        Exceptions::ThrowLateFieldAssignedDuringInitialization(
+            String::Handle(name()));
         UNREACHABLE();
       }
     } else {
@@ -10594,8 +10512,9 @@
       }
     }
     ASSERT(value.IsNull() || value.IsInstance());
-    SetStaticValue(value.IsNull() ? Instance::null_instance()
-                                  : Instance::Cast(value));
+    SetStaticValue(
+        value.IsNull() ? Instance::null_instance() : Instance::Cast(value),
+        is_const());
     return Error::null();
   } else if (StaticValue() == Object::transition_sentinel().raw()) {
     ASSERT(!is_late());
@@ -10687,15 +10606,17 @@
                              class_name, exactness);
 }
 
-void Field::InitializeGuardedListLengthInObjectOffset() const {
+void Field::InitializeGuardedListLengthInObjectOffset(bool unsafe) const {
+  auto setter = unsafe ? &Field::set_guarded_list_length_in_object_offset_unsafe
+                       : &Field::set_guarded_list_length_in_object_offset;
   ASSERT(IsOriginal());
   if (needs_length_check() &&
       (guarded_list_length() != Field::kUnknownFixedLength)) {
     const intptr_t offset = GetListLengthOffset(guarded_cid());
-    set_guarded_list_length_in_object_offset(offset);
+    (this->*setter)(offset);
     ASSERT(offset != Field::kUnknownLengthOffset);
   } else {
-    set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
+    (this->*setter)(Field::kUnknownLengthOffset);
   }
 }
 
@@ -10811,13 +10732,15 @@
 void Field::SetStaticValue(const Instance& value,
                            bool save_initial_value) const {
   ASSERT(Thread::Current()->IsMutatorThread());
+
   ASSERT(is_static());  // Valid only for static dart fields.
   Isolate* isolate = Isolate::Current();
   const intptr_t id = field_id();
+  ASSERT(id >= 0);
   isolate->field_table()->SetAt(id, value.raw());
   if (save_initial_value) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-    StorePointer(&raw_ptr()->saved_initial_value_, value.raw());
+    isolate->group()->initial_field_table()->SetAt(field_id(), value.raw());
 #endif
   }
 }
@@ -11042,6 +10965,8 @@
   // We should never try to record a sentinel.
   ASSERT(value.raw() != Object::sentinel().raw());
 
+  Thread* const thread = Thread::Current();
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
   if ((guarded_cid() == kDynamicCid) ||
       (is_nullable() && value.raw() == Object::null())) {
     // Nothing to do: the field is not guarded or we are storing null into
@@ -11087,16 +11012,16 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 void Field::set_type_test_cache(const SubtypeTestCache& cache) const {
-  StorePointer(&raw_ptr()->type_test_cache_, cache.raw());
+  raw_ptr()->set_type_test_cache(cache.raw());
 }
 #endif
 
 bool Script::HasSource() const {
-  return raw_ptr()->source_ != String::null();
+  return raw_ptr()->source() != String::null();
 }
 
 StringPtr Script::Source() const {
-  return raw_ptr()->source_;
+  return raw_ptr()->source();
 }
 
 bool Script::IsPartOfDartColonLibrary() const {
@@ -11116,11 +11041,11 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 void Script::set_compile_time_constants(const Array& value) const {
-  StorePointer(&raw_ptr()->compile_time_constants_, value.raw());
+  raw_ptr()->set_compile_time_constants(value.raw());
 }
 
 void Script::set_kernel_program_info(const KernelProgramInfo& info) const {
-  StorePointer(&raw_ptr()->kernel_program_info_, info.raw());
+  raw_ptr()->set_kernel_program_info(info.raw());
 }
 
 void Script::set_kernel_script_index(const intptr_t kernel_script_index) const {
@@ -11221,38 +11146,48 @@
 }
 
 void Script::set_url(const String& value) const {
-  StorePointer(&raw_ptr()->url_, value.raw());
+  raw_ptr()->set_url(value.raw());
 }
 
 void Script::set_resolved_url(const String& value) const {
-  StorePointer(&raw_ptr()->resolved_url_, value.raw());
+  raw_ptr()->set_resolved_url(value.raw());
 }
 
 void Script::set_source(const String& value) const {
-  StorePointer(&raw_ptr()->source_, value.raw());
+  raw_ptr()->set_source(value.raw());
 }
 
 void Script::set_line_starts(const TypedData& value) const {
-  StorePointer(&raw_ptr()->line_starts_, value.raw());
+  raw_ptr()->set_line_starts(value.raw());
 }
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+void Script::set_constant_coverage(const ExternalTypedData& value) const {
+  raw_ptr()->set_constant_coverage(value.raw());
+}
+
+ExternalTypedDataPtr Script::constant_coverage() const {
+  return raw_ptr()->constant_coverage();
+}
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 void Script::set_debug_positions(const Array& value) const {
-  StorePointer(&raw_ptr()->debug_positions_, value.raw());
+  raw_ptr()->set_debug_positions(value.raw());
 }
 
 TypedDataPtr Script::line_starts() const {
-  return raw_ptr()->line_starts_;
+  return raw_ptr()->line_starts();
 }
 
 ArrayPtr Script::debug_positions() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_);
+  Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions());
   if (debug_positions_array.IsNull()) {
     // This is created lazily. Now we need it.
     kernel::CollectTokenPositionsFor(*this);
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  return raw_ptr()->debug_positions_;
+  return raw_ptr()->debug_positions();
 }
 
 void Script::set_flags(uint8_t value) const {
@@ -11399,48 +11334,78 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
+// Returns the index in the given source string for the given (1-based) absolute
+// line and column numbers. The line and column offsets are used to calculate
+// the absolute line and column number for the starting index in the source.
+//
+// If the given line number is outside the range of lines represented by the
+// source, the given column number invalid for the given line, or a negative
+// starting index is given, a negative value is returned to indicate failure.
+static intptr_t GetRelativeSourceIndex(const String& src,
+                                       intptr_t line,
+                                       intptr_t line_offset = 0,
+                                       intptr_t column = 1,
+                                       intptr_t column_offset = 0,
+                                       intptr_t starting_index = 0) {
+  if (starting_index < 0 || line < 1 || column < 1) {
+    return -1;
+  }
+  intptr_t len = src.Length();
+  intptr_t current_line = line_offset + 1;
+  intptr_t current_index = starting_index;
+  for (; current_index < len; current_index++) {
+    if (current_line == line) {
+      break;
+    }
+    const uint16_t c = src.CharAt(current_index);
+    if (c == '\n' || c == '\r') {
+      current_line++;
+    }
+    if (c == '\r' && current_index + 1 < len &&
+        src.CharAt(current_index + 1) == '\n') {
+      // \r\n is treated as a single line terminator.
+      current_index++;
+    }
+  }
+  if (current_line != line) {
+    return -1;
+  }
+  // Only adjust with column offset when still on the first line.
+  intptr_t current_column = 1 + (line == line_offset + 1 ? column_offset : 0);
+  for (; current_index < len; current_index++, current_column++) {
+    if (current_column == column) {
+      return current_index;
+    }
+    const uint16_t c = src.CharAt(current_index);
+    if (c == '\n' || c == '\r') {
+      break;
+    }
+  }
+  // Check for a column value representing the source's end.
+  if (current_column == column) {
+    return current_index;
+  }
+  return -1;
+}
+
 StringPtr Script::GetLine(intptr_t line_number, Heap::Space space) const {
   const String& src = String::Handle(Source());
   if (src.IsNull()) {
     return Symbols::OptimizedOut().raw();
   }
-  intptr_t relative_line_number = line_number - line_offset();
-  intptr_t current_line = 1;
-  intptr_t line_start_idx = -1;
-  intptr_t last_char_idx = -1;
-  for (intptr_t ix = 0;
-       (ix < src.Length()) && (current_line <= relative_line_number); ix++) {
-    if ((current_line == relative_line_number) && (line_start_idx < 0)) {
-      line_start_idx = ix;
-    }
-    if (src.CharAt(ix) == '\n') {
-      current_line++;
-    } else if (src.CharAt(ix) == '\r') {
-      if ((ix + 1 != src.Length()) && (src.CharAt(ix + 1) != '\n')) {
-        current_line++;
-      }
-    } else {
-      last_char_idx = ix;
-    }
-  }
-  // Guarantee that returned string is never NULL.
-
-  if (line_start_idx >= 0) {
-    return String::SubString(src, line_start_idx,
-                             last_char_idx - line_start_idx + 1, space);
-  } else {
+  const intptr_t start =
+      GetRelativeSourceIndex(src, line_number, line_offset());
+  if (start < 0) {
     return Symbols::Empty().raw();
   }
-}
-
-StringPtr Script::GetSnippet(TokenPosition from, TokenPosition to) const {
-  intptr_t from_line;
-  intptr_t from_column;
-  intptr_t to_line;
-  intptr_t to_column;
-  GetTokenLocation(from, &from_line, &from_column);
-  GetTokenLocation(to, &to_line, &to_column);
-  return GetSnippet(from_line, from_column, to_line, to_column);
+  intptr_t end = start;
+  for (; end < src.Length(); end++) {
+    const uint16_t c = src.CharAt(end);
+    if (c == '\n' || c == '\r') {
+      break;
+    }
+  }
+  return String::SubString(src, start, end - start, space);
 }
 
 StringPtr Script::GetSnippet(intptr_t from_line,
@@ -11451,49 +11416,17 @@
   if (src.IsNull()) {
     return Symbols::OptimizedOut().raw();
   }
-  intptr_t length = src.Length();
-  intptr_t line = 1 + line_offset();
-  intptr_t column = 1;
-  intptr_t scan_position = 0;
-  intptr_t snippet_start = -1;
-  intptr_t snippet_end = -1;
-  if (from_line - line_offset() == 1) {
-    column += col_offset();
-  }
 
-  while (scan_position != length) {
-    if (snippet_start == -1) {
-      if ((line == from_line) && (column == from_column)) {
-        snippet_start = scan_position;
-      }
-    }
-
-    char c = src.CharAt(scan_position);
-    if (c == '\n') {
-      line++;
-      column = 0;
-    } else if (c == '\r') {
-      line++;
-      column = 0;
-      if ((scan_position + 1 != length) &&
-          (src.CharAt(scan_position + 1) == '\n')) {
-        scan_position++;
-      }
-    }
-    scan_position++;
-    column++;
-
-    if ((line == to_line) && (column == to_column)) {
-      snippet_end = scan_position;
-      break;
-    }
+  const intptr_t start = GetRelativeSourceIndex(src, from_line, line_offset(),
+                                                from_column, col_offset());
+  // Lines and columns are 1-based, so need to subtract one to get offsets.
+  const intptr_t end = GetRelativeSourceIndex(
+      src, to_line, from_line - 1, to_column, from_column - 1, start);
+  // Only need to check end, because a negative start results in a negative end.
+  if (end < 0) {
+    return String::null();
   }
-  String& snippet = String::Handle();
-  if ((snippet_start != -1) && (snippet_end != -1)) {
-    snippet =
-        String::SubString(src, snippet_start, snippet_end - snippet_start);
-  }
-  return snippet.raw();
+  return String::SubString(src, start, end - start);
 }
 
 ScriptPtr Script::New() {
@@ -11633,19 +11566,19 @@
 
 void Library::set_name(const String& name) const {
   ASSERT(name.IsSymbol());
-  StorePointer(&raw_ptr()->name_, name.raw());
+  raw_ptr()->set_name(name.raw());
 }
 
 void Library::set_url(const String& name) const {
-  StorePointer(&raw_ptr()->url_, name.raw());
+  raw_ptr()->set_url(name.raw());
 }
 
 void Library::set_kernel_data(const ExternalTypedData& data) const {
-  StorePointer(&raw_ptr()->kernel_data_, data.raw());
+  raw_ptr()->set_kernel_data(data.raw());
 }
 
 void Library::set_loading_unit(const LoadingUnit& value) const {
-  StorePointer(&raw_ptr()->loading_unit_, value.raw());
+  raw_ptr()->set_loading_unit(value.raw());
 }
 
 void Library::SetName(const String& name) const {
@@ -11672,218 +11605,75 @@
   StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoaded);
 }
 
-static StringPtr MakeClassMetaName(Thread* thread,
-                                   Zone* zone,
-                                   const Class& cls) {
-  return Symbols::FromConcat(thread, Symbols::At(),
-                             String::Handle(zone, cls.Name()));
-}
-
-static StringPtr MakeFieldMetaName(Thread* thread,
-                                   Zone* zone,
-                                   const Field& field) {
-  const String& cname = String::Handle(
-      zone,
-      MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin())));
-  GrowableHandlePtrArray<const String> pieces(zone, 3);
-  pieces.Add(cname);
-  pieces.Add(Symbols::At());
-  pieces.Add(String::Handle(zone, field.name()));
-  return Symbols::FromConcatAll(thread, pieces);
-}
-
-static StringPtr MakeFunctionMetaName(Thread* thread,
-                                      Zone* zone,
-                                      const Function& func) {
-  const String& cname = String::Handle(
-      zone,
-      MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin())));
-  GrowableHandlePtrArray<const String> pieces(zone, 3);
-  pieces.Add(cname);
-  pieces.Add(Symbols::At());
-  pieces.Add(String::Handle(zone, func.name()));
-  return Symbols::FromConcatAll(thread, pieces);
-}
-
-static StringPtr MakeTypeParameterMetaName(Thread* thread,
-                                           Zone* zone,
-                                           const TypeParameter& param) {
-  const String& cname = String::Handle(
-      zone,
-      MakeClassMetaName(thread, zone,
-                        Class::Handle(zone, param.parameterized_class())));
-  GrowableHandlePtrArray<const String> pieces(zone, 3);
-  pieces.Add(cname);
-  pieces.Add(Symbols::At());
-  pieces.Add(String::Handle(zone, param.name()));
-  return Symbols::FromConcatAll(thread, pieces);
-}
-
-void Library::AddMetadata(const Object& owner,
-                          const String& name,
-                          TokenPosition token_pos,
+void Library::AddMetadata(const Object& declaration,
                           intptr_t kernel_offset) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
 #else
   Thread* thread = Thread::Current();
-  ASSERT(thread->IsMutatorThread());
-  Zone* zone = thread->zone();
-  const String& metaname = String::Handle(zone, Symbols::New(thread, name));
-  const Field& field =
-      Field::Handle(zone, Field::NewTopLevel(metaname,
-                                             false,  // is_final
-                                             false,  // is_const
-                                             false,  // is_late
-                                             owner, token_pos, token_pos));
-  field.SetFieldType(Object::dynamic_type());
-  field.set_is_reflectable(false);
-  field.SetStaticValue(Array::empty_array(), true);
-  field.set_kernel_offset(kernel_offset);
-  GrowableObjectArray& metadata =
-      GrowableObjectArray::Handle(zone, this->metadata());
-  metadata.Add(field, Heap::kOld);
+  ASSERT(thread->isolate_group()->program_lock()->IsCurrentThreadWriter());
+
+  MetadataMap map(metadata());
+  map.UpdateOrInsert(declaration, Smi::Handle(Smi::New(kernel_offset)));
+  set_metadata(map.Release());
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-void Library::AddClassMetadata(const Class& cls,
-                               const Object& tl_owner,
-                               TokenPosition token_pos,
-                               intptr_t kernel_offset) const {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  // We use the toplevel class as the owner of a class's metadata field because
-  // a class's metadata is in scope of the library, not the class.
-  AddMetadata(tl_owner,
-              String::Handle(zone, MakeClassMetaName(thread, zone, cls)),
-              token_pos, kernel_offset);
-}
-
-void Library::AddFieldMetadata(const Field& field,
-                               TokenPosition token_pos,
-                               intptr_t kernel_offset) const {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  const auto& owner = Object::Handle(zone, field.RawOwner());
-  const auto& name =
-      String::Handle(zone, MakeFieldMetaName(thread, zone, field));
-  AddMetadata(owner, name, token_pos, kernel_offset);
-}
-
-void Library::AddFunctionMetadata(const Function& func,
-                                  TokenPosition token_pos,
-                                  intptr_t kernel_offset) const {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  const auto& owner = Object::Handle(zone, func.RawOwner());
-  const auto& name =
-      String::Handle(zone, MakeFunctionMetaName(thread, zone, func));
-  AddMetadata(owner, name, token_pos, kernel_offset);
-}
-
-void Library::AddTypeParameterMetadata(const TypeParameter& param,
-                                       TokenPosition token_pos) const {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  const auto& owner = Class::Handle(zone, param.parameterized_class());
-  const auto& name =
-      String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param));
-  AddMetadata(owner, name, token_pos, 0);
-}
-
-void Library::AddLibraryMetadata(const Object& tl_owner,
-                                 TokenPosition token_pos,
-                                 intptr_t kernel_offset) const {
-  AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset);
-}
-
-StringPtr Library::MakeMetadataName(const Object& obj) const {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  if (obj.IsClass()) {
-    return MakeClassMetaName(thread, zone, Class::Cast(obj));
-  } else if (obj.IsField()) {
-    return MakeFieldMetaName(thread, zone, Field::Cast(obj));
-  } else if (obj.IsFunction()) {
-    return MakeFunctionMetaName(thread, zone, Function::Cast(obj));
-  } else if (obj.IsLibrary()) {
-    return Symbols::TopLevel().raw();
-  } else if (obj.IsTypeParameter()) {
-    return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj));
-  }
-  UNIMPLEMENTED();
-  return String::null();
-}
-
-FieldPtr Library::GetMetadataField(const String& metaname) const {
-  const GrowableObjectArray& metadata =
-      GrowableObjectArray::Handle(this->metadata());
-  Field& entry = Field::Handle();
-  String& entryname = String::Handle();
-  intptr_t num_entries = metadata.Length();
-  for (intptr_t i = 0; i < num_entries; i++) {
-    entry ^= metadata.At(i);
-    entryname = entry.name();
-    if (entryname.Equals(metaname)) {
-      return entry.raw();
-    }
-  }
-  return Field::null();
-}
-
-void Library::CloneMetadataFrom(const Library& from_library,
-                                const Function& from_fun,
-                                const Function& to_fun) const {
-  const String& metaname = String::Handle(MakeMetadataName(from_fun));
-  const Field& from_field =
-      Field::Handle(from_library.GetMetadataField(metaname));
-  if (!from_field.IsNull()) {
-    AddFunctionMetadata(to_fun, from_field.token_pos(),
-                        from_field.kernel_offset());
-  }
-}
-
-ObjectPtr Library::GetMetadata(const Object& obj) const {
+ObjectPtr Library::GetMetadata(const Object& declaration) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   return Object::empty_array().raw();
 #else
-  if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() &&
-      !obj.IsLibrary() && !obj.IsTypeParameter()) {
-    UNREACHABLE();
-  }
-  if (obj.IsLibrary()) {
+  RELEASE_ASSERT(declaration.IsClass() || declaration.IsField() ||
+                 declaration.IsFunction() || declaration.IsLibrary() ||
+                 declaration.IsTypeParameter() || declaration.IsNamespace());
+
+  auto thread = Thread::Current();
+  auto zone = thread->zone();
+
+  if (declaration.IsLibrary()) {
     // Ensure top-level class is loaded as it may contain annotations of
     // a library.
-    const auto& cls = Class::Handle(toplevel_class());
+    const auto& cls = Class::Handle(zone, toplevel_class());
     if (!cls.IsNull()) {
       cls.EnsureDeclarationLoaded();
     }
   }
-  const String& metaname = String::Handle(MakeMetadataName(obj));
-  Field& field = Field::Handle(GetMetadataField(metaname));
-  if (field.IsNull()) {
+  Object& value = Object::Handle(zone);
+  {
+    SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
+    MetadataMap map(metadata());
+    value = map.GetOrNull(declaration);
+    set_metadata(map.Release());
+  }
+  if (value.IsNull()) {
     // There is no metadata for this object.
     return Object::empty_array().raw();
   }
-  Object& metadata = Object::Handle(field.StaticValue());
-  if (metadata.raw() == Object::empty_array().raw()) {
-    ASSERT(field.kernel_offset() > 0);
-    metadata = kernel::EvaluateMetadata(
-        field, /* is_annotations_offset = */ obj.IsLibrary());
-    if (metadata.IsArray() || metadata.IsNull()) {
-      ASSERT(metadata.raw() != Object::empty_array().raw());
-      if (!Compiler::IsBackgroundCompilation()) {
-        field.SetStaticValue(
-            metadata.IsNull() ? Object::null_array() : Array::Cast(metadata),
-            true);
-      }
+  if (!value.IsSmi()) {
+    // Metadata is already evaluated.
+    ASSERT(value.IsArray());
+    return value.raw();
+  }
+  const auto& smi_value = Smi::Cast(value);
+  intptr_t kernel_offset = smi_value.Value();
+  ASSERT(kernel_offset > 0);
+  const auto& evaluated_value = Object::Handle(
+      zone, kernel::EvaluateMetadata(
+                *this, kernel_offset,
+                /* is_annotations_offset = */ declaration.IsLibrary() ||
+                    declaration.IsNamespace()));
+  if (evaluated_value.IsArray() || evaluated_value.IsNull()) {
+    ASSERT(evaluated_value.raw() != Object::empty_array().raw());
+    SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+    MetadataMap map(metadata());
+    if (map.GetOrNull(declaration) == smi_value.raw()) {
+      map.UpdateOrInsert(declaration, evaluated_value);
+    } else {
+      ASSERT(map.GetOrNull(declaration) == evaluated_value.raw());
     }
+    set_metadata(map.Release());
   }
-  if (metadata.IsNull()) {
-    // Metadata field exists in order to reference extended metadata.
-    return Object::empty_array().raw();
-  }
-  return metadata.raw();
+  return evaluated_value.raw();
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
@@ -11974,7 +11764,7 @@
   }
   ResolvedNamesMap cache(resolved_names());
   cache.UpdateOrInsert(name, obj);
-  StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw());
+  raw_ptr()->set_resolved_names(cache.Release().raw());
 }
 
 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const {
@@ -12009,7 +11799,7 @@
   }
   ResolvedNamesMap cache(exported_names());
   cache.UpdateOrInsert(name, obj);
-  StorePointer(&raw_ptr()->exported_names_, cache.Release().raw());
+  raw_ptr()->set_exported_names(cache.Release().raw());
 }
 
 void Library::InvalidateResolvedName(const String& name) const {
@@ -12082,7 +11872,7 @@
   new_entry = Smi::New(used);
   new_dict.SetAt(new_dict_size, new_entry);
   // Remember the new dictionary now.
-  StorePointer(&raw_ptr()->dictionary_, new_dict.raw());
+  raw_ptr()->set_dictionary(new_dict.raw());
 }
 
 void Library::AddObject(const Object& obj, const String& name) const {
@@ -12118,7 +11908,7 @@
 
   // Invalidate the cache of loaded scripts.
   if (loaded_scripts() != Array::null()) {
-    StorePointer(&raw_ptr()->loaded_scripts_, Array::null());
+    raw_ptr()->set_loaded_scripts(Array::null());
   }
 }
 
@@ -12280,7 +12070,7 @@
 
     // Create the array of scripts and cache it in loaded_scripts_.
     const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts));
-    StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw());
+    raw_ptr()->set_loaded_scripts(scripts_array.raw());
   }
   return loaded_scripts();
 }
@@ -12430,7 +12220,7 @@
     import = ImportAt(i);
     obj = import.Lookup(name);
     if (!obj.IsNull()) {
-      import_lib = import.library();
+      import_lib = import.target();
       import_lib_url = import_lib.url();
       if (found_obj.raw() != obj.raw()) {
         if (first_import_lib_url.IsNull() ||
@@ -12546,16 +12336,20 @@
 }
 
 void Library::set_toplevel_class(const Class& value) const {
-  ASSERT(raw_ptr()->toplevel_class_ == Class::null());
-  StorePointer(&raw_ptr()->toplevel_class_, value.raw());
+  ASSERT(raw_ptr()->toplevel_class() == Class::null());
+  raw_ptr()->set_toplevel_class(value.raw());
 }
 
 void Library::set_dependencies(const Array& deps) const {
-  StorePointer(&raw_ptr()->dependencies_, deps.raw());
+  raw_ptr()->set_dependencies(deps.raw());
 }
 
-void Library::set_metadata(const GrowableObjectArray& value) const {
-  StorePointer(&raw_ptr()->metadata_, value.raw());
+void Library::set_metadata(const Array& value) const {
+  if (raw_ptr()->metadata() != value.raw()) {
+    DEBUG_ASSERT(
+        IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+    raw_ptr()->set_metadata(value.raw());
+  }
 }
 
 LibraryPtr Library::ImportLibraryAt(intptr_t index) const {
@@ -12563,7 +12357,7 @@
   if (import.IsNull()) {
     return Library::null();
   }
-  return import.library();
+  return import.target();
 }
 
 NamespacePtr Library::ImportAt(intptr_t index) const {
@@ -12578,14 +12372,14 @@
   // We need to preserve the "dart-ext:" imports because they are used by
   // Loader::ReloadNativeExtensions().
   intptr_t native_import_count = 0;
-  Array& imports = Array::Handle(raw_ptr()->imports_);
+  Array& imports = Array::Handle(raw_ptr()->imports());
   Namespace& ns = Namespace::Handle();
   Library& lib = Library::Handle();
   String& url = String::Handle();
   for (int i = 0; i < imports.Length(); ++i) {
     ns = Namespace::RawCast(imports.At(i));
     if (ns.IsNull()) continue;
-    lib = ns.library();
+    lib = ns.target();
     url = lib.url();
     if (url.StartsWith(Symbols::DartExtensionScheme())) {
       native_import_count++;
@@ -12596,20 +12390,20 @@
   for (int i = 0, j = 0; i < imports.Length(); ++i) {
     ns = Namespace::RawCast(imports.At(i));
     if (ns.IsNull()) continue;
-    lib = ns.library();
+    lib = ns.target();
     url = lib.url();
     if (url.StartsWith(Symbols::DartExtensionScheme())) {
       new_imports.SetAt(j++, ns);
     }
   }
 
-  StorePointer(&raw_ptr()->imports_, new_imports.raw());
-  StorePointer(&raw_ptr()->exports_, Object::empty_array().raw());
+  raw_ptr()->set_imports(new_imports.raw());
+  raw_ptr()->set_exports(Object::empty_array().raw());
   StoreNonPointer(&raw_ptr()->num_imports_, 0);
-  StorePointer(&raw_ptr()->resolved_names_, Array::null());
-  StorePointer(&raw_ptr()->exported_names_, Array::null());
-  StorePointer(&raw_ptr()->loaded_scripts_, Array::null());
-  StorePointer(&raw_ptr()->dependencies_, Array::null());
+  raw_ptr()->set_resolved_names(Array::null());
+  raw_ptr()->set_exported_names(Array::null());
+  raw_ptr()->set_loaded_scripts(Array::null());
+  raw_ptr()->set_dependencies(Array::null());
 }
 
 void Library::AddImport(const Namespace& ns) const {
@@ -12618,7 +12412,7 @@
   if (num_imports() == capacity) {
     capacity = capacity + kImportsCapacityIncrement + (capacity >> 2);
     imports = Array::Grow(imports, capacity);
-    StorePointer(&raw_ptr()->imports_, imports.raw());
+    raw_ptr()->set_imports(imports.raw());
   }
   intptr_t index = num_imports();
   imports.SetAt(index, ns);
@@ -12638,7 +12432,7 @@
   Array& exports = Array::Handle(this->exports());
   intptr_t num_exports = exports.Length();
   exports = Array::Grow(exports, num_exports + 1);
-  StorePointer(&raw_ptr()->exports_, exports.raw());
+  raw_ptr()->set_exports(exports.raw());
   exports.SetAt(num_exports, ns);
 }
 
@@ -12655,12 +12449,12 @@
   REUSABLE_FUNCTION_HANDLESCOPE(thread);
   Array& cache = thread->ArrayHandle();
   cache = HashTables::New<ResolvedNamesMap>(64);
-  StorePointer(&raw_ptr()->resolved_names_, cache.raw());
+  raw_ptr()->set_resolved_names(cache.raw());
 }
 
 void Library::ClearResolvedNamesCache() const {
   ASSERT(Thread::Current()->IsMutatorThread());
-  StorePointer(&raw_ptr()->resolved_names_, Array::null());
+  raw_ptr()->set_resolved_names(Array::null());
 }
 
 void Library::InitExportedNamesCache() const {
@@ -12669,11 +12463,11 @@
   REUSABLE_FUNCTION_HANDLESCOPE(thread);
   Array& cache = thread->ArrayHandle();
   cache = HashTables::New<ResolvedNamesMap>(16);
-  StorePointer(&raw_ptr()->exported_names_, cache.raw());
+  raw_ptr()->set_exported_names(cache.raw());
 }
 
 void Library::ClearExportedNamesCache() const {
-  StorePointer(&raw_ptr()->exported_names_, Array::null());
+  raw_ptr()->set_exported_names(Array::null());
 }
 
 void Library::InitClassDictionary() const {
@@ -12684,13 +12478,13 @@
   // TODO(iposva): Find reasonable initial size.
   const int kInitialElementCount = 16;
   dictionary = NewDictionary(kInitialElementCount);
-  StorePointer(&raw_ptr()->dictionary_, dictionary.raw());
+  raw_ptr()->set_dictionary(dictionary.raw());
 }
 
 void Library::InitImportList() const {
   const Array& imports =
       Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld));
-  StorePointer(&raw_ptr()->imports_, imports.raw());
+  raw_ptr()->set_imports(imports.raw());
   StoreNonPointer(&raw_ptr()->num_imports_, 0);
 }
 
@@ -12709,21 +12503,21 @@
   url.Hash();
   const bool dart_scheme = url.StartsWith(Symbols::DartScheme());
   const Library& result = Library::Handle(zone, Library::New());
-  result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw());
-  result.StorePointer(&result.raw_ptr()->url_, url.raw());
-  result.StorePointer(&result.raw_ptr()->resolved_names_, Array::null());
-  result.StorePointer(&result.raw_ptr()->exported_names_, Array::null());
-  result.StorePointer(&result.raw_ptr()->dictionary_,
-                      Object::empty_array().raw());
+  result.raw_ptr()->set_name(Symbols::Empty().raw());
+  result.raw_ptr()->set_url(url.raw());
+  result.raw_ptr()->set_resolved_names(Array::null());
+  result.raw_ptr()->set_exported_names(Array::null());
+  result.raw_ptr()->set_dictionary(Object::empty_array().raw());
+  Array& array = Array::Handle(zone);
+  array = HashTables::New<MetadataMap>(4, Heap::kOld);
+  result.raw_ptr()->set_metadata(array.raw());
+  result.raw_ptr()->set_toplevel_class(Class::null());
   GrowableObjectArray& list = GrowableObjectArray::Handle(zone);
-  list = GrowableObjectArray::New(4, Heap::kOld);
-  result.StorePointer(&result.raw_ptr()->metadata_, list.raw());
-  result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null());
   list = GrowableObjectArray::New(Object::empty_array(), Heap::kOld);
-  result.StorePointer(&result.raw_ptr()->used_scripts_, list.raw());
-  result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
-  result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw());
-  result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null());
+  result.raw_ptr()->set_used_scripts(list.raw());
+  result.raw_ptr()->set_imports(Object::empty_array().raw());
+  result.raw_ptr()->set_exports(Object::empty_array().raw());
+  result.raw_ptr()->set_loaded_scripts(Array::null());
   result.set_native_entry_resolver(NULL);
   result.set_native_entry_symbol_resolver(NULL);
   result.set_flags(0);
@@ -12748,9 +12542,9 @@
   if (import_core_lib) {
     const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
     ASSERT(!core_lib.IsNull());
-    const Namespace& ns = Namespace::Handle(
-        zone,
-        Namespace::New(core_lib, Object::null_array(), Object::null_array()));
+    const Namespace& ns =
+        Namespace::Handle(zone, Namespace::New(core_lib, Object::null_array(),
+                                               Object::null_array(), result));
     result.AddImport(ns);
   }
   return result.raw();
@@ -12795,12 +12589,10 @@
     return DartEntry::InvokeNoSuchMethod(thread, receiver, target_name, args,
                                          args_descriptor_array);
   }
-  if (!function.CanReceiveDynamicInvocation()) {
-    ObjectPtr type_error = function.DoArgumentTypesMatch(
-        args, args_descriptor, instantiator_type_args);
-    if (type_error != Error::null()) {
-      return type_error;
-    }
+  ObjectPtr type_error = function.DoArgumentTypesMatch(args, args_descriptor,
+                                                       instantiator_type_args);
+  if (type_error != Error::null()) {
+    return type_error;
   }
   return DartEntry::InvokeFunction(function, args, args_descriptor_array);
 }
@@ -12997,12 +12789,10 @@
   }
   // This is a static function, so we pass an empty instantiator tav.
   ASSERT(function.is_static());
-  if (!function.CanReceiveDynamicInvocation()) {
-    ObjectPtr type_error = function.DoArgumentTypesMatch(
-        args, args_descriptor, Object::empty_type_arguments());
-    if (type_error != Error::null()) {
-      return type_error;
-    }
+  ObjectPtr type_error = function.DoArgumentTypesMatch(
+      args, args_descriptor, Object::empty_type_arguments());
+  if (type_error != Error::null()) {
+    return type_error;
   }
   return DartEntry::InvokeFunction(function, args, args_descriptor_array);
 }
@@ -13179,7 +12969,7 @@
     const String& original_key =
         String::Handle(reload_context->FindLibraryPrivateKey(*this));
     if (!original_key.IsNull()) {
-      StorePointer(&raw_ptr()->private_key_, original_key.raw());
+      raw_ptr()->set_private_key(original_key.raw());
       return;
     }
   }
@@ -13201,7 +12991,7 @@
   const String& key =
       String::Handle(zone, String::New(private_key, Heap::kOld));
   key.Hash();  // This string may end up in the VM isolate.
-  StorePointer(&raw_ptr()->private_key_, key.raw());
+  raw_ptr()->set_private_key(key.raw());
 }
 
 const String& Library::PrivateCoreLibName(const String& member) {
@@ -13367,10 +13157,6 @@
   return Isolate::Current()->object_store()->_vmservice_library();
 }
 
-LibraryPtr Library::WasmLibrary() {
-  return Isolate::Current()->object_store()->wasm_library();
-}
-
 const char* Library::ToCString() const {
   NoSafepointScope no_safepoint;
   const String& name = String::Handle(url());
@@ -13383,7 +13169,7 @@
     const Array& imports = Array::Handle(this->imports());
     Namespace& import = Namespace::Handle();
     import ^= imports.At(index);
-    return import.library();
+    return import.target();
   }
   return Library::null();
 }
@@ -13430,11 +13216,11 @@
 
 void LibraryPrefix::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
-  StorePointer(&raw_ptr()->name_, value.raw());
+  raw_ptr()->set_name(value.raw());
 }
 
 void LibraryPrefix::set_imports(const Array& value) const {
-  StorePointer(&raw_ptr()->imports_, value.raw());
+  raw_ptr()->set_imports(value.raw());
 }
 
 void LibraryPrefix::set_num_imports(intptr_t value) const {
@@ -13445,7 +13231,7 @@
 }
 
 void LibraryPrefix::set_importer(const Library& value) const {
-  StorePointer(&raw_ptr()->importer_, value.raw());
+  raw_ptr()->set_importer(value.raw());
 }
 
 const char* LibraryPrefix::ToCString() const {
@@ -13453,55 +13239,8 @@
   return prefix.ToCString();
 }
 
-void Namespace::set_metadata_field(const Field& value) const {
-  StorePointer(&raw_ptr()->metadata_field_, value.raw());
-}
-
-void Namespace::AddMetadata(const Object& owner,
-                            TokenPosition token_pos,
-                            intptr_t kernel_offset) {
-  ASSERT(Field::Handle(metadata_field()).IsNull());
-  Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(),
-                                                  false,  // is_final
-                                                  false,  // is_const
-                                                  false,  // is_late
-                                                  owner, token_pos, token_pos));
-  field.set_is_reflectable(false);
-  field.SetFieldType(Object::dynamic_type());
-  field.SetStaticValue(Array::empty_array(), true);
-  field.set_kernel_offset(kernel_offset);
-  set_metadata_field(field);
-}
-
-ObjectPtr Namespace::GetMetadata() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  return Object::empty_array().raw();
-#else
-  Field& field = Field::Handle(metadata_field());
-  if (field.IsNull()) {
-    // There is no metadata for this object.
-    return Object::empty_array().raw();
-  }
-  Object& metadata = Object::Handle();
-  metadata = field.StaticValue();
-  if (field.StaticValue() == Object::empty_array().raw()) {
-    if (field.kernel_offset() > 0) {
-      metadata =
-          kernel::EvaluateMetadata(field, /* is_annotations_offset = */ true);
-    } else {
-      UNREACHABLE();
-    }
-    if (metadata.IsArray()) {
-      ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw());
-      field.SetStaticValue(Array::Cast(metadata), true);
-    }
-  }
-  return metadata.raw();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-}
-
 const char* Namespace::ToCString() const {
-  const Library& lib = Library::Handle(library());
+  const Library& lib = Library::Handle(target());
   return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'",
                      lib.ToCString());
 }
@@ -13555,7 +13294,7 @@
 ObjectPtr Namespace::Lookup(const String& name,
                             ZoneGrowableArray<intptr_t>* trail) const {
   Zone* zone = Thread::Current()->zone();
-  const Library& lib = Library::Handle(zone, library());
+  const Library& lib = Library::Handle(zone, target());
 
   if (trail != NULL) {
     // Look for cycle in reexport graph.
@@ -13616,15 +13355,17 @@
   return static_cast<NamespacePtr>(raw);
 }
 
-NamespacePtr Namespace::New(const Library& library,
+NamespacePtr Namespace::New(const Library& target,
                             const Array& show_names,
-                            const Array& hide_names) {
+                            const Array& hide_names,
+                            const Library& owner) {
   ASSERT(show_names.IsNull() || (show_names.Length() > 0));
   ASSERT(hide_names.IsNull() || (hide_names.Length() > 0));
   const Namespace& result = Namespace::Handle(Namespace::New());
-  result.StorePointer(&result.raw_ptr()->library_, library.raw());
-  result.StorePointer(&result.raw_ptr()->show_names_, show_names.raw());
-  result.StorePointer(&result.raw_ptr()->hide_names_, hide_names.raw());
+  result.raw_ptr()->set_target(target.raw());
+  result.raw_ptr()->set_show_names(show_names.raw());
+  result.raw_ptr()->set_hide_names(hide_names.raw());
+  result.raw_ptr()->set_owner(owner.raw());
   return result.raw();
 }
 
@@ -13649,19 +13390,16 @@
     const uint32_t binary_version) {
   const KernelProgramInfo& info =
       KernelProgramInfo::Handle(KernelProgramInfo::New());
-  info.StorePointer(&info.raw_ptr()->string_offsets_, string_offsets.raw());
-  info.StorePointer(&info.raw_ptr()->string_data_, string_data.raw());
-  info.StorePointer(&info.raw_ptr()->canonical_names_, canonical_names.raw());
-  info.StorePointer(&info.raw_ptr()->metadata_payloads_,
-                    metadata_payloads.raw());
-  info.StorePointer(&info.raw_ptr()->metadata_mappings_,
-                    metadata_mappings.raw());
-  info.StorePointer(&info.raw_ptr()->scripts_, scripts.raw());
-  info.StorePointer(&info.raw_ptr()->constants_table_, constants_table.raw());
-  info.StorePointer(&info.raw_ptr()->libraries_cache_, libraries_cache.raw());
-  info.StorePointer(&info.raw_ptr()->classes_cache_, classes_cache.raw());
-  info.StorePointer(&info.raw_ptr()->retained_kernel_blob_,
-                    retained_kernel_blob.raw());
+  info.raw_ptr()->set_string_offsets(string_offsets.raw());
+  info.raw_ptr()->set_string_data(string_data.raw());
+  info.raw_ptr()->set_canonical_names(canonical_names.raw());
+  info.raw_ptr()->set_metadata_payloads(metadata_payloads.raw());
+  info.raw_ptr()->set_metadata_mappings(metadata_mappings.raw());
+  info.raw_ptr()->set_scripts(scripts.raw());
+  info.raw_ptr()->set_constants_table(constants_table.raw());
+  info.raw_ptr()->set_libraries_cache(libraries_cache.raw());
+  info.raw_ptr()->set_classes_cache(classes_cache.raw());
+  info.raw_ptr()->set_retained_kernel_blob(retained_kernel_blob.raw());
   info.set_kernel_binary_version(binary_version);
   return info.raw();
 }
@@ -13677,11 +13415,11 @@
 }
 
 void KernelProgramInfo::set_scripts(const Array& scripts) const {
-  StorePointer(&raw_ptr()->scripts_, scripts.raw());
+  raw_ptr()->set_scripts(scripts.raw());
 }
 
 void KernelProgramInfo::set_constants(const Array& constants) const {
-  StorePointer(&raw_ptr()->constants_, constants.raw());
+  raw_ptr()->set_constants(constants.raw());
 }
 
 void KernelProgramInfo::set_kernel_binary_version(uint32_t version) const {
@@ -13690,21 +13428,21 @@
 
 void KernelProgramInfo::set_constants_table(
     const ExternalTypedData& value) const {
-  StorePointer(&raw_ptr()->constants_table_, value.raw());
+  raw_ptr()->set_constants_table(value.raw());
 }
 
 void KernelProgramInfo::set_potential_natives(
     const GrowableObjectArray& candidates) const {
-  StorePointer(&raw_ptr()->potential_natives_, candidates.raw());
+  raw_ptr()->set_potential_natives(candidates.raw());
 }
 
 void KernelProgramInfo::set_potential_pragma_functions(
     const GrowableObjectArray& candidates) const {
-  StorePointer(&raw_ptr()->potential_pragma_functions_, candidates.raw());
+  raw_ptr()->set_potential_pragma_functions(candidates.raw());
 }
 
 void KernelProgramInfo::set_libraries_cache(const Array& cache) const {
-  StorePointer(&raw_ptr()->libraries_cache_, cache.raw());
+  raw_ptr()->set_libraries_cache(cache.raw());
 }
 
 typedef UnorderedHashMap<SmiTraits> IntHashMap;
@@ -13720,8 +13458,8 @@
   Object& key = thread->ObjectHandle();
   Smi& value = thread->SmiHandle();
   {
-    Isolate* isolate = thread->isolate();
-    SafepointMutexLocker ml(isolate->kernel_data_lib_cache_mutex());
+    SafepointMutexLocker ml(
+        thread->isolate_group()->kernel_data_lib_cache_mutex());
     data = libraries_cache();
     ASSERT(!data.IsNull());
     IntHashMap table(&key, &value, &data);
@@ -13743,8 +13481,8 @@
   Object& key = thread->ObjectHandle();
   Smi& value = thread->SmiHandle();
   {
-    Isolate* isolate = thread->isolate();
-    SafepointMutexLocker ml(isolate->kernel_data_lib_cache_mutex());
+    SafepointMutexLocker ml(
+        thread->isolate_group()->kernel_data_lib_cache_mutex());
     data = libraries_cache();
     ASSERT(!data.IsNull());
     IntHashMap table(&key, &value, &data);
@@ -13755,7 +13493,7 @@
 }
 
 void KernelProgramInfo::set_classes_cache(const Array& cache) const {
-  StorePointer(&raw_ptr()->classes_cache_, cache.raw());
+  raw_ptr()->set_classes_cache(cache.raw());
 }
 
 ClassPtr KernelProgramInfo::LookupClass(Thread* thread,
@@ -13769,8 +13507,8 @@
   Object& key = thread->ObjectHandle();
   Smi& value = thread->SmiHandle();
   {
-    Isolate* isolate = thread->isolate();
-    SafepointMutexLocker ml(isolate->kernel_data_class_cache_mutex());
+    SafepointMutexLocker ml(
+        thread->isolate_group()->kernel_data_class_cache_mutex());
     data = classes_cache();
     ASSERT(!data.IsNull());
     IntHashMap table(&key, &value, &data);
@@ -13792,8 +13530,8 @@
   Object& key = thread->ObjectHandle();
   Smi& value = thread->SmiHandle();
   {
-    Isolate* isolate = thread->isolate();
-    SafepointMutexLocker ml(isolate->kernel_data_class_cache_mutex());
+    SafepointMutexLocker ml(
+        thread->isolate_group()->kernel_data_class_cache_mutex());
     data = classes_cache();
     ASSERT(!data.IsNull());
     IntHashMap table(&key, &value, &data);
@@ -13951,22 +13689,31 @@
   Function& func = Function::Handle();
   bool fingerprints_match = true;
 
-#define CHECK_FINGERPRINTS(class_name, function_name, dest, fp)                \
+#define CHECK_FINGERPRINTS_INNER(class_name, function_name, dest, fp, kind)    \
   func = GetFunction(all_libs, #class_name, #function_name);                   \
   if (func.IsNull()) {                                                         \
     fingerprints_match = false;                                                \
     OS::PrintErr("Function not found %s.%s\n", #class_name, #function_name);   \
   } else {                                                                     \
     fingerprints_match =                                                       \
-        func.CheckSourceFingerprint(fp) && fingerprints_match;                 \
+        func.CheckSourceFingerprint(fp, kind) && fingerprints_match;           \
   }
 
-#define CHECK_FINGERPRINTS2(class_name, function_name, dest, fp)               \
-  CHECK_FINGERPRINTS(class_name, function_name, dest, fp)
+#define CHECK_FINGERPRINTS(class_name, function_name, dest, fp)                \
+  CHECK_FINGERPRINTS_INNER(class_name, function_name, dest, fp, nullptr)
+#define CHECK_FINGERPRINTS_ASM_INTRINSIC(class_name, function_name, dest, fp)  \
+  CHECK_FINGERPRINTS_INNER(class_name, function_name, dest, fp, "asm-intrinsic")
+#define CHECK_FINGERPRINTS_GRAPH_INTRINSIC(class_name, function_name, dest,    \
+                                           fp)                                 \
+  CHECK_FINGERPRINTS_INNER(class_name, function_name, dest, fp,                \
+                           "graph-intrinsic")
+#define CHECK_FINGERPRINTS_OTHER(class_name, function_name, dest, fp)          \
+  CHECK_FINGERPRINTS_INNER(class_name, function_name, dest, fp, "other")
 
   all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary()));
-  CORE_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
-  CORE_INTEGER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
+  CORE_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC);
+  CORE_INTEGER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC);
+  GRAPH_CORE_INTRINSICS_LIST(CHECK_FINGERPRINTS_GRAPH_INTRINSIC);
 
   all_libs.Add(&Library::ZoneHandle(Library::AsyncLibrary()));
   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
@@ -13975,21 +13722,25 @@
   all_libs.Add(&Library::ZoneHandle(Library::ConvertLibrary()));
   all_libs.Add(&Library::ZoneHandle(Library::InternalLibrary()));
   all_libs.Add(&Library::ZoneHandle(Library::FfiLibrary()));
-  ASYNC_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
-  INTERNAL_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
-  OTHER_RECOGNIZED_LIST(CHECK_FINGERPRINTS2);
+  INTERNAL_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC);
+  OTHER_RECOGNIZED_LIST(CHECK_FINGERPRINTS_OTHER);
   POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS);
+  GRAPH_TYPED_DATA_INTRINSICS_LIST(CHECK_FINGERPRINTS_GRAPH_INTRINSIC);
 
   all_libs.Clear();
   all_libs.Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
-  DEVELOPER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
+  DEVELOPER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC);
 
   all_libs.Clear();
   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
-  MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
+  MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC);
+  GRAPH_MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_GRAPH_INTRINSIC);
 
+#undef CHECK_FINGERPRINTS_INNER
 #undef CHECK_FINGERPRINTS
-#undef CHECK_FINGERPRINTS2
+#undef CHECK_FINGERPRINTS_ASM_INTRINSIC
+#undef CHECK_FINGERPRINTS_GRAPH_INTRINSIC
+#undef CHECK_FINGERPRINTS_OTHER
 
 #define CHECK_FACTORY_FINGERPRINTS(symbol, class_name, factory_name, cid, fp)  \
   func = GetFunction(all_libs, #class_name, #factory_name);                    \
@@ -14495,7 +14246,7 @@
     if (!first_entry) {
       buffer->AddString(separator);
     }
-    buffer->Printf("0x%0.8" Px32 ": ", it.pc_offset());
+    buffer->Printf("0x%.8" Px32 ": ", it.pc_offset());
     for (intptr_t i = 0, n = it.Length(); i < n; i++) {
       buffer->AddString(it.IsObject(i) ? "1" : "0");
     }
@@ -14748,19 +14499,19 @@
   ASSERT((try_index >= 0) && (try_index < num_entries()));
   ASSERT(!handled_types.IsNull());
   const Array& handled_types_data =
-      Array::Handle(raw_ptr()->handled_types_data_);
+      Array::Handle(raw_ptr()->handled_types_data());
   handled_types_data.SetAt(try_index, handled_types);
 }
 
 ArrayPtr ExceptionHandlers::GetHandledTypes(intptr_t try_index) const {
   ASSERT((try_index >= 0) && (try_index < num_entries()));
-  Array& array = Array::Handle(raw_ptr()->handled_types_data_);
+  Array& array = Array::Handle(raw_ptr()->handled_types_data());
   array ^= array.At(try_index);
   return array.raw();
 }
 
 void ExceptionHandlers::set_handled_types_data(const Array& value) const {
-  StorePointer(&raw_ptr()->handled_types_data_, value.raw());
+  raw_ptr()->set_handled_types_data(value.raw());
 }
 
 ExceptionHandlersPtr ExceptionHandlers::New(intptr_t num_handlers) {
@@ -14862,7 +14613,7 @@
 }
 
 void SingleTargetCache::set_target(const Code& value) const {
-  StorePointer(&raw_ptr()->target_, value.raw());
+  raw_ptr()->set_target(value.raw());
 }
 
 const char* SingleTargetCache::ToCString() const {
@@ -14918,7 +14669,7 @@
   result ^=
       Object::Allocate(MonomorphicSmiableCall::kClassId,
                        MonomorphicSmiableCall::InstanceSize(), Heap::kOld);
-  result.StorePointer(&result.raw_ptr()->target_, target.raw());
+  result.raw_ptr()->set_target(target.raw());
   result.StoreNonPointer(&result.raw_ptr()->expected_cid_, expected_cid);
   result.StoreNonPointer(&result.raw_ptr()->entrypoint_, target.EntryPoint());
   return result.raw();
@@ -14936,17 +14687,17 @@
 
 void CallSiteData::set_target_name(const String& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->target_name_, value.raw());
+  raw_ptr()->set_target_name(value.raw());
 }
 
 void CallSiteData::set_arguments_descriptor(const Array& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+  raw_ptr()->set_args_descriptor(value.raw());
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 void ICData::SetReceiversStaticType(const AbstractType& type) const {
-  StorePointer(&raw_ptr()->receivers_static_type_, type.raw());
+  raw_ptr()->set_receivers_static_type(type.raw());
 
 #if defined(TARGET_ARCH_X64)
   if (!type.IsNull() && type.HasTypeClass() && (NumArgsTested() == 1) &&
@@ -14960,6 +14711,24 @@
 }
 #endif
 
+void ICData::SetTargetAtPos(const Array& data,
+                            intptr_t data_pos,
+                            intptr_t num_args_tested,
+                            const Function& target) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // JIT
+  data.SetAt(data_pos + TargetIndexFor(num_args_tested), target);
+#else
+  // AOT
+  ASSERT(target.HasCode());
+  const Code& code = Code::Handle(target.CurrentCode());
+  const Smi& entry_point =
+      Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
+  data.SetAt(data_pos + CodeIndexFor(num_args_tested), code);
+  data.SetAt(data_pos + EntryPointIndexFor(num_args_tested), entry_point);
+#endif
+}
+
 const char* ICData::ToCString() const {
   Zone* zone = Thread::Current()->zone();
   const String& name = String::Handle(zone, target_name());
@@ -14972,7 +14741,7 @@
 }
 
 FunctionPtr ICData::Owner() const {
-  Object& obj = Object::Handle(raw_ptr()->owner_);
+  Object& obj = Object::Handle(raw_ptr()->owner());
   if (obj.IsNull()) {
     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT);
     return Function::null();
@@ -14989,7 +14758,7 @@
   if (IsNull()) {
     return ICData::null();
   }
-  Object& obj = Object::Handle(raw_ptr()->owner_);
+  Object& obj = Object::Handle(raw_ptr()->owner());
   if (obj.IsFunction()) {
     return this->raw();
   } else {
@@ -15000,11 +14769,11 @@
 void ICData::SetOriginal(const ICData& value) const {
   ASSERT(value.IsOriginal());
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
+  raw_ptr()->set_owner(static_cast<ObjectPtr>(value.raw()));
 }
 
 void ICData::set_owner(const Function& value) const {
-  StorePointer(&raw_ptr()->owner_, static_cast<ObjectPtr>(value.raw()));
+  raw_ptr()->set_owner(static_cast<ObjectPtr>(value.raw()));
 }
 
 void ICData::set_deopt_id(intptr_t value) const {
@@ -15018,8 +14787,7 @@
 
 void ICData::set_entries(const Array& value) const {
   ASSERT(!value.IsNull());
-  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->entries_,
-                                                    value.raw());
+  raw_ptr()->set_entries<std::memory_order_release>(value.raw());
 }
 
 intptr_t ICData::NumArgsTested() const {
@@ -15032,27 +14800,27 @@
                   NumArgsTestedBits::update(value, raw_ptr()->state_bits_));
 }
 
-intptr_t ICData::TypeArgsLen() const {
+intptr_t CallSiteData::TypeArgsLen() const {
   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
   return args_desc.TypeArgsLen();
 }
 
-intptr_t ICData::CountWithTypeArgs() const {
+intptr_t CallSiteData::CountWithTypeArgs() const {
   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
   return args_desc.CountWithTypeArgs();
 }
 
-intptr_t ICData::CountWithoutTypeArgs() const {
+intptr_t CallSiteData::CountWithoutTypeArgs() const {
   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
   return args_desc.Count();
 }
 
-intptr_t ICData::SizeWithoutTypeArgs() const {
+intptr_t CallSiteData::SizeWithoutTypeArgs() const {
   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
   return args_desc.Size();
 }
 
-intptr_t ICData::SizeWithTypeArgs() const {
+intptr_t CallSiteData::SizeWithTypeArgs() const {
   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
   return args_desc.SizeWithTypeArgs();
 }
@@ -15128,7 +14896,7 @@
 }
 
 intptr_t ICData::Length() const {
-  return (Smi::Value(entries()->ptr()->length_) / TestEntryLength());
+  return (Smi::Value(entries()->ptr()->length()) / TestEntryLength());
 }
 
 intptr_t ICData::NumberOfChecks() const {
@@ -15186,8 +14954,8 @@
 
 intptr_t ICData::FindCheck(const GrowableArray<intptr_t>& cids) const {
   const intptr_t len = NumberOfChecks();
+  GrowableArray<intptr_t> class_ids;
   for (intptr_t i = 0; i < len; i++) {
-    GrowableArray<intptr_t> class_ids;
     GetClassIdsAt(i, &class_ids);
     bool matches = true;
     for (intptr_t k = 0; k < class_ids.length(); k++) {
@@ -15204,11 +14972,14 @@
   return -1;
 }
 
-void ICData::WriteSentinelAt(intptr_t index) const {
+void ICData::WriteSentinelAt(intptr_t index,
+                             const CallSiteResetter& proof_of_reload) const {
+  USE(proof_of_reload);  // This method can only be called during reload.
+
+  Thread* thread = Thread::Current();
   const intptr_t len = Length();
   ASSERT(index >= 0);
   ASSERT(index < len);
-  Thread* thread = Thread::Current();
   REUSABLE_ARRAY_HANDLESCOPE(thread);
   Array& data = thread->ArrayHandle();
   data = entries();
@@ -15219,13 +14990,20 @@
   }
 }
 
-void ICData::ClearCountAt(intptr_t index) const {
+void ICData::ClearCountAt(intptr_t index,
+                          const CallSiteResetter& proof_of_reload) const {
+  USE(proof_of_reload);  // This method can only be called during reload.
+
   ASSERT(index >= 0);
   ASSERT(index < NumberOfChecks());
   SetCountAt(index, 0);
 }
 
-void ICData::ClearAndSetStaticTarget(const Function& func) const {
+void ICData::ClearAndSetStaticTarget(
+    const Function& func,
+    const CallSiteResetter& proof_of_reload) const {
+  USE(proof_of_reload);  // This method can only be called during reload.
+
   if (IsImmutable()) {
     return;
   }
@@ -15233,12 +15011,13 @@
   if (len == 0) {
     return;
   }
+  Thread* thread = Thread::Current();
+
   // The final entry is always the sentinel.
   ASSERT(IsSentinelAt(len - 1));
   const intptr_t num_args_tested = NumArgsTested();
   if (num_args_tested == 0) {
     // No type feedback is being collected.
-    Thread* thread = Thread::Current();
     REUSABLE_ARRAY_HANDLESCOPE(thread);
     Array& data = thread->ArrayHandle();
     data = entries();
@@ -15256,9 +15035,8 @@
     // Type feedback on arguments is being collected.
     // Fill all but the first entry with the sentinel.
     for (intptr_t i = len - 1; i > 0; i--) {
-      WriteSentinelAt(i);
+      WriteSentinelAt(i, proof_of_reload);
     }
-    Thread* thread = Thread::Current();
     REUSABLE_ARRAY_HANDLESCOPE(thread);
     Array& data = thread->ArrayHandle();
     data = entries();
@@ -15272,84 +15050,6 @@
   }
 }
 
-// Add an initial Smi/Smi check with count 0.
-bool ICData::AddSmiSmiCheckForFastSmiStubs() const {
-  bool is_smi_two_args_op = false;
-
-  ASSERT(NumArgsTested() == 2);
-  Zone* zone = Thread::Current()->zone();
-  const String& name = String::Handle(zone, target_name());
-  const Class& smi_class = Class::Handle(zone, Smi::Class());
-  Function& smi_op_target = Function::Handle(
-      zone, Resolver::ResolveDynamicAnyArgs(zone, smi_class, name));
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  if (smi_op_target.IsNull() &&
-      Function::IsDynamicInvocationForwarderName(name)) {
-    const String& demangled = String::Handle(
-        zone, Function::DemangleDynamicInvocationForwarderName(name));
-    smi_op_target = Resolver::ResolveDynamicAnyArgs(zone, smi_class, demangled);
-  }
-#endif
-
-  if (NumberOfChecksIs(0)) {
-    GrowableArray<intptr_t> class_ids(2);
-    class_ids.Add(kSmiCid);
-    class_ids.Add(kSmiCid);
-    AddCheck(class_ids, smi_op_target);
-    // 'AddCheck' sets the initial count to 1.
-    SetCountAt(0, 0);
-    is_smi_two_args_op = true;
-  } else if (NumberOfChecksIs(1)) {
-    GrowableArray<intptr_t> class_ids(2);
-    Function& target = Function::Handle();
-    GetCheckAt(0, &class_ids, &target);
-    if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) &&
-        (class_ids[1] == kSmiCid)) {
-      is_smi_two_args_op = true;
-    }
-  }
-  return is_smi_two_args_op;
-}
-
-// Used for unoptimized static calls when no class-ids are checked.
-void ICData::AddTarget(const Function& target) const {
-  ASSERT(!target.IsNull());
-  if (NumArgsTested() > 0) {
-    // Create a fake cid entry, so that we can store the target.
-    if (NumArgsTested() == 1) {
-      AddReceiverCheck(kObjectCid, target, 1);
-    } else {
-      GrowableArray<intptr_t> class_ids(NumArgsTested());
-      for (intptr_t i = 0; i < NumArgsTested(); i++) {
-        class_ids.Add(kObjectCid);
-      }
-      AddCheck(class_ids, target);
-    }
-    return;
-  }
-  ASSERT(NumArgsTested() == 0);
-  // Can add only once.
-  const intptr_t old_num = NumberOfChecks();
-  ASSERT(old_num == 0);
-  Thread* thread = Thread::Current();
-  REUSABLE_ARRAY_HANDLESCOPE(thread);
-  Array& data = thread->ArrayHandle();
-  data = entries();
-  const intptr_t new_len = data.Length() + TestEntryLength();
-  data = Array::Grow(data, new_len, Heap::kOld);
-  WriteSentinel(data, TestEntryLength());
-  intptr_t data_pos = old_num * TestEntryLength();
-  ASSERT(!target.IsNull());
-  data.SetAt(data_pos + TargetIndexFor(NumArgsTested()), target);
-  // Set count to 0 as this is called during compilation, before the
-  // call has been executed.
-  data.SetAt(data_pos + CountIndexFor(NumArgsTested()), Object::smi_zero());
-  // Multithreaded access to ICData requires setting of array to be the last
-  // operation.
-  set_entries(data);
-}
-
 bool ICData::ValidateInterceptor(const Function& target) const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   const String& name = String::Handle(target_name());
@@ -15367,9 +15067,28 @@
   return true;
 }
 
+void ICData::EnsureHasCheck(const GrowableArray<intptr_t>& class_ids,
+                            const Function& target,
+                            intptr_t count) const {
+  SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
+
+  if (FindCheck(class_ids) != -1) return;
+  AddCheckInternal(class_ids, target, count);
+}
+
 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
                       const Function& target,
                       intptr_t count) const {
+  SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
+  AddCheckInternal(class_ids, target, count);
+}
+
+void ICData::AddCheckInternal(const GrowableArray<intptr_t>& class_ids,
+                              const Function& target,
+                              intptr_t count) const {
+  ASSERT(
+      IsolateGroup::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
   ASSERT(!is_tracking_exactness());
   ASSERT(!target.IsNull());
   ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
@@ -15379,17 +15098,14 @@
   ASSERT(class_ids.length() == num_args_tested);
   const intptr_t old_num = NumberOfChecks();
   Array& data = Array::Handle(entries());
+
   // ICData of static calls with NumArgsTested() > 0 have initially a
-  // dummy set of cids entered (see ICData::AddTarget). That entry is
+  // dummy set of cids entered (see ICData::NewForStaticCall). That entry is
   // overwritten by first real type feedback data.
-  if (old_num == 1) {
-    bool has_dummy_entry = true;
-    for (intptr_t i = 0; i < num_args_tested; i++) {
-      if (Smi::Value(Smi::RawCast(data.At(i))) != kObjectCid) {
-        has_dummy_entry = false;
-        break;
-      }
-    }
+  if (old_num == 1 && num_args_tested == 2) {
+    const bool has_dummy_entry =
+        Smi::Value(Smi::RawCast(data.At(0))) == kObjectCid &&
+        Smi::Value(Smi::RawCast(data.At(1))) == kObjectCid;
     if (has_dummy_entry) {
       ASSERT(target.raw() == data.At(TargetIndexFor(num_args_tested)));
       // Replace dummy entry.
@@ -15455,10 +15171,32 @@
   }
 }
 
+void ICData::EnsureHasReceiverCheck(intptr_t receiver_class_id,
+                                    const Function& target,
+                                    intptr_t count,
+                                    StaticTypeExactnessState exactness) const {
+  SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
+
+  GrowableArray<intptr_t> class_ids(1);
+  class_ids.Add(receiver_class_id);
+  if (FindCheck(class_ids) != -1) return;
+
+  AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
+}
+
 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
                               const Function& target,
                               intptr_t count,
                               StaticTypeExactnessState exactness) const {
+  SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
+  AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
+}
+
+void ICData::AddReceiverCheckInternal(
+    intptr_t receiver_class_id,
+    const Function& target,
+    intptr_t count,
+    StaticTypeExactnessState exactness) const {
 #if defined(DEBUG)
   GrowableArray<intptr_t> class_ids(1);
   class_ids.Add(receiver_class_id);
@@ -15482,24 +15220,15 @@
     data_pos = 0;
   }
   data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
+  SetTargetAtPos(data, data_pos, kNumArgsTested, target);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  // JIT
-  data.SetAt(data_pos + TargetIndexFor(kNumArgsTested), target);
   data.SetAt(data_pos + CountIndexFor(kNumArgsTested),
              Smi::Handle(Smi::New(count)));
   if (is_tracking_exactness()) {
     data.SetAt(data_pos + ExactnessIndexFor(kNumArgsTested),
                Smi::Handle(Smi::New(exactness.Encode())));
   }
-#else
-  // AOT
-  ASSERT(target.HasCode());
-  const Code& code = Code::Handle(target.CurrentCode());
-  const Smi& entry_point =
-      Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
-  data.SetAt(data_pos + CodeIndexFor(kNumArgsTested), code);
-  data.SetAt(data_pos + EntryPointIndexFor(kNumArgsTested), entry_point);
 #endif
 
   // Multithreaded access to ICData requires setting of array to be the last
@@ -15627,15 +15356,6 @@
 #endif
 }
 
-ObjectPtr ICData::GetTargetOrCodeAt(intptr_t index) const {
-  const intptr_t data_pos =
-      index * TestEntryLength() + TargetIndexFor(NumArgsTested());
-
-  NoSafepointScope no_safepoint;
-  ArrayPtr raw_data = entries();
-  return raw_data->ptr()->data()[data_pos];
-}
-
 void ICData::IncrementCountAt(intptr_t index, intptr_t value) const {
   ASSERT(0 <= value);
   ASSERT(value <= Smi::kMaxValue);
@@ -15686,46 +15406,7 @@
   return count;
 }
 
-void ICData::SetCodeAt(intptr_t index, const Code& value) const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  UNREACHABLE();
-#else
-  Thread* thread = Thread::Current();
-  REUSABLE_ARRAY_HANDLESCOPE(thread);
-  Array& data = thread->ArrayHandle();
-  data = entries();
-  const intptr_t data_pos =
-      index * TestEntryLength() + CodeIndexFor(NumArgsTested());
-  data.SetAt(data_pos, value);
-#endif
-}
-
-void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  UNREACHABLE();
-#else
-  Thread* thread = Thread::Current();
-  REUSABLE_ARRAY_HANDLESCOPE(thread);
-  Array& data = thread->ArrayHandle();
-  data = entries();
-  const intptr_t data_pos =
-      index * TestEntryLength() + EntryPointIndexFor(NumArgsTested());
-  data.SetAt(data_pos, value);
-#endif
-}
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-ICDataPtr ICData::AsUnaryClassChecksForCid(intptr_t cid,
-                                           const Function& target) const {
-  ASSERT(!IsNull());
-  const intptr_t kNumArgsTested = 1;
-  ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
-
-  // Copy count so that we copy the state "count == 0" vs "count > 0".
-  result.AddReceiverCheck(cid, target, GetCountAt(0));
-  return result.raw();
-}
-
 ICDataPtr ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
   ASSERT(!IsNull());
   ASSERT(NumArgsTested() > arg_nr);
@@ -15757,8 +15438,9 @@
       result.IncrementCountAt(duplicate_class_id, count);
     } else {
       // This will make sure that Smi is first if it exists.
-      result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)),
-                              count);
+      result.AddReceiverCheckInternal(class_id,
+                                      Function::Handle(GetTargetAt(i)), count,
+                                      StaticTypeExactnessState::NotTracking());
     }
   }
 
@@ -15993,6 +15675,69 @@
   return result.raw();
 }
 
+ICDataPtr ICData::NewWithCheck(const Function& owner,
+                               const String& target_name,
+                               const Array& arguments_descriptor,
+                               intptr_t deopt_id,
+                               intptr_t num_args_tested,
+                               RebindRule rebind_rule,
+                               GrowableArray<intptr_t>* cids,
+                               const Function& target,
+                               const AbstractType& receiver_type) {
+  ASSERT((cids != nullptr) && !target.IsNull());
+  ASSERT(cids->length() == num_args_tested);
+
+  Zone* zone = Thread::Current()->zone();
+  const auto& result = ICData::Handle(
+      zone,
+      NewDescriptor(zone, owner, target_name, arguments_descriptor, deopt_id,
+                    num_args_tested, rebind_rule, receiver_type));
+
+  const intptr_t kNumEntries = 2;  // 1 entry and a sentinel.
+  const intptr_t entry_len =
+      TestEntryLengthFor(num_args_tested, result.is_tracking_exactness());
+  const auto& array =
+      Array::Handle(zone, Array::New(kNumEntries * entry_len, Heap::kOld));
+
+  auto& cid = Smi::Handle(zone);
+  for (intptr_t i = 0; i < num_args_tested; ++i) {
+    cid = Smi::New((*cids)[i]);
+    array.SetAt(i, cid);
+  }
+
+  SetTargetAtPos(array, 0, num_args_tested, target);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  array.SetAt(CountIndexFor(num_args_tested), Object::smi_zero());
+#endif
+  WriteSentinel(array, entry_len);
+
+  result.set_entries(array);
+
+  return result.raw();
+}
+
+ICDataPtr ICData::NewForStaticCall(const Function& owner,
+                                   const Function& target,
+                                   const Array& arguments_descriptor,
+                                   intptr_t deopt_id,
+                                   intptr_t num_args_tested,
+                                   RebindRule rebind_rule) {
+  // See `MethodRecognizer::NumArgsCheckedForStaticCall`.
+  ASSERT(num_args_tested == 0 || num_args_tested == 2);
+  ASSERT(!target.IsNull());
+
+  Zone* zone = Thread::Current()->zone();
+  const auto& target_name = String::Handle(zone, target.name());
+  GrowableArray<intptr_t> cids(num_args_tested);
+  if (num_args_tested == 2) {
+    cids.Add(kObjectCid);
+    cids.Add(kObjectCid);
+  }
+  return ICData::NewWithCheck(owner, target_name, arguments_descriptor,
+                              deopt_id, num_args_tested, rebind_rule, &cids,
+                              target, Object::null_abstract_type());
+}
+
 #if !defined(DART_PRECOMPILED_RUNTIME)
 ICDataPtr ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
   // See comment in [ICData::Clone] why we access the megamorphic bit first.
@@ -16076,7 +15821,7 @@
     NoSafepointScope no_safepoint;
 
     result ^= raw;
-    result.StorePointer(&result.raw_ptr()->target_, target.raw());
+    result.raw_ptr()->set_target(target.raw());
   }
   return result.raw();
 }
@@ -16177,7 +15922,7 @@
   ASSERT(unwrapped_owner.IsFunction() || unwrapped_owner.IsClass() ||
          unwrapped_owner.IsAbstractType());
 #endif
-  StorePointer(&raw_ptr()->owner_, owner.raw());
+  raw_ptr()->set_owner(owner.raw());
 }
 
 void Code::set_state_bits(intptr_t bits) const {
@@ -16198,31 +15943,28 @@
 
 void Code::set_compressed_stackmaps(const CompressedStackMaps& maps) const {
   ASSERT(maps.IsOld());
-  StorePointer(&raw_ptr()->compressed_stackmaps_, maps.raw());
+  raw_ptr()->set_compressed_stackmaps(maps.raw());
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 intptr_t Code::num_variables() const {
   ASSERT(!FLAG_precompiled_mode);
-  return Smi::Value(Smi::RawCast(raw_ptr()->catch_entry_));
+  return Smi::Value(Smi::RawCast(raw_ptr()->catch_entry()));
 }
 void Code::set_num_variables(intptr_t num_variables) const {
   ASSERT(!FLAG_precompiled_mode);
-  // Object::RawCast is needed for StorePointer template argument resolution.
-  StorePointer(&raw_ptr()->catch_entry_,
-               Object::RawCast(Smi::New(num_variables)));
+  raw_ptr()->set_catch_entry(Smi::New(num_variables));
 }
 #endif
 
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
 TypedDataPtr Code::catch_entry_moves_maps() const {
   ASSERT(FLAG_precompiled_mode);
-  return TypedData::RawCast(raw_ptr()->catch_entry_);
+  return TypedData::RawCast(raw_ptr()->catch_entry());
 }
 void Code::set_catch_entry_moves_maps(const TypedData& maps) const {
   ASSERT(FLAG_precompiled_mode);
-  // Object::RawCast is needed for StorePointer template argument resolution.
-  StorePointer(&raw_ptr()->catch_entry_, Object::RawCast(maps.raw()));
+  raw_ptr()->set_catch_entry(maps.raw());
 }
 #endif
 
@@ -16231,7 +15973,7 @@
   UNREACHABLE();
 #else
   ASSERT(array.IsOld());
-  StorePointer(&raw_ptr()->deopt_info_array_, array.raw());
+  raw_ptr()->set_deopt_info_array(array.raw());
 #endif
 }
 
@@ -16239,7 +15981,7 @@
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
 #else
-  StorePointer(&raw_ptr()->static_calls_target_table_, value.raw());
+  raw_ptr()->set_static_calls_target_table(value.raw());
 #endif
 #if defined(DEBUG)
   // Check that the table is sorted by pc offsets.
@@ -16312,7 +16054,7 @@
   UNREACHABLE();
 #else
   NoSafepointScope no_safepoint;
-  const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_);
+  const Array& table = Array::Handle(raw_ptr()->static_calls_target_table());
   StaticCallsTable entries(table);
   const intptr_t pc_offset = pc - PayloadStart();
   intptr_t imin = 0;
@@ -16342,7 +16084,7 @@
   if (i < 0) {
     return Function::null();
   }
-  const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_);
+  const Array& array = Array::Handle(raw_ptr()->static_calls_target_table());
   StaticCallsTable entries(array);
   return entries[i].Get<kSCallTableFunctionTarget>();
 #endif
@@ -16354,7 +16096,7 @@
 #else
   const intptr_t i = BinarySearchInSCallTable(pc);
   ASSERT(i >= 0);
-  const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_);
+  const Array& array = Array::Handle(raw_ptr()->static_calls_target_table());
   StaticCallsTable entries(array);
   ASSERT(code.IsNull() ||
          (code.function() == entries[i].Get<kSCallTableFunctionTarget>()));
@@ -16368,7 +16110,7 @@
 #else
   const intptr_t i = BinarySearchInSCallTable(pc);
   ASSERT(i >= 0);
-  const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_);
+  const Array& array = Array::Handle(raw_ptr()->static_calls_target_table());
   StaticCallsTable entries(array);
 #if defined(DEBUG)
   if (entries[i].Get<kSCallTableFunctionTarget>() == Function::null()) {
@@ -16400,7 +16142,7 @@
 #if defined(PRODUCT)
   Comments* comments = new Code::Comments(Array::Handle());
 #else
-  Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_));
+  Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments()));
 #endif
   return *comments;
 }
@@ -16410,7 +16152,7 @@
   UNREACHABLE();
 #else
   ASSERT(comments.comments_.IsOld());
-  StorePointer(&raw_ptr()->comments_, comments.comments_.raw());
+  raw_ptr()->set_comments(comments.comments_.raw());
 #endif
 }
 
@@ -16419,9 +16161,7 @@
   UNREACHABLE();
 #else
   ASSERT(offset >= 0);
-  StoreSmi(
-      reinterpret_cast<SmiPtr const*>(&raw_ptr()->return_address_metadata_),
-      Smi::New(offset));
+  raw_ptr()->set_return_address_metadata(Smi::New(offset));
 #endif
 }
 
@@ -16430,7 +16170,7 @@
   UNREACHABLE();
   return -1;
 #else
-  const Object& object = Object::Handle(raw_ptr()->return_address_metadata_);
+  const Object& object = Object::Handle(raw_ptr()->return_address_metadata());
   // In the future we may put something other than a smi in
   // |return_address_metadata_|.
   if (object.IsNull() || !object.IsSmi()) {
@@ -16441,12 +16181,12 @@
 }
 
 ArrayPtr Code::inlined_id_to_function() const {
-  return raw_ptr()->inlined_id_to_function_;
+  return raw_ptr()->inlined_id_to_function();
 }
 
 void Code::set_inlined_id_to_function(const Array& value) const {
   ASSERT(value.IsOld());
-  StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw());
+  raw_ptr()->set_inlined_id_to_function(value.raw());
 }
 
 CodePtr Code::New(intptr_t pointer_offsets_length) {
@@ -16887,7 +16627,7 @@
   DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive());
   // RawInstructions are never allocated in New space and hence a
   // store buffer update is not needed here.
-  StorePointer(&raw_ptr()->active_instructions_, instructions.raw());
+  raw_ptr()->set_active_instructions(instructions.raw());
   Code::InitializeCachedEntryPointsFrom(raw(), instructions.raw(),
                                         unchecked_offset);
 #endif
@@ -17195,22 +16935,22 @@
 }
 
 ArrayPtr MegamorphicCache::buckets() const {
-  return raw_ptr()->buckets_;
+  return raw_ptr()->buckets();
 }
 
 void MegamorphicCache::set_buckets(const Array& buckets) const {
-  StorePointer(&raw_ptr()->buckets_, buckets.raw());
+  raw_ptr()->set_buckets(buckets.raw());
 }
 
 // Class IDs in the table are smi-tagged, so we use a smi-tagged mask
 // and target class ID to avoid untagging (on each iteration of the
 // test loop) in generated code.
 intptr_t MegamorphicCache::mask() const {
-  return Smi::Value(raw_ptr()->mask_);
+  return Smi::Value(raw_ptr()->mask());
 }
 
 void MegamorphicCache::set_mask(intptr_t mask) const {
-  StoreSmi(&raw_ptr()->mask_, Smi::New(mask));
+  raw_ptr()->set_mask(Smi::New(mask));
 }
 
 intptr_t MegamorphicCache::filled_entry_count() const {
@@ -17259,23 +16999,91 @@
   return result.raw();
 }
 
-void MegamorphicCache::Insert(const Smi& class_id, const Object& target) const {
-  SafepointMutexLocker ml(Isolate::Current()->megamorphic_mutex());
-  EnsureCapacityLocked();
-  InsertLocked(class_id, target);
+void MegamorphicCache::EnsureContains(const Smi& class_id,
+                                      const Object& target) const {
+  SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
+
+  if (LookupLocked(class_id) == Object::null()) {
+    InsertLocked(class_id, target);
+  }
+
+#if defined(DEBUG)
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    if (target.IsFunction()) {
+      const auto& function = Function::Cast(target);
+      const auto& entry_point = Smi::Handle(
+          Smi::FromAlignedAddress(Code::EntryPointOf(function.CurrentCode())));
+      ASSERT(LookupLocked(class_id) == entry_point.raw());
+    }
+  } else {
+    ASSERT(LookupLocked(class_id) == target.raw());
+  }
+#endif  // define(DEBUG)
+}
+
+ObjectPtr MegamorphicCache::Lookup(const Smi& class_id) const {
+  SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
+  return LookupLocked(class_id);
+}
+
+ObjectPtr MegamorphicCache::LookupLocked(const Smi& class_id) const {
+  auto thread = Thread::Current();
+  auto isolate_group = thread->isolate_group();
+  auto zone = thread->zone();
+  ASSERT(thread->IsMutatorThread());
+  ASSERT(isolate_group->type_feedback_mutex()->IsOwnedByCurrentThread());
+
+  const auto& backing_array = Array::Handle(zone, buckets());
+  intptr_t id_mask = mask();
+  intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask;
+  intptr_t i = index;
+  do {
+    const classid_t current_cid =
+        Smi::Value(Smi::RawCast(GetClassId(backing_array, i)));
+    if (current_cid == class_id.Value()) {
+      return GetTargetFunction(backing_array, i);
+    } else if (current_cid == kIllegalCid) {
+      return Object::null();
+    }
+    i = (i + 1) & id_mask;
+  } while (i != index);
+  UNREACHABLE();
+}
+
+void MegamorphicCache::InsertLocked(const Smi& class_id,
+                                    const Object& target) const {
+  auto isolate_group = IsolateGroup::Current();
+  ASSERT(isolate_group->type_feedback_mutex()->IsOwnedByCurrentThread());
+
+  // As opposed to ICData we are stopping mutator threads from other isolates
+  // while modifying the megamorphic cache, since updates are not atomic.
+  //
+  // NOTE: In the future we might change the megamorphic cache insertions to
+  // carefully use store-release barriers on the writer as well as
+  // load-acquire barriers on the reader, ...
+  isolate_group->RunWithStoppedMutators(
+      [&]() {
+        EnsureCapacityLocked();
+        InsertEntryLocked(class_id, target);
+      },
+      /*use_force_growth=*/true);
 }
 
 void MegamorphicCache::EnsureCapacityLocked() const {
-  ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
+  auto thread = Thread::Current();
+  auto zone = thread->zone();
+  auto isolate_group = thread->isolate_group();
+  ASSERT(isolate_group->type_feedback_mutex()->IsOwnedByCurrentThread());
+
   intptr_t old_capacity = mask() + 1;
   double load_limit = kLoadFactor * static_cast<double>(old_capacity);
   if (static_cast<double>(filled_entry_count() + 1) > load_limit) {
-    const Array& old_buckets = Array::Handle(buckets());
+    const Array& old_buckets = Array::Handle(zone, buckets());
     intptr_t new_capacity = old_capacity * 2;
     const Array& new_buckets =
-        Array::Handle(Array::New(kEntryLength * new_capacity));
+        Array::Handle(zone, Array::New(kEntryLength * new_capacity));
 
-    auto& target = Object::Handle();
+    auto& target = Object::Handle(zone);
     for (intptr_t i = 0; i < new_capacity; ++i) {
       SetEntry(new_buckets, i, smi_illegal_cid(), target);
     }
@@ -17284,20 +17092,23 @@
     set_filled_entry_count(0);
 
     // Rehash the valid entries.
-    Smi& class_id = Smi::Handle();
+    Smi& class_id = Smi::Handle(zone);
     for (intptr_t i = 0; i < old_capacity; ++i) {
       class_id ^= GetClassId(old_buckets, i);
       if (class_id.Value() != kIllegalCid) {
         target = GetTargetFunction(old_buckets, i);
-        InsertLocked(class_id, target);
+        InsertEntryLocked(class_id, target);
       }
     }
   }
 }
 
-void MegamorphicCache::InsertLocked(const Smi& class_id,
-                                    const Object& target) const {
-  ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
+void MegamorphicCache::InsertEntryLocked(const Smi& class_id,
+                                         const Object& target) const {
+  auto thread = Thread::Current();
+  auto isolate_group = thread->isolate_group();
+  ASSERT(isolate_group->type_feedback_mutex()->IsOwnedByCurrentThread());
+
   ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(static_cast<double>(filled_entry_count() + 1) <=
          (kLoadFactor * static_cast<double>(mask() + 1)));
@@ -17366,25 +17177,25 @@
 ArrayPtr SubtypeTestCache::cache() const {
   // We rely on the fact that any loads from the array are dependent loads and
   // avoid the load-acquire barrier here.
-  return raw_ptr()->cache_;
+  return raw_ptr()->cache<std::memory_order_relaxed>();
 }
 
 void SubtypeTestCache::set_cache(const Array& value) const {
   // We have to ensure that initializing stores to the array are available
   // when releasing the pointer to the array pointer.
   // => We have to use store-release here.
-  StorePointer<ArrayPtr, std::memory_order_release>(&raw_ptr()->cache_,
-                                                    value.raw());
+  raw_ptr()->set_cache<std::memory_order_release>(value.raw());
 }
 
 intptr_t SubtypeTestCache::NumberOfChecks() const {
   NoSafepointScope no_safepoint;
   // Do not count the sentinel;
-  return (Smi::Value(cache()->ptr()->length_) / kTestEntryLength) - 1;
+  return (Smi::Value(cache()->ptr()->length()) / kTestEntryLength) - 1;
 }
 
 void SubtypeTestCache::AddCheck(
     const Object& instance_class_id_or_function,
+    const AbstractType& destination_type,
     const TypeArguments& instance_type_arguments,
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
@@ -17405,6 +17216,7 @@
   auto entry = entries[old_num];
   ASSERT(entry.Get<kInstanceClassIdOrFunction>() == Object::null());
   entry.Set<kInstanceClassIdOrFunction>(instance_class_id_or_function);
+  entry.Set<kDestinationType>(destination_type);
   entry.Set<kInstanceTypeArguments>(instance_type_arguments);
   entry.Set<kInstantiatorTypeArguments>(instantiator_type_arguments);
   entry.Set<kFunctionTypeArguments>(function_type_arguments);
@@ -17422,6 +17234,7 @@
 void SubtypeTestCache::GetCheck(
     intptr_t ix,
     Object* instance_class_id_or_function,
+    AbstractType* destination_type,
     TypeArguments* instance_type_arguments,
     TypeArguments* instantiator_type_arguments,
     TypeArguments* function_type_arguments,
@@ -17432,11 +17245,28 @@
              ->isolate_group()
              ->subtype_test_cache_mutex()
              ->IsOwnedByCurrentThread());
+  GetCurrentCheck(ix, instance_class_id_or_function, destination_type,
+                  instance_type_arguments, instantiator_type_arguments,
+                  function_type_arguments,
+                  instance_parent_function_type_arguments,
+                  instance_delayed_type_arguments, test_result);
+}
 
+void SubtypeTestCache::GetCurrentCheck(
+    intptr_t ix,
+    Object* instance_class_id_or_function,
+    AbstractType* destination_type,
+    TypeArguments* instance_type_arguments,
+    TypeArguments* instantiator_type_arguments,
+    TypeArguments* function_type_arguments,
+    TypeArguments* instance_parent_function_type_arguments,
+    TypeArguments* instance_delayed_type_arguments,
+    Bool* test_result) const {
   Array& data = Array::Handle(cache());
   SubtypeTestCacheTable entries(data);
   auto entry = entries[ix];
   *instance_class_id_or_function = entry.Get<kInstanceClassIdOrFunction>();
+  *destination_type = entry.Get<kDestinationType>();
   *instance_type_arguments = entry.Get<kInstanceTypeArguments>();
   *instantiator_type_arguments = entry.Get<kInstantiatorTypeArguments>();
   *function_type_arguments = entry.Get<kFunctionTypeArguments>();
@@ -17447,12 +17277,166 @@
   *test_result ^= entry.Get<kTestResult>();
 }
 
+bool SubtypeTestCache::HasCheck(
+    const Object& instance_class_id_or_function,
+    const AbstractType& destination_type,
+    const TypeArguments& instance_type_arguments,
+    const TypeArguments& instantiator_type_arguments,
+    const TypeArguments& function_type_arguments,
+    const TypeArguments& instance_parent_function_type_arguments,
+    const TypeArguments& instance_delayed_type_arguments,
+    intptr_t* index,
+    Bool* result) const {
+  ASSERT(Thread::Current()
+             ->isolate_group()
+             ->subtype_test_cache_mutex()
+             ->IsOwnedByCurrentThread());
+  const intptr_t last_index = NumberOfChecks();
+  const auto& data = Array::Handle(cache());
+
+  SubtypeTestCacheTable entries(data);
+  for (intptr_t i = 0; i < last_index; i++) {
+    const auto entry = entries[i];
+    if (entry.Get<kInstanceClassIdOrFunction>() ==
+            instance_class_id_or_function.raw() &&
+        entry.Get<kDestinationType>() == destination_type.raw() &&
+        entry.Get<kInstanceTypeArguments>() == instance_type_arguments.raw() &&
+        entry.Get<kInstantiatorTypeArguments>() ==
+            instantiator_type_arguments.raw() &&
+        entry.Get<kFunctionTypeArguments>() == function_type_arguments.raw() &&
+        entry.Get<kInstanceParentFunctionTypeArguments>() ==
+            instance_parent_function_type_arguments.raw() &&
+        entry.Get<kInstanceDelayedFunctionTypeArguments>() ==
+            instance_delayed_type_arguments.raw()) {
+      if (index != nullptr) {
+        *index = i;
+      }
+      if (result != nullptr) {
+        *result ^= entry.Get<kTestResult>();
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+void SubtypeTestCache::WriteEntryToBuffer(Zone* zone,
+                                          BaseTextBuffer* buffer,
+                                          intptr_t index,
+                                          const char* line_prefix) const {
+  ASSERT(Thread::Current()
+             ->isolate_group()
+             ->subtype_test_cache_mutex()
+             ->IsOwnedByCurrentThread());
+  WriteCurrentEntryToBuffer(zone, buffer, index, line_prefix);
+}
+
+void SubtypeTestCache::WriteCurrentEntryToBuffer(
+    Zone* zone,
+    BaseTextBuffer* buffer,
+    intptr_t index,
+    const char* line_prefix) const {
+  const char* separator =
+      line_prefix == nullptr ? ", " : OS::SCreate(zone, "\n%s", line_prefix);
+  auto& instance_class_id_or_function = Object::Handle(zone);
+  auto& destination_type = AbstractType::Handle(zone);
+  auto& instance_type_arguments = TypeArguments::Handle(zone);
+  auto& instantiator_type_arguments = TypeArguments::Handle(zone);
+  auto& function_type_arguments = TypeArguments::Handle(zone);
+  auto& instance_parent_function_type_arguments = TypeArguments::Handle(zone);
+  auto& instance_delayed_type_arguments = TypeArguments::Handle(zone);
+  auto& result = Bool::Handle(zone);
+  GetCurrentCheck(index, &instance_class_id_or_function, &destination_type,
+                  &instance_type_arguments, &instantiator_type_arguments,
+                  &function_type_arguments,
+                  &instance_parent_function_type_arguments,
+                  &instance_delayed_type_arguments, &result);
+  ASSERT(!result.IsNull());
+  buffer->Printf(
+      "[ %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px
+      ", %#" Px " ]",
+      static_cast<uword>(instance_class_id_or_function.raw()),
+      static_cast<uword>(destination_type.raw()),
+      static_cast<uword>(instance_type_arguments.raw()),
+      static_cast<uword>(instantiator_type_arguments.raw()),
+      static_cast<uword>(function_type_arguments.raw()),
+      static_cast<uword>(instance_parent_function_type_arguments.raw()),
+      static_cast<uword>(instance_delayed_type_arguments.raw()),
+      static_cast<uword>(result.raw()));
+  if (instance_class_id_or_function.IsSmi()) {
+    buffer->Printf("%sclass id: %" Pd "", separator,
+                   Smi::Cast(instance_class_id_or_function).Value());
+  } else {
+    ASSERT(instance_class_id_or_function.IsFunction());
+    buffer->Printf("%sfunction: %s", separator,
+                   Function::Cast(instance_class_id_or_function)
+                       .ToFullyQualifiedCString());
+  }
+  if (!destination_type.IsNull()) {
+    buffer->Printf("%sdestination type: %s", separator,
+                   destination_type.ToCString());
+    if (!destination_type.IsInstantiated()) {
+      AbstractType& test_type = AbstractType::Handle(
+          zone, destination_type.InstantiateFrom(instantiator_type_arguments,
+                                                 function_type_arguments,
+                                                 kAllFree, Heap::kNew));
+      const auto& type_class = Class::Handle(zone, test_type.type_class());
+      buffer->Printf("%sinstantiated type: %s", separator,
+                     test_type.ToCString());
+      buffer->Printf("%sinstantiated type class id: %" Pd "", separator,
+                     type_class.id());
+    }
+  }
+  if (!instance_type_arguments.IsNull()) {
+    if (instance_class_id_or_function.IsSmi()) {
+      buffer->Printf("%sinstance type arguments: %s", separator,
+                     instance_type_arguments.ToCString());
+    } else {
+      ASSERT(instance_class_id_or_function.IsFunction());
+      buffer->Printf("%sclosure instantiator function type arguments: %s",
+                     separator, instance_type_arguments.ToCString());
+    }
+  }
+  if (!instantiator_type_arguments.IsNull()) {
+    buffer->Printf("%sinstantiator type arguments: %s", separator,
+                   instantiator_type_arguments.ToCString());
+  }
+  if (!function_type_arguments.IsNull()) {
+    buffer->Printf("%sfunction type arguments: %s", separator,
+                   function_type_arguments.ToCString());
+  }
+  if (!instance_parent_function_type_arguments.IsNull()) {
+    ASSERT(instance_class_id_or_function.IsFunction());
+    buffer->Printf("%sclosure parent function type arguments: %s", separator,
+                   instance_parent_function_type_arguments.ToCString());
+  }
+  if (!instance_delayed_type_arguments.IsNull()) {
+    ASSERT(instance_class_id_or_function.IsFunction());
+    buffer->Printf("%sclosure delayed function type arguments: %s", separator,
+                   instance_delayed_type_arguments.ToCString());
+  }
+  buffer->Printf("%sresult: %s", separator, result.ToCString());
+}
+
 void SubtypeTestCache::Reset() const {
   set_cache(Array::Handle(cached_array_));
 }
 
 const char* SubtypeTestCache::ToCString() const {
-  return "SubtypeTestCache";
+  auto const zone = Thread::Current()->zone();
+  ZoneTextBuffer buffer(zone);
+  const intptr_t num_checks = NumberOfChecks();
+  buffer.AddString("SubtypeTestCache(");
+  for (intptr_t i = 0; i < num_checks; i++) {
+    if (i != 0) {
+      buffer.AddString(",");
+    }
+    buffer.AddString("{ entry: ");
+    WriteCurrentEntryToBuffer(zone, &buffer, i);
+    buffer.AddString(" }");
+  }
+  buffer.AddString(")");
+  return buffer.buffer();
 }
 
 LoadingUnitPtr LoadingUnit::New() {
@@ -17473,17 +17457,17 @@
 }
 
 LoadingUnitPtr LoadingUnit::parent() const {
-  return raw_ptr()->parent_;
+  return raw_ptr()->parent();
 }
 void LoadingUnit::set_parent(const LoadingUnit& value) const {
-  StorePointer(&raw_ptr()->parent_, value.raw());
+  raw_ptr()->set_parent(value.raw());
 }
 
 ArrayPtr LoadingUnit::base_objects() const {
-  return raw_ptr()->base_objects_;
+  return raw_ptr()->base_objects();
 }
 void LoadingUnit::set_base_objects(const Array& value) const {
-  StorePointer(&raw_ptr()->base_objects_, value.raw());
+  raw_ptr()->set_base_objects(value.raw());
 }
 
 const char* LoadingUnit::ToCString() const {
@@ -17565,7 +17549,7 @@
 }
 
 void ApiError::set_message(const String& message) const {
-  StorePointer(&raw_ptr()->message_, message.raw());
+  raw_ptr()->set_message(message.raw());
 }
 
 const char* ApiError::ToErrorCString() const {
@@ -17645,11 +17629,11 @@
 }
 
 void LanguageError::set_previous_error(const Error& value) const {
-  StorePointer(&raw_ptr()->previous_error_, value.raw());
+  raw_ptr()->set_previous_error(value.raw());
 }
 
 void LanguageError::set_script(const Script& value) const {
-  StorePointer(&raw_ptr()->script_, value.raw());
+  raw_ptr()->set_script(value.raw());
 }
 
 void LanguageError::set_token_pos(TokenPosition token_pos) const {
@@ -17666,11 +17650,11 @@
 }
 
 void LanguageError::set_message(const String& value) const {
-  StorePointer(&raw_ptr()->message_, value.raw());
+  raw_ptr()->set_message(value.raw());
 }
 
 void LanguageError::set_formatted_message(const String& value) const {
-  StorePointer(&raw_ptr()->formatted_message_, value.raw());
+  raw_ptr()->set_formatted_message(value.raw());
 }
 
 StringPtr LanguageError::FormatMessage() const {
@@ -17732,11 +17716,11 @@
 }
 
 void UnhandledException::set_exception(const Instance& exception) const {
-  StorePointer(&raw_ptr()->exception_, exception.raw());
+  raw_ptr()->set_exception(exception.raw());
 }
 
 void UnhandledException::set_stacktrace(const Instance& stacktrace) const {
-  StorePointer(&raw_ptr()->stacktrace_, stacktrace.raw());
+  raw_ptr()->set_stacktrace(stacktrace.raw());
 }
 
 const char* UnhandledException::ToErrorCString() const {
@@ -17789,7 +17773,7 @@
 }
 
 void UnwindError::set_message(const String& message) const {
-  StorePointer(&raw_ptr()->message_, message.raw());
+  raw_ptr()->set_message(message.raw());
 }
 
 void UnwindError::set_is_user_initiated(bool value) const {
@@ -18141,7 +18125,8 @@
 }
 
 InstancePtr Instance::Canonicalize(Thread* thread) const {
-  SafepointMutexLocker ml(thread->isolate()->constant_canonicalization_mutex());
+  SafepointMutexLocker ml(
+      thread->isolate_group()->constant_canonicalization_mutex());
   return CanonicalizeLocked(thread);
 }
 
@@ -18173,10 +18158,10 @@
 #if defined(DEBUG)
 bool Instance::CheckIsCanonical(Thread* thread) const {
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   Instance& result = Instance::Handle(zone);
   const Class& cls = Class::Handle(zone, this->clazz());
-  SafepointMutexLocker ml(isolate->constant_canonicalization_mutex());
+  SafepointMutexLocker ml(
+      thread->isolate_group()->constant_canonicalization_mutex());
   result ^= cls.LookupCanonicalInstance(zone, *this);
   return (result.raw() == this->raw());
 }
@@ -18343,7 +18328,7 @@
   // In weak mode type casts, whether in legacy or opted-in libraries, the null
   // instance is detected and handled in inlined code and therefore cannot be
   // encountered here as a Dart null receiver.
-  ASSERT(Isolate::Current()->null_safety() || !IsNull());
+  ASSERT(Isolate::Current()->use_strict_null_safety_checks() || !IsNull());
   // In strong mode, compute NNBD_SUBTYPE(runtimeType, other).
   // In weak mode, compute LEGACY_SUBTYPE(runtimeType, other).
   return RuntimeTypeIsSubtypeOf(other, other_instantiator_type_arguments,
@@ -18386,13 +18371,15 @@
   return other.IsLegacy() && (other.IsObjectType() || other.IsNeverType());
 }
 
+// Must be kept in sync with GenerateNullIsAssignableToType in
+// stub_code_compiler.cc if any changes are made.
 bool Instance::NullIsAssignableTo(const AbstractType& other) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
 
   // In weak mode, Null is a bottom type (according to LEGACY_SUBTYPE).
-  if (!isolate->null_safety()) {
+  if (!isolate->use_strict_null_safety_checks()) {
     return true;
   }
   // "Left Null" rule: null is assignable when destination type is either
@@ -18423,7 +18410,7 @@
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   // In weak testing mode, Null type is a subtype of any type.
-  if (IsNull() && !isolate->null_safety()) {
+  if (IsNull() && !isolate->use_strict_null_safety_checks()) {
     return true;
   }
   const Class& cls = Class::Handle(zone, clazz());
@@ -18488,7 +18475,7 @@
     return false;
   }
   if (IsNull()) {
-    ASSERT(isolate->null_safety());
+    ASSERT(isolate->use_strict_null_safety_checks());
     if (instantiated_other.IsNullType()) {
       return true;
     }
@@ -18610,7 +18597,7 @@
 
 InstancePtr Instance::New(const Class& cls, Heap::Space space) {
   Thread* thread = Thread::Current();
-  if (cls.EnsureIsFinalized(thread) != Error::null()) {
+  if (cls.EnsureIsAllocateFinalized(thread) != Error::null()) {
     return Instance::null();
   }
   intptr_t instance_size = cls.host_instance_size();
@@ -19204,6 +19191,8 @@
   return false;
 }
 
+// Must be kept in sync with GenerateTypeIsTopTypeForSubtyping in
+// stub_code_compiler.cc if any changes are made.
 bool AbstractType::IsTopTypeForSubtyping() const {
   const classid_t cid = type_class_id();
   if (cid == kDynamicCid || cid == kVoidCid) {
@@ -19212,7 +19201,8 @@
   if (cid == kInstanceCid) {  // Object type.
     // NNBD weak mode uses LEGACY_SUBTYPE for assignability / 'as' tests,
     // and non-nullable Object is a top type according to LEGACY_SUBTYPE.
-    return !IsNonNullable() || !Isolate::Current()->null_safety();
+    return !IsNonNullable() ||
+           !Isolate::Current()->use_strict_null_safety_checks();
   }
   if (cid == kFutureOrCid) {
     // FutureOr<T> where T is a top type behaves as a top type.
@@ -19371,7 +19361,8 @@
   const bool other_is_dart_function_type = other.IsDartFunctionType();
   if (other_is_dart_function_type || other.IsFunctionType()) {
     if (IsFunctionType()) {
-      if (isolate->null_safety() && IsNullable() && other.IsNonNullable()) {
+      if (isolate->use_strict_null_safety_checks() && IsNullable() &&
+          other.IsNonNullable()) {
         return false;
       }
       if (other_is_dart_function_type) {
@@ -19456,7 +19447,7 @@
   } else {
     StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, stub.EntryPoint());
   }
-  StorePointer(&raw_ptr()->type_test_stub_, stub.raw());
+  raw_ptr()->set_type_test_stub(stub.raw());
 }
 
 TypePtr Type::NullType() {
@@ -19618,20 +19609,20 @@
 }
 
 FunctionPtr Type::signature() const {
-  intptr_t cid = raw_ptr()->signature_->GetClassId();
+  intptr_t cid = raw_ptr()->signature()->GetClassId();
   if (cid == kNullCid) {
     return Function::null();
   }
   ASSERT(cid == kFunctionCid);
-  return Function::RawCast(raw_ptr()->signature_);
+  return Function::RawCast(raw_ptr()->signature());
 }
 
 void Type::set_signature(const Function& value) const {
-  StorePointer(&raw_ptr()->signature_, value.raw());
+  raw_ptr()->set_signature(value.raw());
 }
 
 classid_t Type::type_class_id() const {
-  return Smi::Value(raw_ptr()->type_class_id_);
+  return Smi::Value(raw_ptr()->type_class_id());
 }
 
 ClassPtr Type::type_class() const {
@@ -19780,7 +19771,7 @@
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   if (kind == TypeEquality::kInSubtypeTest) {
-    if (isolate->null_safety() &&
+    if (isolate->use_strict_null_safety_checks() &&
         this_type_nullability == Nullability::kNullable &&
         other_type_nullability == Nullability::kNonNullable) {
       return false;
@@ -20209,12 +20200,12 @@
 
 void Type::set_type_class(const Class& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->type_class_id_, Smi::New(value.id()));
+  raw_ptr()->set_type_class_id(Smi::New(value.id()));
 }
 
 void Type::set_arguments(const TypeArguments& value) const {
   ASSERT(!IsCanonical());
-  StorePointer(&raw_ptr()->arguments_, value.raw());
+  raw_ptr()->set_arguments(value.raw());
 }
 
 TypePtr Type::New(Heap::Space space) {
@@ -20361,7 +20352,7 @@
 void TypeRef::set_type(const AbstractType& value) const {
   ASSERT(value.IsNull() || value.IsFunctionType() || value.HasTypeClass());
   ASSERT(!value.IsTypeRef());
-  StorePointer(&raw_ptr()->type_, value.raw());
+  raw_ptr()->set_type(value.raw());
 }
 
 // A TypeRef cannot be canonical by definition. Only its referenced type can be.
@@ -20548,7 +20539,7 @@
   Nullability this_type_param_nullability = nullability();
   Nullability other_type_param_nullability = other_type_param.nullability();
   if (kind == TypeEquality::kInSubtypeTest) {
-    if (Isolate::Current()->null_safety() &&
+    if (Isolate::Current()->use_strict_null_safety_checks() &&
         (this_type_param_nullability == Nullability::kNullable) &&
         (other_type_param_nullability == Nullability::kNonNullable)) {
       return false;
@@ -20616,7 +20607,7 @@
 }
 
 void TypeParameter::set_parameterized_function(const Function& value) const {
-  StorePointer(&raw_ptr()->parameterized_function_, value.raw());
+  raw_ptr()->set_parameterized_function(value.raw());
 }
 
 void TypeParameter::set_index(intptr_t value) const {
@@ -20627,15 +20618,15 @@
 
 void TypeParameter::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
-  StorePointer(&raw_ptr()->name_, value.raw());
+  raw_ptr()->set_name(value.raw());
 }
 
 void TypeParameter::set_bound(const AbstractType& value) const {
-  StorePointer(&raw_ptr()->bound_, value.raw());
+  raw_ptr()->set_bound(value.raw());
 }
 
 void TypeParameter::set_default_argument(const AbstractType& value) const {
-  StorePointer(&raw_ptr()->default_argument_, value.raw());
+  raw_ptr()->set_default_argument(value.raw());
 }
 
 AbstractTypePtr TypeParameter::GetFromTypeArguments(
@@ -20757,6 +20748,7 @@
     }
     object_store->set_canonical_type_parameters(table.Release());
   }
+  ASSERT(!type_parameter.IsDeclaration());
   return type_parameter.raw();
 }
 
@@ -20771,8 +20763,10 @@
   const TypeArguments& type_params = TypeArguments::Handle(
       zone, cls.IsNull() ? function.type_parameters() : cls.type_parameters());
   const intptr_t offset =
-      cls.IsNull() ? function.NumParentTypeParameters()
-                   : (cls.NumTypeArguments() - cls.NumTypeParameters());
+      IsFinalized()
+          ? (cls.IsNull() ? function.NumParentTypeParameters()
+                          : (cls.NumTypeArguments() - cls.NumTypeParameters()))
+          : 0;
   TypeParameter& type_parameter = TypeParameter::Handle(zone);
   type_parameter ^= type_params.TypeAt(index() - offset);
   ASSERT(!type_parameter.IsNull());
@@ -21294,7 +21288,8 @@
 
 MintPtr Mint::NewCanonical(int64_t value) {
   Thread* thread = Thread::Current();
-  SafepointMutexLocker ml(thread->isolate()->constant_canonicalization_mutex());
+  SafepointMutexLocker ml(
+      thread->isolate_group()->constant_canonicalization_mutex());
   return NewCanonicalLocked(thread, value);
 }
 
@@ -21421,7 +21416,8 @@
 
 DoublePtr Double::NewCanonical(double value) {
   Thread* thread = Thread::Current();
-  SafepointMutexLocker ml(thread->isolate()->constant_canonicalization_mutex());
+  SafepointMutexLocker ml(
+      thread->isolate_group()->constant_canonicalization_mutex());
   return NewCanonicalLocked(thread, value);
 }
 
@@ -21519,7 +21515,7 @@
 
 intptr_t String::Hash(StringPtr raw) {
   StringHasher hasher;
-  uword length = Smi::Value(raw->ptr()->length_);
+  uword length = Smi::Value(raw->ptr()->length());
   if (raw->IsOneByteString() || raw->IsExternalOneByteString()) {
     const uint8_t* data;
     if (raw->IsOneByteString()) {
@@ -22516,9 +22512,9 @@
                                      OneByteString::InstanceSize(len), space);
     NoSafepointScope no_safepoint;
     OneByteStringPtr result = static_cast<OneByteStringPtr>(raw);
-    result->ptr()->StoreSmi(&(result->ptr()->length_), Smi::New(len));
+    result->ptr()->set_length(Smi::New(len));
 #if !defined(HASH_IN_OBJECT_HEADER)
-    result->ptr()->StoreSmi(&(result->ptr()->hash_), Smi::New(0));
+    result->ptr()->set_hash(Smi::New(0));
 #endif
     return result;
   }
@@ -23028,7 +23024,7 @@
     ArrayPtr raw = static_cast<ArrayPtr>(
         Object::Allocate(class_id, Array::InstanceSize(len), space));
     NoSafepointScope no_safepoint;
-    raw->ptr()->StoreSmi(&(raw->ptr()->length_), Smi::New(len));
+    raw->ptr()->set_length(Smi::New(len));
     return raw;
   }
 }
@@ -23052,15 +23048,7 @@
 void Array::MakeImmutable() const {
   if (IsImmutable()) return;
   ASSERT(!IsCanonical());
-  NoSafepointScope no_safepoint;
-  uint32_t tags = raw_ptr()->tags_;
-  uint32_t old_tags;
-  do {
-    old_tags = tags;
-    uint32_t new_tags =
-        ObjectLayout::ClassIdTag::update(kImmutableArrayCid, old_tags);
-    tags = CompareAndSwapTags(old_tags, new_tags);
-  } while (tags != old_tags);
+  raw_ptr()->SetClassId(kImmutableArrayCid);
 }
 
 const char* Array::ToCString() const {
@@ -23117,25 +23105,22 @@
   // that it can be traversed over successfully during garbage collection.
   Object::MakeUnusedSpaceTraversable(array, old_size, new_size);
 
-  // For the heap to remain walkable by the sweeper, it must observe the
-  // creation of the filler object no later than the new length of the array.
-  std::atomic_thread_fence(std::memory_order_release);
-
   // Update the size in the header field and length of the array object.
-  uint32_t tags = array.raw_ptr()->tags_;
-  ASSERT(kArrayCid == ObjectLayout::ClassIdTag::decode(tags));
-  uint32_t old_tags;
+  // These release operations are balanced by acquire operations in the
+  // concurrent sweeper.
+  uword old_tags = array.raw_ptr()->tags_;
+  uword new_tags;
+  ASSERT(kArrayCid == ObjectLayout::ClassIdTag::decode(old_tags));
   do {
-    old_tags = tags;
-    uint32_t new_tags = ObjectLayout::SizeTag::update(new_size, old_tags);
-    tags = CompareAndSwapTags(old_tags, new_tags);
-  } while (tags != old_tags);
+    new_tags = ObjectLayout::SizeTag::update(new_size, old_tags);
+  } while (!array.raw_ptr()->tags_.compare_exchange_weak(
+      old_tags, new_tags, std::memory_order_release));
 
   // Between the CAS of the header above and the SetLength below, the array is
   // temporarily in an inconsistent state. The header is considered the
   // overriding source of object size by ObjectLayout::Size, but the ASSERTs in
-  // ObjectLayout::SizeFromClass must handle this special case.
-  array.SetLengthIgnoreRace(new_len);
+  // ObjectLayout::HeapSizeFromClass must handle this special case.
+  array.SetLengthRelease(new_len);
 }
 
 ArrayPtr Array::MakeFixedLength(const GrowableObjectArray& growable_array,
@@ -23215,7 +23200,7 @@
   const Array& contents = Array::Handle(data());
   const Array& new_contents =
       Array::Handle(Array::Grow(contents, new_capacity, space));
-  StorePointer(&(raw_ptr()->data_), new_contents.raw());
+  raw_ptr()->set_data(new_contents.raw());
 }
 
 ObjectPtr GrowableObjectArray::RemoveLast() const {
@@ -23757,7 +23742,7 @@
 
   const Class& cls =
       Class::Handle(Isolate::Current()->class_table()->At(kFfiPointerCid));
-  cls.EnsureIsFinalized(Thread::Current());
+  cls.EnsureIsAllocateFinalized(Thread::Current());
 
   Pointer& result = Pointer::Handle(zone);
   result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space);
@@ -23832,11 +23817,10 @@
                                      ReceivePort::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
-    result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw());
+    result.raw_ptr()->set_send_port(send_port.raw());
 #if !defined(PRODUCT)
-    result.StorePointer(&result.raw_ptr()->debug_name_, debug_name.raw());
-    result.StorePointer(&result.raw_ptr()->allocation_location_,
-                        allocation_location_.raw());
+    result.raw_ptr()->set_debug_name(debug_name.raw());
+    result.raw_ptr()->set_allocation_location(allocation_location_.raw());
 #endif  // !defined(PRODUCT)
   }
   if (is_control_port) {
@@ -24024,14 +24008,13 @@
         Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
     NoSafepointScope no_safepoint;
     result ^= raw;
-    result.StorePointer(&result.raw_ptr()->instantiator_type_arguments_,
-                        instantiator_type_arguments.raw());
-    result.StorePointer(&result.raw_ptr()->function_type_arguments_,
-                        function_type_arguments.raw());
-    result.StorePointer(&result.raw_ptr()->delayed_type_arguments_,
-                        delayed_type_arguments.raw());
-    result.StorePointer(&result.raw_ptr()->function_, function.raw());
-    result.StorePointer(&result.raw_ptr()->context_, context.raw());
+    result.raw_ptr()->set_instantiator_type_arguments(
+        instantiator_type_arguments.raw());
+    result.raw_ptr()->set_function_type_arguments(
+        function_type_arguments.raw());
+    result.raw_ptr()->set_delayed_type_arguments(delayed_type_arguments.raw());
+    result.raw_ptr()->set_function(function.raw());
+    result.raw_ptr()->set_context(context.raw());
   }
   return result.raw();
 }
@@ -24079,42 +24062,42 @@
 }
 
 intptr_t StackTrace::Length() const {
-  const Array& code_array = Array::Handle(raw_ptr()->code_array_);
+  const Array& code_array = Array::Handle(raw_ptr()->code_array());
   return code_array.Length();
 }
 
 ObjectPtr StackTrace::CodeAtFrame(intptr_t frame_index) const {
-  const Array& code_array = Array::Handle(raw_ptr()->code_array_);
+  const Array& code_array = Array::Handle(raw_ptr()->code_array());
   return code_array.At(frame_index);
 }
 
 void StackTrace::SetCodeAtFrame(intptr_t frame_index,
                                 const Object& code) const {
-  const Array& code_array = Array::Handle(raw_ptr()->code_array_);
+  const Array& code_array = Array::Handle(raw_ptr()->code_array());
   code_array.SetAt(frame_index, code);
 }
 
 SmiPtr StackTrace::PcOffsetAtFrame(intptr_t frame_index) const {
-  const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_);
+  const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array());
   return static_cast<SmiPtr>(pc_offset_array.At(frame_index));
 }
 
 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index,
                                     const Smi& pc_offset) const {
-  const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_);
+  const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array());
   pc_offset_array.SetAt(frame_index, pc_offset);
 }
 
 void StackTrace::set_async_link(const StackTrace& async_link) const {
-  StorePointer(&raw_ptr()->async_link_, async_link.raw());
+  raw_ptr()->set_async_link(async_link.raw());
 }
 
 void StackTrace::set_code_array(const Array& code_array) const {
-  StorePointer(&raw_ptr()->code_array_, code_array.raw());
+  raw_ptr()->set_code_array(code_array.raw());
 }
 
 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const {
-  StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw());
+  raw_ptr()->set_pc_offset_array(pc_offset_array.raw());
 }
 
 void StackTrace::set_expand_inlined(bool value) const {
@@ -24296,7 +24279,7 @@
       const intptr_t length = isolate_instructions_image.build_id_length();
       buffer.Printf("build_id: '");
       for (intptr_t i = 0; i < length; i++) {
-        buffer.Printf("%02.2x", build_id[i]);
+        buffer.Printf("%2.2x", build_id[i]);
       }
       buffer.Printf("'\n");
     }
@@ -24315,6 +24298,8 @@
   // for each frame.
   intptr_t frame_index = 0;
   uint32_t frame_skip = 0;
+  // If we're already in a gap, don't print multiple gap markers.
+  bool in_gap = false;
   do {
     for (intptr_t i = frame_skip; i < stack_trace.Length(); i++) {
       code_object = stack_trace.CodeAtFrame(i);
@@ -24328,72 +24313,87 @@
           // To account for gap frames.
           frame_index += Smi::Value(stack_trace.PcOffsetAtFrame(i));
         }
-      } else if (code_object.raw() == StubCode::AsynchronousGapMarker().raw()) {
-        buffer.AddString("<asynchronous suspension>\n");
-      } else {
-        intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i));
-        ASSERT(code_object.IsCode());
-        code ^= code_object.raw();
-        ASSERT(code.IsFunctionCode());
-        function = code.function();
-        const uword pc = code.PayloadStart() + pc_offset;
-#if defined(DART_PRECOMPILED_RUNTIME)
-        // When printing non-symbolic frames, we normally print call
-        // addresses, not return addresses, by subtracting one from the PC to
-        // get an address within the preceding instruction.
-        //
-        // The one exception is a normal closure registered as a listener on a
-        // future. In this case, the returned pc_offset is 0, as the closure
-        // is invoked with the value of the resolved future. Thus, we must
-        // report the return address, as returning a value before the closure
-        // payload will cause failures to decode the frame using DWARF info.
-        const bool is_future_listener = pc_offset == 0;
-        const uword call_addr = is_future_listener ? pc : pc - 1;
-        if (FLAG_dwarf_stack_traces_mode) {
-          // If we have access to the owning function and it would be
-          // invisible in a symbolic stack trace, don't show this frame.
-          // (We can't do the same for inlined functions, though.)
-          if (!FLAG_show_invisible_frames && !function.IsNull() &&
-              !function.is_visible()) {
-            continue;
-          }
-          // This output is formatted like Android's debuggerd. Note debuggerd
-          // prints call addresses instead of return addresses.
-          buffer.Printf("    #%02" Pd " abs %" Pp "", frame_index, call_addr);
-          PrintNonSymbolicStackFrameBody(&buffer, call_addr,
-                                         isolate_instructions, vm_instructions);
-          frame_index++;
-          continue;
-        } else if (function.IsNull()) {
-          // We can't print the symbolic information since the owner was not
-          // retained, so instead print the static symbol + offset like the
-          // non-symbolic stack traces.
-          PrintSymbolicStackFrameIndex(&buffer, frame_index);
-          PrintNonSymbolicStackFrameBody(&buffer, call_addr,
-                                         isolate_instructions, vm_instructions);
-          frame_index++;
-          continue;
-        }
-#endif
-        if (code.is_optimized() && stack_trace.expand_inlined()) {
-          code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions,
-                                                  &inlined_token_positions);
-          ASSERT(inlined_functions.length() >= 1);
-          for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
-            const auto& inlined = *inlined_functions[j];
-            auto const pos = inlined_token_positions[j];
-            if (FLAG_show_invisible_frames || function.is_visible()) {
-              PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index);
-              frame_index++;
-            }
-          }
-        } else if (FLAG_show_invisible_frames || function.is_visible()) {
-          auto const pos = code.GetTokenIndexOfPC(pc);
-          PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index);
-          frame_index++;
-        }
+        continue;
       }
+
+      if (code_object.raw() == StubCode::AsynchronousGapMarker().raw()) {
+        if (!in_gap) {
+          buffer.AddString("<asynchronous suspension>\n");
+        }
+        in_gap = true;
+        continue;
+      }
+
+      intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i));
+      ASSERT(code_object.IsCode());
+      code ^= code_object.raw();
+      ASSERT(code.IsFunctionCode());
+      function = code.function();
+      const uword pc = code.PayloadStart() + pc_offset;
+
+      // If the function is not to be shown, skip.
+      if (!FLAG_show_invisible_frames && !function.IsNull() &&
+          !function.is_visible()) {
+        continue;
+      }
+
+      // A visible frame ends any gap we might be in.
+      in_gap = false;
+
+#if defined(DART_PRECOMPILED_RUNTIME)
+      // When printing non-symbolic frames, we normally print call
+      // addresses, not return addresses, by subtracting one from the PC to
+      // get an address within the preceding instruction.
+      //
+      // The one exception is a normal closure registered as a listener on a
+      // future. In this case, the returned pc_offset is 0, as the closure
+      // is invoked with the value of the resolved future. Thus, we must
+      // report the return address, as returning a value before the closure
+      // payload will cause failures to decode the frame using DWARF info.
+      const bool is_future_listener = pc_offset == 0;
+      const uword call_addr = is_future_listener ? pc : pc - 1;
+
+      if (FLAG_dwarf_stack_traces_mode) {
+        // This output is formatted like Android's debuggerd. Note debuggerd
+        // prints call addresses instead of return addresses.
+        buffer.Printf("    #%02" Pd " abs %" Pp "", frame_index, call_addr);
+        PrintNonSymbolicStackFrameBody(&buffer, call_addr, isolate_instructions,
+                                       vm_instructions);
+        frame_index++;
+        continue;
+      }
+
+      if (function.IsNull()) {
+        in_gap = false;
+        // We can't print the symbolic information since the owner was not
+        // retained, so instead print the static symbol + offset like the
+        // non-symbolic stack traces.
+        PrintSymbolicStackFrameIndex(&buffer, frame_index);
+        PrintNonSymbolicStackFrameBody(&buffer, call_addr, isolate_instructions,
+                                       vm_instructions);
+        frame_index++;
+        continue;
+      }
+#endif
+
+      if (code.is_optimized() && stack_trace.expand_inlined()) {
+        code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions,
+                                                &inlined_token_positions);
+        ASSERT(inlined_functions.length() >= 1);
+        for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
+          const auto& inlined = *inlined_functions[j];
+          auto const pos = inlined_token_positions[j];
+          PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index);
+          frame_index++;
+        }
+        continue;
+      }
+
+      auto const pos = code.GetTokenIndexOfPC(pc);
+      PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index);
+      frame_index++;
     }
+
     // Follow the link.
     frame_skip = stack_trace.skip_sync_start_in_parent_stack()
                      ? StackTrace::kSyncAsyncCroppedFrames
@@ -24423,7 +24423,7 @@
                     "symbolize stack traces in the precompiled runtime.");
 
 void RegExp::set_pattern(const String& pattern) const {
-  StorePointer(&raw_ptr()->pattern_, pattern.raw());
+  raw_ptr()->set_pattern(pattern.raw());
 }
 
 void RegExp::set_function(intptr_t cid,
@@ -24437,25 +24437,25 @@
                           const TypedData& bytecode) const {
   if (sticky) {
     if (is_one_byte) {
-      StorePointer(&raw_ptr()->one_byte_sticky_.bytecode_, bytecode.raw());
+      raw_ptr()->set_one_byte_sticky(bytecode.raw());
     } else {
-      StorePointer(&raw_ptr()->two_byte_sticky_.bytecode_, bytecode.raw());
+      raw_ptr()->set_two_byte_sticky(bytecode.raw());
     }
   } else {
     if (is_one_byte) {
-      StorePointer(&raw_ptr()->one_byte_.bytecode_, bytecode.raw());
+      raw_ptr()->set_one_byte(bytecode.raw());
     } else {
-      StorePointer(&raw_ptr()->two_byte_.bytecode_, bytecode.raw());
+      raw_ptr()->set_two_byte(bytecode.raw());
     }
   }
 }
 
 void RegExp::set_num_bracket_expressions(intptr_t value) const {
-  StoreSmi(&raw_ptr()->num_bracket_expressions_, Smi::New(value));
+  raw_ptr()->set_num_bracket_expressions(Smi::New(value));
 }
 
 void RegExp::set_capture_name_map(const Array& array) const {
-  StorePointer(&raw_ptr()->capture_name_map_, array.raw());
+  raw_ptr()->set_capture_name_map(array.raw());
 }
 
 RegExpPtr RegExp::New(Heap::Space space) {
@@ -24543,9 +24543,7 @@
          Class::null());
   ObjectPtr raw = Object::Allocate(WeakProperty::kClassId,
                                    WeakProperty::InstanceSize(), space);
-  WeakPropertyPtr result = static_cast<WeakPropertyPtr>(raw);
-  result->ptr()->next_ = 0;  // Init the list to NULL.
-  return result;
+  return static_cast<WeakPropertyPtr>(raw);
 }
 
 const char* WeakProperty::ToCString() const {
@@ -24900,9 +24898,13 @@
   const Library& lib = Library::Handle(cls.library());
   switch (kind()) {
     case FunctionLayout::kRegularFunction:
-    case FunctionLayout::kImplicitClosureFunction:
       return dart::VerifyEntryPoint(lib, *this, *this,
                                     {EntryPointPragma::kGetterOnly});
+    case FunctionLayout::kImplicitClosureFunction: {
+      const Function& parent = Function::Handle(parent_function());
+      return dart::VerifyEntryPoint(lib, parent, parent,
+                                    {EntryPointPragma::kGetterOnly});
+    }
     default:
       UNREACHABLE();
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 85add6f..467e1b1 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -63,6 +63,7 @@
 class FlowGraphCompiler;
 class HierarchyInfo;
 class LocalScope;
+class CallSiteResetter;
 class CodeStatistics;
 class IsolateGroupReloadContext;
 
@@ -228,9 +229,9 @@
 
 #define HEAP_OBJECT_IMPLEMENTATION(object, super)                              \
   OBJECT_IMPLEMENTATION(object, super);                                        \
-  const object##Layout* raw_ptr() const {                                      \
+  object##Layout* raw_ptr() const {                                            \
     ASSERT(raw() != null());                                                   \
-    return raw()->ptr();                                                       \
+    return const_cast<object##Layout*>(raw()->ptr());                          \
   }                                                                            \
   SNAPSHOT_READER_SUPPORT(object)                                              \
   friend class StackFrame;                                                     \
@@ -252,9 +253,9 @@
   object() : super() {}                                                        \
   BASE_OBJECT_IMPLEMENTATION(object, super)                                    \
   OBJECT_SERVICE_SUPPORT(object)                                               \
-  const object##Layout* raw_ptr() const {                                      \
+  object##Layout* raw_ptr() const {                                            \
     ASSERT(raw() != null());                                                   \
-    return raw()->ptr();                                                       \
+    return const_cast<object##Layout*>(raw()->ptr());                          \
   }                                                                            \
   static intptr_t NextFieldOffset() { return -kWordSize; }                     \
   SNAPSHOT_READER_SUPPORT(rettype)                                             \
@@ -289,10 +290,6 @@
   ObjectPtr raw() const { return raw_; }
   void operator=(ObjectPtr value) { initializeHandle(this, value); }
 
-  uint32_t CompareAndSwapTags(uint32_t old_tags, uint32_t new_tags) const {
-    raw()->ptr()->tags_.StrongCAS(old_tags, new_tags);
-    return old_tags;
-  }
   bool IsCanonical() const { return raw()->ptr()->IsCanonical(); }
   void SetCanonical() const { raw()->ptr()->SetCanonical(); }
   void ClearCanonical() const { raw()->ptr()->ClearCanonical(); }
@@ -392,11 +389,11 @@
 
 #if defined(HASH_IN_OBJECT_HEADER)
   static uint32_t GetCachedHash(const ObjectPtr obj) {
-    return obj->ptr()->hash_;
+    return obj->ptr()->GetHeaderHash();
   }
 
   static void SetCachedHash(ObjectPtr obj, uint32_t hash) {
-    obj->ptr()->hash_ = hash;
+    obj->ptr()->SetHeaderHash(hash);
   }
 #endif
 
@@ -466,7 +463,6 @@
   static ClassPtr function_class() { return function_class_; }
   static ClassPtr closure_data_class() { return closure_data_class_; }
   static ClassPtr signature_data_class() { return signature_data_class_; }
-  static ClassPtr redirection_data_class() { return redirection_data_class_; }
   static ClassPtr ffi_trampoline_data_class() {
     return ffi_trampoline_data_class_;
   }
@@ -645,9 +641,6 @@
   void StoreSmi(SmiPtr const* addr, SmiPtr value) const {
     raw()->ptr()->StoreSmi(addr, value);
   }
-  void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) const {
-    raw()->ptr()->StoreSmiIgnoreRace(addr, value);
-  }
 
   template <typename FieldType>
   void StoreSimd128(const FieldType* addr, simd128_value_t value) const {
@@ -772,7 +765,6 @@
   static ClassPtr function_class_;        // Class of the Function vm object.
   static ClassPtr closure_data_class_;    // Class of ClosureData vm obj.
   static ClassPtr signature_data_class_;  // Class of SignatureData vm obj.
-  static ClassPtr redirection_data_class_;  // Class of RedirectionData vm obj.
   static ClassPtr ffi_trampoline_data_class_;  // Class of FfiTrampolineData
                                                // vm obj.
   static ClassPtr field_class_;                // Class of the Field vm object.
@@ -1042,7 +1034,7 @@
 
   virtual StringPtr DictionaryName() const { return Name(); }
 
-  ScriptPtr script() const { return raw_ptr()->script_; }
+  ScriptPtr script() const { return raw_ptr()->script(); }
   void set_script(const Script& value) const;
 
   TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
@@ -1054,7 +1046,7 @@
 
   // This class represents a typedef if the signature function is not null.
   FunctionPtr signature_function() const {
-    return raw_ptr()->signature_function_;
+    return raw_ptr()->signature_function();
   }
   void set_signature_function(const Function& value) const;
 
@@ -1077,14 +1069,14 @@
     return OFFSET_OF(ClassLayout, declaration_type_);
   }
 
-  LibraryPtr library() const { return raw_ptr()->library_; }
+  LibraryPtr library() const { return raw_ptr()->library(); }
   void set_library(const Library& value) const;
 
   // The type parameters (and their bounds) are specified as an array of
   // TypeParameter.
   TypeArgumentsPtr type_parameters() const {
     ASSERT(is_declaration_loaded());
-    return raw_ptr()->type_parameters_;
+    return raw_ptr()->type_parameters();
   }
   void set_type_parameters(const TypeArguments& value) const;
   intptr_t NumTypeParameters(Thread* thread) const;
@@ -1172,7 +1164,7 @@
   // The super type of this class, Object type if not explicitly specified.
   AbstractTypePtr super_type() const {
     ASSERT(is_declaration_loaded());
-    return raw_ptr()->super_type_;
+    return raw_ptr()->super_type();
   }
   void set_super_type(const AbstractType& value) const;
   static intptr_t super_type_offset() {
@@ -1188,7 +1180,7 @@
   // Interfaces is an array of Types.
   ArrayPtr interfaces() const {
     ASSERT(is_declaration_loaded());
-    return raw_ptr()->interfaces_;
+    return raw_ptr()->interfaces();
   }
   void set_interfaces(const Array& value) const;
 
@@ -1196,7 +1188,7 @@
   GrowableObjectArrayPtr direct_implementors() const {
     DEBUG_ASSERT(
         IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
-    return raw_ptr()->direct_implementors_;
+    return raw_ptr()->direct_implementors();
   }
   void AddDirectImplementor(const Class& subclass, bool is_mixin) const;
   void ClearDirectImplementors() const;
@@ -1208,7 +1200,7 @@
     return direct_subclasses_unsafe();
   }
   GrowableObjectArrayPtr direct_subclasses_unsafe() const {
-    return raw_ptr()->direct_subclasses_;
+    return raw_ptr()->direct_subclasses();
   }
   void AddDirectSubclass(const Class& subclass) const;
   void ClearDirectSubclasses() const;
@@ -1250,7 +1242,7 @@
   static bool IsInFullSnapshot(ClassPtr cls) {
     NoSafepointScope no_safepoint;
     return LibraryLayout::InFullSnapshotBit::decode(
-        cls->ptr()->library_->ptr()->flags_);
+        cls->ptr()->library()->ptr()->flags_);
   }
 
   // Returns true if the type specified by cls, type_arguments, and nullability
@@ -1274,7 +1266,7 @@
   ArrayPtr fields() const {
     // We rely on the fact that any loads from the array are dependent loads
     // and avoid the load-acquire barrier here.
-    return raw_ptr()->fields_;
+    return raw_ptr()->fields();
   }
   void SetFields(const Array& value) const;
   void AddField(const Field& field) const;
@@ -1298,7 +1290,7 @@
   ArrayPtr current_functions() const {
     // We rely on the fact that any loads from the array are dependent loads
     // and avoid the load-acquire barrier here.
-    return raw_ptr()->functions_;
+    return raw_ptr()->functions();
   }
   ArrayPtr functions() const {
     DEBUG_ASSERT(
@@ -1430,7 +1422,7 @@
     StoreNonPointer(&raw_ptr()->num_native_fields_, value);
   }
 
-  CodePtr allocation_stub() const { return raw_ptr()->allocation_stub_; }
+  CodePtr allocation_stub() const { return raw_ptr()->allocation_stub(); }
   void set_allocation_stub(const Code& value) const;
 
   intptr_t kernel_offset() const {
@@ -1541,7 +1533,7 @@
   // Return the list of code objects that were compiled using CHA of this class.
   // These code objects will be invalidated if new subclasses of this class
   // are finalized.
-  ArrayPtr dependent_code() const { return raw_ptr()->dependent_code_; }
+  ArrayPtr dependent_code() const;
   void set_dependent_code(const Array& array) const;
 
   bool TraceAllocation(Isolate* isolate) const;
@@ -1601,7 +1593,7 @@
   }
 
  private:
-  TypePtr declaration_type() const { return raw_ptr()->declaration_type_; }
+  TypePtr declaration_type() const { return raw_ptr()->declaration_type(); }
 
   // Caches the declaration type of this class.
   void set_declaration_type(const Type& type) const;
@@ -1753,11 +1745,11 @@
 
 class PatchClass : public Object {
  public:
-  ClassPtr patched_class() const { return raw_ptr()->patched_class_; }
-  ClassPtr origin_class() const { return raw_ptr()->origin_class_; }
-  ScriptPtr script() const { return raw_ptr()->script_; }
+  ClassPtr patched_class() const { return raw_ptr()->patched_class(); }
+  ClassPtr origin_class() const { return raw_ptr()->origin_class(); }
+  ScriptPtr script() const { return raw_ptr()->script(); }
   ExternalTypedDataPtr library_kernel_data() const {
-    return raw_ptr()->library_kernel_data_;
+    return raw_ptr()->library_kernel_data();
   }
   void set_library_kernel_data(const ExternalTypedData& data) const;
 
@@ -1778,7 +1770,7 @@
   }
   static bool IsInFullSnapshot(PatchClassPtr cls) {
     NoSafepointScope no_safepoint;
-    return Class::IsInFullSnapshot(cls->ptr()->patched_class_);
+    return Class::IsInFullSnapshot(cls->ptr()->patched_class());
   }
 
   static PatchClassPtr New(const Class& patched_class,
@@ -1799,7 +1791,7 @@
 
 class SingleTargetCache : public Object {
  public:
-  CodePtr target() const { return raw_ptr()->target_; }
+  CodePtr target() const { return raw_ptr()->target(); }
   void set_target(const Code& target) const;
   static intptr_t target_offset() {
     return OFFSET_OF(SingleTargetCacheLayout, target_);
@@ -1832,7 +1824,7 @@
 
 class MonomorphicSmiableCall : public Object {
  public:
-  CodePtr target() const { return raw_ptr()->target_; }
+  CodePtr target() const { return raw_ptr()->target(); }
   classid_t expected_cid() const { return raw_ptr()->expected_cid_; }
 
   static intptr_t InstanceSize() {
@@ -1861,8 +1853,18 @@
 
 class CallSiteData : public Object {
  public:
-  StringPtr target_name() const { return raw_ptr()->target_name_; }
-  ArrayPtr arguments_descriptor() const { return raw_ptr()->args_descriptor_; }
+  StringPtr target_name() const { return raw_ptr()->target_name(); }
+  ArrayPtr arguments_descriptor() const { return raw_ptr()->args_descriptor(); }
+
+  intptr_t TypeArgsLen() const;
+
+  intptr_t CountWithTypeArgs() const;
+
+  intptr_t CountWithoutTypeArgs() const;
+
+  intptr_t SizeWithoutTypeArgs() const;
+
+  intptr_t SizeWithTypeArgs() const;
 
   static intptr_t target_name_offset() {
     return OFFSET_OF(CallSiteDataLayout, target_name_);
@@ -1923,16 +1925,6 @@
 
   intptr_t NumArgsTested() const;
 
-  intptr_t TypeArgsLen() const;
-
-  intptr_t CountWithTypeArgs() const;
-
-  intptr_t CountWithoutTypeArgs() const;
-
-  intptr_t SizeWithoutTypeArgs() const;
-
-  intptr_t SizeWithTypeArgs() const;
-
   intptr_t deopt_id() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
     UNREACHABLE();
@@ -1946,23 +1938,15 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   AbstractTypePtr receivers_static_type() const {
-    return raw_ptr()->receivers_static_type_;
+    return raw_ptr()->receivers_static_type();
   }
-  void SetReceiversStaticType(const AbstractType& type) const;
   bool is_tracking_exactness() const {
     return TrackingExactnessBit::decode(raw_ptr()->state_bits_);
   }
-  void set_tracking_exactness(bool value) const {
-    StoreNonPointer(
-        &raw_ptr()->state_bits_,
-        TrackingExactnessBit::update(value, raw_ptr()->state_bits_));
-  }
 #else
   bool is_tracking_exactness() const { return false; }
 #endif
 
-  void Reset(Zone* zone) const;
-
 // Note: only deopts with reasons before Unknown in this list are recorded in
 // the ICData. All other reasons are used purely for informational messages
 // printed during deoptimization itself.
@@ -2027,7 +2011,6 @@
   static const char* RebindRuleToCString(RebindRule r);
   static bool ParseRebindRule(const char* str, RebindRule* out);
   RebindRule rebind_rule() const;
-  void set_rebind_rule(uint32_t rebind_rule) const;
 
   void set_is_megamorphic(bool value) const {
     // We don't have concurrent RW access to [state_bits_].
@@ -2079,25 +2062,34 @@
 #endif
 
   // Replaces entry |index| with the sentinel.
-  void WriteSentinelAt(intptr_t index) const;
+  // NOTE: Can only be called during reload.
+  void WriteSentinelAt(intptr_t index,
+                       const CallSiteResetter& proof_of_reload) const;
 
   // Clears the count for entry |index|.
-  void ClearCountAt(intptr_t index) const;
+  // NOTE: Can only be called during reload.
+  void ClearCountAt(intptr_t index,
+                    const CallSiteResetter& proof_of_reload) const;
 
   // Clear all entries with the sentinel value and reset the first entry
   // with the dummy target entry.
-  void ClearAndSetStaticTarget(const Function& func) const;
+  // NOTE: Can only be called during reload.
+  void ClearAndSetStaticTarget(const Function& func,
+                               const CallSiteResetter& proof_of_reload) const;
 
   void DebugDump() const;
 
-  // Returns true if this is a two arg smi operation.
-  bool AddSmiSmiCheckForFastSmiStubs() const;
-
-  // Used for unoptimized static calls when no class-ids are checked.
-  void AddTarget(const Function& target) const;
-
   // Adding checks.
 
+  // Ensures there is a check for [class_ids].
+  //
+  // Calls [AddCheck] iff there is no existing check. Ensures test (and
+  // potential update) will be performed under exclusive lock to guard against
+  // multiple threads trying to add the same check.
+  void EnsureHasCheck(const GrowableArray<intptr_t>& class_ids,
+                      const Function& target,
+                      intptr_t count = 1) const;
+
   // Adds one more class test to ICData. Length of 'classes' must be equal to
   // the number of arguments tested. Use only for num_args_tested > 1.
   void AddCheck(const GrowableArray<intptr_t>& class_ids,
@@ -2106,6 +2098,18 @@
 
   StaticTypeExactnessState GetExactnessAt(intptr_t count) const;
 
+  // Ensures there is a receiver check for [receiver_class_id].
+  //
+  // Calls [AddCheckReceiverCheck] iff there is no existing check. Ensures
+  // test (and potential update) will be performed under exclusive lock to
+  // guard against multiple threads trying to add the same check.
+  void EnsureHasReceiverCheck(
+      intptr_t receiver_class_id,
+      const Function& target,
+      intptr_t count = 1,
+      StaticTypeExactnessState exactness =
+          StaticTypeExactnessState::NotTracking()) const;
+
   // Adds sorted so that Smi is the first class-id. Use only for
   // num_args_tested == 1.
   void AddReceiverCheck(intptr_t receiver_class_id,
@@ -2114,9 +2118,6 @@
                         StaticTypeExactnessState exactness =
                             StaticTypeExactnessState::NotTracking()) const;
 
-  // Does entry |index| contain the sentinel value?
-  bool IsSentinelAt(intptr_t index) const;
-
   // Retrieving checks.
 
   void GetCheckAt(intptr_t index,
@@ -2136,10 +2137,6 @@
 
   FunctionPtr GetTargetAt(intptr_t index) const;
 
-  ObjectPtr GetTargetOrCodeAt(intptr_t index) const;
-  void SetCodeAt(intptr_t index, const Code& value) const;
-  void SetEntryPointAt(intptr_t index, const Smi& value) const;
-
   void IncrementCountAt(intptr_t index, intptr_t value) const;
   void SetCountAt(intptr_t index, intptr_t value) const;
   intptr_t GetCountAt(intptr_t index) const;
@@ -2150,8 +2147,6 @@
   // Returns only used entries.
   ICDataPtr AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
   ICDataPtr AsUnaryClassChecks() const { return AsUnaryClassChecksForArgNr(0); }
-  ICDataPtr AsUnaryClassChecksForCid(intptr_t cid,
-                                     const Function& target) const;
 
   // Returns ICData with aggregated receiver count, sorted by highest count.
   // Smi not first!! (the convention for ICData used in code generation is that
@@ -2175,6 +2170,26 @@
       intptr_t num_args_tested,
       RebindRule rebind_rule,
       const AbstractType& receiver_type = Object::null_abstract_type());
+
+  // Similar to [New] makes the ICData have an initial (cids, target) entry.
+  static ICDataPtr NewWithCheck(
+      const Function& owner,
+      const String& target_name,
+      const Array& arguments_descriptor,
+      intptr_t deopt_id,
+      intptr_t num_args_tested,
+      RebindRule rebind_rule,
+      GrowableArray<intptr_t>* cids,
+      const Function& target,
+      const AbstractType& receiver_type = Object::null_abstract_type());
+
+  static ICDataPtr NewForStaticCall(const Function& owner,
+                                    const Function& target,
+                                    const Array& arguments_descriptor,
+                                    intptr_t deopt_id,
+                                    intptr_t num_args_tested,
+                                    RebindRule rebind_rule);
+
   static ICDataPtr NewFrom(const ICData& from, intptr_t num_args_tested);
 
   // Generates a new ICData with descriptor and data array copied (deep clone).
@@ -2218,8 +2233,7 @@
   intptr_t FindCheck(const GrowableArray<intptr_t>& cids) const;
 
   ArrayPtr entries() const {
-    return LoadPointer<ArrayPtr, std::memory_order_acquire>(
-        &raw_ptr()->entries_);
+    return raw_ptr()->entries<std::memory_order_acquire>();
   }
 
   bool receiver_cannot_be_smi() const {
@@ -2241,11 +2255,33 @@
   // for the new entry.
   ArrayPtr Grow(intptr_t* index) const;
 
-  void set_owner(const Function& value) const;
   void set_deopt_id(intptr_t value) const;
-  void SetNumArgsTested(intptr_t value) const;
   void set_entries(const Array& value) const;
+  void set_owner(const Function& value) const;
+  void set_rebind_rule(uint32_t rebind_rule) const;
   void set_state_bits(uint32_t bits) const;
+  void set_tracking_exactness(bool value) const {
+    StoreNonPointer(
+        &raw_ptr()->state_bits_,
+        TrackingExactnessBit::update(value, raw_ptr()->state_bits_));
+  }
+
+  // Does entry |index| contain the sentinel value?
+  bool IsSentinelAt(intptr_t index) const;
+  void SetNumArgsTested(intptr_t value) const;
+  void SetReceiversStaticType(const AbstractType& type) const;
+
+  static void SetTargetAtPos(const Array& data,
+                             intptr_t data_pos,
+                             intptr_t num_args_tested,
+                             const Function& target);
+  void AddCheckInternal(const GrowableArray<intptr_t>& class_ids,
+                        const Function& target,
+                        intptr_t count) const;
+  void AddReceiverCheckInternal(intptr_t receiver_class_id,
+                                const Function& target,
+                                intptr_t count,
+                                StaticTypeExactnessState exactness) const;
 
   // This bit is set when a call site becomes megamorphic and starts using a
   // MegamorphicCache instead of ICData. It means that the entries in the
@@ -2402,7 +2438,7 @@
 
 class Function : public Object {
  public:
-  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name(); }
   StringPtr UserVisibleName() const;  // Same as scrubbed name.
   const char* UserVisibleNameCString() const;
 
@@ -2499,7 +2535,7 @@
   void set_owner(const Object& value) const;
   ClassPtr origin() const;
   ScriptPtr script() const;
-  ObjectPtr RawOwner() const { return raw_ptr()->owner_; }
+  ObjectPtr RawOwner() const { return raw_ptr()->owner(); }
 
   // The NNBD mode of the library declaring this function.
   // TODO(alexmarkov): nnbd_mode() doesn't work for mixins.
@@ -2516,7 +2552,7 @@
   StringPtr native_name() const;
   void set_native_name(const String& name) const;
 
-  AbstractTypePtr result_type() const { return raw_ptr()->result_type_; }
+  AbstractTypePtr result_type() const { return raw_ptr()->result_type(); }
   void set_result_type(const AbstractType& value) const;
 
   // The parameters, starting with NumImplicitParameters() parameters which are
@@ -2524,7 +2560,7 @@
   // Note that type checks exclude implicit parameters.
   AbstractTypePtr ParameterTypeAt(intptr_t index) const;
   void SetParameterTypeAt(intptr_t index, const AbstractType& value) const;
-  ArrayPtr parameter_types() const { return raw_ptr()->parameter_types_; }
+  ArrayPtr parameter_types() const { return raw_ptr()->parameter_types(); }
   void set_parameter_types(const Array& value) const;
   static intptr_t parameter_types_offset() {
     return OFFSET_OF(FunctionLayout, parameter_types_);
@@ -2537,7 +2573,7 @@
   // elements are the names.
   StringPtr ParameterNameAt(intptr_t index) const;
   void SetParameterNameAt(intptr_t index, const String& value) const;
-  ArrayPtr parameter_names() const { return raw_ptr()->parameter_names_; }
+  ArrayPtr parameter_names() const { return raw_ptr()->parameter_names(); }
   static intptr_t parameter_names_offset() {
     return OFFSET_OF(FunctionLayout, parameter_names_);
   }
@@ -2563,7 +2599,7 @@
   // The type parameters (and their bounds) are specified as an array of
   // TypeParameter.
   TypeArgumentsPtr type_parameters() const {
-    return raw_ptr()->type_parameters_;
+    return raw_ptr()->type_parameters();
   }
   void set_type_parameters(const TypeArguments& value) const;
   static intptr_t type_parameters_offset() {
@@ -2628,14 +2664,14 @@
   bool SafeToClosurize() const;
 
   static CodePtr CurrentCodeOf(const FunctionPtr function) {
-    return function->ptr()->code_;
+    return function->ptr()->code();
   }
 
   CodePtr unoptimized_code() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
     return static_cast<CodePtr>(Object::null());
 #else
-    return raw_ptr()->unoptimized_code_;
+    return raw_ptr()->unoptimized_code();
 #endif
   }
   void set_unoptimized_code(const Code& value) const;
@@ -2696,23 +2732,20 @@
                     (1 << kDefaultTypeArgumentsKindFieldSize),
                 "Wrong bit size chosen for default TAV kind field");
 
-  // Fields encoded in an integer stored alongside a default TAV.
+  // Fields encoded in an integer stored alongside a default TAV. The size of
+  // the integer should be <= the size of a target Smi.
   using DefaultTypeArgumentsKindField =
       BitField<intptr_t,
                DefaultTypeArgumentsKind,
                0,
                kDefaultTypeArgumentsKindFieldSize>;
-  // If more space is needed, we can almost certainly reduce the size of this
-  // field.
+  // Just use the rest of the space for the number of parent type parameters.
   using NumParentTypeParametersField =
       BitField<intptr_t,
-               uint16_t,
+               intptr_t,
                DefaultTypeArgumentsKindField::kNextBit,
-               kBitsPerByte * sizeof(uint16_t)>;
-
-  static_assert(NumParentTypeParametersField::kNextBit <=
-                    compiler::target::kSmiBits,
-                "Default TAV info does not fit in a target Smi");
+               compiler::target::kSmiBits -
+                   DefaultTypeArgumentsKindField::kNextBit>;
 
   // Returns a canonicalized vector of the type parameters instantiated
   // to bounds. If non-generic, the empty type arguments vector is returned.
@@ -2817,15 +2850,6 @@
 
   intptr_t ComputeClosureHash() const;
 
-  // Redirection information for a redirecting factory.
-  bool IsRedirectingFactory() const;
-  TypePtr RedirectionType() const;
-  void SetRedirectionType(const Type& type) const;
-  StringPtr RedirectionIdentifier() const;
-  void SetRedirectionIdentifier(const String& identifier) const;
-  FunctionPtr RedirectionTarget() const;
-  void SetRedirectionTarget(const Function& target) const;
-
   FunctionPtr ForwardingTarget() const;
   void SetForwardingChecks(const Array& checks) const;
 
@@ -2850,14 +2874,6 @@
     return (kind() == FunctionLayout::kConstructor) && is_static();
   }
 
-  static bool ClosureBodiesContainNonCovariantArgumentChecks() {
-    return FLAG_precompiled_mode || FLAG_lazy_dispatchers;
-  }
-
-  // Whether this function can receive an invocation where the number and names
-  // of arguments have not been checked.
-  bool CanReceiveDynamicInvocation() const { return IsFfiTrampoline(); }
-
   bool HasThisParameter() const {
     return IsDynamicFunction(/*allow_abstract=*/true) ||
            IsGenerativeConstructor() || (IsFieldInitializer() && !is_static());
@@ -2921,13 +2937,11 @@
   }
   bool IsInFactoryScope() const;
 
-  bool NeedsArgumentTypeChecks() const {
-    return (IsClosureFunction() &&
-            ClosureBodiesContainNonCovariantArgumentChecks()) ||
-           !(is_static() || (kind() == FunctionLayout::kConstructor));
+  bool NeedsTypeArgumentTypeChecks() const {
+    return !(is_static() || (kind() == FunctionLayout::kConstructor));
   }
 
-  bool NeedsTypeArgumentTypeChecks() const {
+  bool NeedsArgumentTypeChecks() const {
     return !(is_static() || (kind() == FunctionLayout::kConstructor));
   }
 
@@ -3584,7 +3598,7 @@
   int32_t SourceFingerprint() const;
 
   // Return false and report an error if the fingerprint does not match.
-  bool CheckSourceFingerprint(int32_t fp) const;
+  bool CheckSourceFingerprint(int32_t fp, const char* kind = nullptr) const;
 
   // Works with map [deopt-id] -> ICData.
   void SaveICDataMap(
@@ -3670,7 +3684,6 @@
   //            don't support during inlining (e.g., optional parameters),
   //            functions which are too big, etc.
   // native: Bridge to C/C++ code.
-  // redirecting: Redirecting generative or factory constructor.
   // external: Just a declaration that expects to be defined in another patch
   //           file.
   // generated_body: Has a generated body.
@@ -3688,7 +3701,6 @@
   V(Inlinable, is_inlinable)                                                   \
   V(Intrinsic, is_intrinsic)                                                   \
   V(Native, is_native)                                                         \
-  V(Redirecting, is_redirecting)                                               \
   V(External, is_external)                                                     \
   V(GeneratedBody, is_generated_body)                                          \
   V(PolymorphicTarget, is_polymorphic_target)                                  \
@@ -3871,11 +3883,11 @@
 
  private:
   // Enclosing function of this signature function.
-  FunctionPtr parent_function() const { return raw_ptr()->parent_function_; }
+  FunctionPtr parent_function() const { return raw_ptr()->parent_function(); }
   void set_parent_function(const Function& value) const;
 
   // Signature type of this signature function.
-  TypePtr signature_type() const { return raw_ptr()->signature_type_; }
+  TypePtr signature_type() const { return raw_ptr()->signature_type(); }
   void set_signature_type(const Type& value) const;
 
   static SignatureDataPtr New(Heap::Space space = Heap::kOld);
@@ -3886,33 +3898,6 @@
   friend class HeapProfiler;
 };
 
-class RedirectionData : public Object {
- public:
-  static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RedirectionDataLayout));
-  }
-
- private:
-  // The type specifies the class and type arguments of the target constructor.
-  TypePtr type() const { return raw_ptr()->type_; }
-  void set_type(const Type& value) const;
-
-  // The optional identifier specifies a named constructor.
-  StringPtr identifier() const { return raw_ptr()->identifier_; }
-  void set_identifier(const String& value) const;
-
-  // The resolved constructor or factory target of the redirection.
-  FunctionPtr target() const { return raw_ptr()->target_; }
-  void set_target(const Function& value) const;
-
-  static RedirectionDataPtr New();
-
-  FINAL_HEAP_OBJECT_IMPLEMENTATION(RedirectionData, Object);
-  friend class Class;
-  friend class Function;
-  friend class HeapProfiler;
-};
-
 enum class EntryPointPragma {
   kAlways,
   kNever,
@@ -3929,17 +3914,17 @@
 
  private:
   // Signature type of this closure function.
-  TypePtr signature_type() const { return raw_ptr()->signature_type_; }
+  TypePtr signature_type() const { return raw_ptr()->signature_type(); }
   void set_signature_type(const Type& value) const;
 
-  FunctionPtr c_signature() const { return raw_ptr()->c_signature_; }
+  FunctionPtr c_signature() const { return raw_ptr()->c_signature(); }
   void set_c_signature(const Function& value) const;
 
-  FunctionPtr callback_target() const { return raw_ptr()->callback_target_; }
+  FunctionPtr callback_target() const { return raw_ptr()->callback_target(); }
   void set_callback_target(const Function& value) const;
 
   InstancePtr callback_exceptional_return() const {
-    return raw_ptr()->callback_exceptional_return_;
+    return raw_ptr()->callback_exceptional_return();
   }
   void set_callback_exceptional_return(const Instance& value) const;
 
@@ -3970,7 +3955,7 @@
       return true;
     }
     NoSafepointScope no_safepoint;
-    return !raw_ptr()->owner_->IsField();
+    return !raw_ptr()->owner()->IsField();
   }
 
   // Returns whether fields must be cloned via [CloneFromOriginal] for the
@@ -3981,7 +3966,7 @@
   // original field of result.
   FieldPtr CloneFromOriginal() const;
 
-  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name(); }
   StringPtr UserVisibleName() const;  // Same as scrubbed name.
   const char* UserVisibleNameCString() const;
   virtual StringPtr DictionaryName() const { return name(); }
@@ -4088,19 +4073,12 @@
   inline intptr_t field_id() const;
   inline void set_field_id(intptr_t field_id) const;
 
-#ifndef DART_PRECOMPILED_RUNTIME
-  InstancePtr saved_initial_value() const {
-    return raw_ptr()->saved_initial_value_;
-  }
-  inline void set_saved_initial_value(const Instance& value) const;
-#endif
-
   ClassPtr Owner() const;
   ClassPtr Origin() const;  // Either mixin class, or same as owner().
   ScriptPtr Script() const;
   ObjectPtr RawOwner() const;
 
-  AbstractTypePtr type() const { return raw_ptr()->type_; }
+  AbstractTypePtr type() const { return raw_ptr()->type(); }
   // Used by class finalizer, otherwise initialized in constructor.
   void SetFieldType(const AbstractType& value) const;
 
@@ -4211,6 +4189,11 @@
   }
 
   void set_guarded_cid(intptr_t cid) const {
+    DEBUG_ASSERT(
+        IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+    set_guarded_cid_unsafe(cid);
+  }
+  void set_guarded_cid_unsafe(intptr_t cid) const {
 #if defined(DEBUG)
     Thread* thread = Thread::Current();
     ASSERT(!IsOriginal() || is_static() || thread->IsMutatorThread() ||
@@ -4226,12 +4209,22 @@
   // been determined. If length is kNoFixedLength this field has multiple
   // list lengths associated with it and cannot be predicted.
   intptr_t guarded_list_length() const;
-  void set_guarded_list_length(intptr_t list_length) const;
+  void set_guarded_list_length_unsafe(intptr_t list_length) const;
+  void set_guarded_list_length(intptr_t list_length) const {
+    DEBUG_ASSERT(
+        IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+    set_guarded_list_length_unsafe(list_length);
+  }
   static intptr_t guarded_list_length_offset() {
     return OFFSET_OF(FieldLayout, guarded_list_length_);
   }
   intptr_t guarded_list_length_in_object_offset() const;
-  void set_guarded_list_length_in_object_offset(intptr_t offset) const;
+  void set_guarded_list_length_in_object_offset_unsafe(intptr_t offset) const;
+  void set_guarded_list_length_in_object_offset(intptr_t offset) const {
+    DEBUG_ASSERT(
+        IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+    set_guarded_list_length_in_object_offset_unsafe(offset);
+  }
   static intptr_t guarded_list_length_in_object_offset_offset() {
     return OFFSET_OF(FieldLayout, guarded_list_length_in_object_offset_);
   }
@@ -4295,6 +4288,11 @@
     return raw_ptr()->is_nullable_ == kNullCid;
   }
   void set_is_nullable(bool val) const {
+    DEBUG_ASSERT(
+        IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+    set_is_nullable_unsafe(val);
+  }
+  void set_is_nullable_unsafe(bool val) const {
     ASSERT(Thread::Current()->IsMutatorThread());
     StoreNonPointer(&raw_ptr()->is_nullable_, val ? kNullCid : kIllegalCid);
   }
@@ -4306,7 +4304,7 @@
   // deoptimization of dependent optimized code.
   void RecordStore(const Object& value) const;
 
-  void InitializeGuardedListLengthInObjectOffset() const;
+  void InitializeGuardedListLengthInObjectOffset(bool unsafe = false) const;
 
   // Return the list of optimized code objects that were optimized under
   // assumptions about guarded class id and nullability of this field.
@@ -4339,7 +4337,7 @@
   FunctionPtr InitializerFunction() const {
     // We rely on the fact that any loads from the initializer function
     // are dependent loads and avoid the load-acquire barrier here.
-    return raw_ptr()->initializer_function_;
+    return raw_ptr()->initializer_function<std::memory_order_relaxed>();
   }
   void SetInitializerFunction(const Function& initializer) const;
   bool HasInitializerFunction() const;
@@ -4371,7 +4369,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   SubtypeTestCachePtr type_test_cache() const {
-    return raw_ptr()->type_test_cache_;
+    return raw_ptr()->type_test_cache();
   }
   void set_type_test_cache(const SubtypeTestCache& cache) const;
 #endif
@@ -4463,7 +4461,7 @@
     set_kind_bits(ConstBit::update(value, raw_ptr()->kind_bits_));
   }
   void set_owner(const Object& value) const {
-    StorePointer(&raw_ptr()->owner_, value.raw());
+    raw_ptr()->set_owner(value.raw());
   }
   void set_token_pos(TokenPosition token_pos) const {
     StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
@@ -4487,11 +4485,11 @@
 
 class Script : public Object {
  public:
-  StringPtr url() const { return raw_ptr()->url_; }
+  StringPtr url() const { return raw_ptr()->url(); }
   void set_url(const String& value) const;
 
   // The actual url which was loaded from disk, if provided by the embedder.
-  StringPtr resolved_url() const { return raw_ptr()->resolved_url_; }
+  StringPtr resolved_url() const { return raw_ptr()->resolved_url(); }
   bool HasSource() const;
   StringPtr Source() const;
   bool IsPartOfDartColonLibrary() const;
@@ -4506,12 +4504,12 @@
   int64_t load_timestamp() const { return raw_ptr()->load_timestamp_; }
 
   ArrayPtr compile_time_constants() const {
-    return raw_ptr()->compile_time_constants_;
+    return raw_ptr()->compile_time_constants();
   }
   void set_compile_time_constants(const Array& value) const;
 
   KernelProgramInfoPtr kernel_program_info() const {
-    return raw_ptr()->kernel_program_info_;
+    return raw_ptr()->kernel_program_info();
   }
   void set_kernel_program_info(const KernelProgramInfo& info) const;
 
@@ -4524,13 +4522,18 @@
 
   TypedDataPtr line_starts() const;
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  ExternalTypedDataPtr constant_coverage() const;
+
+  void set_constant_coverage(const ExternalTypedData& value) const;
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
   void set_line_starts(const TypedData& value) const;
 
   void set_debug_positions(const Array& value) const;
 
   LibraryPtr FindLibrary() const;
   StringPtr GetLine(intptr_t line_number, Heap::Space space = Heap::kNew) const;
-  StringPtr GetSnippet(TokenPosition from, TokenPosition to) const;
   StringPtr GetSnippet(intptr_t from_line,
                        intptr_t from_column,
                        intptr_t to_line,
@@ -4635,11 +4638,11 @@
 
 class Library : public Object {
  public:
-  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name(); }
   void SetName(const String& name) const;
 
-  StringPtr url() const { return raw_ptr()->url_; }
-  StringPtr private_key() const { return raw_ptr()->private_key_; }
+  StringPtr url() const { return raw_ptr()->url(); }
+  StringPtr private_key() const { return raw_ptr()->private_key(); }
   bool LoadNotStarted() const {
     return raw_ptr()->load_state_ == LibraryLayout::kAllocated;
   }
@@ -4656,7 +4659,7 @@
   }
   void SetLoaded() const;
 
-  LoadingUnitPtr loading_unit() const { return raw_ptr()->loading_unit_; }
+  LoadingUnitPtr loading_unit() const { return raw_ptr()->loading_unit(); }
   void set_loading_unit(const LoadingUnit& value) const;
 
   static intptr_t InstanceSize() {
@@ -4734,25 +4737,8 @@
 
   void AddExport(const Namespace& ns) const;
 
-  void AddClassMetadata(const Class& cls,
-                        const Object& tl_owner,
-                        TokenPosition token_pos,
-                        intptr_t kernel_offset) const;
-  void AddFieldMetadata(const Field& field,
-                        TokenPosition token_pos,
-                        intptr_t kernel_offset) const;
-  void AddFunctionMetadata(const Function& func,
-                           TokenPosition token_pos,
-                           intptr_t kernel_offset) const;
-  void AddLibraryMetadata(const Object& tl_owner,
-                          TokenPosition token_pos,
-                          intptr_t kernel_offset) const;
-  void AddTypeParameterMetadata(const TypeParameter& param,
-                                TokenPosition token_pos) const;
-  void CloneMetadataFrom(const Library& from_library,
-                         const Function& from_fun,
-                         const Function& to_fun) const;
-  ObjectPtr GetMetadata(const Object& obj) const;
+  void AddMetadata(const Object& declaration, intptr_t kernel_offset) const;
+  ObjectPtr GetMetadata(const Object& declaration) const;
 
   // Tries to finds a @pragma annotation on [object].
   //
@@ -4770,22 +4756,22 @@
                          const String& pragma_name,
                          Object* options);
 
-  ClassPtr toplevel_class() const { return raw_ptr()->toplevel_class_; }
+  ClassPtr toplevel_class() const { return raw_ptr()->toplevel_class(); }
   void set_toplevel_class(const Class& value) const;
 
   GrowableObjectArrayPtr used_scripts() const {
-    return raw_ptr()->used_scripts_;
+    return raw_ptr()->used_scripts();
   }
 
   // Library imports.
-  ArrayPtr imports() const { return raw_ptr()->imports_; }
-  ArrayPtr exports() const { return raw_ptr()->exports_; }
+  ArrayPtr imports() const { return raw_ptr()->imports(); }
+  ArrayPtr exports() const { return raw_ptr()->exports(); }
   void AddImport(const Namespace& ns) const;
   intptr_t num_imports() const { return raw_ptr()->num_imports_; }
   NamespacePtr ImportAt(intptr_t index) const;
   LibraryPtr ImportLibraryAt(intptr_t index) const;
 
-  ArrayPtr dependencies() const { return raw_ptr()->dependencies_; }
+  ArrayPtr dependencies() const { return raw_ptr()->dependencies(); }
   void set_dependencies(const Array& deps) const;
 
   void DropDependenciesAndCaches() const;
@@ -4871,7 +4857,7 @@
 
   inline intptr_t UrlHash() const;
 
-  ExternalTypedDataPtr kernel_data() const { return raw_ptr()->kernel_data_; }
+  ExternalTypedDataPtr kernel_data() const { return raw_ptr()->kernel_data(); }
   void set_kernel_data(const ExternalTypedData& data) const;
 
   intptr_t kernel_offset() const {
@@ -4913,7 +4899,6 @@
   static LibraryPtr ProfilerLibrary();
   static LibraryPtr TypedDataLibrary();
   static LibraryPtr VMServiceLibrary();
-  static LibraryPtr WasmLibrary();
 
   // Eagerly compile all classes and functions in the library.
   static ErrorPtr CompileAll(bool ignore_error = false);
@@ -4977,13 +4962,17 @@
   void set_num_imports(intptr_t value) const;
   void set_flags(uint8_t flags) const;
   bool HasExports() const;
-  ArrayPtr loaded_scripts() const { return raw_ptr()->loaded_scripts_; }
-  GrowableObjectArrayPtr metadata() const { return raw_ptr()->metadata_; }
-  void set_metadata(const GrowableObjectArray& value) const;
-  ArrayPtr dictionary() const { return raw_ptr()->dictionary_; }
+  ArrayPtr loaded_scripts() const { return raw_ptr()->loaded_scripts(); }
+  ArrayPtr metadata() const {
+    DEBUG_ASSERT(
+        IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
+    return raw_ptr()->metadata();
+  }
+  void set_metadata(const Array& value) const;
+  ArrayPtr dictionary() const { return raw_ptr()->dictionary(); }
   void InitClassDictionary() const;
 
-  ArrayPtr resolved_names() const { return raw_ptr()->resolved_names_; }
+  ArrayPtr resolved_names() const { return raw_ptr()->resolved_names(); }
   bool LookupResolvedNamesCache(const String& name, Object* obj) const;
   void AddToResolvedNamesCache(const String& name, const Object& obj) const;
   void InitResolvedNamesCache() const;
@@ -4991,7 +4980,7 @@
   void InvalidateResolvedName(const String& name) const;
   void InvalidateResolvedNamesCache() const;
 
-  ArrayPtr exported_names() const { return raw_ptr()->exported_names_; }
+  ArrayPtr exported_names() const { return raw_ptr()->exported_names(); }
   bool LookupExportedNamesCache(const String& name, Object* obj) const;
   void AddToExportedNamesCache(const String& name, const Object& obj) const;
   void InitExportedNamesCache() const;
@@ -5007,13 +4996,6 @@
 
   void AllocatePrivateKey() const;
 
-  StringPtr MakeMetadataName(const Object& obj) const;
-  FieldPtr GetMetadataField(const String& metaname) const;
-  void AddMetadata(const Object& owner,
-                   const String& name,
-                   TokenPosition token_pos,
-                   intptr_t kernel_offset) const;
-
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Library, Object);
 
   friend class Bootstrap;
@@ -5031,14 +5013,10 @@
 // the show/hide combinators.
 class Namespace : public Object {
  public:
-  LibraryPtr library() const { return raw_ptr()->library_; }
-  ArrayPtr show_names() const { return raw_ptr()->show_names_; }
-  ArrayPtr hide_names() const { return raw_ptr()->hide_names_; }
-
-  void AddMetadata(const Object& owner,
-                   TokenPosition token_pos,
-                   intptr_t kernel_offset = 0);
-  ObjectPtr GetMetadata() const;
+  LibraryPtr target() const { return raw_ptr()->target(); }
+  ArrayPtr show_names() const { return raw_ptr()->show_names(); }
+  ArrayPtr hide_names() const { return raw_ptr()->hide_names(); }
+  LibraryPtr owner() const { return raw_ptr()->owner(); }
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(NamespaceLayout));
@@ -5050,14 +5028,12 @@
 
   static NamespacePtr New(const Library& library,
                           const Array& show_names,
-                          const Array& hide_names);
+                          const Array& hide_names,
+                          const Library& owner);
 
  private:
   static NamespacePtr New();
 
-  FieldPtr metadata_field() const { return raw_ptr()->metadata_field_; }
-  void set_metadata_field(const Field& value) const;
-
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Namespace, Object);
   friend class Class;
   friend class Precompiler;
@@ -5081,30 +5057,30 @@
     return RoundedAllocationSize(sizeof(KernelProgramInfoLayout));
   }
 
-  TypedDataPtr string_offsets() const { return raw_ptr()->string_offsets_; }
+  TypedDataPtr string_offsets() const { return raw_ptr()->string_offsets(); }
 
-  ExternalTypedDataPtr string_data() const { return raw_ptr()->string_data_; }
+  ExternalTypedDataPtr string_data() const { return raw_ptr()->string_data(); }
 
-  TypedDataPtr canonical_names() const { return raw_ptr()->canonical_names_; }
+  TypedDataPtr canonical_names() const { return raw_ptr()->canonical_names(); }
 
   ExternalTypedDataPtr metadata_payloads() const {
-    return raw_ptr()->metadata_payloads_;
+    return raw_ptr()->metadata_payloads();
   }
 
   ExternalTypedDataPtr metadata_mappings() const {
-    return raw_ptr()->metadata_mappings_;
+    return raw_ptr()->metadata_mappings();
   }
 
   ExternalTypedDataPtr constants_table() const {
-    return raw_ptr()->constants_table_;
+    return raw_ptr()->constants_table();
   }
 
   void set_constants_table(const ExternalTypedData& value) const;
 
-  ArrayPtr scripts() const { return raw_ptr()->scripts_; }
+  ArrayPtr scripts() const { return raw_ptr()->scripts(); }
   void set_scripts(const Array& scripts) const;
 
-  ArrayPtr constants() const { return raw_ptr()->constants_; }
+  ArrayPtr constants() const { return raw_ptr()->constants(); }
   void set_constants(const Array& constants) const;
 
   uint32_t kernel_binary_version() const {
@@ -5118,26 +5094,26 @@
   //
   // This array will hold the functions which might need their native name set.
   GrowableObjectArrayPtr potential_natives() const {
-    return raw_ptr()->potential_natives_;
+    return raw_ptr()->potential_natives();
   }
   void set_potential_natives(const GrowableObjectArray& candidates) const;
 
   GrowableObjectArrayPtr potential_pragma_functions() const {
-    return raw_ptr()->potential_pragma_functions_;
+    return raw_ptr()->potential_pragma_functions();
   }
   void set_potential_pragma_functions(
       const GrowableObjectArray& candidates) const;
 
   ScriptPtr ScriptAt(intptr_t index) const;
 
-  ArrayPtr libraries_cache() const { return raw_ptr()->libraries_cache_; }
+  ArrayPtr libraries_cache() const { return raw_ptr()->libraries_cache(); }
   void set_libraries_cache(const Array& cache) const;
   LibraryPtr LookupLibrary(Thread* thread, const Smi& name_index) const;
   LibraryPtr InsertLibrary(Thread* thread,
                            const Smi& name_index,
                            const Library& lib) const;
 
-  ArrayPtr classes_cache() const { return raw_ptr()->classes_cache_; }
+  ArrayPtr classes_cache() const { return raw_ptr()->classes_cache(); }
   void set_classes_cache(const Array& cache) const;
   ClassPtr LookupClass(Thread* thread, const Smi& name_index) const;
   ClassPtr InsertClass(Thread* thread,
@@ -5967,8 +5943,8 @@
     return Object::null();
 #else
     // Outside the precompiled runtime, they should always have a target.
-    ASSERT(raw->ptr()->target_ != Object::null());
-    return raw->ptr()->target_;
+    ASSERT(raw->ptr()->target() != Object::null());
+    return raw->ptr()->target();
 #endif
   }
 
@@ -6052,14 +6028,14 @@
     UNREACHABLE();
     return NULL;
 #else
-    return raw_ptr()->active_instructions_;
+    return raw_ptr()->active_instructions();
 #endif
   }
 
   // When dual mapping, these return the executable view.
-  InstructionsPtr instructions() const { return raw_ptr()->instructions_; }
+  InstructionsPtr instructions() const { return raw_ptr()->instructions(); }
   static InstructionsPtr InstructionsOf(const CodePtr code) {
-    return code->ptr()->instructions_;
+    return code->ptr()->instructions();
   }
 
   static intptr_t saved_instructions_offset() {
@@ -6086,7 +6062,7 @@
     }
   }
 
-  ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool_; }
+  ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool(); }
   static intptr_t object_pool_offset() {
     return OFFSET_OF(CodeLayout, object_pool_);
   }
@@ -6192,19 +6168,21 @@
   // Returns true if there is a debugger breakpoint set in this code object.
   bool HasBreakpoint() const;
 
-  PcDescriptorsPtr pc_descriptors() const { return raw_ptr()->pc_descriptors_; }
+  PcDescriptorsPtr pc_descriptors() const {
+    return raw_ptr()->pc_descriptors();
+  }
   void set_pc_descriptors(const PcDescriptors& descriptors) const {
     ASSERT(descriptors.IsOld());
-    StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw());
+    raw_ptr()->set_pc_descriptors(descriptors.raw());
   }
 
   CodeSourceMapPtr code_source_map() const {
-    return raw_ptr()->code_source_map_;
+    return raw_ptr()->code_source_map();
   }
 
   void set_code_source_map(const CodeSourceMap& code_source_map) const {
     ASSERT(code_source_map.IsOld());
-    StorePointer(&raw_ptr()->code_source_map_, code_source_map.raw());
+    raw_ptr()->set_code_source_map(code_source_map.raw());
   }
 
   // Array of DeoptInfo objects.
@@ -6213,7 +6191,7 @@
     UNREACHABLE();
     return NULL;
 #else
-    return raw_ptr()->deopt_info_array_;
+    return raw_ptr()->deopt_info_array();
 #endif
   }
   void set_deopt_info_array(const Array& array) const;
@@ -6229,7 +6207,7 @@
 #endif
 
   CompressedStackMapsPtr compressed_stackmaps() const {
-    return raw_ptr()->compressed_stackmaps_;
+    return raw_ptr()->compressed_stackmaps();
   }
   void set_compressed_stackmaps(const CompressedStackMaps& maps) const;
 
@@ -6269,7 +6247,7 @@
     UNREACHABLE();
     return NULL;
 #else
-    return raw_ptr()->static_calls_target_table_;
+    return raw_ptr()->static_calls_target_table();
 #endif
   }
 
@@ -6322,7 +6300,7 @@
     UNREACHABLE();
     return NULL;
 #else
-    return raw_ptr()->return_address_metadata_;
+    return raw_ptr()->return_address_metadata();
 #endif
   }
   // Sets |return_address_metadata|.
@@ -6363,7 +6341,7 @@
     UNREACHABLE();
     return NULL;
 #else
-    return raw_ptr()->var_descriptors_;
+    return raw_ptr()->var_descriptors();
 #endif
   }
   void set_var_descriptors(const LocalVarDescriptors& value) const {
@@ -6371,7 +6349,7 @@
     UNREACHABLE();
 #else
     ASSERT(value.IsOld());
-    StorePointer(&raw_ptr()->var_descriptors_, value.raw());
+    raw_ptr()->set_var_descriptors(value.raw());
 #endif
   }
 
@@ -6379,11 +6357,11 @@
   LocalVarDescriptorsPtr GetLocalVarDescriptors() const;
 
   ExceptionHandlersPtr exception_handlers() const {
-    return raw_ptr()->exception_handlers_;
+    return raw_ptr()->exception_handlers();
   }
   void set_exception_handlers(const ExceptionHandlers& handlers) const {
     ASSERT(handlers.IsOld());
-    StorePointer(&raw_ptr()->exception_handlers_, handlers.raw());
+    raw_ptr()->set_exception_handlers(handlers.raw());
   }
 
   // WARNING: function() returns the owner which is not guaranteed to be
@@ -6395,15 +6373,15 @@
   FunctionPtr function() const {
     ASSERT(IsFunctionCode());
     return Function::RawCast(
-        WeakSerializationReference::Unwrap(raw_ptr()->owner_));
+        WeakSerializationReference::Unwrap(raw_ptr()->owner()));
   }
 
-  ObjectPtr owner() const { return raw_ptr()->owner_; }
+  ObjectPtr owner() const { return raw_ptr()->owner(); }
   void set_owner(const Object& owner) const;
 
   classid_t OwnerClassId() const { return OwnerClassIdOf(raw()); }
   static classid_t OwnerClassIdOf(CodePtr raw) {
-    return WeakSerializationReference::UnwrappedClassIdOf(raw->ptr()->owner_);
+    return WeakSerializationReference::UnwrappedClassIdOf(raw->ptr()->owner());
   }
 
   static intptr_t owner_offset() { return OFFSET_OF(CodeLayout, owner_); }
@@ -6509,12 +6487,12 @@
     UNREACHABLE();
     return false;
 #else
-    return code->ptr()->instructions_ != code->ptr()->active_instructions_;
+    return code->ptr()->instructions() != code->ptr()->active_instructions();
 #endif
   }
 
   void set_object_pool(ObjectPoolPtr object_pool) const {
-    StorePointer(&raw_ptr()->object_pool_, object_pool);
+    raw_ptr()->set_object_pool(object_pool);
   }
 
  private:
@@ -6582,7 +6560,7 @@
 
   void set_instructions(const Instructions& instructions) const {
     ASSERT(Thread::Current()->IsMutatorThread() || !is_alive());
-    StorePointer(&raw_ptr()->instructions_, instructions.raw());
+    raw_ptr()->set_instructions(instructions.raw());
   }
 #if !defined(DART_PRECOMPILED_RUNTIME)
   void set_unchecked_offset(uword offset) const {
@@ -6650,9 +6628,9 @@
 
 class Context : public Object {
  public:
-  ContextPtr parent() const { return raw_ptr()->parent_; }
+  ContextPtr parent() const { return raw_ptr()->parent(); }
   void set_parent(const Context& parent) const {
-    StorePointer(&raw_ptr()->parent_, parent.raw());
+    raw_ptr()->set_parent(parent.raw());
   }
   static intptr_t parent_offset() { return OFFSET_OF(ContextLayout, parent_); }
 
@@ -6665,7 +6643,7 @@
   }
 
   ObjectPtr At(intptr_t context_index) const {
-    return *ObjectAddr(context_index);
+    return raw_ptr()->element(context_index);
   }
   inline void SetAt(intptr_t context_index, const Object& value) const;
 
@@ -6709,11 +6687,6 @@
   static ContextPtr New(intptr_t num_variables, Heap::Space space = Heap::kNew);
 
  private:
-  ObjectPtr const* ObjectAddr(intptr_t context_index) const {
-    ASSERT((context_index >= 0) && (context_index < num_variables()));
-    return &raw_ptr()->data()[context_index];
-  }
-
   void set_num_variables(intptr_t num_variables) const {
     StoreNonPointer(&raw_ptr()->num_variables_, num_variables);
   }
@@ -6849,7 +6822,8 @@
   static MegamorphicCachePtr New(const String& target_name,
                                  const Array& arguments_descriptor);
 
-  void Insert(const Smi& class_id, const Object& target) const;
+  void EnsureContains(const Smi& class_id, const Object& target) const;
+  ObjectPtr Lookup(const Smi& class_id) const;
 
   void SwitchToBareInstructions();
 
@@ -6857,8 +6831,6 @@
     return RoundedAllocationSize(sizeof(MegamorphicCacheLayout));
   }
 
-  static MegamorphicCachePtr Clone(const MegamorphicCache& from);
-
  private:
   friend class Class;
   friend class MegamorphicCacheTable;
@@ -6866,9 +6838,12 @@
 
   static MegamorphicCachePtr New();
 
-  // The caller must hold Isolate::megamorphic_mutex().
-  void EnsureCapacityLocked() const;
+  // The caller must hold IsolateGroup::type_feedback_mutex().
   void InsertLocked(const Smi& class_id, const Object& target) const;
+  void EnsureCapacityLocked() const;
+  ObjectPtr LookupLocked(const Smi& class_id) const;
+
+  void InsertEntryLocked(const Smi& class_id, const Object& target) const;
 
   static inline void SetEntry(const Array& array,
                               intptr_t index,
@@ -6886,16 +6861,18 @@
   enum Entries {
     kTestResult = 0,
     kInstanceClassIdOrFunction = 1,
-    kInstanceTypeArguments = 2,
-    kInstantiatorTypeArguments = 3,
-    kFunctionTypeArguments = 4,
-    kInstanceParentFunctionTypeArguments = 5,
-    kInstanceDelayedFunctionTypeArguments = 6,
-    kTestEntryLength = 7,
+    kDestinationType = 2,
+    kInstanceTypeArguments = 3,
+    kInstantiatorTypeArguments = 4,
+    kFunctionTypeArguments = 5,
+    kInstanceParentFunctionTypeArguments = 6,
+    kInstanceDelayedFunctionTypeArguments = 7,
+    kTestEntryLength = 8,
   };
 
-  intptr_t NumberOfChecks() const;
+  virtual intptr_t NumberOfChecks() const;
   void AddCheck(const Object& instance_class_id_or_function,
+                const AbstractType& destination_type,
                 const TypeArguments& instance_type_arguments,
                 const TypeArguments& instantiator_type_arguments,
                 const TypeArguments& function_type_arguments,
@@ -6904,12 +6881,57 @@
                 const Bool& test_result) const;
   void GetCheck(intptr_t ix,
                 Object* instance_class_id_or_function,
+                AbstractType* destination_type,
                 TypeArguments* instance_type_arguments,
                 TypeArguments* instantiator_type_arguments,
                 TypeArguments* function_type_arguments,
                 TypeArguments* instance_parent_function_type_arguments,
                 TypeArguments* instance_delayed_type_arguments,
                 Bool* test_result) const;
+
+  // Like GetCheck(), but does not require the subtype test cache mutex and so
+  // may see an outdated view of the cache.
+  void GetCurrentCheck(intptr_t ix,
+                       Object* instance_class_id_or_function,
+                       AbstractType* destination_type,
+                       TypeArguments* instance_type_arguments,
+                       TypeArguments* instantiator_type_arguments,
+                       TypeArguments* function_type_arguments,
+                       TypeArguments* instance_parent_function_type_arguments,
+                       TypeArguments* instance_delayed_type_arguments,
+                       Bool* test_result) const;
+
+  // Returns whether all the elements of an existing cache entry, excluding
+  // the result, match the non-pointer arguments. The pointer arguments are
+  // out parameters as follows:
+  //
+  // If [index] is not nullptr, then it is set to the matching entry's index.
+  // If [result] is not nullptr, then it is set to the matching entry's result.
+  bool HasCheck(const Object& instance_class_id_or_function,
+                const AbstractType& destination_type,
+                const TypeArguments& instance_type_arguments,
+                const TypeArguments& instantiator_type_arguments,
+                const TypeArguments& function_type_arguments,
+                const TypeArguments& instance_parent_function_type_arguments,
+                const TypeArguments& instance_delayed_type_arguments,
+                intptr_t* index,
+                Bool* result) const;
+
+  // Writes the cache entry at index [index] to the given text buffer.
+  //
+  // The output is comma separated on a single line if [line_prefix] is nullptr,
+  // otherwise line breaks followed by [line_prefix] is used as a separator.
+  void WriteEntryToBuffer(Zone* zone,
+                          BaseTextBuffer* buffer,
+                          intptr_t index,
+                          const char* line_prefix = nullptr) const;
+
+  // Like WriteEntryToBuffer(), but does not require the subtype test cache
+  // mutex and so may see an outdated view of the cache.
+  void WriteCurrentEntryToBuffer(Zone* zone,
+                                 BaseTextBuffer* buffer,
+                                 intptr_t index,
+                                 const char* line_prefix = nullptr) const;
   void Reset() const;
 
   static SubtypeTestCachePtr New();
@@ -6928,12 +6950,10 @@
   ArrayPtr cache() const;
 
  private:
-  // A VM heap allocated preinitialized empty subtype entry array.
-  static ArrayPtr cached_array_;
-
   void set_cache(const Array& value) const;
 
-  intptr_t TestEntryLength() const;
+  // A VM heap allocated preinitialized empty subtype entry array.
+  static ArrayPtr cached_array_;
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(SubtypeTestCache, Object);
   friend class Class;
@@ -6993,7 +7013,7 @@
 
 class ApiError : public Error {
  public:
-  StringPtr message() const { return raw_ptr()->message_; }
+  StringPtr message() const { return raw_ptr()->message(); }
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(ApiErrorLayout));
@@ -7053,10 +7073,10 @@
   TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
 
  private:
-  ErrorPtr previous_error() const { return raw_ptr()->previous_error_; }
+  ErrorPtr previous_error() const { return raw_ptr()->previous_error(); }
   void set_previous_error(const Error& value) const;
 
-  ScriptPtr script() const { return raw_ptr()->script_; }
+  ScriptPtr script() const { return raw_ptr()->script(); }
   void set_script(const Script& value) const;
 
   void set_token_pos(TokenPosition value) const;
@@ -7066,10 +7086,10 @@
 
   void set_kind(uint8_t value) const;
 
-  StringPtr message() const { return raw_ptr()->message_; }
+  StringPtr message() const { return raw_ptr()->message(); }
   void set_message(const String& value) const;
 
-  StringPtr formatted_message() const { return raw_ptr()->formatted_message_; }
+  StringPtr formatted_message() const { return raw_ptr()->formatted_message(); }
   void set_formatted_message(const String& value) const;
 
   static LanguageErrorPtr New();
@@ -7080,12 +7100,12 @@
 
 class UnhandledException : public Error {
  public:
-  InstancePtr exception() const { return raw_ptr()->exception_; }
+  InstancePtr exception() const { return raw_ptr()->exception(); }
   static intptr_t exception_offset() {
     return OFFSET_OF(UnhandledExceptionLayout, exception_);
   }
 
-  InstancePtr stacktrace() const { return raw_ptr()->stacktrace_; }
+  InstancePtr stacktrace() const { return raw_ptr()->stacktrace(); }
   static intptr_t stacktrace_offset() {
     return OFFSET_OF(UnhandledExceptionLayout, stacktrace_);
   }
@@ -7116,7 +7136,7 @@
   bool is_user_initiated() const { return raw_ptr()->is_user_initiated_; }
   void set_is_user_initiated(bool value) const;
 
-  StringPtr message() const { return raw_ptr()->message_; }
+  StringPtr message() const { return raw_ptr()->message(); }
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(UnwindErrorLayout));
@@ -7344,12 +7364,12 @@
 
 class LibraryPrefix : public Instance {
  public:
-  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name(); }
   virtual StringPtr DictionaryName() const { return name(); }
 
-  ArrayPtr imports() const { return raw_ptr()->imports_; }
+  ArrayPtr imports() const { return raw_ptr()->imports(); }
   intptr_t num_imports() const { return raw_ptr()->num_imports_; }
-  LibraryPtr importer() const { return raw_ptr()->importer_; }
+  LibraryPtr importer() const { return raw_ptr()->importer(); }
 
   LibraryPtr GetLibrary(int index) const;
   void AddImport(const Namespace& import) const;
@@ -7639,7 +7659,6 @@
 
   ArrayPtr instantiations() const;
   void set_instantiations(const Array& value) const;
-  AbstractTypePtr const* TypeAddr(intptr_t index) const;
   void SetLength(intptr_t value) const;
   // Number of fields in the raw object is 4:
   // instantiations_, length_, hash_ and nullability_.
@@ -7899,7 +7918,7 @@
   uword type_test_stub_entry_point() const {
     return raw_ptr()->type_test_stub_entry_point_;
   }
-  CodePtr type_test_stub() const { return raw_ptr()->type_test_stub_; }
+  CodePtr type_test_stub() const { return raw_ptr()->type_test_stub(); }
 
   void SetTypeTestingStub(const Code& stub) const;
 
@@ -7960,7 +7979,7 @@
   virtual classid_t type_class_id() const;
   virtual ClassPtr type_class() const;
   void set_type_class(const Class& value) const;
-  virtual TypeArgumentsPtr arguments() const { return raw_ptr()->arguments_; }
+  virtual TypeArgumentsPtr arguments() const { return raw_ptr()->arguments(); }
   virtual void set_arguments(const TypeArguments& value) const;
   virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -8120,7 +8139,7 @@
     return (type() != AbstractType::null()) &&
            AbstractType::Handle(type()).HasTypeClass();
   }
-  AbstractTypePtr type() const { return raw_ptr()->type_; }
+  AbstractTypePtr type() const { return raw_ptr()->type(); }
   void set_type(const AbstractType& value) const;
   virtual classid_t type_class_id() const {
     return AbstractType::Handle(type()).type_class_id();
@@ -8202,6 +8221,9 @@
     return TypeParameterLayout::DeclarationBit::decode(raw_ptr()->flags_);
   }
   void SetDeclaration(bool value) const;
+  static intptr_t nullability_offset() {
+    return OFFSET_OF(TypeParameterLayout, nullability_);
+  }
   virtual Nullability nullability() const {
     return static_cast<Nullability>(raw_ptr()->nullability_);
   }
@@ -8211,7 +8233,7 @@
   classid_t parameterized_class_id() const;
   ClassPtr parameterized_class() const;
   FunctionPtr parameterized_function() const {
-    return raw_ptr()->parameterized_function_;
+    return raw_ptr()->parameterized_function();
   }
   bool IsClassTypeParameter() const {
     return parameterized_class_id() != kFunctionCid;
@@ -8219,6 +8241,13 @@
   bool IsFunctionTypeParameter() const {
     return parameterized_function() != Function::null();
   }
+  ObjectPtr Owner() const {
+    if (IsClassTypeParameter()) {
+      return parameterized_class();
+    } else {
+      return parameterized_function();
+    }
+  }
 
   static intptr_t parameterized_class_id_offset() {
     return OFFSET_OF(TypeParameterLayout, parameterized_class_id_);
@@ -8227,16 +8256,16 @@
     return OFFSET_OF(TypeParameterLayout, index_);
   }
 
-  StringPtr name() const { return raw_ptr()->name_; }
+  StringPtr name() const { return raw_ptr()->name(); }
   static intptr_t name_offset() {
     return OFFSET_OF(TypeParameterLayout, name_);
   }
   intptr_t index() const { return raw_ptr()->index_; }
   void set_index(intptr_t value) const;
-  AbstractTypePtr bound() const { return raw_ptr()->bound_; }
+  AbstractTypePtr bound() const { return raw_ptr()->bound(); }
   void set_bound(const AbstractType& value) const;
   AbstractTypePtr default_argument() const {
-    return raw_ptr()->default_argument_;
+    return raw_ptr()->default_argument();
   }
   void set_default_argument(const AbstractType& value) const;
   static intptr_t bound_offset() {
@@ -8620,7 +8649,7 @@
 
   intptr_t Length() const { return LengthOf(raw()); }
   static intptr_t LengthOf(StringPtr obj) {
-    return Smi::Value(obj->ptr()->length_);
+    return Smi::Value(obj->ptr()->length());
   }
   static intptr_t length_offset() { return OFFSET_OF(StringLayout, length_); }
 
@@ -8641,7 +8670,15 @@
     return GetCachedHash(raw()) != 0;
   }
 
-  static intptr_t hash_offset() { return OFFSET_OF(StringLayout, hash_); }
+  static intptr_t hash_offset() {
+#if defined(HASH_IN_OBJECT_HEADER)
+    COMPILE_ASSERT(ObjectLayout::kHashTagPos % kBitsPerByte == 0);
+    return OFFSET_OF(ObjectLayout, tags_) +
+           ObjectLayout::kHashTagPos / kBitsPerByte;
+#else
+    return OFFSET_OF(StringLayout, hash_);
+#endif
+  }
   static intptr_t Hash(const String& str, intptr_t begin_index, intptr_t len);
   static intptr_t Hash(const char* characters, intptr_t len);
   static intptr_t Hash(const uint16_t* characters, intptr_t len);
@@ -8866,7 +8903,7 @@
     return Smi::Value(obj->ptr()->hash_);
   }
 
-  static void SetCachedHash(StringPtr obj, uintptr_t hash) {
+  static void SetCachedHash(StringPtr obj, uint32_t hash) {
     obj->ptr()->hash_ = Smi::New(hash);
   }
 #endif
@@ -8881,7 +8918,7 @@
   void SetLength(intptr_t value) const {
     // This is only safe because we create a new Smi, which does not cause
     // heap allocation.
-    StoreSmi(&raw_ptr()->length_, Smi::New(value));
+    raw_ptr()->set_length(Smi::New(value));
   }
 
   void SetHash(intptr_t value) const { SetCachedHash(raw(), value); }
@@ -8965,7 +9002,7 @@
   }
 
   static intptr_t UnroundedSize(OneByteStringPtr str) {
-    return UnroundedSize(Smi::Value(str->ptr()->length_));
+    return UnroundedSize(Smi::Value(str->ptr()->length()));
   }
   static intptr_t UnroundedSize(intptr_t len) {
     return sizeof(OneByteStringLayout) + (len * kBytesPerElement);
@@ -9104,7 +9141,7 @@
     return OFFSET_OF_RETURNED_VALUE(TwoByteStringLayout, data);
   }
   static intptr_t UnroundedSize(TwoByteStringPtr str) {
-    return UnroundedSize(Smi::Value(str->ptr()->length_));
+    return UnroundedSize(Smi::Value(str->ptr()->length()));
   }
   static intptr_t UnroundedSize(intptr_t len) {
     return sizeof(TwoByteStringLayout) + (len * kBytesPerElement);
@@ -9434,7 +9471,7 @@
 
   intptr_t Length() const { return LengthOf(raw()); }
   static intptr_t LengthOf(const ArrayPtr array) {
-    return Smi::Value(array->ptr()->length_);
+    return Smi::Value(array->ptr()->length());
   }
 
   static intptr_t length_offset() { return OFFSET_OF(ArrayLayout, length_); }
@@ -9459,8 +9496,8 @@
   static bool Equals(ArrayPtr a, ArrayPtr b) {
     if (a == b) return true;
     if (a->IsRawNull() || b->IsRawNull()) return false;
-    if (a->ptr()->length_ != b->ptr()->length_) return false;
-    if (a->ptr()->type_arguments_ != b->ptr()->type_arguments_) return false;
+    if (a->ptr()->length() != b->ptr()->length()) return false;
+    if (a->ptr()->type_arguments() != b->ptr()->type_arguments()) return false;
     const intptr_t length = LengthOf(a);
     return memcmp(a->ptr()->data(), b->ptr()->data(), kWordSize * length) == 0;
   }
@@ -9469,20 +9506,20 @@
 
   template <std::memory_order order = std::memory_order_relaxed>
   ObjectPtr At(intptr_t index) const {
-    return LoadPointer<ObjectPtr, order>(ObjectAddr(index));
+    return raw_ptr()->element(index);
   }
   template <std::memory_order order = std::memory_order_relaxed>
   void SetAt(intptr_t index, const Object& value) const {
     // TODO(iposva): Add storing NoSafepointScope.
-    StoreArrayPointer<ObjectPtr, order>(ObjectAddr(index), value.raw());
+    raw_ptr()->set_element(index, value.raw());
   }
 
   // Access to the array with acquire release semantics.
   ObjectPtr AtAcquire(intptr_t index) const {
-    return At<std::memory_order_acquire>(index);
+    return raw_ptr()->element<std::memory_order_acquire>(index);
   }
   void SetAtRelease(intptr_t index, const Object& value) const {
-    SetAt<std::memory_order_release>(index, value);
+    raw_ptr()->set_element<std::memory_order_release>(index, value.raw());
   }
 
   bool IsImmutable() const { return raw()->GetClassId() == kImmutableArrayCid; }
@@ -9491,7 +9528,7 @@
   static const intptr_t kElementTypeTypeArgPos = 0;
 
   virtual TypeArgumentsPtr GetTypeArguments() const {
-    return raw_ptr()->type_arguments_;
+    return raw_ptr()->type_arguments();
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
     // An Array is raw or takes one type argument. However, its type argument
@@ -9584,10 +9621,10 @@
   }
 
   void SetLength(intptr_t value) const {
-    StoreSmi(&raw_ptr()->length_, Smi::New(value));
+    raw_ptr()->set_length(Smi::New(value));
   }
-  void SetLengthIgnoreRace(intptr_t value) const {
-    StoreSmiIgnoreRace(&raw_ptr()->length_, Smi::New(value));
+  void SetLengthRelease(intptr_t value) const {
+    raw_ptr()->set_length<std::memory_order_release>(Smi::New(value));
   }
 
   template <typename type, std::memory_order order = std::memory_order_relaxed>
@@ -9653,35 +9690,33 @@
   intptr_t Capacity() const {
     NoSafepointScope no_safepoint;
     ASSERT(!IsNull());
-    return Smi::Value(DataArray()->length_);
+    return Smi::Value(DataArray()->length());
   }
   intptr_t Length() const {
     ASSERT(!IsNull());
-    return Smi::Value(raw_ptr()->length_);
+    return Smi::Value(raw_ptr()->length());
   }
   void SetLength(intptr_t value) const {
     // This is only safe because we create a new Smi, which does not cause
     // heap allocation.
-    StoreSmi(&raw_ptr()->length_, Smi::New(value));
+    raw_ptr()->set_length(Smi::New(value));
   }
 
-  ArrayPtr data() const { return raw_ptr()->data_; }
-  void SetData(const Array& value) const {
-    StorePointer(&raw_ptr()->data_, value.raw());
-  }
+  ArrayPtr data() const { return raw_ptr()->data(); }
+  void SetData(const Array& value) const { raw_ptr()->set_data(value.raw()); }
 
   ObjectPtr At(intptr_t index) const {
     NoSafepointScope no_safepoint;
     ASSERT(!IsNull());
     ASSERT(index < Length());
-    return *ObjectAddr(index);
+    return data()->ptr()->element(index);
   }
   void SetAt(intptr_t index, const Object& value) const {
     ASSERT(!IsNull());
     ASSERT(index < Length());
 
     // TODO(iposva): Add storing NoSafepointScope.
-    data()->ptr()->StoreArrayPointer(ObjectAddr(index), value.raw());
+    data()->ptr()->set_element(index, value.raw());
   }
 
   void Add(const Object& value, Heap::Space space = Heap::kNew) const;
@@ -9690,7 +9725,7 @@
   ObjectPtr RemoveLast() const;
 
   virtual TypeArgumentsPtr GetTypeArguments() const {
-    return raw_ptr()->type_arguments_;
+    return raw_ptr()->type_arguments();
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
     // A GrowableObjectArray is raw or takes one type argument. However, its
@@ -9698,7 +9733,7 @@
     // reusing the type argument vector of the instantiator.
     ASSERT(value.IsNull() || ((value.Length() >= 1) && value.IsInstantiated() &&
                               value.IsCanonical()));
-    StorePointer(&raw_ptr()->type_arguments_, value.raw());
+    raw_ptr()->set_type_arguments(value.raw());
   }
 
   // We don't expect a growable object array to be canonicalized.
@@ -9737,19 +9772,15 @@
                                     Heap::Space space = Heap::kNew);
 
   static SmiPtr NoSafepointLength(const GrowableObjectArrayPtr array) {
-    return array->ptr()->length_;
+    return array->ptr()->length();
   }
 
   static ArrayPtr NoSafepointData(const GrowableObjectArrayPtr array) {
-    return array->ptr()->data_;
+    return array->ptr()->data();
   }
 
  private:
   ArrayLayout* DataArray() const { return data()->ptr(); }
-  ObjectPtr* ObjectAddr(intptr_t index) const {
-    ASSERT((index >= 0) && (index < Length()));
-    return &(DataArray()->data()[index]);
-  }
 
   static const int kDefaultInitialCapacity = 0;
 
@@ -9866,11 +9897,11 @@
     return OFFSET_OF(TypedDataBaseLayout, length_);
   }
 
-  SmiPtr length() const { return raw_ptr()->length_; }
+  SmiPtr length() const { return raw_ptr()->length(); }
 
   intptr_t Length() const {
     ASSERT(!IsNull());
-    return Smi::Value(raw_ptr()->length_);
+    return Smi::Value(raw_ptr()->length());
   }
 
   intptr_t LengthInBytes() const {
@@ -9917,7 +9948,7 @@
  protected:
   void SetLength(intptr_t value) const {
     ASSERT(value <= Smi::kMaxValue);
-    StoreSmi(&raw_ptr()->length_, Smi::New(value));
+    raw_ptr()->set_length(Smi::New(value));
   }
 
   virtual uint8_t* Validate(uint8_t* data) const {
@@ -10147,7 +10178,7 @@
 
   void SetLength(intptr_t value) const {
     ASSERT(value <= Smi::kMaxValue);
-    StoreSmi(&raw_ptr()->length_, Smi::New(value));
+    raw_ptr()->set_length(Smi::New(value));
   }
 
   void SetData(uint8_t* data) const {
@@ -10198,22 +10229,22 @@
     return OFFSET_OF(TypedDataViewLayout, offset_in_bytes_);
   }
 
-  InstancePtr typed_data() const { return raw_ptr()->typed_data_; }
+  InstancePtr typed_data() const { return raw_ptr()->typed_data(); }
 
   void InitializeWith(const TypedDataBase& typed_data,
                       intptr_t offset_in_bytes,
                       intptr_t length) {
     const classid_t cid = typed_data.GetClassId();
     ASSERT(IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid));
-    StorePointer(&raw_ptr()->typed_data_, typed_data.raw());
-    StoreSmi(&raw_ptr()->length_, Smi::New(length));
-    StoreSmi(&raw_ptr()->offset_in_bytes_, Smi::New(offset_in_bytes));
+    raw_ptr()->set_typed_data(typed_data.raw());
+    raw_ptr()->set_length(Smi::New(length));
+    raw_ptr()->set_offset_in_bytes(Smi::New(offset_in_bytes));
 
     // Update the inner pointer.
     RecomputeDataField();
   }
 
-  SmiPtr offset_in_bytes() const { return raw_ptr()->offset_in_bytes_; }
+  SmiPtr offset_in_bytes() const { return raw_ptr()->offset_in_bytes(); }
 
  protected:
   virtual uint8_t* Validate(uint8_t* data) const { return data; }
@@ -10222,11 +10253,10 @@
   void RecomputeDataField() { raw()->ptr()->RecomputeDataField(); }
 
   void Clear() {
-    StoreSmi(&raw_ptr()->length_, Smi::New(0));
-    StoreSmi(&raw_ptr()->offset_in_bytes_, Smi::New(0));
+    raw_ptr()->set_length(Smi::New(0));
+    raw_ptr()->set_offset_in_bytes(Smi::New(0));
     StoreNonPointer(&raw_ptr()->data_, nullptr);
-    StorePointer(&raw_ptr()->typed_data_,
-                 TypedDataBase::RawCast(Object::null()));
+    raw_ptr()->set_typed_data(TypedDataBase::RawCast(Object::null()));
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(TypedDataView, TypedDataBase);
@@ -10343,7 +10373,7 @@
                               Heap::Space space = Heap::kNew);
 
   virtual TypeArgumentsPtr GetTypeArguments() const {
-    return raw_ptr()->type_arguments_;
+    return raw_ptr()->type_arguments();
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
     ASSERT(value.IsNull() ||
@@ -10351,48 +10381,46 @@
             value.IsInstantiated() /*&& value.IsCanonical()*/));
     // TODO(asiva): Values read from a message snapshot are not properly marked
     // as canonical. See for example tests/isolate/message3_test.dart.
-    StorePointer(&raw_ptr()->type_arguments_, value.raw());
+    raw_ptr()->set_type_arguments(value.raw());
   }
   static intptr_t type_arguments_offset() {
     return OFFSET_OF(LinkedHashMapLayout, type_arguments_);
   }
 
-  TypedDataPtr index() const { return raw_ptr()->index_; }
+  TypedDataPtr index() const { return raw_ptr()->index(); }
   void SetIndex(const TypedData& value) const {
     ASSERT(!value.IsNull());
-    StorePointer(&raw_ptr()->index_, value.raw());
+    raw_ptr()->set_index(value.raw());
   }
   static intptr_t index_offset() {
     return OFFSET_OF(LinkedHashMapLayout, index_);
   }
 
-  ArrayPtr data() const { return raw_ptr()->data_; }
-  void SetData(const Array& value) const {
-    StorePointer(&raw_ptr()->data_, value.raw());
-  }
+  ArrayPtr data() const { return raw_ptr()->data(); }
+  void SetData(const Array& value) const { raw_ptr()->set_data(value.raw()); }
   static intptr_t data_offset() {
     return OFFSET_OF(LinkedHashMapLayout, data_);
   }
 
-  SmiPtr hash_mask() const { return raw_ptr()->hash_mask_; }
+  SmiPtr hash_mask() const { return raw_ptr()->hash_mask(); }
   void SetHashMask(intptr_t value) const {
-    StoreSmi(&raw_ptr()->hash_mask_, Smi::New(value));
+    raw_ptr()->set_hash_mask(Smi::New(value));
   }
   static intptr_t hash_mask_offset() {
     return OFFSET_OF(LinkedHashMapLayout, hash_mask_);
   }
 
-  SmiPtr used_data() const { return raw_ptr()->used_data_; }
+  SmiPtr used_data() const { return raw_ptr()->used_data(); }
   void SetUsedData(intptr_t value) const {
-    StoreSmi(&raw_ptr()->used_data_, Smi::New(value));
+    raw_ptr()->set_used_data(Smi::New(value));
   }
   static intptr_t used_data_offset() {
     return OFFSET_OF(LinkedHashMapLayout, used_data_);
   }
 
-  SmiPtr deleted_keys() const { return raw_ptr()->deleted_keys_; }
+  SmiPtr deleted_keys() const { return raw_ptr()->deleted_keys(); }
   void SetDeletedKeys(intptr_t value) const {
-    StoreSmi(&raw_ptr()->deleted_keys_, Smi::New(value));
+    raw_ptr()->set_deleted_keys(Smi::New(value));
   }
   static intptr_t deleted_keys_offset() {
     return OFFSET_OF(LinkedHashMapLayout, deleted_keys_);
@@ -10400,11 +10428,11 @@
 
   intptr_t Length() const {
     // The map may be uninitialized.
-    if (raw_ptr()->used_data_ == Object::null()) return 0;
-    if (raw_ptr()->deleted_keys_ == Object::null()) return 0;
+    if (raw_ptr()->used_data() == Object::null()) return 0;
+    if (raw_ptr()->deleted_keys() == Object::null()) return 0;
 
-    intptr_t used = Smi::Value(raw_ptr()->used_data_);
-    intptr_t deleted = Smi::Value(raw_ptr()->deleted_keys_);
+    intptr_t used = Smi::Value(raw_ptr()->used_data());
+    intptr_t deleted = Smi::Value(raw_ptr()->deleted_keys());
     return (used >> 1) - deleted;
   }
 
@@ -10464,41 +10492,41 @@
 class Closure : public Instance {
  public:
   TypeArgumentsPtr instantiator_type_arguments() const {
-    return raw_ptr()->instantiator_type_arguments_;
+    return raw_ptr()->instantiator_type_arguments();
   }
   void set_instantiator_type_arguments(const TypeArguments& args) const {
-    StorePointer(&raw_ptr()->instantiator_type_arguments_, args.raw());
+    raw_ptr()->set_instantiator_type_arguments(args.raw());
   }
   static intptr_t instantiator_type_arguments_offset() {
     return OFFSET_OF(ClosureLayout, instantiator_type_arguments_);
   }
 
   TypeArgumentsPtr function_type_arguments() const {
-    return raw_ptr()->function_type_arguments_;
+    return raw_ptr()->function_type_arguments();
   }
   void set_function_type_arguments(const TypeArguments& args) const {
-    StorePointer(&raw_ptr()->function_type_arguments_, args.raw());
+    raw_ptr()->set_function_type_arguments(args.raw());
   }
   static intptr_t function_type_arguments_offset() {
     return OFFSET_OF(ClosureLayout, function_type_arguments_);
   }
 
   TypeArgumentsPtr delayed_type_arguments() const {
-    return raw_ptr()->delayed_type_arguments_;
+    return raw_ptr()->delayed_type_arguments();
   }
   void set_delayed_type_arguments(const TypeArguments& args) const {
-    StorePointer(&raw_ptr()->delayed_type_arguments_, args.raw());
+    raw_ptr()->set_delayed_type_arguments(args.raw());
   }
   static intptr_t delayed_type_arguments_offset() {
     return OFFSET_OF(ClosureLayout, delayed_type_arguments_);
   }
 
-  FunctionPtr function() const { return raw_ptr()->function_; }
+  FunctionPtr function() const { return raw_ptr()->function(); }
   static intptr_t function_offset() {
     return OFFSET_OF(ClosureLayout, function_);
   }
 
-  ContextPtr context() const { return raw_ptr()->context_; }
+  ContextPtr context() const { return raw_ptr()->context(); }
   static intptr_t context_offset() {
     return OFFSET_OF(ClosureLayout, context_);
   }
@@ -10508,7 +10536,7 @@
   // No need for NumParentTypeParameters, as a closure is always closed over
   // its parents type parameters (i.e., function_type_parameters() above).
 
-  SmiPtr hash() const { return raw_ptr()->hash_; }
+  SmiPtr hash() const { return raw_ptr()->hash(); }
   static intptr_t hash_offset() { return OFFSET_OF(ClosureLayout, hash_); }
 
   static intptr_t InstanceSize() {
@@ -10560,18 +10588,18 @@
 
 class ReceivePort : public Instance {
  public:
-  SendPortPtr send_port() const { return raw_ptr()->send_port_; }
+  SendPortPtr send_port() const { return raw_ptr()->send_port(); }
   Dart_Port Id() const { return send_port()->ptr()->id_; }
 
-  InstancePtr handler() const { return raw_ptr()->handler_; }
+  InstancePtr handler() const { return raw_ptr()->handler(); }
   void set_handler(const Instance& value) const;
 
 #if !defined(PRODUCT)
   StackTracePtr allocation_location() const {
-    return raw_ptr()->allocation_location_;
+    return raw_ptr()->allocation_location();
   }
 
-  StringPtr debug_name() const { return raw_ptr()->debug_name_; }
+  StringPtr debug_name() const { return raw_ptr()->debug_name(); }
 #endif
 
   static intptr_t InstanceSize() {
@@ -10661,15 +10689,15 @@
 
   intptr_t Length() const;
 
-  StackTracePtr async_link() const { return raw_ptr()->async_link_; }
+  StackTracePtr async_link() const { return raw_ptr()->async_link(); }
   void set_async_link(const StackTrace& async_link) const;
   void set_expand_inlined(bool value) const;
 
-  ArrayPtr code_array() const { return raw_ptr()->code_array_; }
+  ArrayPtr code_array() const { return raw_ptr()->code_array(); }
   ObjectPtr CodeAtFrame(intptr_t frame_index) const;
   void SetCodeAtFrame(intptr_t frame_index, const Object& code) const;
 
-  ArrayPtr pc_offset_array() const { return raw_ptr()->pc_offset_array_; }
+  ArrayPtr pc_offset_array() const { return raw_ptr()->pc_offset_array(); }
   SmiPtr PcOffsetAtFrame(intptr_t frame_index) const;
   void SetPcOffsetAtFrame(intptr_t frame_index, const Smi& pc_offset) const;
 
@@ -10794,19 +10822,19 @@
                        : raw_ptr()->num_two_byte_registers_;
   }
 
-  StringPtr pattern() const { return raw_ptr()->pattern_; }
+  StringPtr pattern() const { return raw_ptr()->pattern(); }
   SmiPtr num_bracket_expressions() const {
-    return raw_ptr()->num_bracket_expressions_;
+    return raw_ptr()->num_bracket_expressions();
   }
-  ArrayPtr capture_name_map() const { return raw_ptr()->capture_name_map_; }
+  ArrayPtr capture_name_map() const { return raw_ptr()->capture_name_map(); }
 
   TypedDataPtr bytecode(bool is_one_byte, bool sticky) const {
     if (sticky) {
-      return is_one_byte ? raw_ptr()->one_byte_sticky_.bytecode_
-                         : raw_ptr()->two_byte_sticky_.bytecode_;
+      return TypedData::RawCast(is_one_byte ? raw_ptr()->one_byte_sticky_
+                                            : raw_ptr()->two_byte_sticky_);
     } else {
-      return is_one_byte ? raw_ptr()->one_byte_.bytecode_
-                         : raw_ptr()->two_byte_.bytecode_;
+      return TypedData::RawCast(is_one_byte ? raw_ptr()->one_byte_
+                                            : raw_ptr()->two_byte_);
     }
   }
 
@@ -10814,24 +10842,24 @@
     if (sticky) {
       switch (cid) {
         case kOneByteStringCid:
-          return OFFSET_OF(RegExpLayout, one_byte_sticky_.function_);
+          return OFFSET_OF(RegExpLayout, one_byte_sticky_);
         case kTwoByteStringCid:
-          return OFFSET_OF(RegExpLayout, two_byte_sticky_.function_);
+          return OFFSET_OF(RegExpLayout, two_byte_sticky_);
         case kExternalOneByteStringCid:
-          return OFFSET_OF(RegExpLayout, external_one_byte_sticky_function_);
+          return OFFSET_OF(RegExpLayout, external_one_byte_sticky_);
         case kExternalTwoByteStringCid:
-          return OFFSET_OF(RegExpLayout, external_two_byte_sticky_function_);
+          return OFFSET_OF(RegExpLayout, external_two_byte_sticky_);
       }
     } else {
       switch (cid) {
         case kOneByteStringCid:
-          return OFFSET_OF(RegExpLayout, one_byte_.function_);
+          return OFFSET_OF(RegExpLayout, one_byte_);
         case kTwoByteStringCid:
-          return OFFSET_OF(RegExpLayout, two_byte_.function_);
+          return OFFSET_OF(RegExpLayout, two_byte_);
         case kExternalOneByteStringCid:
-          return OFFSET_OF(RegExpLayout, external_one_byte_function_);
+          return OFFSET_OF(RegExpLayout, external_one_byte_);
         case kExternalTwoByteStringCid:
-          return OFFSET_OF(RegExpLayout, external_two_byte_function_);
+          return OFFSET_OF(RegExpLayout, external_two_byte_);
       }
     }
 
@@ -10922,16 +10950,16 @@
 
 class WeakProperty : public Instance {
  public:
-  ObjectPtr key() const { return raw_ptr()->key_; }
+  ObjectPtr key() const { return raw_ptr()->key(); }
+  void set_key(const Object& key) const { raw_ptr()->set_key(key.raw()); }
+  static intptr_t key_offset() { return OFFSET_OF(WeakPropertyLayout, key_); }
 
-  void set_key(const Object& key) const {
-    StorePointer(&raw_ptr()->key_, key.raw());
-  }
-
-  ObjectPtr value() const { return raw_ptr()->value_; }
-
+  ObjectPtr value() const { return raw_ptr()->value(); }
   void set_value(const Object& value) const {
-    StorePointer(&raw_ptr()->value_, value.raw());
+    raw_ptr()->set_value(value.raw());
+  }
+  static intptr_t value_offset() {
+    return OFFSET_OF(WeakPropertyLayout, value_);
   }
 
   static WeakPropertyPtr New(Heap::Space space = Heap::kNew);
@@ -10941,7 +10969,7 @@
   }
 
   static void Clear(WeakPropertyPtr raw_weak) {
-    ASSERT(raw_weak->ptr()->next_ == 0);
+    ASSERT(raw_weak->ptr()->next_ == WeakProperty::null());
     // This action is performed by the GC. No barrier.
     raw_weak->ptr()->key_ = Object::null();
     raw_weak->ptr()->value_ = Object::null();
@@ -10954,10 +10982,10 @@
 
 class MirrorReference : public Instance {
  public:
-  ObjectPtr referent() const { return raw_ptr()->referent_; }
+  ObjectPtr referent() const { return raw_ptr()->referent(); }
 
   void set_referent(const Object& referent) const {
-    StorePointer(&raw_ptr()->referent_, referent.raw());
+    raw_ptr()->set_referent(referent.raw());
   }
 
   AbstractTypePtr GetAbstractTypeReferent() const;
@@ -10994,7 +11022,7 @@
   }
   static intptr_t tag_offset() { return OFFSET_OF(UserTagLayout, tag_); }
 
-  StringPtr label() const { return raw_ptr()->label_; }
+  StringPtr label() const { return raw_ptr()->label(); }
 
   void MakeActive() const;
 
@@ -11013,7 +11041,7 @@
   static void AddTagToIsolate(Thread* thread, const UserTag& tag);
 
   void set_label(const String& tag_label) const {
-    StorePointer(&raw_ptr()->label_, tag_label.raw());
+    raw_ptr()->set_label(tag_label.raw());
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(UserTag, Instance);
@@ -11028,7 +11056,7 @@
   }
 
   virtual TypeArgumentsPtr GetTypeArguments() const {
-    return raw_ptr()->type_arguments_;
+    return raw_ptr()->type_arguments();
   }
   static intptr_t type_arguments_offset() {
     return OFFSET_OF(FutureOrLayout, type_arguments_);
@@ -11083,7 +11111,7 @@
 
 intptr_t Field::HostOffset() const {
   ASSERT(is_instance());  // Valid only for dart instance fields.
-  return (Smi::Value(raw_ptr()->host_offset_or_field_id_) * kWordSize);
+  return (Smi::Value(raw_ptr()->host_offset_or_field_id()) * kWordSize);
 }
 
 intptr_t Field::TargetOffset() const {
@@ -11107,8 +11135,8 @@
                       intptr_t target_offset_in_bytes) const {
   ASSERT(is_instance());  // Valid only for dart instance fields.
   ASSERT(kWordSize != 0);
-  StoreSmi(&raw_ptr()->host_offset_or_field_id_,
-           Smi::New(host_offset_in_bytes / kWordSize));
+  raw_ptr()->set_host_offset_or_field_id(
+      Smi::New(host_offset_in_bytes / kWordSize));
 #if !defined(DART_PRECOMPILED_RUNTIME)
   ASSERT(compiler::target::kWordSize != 0);
   StoreNonPointer(&raw_ptr()->target_offset_,
@@ -11121,27 +11149,21 @@
 InstancePtr Field::StaticValue() const {
   ASSERT(is_static());  // Valid only for static dart fields.
   return Isolate::Current()->field_table()->At(
-      Smi::Value(raw_ptr()->host_offset_or_field_id_));
+      Smi::Value(raw_ptr()->host_offset_or_field_id()));
 }
 
 inline intptr_t Field::field_id() const {
-  return Smi::Value(raw_ptr()->host_offset_or_field_id_);
+  return Smi::Value(raw_ptr()->host_offset_or_field_id());
 }
 
 void Field::set_field_id(intptr_t field_id) const {
   ASSERT(is_static());
   ASSERT(Thread::Current()->IsMutatorThread());
-  StoreSmi(&raw_ptr()->host_offset_or_field_id_, Smi::New(field_id));
+  raw_ptr()->set_host_offset_or_field_id(Smi::New(field_id));
 }
 
-#ifndef DART_PRECOMPILED_RUNTIME
-void Field::set_saved_initial_value(const Instance& value) const {
-  StorePointer(&raw_ptr()->saved_initial_value_, value.raw());
-}
-#endif
-
 void Context::SetAt(intptr_t index, const Object& value) const {
-  StorePointer(ObjectAddr(index), value.raw());
+  raw_ptr()->set_element(index, value.raw());
 }
 
 intptr_t Instance::GetNativeField(int index) const {
@@ -11223,7 +11245,7 @@
 }
 
 inline intptr_t Type::Hash() const {
-  intptr_t result = Smi::Value(raw_ptr()->hash_);
+  intptr_t result = Smi::Value(raw_ptr()->hash());
   if (result != 0) {
     return result;
   }
@@ -11233,12 +11255,12 @@
 inline void Type::SetHash(intptr_t value) const {
   // This is only safe because we create a new Smi, which does not cause
   // heap allocation.
-  StoreSmi(&raw_ptr()->hash_, Smi::New(value));
+  raw_ptr()->set_hash(Smi::New(value));
 }
 
 inline intptr_t TypeParameter::Hash() const {
   ASSERT(IsFinalized());
-  intptr_t result = Smi::Value(raw_ptr()->hash_);
+  intptr_t result = Smi::Value(raw_ptr()->hash());
   if (result != 0) {
     return result;
   }
@@ -11248,12 +11270,12 @@
 inline void TypeParameter::SetHash(intptr_t value) const {
   // This is only safe because we create a new Smi, which does not cause
   // heap allocation.
-  StoreSmi(&raw_ptr()->hash_, Smi::New(value));
+  raw_ptr()->set_hash(Smi::New(value));
 }
 
 inline intptr_t TypeArguments::Hash() const {
   if (IsNull()) return kAllDynamicHash;
-  intptr_t result = Smi::Value(raw_ptr()->hash_);
+  intptr_t result = Smi::Value(raw_ptr()->hash());
   if (result != 0) {
     return result;
   }
@@ -11263,7 +11285,7 @@
 inline void TypeArguments::SetHash(intptr_t value) const {
   // This is only safe because we create a new Smi, which does not cause
   // heap allocation.
-  StoreSmi(&raw_ptr()->hash_, Smi::New(value));
+  raw_ptr()->set_hash(Smi::New(value));
 }
 
 inline uint16_t String::CharAt(StringPtr str, intptr_t index) {
@@ -11419,6 +11441,7 @@
 using SubtypeTestCacheTable = ArrayOfTuplesView<SubtypeTestCache::Entries,
                                                 std::tuple<Object,
                                                            Object,
+                                                           AbstractType,
                                                            TypeArguments,
                                                            TypeArguments,
                                                            TypeArguments,
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index bea8d14..907dda1 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -468,6 +468,8 @@
     }
   }
 
+  Thread* thread = Thread::Current();
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
   const Array& field_list = Array::Handle(fields());
   Field& field = Field::Handle();
   for (intptr_t i = 0; i < field_list.Length(); i++) {
@@ -902,8 +904,8 @@
           (class_ids[1] == kSmiCid)) {
         // The smi fast path case, preserve the initial entry but reset the
         // count.
-        ic.ClearCountAt(0);
-        ic.WriteSentinelAt(1);
+        ic.ClearCountAt(0, *this);
+        ic.WriteSentinelAt(1, *this);
         entries_ = ic.entries();
         entries_.Truncate(2 * ic.TestEntryLength());
         return;
@@ -953,7 +955,7 @@
                  Object::Handle(zone_, ic.Owner()).ToCString());
       return;
     }
-    ic.ClearAndSetStaticTarget(new_target_);
+    ic.ClearAndSetStaticTarget(new_target_, *this);
   } else {
     FATAL("Unexpected rebind rule.");
   }
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index e99a13d..1dfe634 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -352,10 +352,6 @@
   }
 }
 
-void RedirectionData::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Object::PrintJSONImpl(stream, ref);
-}
-
 void FfiTrampolineData::PrintJSONImpl(JSONStream* stream, bool ref) const {
   Object::PrintJSONImpl(stream, ref);
 }
@@ -523,7 +519,7 @@
       jsdep.AddProperty("isDeferred", false);
       jsdep.AddProperty("isExport", false);
       jsdep.AddProperty("isImport", true);
-      target = ns.library();
+      target = ns.target();
       jsdep.AddProperty("target", target);
     }
 
@@ -537,7 +533,7 @@
       jsdep.AddProperty("isDeferred", false);
       jsdep.AddProperty("isExport", true);
       jsdep.AddProperty("isImport", false);
-      target = ns.library();
+      target = ns.target();
       jsdep.AddProperty("target", target);
     }
 
@@ -563,7 +559,7 @@
             prefix_name = prefix.name();
             ASSERT(!prefix_name.IsNull());
             jsdep.AddProperty("prefix", prefix_name.ToCString());
-            target = ns.library();
+            target = ns.target();
             jsdep.AddProperty("target", target);
           }
         }
@@ -1457,6 +1453,7 @@
   const StackTrace& allocation_location_ =
       StackTrace::Handle(allocation_location());
   const String& debug_name_ = String::Handle(debug_name());
+  obj.AddServiceId(*this);
   obj.AddProperty("kind", "ReceivePort");
   obj.AddProperty64("portId", Id());
   obj.AddProperty("debugName", debug_name_.ToCString());
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 5031b69..143a7bb 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -218,19 +218,6 @@
 
   String& function_name = String::Handle(zone);
   Function& function = Function::Handle(zone);
-  function_name = async_lib.PrivateName(Symbols::SetAsyncThreadStackTrace());
-  ASSERT(!function_name.IsNull());
-  function = Resolver::ResolveStatic(async_lib, Object::null_string(),
-                                     function_name, 0, 1, Object::null_array());
-  ASSERT(!function.IsNull());
-  set_async_set_thread_stack_trace(function);
-
-  function_name = async_lib.PrivateName(Symbols::ClearAsyncThreadStackTrace());
-  ASSERT(!function_name.IsNull());
-  function = Resolver::ResolveStatic(async_lib, Object::null_string(),
-                                     function_name, 0, 0, Object::null_array());
-  ASSERT(!function.IsNull());
-  set_async_clear_thread_stack_trace(function);
 
   function_name = async_lib.PrivateName(Symbols::AsyncStarMoveNextHelper());
   ASSERT(!function_name.IsNull());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index ed3e69d..7ffcb71 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -28,8 +28,7 @@
   M(Math, math)                                                                \
   M(Mirrors, mirrors)                                                          \
   M(TypedData, typed_data)                                                     \
-  M(VMService, _vmservice)                                                     \
-  M(Wasm, wasm)
+  M(VMService, _vmservice)
 
 // TODO(liama): Once NNBD is enabled, *_type will be deleted and all uses will
 // be replaced with *_type_non_nullable. Later, once we drop support for opted
@@ -151,7 +150,6 @@
   RW(Library, root_library)                                                    \
   RW(Library, typed_data_library)                                              \
   RW(Library, _vmservice_library)                                              \
-  RW(Library, wasm_library)                                                    \
   RW(GrowableObjectArray, libraries)                                           \
   RW(Array, libraries_map)                                                     \
   RW(Array, loading_units)                                                     \
@@ -166,8 +164,6 @@
   RW(Function, simple_instance_of_function)                                    \
   RW(Function, simple_instance_of_true_function)                               \
   RW(Function, simple_instance_of_false_function)                              \
-  RW(Function, async_clear_thread_stack_trace)                                 \
-  RW(Function, async_set_thread_stack_trace)                                   \
   RW(Function, async_star_move_next_helper)                                    \
   RW(Function, complete_on_async_return)                                       \
   RW(Function, complete_on_async_error)                                        \
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 01a7024..cc5e5c1 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2354,24 +2354,133 @@
   }
 }
 
-ISOLATE_UNIT_TEST_CASE(Script) {
-  const char* url_chars = "builtin:test-case";
-  const char* source_chars = "This will not compile.";
-  const String& url = String::Handle(String::New(url_chars));
-  const String& source = String::Handle(String::New(source_chars));
-  const Script& script = Script::Handle(Script::New(url, source));
+static void CheckLinesWithOffset(Zone* zone, const intptr_t offset) {
+  const char* url_chars = "";
+  // Nine lines, mix of \n, \r, \r\n line terminators, lines 3, 4, 7, and 8
+  // are non-empty. Ends with a \r as a double-check that the \r followed by
+  // \n check doesn't go out of bounds.
+  //
+  // Line starts:             1 2 3    4      5 6   7    8    9
+  const char* source_chars = "\n\nxyz\nabc\r\n\n\r\ndef\rghi\r";
+  const String& url = String::Handle(zone, String::New(url_chars));
+  const String& source = String::Handle(zone, String::New(source_chars));
+  const Script& script = Script::Handle(zone, Script::New(url, source));
   EXPECT(!script.IsNull());
   EXPECT(script.IsScript());
-  String& str = String::Handle(script.url());
-  EXPECT_EQ(17, str.Length());
-  EXPECT_EQ('b', str.CharAt(0));
-  EXPECT_EQ(':', str.CharAt(7));
-  EXPECT_EQ('e', str.CharAt(16));
-  str = script.Source();
-  EXPECT_EQ(22, str.Length());
-  EXPECT_EQ('T', str.CharAt(0));
-  EXPECT_EQ('n', str.CharAt(10));
-  EXPECT_EQ('.', str.CharAt(21));
+  script.SetLocationOffset(offset, 10);
+  auto& str = String::Handle(zone);
+  str = script.GetLine(offset + 1);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset + 2);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset + 3);
+  EXPECT_STREQ("xyz", str.ToCString());
+  str = script.GetLine(offset + 4);
+  EXPECT_STREQ("abc", str.ToCString());
+  str = script.GetLine(offset + 5);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset + 6);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset + 7);
+  EXPECT_STREQ("def", str.ToCString());
+  str = script.GetLine(offset + 8);
+  EXPECT_STREQ("ghi", str.ToCString());
+  str = script.GetLine(offset + 9);
+  EXPECT_STREQ("", str.ToCString());
+  // Using "column" of \r at end of line for to_column.
+  str = script.GetSnippet(offset + 3, 1, offset + 7, 4);
+  EXPECT_STREQ("xyz\nabc\r\n\n\r\ndef", str.ToCString());
+  // Lines not in the range of (1-based) line indices in the source should
+  // return the empty string.
+  str = script.GetLine(-500);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(0);
+  EXPECT_STREQ("", str.ToCString());
+  if (offset > 0) {
+    str = script.GetLine(1);  // Absolute, not relative to offset.
+    EXPECT_STREQ("", str.ToCString());
+  }
+  if (offset > 2) {
+    str = script.GetLine(3);  // Absolute, not relative to offset.
+    EXPECT_STREQ("", str.ToCString());
+  }
+  str = script.GetLine(offset - 500);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset + 10);
+  EXPECT_STREQ("", str.ToCString());
+  str = script.GetLine(offset + 10000);
+  EXPECT_STREQ("", str.ToCString());
+  // Snippets not contained within the source should be the null string.
+  str = script.GetSnippet(-1, 1, 2, 2);
+  EXPECT(str.IsNull());
+  str = script.GetSnippet(offset - 1, 1, offset + 2, 2);
+  EXPECT(str.IsNull());
+  str = script.GetSnippet(offset + 5, 15, offset + 6, 2);
+  EXPECT(str.IsNull());
+  str = script.GetSnippet(offset + 20, 1, offset + 30, 1);
+  EXPECT(str.IsNull());
+}
+
+ISOLATE_UNIT_TEST_CASE(Script) {
+  {
+    const char* url_chars = "builtin:test-case";
+    const char* source_chars = "This will not compile.";
+    const String& url = String::Handle(String::New(url_chars));
+    const String& source = String::Handle(String::New(source_chars));
+    const Script& script = Script::Handle(Script::New(url, source));
+    EXPECT(!script.IsNull());
+    EXPECT(script.IsScript());
+    String& str = String::Handle(script.url());
+    EXPECT_EQ(17, str.Length());
+    EXPECT_EQ('b', str.CharAt(0));
+    EXPECT_EQ(':', str.CharAt(7));
+    EXPECT_EQ('e', str.CharAt(16));
+    str = script.Source();
+    EXPECT_EQ(22, str.Length());
+    EXPECT_EQ('T', str.CharAt(0));
+    EXPECT_EQ('n', str.CharAt(10));
+    EXPECT_EQ('.', str.CharAt(21));
+  }
+
+  CheckLinesWithOffset(Z, 0);
+  CheckLinesWithOffset(Z, 500);
+  CheckLinesWithOffset(Z, 10000);
+
+  {
+    const char* url_chars = "";
+    // Single line, no terminators.
+    const char* source_chars = "abc";
+    const String& url = String::Handle(String::New(url_chars));
+    const String& source = String::Handle(String::New(source_chars));
+    const Script& script = Script::Handle(Script::New(url, source));
+    EXPECT(!script.IsNull());
+    EXPECT(script.IsScript());
+    auto& str = String::Handle(Z);
+    str = script.GetLine(1);
+    EXPECT_STREQ("abc", str.ToCString());
+    str = script.GetSnippet(1, 1, 1, 2);
+    EXPECT_STREQ("a", str.ToCString());
+    str = script.GetSnippet(1, 2, 1, 4);
+    EXPECT_STREQ("bc", str.ToCString());
+    // Lines not in the source should return the empty string.
+    str = script.GetLine(-500);
+    EXPECT_STREQ("", str.ToCString());
+    str = script.GetLine(0);
+    EXPECT_STREQ("", str.ToCString());
+    str = script.GetLine(2);
+    EXPECT_STREQ("", str.ToCString());
+    str = script.GetLine(10000);
+    EXPECT_STREQ("", str.ToCString());
+    // Snippets not contained within the source should be the null string.
+    str = script.GetSnippet(-1, 1, 1, 2);
+    EXPECT(str.IsNull());
+    str = script.GetSnippet(2, 1, 2, 2);
+    EXPECT(str.IsNull());
+    str = script.GetSnippet(1, 1, 1, 5);
+    EXPECT(str.IsNull());
+  }
 
   TransitionVMToNative transition(thread);
   const char* kScript = "main() {}";
@@ -2950,12 +3059,17 @@
 }
 
 static FieldPtr CreateTestField(const char* name) {
+  auto thread = Thread::Current();
   const Class& cls = Class::Handle(CreateTestClass("global:"));
-  const String& field_name =
-      String::Handle(Symbols::New(Thread::Current(), name));
+  const String& field_name = String::Handle(Symbols::New(thread, name));
   const Field& field = Field::Handle(Field::New(
       field_name, true, false, false, true, false, cls, Object::dynamic_type(),
       TokenPosition::kMinSource, TokenPosition::kMinSource));
+  {
+    SafepointWriteRwLocker locker(thread,
+                                  thread->isolate_group()->program_lock());
+    thread->isolate_group()->RegisterStaticField(field, Instance::sentinel());
+  }
   return field.raw();
 }
 
@@ -3065,48 +3179,108 @@
 
   // Check ICData for unoptimized static calls.
   const intptr_t kNumArgsChecked = 0;
-  const ICData& scall_icdata =
-      ICData::Handle(ICData::New(function, target_name, args_descriptor, 57,
-                                 kNumArgsChecked, ICData::kInstance));
-  scall_icdata.AddTarget(target1);
+  const ICData& scall_icdata = ICData::Handle(
+      ICData::NewForStaticCall(function, target1, args_descriptor, 57,
+                               kNumArgsChecked, ICData::kInstance));
   EXPECT_EQ(target1.raw(), scall_icdata.GetTargetAt(0));
 }
 
 ISOLATE_UNIT_TEST_CASE(SubtypeTestCache) {
   SafepointMutexLocker ml(thread->isolate_group()->subtype_test_cache_mutex());
 
-  String& class_name = String::Handle(Symbols::New(thread, "EmptyClass"));
+  String& class1_name = String::Handle(Symbols::New(thread, "EmptyClass1"));
   Script& script = Script::Handle();
-  const Class& empty_class =
-      Class::Handle(CreateDummyClass(class_name, script));
+  const Class& empty_class1 =
+      Class::Handle(CreateDummyClass(class1_name, script));
+  String& class2_name = String::Handle(Symbols::New(thread, "EmptyClass2"));
+  const Class& empty_class2 =
+      Class::Handle(CreateDummyClass(class2_name, script));
   SubtypeTestCache& cache = SubtypeTestCache::Handle(SubtypeTestCache::New());
   EXPECT(!cache.IsNull());
   EXPECT_EQ(0, cache.NumberOfChecks());
-  const Object& class_id_or_fun = Object::Handle(Smi::New(empty_class.id()));
+  const Object& class_id_or_fun = Object::Handle(Smi::New(empty_class1.id()));
+  const AbstractType& dest_type =
+      AbstractType::Handle(Type::NewNonParameterizedType(empty_class2));
   const TypeArguments& targ_0 = TypeArguments::Handle(TypeArguments::New(2));
   const TypeArguments& targ_1 = TypeArguments::Handle(TypeArguments::New(3));
   const TypeArguments& targ_2 = TypeArguments::Handle(TypeArguments::New(4));
   const TypeArguments& targ_3 = TypeArguments::Handle(TypeArguments::New(5));
   const TypeArguments& targ_4 = TypeArguments::Handle(TypeArguments::New(6));
-  cache.AddCheck(class_id_or_fun, targ_0, targ_1, targ_2, targ_3, targ_4,
-                 Bool::True());
+  cache.AddCheck(class_id_or_fun, dest_type, targ_0, targ_1, targ_2, targ_3,
+                 targ_4, Bool::True());
   EXPECT_EQ(1, cache.NumberOfChecks());
   Object& test_class_id_or_fun = Object::Handle();
+  AbstractType& test_dest_type = AbstractType::Handle();
   TypeArguments& test_targ_0 = TypeArguments::Handle();
   TypeArguments& test_targ_1 = TypeArguments::Handle();
   TypeArguments& test_targ_2 = TypeArguments::Handle();
   TypeArguments& test_targ_3 = TypeArguments::Handle();
   TypeArguments& test_targ_4 = TypeArguments::Handle();
   Bool& test_result = Bool::Handle();
-  cache.GetCheck(0, &test_class_id_or_fun, &test_targ_0, &test_targ_1,
-                 &test_targ_2, &test_targ_3, &test_targ_4, &test_result);
+  cache.GetCheck(0, &test_class_id_or_fun, &test_dest_type, &test_targ_0,
+                 &test_targ_1, &test_targ_2, &test_targ_3, &test_targ_4,
+                 &test_result);
   EXPECT_EQ(class_id_or_fun.raw(), test_class_id_or_fun.raw());
+  EXPECT_EQ(dest_type.raw(), test_dest_type.raw());
   EXPECT_EQ(targ_0.raw(), test_targ_0.raw());
   EXPECT_EQ(targ_1.raw(), test_targ_1.raw());
   EXPECT_EQ(targ_2.raw(), test_targ_2.raw());
+  EXPECT_EQ(targ_3.raw(), test_targ_3.raw());
+  EXPECT_EQ(targ_4.raw(), test_targ_4.raw());
   EXPECT_EQ(Bool::True().raw(), test_result.raw());
 }
 
+ISOLATE_UNIT_TEST_CASE(MegamorphicCache) {
+  const auto& name = String::Handle(String::New("name"));
+  const auto& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::NewBoxed(1, 1, Object::null_array()));
+
+  const auto& cidA = Smi::Handle(Smi::New(1));
+  const auto& cidB = Smi::Handle(Smi::New(2));
+
+  const auto& valueA = Smi::Handle(Smi::New(42));
+  const auto& valueB = Smi::Handle(Smi::New(43));
+
+  // Test normal insert/lookup methods.
+  {
+    const auto& cache =
+        MegamorphicCache::Handle(MegamorphicCache::New(name, args_descriptor));
+
+    EXPECT(cache.Lookup(cidA) == Object::null());
+    cache.EnsureContains(cidA, valueA);
+    EXPECT(cache.Lookup(cidA) == valueA.raw());
+
+    EXPECT(cache.Lookup(cidB) == Object::null());
+    cache.EnsureContains(cidB, valueB);
+    EXPECT(cache.Lookup(cidB) == valueB.raw());
+  }
+
+  // Try to insert many keys to hit collisions & growth.
+  {
+    const auto& cache =
+        MegamorphicCache::Handle(MegamorphicCache::New(name, args_descriptor));
+
+    auto& cid = Smi::Handle();
+    auto& value = Object::Handle();
+    for (intptr_t i = 0; i < 100; ++i) {
+      cid = Smi::New(100 * i);
+      if (cid.Value() == kIllegalCid) continue;
+
+      value = Smi::New(i);
+      cache.EnsureContains(cid, value);
+    }
+    auto& expected = Object::Handle();
+    for (intptr_t i = 0; i < 100; ++i) {
+      cid = Smi::New(100 * i);
+      if (cid.Value() == kIllegalCid) continue;
+
+      expected = Smi::New(i);
+      value = cache.Lookup(cid);
+      EXPECT(Smi::Cast(value).Equals(Smi::Cast(expected)));
+    }
+  }
+}
+
 ISOLATE_UNIT_TEST_CASE(FieldTests) {
   const String& f = String::Handle(String::New("oneField"));
   const String& getter_f = String::Handle(Field::GetterName(f));
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 0a9ffa1..e79827b 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -23,6 +23,7 @@
 #include <zircon/syscalls.h>
 #include <zircon/syscalls/object.h>
 #include <zircon/time.h>
+#include <zircon/threads.h>
 #include <zircon/types.h>
 
 #include "platform/assert.h"
@@ -216,9 +217,11 @@
 }
 
 int64_t OS::GetCurrentThreadCPUMicros() {
-  zx_time_t now = 0;
-  zx_clock_get(ZX_CLOCK_THREAD, &now);
-  return now / kNanosecondsPerMicrosecond;
+  zx_info_thread_stats_t info = {};
+  zx_status_t status = zx_object_get_info(thrd_get_zx_handle(thrd_current()),
+                                          ZX_INFO_THREAD_STATS, &info,
+                                          sizeof(info), nullptr, nullptr);
+  return status == ZX_OK ? info.total_runtime / kNanosecondsPerMicrosecond : 0;
 }
 
 // On Fuchsia, thread timestamp values are not used in the tracing/timeline
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index f4bf134..c9cf923 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -74,20 +74,17 @@
                     Symbols::CurrentContextVar(), Object::dynamic_type());
   current_context_var_ = temp;
 
-  const bool reify_generic_argument = function.IsGeneric();
-
-  const bool load_optional_arguments = function.HasOptionalParameters();
-
-  const bool check_arguments = function.CanReceiveDynamicInvocation();
-
-  const bool need_argument_descriptor =
-      load_optional_arguments || check_arguments || reify_generic_argument;
-
-  if (need_argument_descriptor) {
+  if (function.PrologueNeedsArgumentsDescriptor()) {
     arg_desc_var_ = new (zone())
         LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                       Symbols::ArgDescVar(), Object::dynamic_type());
   }
+
+  // The code generated by the prologue builder for loading optional arguments
+  // requires the expression temporary variable.
+  if (function.HasOptionalParameters()) {
+    EnsureExpressionTemp();
+  }
 }
 
 void ParsedFunction::AddToGuardedFields(const Field* field) const {
@@ -339,19 +336,33 @@
 ParsedFunction::EnsureDynamicClosureCallVars() {
   ASSERT(function().IsDynamicClosureCallDispatcher(thread()));
   if (dynamic_closure_call_vars_ != nullptr) return dynamic_closure_call_vars_;
-  dynamic_closure_call_vars_ = new (zone()) DynamicClosureCallVars();
+  const auto& saved_args_desc =
+      Array::Handle(zone(), function().saved_args_desc());
+  const ArgumentsDescriptor descriptor(saved_args_desc);
 
+  dynamic_closure_call_vars_ =
+      new (zone()) DynamicClosureCallVars(zone(), descriptor.NamedCount());
+
+  auto const pos = function().token_pos();
   const auto& type_Dynamic = Object::dynamic_type();
   const auto& type_Function =
       Type::ZoneHandle(zone(), Type::DartFunctionType());
   const auto& type_Smi = Type::ZoneHandle(zone(), Type::SmiType());
 #define INIT_FIELD(Name, TypeName, Symbol)                                     \
-  dynamic_closure_call_vars_->Name = new (zone())                              \
-      LocalVariable(function().token_pos(), function().token_pos(),            \
-                    Symbols::DynamicCall##Symbol##Var(), type_##TypeName);
+  dynamic_closure_call_vars_->Name = new (zone()) LocalVariable(               \
+      pos, pos, Symbols::DynamicCall##Symbol##Var(), type_##TypeName);
   FOR_EACH_DYNAMIC_CLOSURE_CALL_VARIABLE(INIT_FIELD);
 #undef INIT_FIELD
 
+  for (intptr_t i = 0; i < descriptor.NamedCount(); i++) {
+    auto const name = OS::SCreate(
+        zone(), ":dyn_call_named_argument_%" Pd "_parameter_index", i);
+    auto const var = new (zone()) LocalVariable(
+        pos, pos, String::ZoneHandle(zone(), Symbols::New(thread(), name)),
+        type_Smi);
+    dynamic_closure_call_vars_->named_argument_parameter_indices.Add(var);
+  }
+
   return dynamic_closure_call_vars_;
 }
 
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 76b6249..2aa73d8 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -237,6 +237,9 @@
   // Variables needed for the InvokeFieldDispatcher for dynamic closure calls,
   // because they are both read and written to by the builders.
   struct DynamicClosureCallVars : ZoneAllocated {
+    DynamicClosureCallVars(Zone* zone, intptr_t num_named)
+        : named_argument_parameter_indices(zone, num_named) {}
+
 #define FOR_EACH_DYNAMIC_CLOSURE_CALL_VARIABLE(V)                              \
   V(current_function, Function, CurrentFunction)                               \
   V(current_num_processed, Smi, CurrentNumProcessed)                           \
@@ -246,6 +249,10 @@
 #define DEFINE_FIELD(Name, _, __) LocalVariable* Name = nullptr;
     FOR_EACH_DYNAMIC_CLOSURE_CALL_VARIABLE(DEFINE_FIELD)
 #undef DEFINE_FIELD
+
+    // An array of local variables, one for each named parameter in the
+    // saved arguments descriptor.
+    ZoneGrowableArray<LocalVariable*> named_argument_parameter_indices;
   };
 
   DynamicClosureCallVars* dynamic_closure_call_vars() const {
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 9d5c331..c7312de 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -29,6 +29,8 @@
       return "live";
     case kControlPort:
       return "control";
+    case kInactivePort:
+      return "inactive";
     default:
       UNREACHABLE();
       return "UNKNOWN";
@@ -72,10 +74,11 @@
 
   Entry& entry = *it;
   PortState old_state = entry.state;
-  ASSERT(old_state == kNewPort);
   entry.state = state;
   if (state == kLivePort) {
     entry.handler->increment_live_ports();
+  } else if (state == kInactivePort && old_state == kLivePort) {
+    entry.handler->decrement_live_ports();
   }
   if (FLAG_trace_isolates) {
     OS::PrintErr(
@@ -211,6 +214,18 @@
   return handler->IsCurrentIsolate();
 }
 
+bool PortMap::IsLivePort(Dart_Port id) {
+  MutexLocker ml(mutex_);
+  auto it = ports_->TryLookup(id);
+  if (it == ports_->end()) {
+    // Port does not exist.
+    return false;
+  }
+
+  PortState state = (*it).state;
+  return (state == kLivePort || state == kControlPort);
+}
+
 Isolate* PortMap::GetIsolate(Dart_Port id) {
   MutexLocker ml(mutex_);
   auto it = ports_->TryLookup(id);
diff --git a/runtime/vm/port.h b/runtime/vm/port.h
index 0297f1d..1405362 100644
--- a/runtime/vm/port.h
+++ b/runtime/vm/port.h
@@ -28,6 +28,8 @@
     kNewPort = 0,      // a newly allocated port
     kLivePort = 1,     // a regular port (has a ReceivePort)
     kControlPort = 2,  // a special control port (has a ReceivePort)
+    kInactivePort =
+        3,  // an inactive port (has a ReceivePort) not considered live.
   };
 
   // Allocate a port for the provided handler and return its VM-global id.
@@ -55,6 +57,9 @@
   // Returns whether a port is local to the current isolate.
   static bool IsLocalPort(Dart_Port id);
 
+  // Returns whether a port is live (e.g., is not new or inactive).
+  static bool IsLivePort(Dart_Port id);
+
   // Returns the owning Isolate for port 'id'.
   static Isolate* GetIsolate(Dart_Port id);
 
@@ -84,9 +89,6 @@
   // Allocate a new unique port.
   static Dart_Port AllocatePort();
 
-  static bool IsActivePort(Dart_Port id);
-  static bool IsLivePort(Dart_Port id);
-
   // Lock protecting access to the port map.
   static Mutex* mutex_;
 
diff --git a/runtime/vm/port_set.h b/runtime/vm/port_set.h
index 97a2c9a..a632f50 100644
--- a/runtime/vm/port_set.h
+++ b/runtime/vm/port_set.h
@@ -7,6 +7,7 @@
 
 #include "include/dart_api.h"
 
+#include "platform/allocation.h"
 #include "platform/globals.h"
 #include "platform/utils.h"
 
@@ -18,7 +19,7 @@
   static constexpr Dart_Port kFreePort = static_cast<Dart_Port>(0);
   static constexpr Dart_Port kDeletedPort = static_cast<Dart_Port>(3);
 
-  struct Entry {
+  struct Entry : public MallocAllocated {
     Entry() : port(kFreePort) {}
 
     // Free entries have set this to 0.
diff --git a/runtime/vm/port_test.cc b/runtime/vm/port_test.cc
index 2fb63d7..afcbb7b 100644
--- a/runtime/vm/port_test.cc
+++ b/runtime/vm/port_test.cc
@@ -106,6 +106,11 @@
   EXPECT(PortMapTestPeer::IsActivePort(port));
   EXPECT(PortMapTestPeer::IsLivePort(port));
 
+  // Inactive port.
+  PortMap::SetPortState(port, PortMap::kInactivePort);
+  EXPECT(PortMapTestPeer::IsActivePort(port));
+  EXPECT(!PortMapTestPeer::IsLivePort(port));
+
   PortMap::ClosePort(port);
   EXPECT(!PortMapTestPeer::IsActivePort(port));
   EXPECT(!PortMapTestPeer::IsLivePort(port));
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 1feb330..64adf66 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -45,26 +45,26 @@
     return;
   }
   // Validate that the tags_ field is sensible.
-  uint32_t tags = tags_;
+  uword tags = tags_;
   if (IsNewObject()) {
     if (!NewBit::decode(tags)) {
-      FATAL1("New object missing kNewBit: %x\n", tags);
+      FATAL1("New object missing kNewBit: %" Px "\n", tags);
     }
     if (OldBit::decode(tags)) {
-      FATAL1("New object has kOldBit: %x\n", tags);
+      FATAL1("New object has kOldBit: %" Px "\n", tags);
     }
     if (OldAndNotMarkedBit::decode(tags)) {
-      FATAL1("New object has kOldAndNotMarkedBit: %x\n", tags);
+      FATAL1("New object has kOldAndNotMarkedBit: %" Px "\n", tags);
     }
     if (OldAndNotRememberedBit::decode(tags)) {
-      FATAL1("New object has kOldAndNotRememberedBit: %x\n", tags);
+      FATAL1("New object has kOldAndNotRememberedBit: %" Px "\n", tags);
     }
   } else {
     if (NewBit::decode(tags)) {
-      FATAL1("Old object has kNewBit: %x\n", tags);
+      FATAL1("Old object has kNewBit: %" Px "\n", tags);
     }
     if (!OldBit::decode(tags)) {
-      FATAL1("Old object missing kOldBit: %x\n", tags);
+      FATAL1("Old object missing kOldBit: %" Px "\n", tags);
     }
   }
   const intptr_t class_id = ClassIdTag::decode(tags);
@@ -90,7 +90,7 @@
 // compaction when the class objects are moving. Can use the class
 // id in the header and the sizes in the Class Table.
 // Cannot deference ptr()->tags_. May dereference other parts of the object.
-intptr_t ObjectLayout::HeapSizeFromClass(uint32_t tags) const {
+intptr_t ObjectLayout::HeapSizeFromClass(uword tags) const {
   intptr_t class_id = ClassIdTag::decode(tags);
   intptr_t instance_size = 0;
   switch (class_id) {
@@ -145,7 +145,8 @@
     case kArrayCid:
     case kImmutableArrayCid: {
       const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
-      intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
+      intptr_t array_length =
+          Smi::Value(raw_array->ptr()->length<std::memory_order_acquire>());
       instance_size = Array::InstanceSize(array_length);
       break;
     }
@@ -268,7 +269,7 @@
     } while ((instance_size > tags_size) && (--retries_remaining > 0));
   }
   if ((instance_size != tags_size) && (tags_size != 0)) {
-    FATAL3("Size mismatch: %" Pd " from class vs %" Pd " from tags %x\n",
+    FATAL3("Size mismatch: %" Pd " from class vs %" Pd " from tags %" Px "\n",
            instance_size, tags_size, tags);
   }
 #endif  // DEBUG
@@ -337,13 +338,6 @@
         break;
       }
 #undef RAW_VISITPOINTERS
-#define RAW_VISITPOINTERS(clazz) case k##clazz##Cid:
-      CLASS_LIST_WASM(RAW_VISITPOINTERS) {
-        // These wasm types do not have any fields or type arguments.
-        size = HeapSize();
-        break;
-      }
-#undef RAW_VISITPOINTERS
     case kFreeListElement: {
       uword addr = ObjectLayout::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
@@ -513,7 +507,6 @@
 COMPRESSED_VISITOR(Closure)
 REGULAR_VISITOR(ClosureData)
 REGULAR_VISITOR(SignatureData)
-REGULAR_VISITOR(RedirectionData)
 REGULAR_VISITOR(FfiTrampolineData)
 REGULAR_VISITOR(Script)
 REGULAR_VISITOR(Library)
@@ -547,7 +540,7 @@
 VARIABLE_VISITOR(LocalVarDescriptors, raw_obj->ptr()->num_entries_)
 VARIABLE_VISITOR(ExceptionHandlers, raw_obj->ptr()->num_entries_)
 VARIABLE_VISITOR(Context, raw_obj->ptr()->num_variables_)
-VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->ptr()->length_))
+VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->ptr()->length()))
 VARIABLE_COMPRESSED_VISITOR(
     TypedData,
     TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
@@ -672,7 +665,7 @@
                                                ObjectPointerVisitor* visitor) {
   // Make sure that we got here with the tagged pointer as this.
   ASSERT(raw_obj->IsHeapObject());
-  uint32_t tags = raw_obj->ptr()->tags_;
+  uword tags = raw_obj->ptr()->tags_;
   intptr_t instance_size = SizeTag::decode(tags);
   if (instance_size == 0) {
     instance_size = visitor->isolate_group()->GetClassSizeForHeapWalkAt(
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 91a2ddc..15af026 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -48,10 +48,10 @@
 class CodeStatistics;
 
 #define VISIT_FROM(type, first)                                                \
-  type* from() { return reinterpret_cast<type*>(&first); }
+  type* from() { return reinterpret_cast<type*>(&first##_); }
 
 #define VISIT_TO(type, last)                                                   \
-  type* to() { return reinterpret_cast<type*>(&last); }
+  type* to() { return reinterpret_cast<type*>(&last##_); }
 
 #define VISIT_TO_LENGTH(type, last)                                            \
   type* to(intptr_t length) { return reinterpret_cast<type*>(last); }
@@ -130,10 +130,8 @@
     kSizeTagSize = 8,
     kClassIdTagPos = kSizeTagPos + kSizeTagSize,  // = 16
     kClassIdTagSize = 16,
-#if defined(HASH_IN_OBJECT_HEADER)
     kHashTagPos = kClassIdTagPos + kClassIdTagSize,  // = 32
-    kHashTagSize = 16,
-#endif
+    kHashTagSize = 32,
   };
 
   static const intptr_t kGenerationalBarrierMask = 1 << kNewBit;
@@ -177,7 +175,7 @@
    private:
     // The actual unscaled bit field used within the tag field.
     class SizeBits
-        : public BitField<uint32_t, intptr_t, kSizeTagPos, kSizeTagSize> {};
+        : public BitField<uword, intptr_t, kSizeTagPos, kSizeTagSize> {};
 
     static UNLESS_DEBUG(constexpr) intptr_t SizeToTagValue(intptr_t size) {
       DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment));
@@ -188,64 +186,66 @@
     }
   };
 
-  class ClassIdTag : public BitField<uint32_t,
+  class ClassIdTag : public BitField<uword,
                                      ClassIdTagType,
                                      kClassIdTagPos,
                                      kClassIdTagSize> {};
   COMPILE_ASSERT(kBitsPerByte * sizeof(ClassIdTagType) == kClassIdTagSize);
 
+#if defined(HASH_IN_OBJECT_HEADER)
+  class HashTag : public BitField<uword, uint32_t, kHashTagPos, kHashTagSize> {
+  };
+#endif
+
   class CardRememberedBit
-      : public BitField<uint32_t, bool, kCardRememberedBit, 1> {};
+      : public BitField<uword, bool, kCardRememberedBit, 1> {};
 
   class OldAndNotMarkedBit
-      : public BitField<uint32_t, bool, kOldAndNotMarkedBit, 1> {};
+      : public BitField<uword, bool, kOldAndNotMarkedBit, 1> {};
 
-  class NewBit : public BitField<uint32_t, bool, kNewBit, 1> {};
+  class NewBit : public BitField<uword, bool, kNewBit, 1> {};
 
-  class CanonicalBit : public BitField<uint32_t, bool, kCanonicalBit, 1> {};
+  class CanonicalBit : public BitField<uword, bool, kCanonicalBit, 1> {};
 
-  class OldBit : public BitField<uint32_t, bool, kOldBit, 1> {};
+  class OldBit : public BitField<uword, bool, kOldBit, 1> {};
 
   class OldAndNotRememberedBit
-      : public BitField<uint32_t, bool, kOldAndNotRememberedBit, 1> {};
+      : public BitField<uword, bool, kOldAndNotRememberedBit, 1> {};
 
   class ReservedBits
-      : public BitField<uint32_t, intptr_t, kReservedTagPos, kReservedTagSize> {
-  };
+      : public BitField<uword, intptr_t, kReservedTagPos, kReservedTagSize> {};
 
   class Tags {
    public:
     Tags() : tags_(0) {}
 
-    NO_SANITIZE_THREAD
-    operator uint32_t() const {
-      return *reinterpret_cast<const uint32_t*>(&tags_);
+    operator uword() const { return tags_.load(std::memory_order_relaxed); }
+
+    uword operator=(uword tags) {
+      tags_.store(tags, std::memory_order_relaxed);
+      return tags;
     }
 
-    NO_SANITIZE_THREAD
-    uint32_t operator=(uint32_t tags) {
-      return *reinterpret_cast<uint32_t*>(&tags_) = tags;
-    }
+    uword load(std::memory_order order) const { return tags_.load(order); }
 
-    NO_SANITIZE_THREAD
-    bool StrongCAS(uint32_t old_tags, uint32_t new_tags) {
-      return tags_.compare_exchange_strong(old_tags, new_tags,
-                                           std::memory_order_relaxed);
-    }
-
-    NO_SANITIZE_THREAD
-    bool WeakCAS(uint32_t old_tags, uint32_t new_tags) {
-      return tags_.compare_exchange_weak(old_tags, new_tags,
-                                         std::memory_order_relaxed);
+    bool compare_exchange_weak(uword old_tags,
+                               uword new_tags,
+                               std::memory_order order) {
+      return tags_.compare_exchange_weak(old_tags, new_tags, order);
     }
 
     template <class TagBitField>
-    NO_SANITIZE_THREAD typename TagBitField::Type Read() const {
-      return TagBitField::decode(*reinterpret_cast<const uint32_t*>(&tags_));
+    typename TagBitField::Type Read() const {
+      return TagBitField::decode(tags_.load(std::memory_order_relaxed));
     }
 
     template <class TagBitField>
-    NO_SANITIZE_THREAD void UpdateBool(bool value) {
+    NO_SANITIZE_THREAD typename TagBitField::Type ReadIgnoreRace() const {
+      return TagBitField::decode(*reinterpret_cast<const uword*>(&tags_));
+    }
+
+    template <class TagBitField>
+    void UpdateBool(bool value) {
       if (value) {
         tags_.fetch_or(TagBitField::encode(true), std::memory_order_relaxed);
       } else {
@@ -254,29 +254,39 @@
     }
 
     template <class TagBitField>
-    NO_SANITIZE_THREAD void UpdateUnsynchronized(
-        typename TagBitField::Type value) {
-      *reinterpret_cast<uint32_t*>(&tags_) =
-          TagBitField::update(value, *reinterpret_cast<uint32_t*>(&tags_));
+    void Update(typename TagBitField::Type value) {
+      uword old_tags = tags_.load(std::memory_order_relaxed);
+      uword new_tags;
+      do {
+        new_tags = TagBitField::update(value, old_tags);
+      } while (!tags_.compare_exchange_weak(old_tags, new_tags,
+                                            std::memory_order_relaxed));
     }
 
     template <class TagBitField>
-    NO_SANITIZE_THREAD bool TryAcquire() {
-      uint32_t mask = TagBitField::encode(true);
-      uint32_t old_tags = tags_.fetch_or(mask, std::memory_order_relaxed);
+    void UpdateUnsynchronized(typename TagBitField::Type value) {
+      tags_.store(
+          TagBitField::update(value, tags_.load(std::memory_order_relaxed)),
+          std::memory_order_relaxed);
+    }
+
+    template <class TagBitField>
+    bool TryAcquire() {
+      uword mask = TagBitField::encode(true);
+      uword old_tags = tags_.fetch_or(mask, std::memory_order_relaxed);
       return !TagBitField::decode(old_tags);
     }
 
     template <class TagBitField>
-    NO_SANITIZE_THREAD bool TryClear() {
-      uint32_t mask = ~TagBitField::encode(true);
-      uint32_t old_tags = tags_.fetch_and(mask, std::memory_order_relaxed);
+    bool TryClear() {
+      uword mask = ~TagBitField::encode(true);
+      uword old_tags = tags_.fetch_and(mask, std::memory_order_relaxed);
       return TagBitField::decode(old_tags);
     }
 
    private:
-    std::atomic<uint32_t> tags_;
-    COMPILE_ASSERT(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t));
+    std::atomic<uword> tags_;
+    COMPILE_ASSERT(sizeof(std::atomic<uword>) == sizeof(uword));
   };
 
   // Assumes this is a heap object.
@@ -292,10 +302,15 @@
 
   // Support for GC marking bit. Marked objects are either grey (not yet
   // visited) or black (already visited).
+  static bool IsMarked(uword tags) { return !OldAndNotMarkedBit::decode(tags); }
   bool IsMarked() const {
     ASSERT(IsOldObject());
     return !tags_.Read<OldAndNotMarkedBit>();
   }
+  bool IsMarkedIgnoreRace() const {
+    ASSERT(IsOldObject());
+    return !tags_.ReadIgnoreRace<OldAndNotMarkedBit>();
+  }
   void SetMarkBit() {
     ASSERT(IsOldObject());
     ASSERT(!IsMarked());
@@ -357,8 +372,13 @@
 
   intptr_t GetClassId() const { return tags_.Read<ClassIdTag>(); }
 
+#if defined(HASH_IN_OBJECT_HEADER)
+  uint32_t GetHeaderHash() const { return tags_.Read<HashTag>(); }
+  void SetHeaderHash(uint32_t h) { tags_.Update<HashTag>(h); }
+#endif
+
   intptr_t HeapSize() const {
-    uint32_t tags = tags_;
+    uword tags = tags_;
     intptr_t result = SizeTag::decode(tags);
     if (result != 0) {
 #if defined(DEBUG)
@@ -382,7 +402,7 @@
   }
 
   // This variant must not deference this->tags_.
-  intptr_t HeapSize(uint32_t tags) const {
+  intptr_t HeapSize(uword tags) const {
     intptr_t result = SizeTag::decode(tags);
     if (result != 0) {
       return result;
@@ -502,30 +522,23 @@
 
  private:
   Tags tags_;  // Various object tags (bits).
-#if defined(HASH_IN_OBJECT_HEADER)
-  // On 64 bit there is a hash field in the header for the identity hash.
-  uint32_t hash_;
-#elif defined(IS_SIMARM_X64)
-  // On simarm_x64 the hash isn't used, but we need the padding anyway so that
-  // the object layout fits assumptions made about X64.
-  uint32_t padding_;
-#endif
 
   intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
                                    intptr_t class_id);
 
-  intptr_t HeapSizeFromClass(uint32_t tags) const;
+  intptr_t HeapSizeFromClass(uword tags) const;
 
-  void SetClassId(intptr_t new_cid) {
+  void SetClassId(intptr_t new_cid) { tags_.Update<ClassIdTag>(new_cid); }
+  void SetClassIdUnsynchronized(intptr_t new_cid) {
     tags_.UpdateUnsynchronized<ClassIdTag>(new_cid);
   }
 
   // All writes to heap objects should ultimately pass through one of the
   // methods below or their counterparts in Object, to ensure that the
   // write barrier is correctly applied.
-
+ protected:
   template <typename type, std::memory_order order = std::memory_order_relaxed>
-  type LoadPointer(type const* addr) {
+  type LoadPointer(type const* addr) const {
     return reinterpret_cast<std::atomic<type>*>(const_cast<type*>(addr))
         ->load(order);
   }
@@ -555,10 +568,11 @@
     }
   }
 
+ private:
   DART_FORCE_INLINE
   void CheckHeapPointerStore(ObjectPtr value, Thread* thread) {
-    uint32_t source_tags = this->tags_;
-    uint32_t target_tags = value->ptr()->tags_;
+    uword source_tags = this->tags_;
+    uword target_tags = value->ptr()->tags_;
     if (((source_tags >> kBarrierOverlapShift) & target_tags &
          thread->write_barrier_mask()) != 0) {
       if (value->IsNewObject()) {
@@ -604,8 +618,8 @@
   DART_FORCE_INLINE void CheckArrayPointerStore(type const* addr,
                                                 ObjectPtr value,
                                                 Thread* thread) {
-    uint32_t source_tags = this->tags_;
-    uint32_t target_tags = value->ptr()->tags_;
+    uword source_tags = this->tags_;
+    uword target_tags = value->ptr()->tags_;
     if (((source_tags >> kBarrierOverlapShift) & target_tags &
          thread->write_barrier_mask()) != 0) {
       if (value->IsNewObject()) {
@@ -636,24 +650,26 @@
     }
   }
 
+ protected:
+  template <typename type, std::memory_order order = std::memory_order_relaxed>
+  type LoadSmi(type const* addr) const {
+    return reinterpret_cast<std::atomic<type>*>(const_cast<type*>(addr))
+        ->load(order);
+  }
   // Use for storing into an explicitly Smi-typed field of an object
   // (i.e., both the previous and new value are Smis).
+  template <std::memory_order order = std::memory_order_relaxed>
   void StoreSmi(SmiPtr const* addr, SmiPtr value) {
     // Can't use Contains, as array length is initialized through this method.
     ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this));
-    *const_cast<SmiPtr*>(addr) = value;
-  }
-  NO_SANITIZE_THREAD
-  void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) {
-    // Can't use Contains, as array length is initialized through this method.
-    ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this));
-    *const_cast<SmiPtr*>(addr) = value;
+    reinterpret_cast<std::atomic<SmiPtr>*>(const_cast<SmiPtr*>(addr))
+        ->store(value, order);
   }
 
- protected:
   friend class StoreBufferUpdateVisitor;  // RememberCard
   void RememberCard(ObjectPtr const* slot);
 
+ private:
   friend class Array;
   friend class ByteBuffer;
   friend class CidRewriteVisitor;
@@ -666,6 +682,7 @@
   friend class FreeListElement;
   friend class Function;
   friend class GCMarker;
+  friend class GCSweeper;
   friend class ExternalTypedData;
   friend class ForwardList;
   friend class GrowableObjectArray;  // StorePointer
@@ -707,6 +724,66 @@
   return ptr()->GetClassId();
 }
 
+#define POINTER_FIELD(type, name)                                              \
+ public:                                                                       \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  type name() const {                                                          \
+    return LoadPointer<type, order>(&name##_);                                 \
+  }                                                                            \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  void set_##name(type value) {                                                \
+    StorePointer<type, order>(&name##_, value);                                \
+  }                                                                            \
+                                                                               \
+ protected:                                                                    \
+  type name##_;
+
+#define ARRAY_POINTER_FIELD(type, name)                                        \
+ public:                                                                       \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  type name() const {                                                          \
+    return LoadPointer<type, order>(&name##_);                                 \
+  }                                                                            \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  void set_##name(type value) {                                                \
+    StoreArrayPointer<type, order>(&name##_, value);                           \
+  }                                                                            \
+                                                                               \
+ protected:                                                                    \
+  type name##_;
+
+#define VARIABLE_POINTER_FIELDS(type, accessor_name, array_name)               \
+ public:                                                                       \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  type accessor_name(intptr_t index) const {                                   \
+    return LoadPointer<type, order>(&array_name()[index]);                     \
+  }                                                                            \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  void set_##accessor_name(intptr_t index, type value) {                       \
+    StoreArrayPointer<type, order>(&array_name()[index], value);               \
+  }                                                                            \
+                                                                               \
+ protected:                                                                    \
+  type* array_name() { OPEN_ARRAY_START(type, type); }                         \
+  type const* array_name() const { OPEN_ARRAY_START(type, type); }
+
+#define SMI_FIELD(type, name)                                                  \
+ public:                                                                       \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  type name() const {                                                          \
+    type result = LoadSmi<type, order>(&name##_);                              \
+    ASSERT(!result.IsHeapObject());                                            \
+    return result;                                                             \
+  }                                                                            \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  void set_##name(type value) {                                                \
+    ASSERT(!value.IsHeapObject());                                             \
+    StoreSmi<order>(&name##_, value);                                          \
+  }                                                                            \
+                                                                               \
+ protected:                                                                    \
+  type name##_;
+
 class ClassLayout : public ObjectLayout {
  public:
   enum ClassFinalizedState {
@@ -732,27 +809,32 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Class);
 
-  VISIT_FROM(ObjectPtr, name_);
-  StringPtr name_;
-  StringPtr user_name_;
-  ArrayPtr functions_;
-  ArrayPtr functions_hash_table_;
-  ArrayPtr fields_;
-  ArrayPtr offset_in_words_to_field_;
-  ArrayPtr interfaces_;  // Array of AbstractType.
-  ScriptPtr script_;
-  LibraryPtr library_;
-  TypeArgumentsPtr type_parameters_;  // Array of TypeParameter.
-  AbstractTypePtr super_type_;
-  FunctionPtr signature_function_;  // Associated function for typedef class.
-  ArrayPtr constants_;        // Canonicalized const instances of this class.
-  TypePtr declaration_type_;  // Declaration type for this class.
-  ArrayPtr invocation_dispatcher_cache_;  // Cache for dispatcher functions.
-  CodePtr allocation_stub_;  // Stub code for allocation of instances.
-  GrowableObjectArrayPtr direct_implementors_;  // Array of Class.
-  GrowableObjectArrayPtr direct_subclasses_;    // Array of Class.
-  ArrayPtr dependent_code_;                     // CHA optimized codes.
-  VISIT_TO(ObjectPtr, dependent_code_);
+  VISIT_FROM(ObjectPtr, name)
+  POINTER_FIELD(StringPtr, name)
+  POINTER_FIELD(StringPtr, user_name)
+  POINTER_FIELD(ArrayPtr, functions)
+  POINTER_FIELD(ArrayPtr, functions_hash_table)
+  POINTER_FIELD(ArrayPtr, fields)
+  POINTER_FIELD(ArrayPtr, offset_in_words_to_field)
+  POINTER_FIELD(ArrayPtr, interfaces)  // Array of AbstractType.
+  POINTER_FIELD(ScriptPtr, script)
+  POINTER_FIELD(LibraryPtr, library)
+  POINTER_FIELD(TypeArgumentsPtr, type_parameters)  // Array of TypeParameter.
+  POINTER_FIELD(AbstractTypePtr, super_type)
+  POINTER_FIELD(FunctionPtr,
+                signature_function)  // Associated function for typedef class.
+  POINTER_FIELD(ArrayPtr,
+                constants)  // Canonicalized const instances of this class.
+  POINTER_FIELD(TypePtr, declaration_type)  // Declaration type for this class.
+  POINTER_FIELD(ArrayPtr,
+                invocation_dispatcher_cache)  // Cache for dispatcher functions.
+  POINTER_FIELD(CodePtr,
+                allocation_stub)  // Stub code for allocation of instances.
+  POINTER_FIELD(GrowableObjectArrayPtr,
+                direct_implementors)                        // Array of Class.
+  POINTER_FIELD(GrowableObjectArrayPtr, direct_subclasses)  // Array of Class.
+  POINTER_FIELD(ArrayPtr, dependent_code)  // CHA optimized codes.
+  VISIT_TO(ObjectPtr, dependent_code)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
@@ -819,12 +901,12 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(PatchClass);
 
-  VISIT_FROM(ObjectPtr, patched_class_);
-  ClassPtr patched_class_;
-  ClassPtr origin_class_;
-  ScriptPtr script_;
-  ExternalTypedDataPtr library_kernel_data_;
-  VISIT_TO(ObjectPtr, library_kernel_data_);
+  VISIT_FROM(ObjectPtr, patched_class)
+  POINTER_FIELD(ClassPtr, patched_class)
+  POINTER_FIELD(ClassPtr, origin_class)
+  POINTER_FIELD(ScriptPtr, script)
+  POINTER_FIELD(ExternalTypedDataPtr, library_kernel_data)
+  VISIT_TO(ObjectPtr, library_kernel_data)
 
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
@@ -1008,16 +1090,17 @@
   uword entry_point_;            // Accessed from generated code.
   uword unchecked_entry_point_;  // Accessed from generated code.
 
-  VISIT_FROM(ObjectPtr, name_);
-  StringPtr name_;
-  ObjectPtr owner_;  // Class or patch class or mixin class
-                     // where this function is defined.
-  AbstractTypePtr result_type_;
-  ArrayPtr parameter_types_;
-  ArrayPtr parameter_names_;
-  TypeArgumentsPtr type_parameters_;  // Array of TypeParameter.
-  ObjectPtr data_;  // Additional data specific to the function kind. See
-                    // Function::set_data() for details.
+  VISIT_FROM(ObjectPtr, name)
+  POINTER_FIELD(StringPtr, name)
+  POINTER_FIELD(ObjectPtr, owner)  // Class or patch class or mixin class
+                                   // where this function is defined.
+  POINTER_FIELD(AbstractTypePtr, result_type)
+  POINTER_FIELD(ArrayPtr, parameter_types)
+  POINTER_FIELD(ArrayPtr, parameter_names)
+  POINTER_FIELD(TypeArgumentsPtr, type_parameters)  // Array of TypeParameter.
+  POINTER_FIELD(ObjectPtr,
+                data)  // Additional data specific to the function kind. See
+                       // Function::set_data() for details.
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
@@ -1033,17 +1116,19 @@
     UNREACHABLE();
     return NULL;
   }
-  ArrayPtr ic_data_array_;  // ICData of unoptimized code.
+  POINTER_FIELD(ArrayPtr, ic_data_array);  // ICData of unoptimized code.
   ObjectPtr* to_no_code() {
     return reinterpret_cast<ObjectPtr*>(&ic_data_array_);
   }
-  CodePtr code_;  // Currently active code. Accessed from generated code.
-  NOT_IN_PRECOMPILED(CodePtr unoptimized_code_);  // Unoptimized code, keep it
+  POINTER_FIELD(CodePtr,
+                code);  // Currently active code. Accessed from generated code.
+  NOT_IN_PRECOMPILED(
+      POINTER_FIELD(CodePtr, unoptimized_code));  // Unoptimized code, keep it
                                                   // after optimization.
 #if defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(ObjectPtr, code_);
+  VISIT_TO(ObjectPtr, code);
 #else
-  VISIT_TO(ObjectPtr, unoptimized_code_);
+  VISIT_TO(ObjectPtr, unoptimized_code);
 #endif
 
   NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_);
@@ -1100,16 +1185,18 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(ClosureData);
 
-  VISIT_FROM(ObjectPtr, context_scope_);
-  ContextScopePtr context_scope_;
-  FunctionPtr parent_function_;  // Enclosing function of this local function.
-  TypePtr signature_type_;
-  InstancePtr closure_;  // Closure object for static implicit closures.
+  VISIT_FROM(ObjectPtr, context_scope)
+  POINTER_FIELD(ContextScopePtr, context_scope)
+  POINTER_FIELD(FunctionPtr,
+                parent_function)  // Enclosing function of this local function.
+  POINTER_FIELD(TypePtr, signature_type)
+  POINTER_FIELD(InstancePtr,
+                closure)  // Closure object for static implicit closures.
   // Instantiate-to-bounds TAV for use when no TAV is provided.
-  TypeArgumentsPtr default_type_arguments_;
+  POINTER_FIELD(TypeArgumentsPtr, default_type_arguments)
   // Additional information about the instantiate-to-bounds TAV.
-  SmiPtr default_type_arguments_info_;
-  VISIT_TO(ObjectPtr, default_type_arguments_info_);
+  POINTER_FIELD(SmiPtr, default_type_arguments_info)
+  VISIT_TO(ObjectPtr, default_type_arguments_info)
 
   friend class Function;
 };
@@ -1118,42 +1205,31 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(SignatureData);
 
-  VISIT_FROM(ObjectPtr, parent_function_);
-  FunctionPtr parent_function_;  // Enclosing function of this sig. function.
-  TypePtr signature_type_;
-  VISIT_TO(ObjectPtr, signature_type_);
+  VISIT_FROM(ObjectPtr, parent_function)
+  POINTER_FIELD(FunctionPtr,
+                parent_function);  // Enclosing function of this sig. function.
+  POINTER_FIELD(TypePtr, signature_type)
+  VISIT_TO(ObjectPtr, signature_type)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class Function;
 };
 
-class RedirectionDataLayout : public ObjectLayout {
- private:
-  RAW_HEAP_OBJECT_IMPLEMENTATION(RedirectionData);
-
-  VISIT_FROM(ObjectPtr, type_);
-  TypePtr type_;
-  StringPtr identifier_;
-  FunctionPtr target_;
-  VISIT_TO(ObjectPtr, target_);
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
-};
-
 class FfiTrampolineDataLayout : public ObjectLayout {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData);
 
-  VISIT_FROM(ObjectPtr, signature_type_);
-  TypePtr signature_type_;
-  FunctionPtr c_signature_;
+  VISIT_FROM(ObjectPtr, signature_type)
+  POINTER_FIELD(TypePtr, signature_type)
+  POINTER_FIELD(FunctionPtr, c_signature)
 
   // Target Dart method for callbacks, otherwise null.
-  FunctionPtr callback_target_;
+  POINTER_FIELD(FunctionPtr, callback_target)
 
   // For callbacks, value to return if Dart target throws an exception.
-  InstancePtr callback_exceptional_return_;
+  POINTER_FIELD(InstancePtr, callback_exceptional_return)
 
-  VISIT_TO(ObjectPtr, callback_exceptional_return_);
+  VISIT_TO(ObjectPtr, callback_exceptional_return)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // Callback id for callbacks.
@@ -1171,23 +1247,19 @@
 class FieldLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
 
-  VISIT_FROM(ObjectPtr, name_);
-  StringPtr name_;
-  ObjectPtr owner_;  // Class or patch class or mixin class
-                     // where this field is defined or original field.
-  AbstractTypePtr type_;
-  FunctionPtr initializer_function_;  // Static initializer function.
+  VISIT_FROM(ObjectPtr, name)
+  POINTER_FIELD(StringPtr, name)
+  POINTER_FIELD(ObjectPtr, owner)  // Class or patch class or mixin class
+  // where this field is defined or original field.
+  POINTER_FIELD(AbstractTypePtr, type)
+  POINTER_FIELD(FunctionPtr,
+                initializer_function)  // Static initializer function.
 
   // - for instance fields: offset in words to the value in the class instance.
   // - for static fields: index into field_table.
-  SmiPtr host_offset_or_field_id_;
-
-  // When generating APPJIT snapshots after running the application it is
-  // necessary to save the initial value of static fields so that we can
-  // restore the value back to the original initial value.
-  NOT_IN_PRECOMPILED(InstancePtr saved_initial_value_);  // Saved initial value
-  SmiPtr guarded_list_length_;
-  ArrayPtr dependent_code_;
+  SMI_FIELD(SmiPtr, host_offset_or_field_id)
+  SMI_FIELD(SmiPtr, guarded_list_length)
+  POINTER_FIELD(ArrayPtr, dependent_code)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFull:
@@ -1204,10 +1276,11 @@
     return NULL;
   }
 #if defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(ObjectPtr, dependent_code_);
+  VISIT_TO(ObjectPtr, dependent_code);
 #else
-  SubtypeTestCachePtr type_test_cache_;  // For type test in implicit setter.
-  VISIT_TO(ObjectPtr, type_test_cache_);
+  POINTER_FIELD(SubtypeTestCachePtr,
+                type_test_cache);  // For type test in implicit setter.
+  VISIT_TO(ObjectPtr, type_test_cache);
 #endif
   TokenPosition token_pos_;
   TokenPosition end_token_pos_;
@@ -1242,7 +1315,7 @@
   friend class StoreInstanceFieldInstr;  // For sizeof(guarded_cid_/...)
 };
 
-class ScriptLayout : public ObjectLayout {
+class alignas(8) ScriptLayout : public ObjectLayout {
  public:
   enum {
     kLazyLookupSourceAndLineStartsPos = 0,
@@ -1252,15 +1325,18 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Script);
 
-  VISIT_FROM(ObjectPtr, url_);
-  StringPtr url_;
-  StringPtr resolved_url_;
-  ArrayPtr compile_time_constants_;
-  TypedDataPtr line_starts_;
-  ArrayPtr debug_positions_;
-  KernelProgramInfoPtr kernel_program_info_;
-  StringPtr source_;
-  VISIT_TO(ObjectPtr, source_);
+  VISIT_FROM(ObjectPtr, url)
+  POINTER_FIELD(StringPtr, url)
+  POINTER_FIELD(StringPtr, resolved_url)
+  POINTER_FIELD(ArrayPtr, compile_time_constants)
+  POINTER_FIELD(TypedDataPtr, line_starts)
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  POINTER_FIELD(ExternalTypedDataPtr, constant_coverage)
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  POINTER_FIELD(ArrayPtr, debug_positions)
+  POINTER_FIELD(KernelProgramInfoPtr, kernel_program_info)
+  POINTER_FIELD(StringPtr, source)
+  VISIT_TO(ObjectPtr, source)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
@@ -1288,8 +1364,13 @@
                kLazyLookupSourceAndLineStartsSize>;
   uint8_t flags_;
 
-  intptr_t kernel_script_index_;
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   int64_t load_timestamp_;
+  int32_t kernel_script_index_;
+#else
+  int32_t kernel_script_index_;
+  int64_t load_timestamp_;
+#endif
 };
 
 class LibraryLayout : public ObjectLayout {
@@ -1322,19 +1403,21 @@
 
   RAW_HEAP_OBJECT_IMPLEMENTATION(Library);
 
-  VISIT_FROM(ObjectPtr, name_);
-  StringPtr name_;
-  StringPtr url_;
-  StringPtr private_key_;
-  ArrayPtr dictionary_;              // Top-level names in this library.
-  GrowableObjectArrayPtr metadata_;  // Metadata on classes, methods etc.
-  ClassPtr toplevel_class_;          // Class containing top-level elements.
-  GrowableObjectArrayPtr used_scripts_;
-  LoadingUnitPtr loading_unit_;
-  ArrayPtr imports_;  // List of Namespaces imported without prefix.
-  ArrayPtr exports_;  // List of re-exported Namespaces.
-  ArrayPtr dependencies_;
-  ExternalTypedDataPtr kernel_data_;
+  VISIT_FROM(ObjectPtr, name)
+  POINTER_FIELD(StringPtr, name)
+  POINTER_FIELD(StringPtr, url)
+  POINTER_FIELD(StringPtr, private_key)
+  POINTER_FIELD(ArrayPtr, dictionary)  // Top-level names in this library.
+  POINTER_FIELD(ArrayPtr, metadata)    // Metadata on classes, methods etc.
+  POINTER_FIELD(ClassPtr,
+                toplevel_class)  // Class containing top-level elements.
+  POINTER_FIELD(GrowableObjectArrayPtr, used_scripts)
+  POINTER_FIELD(LoadingUnitPtr, loading_unit)
+  POINTER_FIELD(ArrayPtr,
+                imports)  // List of Namespaces imported without prefix.
+  POINTER_FIELD(ArrayPtr, exports)  // List of re-exported Namespaces.
+  POINTER_FIELD(ArrayPtr, dependencies)
+  POINTER_FIELD(ExternalTypedDataPtr, kernel_data)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
@@ -1351,10 +1434,13 @@
     UNREACHABLE();
     return NULL;
   }
-  ArrayPtr resolved_names_;  // Cache of resolved names in library scope.
-  ArrayPtr exported_names_;  // Cache of exported names by library.
-  ArrayPtr loaded_scripts_;  // Array of scripts loaded in this library.
-  VISIT_TO(ObjectPtr, loaded_scripts_);
+  POINTER_FIELD(ArrayPtr,
+                resolved_names);  // Cache of resolved names in library scope.
+  POINTER_FIELD(ArrayPtr,
+                exported_names);  // Cache of exported names by library.
+  POINTER_FIELD(ArrayPtr,
+                loaded_scripts);  // Array of scripts loaded in this library.
+  VISIT_TO(ObjectPtr, loaded_scripts);
 
   Dart_NativeEntryResolver native_entry_resolver_;  // Resolves natives.
   Dart_NativeEntrySymbol native_entry_symbol_resolver_;
@@ -1374,34 +1460,33 @@
 class NamespaceLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace);
 
-  VISIT_FROM(ObjectPtr, library_);
-  LibraryPtr library_;       // library with name dictionary.
-  ArrayPtr show_names_;      // list of names that are exported.
-  ArrayPtr hide_names_;      // list of names that are hidden.
-  FieldPtr metadata_field_;  // remembers the token pos of metadata if any,
-                             // and the metadata values if computed.
-  VISIT_TO(ObjectPtr, metadata_field_);
+  VISIT_FROM(ObjectPtr, target)
+  POINTER_FIELD(LibraryPtr, target)    // library with name dictionary.
+  POINTER_FIELD(ArrayPtr, show_names)  // list of names that are exported.
+  POINTER_FIELD(ArrayPtr, hide_names)  // list of names that are hidden.
+  POINTER_FIELD(LibraryPtr, owner)
+  VISIT_TO(ObjectPtr, owner)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
 class KernelProgramInfoLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo);
 
-  VISIT_FROM(ObjectPtr, string_offsets_);
-  TypedDataPtr string_offsets_;
-  ExternalTypedDataPtr string_data_;
-  TypedDataPtr canonical_names_;
-  ExternalTypedDataPtr metadata_payloads_;
-  ExternalTypedDataPtr metadata_mappings_;
-  ArrayPtr scripts_;
-  ArrayPtr constants_;
-  GrowableObjectArrayPtr potential_natives_;
-  GrowableObjectArrayPtr potential_pragma_functions_;
-  ExternalTypedDataPtr constants_table_;
-  ArrayPtr libraries_cache_;
-  ArrayPtr classes_cache_;
-  ObjectPtr retained_kernel_blob_;
-  VISIT_TO(ObjectPtr, retained_kernel_blob_);
+  VISIT_FROM(ObjectPtr, string_offsets)
+  POINTER_FIELD(TypedDataPtr, string_offsets)
+  POINTER_FIELD(ExternalTypedDataPtr, string_data)
+  POINTER_FIELD(TypedDataPtr, canonical_names)
+  POINTER_FIELD(ExternalTypedDataPtr, metadata_payloads)
+  POINTER_FIELD(ExternalTypedDataPtr, metadata_mappings)
+  POINTER_FIELD(ArrayPtr, scripts)
+  POINTER_FIELD(ArrayPtr, constants)
+  POINTER_FIELD(GrowableObjectArrayPtr, potential_natives)
+  POINTER_FIELD(GrowableObjectArrayPtr, potential_pragma_functions)
+  POINTER_FIELD(ExternalTypedDataPtr, constants_table)
+  POINTER_FIELD(ArrayPtr, libraries_cache)
+  POINTER_FIELD(ArrayPtr, classes_cache)
+  POINTER_FIELD(ObjectPtr, retained_kernel_blob)
+  VISIT_TO(ObjectPtr, retained_kernel_blob)
 
   uint32_t kernel_binary_version_;
 
@@ -1417,9 +1502,9 @@
   VISIT_NOTHING();
   ClassIdTagType cid_;
 #else
-  VISIT_FROM(ObjectPtr, target_);
-  ObjectPtr target_;
-  VISIT_TO(ObjectPtr, target_);
+  VISIT_FROM(ObjectPtr, target)
+  POINTER_FIELD(ObjectPtr, target)
+  VISIT_TO(ObjectPtr, target)
 #endif
 };
 
@@ -1472,39 +1557,40 @@
   uword unchecked_entry_point_;              // Accessed from generated code.
   uword monomorphic_unchecked_entry_point_;  // Accessed from generated code.
 
-  VISIT_FROM(ObjectPtr, object_pool_);
-  ObjectPoolPtr object_pool_;     // Accessed from generated code.
-  InstructionsPtr instructions_;  // Accessed from generated code.
+  VISIT_FROM(ObjectPtr, object_pool)
+  POINTER_FIELD(ObjectPoolPtr, object_pool)  // Accessed from generated code.
+  POINTER_FIELD(InstructionsPtr,
+                instructions)  // Accessed from generated code.
   // If owner_ is Function::null() the owner is a regular stub.
   // If owner_ is a Class the owner is the allocation stub for that class.
   // Else, owner_ is a regular Dart Function.
-  ObjectPtr owner_;  // Function, Null, or a Class.
-  ExceptionHandlersPtr exception_handlers_;
-  PcDescriptorsPtr pc_descriptors_;
+  POINTER_FIELD(ObjectPtr, owner)  // Function, Null, or a Class.
+  POINTER_FIELD(ExceptionHandlersPtr, exception_handlers)
+  POINTER_FIELD(PcDescriptorsPtr, pc_descriptors)
   // If FLAG_precompiled_mode, then this field contains
   //   TypedDataPtr catch_entry_moves_maps
   // Otherwise, it is
   //   SmiPtr num_variables
-  ObjectPtr catch_entry_;
-  CompressedStackMapsPtr compressed_stackmaps_;
-  ArrayPtr inlined_id_to_function_;
-  CodeSourceMapPtr code_source_map_;
-  NOT_IN_PRECOMPILED(InstructionsPtr active_instructions_);
-  NOT_IN_PRECOMPILED(ArrayPtr deopt_info_array_);
+  POINTER_FIELD(ObjectPtr, catch_entry)
+  POINTER_FIELD(CompressedStackMapsPtr, compressed_stackmaps)
+  POINTER_FIELD(ArrayPtr, inlined_id_to_function)
+  POINTER_FIELD(CodeSourceMapPtr, code_source_map)
+  NOT_IN_PRECOMPILED(POINTER_FIELD(InstructionsPtr, active_instructions))
+  NOT_IN_PRECOMPILED(POINTER_FIELD(ArrayPtr, deopt_info_array))
   // (code-offset, function, code) triples.
-  NOT_IN_PRECOMPILED(ArrayPtr static_calls_target_table_);
+  NOT_IN_PRECOMPILED(POINTER_FIELD(ArrayPtr, static_calls_target_table))
   // If return_address_metadata_ is a Smi, it is the offset to the prologue.
   // Else, return_address_metadata_ is null.
-  NOT_IN_PRODUCT(ObjectPtr return_address_metadata_);
-  NOT_IN_PRODUCT(LocalVarDescriptorsPtr var_descriptors_);
-  NOT_IN_PRODUCT(ArrayPtr comments_);
+  NOT_IN_PRODUCT(POINTER_FIELD(ObjectPtr, return_address_metadata))
+  NOT_IN_PRODUCT(POINTER_FIELD(LocalVarDescriptorsPtr, var_descriptors))
+  NOT_IN_PRODUCT(POINTER_FIELD(ArrayPtr, comments))
 
 #if !defined(PRODUCT)
-  VISIT_TO(ObjectPtr, comments_);
+  VISIT_TO(ObjectPtr, comments);
 #elif defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(ObjectPtr, code_source_map_);
+  VISIT_TO(ObjectPtr, code_source_map);
 #else
-  VISIT_TO(ObjectPtr, static_calls_target_table_);
+  VISIT_TO(ObjectPtr, static_calls_target_table);
 #endif
 
   // Compilation timestamp.
@@ -1833,8 +1919,8 @@
   class KindBits : public BitField<int32_t, int8_t, kKindPos, kKindSize> {};
 
   struct VarInfo {
-    int32_t index_kind;  // Bitfield for slot index on stack or in context,
-                         // and Entry kind of type VarInfoKind.
+    int32_t index_kind = 0;  // Bitfield for slot index on stack or in context,
+                             // and Entry kind of type VarInfoKind.
     TokenPosition declaration_pos;  // Token position of declaration.
     TokenPosition begin_pos;        // Token position of scope start.
     TokenPosition end_pos;          // Token position of scope end.
@@ -1859,7 +1945,7 @@
   // platforms.
   uword num_entries_;
 
-  VISIT_FROM(ObjectPtr, names()[0]);
+  ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&names()[0]); }
   StringPtr* names() {
     // Array of [num_entries_] variable names.
     OPEN_ARRAY_START(StringPtr, StringPtr);
@@ -1884,9 +1970,9 @@
 
   // Array with [num_entries_] entries. Each entry is an array of all handled
   // exception types.
-  VISIT_FROM(ObjectPtr, handled_types_data_)
-  ArrayPtr handled_types_data_;
-  VISIT_TO_LENGTH(ObjectPtr, &handled_types_data_);
+  VISIT_FROM(ObjectPtr, handled_types_data)
+  POINTER_FIELD(ArrayPtr, handled_types_data)
+  VISIT_TO_LENGTH(ObjectPtr, &handled_types_data_)
 
   // Exception handler info of length [num_entries_].
   const ExceptionHandlerInfo* data() const {
@@ -1904,12 +1990,10 @@
 
   int32_t num_variables_;
 
-  VISIT_FROM(ObjectPtr, parent_);
-  ContextPtr parent_;
-
+  VISIT_FROM(ObjectPtr, parent)
+  POINTER_FIELD(ContextPtr, parent)
   // Variable length data follows here.
-  ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
-  ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  VARIABLE_POINTER_FIELDS(ObjectPtr, element, data)
   VISIT_TO_LENGTH(ObjectPtr, &data()[length - 1]);
 
   friend class Object;
@@ -1968,9 +2052,9 @@
 
 class SingleTargetCacheLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache);
-  VISIT_FROM(ObjectPtr, target_);
-  CodePtr target_;
-  VISIT_TO(ObjectPtr, target_);
+  VISIT_FROM(ObjectPtr, target)
+  POINTER_FIELD(CodePtr, target)
+  VISIT_TO(ObjectPtr, target)
   uword entry_point_;
   ClassIdTagType lower_limit_;
   ClassIdTagType upper_limit_;
@@ -1978,9 +2062,10 @@
 
 class MonomorphicSmiableCallLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MonomorphicSmiableCall);
-  VISIT_FROM(ObjectPtr, target_);
-  CodePtr target_;  // Entrypoint PC in bare mode, Code in non-bare mode.
-  VISIT_TO(ObjectPtr, target_);
+  VISIT_FROM(ObjectPtr, target)
+  POINTER_FIELD(CodePtr,
+                target);  // Entrypoint PC in bare mode, Code in non-bare mode.
+  VISIT_TO(ObjectPtr, target)
   uword expected_cid_;
   uword entrypoint_;
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
@@ -1989,18 +2074,18 @@
 // Abstract base class for RawICData/RawMegamorphicCache
 class CallSiteDataLayout : public ObjectLayout {
  protected:
-  StringPtr target_name_;  // Name of target function.
+  POINTER_FIELD(StringPtr, target_name);  // Name of target function.
   // arg_descriptor in RawICData and in RawMegamorphicCache should be
   // in the same position so that NoSuchMethod can access it.
-  ArrayPtr args_descriptor_;  // Arguments descriptor.
+  POINTER_FIELD(ArrayPtr, args_descriptor);  // Arguments descriptor.
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(CallSiteData)
 };
 
 class UnlinkedCallLayout : public CallSiteDataLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall);
-  VISIT_FROM(ObjectPtr, target_name_);
-  VISIT_TO(ObjectPtr, args_descriptor_);
+  VISIT_FROM(ObjectPtr, target_name)
+  VISIT_TO(ObjectPtr, args_descriptor)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   bool can_patch_to_monomorphic_;
@@ -2008,12 +2093,13 @@
 
 class ICDataLayout : public CallSiteDataLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ICData);
-  VISIT_FROM(ObjectPtr, target_name_);
-  ArrayPtr entries_;  // Contains class-ids, target and count.
+  VISIT_FROM(ObjectPtr, target_name)
+  POINTER_FIELD(ArrayPtr, entries)  // Contains class-ids, target and count.
   // Static type of the receiver, if instance call and available.
-  NOT_IN_PRECOMPILED(AbstractTypePtr receivers_static_type_);
-  ObjectPtr owner_;  // Parent/calling function or original IC of cloned IC.
-  VISIT_TO(ObjectPtr, owner_);
+  NOT_IN_PRECOMPILED(POINTER_FIELD(AbstractTypePtr, receivers_static_type))
+  POINTER_FIELD(ObjectPtr,
+                owner)  // Parent/calling function or original IC of cloned IC.
+  VISIT_TO(ObjectPtr, owner)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
@@ -2036,10 +2122,11 @@
 
 class MegamorphicCacheLayout : public CallSiteDataLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MegamorphicCache);
-  VISIT_FROM(ObjectPtr, target_name_)
-  ArrayPtr buckets_;
-  SmiPtr mask_;
-  VISIT_TO(ObjectPtr, mask_)
+
+  VISIT_FROM(ObjectPtr, target_name)
+  POINTER_FIELD(ArrayPtr, buckets)
+  SMI_FIELD(SmiPtr, mask)
+  VISIT_TO(ObjectPtr, mask)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   int32_t filled_entry_count_;
@@ -2047,17 +2134,19 @@
 
 class SubtypeTestCacheLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(SubtypeTestCache);
-  VISIT_FROM(ObjectPtr, cache_);
-  ArrayPtr cache_;
-  VISIT_TO(ObjectPtr, cache_);
+
+  VISIT_FROM(ObjectPtr, cache)
+  POINTER_FIELD(ArrayPtr, cache)
+  VISIT_TO(ObjectPtr, cache)
 };
 
 class LoadingUnitLayout : public ObjectLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LoadingUnit);
-  VISIT_FROM(ObjectPtr, parent_);
-  LoadingUnitPtr parent_;
-  ArrayPtr base_objects_;
-  VISIT_TO(ObjectPtr, base_objects_);
+
+  VISIT_FROM(ObjectPtr, parent)
+  POINTER_FIELD(LoadingUnitPtr, parent)
+  POINTER_FIELD(ArrayPtr, base_objects)
+  VISIT_TO(ObjectPtr, base_objects)
   int32_t id_;
   bool load_outstanding_;
   bool loaded_;
@@ -2070,20 +2159,21 @@
 class ApiErrorLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ApiError);
 
-  VISIT_FROM(ObjectPtr, message_)
-  StringPtr message_;
-  VISIT_TO(ObjectPtr, message_)
+  VISIT_FROM(ObjectPtr, message)
+  POINTER_FIELD(StringPtr, message)
+  VISIT_TO(ObjectPtr, message)
 };
 
 class LanguageErrorLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LanguageError);
 
-  VISIT_FROM(ObjectPtr, previous_error_)
-  ErrorPtr previous_error_;  // May be null.
-  ScriptPtr script_;
-  StringPtr message_;
-  StringPtr formatted_message_;  // Incl. previous error's formatted message.
-  VISIT_TO(ObjectPtr, formatted_message_)
+  VISIT_FROM(ObjectPtr, previous_error)
+  POINTER_FIELD(ErrorPtr, previous_error)  // May be null.
+  POINTER_FIELD(ScriptPtr, script)
+  POINTER_FIELD(StringPtr, message)
+  POINTER_FIELD(StringPtr,
+                formatted_message)  // Incl. previous error's formatted message.
+  VISIT_TO(ObjectPtr, formatted_message)
   TokenPosition token_pos_;  // Source position in script_.
   bool report_after_token_;  // Report message at or after the token.
   int8_t kind_;              // Of type Report::Kind.
@@ -2094,19 +2184,19 @@
 class UnhandledExceptionLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnhandledException);
 
-  VISIT_FROM(ObjectPtr, exception_)
-  InstancePtr exception_;
-  InstancePtr stacktrace_;
-  VISIT_TO(ObjectPtr, stacktrace_)
+  VISIT_FROM(ObjectPtr, exception)
+  POINTER_FIELD(InstancePtr, exception)
+  POINTER_FIELD(InstancePtr, stacktrace)
+  VISIT_TO(ObjectPtr, stacktrace)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
 class UnwindErrorLayout : public ErrorLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnwindError);
 
-  VISIT_FROM(ObjectPtr, message_)
-  StringPtr message_;
-  VISIT_TO(ObjectPtr, message_)
+  VISIT_FROM(ObjectPtr, message)
+  POINTER_FIELD(StringPtr, message)
+  VISIT_TO(ObjectPtr, message)
   bool is_user_initiated_;
 };
 
@@ -2117,11 +2207,11 @@
 class LibraryPrefixLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix);
 
-  VISIT_FROM(ObjectPtr, name_)
-  StringPtr name_;       // Library prefix name.
-  ArrayPtr imports_;     // Libraries imported with this prefix.
-  LibraryPtr importer_;  // Library which declares this prefix.
-  VISIT_TO(ObjectPtr, importer_)
+  VISIT_FROM(ObjectPtr, name)
+  POINTER_FIELD(StringPtr, name)       // Library prefix name.
+  POINTER_FIELD(ArrayPtr, imports)     // Libraries imported with this prefix.
+  POINTER_FIELD(LibraryPtr, importer)  // Library which declares this prefix.
+  VISIT_TO(ObjectPtr, importer)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
@@ -2147,20 +2237,15 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeArguments);
 
-  VISIT_FROM(ObjectPtr, instantiations_)
+  VISIT_FROM(ObjectPtr, instantiations)
   // The instantiations_ array remains empty for instantiated type arguments.
-  ArrayPtr instantiations_;  // Of 3-tuple: 2 instantiators, result.
-  SmiPtr length_;
-  SmiPtr hash_;
-  SmiPtr nullability_;
-
+  POINTER_FIELD(ArrayPtr,
+                instantiations)  // Of 3-tuple: 2 instantiators, result.
+  SMI_FIELD(SmiPtr, length)
+  SMI_FIELD(SmiPtr, hash)
+  SMI_FIELD(SmiPtr, nullability)
   // Variable length data follows here.
-  AbstractTypePtr const* types() const {
-    OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
-  }
-  AbstractTypePtr* types() {
-    OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
-  }
+  VARIABLE_POINTER_FIELDS(AbstractTypePtr, element, types)
   ObjectPtr* to(intptr_t length) {
     return reinterpret_cast<ObjectPtr*>(&types()[length - 1]);
   }
@@ -2183,8 +2268,10 @@
   static constexpr intptr_t kTypeStateBitSize = 2;
 
   uword type_test_stub_entry_point_;  // Accessed from generated code.
-  CodePtr type_test_stub_;  // Must be the last field, since subclasses use it
-                            // in their VISIT_FROM.
+  POINTER_FIELD(
+      CodePtr,
+      type_test_stub)  // Must be the last field, since subclasses use it
+                       // in their VISIT_FROM.
 
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
@@ -2197,14 +2284,15 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
-  VISIT_FROM(ObjectPtr, type_test_stub_)
-  SmiPtr type_class_id_;
-  TypeArgumentsPtr arguments_;
-  SmiPtr hash_;
+  VISIT_FROM(ObjectPtr, type_test_stub)
+  POINTER_FIELD(SmiPtr, type_class_id)
+  POINTER_FIELD(TypeArgumentsPtr, arguments)
+  POINTER_FIELD(SmiPtr, hash)
   // This type object represents a function type if its signature field is a
   // non-null function object.
-  FunctionPtr signature_;  // If not null, this type is a function type.
-  VISIT_TO(ObjectPtr, signature_)
+  POINTER_FIELD(FunctionPtr,
+                signature)  // If not null, this type is a function type.
+  VISIT_TO(ObjectPtr, signature)
   TokenPosition token_pos_;
   int8_t type_state_;
   int8_t nullability_;
@@ -2219,9 +2307,9 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
 
-  VISIT_FROM(ObjectPtr, type_test_stub_)
-  AbstractTypePtr type_;  // The referenced type.
-  VISIT_TO(ObjectPtr, type_)
+  VISIT_FROM(ObjectPtr, type_test_stub)
+  POINTER_FIELD(AbstractTypePtr, type)  // The referenced type.
+  VISIT_TO(ObjectPtr, type)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
@@ -2229,17 +2317,18 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
 
-  VISIT_FROM(ObjectPtr, type_test_stub_)
-  StringPtr name_;
-  SmiPtr hash_;
-  AbstractTypePtr bound_;  // ObjectType if no explicit bound specified.
+  VISIT_FROM(ObjectPtr, type_test_stub)
+  POINTER_FIELD(StringPtr, name)
+  POINTER_FIELD(SmiPtr, hash)
+  POINTER_FIELD(AbstractTypePtr,
+                bound)  // ObjectType if no explicit bound specified.
   // The instantiation to bounds of this parameter as calculated by the CFE.
   //
   // TODO(dartbug.com/43901): Once a separate TypeParameters class has been
   // added, move these there and remove them from TypeParameter objects.
-  AbstractTypePtr default_argument_;
-  FunctionPtr parameterized_function_;
-  VISIT_TO(ObjectPtr, parameterized_function_)
+  POINTER_FIELD(AbstractTypePtr, default_argument)
+  POINTER_FIELD(FunctionPtr, parameterized_function)
+  VISIT_TO(ObjectPtr, parameterized_function)
   ClassIdTagType parameterized_class_id_;
   TokenPosition token_pos_;
   int16_t index_;
@@ -2269,15 +2358,15 @@
 
   // The following fields are also declared in the Dart source of class
   // _Closure.
-  VISIT_FROM(RawCompressed, instantiator_type_arguments_)
-  TypeArgumentsPtr instantiator_type_arguments_;
-  TypeArgumentsPtr function_type_arguments_;
-  TypeArgumentsPtr delayed_type_arguments_;
-  FunctionPtr function_;
-  ContextPtr context_;
-  SmiPtr hash_;
+  VISIT_FROM(RawCompressed, instantiator_type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, instantiator_type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, function_type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, delayed_type_arguments)
+  POINTER_FIELD(FunctionPtr, function)
+  POINTER_FIELD(ContextPtr, context)
+  POINTER_FIELD(SmiPtr, hash)
 
-  VISIT_TO(RawCompressed, hash_)
+  VISIT_TO(RawCompressed, hash)
 
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
@@ -2346,13 +2435,13 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(String);
 
  protected:
-  VISIT_FROM(ObjectPtr, length_)
-  SmiPtr length_;
+  VISIT_FROM(ObjectPtr, length)
+  SMI_FIELD(SmiPtr, length)
 #if !defined(HASH_IN_OBJECT_HEADER)
-  SmiPtr hash_;
-  VISIT_TO(ObjectPtr, hash_)
+  SMI_FIELD(SmiPtr, hash)
+  VISIT_TO(ObjectPtr, hash)
 #else
-  VISIT_TO(ObjectPtr, length_)
+  VISIT_TO(ObjectPtr, length)
 #endif
 
  private:
@@ -2421,7 +2510,7 @@
  protected:
   // The length of the view in element sizes (obtainable via
   // [TypedDataBase::ElementSizeInBytes]).
-  SmiPtr length_;
+  SMI_FIELD(SmiPtr, length);
 
  private:
   friend class TypedDataViewLayout;
@@ -2440,7 +2529,7 @@
   void RecomputeDataField() { data_ = internal_data(); }
 
  protected:
-  VISIT_FROM(RawCompressed, length_)
+  VISIT_FROM(RawCompressed, length)
   VISIT_TO_LENGTH(RawCompressed, &length_)
 
   // Variable length data follows here.
@@ -2476,7 +2565,7 @@
   // Recompute [data_] based on internal/external [typed_data_].
   void RecomputeDataField() {
     const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
-    uint8_t* payload = typed_data_->ptr()->data_;
+    uint8_t* payload = typed_data()->ptr()->data_;
     data_ = payload + offset_in_bytes;
   }
 
@@ -2489,12 +2578,12 @@
   void RecomputeDataFieldForInternalTypedData() {
     const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
     uint8_t* payload = reinterpret_cast<uint8_t*>(
-        ObjectLayout::ToAddr(typed_data_) + TypedDataLayout::payload_offset());
+        ObjectLayout::ToAddr(typed_data()) + TypedDataLayout::payload_offset());
     data_ = payload + offset_in_bytes;
   }
 
   void ValidateInnerPointer() {
-    if (typed_data_->ptr()->GetClassId() == kNullCid) {
+    if (typed_data()->ptr()->GetClassId() == kNullCid) {
       // The view object must have gotten just initialized.
       if (data_ != nullptr || RawSmiValue(offset_in_bytes_) != 0 ||
           RawSmiValue(length_) != 0) {
@@ -2502,7 +2591,7 @@
       }
     } else {
       const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
-      uint8_t* payload = typed_data_->ptr()->data_;
+      uint8_t* payload = typed_data()->ptr()->data_;
       if ((payload + offset_in_bytes) != data_) {
         FATAL("RawTypedDataView has invalid inner pointer.");
       }
@@ -2510,10 +2599,10 @@
   }
 
  protected:
-  VISIT_FROM(ObjectPtr, length_)
-  TypedDataBasePtr typed_data_;
-  SmiPtr offset_in_bytes_;
-  VISIT_TO(ObjectPtr, offset_in_bytes_)
+  VISIT_FROM(ObjectPtr, length)
+  POINTER_FIELD(TypedDataBasePtr, typed_data)
+  SMI_FIELD(SmiPtr, offset_in_bytes)
+  VISIT_TO(ObjectPtr, offset_in_bytes)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class Api;
@@ -2557,12 +2646,11 @@
 class ArrayLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Array);
 
-  VISIT_FROM(RawCompressed, type_arguments_)
-  TypeArgumentsPtr type_arguments_;
-  SmiPtr length_;
+  VISIT_FROM(RawCompressed, type_arguments)
+  ARRAY_POINTER_FIELD(TypeArgumentsPtr, type_arguments)
+  SMI_FIELD(SmiPtr, length)
   // Variable length data follows here.
-  ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
-  ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  VARIABLE_POINTER_FIELDS(ObjectPtr, element, data)
   VISIT_TO_LENGTH(RawCompressed, &data()[length - 1])
 
   friend class LinkedHashMapSerializationCluster;
@@ -2593,11 +2681,11 @@
 class GrowableObjectArrayLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(GrowableObjectArray);
 
-  VISIT_FROM(RawCompressed, type_arguments_)
-  TypeArgumentsPtr type_arguments_;
-  SmiPtr length_;
-  ArrayPtr data_;
-  VISIT_TO(RawCompressed, data_)
+  VISIT_FROM(RawCompressed, type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, type_arguments)
+  SMI_FIELD(SmiPtr, length)
+  POINTER_FIELD(ArrayPtr, data)
+  VISIT_TO(RawCompressed, data)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class SnapshotReader;
@@ -2607,14 +2695,14 @@
 class LinkedHashMapLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LinkedHashMap);
 
-  VISIT_FROM(RawCompressed, type_arguments_)
-  TypeArgumentsPtr type_arguments_;
-  TypedDataPtr index_;
-  SmiPtr hash_mask_;
-  ArrayPtr data_;
-  SmiPtr used_data_;
-  SmiPtr deleted_keys_;
-  VISIT_TO(RawCompressed, deleted_keys_)
+  VISIT_FROM(RawCompressed, type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, type_arguments)
+  POINTER_FIELD(TypedDataPtr, index)
+  POINTER_FIELD(SmiPtr, hash_mask)
+  POINTER_FIELD(ArrayPtr, data)
+  POINTER_FIELD(SmiPtr, used_data)
+  POINTER_FIELD(SmiPtr, deleted_keys)
+  VISIT_TO(RawCompressed, deleted_keys)
 
   friend class SnapshotReader;
 };
@@ -2682,16 +2770,16 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData);
 
  protected:
-  VISIT_FROM(RawCompressed, length_)
-  VISIT_TO(RawCompressed, length_)
+  VISIT_FROM(RawCompressed, length)
+  VISIT_TO(RawCompressed, length)
 };
 
 class PointerLayout : public PointerBaseLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
 
-  VISIT_FROM(RawCompressed, type_arguments_)
-  TypeArgumentsPtr type_arguments_;
-  VISIT_TO(RawCompressed, type_arguments_)
+  VISIT_FROM(RawCompressed, type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, type_arguments)
+  VISIT_TO(RawCompressed, type_arguments)
 
   friend class Pointer;
 };
@@ -2723,15 +2811,15 @@
 class ReceivePortLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ReceivePort);
 
-  VISIT_FROM(ObjectPtr, send_port_)
-  SendPortPtr send_port_;
-  InstancePtr handler_;
+  VISIT_FROM(ObjectPtr, send_port)
+  POINTER_FIELD(SendPortPtr, send_port)
+  POINTER_FIELD(InstancePtr, handler)
 #if !defined(PRODUCT)
-  StringPtr debug_name_;
-  StackTracePtr allocation_location_;
-  VISIT_TO(ObjectPtr, allocation_location_)
+  POINTER_FIELD(StringPtr, debug_name)
+  POINTER_FIELD(StackTracePtr, allocation_location)
+  VISIT_TO(ObjectPtr, allocation_location)
 #else
-  VISIT_TO(ObjectPtr, handler_);
+  VISIT_TO(ObjectPtr, handler)
 #endif  // !defined(PRODUCT)
 };
 
@@ -2747,11 +2835,13 @@
 class StackTraceLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(StackTrace);
 
-  VISIT_FROM(ObjectPtr, async_link_)
-  StackTracePtr async_link_;  // Link to parent async stack trace.
-  ArrayPtr code_array_;       // Code object for each frame in the stack trace.
-  ArrayPtr pc_offset_array_;  // Offset of PC for each frame.
-  VISIT_TO(ObjectPtr, pc_offset_array_)
+  VISIT_FROM(ObjectPtr, async_link)
+  POINTER_FIELD(StackTracePtr,
+                async_link);  // Link to parent async stack trace.
+  POINTER_FIELD(ArrayPtr,
+                code_array);  // Code object for each frame in the stack trace.
+  POINTER_FIELD(ArrayPtr, pc_offset_array);  // Offset of PC for each frame.
+  VISIT_TO(ObjectPtr, pc_offset_array)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // False for pre-allocated stack trace (used in OOM and Stack overflow).
@@ -2766,31 +2856,19 @@
 class RegExpLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(RegExp);
 
-  VISIT_FROM(ObjectPtr, num_bracket_expressions_)
-  SmiPtr num_bracket_expressions_;
-  ArrayPtr capture_name_map_;
-  StringPtr pattern_;  // Pattern to be used for matching.
-  union {
-    FunctionPtr function_;
-    TypedDataPtr bytecode_;
-  } one_byte_;
-  union {
-    FunctionPtr function_;
-    TypedDataPtr bytecode_;
-  } two_byte_;
-  FunctionPtr external_one_byte_function_;
-  FunctionPtr external_two_byte_function_;
-  union {
-    FunctionPtr function_;
-    TypedDataPtr bytecode_;
-  } one_byte_sticky_;
-  union {
-    FunctionPtr function_;
-    TypedDataPtr bytecode_;
-  } two_byte_sticky_;
-  FunctionPtr external_one_byte_sticky_function_;
-  FunctionPtr external_two_byte_sticky_function_;
-  VISIT_TO(ObjectPtr, external_two_byte_sticky_function_)
+  VISIT_FROM(ObjectPtr, num_bracket_expressions)
+  POINTER_FIELD(SmiPtr, num_bracket_expressions)
+  POINTER_FIELD(ArrayPtr, capture_name_map)
+  POINTER_FIELD(StringPtr, pattern)   // Pattern to be used for matching.
+  POINTER_FIELD(ObjectPtr, one_byte)  // FunctionPtr or TypedDataPtr
+  POINTER_FIELD(ObjectPtr, two_byte)
+  POINTER_FIELD(ObjectPtr, external_one_byte)
+  POINTER_FIELD(ObjectPtr, external_two_byte)
+  POINTER_FIELD(ObjectPtr, one_byte_sticky)
+  POINTER_FIELD(ObjectPtr, two_byte_sticky)
+  POINTER_FIELD(ObjectPtr, external_one_byte_sticky)
+  POINTER_FIELD(ObjectPtr, external_two_byte_sticky)
+  VISIT_TO(ObjectPtr, external_two_byte_sticky)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // The same pattern may use different amount of registers if compiled
@@ -2810,15 +2888,15 @@
 class WeakPropertyLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(WeakProperty);
 
-  VISIT_FROM(ObjectPtr, key_)
-  ObjectPtr key_;
-  ObjectPtr value_;
-  VISIT_TO(ObjectPtr, value_)
+  VISIT_FROM(ObjectPtr, key)
+  POINTER_FIELD(ObjectPtr, key)
+  POINTER_FIELD(ObjectPtr, value)
+  VISIT_TO(ObjectPtr, value)
   ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
-  // Linked list is chaining all pending weak properties.
-  // Untyped to make it clear that it is not to be visited by GC.
-  uword next_;
+  // Linked list is chaining all pending weak properties. Not visited by
+  // pointer visitors.
+  WeakPropertyPtr next_;
 
   friend class GCMarker;
   template <bool>
@@ -2833,18 +2911,18 @@
 class MirrorReferenceLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MirrorReference);
 
-  VISIT_FROM(ObjectPtr, referent_)
-  ObjectPtr referent_;
-  VISIT_TO(ObjectPtr, referent_)
+  VISIT_FROM(ObjectPtr, referent)
+  POINTER_FIELD(ObjectPtr, referent)
+  VISIT_TO(ObjectPtr, referent)
 };
 
 // UserTag are used by the profiler to track Dart script state.
 class UserTagLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UserTag);
 
-  VISIT_FROM(ObjectPtr, label_)
-  StringPtr label_;
-  VISIT_TO(ObjectPtr, label_)
+  VISIT_FROM(ObjectPtr, label)
+  POINTER_FIELD(StringPtr, label)
+  VISIT_TO(ObjectPtr, label)
 
   // Isolate unique tag.
   uword tag_;
@@ -2859,9 +2937,9 @@
 class FutureOrLayout : public InstanceLayout {
   RAW_HEAP_OBJECT_IMPLEMENTATION(FutureOr);
 
-  VISIT_FROM(RawCompressed, type_arguments_)
-  TypeArgumentsPtr type_arguments_;
-  VISIT_TO(RawCompressed, type_arguments_)
+  VISIT_FROM(RawCompressed, type_arguments)
+  POINTER_FIELD(TypeArgumentsPtr, type_arguments)
+  VISIT_TO(RawCompressed, type_arguments)
 
   friend class SnapshotReader;
 };
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index d810d3d..103611e 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -47,9 +47,6 @@
   F(ClosureData, closure_)                                                     \
   F(SignatureData, parent_function_)                                           \
   F(SignatureData, signature_type_)                                            \
-  F(RedirectionData, type_)                                                    \
-  F(RedirectionData, identifier_)                                              \
-  F(RedirectionData, target_)                                                  \
   F(Field, name_)                                                              \
   F(Field, owner_)                                                             \
   F(Field, type_)                                                              \
@@ -78,10 +75,10 @@
   F(Library, resolved_names_)                                                  \
   F(Library, exported_names_)                                                  \
   F(Library, loaded_scripts_)                                                  \
-  F(Namespace, library_)                                                       \
+  F(Namespace, target_)                                                        \
   F(Namespace, show_names_)                                                    \
   F(Namespace, hide_names_)                                                    \
-  F(Namespace, metadata_field_)                                                \
+  F(Namespace, owner_)                                                         \
   F(KernelProgramInfo, string_offsets_)                                        \
   F(KernelProgramInfo, string_data_)                                           \
   F(KernelProgramInfo, canonical_names_)                                       \
@@ -155,7 +152,6 @@
   F(Closure, context_)                                                         \
   F(Closure, hash_)                                                            \
   F(String, length_)                                                           \
-  F(String, hash_)                                                             \
   F(Array, type_arguments_)                                                    \
   F(Array, length_)                                                            \
   F(GrowableObjectArray, type_arguments_)                                      \
@@ -177,10 +173,14 @@
   F(RegExp, num_bracket_expressions_)                                          \
   F(RegExp, capture_name_map_)                                                 \
   F(RegExp, pattern_)                                                          \
-  F(RegExp, external_one_byte_function_)                                       \
-  F(RegExp, external_two_byte_function_)                                       \
-  F(RegExp, external_one_byte_sticky_function_)                                \
-  F(RegExp, external_two_byte_sticky_function_)                                \
+  F(RegExp, one_byte_)                                                         \
+  F(RegExp, two_byte_)                                                         \
+  F(RegExp, external_one_byte_)                                                \
+  F(RegExp, external_two_byte_)                                                \
+  F(RegExp, one_byte_sticky_)                                                  \
+  F(RegExp, two_byte_sticky_)                                                  \
+  F(RegExp, external_one_byte_sticky_)                                         \
+  F(RegExp, external_two_byte_sticky_)                                         \
   F(WeakProperty, key_)                                                        \
   F(WeakProperty, value_)                                                      \
   F(MirrorReference, referent_)                                                \
@@ -205,7 +205,6 @@
   F(Code, static_calls_target_table_)                                          \
   F(ICData, receivers_static_type_)                                            \
   F(Function, unoptimized_code_)                                               \
-  F(Field, saved_initial_value_)                                               \
   F(Field, type_test_cache_)                                                   \
   F(WeakSerializationReference, target_)
 
@@ -213,6 +212,8 @@
   F(ReceivePort, debug_name_)                                                  \
   F(ReceivePort, allocation_location_)
 
+#define NON_HEADER_HASH_CLASSES_AND_FIELDS(F) F(String, hash_)
+
 OffsetsTable::OffsetsTable(Zone* zone) : cached_offsets_(zone) {
   for (intptr_t i = 0; offsets_table[i].class_id != -1; ++i) {
     OffsetsTableEntry entry = offsets_table[i];
@@ -236,6 +237,10 @@
     NON_PRODUCT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
 #endif
 
+#if !defined(HASH_IN_OBJECT_HEADER)
+    NON_HEADER_HASH_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
+#endif
+
 #if defined(DART_PRECOMPILED_RUNTIME)
     AOT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
 #else
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 4b011d9..853c1cac 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -61,7 +61,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   if (writer->can_send_any_object() ||
-      writer->AllowObjectsInDartLibrary(library_)) {
+      writer->AllowObjectsInDartLibrary(library())) {
     writer->WriteClassId(this);
   } else {
     // We do not allow regular dart instances in isolate messages.
@@ -122,7 +122,7 @@
                          bool as_reference) {
   ASSERT(writer != NULL);
 
-  if (signature_ != Function::null()) {
+  if (signature() != Function::null()) {
     writer->SetWriteException(Exceptions::kArgument,
                               "Illegal argument in isolate message"
                               " : (function types are not supported yet)");
@@ -132,7 +132,7 @@
   // Only resolved and finalized types should be written to a snapshot.
   ASSERT((type_state_ == TypeLayout::kFinalizedInstantiated) ||
          (type_state_ == TypeLayout::kFinalizedUninstantiated));
-  ASSERT(type_class_id_ != Object::null());
+  ASSERT(type_class_id() != Object::null());
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -141,13 +141,13 @@
   writer->WriteIndexedObject(kTypeCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  if (type_class_id_->IsHeapObject()) {
+  if (type_class_id()->IsHeapObject()) {
     // Type class is still an unresolved class.
     UNREACHABLE();
   }
 
   // Lookup the type class.
-  SmiPtr raw_type_class_id = Smi::RawCast(type_class_id_);
+  SmiPtr raw_type_class_id = Smi::RawCast(type_class_id());
   ClassPtr type_class =
       writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
 
@@ -167,7 +167,7 @@
   writer->Write<uint8_t>(combined);
 
   // Write out all the object pointer fields.
-  ASSERT(type_class_id_ != Object::null());
+  ASSERT(type_class_id() != Object::null());
   SnapshotWriterVisitor visitor(writer, as_reference);
   visitor.VisitPointers(from(), to());
 
@@ -297,13 +297,13 @@
   visitor.VisitPointers(from(), to());
 
   if (parameterized_class_id_ != kFunctionCid) {
-    ASSERT(parameterized_function_ == Function::null());
+    ASSERT(parameterized_function() == Function::null());
     // Write out the parameterized class.
     ClassPtr param_class =
         writer->isolate()->class_table()->At(parameterized_class_id_);
     writer->WriteObjectImpl(param_class, kAsReference);
   } else {
-    ASSERT(parameterized_function_ != Function::null());
+    ASSERT(parameterized_function() != Function::null());
   }
 }
 
@@ -353,10 +353,10 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the length field.
-  writer->Write<ObjectPtr>(length_);
+  writer->Write<ObjectPtr>(length());
 
   // Write out the individual types.
-  intptr_t len = Smi::Value(length_);
+  intptr_t len = Smi::Value(length());
   for (intptr_t i = 0; i < len; i++) {
     // The Dart VM reuses type argument lists across instances in order
     // to reduce memory footprint, this can sometimes lead to a type from
@@ -366,10 +366,10 @@
     if (!writer->can_send_any_object()) {
       // Lookup the type class.
       TypePtr raw_type = Type::RawCast(types()[i]);
-      SmiPtr raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id_);
+      SmiPtr raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id());
       ClassPtr type_class =
           writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
-      if (!writer->AllowObjectsInDartLibrary(type_class->ptr()->library_)) {
+      if (!writer->AllowObjectsInDartLibrary(type_class->ptr()->library())) {
         writer->WriteVMIsolateObject(kDynamicType);
       } else {
         writer->WriteObjectImpl(types()[i], as_reference);
@@ -400,7 +400,7 @@
   FunctionPtr func = writer->IsSerializableClosure(ClosurePtr(this));
   if (func != Function::null()) {
     writer->WriteStaticImplicitClosure(
-        object_id, func, writer->GetObjectTags(this), delayed_type_arguments_);
+        object_id, func, writer->GetObjectTags(this), delayed_type_arguments());
     return;
   }
 
@@ -567,7 +567,6 @@
 MESSAGE_SNAPSHOT_UNREACHABLE(ObjectPool);
 MESSAGE_SNAPSHOT_UNREACHABLE(PatchClass);
 MESSAGE_SNAPSHOT_UNREACHABLE(PcDescriptors);
-MESSAGE_SNAPSHOT_UNREACHABLE(RedirectionData);
 MESSAGE_SNAPSHOT_UNREACHABLE(Script);
 MESSAGE_SNAPSHOT_UNREACHABLE(SignatureData);
 MESSAGE_SNAPSHOT_UNREACHABLE(SingleTargetCache);
@@ -934,7 +933,7 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   StringWriteTo(writer, object_id, kind, kOneByteStringCid,
-                writer->GetObjectTags(this), length_, data());
+                writer->GetObjectTags(this), length(), data());
 }
 
 void TwoByteStringLayout::WriteTo(SnapshotWriter* writer,
@@ -942,7 +941,7 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
-                writer->GetObjectTags(this), length_, data());
+                writer->GetObjectTags(this), length(), data());
 }
 
 ExternalOneByteStringPtr ExternalOneByteString::ReadFrom(SnapshotReader* reader,
@@ -969,7 +968,7 @@
                                           bool as_reference) {
   // Serialize as a non-external one byte string.
   StringWriteTo(writer, object_id, kind, kOneByteStringCid,
-                writer->GetObjectTags(this), length_, external_data_);
+                writer->GetObjectTags(this), length(), external_data_);
 }
 
 void ExternalTwoByteStringLayout::WriteTo(SnapshotWriter* writer,
@@ -978,7 +977,7 @@
                                           bool as_reference) {
   // Serialize as a non-external two byte string.
   StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
-                writer->GetObjectTags(this), length_, external_data_);
+                writer->GetObjectTags(this), length(), external_data_);
 }
 
 ArrayPtr Array::ReadFrom(SnapshotReader* reader,
@@ -1047,7 +1046,7 @@
                           bool as_reference) {
   ASSERT(!this->IsCanonical());
   writer->ArrayWriteTo(object_id, kArrayCid, writer->GetObjectTags(this),
-                       length_, type_arguments_, data(), as_reference);
+                       length(), type_arguments(), data(), as_reference);
 }
 
 void ImmutableArrayLayout::WriteTo(SnapshotWriter* writer,
@@ -1461,9 +1460,6 @@
     writer->Write<ObjectPtr>(length_);
     uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     void* passed_data = malloc(bytes);
-    if (passed_data == NULL) {
-      OUT_OF_MEMORY();
-    }
     memmove(passed_data, data, bytes);
     static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
         bytes,
@@ -1546,9 +1542,6 @@
   writer->Write<ObjectPtr>(length_);
   uint8_t* data = reinterpret_cast<uint8_t*>(data_);
   void* passed_data = malloc(bytes);
-  if (passed_data == NULL) {
-    OUT_OF_MEMORY();
-  }
   memmove(passed_data, data, bytes);
   static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
       bytes,
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 0111496..003ceb7 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -166,7 +166,7 @@
   char_in_capture_ = Local(Symbols::char_in_capture());
   char_in_match_ = Local(Symbols::char_in_match());
   index_temp_ = Local(Symbols::index_temp());
-  result_ = Local(Symbols::result());
+  result_ = Local(Symbols::c_result());
 
   string_param_ = Parameter(Symbols::string_param(),
                             RegExpMacroAssembler::kParamStringIndex);
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 0b4ceb7..23f05e8 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -556,21 +556,35 @@
   }
   const Function& function =
       Function::Handle(caller_frame->LookupDartFunction());
-  OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString());
+  if (function.IsInvokeFieldDispatcher() ||
+      function.IsNoSuchMethodDispatcher()) {
+    const auto& args_desc_array = Array::Handle(function.saved_args_desc());
+    const ArgumentsDescriptor args_desc(args_desc_array);
+    OS::PrintErr(" -> Function %s [%s]\n", function.ToFullyQualifiedCString(),
+                 args_desc.ToCString());
+  } else {
+    OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString());
+  }
 }
 
-// This updates the type test cache, an array containing 5-value elements
-// (instance class (or function if the instance is a closure), instance type
-// arguments, instantiator type arguments, function type arguments,
-// and test_result). It can be applied to classes with type arguments in which
-// case it contains just the result of the class subtype test, not including the
-// evaluation of type arguments.
+// This updates the type test cache, an array containing 8 elements:
+// - instance class (or function if the instance is a closure)
+// - instance type arguments (null if the instance class is not generic)
+// - instantiator type arguments (null if the type is instantiated)
+// - function type arguments (null if the type is instantiated)
+// - instance parent function type arguments (null if instance is not a closure)
+// - instance delayed type arguments (null if instance is not a closure)
+// - destination type (null if the type was known at compile time)
+// - test result
+// It can be applied to classes with type arguments in which case it contains
+// just the result of the class subtype test, not including the evaluation of
+// type arguments.
 // This operation is currently very slow (lookup of code is not efficient yet).
 static void UpdateTypeTestCache(
     Zone* zone,
     Thread* thread,
     const Instance& instance,
-    const AbstractType& type,
+    const AbstractType& destination_type,
     const TypeArguments& instantiator_type_arguments,
     const TypeArguments& function_type_arguments,
     const Bool& result,
@@ -604,6 +618,32 @@
       instance_type_arguments = instance.GetTypeArguments();
     }
   }
+  if (FLAG_trace_type_checks) {
+    const auto& instance_class_name =
+        String::Handle(zone, instance_class.Name());
+    TextBuffer buffer(256);
+    buffer.Printf("  Updating test cache %#" Px " with result %s for:\n",
+                  static_cast<uword>(new_cache.raw()), result.ToCString());
+    if (instance.IsString()) {
+      buffer.Printf("    instance: '%s'\n", instance.ToCString());
+    } else {
+      buffer.Printf("    instance: %s\n", instance.ToCString());
+    }
+    buffer.Printf("    class: %s (%" Pd ")\n", instance_class_name.ToCString(),
+                  instance_class.id());
+    buffer.Printf(
+        "    raw entry: [ %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px
+        ", %#" Px ", %#" Px ", %#" Px " ]\n",
+        static_cast<uword>(instance_class_id_or_function.raw()),
+        static_cast<uword>(destination_type.raw()),
+        static_cast<uword>(instance_type_arguments.raw()),
+        static_cast<uword>(instantiator_type_arguments.raw()),
+        static_cast<uword>(function_type_arguments.raw()),
+        static_cast<uword>(instance_parent_function_type_arguments.raw()),
+        static_cast<uword>(instance_delayed_type_arguments.raw()),
+        static_cast<uword>(result.raw()));
+    OS::PrintErr("%s", buffer.buffer());
+  }
   {
     SafepointMutexLocker ml(
         thread->isolate_group()->subtype_test_cache_mutex());
@@ -627,82 +667,45 @@
            instance_parent_function_type_arguments.IsCanonical());
     ASSERT(instance_delayed_type_arguments.IsNull() ||
            instance_delayed_type_arguments.IsCanonical());
-    auto& last_instance_class_id_or_function = Object::Handle(zone);
-    auto& last_instance_type_arguments = TypeArguments::Handle(zone);
-    auto& last_instantiator_type_arguments = TypeArguments::Handle(zone);
-    auto& last_function_type_arguments = TypeArguments::Handle(zone);
-    auto& last_instance_parent_function_type_arguments =
-        TypeArguments::Handle(zone);
-    auto& last_instance_delayed_type_arguments = TypeArguments::Handle(zone);
-    Bool& last_result = Bool::Handle(zone);
-    for (intptr_t i = 0; i < len; ++i) {
-      new_cache.GetCheck(
-          i, &last_instance_class_id_or_function, &last_instance_type_arguments,
-          &last_instantiator_type_arguments, &last_function_type_arguments,
-          &last_instance_parent_function_type_arguments,
-          &last_instance_delayed_type_arguments, &last_result);
-      if ((last_instance_class_id_or_function.raw() ==
-           instance_class_id_or_function.raw()) &&
-          (last_instance_type_arguments.raw() ==
-           instance_type_arguments.raw()) &&
-          (last_instantiator_type_arguments.raw() ==
-           instantiator_type_arguments.raw()) &&
-          (last_function_type_arguments.raw() ==
-           function_type_arguments.raw()) &&
-          (last_instance_parent_function_type_arguments.raw() ==
-           instance_parent_function_type_arguments.raw()) &&
-          (last_instance_delayed_type_arguments.raw() ==
-           instance_delayed_type_arguments.raw())) {
-        // Some other isolate might have updated the cache between entry was
-        // found missing and now.
-        return;
+    intptr_t colliding_index = -1;
+    auto& old_result = Bool::Handle(zone);
+    if (new_cache.HasCheck(
+            instance_class_id_or_function, destination_type,
+            instance_type_arguments, instantiator_type_arguments,
+            function_type_arguments, instance_parent_function_type_arguments,
+            instance_delayed_type_arguments, &colliding_index, &old_result)) {
+      if (FLAG_trace_type_checks) {
+        TextBuffer buffer(256);
+        buffer.Printf("  Collision for test cache %#" Px " at index %" Pd ":\n",
+                      static_cast<uword>(new_cache.raw()), colliding_index);
+        buffer.Printf("    entry: ");
+        new_cache.WriteEntryToBuffer(zone, &buffer, colliding_index, "      ");
+        OS::PrintErr("%s\n", buffer.buffer());
       }
+      if (!FLAG_enable_isolate_groups) {
+        FATAL("Duplicate subtype test cache entry");
+      }
+      if (old_result.raw() != result.raw()) {
+        FATAL("Existing subtype test cache entry has result %s, not %s",
+              old_result.ToCString(), result.ToCString());
+      }
+      // Some other isolate might have updated the cache between entry was
+      // found missing and now.
+      return;
     }
-    new_cache.AddCheck(instance_class_id_or_function, instance_type_arguments,
-                       instantiator_type_arguments, function_type_arguments,
+    new_cache.AddCheck(instance_class_id_or_function, destination_type,
+                       instance_type_arguments, instantiator_type_arguments,
+                       function_type_arguments,
                        instance_parent_function_type_arguments,
                        instance_delayed_type_arguments, result);
     if (FLAG_trace_type_checks) {
-      AbstractType& test_type = AbstractType::Handle(zone, type.raw());
-      if (!test_type.IsInstantiated()) {
-        test_type =
-            type.InstantiateFrom(instantiator_type_arguments,
-                                 function_type_arguments, kAllFree, Heap::kNew);
-      }
-      const auto& type_class = Class::Handle(zone, test_type.type_class());
-      const auto& instance_class_name =
-          String::Handle(zone, instance_class.Name());
-      OS::PrintErr(
-          "  Updated test cache %#" Px " ix: %" Pd
-          " with (cid-or-fun:"
-          " %#" Px ", type-args: %#" Px ", i-type-args: %#" Px
-          ", "
-          "f-type-args: %#" Px ", p-type-args: %#" Px
-          ", "
-          "d-type-args: %#" Px
-          ", result: %s)\n"
-          "    instance  [class: (%#" Px " '%s' cid: %" Pd
-          "),    type-args: %#" Px
-          " %s]\n"
-          "    test-type [class: (%#" Px " '%s' cid: %" Pd
-          "), i-type-args: %#" Px " %s, f-type-args: %#" Px " %s]\n",
-          static_cast<uword>(new_cache.raw()), len,
-          static_cast<uword>(instance_class_id_or_function.raw()),
-          static_cast<uword>(instance_type_arguments.raw()),
-          static_cast<uword>(instantiator_type_arguments.raw()),
-          static_cast<uword>(function_type_arguments.raw()),
-          static_cast<uword>(instance_parent_function_type_arguments.raw()),
-          static_cast<uword>(instance_delayed_type_arguments.raw()),
-          result.ToCString(), static_cast<uword>(instance_class.raw()),
-          instance_class_name.ToCString(), instance_class.id(),
-          static_cast<uword>(instance_type_arguments.raw()),
-          instance_type_arguments.ToCString(),
-          static_cast<uword>(type_class.raw()),
-          String::Handle(zone, type_class.Name()).ToCString(), type_class.id(),
-          static_cast<uword>(instantiator_type_arguments.raw()),
-          instantiator_type_arguments.ToCString(),
-          static_cast<uword>(function_type_arguments.raw()),
-          function_type_arguments.ToCString());
+      TextBuffer buffer(256);
+      buffer.Printf("  Added new entry to test cache %#" Px " at index %" Pd
+                    ":\n",
+                    static_cast<uword>(new_cache.raw()), len);
+      buffer.Printf("    new entry: ");
+      new_cache.WriteEntryToBuffer(zone, &buffer, len, "      ");
+      OS::PrintErr("%s\n", buffer.buffer());
     }
   }
 }
@@ -775,10 +778,10 @@
   ASSERT(mode == kTypeCheckFromInline);
 #endif
 
-  ASSERT(!dst_type.IsDynamicType());  // No need to check assignment.
-  // A null instance is already detected and allowed in inlined code, unless
-  // strong checking is enabled.
-  ASSERT(!src_instance.IsNull() || isolate->null_safety());
+  // These are guaranteed on the calling side.
+  ASSERT(!dst_type.IsDynamicType());
+  ASSERT(!src_instance.IsNull() || isolate->use_strict_null_safety_checks());
+
   const bool is_instance_of = src_instance.IsAssignableTo(
       dst_type, instantiator_type_arguments, function_type_arguments);
 
@@ -788,16 +791,6 @@
                    Bool::Get(is_instance_of));
   }
   if (!is_instance_of) {
-    // Throw a dynamic type error.
-    const TokenPosition location = GetCallerLocation();
-    const AbstractType& src_type =
-        AbstractType::Handle(zone, src_instance.GetType(Heap::kNew));
-    if (!dst_type.IsInstantiated()) {
-      // Instantiate dst_type before reporting the error.
-      dst_type = dst_type.InstantiateFrom(instantiator_type_arguments,
-                                          function_type_arguments, kAllFree,
-                                          Heap::kNew);
-    }
     if (dst_name.IsNull()) {
 #if !defined(TARGET_ARCH_IA32)
       // Can only come here from type testing stub.
@@ -821,6 +814,57 @@
 #endif
     }
 
+    if (dst_name.raw() ==
+        Symbols::dynamic_assert_assignable_stc_check().raw()) {
+#if !defined(TARGET_ARCH_IA32)
+      // Can only come here from type testing stub via dynamic AssertAssignable.
+      ASSERT(mode != kTypeCheckFromInline);
+#endif
+      // This was a dynamic closure call where the destination name was not
+      // known at compile-time. Thus, fetch the original arguments and arguments
+      // descriptor and re-do the type check  in the runtime, which causes the
+      // error with the proper destination name to be thrown.
+      DartFrameIterator iterator(thread,
+                                 StackFrameIterator::kNoCrossThreadIteration);
+      StackFrame* caller_frame = iterator.NextFrame();
+      const auto& dispatcher =
+          Function::Handle(zone, caller_frame->LookupDartFunction());
+      ASSERT(dispatcher.IsInvokeFieldDispatcher());
+      const auto& orig_arguments_desc =
+          Array::Handle(zone, dispatcher.saved_args_desc());
+      const ArgumentsDescriptor args_desc(orig_arguments_desc);
+      const intptr_t arg_count = args_desc.CountWithTypeArgs();
+      const auto& orig_arguments = Array::Handle(zone, Array::New(arg_count));
+      auto& obj = Object::Handle(zone);
+      for (intptr_t i = 0; i < arg_count; i++) {
+        obj = *reinterpret_cast<ObjectPtr*>(
+            ParamAddress(caller_frame->fp(), arg_count - i));
+        orig_arguments.SetAt(i, obj);
+      }
+      const auto& receiver = Closure::CheckedHandle(
+          zone, orig_arguments.At(args_desc.FirstArgIndex()));
+      const auto& function = Function::Handle(zone, receiver.function());
+      const auto& result = Object::Handle(
+          zone, function.DoArgumentTypesMatch(orig_arguments, args_desc));
+      if (result.IsError()) {
+        Exceptions::PropagateError(Error::Cast(result));
+      }
+      // IsAssignableTo returned false, so we should have thrown a type
+      // error in DoArgumentsTypesMatch.
+      UNREACHABLE();
+    }
+
+    ASSERT(!dst_name.IsNull());
+    // Throw a dynamic type error.
+    const TokenPosition location = GetCallerLocation();
+    const AbstractType& src_type =
+        AbstractType::Handle(zone, src_instance.GetType(Heap::kNew));
+    if (!dst_type.IsInstantiated()) {
+      // Instantiate dst_type before reporting the error.
+      dst_type = dst_type.InstantiateFrom(instantiator_type_arguments,
+                                          function_type_arguments, kAllFree,
+                                          Heap::kNew);
+    }
     Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name);
     UNREACHABLE();
   }
@@ -1109,9 +1153,15 @@
   return result.raw();
 }
 
-static void TrySwitchInstanceCall(const ICData& ic_data,
-                                  const Function& target_function) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
+static void TrySwitchInstanceCall(Thread* thread,
+                                  StackFrame* caller_frame,
+                                  const Code& caller_code,
+                                  const Function& caller_function,
+                                  const ICData& ic_data,
+                                  const Function& target_function) {
+  auto zone = thread->zone();
+
   // Monomorphic/megamorphic calls only check the receiver CID.
   if (ic_data.NumArgsTested() != 1) return;
 
@@ -1125,24 +1175,14 @@
   if (Isolate::Current()->has_attempted_stepping()) return;
 #endif
 
-  Thread* thread = Thread::Current();
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame->IsDartFrame());
-
   // Monomorphic/megamorphic calls are only for unoptimized code.
-  Zone* zone = thread->zone();
-  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  if (caller_code.is_optimized()) return;
+  ASSERT(!caller_code.is_optimized());
 
   // Code is detached from its function. This will prevent us from resetting
   // the switchable call later because resets are function based and because
   // the ic_data_array belongs to the function instead of the code. This should
   // only happen because of reload, but it sometimes happens with KBC mixed mode
   // probably through a race between foreground and background compilation.
-  const Function& caller_function =
-      Function::Handle(zone, caller_code.function());
   if (caller_function.unoptimized_code() != caller_code.raw()) {
     return;
   }
@@ -1193,9 +1233,8 @@
     }
     return;  // Success.
   }
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 // Perform the subtype and return constant function based on the result.
 static FunctionPtr ComputeTypeCheckTarget(const Instance& receiver,
@@ -1211,153 +1250,38 @@
   return target.raw();
 }
 
-static FunctionPtr InlineCacheMissHandlerGivenTargetFunction(
-    const GrowableArray<const Instance*>& args,  // Checked arguments only.
-    const ICData& ic_data,
-    intptr_t count,
-    const Function& target_function) {
-  if (target_function.IsNull()) {
-    return target_function.raw();
-  }
+static FunctionPtr Resolve(
+    Thread* thread,
+    Zone* zone,
+    const GrowableArray<const Instance*>& caller_arguments,
+    const Class& receiver_class,
+    const String& name,
+    const Array& descriptor) {
+  ASSERT(name.IsSymbol());
+  auto& target_function = Function::Handle(zone);
+  ArgumentsDescriptor args_desc(descriptor);
 
-  const Instance& receiver = *args[0];
-
-  if (args.length() == 1) {
-    if (ic_data.is_tracking_exactness()) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-      const auto state = receiver.IsNull()
-                             ? StaticTypeExactnessState::NotExact()
-                             : StaticTypeExactnessState::Compute(
-                                   Type::Cast(AbstractType::Handle(
-                                       ic_data.receivers_static_type())),
-                                   receiver);
-      ic_data.AddReceiverCheck(
-          receiver.GetClassId(), target_function, count,
-          /*exactness=*/state.CollapseSuperTypeExactness());
-#else
-      UNREACHABLE();
-#endif
-    } else {
-      ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function, count);
-    }
-  } else {
-    GrowableArray<intptr_t> class_ids(args.length());
-    ASSERT(ic_data.NumArgsTested() == args.length());
-    for (intptr_t i = 0; i < args.length(); i++) {
-      class_ids.Add(args[i]->GetClassId());
-    }
-    ic_data.AddCheck(class_ids, target_function, count);
-  }
-  if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) {
-    DartFrameIterator iterator(Thread::Current(),
-                               StackFrameIterator::kNoCrossThreadIteration);
-    StackFrame* caller_frame = iterator.NextFrame();
-    ASSERT(caller_frame != NULL);
-    if (FLAG_trace_ic_miss_in_optimized) {
-      const Code& caller = Code::Handle(Code::LookupCode(caller_frame->pc()));
-      if (caller.is_optimized()) {
-        OS::PrintErr("IC miss in optimized code; call %s -> %s\n",
-                     Function::Handle(caller.function()).ToCString(),
-                     target_function.ToCString());
-      }
-    }
-    if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler %" Pd " call at %#" Px
-                   "' "
-                   "adding <%s> id:%" Pd " -> <%s>\n",
-                   args.length(), caller_frame->pc(),
-                   Class::Handle(receiver.clazz()).ToCString(),
-                   receiver.GetClassId(), target_function.ToCString());
-    }
-  }
-
-  TrySwitchInstanceCall(ic_data, target_function);
-
-  return target_function.raw();
-}
-
-static FunctionPtr InlineCacheMissHandler(
-    const GrowableArray<const Instance*>& args,  // Checked arguments only.
-    const ICData& ic_data,
-    intptr_t count = 1) {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-
-  const Instance& receiver = *args[0];
-  ArgumentsDescriptor arguments_descriptor(
-      Array::Handle(zone, ic_data.arguments_descriptor()));
-  String& function_name = String::Handle(zone, ic_data.target_name());
-  ASSERT(function_name.IsSymbol());
-
-  const Class& receiver_class = Class::Handle(zone, receiver.clazz());
-  Function& target_function = Function::Handle(zone);
   if (receiver_class.EnsureIsFinalized(thread) == Error::null()) {
-    target_function = Resolver::ResolveDynamicForReceiverClass(
-        receiver_class, function_name, arguments_descriptor);
+    target_function = Resolver::ResolveDynamicForReceiverClass(receiver_class,
+                                                               name, args_desc);
+  }
+  if (caller_arguments.length() == 2 &&
+      target_function.raw() ==
+          thread->isolate()->object_store()->simple_instance_of_function()) {
+    // Replace the target function with constant function.
+    const AbstractType& type = AbstractType::Cast(*caller_arguments[1]);
+    target_function =
+        ComputeTypeCheckTarget(*caller_arguments[0], type, args_desc);
   }
 
-  ObjectStore* store = thread->isolate()->object_store();
-  if (target_function.raw() == store->simple_instance_of_function()) {
-    // Replace the target function with constant function.
-    ASSERT(args.length() == 2);
-    const AbstractType& type = AbstractType::Cast(*args[1]);
-    target_function =
-        ComputeTypeCheckTarget(receiver, type, arguments_descriptor);
-  }
   if (target_function.IsNull()) {
-    if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n",
-                   String::Handle(zone, ic_data.target_name()).ToCString(),
-                   receiver.ToCString());
-    }
-    const Array& args_descriptor =
-        Array::Handle(zone, ic_data.arguments_descriptor());
-    const String& target_name = String::Handle(zone, ic_data.target_name());
-    target_function =
-        InlineCacheMissHelper(receiver_class, args_descriptor, target_name);
+    target_function = InlineCacheMissHelper(receiver_class, descriptor, name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
-    return target_function.raw();
   }
 
-  return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, count,
-                                                   target_function);
-}
-
-// Handles inline cache misses by updating the IC data array of the call site.
-//   Arg0: Receiver object.
-//   Arg1: IC data object.
-//   Returns: target function with compiled code or null.
-// Modifies the instance call to hold the updated IC data array.
-DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) {
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(1));
-  RELEASE_ASSERT(!FLAG_precompiled_mode);
-  GrowableArray<const Instance*> args(1);
-  args.Add(&receiver);
-  const Function& result =
-      Function::Handle(zone, InlineCacheMissHandler(args, ic_data));
-  arguments.SetReturn(result);
-}
-
-// Handles inline cache misses by updating the IC data array of the call site.
-//   Arg0: Receiver object.
-//   Arg1: Argument after receiver.
-//   Arg2: IC data object.
-//   Returns: target function with compiled code or null.
-// Modifies the instance call to hold the updated IC data array.
-DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) {
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  const Instance& other = Instance::CheckedHandle(zone, arguments.ArgAt(1));
-  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(2));
-  RELEASE_ASSERT(!FLAG_precompiled_mode);
-  GrowableArray<const Instance*> args(2);
-  args.Add(&receiver);
-  args.Add(&other);
-  const Function& result =
-      Function::Handle(zone, InlineCacheMissHandler(args, ic_data));
-  arguments.SetReturn(result);
+  return target_function.raw();
 }
 
 // Handles a static call in unoptimized code that has one argument type not
@@ -1372,7 +1296,7 @@
   const Function& target = Function::Handle(zone, ic_data.GetTargetAt(0));
   target.EnsureHasCode();
   ASSERT(!target.IsNull() && target.HasCode());
-  ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
+  ic_data.EnsureHasReceiverCheck(arg.GetClassId(), target, 1);
   if (FLAG_trace_ic) {
     DartFrameIterator iterator(thread,
                                StackFrameIterator::kNoCrossThreadIteration);
@@ -1400,7 +1324,7 @@
   GrowableArray<intptr_t> cids(2);
   cids.Add(arg0.GetClassId());
   cids.Add(arg1.GetClassId());
-  ic_data.AddCheck(cids, target);
+  ic_data.EnsureHasCheck(cids, target);
   if (FLAG_trace_ic) {
     DartFrameIterator iterator(thread,
                                StackFrameIterator::kNoCrossThreadIteration);
@@ -1413,6 +1337,8 @@
   arguments.SetReturn(target);
 }
 
+#if defined(DART_PRECOMPILED_RUNTIME)
+
 static bool IsSingleTarget(Isolate* isolate,
                            Zone* zone,
                            intptr_t lower_cid,
@@ -1436,7 +1362,6 @@
   return true;
 }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
 
 class SavedUnlinkedCallMapKeyEqualsTraits : public AllStatic {
  public:
@@ -1511,51 +1436,124 @@
 
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-class SwitchableCallHandler {
+enum class MissHandler {
+  kInlineCacheMiss,
+  kSwitchableCallMiss,
+};
+
+// Handles updating of type feedback and possible patching of instance calls.
+//
+// It works in 3 separate steps:
+//   - resolve the actual target
+//   - update type feedback & (optionally) perform call site transition
+//   - return the right values
+//
+// Depending on the JIT/AOT mode we obtain current and patch new (target, data)
+// differently:
+//
+//   - JIT calls must be patched with CodePatcher::PatchInstanceCallAt()
+//   - AOT calls must be patched with CodePatcher::PatchSwitchableCallAt()
+//
+// Independent of which miss handler was used or how we will return, we look at
+// current (target, data) and see if we need to transition the call site to a
+// new (target, data). We do this while holding `IG->patchable_call_mutex()`.
+//
+// Depending on which miss handler got called we might need to return
+// differently:
+//
+//   - SwitchableCallMiss will get get (stub, data) return value
+//   - InlineCache*Miss will get get function as return value
+//
+class PatchableCallHandler {
  public:
-  SwitchableCallHandler(Thread* thread,
-                        const Instance& receiver,
-                        NativeArguments arguments,
-                        StackFrame* caller_frame,
-                        const Code& caller_code,
-                        const Function& caller_function)
+  PatchableCallHandler(Thread* thread,
+                       const GrowableArray<const Instance*>& caller_arguments,
+                       MissHandler miss_handler,
+                       NativeArguments arguments,
+                       StackFrame* caller_frame,
+                       const Code& caller_code,
+                       const Function& caller_function)
       : isolate_(thread->isolate()),
         thread_(thread),
         zone_(thread->zone()),
-        receiver_(receiver),
+        caller_arguments_(caller_arguments),
+        miss_handler_(miss_handler),
         arguments_(arguments),
         caller_frame_(caller_frame),
         caller_code_(caller_code),
         caller_function_(caller_function),
         name_(String::Handle()),
-        args_descriptor_(Array::Handle()) {}
+        args_descriptor_(Array::Handle()) {
+    // We only have two arg IC calls in JIT mode.
+    ASSERT(caller_arguments_.length() == 1 || !FLAG_precompiled_mode);
+  }
 
+  void ResolveSwitchAndReturn(const Object& data);
+
+ private:
   FunctionPtr ResolveTargetFunction(const Object& data);
   void HandleMiss(const Object& old_data,
                   const Code& old_target,
                   const Function& target_function);
 
- private:
-  void DoUnlinkedCall(const UnlinkedCall& unlinked,
-                      const Function& target_function);
+#if defined(DART_PRECOMPILED_RUNTIME)
+  void DoUnlinkedCallAOT(const UnlinkedCall& unlinked,
+                         const Function& target_function);
+  void DoMonomorphicMissAOT(const Object& data,
+                            const Function& target_function);
+  void DoSingleTargetMissAOT(const SingleTargetCache& data,
+                             const Function& target_function);
+  void DoICDataMissAOT(const ICData& data, const Function& target_function);
   bool CanExtendSingleTargetRange(const String& name,
                                   const Function& old_target,
                                   const Function& target_function,
                                   intptr_t* lower,
                                   intptr_t* upper);
-  void DoMonomorphicMiss(const Object& data, const Function& target_function);
-#if defined(DART_PRECOMPILED_RUNTIME)
-  void DoSingleTargetMiss(const SingleTargetCache& data,
-                          const Function& target_function);
+#else
+  void DoMonomorphicMissJIT(const Object& data,
+                            const Function& target_function);
+  void DoICDataMissJIT(const ICData& data,
+                       const Object& old_data,
+                       const Function& target_function);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  void DoICDataMiss(const ICData& data, const Function& target_function);
   void DoMegamorphicMiss(const MegamorphicCache& data,
                          const Function& target_function);
 
+  void UpdateICDataWithTarget(const ICData& ic_data,
+                              const Function& target_function);
+  void TrySwitch(const ICData& ic_data, const Function& target_function);
+
+  void ReturnAOT(const Code& stub, const Object& data);
+  void ReturnJIT(const Code& stub, const Object& data, const Function& target);
+  void ReturnJITorAOT(const Code& stub,
+                      const Object& data,
+                      const Function& target);
+
+  const Instance& receiver() { return *caller_arguments_[0]; }
+
+  bool should_consider_patching() {
+    // In AOT we use switchable calls.
+    if (FLAG_precompiled_mode) return true;
+
+    // In JIT instance calls use a different calling sequence in unoptimized vs
+    // optimized code (see [FlowGraphCompiler::EmitInstanceCallJIT] vs
+    // [FlowGraphCompiler::EmitOptimizedInstanceCall]).
+    //
+    // The [CodePatcher::GetInstanceCallAt], [CodePatcher::PatchInstanceCallAt]
+    // only recognize unoptimized call pattern.
+    //
+    // So we will not try to switch optimized instance calls.
+    return !caller_code_.is_optimized();
+  }
+
+  ICDataPtr NewICData();
+  ICDataPtr NewICDataWithTarget(intptr_t cid, const Function& target);
+
   Isolate* isolate_;
   Thread* thread_;
   Zone* zone_;
-  const Instance& receiver_;
+  const GrowableArray<const Instance*>& caller_arguments_;
+  MissHandler miss_handler_;
   NativeArguments arguments_;
   StackFrame* caller_frame_;
   const Code& caller_code_;
@@ -1567,18 +1565,14 @@
   bool is_monomorphic_hit_ = false;
 };
 
-void SwitchableCallHandler::DoUnlinkedCall(const UnlinkedCall& unlinked,
-                                           const Function& target_function) {
-  const String& name = String::Handle(zone_, unlinked.target_name());
-  const Array& descriptor =
-      Array::Handle(zone_, unlinked.arguments_descriptor());
-  const ICData& ic_data =
-      ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
-                                        DeoptId::kNone, 1, /* args_tested */
-                                        ICData::kInstance));
-  if (!target_function.IsNull()) {
-    ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
-  }
+#if defined(DART_PRECOMPILED_RUNTIME)
+void PatchableCallHandler::DoUnlinkedCallAOT(const UnlinkedCall& unlinked,
+                                             const Function& target_function) {
+  const auto& ic_data = ICData::Handle(
+      zone_,
+      target_function.IsNull()
+          ? NewICData()
+          : NewICDataWithTarget(receiver().GetClassId(), target_function));
 
   Object& object = Object::Handle(zone_, ic_data.raw());
   Code& code = Code::Handle(zone_, StubCode::ICCallThroughCode().raw());
@@ -1597,7 +1591,7 @@
     const Code& target_code =
         Code::Handle(zone_, target_function.CurrentCode());
     const Smi& expected_cid =
-        Smi::Handle(zone_, Smi::New(receiver_.GetClassId()));
+        Smi::Handle(zone_, Smi::New(receiver().GetClassId()));
 
     if (unlinked.can_patch_to_monomorphic()) {
       object = expected_cid.raw();
@@ -1608,16 +1602,15 @@
       code = StubCode::MonomorphicSmiableCheck().raw();
     }
   }
-  CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
-      thread_, caller_frame_->pc(), caller_code_, object, code);
+  CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_, object,
+                                     code);
 
   // Return the ICData. The miss stub will jump to continue in the IC lookup
   // stub.
-  arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-  arguments_.SetReturn(ic_data);
+  ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
 }
 
-bool SwitchableCallHandler::CanExtendSingleTargetRange(
+bool PatchableCallHandler::CanExtendSingleTargetRange(
     const String& name,
     const Function& old_target,
     const Function& target_function,
@@ -1627,19 +1620,20 @@
     return false;
   }
   intptr_t unchecked_lower, unchecked_upper;
-  if (receiver_.GetClassId() < *lower) {
-    unchecked_lower = receiver_.GetClassId();
+  if (receiver().GetClassId() < *lower) {
+    unchecked_lower = receiver().GetClassId();
     unchecked_upper = *lower - 1;
-    *lower = receiver_.GetClassId();
+    *lower = receiver().GetClassId();
   } else {
-    unchecked_upper = receiver_.GetClassId();
+    unchecked_upper = receiver().GetClassId();
     unchecked_lower = *upper + 1;
-    *upper = receiver_.GetClassId();
+    *upper = receiver().GetClassId();
   }
 
   return IsSingleTarget(isolate_, zone_, unchecked_lower, unchecked_upper,
                         target_function, name);
 }
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 static ICDataPtr FindICDataForInstanceCall(Zone* zone,
@@ -1661,33 +1655,10 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-static FunctionPtr Resolve(Thread* thread,
-                           Zone* zone,
-                           const Class& receiver_class,
-                           const String& name,
-                           const Array& descriptor) {
-  ASSERT(name.IsSymbol());
-  Function& target_function = Function::Handle(zone);
-
-  if (receiver_class.EnsureIsFinalized(thread) == Error::null()) {
-    ArgumentsDescriptor args_desc(descriptor);
-    target_function = Resolver::ResolveDynamicForReceiverClass(receiver_class,
-                                                               name, args_desc);
-  }
-
-  if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(receiver_class, descriptor, name);
-    if (target_function.IsNull()) {
-      ASSERT(!FLAG_lazy_dispatchers);
-    }
-  }
-
-  return target_function.raw();
-}
-
-void SwitchableCallHandler::DoMonomorphicMiss(const Object& data,
-                                              const Function& target_function) {
 #if defined(DART_PRECOMPILED_RUNTIME)
+void PatchableCallHandler::DoMonomorphicMissAOT(
+    const Object& data,
+    const Function& target_function) {
   classid_t old_expected_cid;
   if (data.IsSmi()) {
     old_expected_cid = Smi::Cast(data).Value();
@@ -1695,27 +1666,22 @@
     RELEASE_ASSERT(data.IsMonomorphicSmiableCall());
     old_expected_cid = MonomorphicSmiableCall::Cast(data).expected_cid();
   }
-  const bool is_monomorphic_hit = old_expected_cid == receiver_.GetClassId();
+  const bool is_monomorphic_hit = old_expected_cid == receiver().GetClassId();
   const auto& old_receiver_class =
       Class::Handle(zone_, isolate_->class_table()->At(old_expected_cid));
   const auto& old_target = Function::Handle(
-      zone_,
-      Resolve(thread_, zone_, old_receiver_class, name_, args_descriptor_));
+      zone_, Resolve(thread_, zone_, caller_arguments_, old_receiver_class,
+                     name_, args_descriptor_));
 
-  const ICData& ic_data = ICData::Handle(
-      zone_, ICData::New(caller_function_, name_, args_descriptor_,
-                         DeoptId::kNone, 1, /* args_tested */
-                         ICData::kInstance));
-  // Add the first target.
-  if (!old_target.IsNull()) {
-    ic_data.AddReceiverCheck(old_expected_cid, old_target);
-  }
+  const auto& ic_data = ICData::Handle(
+      zone_, old_target.IsNull()
+                 ? NewICData()
+                 : NewICDataWithTarget(old_expected_cid, old_target));
 
   if (is_monomorphic_hit) {
     // The site just have been updated to monomorphic state with same
     // exact class id - do nothing in that case: stub will call through ic data.
-    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     return;
   }
 
@@ -1731,25 +1697,29 @@
     cache.set_lower_limit(lower);
     cache.set_upper_limit(upper);
     const Code& stub = StubCode::SingleTargetCall();
-    CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
-        thread_, caller_frame_->pc(), caller_code_, cache, stub);
+    CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_, cache,
+                                       stub);
     // Return the ICData. The miss stub will jump to continue in the IC call
     // stub.
-    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     return;
   }
 
   // Patch to call through stub.
   const Code& stub = StubCode::ICCallThroughCode();
-  CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
-      thread_, caller_frame_->pc(), caller_code_, ic_data, stub);
+  CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_, ic_data,
+                                     stub);
 
   // Return the ICData. The miss stub will jump to continue in the IC lookup
   // stub.
-  arguments_.SetArgAt(0, stub);
-  arguments_.SetReturn(ic_data);
-#else   // JIT
+  ReturnAOT(stub, ic_data);
+}
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+void PatchableCallHandler::DoMonomorphicMissJIT(
+    const Object& data,
+    const Function& target_function) {
   const ICData& ic_data = ICData::Handle(
       zone_,
       FindICDataForInstanceCall(zone_, caller_code_, caller_frame_->pc()));
@@ -1759,32 +1729,25 @@
   const Code& stub = ic_data.is_tracking_exactness()
                          ? StubCode::OneArgCheckInlineCacheWithExactnessCheck()
                          : StubCode::OneArgCheckInlineCache();
-  CodePatcher::PatchInstanceCallAtWithMutatorsStopped(
-      thread_, caller_frame_->pc(), caller_code_, ic_data, stub);
+  CodePatcher::PatchInstanceCallAt(caller_frame_->pc(), caller_code_, ic_data,
+                                   stub);
   if (FLAG_trace_ic) {
     OS::PrintErr("Instance call at %" Px
                  " switching to polymorphic dispatch, %s\n",
                  caller_frame_->pc(), ic_data.ToCString());
   }
 
-  // ICData can be shared between unoptimized and optimized code, so beware that
-  // the new receiver class may have already been added through the optimized
-  // code.
-  if (!ic_data.HasReceiverClassId(receiver_.GetClassId())) {
-    GrowableArray<const Instance*> args(1);
-    args.Add(&receiver_);
-    // Don't count during insertion because the IC stub we continue through will
-    // do an increment.
-    InlineCacheMissHandlerGivenTargetFunction(args, ic_data, /*count=*/0,
-                                              target_function);
-  }
-  arguments_.SetArgAt(0, stub);
-  arguments_.SetReturn(ic_data);
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
+  ASSERT(caller_arguments_.length() == 1);
+  UpdateICDataWithTarget(ic_data, target_function);
+  ASSERT(should_consider_patching());
+  TrySwitchInstanceCall(thread_, caller_frame_, caller_code_, caller_function_,
+                        ic_data, target_function);
+  ReturnJIT(stub, ic_data, target_function);
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #if defined(DART_PRECOMPILED_RUNTIME)
-void SwitchableCallHandler::DoSingleTargetMiss(
+void PatchableCallHandler::DoSingleTargetMissAOT(
     const SingleTargetCache& data,
     const Function& target_function) {
   const Code& old_target_code = Code::Handle(zone_, data.target());
@@ -1792,13 +1755,11 @@
       Function::Handle(zone_, Function::RawCast(old_target_code.owner()));
 
   // We lost the original ICData when we patched to the monomorphic case.
-  const ICData& ic_data = ICData::Handle(
-      zone_, ICData::New(caller_function_, name_, args_descriptor_,
-                         DeoptId::kNone, 1, /* args_tested */
-                         ICData::kInstance));
-  if (!target_function.IsNull()) {
-    ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
-  }
+  const auto& ic_data = ICData::Handle(
+      zone_,
+      target_function.IsNull()
+          ? NewICData()
+          : NewICDataWithTarget(receiver().GetClassId(), target_function));
 
   intptr_t lower = data.lower_limit();
   intptr_t upper = data.upper_limit();
@@ -1808,27 +1769,26 @@
     data.set_upper_limit(upper);
     // Return the ICData. The single target stub will jump to continue in the
     // IC call stub.
-    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     return;
   }
 
   // Call site is not single target, switch to call using ICData.
   const Code& stub = StubCode::ICCallThroughCode();
-  CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
-      thread_, caller_frame_->pc(), caller_code_, ic_data, stub);
+  CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_, ic_data,
+                                     stub);
 
   // Return the ICData. The single target stub will jump to continue in the
   // IC call stub.
-  arguments_.SetArgAt(0, stub);
-  arguments_.SetReturn(ic_data);
+  ReturnAOT(stub, ic_data);
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-void SwitchableCallHandler::DoICDataMiss(const ICData& ic_data,
-                                         const Function& target_function) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+void PatchableCallHandler::DoICDataMissAOT(const ICData& ic_data,
+                                           const Function& target_function) {
   const String& name = String::Handle(zone_, ic_data.target_name());
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
+  const Class& cls = Class::Handle(zone_, receiver().clazz());
   ASSERT(!cls.IsNull());
   const Array& descriptor =
       Array::CheckedHandle(zone_, ic_data.arguments_descriptor());
@@ -1839,8 +1799,7 @@
   }
 
   if (target_function.IsNull()) {
-    arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::NoSuchMethodDispatcher(), ic_data);
     return;
   }
 
@@ -1858,40 +1817,75 @@
     const Code& target_code =
         Code::Handle(zone_, target_function.EnsureHasCode());
     const Smi& expected_cid =
-        Smi::Handle(zone_, Smi::New(receiver_.GetClassId()));
+        Smi::Handle(zone_, Smi::New(receiver().GetClassId()));
     ASSERT(target_code.HasMonomorphicEntry());
-    CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
-        thread_, caller_frame_->pc(), caller_code_, expected_cid, target_code);
-    arguments_.SetArgAt(0, target_code);
-    arguments_.SetReturn(expected_cid);
+    CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_,
+                                       expected_cid, target_code);
+    ReturnAOT(target_code, expected_cid);
   } else {
-    // IC entry might have been added while we waited to get into runtime.
-    GrowableArray<intptr_t> class_ids(1);
-    class_ids.Add(receiver_.GetClassId());
-    if (ic_data.FindCheck(class_ids) == -1) {
-      ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
-    }
+    ic_data.EnsureHasReceiverCheck(receiver().GetClassId(), target_function);
     if (number_of_checks > FLAG_max_polymorphic_checks) {
       // Switch to megamorphic call.
       const MegamorphicCache& cache = MegamorphicCache::Handle(
           zone_, MegamorphicCacheTable::Lookup(thread_, name, descriptor));
       const Code& stub = StubCode::MegamorphicCall();
 
-      CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
-          thread_, caller_frame_->pc(), caller_code_, cache, stub);
-      arguments_.SetArgAt(0, stub);
-      arguments_.SetReturn(cache);
+      CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_,
+                                         cache, stub);
+      ReturnAOT(stub, cache);
     } else {
-      arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-      arguments_.SetReturn(ic_data);
+      ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     }
   }
 }
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-void SwitchableCallHandler::DoMegamorphicMiss(const MegamorphicCache& data,
-                                              const Function& target_function) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+void PatchableCallHandler::DoICDataMissJIT(const ICData& ic_data,
+                                           const Object& old_code,
+                                           const Function& target_function) {
+  ASSERT(ic_data.NumArgsTested() == caller_arguments_.length());
+
+  if (ic_data.NumArgsTested() == 1) {
+    ASSERT(old_code.raw() == StubCode::OneArgCheckInlineCache().raw() ||
+           old_code.raw() ==
+               StubCode::OneArgCheckInlineCacheWithExactnessCheck().raw() ||
+           old_code.raw() ==
+               StubCode::OneArgOptimizedCheckInlineCache().raw() ||
+           old_code.raw() ==
+               StubCode::OneArgOptimizedCheckInlineCacheWithExactnessCheck()
+                   .raw() ||
+           old_code.raw() == StubCode::ICCallBreakpoint().raw() ||
+           (old_code.IsNull() && !should_consider_patching()));
+    UpdateICDataWithTarget(ic_data, target_function);
+    if (should_consider_patching()) {
+      TrySwitchInstanceCall(thread_, caller_frame_, caller_code_,
+                            caller_function_, ic_data, target_function);
+    }
+    const Code& stub = Code::Handle(
+        zone_, ic_data.is_tracking_exactness()
+                   ? StubCode::OneArgCheckInlineCacheWithExactnessCheck().raw()
+                   : StubCode::OneArgCheckInlineCache().raw());
+    ReturnJIT(stub, ic_data, target_function);
+  } else {
+    ASSERT(old_code.raw() == StubCode::TwoArgsCheckInlineCache().raw() ||
+           old_code.raw() == StubCode::SmiAddInlineCache().raw() ||
+           old_code.raw() == StubCode::SmiLessInlineCache().raw() ||
+           old_code.raw() == StubCode::SmiEqualInlineCache().raw() ||
+           old_code.raw() ==
+               StubCode::TwoArgsOptimizedCheckInlineCache().raw() ||
+           old_code.raw() == StubCode::ICCallBreakpoint().raw() ||
+           (old_code.IsNull() && !should_consider_patching()));
+    UpdateICDataWithTarget(ic_data, target_function);
+    ReturnJIT(StubCode::TwoArgsCheckInlineCache(), ic_data, target_function);
+  }
+}
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+void PatchableCallHandler::DoMegamorphicMiss(const MegamorphicCache& data,
+                                             const Function& target_function) {
   const String& name = String::Handle(zone_, data.target_name());
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
+  const Class& cls = Class::Handle(zone_, receiver().clazz());
   ASSERT(!cls.IsNull());
   const Array& descriptor =
       Array::CheckedHandle(zone_, data.arguments_descriptor());
@@ -1901,19 +1895,98 @@
                  cls.ToCString(), args_desc.TypeArgsLen(), name.ToCString());
   }
   if (target_function.IsNull()) {
-    arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
-    arguments_.SetReturn(data);
+    ReturnJITorAOT(StubCode::NoSuchMethodDispatcher(), data, target_function);
     return;
   }
 
   // Insert function found into cache.
   const Smi& class_id = Smi::Handle(zone_, Smi::New(cls.id()));
-  data.Insert(class_id, target_function);
-  arguments_.SetArgAt(0, StubCode::MegamorphicCall());
+  data.EnsureContains(class_id, target_function);
+  ReturnJITorAOT(StubCode::MegamorphicCall(), data, target_function);
+}
+
+void PatchableCallHandler::UpdateICDataWithTarget(
+    const ICData& ic_data,
+    const Function& target_function) {
+  if (target_function.IsNull()) return;
+
+  // If, upon return of the runtime, we will invoke the target directly we have
+  // to increment the call count here in the ICData.
+  // If we instead only insert a new ICData entry and will return to the IC stub
+  // which will call the target, the stub will take care of the increment.
+  const bool call_target_directly =
+      miss_handler_ == MissHandler::kInlineCacheMiss;
+  const intptr_t invocation_count = call_target_directly ? 1 : 0;
+
+  if (caller_arguments_.length() == 1) {
+    auto exactness = StaticTypeExactnessState::NotTracking();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    if (ic_data.is_tracking_exactness()) {
+      exactness = receiver().IsNull()
+                      ? StaticTypeExactnessState::NotExact()
+                      : StaticTypeExactnessState::Compute(
+                            Type::Cast(AbstractType::Handle(
+                                ic_data.receivers_static_type())),
+                            receiver());
+    }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+    ic_data.EnsureHasReceiverCheck(receiver().GetClassId(), target_function,
+                                   invocation_count, exactness);
+  } else {
+    GrowableArray<intptr_t> class_ids(caller_arguments_.length());
+    ASSERT(ic_data.NumArgsTested() == caller_arguments_.length());
+    for (intptr_t i = 0; i < caller_arguments_.length(); i++) {
+      class_ids.Add(caller_arguments_[i]->GetClassId());
+    }
+    ic_data.EnsureHasCheck(class_ids, target_function, invocation_count);
+  }
+}
+
+void PatchableCallHandler::ReturnAOT(const Code& stub, const Object& data) {
+  ASSERT(miss_handler_ == MissHandler::kSwitchableCallMiss);
+  arguments_.SetArgAt(0, stub);  // Second return value.
   arguments_.SetReturn(data);
 }
 
-FunctionPtr SwitchableCallHandler::ResolveTargetFunction(const Object& data) {
+void PatchableCallHandler::ReturnJIT(const Code& stub,
+                                     const Object& data,
+                                     const Function& target) {
+  // In JIT we can have two different miss handlers to which we return slightly
+  // differently.
+  if (miss_handler_ == MissHandler::kSwitchableCallMiss) {
+    arguments_.SetArgAt(0, stub);  // Second return value.
+    arguments_.SetReturn(data);
+  } else {
+    ASSERT(miss_handler_ == MissHandler::kInlineCacheMiss);
+    arguments_.SetReturn(target);
+  }
+}
+
+void PatchableCallHandler::ReturnJITorAOT(const Code& stub,
+                                          const Object& data,
+                                          const Function& target) {
+#if defined(DART_PRECOMPILED_MODE)
+  ReturnAOT(stub, data);
+#else
+  ReturnJIT(stub, data, target);
+#endif
+}
+
+ICDataPtr PatchableCallHandler::NewICData() {
+  return ICData::New(caller_function_, name_, args_descriptor_, DeoptId::kNone,
+                     /*num_args_tested=*/1, ICData::kInstance);
+}
+
+ICDataPtr PatchableCallHandler::NewICDataWithTarget(intptr_t cid,
+                                                    const Function& target) {
+  GrowableArray<intptr_t> cids(1);
+  cids.Add(cid);
+  return ICData::NewWithCheck(caller_function_, name_, args_descriptor_,
+                              DeoptId::kNone, /*num_args_tested=*/1,
+                              ICData::kInstance, &cids, target);
+}
+
+FunctionPtr PatchableCallHandler::ResolveTargetFunction(const Object& data) {
   switch (data.GetClassId()) {
     case kUnlinkedCallCid: {
       const auto& unlinked_call = UnlinkedCall::Cast(data);
@@ -1974,42 +2047,81 @@
     default:
       UNREACHABLE();
   }
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
-  return Resolve(thread_, zone_, cls, name_, args_descriptor_);
+  const Class& cls = Class::Handle(zone_, receiver().clazz());
+  return Resolve(thread_, zone_, caller_arguments_, cls, name_,
+                 args_descriptor_);
 }
 
-void SwitchableCallHandler::HandleMiss(const Object& old_data,
-                                       const Code& old_code,
-                                       const Function& target_function) {
+void PatchableCallHandler::ResolveSwitchAndReturn(const Object& old_data) {
+  // Find out actual target (which can be time consuminmg) without holding any
+  // locks.
+  const auto& target_function =
+      Function::Handle(zone_, ResolveTargetFunction(old_data));
+
+  auto& code = Code::Handle(zone_);
+  auto& data = Object::Handle(zone_);
+
+  // We ensure any transition in a patchable calls are done in an atomic
+  // manner, we ensure we always transition forward (e.g. Monomorphic ->
+  // Polymorphic).
+  //
+  // Mutators are only stopped if we actually need to patch a patchable call.
+  // We may not do that if we e.g. just add one more check to an ICData.
+  SafepointMutexLocker ml(thread_->isolate_group()->patchable_call_mutex());
+
+#if defined(DART_PRECOMPILED_RUNTIME)
+  data =
+      CodePatcher::GetSwitchableCallDataAt(caller_frame_->pc(), caller_code_);
+  DEBUG_ONLY(code = CodePatcher::GetSwitchableCallTargetAt(caller_frame_->pc(),
+                                                           caller_code_));
+#else
+  if (should_consider_patching()) {
+    code ^= CodePatcher::GetInstanceCallAt(caller_frame_->pc(), caller_code_,
+                                           &data);
+  } else {
+    ASSERT(old_data.IsICData() || old_data.IsMegamorphicCache());
+    data = old_data.raw();
+  }
+#endif
+  HandleMiss(data, code, target_function);
+}
+
+void PatchableCallHandler::HandleMiss(const Object& old_data,
+                                      const Code& old_code,
+                                      const Function& target_function) {
   switch (old_data.GetClassId()) {
+#if defined(DART_PRECOMPILED_RUNTIME)
     case kUnlinkedCallCid:
       ASSERT(old_code.raw() == StubCode::SwitchableCallMiss().raw());
-      DoUnlinkedCall(UnlinkedCall::Cast(old_data), target_function);
+      DoUnlinkedCallAOT(UnlinkedCall::Cast(old_data), target_function);
       break;
     case kMonomorphicSmiableCallCid:
       ASSERT(old_code.raw() == StubCode::MonomorphicSmiableCheck().raw());
       FALL_THROUGH;
-#if defined(DART_PRECOMPILED_RUNTIME)
     case kSmiCid:
-      DoMonomorphicMiss(old_data, target_function);
+      DoMonomorphicMissAOT(old_data, target_function);
       break;
     case kSingleTargetCacheCid:
       ASSERT(old_code.raw() == StubCode::SingleTargetCall().raw());
-      DoSingleTargetMiss(SingleTargetCache::Cast(old_data), target_function);
+      DoSingleTargetMissAOT(SingleTargetCache::Cast(old_data), target_function);
+      break;
+    case kICDataCid:
+      ASSERT(old_code.raw() == StubCode::ICCallThroughCode().raw());
+      DoICDataMissAOT(ICData::Cast(old_data), target_function);
       break;
 #else
     case kArrayCid:
       // ICData three-element array: Smi(receiver CID), Smi(count),
       // Function(target). It is the Array from ICData::entries_.
-      DoMonomorphicMiss(old_data, target_function);
+      DoMonomorphicMissJIT(old_data, target_function);
       break;
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
     case kICDataCid:
-      ASSERT(old_code.raw() == StubCode::ICCallThroughCode().raw());
-      DoICDataMiss(ICData::Cast(old_data), target_function);
+      DoICDataMissJIT(ICData::Cast(old_data), old_code, target_function);
       break;
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
     case kMegamorphicCacheCid:
-      ASSERT(old_code.raw() == StubCode::MegamorphicCall().raw());
+      ASSERT(old_code.raw() == StubCode::MegamorphicCall().raw() ||
+             (old_code.IsNull() && !should_consider_patching()));
       DoMegamorphicMiss(MegamorphicCache::Cast(old_data), target_function);
       break;
     default:
@@ -2017,6 +2129,60 @@
   }
 }
 
+static void InlineCacheMissHandler(Thread* thread,
+                                   Zone* zone,
+                                   const GrowableArray<const Instance*>& args,
+                                   const ICData& ic_data,
+                                   NativeArguments native_arguments) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  DartFrameIterator iterator(thread,
+                             StackFrameIterator::kNoCrossThreadIteration);
+  StackFrame* caller_frame = iterator.NextFrame();
+  const auto& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
+  const auto& caller_function =
+      Function::Handle(zone, caller_frame->LookupDartFunction());
+
+  PatchableCallHandler handler(thread, args, MissHandler::kInlineCacheMiss,
+                               native_arguments, caller_frame, caller_code,
+                               caller_function);
+
+  handler.ResolveSwitchAndReturn(ic_data);
+#else
+  UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+}
+
+// Handles inline cache misses by updating the IC data array of the call site.
+//   Arg0: Receiver object.
+//   Arg1: IC data object.
+//   Returns: target function with compiled code or null.
+// Modifies the instance call to hold the updated IC data array.
+DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) {
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(1));
+  RELEASE_ASSERT(!FLAG_precompiled_mode);
+  GrowableArray<const Instance*> args(1);
+  args.Add(&receiver);
+  InlineCacheMissHandler(thread, zone, args, ic_data, arguments);
+}
+
+// Handles inline cache misses by updating the IC data array of the call site.
+//   Arg0: Receiver object.
+//   Arg1: Argument after receiver.
+//   Arg2: IC data object.
+//   Returns: target function with compiled code or null.
+// Modifies the instance call to hold the updated IC data array.
+DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) {
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const Instance& other = Instance::CheckedHandle(zone, arguments.ArgAt(1));
+  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(2));
+  RELEASE_ASSERT(!FLAG_precompiled_mode);
+  GrowableArray<const Instance*> args(2);
+  args.Add(&receiver);
+  args.Add(&other);
+  InlineCacheMissHandler(thread, zone, args, ic_data, arguments);
+}
+
 // Handle the first use of an instance call
 //   Arg1: Receiver.
 //   Arg0: Stub out.
@@ -2040,40 +2206,20 @@
   const Function& caller_function =
       Function::Handle(zone, caller_frame->LookupDartFunction());
 
-  Object& old_data = Object::Handle(zone);
-  Code& old_code = Code::Handle(zone);
-
+  auto& old_data = Object::Handle(zone);
 #if defined(DART_PRECOMPILED_RUNTIME)
-  // Grab old_data and do potentially long-running step of resolving the
-  // target function before we stop mutators.
-  // This will reduce amount of time spent with all mutators are stopped
-  // hopefully leaving only code patching to be done then.
   old_data =
       CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code);
 #else
-  old_code ^= CodePatcher::GetInstanceCallAt(caller_frame->pc(), caller_code,
-                                             &old_data);
+  CodePatcher::GetInstanceCallAt(caller_frame->pc(), caller_code, &old_data);
 #endif
-  SwitchableCallHandler handler(thread, receiver, arguments, caller_frame,
-                                caller_code, caller_function);
-  const Function& target_function =
-      Function::Handle(zone, handler.ResolveTargetFunction(old_data));
-  thread->isolate_group()->RunWithStoppedMutators(
-      [&]() {
-#if defined(DART_PRECOMPILED_RUNTIME)
-        old_data = CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(),
-                                                        caller_code);
-#if defined(DEBUG)
-        old_code ^= CodePatcher::GetSwitchableCallTargetAt(caller_frame->pc(),
-                                                           caller_code);
-#endif
-#else
-        old_code ^= CodePatcher::GetInstanceCallAt(caller_frame->pc(),
-                                                   caller_code, &old_data);
-#endif
-        handler.HandleMiss(old_data, old_code, target_function);
-      },
-      /*use_force_growth=*/true);
+
+  GrowableArray<const Instance*> caller_arguments(1);
+  caller_arguments.Add(&receiver);
+  PatchableCallHandler handler(thread, caller_arguments,
+                               MissHandler::kSwitchableCallMiss, arguments,
+                               caller_frame, caller_code, caller_function);
+  handler.ResolveSwitchAndReturn(old_data);
 }
 
 // Used to find the correct receiver and function to invoke or to fall back to
@@ -2574,15 +2720,20 @@
 
   if (Compiler::CanOptimizeFunction(thread, function)) {
     if (FLAG_background_compilation) {
-      Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField());
-      while (!field.IsNull()) {
-        if (FLAG_trace_optimization || FLAG_trace_field_guards) {
-          THR_Print("Lazy disabling unboxing of %s\n", field.ToCString());
+      {
+        SafepointWriteRwLocker ml(thread,
+                                  thread->isolate_group()->program_lock());
+        Field& field =
+            Field::Handle(zone, isolate->GetDeoptimizingBoxedField());
+        while (!field.IsNull()) {
+          if (FLAG_trace_optimization || FLAG_trace_field_guards) {
+            THR_Print("Lazy disabling unboxing of %s\n", field.ToCString());
+          }
+          field.set_is_unboxing_candidate(false);
+          field.DeoptimizeDependentCode();
+          // Get next field.
+          field = isolate->GetDeoptimizingBoxedField();
         }
-        field.set_is_unboxing_candidate(false);
-        field.DeoptimizeDependentCode();
-        // Get next field.
-        field = isolate->GetDeoptimizingBoxedField();
       }
       if (!BackgroundCompiler::IsDisabled(isolate,
                                           /* optimizing_compiler = */ true) &&
@@ -3078,9 +3229,15 @@
   arguments.SetReturn(result);
 }
 
-DEFINE_RUNTIME_ENTRY(LateInitializationError, 1) {
+DEFINE_RUNTIME_ENTRY(LateFieldAssignedDuringInitializationError, 1) {
   const Field& field = Field::CheckedHandle(zone, arguments.ArgAt(0));
-  Exceptions::ThrowLateInitializationError(String::Handle(field.name()));
+  Exceptions::ThrowLateFieldAssignedDuringInitialization(
+      String::Handle(field.name()));
+}
+
+DEFINE_RUNTIME_ENTRY(LateFieldNotInitializedError, 1) {
+  const Field& field = Field::CheckedHandle(zone, arguments.ArgAt(0));
+  Exceptions::ThrowLateFieldNotInitialized(String::Handle(field.name()));
 }
 
 DEFINE_RUNTIME_ENTRY(NotLoaded, 0) {
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index 752ca63..0870d45 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -51,22 +51,20 @@
   if (runtime_entry->is_leaf()) {
     ASSERT(argument_count == runtime_entry->argument_count());
     __ LoadFromOffset(
-        kWord, TMP, THR,
-        compiler::target::Thread::OffsetFromThread(runtime_entry));
+        TMP, THR, compiler::target::Thread::OffsetFromThread(runtime_entry));
     __ str(TMP,
            compiler::Address(THR, compiler::target::Thread::vm_tag_offset()));
     __ blx(TMP);
     __ LoadImmediate(TMP, VMTag::kDartTagId);
     __ str(TMP,
            compiler::Address(THR, compiler::target::Thread::vm_tag_offset()));
-    ASSERT((kAbiPreservedCpuRegs & (1 << THR)) != 0);
-    ASSERT((kAbiPreservedCpuRegs & (1 << PP)) != 0);
+    COMPILE_ASSERT(IsAbiPreservedRegister(THR));
+    COMPILE_ASSERT(IsAbiPreservedRegister(PP));
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
     __ LoadFromOffset(
-        kWord, R9, THR,
-        compiler::target::Thread::OffsetFromThread(runtime_entry));
+        R9, THR, compiler::target::Thread::OffsetFromThread(runtime_entry));
     __ LoadImmediate(R4, argument_count);
     __ BranchLinkToRuntime();
   }
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index 1580e1a..93a80fd 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -73,8 +73,8 @@
     __ str(TMP, compiler::Address(THR, Thread::vm_tag_offset()));
     __ mov(SP, kCallLeafRuntimeCalleeSaveScratch2);
     __ mov(CSP, kCallLeafRuntimeCalleeSaveScratch1);
-    ASSERT((kAbiPreservedCpuRegs & (1 << THR)) != 0);
-    ASSERT((kAbiPreservedCpuRegs & (1 << PP)) != 0);
+    COMPILE_ASSERT(IsAbiPreservedRegister(THR));
+    COMPILE_ASSERT(IsAbiPreservedRegister(PP));
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 40f5bd8..34ac296 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -50,7 +50,8 @@
   V(UpdateFieldCid)                                                            \
   V(InitInstanceField)                                                         \
   V(InitStaticField)                                                           \
-  V(LateInitializationError)                                                   \
+  V(LateFieldAssignedDuringInitializationError)                                \
+  V(LateFieldNotInitializedError)                                              \
   V(CompileFunction)                                                           \
   V(SwitchableCallMiss)                                                        \
   V(NotLoaded)
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index bed2d5c..c84dc26 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -345,10 +345,6 @@
     // Keep :is_sync for asynchronous debugging.
     return false;
   }
-  if (str.raw() == Symbols::AsyncStackTraceVar().raw()) {
-    // Keep :async_stack_trace for asynchronous debugging.
-    return false;
-  }
   if (str.raw() == Symbols::FunctionTypeArgumentsVar().raw()) {
     // Keep :function_type_arguments for accessing type variables in debugging.
     return false;
@@ -697,7 +693,6 @@
     for (intptr_t i = 0; i < scope->num_variables(); i++) {
       LocalVariable* variable = scope->VariableAt(i);
       if (variable->is_forced_stack() ||
-          (variable->name().raw() == Symbols::StackTraceVar().raw()) ||
           (variable->name().raw() == Symbols::ExceptionVar().raw()) ||
           (variable->name().raw() == Symbols::SavedTryContextVar().raw()) ||
           (variable->name().raw() == Symbols::ArgDescVar().raw()) ||
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index b207114..6a674bb 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2238,14 +2238,15 @@
   LinkedHashMap& map = LinkedHashMap::Handle();
   Array& map_data = Array::Handle();
   Field& field = Field::Handle();
+  WeakProperty& wp = WeakProperty::Handle();
   String& name = String::Handle();
   limit = Utils::Minimum(limit, length);
   for (intptr_t i = 0; i < limit; ++i) {
     JSONObject jselement(&elements);
     element = path.At(i * 2);
     jselement.AddProperty("value", element);
-    // Interpret the word offset from parent as list index, map key
-    // or instance field.
+    // Interpret the word offset from parent as list index, map key,
+    // weak property, or instance field.
     if (i > 0) {
       slot_offset ^= path.At((i * 2) - 1);
       if (element.IsArray() || element.IsGrowableObjectArray()) {
@@ -2266,9 +2267,15 @@
             break;
           }
         }
+      } else if (element.IsWeakProperty()) {
+        wp ^= static_cast<WeakPropertyPtr>(element.raw());
+        element = wp.key();
+        jselement.AddProperty("parentMapKey", element);
       } else if (element.IsInstance()) {
         element_class = element.clazz();
         element_field_map = element_class.OffsetToFieldMap();
+        OS::PrintErr("Class: %s Map: %s\n", element_class.ToCString(),
+                     element_field_map.ToCString());
         intptr_t offset = slot_offset.Value();
         if (offset > 0 && offset < element_field_map.Length()) {
           field ^= element_field_map.At(offset);
@@ -3178,11 +3185,14 @@
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "PortList");
   {
-    Instance& port = Instance::Handle(zone.GetZone());
+    ReceivePort& port = ReceivePort::Handle(zone.GetZone());
     JSONArray arr(&jsobj, "ports");
     for (int i = 0; i < ports.Length(); ++i) {
       port ^= ports.At(i);
-      arr.AddValue(port);
+      // Don't report inactive ports.
+      if (PortMap::IsLivePort(port.Id())) {
+        arr.AddValue(port);
+      }
     }
   }
   return true;
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index f785a65..ab07c2a 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -398,18 +398,18 @@
     if (FLAG_trace_service) {
       OS::PrintErr("vm-service: ShutdownIsolate\n");
     }
-    Isolate* I = reinterpret_cast<Isolate*>(parameter);
-    ASSERT(ServiceIsolate::IsServiceIsolate(I));
+    Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(parameter));
     {
-      // Print the error if there is one.  This may execute dart code to
-      // print the exception object, so we need to use a StartIsolateScope.
-      ASSERT(Isolate::Current() == NULL);
-      StartIsolateScope start_scope(I);
-      Thread* T = Thread::Current();
-      ASSERT(I == T->isolate());
-      I->WaitForOutstandingSpawns();
+      auto T = Thread::Current();
+      TransitionNativeToVM transition(T);
       StackZone zone(T);
       HandleScope handle_scope(T);
+
+      auto I = T->isolate();
+      ASSERT(ServiceIsolate::IsServiceIsolate(I));
+
+      // Print the error if there is one.  This may execute dart code to
+      // print the exception object, so we need to use a StartIsolateScope.
       Error& error = Error::Handle(Z);
       error = T->sticky_error();
       if (!error.IsNull() && !error.IsUnwindError()) {
@@ -421,11 +421,8 @@
         OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Error: %s\n",
                      error.ToErrorCString());
       }
-      Dart::RunShutdownCallback();
     }
-
-    // Shut the isolate down.
-    Dart::ShutdownIsolate(I);
+    Dart_ShutdownIsolate();
     if (FLAG_trace_service) {
       OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Shutdown.\n");
     }
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 10a5996..6655cbe 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -926,19 +926,25 @@
 }
 
 uint32_t SnapshotWriter::GetObjectTags(ObjectPtr raw) {
-  return raw->ptr()->tags_;
+  uword tags = raw->ptr()->tags_;
+#if defined(HASH_IN_OBJECT_HEADER)
+  // Clear hash to make the narrowing cast safe / appease UBSAN.
+  tags = ObjectLayout::HashTag::update(0, tags);
+#endif
+  return tags;
 }
 
 uint32_t SnapshotWriter::GetObjectTags(ObjectLayout* raw) {
-  return raw->tags_;
+  uword tags = raw->tags_;
+#if defined(HASH_IN_OBJECT_HEADER)
+  // Clear hash to make the narrowing cast safe / appease UBSAN.
+  tags = ObjectLayout::HashTag::update(0, tags);
+#endif
+  return tags;
 }
 
 uword SnapshotWriter::GetObjectTagsAndHash(ObjectPtr raw) {
-  uword result = raw->ptr()->tags_;
-#if defined(HASH_IN_OBJECT_HEADER)
-  result |= static_cast<uword>(raw->ptr()->hash_) << 32;
-#endif
-  return result;
+  return raw->ptr()->tags_;
 }
 
 #define VM_OBJECT_CLASS_LIST(V)                                                \
@@ -1317,10 +1323,10 @@
   ASSERT(!IsSingletonClassId(class_id) && !IsBootstrapedClassId(class_id));
 
   // Write out the library url and class name.
-  LibraryPtr library = cls->library_;
+  LibraryPtr library = cls->library();
   ASSERT(library != Library::null());
   WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
-  WriteObjectImpl(cls->name_, kAsInlinedObject);
+  WriteObjectImpl(cls->name(), kAsInlinedObject);
 }
 
 void SnapshotWriter::WriteStaticImplicitClosure(
@@ -1340,11 +1346,11 @@
   // Write out the library url, class name and signature function name.
   ClassPtr cls = GetFunctionOwner(func);
   ASSERT(cls != Class::null());
-  LibraryPtr library = cls->ptr()->library_;
+  LibraryPtr library = cls->ptr()->library();
   ASSERT(library != Library::null());
-  WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
-  WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
-  WriteObjectImpl(func->ptr()->name_, kAsInlinedObject);
+  WriteObjectImpl(library->ptr()->url(), kAsInlinedObject);
+  WriteObjectImpl(cls->ptr()->name(), kAsInlinedObject);
+  WriteObjectImpl(func->ptr()->name(), kAsInlinedObject);
   WriteObjectImpl(delayed_type_arguments, kAsInlinedObject);
 }
 
@@ -1392,7 +1398,7 @@
 FunctionPtr SnapshotWriter::IsSerializableClosure(ClosurePtr closure) {
   // Extract the function object to check if this closure
   // can be sent in an isolate message.
-  FunctionPtr func = closure->ptr()->function_;
+  FunctionPtr func = closure->ptr()->function();
   // We only allow closure of top level methods or static functions in a
   // class to be sent in isolate messages.
   if (can_send_any_object() &&
@@ -1416,8 +1422,8 @@
 }
 
 ClassPtr SnapshotWriter::GetFunctionOwner(FunctionPtr func) {
-  ObjectPtr owner = func->ptr()->owner_;
-  uint32_t tags = GetObjectTags(owner);
+  ObjectPtr owner = func->ptr()->owner();
+  uword tags = GetObjectTags(owner);
   intptr_t class_id = ObjectLayout::ClassIdTag::decode(tags);
   if (class_id == kClassCid) {
     return static_cast<ClassPtr>(owner);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 90e62a0..2d15658 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -398,7 +398,6 @@
   friend class MirrorReference;
   friend class Namespace;
   friend class PatchClass;
-  friend class RedirectionData;
   friend class RegExp;
   friend class Script;
   friend class SignatureData;
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 4ed6a46..3f074ff 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -105,7 +105,7 @@
       return true;
   }
   if (func.is_abstract() || func.IsImplicitConstructor() ||
-      func.IsRedirectingFactory() || func.is_synthetic()) {
+      func.is_synthetic()) {
     return true;
   }
   if (func.IsNonImplicitClosureFunction() &&
@@ -565,6 +565,19 @@
 
     // Visit all closures for this isolate.
     VisitClosures(&ranges);
+
+    // Output constant coverage if coverage is requested.
+    if (IsReportRequested(kCoverage)) {
+      // Find all scripts. We need to go though all scripts because a script
+      // (even one we don't want) can add coverage to another library (i.e.
+      // potentially one we want).
+      DirectChainedHashMap<ScriptTableTrait> local_script_table;
+      GrowableArray<ScriptTableEntry*> local_script_table_entries;
+      CollectAllScripts(&local_script_table, &local_script_table_entries);
+      CollectConstConstructorCoverageFromScripts(&local_script_table_entries,
+                                                 &ranges);
+      CleanupCollectedScripts(&local_script_table, &local_script_table_entries);
+    }
   }
 
   // Print the script table.
@@ -572,5 +585,102 @@
   PrintScriptTable(&scripts);
 }
 
+void SourceReport::CollectAllScripts(
+    DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+    GrowableArray<ScriptTableEntry*>* local_script_table_entries) {
+  ScriptTableEntry wrapper;
+  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
+      zone(), thread()->isolate()->object_store()->libraries());
+  Library& lib = Library::Handle(zone());
+  Script& scriptRef = Script::Handle(zone());
+  for (int i = 0; i < libs.Length(); i++) {
+    lib ^= libs.At(i);
+    const Array& scripts = Array::Handle(zone(), lib.LoadedScripts());
+    for (intptr_t j = 0; j < scripts.Length(); j++) {
+      scriptRef ^= scripts.At(j);
+      const String& url = String::Handle(zone(), scriptRef.url());
+      wrapper.key = &url;
+      wrapper.script = &Script::Handle(zone(), scriptRef.raw());
+      ScriptTableEntry* pair = local_script_table->LookupValue(&wrapper);
+      if (pair != NULL) {
+        // Existing one.
+        continue;
+      }
+      // New one. Insert.
+      ScriptTableEntry* tmp = new ScriptTableEntry();
+      tmp->key = &url;
+      tmp->index = next_script_index_++;
+      tmp->script = wrapper.script;
+      local_script_table_entries->Add(tmp);
+      local_script_table->Insert(tmp);
+    }
+  }
+}
+
+void SourceReport::CleanupCollectedScripts(
+    DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+    GrowableArray<ScriptTableEntry*>* local_script_table_entries) {
+  for (intptr_t i = 0; i < local_script_table_entries->length(); i++) {
+    delete local_script_table_entries->operator[](i);
+    local_script_table_entries->operator[](i) = NULL;
+  }
+  local_script_table_entries->Clear();
+  local_script_table->Clear();
+}
+
+void SourceReport::CollectConstConstructorCoverageFromScripts(
+    GrowableArray<ScriptTableEntry*>* local_script_table_entries,
+    JSONArray* ranges) {
+  // Now output the wanted constant coverage.
+  for (intptr_t i = 0; i < local_script_table_entries->length(); i++) {
+    const Script* script = local_script_table_entries->At(i)->script;
+    bool script_ok = true;
+    if (script_ != NULL && !script_->IsNull()) {
+      if (script->raw() != script_->raw()) {
+        // This is the wrong script.
+        script_ok = false;
+      }
+    }
+
+    // Whether we want *this* script or not we need to look at the constant
+    // constructor coverage. Any of those could be in a script we *do* want.
+    {
+      Script& scriptRef = Script::Handle(zone());
+      const Array& constructors =
+          Array::Handle(kernel::CollectConstConstructorCoverageFrom(*script));
+      intptr_t constructors_count = constructors.Length();
+      Function& constructor = Function::Handle(zone());
+      Code& code = Code::Handle(zone());
+      for (intptr_t i = 0; i < constructors_count; i++) {
+        constructor ^= constructors.At(i);
+        // Check if we want coverage for this constructor.
+        if (ShouldSkipFunction(constructor)) {
+          continue;
+        }
+        scriptRef ^= constructor.script();
+        code ^= constructor.unoptimized_code();
+        const TokenPosition begin_pos = constructor.token_pos();
+        const TokenPosition end_pos = constructor.end_token_pos();
+        JSONObject range(ranges);
+        range.AddProperty("scriptIndex", GetScriptIndex(scriptRef));
+        range.AddProperty("compiled",
+                          !code.IsNull());  // Does this make a difference?
+        range.AddProperty("startPos", begin_pos);
+        range.AddProperty("endPos", end_pos);
+
+        JSONObject cov(&range, "coverage");
+        {
+          JSONArray hits(&cov, "hits");
+          hits.AddValue(begin_pos);
+        }
+        {
+          JSONArray misses(&cov, "misses");
+          // No misses
+        }
+      }
+    }
+  }
+}
+
 }  // namespace dart
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 0a3ddb1..4ec20c9 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -112,6 +112,18 @@
     }
   };
 
+  void CollectAllScripts(
+      DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+      GrowableArray<ScriptTableEntry*>* local_script_table_entries);
+
+  void CleanupCollectedScripts(
+      DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+      GrowableArray<ScriptTableEntry*>* local_script_table_entries);
+
+  void CollectConstConstructorCoverageFromScripts(
+      GrowableArray<ScriptTableEntry*>* local_script_table_entries,
+      JSONArray* ranges);
+
   intptr_t report_set_;
   CompileMode compile_mode_;
   Thread* thread_;
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index 5b146ff..fb01137 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -12,7 +12,9 @@
 
 // Keep in sync with
 // sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED.
-const intptr_t kStreamController_StateSubscribed = 1;
+const intptr_t k_StreamController__STATE_SUBSCRIBED = 1;
+// sdk/lib/async/future_impl.dart:_FutureListener.stateWhencomplete.
+const intptr_t k_FutureListener_stateWhencomplete = 8;
 
 // Find current yield index from async closure.
 // Async closures contains a variable, :await_jump_var that holds the index into
@@ -66,6 +68,8 @@
       stream_iterator_class(Class::Handle(zone)),
       future_result_or_listeners_field(Field::Handle(zone)),
       callback_field(Field::Handle(zone)),
+      future_listener_state_field(Field::Handle(zone)),
+      future_listener_result_field(Field::Handle(zone)),
       controller_controller_field(Field::Handle(zone)),
       var_data_field(Field::Handle(zone)),
       state_field(Field::Handle(zone)),
@@ -107,6 +111,12 @@
   callback_field =
       future_listener_class.LookupFieldAllowPrivate(Symbols::callback());
   ASSERT(!callback_field.IsNull());
+  future_listener_state_field =
+      future_listener_class.LookupFieldAllowPrivate(Symbols::state());
+  ASSERT(!future_listener_state_field.IsNull());
+  future_listener_result_field =
+      future_listener_class.LookupFieldAllowPrivate(Symbols::result());
+  ASSERT(!future_listener_result_field.IsNull());
   // - async*:
   controller_controller_field =
       async_start_stream_controller_class.LookupFieldAllowPrivate(
@@ -126,16 +136,24 @@
   ASSERT(!state_data_field.IsNull());
 }
 
-ClosurePtr CallerClosureFinder::GetCallerInFutureImpl(const Object& future_) {
-  ASSERT(!future_.IsNull());
-  ASSERT(future_.GetClassId() == future_impl_class.id());
+ClosurePtr CallerClosureFinder::GetCallerInFutureImpl(const Object& future) {
+  ASSERT(!future.IsNull());
+  ASSERT(future.GetClassId() == future_impl_class.id());
 
-  listener_ =
-      Instance::Cast(future_).GetField(future_result_or_listeners_field);
+  listener_ = Instance::Cast(future).GetField(future_result_or_listeners_field);
   if (listener_.GetClassId() != future_listener_class.id()) {
     return Closure::null();
   }
 
+  // If the _FutureListener is a whenComplete listener, follow the Future being
+  // completed, `result`, instead of the dangling whenComplete `callback`.
+  state_ = Instance::Cast(listener_).GetField(future_listener_state_field);
+  ASSERT(state_.IsSmi());
+  if (Smi::Cast(state_).Value() == k_FutureListener_stateWhencomplete) {
+    future_ = Instance::Cast(listener_).GetField(future_listener_result_field);
+    return GetCallerInFutureImpl(future_);
+  }
+
   callback_ = Instance::Cast(listener_).GetField(callback_field);
   // This happens for e.g.: await f().catchError(..);
   if (callback_.IsNull()) {
@@ -166,7 +184,7 @@
 
   state_ = Instance::Cast(controller_).GetField(state_field);
   ASSERT(state_.IsSmi());
-  if (Smi::Cast(state_).Value() != kStreamController_StateSubscribed) {
+  if (Smi::Cast(state_).Value() != k_StreamController__STATE_SUBSCRIBED) {
     return Closure::null();
   }
 
@@ -479,37 +497,4 @@
   return collected_frames_count;
 }
 
-intptr_t StackTraceUtils::ExtractAsyncStackTraceInfo(
-    Thread* thread,
-    Function* async_function,
-    StackTrace* async_stack_trace_out,
-    Array* async_code_array,
-    Array* async_pc_offset_array) {
-  if (thread->async_stack_trace() == StackTrace::null()) {
-    return 0;
-  }
-  *async_stack_trace_out = thread->async_stack_trace();
-  ASSERT(!async_stack_trace_out->IsNull());
-  const StackTrace& async_stack_trace =
-      StackTrace::Handle(thread->async_stack_trace());
-  const intptr_t async_stack_trace_length = async_stack_trace.Length();
-  // At least two entries (0: gap marker, 1: async function).
-  RELEASE_ASSERT(async_stack_trace_length >= 2);
-  // Validate the structure of this stack trace.
-  *async_code_array = async_stack_trace.code_array();
-  ASSERT(!async_code_array->IsNull());
-  *async_pc_offset_array = async_stack_trace.pc_offset_array();
-  ASSERT(!async_pc_offset_array->IsNull());
-  // We start with the asynchronous gap marker.
-  ASSERT(async_code_array->At(0) != Code::null());
-  ASSERT(async_code_array->At(0) == StubCode::AsynchronousGapMarker().raw());
-  const Object& code_object = Object::Handle(async_code_array->At(1));
-  ASSERT(code_object.IsCode());
-  *async_function = Code::Cast(code_object).function();
-  ASSERT(!async_function->IsNull());
-  ASSERT(async_function->IsAsyncFunction() ||
-         async_function->IsAsyncGenerator());
-  return async_stack_trace_length;
-}
-
 }  // namespace dart
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 660746a..215da83 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -54,6 +54,8 @@
 
   Field& future_result_or_listeners_field;
   Field& callback_field;
+  Field& future_listener_state_field;
+  Field& future_listener_result_field;
   Field& controller_controller_field;
   Field& var_data_field;
   Field& state_field;
@@ -111,17 +113,6 @@
                                 intptr_t array_offset,
                                 intptr_t count,
                                 int skip_frames);
-
-  /// If |thread| has no async_stack_trace, does nothing.
-  /// Populates |async_function| with the top function of the async stack
-  /// trace. Populates |async_stack_trace|, |async_code_array|, and
-  /// |async_pc_offset_array| with the thread's async_stack_trace.
-  /// Returns the length of the asynchronous stack trace.
-  static intptr_t ExtractAsyncStackTraceInfo(Thread* thread,
-                                             Function* async_function,
-                                             StackTrace* async_stack_trace,
-                                             Array* async_code_array,
-                                             Array* async_pc_offset_array);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index d127701..c08bfd6 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -7,6 +7,17 @@
 
 namespace dart {
 
+#define VM_TYPE_TESTING_STUB_CODE_LIST(V)                                      \
+  V(DefaultTypeTest)                                                           \
+  V(DefaultNullableTypeTest)                                                   \
+  V(TopTypeTypeTest)                                                           \
+  V(UnreachableTypeTest)                                                       \
+  V(TypeParameterTypeTest)                                                     \
+  V(NullableTypeParameterTypeTest)                                             \
+  V(SlowTypeTest)                                                              \
+  V(LazySpecializeTypeTest)                                                    \
+  V(LazySpecializeNullableTypeTest)
+
 // List of stubs created in the VM isolate, these stubs are shared by different
 // isolates running in this dart process.
 #define VM_STUB_CODE_LIST(V)                                                   \
@@ -75,19 +86,15 @@
   V(OneArgUnoptimizedStaticCall)                                               \
   V(TwoArgsUnoptimizedStaticCall)                                              \
   V(AssertSubtype)                                                             \
+  V(TypeIsTopTypeForSubtyping)                                                 \
+  V(TypeIsTopTypeForSubtypingNullSafe)                                         \
+  V(NullIsAssignableToType)                                                    \
+  V(NullIsAssignableToTypeNullSafe)                                            \
   V(Subtype1TestCache)                                                         \
-  V(Subtype2TestCache)                                                         \
-  V(Subtype4TestCache)                                                         \
-  V(Subtype6TestCache)                                                         \
-  V(DefaultTypeTest)                                                           \
-  V(DefaultNullableTypeTest)                                                   \
-  V(TopTypeTypeTest)                                                           \
-  V(UnreachableTypeTest)                                                       \
-  V(TypeParameterTypeTest)                                                     \
-  V(NullableTypeParameterTypeTest)                                             \
-  V(SlowTypeTest)                                                              \
-  V(LazySpecializeTypeTest)                                                    \
-  V(LazySpecializeNullableTypeTest)                                            \
+  V(Subtype3TestCache)                                                         \
+  V(Subtype5TestCache)                                                         \
+  V(Subtype7TestCache)                                                         \
+  VM_TYPE_TESTING_STUB_CODE_LIST(V)                                            \
   V(CallClosureNoSuchMethod)                                                   \
   V(FrameAwaitingMaterialization)                                              \
   V(AsynchronousGapMarker)                                                     \
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 7737d2a..1e408f1 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -30,7 +30,6 @@
   V(AssignIndexToken, "[]=")                                                   \
   V(AsyncFuture, ":async_future")                                              \
   V(AsyncOperation, ":async_op")                                               \
-  V(AsyncStackTraceVar, ":async_stack_trace")                                  \
   V(AsyncStarMoveNextHelper, "_asyncStarMoveNextHelper")                       \
   V(AwaitContextVar, ":await_ctx_var")                                         \
   V(AwaitJumpVar, ":await_jump_var")                                           \
@@ -46,7 +45,6 @@
   V(CheckLoaded, "_checkLoaded")                                               \
   V(Class, "Class")                                                            \
   V(ClassID, "ClassID")                                                        \
-  V(ClearAsyncThreadStackTrace, "_clearAsyncThreadStackTrace")                 \
   V(ClosureData, "ClosureData")                                                \
   V(ClosureParameter, ":closure")                                              \
   V(Code, "Code")                                                              \
@@ -66,19 +64,14 @@
   V(Current, "current")                                                        \
   V(CurrentContextVar, ":current_context_var")                                 \
   V(CyclicInitializationError, "CyclicInitializationError")                    \
-  V(LateInitializationError, "_LateInitializationError")                       \
   V(DartAsync, "dart:async")                                                   \
   V(DartCollection, "dart:collection")                                         \
   V(DartCore, "dart:core")                                                     \
   V(DartDeveloper, "dart:developer")                                           \
-  V(DartDeveloperCausalAsyncStacks, "dart.developer.causal_async_stacks")      \
   V(DartDeveloperTimeline, "dart.developer.timeline")                          \
   V(DartExtensionScheme, "dart-ext:")                                          \
   V(DartFfi, "dart:ffi")                                                       \
   V(DartFfiLibName, "ffi")                                                     \
-  V(DartWasm, "dart:wasm")                                                     \
-  V(DartWasmLibName, "wasm")                                                   \
-  V(DartLibraryWasm, "dart.library.wasm")                                      \
   V(DartIOLibName, "dart.io")                                                  \
   V(DartInternal, "dart:_internal")                                            \
   V(DartIsVM, "dart.isVM")                                                     \
@@ -100,6 +93,8 @@
   V(Default, "Default")                                                        \
   V(DefaultLabel, ":L")                                                        \
   V(DotCreate, "._create")                                                     \
+  V(DotFieldNI, ".fieldNI")                                                    \
+  V(DotFieldADI, ".fieldADI")                                                  \
   V(DotRange, ".range")                                                        \
   V(DotUnder, "._")                                                            \
   V(DotValue, ".value")                                                        \
@@ -202,6 +197,7 @@
   V(IteratorParameter, ":iterator")                                            \
   V(KernelProgramInfo, "KernelProgramInfo")                                    \
   V(LanguageError, "LanguageError")                                            \
+  V(LateError, "LateError")                                                    \
   V(LeftShiftOperator, "<<")                                                   \
   V(Length, "length")                                                          \
   V(LessEqualOperator, "<=")                                                   \
@@ -244,14 +240,12 @@
   V(QuoteIsNotASubtypeOf, "' is not a subtype of ")                            \
   V(RParenArrow, ") => ")                                                      \
   V(RangeError, "RangeError")                                                  \
-  V(RedirectionData, "RedirectionData")                                        \
   V(RegExp, "RegExp")                                                          \
   V(RightShiftOperator, ">>")                                                  \
   V(SavedTryContextVar, ":saved_try_context_var")                              \
   V(Script, "Script")                                                          \
   V(SecondArg, "y")                                                            \
   V(Set, "set")                                                                \
-  V(SetAsyncThreadStackTrace, "_setAsyncThreadStackTrace")                     \
   V(SetterPrefix, "set:")                                                      \
   V(SignatureData, "SignatureData")                                            \
   V(SingleTargetCache, "SingleTargetCache")                                    \
@@ -262,7 +256,6 @@
   V(SpaceWhereNewLine, " where\n")                                             \
   V(StackOverflowError, "StackOverflowError")                                  \
   V(StackTraceParameter, ":stack_trace")                                       \
-  V(StackTraceVar, ":stack_trace_var")                                         \
   V(Stream, "stream")                                                          \
   V(StreamController, "StreamController")                                      \
   V(StreamIterator, "StreamIterator")                                          \
@@ -302,11 +295,6 @@
   V(UnwindError, "UnwindError")                                                \
   V(Value, "value")                                                            \
   V(Values, "values")                                                          \
-  V(WasmInt32, "Int32")                                                        \
-  V(WasmInt64, "Int64")                                                        \
-  V(WasmFloat, "Float")                                                        \
-  V(WasmDouble, "Double")                                                      \
-  V(WasmVoid, "Void")                                                          \
   V(YieldKw, "yield")                                                          \
   V(_AsyncAwaitStart, "start")                                                 \
   V(_AsyncStarStreamController, "_AsyncStarStreamController")                  \
@@ -472,6 +460,8 @@
   V(controller, "controller")                                                  \
   V(current_character, ":current_character")                                   \
   V(current_position, ":current_position")                                     \
+  V(dynamic_assert_assignable_stc_check,                                       \
+    ":dynamic_assert_assignable_stc_check")                                    \
   V(getID, "getID")                                                            \
   V(hashCode, "get:hashCode")                                                  \
   V(identityHashCode, "identityHashCode")                                      \
@@ -488,13 +478,14 @@
   V(position_registers, ":position_registers")                                 \
   V(print, "print")                                                            \
   V(removeLast, "removeLast")                                                  \
-  V(result, ":result")                                                         \
+  V(c_result, ":result")                                                       \
+  V(result, "result")                                                          \
   V(stack, ":stack")                                                           \
   V(stack_pointer, ":stack_pointer")                                           \
   V(start_index_param, ":start_index_param")                                   \
+  V(state, "state")                                                            \
   V(string_param, ":string_param")                                             \
   V(string_param_length, ":string_param_length")                               \
-  V(timeout, "timeout")                                                        \
   V(toString, "toString")                                                      \
   V(vm_prefer_inline, "vm:prefer-inline")                                      \
   V(vm_entry_point, "vm:entry-point")                                          \
@@ -502,8 +493,10 @@
   V(vm_inferred_type_metadata, "vm.inferred-type.metadata")                    \
   V(vm_never_inline, "vm:never-inline")                                        \
   V(vm_non_nullable_result_type, "vm:non-nullable-result-type")                \
+  V(vm_recognized, "vm:recognized")                                            \
   V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn")            \
-  V(vm_procedure_attributes_metadata, "vm.procedure-attributes.metadata")
+  V(vm_procedure_attributes_metadata, "vm.procedure-attributes.metadata")      \
+  V(vm_ffi_struct_fields, "vm:ffi:struct-fields")
 
 // Contains a list of frequently used strings in a canonicalized form. This
 // list is kept in the vm_isolate in order to share the copy across isolates
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 703dfabd..4954982 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -234,7 +234,6 @@
 DEFINE_TAGGED_POINTER(Function, Object)
 DEFINE_TAGGED_POINTER(ClosureData, Object)
 DEFINE_TAGGED_POINTER(SignatureData, Object)
-DEFINE_TAGGED_POINTER(RedirectionData, Object)
 DEFINE_TAGGED_POINTER(FfiTrampolineData, Object)
 DEFINE_TAGGED_POINTER(Field, Object)
 DEFINE_TAGGED_POINTER(Script, Object)
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 68448fc..04b895a 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -71,7 +71,6 @@
       store_buffer_block_(NULL),
       marking_stack_block_(NULL),
       vm_tag_(0),
-      async_stack_trace_(StackTrace::null()),
       unboxed_int64_runtime_arg_(0),
       active_exception_(Object::null()),
       active_stacktrace_(Object::null()),
@@ -215,19 +214,6 @@
 #undef REUSABLE_HANDLE_ALLOCATION
 }
 
-#ifndef PRODUCT
-// Collect information about each individual zone associated with this thread.
-void Thread::PrintJSON(JSONStream* stream) const {
-  JSONObject jsobj(stream);
-  jsobj.AddProperty("type", "_Thread");
-  jsobj.AddPropertyF("id", "threads/%" Pd "",
-                     OSThread::ThreadIdToIntPtr(os_thread()->trace_id()));
-  jsobj.AddProperty("kind", TaskKindToCString(task_kind()));
-  jsobj.AddPropertyF("_zoneHighWatermark", "%" Pu "", zone_high_watermark());
-  jsobj.AddPropertyF("_zoneCapacity", "%" Pu "", current_zone_capacity());
-}
-#endif
-
 GrowableObjectArrayPtr Thread::pending_functions() {
   if (pending_functions_ == GrowableObjectArray::null()) {
     pending_functions_ = GrowableObjectArray::New(Heap::kOld);
@@ -285,19 +271,6 @@
   }
 }
 
-StackTracePtr Thread::async_stack_trace() const {
-  return async_stack_trace_;
-}
-
-void Thread::set_async_stack_trace(const StackTrace& stack_trace) {
-  ASSERT(!stack_trace.IsNull());
-  async_stack_trace_ = stack_trace.raw();
-}
-
-void Thread::clear_async_stack_trace() {
-  async_stack_trace_ = StackTrace::null();
-}
-
 bool Thread::EnterIsolate(Isolate* isolate) {
   const bool kIsMutatorThread = true;
   Thread* thread = isolate->ScheduleThread(kIsMutatorThread);
@@ -667,7 +640,6 @@
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&active_exception_));
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&active_stacktrace_));
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
-  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&async_stack_trace_));
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&ffi_callback_code_));
 
   // Visit the api local scope as it has all the api local handles.
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 9cabac7..cc3c410 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -657,13 +657,6 @@
   void ClearStickyError();
   DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();
 
-  StackTracePtr async_stack_trace() const;
-  void set_async_stack_trace(const StackTrace& stack_trace);
-  void clear_async_stack_trace();
-  static intptr_t async_stack_trace_offset() {
-    return OFFSET_OF(Thread, async_stack_trace_);
-  }
-
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object)                                \
   void set_reusable_##object##_handle_scope_active(bool value) {               \
@@ -922,7 +915,6 @@
   MarkingStackBlock* marking_stack_block_;
   MarkingStackBlock* deferred_marking_stack_block_;
   uword volatile vm_tag_;
-  StackTracePtr async_stack_trace_;
   // Memory location dedicated for passing unboxed int64 values from
   // generated code to runtime.
   // TODO(dartbug.com/33549): Clean this up when unboxed values
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 8ef9227..f4f6c45 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -95,45 +95,6 @@
   }
 }
 
-#ifndef PRODUCT
-void ThreadRegistry::PrintJSON(JSONStream* stream) const {
-  MonitorLocker ml(threads_lock());
-  JSONArray threads(stream);
-  Thread* current = active_list_;
-  while (current != NULL) {
-    threads.AddValue(current);
-    current = current->next_;
-  }
-}
-#endif
-
-intptr_t ThreadRegistry::CountZoneHandles(Isolate* isolate_of_interest) const {
-  MonitorLocker ml(threads_lock());
-  intptr_t count = 0;
-  Thread* current = active_list_;
-  while (current != NULL) {
-    if (current->isolate() == isolate_of_interest) {
-      count += current->CountZoneHandles();
-    }
-    current = current->next_;
-  }
-  return count;
-}
-
-intptr_t ThreadRegistry::CountScopedHandles(
-    Isolate* isolate_of_interest) const {
-  MonitorLocker ml(threads_lock());
-  intptr_t count = 0;
-  Thread* current = active_list_;
-  while (current != NULL) {
-    if (current->isolate() == isolate_of_interest) {
-      count += current->CountScopedHandles();
-    }
-    current = current->next_;
-  }
-  return count;
-}
-
 void ThreadRegistry::AddToActiveListLocked(Thread* thread) {
   ASSERT(thread != NULL);
   ASSERT(threads_lock()->IsOwnedByCurrentThread());
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index d8dc02e..e0c80a3 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -37,9 +37,6 @@
   void PrintJSON(JSONStream* stream) const;
 #endif
 
-  intptr_t CountZoneHandles(Isolate* isolate_of_interest) const;
-  intptr_t CountScopedHandles(Isolate* isolate_of_interest) const;
-
  private:
   Thread* active_list() const { return active_list_; }
   Monitor* threads_lock() const { return &threads_lock_; }
diff --git a/runtime/vm/thread_state.h b/runtime/vm/thread_state.h
index 90cd58e..58e57aa 100644
--- a/runtime/vm/thread_state.h
+++ b/runtime/vm/thread_state.h
@@ -50,9 +50,6 @@
 
   void IncrementMemoryCapacity(uintptr_t value) {
     current_zone_capacity_ += value;
-    if (current_zone_capacity_ > zone_high_watermark_) {
-      zone_high_watermark_ = current_zone_capacity_;
-    }
   }
 
   void DecrementMemoryCapacity(uintptr_t value) {
@@ -61,9 +58,6 @@
   }
 
   uintptr_t current_zone_capacity() const { return current_zone_capacity_; }
-  uintptr_t zone_high_watermark() const { return zone_high_watermark_; }
-
-  void ResetHighWatermark() { zone_high_watermark_ = current_zone_capacity_; }
 
   StackResource* top_resource() const { return top_resource_; }
   void set_top_resource(StackResource* value) { top_resource_ = value; }
@@ -101,7 +95,6 @@
   OSThread* os_thread_ = nullptr;
   Zone* zone_ = nullptr;
   uintptr_t current_zone_capacity_ = 0;
-  uintptr_t zone_high_watermark_ = 0;
   StackResource* top_resource_ = nullptr;
   LongJumpScope* long_jump_base_ = nullptr;
 
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 048cda9..1640296 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -296,7 +296,9 @@
   bool wait = true;
 
   EXPECT(isolate->heap()->GrowthControlState());
-  isolate->heap()->DisableGrowthControl();
+
+  NoHeapGrowthControlScope no_heap_growth_scope;
+
   for (intptr_t i = 0; i < kTaskCount; i++) {
     Dart::thread_pool()->Run<SimpleTaskWithZoneAllocation>(
         (i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait);
@@ -311,37 +313,6 @@
     done_count = 0;
   }
 
-  // Get the information for the current isolate.
-  // We only need to check the current isolate since all tasks are spawned
-  // inside this single isolate.
-  JSONStream stream;
-  isolate->PrintJSON(&stream, false);
-  const char* json = stream.ToCString();
-
-  Thread* current_thread = Thread::Current();
-
-  // Confirm all expected entries are in the JSON output.
-  for (intptr_t i = 0; i < kTaskCount; i++) {
-    Thread* thread = threads[i];
-    StackZone stack_zone(current_thread);
-    Zone* current_zone = current_thread->zone();
-
-    // Check the thread exists and is the correct size.
-    char* thread_info_buf = OS::SCreate(
-        current_zone,
-        "\"type\":\"_Thread\","
-        "\"id\":\"threads\\/%" Pd
-        "\","
-        "\"kind\":\"%s\","
-        "\"_zoneHighWatermark\":\"%" Pu
-        "\","
-        "\"_zoneCapacity\":\"%" Pu "\"",
-        OSThread::ThreadIdToIntPtr(thread->os_thread()->trace_id()),
-        Thread::TaskKindToCString(thread->task_kind()),
-        thread->zone_high_watermark(), thread->current_zone_capacity());
-    EXPECT_SUBSTRING(thread_info_buf, json);
-  }
-
   // Unblock the tasks so they can finish.
   {
     MonitorLocker sync_ml(&sync);
@@ -1027,6 +998,38 @@
   EXPECT(!lock.IsCurrentThreadWriter());
 }
 
+template <typename LockType, typename LockerType>
+static void RunLockerWithLongJumpTest() {
+  const intptr_t kNumIterations = 5;
+  intptr_t execution_count = 0;
+  intptr_t thrown_count = 0;
+  LockType lock;
+  for (intptr_t i = 0; i < kNumIterations; ++i) {
+    LongJumpScope jump;
+    if (setjmp(*jump.Set()) == 0) {
+      LockerType locker(Thread::Current(), &lock);
+      execution_count++;
+      Thread::Current()->long_jump_base()->Jump(
+          1, Object::background_compilation_error());
+    } else {
+      thrown_count++;
+    }
+  }
+  EXPECT_EQ(kNumIterations, execution_count);
+  EXPECT_EQ(kNumIterations, thrown_count);
+}
+ISOLATE_UNIT_TEST_CASE(SafepointRwLockWriteWithLongJmp) {
+  RunLockerWithLongJumpTest<SafepointRwLock, SafepointWriteRwLocker>();
+}
+
+ISOLATE_UNIT_TEST_CASE(SafepointRwLockReadWithLongJmp) {
+  RunLockerWithLongJumpTest<SafepointRwLock, SafepointReadRwLocker>();
+}
+
+ISOLATE_UNIT_TEST_CASE(SafepointMutexLockerWithLongJmp) {
+  RunLockerWithLongJumpTest<Mutex, SafepointMutexLocker>();
+}
+
 struct ReaderThreadState {
   ThreadJoinId reader_id = OSThread::kInvalidThreadJoinId;
   SafepointRwLock* rw_lock = nullptr;
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index d5be399..38e739a 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -574,7 +574,7 @@
 };
 
 // A block of |TimelineEvent|s. Not thread safe.
-class TimelineEventBlock {
+class TimelineEventBlock : public MallocAllocated {
  public:
   static const intptr_t kBlockSize = 64;
 
@@ -707,7 +707,7 @@
 };
 
 // Recorder of |TimelineEvent|s.
-class TimelineEventRecorder {
+class TimelineEventRecorder : public MallocAllocated {
  public:
   TimelineEventRecorder();
   virtual ~TimelineEventRecorder() {}
diff --git a/runtime/vm/token_position.cc b/runtime/vm/token_position.cc
index b94ddff..0f8ae68 100644
--- a/runtime/vm/token_position.cc
+++ b/runtime/vm/token_position.cc
@@ -27,12 +27,12 @@
 }
 
 #define DEFINE_VALUES(name, value)                                             \
-  const TokenPosition TokenPosition::k##name = TokenPosition(value);
+  const TokenPosition TokenPosition::k##name(value);
 SENTINEL_TOKEN_DESCRIPTORS(DEFINE_VALUES);
 #undef DEFINE_VALUES
-const TokenPosition TokenPosition::kMinSource = TokenPosition(kMinSourcePos);
+const TokenPosition TokenPosition::kMinSource(kMinSourcePos);
 
-const TokenPosition TokenPosition::kMaxSource = TokenPosition(kMaxSourcePos);
+const TokenPosition TokenPosition::kMaxSource(kMaxSourcePos);
 
 const char* TokenPosition::ToCString() const {
   switch (value_) {
diff --git a/runtime/vm/token_position.h b/runtime/vm/token_position.h
index c28f9a4..270a14c 100644
--- a/runtime/vm/token_position.h
+++ b/runtime/vm/token_position.h
@@ -95,11 +95,10 @@
   // Encode for writing into a snapshot.
   int32_t SnapshotEncode();
 
-  // Increment the token position.
+  // Given a real token position, returns the next real token position.
   TokenPosition Next() {
     ASSERT(IsReal());
-    value_++;
-    return *this;
+    return TokenPosition(value_ + 1);
   }
 
   // The raw value.
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index f86d082..5f3d862 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -95,8 +95,9 @@
   auto isolate = Isolate::Current();
 
   if (type.IsTypeRef()) {
-    return isolate->null_safety() ? StubCode::DefaultTypeTest().raw()
-                                  : StubCode::DefaultNullableTypeTest().raw();
+    return isolate->use_strict_null_safety_checks()
+               ? StubCode::DefaultTypeTest().raw()
+               : StubCode::DefaultNullableTypeTest().raw();
   }
 
   // During bootstrapping we have no access to stubs yet, so we'll just return
@@ -281,7 +282,8 @@
     __ Bind(&continue_checking);
 
   } else if (type.IsObjectType()) {
-    ASSERT(type.IsNonNullable() && Isolate::Current()->null_safety());
+    ASSERT(type.IsNonNullable() &&
+           Isolate::Current()->use_strict_null_safety_checks());
     compiler::Label continue_checking;
     __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
     __ BranchIf(EQUAL, &continue_checking);
@@ -493,8 +495,8 @@
     // Weak NNBD mode uses LEGACY_SUBTYPE which ignores nullability.
     // We don't need to check nullability of LHS for nullable and legacy RHS
     // ("Right Legacy", "Right Nullable" rules).
-    if (Isolate::Current()->null_safety() && !type_arg.IsNullable() &&
-        !type_arg.IsLegacy()) {
+    if (Isolate::Current()->use_strict_null_safety_checks() &&
+        !type_arg.IsNullable() && !type_arg.IsLegacy()) {
       // Nullable type is not a subtype of non-nullable type.
       // TODO(dartbug.com/40736): Allocate a register for instance type argument
       // and avoid reloading it.
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 528aeb9e..52f46f8 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -220,7 +220,7 @@
 }
 
 bool TestCase::IsNNBD() {
-  return !KernelIsolate::GetExperimentalFlag("no-non-nullable");
+  return KernelIsolate::GetExperimentalFlag(ExperimentalFeature::non_nullable);
 }
 
 #ifndef PRODUCT
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 7010b26..350c241 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -16,6 +16,7 @@
 
 #include "platform/assert.h"
 #include "platform/utils.h"
+#include "vm/heap/pages.h"
 #include "vm/isolate.h"
 
 // #define VIRTUAL_MEMORY_LOGGING 1
@@ -75,7 +76,7 @@
   // Also detect for missing support of memfd_create syscall.
   if (FLAG_dual_map_code) {
     intptr_t size = PageSize();
-    intptr_t alignment = 256 * 1024;  // e.g. heap page size.
+    intptr_t alignment = kOldPageSize;
     VirtualMemory* vm = AllocateAligned(size, alignment, true, "memfd-test");
     if (vm == NULL) {
       LOG_INFO("memfd_create not supported; disabling dual mapping of code.\n");
@@ -93,6 +94,25 @@
     delete vm;
   }
 #endif  // defined(DUAL_MAPPING_SUPPORTED)
+
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+  FILE* fp = fopen("/proc/sys/vm/max_map_count", "r");
+  if (fp != nullptr) {
+    size_t max_map_count = 0;
+    int count = fscanf(fp, "%zu", &max_map_count);
+    fclose(fp);
+    if (count == 1) {
+      size_t max_heap_pages = FLAG_old_gen_heap_size * MB / kOldPageSize;
+      if (max_map_count < max_heap_pages) {
+        OS::PrintErr(
+            "warning: vm.max_map_count (%zu) is not large enough to support "
+            "--old_gen_heap_size=%d. Consider increasing it with `sysctl -w "
+            "vm.max_map_count=%zu`\n",
+            max_map_count, FLAG_old_gen_heap_size, max_heap_pages);
+      }
+    }
+  }
+#endif
 }
 
 bool VirtualMemory::DualMappingEnabled() {
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index a0e71ef..0f71c57 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -21,6 +21,7 @@
   "bootstrap_natives.h",
   "bss_relocs.cc",
   "bss_relocs.h",
+  "canonical_tables.cc",
   "canonical_tables.h",
   "class_finalizer.cc",
   "class_finalizer.h",
@@ -98,6 +99,8 @@
   "elf.h",
   "exceptions.cc",
   "exceptions.h",
+  "experimental_features.cc",
+  "experimental_features.h",
   "ffi_callback_trampolines.cc",
   "ffi_callback_trampolines.h",
   "field_table.cc",
@@ -449,3 +452,15 @@
   "virtual_memory_test.cc",
   "zone_test.cc",
 ]
+
+constants_sources = [
+  "constants_arm.cc",
+  "constants_arm.h",
+  "constants_arm64.cc",
+  "constants_arm64.h",
+  "constants_base.h",
+  "constants_ia32.cc",
+  "constants_ia32.h",
+  "constants_x64.cc",
+  "constants_x64.h",
+]
diff --git a/samples/ffi/async/async_test.dart b/samples/ffi/async/async_test.dart
index 297a76e..f438582 100644
--- a/samples/ffi/async/async_test.dart
+++ b/samples/ffi/async/async_test.dart
@@ -6,8 +6,6 @@
 //
 // SharedObjects=ffi_test_dynamic_library ffi_test_functions
 
-// @dart = 2.9
-
 import 'sample_async_callback.dart' as sample0;
 import 'sample_native_port_call.dart' as sample1;
 
diff --git a/samples/ffi/async/sample_async_callback.dart b/samples/ffi/async/sample_async_callback.dart
index 5e6d79a..59ae31b 100644
--- a/samples/ffi/async/sample_async_callback.dart
+++ b/samples/ffi/async/sample_async_callback.dart
@@ -8,8 +8,6 @@
 //
 // TODO(dartbug.com/37022): Update this when we get real async callbacks.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 import 'dart:isolate';
 
diff --git a/samples/ffi/async/sample_native_port_call.dart b/samples/ffi/async/sample_native_port_call.dart
index a2c3ee4..302a50f 100644
--- a/samples/ffi/async/sample_native_port_call.dart
+++ b/samples/ffi/async/sample_native_port_call.dart
@@ -16,8 +16,6 @@
 // The advantage is that finalizers can be used when passing ownership of data
 // (buffers) from C to Dart.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 import 'dart:isolate';
 import 'dart:typed_data';
@@ -79,8 +77,8 @@
 }
 
 class CppRequest {
-  final SendPort replyPort;
-  final int pendingCall;
+  final SendPort? replyPort;
+  final int? pendingCall;
   final String method;
   final Uint8List data;
 
@@ -114,9 +112,9 @@
     final int argument = cppRequest.data[0];
     final int result = myCallback1(argument);
     final cppResponse =
-        CppResponse(cppRequest.pendingCall, Uint8List.fromList([result]));
+        CppResponse(cppRequest.pendingCall!, Uint8List.fromList([result]));
     print('Dart:   Responding: $cppResponse');
-    cppRequest.replyPort.send(cppResponse.toCppMessage());
+    cppRequest.replyPort!.send(cppResponse.toCppMessage());
   } else if (cppRequest.method == 'myCallback2') {
     final int argument = cppRequest.data[0];
     myCallback2(argument);
diff --git a/samples/ffi/coordinate.dart b/samples/ffi/coordinate.dart
index 4ff34f5..8a54ba9 100644
--- a/samples/ffi/coordinate.dart
+++ b/samples/ffi/coordinate.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import "package:ffi/ffi.dart";
@@ -11,12 +9,12 @@
 /// Sample struct for dart:ffi library.
 class Coordinate extends Struct {
   @Double()
-  double x;
+  external double x;
 
   @Double()
-  double y;
+  external double y;
 
-  Pointer<Coordinate> next;
+  external Pointer<Coordinate> next;
 
   factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
     return allocate<Coordinate>().ref
diff --git a/samples/ffi/dylib_utils.dart b/samples/ffi/dylib_utils.dart
index 39653fa..220c0fc 100644
--- a/samples/ffi/dylib_utils.dart
+++ b/samples/ffi/dylib_utils.dart
@@ -2,13 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 import 'dart:io' show Platform;
 
-String _platformPath(String name, {String path}) {
-  if (path == null) path = "";
+String _platformPath(String name, String path) {
   if (Platform.isLinux || Platform.isAndroid)
     return path + "lib" + name + ".so";
   if (Platform.isMacOS) return path + "lib" + name + ".dylib";
@@ -16,7 +13,7 @@
   throw Exception("Platform not implemented");
 }
 
-DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
-  String fullPath = _platformPath(name, path: path);
+DynamicLibrary dlopenPlatformSpecific(String name, {String path = ""}) {
+  String fullPath = _platformPath(name, path);
   return DynamicLibrary.open(fullPath);
 }
diff --git a/samples/ffi/resource_management/pool.dart b/samples/ffi/resource_management/pool.dart
index 776c331..7064f9f 100644
--- a/samples/ffi/resource_management/pool.dart
+++ b/samples/ffi/resource_management/pool.dart
@@ -4,8 +4,6 @@
 //
 // Explicit pool used for managing resources.
 
-// @dart = 2.9
-
 import "dart:async";
 import 'dart:convert';
 import 'dart:ffi';
diff --git a/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart b/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart
index 8d3401b..cab2cb0 100644
--- a/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart
+++ b/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart
@@ -4,8 +4,6 @@
 //
 // Sample illustrating resources are not cleaned up when isolate is shutdown.
 
-// @dart = 2.9
-
 import 'dart:io';
 import "dart:isolate";
 import 'dart:ffi';
@@ -24,7 +22,7 @@
       receiveFromHelper.sendPort,
     );
     print("Main: Helper started.");
-    Pointer<SomeResource> resource;
+    Pointer<SomeResource> resource = nullptr;
     receiveFromHelper.listen((message) {
       if (message is int) {
         resource = Pointer<SomeResource>.fromAddress(message);
diff --git a/samples/ffi/resource_management/pool_sample.dart b/samples/ffi/resource_management/pool_sample.dart
index 87c5e39..00ee1ae 100644
--- a/samples/ffi/resource_management/pool_sample.dart
+++ b/samples/ffi/resource_management/pool_sample.dart
@@ -4,8 +4,6 @@
 //
 // Sample illustrating resource management with an explicit pool.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:expect/expect.dart';
diff --git a/samples/ffi/resource_management/pool_zoned_sample.dart b/samples/ffi/resource_management/pool_zoned_sample.dart
index 0b4e8ff..05f1794 100644
--- a/samples/ffi/resource_management/pool_zoned_sample.dart
+++ b/samples/ffi/resource_management/pool_zoned_sample.dart
@@ -4,8 +4,6 @@
 //
 // Sample illustrating resource management with an implicit pool in the zone.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:expect/expect.dart';
diff --git a/samples/ffi/resource_management/resource_management_test.dart b/samples/ffi/resource_management/resource_management_test.dart
index 4b2bbb0..1cc14f7 100644
--- a/samples/ffi/resource_management/resource_management_test.dart
+++ b/samples/ffi/resource_management/resource_management_test.dart
@@ -6,8 +6,6 @@
 //
 // SharedObjects=ffi_test_dynamic_library ffi_test_functions
 
-// @dart = 2.9
-
 import 'pool_isolate_shutdown_sample.dart' as pool_isolate;
 import 'pool_sample.dart' as pool;
 import 'pool_zoned_sample.dart' as pool_zoned;
diff --git a/samples/ffi/resource_management/unmanaged_sample.dart b/samples/ffi/resource_management/unmanaged_sample.dart
index b8c9971..9c3e0f0 100644
--- a/samples/ffi/resource_management/unmanaged_sample.dart
+++ b/samples/ffi/resource_management/unmanaged_sample.dart
@@ -4,8 +4,6 @@
 //
 // Sample illustrating manual resource management, not advised.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:expect/expect.dart';
diff --git a/samples/ffi/sample_ffi_bitfield.dart b/samples/ffi/sample_ffi_bitfield.dart
index 91bb65d..cc10a2d 100644
--- a/samples/ffi/sample_ffi_bitfield.dart
+++ b/samples/ffi/sample_ffi_bitfield.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:ffi/ffi.dart';
@@ -20,7 +18,7 @@
 /// } ScreenCellAttrs;
 class ScreenCellAttrs extends Struct {
   @Int16()
-  int bits;
+  external int bits;
 
   int get bold => getBits(kBoldFieldOffset, kBoldFieldLength);
   void set bold(int value) =>
diff --git a/samples/ffi/sample_ffi_data.dart b/samples/ffi/sample_ffi_data.dart
index 09dba76..8e713d0 100644
--- a/samples/ffi/sample_ffi_data.dart
+++ b/samples/ffi/sample_ffi_data.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 import 'package:ffi/ffi.dart';
 
diff --git a/samples/ffi/sample_ffi_dynamic_library.dart b/samples/ffi/sample_ffi_dynamic_library.dart
index 94863d0..28772ff 100644
--- a/samples/ffi/sample_ffi_dynamic_library.dart
+++ b/samples/ffi/sample_ffi_dynamic_library.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'dylib_utils.dart';
diff --git a/samples/ffi/sample_ffi_functions.dart b/samples/ffi/sample_ffi_functions.dart
index 4cd30b0..bff74eb 100644
--- a/samples/ffi/sample_ffi_functions.dart
+++ b/samples/ffi/sample_ffi_functions.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:ffi/ffi.dart';
@@ -202,46 +200,6 @@
   }
 
   {
-    // Passing in null for an int argument throws a null pointer exception.
-    BinaryOp sumPlus42 =
-        ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
-
-    int x = null;
-    try {
-      sumPlus42(43, x);
-    } on Error {
-      print('Expected exception on passing null for int');
-    }
-  }
-
-  {
-    // Passing in null for a double argument throws a null pointer exception.
-    DoubleUnaryOp times1_337Double = ffiTestFunctions
-        .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
-
-    double x = null;
-    try {
-      times1_337Double(x);
-    } on Error {
-      print('Expected exception on passing null for double');
-    }
-  }
-
-  {
-    // Passing in null for an int argument throws a null pointer exception.
-    VigesimalOp sumManyNumbers = ffiTestFunctions
-        .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
-
-    int x = null;
-    try {
-      sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13,
-          14.0, 15, 16.0, 17, 18.0, x, 20.0);
-    } on Error {
-      print('Expected exception on passing null for int');
-    }
-  }
-
-  {
     // Passing in nullptr for a pointer argument results in a nullptr in c.
     Int64PointerUnOp nullableInt64ElemAt1 =
         ffiTestFunctions.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>(
diff --git a/samples/ffi/sample_ffi_functions_callbacks.dart b/samples/ffi/sample_ffi_functions_callbacks.dart
index 79f9a41..affdcef 100644
--- a/samples/ffi/sample_ffi_functions_callbacks.dart
+++ b/samples/ffi/sample_ffi_functions_callbacks.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'coordinate.dart';
diff --git a/samples/ffi/sample_ffi_functions_callbacks_closures.dart b/samples/ffi/sample_ffi_functions_callbacks_closures.dart
index a6ce9a6..1d08340 100644
--- a/samples/ffi/sample_ffi_functions_callbacks_closures.dart
+++ b/samples/ffi/sample_ffi_functions_callbacks_closures.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:expect/expect.dart';
diff --git a/samples/ffi/sample_ffi_functions_structs.dart b/samples/ffi/sample_ffi_functions_structs.dart
index 7129658..9aefb57 100644
--- a/samples/ffi/sample_ffi_functions_structs.dart
+++ b/samples/ffi/sample_ffi_functions_structs.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'coordinate.dart';
diff --git a/samples/ffi/sample_ffi_structs.dart b/samples/ffi/sample_ffi_structs.dart
index d5af59e..bd6d7c7 100644
--- a/samples/ffi/sample_ffi_structs.dart
+++ b/samples/ffi/sample_ffi_structs.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 
 import 'package:ffi/ffi.dart';
diff --git a/samples/ffi/samples_test.dart b/samples/ffi/samples_test.dart
index a3674a4..954aa9c 100644
--- a/samples/ffi/samples_test.dart
+++ b/samples/ffi/samples_test.dart
@@ -6,8 +6,6 @@
 //
 // SharedObjects=ffi_test_dynamic_library ffi_test_functions
 
-// @dart = 2.9
-
 import 'sample_ffi_bitfield.dart' as bitfield;
 import 'sample_ffi_data.dart' as data;
 import 'sample_ffi_dynamic_library.dart' as dynamic_library;
diff --git a/samples/ffi/sqlite/example/main.dart b/samples/ffi/sqlite/example/main.dart
index 6af01d4..480ef42 100644
--- a/samples/ffi/sqlite/example/main.dart
+++ b/samples/ffi/sqlite/example/main.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import "../lib/sqlite.dart";
 
 void main() {
diff --git a/samples/ffi/sqlite/lib/sqlite.dart b/samples/ffi/sqlite/lib/sqlite.dart
index 825e434..d6bac5b 100644
--- a/samples/ffi/sqlite/lib/sqlite.dart
+++ b/samples/ffi/sqlite/lib/sqlite.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /// A synchronous SQLite wrapper.
 ///
 /// Written using dart:ffi.
diff --git a/samples/ffi/sqlite/lib/src/bindings/bindings.dart b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
index a1cdba7..a3d73bd 100644
--- a/samples/ffi/sqlite/lib/src/bindings/bindings.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import "dart:ffi";
 import "package:ffi/ffi.dart";
 
@@ -13,7 +11,7 @@
 import "types.dart";
 
 class _SQLiteBindings {
-  DynamicLibrary sqlite;
+  late DynamicLibrary sqlite;
 
   /// Opening A New Database Connection
   ///
@@ -29,10 +27,13 @@
   /// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
   /// an English language description of the error following a failure of any
   /// of the sqlite3_open() routines.
-  int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
-      int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
+  late int Function(
+      Pointer<Utf8> filename,
+      Pointer<Pointer<Database>> databaseOut,
+      int flags,
+      Pointer<Utf8> vfs) sqlite3_open_v2;
 
-  int Function(Pointer<Database> database) sqlite3_close_v2;
+  late int Function(Pointer<Database> database) sqlite3_close_v2;
 
   /// Compiling An SQL Statement
   ///
@@ -81,7 +82,7 @@
   /// that is returned (the sqlite3_stmt object) contains a copy of the
   /// original SQL text. This causes the [sqlite3_step] interface to
   /// behave differently in three ways:
-  int Function(
+  late int Function(
       Pointer<Database> database,
       Pointer<Utf8> query,
       int nbytes,
@@ -164,7 +165,7 @@
   /// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
   /// then the more specific [error codes] are returned directly
   /// by sqlite3_step().  The use of the "v2" interface is recommended.
-  int Function(Pointer<Statement> statement) sqlite3_step;
+  late int Function(Pointer<Statement> statement) sqlite3_step;
 
   /// CAPI3REF: Reset A Prepared Statement Object
   ///
@@ -187,7 +188,7 @@
   /// [sqlite3_reset] returns an appropriate [Errors].
   ///
   /// ^The [sqlite3_reset] interface does not change the values
-  int Function(Pointer<Statement> statement) sqlite3_reset;
+  late int Function(Pointer<Statement> statement) sqlite3_reset;
 
   /// Destroy A Prepared Statement Object
   ///
@@ -212,14 +213,14 @@
   /// a prepared statement after it has been finalized.  Any use of a prepared
   /// statement after it has been finalized can result in undefined and
   /// undesirable behavior such as segfaults and heap corruption.
-  int Function(Pointer<Statement> statement) sqlite3_finalize;
+  late int Function(Pointer<Statement> statement) sqlite3_finalize;
 
   /// Number Of Columns In A Result Set
   ///
   /// ^Return the number of columns in the result set returned by the
   /// prepared statement. ^This routine returns 0 if pStmt is an SQL
   /// statement that does not return data (for example an [UPDATE]).
-  int Function(Pointer<Statement> statement) sqlite3_column_count;
+  late int Function(Pointer<Statement> statement) sqlite3_column_count;
 
   /// Column Names In A Result Set
   ///
@@ -244,7 +245,7 @@
   /// ^The name of a result column is the value of the "AS" clause for
   /// that column, if there is an AS clause.  If there is no AS clause
   /// then the name of the column is unspecified and may change from
-  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+  late Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_name;
 
   /// CAPI3REF: Declared Datatype Of A Query Result
@@ -274,28 +275,28 @@
   /// strongly typed, but the typing is dynamic not static.  ^Type
   /// is associated with individual values, not with the containers
   /// used to hold those values.
-  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+  late Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_decltype;
 
-  int Function(Pointer<Statement> statement, int columnIndex)
+  late int Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_type;
 
-  Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
+  late Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_value;
 
-  double Function(Pointer<Statement> statement, int columnIndex)
+  late double Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_double;
 
-  int Function(Pointer<Statement> statement, int columnIndex)
+  late int Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_int;
 
-  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+  late Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_text;
 
   /// The sqlite3_errstr() interface returns the English-language text that
   /// describes the result code, as UTF-8. Memory to hold the error message
   /// string is managed internally and must not be freed by the application.
-  Pointer<Utf8> Function(int code) sqlite3_errstr;
+  late Pointer<Utf8> Function(int code) sqlite3_errstr;
 
   /// Error Codes And Messages
   ///
@@ -328,7 +329,7 @@
   /// If an interface fails with SQLITE_MISUSE, that means the interface
   /// was invoked incorrectly by the application.  In that case, the
   /// error code and message may or may not be set.
-  Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
+  late Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
 
   _SQLiteBindings() {
     sqlite = dlopenPlatformSpecific("sqlite3");
@@ -392,5 +393,5 @@
   }
 }
 
-_SQLiteBindings _cachedBindings;
+_SQLiteBindings? _cachedBindings;
 _SQLiteBindings get bindings => _cachedBindings ??= _SQLiteBindings();
diff --git a/samples/ffi/sqlite/lib/src/bindings/constants.dart b/samples/ffi/sqlite/lib/src/bindings/constants.dart
index 120d567..71aa82e 100644
--- a/samples/ffi/sqlite/lib/src/bindings/constants.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/constants.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /// Result Codes
 ///
 /// Many SQLite functions return an integer result code from the set shown
diff --git a/samples/ffi/sqlite/lib/src/bindings/signatures.dart b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
index 8e5d6e6..2f38dad 100644
--- a/samples/ffi/sqlite/lib/src/bindings/signatures.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import "dart:ffi";
 
 import "package:ffi/ffi.dart";
diff --git a/samples/ffi/sqlite/lib/src/bindings/types.dart b/samples/ffi/sqlite/lib/src/bindings/types.dart
index f6a1736..494cdef 100644
--- a/samples/ffi/sqlite/lib/src/bindings/types.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import "dart:ffi";
 
 /// Database Connection Handle
diff --git a/samples/ffi/sqlite/lib/src/collections/closable_iterator.dart b/samples/ffi/sqlite/lib/src/collections/closable_iterator.dart
index 83ca2ba..a86a58b 100644
--- a/samples/ffi/sqlite/lib/src/collections/closable_iterator.dart
+++ b/samples/ffi/sqlite/lib/src/collections/closable_iterator.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /// This iterator should be [close]d after use.
 ///
 /// [ClosableIterator]s often use resources which should be freed after use.
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index 38121a9..7725609 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import "dart:collection";
 import "dart:ffi";
 
@@ -23,7 +21,7 @@
 ///
 /// This database interacts with SQLite synchonously.
 class Database {
-  Pointer<types.Database> _database;
+  late Pointer<types.Database> _database;
   bool _open = false;
 
   /// Open a database located at the file [path].
@@ -108,11 +106,8 @@
     return Result._(this, statement, columnIndices);
   }
 
-  SQLiteException _loadError([int errorCode]) {
+  SQLiteException _loadError(int errorCode) {
     String errorMessage = bindings.sqlite3_errmsg(_database).ref.toString();
-    if (errorCode == null) {
-      return SQLiteException(errorMessage);
-    }
     String errorCodeExplanation =
         bindings.sqlite3_errstr(errorCode).ref.toString();
     return SQLiteException(
@@ -126,18 +121,13 @@
 /// Please note that this iterator should be [close]d manually if not all [Row]s
 /// are consumed.
 class Result extends IterableBase<Row> implements ClosableIterable<Row> {
-  final Database _database;
   final ClosableIterator<Row> _iterator;
-  final Pointer<Statement> _statement;
-  final Map<String, int> _columnIndices;
-
-  Row _currentRow = null;
 
   Result._(
-    this._database,
-    this._statement,
-    this._columnIndices,
-  ) : _iterator = _ResultIterator(_statement, _columnIndices) {}
+    Database database,
+    Pointer<Statement> statement,
+    Map<String, int> columnIndices,
+  ) : _iterator = _ResultIterator(statement, columnIndices) {}
 
   void close() => _iterator.close();
 
@@ -148,7 +138,7 @@
   final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
-  Row _currentRow = null;
+  Row? _currentRow;
   bool _closed = false;
 
   _ResultIterator(this._statement, this._columnIndices) {}
@@ -172,7 +162,7 @@
     if (_closed) {
       throw SQLiteException("The result has already been closed.");
     }
-    return _currentRow;
+    return _currentRow!;
   }
 
   void close() {
@@ -197,7 +187,7 @@
   /// for the column by the query compiler.
   dynamic readColumn(String columnName,
       {Convert convert = Convert.DynamicType}) {
-    return readColumnByIndex(_columnIndices[columnName], convert: convert);
+    return readColumnByIndex(_columnIndices[columnName]!, convert: convert);
   }
 
   /// Reads column [columnName].
@@ -227,7 +217,6 @@
         return readColumnByIndexAsText(columnIndex);
       case Type.Null:
         return null;
-        break;
       default:
     }
   }
@@ -235,7 +224,7 @@
   /// Reads column [columnName] and converts to [Type.Integer] if not an
   /// integer.
   int readColumnAsInt(String columnName) {
-    return readColumnByIndexAsInt(_columnIndices[columnName]);
+    return readColumnByIndexAsInt(_columnIndices[columnName]!);
   }
 
   /// Reads column [columnIndex] and converts to [Type.Integer] if not an
@@ -247,7 +236,7 @@
 
   /// Reads column [columnName] and converts to [Type.Text] if not text.
   String readColumnAsText(String columnName) {
-    return readColumnByIndexAsText(_columnIndices[columnName]);
+    return readColumnByIndexAsText(_columnIndices[columnName]!);
   }
 
   /// Reads column [columnIndex] and converts to [Type.Text] if not text.
@@ -298,7 +287,6 @@
     case "null":
       return Type.Null;
   }
-  if (textRepresentation == null) return Type.Null;
   throw Exception("Unknown type [$textRepresentation]");
 }
 
diff --git a/samples/ffi/sqlite/lib/src/ffi/arena.dart b/samples/ffi/sqlite/lib/src/ffi/arena.dart
index a26e807..d01b64f 100644
--- a/samples/ffi/sqlite/lib/src/ffi/arena.dart
+++ b/samples/ffi/sqlite/lib/src/ffi/arena.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import "dart:async";
 import "dart:ffi";
 
diff --git a/samples/ffi/sqlite/lib/src/ffi/dylib_utils.dart b/samples/ffi/sqlite/lib/src/ffi/dylib_utils.dart
index 39653fa..220c0fc 100644
--- a/samples/ffi/sqlite/lib/src/ffi/dylib_utils.dart
+++ b/samples/ffi/sqlite/lib/src/ffi/dylib_utils.dart
@@ -2,13 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:ffi';
 import 'dart:io' show Platform;
 
-String _platformPath(String name, {String path}) {
-  if (path == null) path = "";
+String _platformPath(String name, String path) {
   if (Platform.isLinux || Platform.isAndroid)
     return path + "lib" + name + ".so";
   if (Platform.isMacOS) return path + "lib" + name + ".dylib";
@@ -16,7 +13,7 @@
   throw Exception("Platform not implemented");
 }
 
-DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
-  String fullPath = _platformPath(name, path: path);
+DynamicLibrary dlopenPlatformSpecific(String name, {String path = ""}) {
+  String fullPath = _platformPath(name, path);
   return DynamicLibrary.open(fullPath);
 }
diff --git a/samples/ffi/sqlite/pubspec.yaml b/samples/ffi/sqlite/pubspec.yaml
index dcc5d40..71d9d59 100644
--- a/samples/ffi/sqlite/pubspec.yaml
+++ b/samples/ffi/sqlite/pubspec.yaml
@@ -4,8 +4,8 @@
   Sqlite3 wrapper. Demo for dart:ffi.
 author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
 environment:
-  sdk: '>=2.1.0 <3.0.0'
+  sdk: '>=2.12.0-0 <3.0.0'
 dependencies:
-  ffi: ^0.1.3
+  ffi: ^0.2.0-nullsafety.1
 dev_dependencies:
-  test: ^1.5.3
+  test: ^1.16.0-nullsafety.12
diff --git a/samples/ffi/sqlite/test/sqlite_test.dart b/samples/ffi/sqlite/test/sqlite_test.dart
index f7d3744..130c95f 100644
--- a/samples/ffi/sqlite/test/sqlite_test.dart
+++ b/samples/ffi/sqlite/test/sqlite_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 // VMOptions=--optimization-counter-threshold=5
 
 import "dart:ffi";
@@ -49,8 +47,7 @@
       expect(true, 1 <= id && id <= 3);
       String name = r.readColumnByIndex(1);
       expect(true, name is String);
-      String alternativeName = r.readColumn("alternative_name");
-      expect(true, alternativeName is String || alternativeName == null);
+      final alternativeName = r.readColumn("alternative_name") as String?;
       dynamic multiTypedValue = r.readColumn("multi_typed_column");
       expect(
           true,
@@ -76,8 +73,7 @@
       expect(true, 1 <= id && id <= 3);
       String name = r.readColumnByIndex(1);
       expect(true, name is String);
-      String alternativeName = r.readColumn("alternative_name");
-      expect(true, alternativeName is String || alternativeName == null);
+      final alternativeName = r.readColumn("alternative_name") as String?;
       dynamic multiTypedValue = r.readColumn("multi_typed_column");
       expect(
           true,
diff --git a/samples_2/.gitignore b/samples_2/.gitignore
new file mode 100644
index 0000000..485dee6
--- /dev/null
+++ b/samples_2/.gitignore
@@ -0,0 +1 @@
+.idea
diff --git a/samples_2/README b/samples_2/README
new file mode 100644
index 0000000..0e9d731
--- /dev/null
+++ b/samples_2/README
@@ -0,0 +1,4 @@
+This directory contains sample Dart programs.
+
+The samples in this directory have not been migrated to non-nullable by
+default. Please see directory `samples` for migrated samples.
diff --git a/samples_2/ffi/async/async_test.dart b/samples_2/ffi/async/async_test.dart
new file mode 100644
index 0000000..297a76e
--- /dev/null
+++ b/samples_2/ffi/async/async_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file exercises the sample files so that they are tested.
+//
+// SharedObjects=ffi_test_dynamic_library ffi_test_functions
+
+// @dart = 2.9
+
+import 'sample_async_callback.dart' as sample0;
+import 'sample_native_port_call.dart' as sample1;
+
+main() {
+  sample0.main();
+  sample1.main();
+}
diff --git a/samples_2/ffi/async/sample_async_callback.dart b/samples_2/ffi/async/sample_async_callback.dart
new file mode 100644
index 0000000..5e6d79a
--- /dev/null
+++ b/samples_2/ffi/async/sample_async_callback.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Sample showing how to do async callbacks by telling the Dart isolate to
+// yields its execution thread to C so it can perform the callbacks on the
+// main Dart thread.
+//
+// TODO(dartbug.com/37022): Update this when we get real async callbacks.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+
+import '../dylib_utils.dart';
+
+int globalResult = 0;
+int numCallbacks1 = 0;
+int numCallbacks2 = 0;
+
+main() async {
+  print("Dart = Dart mutator thread executing Dart.");
+  print("C Da = Dart mutator thread executing C.");
+  print("C T1 = Some C thread executing C.");
+  print("C T2 = Some C thread executing C.");
+  print("C    = C T1 or C T2.");
+  print("Dart: Setup.");
+  Expect.isTrue(NativeApi.majorVersion == 2);
+  Expect.isTrue(NativeApi.minorVersion >= 0);
+  final initializeApi = dl.lookupFunction<IntPtr Function(Pointer<Void>),
+      int Function(Pointer<Void>)>("InitDartApiDL");
+  Expect.isTrue(initializeApi(NativeApi.initializeApiDLData) == 0);
+
+  final interactiveCppRequests = ReceivePort()..listen(requestExecuteCallback);
+  final int nativePort = interactiveCppRequests.sendPort.nativePort;
+  registerCallback1(nativePort, callback1FP);
+  registerCallback2(nativePort, callback2FP);
+  print("Dart: Tell C to start worker threads.");
+  startWorkSimulator();
+
+  // We need to yield control in order to be able to receive messages.
+  while (numCallbacks2 < 3) {
+    print("Dart: Yielding (able to receive messages on port).");
+    await asyncSleep(500);
+  }
+  print("Dart: Received expected number of callbacks.");
+
+  Expect.equals(2, numCallbacks1);
+  Expect.equals(3, numCallbacks2);
+  Expect.equals(14, globalResult);
+
+  print("Dart: Tell C to stop worker threads.");
+  stopWorkSimulator();
+  interactiveCppRequests.close();
+  print("Dart: Done.");
+}
+
+int callback1(int a) {
+  print("Dart:     callback1($a).");
+  numCallbacks1++;
+  return a + 3;
+}
+
+void callback2(int a) {
+  print("Dart:     callback2($a).");
+  globalResult += a;
+  numCallbacks2++;
+}
+
+void requestExecuteCallback(dynamic message) {
+  final int work_address = message;
+  final work = Pointer<Work>.fromAddress(work_address);
+  print("Dart:   Calling into C to execute callback ($work).");
+  executeCallback(work);
+  print("Dart:   Done with callback.");
+}
+
+final callback1FP = Pointer.fromFunction<IntPtr Function(IntPtr)>(callback1, 0);
+
+final callback2FP = Pointer.fromFunction<Void Function(IntPtr)>(callback2);
+
+final dl = dlopenPlatformSpecific("ffi_test_functions");
+
+final registerCallback1 = dl.lookupFunction<
+        Void Function(Int64 sendPort,
+            Pointer<NativeFunction<IntPtr Function(IntPtr)>> functionPointer),
+        void Function(int sendPort,
+            Pointer<NativeFunction<IntPtr Function(IntPtr)>> functionPointer)>(
+    'RegisterMyCallbackBlocking');
+
+final registerCallback2 = dl.lookupFunction<
+        Void Function(Int64 sendPort,
+            Pointer<NativeFunction<Void Function(IntPtr)>> functionPointer),
+        void Function(int sendPort,
+            Pointer<NativeFunction<Void Function(IntPtr)>> functionPointer)>(
+    'RegisterMyCallbackNonBlocking');
+
+final startWorkSimulator =
+    dl.lookupFunction<Void Function(), void Function()>('StartWorkSimulator');
+
+final stopWorkSimulator =
+    dl.lookupFunction<Void Function(), void Function()>('StopWorkSimulator');
+
+final executeCallback = dl.lookupFunction<Void Function(Pointer<Work>),
+    void Function(Pointer<Work>)>('ExecuteCallback');
+
+class Work extends Struct {}
+
+Future asyncSleep(int ms) {
+  return new Future.delayed(Duration(milliseconds: ms));
+}
diff --git a/samples_2/ffi/async/sample_native_port_call.dart b/samples_2/ffi/async/sample_native_port_call.dart
new file mode 100644
index 0000000..a2c3ee4
--- /dev/null
+++ b/samples_2/ffi/async/sample_native_port_call.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Sample showing how to do calls from C into Dart through native ports.
+//
+// This sample does not use FFI callbacks to do the callbacks at all. Instead,
+// it sends a message to Dart through native ports, decodes the message in Dart
+// does a method call in Dart and sends the result back to C through a native
+// port.
+//
+// The disadvantage of this approach compared to `sample_async_callback.dart`
+// is that it requires more boilerplate, because it does not use the automatic
+// marshalling of data of the FFI.
+//
+// The advantage is that finalizers can be used when passing ownership of data
+// (buffers) from C to Dart.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+import 'dart:isolate';
+import 'dart:typed_data';
+
+import 'package:expect/expect.dart';
+
+import '../dylib_utils.dart';
+
+var globalResult = 0;
+var numCallbacks1 = 0;
+var numCallbacks2 = 0;
+
+main() async {
+  print("Dart = Dart mutator thread executing Dart.");
+  print("C Da = Dart mutator thread executing C.");
+  print("C T1 = Some C thread executing C.");
+  print("C T2 = Some C thread executing C.");
+  print("C    = C T1 or C T2.");
+  print("Dart: Setup.");
+  Expect.isTrue(NativeApi.majorVersion == 2);
+  Expect.isTrue(NativeApi.minorVersion >= 0);
+  final initializeApi = dl.lookupFunction<IntPtr Function(Pointer<Void>),
+      int Function(Pointer<Void>)>("InitDartApiDL");
+  Expect.isTrue(initializeApi(NativeApi.initializeApiDLData) == 0);
+
+  final interactiveCppRequests = ReceivePort()..listen(handleCppRequests);
+  final int nativePort = interactiveCppRequests.sendPort.nativePort;
+  registerSendPort(nativePort);
+  print("Dart: Tell C to start worker threads.");
+  startWorkSimulator2();
+
+  // We need to yield control in order to be able to receive messages.
+  while (numCallbacks2 < 3) {
+    print("Dart: Yielding (able to receive messages on port).");
+    await asyncSleep(500);
+  }
+  print("Dart: Received expected number of callbacks.");
+
+  Expect.equals(2, numCallbacks1);
+  Expect.equals(3, numCallbacks2);
+  Expect.equals(14, globalResult);
+
+  print("Dart: Tell C to stop worker threads.");
+  stopWorkSimulator2();
+  interactiveCppRequests.close();
+  print("Dart: Done.");
+}
+
+int myCallback1(int a) {
+  print("Dart:     myCallback1($a).");
+  numCallbacks1++;
+  return a + 3;
+}
+
+void myCallback2(int a) {
+  print("Dart:     myCallback2($a).");
+  globalResult += a;
+  numCallbacks2++;
+}
+
+class CppRequest {
+  final SendPort replyPort;
+  final int pendingCall;
+  final String method;
+  final Uint8List data;
+
+  factory CppRequest.fromCppMessage(List message) {
+    return CppRequest._(message[0], message[1], message[2], message[3]);
+  }
+
+  CppRequest._(this.replyPort, this.pendingCall, this.method, this.data);
+
+  String toString() => 'CppRequest(method: $method, ${data.length} bytes)';
+}
+
+class CppResponse {
+  final int pendingCall;
+  final Uint8List data;
+
+  CppResponse(this.pendingCall, this.data);
+
+  List toCppMessage() => List.from([pendingCall, data], growable: false);
+
+  String toString() => 'CppResponse(message: ${data.length})';
+}
+
+void handleCppRequests(dynamic message) {
+  final cppRequest = CppRequest.fromCppMessage(message);
+  print('Dart:   Got message: $cppRequest');
+
+  if (cppRequest.method == 'myCallback1') {
+    // Use the data in any way you like. Here we just take the first byte as
+    // the argument to the function.
+    final int argument = cppRequest.data[0];
+    final int result = myCallback1(argument);
+    final cppResponse =
+        CppResponse(cppRequest.pendingCall, Uint8List.fromList([result]));
+    print('Dart:   Responding: $cppResponse');
+    cppRequest.replyPort.send(cppResponse.toCppMessage());
+  } else if (cppRequest.method == 'myCallback2') {
+    final int argument = cppRequest.data[0];
+    myCallback2(argument);
+  }
+}
+
+final dl = dlopenPlatformSpecific("ffi_test_functions");
+
+final registerSendPort = dl.lookupFunction<Void Function(Int64 sendPort),
+    void Function(int sendPort)>('RegisterSendPort');
+
+final startWorkSimulator2 =
+    dl.lookupFunction<Void Function(), void Function()>('StartWorkSimulator2');
+
+final stopWorkSimulator2 =
+    dl.lookupFunction<Void Function(), void Function()>('StopWorkSimulator2');
+
+Future asyncSleep(int ms) {
+  return new Future.delayed(Duration(milliseconds: ms), () => true);
+}
diff --git a/samples_2/ffi/coordinate.dart b/samples_2/ffi/coordinate.dart
new file mode 100644
index 0000000..4ff34f5
--- /dev/null
+++ b/samples_2/ffi/coordinate.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.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import "package:ffi/ffi.dart";
+
+/// Sample struct for dart:ffi library.
+class Coordinate extends Struct {
+  @Double()
+  double x;
+
+  @Double()
+  double y;
+
+  Pointer<Coordinate> next;
+
+  factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
+    return allocate<Coordinate>().ref
+      ..x = x
+      ..y = y
+      ..next = next;
+  }
+}
diff --git a/samples_2/ffi/dylib_utils.dart b/samples_2/ffi/dylib_utils.dart
new file mode 100644
index 0000000..39653fa
--- /dev/null
+++ b/samples_2/ffi/dylib_utils.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+import 'dart:io' show Platform;
+
+String _platformPath(String name, {String path}) {
+  if (path == null) path = "";
+  if (Platform.isLinux || Platform.isAndroid)
+    return path + "lib" + name + ".so";
+  if (Platform.isMacOS) return path + "lib" + name + ".dylib";
+  if (Platform.isWindows) return path + name + ".dll";
+  throw Exception("Platform not implemented");
+}
+
+DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
+  String fullPath = _platformPath(name, path: path);
+  return DynamicLibrary.open(fullPath);
+}
diff --git a/samples_2/ffi/resource_management/pool.dart b/samples_2/ffi/resource_management/pool.dart
new file mode 100644
index 0000000..776c331
--- /dev/null
+++ b/samples_2/ffi/resource_management/pool.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Explicit pool used for managing resources.
+
+// @dart = 2.9
+
+import "dart:async";
+import 'dart:convert';
+import 'dart:ffi';
+import 'dart:typed_data';
+
+import 'package:ffi/ffi.dart' as packageFfi;
+import 'package:ffi/ffi.dart' show Utf8;
+
+/// Manages native resources.
+///
+/// Primary implementations are [Pool] and [Unmanaged].
+abstract class ResourceManager {
+  /// Allocates memory on the native heap.
+  ///
+  /// The native memory is under management by this [ResourceManager].
+  ///
+  /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
+  /// against the default public heap. Allocation of either element size or count
+  /// of 0 is undefined.
+  ///
+  /// Throws an ArgumentError on failure to allocate.
+  Pointer<T> allocate<T extends NativeType>({int count: 1});
+}
+
+/// Manages native resources.
+class Pool implements ResourceManager {
+  /// Native memory under management by this [Pool].
+  final List<Pointer<NativeType>> _managedMemoryPointers = [];
+
+  /// Callbacks for releasing native resources under management by this [Pool].
+  final List<Function()> _managedResourceReleaseCallbacks = [];
+
+  /// Allocates memory on the native heap.
+  ///
+  /// The native memory is under management by this [Pool].
+  ///
+  /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
+  /// against the default public heap. Allocation of either element size or count
+  /// of 0 is undefined.
+  ///
+  /// Throws an ArgumentError on failure to allocate.
+  Pointer<T> allocate<T extends NativeType>({int count: 1}) {
+    final p = Unmanaged().allocate<T>(count: count);
+    _managedMemoryPointers.add(p);
+    return p;
+  }
+
+  /// Registers [resource] in this pool.
+  ///
+  /// Executes [releaseCallback] on [releaseAll].
+  T using<T>(T resource, Function(T) releaseCallback) {
+    _managedResourceReleaseCallbacks.add(() => releaseCallback(resource));
+    return resource;
+  }
+
+  /// Registers [releaseResourceCallback] to be executed on [releaseAll].
+  void onReleaseAll(Function() releaseResourceCallback) {
+    _managedResourceReleaseCallbacks.add(releaseResourceCallback);
+  }
+
+  /// Releases all resources that this [Pool] manages.
+  void releaseAll() {
+    for (final c in _managedResourceReleaseCallbacks) {
+      c();
+    }
+    _managedResourceReleaseCallbacks.clear();
+    for (final p in _managedMemoryPointers) {
+      Unmanaged().free(p);
+    }
+    _managedMemoryPointers.clear();
+  }
+}
+
+/// Creates a [Pool] to manage native resources.
+///
+/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
+R using<R>(R Function(Pool) f) {
+  final p = Pool();
+  try {
+    return f(p);
+  } finally {
+    p.releaseAll();
+  }
+}
+
+/// Creates a zoned [Pool] to manage native resources.
+///
+/// Pool is availabe through [currentPool].
+///
+/// Please note that all throws are caught and packaged in [RethrownError].
+///
+/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
+R usePool<R>(R Function() f) {
+  final p = Pool();
+  try {
+    return runZoned(() => f(),
+        zoneValues: {#_pool: p},
+        onError: (error, st) => throw RethrownError(error, st));
+  } finally {
+    p.releaseAll();
+  }
+}
+
+/// The [Pool] in the current zone.
+Pool get currentPool => Zone.current[#_pool];
+
+class RethrownError {
+  dynamic original;
+  StackTrace originalStackTrace;
+  RethrownError(this.original, this.originalStackTrace);
+  toString() => """RethrownError(${original})
+${originalStackTrace}""";
+}
+
+/// Does not manage it's resources.
+class Unmanaged implements ResourceManager {
+  /// Allocates memory on the native heap.
+  ///
+  /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
+  /// against the default public heap. Allocation of either element size or count
+  /// of 0 is undefined.
+  ///
+  /// Throws an ArgumentError on failure to allocate.
+  Pointer<T> allocate<T extends NativeType>({int count = 1}) =>
+      packageFfi.allocate(count: count);
+
+  /// Releases memory on the native heap.
+  ///
+  /// For POSIX-based systems, this uses free. On Windows, it uses HeapFree
+  /// against the default public heap. It may only be used against pointers
+  /// allocated in a manner equivalent to [allocate].
+  ///
+  /// Throws an ArgumentError on failure to free.
+  ///
+  void free(Pointer pointer) => packageFfi.free(pointer);
+}
+
+/// Does not manage it's resources.
+final Unmanaged unmanaged = Unmanaged();
+
+extension Utf8InPool on String {
+  /// Convert a [String] to a Utf8-encoded null-terminated C string.
+  ///
+  /// If 'string' contains NULL bytes, the converted string will be truncated
+  /// prematurely. Unpaired surrogate code points in [string] will be preserved
+  /// in the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
+  ///
+  /// Returns a malloc-allocated pointer to the result.
+  ///
+  /// The memory is managed by the [Pool] passed in as [pool].
+  Pointer<Utf8> toUtf8(ResourceManager pool) {
+    final units = utf8.encode(this);
+    final Pointer<Uint8> result = pool.allocate<Uint8>(count: units.length + 1);
+    final Uint8List nativeString = result.asTypedList(units.length + 1);
+    nativeString.setAll(0, units);
+    nativeString[units.length] = 0;
+    return result.cast();
+  }
+}
+
+extension Utf8Helpers on Pointer<Utf8> {
+  /// Returns the length of a null-terminated string -- the number of (one-byte)
+  /// characters before the first null byte.
+  int strlen() {
+    final Pointer<Uint8> array = this.cast<Uint8>();
+    final Uint8List nativeString = array.asTypedList(_maxSize);
+    return nativeString.indexWhere((char) => char == 0);
+  }
+
+  /// Creates a [String] containing the characters UTF-8 encoded in [this].
+  ///
+  /// [this] must be a zero-terminated byte sequence of valid UTF-8
+  /// encodings of Unicode code points. It may also contain UTF-8 encodings of
+  /// unpaired surrogate code points, which is not otherwise valid UTF-8, but
+  /// which may be created when encoding a Dart string containing an unpaired
+  /// surrogate. See [Utf8Decoder] for details on decoding.
+  ///
+  /// Returns a Dart string containing the decoded code points.
+  String contents() {
+    final int length = strlen();
+    return utf8.decode(Uint8List.view(
+        this.cast<Uint8>().asTypedList(length).buffer, 0, length));
+  }
+}
+
+const int _kMaxSmi64 = (1 << 62) - 1;
+const int _kMaxSmi32 = (1 << 30) - 1;
+final int _maxSize = sizeOf<IntPtr>() == 8 ? _kMaxSmi64 : _kMaxSmi32;
diff --git a/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart b/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart
new file mode 100644
index 0000000..8d3401b
--- /dev/null
+++ b/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Sample illustrating resources are not cleaned up when isolate is shutdown.
+
+// @dart = 2.9
+
+import 'dart:io';
+import "dart:isolate";
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'pool.dart';
+import '../dylib_utils.dart';
+
+void main() {
+  final receiveFromHelper = ReceivePort();
+
+  Isolate.spawn(helperIsolateMain, receiveFromHelper.sendPort)
+      .then((helperIsolate) {
+    helperIsolate.addOnExitListener(
+      receiveFromHelper.sendPort,
+    );
+    print("Main: Helper started.");
+    Pointer<SomeResource> resource;
+    receiveFromHelper.listen((message) {
+      if (message is int) {
+        resource = Pointer<SomeResource>.fromAddress(message);
+        print("Main: Received resource from helper: $resource.");
+        print("Main: Shutting down helper.");
+        helperIsolate.kill(priority: Isolate.immediate);
+      } else {
+        // Isolate kill message.
+        Expect.isNull(message);
+        print("Main: Helper is shut down.");
+        print(
+            "Main: Trying to use resource after isolate that was supposed to free it was shut down.");
+        useResource(resource);
+        print("Main: Releasing resource manually.");
+        releaseResource(resource);
+        print("Main: Shutting down receive port, end of main.");
+        receiveFromHelper.close();
+      }
+    });
+  });
+}
+
+/// If set to `false`, this sample can segfault due to use after free and
+/// double free.
+const keepHelperIsolateAlive = true;
+
+void helperIsolateMain(SendPort sendToMain) {
+  using((Pool pool) {
+    final resource = pool.using(allocateResource(), releaseResource);
+    pool.onReleaseAll(() {
+      // Will only run print if [keepHelperIsolateAlive] is false.
+      print("Helper: Releasing all resources.");
+    });
+    print("Helper: Resource allocated.");
+    useResource(resource);
+    print("Helper: Sending resource to main: $resource.");
+    sendToMain.send(resource.address);
+    print("Helper: Going to sleep.");
+    if (keepHelperIsolateAlive) {
+      while (true) {
+        sleep(Duration(seconds: 1));
+        print("Helper: sleeping.");
+      }
+    }
+  });
+}
+
+final ffiTestDynamicLibrary =
+    dlopenPlatformSpecific("ffi_test_dynamic_library");
+
+final allocateResource = ffiTestDynamicLibrary.lookupFunction<
+    Pointer<SomeResource> Function(),
+    Pointer<SomeResource> Function()>("AllocateResource");
+
+final useResource = ffiTestDynamicLibrary.lookupFunction<
+    Void Function(Pointer<SomeResource>),
+    void Function(Pointer<SomeResource>)>("UseResource");
+
+final releaseResource = ffiTestDynamicLibrary.lookupFunction<
+    Void Function(Pointer<SomeResource>),
+    void Function(Pointer<SomeResource>)>("ReleaseResource");
+
+/// Represents some opaque resource being managed by a library.
+class SomeResource extends Struct {}
diff --git a/samples_2/ffi/resource_management/pool_sample.dart b/samples_2/ffi/resource_management/pool_sample.dart
new file mode 100644
index 0000000..87c5e39
--- /dev/null
+++ b/samples_2/ffi/resource_management/pool_sample.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Sample illustrating resource management with an explicit pool.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'pool.dart';
+import '../dylib_utils.dart';
+
+main() {
+  final ffiTestDynamicLibrary =
+      dlopenPlatformSpecific("ffi_test_dynamic_library");
+
+  final MemMove = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<Void>, Pointer<Void>, IntPtr),
+      void Function(Pointer<Void>, Pointer<Void>, int)>("MemMove");
+
+  // To ensure resources are freed, wrap them in a [using] call.
+  using((Pool pool) {
+    final p = pool.allocate<Int64>(count: 2);
+    p[0] = 24;
+    MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
+    print(p[1]);
+    Expect.equals(24, p[1]);
+  });
+
+  // Resources are freed also when abnormal control flow occurs.
+  try {
+    using((Pool pool) {
+      final p = pool.allocate<Int64>(count: 2);
+      p[0] = 25;
+      MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
+      print(p[1]);
+      Expect.equals(25, p[1]);
+      throw Exception("Some random exception");
+    });
+    // `free(p)` has been called.
+  } on Exception catch (e) {
+    print("Caught exception: $e");
+  }
+
+  // In a pool multiple resources can be allocated, which will all be freed
+  // at the end of the scope.
+  using((Pool pool) {
+    final p = pool.allocate<Int64>(count: 2);
+    final p2 = pool.allocate<Int64>(count: 2);
+    p[0] = 1;
+    p[1] = 2;
+    MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
+    Expect.equals(1, p2[0]);
+    Expect.equals(2, p2[1]);
+  });
+
+  // If the resource allocation happens in a different scope, then one either
+  // needs to pass the pool to that scope.
+  f1(Pool pool) {
+    return pool.allocate<Int64>(count: 2);
+  }
+
+  using((Pool pool) {
+    final p = f1(pool);
+    final p2 = f1(pool);
+    p[0] = 1;
+    p[1] = 2;
+    MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
+    Expect.equals(1, p2[0]);
+    Expect.equals(2, p2[1]);
+  });
+
+  // Using Strings.
+  using((Pool pool) {
+    final p = "Hello world!".toUtf8(pool);
+    print(p.contents());
+  });
+
+  final allocateResource = ffiTestDynamicLibrary.lookupFunction<
+      Pointer<SomeResource> Function(),
+      Pointer<SomeResource> Function()>("AllocateResource");
+
+  final useResource = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<SomeResource>),
+      void Function(Pointer<SomeResource>)>("UseResource");
+
+  final releaseResource = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<SomeResource>),
+      void Function(Pointer<SomeResource>)>("ReleaseResource");
+
+  // Using an FFI call to release a resource.
+  using((Pool pool) {
+    final r = pool.using(allocateResource(), releaseResource);
+    useResource(r);
+  });
+
+  // Using an FFI call to release a resource with abnormal control flow.
+  try {
+    using((Pool pool) {
+      final r = pool.using(allocateResource(), releaseResource);
+      useResource(r);
+
+      throw Exception("Some random exception");
+    });
+    // Resource has been freed.
+  } on Exception catch (e) {
+    print("Caught exception: $e");
+  }
+}
+
+/// Represents some opaque resource being managed by a library.
+class SomeResource extends Struct {}
diff --git a/samples_2/ffi/resource_management/pool_zoned_sample.dart b/samples_2/ffi/resource_management/pool_zoned_sample.dart
new file mode 100644
index 0000000..0b4e8ff
--- /dev/null
+++ b/samples_2/ffi/resource_management/pool_zoned_sample.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Sample illustrating resource management with an implicit pool in the zone.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'pool.dart';
+import '../dylib_utils.dart';
+
+main() {
+  final ffiTestDynamicLibrary =
+      dlopenPlatformSpecific("ffi_test_dynamic_library");
+
+  final MemMove = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<Void>, Pointer<Void>, IntPtr),
+      void Function(Pointer<Void>, Pointer<Void>, int)>("MemMove");
+
+  // To ensure resources are freed, wrap them in a [using] call.
+  usePool(() {
+    final p = currentPool.allocate<Int64>(count: 2);
+    p[0] = 24;
+    MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
+    print(p[1]);
+    Expect.equals(24, p[1]);
+  });
+
+  // Resources are freed also when abnormal control flow occurs.
+  try {
+    usePool(() {
+      final p = currentPool.allocate<Int64>(count: 2);
+      p[0] = 25;
+      MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
+      print(p[1]);
+      Expect.equals(25, p[1]);
+      throw Exception("Some random exception");
+    });
+  } on RethrownError catch (e) {
+    // Note that exceptions are wrapped when using zones.
+    print("Caught exception: ${e.original}");
+  }
+
+  // In a pool multiple resources can be allocated, which will all be freed
+  // at the end of the scope.
+  usePool(() {
+    final p = currentPool.allocate<Int64>(count: 2);
+    final p2 = currentPool.allocate<Int64>(count: 2);
+    p[0] = 1;
+    p[1] = 2;
+    MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
+    Expect.equals(1, p2[0]);
+    Expect.equals(2, p2[1]);
+  });
+
+  // If the resource allocation happens in a different scope, it is in the
+  // same zone, so it's lifetime is automatically managed by the pool.
+  f1() {
+    return currentPool.allocate<Int64>(count: 2);
+  }
+
+  usePool(() {
+    final p = f1();
+    final p2 = f1();
+    p[0] = 1;
+    p[1] = 2;
+    MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
+    Expect.equals(1, p2[0]);
+    Expect.equals(2, p2[1]);
+  });
+
+  // Using Strings.
+  usePool(() {
+    final p = "Hello world!".toUtf8(currentPool);
+    print(p.contents());
+  });
+
+  final allocateResource = ffiTestDynamicLibrary.lookupFunction<
+      Pointer<SomeResource> Function(),
+      Pointer<SomeResource> Function()>("AllocateResource");
+
+  final useResource = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<SomeResource>),
+      void Function(Pointer<SomeResource>)>("UseResource");
+
+  final releaseResource = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<SomeResource>),
+      void Function(Pointer<SomeResource>)>("ReleaseResource");
+
+  // Using an FFI call to release a resource.
+  usePool(() {
+    final r = currentPool.using(allocateResource(), releaseResource);
+    useResource(r);
+  });
+
+  // Using an FFI call to release a resource with abnormal control flow.
+  try {
+    usePool(() {
+      final r = currentPool.using(allocateResource(), releaseResource);
+      useResource(r);
+
+      throw Exception("Some random exception");
+    });
+    // Resource has been freed.
+  } on RethrownError catch (e) {
+    // Note that exceptions are wrapped when using zones.
+    print("Caught exception: ${e.original}");
+  }
+}
+
+/// Represents some opaque resource being managed by a library.
+class SomeResource extends Struct {}
diff --git a/samples_2/ffi/resource_management/resource_management_test.dart b/samples_2/ffi/resource_management/resource_management_test.dart
new file mode 100644
index 0000000..4b2bbb0
--- /dev/null
+++ b/samples_2/ffi/resource_management/resource_management_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file exercises the sample files so that they are tested.
+//
+// SharedObjects=ffi_test_dynamic_library ffi_test_functions
+
+// @dart = 2.9
+
+import 'pool_isolate_shutdown_sample.dart' as pool_isolate;
+import 'pool_sample.dart' as pool;
+import 'pool_zoned_sample.dart' as pool_zoned;
+import 'unmanaged_sample.dart' as unmanaged;
+
+main() {
+  pool_isolate.main();
+  pool.main();
+  pool_zoned.main();
+  unmanaged.main();
+}
diff --git a/samples_2/ffi/resource_management/unmanaged_sample.dart b/samples_2/ffi/resource_management/unmanaged_sample.dart
new file mode 100644
index 0000000..b8c9971
--- /dev/null
+++ b/samples_2/ffi/resource_management/unmanaged_sample.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Sample illustrating manual resource management, not advised.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'pool.dart';
+import '../dylib_utils.dart';
+
+main() {
+  final ffiTestDynamicLibrary =
+      dlopenPlatformSpecific("ffi_test_dynamic_library");
+
+  final MemMove = ffiTestDynamicLibrary.lookupFunction<
+      Void Function(Pointer<Void>, Pointer<Void>, IntPtr),
+      void Function(Pointer<Void>, Pointer<Void>, int)>("MemMove");
+
+  // To ensure resources are freed, call free manually.
+  //
+  // For automatic management use a Pool.
+  final p = unmanaged.allocate<Int64>(count: 2);
+  p[0] = 24;
+  MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
+  print(p[1]);
+  Expect.equals(24, p[1]);
+  unmanaged.free(p);
+
+  // Using Strings.
+  final p2 = "Hello world!".toUtf8(unmanaged);
+  print(p2.contents());
+  unmanaged.free(p2);
+}
diff --git a/samples_2/ffi/sample_ffi_bitfield.dart b/samples_2/ffi/sample_ffi_bitfield.dart
new file mode 100644
index 0000000..91bb65d
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_bitfield.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+import 'package:expect/expect.dart';
+
+/// typedef struct {
+///     unsigned int bold      : 1;
+///     unsigned int underline : 2;
+///     unsigned int italic    : 1;
+///     unsigned int blink     : 1;
+///     unsigned int reverse   : 1;
+///     unsigned int strike    : 1;
+///     unsigned int font      : 4;
+/// } ScreenCellAttrs;
+class ScreenCellAttrs extends Struct {
+  @Int16()
+  int bits;
+
+  int get bold => getBits(kBoldFieldOffset, kBoldFieldLength);
+  void set bold(int value) =>
+      setBits(kBoldFieldOffset, kBoldFieldLength, value);
+
+  int get underline => getBits(kUnderlineFieldOffset, kUnderlineFieldLength);
+  void set underline(int value) =>
+      setBits(kUnderlineFieldOffset, kUnderlineFieldLength, value);
+
+  int get italic => getBits(kItalicFieldOffset, kItalicFieldLength);
+  void set italic(int value) =>
+      setBits(kItalicFieldOffset, kItalicFieldLength, value);
+
+  int get blink => getBits(kBlinkFieldOffset, kBlinkFieldLength);
+  void set blink(int value) =>
+      setBits(kBlinkFieldOffset, kBlinkFieldLength, value);
+
+  int get reverse => getBits(kReverseFieldOffset, kReverseFieldLength);
+  void set reverse(int value) =>
+      setBits(kReverseFieldOffset, kReverseFieldLength, value);
+
+  int get strike => getBits(kStrikeFieldOffset, kStrikeFieldLength);
+  void set strike(int value) =>
+      setBits(kStrikeFieldOffset, kStrikeFieldLength, value);
+
+  int get font => getBits(kFontFieldOffset, kFontFieldLength);
+  void set font(int value) =>
+      setBits(kFontFieldOffset, kFontFieldLength, value);
+
+  int getBits(int offset, int length) => bits.getBits(offset, length);
+
+  void setBits(int offset, int length, int value) {
+    bits = bits.setBits(offset, length, value);
+  }
+}
+
+const int kBoldFieldOffset = 0;
+const int kBoldFieldLength = 1;
+const int kUnderlineFieldOffset = kBoldFieldOffset + kBoldFieldLength;
+const int kUnderlineFieldLength = 2;
+const int kItalicFieldOffset = kUnderlineFieldOffset + kUnderlineFieldLength;
+const int kItalicFieldLength = 1;
+const int kBlinkFieldOffset = kItalicFieldOffset + kItalicFieldLength;
+const int kBlinkFieldLength = 1;
+const int kReverseFieldOffset = kBlinkFieldOffset + kBlinkFieldLength;
+const int kReverseFieldLength = 1;
+const int kStrikeFieldOffset = kReverseFieldOffset + kReverseFieldLength;
+const int kStrikeFieldLength = 1;
+const int kFontFieldOffset = kStrikeFieldOffset + kStrikeFieldLength;
+const int kFontFieldLength = 4;
+
+/// Extension to use a 64-bit integer as bit field.
+extension IntBitField on int {
+  static int _bitMask(int offset, int lenght) => ((1 << lenght) - 1) << offset;
+
+  /// Read `length` bits at `offset`.
+  ///
+  /// Truncates everything.
+  int getBits(int offset, int length) {
+    final mask = _bitMask(offset, length);
+    return (this & mask) >> offset;
+  }
+
+  /// Returns a new integer value in which `length` bits are overwritten at
+  /// `offset`.
+  ///
+  /// Truncates everything.
+  int setBits(int offset, int length, int value) {
+    final mask = _bitMask(offset, length);
+    return (this & ~mask) | ((value << offset) & mask);
+  }
+}
+
+main() {
+  final p = allocate<ScreenCellAttrs>(count: 3);
+
+  // Zeroes out all fields.
+  p.ref.bits = 0;
+
+  // Set individual fields.
+  p.ref.blink = 0;
+  p.ref.bold = 1;
+  p.ref.font = 15;
+  p.ref.italic = 1;
+  p.ref.reverse = 0;
+  p.ref.strike = 0;
+  p.ref.underline = 2;
+
+  // Read individual fields.
+  print(p.ref.blink);
+  print(p.ref.bold);
+  print(p.ref.font);
+  print(p.ref.italic);
+  print(p.ref.reverse);
+  print(p.ref.strike);
+  print(p.ref.underline);
+
+  // A check for automated testing.
+  Expect.equals(1933, p.ref.bits);
+
+  free(p);
+}
diff --git a/samples_2/ffi/sample_ffi_data.dart b/samples_2/ffi/sample_ffi_data.dart
new file mode 100644
index 0000000..09dba76
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_data.dart
@@ -0,0 +1,241 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+main() {
+  print('start main');
+
+  {
+    // Basic operation: allocate, get, set, and free.
+    Pointer<Int64> p = allocate();
+    p.value = 42;
+    int pValue = p.value;
+    print('${p.runtimeType} value: ${pValue}');
+    free(p);
+  }
+
+  {
+    // Undefined behavior before set.
+    Pointer<Int64> p = allocate();
+    int pValue = p.value;
+    print('If not set, returns garbage: ${pValue}');
+    free(p);
+  }
+
+  {
+    // Pointers can be created from an address.
+    Pointer<Int64> pHelper = allocate();
+    pHelper.value = 1337;
+
+    int address = pHelper.address;
+    print('Address: ${address}');
+
+    Pointer<Int64> p = Pointer.fromAddress(address);
+    print('${p.runtimeType} value: ${p.value}');
+
+    free(pHelper);
+  }
+
+  {
+    // Address is zeroed out after free.
+    Pointer<Int64> p = allocate();
+    free(p);
+    print('After free, address is zero: ${p.address}');
+  }
+
+  {
+    // Allocating too much throws an exception.
+    try {
+      int maxMint = 9223372036854775807; // 2^63 - 1
+      allocate<Int64>(count: maxMint);
+    } on Error {
+      print('Expected exception on allocating too much');
+    }
+    try {
+      int maxInt1_8 = 1152921504606846975; // 2^60 -1
+      allocate<Int64>(count: maxInt1_8);
+    } on Error {
+      print('Expected exception on allocating too much');
+    }
+  }
+
+  {
+    // Pointers can be cast into another type,
+    // resulting in the corresponding bits read.
+    Pointer<Int64> p1 = allocate();
+    p1.value = 9223372036854775807; // 2^63 - 1
+
+    Pointer<Int32> p2 = p1.cast();
+    print('${p2.runtimeType} value: ${p2.value}'); // -1
+
+    Pointer<Int32> p3 = p2.elementAt(1);
+    print('${p3.runtimeType} value: ${p3.value}'); // 2^31 - 1
+
+    free(p1);
+  }
+
+  {
+    // Data can be tightly packed in memory.
+    Pointer<Int8> p = allocate(count: 8);
+    for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+      p.elementAt(i).value = i * 3;
+    }
+    for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+      print('p.elementAt($i) value: ${p.elementAt(i).value}');
+    }
+    free(p);
+  }
+
+  {
+    // Values that don't fit are truncated.
+    Pointer<Int32> p11 = allocate();
+
+    p11.value = 9223372036854775807;
+
+    print(p11);
+
+    free(p11);
+  }
+
+  {
+    // Doubles.
+    Pointer<Double> p = allocate();
+    p.value = 3.14159265359;
+    print('${p.runtimeType} value: ${p.value}');
+    p.value = 3.14;
+    print('${p.runtimeType} value: ${p.value}');
+    free(p);
+  }
+
+  {
+    // Floats.
+    Pointer<Float> p = allocate();
+    p.value = 3.14159265359;
+    print('${p.runtimeType} value: ${p.value}');
+    p.value = 3.14;
+    print('${p.runtimeType} value: ${p.value}');
+    free(p);
+  }
+
+  {
+    // IntPtr varies in size based on whether the platform is 32 or 64 bit.
+    // Addresses of pointers fit in this size.
+    Pointer<IntPtr> p = allocate();
+    int p14addr = p.address;
+    p.value = p14addr;
+    int pValue = p.value;
+    print('${p.runtimeType} value: ${pValue}');
+    free(p);
+  }
+
+  {
+    // Void pointers are unsized.
+    // The size of the element it is pointing to is undefined,
+    // they cannot be allocated, read, or written.
+
+    Pointer<IntPtr> p1 = allocate();
+    Pointer<Void> p2 = p1.cast();
+    print('${p2.runtimeType} address: ${p2.address}');
+
+    free(p1);
+  }
+
+  {
+    // Pointer to a pointer to something.
+    Pointer<Int16> pHelper = allocate();
+    pHelper.value = 17;
+
+    Pointer<Pointer<Int16>> p = allocate();
+
+    // Storing into a pointer pointer automatically unboxes.
+    p.value = pHelper;
+
+    // Reading from a pointer pointer automatically boxes.
+    Pointer<Int16> pHelper2 = p.value;
+    print('${pHelper2.runtimeType} value: ${pHelper2.value}');
+
+    int pValue = p.value.value;
+    print('${p.runtimeType} value\'s value: ${pValue}');
+
+    free(p);
+    free(pHelper);
+  }
+
+  {
+    // The pointer to pointer types must match up.
+    Pointer<Int8> pHelper = allocate();
+    pHelper.value = 123;
+
+    Pointer<Pointer<Int16>> p = allocate();
+
+    // Trying to store `pHelper` into `p.val` would result in a type mismatch.
+
+    free(pHelper);
+    free(p);
+  }
+
+  {
+    // `nullptr` points to address 0 in c++.
+    Pointer<Pointer<Int8>> pointerToPointer = allocate();
+    Pointer<Int8> value = nullptr;
+    pointerToPointer.value = value;
+    value = pointerToPointer.value;
+    print("Loading a pointer to the 0 address is null: ${value}");
+    free(pointerToPointer);
+  }
+
+  {
+    // The toplevel function sizeOf returns element size in bytes.
+    print('sizeOf<Double>(): ${sizeOf<Double>()}');
+    print('sizeOf<Int16>(): ${sizeOf<Int16>()}');
+    print('sizeOf<IntPtr>(): ${sizeOf<IntPtr>()}');
+  }
+
+  {
+    // With IntPtr pointers, one could manually setup aribtrary data
+    // structres in C memory.
+    //
+    // However, it is advised to use Pointer<Pointer<...>> for that.
+
+    void createChain(Pointer<IntPtr> head, int length, int value) {
+      if (length == 0) {
+        head.value = value;
+        return;
+      }
+      Pointer<IntPtr> next = allocate<IntPtr>();
+      head.value = next.address;
+      createChain(next, length - 1, value);
+    }
+
+    int getChainValue(Pointer<IntPtr> head, int length) {
+      if (length == 0) {
+        return head.value;
+      }
+      Pointer<IntPtr> next = Pointer.fromAddress(head.value);
+      return getChainValue(next, length - 1);
+    }
+
+    void freeChain(Pointer<IntPtr> head, int length) {
+      Pointer<IntPtr> next = Pointer.fromAddress(head.value);
+      free(head);
+      if (length == 0) {
+        return;
+      }
+      freeChain(next, length - 1);
+    }
+
+    int length = 10;
+    Pointer<IntPtr> head = allocate();
+    createChain(head, length, 512);
+    int tailValue = getChainValue(head, length);
+    print('tailValue: ${tailValue}');
+    freeChain(head, length);
+  }
+
+  print("end main");
+}
diff --git a/samples_2/ffi/sample_ffi_dynamic_library.dart b/samples_2/ffi/sample_ffi_dynamic_library.dart
new file mode 100644
index 0000000..94863d0
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_dynamic_library.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.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'dylib_utils.dart';
+
+typedef NativeDoubleUnOp = Double Function(Double);
+
+typedef DoubleUnOp = double Function(double);
+
+main() {
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  print(l);
+  print(l.runtimeType);
+
+  var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
+  print(timesFour);
+  print(timesFour.runtimeType);
+
+  print(timesFour(3.0));
+}
diff --git a/samples_2/ffi/sample_ffi_functions.dart b/samples_2/ffi/sample_ffi_functions.dart
new file mode 100644
index 0000000..4cd30b0
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_functions.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+
+import 'dylib_utils.dart';
+
+typedef NativeUnaryOp = Int32 Function(Int32);
+typedef NativeBinaryOp = Int32 Function(Int32, Int32);
+typedef UnaryOp = int Function(int);
+typedef BinaryOp = int Function(int, int);
+typedef GenericBinaryOp<T> = int Function(int, T);
+typedef NativeQuadOpSigned = Int64 Function(Int64, Int32, Int16, Int8);
+typedef NativeQuadOpUnsigned = Uint64 Function(Uint64, Uint32, Uint16, Uint8);
+typedef NativeFunc4 = IntPtr Function(IntPtr);
+typedef NativeDoubleUnaryOp = Double Function(Double);
+typedef NativeFloatUnaryOp = Float Function(Float);
+typedef NativeDecenaryOp = IntPtr Function(IntPtr, IntPtr, IntPtr, IntPtr,
+    IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr);
+typedef NativeDecenaryOp2 = Int16 Function(
+    Int8, Int16, Int8, Int16, Int8, Int16, Int8, Int16, Int8, Int16);
+typedef NativeDoubleDecenaryOp = Double Function(Double, Double, Double, Double,
+    Double, Double, Double, Double, Double, Double);
+typedef NativeVigesimalOp = Double Function(
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double);
+typedef Int64PointerUnOp = Pointer<Int64> Function(Pointer<Int64>);
+typedef QuadOp = int Function(int, int, int, int);
+typedef DoubleUnaryOp = double Function(double);
+typedef DecenaryOp = int Function(
+    int, int, int, int, int, int, int, int, int, int);
+typedef DoubleDecenaryOp = double Function(double, double, double, double,
+    double, double, double, double, double, double);
+typedef VigesimalOp = double Function(
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double);
+
+main() {
+  print('start main');
+
+  DynamicLibrary ffiTestFunctions =
+      dlopenPlatformSpecific("ffi_test_functions");
+
+  {
+    // A int32 bin op.
+    BinaryOp sumPlus42 =
+        ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
+
+    var result = sumPlus42(3, 17);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Various size arguments.
+    QuadOp intComputation = ffiTestFunctions
+        .lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
+    var result = intComputation(125, 250, 500, 1000);
+    print(result);
+    print(result.runtimeType);
+
+    var mint = 0x7FFFFFFFFFFFFFFF; // 2 ^ 63 - 1
+    result = intComputation(1, 1, 0, mint);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Unsigned int parameters.
+    QuadOp uintComputation = ffiTestFunctions
+        .lookupFunction<NativeQuadOpUnsigned, QuadOp>("UintComputation");
+    var result = uintComputation(0xFF, 0xFFFF, 0xFFFFFFFF, -1);
+    result = uintComputation(1, 1, 0, -1);
+    print(result);
+    print(result.runtimeType);
+    print(-0xFF + 0xFFFF - 0xFFFFFFFF);
+  }
+
+  {
+    // Architecture size argument.
+    Pointer<NativeFunction<NativeFunc4>> p = ffiTestFunctions.lookup("Times3");
+    UnaryOp f6 = p.asFunction();
+    var result = f6(1337);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Function with double.
+    DoubleUnaryOp times1_337Double = ffiTestFunctions
+        .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
+    var result = times1_337Double(2.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Function with float.
+    DoubleUnaryOp times1_337Float = ffiTestFunctions
+        .lookupFunction<NativeFloatUnaryOp, DoubleUnaryOp>("Times1_337Float");
+    var result = times1_337Float(1000.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Function with many arguments: arguments get passed in registers and stack.
+    DecenaryOp sumManyInts = ffiTestFunctions
+        .lookupFunction<NativeDecenaryOp, DecenaryOp>("SumManyInts");
+    var result = sumManyInts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Function with many arguments: arguments get passed in registers and stack.
+    DecenaryOp sumManyInts = ffiTestFunctions
+        .lookupFunction<NativeDecenaryOp2, DecenaryOp>("SumManySmallInts");
+    var result = sumManyInts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Function with many double arguments.
+    DoubleDecenaryOp sumManyDoubles = ffiTestFunctions.lookupFunction<
+        NativeDoubleDecenaryOp, DoubleDecenaryOp>("SumManyDoubles");
+    var result =
+        sumManyDoubles(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // Function with many arguments, ints and doubles mixed.
+    VigesimalOp sumManyNumbers = ffiTestFunctions
+        .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+    var result = sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11,
+        12.0, 13, 14.0, 15, 16.0, 17, 18.0, 19, 20.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // pass an array / pointer as argument
+    Int64PointerUnOp assign1337Index1 = ffiTestFunctions
+        .lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
+    Pointer<Int64> p2 = allocate(count: 2);
+    p2.value = 42;
+    p2[1] = 1000;
+    print(p2.elementAt(1).address.toRadixString(16));
+    print(p2[1]);
+    Pointer<Int64> result = assign1337Index1(p2);
+    print(p2[1]);
+    print(assign1337Index1);
+    print(assign1337Index1.runtimeType);
+    print(result);
+    print(result.runtimeType);
+    print(result.address.toRadixString(16));
+    print(result.value);
+  }
+
+  {
+    // Passing in null for an int argument throws a null pointer exception.
+    BinaryOp sumPlus42 =
+        ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
+
+    int x = null;
+    try {
+      sumPlus42(43, x);
+    } on Error {
+      print('Expected exception on passing null for int');
+    }
+  }
+
+  {
+    // Passing in null for a double argument throws a null pointer exception.
+    DoubleUnaryOp times1_337Double = ffiTestFunctions
+        .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
+
+    double x = null;
+    try {
+      times1_337Double(x);
+    } on Error {
+      print('Expected exception on passing null for double');
+    }
+  }
+
+  {
+    // Passing in null for an int argument throws a null pointer exception.
+    VigesimalOp sumManyNumbers = ffiTestFunctions
+        .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+
+    int x = null;
+    try {
+      sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13,
+          14.0, 15, 16.0, 17, 18.0, x, 20.0);
+    } on Error {
+      print('Expected exception on passing null for int');
+    }
+  }
+
+  {
+    // Passing in nullptr for a pointer argument results in a nullptr in c.
+    Int64PointerUnOp nullableInt64ElemAt1 =
+        ffiTestFunctions.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>(
+            "NullableInt64ElemAt1");
+
+    Pointer<Int64> result = nullableInt64ElemAt1(nullptr);
+    print(result);
+    print(result.runtimeType);
+
+    Pointer<Int64> p2 = allocate(count: 2);
+    result = nullableInt64ElemAt1(p2);
+    print(result);
+    print(result.runtimeType);
+    free(p2);
+  }
+
+  print("end main");
+}
diff --git a/samples_2/ffi/sample_ffi_functions_callbacks.dart b/samples_2/ffi/sample_ffi_functions_callbacks.dart
new file mode 100644
index 0000000..79f9a41
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_functions_callbacks.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'coordinate.dart';
+import 'dylib_utils.dart';
+
+typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
+
+typedef CoordinateTrice = Pointer<Coordinate> Function(
+    Pointer<NativeFunction<NativeCoordinateOp>>, Pointer<Coordinate>);
+
+typedef BinaryOp = int Function(int, int);
+typedef NativeIntptrBinOp = IntPtr Function(IntPtr, IntPtr);
+typedef NativeIntptrBinOpLookup = Pointer<NativeFunction<NativeIntptrBinOp>>
+    Function();
+
+typedef NativeApplyTo42And74Type = IntPtr Function(
+    Pointer<NativeFunction<NativeIntptrBinOp>>);
+
+typedef ApplyTo42And74Type = int Function(
+    Pointer<NativeFunction<NativeIntptrBinOp>>);
+
+int myPlus(int a, int b) {
+  print("myPlus");
+  print(a);
+  print(b);
+  return a + b;
+}
+
+main() {
+  print('start main');
+
+  DynamicLibrary ffiTestFunctions =
+      dlopenPlatformSpecific("ffi_test_functions");
+
+  {
+    // Pass a c pointer to a c function as an argument to a c function.
+    Pointer<NativeFunction<NativeCoordinateOp>> transposeCoordinatePointer =
+        ffiTestFunctions.lookup("TransposeCoordinate");
+    Pointer<NativeFunction<CoordinateTrice>> p2 =
+        ffiTestFunctions.lookup("CoordinateUnOpTrice");
+    CoordinateTrice coordinateUnOpTrice = p2.asFunction();
+    Coordinate c1 = Coordinate.allocate(10.0, 20.0, nullptr);
+    c1.next = c1.addressOf;
+    Coordinate result =
+        coordinateUnOpTrice(transposeCoordinatePointer, c1.addressOf).ref;
+    print(result.runtimeType);
+    print(result.x);
+    print(result.y);
+  }
+
+  {
+    // Return a c pointer to a c function from a c function.
+    Pointer<NativeFunction<NativeIntptrBinOpLookup>> p14 =
+        ffiTestFunctions.lookup("IntptrAdditionClosure");
+    NativeIntptrBinOpLookup intptrAdditionClosure = p14.asFunction();
+
+    Pointer<NativeFunction<NativeIntptrBinOp>> intptrAdditionPointer =
+        intptrAdditionClosure();
+    BinaryOp intptrAddition = intptrAdditionPointer.asFunction();
+    print(intptrAddition(10, 27));
+  }
+
+  {
+    Pointer<NativeFunction<NativeIntptrBinOp>> pointer =
+        Pointer.fromFunction(myPlus, 0);
+    print(pointer);
+
+    Pointer<NativeFunction<NativeApplyTo42And74Type>> p17 =
+        ffiTestFunctions.lookup("ApplyTo42And74");
+    ApplyTo42And74Type applyTo42And74 = p17.asFunction();
+
+    int result = applyTo42And74(pointer);
+    print(result);
+  }
+
+  print("end main");
+}
diff --git a/samples_2/ffi/sample_ffi_functions_callbacks_closures.dart b/samples_2/ffi/sample_ffi_functions_callbacks_closures.dart
new file mode 100644
index 0000000..a6ce9a6
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_functions_callbacks_closures.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'dylib_utils.dart';
+
+void main() {
+  print('start main');
+
+  doDynamicLinking();
+
+  int counter = 0;
+  void closure() {
+    counter++;
+  }
+
+  // C holds on to this closure through a `Dart_PersistenHandle`.
+  registerClosureCallback(closure);
+
+  // Some time later this closure can be invoked.
+  invokeClosureCallback();
+  Expect.equals(1, counter);
+
+  // When C is done it needs to stop holding on to the closure such that the
+  // Dart GC can collect the closure.
+  releaseClosureCallback();
+
+  print('end main');
+}
+
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
+
+final registerClosureCallback =
+    testLibrary.lookupFunction<Void Function(Handle), void Function(Object)>(
+        "RegisterClosureCallback");
+
+final invokeClosureCallback = testLibrary
+    .lookupFunction<Void Function(), void Function()>("InvokeClosureCallback");
+
+final releaseClosureCallback = testLibrary
+    .lookupFunction<Void Function(), void Function()>("ReleaseClosureCallback");
+
+void doClosureCallback(Object callback) {
+  final callback_as_function = callback as void Function();
+  callback_as_function();
+}
+
+final closureCallbackPointer =
+    Pointer.fromFunction<Void Function(Handle)>(doClosureCallback);
+
+void doDynamicLinking() {
+  Expect.isTrue(NativeApi.majorVersion == 2);
+  Expect.isTrue(NativeApi.minorVersion >= 0);
+  final initializeApi = testLibrary.lookupFunction<
+      IntPtr Function(Pointer<Void>),
+      int Function(Pointer<Void>)>("InitDartApiDL");
+  Expect.isTrue(initializeApi(NativeApi.initializeApiDLData) == 0);
+
+  final registerClosureCallback = testLibrary.lookupFunction<
+      Void Function(Pointer),
+      void Function(Pointer)>("RegisterClosureCallbackFP");
+  registerClosureCallback(closureCallbackPointer);
+}
diff --git a/samples_2/ffi/sample_ffi_functions_structs.dart b/samples_2/ffi/sample_ffi_functions_structs.dart
new file mode 100644
index 0000000..7129658
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_functions_structs.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'coordinate.dart';
+import 'dylib_utils.dart';
+
+import 'package:ffi/ffi.dart';
+
+typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
+
+main() {
+  print('start main');
+
+  DynamicLibrary ffiTestFunctions =
+      dlopenPlatformSpecific("ffi_test_functions");
+
+  {
+    // Pass a struct to a c function and get a struct as return value.
+    Pointer<NativeFunction<NativeCoordinateOp>> p1 =
+        ffiTestFunctions.lookup("TransposeCoordinate");
+    NativeCoordinateOp f1 = p1.asFunction();
+
+    Coordinate c1 = Coordinate.allocate(10.0, 20.0, nullptr);
+    Coordinate c2 = Coordinate.allocate(42.0, 84.0, c1.addressOf);
+    c1.next = c2.addressOf;
+
+    Coordinate result = f1(c1.addressOf).ref;
+
+    print(c1.x);
+    print(c1.y);
+
+    print(result.runtimeType);
+
+    print(result.x);
+    print(result.y);
+  }
+
+  {
+    // Pass an array of structs to a c funtion.
+    Pointer<NativeFunction<NativeCoordinateOp>> p1 =
+        ffiTestFunctions.lookup("CoordinateElemAt1");
+    NativeCoordinateOp f1 = p1.asFunction();
+
+    Pointer<Coordinate> c1 = allocate<Coordinate>(count: 3);
+    Pointer<Coordinate> c2 = c1.elementAt(1);
+    Pointer<Coordinate> c3 = c1.elementAt(2);
+    c1.ref.x = 10.0;
+    c1.ref.y = 10.0;
+    c1.ref.next = c3;
+    c2.ref.x = 20.0;
+    c2.ref.y = 20.0;
+    c2.ref.next = c1;
+    c3.ref.x = 30.0;
+    c3.ref.y = 30.0;
+    c3.ref.next = c2;
+
+    Coordinate result = f1(c1).ref;
+
+    print(result.x);
+    print(result.y);
+  }
+
+  print("end main");
+}
diff --git a/samples_2/ffi/sample_ffi_structs.dart b/samples_2/ffi/sample_ffi_structs.dart
new file mode 100644
index 0000000..d5af59e
--- /dev/null
+++ b/samples_2/ffi/sample_ffi_structs.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+
+import 'coordinate.dart';
+
+main() {
+  print('start main');
+
+  {
+    // Allocates each coordinate separately in c memory.
+    Coordinate c1 = Coordinate.allocate(10.0, 10.0, nullptr);
+    Coordinate c2 = Coordinate.allocate(20.0, 20.0, c1.addressOf);
+    Coordinate c3 = Coordinate.allocate(30.0, 30.0, c2.addressOf);
+    c1.next = c3.addressOf;
+
+    Coordinate currentCoordinate = c1;
+    for (var i in [0, 1, 2, 3, 4]) {
+      currentCoordinate = currentCoordinate.next.ref;
+      print("${currentCoordinate.x}; ${currentCoordinate.y}");
+    }
+
+    free(c1.addressOf);
+    free(c2.addressOf);
+    free(c3.addressOf);
+  }
+
+  {
+    // Allocates coordinates consecutively in c memory.
+    Pointer<Coordinate> c1 = allocate<Coordinate>(count: 3);
+    Pointer<Coordinate> c2 = c1.elementAt(1);
+    Pointer<Coordinate> c3 = c1.elementAt(2);
+    c1.ref.x = 10.0;
+    c1.ref.y = 10.0;
+    c1.ref.next = c3;
+    c2.ref.x = 20.0;
+    c2.ref.y = 20.0;
+    c2.ref.next = c1;
+    c3.ref.x = 30.0;
+    c3.ref.y = 30.0;
+    c3.ref.next = c2;
+
+    Coordinate currentCoordinate = c1.ref;
+    for (var i in [0, 1, 2, 3, 4]) {
+      currentCoordinate = currentCoordinate.next.ref;
+      print("${currentCoordinate.x}; ${currentCoordinate.y}");
+    }
+
+    free(c1);
+  }
+
+  {
+    Coordinate c = Coordinate.allocate(10, 10, nullptr);
+    print(c is Coordinate);
+    print(c is Pointer<Void>);
+    print(c is Pointer);
+    free(c.addressOf);
+  }
+
+  print("end main");
+}
diff --git a/samples_2/ffi/samples_test.dart b/samples_2/ffi/samples_test.dart
new file mode 100644
index 0000000..a3674a4
--- /dev/null
+++ b/samples_2/ffi/samples_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file exercises the sample files so that they are tested.
+//
+// SharedObjects=ffi_test_dynamic_library ffi_test_functions
+
+// @dart = 2.9
+
+import 'sample_ffi_bitfield.dart' as bitfield;
+import 'sample_ffi_data.dart' as data;
+import 'sample_ffi_dynamic_library.dart' as dynamic_library;
+import 'sample_ffi_functions_callbacks_closures.dart'
+    as functions_callbacks_closures;
+import 'sample_ffi_functions_callbacks.dart' as functions_callbacks;
+import 'sample_ffi_functions_structs.dart' as functions_structs;
+import 'sample_ffi_functions.dart' as functions;
+import 'sample_ffi_structs.dart' as structs;
+
+main() {
+  bitfield.main();
+  data.main();
+  dynamic_library.main();
+  functions_callbacks_closures.main();
+  functions_callbacks.main();
+  functions_structs.main();
+  functions.main();
+  structs.main();
+}
diff --git a/samples_2/ffi/sqlite/.gitignore b/samples_2/ffi/sqlite/.gitignore
new file mode 100644
index 0000000..7a6bc2e
--- /dev/null
+++ b/samples_2/ffi/sqlite/.gitignore
@@ -0,0 +1,7 @@
+.dart_tool
+.gdb_history
+.packages
+.vscode
+pubspec.lock
+test.db
+test.db-journal
\ No newline at end of file
diff --git a/samples_2/ffi/sqlite/README.md b/samples_2/ffi/sqlite/README.md
new file mode 100644
index 0000000..fbd5cb9
--- /dev/null
+++ b/samples_2/ffi/sqlite/README.md
@@ -0,0 +1,55 @@
+# Sample code dart:ffi
+
+This is an illustrative sample for how to use `dart:ffi`.
+
+## Prerequirement
+
+For Windows, Linux, and MacOS, you should make sure, sqlite dev lib installed on your system.
+
+Windows user can download dll from https://www.sqlite.org/download.html
+
+If you do not have any sqlite3.dll or so file, you may found error message:
+
+```
+Unhandled exception:
+Invalid argument(s): Failed to load dynamic library (126)
+#0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:13:55)
+#1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
+```
+
+## Building and Running this Sample
+
+Building and running this sample is done through pub.
+Running `pub get` and `pub run example/main` should produce the following output.
+
+```sh
+$ pub get
+Resolving dependencies... (6.8s)
++ analyzer 0.35.4
+...
++ yaml 2.1.15
+Downloading analyzer 0.35.4...
+Downloading kernel 0.3.14...
+Downloading front_end 0.1.14...
+Changed 47 dependencies!
+Precompiling executables... (18.0s)
+Precompiled test:test.
+
+```
+
+```
+$ pub run example/main
+1 Chocolade chip cookie Chocolade cookie foo
+2 Ginger cookie null 42
+3 Cinnamon roll null null
+1 Chocolade chip cookie Chocolade cookie foo
+2 Ginger cookie null 42
+expected exception on accessing result data after close: The result has already been closed.
+expected this query to fail: no such column: non_existing_column (Code 1: SQL logic error)
+```
+
+## Tutorial
+
+A tutorial walking through the code is available in [docs/sqlite-tutorial.md](docs/sqlite-tutorial.md).
+For information on how to use this package within a Flutter app, see [docs/android.md](docs/android.md).
+(Note: iOS is not yet supported).
diff --git a/samples_2/ffi/sqlite/docs/android.md b/samples_2/ffi/sqlite/docs/android.md
new file mode 100644
index 0000000..7478c17
--- /dev/null
+++ b/samples_2/ffi/sqlite/docs/android.md
@@ -0,0 +1,53 @@
+**This documentation is for demonstration/testing purposes only!**
+
+# Using FFI with Flutter
+
+## Android
+
+Before using the FFI on Android, you need to procure an Android-compatible build of the native library you want to link against.
+It's important that the shared object(s) be compatible with ABI version you wish to target (or else, that you have multiple builds for different ABIs).
+See [https://developer.android.com/ndk/guides/abis] for more details on Android ABIs.
+Within Flutter, the target ABI is controlled by the `--target-platform` parameter to the `flutter` command.
+
+The workflow for packaging a native library will depend significantly on the library itself, but to illustrate the challenges at play, we'll demonstrate how to build the SQLite library from source to use with the FFI on an Android device.
+
+### Building SQLite for Android
+
+Every Android device ships with a copy of the SQLite library (`/system/lib/libsqlite.so`).
+Unfortunately, this library cannot be loaded directly by apps (see [https://developer.android.com/about/versions/nougat/android-7.0-changes#ndk]).
+It is accessible only through Java.
+Instead, we can build SQLite directly with the NDK.
+
+First, download the SQLite "amalgamation" source from [https://www.sqlite.org/download.html].
+For the sake of brevity, we'll assume the file has been saved as `sqlite-amalgamation-XXXXXXX.zip`, the Android SDK (with NDK extension) is available in `~/Android`, and we're on a Linux workstation.
+
+```sh
+unzip sqlite-amalgamation-XXXXXXX.zip
+cd sqlite-amalgamation-XXXXXXX
+~/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang -c sqlite3.c -o sqlite3.o
+~/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld -shared sqlite3.o -o libsqlite3.so
+```
+
+Note the use of the `aarch64` prefix to the compiler: this indicates that we're building a shared object for the `arm64-v8a` ABI.
+This will be important later.
+
+### Update Gradle script
+
+Next we need to instruct Gradle to package this library with the app, so it will be available to load off the Android device at runtime.
+Create a folder `native-libraries` in the root folder of the app, and update the `android/app/build.gradle` file:
+
+```groovy
+android {
+    // ...
+    sourceSets {
+        main {
+            jniLibs.srcDir "${project.projectDir.path}/../../native-libraries"
+        }
+    }
+}
+```
+
+Within the `native-libraries` folder, the libraries are organized by ABI.
+Therefore, we must copy the compiled `libsqlite3.so` into `native-libraries/arm64-v8a/libsqlite3.so`.
+If multiple sub-directories are present, the libraries from the sub-directory corresponding to the target ABI will be available in the application's linking path, so the library can be loaded with `DynamicLibrary.open("libsqlite3.so")` in Dart.
+Finally, pass `--target-platform=android-arm64` to the `flutter` command when running or building the app since `libsqlite3.so` was compiled for the `arm64-v8a` ABI.
diff --git a/samples_2/ffi/sqlite/docs/lib/scenario-default.svg b/samples_2/ffi/sqlite/docs/lib/scenario-default.svg
new file mode 100644
index 0000000..6ffa8a3
--- /dev/null
+++ b/samples_2/ffi/sqlite/docs/lib/scenario-default.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xl="http://www.w3.org/1999/xlink" viewBox="27.846457 27.846457 426.19686 227.77166" width="426.19686" height="227.77166">
+  <defs>
+    <font-face font-family="Helvetica Neue" font-size="16" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400">
+      <font-face-src>
+        <font-face-name name="HelveticaNeue"/>
+      </font-face-src>
+    </font-face>
+    <font-face font-family="Helvetica Neue" font-size="10" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400">
+      <font-face-src>
+        <font-face-name name="HelveticaNeue"/>
+      </font-face-src>
+    </font-face>
+  </defs>
+  <metadata> Produced by OmniGraffle 7.9.4 
+    <dc:date>2019-03-13 09:56:08 +0000</dc:date>
+  </metadata>
+  <g id="Canvas_1" fill="none" fill-opacity="1" stroke="none" stroke-dasharray="none" stroke-opacity="1">
+    <title>Canvas 1</title>
+    <rect fill="white" x="27.846457" y="27.846457" width="426.19686" height="227.77166"/>
+    <g id="Canvas_1: Layer 1">
+      <title>Layer 1</title>
+      <g id="Graphic_3">
+        <rect x="28.346457" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="28.346457" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(33.346457 110.00952)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="14.703685" y="15">Flutter </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="22.847685" y="33.448">App</tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="8.031685" y="69.896">(Imports </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="4.775685" y="88.34399">package)</tspan>
+        </text>
+      </g>
+      <g id="Graphic_5">
+        <rect x="368.50395" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="368.50395" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(373.50395 137.45752)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="14.855685" y="15">Native </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="12.927685" y="33.448">Library</tspan>
+        </text>
+      </g>
+      <g id="Graphic_6">
+        <rect x="311.81103" y="85.03937" width="56.692915" height="141.73229" fill="white"/>
+        <rect x="311.81103" y="85.03937" width="56.692915" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(316.81103 146.68152)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x=".5064575" y="15">dart:ffi</tspan>
+        </text>
+      </g>
+      <g id="Graphic_7">
+        <rect x="113.38583" y="85.03937" width="56.692915" height="141.73229" fill="white"/>
+        <rect x="113.38583" y="85.03937" width="56.692915" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(118.38583 119.20552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="3.9014575" y="10">Package </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="15.571457" y="22.28">API</tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="1.8614575" y="46.56">(Does not </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="7.0514575" y="58.839996">expose </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="7.7764575" y="71.119995">dart:ffi)</tspan>
+        </text>
+      </g>
+      <g id="Graphic_8">
+        <rect x="28.346457" y="226.77166" width="311.81103" height="28.346457" fill="white"/>
+        <rect x="28.346457" y="226.77166" width="311.81103" height="28.346457" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(33.346457 231.7209)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="135.79352" y="15">Dart</tspan>
+        </text>
+      </g>
+      <g id="Graphic_9">
+        <rect x="340.1575" y="226.77166" width="113.38583" height="28.346457" fill="white"/>
+        <rect x="340.1575" y="226.77166" width="113.38583" height="28.346457" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(345.1575 231.7209)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="23.428915" y="15">C / C++</tspan>
+        </text>
+      </g>
+      <g id="Graphic_10">
+        <rect x="28.346457" y="28.346457" width="85.03937" height="56.692915" fill="white"/>
+        <rect x="28.346457" y="28.346457" width="85.03937" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(33.346457 38.244917)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="22.847685" y="15">App </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="1.2236848" y="33.448">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_11">
+        <rect x="113.38583" y="28.346457" width="198.4252" height="56.692915" fill="white"/>
+        <rect x="113.38583" y="28.346457" width="198.4252" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(118.38583 38.244917)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="63.1006" y="15">Package</tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="57.9166" y="33.448">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_12">
+        <rect x="311.81103" y="28.346457" width="56.692915" height="56.692915" fill="white"/>
+        <rect x="311.81103" y="28.346457" width="56.692915" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(316.81103 29.020918)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="8.234457" y="15">Dart </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.490457" y="33.448">VM </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="4.2264575" y="51.895996">Team</tspan>
+        </text>
+      </g>
+      <g id="Graphic_13">
+        <rect x="255.11812" y="85.03937" width="56.692915" height="141.73229" fill="white"/>
+        <rect x="255.11812" y="85.03937" width="56.692915" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(260.11812 149.76552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="3.8064575" y="10">Bindings</tspan>
+        </text>
+      </g>
+      <g id="Graphic_14">
+        <rect x="368.50395" y="28.346457" width="85.03937" height="56.692915" fill="white"/>
+        <rect x="368.50395" y="28.346457" width="85.03937" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(373.50395 29.020918)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="14.855686" y="15">Native </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="12.927686" y="33.448">Library </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="1.2236862" y="51.895996">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_15">
+        <rect x="170.07874" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="170.07874" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(175.07874 106.92552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="18.074685" y="10">Package </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="2.8746848" y="22.28">Implementation</tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="9.559685" y="46.56">(Code which </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="7.259685" y="58.839996">converts C++ </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x=".1996848" y="71.119995">abstractions into </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="28.074685" y="83.39999">Dart </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="8.629685" y="95.67999">abstractions)</tspan>
+        </text>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/samples_2/ffi/sqlite/docs/lib/scenario-full.svg b/samples_2/ffi/sqlite/docs/lib/scenario-full.svg
new file mode 100644
index 0000000..4ae18c5
--- /dev/null
+++ b/samples_2/ffi/sqlite/docs/lib/scenario-full.svg
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="27.846457 27.846457 511.23623 227.77166" width="511.23623" height="227.77166">
+  <defs>
+    <font-face font-family="Helvetica Neue" font-size="16" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400">
+      <font-face-src>
+        <font-face-name name="HelveticaNeue"/>
+      </font-face-src>
+    </font-face>
+    <font-face font-family="Helvetica Neue" font-size="10" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400">
+      <font-face-src>
+        <font-face-name name="HelveticaNeue"/>
+      </font-face-src>
+    </font-face>
+  </defs>
+  <metadata> Produced by OmniGraffle 7.9.4 
+    <dc:date>2019-03-13 09:53:08 +0000</dc:date>
+  </metadata>
+  <g id="Canvas_1" stroke-opacity="1" stroke="none" stroke-dasharray="none" fill-opacity="1" fill="none">
+    <title>Canvas 1</title>
+    <rect fill="white" x="27.846457" y="27.846457" width="511.23623" height="227.77166"/>
+    <g id="Canvas_1: Layer 1">
+      <title>Layer 1</title>
+      <g id="Graphic_3">
+        <rect x="28.346457" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="28.346457" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(33.346457 110.00952)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="14.703685" y="15">Flutter </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="22.847685" y="33.448">App</tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="8.031685" y="69.896">(Imports </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="4.775685" y="88.34399">package)</tspan>
+        </text>
+      </g>
+      <g id="Graphic_5">
+        <rect x="453.5433" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="453.5433" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(458.5433 137.45752)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="14.855685" y="15">Native </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="12.927685" y="33.448">Library</tspan>
+        </text>
+      </g>
+      <g id="Graphic_6">
+        <rect x="311.81103" y="85.03937" width="56.692915" height="141.73229" fill="white"/>
+        <rect x="311.81103" y="85.03937" width="56.692915" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(316.81103 146.68152)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x=".5064575" y="15">dart:ffi</tspan>
+        </text>
+      </g>
+      <g id="Graphic_7">
+        <rect x="113.38583" y="85.03937" width="56.692915" height="141.73229" fill="white"/>
+        <rect x="113.38583" y="85.03937" width="56.692915" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(118.38583 119.20552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="3.9014575" y="10">Package </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="15.571457" y="22.28">API</tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="1.8614575" y="46.56">(Does not </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="7.0514575" y="58.839996">expose </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="7.7764575" y="71.119995">dart:ffi)</tspan>
+        </text>
+      </g>
+      <g id="Graphic_8">
+        <rect x="28.346457" y="226.77166" width="311.81103" height="28.346457" fill="white"/>
+        <rect x="28.346457" y="226.77166" width="311.81103" height="28.346457" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(33.346457 231.7209)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="135.79352" y="15">Dart</tspan>
+        </text>
+      </g>
+      <g id="Graphic_9">
+        <rect x="340.1575" y="226.77166" width="198.4252" height="28.346457" fill="white"/>
+        <rect x="340.1575" y="226.77166" width="198.4252" height="28.346457" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(345.1575 231.7209)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="65.9486" y="15">C / C++</tspan>
+        </text>
+      </g>
+      <g id="Graphic_10">
+        <rect x="28.346457" y="28.346457" width="85.03937" height="56.692915" fill="white"/>
+        <rect x="28.346457" y="28.346457" width="85.03937" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(33.346457 38.244917)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="22.847685" y="15">App </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="1.2236848" y="33.448">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_11">
+        <rect x="113.38583" y="28.346457" width="198.4252" height="56.692915" fill="white"/>
+        <rect x="113.38583" y="28.346457" width="198.4252" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(118.38583 38.244917)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="63.1006" y="15">Package</tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="57.9166" y="33.448">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_12">
+        <rect x="311.81103" y="28.346457" width="56.692915" height="56.692915" fill="white"/>
+        <rect x="311.81103" y="28.346457" width="56.692915" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(316.81103 29.020918)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="8.234457" y="15">Dart </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="11.490457" y="33.448">VM </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="4.2264575" y="51.895996">Team</tspan>
+        </text>
+      </g>
+      <g id="Graphic_13">
+        <rect x="255.11812" y="85.03937" width="56.692915" height="141.73229" fill="white"/>
+        <rect x="255.11812" y="85.03937" width="56.692915" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(260.11812 149.76552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="3.8064575" y="10">Bindings</tspan>
+        </text>
+      </g>
+      <g id="Graphic_14">
+        <rect x="453.5433" y="28.346457" width="85.03937" height="56.692915" fill="white"/>
+        <rect x="453.5433" y="28.346457" width="85.03937" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(458.5433 29.020918)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="14.855686" y="15">Native </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="12.927686" y="33.448">Library </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="1.2236862" y="51.895996">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_15">
+        <rect x="170.07874" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="170.07874" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(175.07874 106.92552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="18.074685" y="10">Package </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="2.8746848" y="22.28">Implementation</tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="9.559685" y="46.56">(Code which </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="7.259685" y="58.839996">converts C++ </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x=".1996848" y="71.119995">abstractions into </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="28.074685" y="83.39999">Dart </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="8.629685" y="95.67999">abstractions)</tspan>
+        </text>
+      </g>
+      <g id="Graphic_16">
+        <rect x="368.50395" y="28.346457" width="85.03937" height="56.692915" fill="white"/>
+        <rect x="368.50395" y="28.346457" width="85.03937" height="56.692915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(373.50395 38.244917)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="6.407685" y="15">Package </tspan>
+          <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="1.2236848" y="33.448">Developer</tspan>
+        </text>
+      </g>
+      <g id="Graphic_17">
+        <rect x="368.50395" y="85.03937" width="85.03937" height="141.73229" fill="white"/>
+        <rect x="368.50395" y="85.03937" width="85.03937" height="141.73229" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <text transform="translate(373.50395 119.20552)" fill="black">
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="14.554685" y="10">Glue code</tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="9.559685" y="34.28">(Code which </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="8.719685" y="46.56">takes care of </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x="5.194685" y="58.839996">things such as </tspan>
+          <tspan font-family="Helvetica Neue" font-size="10" font-weight="400" fill="black" x=".7796848" y="71.119995">C++ exceptions)</tspan>
+        </text>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/samples_2/ffi/sqlite/docs/sqlite-tutorial.md b/samples_2/ffi/sqlite/docs/sqlite-tutorial.md
new file mode 100644
index 0000000..c7ea858
--- /dev/null
+++ b/samples_2/ffi/sqlite/docs/sqlite-tutorial.md
@@ -0,0 +1,234 @@
+# dart:ffi SQLite mini tutorial
+
+In this mini tutorial we learn how to bind SQLite, a native library, in Dart using Dart's new foreign function interface `dart:ffi`.
+We build a package which provides a Dartlike SQLite API using objects and `Iterator`s.
+Inside the package we write Dart code which directly invokes C functions and manipulates C memory.
+
+## Binding C Functions to Dart
+
+The first step is to load a Native Library:
+
+```dart
+import "dart:ffi";
+
+DynamicLibrary sqlite = dlopenPlatformSpecific("sqlite3");
+```
+
+In a `DynamicLibrary` we can `lookup` functions.
+Let's lookup the function `sqlite3_prepare_v2` in the SQLite library.
+That function has the following signature in the library header file.
+
+```c++
+SQLITE_API int sqlite3_prepare_v2(
+  sqlite3 *db,            /* Database handle */
+  const char *zSql,       /* SQL statement, UTF-8 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+```
+
+In order to lookup a function, we need a _C signature_ and a _Dart signature_.
+
+```dart
+typedef sqlite3_prepare_v2_native_t = Int32 Function(
+    DatabasePointer database,
+    CString query,
+    Int32 nbytes,
+    Pointer<StatementPointer> statementOut,
+    Pointer<CString> tail);
+
+typedef Sqlite3_prepare_v2_t = int Function(
+    DatabasePointer database,
+    CString query,
+    int nbytes,
+    Pointer<StatementPointer> statementOut,
+    Pointer<CString> tail);
+```
+
+With these two signatures we can `lookup` the C function and expose it as a Dart function with `asFunction`.
+
+```dart
+Sqlite3_prepare_v2_t sqlite3_prepare_v2 = sqlite
+    .lookup<NativeFunction<sqlite3_prepare_v2_native_t>>("sqlite3_prepare_v2")
+    .asFunction();
+```
+
+Browse the code: [platform specific dynamic library loading](../lib/src/ffi/dylib_utils.dart), [C signatures](../lib/src/bindings/signatures.dart), [Dart signatures and bindings](../lib/src/bindings/bindings.dart), and [dart:ffi dynamic library interface](../../../../sdk/lib/ffi/dynamic_library.dart).
+
+## Managing C Memory
+
+In order to call `sqlite3_prepare_v2` to prepare a SQLite statement before executing, we need to be able to pass C pointers to C functions.
+
+Database and Statement pointers are opaque pointers in the SQLite C API.
+We specify these as classes extending `Pointer<Void>`.
+
+```dart
+class DatabasePointer extends Pointer<Void> {}
+class StatementPointer extends Pointer<Void> {}
+```
+
+Strings in C are pointers to character arrays.
+
+```dart
+class CString extends Pointer<Uint8> {}
+```
+
+Pointers to C integers, floats, an doubles can be read from and written through to `dart:ffi`.
+However, before we can write to C memory from dart, we need to `allocate` some memory.
+
+```dart
+Pointer<Uint8> p = allocate(); // Infers type argument allocate<Uint8>(), and allocates 1 byte.
+p.value = 123;                 // Stores a Dart int into this C int8.
+int v = p.value;               // Loads a value from C memory.
+```
+
+Note that you can only load a Dart `int` from a C `Uint8`.
+Trying to load a Dart `double` will result in a runtime exception.
+
+We've almost modeled C Strings.
+The last thing we need is to use this `Pointer` as an array.
+We can do this by using `elementAt`.
+
+```dart
+CString string = allocate(count: 4).cast(); // Allocates 4 bytes and casts it to a string.
+string.value = 70;                          // Stores 'F' at index 0.
+string[1] = 70;                             // Stores 'F' at index 1.
+string[2] = 73;                             // Stores 'I' at index 2.
+string[3] = 0;                              // Null terminates the string.
+```
+
+We wrap the above logic of allocating strings in the constructor `CString.allocate`.
+
+Now we have all ingredients to call `sqlite3_prepare_v2`.
+
+```dart
+Pointer<StatementPointer> statementOut = allocate();
+CString queryC = CString.allocate(query);
+int resultCode = sqlite3_prepare_v2(
+    _database, queryC, -1, statementOut, nullptr);
+```
+
+With `dart:ffi` we are responsible for freeing C memory that we allocate.
+So after calling `sqlite3_prepare_v2` we read out the statement pointer, and free the statement pointer pointer and `CString` which held the query string.
+
+```
+StatementPointer statement = statementOut.value;
+statementOut.free();
+queryC.free();
+```
+
+Browse the code: [CString class](../lib/src/ffi/utf8.dart), [code calling sqlite3_prepare_v2](../lib/src/database.dart#57), and [dart:ffi pointer interface](../../../../sdk/lib/ffi/ffi.dart).
+
+## Dart API
+
+We would like to present the users of our package with an object oriented API - not exposing any `dart:ffi` objects to them.
+
+The SQLite C API returns a cursor to the first row of a result after executing a query.
+We can read out the columns of this row and move the cursor to the next row.
+The most natural way to expose this in Dart is through an `Iterable`.
+We provide our package users with the following API.
+
+```dart
+class Result implements Iterable<Row> {}
+
+class Row {
+  dynamic readColumnByIndex(int columnIndex) {}
+  dynamic readColumn(String columnName) {}
+}
+```
+
+However, this interface does not completely match the semantics of the C API.
+When we start reading the next `Row`, we do no longer have access to the previous `Row`.
+We can model this by letting a `Row` keep track if its current or not.
+
+```dart
+class Row {
+  bool _isCurrentRow = true;
+
+  dynamic readColumnByIndex(int columnIndex) {
+    if (!_isCurrentRow) {
+      throw Exception(
+          "This row is not the current row, reading data from the non-current"
+          " row is not supported by sqlite.");
+    }
+    // ...
+    }
+}
+```
+
+A second mismatch between Dart and C is that in C we have to manually release resources.
+After executing a query and reading its results we need to call `sqlite3_finalize(statement)`.
+
+We can take two approaches here, either we structure the API in such a way that users of our package (implicitly) release resources, or we use finalizers to release resources.
+In this tutorial we take the first approach.
+
+If our users iterate over all `Row`s, we can implicitly finalize the statement after they are done with the last row.
+However, if they decide they do not want to iterate over the whole result, they need to explicitly state this.
+In this tutorial, we use the `ClosableIterator` abstraction for `Iterators` with backing resources that need to be `close`d.
+
+```dart
+Result result = d.query("""
+  select id, name
+  from Cookies
+  ;""");
+for (Row r in result) {
+  String name = r.readColumn("name");
+  print(name);
+}
+// Implicitly closes the iterator.
+
+result = d.query("""
+  select id, name
+  from Cookies
+  ;""");
+for (Row r in result) {
+  int id = r.readColumn("id");
+  if (id == 1) {
+    result.close(); // Explicitly closes the iterator, releasing underlying resources.
+    break;
+  }
+}
+```
+
+Browse the code: [Database, Result, Row](../lib/src/database.dart), and [CloseableIterator](../lib/src/collections/closable_iterator.dart).
+
+## Architecture Overview
+
+The following diagram summarized what we have implemented as _package developers_ in this tutorial.
+
+![architecture](lib/scenario-default.svg)
+
+As the package developers wrapping an existing native library, we have only written Dart code - not any C/C++ code.
+We specified bindings to the native library.
+We have provided our package users with an object oriented API without exposing any `dart:ffi` objects.
+And finally, we have implemented the package API by calling the C API.
+
+## Current dart:ffi Development Status
+
+In this minitutorial we used these `dart:ffi` features:
+
+* Loading dynamic libararies and looking up C functions in these dynamic libraries.
+* Calling C functions, with `dart:ffi` automatically marshalling arguments and return value.
+* Manipulating C memory through `Pointer`s with `allocate`, `free`, `load`, `store`, and `elementAt`.
+
+Features which we did not use in this tutorial:
+
+* `@struct` on subtypes of `Pointer` to define a struct with fields. (However, this feature is likely to change in the future.)
+
+Features which `dart:ffi` does not support yet:
+
+* Callbacks from C back into Dart.
+* Finalizers
+* C++ Exceptions (Not on roadmap yet.)
+
+Platform limitations:
+
+* `dart:ffi` is only enabled on 64 bit Windows, Linux, and MacOS. (Arm64 and 32 bit Intel are under review.)
+* `dart:ffi` only works in JIT mode, not in AOT.
+
+It is possible to work around some of the current limitations by adding a C/C++ layer.
+For example we could catch C++ exceptions in a C++ layer, and rethrow them in Dart.
+The architecture diagram would change to the following in that case.
+
+![architecture2](lib/scenario-full.svg)
diff --git a/samples_2/ffi/sqlite/example/main.dart b/samples_2/ffi/sqlite/example/main.dart
new file mode 100644
index 0000000..6af01d4
--- /dev/null
+++ b/samples_2/ffi/sqlite/example/main.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "../lib/sqlite.dart";
+
+void main() {
+  Database d = Database("test.db");
+  d.execute("drop table if exists Cookies;");
+  d.execute("""
+      create table Cookies (
+        id integer primary key,
+        name text not null,
+        alternative_name text
+      );""");
+  d.execute("""
+      insert into Cookies (id, name, alternative_name)
+      values
+        (1,'Chocolade chip cookie', 'Chocolade cookie'),
+        (2,'Ginger cookie', null),
+        (3,'Cinnamon roll', null)
+      ;""");
+  Result result = d.query("""
+      select
+        id,
+        name,
+        alternative_name,
+        case
+          when id=1 then 'foo'
+          when id=2 then 42
+          when id=3 then null
+        end as multi_typed_column
+      from Cookies
+      ;""");
+  for (Row r in result) {
+    int id = r.readColumnAsInt("id");
+    String name = r.readColumnByIndex(1);
+    String alternativeName = r.readColumn("alternative_name");
+    dynamic multiTypedValue = r.readColumn("multi_typed_column");
+    print("$id $name $alternativeName $multiTypedValue");
+  }
+  result = d.query("""
+      select
+        id,
+        name,
+        alternative_name,
+        case
+          when id=1 then 'foo'
+          when id=2 then 42
+          when id=3 then null
+        end as multi_typed_column
+      from Cookies
+      ;""");
+  for (Row r in result) {
+    int id = r.readColumnAsInt("id");
+    String name = r.readColumnByIndex(1);
+    String alternativeName = r.readColumn("alternative_name");
+    dynamic multiTypedValue = r.readColumn("multi_typed_column");
+    print("$id $name $alternativeName $multiTypedValue");
+    if (id == 2) {
+      result.close();
+      break;
+    }
+  }
+  try {
+    result.iterator.moveNext();
+  } on SQLiteException catch (e) {
+    print("expected exception on accessing result data after close: $e");
+  }
+  try {
+    d.query("""
+      select
+        id,
+        non_existing_column
+      from Cookies
+      ;""");
+  } on SQLiteException catch (e) {
+    print("expected this query to fail: $e");
+  }
+  d.execute("drop table Cookies;");
+  d.close();
+}
diff --git a/samples_2/ffi/sqlite/lib/sqlite.dart b/samples_2/ffi/sqlite/lib/sqlite.dart
new file mode 100644
index 0000000..825e434
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/sqlite.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+/// A synchronous SQLite wrapper.
+///
+/// Written using dart:ffi.
+library sqlite;
+
+export "src/database.dart";
diff --git a/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart b/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart
new file mode 100644
index 0000000..a1cdba7
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -0,0 +1,396 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+import "../ffi/dylib_utils.dart";
+
+import "signatures.dart";
+import "types.dart";
+
+class _SQLiteBindings {
+  DynamicLibrary sqlite;
+
+  /// Opening A New Database Connection
+  ///
+  /// ^These routines open an SQLite database file as specified by the
+  /// filename argument. ^The filename argument is interpreted as UTF-8 for
+  /// sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
+  /// order for sqlite3_open16(). ^(A database connection handle is usually
+  /// returned in *ppDb, even if an error occurs.  The only exception is that
+  /// if SQLite is unable to allocate memory to hold the sqlite3 object,
+  /// a NULL will be written into *ppDb instead of a pointer to the sqlite3
+  /// object.)^ ^(If the database is opened (and/or created) successfully, then
+  /// [SQLITE_OK] is returned.  Otherwise an error code is returned.)^ ^The
+  /// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
+  /// an English language description of the error following a failure of any
+  /// of the sqlite3_open() routines.
+  int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
+      int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
+
+  int Function(Pointer<Database> database) sqlite3_close_v2;
+
+  /// Compiling An SQL Statement
+  ///
+  /// To execute an SQL query, it must first be compiled into a byte-code
+  /// program using one of these routines.
+  ///
+  /// The first argument, "db", is a database connection obtained from a
+  /// prior successful call to sqlite3_open, [sqlite3_open_v2] or
+  /// sqlite3_open16.  The database connection must not have been closed.
+  ///
+  /// The second argument, "zSql", is the statement to be compiled, encoded
+  /// as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
+  /// interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
+  /// use UTF-16.
+  ///
+  /// ^If the nByte argument is less than zero, then zSql is read up to the
+  /// first zero terminator. ^If nByte is non-negative, then it is the maximum
+  /// number of  bytes read from zSql.  ^When nByte is non-negative, the
+  /// zSql string ends at either the first '\000' or '\u0000' character or
+  /// the nByte-th byte, whichever comes first. If the caller knows
+  /// that the supplied string is nul-terminated, then there is a small
+  /// performance advantage to be gained by passing an nByte parameter that
+  /// is equal to the number of bytes in the input string <i>including</i>
+  /// the nul-terminator bytes.
+  ///
+  /// ^If pzTail is not NULL then *pzTail is made to point to the first byte
+  /// past the end of the first SQL statement in zSql.  These routines only
+  /// compile the first statement in zSql, so *pzTail is left pointing to
+  /// what remains uncompiled.
+  ///
+  /// ^*ppStmt is left pointing to a compiled prepared statement that can be
+  /// executed using sqlite3_step.  ^If there is an error, *ppStmt is set
+  /// to NULL.  ^If the input text contains no SQL (if the input is an empty
+  /// string or a comment) then *ppStmt is set to NULL.
+  /// The calling procedure is responsible for deleting the compiled
+  /// SQL statement using [sqlite3_finalize] after it has finished with it.
+  /// ppStmt may not be NULL.
+  ///
+  /// ^On success, the sqlite3_prepare family of routines return [SQLITE_OK];
+  /// otherwise an error code is returned.
+  ///
+  /// The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
+  /// recommended for all new programs. The two older interfaces are retained
+  /// for backwards compatibility, but their use is discouraged.
+  /// ^In the "v2" interfaces, the prepared statement
+  /// that is returned (the sqlite3_stmt object) contains a copy of the
+  /// original SQL text. This causes the [sqlite3_step] interface to
+  /// behave differently in three ways:
+  int Function(
+      Pointer<Database> database,
+      Pointer<Utf8> query,
+      int nbytes,
+      Pointer<Pointer<Statement>> statementOut,
+      Pointer<Pointer<Utf8>> tail) sqlite3_prepare_v2;
+
+  /// Evaluate An SQL Statement
+  ///
+  /// After a prepared statement has been prepared using either
+  /// [sqlite3_prepare_v2] or sqlite3_prepare16_v2() or one of the legacy
+  /// interfaces sqlite3_prepare() or sqlite3_prepare16(), this function
+  /// must be called one or more times to evaluate the statement.
+  ///
+  /// The details of the behavior of the sqlite3_step() interface depend
+  /// on whether the statement was prepared using the newer "v2" interface
+  /// [sqlite3_prepare_v2] and sqlite3_prepare16_v2() or the older legacy
+  /// interface sqlite3_prepare() and sqlite3_prepare16().  The use of the
+  /// new "v2" interface is recommended for new applications but the legacy
+  /// interface will continue to be supported.
+  ///
+  /// ^In the legacy interface, the return value will be either [SQLITE_BUSY],
+  /// [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
+  /// ^With the "v2" interface, any of the other [result codes] or
+  /// [extended result codes] might be returned as well.
+  ///
+  /// ^[SQLITE_BUSY] means that the database engine was unable to acquire the
+  /// database locks it needs to do its job.  ^If the statement is a [COMMIT]
+  /// or occurs outside of an explicit transaction, then you can retry the
+  /// statement.  If the statement is not a [COMMIT] and occurs within an
+  /// explicit transaction then you should rollback the transaction before
+  /// continuing.
+  ///
+  /// ^[SQLITE_DONE] means that the statement has finished executing
+  /// successfully.  sqlite3_step() should not be called again on this virtual
+  /// machine without first calling [sqlite3_reset()] to reset the virtual
+  /// machine back to its initial state.
+  ///
+  /// ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
+  /// is returned each time a new row of data is ready for processing by the
+  /// caller. The values may be accessed using the [column access functions].
+  /// sqlite3_step() is called again to retrieve the next row of data.
+  ///
+  /// ^[SQLITE_ERROR] means that a run-time error (such as a constraint
+  /// violation) has occurred.  sqlite3_step() should not be called again on
+  /// the VM. More information may be found by calling [sqlite3_errmsg()].
+  /// ^With the legacy interface, a more specific error code (for example,
+  /// [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
+  /// can be obtained by calling [sqlite3_reset()] on the
+  /// prepared statement.  ^In the "v2" interface,
+  /// the more specific error code is returned directly by sqlite3_step().
+  ///
+  /// [SQLITE_MISUSE] means that the this routine was called inappropriately.
+  /// Perhaps it was called on a prepared statement that has
+  /// already been [sqlite3_finalize | finalized] or on one that had
+  /// previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
+  /// be the case that the same database connection is being used by two or
+  /// more threads at the same moment in time.
+  ///
+  /// For all versions of SQLite up to and including 3.6.23.1, a call to
+  /// [sqlite3_reset] was required after sqlite3_step() returned anything
+  /// other than [Errors.SQLITE_ROW] before any subsequent invocation of
+  /// sqlite3_step().  Failure to reset the prepared statement using
+  /// [sqlite3_reset()] would result in an [Errors.SQLITE_MISUSE] return from
+  /// sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
+  /// calling [sqlite3_reset] automatically in this circumstance rather
+  /// than returning [Errors.SQLITE_MISUSE]. This is not considered a
+  /// compatibility break because any application that ever receives an
+  /// [Errors.SQLITE_MISUSE] error is broken by definition.  The
+  /// [SQLITE_OMIT_AUTORESET] compile-time option
+  /// can be used to restore the legacy behavior.
+  ///
+  /// <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
+  /// API always returns a generic error code, [SQLITE_ERROR], following any
+  /// error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
+  /// [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
+  /// specific [error codes] that better describes the error.
+  /// We admit that this is a goofy design.  The problem has been fixed
+  /// with the "v2" interface.  If you prepare all of your SQL statements
+  /// using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
+  /// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+  /// then the more specific [error codes] are returned directly
+  /// by sqlite3_step().  The use of the "v2" interface is recommended.
+  int Function(Pointer<Statement> statement) sqlite3_step;
+
+  /// CAPI3REF: Reset A Prepared Statement Object
+  ///
+  /// The sqlite3_reset() function is called to reset a prepared statement
+  /// object back to its initial state, ready to be re-executed.
+  /// ^Any SQL statement variables that had values bound to them using
+  /// the sqlite3_bind_blob | sqlite3_bind_*() API retain their values.
+  /// Use sqlite3_clear_bindings() to reset the bindings.
+  ///
+  /// ^The [sqlite3_reset] interface resets the prepared statement S
+  /// back to the beginning of its program.
+  ///
+  /// ^If the most recent call to [sqlite3_step] for the
+  /// prepared statement S returned [Errors.SQLITE_ROW] or [Errors.SQLITE_DONE],
+  /// or if [sqlite3_step] has never before been called on S,
+  /// then [sqlite3_reset] returns [Errors.SQLITE_OK].
+  ///
+  /// ^If the most recent call to [sqlite3_step(S)] for the
+  /// prepared statement S indicated an error, then
+  /// [sqlite3_reset] returns an appropriate [Errors].
+  ///
+  /// ^The [sqlite3_reset] interface does not change the values
+  int Function(Pointer<Statement> statement) sqlite3_reset;
+
+  /// Destroy A Prepared Statement Object
+  ///
+  /// ^The sqlite3_finalize() function is called to delete a prepared statement.
+  /// ^If the most recent evaluation of the statement encountered no errors
+  /// or if the statement is never been evaluated, then sqlite3_finalize()
+  /// returns SQLITE_OK.  ^If the most recent evaluation of statement S failed,
+  /// then sqlite3_finalize(S) returns the appropriate error code or extended
+  /// error code.
+  ///
+  /// ^The sqlite3_finalize(S) routine can be called at any point during
+  /// the life cycle of prepared statement S:
+  /// before statement S is ever evaluated, after
+  /// one or more calls to [sqlite3_reset], or after any call
+  /// to [sqlite3_step] regardless of whether or not the statement has
+  /// completed execution.
+  ///
+  /// ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
+  ///
+  /// The application must finalize every prepared statement in order to avoid
+  /// resource leaks.  It is a grievous error for the application to try to use
+  /// a prepared statement after it has been finalized.  Any use of a prepared
+  /// statement after it has been finalized can result in undefined and
+  /// undesirable behavior such as segfaults and heap corruption.
+  int Function(Pointer<Statement> statement) sqlite3_finalize;
+
+  /// Number Of Columns In A Result Set
+  ///
+  /// ^Return the number of columns in the result set returned by the
+  /// prepared statement. ^This routine returns 0 if pStmt is an SQL
+  /// statement that does not return data (for example an [UPDATE]).
+  int Function(Pointer<Statement> statement) sqlite3_column_count;
+
+  /// Column Names In A Result Set
+  ///
+  /// ^These routines return the name assigned to a particular column
+  /// in the result set of a SELECT statement.  ^The sqlite3_column_name()
+  /// interface returns a pointer to a zero-terminated UTF-8 string
+  /// and sqlite3_column_name16() returns a pointer to a zero-terminated
+  /// UTF-16 string.  ^The first parameter is the prepared statement
+  /// that implements the SELECT statement. ^The second parameter is the
+  /// column number.  ^The leftmost column is number 0.
+  ///
+  /// ^The returned string pointer is valid until either the prepared statement
+  /// is destroyed by [sqlite3_finalize] or until the statement is automatically
+  /// reprepared by the first call to [sqlite3_step] for a particular run
+  /// or until the next call to
+  /// sqlite3_column_name() or sqlite3_column_name16() on the same column.
+  ///
+  /// ^If sqlite3_malloc() fails during the processing of either routine
+  /// (for example during a conversion from UTF-8 to UTF-16) then a
+  /// NULL pointer is returned.
+  ///
+  /// ^The name of a result column is the value of the "AS" clause for
+  /// that column, if there is an AS clause.  If there is no AS clause
+  /// then the name of the column is unspecified and may change from
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_name;
+
+  /// CAPI3REF: Declared Datatype Of A Query Result
+  ///
+  /// ^(The first parameter is a prepared statement.
+  /// If this statement is a SELECT statement and the Nth column of the
+  /// returned result set of that SELECT is a table column (not an
+  /// expression or subquery) then the declared type of the table
+  /// column is returned.)^  ^If the Nth column of the result set is an
+  /// expression or subquery, then a NULL pointer is returned.
+  /// ^The returned string is always UTF-8 encoded.
+  ///
+  /// ^(For example, given the database schema:
+  ///
+  /// CREATE TABLE t1(c1 VARIANT);
+  ///
+  /// and the following statement to be compiled:
+  ///
+  /// SELECT c1 + 1, c1 FROM t1;
+  ///
+  /// this routine would return the string "VARIANT" for the second result
+  /// column (i==1), and a NULL pointer for the first result column (i==0).)^
+  ///
+  /// ^SQLite uses dynamic run-time typing.  ^So just because a column
+  /// is declared to contain a particular type does not mean that the
+  /// data stored in that column is of the declared type.  SQLite is
+  /// strongly typed, but the typing is dynamic not static.  ^Type
+  /// is associated with individual values, not with the containers
+  /// used to hold those values.
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_decltype;
+
+  int Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_type;
+
+  Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_value;
+
+  double Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_double;
+
+  int Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_int;
+
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_text;
+
+  /// The sqlite3_errstr() interface returns the English-language text that
+  /// describes the result code, as UTF-8. Memory to hold the error message
+  /// string is managed internally and must not be freed by the application.
+  Pointer<Utf8> Function(int code) sqlite3_errstr;
+
+  /// Error Codes And Messages
+  ///
+  /// ^The sqlite3_errcode() interface returns the numeric [result code] or
+  /// [extended result code] for the most recent failed sqlite3_* API call
+  /// associated with a [database connection]. If a prior API call failed
+  /// but the most recent API call succeeded, the return value from
+  /// sqlite3_errcode() is undefined.  ^The sqlite3_extended_errcode()
+  /// interface is the same except that it always returns the
+  /// [extended result code] even when extended result codes are
+  /// disabled.
+  ///
+  /// ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+  /// text that describes the error, as either UTF-8 or UTF-16 respectively.
+  /// ^(Memory to hold the error message string is managed internally.
+  /// The application does not need to worry about freeing the result.
+  /// However, the error string might be overwritten or deallocated by
+  /// subsequent calls to other SQLite interface functions.)^
+  ///
+  /// When the serialized [threading mode] is in use, it might be the
+  /// case that a second error occurs on a separate thread in between
+  /// the time of the first error and the call to these interfaces.
+  /// When that happens, the second error will be reported since these
+  /// interfaces always report the most recent result.  To avoid
+  /// this, each thread can obtain exclusive use of the [database connection] D
+  /// by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
+  /// to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
+  /// all calls to the interfaces listed here are completed.
+  ///
+  /// If an interface fails with SQLITE_MISUSE, that means the interface
+  /// was invoked incorrectly by the application.  In that case, the
+  /// error code and message may or may not be set.
+  Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
+
+  _SQLiteBindings() {
+    sqlite = dlopenPlatformSpecific("sqlite3");
+    sqlite3_open_v2 = sqlite
+        .lookup<NativeFunction<sqlite3_open_v2_native_t>>("sqlite3_open_v2")
+        .asFunction();
+    sqlite3_close_v2 = sqlite
+        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2")
+        .asFunction();
+    sqlite3_prepare_v2 = sqlite
+        .lookup<NativeFunction<sqlite3_prepare_v2_native_t>>(
+            "sqlite3_prepare_v2")
+        .asFunction();
+    sqlite3_step = sqlite
+        .lookup<NativeFunction<sqlite3_step_native_t>>("sqlite3_step")
+        .asFunction();
+    sqlite3_reset = sqlite
+        .lookup<NativeFunction<sqlite3_reset_native_t>>("sqlite3_reset")
+        .asFunction();
+    sqlite3_finalize = sqlite
+        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize")
+        .asFunction();
+    sqlite3_errstr = sqlite
+        .lookup<NativeFunction<sqlite3_errstr_native_t>>("sqlite3_errstr")
+        .asFunction();
+    sqlite3_errmsg = sqlite
+        .lookup<NativeFunction<sqlite3_errmsg_native_t>>("sqlite3_errmsg")
+        .asFunction();
+    sqlite3_column_count = sqlite
+        .lookup<NativeFunction<sqlite3_column_count_native_t>>(
+            "sqlite3_column_count")
+        .asFunction();
+    sqlite3_column_name = sqlite
+        .lookup<NativeFunction<sqlite3_column_name_native_t>>(
+            "sqlite3_column_name")
+        .asFunction();
+    sqlite3_column_decltype = sqlite
+        .lookup<NativeFunction<sqlite3_column_decltype_native_t>>(
+            "sqlite3_column_decltype")
+        .asFunction();
+    sqlite3_column_type = sqlite
+        .lookup<NativeFunction<sqlite3_column_type_native_t>>(
+            "sqlite3_column_type")
+        .asFunction();
+    sqlite3_column_value = sqlite
+        .lookup<NativeFunction<sqlite3_column_value_native_t>>(
+            "sqlite3_column_value")
+        .asFunction();
+    sqlite3_column_double = sqlite
+        .lookup<NativeFunction<sqlite3_column_double_native_t>>(
+            "sqlite3_column_double")
+        .asFunction();
+    sqlite3_column_int = sqlite
+        .lookup<NativeFunction<sqlite3_column_int_native_t>>(
+            "sqlite3_column_int")
+        .asFunction();
+    sqlite3_column_text = sqlite
+        .lookup<NativeFunction<sqlite3_column_text_native_t>>(
+            "sqlite3_column_text")
+        .asFunction();
+  }
+}
+
+_SQLiteBindings _cachedBindings;
+_SQLiteBindings get bindings => _cachedBindings ??= _SQLiteBindings();
diff --git a/samples_2/ffi/sqlite/lib/src/bindings/constants.dart b/samples_2/ffi/sqlite/lib/src/bindings/constants.dart
new file mode 100644
index 0000000..120d567
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/bindings/constants.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+/// Result Codes
+///
+/// Many SQLite functions return an integer result code from the set shown
+/// here in order to indicates success or failure.
+///
+/// New error codes may be added in future versions of SQLite.
+///
+/// See also: SQLITE_IOERR_READ | extended result codes,
+/// sqlite3_vtab_on_conflict() SQLITE_ROLLBACK | result codes.
+class Errors {
+  /// Successful result
+  static const int SQLITE_OK = 0;
+
+  /// Generic error
+  static const int SQLITE_ERROR = 1;
+
+  /// Internal logic error in SQLite
+  static const int SQLITE_INTERNAL = 2;
+
+  /// Access permission denied
+  static const int SQLITE_PERM = 3;
+
+  /// Callback routine requested an abort
+  static const int SQLITE_ABORT = 4;
+
+  /// The database file is locked
+  static const int SQLITE_BUSY = 5;
+
+  /// A table in the database is locked
+  static const int SQLITE_LOCKED = 6;
+
+  /// A malloc() failed
+  static const int SQLITE_NOMEM = 7;
+
+  /// Attempt to write a readonly database
+  static const int SQLITE_READONLY = 8;
+
+  /// Operation terminated by sqlite3_interrupt()
+  static const int SQLITE_INTERRUPT = 9;
+
+  /// Some kind of disk I/O error occurred
+  static const int SQLITE_IOERR = 10;
+
+  /// The database disk image is malformed
+  static const int SQLITE_CORRUPT = 11;
+
+  /// Unknown opcode in sqlite3_file_control()
+  static const int SQLITE_NOTFOUND = 12;
+
+  /// Insertion failed because database is full
+  static const int SQLITE_FULL = 13;
+
+  /// Unable to open the database file
+  static const int SQLITE_CANTOPEN = 14;
+
+  /// Database lock protocol error
+  static const int SQLITE_PROTOCOL = 15;
+
+  /// Internal use only
+  static const int SQLITE_EMPTY = 16;
+
+  /// The database schema changed
+  static const int SQLITE_SCHEMA = 17;
+
+  /// String or BLOB exceeds size limit
+  static const int SQLITE_TOOBIG = 18;
+
+  /// Abort due to constraint violation
+  static const int SQLITE_CONSTRAINT = 19;
+
+  /// Data type mismatch
+  static const int SQLITE_MISMATCH = 20;
+
+  /// Library used incorrectly
+  static const int SQLITE_MISUSE = 21;
+
+  /// Uses OS features not supported on host
+  static const int SQLITE_NOLFS = 22;
+
+  /// Authorization denied
+  static const int SQLITE_AUTH = 23;
+
+  /// Not used
+  static const int SQLITE_FORMAT = 24;
+
+  /// 2nd parameter to sqlite3_bind out of range
+  static const int SQLITE_RANGE = 25;
+
+  /// File opened that is not a database file
+  static const int SQLITE_NOTADB = 26;
+
+  /// Notifications from sqlite3_log()
+  static const int SQLITE_NOTICE = 27;
+
+  /// Warnings from sqlite3_log()
+  static const int SQLITE_WARNING = 28;
+
+  /// sqlite3_step() has another row ready
+  static const int SQLITE_ROW = 100;
+
+  /// sqlite3_step() has finished executing
+  static const int SQLITE_DONE = 101;
+}
+
+/// Flags For File Open Operations
+///
+/// These bit values are intended for use in the
+/// 3rd parameter to the [sqlite3_open_v2()] interface and
+/// in the 4th parameter to the [sqlite3_vfs.xOpen] method.
+class Flags {
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_READONLY = 0x00000001;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_READWRITE = 0x00000002;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_CREATE = 0x00000004;
+
+  /// VFS only
+  static const int SQLITE_OPEN_DELETEONCLOSE = 0x00000008;
+
+  /// VFS only
+  static const int SQLITE_OPEN_EXCLUSIVE = 0x00000010;
+
+  /// VFS only
+  static const int SQLITE_OPEN_AUTOPROXY = 0x00000020;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_URI = 0x00000040;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_MEMORY = 0x00000080;
+
+  /// VFS only
+  static const int SQLITE_OPEN_MAIN_DB = 0x00000100;
+
+  /// VFS only
+  static const int SQLITE_OPEN_TEMP_DB = 0x00000200;
+
+  /// VFS only
+  static const int SQLITE_OPEN_TRANSIENT_DB = 0x00000400;
+
+  /// VFS only
+  static const int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800;
+
+  /// VFS only
+  static const int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000;
+
+  /// VFS only
+  static const int SQLITE_OPEN_SUBJOURNAL = 0x00002000;
+
+  /// VFS only
+  static const int SQLITE_OPEN_MASTER_JOURNAL = 0x00004000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_NOMUTEX = 0x00008000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_FULLMUTEX = 0x00010000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_SHAREDCACHE = 0x00020000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_PRIVATECACHE = 0x00040000;
+
+  /// VFS only
+  static const int SQLITE_OPEN_WAL = 0x00080000;
+}
+
+class Types {
+  static const int SQLITE_INTEGER = 1;
+  static const int SQLITE_FLOAT = 2;
+  static const int SQLITE_TEXT = 3;
+  static const int SQLITE_BLOB = 4;
+  static const int SQLITE_NULL = 5;
+}
diff --git a/samples_2/ffi/sqlite/lib/src/bindings/signatures.dart b/samples_2/ffi/sqlite/lib/src/bindings/signatures.dart
new file mode 100644
index 0000000..8e5d6e6
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/bindings/signatures.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "dart:ffi";
+
+import "package:ffi/ffi.dart";
+
+import "types.dart";
+
+typedef sqlite3_open_v2_native_t = Int32 Function(Pointer<Utf8> filename,
+    Pointer<Pointer<Database>> ppDb, Int32 flags, Pointer<Utf8> vfs);
+
+typedef sqlite3_close_v2_native_t = Int32 Function(Pointer<Database> database);
+
+typedef sqlite3_prepare_v2_native_t = Int32 Function(
+    Pointer<Database> database,
+    Pointer<Utf8> query,
+    Int32 nbytes,
+    Pointer<Pointer<Statement>> statementOut,
+    Pointer<Pointer<Utf8>> tail);
+
+typedef sqlite3_step_native_t = Int32 Function(Pointer<Statement> statement);
+
+typedef sqlite3_reset_native_t = Int32 Function(Pointer<Statement> statement);
+
+typedef sqlite3_finalize_native_t = Int32 Function(
+    Pointer<Statement> statement);
+
+typedef sqlite3_errstr_native_t = Pointer<Utf8> Function(Int32 error);
+
+typedef sqlite3_errmsg_native_t = Pointer<Utf8> Function(
+    Pointer<Database> database);
+
+typedef sqlite3_column_count_native_t = Int32 Function(
+    Pointer<Statement> statement);
+
+typedef sqlite3_column_name_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_decltype_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_type_native_t = Int32 Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_value_native_t = Pointer<Value> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_double_native_t = Double Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_int_native_t = Int32 Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_text_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
diff --git a/samples_2/ffi/sqlite/lib/src/bindings/types.dart b/samples_2/ffi/sqlite/lib/src/bindings/types.dart
new file mode 100644
index 0000000..f6a1736
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/bindings/types.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "dart:ffi";
+
+/// Database Connection Handle
+///
+/// Each open SQLite database is represented by a pointer to an instance of
+/// the opaque structure named "sqlite3".  It is useful to think of an sqlite3
+/// pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
+/// [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
+/// is its destructor.  There are many other interfaces (such as
+/// [sqlite3_prepare_v2()], [sqlite3_create_function()], and
+/// [sqlite3_busy_timeout()] to name but three) that are methods on an
+class Database extends Struct {}
+
+/// SQL Statement Object
+///
+/// An instance of this object represents a single SQL statement.
+/// This object is variously known as a "prepared statement" or a
+/// "compiled SQL statement" or simply as a "statement".
+///
+/// The life of a statement object goes something like this:
+///
+/// <ol>
+/// <li> Create the object using [sqlite3_prepare_v2()] or a related
+///      function.
+/// <li> Bind values to [host parameters] using the sqlite3_bind_*()
+///      interfaces.
+/// <li> Run the SQL by calling [sqlite3_step()] one or more times.
+/// <li> Reset the statement using [sqlite3_reset()] then go back
+///      to step 2.  Do this zero or more times.
+/// <li> Destroy the object using [sqlite3_finalize()].
+/// </ol>
+///
+/// Refer to documentation on individual methods above for additional
+/// information.
+class Statement extends Struct {}
+
+/// Dynamically Typed Value Object
+///
+/// SQLite uses the sqlite3_value object to represent all values
+/// that can be stored in a database table. SQLite uses dynamic typing
+/// for the values it stores.  ^Values stored in sqlite3_value objects
+/// can be integers, floating point values, strings, BLOBs, or NULL.
+///
+/// An sqlite3_value object may be either "protected" or "unprotected".
+/// Some interfaces require a protected sqlite3_value.  Other interfaces
+/// will accept either a protected or an unprotected sqlite3_value.
+/// Every interface that accepts sqlite3_value arguments specifies
+/// whether or not it requires a protected sqlite3_value.
+///
+/// The terms "protected" and "unprotected" refer to whether or not
+/// a mutex is held.  An internal mutex is held for a protected
+/// sqlite3_value object but no mutex is held for an unprotected
+/// sqlite3_value object.  If SQLite is compiled to be single-threaded
+/// (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
+/// or if SQLite is run in one of reduced mutex modes
+/// [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
+/// then there is no distinction between protected and unprotected
+/// sqlite3_value objects and they can be used interchangeably.  However,
+/// for maximum code portability it is recommended that applications
+/// still make the distinction between protected and unprotected
+/// sqlite3_value objects even when not strictly required.
+///
+/// ^The sqlite3_value objects that are passed as parameters into the
+/// implementation of [application-defined SQL functions] are protected.
+/// ^The sqlite3_value object returned by
+/// [sqlite3_column_value()] is unprotected.
+/// Unprotected sqlite3_value objects may only be used with
+/// [sqlite3_result_value()] and [sqlite3_bind_value()].
+/// The [sqlite3_value_blob | sqlite3_value_type()] family of
+/// interfaces require protected sqlite3_value objects.
+class Value extends Struct {}
diff --git a/samples_2/ffi/sqlite/lib/src/collections/closable_iterator.dart b/samples_2/ffi/sqlite/lib/src/collections/closable_iterator.dart
new file mode 100644
index 0000000..83ca2ba
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/collections/closable_iterator.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+/// This iterator should be [close]d after use.
+///
+/// [ClosableIterator]s often use resources which should be freed after use.
+/// The consumer of the iterator can either manually [close] the iterator, or
+/// consume all elements on which the iterator will automatically be closed.
+abstract class ClosableIterator<T> extends Iterator<T> {
+  /// Close this iterator.
+  void close();
+
+  /// Moves to the next element and [close]s the iterator if it was the last
+  /// element.
+  bool moveNext();
+}
+
+/// This iterable's iterator should be [close]d after use.
+///
+/// Companion class of [ClosableIterator].
+abstract class ClosableIterable<T> extends Iterable<T> {
+  /// Close this iterables iterator.
+  void close();
+
+  /// Returns a [ClosableIterator] that allows iterating the elements of this
+  /// [ClosableIterable].
+  ClosableIterator<T> get iterator;
+}
diff --git a/samples_2/ffi/sqlite/lib/src/database.dart b/samples_2/ffi/sqlite/lib/src/database.dart
new file mode 100644
index 0000000..38121a9
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/database.dart
@@ -0,0 +1,314 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "dart:collection";
+import "dart:ffi";
+
+import "package:ffi/ffi.dart";
+
+import "bindings/bindings.dart";
+
+import "bindings/types.dart" as types;
+import "bindings/types.dart" hide Database;
+
+import "bindings/constants.dart";
+import "collections/closable_iterator.dart";
+
+/// [Database] represents an open connection to a SQLite database.
+///
+/// All functions against a database may throw [SQLiteError].
+///
+/// This database interacts with SQLite synchonously.
+class Database {
+  Pointer<types.Database> _database;
+  bool _open = false;
+
+  /// Open a database located at the file [path].
+  Database(String path,
+      [int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
+    Pointer<Pointer<types.Database>> dbOut = allocate();
+    final pathC = Utf8.toUtf8(path);
+    final int resultCode =
+        bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
+    _database = dbOut.value;
+    free(dbOut);
+    free(pathC);
+
+    if (resultCode == Errors.SQLITE_OK) {
+      _open = true;
+    } else {
+      // Even if "open" fails, sqlite3 will still create a database object. We
+      // can just destroy it.
+      SQLiteException exception = _loadError(resultCode);
+      close();
+      throw exception;
+    }
+  }
+
+  /// Close the database.
+  ///
+  /// This should only be called once on a database unless an exception is
+  /// thrown. It should be called at least once to finalize the database and
+  /// avoid resource leaks.
+  void close() {
+    assert(_open);
+    final int resultCode = bindings.sqlite3_close_v2(_database);
+    if (resultCode == Errors.SQLITE_OK) {
+      _open = false;
+    } else {
+      throw _loadError(resultCode);
+    }
+  }
+
+  /// Execute a query, discarding any returned rows.
+  void execute(String query) {
+    Pointer<Pointer<Statement>> statementOut = allocate();
+    Pointer<Utf8> queryC = Utf8.toUtf8(query);
+    int resultCode = bindings.sqlite3_prepare_v2(
+        _database, queryC, -1, statementOut, nullptr);
+    Pointer<Statement> statement = statementOut.value;
+    free(statementOut);
+    free(queryC);
+
+    while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
+      resultCode = bindings.sqlite3_step(statement);
+    }
+    bindings.sqlite3_finalize(statement);
+    if (resultCode != Errors.SQLITE_DONE) {
+      throw _loadError(resultCode);
+    }
+  }
+
+  /// Evaluate a query and return the resulting rows as an iterable.
+  Result query(String query) {
+    Pointer<Pointer<Statement>> statementOut = allocate();
+    Pointer<Utf8> queryC = Utf8.toUtf8(query);
+    int resultCode = bindings.sqlite3_prepare_v2(
+        _database, queryC, -1, statementOut, nullptr);
+    Pointer<Statement> statement = statementOut.value;
+    free(statementOut);
+    free(queryC);
+
+    if (resultCode != Errors.SQLITE_OK) {
+      bindings.sqlite3_finalize(statement);
+      throw _loadError(resultCode);
+    }
+
+    Map<String, int> columnIndices = {};
+    int columnCount = bindings.sqlite3_column_count(statement);
+    for (int i = 0; i < columnCount; i++) {
+      String columnName =
+          bindings.sqlite3_column_name(statement, i).ref.toString();
+      columnIndices[columnName] = i;
+    }
+
+    return Result._(this, statement, columnIndices);
+  }
+
+  SQLiteException _loadError([int errorCode]) {
+    String errorMessage = bindings.sqlite3_errmsg(_database).ref.toString();
+    if (errorCode == null) {
+      return SQLiteException(errorMessage);
+    }
+    String errorCodeExplanation =
+        bindings.sqlite3_errstr(errorCode).ref.toString();
+    return SQLiteException(
+        "$errorMessage (Code $errorCode: $errorCodeExplanation)");
+  }
+}
+
+/// [Result] represents a [Database.query]'s result and provides an [Iterable]
+/// interface for the results to be consumed.
+///
+/// Please note that this iterator should be [close]d manually if not all [Row]s
+/// are consumed.
+class Result extends IterableBase<Row> implements ClosableIterable<Row> {
+  final Database _database;
+  final ClosableIterator<Row> _iterator;
+  final Pointer<Statement> _statement;
+  final Map<String, int> _columnIndices;
+
+  Row _currentRow = null;
+
+  Result._(
+    this._database,
+    this._statement,
+    this._columnIndices,
+  ) : _iterator = _ResultIterator(_statement, _columnIndices) {}
+
+  void close() => _iterator.close();
+
+  ClosableIterator<Row> get iterator => _iterator;
+}
+
+class _ResultIterator implements ClosableIterator<Row> {
+  final Pointer<Statement> _statement;
+  final Map<String, int> _columnIndices;
+
+  Row _currentRow = null;
+  bool _closed = false;
+
+  _ResultIterator(this._statement, this._columnIndices) {}
+
+  bool moveNext() {
+    if (_closed) {
+      throw SQLiteException("The result has already been closed.");
+    }
+    _currentRow?._setNotCurrent();
+    int stepResult = bindings.sqlite3_step(_statement);
+    if (stepResult == Errors.SQLITE_ROW) {
+      _currentRow = Row._(_statement, _columnIndices);
+      return true;
+    } else {
+      close();
+      return false;
+    }
+  }
+
+  Row get current {
+    if (_closed) {
+      throw SQLiteException("The result has already been closed.");
+    }
+    return _currentRow;
+  }
+
+  void close() {
+    _currentRow?._setNotCurrent();
+    _closed = true;
+    bindings.sqlite3_finalize(_statement);
+  }
+}
+
+class Row {
+  final Pointer<Statement> _statement;
+  final Map<String, int> _columnIndices;
+
+  bool _isCurrentRow = true;
+
+  Row._(this._statement, this._columnIndices) {}
+
+  /// Reads column [columnName].
+  ///
+  /// By default it returns a dynamically typed value. If [convert] is set to
+  /// [Convert.StaticType] the value is converted to the static type computed
+  /// for the column by the query compiler.
+  dynamic readColumn(String columnName,
+      {Convert convert = Convert.DynamicType}) {
+    return readColumnByIndex(_columnIndices[columnName], convert: convert);
+  }
+
+  /// Reads column [columnName].
+  ///
+  /// By default it returns a dynamically typed value. If [convert] is set to
+  /// [Convert.StaticType] the value is converted to the static type computed
+  /// for the column by the query compiler.
+  dynamic readColumnByIndex(int columnIndex,
+      {Convert convert = Convert.DynamicType}) {
+    _checkIsCurrentRow();
+
+    Type dynamicType;
+    if (convert == Convert.DynamicType) {
+      dynamicType =
+          _typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
+    } else {
+      dynamicType = _typeFromText(bindings
+          .sqlite3_column_decltype(_statement, columnIndex)
+          .ref
+          .toString());
+    }
+
+    switch (dynamicType) {
+      case Type.Integer:
+        return readColumnByIndexAsInt(columnIndex);
+      case Type.Text:
+        return readColumnByIndexAsText(columnIndex);
+      case Type.Null:
+        return null;
+        break;
+      default:
+    }
+  }
+
+  /// Reads column [columnName] and converts to [Type.Integer] if not an
+  /// integer.
+  int readColumnAsInt(String columnName) {
+    return readColumnByIndexAsInt(_columnIndices[columnName]);
+  }
+
+  /// Reads column [columnIndex] and converts to [Type.Integer] if not an
+  /// integer.
+  int readColumnByIndexAsInt(int columnIndex) {
+    _checkIsCurrentRow();
+    return bindings.sqlite3_column_int(_statement, columnIndex);
+  }
+
+  /// Reads column [columnName] and converts to [Type.Text] if not text.
+  String readColumnAsText(String columnName) {
+    return readColumnByIndexAsText(_columnIndices[columnName]);
+  }
+
+  /// Reads column [columnIndex] and converts to [Type.Text] if not text.
+  String readColumnByIndexAsText(int columnIndex) {
+    _checkIsCurrentRow();
+    return bindings.sqlite3_column_text(_statement, columnIndex).ref.toString();
+  }
+
+  void _checkIsCurrentRow() {
+    if (!_isCurrentRow) {
+      throw Exception(
+          "This row is not the current row, reading data from the non-current"
+          " row is not supported by sqlite.");
+    }
+  }
+
+  void _setNotCurrent() {
+    _isCurrentRow = false;
+  }
+}
+
+Type _typeFromCode(int code) {
+  switch (code) {
+    case Types.SQLITE_INTEGER:
+      return Type.Integer;
+    case Types.SQLITE_FLOAT:
+      return Type.Float;
+    case Types.SQLITE_TEXT:
+      return Type.Text;
+    case Types.SQLITE_BLOB:
+      return Type.Blob;
+    case Types.SQLITE_NULL:
+      return Type.Null;
+  }
+  throw Exception("Unknown type [$code]");
+}
+
+Type _typeFromText(String textRepresentation) {
+  switch (textRepresentation) {
+    case "integer":
+      return Type.Integer;
+    case "float":
+      return Type.Float;
+    case "text":
+      return Type.Text;
+    case "blob":
+      return Type.Blob;
+    case "null":
+      return Type.Null;
+  }
+  if (textRepresentation == null) return Type.Null;
+  throw Exception("Unknown type [$textRepresentation]");
+}
+
+enum Type { Integer, Float, Text, Blob, Null }
+
+enum Convert { DynamicType, StaticType }
+
+class SQLiteException {
+  final String message;
+  SQLiteException(this.message);
+
+  String toString() => message;
+}
diff --git a/samples_2/ffi/sqlite/lib/src/ffi/arena.dart b/samples_2/ffi/sqlite/lib/src/ffi/arena.dart
new file mode 100644
index 0000000..a26e807
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/ffi/arena.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "dart:async";
+import "dart:ffi";
+
+import 'package:ffi/ffi.dart';
+
+/// [Arena] manages allocated C memory.
+///
+/// Arenas are zoned.
+class Arena {
+  Arena();
+
+  List<Pointer<Void>> _allocations = [];
+
+  /// Bound the lifetime of [ptr] to this [Arena].
+  T scoped<T extends Pointer>(T ptr) {
+    _allocations.add(ptr.cast());
+    return ptr;
+  }
+
+  /// Frees all memory pointed to by [Pointer]s in this arena.
+  void finalize() {
+    for (final ptr in _allocations) {
+      free(ptr);
+    }
+  }
+
+  /// The last [Arena] in the zone.
+  factory Arena.current() {
+    return Zone.current[#_currentArena];
+  }
+}
+
+/// Bound the lifetime of [ptr] to the current [Arena].
+T scoped<T extends Pointer>(T ptr) => Arena.current().scoped(ptr);
+
+class RethrownError {
+  dynamic original;
+  StackTrace originalStackTrace;
+  RethrownError(this.original, this.originalStackTrace);
+  toString() => """RethrownError(${original})
+${originalStackTrace}""";
+}
+
+/// Runs the [body] in an [Arena] freeing all memory which is [scoped] during
+/// execution of [body] at the end of the execution.
+R runArena<R>(R Function(Arena) body) {
+  Arena arena = Arena();
+  try {
+    return runZoned(() => body(arena),
+        zoneValues: {#_currentArena: arena},
+        onError: (error, st) => throw RethrownError(error, st));
+  } finally {
+    arena.finalize();
+  }
+}
diff --git a/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart b/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart
new file mode 100644
index 0000000..39653fa
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+import 'dart:io' show Platform;
+
+String _platformPath(String name, {String path}) {
+  if (path == null) path = "";
+  if (Platform.isLinux || Platform.isAndroid)
+    return path + "lib" + name + ".so";
+  if (Platform.isMacOS) return path + "lib" + name + ".dylib";
+  if (Platform.isWindows) return path + name + ".dll";
+  throw Exception("Platform not implemented");
+}
+
+DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
+  String fullPath = _platformPath(name, path: path);
+  return DynamicLibrary.open(fullPath);
+}
diff --git a/samples_2/ffi/sqlite/pubspec.yaml b/samples_2/ffi/sqlite/pubspec.yaml
new file mode 100644
index 0000000..dcc5d40
--- /dev/null
+++ b/samples_2/ffi/sqlite/pubspec.yaml
@@ -0,0 +1,11 @@
+name: sqlite3
+version: 0.0.1
+description: >-
+  Sqlite3 wrapper. Demo for dart:ffi.
+author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
+environment:
+  sdk: '>=2.1.0 <3.0.0'
+dependencies:
+  ffi: ^0.1.3
+dev_dependencies:
+  test: ^1.5.3
diff --git a/samples_2/ffi/sqlite/test/sqlite_test.dart b/samples_2/ffi/sqlite/test/sqlite_test.dart
new file mode 100644
index 0000000..f7d3744
--- /dev/null
+++ b/samples_2/ffi/sqlite/test/sqlite_test.dart
@@ -0,0 +1,177 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// VMOptions=--optimization-counter-threshold=5
+
+import "dart:ffi";
+import "dart:io";
+
+import "package:ffi/ffi.dart";
+import "package:test/test.dart";
+
+import '../lib/sqlite.dart';
+
+void main() {
+  final dbPath = Platform.script.resolve("test.db").path;
+  test("sqlite integration test", () {
+    Database d = Database(dbPath);
+    d.execute("drop table if exists Cookies;");
+    d.execute("""
+      create table Cookies (
+        id integer primary key,
+        name text not null,
+        alternative_name text
+      );""");
+    d.execute("""
+      insert into Cookies (id, name, alternative_name)
+      values
+        (1,'Chocolade chip cookie', 'Chocolade cookie'),
+        (2,'Ginger cookie', null),
+        (3,'Cinnamon roll', null)
+      ;""");
+    Result result = d.query("""
+      select
+        id,
+        name,
+        alternative_name,
+        case
+          when id=1 then 'foo'
+          when id=2 then 42
+          when id=3 then null
+        end as multi_typed_column
+      from Cookies
+      ;""");
+    for (Row r in result) {
+      int id = r.readColumnAsInt("id");
+      expect(true, 1 <= id && id <= 3);
+      String name = r.readColumnByIndex(1);
+      expect(true, name is String);
+      String alternativeName = r.readColumn("alternative_name");
+      expect(true, alternativeName is String || alternativeName == null);
+      dynamic multiTypedValue = r.readColumn("multi_typed_column");
+      expect(
+          true,
+          multiTypedValue == 42 ||
+              multiTypedValue == 'foo' ||
+              multiTypedValue == null);
+      print("$id $name $alternativeName $multiTypedValue");
+    }
+    result = d.query("""
+      select
+        id,
+        name,
+        alternative_name,
+        case
+          when id=1 then 'foo'
+          when id=2 then 42
+          when id=3 then null
+        end as multi_typed_column
+      from Cookies
+      ;""");
+    for (Row r in result) {
+      int id = r.readColumnAsInt("id");
+      expect(true, 1 <= id && id <= 3);
+      String name = r.readColumnByIndex(1);
+      expect(true, name is String);
+      String alternativeName = r.readColumn("alternative_name");
+      expect(true, alternativeName is String || alternativeName == null);
+      dynamic multiTypedValue = r.readColumn("multi_typed_column");
+      expect(
+          true,
+          multiTypedValue == 42 ||
+              multiTypedValue == 'foo' ||
+              multiTypedValue == null);
+      print("$id $name $alternativeName $multiTypedValue");
+      if (id == 2) {
+        result.close();
+        break;
+      }
+    }
+    try {
+      result.iterator.moveNext();
+    } on SQLiteException catch (e) {
+      print("expected exception on accessing result data after close: $e");
+    }
+    try {
+      d.query("""
+      select
+        id,
+        non_existing_column
+      from Cookies
+      ;""");
+    } on SQLiteException catch (e) {
+      print("expected this query to fail: $e");
+    }
+    d.execute("drop table Cookies;");
+    d.close();
+  });
+
+  test("concurrent db open and queries", () {
+    Database d = Database(dbPath);
+    Database d2 = Database(dbPath);
+    d.execute("drop table if exists Cookies;");
+    d.execute("""
+      create table Cookies (
+        id integer primary key,
+        name text not null,
+        alternative_name text
+      );""");
+    d.execute("""
+      insert into Cookies (id, name, alternative_name)
+      values
+        (1,'Chocolade chip cookie', 'Chocolade cookie'),
+        (2,'Ginger cookie', null),
+        (3,'Cinnamon roll', null)
+      ;""");
+    Result r = d.query("select * from Cookies;");
+    Result r2 = d2.query("select * from Cookies;");
+    r.iterator..moveNext();
+    r2.iterator..moveNext();
+    r.iterator..moveNext();
+    Result r3 = d2.query("select * from Cookies;");
+    r3.iterator..moveNext();
+    expect(2, r.iterator.current.readColumn("id"));
+    expect(1, r2.iterator.current.readColumn("id"));
+    expect(1, r3.iterator.current.readColumn("id"));
+    r.close();
+    r2.close();
+    r3.close();
+    d.close();
+    d2.close();
+  });
+
+  test("stress test", () {
+    Database d = Database(dbPath);
+    d.execute("drop table if exists Cookies;");
+    d.execute("""
+      create table Cookies (
+        id integer primary key,
+        name text not null,
+        alternative_name text
+      );""");
+    int repeats = 100;
+    for (int i = 0; i < repeats; i++) {
+      d.execute("""
+      insert into Cookies (name, alternative_name)
+      values
+        ('Chocolade chip cookie', 'Chocolade cookie'),
+        ('Ginger cookie', null),
+        ('Cinnamon roll', null)
+      ;""");
+    }
+    Result r = d.query("select count(*) from Cookies;");
+    int count = r.first.readColumnByIndexAsInt(0);
+    expect(count, 3 * repeats);
+    r.close();
+    d.close();
+  });
+  test("Utf8 unit test", () {
+    final String test = 'Hasta Mañana';
+    final medium = Utf8.toUtf8(test);
+    expect(test, medium.ref.toString());
+    free(medium);
+  });
+}
diff --git a/samples_2/sample_extension/.gitignore b/samples_2/sample_extension/.gitignore
new file mode 100644
index 0000000..518f7dd
--- /dev/null
+++ b/samples_2/sample_extension/.gitignore
@@ -0,0 +1,9 @@
+/Makefile
+/*.Makefile
+/*.sln
+/*.target.mk
+/*.vcproj
+/*.vcxproj
+/*.vcxproj.filters
+/*.vcxproj.user
+/*.xcodeproj
diff --git a/samples_2/sample_extension/README.md b/samples_2/sample_extension/README.md
new file mode 100644
index 0000000..2e13091
--- /dev/null
+++ b/samples_2/sample_extension/README.md
@@ -0,0 +1,13 @@
+This directory contains samples of native extensions.
+
+To run the samples, first build both the Dart SDK and the runtime. For example:
+
+```
+$ ./tools/build.py create_sdk runtime
+```
+
+Then execute the sample programs. For example:
+
+```
+$ xcodebuild/ReleaseX64/dart samples/sample_extension/test/sample_extension_test.dart
+```
diff --git a/samples_2/sample_extension/sample_asynchronous_extension.dart b/samples_2/sample_extension/sample_asynchronous_extension.dart
new file mode 100644
index 0000000..541652d
--- /dev/null
+++ b/samples_2/sample_extension/sample_asynchronous_extension.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+library sample_asynchronous_extension;
+
+import 'dart:async';
+import 'dart:isolate';
+import 'dart-ext:sample_extension';
+
+// A class caches the native port used to call an asynchronous extension.
+class RandomArray {
+  static SendPort _port;
+
+  Future<List<int>> randomArray(int seed, int length) {
+    var completer = new Completer<List<int>>();
+    var replyPort = new RawReceivePort();
+    var args = new List(3);
+    args[0] = seed;
+    args[1] = length;
+    args[2] = replyPort.sendPort;
+    _servicePort.send(args);
+    replyPort.handler = (result) {
+      replyPort.close();
+      if (result != null) {
+        completer.complete(result);
+      } else {
+        completer.completeError(new Exception("Random array creation failed"));
+      }
+    };
+    return completer.future;
+  }
+
+  SendPort get _servicePort {
+    if (_port == null) {
+      _port = _newServicePort();
+    }
+    return _port;
+  }
+
+  SendPort _newServicePort() native "RandomArray_ServicePort";
+}
diff --git a/samples_2/sample_extension/sample_extension.cc b/samples_2/sample_extension/sample_extension.cc
new file mode 100644
index 0000000..2e04cec
--- /dev/null
+++ b/samples_2/sample_extension/sample_extension.cc
@@ -0,0 +1,178 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "include/dart_api.h"
+#include "include/dart_native_api.h"
+
+Dart_NativeFunction ResolveName(Dart_Handle name,
+                                int argc,
+                                bool* auto_setup_scope);
+
+DART_EXPORT Dart_Handle sample_extension_Init(Dart_Handle parent_library) {
+  if (Dart_IsError(parent_library)) {
+    return parent_library;
+  }
+
+  Dart_Handle result_code =
+      Dart_SetNativeResolver(parent_library, ResolveName, NULL);
+  if (Dart_IsError(result_code)) {
+    return result_code;
+  }
+
+  return Dart_Null();
+}
+
+Dart_Handle HandleError(Dart_Handle handle) {
+  if (Dart_IsError(handle)) {
+    Dart_PropagateError(handle);
+  }
+  return handle;
+}
+
+void SystemRand(Dart_NativeArguments arguments) {
+  Dart_EnterScope();
+  Dart_Handle result = HandleError(Dart_NewInteger(rand()));
+  Dart_SetReturnValue(arguments, result);
+  Dart_ExitScope();
+}
+
+void SystemSrand(Dart_NativeArguments arguments) {
+  Dart_EnterScope();
+  bool success = false;
+  Dart_Handle seed_object = HandleError(Dart_GetNativeArgument(arguments, 0));
+  if (Dart_IsInteger(seed_object)) {
+    bool fits;
+    HandleError(Dart_IntegerFitsIntoInt64(seed_object, &fits));
+    if (fits) {
+      int64_t seed;
+      HandleError(Dart_IntegerToInt64(seed_object, &seed));
+      srand(static_cast<unsigned>(seed));
+      success = true;
+    }
+  }
+  Dart_SetReturnValue(arguments, HandleError(Dart_NewBoolean(success)));
+  Dart_ExitScope();
+}
+
+uint8_t* randomArray(int seed, int length) {
+  if (length <= 0 || length > 10000000) {
+    return NULL;
+  }
+  uint8_t* values = reinterpret_cast<uint8_t*>(malloc(length));
+  if (NULL == values) {
+    return NULL;
+  }
+  srand(seed);
+  for (int i = 0; i < length; ++i) {
+    values[i] = rand() % 256;
+  }
+  return values;
+}
+
+void wrappedRandomArray(Dart_Port dest_port_id, Dart_CObject* message) {
+  Dart_Port reply_port_id = ILLEGAL_PORT;
+  if (message->type == Dart_CObject_kArray &&
+      3 == message->value.as_array.length) {
+    // Use .as_array and .as_int32 to access the data in the Dart_CObject.
+    Dart_CObject* param0 = message->value.as_array.values[0];
+    Dart_CObject* param1 = message->value.as_array.values[1];
+    Dart_CObject* param2 = message->value.as_array.values[2];
+    if (param0->type == Dart_CObject_kInt32 &&
+        param1->type == Dart_CObject_kInt32 &&
+        param2->type == Dart_CObject_kSendPort) {
+      int seed = param0->value.as_int32;
+      int length = param1->value.as_int32;
+      reply_port_id = param2->value.as_send_port.id;
+      uint8_t* values = randomArray(seed, length);
+
+      if (values != NULL) {
+        Dart_CObject result;
+        result.type = Dart_CObject_kTypedData;
+        result.value.as_typed_data.type = Dart_TypedData_kUint8;
+        result.value.as_typed_data.values = values;
+        result.value.as_typed_data.length = length;
+        if (Dart_PostCObject(reply_port_id, &result)) {
+          Dart_CObject error;
+          error.type = Dart_CObject_kNull;
+          Dart_PostCObject(reply_port_id, &error);
+        }
+        free(values);
+        // It is OK that result is destroyed when function exits.
+        // Dart_PostCObject has copied its data.
+        return;
+      }
+    }
+  }
+  fprintf(stderr,
+          "Invalid message received, cannot proceed. Aborting the process.\n");
+  abort();
+}
+
+void randomArrayServicePort(Dart_NativeArguments arguments) {
+  Dart_EnterScope();
+  Dart_SetReturnValue(arguments, Dart_Null());
+  Dart_Port service_port =
+      Dart_NewNativePort("RandomArrayService", wrappedRandomArray, true);
+  if (service_port != ILLEGAL_PORT) {
+    Dart_Handle send_port = HandleError(Dart_NewSendPort(service_port));
+    Dart_SetReturnValue(arguments, send_port);
+  }
+  Dart_ExitScope();
+}
+
+struct FunctionLookup {
+  const char* name;
+  Dart_NativeFunction function;
+};
+
+FunctionLookup function_list[] = {
+    {"SystemRand", SystemRand},
+    {"SystemSrand", SystemSrand},
+    {"RandomArray_ServicePort", randomArrayServicePort},
+    {NULL, NULL}};
+
+FunctionLookup no_scope_function_list[] = {{"NoScopeSystemRand", SystemRand},
+                                           {NULL, NULL}};
+
+Dart_NativeFunction ResolveName(Dart_Handle name,
+                                int argc,
+                                bool* auto_setup_scope) {
+  if (!Dart_IsString(name)) {
+    return NULL;
+  }
+  Dart_NativeFunction result = NULL;
+  if (auto_setup_scope == NULL) {
+    return NULL;
+  }
+
+  Dart_EnterScope();
+  const char* cname;
+  HandleError(Dart_StringToCString(name, &cname));
+
+  for (int i = 0; function_list[i].name != NULL; ++i) {
+    if (strcmp(function_list[i].name, cname) == 0) {
+      *auto_setup_scope = true;
+      result = function_list[i].function;
+      break;
+    }
+  }
+
+  if (result != NULL) {
+    Dart_ExitScope();
+    return result;
+  }
+
+  for (int i = 0; no_scope_function_list[i].name != NULL; ++i) {
+    if (strcmp(no_scope_function_list[i].name, cname) == 0) {
+      *auto_setup_scope = false;
+      result = no_scope_function_list[i].function;
+      break;
+    }
+  }
+
+  Dart_ExitScope();
+  return result;
+}
diff --git a/samples_2/sample_extension/sample_extension_dllmain_win.cc b/samples_2/sample_extension/sample_extension_dllmain_win.cc
new file mode 100644
index 0000000..b7b7c57
--- /dev/null
+++ b/samples_2/sample_extension/sample_extension_dllmain_win.cc
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if defined(_WIN32)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
+  return true;
+}
+
+#endif  // defined(_WIN32)
diff --git a/samples_2/sample_extension/sample_synchronous_extension.dart b/samples_2/sample_extension/sample_synchronous_extension.dart
new file mode 100644
index 0000000..e5ad660
--- /dev/null
+++ b/samples_2/sample_extension/sample_synchronous_extension.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+library sample_synchronous_extension;
+
+import 'dart-ext:sample_extension';
+
+// The simplest way to call native code: top-level functions.
+int systemRand() native "SystemRand";
+int noScopeSystemRand() native "NoScopeSystemRand";
+bool systemSrand(int seed) native "SystemSrand";
diff --git a/samples_2/sample_extension/test/sample_extension_app_snapshot_test.dart b/samples_2/sample_extension/test/sample_extension_app_snapshot_test.dart
new file mode 100644
index 0000000..b2eb204
--- /dev/null
+++ b/samples_2/sample_extension/test/sample_extension_app_snapshot_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing native extensions.
+
+// @dart = 2.9
+
+// OtherResources=../sample_synchronous_extension.dart
+// OtherResources=../sample_asynchronous_extension.dart
+// OtherResources=../test_sample_synchronous_extension.dart
+// OtherResources=../test_sample_asynchronous_extension.dart
+
+import 'sample_extension_test_helper.dart';
+
+void main() {
+  testNativeExtensions("app-jit");
+}
diff --git a/samples_2/sample_extension/test/sample_extension_test.dart b/samples_2/sample_extension/test/sample_extension_test.dart
new file mode 100644
index 0000000..393463b
--- /dev/null
+++ b/samples_2/sample_extension/test/sample_extension_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing native extensions.
+
+// @dart = 2.9
+
+import 'sample_extension_test_helper.dart';
+
+void main() {
+  testNativeExtensions(null /* no snapshot */);
+}
diff --git a/samples_2/sample_extension/test/sample_extension_test_helper.dart b/samples_2/sample_extension/test/sample_extension_test_helper.dart
new file mode 100644
index 0000000..9c701bf
--- /dev/null
+++ b/samples_2/sample_extension/test/sample_extension_test_helper.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing native extensions.
+
+// @dart = 2.9
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:isolate';
+
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+
+Future copyFileToDirectory(String file, String directory) async {
+  String src = file;
+  String dst = directory;
+  ProcessResult result;
+  switch (Platform.operatingSystem) {
+    case 'linux':
+    case 'macos':
+      result = await Process.run('cp', [src, dst]);
+      break;
+    case 'windows':
+      result = await Process.run('cmd.exe', ['/C', 'copy $src $dst']);
+      break;
+    default:
+      Expect.fail('Unknown operating system ${Platform.operatingSystem}');
+  }
+  if (result.exitCode != 0) {
+    print(result.stdout);
+    print(result.stderr);
+    throw "Failed to copy test file ($file) to temporary directory ($directory)";
+  }
+}
+
+Future run(String program, List<String> arguments) async {
+  print("+ $program ${arguments.join(' ')}");
+  ProcessResult result = await Process.run(program, arguments);
+  if (result.exitCode != 0) {
+    print('Failing process stdout: ${result.stdout}');
+    print('Failing process stderr: ${result.stderr}');
+    print('End failing process stderr');
+    Expect.fail('Test failed with exit code ${result.exitCode}');
+  }
+}
+
+Future testNativeExtensions(String snapshotKind) async {
+  String buildDirectory = dirname(Platform.executable);
+  Directory tempDirectory =
+      Directory.systemTemp.createTempSync('sample_extension_');
+  try {
+    String testDirectory = tempDirectory.path;
+    String sourceDirectory = Platform.script.resolve('..').toFilePath();
+
+    // Copy sample_extension dart files and sample_extension tests to the
+    // temporary test directory.
+    for (var file in [
+      'sample_synchronous_extension.dart',
+      'sample_asynchronous_extension.dart',
+      'test_sample_synchronous_extension.dart',
+      'test_sample_asynchronous_extension.dart'
+    ]) {
+      await copyFileToDirectory(join(sourceDirectory, file), testDirectory);
+    }
+
+    for (var test in [
+      'test_sample_synchronous_extension.dart',
+      'test_sample_asynchronous_extension.dart'
+    ]) {
+      String script = join(testDirectory, test);
+      String snapshot;
+      if (snapshotKind == null) {
+        snapshot = script;
+      } else {
+        snapshot = join(testDirectory, "$test.snapshot");
+        List<String> args = new List<String>.from(Platform.executableArguments);
+        args.add('--snapshot=$snapshot');
+        args.add('--snapshot-kind=$snapshotKind');
+        args.add(script);
+        await run(Platform.executable, args);
+      }
+
+      List<String> args = new List<String>.from(Platform.executableArguments);
+      args.add(snapshot);
+      await run(Platform.executable, args);
+    }
+  } finally {
+    tempDirectory.deleteSync(recursive: true);
+  }
+}
diff --git a/samples_2/sample_extension/test_sample_asynchronous_extension.dart b/samples_2/sample_extension/test_sample_asynchronous_extension.dart
new file mode 100644
index 0000000..5ceb7c8
--- /dev/null
+++ b/samples_2/sample_extension/test_sample_asynchronous_extension.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+library test_sample_extension;
+
+import 'sample_asynchronous_extension.dart';
+
+void check(bool condition, String message) {
+  if (!condition) {
+    throw new StateError(message);
+  }
+}
+
+void main() {
+  RandomArray r = new RandomArray();
+  r.randomArray(17, 100).then((list_100) {
+    r.randomArray(17, 200).then((list_200) {
+      for (var i = 0; i < 100; ++i) {
+        check(list_100[i] == list_200[i], "list_100[i] == list_200[i]");
+      }
+    });
+  });
+
+  // Gets a list of 256000 random uint8 values, using seed 19, and
+  // runs checkNormal on that list.
+  r.randomArray(19, 256000).then(checkNormal);
+}
+
+void checkNormal(List l) {
+  // Count how many times each byte value occurs.  Assert that the counts
+  // are all within a reasonable (six-sigma) range.
+  List counts = new List<int>.filled(256, 0);
+  for (var e in l) {
+    counts[e]++;
+  }
+  new RandomArray().randomArray(18, 256000).then(checkCorrelation(counts));
+}
+
+Function checkCorrelation(List counts) {
+  return (List l) {
+    List counts_2 = new List<int>.filled(256, 0);
+    for (var e in l) {
+      counts_2[e]++;
+    }
+    var product = 0;
+    for (var i = 0; i < 256; ++i) {
+      check(counts[i] < 1200, "counts[i] < 1200");
+      check(counts_2[i] < 1200, "counts_2[i] < 1200");
+      check(counts[i] > 800, "counts[i] > 800");
+      check(counts[i] > 800, "counts[i] > 800");
+
+      product += counts[i] * counts_2[i];
+    }
+    check(product < 256000000 * 1.001, "product < 256000000 * 1.001");
+    check(product > 256000000 * 0.999, "product > 256000000 * 0.999");
+  };
+}
diff --git a/samples_2/sample_extension/test_sample_synchronous_extension.dart b/samples_2/sample_extension/test_sample_synchronous_extension.dart
new file mode 100644
index 0000000..77d2fc3
--- /dev/null
+++ b/samples_2/sample_extension/test_sample_synchronous_extension.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+library test_sample_extension;
+
+import 'sample_synchronous_extension.dart';
+
+void check(bool condition, String message) {
+  if (!condition) {
+    throw new StateError(message);
+  }
+}
+
+void checkSystemRand() {
+  systemSrand(17);
+  var x1 = systemRand();
+  var x2 = systemRand();
+  var x3 = systemRand();
+  check(x1 != x2, "x1 != x2");
+  check(x1 != x3, "x1 != x3");
+  check(x2 != x3, "x2 != x3");
+  systemSrand(17);
+  check(x1 == systemRand(), "x1 == systemRand()");
+  check(x2 == systemRand(), "x2 == systemRand()");
+  check(x3 == systemRand(), "x3 == systemRand()");
+  systemSrand(18);
+  check(x1 != systemRand(), "x1 != systemRand()");
+  check(x2 != systemRand(), "x2 != systemRand()");
+  check(x3 != systemRand(), "x3 != systemRand()");
+}
+
+void checkNoScopeSystemRand() {
+  systemSrand(17);
+  var x1 = noScopeSystemRand();
+  var x2 = noScopeSystemRand();
+  var x3 = noScopeSystemRand();
+  check(x1 != x2, "x1 != x2");
+  check(x1 != x3, "x1 != x3");
+  check(x2 != x3, "x2 != x3");
+  systemSrand(17);
+  check(x1 == noScopeSystemRand(), "x1 == noScopeSystemRand()");
+  check(x2 == noScopeSystemRand(), "x2 == noScopeSystemRand()");
+  check(x3 == noScopeSystemRand(), "x3 == noScopeSystemRand()");
+  systemSrand(18);
+  check(x1 != noScopeSystemRand(), "x1 != noScopeSystemRand()");
+  check(x2 != noScopeSystemRand(), "x2 != noScopeSystemRand()");
+  check(x3 != noScopeSystemRand(), "x3 != noScopeSystemRand()");
+}
+
+void main() {
+  checkSystemRand();
+  checkNoScopeSystemRand();
+}
diff --git a/samples_2/samples_2.status b/samples_2/samples_2.status
new file mode 100644
index 0000000..2fe1de2
--- /dev/null
+++ b/samples_2/samples_2.status
@@ -0,0 +1,38 @@
+# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $arch == arm ]
+sample_extension/test/*: Skip # Issue 14705
+
+[ $builder_tag == asan ]
+ffi/samples_test: SkipByDesign # FFI skips, see ffi.status
+
+[ $builder_tag == optimization_counter_threshold ]
+sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign # This test is too slow for testing with low optimization counter threshold.
+
+[ $compiler == dart2js && $runtime == none ]
+*: Fail, Pass # TODO(ahe): Triage these tests.
+
+[ $compiler == none && $mode == debug && $runtime == vm && $system == windows ]
+sample_extension/test/sample_extension_app_snapshot_test: Pass, RuntimeError # Issue 28842
+
+[ $compiler == none && $runtime == vm && $system == fuchsia ]
+*: Skip # Not yet triaged.
+
+[ $arch == simarm || $arch == simarm64 ]
+ffi/*: SkipByDesign # FFI skips, see ffi.status
+
+[ $arch != x64 || $compiler != dartk || $system != linux || $hot_reload || $hot_reload_rollback ]
+ffi/sqlite/test/sqlite_test: SkipByDesign # FFI not supported or libsqlite3.so not available.
+
+[ $compiler == app_jitk || $compiler == dartkp ]
+sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign
+sample_extension/test/sample_extension_test: SkipByDesign
+
+[ $runtime == d8 || $browser ]
+ffi/*: SkipByDesign # Skip tests that use dart:ffi.
+sample_extension/*: SkipByDesign # Skip tests that use dart:io.
+
+[ $hot_reload || $hot_reload_rollback ]
+sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign # Cannot reload with URI pointing to app snapshot.
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 392c905..efa745a 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -46,16 +46,18 @@
 # ......snapshots/
 # ........analysis_server.dart.snapshot
 # ........dart2js.dart.snapshot
+# ........dart2native.dart.snapshot (if not on ia32)
 # ........dartanalyzer.dart.snapshot
-# ........dds.dart.snapshot
+# ........dartdev.dill
+# ........dartdevc.dart.snapshot
 # ........dartdoc.dart.snapshot
 # ........dartfmt.dart.snapshot
-# ........dartdevc.dart.snapshot
+# ........dds.dart.snapshot
+# ........frontend_server.dart.snapshot
 # ........gen_kernel.dart.snapshot (if not on ia32)
-# ........dart2native.dart.snapshot (if not on ia32)
+# ........kernel-service.dart.snapshot
 # ........kernel_worker.dart.snapshot
 # ........pub.dart.snapshot
-# ........frontend_server.dart.snapshot
 # ......resources/
 # ........dartdoc/
 # ...........packages
@@ -73,7 +75,6 @@
 # ........dart2js_server_platform.dill
 # ........dart2js_platform_strong.dill
 # ........dart2js_server_platform_strong.dill
-# ........dartdev.dill
 # ........vm_platform_strong.dill
 # ........dev_compiler/
 # ......async/
@@ -90,7 +91,6 @@
 # ......math/
 # ......mirrors/
 # ......typed_data/
-# ......wasm/
 # ......api_readme.md
 
 # Scripts that go under bin/
@@ -232,7 +232,6 @@
   "mirrors",
   "svg",
   "typed_data",
-  "wasm",
   "web_audio",
   "web_gl",
   "web_sql",
@@ -317,45 +316,6 @@
   ]
 }
 
-if (target_cpu == "x64") {
-  if (is_linux || is_android || is_fuchsia) {
-    copy_tree_specs += [
-      {
-        target = "copy_libtensorflowlite_c"
-        visibility = [ ":create_common_sdk" ]
-        deps = [ ":copy_libraries" ]
-        source = "../third_party/pkg/tflite_native/lib/src/blobs"
-        dest = "$root_out_dir/dart-sdk/bin/snapshots"
-        ignore_patterns = "*.dll,*mac64.so"
-      },
-    ]
-  }
-  if (is_mac) {
-    copy_tree_specs += [
-      {
-        target = "copy_libtensorflowlite_c"
-        visibility = [ ":create_common_sdk" ]
-        deps = [ ":copy_libraries" ]
-        source = "../third_party/pkg/tflite_native/lib/src/blobs"
-        dest = "$root_out_dir/dart-sdk/bin/snapshots"
-        ignore_patterns = "*.dll,*linux64.so"
-      },
-    ]
-  }
-  if (is_win) {
-    copy_tree_specs += [
-      {
-        target = "copy_libtensorflowlite_c"
-        visibility = [ ":create_common_sdk" ]
-        deps = [ ":copy_libraries" ]
-        source = "../third_party/pkg/tflite_native/lib/src/blobs"
-        dest = "$root_out_dir/dart-sdk/bin/snapshots"
-        ignore_patterns = "*.so"
-      },
-    ]
-  }
-}
-
 # This generates targets for everything in copy_tree_specs. The targets have the
 # same name as the "target" fields in the scopes of copy_tree_specs.
 copy_trees("copy_trees") {
@@ -586,18 +546,23 @@
   visibility = [ ":create_common_sdk" ]
   deps = [
     ":copy_libraries",
-    "../third_party/wasmer:wasmer",
+    "../third_party/wasmer:wasmer_wrap",
   ]
-  outputs =
-      [ "$root_out_dir/dart-sdk/bin/third_party/wasmer/{{source_file_part}}" ]
   if (is_win) {
-    sources = [ "$target_out_dir/../third_party/wasmer/wasmer.dll" ]
+    prefix = ""
+    suffix = "dll"
   } else if (is_mac) {
-    sources = [ "$target_out_dir/../third_party/wasmer/libwasmer.dylib" ]
+    prefix = "lib"
+    suffix = "dylib"
   } else {
     # TODO(dartbug.com/37882): Support Fuchsia.
-    sources = [ "$target_out_dir/../third_party/wasmer/libwasmer.so" ]
+    prefix = "lib"
+    suffix = "so"
   }
+  sources = [ "$root_out_dir/${prefix}wasmer_wrap.$suffix" ]
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/third_party/wasmer/${prefix}wasmer.$suffix",
+  ]
 }
 
 # This rule copies dill files to lib/_internal.
@@ -618,7 +583,7 @@
     "../utils/dartdev:dartdev",
   ]
   sources = [ "$root_out_dir/dartdev.dill" ]
-  outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ]
+  outputs = [ "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}" ]
 }
 
 copy("copy_dart2js_dill_files") {
@@ -920,9 +885,6 @@
   if (is_win) {
     public_deps += [ ":copy_7zip" ]
   }
-  if (target_cpu == "x64") {
-    public_deps += [ ":copy_libtensorflowlite_c" ]
-  }
 
   # CIPD only has versions of the Rust compiler for linux and mac x64 hosts.
   # We also disallow cross-compialtion (it may be possible in future, but it
diff --git a/sdk/bin/dartfix b/sdk/bin/dartfix
deleted file mode 100755
index bbeb80d..0000000
--- a/sdk/bin/dartfix
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Run dartfix.dart on the Dart VM. This script assumes the Dart SDK's
-# directory structure.
-
-function follow_links() {
-  file="$1"
-  while [ -h "$file" ]; do
-    # On Mac OS, readlink -f doesn't work.
-    file="$(readlink "$file")"
-  done
-  echo "$file"
-}
-
-# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
-PROG_NAME="$(follow_links "$BASH_SOURCE")"
-
-# Handle the case where dart-sdk/bin has been symlinked to.
-BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-
-SNAPSHOT="$BIN_DIR/snapshots/dartfix.dart.snapshot"
-
-# We are running the snapshot in the built SDK.
-DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "$@"
diff --git a/sdk/bin/dartfix.bat b/sdk/bin/dartfix.bat
deleted file mode 100644
index b58475c..0000000
--- a/sdk/bin/dartfix.bat
+++ /dev/null
@@ -1,44 +0,0 @@
-@echo off
-REM Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-REM for details. All rights reserved. Use of this source code is governed by a
-REM BSD-style license that can be found in the LICENSE file.
-
-setlocal
-rem Handle the case where dart-sdk/bin has been symlinked to.
-set DIR_NAME_WITH_SLASH=%~dp0
-set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
-call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
-rem Get rid of surrounding quotes.
-for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
-
-set DART=%BIN_DIR%\dart
-set SNAPSHOT=%BIN_DIR%\snapshots\dartfix.dart.snapshot
-
-"%DART%" "%SNAPSHOT%" %*
-
-endlocal
-
-exit /b %errorlevel%
-
-rem Follow the symbolic links (junctions points) using `dir to determine the
-rem canonical path. Output with a link looks something like this
-rem
-rem 01/03/2013  10:11 PM    <JUNCTION>     abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
-rem
-rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
-rem surrounded by right angle bracket and left square bracket. Once we get
-rem the filename, which is name of the link, we recursively follow that.
-:follow_links
-setlocal
-for %%i in (%1) do set result=%%~fi
-set current=
-for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
-                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
-  set current=%%i
-)
-if not "%current%"=="" call :follow_links "%current%", result
-endlocal & set %~2=%result%
-goto :eof
-
-:end
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
index 9b45b66..6799347 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
@@ -83,7 +83,7 @@
 @patch
 class ReceivePort {
   @patch
-  factory ReceivePort() = _ReceivePort;
+  factory ReceivePort([String debugName]) = _ReceivePort;
 
   @patch
   factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =>
@@ -94,6 +94,8 @@
 /// (async_helper, unittest) create a dummy receive port to keep the Dart VM
 /// alive.
 class _ReceivePort extends Stream implements ReceivePort {
+  _ReceivePort([String debugName = '']);
+
   close() {}
 
   get sendPort => _unsupported();
@@ -108,7 +110,8 @@
 @patch
 class RawReceivePort {
   @patch
-  factory RawReceivePort([Function? handler]) => _unsupported();
+  factory RawReceivePort([Function? handler, String debugName = '']) =>
+      _unsupported();
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index bac9226..f0fa4f0 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -12,27 +12,50 @@
 @notNull
 external bool compileTimeFlag(String flag);
 
-_throwNullSafetyWarningError() => throw UnsupportedError(
-    'Null safety errors cannot be shown as warnings when running with sound '
-    'null safety.');
+_throwInvalidFlagError(String message) =>
+    throw UnsupportedError('Invalid flag combination.\n$message');
 
 @notNull
 bool _weakNullSafetyWarnings = false;
 
-/// Sets the runtime mode to show warnings when running with weak null safety.
+/// Sets the runtime mode to show warnings when types violate sound null safety.
 ///
-/// These are warnings for issues that will become errors when sound null safety
-/// is enabled. Showing warnings while running with sound null safety is not
-/// supported (they will be errors).
+/// This option is not compatible with weak null safety errors or sound null
+/// safety (the warnings will be errors).
 void weakNullSafetyWarnings(bool showWarnings) {
   if (showWarnings && compileTimeFlag('soundNullSafety')) {
-    _throwNullSafetyWarningError();
+    _throwInvalidFlagError(
+        'Null safety violations cannot be shown as warnings when running with '
+        'sound null safety.');
   }
 
   _weakNullSafetyWarnings = showWarnings;
 }
 
 @notNull
+bool _weakNullSafetyErrors = false;
+
+/// Sets the runtime mode to throw errors when types violate sound null safety.
+///
+/// This option is not compatible with weak null safety warnings (the warnings
+/// are now errors) or sound null safety (the errors are already errors).
+void weakNullSafetyErrors(bool showErrors) {
+  if (showErrors && compileTimeFlag('soundNullSafety')) {
+    _throwInvalidFlagError(
+        'Null safety violations are already thrown as errors when running with '
+        'sound null safety.');
+  }
+
+  if (showErrors && _weakNullSafetyWarnings) {
+    _throwInvalidFlagError(
+        'Null safety violations can be shown as warnings or thrown as errors, '
+        'not both.');
+  }
+
+  _weakNullSafetyErrors = showErrors;
+}
+
+@notNull
 bool _nonNullAsserts = false;
 
 /// Sets the runtime mode to insert non-null assertions on non-nullable method
@@ -250,10 +273,12 @@
   JS('void', 'console.warn(#)', arg);
 }
 
-void _nullWarn(arg) {
+void _nullWarn(message) {
   if (_weakNullSafetyWarnings) {
-    _warn('$arg\n'
+    _warn('$message\n'
         'This will become a failure when runtime null safety is enabled.');
+  } else if (_weakNullSafetyErrors) {
+    throw TypeErrorImpl(message);
   }
 }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 2b48b5d..1cd3bc4 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -26,7 +26,7 @@
         getTraceFromException,
         RuntimeError;
 
-import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
+import 'dart:_foreign_helper' show JS;
 import 'dart:_native_typed_data' show NativeUint8List;
 import 'dart:_rti' show getRuntimeType;
 
@@ -459,9 +459,15 @@
     assertUnreachable();
   }
 
+  factory List._ofArray(Iterable<E> elements) {
+    return JSArray<E>.markGrowable(
+        JS('effects:none;depends:no-static', '#.slice(0)', elements));
+  }
+
   factory List._of(Iterable<E> elements) {
-    // This is essentially `addAll`, but without a check for modifiability or
-    // ConcurrentModificationError on the receiver.
+    if (elements is JSArray) return List._ofArray(elements);
+    // This is essentially `<E>[]..addAll(elements)`, but without a check for
+    // modifiability or ConcurrentModificationError on the receiver.
     List<E> list = <E>[];
     for (final e in elements) {
       list.add(e);
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
index 228fc3a..1c0b053 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -111,7 +111,7 @@
 @patch
 class ReceivePort {
   @patch
-  factory ReceivePort() = _ReceivePortImpl;
+  factory ReceivePort([String debugName]) = _ReceivePortImpl;
 
   @patch
   factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
@@ -120,6 +120,8 @@
 }
 
 class _ReceivePortImpl extends Stream implements ReceivePort {
+  _ReceivePortImpl([String debugName = '']);
+
   StreamSubscription listen(void Function(dynamic)? onData,
       {Function? onError,
       void Function()? onDone,
@@ -135,7 +137,7 @@
 @patch
 class RawReceivePort {
   @patch
-  factory RawReceivePort([Function? handler]) {
+  factory RawReceivePort([Function? handler, String debugName = '']) {
     throw new UnsupportedError('new RawReceivePort');
   }
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart
index e3a6b03..93bd80c 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_array.dart
@@ -26,7 +26,9 @@
     return new JSArray<E>.fixed(length);
   }
 
-  /// Returns a fresh JavaScript Array, marked as fixed-length.
+  /// Returns a fresh JavaScript Array, marked as fixed-length. The holes in the
+  /// array yield `undefined`, making the Dart List appear to be filled with
+  /// `null` values.
   ///
   /// [length] must be a non-negative integer.
   factory JSArray.fixed(int length) {
@@ -36,8 +38,34 @@
     if (length is! int) {
       throw new ArgumentError.value(length, 'length', 'is not an integer');
     }
-    // The JavaScript Array constructor with one argument throws if
-    // the value is not a UInt32. Give a better error message.
+    // The JavaScript Array constructor with one argument throws if the value is
+    // not a UInt32 but the error message does not contain the bad value. Give a
+    // better error message.
+    int maxJSArrayLength = 0xFFFFFFFF;
+    if (length < 0 || length > maxJSArrayLength) {
+      throw new RangeError.range(length, 0, maxJSArrayLength, 'length');
+    }
+    return new JSArray<E>.markFixed(JS('', 'new Array(#)', length));
+  }
+
+  /// Returns a fresh JavaScript Array, marked as fixed-length.  The Array is
+  /// allocated but no elements are assigned.
+  ///
+  /// All elements of the array must be assigned before the array is valid. This
+  /// is essentially the same as `JSArray.fixed` except that global type
+  /// inference starts with bottom for the element type.
+  ///
+  /// [length] must be a non-negative integer.
+  factory JSArray.allocateFixed(int length) {
+    // Explicit type test is necessary to guard against JavaScript conversions
+    // in unchecked mode, and against `new Array(null)` which creates a single
+    // element Array containing `null`.
+    if (length is! int) {
+      throw new ArgumentError.value(length, 'length', 'is not an integer');
+    }
+    // The JavaScript Array constructor with one argument throws if the value is
+    // not a UInt32 but the error message does not contain the bad value. Give a
+    // better error message.
     int maxJSArrayLength = 0xFFFFFFFF;
     if (length < 0 || length > maxJSArrayLength) {
       throw new RangeError.range(length, 0, maxJSArrayLength, 'length');
@@ -48,9 +76,11 @@
   /// Returns a fresh growable JavaScript Array of zero length length.
   factory JSArray.emptyGrowable() => new JSArray<E>.markGrowable(JS('', '[]'));
 
-  /// Returns a fresh growable JavaScript Array with initial length.
+  /// Returns a fresh growable JavaScript Array with initial length. The holes
+  /// in the array yield `undefined`, making the Dart List appear to be filled
+  /// with `null` values.
   ///
-  /// [validatedLength] must be a non-negative integer.
+  /// [length] must be a non-negative integer.
   factory JSArray.growable(int length) {
     // Explicit type test is necessary to guard against JavaScript conversions
     // in unchecked mode.
@@ -60,6 +90,23 @@
     return new JSArray<E>.markGrowable(JS('', 'new Array(#)', length));
   }
 
+  /// Returns a fresh growable JavaScript Array with initial length. The Array
+  /// is allocated but no elements are assigned.
+  ///
+  /// All elements of the array must be assigned before the array is valid. This
+  /// is essentially the same as `JSArray.growable` except that global type
+  /// inference starts with bottom for the element type.
+  ///
+  /// [length] must be a non-negative integer.
+  factory JSArray.allocateGrowable(int length) {
+    // Explicit type test is necessary to guard against JavaScript conversions
+    // in unchecked mode.
+    if ((length is! int) || (length < 0)) {
+      throw new ArgumentError('Length must be a non-negative integer: $length');
+    }
+    return new JSArray<E>.markGrowable(JS('', 'new Array(#)', length));
+  }
+
   /// Constructor for adding type parameters to an existing JavaScript Array.
   /// The compiler specially recognizes this constructor.
   ///
diff --git a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
index 2b66dfc..02ec093 100644
--- a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -739,7 +739,7 @@
 @Native('Float32Array')
 class NativeFloat32List extends NativeTypedArrayOfDouble
     implements Float32List {
-  factory NativeFloat32List(int length) => _create1(_checkLength(length));
+  factory NativeFloat32List(int length) => _createLength(_checkLength(length));
 
   factory NativeFloat32List.fromList(List<double> elements) =>
       _create1(_ensureNativeList(elements));
@@ -760,6 +760,11 @@
     return _create1(source);
   }
 
+  static NativeFloat32List _createLength(int arg) => JS(
+      'returns:NativeFloat32List;effects:none;depends:none;new:true',
+      'new Float32Array(#)',
+      arg);
+
   static NativeFloat32List _create1(arg) =>
       JS('NativeFloat32List', 'new Float32Array(#)', arg);
 
@@ -773,7 +778,7 @@
 @Native('Float64Array')
 class NativeFloat64List extends NativeTypedArrayOfDouble
     implements Float64List {
-  factory NativeFloat64List(int length) => _create1(_checkLength(length));
+  factory NativeFloat64List(int length) => _createLength(_checkLength(length));
 
   factory NativeFloat64List.fromList(List<double> elements) =>
       _create1(_ensureNativeList(elements));
@@ -794,6 +799,11 @@
     return _create1(source);
   }
 
+  static NativeFloat64List _createLength(int arg) => JS(
+      'returns:NativeFloat64List;effects:none;depends:none;new:true',
+      'new Float64Array(#)',
+      arg);
+
   static NativeFloat64List _create1(arg) =>
       JS('NativeFloat64List', 'new Float64Array(#)', arg);
 
@@ -806,7 +816,7 @@
 
 @Native('Int16Array')
 class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
-  factory NativeInt16List(int length) => _create1(_checkLength(length));
+  factory NativeInt16List(int length) => _createLength(_checkLength(length));
 
   factory NativeInt16List.fromList(List<int> elements) =>
       _create1(_ensureNativeList(elements));
@@ -832,6 +842,11 @@
     return _create1(source);
   }
 
+  static NativeInt16List _createLength(int arg) => JS(
+      'returns:NativeInt16List;effects:none;depends:none;new:true',
+      'new Int16Array(#)',
+      arg);
+
   static NativeInt16List _create1(arg) =>
       JS('NativeInt16List', 'new Int16Array(#)', arg);
 
@@ -844,7 +859,7 @@
 
 @Native('Int32Array')
 class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
-  factory NativeInt32List(int length) => _create1(_checkLength(length));
+  factory NativeInt32List(int length) => _createLength(_checkLength(length));
 
   factory NativeInt32List.fromList(List<int> elements) =>
       _create1(_ensureNativeList(elements));
@@ -870,6 +885,11 @@
     return _create1(source);
   }
 
+  static NativeInt32List _createLength(int arg) => JS(
+      'returns:NativeInt32List;effects:none;depends:none;new:true',
+      'new Int32Array(#)',
+      arg);
+
   static NativeInt32List _create1(arg) =>
       JS('NativeInt32List', 'new Int32Array(#)', arg);
 
@@ -882,7 +902,7 @@
 
 @Native('Int8Array')
 class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
-  factory NativeInt8List(int length) => _create1(_checkLength(length));
+  factory NativeInt8List(int length) => _createLength(_checkLength(length));
 
   factory NativeInt8List.fromList(List<int> elements) =>
       _create1(_ensureNativeList(elements));
@@ -908,6 +928,11 @@
     return _create1(source);
   }
 
+  static NativeInt8List _createLength(int arg) => JS(
+      'returns:NativeInt8List;effects:none;depends:none;new:true',
+      'new Int8Array(#)',
+      arg);
+
   static NativeInt8List _create1(arg) =>
       JS('NativeInt8List', 'new Int8Array(#)', arg);
 
@@ -920,7 +945,7 @@
 
 @Native('Uint16Array')
 class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
-  factory NativeUint16List(int length) => _create1(_checkLength(length));
+  factory NativeUint16List(int length) => _createLength(_checkLength(length));
 
   factory NativeUint16List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
@@ -946,6 +971,11 @@
     return _create1(source);
   }
 
+  static NativeUint16List _createLength(int arg) => JS(
+      'returns:NativeUint16List;effects:none;depends:none;new:true',
+      'new Uint16Array(#)',
+      arg);
+
   static NativeUint16List _create1(arg) =>
       JS('NativeUint16List', 'new Uint16Array(#)', arg);
 
@@ -958,7 +988,7 @@
 
 @Native('Uint32Array')
 class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
-  factory NativeUint32List(int length) => _create1(_checkLength(length));
+  factory NativeUint32List(int length) => _createLength(_checkLength(length));
 
   factory NativeUint32List.fromList(List<int> elements) =>
       _create1(_ensureNativeList(elements));
@@ -984,6 +1014,11 @@
     return _create1(source);
   }
 
+  static NativeUint32List _createLength(int arg) => JS(
+      'returns:NativeUint32List;effects:none;depends:none;new:true',
+      'new Uint32Array(#)',
+      arg);
+
   static NativeUint32List _create1(arg) =>
       JS('NativeUint32List', 'new Uint32Array(#)', arg);
 
@@ -997,7 +1032,8 @@
 @Native('Uint8ClampedArray,CanvasPixelArray')
 class NativeUint8ClampedList extends NativeTypedArrayOfInt
     implements Uint8ClampedList {
-  factory NativeUint8ClampedList(int length) => _create1(_checkLength(length));
+  factory NativeUint8ClampedList(int length) =>
+      _createLength(_checkLength(length));
 
   factory NativeUint8ClampedList.fromList(List<int> elements) =>
       _create1(_ensureNativeList(elements));
@@ -1026,6 +1062,11 @@
     return _create1(source);
   }
 
+  static NativeUint8ClampedList _createLength(int arg) => JS(
+      'returns:NativeUint8ClampedList;effects:none;depends:none;new:true',
+      'new Uint8ClampedArray(#)',
+      arg);
+
   static NativeUint8ClampedList _create1(arg) =>
       JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#)', arg);
 
@@ -1046,7 +1087,7 @@
 // dispatch record for Uint8List.
 @Native('Uint8Array,!nonleaf')
 class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
-  factory NativeUint8List(int length) => _create1(_checkLength(length));
+  factory NativeUint8List(int length) => _createLength(_checkLength(length));
 
   factory NativeUint8List.fromList(List<int> elements) =>
       _create1(_ensureNativeList(elements));
@@ -1074,6 +1115,11 @@
     return _create1(source);
   }
 
+  static NativeUint8List _createLength(int arg) => JS(
+      'returns:NativeUint8List;effects:none;depends:none;new:true',
+      'new Uint8Array(#)',
+      arg);
+
   static NativeUint8List _create1(arg) =>
       JS('NativeUint8List', 'new Uint8Array(#)', arg);
 
diff --git a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
index 16ab9b0..c6adb12 100644
--- a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -209,9 +209,9 @@
   }
 
   String? namedGroup(String name) {
-    var groups = JS('Object|Null', '#.groups', _match);
+    var groups = JS('=Object|Null', '#.groups', _match);
     if (groups != null) {
-      var result = JS('String|Null', '#[#]', groups, name);
+      String? result = JS('String|Null', '#[#]', groups, name);
       if (result != null || JS('bool', '# in #', name, groups)) {
         return result;
       }
@@ -220,7 +220,7 @@
   }
 
   Iterable<String> get groupNames {
-    var groups = JS('Object|Null', '#.groups', _match);
+    var groups = JS('=Object|Null', '#.groups', _match);
     if (groups != null) {
       var keys = new JSArray<String>.markGrowable(
           JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', groups));
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index ab7da7e..eb87192 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -134,8 +134,6 @@
       categories: "Client",
       maturity: Maturity.WEB_STABLE,
       platforms: DART2JS_PLATFORM),
-  "wasm": const LibraryInfo("wasm/wasm.dart",
-      categories: "Server", maturity: Maturity.EXPERIMENTAL),
   "web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart",
       categories: "Client",
       maturity: Maturity.WEB_STABLE,
diff --git a/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
index 79b69ee..7f66713 100644
--- a/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
+++ b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
@@ -2,3 +2,5 @@
 # make it easer to depend on libraries.dart from sdk packages like dart2js.
 name: sdk_library_metadata
 publish_to: none
+environment:
+  sdk: '>=2.11.0 <3.0.0'
diff --git a/sdk/lib/_internal/vm/bin/io_service_patch.dart b/sdk/lib/_internal/vm/bin/io_service_patch.dart
index d54bbf2..7b93d0e 100644
--- a/sdk/lib/_internal/vm/bin/io_service_patch.dart
+++ b/sdk/lib/_internal/vm/bin/io_service_patch.dart
@@ -74,7 +74,7 @@
 
   static void _ensureInitialize() {
     if (_receivePort == null) {
-      _receivePort = new RawReceivePort();
+      _receivePort = new RawReceivePort(null, 'IO Service');
       _replyToPort = _receivePort!.sendPort;
       _receivePort!.handler = (data) {
         assert(data is List && data.length == 2);
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index 976b1f1..0cb43ee 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -574,16 +574,29 @@
 
   static Future<ConnectionTask<_NativeSocket>> startConnect(
       dynamic host, int port, dynamic sourceAddress) {
+    // Looks up [sourceAddress] to one or more IP addresses,
+    // then tries connecting to each one until a connection succeeds.
+    // Attempts are staggered by a minimum delay, so a new
+    // attempt isn't made until either a previous attempt has *failed*,
+    // or the delay has passed.
+    // This ensures that at most *n* uncompleted connections can be
+    // active after *n* × *delay* time has passed.
     if (host is String) {
       host = escapeLinkLocalAddress(host);
     }
     _throwOnBadPort(port);
-    if (sourceAddress != null && sourceAddress is! _InternetAddress) {
-      if (sourceAddress is String) {
-        sourceAddress = new InternetAddress(sourceAddress);
+    _InternetAddress? source;
+    if (sourceAddress != null) {
+      if (sourceAddress is _InternetAddress) {
+        source = sourceAddress;
+      } else if (sourceAddress is String) {
+        source = new _InternetAddress.fromString(sourceAddress);
+      } else {
+        throw ArgumentError.value(sourceAddress, "sourceAddress",
+            "Must be a string or native InternetAddress");
       }
     }
-    return new Future.value(host).then((host) {
+    return new Future.value(host).then<List<InternetAddress>>((host) {
       if (host is _InternetAddress) return [host];
       return lookup(host).then((addresses) {
         if (addresses.isEmpty) {
@@ -592,128 +605,166 @@
         return addresses;
       });
     }).then((addresses) {
-      var completer = new Completer<_NativeSocket>();
-      var it = (addresses as List<InternetAddress>).iterator;
+      assert(addresses.isNotEmpty);
+      // Completer for result.
+      var result = new Completer<_NativeSocket>();
+      // Index of next address in [addresses] to try.
+      var index = 0;
+      // Error, set if an error occurs.
+      // Keeps first error if multiple errors occour.
       var error = null;
-      var connecting = new HashMap();
+      // Active timers for on-going connection attempts.
+      // Contains all sockets which haven't received and initial
+      // write or error event.
+      var connecting = <_NativeSocket>{};
+      // Timer counting down from the last connection attempt.
+      // Reset when a new connection is attempted,
+      // which happens either when a previous timer runs out,
+      // or when a previous connection attempt fails.
+      Timer? timer;
 
+      // Attempt to connect to the next address in [addresses].
+      //
+      // Called initially, then when either a connection attempt fails,
+      // or an amount of time has passed since the last connection
+      // was attempted.
       void connectNext() {
-        if (!it.moveNext()) {
+        timer?.cancel();
+        if (index >= addresses.length) {
           if (connecting.isEmpty) {
             assert(error != null);
-            completer.completeError(error);
+            assert(!result.isCompleted);
+            result.completeError(error);
           }
           return;
         }
-        final _InternetAddress address = it.current as _InternetAddress;
+        final address = addresses[index++] as _InternetAddress;
         var socket = new _NativeSocket.normal(address);
-        var result;
-        if (sourceAddress == null) {
-          if (address.type == InternetAddressType.unix) {
-            result = socket.nativeCreateUnixDomainConnect(
+        // Will contain values of various types representing the result
+        // of trying to create a connection.
+        // A value of `true` means success, everything else means failure.
+        Object? connectionResult;
+        if (address.type == InternetAddressType.unix) {
+          if (source == null) {
+            connectionResult = socket.nativeCreateUnixDomainConnect(
                 address.address, _Namespace._namespace);
           } else {
-            result = socket.nativeCreateConnect(
-                address._in_addr, port, address._scope_id);
+            assert(source.type == InternetAddressType.unix);
+            connectionResult = socket.nativeCreateUnixDomainBindConnect(
+                address.address, source.address, _Namespace._namespace);
           }
+          assert(connectionResult == true ||
+              connectionResult is Error ||
+              connectionResult is OSError);
         } else {
-          assert(sourceAddress is _InternetAddress);
-          if (address.type == InternetAddressType.unix) {
-            assert(sourceAddress.type == InternetAddressType.unix);
-            result = socket.nativeCreateUnixDomainBindConnect(
-                address.address, sourceAddress.address, _Namespace._namespace);
+          if (source == null) {
+            connectionResult = socket.nativeCreateConnect(
+                address._in_addr, port, address._scope_id);
           } else {
-            result = socket.nativeCreateBindConnect(address._in_addr, port,
-                sourceAddress._in_addr, address._scope_id);
+            connectionResult = socket.nativeCreateBindConnect(
+                address._in_addr, port, source._in_addr, address._scope_id);
           }
+          assert(connectionResult == true || connectionResult is OSError);
         }
-        if (result is OSError) {
-          // Keep first error, if present.
-          if (error == null) {
-            int errorCode = result.errorCode;
-            if (sourceAddress != null &&
+        if (connectionResult != true) {
+          // connectionResult was not a success.
+          if (connectionResult is OSError) {
+            int errorCode = connectionResult.errorCode;
+            if (source != null &&
                 errorCode != null &&
                 socket.isBindError(errorCode)) {
-              error = createError(result, "Bind failed", sourceAddress);
+              error = createError(connectionResult, "Bind failed", source);
             } else {
-              error = createError(result, "Connection failed", address, port);
+              error = createError(
+                  connectionResult, "Connection failed", address, port);
             }
+          } else if (connectionResult is Error) {
+            error = connectionResult;
+          } else {
+            error = createError(null, "Connection failed", address);
           }
-          connectNext();
-        } else {
-          // Query the local port for error messages.
-          try {
-            socket.port;
-          } catch (e) {
-            if (error == null) {
-              error = createError(e, "Connection failed", address, port);
-            }
-            connectNext();
-          }
-          // Set up timer for when we should retry the next address
-          // (if any).
-          var duration =
-              address.isLoopback ? _retryDurationLoopback : _retryDuration;
-          var timer = new Timer(duration, connectNext);
-
-          connecting[socket] = timer;
-          // Setup handlers for receiving the first write event which
-          // indicate that the socket is fully connected.
-          socket.setHandlers(write: () {
-            timer.cancel();
-            connecting.remove(socket);
-            // From 'man 2 connect':
-            // After select(2) indicates writability, use getsockopt(2) to read
-            // the SO_ERROR option at level SOL_SOCKET to determine whether
-            // connect() completed successfully (SO_ERROR is zero) or
-            // unsuccessfully.
-            OSError osError = socket.nativeGetError();
-            if (osError.errorCode != 0) {
-              socket.close();
-              if (error == null) error = osError;
-              if (connecting.isEmpty) connectNext();
-              return;
-            }
-            socket.setListening(read: false, write: false);
-            completer.complete(socket);
-            connecting.forEach((s, t) {
-              t.cancel();
-              s.close();
-              s.setHandlers();
-              s.setListening(read: false, write: false);
-            });
-            connecting.clear();
-          }, error: (e, st) {
-            timer.cancel();
-            socket.close();
-            // Keep first error, if present.
-            if (error == null) error = e;
-            connecting.remove(socket);
-            if (connecting.isEmpty) connectNext();
-          });
-          socket.setListening(read: false, write: true);
+          connectNext(); // Try again after failure to connect.
+          return;
         }
+        // Query the local port for error messages.
+        try {
+          socket.port;
+        } catch (e) {
+          if (error == null) {
+            error = createError(e, "Connection failed", address, port);
+          }
+          connectNext(); // Try again after failure to connect.
+          return;
+        }
+
+        // Try again if no response (failure or success) within a duration.
+        // If this occurs, the socket is still trying to connect, and might
+        // succeed or fail later.
+        var duration =
+            address.isLoopback ? _retryDurationLoopback : _retryDuration;
+        timer = new Timer(duration, connectNext);
+
+        connecting.add(socket);
+        // Setup handlers for receiving the first write event which
+        // indicate that the socket is fully connected.
+        socket.setHandlers(write: () {
+          // First remote response on connection.
+          // If error, drop the socket and go to the next address.
+          // If success, complete with the socket
+          // and stop all other open connection attempts.
+          connecting.remove(socket);
+          // From 'man 2 connect':
+          // After select(2) indicates writability, use getsockopt(2) to read
+          // the SO_ERROR option at level SOL_SOCKET to determine whether
+          // connect() completed successfully (SO_ERROR is zero) or
+          // unsuccessfully.
+          OSError osError = socket.nativeGetError();
+          if (osError.errorCode != 0) {
+            socket.close();
+            error ??= osError;
+            connectNext(); // Try again after failure to connect.
+            return;
+          }
+          // Connection success!
+          // Stop all other connecting sockets and timers.
+          timer!.cancel();
+          socket.setListening(read: false, write: false);
+          for (var s in connecting) {
+            s.close();
+            s.setHandlers();
+            s.setListening(read: false, write: false);
+          }
+          connecting.clear();
+          result.complete(socket);
+        }, error: (e, st) {
+          connecting.remove(socket);
+          socket.close();
+          socket.setHandlers();
+          socket.setListening(read: false, write: false);
+          // Keep first error, if present.
+          error ??= e;
+          connectNext(); // Try again after failure to connect.
+        });
+        socket.setListening(read: false, write: true);
       }
 
       void onCancel() {
-        connecting.forEach((s, t) {
-          t.cancel();
+        timer?.cancel();
+        for (var s in connecting) {
           s.close();
           s.setHandlers();
           s.setListening(read: false, write: false);
-          if (error == null) {
-            error = createError(null,
-                "Connection attempt cancelled, host: ${host}, port: ${port}");
-          }
-        });
+        }
         connecting.clear();
-        if (!completer.isCompleted) {
-          completer.completeError(error);
+        if (!result.isCompleted) {
+          error ??= createError(null,
+              "Connection attempt cancelled, host: ${host}, port: ${port}");
+          result.completeError(error);
         }
       }
 
       connectNext();
-      return new ConnectionTask<_NativeSocket>._(completer.future, onCancel);
+      return new ConnectionTask<_NativeSocket>._(result.future, onCancel);
     });
   }
 
@@ -1206,7 +1257,7 @@
   void connectToEventHandler() {
     assert(!isClosed);
     if (eventPort == null) {
-      eventPort = new RawReceivePort(multiplex);
+      eventPort = new RawReceivePort(multiplex, 'Socket Event Handler');
     }
   }
 
diff --git a/sdk/lib/_internal/vm/lib/array.dart b/sdk/lib/_internal/vm/lib/array.dart
index d615f7b..90a6fda 100644
--- a/sdk/lib/_internal/vm/lib/array.dart
+++ b/sdk/lib/_internal/vm/lib/array.dart
@@ -6,11 +6,17 @@
 
 @pragma("vm:entry-point")
 class _List<E> extends FixedLengthListBase<E> {
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type",
       <dynamic>[_List, "result-type-uses-passed-type-arguments"])
   @pragma("vm:prefer-inline")
   factory _List(length) native "List_allocate";
 
+  // Specialization of List.empty constructor for growable == false.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  @pragma("vm:prefer-inline")
+  factory _List.empty() => _List<E>(0);
+
   // Specialization of List.filled constructor for growable == false.
   // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
   factory _List.filled(int length, E fill) {
@@ -34,14 +40,84 @@
     return result;
   }
 
+  // Specialization of List.of constructor for growable == false.
+  factory _List.of(Iterable<E> elements) {
+    if (elements is _GrowableList) {
+      return _List._ofGrowableList(unsafeCast(elements));
+    }
+    if (elements is _List) {
+      return _List._ofList(unsafeCast(elements));
+    }
+    if (elements is _ImmutableList) {
+      return _List._ofImmutableList(unsafeCast(elements));
+    }
+    if (elements is EfficientLengthIterable) {
+      return _List._ofEfficientLengthIterable(unsafeCast(elements));
+    }
+    return _List._ofOther(elements);
+  }
+
+  factory _List._ofGrowableList(_GrowableList<E> elements) {
+    final int length = elements.length;
+    final list = _List<E>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _List._ofList(_List<E> elements) {
+    final int length = elements.length;
+    final list = _List<E>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _List._ofImmutableList(_ImmutableList<E> elements) {
+    final int length = elements.length;
+    final list = _List<E>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _List._ofEfficientLengthIterable(
+      EfficientLengthIterable<E> elements) {
+    final int length = elements.length;
+    final list = _List<E>(length);
+    if (length > 0) {
+      int i = 0;
+      for (var element in elements) {
+        list[i++] = element;
+      }
+      if (i != length) throw ConcurrentModificationError(elements);
+    }
+    return list;
+  }
+
+  factory _List._ofOther(Iterable<E> elements) {
+    // The static type of `makeListFixedLength` is `List<E>`, not `_List<E>`,
+    // but we know that is what it does.  `makeListFixedLength` is too generally
+    // typed since it is available on the web platform which has different
+    // system List types.
+    return unsafeCast(makeListFixedLength(_GrowableList<E>._ofOther(elements)));
+  }
+
+  @pragma("vm:recognized", "graph-intrinsic")
   E operator [](int index) native "List_getIndexed";
 
+  @pragma("vm:recognized", "other")
   void operator []=(int index, E value) {
     _setIndexed(index, value);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void _setIndexed(int index, E value) native "List_setIndexed";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "List_getLength";
@@ -188,8 +264,10 @@
   factory _ImmutableList._from(List from, int offset, int length)
       native "ImmutableList_from";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   E operator [](int index) native "List_getIndexed";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "List_getLength";
@@ -273,10 +351,7 @@
     assert(array is _List<E> || array is _ImmutableList<E>);
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 
   @pragma("vm:prefer-inline")
   bool moveNext() {
diff --git a/sdk/lib/_internal/vm/lib/array_patch.dart b/sdk/lib/_internal/vm/lib/array_patch.dart
index ef181be..07d7e75 100644
--- a/sdk/lib/_internal/vm/lib/array_patch.dart
+++ b/sdk/lib/_internal/vm/lib/array_patch.dart
@@ -12,6 +12,7 @@
   }
 
   @patch
+  @pragma("vm:recognized", "other")
   factory List([int? length]) native "List_new";
 
   @patch
@@ -29,43 +30,27 @@
 
   @patch
   factory List.from(Iterable elements, {bool growable: true}) {
-    if (elements is EfficientLengthIterable<E>) {
-      int length = elements.length;
-      var list = growable ? new _GrowableList<E>(length) : new _List<E>(length);
-      if (length > 0) {
-        // Avoid creating iterator unless necessary.
-        int i = 0;
-        for (var element in elements) {
-          list[i++] = element;
-        }
-      }
-      return list;
-    }
     // If elements is an Iterable<E>, we won't need a type-test for each
-    // element. In the "common case" that elements is an Iterable<E>, this
-    // replaces a type-test on every element with a single type-test before
-    // starting the loop.
+    // element.
     if (elements is Iterable<E>) {
-      List<E> list = new _GrowableList<E>(0);
-      for (E e in elements) {
-        list.add(e);
-      }
-      if (growable) return list;
-      return makeListFixedLength(list);
-    } else {
-      List<E> list = new _GrowableList<E>(0);
-      for (E e in elements) {
-        list.add(e);
-      }
-      if (growable) return list;
-      return makeListFixedLength(list);
+      return List.of(elements, growable: growable);
     }
+
+    List<E> list = new _GrowableList<E>(0);
+    for (E e in elements) {
+      list.add(e);
+    }
+    if (growable) return list;
+    return makeListFixedLength(list);
   }
 
   @patch
   factory List.of(Iterable<E> elements, {bool growable: true}) {
-    // TODO(32937): Specialize to benefit from known element type.
-    return List.from(elements, growable: growable);
+    if (growable) {
+      return _GrowableList.of(elements);
+    } else {
+      return _List.of(elements);
+    }
   }
 
   @patch
@@ -89,11 +74,8 @@
   // Factory constructing a mutable List from a parser generated List literal.
   // [elements] contains elements that are already type checked.
   @pragma("vm:entry-point", "call")
-  factory List._fromLiteral(List elements) {
-    if (elements.isEmpty) {
-      return new _GrowableList<E>(0);
-    }
-    final result = new _GrowableList<E>._withData(unsafeCast<_List>(elements));
+  factory List._fromLiteral(_List elements) {
+    final result = new _GrowableList<E>._withData(elements);
     result._setLength(elements.length);
     return result;
   }
diff --git a/sdk/lib/_internal/vm/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart
index 659f31f..8816675 100644
--- a/sdk/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk/lib/_internal/vm/lib/async_patch.dart
@@ -265,24 +265,5 @@
   }
 }
 
-/// Returns a [StackTrace] object containing the synchronous prefix for this
-/// asynchronous method.
-//
-// This method is recognized. It performs a runtime call if
-// FLAG_causal_async_stacks is enabled or returns `null` otherwise.
-@pragma("vm:prefer-inline")
-Object _asyncStackTraceHelper(Function async_op)
-    native "StackTrace_asyncStackTraceHelper";
-
-// This method is asm intrinsified.
-@pragma("vm:entry-point", "call")
-void _clearAsyncThreadStackTrace()
-    native "StackTrace_clearAsyncThreadStackTrace";
-
-// This method is asm intrinsified.
-@pragma("vm:entry-point", "call")
-void _setAsyncThreadStackTrace(StackTrace stackTrace)
-    native "StackTrace_setAsyncThreadStackTrace";
-
 void _moveNextDebuggerStepCheck(Function async_op)
     native "AsyncStarMoveNext_debuggerStepCheck";
diff --git a/sdk/lib/_internal/vm/lib/bigint_patch.dart b/sdk/lib/_internal/vm/lib/bigint_patch.dart
index 5cc0bef..dd627df 100644
--- a/sdk/lib/_internal/vm/lib/bigint_patch.dart
+++ b/sdk/lib/_internal/vm/lib/bigint_patch.dart
@@ -559,6 +559,7 @@
   /// Does *not* clear digits below ds.
   ///
   /// Note: This function may be intrinsified.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:never-inline")
   static void _lsh(
       Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
@@ -635,6 +636,7 @@
   /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
   ///
   /// Note: This function may be intrinsified.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:never-inline")
   static void _rsh(
       Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
@@ -763,6 +765,7 @@
   /// used >= otherUsed > 0.
   ///
   /// Note: This function may be intrinsified.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:never-inline")
   static void _absAdd(Uint32List digits, int used, Uint32List otherDigits,
       int otherUsed, Uint32List resultDigits) {
@@ -785,6 +788,7 @@
   /// used >= otherUsed > 0.
   ///
   /// Note: This function may be intrinsified.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:never-inline")
   static void _absSub(Uint32List digits, int used, Uint32List otherDigits,
       int otherUsed, Uint32List resultDigits) {
@@ -1114,6 +1118,7 @@
   ///
   /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
   /// process digit pairs at even indices and returns 2.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:never-inline")
   static int _mulAdd(
@@ -1166,6 +1171,7 @@
   ///
   /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
   /// process digit pairs at even indices and returns 2.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:never-inline")
   static int _sqrAdd(
@@ -1288,6 +1294,7 @@
   /// Estimate `args[_quotientDigit.._quotientHighDigit] = digits[i-3..i] ~/
   /// args[_divisorLowTopDigit.._divisorTopDigit]`.
   /// Returns 2.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:never-inline")
   static int _estimateQuotientDigit(Uint32List args, Uint32List digits, int i) {
@@ -2642,6 +2649,7 @@
   //   args[_muDigit.._muHighDigit] =
   //     args[_rhoDigit.._rhoHighDigit] * digits[i..i+1] mod _digitBase^2.
   //   Returns 2.
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:never-inline")
   static int _mulMod(Uint32List args, Uint32List digits, int i) {
diff --git a/sdk/lib/_internal/vm/lib/class_id_fasta.dart b/sdk/lib/_internal/vm/lib/class_id_fasta.dart
index c81bd60..006314b 100644
--- a/sdk/lib/_internal/vm/lib/class_id_fasta.dart
+++ b/sdk/lib/_internal/vm/lib/class_id_fasta.dart
@@ -6,7 +6,7 @@
 
 @pragma("vm:entry-point")
 class ClassID {
-  @pragma("vm:entry-point", "call")
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int getID(Object value) native "ClassID_getID";
 
diff --git a/sdk/lib/_internal/vm/lib/collection_patch.dart b/sdk/lib/_internal/vm/lib/collection_patch.dart
index 1307fb7..a1acbcb 100644
--- a/sdk/lib/_internal/vm/lib/collection_patch.dart
+++ b/sdk/lib/_internal/vm/lib/collection_patch.dart
@@ -845,10 +845,7 @@
     return false;
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 }
 
 /**
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index 67ba9b2..4574455 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -46,33 +46,43 @@
 
 // Base class for VM-internal classes; keep in sync with _HashFieldBase.
 abstract class _HashVMBase {
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:typed_data#_Uint32List")
   @pragma("vm:prefer-inline")
   Uint32List get _index native "LinkedHashMap_getIndex";
+  @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   void set _index(Uint32List value) native "LinkedHashMap_setIndex";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get _hashMask native "LinkedHashMap_getHashMask";
+  @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   void set _hashMask(int value) native "LinkedHashMap_setHashMask";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_List")
   @pragma("vm:prefer-inline")
   List get _data native "LinkedHashMap_getData";
+  @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   void set _data(List value) native "LinkedHashMap_setData";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get _usedData native "LinkedHashMap_getUsedData";
+  @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   void set _usedData(int value) native "LinkedHashMap_setUsedData";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get _deletedKeys native "LinkedHashMap_getDeletedKeys";
+  @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   void set _deletedKeys(int value) native "LinkedHashMap_setDeletedKeys";
 }
@@ -464,10 +474,7 @@
     }
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 }
 
 // Set implementation, analogous to _CompactLinkedHashMap.
diff --git a/sdk/lib/_internal/vm/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart
index 6f82337..851c554 100644
--- a/sdk/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk/lib/_internal/vm/lib/convert_patch.dart
@@ -1700,7 +1700,7 @@
     return size;
   }
 
-  // This method is recognized by the VM and compiled into specialized code.
+  @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   int _scan(Uint8List bytes, int start, int end, String scanTable) {
     int size = 0;
diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
index d138549..34b26f3 100644
--- a/sdk/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk/lib/_internal/vm/lib/core_patch.dart
@@ -133,10 +133,7 @@
   Iterable<T>? _yieldEachIterable;
 
   @override
-  T get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as T;
-  }
+  T get current => _current as T;
 
   _SyncIterator(this._moveNextFn);
 
diff --git a/sdk/lib/_internal/vm/lib/double.dart b/sdk/lib/_internal/vm/lib/double.dart
index 83b3262..7500050 100644
--- a/sdk/lib/_internal/vm/lib/double.dart
+++ b/sdk/lib/_internal/vm/lib/double.dart
@@ -6,36 +6,45 @@
 
 @pragma("vm:entry-point")
 class _Double implements double {
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   factory _Double.fromInteger(int value) native "Double_doubleFromInteger";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   int get hashCode native "Double_hashCode";
+  @pragma("vm:recognized", "asm-intrinsic")
   int get _identityHashCode native "Double_hashCode";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   @pragma("vm:never-inline")
   double operator +(num other) {
     return _add(other.toDouble());
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Double)
   double _add(double other) native "Double_add";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   @pragma("vm:never-inline")
   double operator -(num other) {
     return _sub(other.toDouble());
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Double)
   double _sub(double other) native "Double_sub";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   @pragma("vm:never-inline")
   double operator *(num other) {
     return _mul(other.toDouble());
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Double)
   double _mul(double other) native "Double_mul";
 
@@ -46,12 +55,14 @@
   @pragma("vm:non-nullable-result-type")
   int _trunc_div(double other) native "Double_trunc_div";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   @pragma("vm:never-inline")
   double operator /(num other) {
     return _div(other.toDouble());
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Double)
   double _div(double other) native "Double_div";
 
@@ -59,6 +70,7 @@
     return _modulo(other.toDouble());
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   double _modulo(double other) native "Double_modulo";
 
@@ -68,9 +80,11 @@
 
   double _remainder(double other) native "Double_remainder";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   double operator -() native "Double_flipSignBit";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator ==(Object other) {
@@ -82,12 +96,14 @@
   @pragma("vm:exact-result-type", bool)
   bool _equalToInteger(int other) native "Double_equalToInteger";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator <(num other) {
     return other > this;
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator >(num other) {
@@ -97,12 +113,14 @@
   @pragma("vm:exact-result-type", bool)
   bool _greaterThan(double other) native "Double_greaterThan";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator >=(num other) {
     return (this == other) || (this > other);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator <=(num other) {
@@ -117,6 +135,7 @@
     return new _Double.fromInteger(other)._sub(this);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double _mulFromInteger(int other) {
     return new _Double.fromInteger(other)._mul(this);
@@ -137,10 +156,13 @@
   bool _greaterThanFromInteger(int other)
       native "Double_greaterThanFromInteger";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool get isNegative native "Double_getIsNegative";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool get isInfinite native "Double_getIsInfinite";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool get isNaN native "Double_getIsNaN";
   bool get isFinite => !isInfinite && !isNaN; // Can be optimized.
@@ -162,12 +184,16 @@
   int ceil() => ceilToDouble().toInt();
   int truncate() => truncateToDouble().toInt();
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   double roundToDouble() native "Double_round";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   double floorToDouble() native "Double_floor";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   double ceilToDouble() native "Double_ceil";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Double)
   double truncateToDouble() native "Double_truncate";
 
@@ -188,6 +214,7 @@
     return this;
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int toInt() native "Double_toInt";
 
diff --git a/sdk/lib/_internal/vm/lib/errors_patch.dart b/sdk/lib/_internal/vm/lib/errors_patch.dart
index 75776ec..a33b803 100644
--- a/sdk/lib/_internal/vm/lib/errors_patch.dart
+++ b/sdk/lib/_internal/vm/lib/errors_patch.dart
@@ -44,8 +44,8 @@
 
   static _doThrowNew(int assertionStart, int assertionEnd, Object? message)
       native "AssertionError_throwNew";
-  static _doThrowNewSource(String failedAssertion, int line, int column, Object? message)
-      native "AssertionError_throwNewSource";
+  static _doThrowNewSource(String failedAssertion, int line, int column,
+      Object? message) native "AssertionError_throwNewSource";
 
   @pragma("vm:entry-point", "call")
   static _evaluateAssertion(condition) {
@@ -494,18 +494,3 @@
 
   toString() => "Error: field '$_name' is already initialized.";
 }
-
-class _LateInitializationError extends Error
-    implements LateInitializationError {
-  @pragma("vm:entry-point")
-  _LateInitializationError(this._name);
-
-  @pragma("vm:entry-point")
-  static void _throwNew(String name) {
-    throw _LateInitializationError(name);
-  }
-
-  String toString() => "LateInitializationError: $_name";
-
-  final String _name;
-}
diff --git a/sdk/lib/_internal/vm/lib/expando_patch.dart b/sdk/lib/_internal/vm/lib/expando_patch.dart
index 1d99cab..01cbe51 100644
--- a/sdk/lib/_internal/vm/lib/expando_patch.dart
+++ b/sdk/lib/_internal/vm/lib/expando_patch.dart
@@ -13,7 +13,7 @@
         _used = 0;
 
   static const _minSize = 8;
-  static final _deletedEntry = new _WeakProperty(null, null);
+  static final _deletedEntry = new _WeakProperty();
 
   @patch
   T? operator [](Object object) {
@@ -25,7 +25,7 @@
 
     while (wp != null) {
       if (identical(wp.key, object)) {
-        return wp.value;
+        return unsafeCast<T?>(wp.value);
       } else if (wp.key == null) {
         // This entry has been cleared by the GC.
         _data[idx] = _deletedEntry;
@@ -82,7 +82,10 @@
     }
 
     if (_used < _limit) {
-      _data[idx] = new _WeakProperty(object, value);
+      var ephemeron = new _WeakProperty();
+      ephemeron.key = object;
+      ephemeron.value = value;
+      _data[idx] = ephemeron;
       _used++;
       return;
     }
diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
index 02bc8c7..79fc3a3 100644
--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart
@@ -39,12 +39,13 @@
 
 int _sizeOf<T extends NativeType>() native "Ffi_sizeOf";
 
-// Implemented in the method recognizer.
+@pragma("vm:recognized", "other")
 Pointer<T> _fromAddress<T extends NativeType>(int ptr) native "Ffi_fromAddress";
 
 // The real implementation of this function (for interface calls) lives in
 // BuildFfiAsFunctionCall in the Kernel frontend. No calls can actually reach
 // this function.
+@pragma("vm:recognized", "other")
 DS _asFunctionInternal<DS extends Function, NS extends Function>(
     Pointer<NativeFunction<NS>> ptr) native "Ffi_asFunctionInternal";
 
@@ -67,6 +68,7 @@
 //
 // Function objects returned by this native method are not Dart instances,
 // so we need to use top type as a return type to avoid type check.
+@pragma("vm:recognized", "other")
 dynamic _nativeCallbackFunction<NS extends Function>(Function target,
     Object? exceptionalReturn) native "Ffi_nativeCallbackFunction";
 
@@ -92,8 +94,8 @@
         "Pointer.fromFunction cannot be called dynamically.");
   }
 
-  // Implemented in the method recognizer.
   @patch
+  @pragma("vm:recognized", "other")
   int get address native "Ffi_address";
 
   // For statically known types, this is rewired.
@@ -112,6 +114,7 @@
 
 /// Returns an integer encoding the ABI used for size and alignment
 /// calculations. See pkg/vm/lib/transformations/ffi.dart.
+@pragma("vm:recognized", "other")
 @pragma('vm:prefer-inline')
 int _abi()
     native "Recognized method: IR graph is built in the flow graph builder.";
@@ -122,67 +125,91 @@
 // allocating a Pointer with in elementAt/offsetBy. Allocating these pointers
 // and GCing new spaces takes a lot of the benchmark time. The next speedup is
 // getting rid of these allocations by inlining these functions.
+@pragma("vm:recognized", "other")
 int _loadInt8(Pointer pointer, int offsetInBytes) native "Ffi_loadInt8";
 
+@pragma("vm:recognized", "other")
 int _loadInt16(Pointer pointer, int offsetInBytes) native "Ffi_loadInt16";
 
+@pragma("vm:recognized", "other")
 int _loadInt32(Pointer pointer, int offsetInBytes) native "Ffi_loadInt32";
 
+@pragma("vm:recognized", "other")
 int _loadInt64(Pointer pointer, int offsetInBytes) native "Ffi_loadInt64";
 
+@pragma("vm:recognized", "other")
 int _loadUint8(Pointer pointer, int offsetInBytes) native "Ffi_loadUint8";
 
+@pragma("vm:recognized", "other")
 int _loadUint16(Pointer pointer, int offsetInBytes) native "Ffi_loadUint16";
 
+@pragma("vm:recognized", "other")
 int _loadUint32(Pointer pointer, int offsetInBytes) native "Ffi_loadUint32";
 
+@pragma("vm:recognized", "other")
 int _loadUint64(Pointer pointer, int offsetInBytes) native "Ffi_loadUint64";
 
+@pragma("vm:recognized", "other")
 int _loadIntPtr(Pointer pointer, int offsetInBytes) native "Ffi_loadIntPtr";
 
+@pragma("vm:recognized", "other")
 double _loadFloat(Pointer pointer, int offsetInBytes) native "Ffi_loadFloat";
 
+@pragma("vm:recognized", "other")
 double _loadDouble(Pointer pointer, int offsetInBytes) native "Ffi_loadDouble";
 
+@pragma("vm:recognized", "other")
 Pointer<S> _loadPointer<S extends NativeType>(
     Pointer pointer, int offsetInBytes) native "Ffi_loadPointer";
 
 S _loadStruct<S extends Struct>(Pointer<S> pointer, int index)
     native "Ffi_loadStruct";
 
+@pragma("vm:recognized", "other")
 void _storeInt8(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeInt8";
 
+@pragma("vm:recognized", "other")
 void _storeInt16(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeInt16";
 
+@pragma("vm:recognized", "other")
 void _storeInt32(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeInt32";
 
+@pragma("vm:recognized", "other")
 void _storeInt64(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeInt64";
 
+@pragma("vm:recognized", "other")
 void _storeUint8(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeUint8";
 
+@pragma("vm:recognized", "other")
 void _storeUint16(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeUint16";
 
+@pragma("vm:recognized", "other")
 void _storeUint32(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeUint32";
 
+@pragma("vm:recognized", "other")
 void _storeUint64(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeUint64";
 
+@pragma("vm:recognized", "other")
 void _storeIntPtr(Pointer pointer, int offsetInBytes, int value)
     native "Ffi_storeIntPtr";
 
+@pragma("vm:recognized", "other")
 void _storeFloat(Pointer pointer, int offsetInBytes, double value)
     native "Ffi_storeFloat";
 
+@pragma("vm:recognized", "other")
 void _storeDouble(Pointer pointer, int offsetInBytes, double value)
     native "Ffi_storeDouble";
 
+@pragma("vm:recognized", "other")
 void _storePointer<S extends NativeType>(Pointer pointer, int offsetInBytes,
     Pointer<S> value) native "Ffi_storePointer";
 
diff --git a/sdk/lib/_internal/vm/lib/growable_array.dart b/sdk/lib/_internal/vm/lib/growable_array.dart
index 0e63557..059454e 100644
--- a/sdk/lib/_internal/vm/lib/growable_array.dart
+++ b/sdk/lib/_internal/vm/lib/growable_array.dart
@@ -107,6 +107,11 @@
     return new _GrowableList<T>._withData(data);
   }
 
+  // Specialization of List.empty constructor for growable == true.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  @pragma("vm:prefer-inline")
+  factory _GrowableList.empty() => _GrowableList(0);
+
   // Specialization of List.filled constructor for growable == true.
   // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
   factory _GrowableList.filled(int length, T fill) {
@@ -130,14 +135,83 @@
     return result;
   }
 
+  // Specialization of List.of constructor for growable == true.
+  factory _GrowableList.of(Iterable<T> elements) {
+    if (elements is _GrowableList) {
+      return _GrowableList._ofGrowableList(unsafeCast(elements));
+    }
+    if (elements is _List) {
+      return _GrowableList._ofList(unsafeCast(elements));
+    }
+    if (elements is _ImmutableList) {
+      return _GrowableList._ofImmutableList(unsafeCast(elements));
+    }
+    if (elements is EfficientLengthIterable) {
+      return _GrowableList._ofEfficientLengthIterable(unsafeCast(elements));
+    }
+    return _GrowableList._ofOther(elements);
+  }
+
+  factory _GrowableList._ofList(_List<T> elements) {
+    final int length = elements.length;
+    final list = _GrowableList<T>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _GrowableList._ofGrowableList(_GrowableList<T> elements) {
+    final int length = elements.length;
+    final list = _GrowableList<T>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _GrowableList._ofImmutableList(_ImmutableList<T> elements) {
+    final int length = elements.length;
+    final list = _GrowableList<T>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _GrowableList._ofEfficientLengthIterable(
+      EfficientLengthIterable<T> elements) {
+    final int length = elements.length;
+    final list = _GrowableList<T>(length);
+    if (length > 0) {
+      int i = 0;
+      for (var element in elements) {
+        list[i++] = element;
+      }
+      if (i != length) throw ConcurrentModificationError(elements);
+    }
+    return list;
+  }
+
+  factory _GrowableList._ofOther(Iterable<T> elements) {
+    final list = _GrowableList<T>(0);
+    for (var elements in elements) {
+      list.add(elements);
+    }
+    return list;
+  }
+
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type",
       <dynamic>[_GrowableList, "result-type-uses-passed-type-arguments"])
   factory _GrowableList._withData(_List data) native "GrowableList_allocate";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get _capacity native "GrowableList_getCapacity";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "GrowableList_getLength";
@@ -170,16 +244,21 @@
     _setLength(new_length);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void _setLength(int new_length) native "GrowableList_setLength";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void _setData(_List array) native "GrowableList_setData";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   T operator [](int index) native "GrowableList_getIndexed";
 
+  @pragma("vm:recognized", "other")
   void operator []=(int index, T value) {
     _setIndexed(index, value);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void _setIndexed(int index, T? value) native "GrowableList_setIndexed";
 
   @pragma("vm:entry-point", "call")
@@ -187,7 +266,7 @@
   void add(T value) {
     var len = length;
     if (len == _capacity) {
-      _grow(_nextCapacity(len));
+      _growToNextCapacity();
     }
     _setLength(len + 1);
     this[len] = value;
@@ -203,6 +282,9 @@
       var cap = _capacity;
       // Pregrow if we know iterable.length.
       var iterLen = iterable.length;
+      if (iterLen == 0) {
+        return;
+      }
       var newLen = len + iterLen;
       if (newLen > cap) {
         do {
@@ -233,7 +315,7 @@
         if (this.length != newLen) throw new ConcurrentModificationError(this);
         len = newLen;
       }
-      _grow(_nextCapacity(_capacity));
+      _growToNextCapacity();
     } while (true);
   }
 
@@ -293,6 +375,14 @@
     _setData(newData);
   }
 
+  // This method is marked as never-inline to conserve code size.
+  // It is called in rare cases, but used in the add() which is
+  // used very often and always inlined.
+  @pragma("vm:never-inline")
+  void _growToNextCapacity() {
+    _grow(_nextCapacity(_capacity));
+  }
+
   void _shrink(int new_capacity, int new_length) {
     var newData = _allocateData(new_capacity);
     // This is a work-around for dartbug.com/30090. See the comment in _grow.
diff --git a/sdk/lib/_internal/vm/lib/identical_patch.dart b/sdk/lib/_internal/vm/lib/identical_patch.dart
index 4b57430..9a9ff56 100644
--- a/sdk/lib/_internal/vm/lib/identical_patch.dart
+++ b/sdk/lib/_internal/vm/lib/identical_patch.dart
@@ -5,6 +5,7 @@
 // part of "core_patch.dart";
 
 @patch
+@pragma("vm:recognized", "other")
 @pragma("vm:exact-result-type", bool)
 bool identical(Object? a, Object? b) native "Identical_comparison";
 
diff --git a/sdk/lib/_internal/vm/lib/immutable_map.dart b/sdk/lib/_internal/vm/lib/immutable_map.dart
index 7be9890..2f653f5 100644
--- a/sdk/lib/_internal/vm/lib/immutable_map.dart
+++ b/sdk/lib/_internal/vm/lib/immutable_map.dart
@@ -173,10 +173,7 @@
     return false;
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 }
 
 class _ImmutableMapValueIterator<E> implements Iterator<E> {
@@ -197,10 +194,7 @@
     return false;
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 }
 
 class _ImmutableMapEntryIterator<K, V> implements Iterator<MapEntry<K, V>> {
@@ -222,8 +216,5 @@
     return false;
   }
 
-  MapEntry<K, V> get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as MapEntry<K, V>;
-  }
+  MapEntry<K, V> get current => _current as MapEntry<K, V>;
 }
diff --git a/sdk/lib/_internal/vm/lib/integers.dart b/sdk/lib/_internal/vm/lib/integers.dart
index 9fd3a76..3ce3af5 100644
--- a/sdk/lib/_internal/vm/lib/integers.dart
+++ b/sdk/lib/_internal/vm/lib/integers.dart
@@ -5,16 +5,20 @@
 // part of "core_patch.dart";
 
 abstract class _IntegerImplementation implements int {
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   num operator +(num other) => other._addFromInteger(this);
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   num operator -(num other) => other._subFromInteger(this);
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   num operator *(num other) => other._mulFromInteger(this);
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator ~/(num other) {
@@ -36,6 +40,7 @@
     return other._moduloFromInteger(this);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator -() {
@@ -44,12 +49,15 @@
     return unsafeCast<int>(0 - this);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator &(int other) => other._bitAndFromInteger(this);
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator |(int other) => other._bitOrFromInteger(this);
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator ^(int other) => other._bitXorFromInteger(this);
@@ -60,24 +68,31 @@
 
   @pragma("vm:non-nullable-result-type")
   int _bitAndFromSmi(_Smi other) native "Integer_bitAndFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _bitAndFromInteger(int other) native "Integer_bitAndFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _bitOrFromInteger(int other) native "Integer_bitOrFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _bitXorFromInteger(int other) native "Integer_bitXorFromInteger";
   @pragma("vm:non-nullable-result-type")
   int _shrFromInteger(int other) native "Integer_shrFromInteger";
   @pragma("vm:non-nullable-result-type")
   int _shlFromInteger(int other) native "Integer_shlFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _addFromInteger(int other) native "Integer_addFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _subFromInteger(int other) native "Integer_subFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _mulFromInteger(int other) native "Integer_mulFromInteger";
   @pragma("vm:non-nullable-result-type")
   int _truncDivFromInteger(int other) native "Integer_truncDivFromInteger";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   int _moduloFromInteger(int other) native "Integer_moduloFromInteger";
   int _remainderFromInteger(int other) {
@@ -86,41 +101,49 @@
     return unsafeCast<int>(other - (other ~/ this) * this);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator >>(int other) => other._shrFromInteger(this);
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator <<(int other) => other._shlFromInteger(this);
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator <(num other) {
     return other > this;
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator >(num other) {
     return other._greaterThanFromInteger(this);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator >=(num other) {
     return (this == other) || (this > other);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator <=(num other) {
     return (this == other) || (this < other);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool _greaterThanFromInteger(int other)
       native "Integer_greaterThanFromInteger";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:never-inline")
   bool operator ==(Object other) {
@@ -130,6 +153,7 @@
     return false;
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool _equalToInteger(int other) native "Integer_equalToInteger";
   int abs() {
@@ -137,7 +161,11 @@
   }
 
   int get sign {
-    return (this > 0) ? 1 : (this < 0) ? -1 : 0;
+    return (this > 0)
+        ? 1
+        : (this < 0)
+            ? -1
+            : 0;
   }
 
   bool get isEven => ((this & 1) == 0);
@@ -268,6 +296,7 @@
     return this;
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Double)
   double toDouble() {
     return new _Double.fromInteger(this);
@@ -515,13 +544,16 @@
 
   int get hashCode => this;
   int get _identityHashCode => this;
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator ~() native "Smi_bitNegate";
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get bitLength native "Smi_bitLength";
 
   int operator &(int other) => other._bitAndFromSmi(this);
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _bitAndFromSmi(_Smi other) native "Smi_bitAndFromSmi";
 
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index ad5f5b7..f1d22c9 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -36,19 +36,19 @@
     native "Internal_extractTypeArguments";
 
 /// The returned string is a [_OneByteString] with uninitialized content.
-@pragma("vm:entry-point", "call")
+@pragma("vm:recognized", "asm-intrinsic")
 String allocateOneByteString(int length)
     native "Internal_allocateOneByteString";
 
 /// The [string] must be a [_OneByteString]. The [index] must be valid.
-@pragma("vm:entry-point", "call")
+@pragma("vm:recognized", "asm-intrinsic")
 void writeIntoOneByteString(String string, int index, int codePoint)
     native "Internal_writeIntoOneByteString";
 
-/// This function is recognized by the VM and compiled into specialized code.
 /// It is assumed that [from] is a native [Uint8List] class and [to] is a
 /// [_OneByteString]. The [fromStart] and [toStart] indices together with the
 /// [length] must specify ranges within the bounds of the list / string.
+@pragma("vm:recognized", "other")
 @pragma("vm:prefer-inline")
 void copyRangeFromUint8ListToOneByteString(
     Uint8List from, String to, int fromStart, int toStart, int length) {
@@ -58,12 +58,12 @@
 }
 
 /// The returned string is a [_TwoByteString] with uninitialized content.
-@pragma("vm:entry-point", "call")
+@pragma("vm:recognized", "asm-intrinsic")
 String allocateTwoByteString(int length)
     native "Internal_allocateTwoByteString";
 
 /// The [string] must be a [_TwoByteString]. The [index] must be valid.
-@pragma("vm:entry-point", "call")
+@pragma("vm:recognized", "asm-intrinsic")
 void writeIntoTwoByteString(String string, int index, int codePoint)
     native "Internal_writeIntoTwoByteString";
 
@@ -106,6 +106,7 @@
 
 bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
 
+@pragma("vm:recognized", "other")
 @pragma("vm:entry-point", "call")
 @pragma("vm:exact-result-type", bool)
 @pragma("vm:prefer-inline")
@@ -163,7 +164,7 @@
 
 // This function can be used to keep an object alive til that point.
 //
-// This is implemented by a recognized method.
+@pragma("vm:recognized", "other")
 @pragma('vm:prefer-inline')
 void reachabilityFence(Object object) native "Internal_reachabilityFence";
 
@@ -194,3 +195,26 @@
 
 @patch
 bool isSentinel(dynamic value) => throw UnsupportedError('isSentinel');
+
+@patch
+class LateError {
+  @pragma("vm:entry-point")
+  static _throwFieldAlreadyInitialized(String fieldName) {
+    throw new LateError.fieldAI(fieldName);
+  }
+
+  @pragma("vm:entry-point")
+  static _throwLocalNotInitialized(String localName) {
+    throw new LateError.localNI(localName);
+  }
+
+  @pragma("vm:entry-point")
+  static _throwLocalAlreadyInitialized(String localName) {
+    throw new LateError.localAI(localName);
+  }
+
+  @pragma("vm:entry-point")
+  static _throwLocalAssignedDuringInitialization(String localName) {
+    throw new LateError.localADI(localName);
+  }
+}
diff --git a/sdk/lib/_internal/vm/lib/isolate_patch.dart b/sdk/lib/_internal/vm/lib/isolate_patch.dart
index 97e90ce..34ce5e4 100644
--- a/sdk/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/vm/lib/isolate_patch.dart
@@ -188,6 +188,12 @@
   // Call into the VM to close the VM maintained mappings.
   _closeInternal() native "RawReceivePortImpl_closeInternal";
 
+  // Set this port as active or inactive in the VM. If inactive, this port
+  // will not be considered live even if it hasn't been explicitly closed.
+  // TODO(bkonyi): determine if we want to expose this as an option through
+  // RawReceivePort.
+  _setActive(bool active) native "RawReceivePortImpl_setActive";
+
   void set handler(Function? value) {
     final id = this._get_id();
     if (!_portMap.containsKey(id)) {
@@ -234,20 +240,12 @@
 typedef _BinaryFunction(Never args, Never message);
 
 /**
- * Takes the real entry point as argument and invokes it with the
- * initial message.  Defers execution of the entry point until the
- * isolate is in the message loop.
+ * Takes the real entry point as argument and schedules it to run in the message
+ * queue.
  */
 @pragma("vm:entry-point", "call")
 void _startMainIsolate(Function entryPoint, List<String>? args) {
-  _startIsolate(
-      null, // no parent port
-      entryPoint,
-      args,
-      null, // no message
-      true, // isSpawnUri
-      null, // no control port
-      null); // no capabilities
+  _delayEntrypointInvocation(entryPoint, args, null, true);
 }
 
 /**
@@ -262,47 +260,21 @@
 }
 
 /**
- * Takes the real entry point as argument and invokes it with the initial
- * message.
+ * Takes the real entry point as argument and schedules it to run in the message
+ * queue.
  */
 @pragma("vm:entry-point", "call")
 void _startIsolate(
-    SendPort? parentPort,
-    Function entryPoint,
-    List<String>? args,
-    Object? message,
-    bool isSpawnUri,
-    RawReceivePort? controlPort,
-    List? capabilities) {
-  // The control port (aka the main isolate port) does not handle any messages.
-  if (controlPort != null) {
-    controlPort.handler = (_) {}; // Nobody home on the control port.
+    Function entryPoint, List<String>? args, Object? message, bool isSpawnUri) {
+  _delayEntrypointInvocation(entryPoint, args, message, isSpawnUri);
+}
 
-    if (parentPort != null) {
-      // Build a message to our parent isolate providing access to the
-      // current isolate's control port and capabilities.
-      //
-      // TODO(floitsch): Send an error message if we can't find the entry point.
-      final readyMessage = List<Object?>.filled(2, null);
-      readyMessage[0] = controlPort.sendPort;
-      readyMessage[1] = capabilities;
-
-      // Out of an excess of paranoia we clear the capabilities from the
-      // stack.  Not really necessary.
-      capabilities = null;
-      parentPort.send(readyMessage);
-    }
-  }
-  assert(capabilities == null);
-
-  // Delay all user code handling to the next run of the message loop. This
-  // allows us to intercept certain conditions in the event dispatch, such as
-  // starting in paused state.
-  RawReceivePort port = new RawReceivePort();
+void _delayEntrypointInvocation(Function entryPoint, List<String>? args,
+    Object? message, bool allowZeroOneOrTwoArgs) {
+  final port = RawReceivePort();
   port.handler = (_) {
     port.close();
-
-    if (isSpawnUri) {
+    if (allowZeroOneOrTwoArgs) {
       if (entryPoint is _BinaryFunction) {
         (entryPoint as dynamic)(args, message);
       } else if (entryPoint is _UnaryFunction) {
@@ -314,7 +286,6 @@
       entryPoint(message);
     }
   };
-  // Make sure the message handler is triggered.
   port.sendPort.send(null);
 }
 
@@ -385,7 +356,8 @@
     }
 
     const bool newIsolateGroup = false;
-    final RawReceivePort readyPort = new RawReceivePort();
+    final RawReceivePort readyPort =
+        new RawReceivePort(null, 'Isolate.spawn ready');
     try {
       spawnFunction(
           readyPort.sendPort,
@@ -462,7 +434,8 @@
     // The VM will invoke [_startIsolate] and not `main`.
     final packageConfigString = packageConfig?.toString();
 
-    final RawReceivePort readyPort = new RawReceivePort();
+    final RawReceivePort readyPort =
+        new RawReceivePort(null, 'Isolate.spawnUri ready');
     try {
       _spawnUri(
           readyPort.sendPort,
diff --git a/sdk/lib/_internal/vm/lib/math_patch.dart b/sdk/lib/_internal/vm/lib/math_patch.dart
index b41daad..0e384ca 100644
--- a/sdk/lib/_internal/vm/lib/math_patch.dart
+++ b/sdk/lib/_internal/vm/lib/math_patch.dart
@@ -14,6 +14,7 @@
 /// There are no parts of this patch library.
 
 @patch
+@pragma("vm:recognized", "other")
 @pragma("vm:prefer-inline")
 T min<T extends num>(T a, T b) {
   if (a > b) return b;
@@ -38,6 +39,7 @@
 }
 
 @patch
+@pragma("vm:recognized", "other")
 @pragma("vm:prefer-inline")
 T max<T extends num>(T a, T b) {
   if (a > b) return a;
@@ -74,6 +76,7 @@
   return _doublePow(x.toDouble(), exponent.toDouble());
 }
 
+@pragma("vm:recognized", "other")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 double _doublePow(double base, double exponent) {
   if (exponent == 0.0) {
@@ -100,6 +103,7 @@
 
 double _pow(double base, double exponent) native "Math_doublePow";
 
+@pragma("vm:recognized", "other")
 int _intPow(int base, int exponent) {
   // Exponentiation by squaring.
   int result = 1;
@@ -117,34 +121,42 @@
 }
 
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double sin(num radians) => _sin(radians.toDouble());
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double cos(num radians) => _cos(radians.toDouble());
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double tan(num radians) => _tan(radians.toDouble());
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double acos(num x) => _acos(x.toDouble());
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double asin(num x) => _asin(x.toDouble());
 @patch
+@pragma("vm:recognized", "graph-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double atan(num x) => _atan(x.toDouble());
 @patch
+@pragma("vm:recognized", "asm-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Double")
 @pragma("vm:never-inline")
 double sqrt(num x) => _sqrt(x.toDouble());
@@ -208,6 +220,7 @@
   // This is a native to prevent 64-bit operations in Dart, which
   // fail with --throw_on_javascript_int_overflow.
   // TODO(regis): Implement in Dart and remove Random_nextState in math.cc.
+  @pragma("vm:recognized", "asm-intrinsic")
   void _nextState() native "Random_nextState";
 
   int nextInt(int max) {
diff --git a/sdk/lib/_internal/vm/lib/mirrors_impl.dart b/sdk/lib/_internal/vm/lib/mirrors_impl.dart
index 712d2c8..acd95e1 100644
--- a/sdk/lib/_internal/vm/lib/mirrors_impl.dart
+++ b/sdk/lib/_internal/vm/lib/mirrors_impl.dart
@@ -703,11 +703,11 @@
       throw new ArgumentError.notNull('other');
     }
     ClassMirror otherDeclaration = other.originalDeclaration as ClassMirror;
-    ClassMirror c = this;
+    ClassMirror? c = this;
     while (c != null) {
       c = c.originalDeclaration as ClassMirror;
       if (c == otherDeclaration) return true;
-      c = c.superclass as ClassMirror;
+      c = c.superclass as ClassMirror?;
     }
     return false;
   }
diff --git a/sdk/lib/_internal/vm/lib/object_patch.dart b/sdk/lib/_internal/vm/lib/object_patch.dart
index e862e5c..fe23069 100644
--- a/sdk/lib/_internal/vm/lib/object_patch.dart
+++ b/sdk/lib/_internal/vm/lib/object_patch.dart
@@ -4,8 +4,10 @@
 
 // part of "core_patch.dart";
 
+@pragma("vm:recognized", "asm-intrinsic")
 @pragma("vm:exact-result-type", "dart:core#_Smi")
 int _getHash(obj) native "Object_getHash";
+@pragma("vm:recognized", "asm-intrinsic")
 void _setHash(obj, hash) native "Object_setHash";
 
 @patch
@@ -13,6 +15,7 @@
 class Object {
   // The VM has its own implementation of equals.
   @patch
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   @pragma("vm:prefer-inline")
   bool operator ==(Object other) native "Object_equals";
@@ -52,9 +55,11 @@
   }
 
   @patch
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Type")
   Type get runtimeType native "Object_runtimeType";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:entry-point", "call")
   @pragma("vm:exact-result-type", bool)
   static bool _haveSameRuntimeType(a, b) native "Object_haveSameRuntimeType";
diff --git a/sdk/lib/_internal/vm/lib/profiler.dart b/sdk/lib/_internal/vm/lib/profiler.dart
index 745eaa5..812916e 100644
--- a/sdk/lib/_internal/vm/lib/profiler.dart
+++ b/sdk/lib/_internal/vm/lib/profiler.dart
@@ -18,11 +18,14 @@
 class _UserTag implements UserTag {
   factory _UserTag(String label) native "UserTag_new";
   String get label native "UserTag_label";
+  @pragma("vm:recognized", "asm-intrinsic")
   UserTag makeCurrent() native "UserTag_makeCurrent";
 }
 
 @patch
 UserTag getCurrentTag() => _getCurrentTag();
+@pragma("vm:recognized", "asm-intrinsic")
 UserTag _getCurrentTag() native "Profiler_getCurrentTag";
 
+@pragma("vm:recognized", "asm-intrinsic")
 UserTag _getDefaultTag() native "UserTag_defaultTag";
diff --git a/sdk/lib/_internal/vm/lib/regexp_patch.dart b/sdk/lib/_internal/vm/lib/regexp_patch.dart
index 153080b..73e38a1 100644
--- a/sdk/lib/_internal/vm/lib/regexp_patch.dart
+++ b/sdk/lib/_internal/vm/lib/regexp_patch.dart
@@ -350,9 +350,11 @@
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   ];
 
+  @pragma("vm:recognized", "asm-intrinsic")
   List<int>? _ExecuteMatch(String str, int start_index)
       native "RegExp_ExecuteMatch";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   List<int>? _ExecuteMatchSticky(String str, int start_index)
       native "RegExp_ExecuteMatchSticky";
 }
diff --git a/sdk/lib/_internal/vm/lib/string_patch.dart b/sdk/lib/_internal/vm/lib/string_patch.dart
index 5d6612d..a8b949a 100644
--- a/sdk/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk/lib/_internal/vm/lib/string_patch.dart
@@ -94,9 +94,11 @@
     throw new UnsupportedError("_StringBase can't be instaniated");
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get hashCode native "String_getHashCode";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get _identityHashCode native "String_getHashCode";
 
@@ -249,14 +251,17 @@
   static String _createFromCodePoints(List<int> codePoints, int start, int end)
       native "StringBase_createFromCodePoints";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   String operator [](int index) native "String_charAt";
 
   int codeUnitAt(int index); // Implemented in the subclasses.
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "String_getLength";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool get isEmpty {
     return this.length == 0;
@@ -306,6 +311,7 @@
     return 0;
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool _substringMatches(int start, String other) {
     if (other.isEmpty) return true;
@@ -838,6 +844,7 @@
    * into a result string.
    * Modifies the input list if it contains non-`String` values.
    */
+  @pragma("vm:recognized", "other")
   @pragma("vm:entry-point", "call")
   static String _interpolate(final List values) {
     final numValues = values.length;
@@ -955,9 +962,11 @@
     throw "Unreachable";
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get hashCode native "String_getHashCode";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
@@ -965,11 +974,13 @@
     return _StringBase._isOneByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     return super == other;
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", _OneByteString)
   String _substringUncheckedNative(int startIndex, int endIndex)
       native "OneByteString_substringUnchecked";
@@ -1291,9 +1302,11 @@
     return _StringBase._isTwoByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     return super == other;
@@ -1310,6 +1323,7 @@
     return _StringBase._isOneByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
@@ -1328,6 +1342,7 @@
     return _StringBase._isTwoByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
@@ -1409,8 +1424,5 @@
     return true;
   }
 
-  Match get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as Match;
-  }
+  Match get current => _current as Match;
 }
diff --git a/sdk/lib/_internal/vm/lib/timer_impl.dart b/sdk/lib/_internal/vm/lib/timer_impl.dart
index db626c2..ac1939d 100644
--- a/sdk/lib/_internal/vm/lib/timer_impl.dart
+++ b/sdk/lib/_internal/vm/lib/timer_impl.dart
@@ -138,6 +138,7 @@
 
   static RawReceivePort? _receivePort;
   static SendPort? _sendPort;
+  static bool _receivePortActive = false;
   static int _scheduledWakeupTime = 0;
 
   static bool _handlingCallbacks = false;
@@ -262,12 +263,10 @@
   // Enqueue one message for each zero timer. To be able to distinguish from
   // EventHandler messages we send a _ZERO_EVENT instead of a _TIMEOUT_EVENT.
   static void _notifyZeroHandler() {
-    var port = _sendPort;
-    if (port == null) {
-      port = _createTimerHandler();
-      _sendPort = port;
+    if (!_receivePortActive) {
+      _createTimerHandler();
     }
-    port.send(_ZERO_EVENT);
+    _sendPort!.send(_ZERO_EVENT);
   }
 
   // Handle the notification of a zero timer. Make sure to also execute non-zero
@@ -314,7 +313,6 @@
       _cancelWakeup();
       return;
     }
-
     // Only send a message if the requested wakeup time differs from the
     // already scheduled wakeup time.
     var wakeupTime = _heap.first._wakeupTime;
@@ -433,12 +431,10 @@
 
   // Tell the event handler to wake this isolate at a specific time.
   static void _scheduleWakeup(int wakeupTime) {
-    var port = _sendPort;
-    if (port == null) {
-      port = _createTimerHandler();
-      _sendPort = port;
+    if (!_receivePortActive) {
+      _createTimerHandler();
     }
-    VMLibraryHooks.eventHandlerSendData(null, port, wakeupTime);
+    VMLibraryHooks.eventHandlerSendData(null, _sendPort, wakeupTime);
     _scheduledWakeupTime = wakeupTime;
   }
 
@@ -452,22 +448,23 @@
 
   // Create a receive port and register a message handler for the timer
   // events.
-  static SendPort _createTimerHandler() {
-    assert(_receivePort == null);
-    assert(_sendPort == null);
-    final port = new RawReceivePort(_handleMessage);
-    final sendPort = port.sendPort;
-    _receivePort = port;
-    _sendPort = sendPort;
-    _scheduledWakeupTime = 0;
-    return sendPort;
+  static void _createTimerHandler() {
+    if (_receivePort == null) {
+      assert(_receivePort == null);
+      assert(_sendPort == null);
+      _receivePort = RawReceivePort(_handleMessage, 'Timer');
+      _sendPort = _receivePort!.sendPort;
+      _scheduledWakeupTime = 0;
+    } else {
+      (_receivePort as _RawReceivePortImpl)._setActive(true);
+    }
+    _receivePortActive = true;
   }
 
   static void _shutdownTimerHandler() {
-    _sendPort = null;
     _scheduledWakeupTime = 0;
-    _receivePort!.close();
-    _receivePort = null;
+    (_receivePort as _RawReceivePortImpl)._setActive(false);
+    _receivePortActive = false;
   }
 
   // The Timer factory registered with the dart:async library by the embedder.
diff --git a/sdk/lib/_internal/vm/lib/type_patch.dart b/sdk/lib/_internal/vm/lib/type_patch.dart
index 1b8f3c1..52be775 100644
--- a/sdk/lib/_internal/vm/lib/type_patch.dart
+++ b/sdk/lib/_internal/vm/lib/type_patch.dart
@@ -18,9 +18,11 @@
     throw "Unreachable";
   }
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get hashCode native "Type_getHashCode";
 
+  @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", bool)
   bool operator ==(other) native "Type_equality";
 }
diff --git a/sdk/lib/_internal/vm/lib/typed_data_patch.dart b/sdk/lib/_internal/vm/lib/typed_data_patch.dart
index ccd3183..d608ab6 100644
--- a/sdk/lib/_internal/vm/lib/typed_data_patch.dart
+++ b/sdk/lib/_internal/vm/lib/typed_data_patch.dart
@@ -36,6 +36,7 @@
 @patch
 class ByteData implements TypedData {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:entry-point")
   factory ByteData(int length) {
     final list = new Uint8List(length) as _TypedList;
@@ -2066,57 +2067,82 @@
 
   // Methods implementing the collection interface.
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "TypedData_length";
 
   // Internal utility methods.
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getInt8(int offsetInBytes) native "TypedData_GetInt8";
+  @pragma("vm:recognized", "other")
   void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getUint8(int offsetInBytes) native "TypedData_GetUint8";
+  @pragma("vm:recognized", "other")
   void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getInt16(int offsetInBytes) native "TypedData_GetInt16";
+  @pragma("vm:recognized", "other")
   void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getUint16(int offsetInBytes) native "TypedData_GetUint16";
+  @pragma("vm:recognized", "other")
   void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16";
 
+  @pragma("vm:recognized", "other")
   int _getInt32(int offsetInBytes) native "TypedData_GetInt32";
+  @pragma("vm:recognized", "other")
   void _setInt32(int offsetInBytes, int value) native "TypedData_SetInt32";
 
+  @pragma("vm:recognized", "other")
   int _getUint32(int offsetInBytes) native "TypedData_GetUint32";
+  @pragma("vm:recognized", "other")
   void _setUint32(int offsetInBytes, int value) native "TypedData_SetUint32";
 
+  @pragma("vm:recognized", "other")
   int _getInt64(int offsetInBytes) native "TypedData_GetInt64";
+  @pragma("vm:recognized", "other")
   void _setInt64(int offsetInBytes, int value) native "TypedData_SetInt64";
 
+  @pragma("vm:recognized", "other")
   int _getUint64(int offsetInBytes) native "TypedData_GetUint64";
+  @pragma("vm:recognized", "other")
   void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32";
+  @pragma("vm:recognized", "other")
   void _setFloat32(int offsetInBytes, double value)
       native "TypedData_SetFloat32";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64";
+  @pragma("vm:recognized", "other")
   void _setFloat64(int offsetInBytes, double value)
       native "TypedData_SetFloat64";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 _getFloat32x4(int offsetInBytes) native "TypedData_GetFloat32x4";
+  @pragma("vm:recognized", "other")
   void _setFloat32x4(int offsetInBytes, Float32x4 value)
       native "TypedData_SetFloat32x4";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _getInt32x4(int offsetInBytes) native "TypedData_GetInt32x4";
+  @pragma("vm:recognized", "other")
   void _setInt32x4(int offsetInBytes, Int32x4 value)
       native "TypedData_SetInt32x4";
 
@@ -2145,6 +2171,7 @@
 @patch
 class Int8List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int8List)
   @pragma("vm:prefer-inline")
   factory Int8List(int length) native "TypedData_Int8Array_new";
@@ -2165,6 +2192,7 @@
   }
 
   // Method(s) implementing List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2173,6 +2201,7 @@
     return _getInt8(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2194,6 +2223,7 @@
 @patch
 class Uint8List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint8List)
   @pragma("vm:prefer-inline")
   factory Uint8List(int length) native "TypedData_Uint8Array_new";
@@ -2214,6 +2244,7 @@
   }
 
   // Methods implementing List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2222,6 +2253,7 @@
     return _getUint8(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2243,6 +2275,7 @@
 @patch
 class Uint8ClampedList {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint8ClampedList)
   @pragma("vm:prefer-inline")
   factory Uint8ClampedList(int length) native "TypedData_Uint8ClampedArray_new";
@@ -2263,6 +2296,7 @@
   }
 
   // Methods implementing List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2271,6 +2305,7 @@
     return _getUint8(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2292,6 +2327,7 @@
 @patch
 class Int16List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int16List)
   @pragma("vm:prefer-inline")
   factory Int16List(int length) native "TypedData_Int16Array_new";
@@ -2312,6 +2348,7 @@
   }
 
   // Method(s) implementing List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2320,6 +2357,7 @@
     return _getIndexedInt16(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2361,6 +2399,7 @@
 @patch
 class Uint16List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint16List)
   @pragma("vm:prefer-inline")
   factory Uint16List(int length) native "TypedData_Uint16Array_new";
@@ -2381,6 +2420,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2389,6 +2429,7 @@
     return _getIndexedUint16(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2430,6 +2471,7 @@
 @patch
 class Int32List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32List)
   @pragma("vm:prefer-inline")
   factory Int32List(int length) native "TypedData_Int32Array_new";
@@ -2450,6 +2492,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2457,6 +2500,7 @@
     return _getIndexedInt32(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2486,6 +2530,7 @@
 @patch
 class Uint32List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint32List)
   @pragma("vm:prefer-inline")
   factory Uint32List(int length) native "TypedData_Uint32Array_new";
@@ -2506,6 +2551,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2513,6 +2559,7 @@
     return _getIndexedUint32(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2542,6 +2589,7 @@
 @patch
 class Int64List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int64List)
   @pragma("vm:prefer-inline")
   factory Int64List(int length) native "TypedData_Int64Array_new";
@@ -2562,6 +2610,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2569,6 +2618,7 @@
     return _getIndexedInt64(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2598,6 +2648,7 @@
 @patch
 class Uint64List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint64List)
   @pragma("vm:prefer-inline")
   factory Uint64List(int length) native "TypedData_Uint64Array_new";
@@ -2618,6 +2669,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2625,6 +2677,7 @@
     return _getIndexedUint64(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2654,6 +2707,7 @@
 @patch
 class Float32List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32List)
   @pragma("vm:prefer-inline")
   factory Float32List(int length) native "TypedData_Float32Array_new";
@@ -2674,6 +2728,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2682,6 +2737,7 @@
     return _getIndexedFloat32(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, double value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2711,6 +2767,7 @@
 @patch
 class Float64List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64List)
   @pragma("vm:prefer-inline")
   factory Float64List(int length) native "TypedData_Float64Array_new";
@@ -2731,6 +2788,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2739,6 +2797,7 @@
     return _getIndexedFloat64(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, double value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2768,6 +2827,7 @@
 @patch
 class Float32x4List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4List)
   @pragma("vm:prefer-inline")
   factory Float32x4List(int length) native "TypedData_Float32x4Array_new";
@@ -2787,6 +2847,7 @@
     throw "Unreachable";
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2795,6 +2856,7 @@
     return _getIndexedFloat32x4(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, Float32x4 value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2824,6 +2886,7 @@
 @patch
 class Int32x4List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4List)
   @pragma("vm:prefer-inline")
   factory Int32x4List(int length) native "TypedData_Int32x4Array_new";
@@ -2843,6 +2906,7 @@
     throw "Unreachable";
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2851,6 +2915,7 @@
     return _getIndexedInt32x4(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, Int32x4 value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2880,6 +2945,7 @@
 @patch
 class Float64x2List {
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2List)
   @pragma("vm:prefer-inline")
   factory Float64x2List(int length) native "TypedData_Float64x2Array_new";
@@ -2899,6 +2965,7 @@
     throw "Unreachable";
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2907,6 +2974,7 @@
     return _getIndexedFloat64x2(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, Float64x2 value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2976,6 +3044,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -2984,6 +3053,7 @@
     return _getUint8(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -3011,6 +3081,7 @@
   }
 
   // Method(s) implementing the List interface.
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
@@ -3019,6 +3090,7 @@
     return _getUint8(index);
   }
 
+  @pragma("vm:recognized", "graph-intrinsic")
   void operator []=(int index, int value) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -3511,6 +3583,7 @@
     return _Float32x4FromDoubles(x, y, z, w);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   static _Float32x4 _Float32x4FromDoubles(
       double x, double y, double z, double w) native "Float32x4_fromDoubles";
@@ -3522,65 +3595,90 @@
     return _Float32x4Splat(v);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   static _Float32x4 _Float32x4Splat(double v) native "Float32x4_splat";
 
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.zero() native "Float32x4_zero";
 
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.fromInt32x4Bits(Int32x4 x)
       native "Float32x4_fromInt32x4Bits";
 
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.fromFloat64x2(Float64x2 v) native "Float32x4_fromFloat64x2";
 }
 
 @pragma("vm:entry-point")
 class _Float32x4 implements Float32x4 {
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator +(Float32x4 other) native "Float32x4_add";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator -() native "Float32x4_negate";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator -(Float32x4 other) native "Float32x4_sub";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator *(Float32x4 other) native "Float32x4_mul";
+  @pragma("vm:recognized", "graph-intrinsic")
   Float32x4 operator /(Float32x4 other) native "Float32x4_div";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 lessThan(Float32x4 other) native "Float32x4_cmplt";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 lessThanOrEqual(Float32x4 other) native "Float32x4_cmplte";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 greaterThan(Float32x4 other) native "Float32x4_cmpgt";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 greaterThanOrEqual(Float32x4 other) native "Float32x4_cmpgte";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 equal(Float32x4 other) native "Float32x4_cmpequal";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 notEqual(Float32x4 other) native "Float32x4_cmpnequal";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 scale(double s) native "Float32x4_scale";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 abs() native "Float32x4_abs";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit)
       native "Float32x4_clamp";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get x native "Float32x4_getX";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get y native "Float32x4_getY";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get z native "Float32x4_getZ";
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get w native "Float32x4_getW";
+  @pragma("vm:recognized", "other")
   int get signMask native "Float32x4_getSignMask";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 shuffle(int mask) native "Float32x4_shuffle";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix";
 
@@ -3590,6 +3688,7 @@
     return _withX(x);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 _withX(double x) native "Float32x4_setX";
 
@@ -3599,6 +3698,7 @@
     return _withY(y);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 _withY(double y) native "Float32x4_setY";
 
@@ -3608,6 +3708,7 @@
     return _withZ(z);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 _withZ(double z) native "Float32x4_setZ";
 
@@ -3617,17 +3718,23 @@
     return _withW(w);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 _withW(double w) native "Float32x4_setW";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 min(Float32x4 other) native "Float32x4_min";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 max(Float32x4 other) native "Float32x4_max";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 sqrt() native "Float32x4_sqrt";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 reciprocal() native "Float32x4_reciprocal";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 reciprocalSqrt() native "Float32x4_reciprocalSqrt";
 }
@@ -3644,6 +3751,7 @@
     return _Int32x4FromInts(x, y, z, w);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   static _Int32x4 _Int32x4FromInts(int x, int y, int z, int w)
       native "Int32x4_fromInts";
@@ -3658,11 +3766,13 @@
     return _Int32x4FromBools(x, y, z, w);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   static _Int32x4 _Int32x4FromBools(bool x, bool y, bool z, bool w)
       native "Int32x4_fromBools";
 
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   factory Int32x4.fromFloat32x4Bits(Float32x4 x)
       native "Int32x4_fromFloat32x4Bits";
@@ -3679,9 +3789,12 @@
   int get y native "Int32x4_getY";
   int get z native "Int32x4_getZ";
   int get w native "Int32x4_getW";
+  @pragma("vm:recognized", "other")
   int get signMask native "Int32x4_getSignMask";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 shuffle(int mask) native "Int32x4_shuffle";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix";
 
@@ -3721,12 +3834,16 @@
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _withW(int w) native "Int32x4_setW";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", bool)
   bool get flagX native "Int32x4_getFlagX";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", bool)
   bool get flagY native "Int32x4_getFlagY";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", bool)
   bool get flagZ native "Int32x4_getFlagZ";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", bool)
   bool get flagW native "Int32x4_getFlagW";
 
@@ -3736,6 +3853,7 @@
     return _withFlagX(x);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _withFlagX(bool x) native "Int32x4_setFlagX";
 
@@ -3745,6 +3863,7 @@
     return _withFlagY(y);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _withFlagY(bool y) native "Int32x4_setFlagY";
 
@@ -3754,6 +3873,7 @@
     return _withFlagZ(z);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _withFlagZ(bool z) native "Int32x4_setFlagZ";
 
@@ -3763,9 +3883,11 @@
     return _withFlagW(w);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _withFlagW(bool w) native "Int32x4_setFlagW";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 select(Float32x4 trueValue, Float32x4 falseValue)
       native "Int32x4_select";
@@ -3781,6 +3903,7 @@
     return _Float64x2FromDoubles(x, y);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   static _Float64x2 _Float64x2FromDoubles(double x, double y)
       native "Float64x2_fromDoubles";
@@ -3792,36 +3915,49 @@
     return _Float64x2Splat(v);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   static _Float64x2 _Float64x2Splat(double v) native "Float64x2_splat";
 
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   factory Float64x2.zero() native "Float64x2_zero";
 
   @patch
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   factory Float64x2.fromFloat32x4(Float32x4 v) native "Float64x2_fromFloat32x4";
 }
 
 @pragma("vm:entry-point")
 class _Float64x2 implements Float64x2 {
+  @pragma("vm:recognized", "graph-intrinsic")
   Float64x2 operator +(Float64x2 other) native "Float64x2_add";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 operator -() native "Float64x2_negate";
+  @pragma("vm:recognized", "graph-intrinsic")
   Float64x2 operator -(Float64x2 other) native "Float64x2_sub";
+  @pragma("vm:recognized", "graph-intrinsic")
   Float64x2 operator *(Float64x2 other) native "Float64x2_mul";
+  @pragma("vm:recognized", "graph-intrinsic")
   Float64x2 operator /(Float64x2 other) native "Float64x2_div";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 scale(double s) native "Float64x2_scale";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 abs() native "Float64x2_abs";
   Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit)
       native "Float64x2_clamp";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get x native "Float64x2_getX";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get y native "Float64x2_getY";
+  @pragma("vm:recognized", "other")
   int get signMask native "Float64x2_getSignMask";
 
   @pragma("vm:prefer-inline")
@@ -3830,6 +3966,7 @@
     return _withX(x);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 _withX(double x) native "Float64x2_setX";
 
@@ -3839,13 +3976,17 @@
     return _withY(y);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 _withY(double y) native "Float64x2_setY";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 min(Float64x2 other) native "Float64x2_min";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 max(Float64x2 other) native "Float64x2_max";
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 sqrt() native "Float64x2_sqrt";
 }
@@ -3875,10 +4016,7 @@
     return false;
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 }
 
 abstract class _TypedListView extends _TypedListBase implements TypedData {
@@ -3892,14 +4030,17 @@
     return _typedData.buffer;
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:prefer-inline")
   _TypedList get _typedData native "TypedDataView_typedData";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get offsetInBytes native "TypedDataView_offsetInBytes";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "TypedDataView_length";
@@ -3910,6 +4051,7 @@
     with _IntListMixin, _TypedIntListMixin<Int8List>
     implements Int8List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int8ArrayView)
   factory _Int8ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Int8ArrayView_new";
@@ -3949,6 +4091,7 @@
     with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint8ArrayView)
   factory _Uint8ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Uint8ArrayView_new";
@@ -3988,6 +4131,7 @@
     with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
     implements Uint8ClampedList {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint8ClampedArrayView)
   factory _Uint8ClampedArrayView._(_TypedList buffer, int offsetInBytes,
       int length) native "TypedDataView_Uint8ClampedArrayView_new";
@@ -4027,6 +4171,7 @@
     with _IntListMixin, _TypedIntListMixin<Int16List>
     implements Int16List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int16ArrayView)
   factory _Int16ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Int16ArrayView_new";
@@ -4079,6 +4224,7 @@
     with _IntListMixin, _TypedIntListMixin<Uint16List>
     implements Uint16List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint16ArrayView)
   factory _Uint16ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Uint16ArrayView_new";
@@ -4132,6 +4278,7 @@
     with _IntListMixin, _TypedIntListMixin<Int32List>
     implements Int32List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32ArrayView)
   factory _Int32ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Int32ArrayView_new";
@@ -4171,6 +4318,7 @@
     with _IntListMixin, _TypedIntListMixin<Uint32List>
     implements Uint32List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint32ArrayView)
   factory _Uint32ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Uint32ArrayView_new";
@@ -4210,6 +4358,7 @@
     with _IntListMixin, _TypedIntListMixin<Int64List>
     implements Int64List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int64ArrayView)
   factory _Int64ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Int64ArrayView_new";
@@ -4249,6 +4398,7 @@
     with _IntListMixin, _TypedIntListMixin<Uint64List>
     implements Uint64List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Uint64ArrayView)
   factory _Uint64ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Uint64ArrayView_new";
@@ -4288,6 +4438,7 @@
     with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
     implements Float32List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32ArrayView)
   factory _Float32ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Float32ArrayView_new";
@@ -4327,6 +4478,7 @@
     with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
     implements Float64List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64ArrayView)
   factory _Float64ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Float64ArrayView_new";
@@ -4366,6 +4518,7 @@
     with _Float32x4ListMixin
     implements Float32x4List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float32x4ArrayView)
   factory _Float32x4ArrayView._(_TypedList buffer, int offsetInBytes,
       int length) native "TypedDataView_Float32x4ArrayView_new";
@@ -4403,6 +4556,7 @@
     with _Int32x4ListMixin
     implements Int32x4List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Int32x4ArrayView)
   factory _Int32x4ArrayView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_Int32x4ArrayView_new";
@@ -4440,6 +4594,7 @@
     with _Float64x2ListMixin
     implements Float64x2List {
   // Constructor.
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _Float64x2ArrayView)
   factory _Float64x2ArrayView._(_TypedList buffer, int offsetInBytes,
       int length) native "TypedDataView_Float64x2ArrayView_new";
@@ -4474,6 +4629,7 @@
 
 @pragma("vm:entry-point")
 class _ByteDataView implements ByteData {
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _ByteDataView)
   factory _ByteDataView._(_TypedList buffer, int offsetInBytes, int length)
       native "TypedDataView_ByteDataView_new";
@@ -4720,14 +4876,17 @@
     _typedData._setFloat32x4(offsetInBytes + byteOffset, value);
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:prefer-inline")
   _TypedList get _typedData native "TypedDataView_typedData";
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get offsetInBytes native "TypedDataView_offsetInBytes";
 
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
   @pragma("vm:prefer-inline")
   int get length native "TypedDataView_length";
@@ -4773,6 +4932,7 @@
   return value & 0xFF;
 }
 
+@pragma("vm:recognized", "other")
 @pragma("vm:exact-result-type", "dart:core#_Smi")
 int _toClampedUint8(int value) {
   if (value < 0) return 0;
diff --git a/sdk/lib/_internal/vm/lib/wasm_patch.dart b/sdk/lib/_internal/vm/lib/wasm_patch.dart
deleted file mode 100644
index f3a996d..0000000
--- a/sdk/lib/_internal/vm/lib/wasm_patch.dart
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:_internal' show patch;
-import "dart:nativewrappers" show NativeFieldWrapperClass1;
-import 'dart:typed_data';
-
-@patch
-@pragma("vm:entry-point")
-class Int32 {}
-
-@patch
-@pragma("vm:entry-point")
-class Int64 {}
-
-@patch
-@pragma("vm:entry-point")
-class Float {}
-
-@patch
-@pragma("vm:entry-point")
-class Double {}
-
-@patch
-@pragma("vm:entry-point")
-class Void {}
-
-@patch
-class WasmModule {
-  @patch
-  factory WasmModule(Uint8List data) {
-    return _NativeWasmModule(data);
-  }
-}
-
-@patch
-class WasmMemory {
-  @patch
-  factory WasmMemory(int initialPages, [int? maxPages]) {
-    return _NativeWasmMemory(initialPages, maxPages);
-  }
-}
-
-@patch
-class WasmImports {
-  @patch
-  factory WasmImports() {
-    return _NativeWasmImports();
-  }
-}
-
-class _NativeWasmModule extends NativeFieldWrapperClass1 implements WasmModule {
-  _NativeWasmModule(Uint8List data) {
-    _init(data);
-  }
-
-  WasmInstance instantiate(covariant _NativeWasmImports imports) {
-    return _NativeWasmInstance(this, imports);
-  }
-
-  void _init(Uint8List data) native 'Wasm_initModule';
-  String describe() native 'Wasm_describeModule';
-}
-
-class _NativeWasmImports extends NativeFieldWrapperClass1
-    implements WasmImports {
-  List<WasmMemory> _memories;
-  List<Function> _fns;
-
-  _NativeWasmImports()
-      : _memories = [],
-        _fns = [] {
-    _init();
-  }
-
-  void addMemory(String moduleName, String name, WasmMemory memory) {
-    _memories.add(memory);
-    _addMemory(moduleName, name, memory);
-  }
-
-  void addGlobal<T>(String moduleName, String name, num value, bool mutable) {
-    _addGlobal(moduleName, name, value, T, mutable);
-  }
-
-  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 {
-  late int _pages;
-  late Uint8List _buffer;
-
-  _NativeWasmMemory(int initialPages, int? maxPages) {
-    _buffer = _init(initialPages, maxPages);
-    _pages = initialPages;
-  }
-
-  _NativeWasmMemory.fromInstance(_NativeWasmInstance inst) {
-    _buffer = _initFromInstance(inst);
-    _pages = _getPages();
-  }
-
-  int get lengthInPages => _pages;
-  int get lengthInBytes => _buffer.lengthInBytes;
-  int operator [](int index) => _buffer[index];
-  void operator []=(int index, int value) {
-    _buffer[index] = value;
-  }
-
-  int grow(int deltaPages) {
-    int oldPages = _pages;
-    _buffer = _grow(deltaPages);
-    _pages += deltaPages;
-    return oldPages;
-  }
-
-  Uint8List _init(int initialPages, int? maxPages) native 'Wasm_initMemory';
-  Uint8List _grow(int deltaPages) native 'Wasm_growMemory';
-  Uint8List _initFromInstance(_NativeWasmInstance inst)
-      native 'Wasm_initMemoryFromInstance';
-  int _getPages() native 'Wasm_getMemoryPages';
-}
-
-class _NativeWasmInstance extends NativeFieldWrapperClass1
-    implements WasmInstance {
-  _NativeWasmModule _module;
-  _NativeWasmImports _imports;
-
-  _NativeWasmInstance(_NativeWasmModule module, _NativeWasmImports imports)
-      : _module = module,
-        _imports = imports {
-    _init(module, imports);
-  }
-
-  WasmFunction<T> lookupFunction<T extends Function>(String name) {
-    return _NativeWasmFunction<T>(this, name);
-  }
-
-  WasmMemory get memory {
-    return _NativeWasmMemory.fromInstance(this);
-  }
-
-  void _init(_NativeWasmModule module, _NativeWasmImports imports)
-      native 'Wasm_initInstance';
-}
-
-class _NativeWasmFunction<T extends Function> extends NativeFieldWrapperClass1
-    implements WasmFunction<T> {
-  _NativeWasmInstance _inst;
-
-  _NativeWasmFunction(_NativeWasmInstance inst, String name) : _inst = inst {
-    _init(inst, name, T);
-  }
-
-  num call(List<num> args) {
-    var arg_copy = List<num>.from(args, growable: false);
-    return _call(arg_copy);
-  }
-
-  void _init(_NativeWasmInstance inst, String name, Type fnType)
-      native 'Wasm_initFunction';
-  num _call(List<num> args) native 'Wasm_callFunction';
-}
diff --git a/sdk/lib/_internal/vm/lib/weak_property.dart b/sdk/lib/_internal/vm/lib/weak_property.dart
index bc903e9..defcd40 100644
--- a/sdk/lib/_internal/vm/lib/weak_property.dart
+++ b/sdk/lib/_internal/vm/lib/weak_property.dart
@@ -6,15 +6,17 @@
 
 @pragma("vm:entry-point")
 class _WeakProperty {
-  factory _WeakProperty(key, value) => _new(key, value);
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  get key native "WeakProperty_getKey";
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  set key(k) native "WeakProperty_setKey";
 
-  get key => _getKey();
-  get value => _getValue();
-  set value(value) => _setValue(value);
-
-  static _WeakProperty _new(key, value) native "WeakProperty_new";
-
-  _getKey() native "WeakProperty_getKey";
-  _getValue() native "WeakProperty_getValue";
-  _setValue(value) native "WeakProperty_setValue";
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  get value native "WeakProperty_getValue";
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  set value(v) native "WeakProperty_setValue";
 }
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 223af14..43e3c1c 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -101,6 +101,7 @@
         checkNotNullable,
         EmptyIterator,
         IterableElementError,
+        nullFuture,
         printToZone,
         printToConsole,
         Since,
diff --git a/sdk/lib/async/broadcast_stream_controller.dart b/sdk/lib/async/broadcast_stream_controller.dart
index c362eea..4db2a34 100644
--- a/sdk/lib/async/broadcast_stream_controller.dart
+++ b/sdk/lib/async/broadcast_stream_controller.dart
@@ -251,8 +251,7 @@
   }
 
   void addError(Object error, [StackTrace? stackTrace]) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     if (!_mayAddEvent) throw _addEventError();
     AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
     if (replacement != null) {
@@ -486,8 +485,7 @@
   }
 
   void addError(Object error, [StackTrace? stackTrace]) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     stackTrace ??= AsyncError.defaultStackTrace(error);
     if (!isClosed && _isFiring) {
       _addPendingEvent(new _DelayedError(error, stackTrace));
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 0e1d703..0473bc3 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -147,8 +147,11 @@
  */
 abstract class Future<T> {
   /// A `Future<Null>` completed with `null`.
-  static final _Future<Null> _nullFuture =
-      new _Future<Null>.zoneValue(null, _rootZone);
+  ///
+  /// Currently shared with `dart:internal`.
+  /// If that future can be removed, then change this back to
+  /// `_Future<Null>.zoneValue(null, _rootZone);`
+  static final _Future<Null> _nullFuture = nullFuture as _Future<Null>;
 
   /// A `Future<bool>` completed with `false`.
   static final _Future<bool> _falseFuture =
@@ -275,7 +278,7 @@
    */
   factory Future.error(Object error, [StackTrace? stackTrace]) {
     // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     if (!identical(Zone.current, _rootZone)) {
       AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
       if (replacement != null) {
@@ -361,7 +364,7 @@
    * The call to [cleanUp] should not throw. If it does, the error will be an
    * uncaught asynchronous error.
    */
-  @pragma("vm:entry-point")
+  @pragma("vm:recognized", "other")
   static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
       {bool eagerError = false, void cleanUp(T successValue)?}) {
     // This is a VM recognised method, and the _future variable is deliberately
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 4e24a48..862c871 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -18,7 +18,7 @@
 
   void completeError(Object error, [StackTrace? stackTrace]) {
     // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     if (!future._mayComplete) throw new StateError("Future already completed");
     AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
     if (replacement != null) {
@@ -74,15 +74,22 @@
   static const int maskType =
       maskValue | maskError | maskTestError | maskWhencomplete;
   static const int stateIsAwait = 16;
+
   // Listeners on the same future are linked through this link.
   _FutureListener? _nextListener;
+
   // The future to complete when this listener is activated.
+  @pragma("vm:entry-point")
   final _Future<T> result;
+
   // Which fields means what.
+  @pragma("vm:entry-point")
   final int state;
+
   // Used for then/whenDone callback and error test
   @pragma("vm:entry-point")
   final Function? callback;
+
   // Used for error callbacks.
   final Function? errorCallback;
 
@@ -768,6 +775,7 @@
     }
   }
 
+  @pragma("vm:recognized", "other")
   @pragma("vm:entry-point")
   Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()?}) {
     if (_isComplete) return new _Future.immediate(this);
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 150a759..60f4aa1 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -152,7 +152,7 @@
   @Since("2.5")
   factory Stream.error(Object error, [StackTrace? stackTrace]) {
     // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     return (_AsyncStreamController<T>(null, null, null, null)
           .._addError(error, stackTrace ?? AsyncError.defaultStackTrace(error))
           .._closeUnchecked())
@@ -2212,20 +2212,22 @@
 }
 
 /**
- * An [Iterator] like interface for the values of a [Stream].
+ * An [Iterator]-like interface for the values of a [Stream].
  *
  * This wraps a [Stream] and a subscription on the stream. It listens
  * on the stream, and completes the future returned by [moveNext] when the
  * next value becomes available.
  *
  * The stream may be paused between calls to [moveNext].
+ *
+ * The [current] value must only be used after a future returned by [moveNext]
+ * has completed with `true`, and only until [moveNext] is called again.
  */
 abstract class StreamIterator<T> {
   /** Create a [StreamIterator] on [stream]. */
-  factory StreamIterator(Stream<T> stream)
+  factory StreamIterator(Stream<T> stream) =>
       // TODO(lrn): use redirecting factory constructor when type
       // arguments are supported.
-      =>
       new _StreamIterator<T>(stream);
 
   /**
@@ -2247,14 +2249,16 @@
   /**
    * The current value of the stream.
    *
-   * Is `null` before the first call to [moveNext] and after a call to
-   * `moveNext` completes with a `false` result or an error.
-   *
-   * When a `moveNext` call completes with `true`, the `current` field holds
+   * When a [moveNext] call completes with `true`, the [current] field holds
    * the most recent event of the stream, and it stays like that until the next
-   * call to `moveNext`.
-   * Between a call to `moveNext` and when its returned future completes,
-   * the value is unspecified.
+   * call to [moveNext]. This value must only be read after a call to [moveNext]
+   * has completed with `true`, and only until the [moveNext] is called again.
+   *
+   * If the StreamIterator has not yet been moved to the first element
+   * ([moveNext] has not been called and completed yet), or if the
+   * StreamIterator has been moved past the last element ([moveNext] has
+   * returned `false`), then [current] is unspecified. A [StreamIterator] may
+   * either throw or return an iterator-specific default value in that case.
    */
   T get current;
 
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 4c3e4f9..dbaacc1 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -628,8 +628,7 @@
    * Send or enqueue an error event.
    */
   void addError(Object error, [StackTrace? stackTrace]) {
-    // TODO(40614): Remove once non-nullability is sound. Use checkNotNullable.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     if (!_mayAddEvent) throw _badEventState();
     AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
     if (replacement != null) {
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 6ec5d03..bb4a1ba 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -1009,7 +1009,7 @@
   bool _hasValue = false;
 
   _StreamIterator(final Stream<T> stream)
-      : _stateData = ArgumentError.checkNotNull(stream, "stream");
+      : _stateData = checkNotNullable(stream, "stream");
 
   T get current {
     if (_hasValue) return _stateData as dynamic;
diff --git a/sdk/lib/async/stream_transformers.dart b/sdk/lib/async/stream_transformers.dart
index ca7934c..aa99f5f 100644
--- a/sdk/lib/async/stream_transformers.dart
+++ b/sdk/lib/async/stream_transformers.dart
@@ -229,8 +229,7 @@
   }
 
   void addError(Object error, [StackTrace? stackTrace]) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     var sink = _sink;
     if (sink == null) {
       throw StateError("Sink is closed");
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index b4e3994..f662d53 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -36,16 +36,14 @@
 typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
     ZoneSpecification? specification, Map<Object?, Object?>? zoneValues);
 
-/** Pair of error and stack trace. Returned by [Zone.errorCallback]. */
+/// Pair of error and stack trace. Returned by [Zone.errorCallback].
 class AsyncError implements Error {
   final Object error;
   final StackTrace stackTrace;
 
-  AsyncError(this.error, StackTrace? stackTrace)
-      : stackTrace = stackTrace ?? defaultStackTrace(error) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
-  }
+  AsyncError(Object error, StackTrace? stackTrace)
+      : error = checkNotNullable(error, "error"),
+        stackTrace = stackTrace ?? defaultStackTrace(error);
 
   /// A default stack trace for an error.
   ///
@@ -795,8 +793,7 @@
   }
 
   AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     var implementation = _delegationTarget._errorCallback;
     _Zone implZone = implementation.zone;
     if (identical(implZone, _rootZone)) return null;
@@ -1130,8 +1127,7 @@
   }
 
   AsyncError? errorCallback(Object error, StackTrace? stackTrace) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     var implementation = this._errorCallback;
     final _Zone implementationZone = implementation.zone;
     if (identical(implementationZone, _rootZone)) return null;
@@ -1532,7 +1528,7 @@
     {Map<Object?, Object?>? zoneValues,
     ZoneSpecification? zoneSpecification,
     @Deprecated("Use runZonedGuarded instead") Function? onError}) {
-  ArgumentError.checkNotNull(body, "body");
+  checkNotNullable(body, "body");
   if (onError != null) {
     // TODO: Remove this when code have been migrated off using [onError].
     if (onError is! void Function(Object, StackTrace)) {
@@ -1592,8 +1588,8 @@
 @Since("2.8")
 R? runZonedGuarded<R>(R body(), void onError(Object error, StackTrace stack),
     {Map<Object?, Object?>? zoneValues, ZoneSpecification? zoneSpecification}) {
-  ArgumentError.checkNotNull(body, "body");
-  ArgumentError.checkNotNull(onError, "onError");
+  checkNotNullable(body, "body");
+  checkNotNullable(onError, "onError");
   _Zone parentZone = Zone._current;
   HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
       Zone zone, Object error, StackTrace stackTrace) {
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
index 17f84a2..9e697a5 100644
--- a/sdk/lib/collection/iterable.dart
+++ b/sdk/lib/collection/iterable.dart
@@ -197,7 +197,7 @@
   }
 
   E elementAt(int index) {
-    ArgumentError.checkNotNull(index, "index");
+    checkNotNullable(index, "index");
     RangeError.checkNotNegative(index, "index");
     int elementIndex = 0;
     for (E element in this) {
diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart
index 843eedd..6d6be81 100644
--- a/sdk/lib/collection/linked_list.dart
+++ b/sdk/lib/collection/linked_list.dart
@@ -6,7 +6,7 @@
 
 /// A specialized double-linked list of elements that extends [LinkedListEntry].
 ///
-/// This is not a generic data structure. It only accepts elements that extend
+/// This is not a generic data structure. It only accepts elements that *extend*
 /// the [LinkedListEntry] class. See the [Queue] implementations for generic
 /// collections that allow constant time adding and removing at the ends.
 ///
@@ -17,6 +17,9 @@
 /// Because the elements themselves contain the links of this linked list,
 /// each element can be in only one list at a time. To add an element to another
 /// list, it must first be removed from its current list (if any).
+/// For the same reason, the [remove] and [contains] methods
+/// are based on *identity*, even if the [LinkedListEntry] chooses
+/// to override [Object.operator==].
 ///
 /// In return, each element knows its own place in the linked list, as well as
 /// which list it is in. This allows constant time
@@ -61,6 +64,13 @@
     return true;
   }
 
+  /// Whether [entry] is a [LinkedListEntry] belonging to this list.
+  ///
+  /// The [entry] is considered as belonging to this list if
+  /// its [LinkedListEntry.list] is this list.
+  bool contains(Object? entry) =>
+      entry is LinkedListEntry && identical(this, entry.list);
+
   Iterator<E> get iterator => _LinkedListIterator<E>(this);
 
   int get length => _length;
@@ -181,10 +191,7 @@
         _next = list._first,
         _visitedFirst = false;
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 
   bool moveNext() {
     if (_modificationCount != _list._modificationCount) {
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 045bbd5..327a7ea 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -523,7 +523,7 @@
   }
 
   void insert(int index, E element) {
-    ArgumentError.checkNotNull(index, "index");
+    checkNotNullable(index, "index");
     var length = this.length;
     RangeError.checkValueInInterval(index, 0, length, "index");
     add(element);
diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart
index 85a3155..b0ab270 100644
--- a/sdk/lib/collection/maps.dart
+++ b/sdk/lib/collection/maps.dart
@@ -258,10 +258,7 @@
     return false;
   }
 
-  V get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as V;
-  }
+  V get current => _current as V;
 }
 
 /// Mixin that overrides mutating map operations with implementations that
@@ -288,7 +285,7 @@
   }
 
   /// This operation is not supported by an unmodifiable map.
-  V remove(Object? key) {
+  V? remove(Object? key) {
     throw UnsupportedError("Cannot modify unmodifiable map");
   }
 
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 26abbfe..c238840 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -518,10 +518,7 @@
     return true;
   }
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 }
 
 /// List based [Queue].
@@ -901,10 +898,7 @@
         _modificationCount = queue._modificationCount,
         _position = queue._head;
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 
   bool moveNext() {
     _queue._checkModification(_modificationCount);
diff --git a/sdk/lib/collection/set.dart b/sdk/lib/collection/set.dart
index 0a6ccbf..5cd75d6 100644
--- a/sdk/lib/collection/set.dart
+++ b/sdk/lib/collection/set.dart
@@ -268,7 +268,7 @@
   }
 
   E elementAt(int index) {
-    ArgumentError.checkNotNull(index, "index");
+    checkNotNullable(index, "index");
     RangeError.checkNotNegative(index, "index");
     int elementIndex = 0;
     for (E element in this) {
diff --git a/sdk/lib/convert/chunked_conversion.dart b/sdk/lib/convert/chunked_conversion.dart
index d2c24f0..19a8561 100644
--- a/sdk/lib/convert/chunked_conversion.dart
+++ b/sdk/lib/convert/chunked_conversion.dart
@@ -73,8 +73,7 @@
   }
 
   void addError(Object error, [StackTrace? stackTrace]) {
-    // TODO(40614): Remove once non-nullability is sound.
-    ArgumentError.checkNotNull(error, "error");
+    checkNotNullable(error, "error");
     _eventSink.addError(error, stackTrace);
   }
 
diff --git a/sdk/lib/convert/convert.dart b/sdk/lib/convert/convert.dart
index 6173782..1ea3d26 100644
--- a/sdk/lib/convert/convert.dart
+++ b/sdk/lib/convert/convert.dart
@@ -55,7 +55,7 @@
 
 import 'dart:async';
 import 'dart:typed_data';
-import 'dart:_internal' show CastConverter, parseHexByte;
+import 'dart:_internal' show CastConverter, checkNotNullable, parseHexByte;
 
 part 'ascii.dart';
 part 'base64.dart';
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index aa85fcc..e8c9dcb 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -394,7 +394,7 @@
           "DateTime is outside valid range: $millisecondsSinceEpoch");
     }
     // For backwards compatibility with legacy mode.
-    ArgumentError.checkNotNull(isUtc, "isUtc");
+    checkNotNullable(isUtc, "isUtc");
   }
 
   /**
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 839792e..7482058 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -170,7 +170,7 @@
   Iterable<R> cast<R>() => Iterable.castFrom<E, R>(this);
 
   /**
-   * Returns the lazy concatentation of this iterable and [other].
+   * Returns the lazy concatenation of this iterable and [other].
    *
    * The returned iterable will provide the same elements as this iterable,
    * and, after that, the elements of [other], in the same order as in the
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index ecd4c97..e342bb7 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -27,7 +27,7 @@
  * The following code illustrates that some List implementations support
  * only a subset of the API.
  *
- *     List<int> fixedLengthList = new List(5);
+ *     List<int> fixedLengthList = new List.filled(5);
  *     fixedLengthList.length = 0;  // Error
  *     fixedLengthList.add(499);    // Error
  *     fixedLengthList[0] = 87;
@@ -55,13 +55,16 @@
   /**
    * Creates a list of the given length.
    *
-   * This constructor will throw an exception if [E] is not a nullable type.
-   * In this case, another constructor such as [List.filled] must be used
-   * instead.
+   * **NOTICE**: This constructor cannot be used in null-safe code.
+   * Use [List.filled] to create a non-empty list.
+   * This requires a fill value to initialize the list elements with.
+   * To create an empty list, use `[]` for a growable list or
+   * `List.empty` for a fixed length list (or where growability is determined
+   * at run-time).
    *
    * The created list is fixed-length if [length] is provided.
    *
-   *     List fixedLengthList = new List(3);
+   *     List fixedLengthList = new List.filled(3);
    *     fixedLengthList.length;     // 3
    *     fixedLengthList.length = 1; // Error
    *
@@ -84,14 +87,8 @@
    *
    * If the element type is not nullable, [length] must not be greater than
    * zero.
-   *
-   * This constructor cannot be used in null-safe code.
-   * Use [List.filled] to create a non-empty list.
-   * This requires a fill value to initialize the list elements with.
-   * To create an empty list, use `[]` for a growable list or
-   * `List.empty` for a fixed length list (or where growability is determined
-   * at run-time).
    */
+  @deprecated
   external factory List([int? length]);
 
   /**
@@ -485,7 +482,7 @@
   void clear();
 
   /**
-   * Inserts the object at position [index] in this list.
+   * Inserts [element] at position [index] in this list.
    *
    * This increases the length of the list by one and shifts all objects
    * at or after the index towards the end of the list.
@@ -705,7 +702,7 @@
    *
    * Example:
    * ```dart
-   *  List<int> list = new List(3);
+   *  List<int> list = new List.filled(3);
    *     list.fillRange(0, 2, 1);
    *     print(list); //  [1, 1, null]
    * ```
@@ -742,7 +739,7 @@
    * in numerical order.
    *
    *     List<String> words = ['fee', 'fi', 'fo', 'fum'];
-   *     Map<int, String> map = words.asMap();
+   *     Map<int, String> map = words.asMap();  // {0: fee, 1: fi, 2: fo, 3: fum}
    *     map[0] + map[1];   // 'feefi';
    *     map.keys.toList(); // [0, 1, 2, 3]
    */
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 0f7d97b..b55d80d 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -27,6 +27,7 @@
    * through their identity. An [Object] instance is equal to itself
    * only.
    */
+  @pragma("vm:recognized", "other")
   const Object();
 
   /**
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 6f47e07..edb05cf 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -136,7 +136,7 @@
   Iterator<E> get iterator;
 
   /**
-   * Returns true if [value] is in the set.
+   * Returns `true` if [value] is in the set.
    */
   bool contains(Object? value);
 
@@ -172,9 +172,9 @@
   void addAll(Iterable<E> elements);
 
   /**
-   * Removes [value] from the set. Returns true if [value] was
-   * in the set. Returns false otherwise. The method has no effect
-   * if [value] value was not in the set.
+   * Removes [value] from the set. Returns `true` if [value] was
+   * in the set. Returns `false` otherwise. The method has no effect
+   * if [value] was not in the set.
    */
   bool remove(Object? value);
 
@@ -205,7 +205,7 @@
    * Checks for each element of [elements] whether there is an element in this
    * set that is equal to it (according to `this.contains`), and if so, the
    * equal element in this set is retained, and elements that are not equal
-   * to any element in `elements` are removed.
+   * to any element in [elements] are removed.
    */
   void retainAll(Iterable<Object?> elements);
 
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 998cb83..143ad63 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -609,7 +609,8 @@
 
   /// Returns a hash code computed as `toString().hashCode`.
   ///
-  /// This guarantees that URIs with the same normalized
+  /// This guarantees that URIs with the same normalized string representation
+  /// have the same hash code.
   int get hashCode;
 
   /// A URI is equal to another URI with the same normalized representation.
diff --git a/sdk/lib/developer/service.dart b/sdk/lib/developer/service.dart
index a563f39..6fd58c3 100644
--- a/sdk/lib/developer/service.dart
+++ b/sdk/lib/developer/service.dart
@@ -41,7 +41,8 @@
   /// Uri to access the service).
   static Future<ServiceProtocolInfo> getInfo() async {
     // Port to receive response from service isolate.
-    final RawReceivePort receivePort = new RawReceivePort();
+    final RawReceivePort receivePort =
+        new RawReceivePort(null, 'Service.getInfo');
     final Completer<Uri?> uriCompleter = new Completer<Uri?>();
     receivePort.handler = (Uri? uri) => uriCompleter.complete(uri);
     // Request the information from the service isolate.
@@ -62,7 +63,8 @@
     // TODO: When NNBD is complete, delete the following line.
     ArgumentError.checkNotNull(enable, 'enable');
     // Port to receive response from service isolate.
-    final RawReceivePort receivePort = new RawReceivePort();
+    final RawReceivePort receivePort =
+        new RawReceivePort(null, 'Service.controlWebServer');
     final Completer<Uri> uriCompleter = new Completer<Uri>();
     receivePort.handler = (Uri uri) => uriCompleter.complete(uri);
     // Request the information from the service isolate.
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index cc9cf40..aaa0ee4 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -364,6 +364,7 @@
 }
 
 /// Returns true if the Dart Timeline stream is enabled.
+@pragma("vm:recognized", "asm-intrinsic")
 external bool _isDartStreamEnabled();
 
 /// Returns the next async task id.
diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart
index 0faf7ca..da034ef 100644
--- a/sdk/lib/ffi/struct.dart
+++ b/sdk/lib/ffi/struct.dart
@@ -4,19 +4,48 @@
 
 part of dart.ffi;
 
-/// This class is extended to define structs.
+/// The supertype of all FFI struct types.
 ///
-/// Fields in a struct, annotated with a subtype of [NativeType], are
-/// automatically transformed into wrappers to access the fields of the struct
-/// in native memory.
+/// FFI struct types should extend this class and declare fields corresponding
+/// to the underlying native structure.
 ///
-/// All fields in a struct must either have a type which extends [NativeType] or
-/// else have an annotation indicating the corresponding native type (e.g.
-/// "@Int32()" for "int").
+/// Field declarations in a [Struct] subclass declaration are automatically
+/// given a setter and getter implementation which accesses the native struct's
+/// field in memory.
+///
+/// All field declarations in a [Struct] subclass declaration must either have
+/// type [int] or [float] and be annotated with a [NativeType] representing the
+/// native type, or must be of type [Pointer]. For example:
+///
+/// ```
+/// typedef struct {
+///  int a;
+///  float b;
+///  void* c;
+/// } my_struct;
+/// ```
+///
+/// ```
+/// class MyStruct extends Struct {
+///   @Int32
+///   external int a;
+///
+///   @Float
+///   external double b;
+///
+///   external Pointer<Void> c;
+/// }
+/// ```
+///
+/// All field declarations in a [Struct] subclass declaration must be marked
+/// `external`. You cannot create instances of the class, only have it point to
+/// existing native memory, so there is no memory in which to store non-native
+/// fields. External fields also cannot be initialized by constructors since no
+/// Dart object is being created.
 ///
 /// Instances of a subclass of [Struct] have reference semantics and are backed
 /// by native memory. The may allocated via allocation or loaded from a
-/// [Pointer], but not by a generative constructor.
+/// [Pointer], but cannot be created by a generative constructor.
 abstract class Struct extends NativeType {
   final Object _addressOf;
 
diff --git a/sdk/lib/html/doc/WORKAROUNDS.md b/sdk/lib/html/doc/WORKAROUNDS.md
new file mode 100644
index 0000000..d3d8456
--- /dev/null
+++ b/sdk/lib/html/doc/WORKAROUNDS.md
@@ -0,0 +1,128 @@
+Dart web platform libraries e.g. `dart:html` is partially hand-written and
+partially generated, with the code generation using the Chrome IDL as the source
+of truth for many browser interfaces. This introduces a dependency on the
+version of the IDL and doesn’t always match up with other browser interfaces.
+
+Currently, we do not intend on updating our scripts to use a newer version of
+the IDL, so APIs and classes in these libraries may be inaccurate.
+
+In order to work around this, we ask users to leverage JS interop. Longer term,
+we intend to revamp our web library offerings to be more robust and reliable.
+
+The following are workarounds to common issues you might see with using the web
+platform libraries.
+
+## Common Issues
+
+### Missing/broken APIs
+
+As mentioned above, there exists stale interfaces. While some of these may be
+fixed in the source code, many might not.
+
+In order to circumvent this, you can use the `js_util` library, like
+`getProperty`, `setProperty`, `callMethod`, and `callConstructor`.
+
+Let’s look at an example. `FileReader` is a `dart:html` interface that is
+missing the API `readAsBinaryString` ([#42834][]). We can work around this by
+doing something like the following:
+
+```
+import 'dart:html';
+import 'dart:js_util' as js_util;
+
+import 'package:async_helper/async_minitest.dart';
+import 'package:expect/expect.dart';
+
+void main() async {
+  var reader = new FileReader();
+  reader.onLoad.listen(expectAsync((event) {
+    String result = reader.result as String;
+    Expect.equals(result, '00000000');
+  }));
+  js_util.callMethod(reader, 'readAsBinaryString', [new Blob(['00000000'])]);
+  // We can manipulate properties as well.
+  js_util.setProperty(reader, 'foo', 'bar'); // reader.foo is now ‘bar’
+  Expect.equals(js_util.getProperty(reader, 'foo'), 'bar');
+}
+```
+
+In the case where the API is missing a constructor, we can use
+`callConstructor`. For example, instead of using the factory constructor for
+`KeyboardEvent`, we can do the following:
+
+```
+import 'dart:html';
+import 'dart:js_util' as js_util;
+
+import 'package:expect/expect.dart';
+
+void main() {
+  List<dynamic> eventArgs = <dynamic>[
+    'KeyboardEvent',
+    <String, dynamic>{'key': 'A'}
+  ];
+  KeyboardEvent event = js_util.callConstructor(
+      js_util.getProperty(window, 'KeyboardEvent'), js_util.jsify(eventArgs));
+  Expect.equals(event.key, 'A');
+}
+```
+
+### Private/unimplemented native types
+
+There are several native interfaces that are suppressed e.g.
+`USBDevice` ([#42200][]) due to historical reasons. These native interfaces are
+marked with `@Native`, are private, and have no attributes associated with them.
+Therefore, unlike other `@Native` objects, we can’t access any of the APIs or
+attributes associated with this interface. We can use the `js_util` library
+again to circumvent this issue. For example, we can manipulate a
+`_SubtleCrypto` object:
+
+```
+import 'dart:html';
+import 'dart:js_util' as js_util;
+import 'dart:typed_data';
+
+import 'package:js/js.dart';
+
+@JS()
+external Crypto get crypto;
+
+void main() async {
+  var subtle = crypto.subtle!;
+  var array = Uint8List(16);
+  var promise = js_util.promiseToFuture<ByteBuffer>(js_util
+      .callMethod(subtle, 'digest', ['SHA-256', array])); // SubtleCrypto.digest
+  var digest = await promise;
+}
+```
+
+What you shouldn’t do is attempt to cast these native objects using your own JS
+interop types, e.g.
+
+```
+import 'dart:html';
+
+import 'package:js/js.dart';
+
+@JS()
+external Crypto get crypto;
+
+@JS()
+class SubtleCrypto {}
+
+void main() {
+  SubtleCrypto subtle = crypto.subtle! as SubtleCrypto;
+}
+```
+
+With the above, you’ll see a type error:
+
+`Uncaught TypeError: Instance of 'SubtleCrypto': type 'Interceptor' is not a subtype of type 'SubtleCrypto'`
+
+This is because the types in the `@Native` annotation are reserved and the above
+leads to namespace conflicts between the `@Native` type and the user JS interop
+type in the compiler. These `@Native` types inherit the `Interceptor` class,
+which is why you see the message above.
+
+[#42834]: https://github.com/dart-lang/sdk/issues/42834
+[#42200]: https://github.com/dart-lang/sdk/issues/42200
diff --git a/sdk/lib/html/html_common/conversions_dart2js.dart b/sdk/lib/html/html_common/conversions_dart2js.dart
index c1fb0be..f0ed6d2 100644
--- a/sdk/lib/html/html_common/conversions_dart2js.dart
+++ b/sdk/lib/html/html_common/conversions_dart2js.dart
@@ -13,7 +13,29 @@
   return dict;
 }
 
-/// Converts a flat Dart map into a JavaScript object with properties.
+/// Converts values that occur within a Dart map for map conversion.
+///
+/// This includes other maps, lists, or values that don't need a conversion e.g.
+/// bool, String.
+_convertDartToNative_Value(Object? value) {
+  if (value == null) return value;
+  if (value is String || value is num || value is bool) return value;
+  if (value is Map) return convertDartToNative_Dictionary(value);
+  if (value is List) {
+    var array = JS('var', '[]');
+    value.forEach((element) {
+      JS('void', '#.push(#)', array, _convertDartToNative_Value(element));
+    });
+    value = array;
+  }
+  return value;
+}
+
+/// Converts a potentially nested Dart map to a JavaScript object with
+/// properties.
+///
+/// This method requires that the values within the map are either maps
+/// themselves, lists, or do not need a conversion.
 convertDartToNative_Dictionary(Map? dict, [void postCreate(Object? f)?]) {
   if (dict == null) return null;
   var object = JS('var', '{}');
@@ -21,7 +43,7 @@
     postCreate(object);
   }
   dict.forEach((key, value) {
-    JS('void', '#[#] = #', object, key, value);
+    JS('void', '#[#] = #', object, key, _convertDartToNative_Value(value));
   });
   return object;
 }
diff --git a/sdk/lib/internal/errors.dart b/sdk/lib/internal/errors.dart
index 5f8ca81..8b93cd1 100644
--- a/sdk/lib/internal/errors.dart
+++ b/sdk/lib/internal/errors.dart
@@ -12,10 +12,16 @@
   // The constructor names have been deliberately shortened to reduce the size
   // of unminified code as used by DDC.
 
+  @pragma("vm:entry-point")
   LateError.fieldADI(String fieldName)
       : _message =
             "Field '$fieldName' has been assigned during initialization.";
 
+  LateError.localADI(String localName)
+      : _message =
+            "Local '$localName' has been assigned during initialization.";
+
+  @pragma("vm:entry-point")
   LateError.fieldNI(String fieldName)
       : _message = "Field '${fieldName}' has not been initialized.";
 
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index 401777d..858f1f5 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -119,6 +119,28 @@
   return digit1 * 16 + digit2 - (digit2 & 256);
 }
 
+/// A resusable `null`-valued future used by `dart:async`.
+///
+/// **DO NOT USE.**
+///
+/// This future is used in situations where a future is expected,
+/// but no asynchronous computation actually happens,
+/// like cancelling a stream from a controller with no `onCancel` callback.
+/// *Some code depends on recognizing this future in order to react
+/// synchronously.*
+/// It does so to avoid changing event interleaving during the null safety
+/// migration where, for example, the [StreamSubscription.cancel] method
+/// stopped being able to return `null`.
+/// The code that would be broken by such a timing change is fragile,
+/// but we are not able to simply change it.
+/// For better or worse, code depends on the precise timing that our libraries
+/// have so far exhibited.
+///
+/// This future will be removed again if we can ever do so.
+/// Do not use it for anything other than preserving timing
+/// during the null safety migration.
+final Future<Null> nullFuture = Zone.root.run(() => Future<Null>.value(null));
+
 /// A default hash function used by the platform in various places.
 ///
 /// This is currently the [Jenkins hash function][1] but using masking to keep
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 2817132..55134af 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -325,10 +325,7 @@
         _length = iterable.length,
         _index = 0;
 
-  E get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as E;
-  }
+  E get current => _current as E;
 
   @pragma("vm:prefer-inline")
   bool moveNext() {
@@ -396,10 +393,7 @@
     return false;
   }
 
-  T get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as T;
-  }
+  T get current => _current as T;
 }
 
 /**
@@ -471,10 +465,7 @@
 
   ExpandIterator(this._iterator, this._f);
 
-  T get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as T;
-  }
+  T get current => _current as T;
 
   bool moveNext() {
     if (_currentExpansion == null) return false;
diff --git a/sdk/lib/internal/linked_list.dart b/sdk/lib/internal/linked_list.dart
index b5e5275..ddb0331 100644
--- a/sdk/lib/internal/linked_list.dart
+++ b/sdk/lib/internal/linked_list.dart
@@ -99,10 +99,7 @@
   /// The current element of the iterator.
   T? _current;
 
-  T get current {
-    final cur = _current;
-    return (cur != null) ? cur : cur as T;
-  }
+  T get current => _current as T;
 
   /// The list the iterator iterates over.
   ///
diff --git a/sdk/lib/internal/list.dart b/sdk/lib/internal/list.dart
index 0a8b6a9..fc24360 100644
--- a/sdk/lib/internal/list.dart
+++ b/sdk/lib/internal/list.dart
@@ -328,13 +328,15 @@
  * Converts a fixed-length list to an unmodifiable list.
  *
  * For internal use only.
- * Only works for core fixed-length lists as created by `new List(length)`,
+ *
+ * Only works for core fixed-length lists as created by
+ * `List.filled(length)`/`List.empty()`,
  * or as returned by [makeListFixedLength].
  *
  * The operation is efficient. It doesn't copy the elements, but converts
  * the existing list directly to a fixed length list.
  * That means that it is a destructive conversion.
- * The original list should not be used afterwards.
+ * The original list reference should not be used afterwards.
  *
  * The unmodifiable list type is similar to the one used by const lists.
  */
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 15b4cd3..0b9d207 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -91,12 +91,6 @@
           "_internal/vm/lib/ffi_struct_patch.dart"
         ]
       },
-      "wasm": {
-        "uri": "wasm/wasm.dart",
-        "patches": [
-          "_internal/vm/lib/wasm_patch.dart"
-        ]
-      },
       "_http": {
         "uri": "_http/http.dart"
       },
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 50e350e..f6cb8c3 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -95,11 +95,6 @@
         - "_internal/vm/lib/ffi_native_type_patch.dart"
         - "_internal/vm/lib/ffi_struct_patch.dart"
 
-    wasm:
-      uri: "wasm/wasm.dart"
-      patches:
-        - "_internal/vm/lib/wasm_patch.dart"
-
     _http:
       uri: "_http/http.dart"
 
diff --git a/sdk/lib/vmservice/message.dart b/sdk/lib/vmservice/message.dart
index ee29fe3..5b07cea 100644
--- a/sdk/lib/vmservice/message.dart
+++ b/sdk/lib/vmservice/message.dart
@@ -156,7 +156,7 @@
   }
 
   Future<Response> sendToIsolate(SendPort sendPort) {
-    final receivePort = RawReceivePort();
+    final receivePort = RawReceivePort(null, 'Isolate Message');
     receivePort.handler = (value) {
       receivePort.close();
       _setResponseFromPort(value);
@@ -200,7 +200,7 @@
   }
 
   Future<Response> sendToVM() {
-    final receivePort = RawReceivePort();
+    final receivePort = RawReceivePort(null, 'VM Message');
     receivePort.handler = (value) {
       receivePort.close();
       _setResponseFromPort(value);
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 98ce332..f7f4a26 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -21,8 +21,8 @@
 part 'message_router.dart';
 part 'named_lookup.dart';
 
-final isolateControlPort = RawReceivePort();
-final scriptLoadPort = RawReceivePort();
+final isolateControlPort = RawReceivePort(null, 'Isolate Control Port');
+final scriptLoadPort = RawReceivePort(null, 'Script Load');
 
 abstract class IsolateEmbedderData {
   void cleanup();
diff --git a/sdk/lib/wasm/wasm.dart b/sdk/lib/wasm/wasm.dart
deleted file mode 100644
index 768445e..0000000
--- a/sdk/lib/wasm/wasm.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// {@category VM}
-/// {@nodoc}
-library dart.wasm;
-
-import 'dart:typed_data';
-
-// Represents the WASM 32-bit int type.
-class Int32 {}
-
-// Represents the WASM 64-bit int type.
-class Int64 {}
-
-// Represents the WASM 32-bit float type.
-class Float {}
-
-// Represents the WASM 64-bit float type.
-class Double {}
-
-// Represents the return type of a void function in WASM.
-class Void {}
-
-// WasmModule is a compiled module that can be instantiated.
-abstract class WasmModule {
-  // Compile a module.
-  external factory WasmModule(Uint8List data);
-
-  // Instantiate the module with the given imports.
-  WasmInstance instantiate(WasmImports imports);
-
-  // Describes the imports and exports that the module expects, for debugging.
-  String describe();
-}
-
-// WasmImports holds all the imports for a WasmInstance.
-abstract class WasmImports {
-  // Create an imports object.
-  external factory WasmImports();
-
-  // Add a global variable to the imports.
-  void addGlobal<T>(String moduleName, String name, num value, bool mutable);
-
-  // Add a memory to the imports.
-  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.
-abstract class WasmMemory {
-  // Create a new memory with the given number of initial pages, and optional
-  // maximum number of pages.
-  external factory WasmMemory(int initialPages, [int? maxPages]);
-
-  // The WASM spec defines the page size as 64KiB.
-  static const int kPageSizeInBytes = 64 * 1024;
-
-  // Returns the length of the memory in pages.
-  int get lengthInPages;
-
-  // Returns the length of the memory in bytes.
-  int get lengthInBytes;
-
-  // Returns the byte at the given index.
-  int operator [](int index);
-
-  // Sets the byte at the iven index to value.
-  void operator []=(int index, int value);
-
-  // Grow the memory by deltaPages. Returns the number of pages before resizing.
-  int grow(int deltaPages);
-}
-
-// WasmInstance is an instantiated WasmModule.
-abstract class WasmInstance {
-  // Find an exported function with the given signature.
-  WasmFunction<T> lookupFunction<T extends Function>(String name);
-
-  // Returns this instance's memory.
-  WasmMemory get memory;
-}
-
-// WasmFunction is a callable function in a WasmInstance.
-abstract class WasmFunction<T extends Function> {
-  num call(List<num> args);
-}
diff --git a/sdk/lib/wasm/wasm_sources.gni b/sdk/lib/wasm/wasm_sources.gni
deleted file mode 100644
index e63af2d..0000000
--- a/sdk/lib/wasm/wasm_sources.gni
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-wasm_sdk_sources = [ "wasm.dart" ]
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 8970fe8..32c17f0 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -43,6 +43,12 @@
 LanguageFeatures/Subtyping/static/tests/left_bottom_A01_t02: Skip # Type aliases are not supported by analyzer
 LanguageFeatures/Subtyping/static/tests/left_bottom_A01_t04: Skip # Type aliases are not supported by analyzer
 LanguageFeatures/Subtyping/static/tests/left_bottom_A01_t06: Skip # Type aliases are not supported by analyzer
+LanguageFeatures/nnbd/Least-greatest-closure/nonfunction_typedef/nonfunction_dynamic_t01: Skip # Type aliases are not fully supported by analyzer yet
+LanguageFeatures/nnbd/Least-greatest-closure/nonfunction_typedef/nonfunction_dynamic_t02: Skip # Type aliases are not fully supported by analyzer yet
+LanguageFeatures/nnbd/Least-greatest-closure/nonfunction_typedef/nonfunction_dynamic_t03: Skip # Type aliases are not fully supported by analyzer yet
+LanguageFeatures/nnbd/Least-greatest-closure/nonfunction_typedef/nonfunction_static_t01: Skip # Type aliases are not fully supported by analyzer yet
+LanguageFeatures/nnbd/Least-greatest-closure/nonfunction_typedef/nonfunction_static_t02: Skip # Type aliases are not fully supported by analyzer yet
+LanguageFeatures/nnbd/Least-greatest-closure/nonfunction_typedef/nonfunction_static_t03: Skip # Type aliases are not fully supported by analyzer yet
 
 [ $compiler == fasta ]
 Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t10: Skip # Type aliases are not fully implemented
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 6bb5259..3208f10 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -21,6 +21,23 @@
 Language/Libraries_and_Scripts/Scripts/main_optional_parameters_t03: SkipByDesign # https://github.com/dart-lang/co19/issues/952
 Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: SkipByDesign # binary '~' produces different results in JavaScript and Dart
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A01_t01: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A01_t02: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A01_t03: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A02_t01: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A02_t04: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t01: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t02: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t03: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t04: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t06: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A04_t01: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A04_t02: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A05_t01: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A05_t02: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/static_analysis_external_A05_t03: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/syntax_A01_t03: SkipByDesign # External variables are not supported by dart2js
+LanguageFeatures/Abstract-external-fields/syntax_A02_t03: SkipByDesign # External variables are not supported by dart2js
 LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecond_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
@@ -32,7 +49,7 @@
 LibTest/core/int/operator_truncating_division_A01_t02: SkipByDesign # Division by zero is not an error in JavaScript
 LibTest/core/int/parse_A01_t02: SkipByDesign # big integers cannot be represented in JavaScript
 LibTest/core/int/remainder_A01_t03: SkipByDesign # Division by zero is not an error in JavaScript
-LibTest/html/HttpRequest/*: Skip # https://github.com/dart-lang/co19/issues/932
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # https://github.com/dart-lang/co19/issues/932
 LibTest/html/HttpRequestUpload/*: Skip # https://github.com/dart-lang/co19/issues/932
 LibTest/io/*: SkipByDesign # dart:io not supported.
 LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
index 50a7573..776d905 100644
--- a/tests/co19/co19-dartdevc.status
+++ b/tests/co19/co19-dartdevc.status
@@ -85,7 +85,7 @@
 LibTest/core/int/remainder_A01_t03: SkipByDesign # Division by zero is not an error in JavaScript
 LibTest/html/Element/blur_A01_t01: Skip # Times out
 LibTest/html/Element/focus_A01_t01: Skip # Times out
-LibTest/html/HttpRequest/*: Skip # https://github.com/dart-lang/co19/issues/932
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # https://github.com/dart-lang/co19/issues/932
 LibTest/html/HttpRequestUpload/*: Skip # https://github.com/dart-lang/co19/issues/932
 LibTest/html/IFrameElement/blur_A01_t01: Skip # Times out
 LibTest/html/IFrameElement/focus_A01_t01: Skip # Times out
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index ee639b0..82030bb 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -13,155 +13,14 @@
 LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: Crash
 
 [ $runtime == dart_precompiled ]
-LibTest/io/Process/kill_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/run_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/start_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/start_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/start_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/start_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/start_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/start_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/stderr_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/stdin_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Process/stdout_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/ProcessSignal/watch_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/ProcessSignal/watch_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A02_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A02_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A03_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A04_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A04_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A04_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A04_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lockSync_A05_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A01_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A02_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A03_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A04_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A04_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A04_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A04_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/lock_A05_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlockSync_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlockSync_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlockSync_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlockSync_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlock_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlock_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlock_A01_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RandomAccessFile/unlock_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/join_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/join_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/join_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/multicastInterface_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/receive_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/reduce_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/reduce_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawDatagramSocket/reduce_A04_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/first_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/first_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/first_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/isEmpty_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/last_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/length_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/single_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/RawSecureServerSocket/single_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t05: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t06: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A01_t07: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/any_A04_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/first_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/first_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/first_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/first_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/first_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/isEmpty_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/isEmpty_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/isEmpty_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/isEmpty_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/last_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/last_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/length_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/length_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readByteSync_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readByteSync_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readByteSync_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readByteSync_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A03_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A04_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A05_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A05_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/readLineSync_A05_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdin/supportsAnsiEscapes_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/Stdout_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/addError_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/addError_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/addError_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/addError_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/addError_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/addStream_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t05: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t06: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t07: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t08: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A02_t09: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/add_A04_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/nonBlocking_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/supportsAnsiEscapes_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A02_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A02_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A02_t05: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeAll_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeCharCode_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeCharCode_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A01_t04: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A01_t05: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A01_t07: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/write_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeln_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeln_A01_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeln_A01_t03: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/Stdout/writeln_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/exit/exit_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/exit/exit_A02_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/exit/exit_A03_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/exit/exit_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/exitCode/exitCode_A01_t01: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/exitCode/exitCode_A03_t02: Skip # https://github.com/dart-lang/issues/926
-LibTest/io/stderr/stderr_A01_t01: Skip # https://github.com/dart-lang/issues/926
+LibTest/io/RawDatagramSocket/join_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/join_A01_t02: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/join_A02_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/multicastInterface_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/receive_A02_t02: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/reduce_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/reduce_A02_t02: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/reduce_A04_t01: Skip # https://github.com/dart-lang/co19/issues/195
 LibTest/mirrors/*: SkipByDesign # dart:mirrors is not supported:
 
 [ $runtime == vm ]
diff --git a/tests/corelib/regress_42011_test.dart b/tests/corelib/regress_42011_test.dart
new file mode 100644
index 0000000..45a9e81
--- /dev/null
+++ b/tests/corelib/regress_42011_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/42011
+main() {
+  var a = [];
+  // No elements are added, so should not get a ConcurrentModificationError.
+  a.addAll(a);
+}
diff --git a/tests/corelib_2/regress_42011_test.dart b/tests/corelib_2/regress_42011_test.dart
new file mode 100644
index 0000000..45a9e81
--- /dev/null
+++ b/tests/corelib_2/regress_42011_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/42011
+main() {
+  var a = [];
+  // No elements are added, so should not get a ConcurrentModificationError.
+  a.addAll(a);
+}
diff --git a/tests/dart2js/list_generate_1_test.dart b/tests/dart2js/list_generate_1_test.dart
new file mode 100644
index 0000000..1b2fb4d
--- /dev/null
+++ b/tests/dart2js/list_generate_1_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+dynamic function = 'function';
+dynamic growable = 'growable';
+dynamic length = 'length';
+
+// Use top level dynamic variables so this call is not lowered.  This function
+// and the callers (test1, test2) are not inlined to prevent store-forwarding of
+// the top-level variables.
+@pragma('dart2js:noInline')
+List<T> general<T>() => List<T>.generate(length, function, growable: growable);
+
+void main() {
+  function = (int i) => i;
+  growable = true;
+  length = 5;
+
+  test1();
+
+  int k = 0;
+  function = (int u) => seq3(u += 10, k += 100, () => u += k + 100000);
+  growable = false;
+  length = 5;
+
+  test2();
+}
+
+@pragma('dart2js:noInline')
+void test1() {
+  // Simple test.
+  final r1 = List<num>.generate(5, (i) => i, growable: true);
+  final r2 = general<num>();
+
+  Expect.equals('[0, 1, 2, 3, 4]', '$r1');
+  Expect.equals('[0, 1, 2, 3, 4]', '$r2');
+}
+
+// A sequence of two operations in expression form, returning the last value.
+T seq2<T>(dynamic a, T b) => b;
+T seq3<T>(dynamic a, dynamic b, T c) => c;
+
+@pragma('dart2js:noInline')
+void test2() {
+  // Test with a complex environment.
+  int c = 0;
+  final r1 = List<int Function()>.generate(
+    5,
+    (i) => seq3(i += 10, c += 100, () => i += c + 100000),
+    growable: false,
+  );
+  final r2 = general<int Function()>();
+
+  final e12 = r1[2];
+  final e22 = r2[2];
+
+  final s123 = [e12(), e12(), e12()];
+  final s223 = [e22(), e22(), e22()];
+
+  // 'i' is bound to the loop variable (2 for element at [2]).
+  // 'i' is incremented by 10, so the low digits are '12'
+  // 'c' is shared by all closures, and has been incremented to 500 at end of
+  // construction, so each call increments 'i' by 100500.
+  Expect.equals('[100512, 201012, 301512]', '$s123');
+  Expect.equals('[100512, 201012, 301512]', '$s123');
+}
diff --git a/tests/dart2js/list_generate_2_test.dart b/tests/dart2js/list_generate_2_test.dart
new file mode 100644
index 0000000..83487e5
--- /dev/null
+++ b/tests/dart2js/list_generate_2_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  test(0, '[]');
+  test(1, '[[[1]]]');
+  test(2, '[[[1]], [[2], [3, 4]]]');
+  test(3, '[[[1]], [[2], [3, 4]], [[5], [6, 7], [8, 9, 10]]]');
+}
+
+void test(int i, String expected) {
+  // Many nested closures with shadowing variables.
+  int c = 0;
+  final r = List.generate(
+      i, (i) => List.generate(i + 1, (i) => List.generate(i + 1, (i) => ++c)));
+
+  Expect.equals(expected, '$r');
+}
diff --git a/tests/dart2js/native/fake_thing_test.dart b/tests/dart2js/native/fake_thing_test.dart
index 0131821..542a5ca 100644
--- a/tests/dart2js/native/fake_thing_test.dart
+++ b/tests/dart2js/native/fake_thing_test.dart
@@ -26,13 +26,9 @@
 })()""");
 }
 
-inscrutable(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 0) {
-    return x;
-  } else {
-    return 42;
-  }
-}
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+inscrutable(x) => x;
 
 main() {
   setup();
diff --git a/tests/dart2js/native/name_conflict_test.dart b/tests/dart2js/native/name_conflict_test.dart
new file mode 100644
index 0000000..555c78e
--- /dev/null
+++ b/tests/dart2js/native/name_conflict_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for correct hidden native class when abstract class has same name.
+
+library main;
+
+import 'dart:_js_helper';
+import 'dart:_foreign_helper' show JS;
+
+import 'native_testing.dart';
+
+// 'I' is the name of an abstract class and the name of the native class.
+
+abstract class I {
+  I read();
+  write(I x);
+}
+
+// Native impl has same name as abstract class.
+@Native("I")
+class Impl implements I {
+  Impl read() native;
+  write(I x) native;
+}
+
+makeI() => JS('creates:Impl; returns:I;', 'makeI()');
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is all inside 'setup' and so not accessible from the global
+  // scope.
+  function I(){}
+  I.prototype.read = function() { return this._x; };
+  I.prototype.write = function(x) { this._x = x; };
+  makeI = function(){return new I()};
+  self.nativeConstructor(I);
+})()""");
+}
+
+// A pure Dart implementation of I.
+
+class ProxyI implements I {
+  ProxyI? b;
+  ProxyI read() {
+    return b!;
+  }
+
+  write(I x) {
+    b = x as ProxyI;
+  }
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeI();
+  var a2 = makeI();
+  var b1 = new ProxyI();
+  var b2 = new ProxyI();
+  var ob = new Object();
+
+  Expect.isFalse(ob is I, 'ob is I');
+  Expect.isFalse(ob is ProxyI, 'ob is ProxyI');
+
+  Expect.isTrue(b1 is I, 'b1 is I');
+  Expect.isTrue(b1 is ProxyI, 'b1 is ProxyI');
+
+  Expect.isTrue(a1 is I, 'a1 is I');
+  Expect.isFalse(a1 is ProxyI, 'a1 is ProxyI');
+
+  Expect.isTrue(confuse(a1) is I, 'a1 is I');
+  Expect.isFalse(confuse(a1) is ProxyI, 'a1 is ProxyI');
+}
diff --git a/tests/dart2js/native/native_library_same_name_used_frog_test.dart b/tests/dart2js/native/native_library_same_name_used_frog_test.dart
deleted file mode 100644
index 4909b7f..0000000
--- a/tests/dart2js/native/native_library_same_name_used_frog_test.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test for correct hidden native class when abstract class has same name.
-
-library main;
-
-import 'native_testing.dart';
-import 'native_library_same_name_used_lib1.dart';
-
-void setup() {
-  JS('', r"""
-(function(){
-  // This code is all inside 'setup' and so not accessible from the global
-  // scope.
-  function I(){}
-  I.prototype.read = function() { return this._x; };
-  I.prototype.write = function(x) { this._x = x; };
-  makeI = function(){return new I()};
-  self.nativeConstructor(I);
-})()""");
-}
-
-// A pure Dart implementation of I.
-
-class ProxyI implements I {
-  ProxyI b;
-  ProxyI read() {
-    return b;
-  }
-
-  write(ProxyI x) {
-    b = x;
-  }
-}
-
-main() {
-  nativeTesting();
-  setup();
-
-  var a1 = makeI();
-  var a2 = makeI();
-  var b1 = new ProxyI();
-  var b2 = new ProxyI();
-  var ob = new Object();
-
-  Expect.isFalse(ob is I, 'ob is I');
-  Expect.isFalse(ob is ProxyI, 'ob is ProxyI');
-
-  Expect.isTrue(b1 is I, 'b1 is I');
-  Expect.isTrue(b1 is ProxyI, 'b1 is ProxyI');
-
-  Expect.isTrue(a1 is I, 'a1 is I');
-  Expect.isFalse(a1 is ProxyI, 'a1 is ProxyI');
-
-  Expect.isTrue(confuse(a1) is I, 'a1 is I');
-  Expect.isFalse(confuse(a1) is ProxyI, 'a1 is ProxyI');
-}
diff --git a/tests/dart2js/native/native_library_same_name_used_lib1.dart b/tests/dart2js/native/native_library_same_name_used_lib1.dart
deleted file mode 100644
index 5046ff7..0000000
--- a/tests/dart2js/native/native_library_same_name_used_lib1.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// 'I' is the name of an abstract class and the name of the native class.
-
-library native_library_same_name_used_lib1;
-
-import 'native_library_same_name_used_lib2.dart';
-import 'dart:_foreign_helper' show JS;
-
-abstract class I {
-  I read();
-  write(I x);
-}
-
-makeI() => JS('creates:Impl; returns:I;', 'makeI()');
diff --git a/tests/dart2js/native/native_library_same_name_used_lib2.dart b/tests/dart2js/native/native_library_same_name_used_lib2.dart
deleted file mode 100644
index feec6bb..0000000
--- a/tests/dart2js/native/native_library_same_name_used_lib2.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Native implementation.
-
-library lib2;
-
-import 'native_library_same_name_used_lib1.dart'; // To get abstract class I.
-import 'dart:_js_helper';
-
-// Native impl has same name as abstract class.
-@Native("I")
-class Impl implements I {
-  Impl read() native;
-  write(Impl x) native;
-}
diff --git a/tests/dart2js_2/native/fake_thing_test.dart b/tests/dart2js_2/native/fake_thing_test.dart
index 8e1ca18..63fda12 100644
--- a/tests/dart2js_2/native/fake_thing_test.dart
+++ b/tests/dart2js_2/native/fake_thing_test.dart
@@ -28,13 +28,9 @@
 })()""");
 }
 
-inscrutable(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 0) {
-    return x;
-  } else {
-    return 42;
-  }
-}
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+inscrutable(x) => x;
 
 main() {
   setup();
diff --git a/tests/dart2js_2/native/name_conflict_test.dart b/tests/dart2js_2/native/name_conflict_test.dart
new file mode 100644
index 0000000..d39bf3b
--- /dev/null
+++ b/tests/dart2js_2/native/name_conflict_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.7
+
+// Test for correct hidden native class when abstract class has same name.
+
+library main;
+
+import 'dart:_js_helper';
+import 'dart:_foreign_helper' show JS;
+
+import 'native_testing.dart';
+
+// 'I' is the name of an abstract class and the name of the native class.
+
+abstract class I {
+  I read();
+  write(I x);
+}
+
+// Native impl has same name as abstract class.
+@Native("I")
+class Impl implements I {
+  Impl read() native;
+  write(I x) native;
+}
+
+makeI() => JS('creates:Impl; returns:I;', 'makeI()');
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is all inside 'setup' and so not accessible from the global
+  // scope.
+  function I(){}
+  I.prototype.read = function() { return this._x; };
+  I.prototype.write = function(x) { this._x = x; };
+  makeI = function(){return new I()};
+  self.nativeConstructor(I);
+})()""");
+}
+
+// A pure Dart implementation of I.
+
+class ProxyI implements I {
+  ProxyI b;
+  ProxyI read() {
+    return b;
+  }
+
+  write(I x) {
+    b = x;
+  }
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeI();
+  var a2 = makeI();
+  var b1 = new ProxyI();
+  var b2 = new ProxyI();
+  var ob = new Object();
+
+  Expect.isFalse(ob is I, 'ob is I');
+  Expect.isFalse(ob is ProxyI, 'ob is ProxyI');
+
+  Expect.isTrue(b1 is I, 'b1 is I');
+  Expect.isTrue(b1 is ProxyI, 'b1 is ProxyI');
+
+  Expect.isTrue(a1 is I, 'a1 is I');
+  Expect.isFalse(a1 is ProxyI, 'a1 is ProxyI');
+
+  Expect.isTrue(confuse(a1) is I, 'a1 is I');
+  Expect.isFalse(confuse(a1) is ProxyI, 'a1 is ProxyI');
+}
diff --git a/tests/dart2js_2/native/native_library_same_name_used_frog_test.dart b/tests/dart2js_2/native/native_library_same_name_used_frog_test.dart
deleted file mode 100644
index 974bf07..0000000
--- a/tests/dart2js_2/native/native_library_same_name_used_frog_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart = 2.7
-
-// Test for correct hidden native class when abstract class has same name.
-
-library main;
-
-import 'native_testing.dart';
-import 'native_library_same_name_used_lib1.dart';
-
-void setup() {
-  JS('', r"""
-(function(){
-  // This code is all inside 'setup' and so not accessible from the global
-  // scope.
-  function I(){}
-  I.prototype.read = function() { return this._x; };
-  I.prototype.write = function(x) { this._x = x; };
-  makeI = function(){return new I()};
-  self.nativeConstructor(I);
-})()""");
-}
-
-// A pure Dart implementation of I.
-
-class ProxyI implements I {
-  ProxyI b;
-  ProxyI read() {
-    return b;
-  }
-
-  write(ProxyI x) {
-    b = x;
-  }
-}
-
-main() {
-  nativeTesting();
-  setup();
-
-  var a1 = makeI();
-  var a2 = makeI();
-  var b1 = new ProxyI();
-  var b2 = new ProxyI();
-  var ob = new Object();
-
-  Expect.isFalse(ob is I, 'ob is I');
-  Expect.isFalse(ob is ProxyI, 'ob is ProxyI');
-
-  Expect.isTrue(b1 is I, 'b1 is I');
-  Expect.isTrue(b1 is ProxyI, 'b1 is ProxyI');
-
-  Expect.isTrue(a1 is I, 'a1 is I');
-  Expect.isFalse(a1 is ProxyI, 'a1 is ProxyI');
-
-  Expect.isTrue(confuse(a1) is I, 'a1 is I');
-  Expect.isFalse(confuse(a1) is ProxyI, 'a1 is ProxyI');
-}
diff --git a/tests/dart2js_2/native/native_library_same_name_used_lib1.dart b/tests/dart2js_2/native/native_library_same_name_used_lib1.dart
deleted file mode 100644
index 9e21adf..0000000
--- a/tests/dart2js_2/native/native_library_same_name_used_lib1.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart = 2.7
-
-// 'I' is the name of an abstract class and the name of the native class.
-
-library native_library_same_name_used_lib1;
-
-import 'native_library_same_name_used_lib2.dart';
-import 'dart:_foreign_helper' show JS;
-
-abstract class I {
-  I read();
-  write(I x);
-}
-
-makeI() => JS('creates:Impl; returns:I;', 'makeI()');
diff --git a/tests/dart2js_2/native/native_library_same_name_used_lib2.dart b/tests/dart2js_2/native/native_library_same_name_used_lib2.dart
deleted file mode 100644
index bec6852..0000000
--- a/tests/dart2js_2/native/native_library_same_name_used_lib2.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart = 2.7
-
-// Native implementation.
-
-library lib2;
-
-import 'native_library_same_name_used_lib1.dart'; // To get abstract class I.
-import 'dart:_js_helper';
-
-// Native impl has same name as abstract class.
-@Native("I")
-class Impl implements I {
-  Impl read() native;
-  write(Impl x) native;
-}
diff --git a/tests/dartdevc/debugger/debugger_test.dart b/tests/dartdevc/debugger/debugger_test.dart
index 79b12a1..b92bc8d 100644
--- a/tests/dartdevc/debugger/debugger_test.dart
+++ b/tests/dartdevc/debugger/debugger_test.dart
@@ -127,7 +127,7 @@
   // Cache blocker is a workaround for:
   // https://code.google.com/p/dart/issues/detail?id=11834
   var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
-  var goldenUrl = '/root_dart/tests/dartdevc_2/debugger/'
+  var goldenUrl = '/root_dart/tests/dartdevc/debugger/'
       'debugger_test_golden.txt?cacheBlock=$cacheBlocker';
 
   String? golden;
@@ -324,7 +324,7 @@
     if (actualStr != golden) {
       var helpMessage =
           'Debugger output does not match the golden data found in:\n'
-          'tests/dartdevc_2/debugger/debugger_test_golden.txt\n'
+          'tests/dartdevc/debugger/debugger_test_golden.txt\n'
           'The new golden data is copied to the clipboard when you click on '
           'this window.\n'
           'Please update the golden file with the following output and review '
@@ -352,12 +352,6 @@
         }
       });
     }
-    // TODO(vsm): This comparison appears to be badly broken for several
-    // reasons:
-    //   (1) The golden file isn't properly read on the bots or locally (see try
-    //       / catch above).
-    //   (2) The actual string appears to vary locally vs on the bots.
-    //   (3) Because of (2), visualizing the diff is difficult.
-    // expect(actualStr == golden, isTrue);
+    expect(actualStr == golden, isTrue);
   });
 }
diff --git a/tests/dartdevc/debugger/debugger_test_golden.txt b/tests/dartdevc/debugger/debugger_test_golden.txt
new file mode 100644
index 0000000..76772be
--- /dev/null
+++ b/tests/dartdevc/debugger/debugger_test_golden.txt
@@ -0,0 +1,6751 @@
+Test: List<String> formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "List<String> length 3"
+]
+-----------------------------------
+Test: List<String> formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "0: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "foo"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "1: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "bar"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "2: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "baz"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: List<Object> instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "List<Object> length 3"
+]
+-----------------------------------
+Test: List<Object> instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "0: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "42"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "1: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "bar"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "2: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "true"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: List<Object> definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "List<Object> implements List<Object>, JSIndexable<Object>"
+]
+-----------------------------------
+Test: List<Object> definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "+: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "add: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "addAll: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "any: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "asMap: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "cast: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "checkGrowable: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "checkMutable: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "clear: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "contains: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "elementAt: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "every: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "expand: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "fillRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "firstWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "fold: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "followedBy: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "forEach: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "getRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "indexOf: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "indexWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "insert: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "insertAll: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "join: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lastIndexOf: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lastIndexWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lastWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "map: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "reduce: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "remove: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeAt: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeLast: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "replaceRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "retainWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "setAll: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "setRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "shuffle: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "singleWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "skip: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "skipWhile: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "sort: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "sublist: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "take: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "takeWhile: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "toList: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "toSet: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "where: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "whereType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_get: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_removeWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_set: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_setLengthUnsafe: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: List<int> large instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "List<int> length 200"
+]
+-----------------------------------
+Test: List<int> large instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": ""
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": ""
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: List<int> large definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "List<int> implements List<int>, JSIndexable<int>"
+]
+-----------------------------------
+Test: List<int> large definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "+: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "add: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "addAll: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "any: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "asMap: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "cast: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "checkGrowable: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "checkMutable: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "clear: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "contains: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "elementAt: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "every: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "expand: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "fillRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "firstWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "fold: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "followedBy: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "forEach: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "getRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "indexOf: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "indexWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "insert: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "insertAll: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "join: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lastIndexOf: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lastIndexWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lastWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "map: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "reduce: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "remove: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeAt: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeLast: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "removeWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "replaceRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "retainWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "setAll: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "setRange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "shuffle: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "singleWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "skip: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "skipWhile: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "sort: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "sublist: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "take: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "takeWhile: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "toList: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "toSet: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "where: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "whereType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_get: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_removeWhere: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_set: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_setLengthUnsafe: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Iterable instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "MappedListIterable<String, String> length 3"
+]
+-----------------------------------
+Test: Iterable instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "0: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "foofoofoofoofoo"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "1: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "barbarbarbarbar"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "2: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "bazbazbazbazbaz"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Iterable definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "MappedListIterable<String, String>"
+]
+-----------------------------------
+Test: Iterable definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "fold: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "map: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Set instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "_HashSet<dynamic> length 3"
+]
+-----------------------------------
+Test: Set instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "0: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "foo"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "1: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "42"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "2: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "true"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Set definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "_HashSet<dynamic> implements HashSet<dynamic>, LinkedHashSet<dynamic>"
+]
+-----------------------------------
+Test: Set definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "add: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "contains: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "lookup: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "remove: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_newSet: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_newSimilarSet: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Map<String, int> formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "IdentityMap<String, int> length 3"
+]
+-----------------------------------
+Test: Map<String, int> formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "0: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "1: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "2: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Map<dynamic, dynamic> instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "LinkedMap<dynamic, dynamic> length 3"
+]
+-----------------------------------
+Test: Map<dynamic, dynamic> instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "0: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "1: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "2: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Map<dynamic, dynamic> definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "LinkedMap<dynamic, dynamic>"
+]
+-----------------------------------
+Test: Map<dynamic, dynamic> definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "clear: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "remove: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_get: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_set: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Function formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "(int, int) => int"
+]
+-----------------------------------
+Test: Function formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "signature: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "(int, int) => int"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "JavaScript Function: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Function with functon arguments formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "(String, (Event$) => bool) => Null"
+]
+-----------------------------------
+Test: Function with functon arguments formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "signature: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "(String, (Event$) => bool) => Null"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "JavaScript Function: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: dart:html method
+Value:
+null
+-----------------------------------
+Test: Raw reference to dart constructor formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "TestClass"
+]
+-----------------------------------
+Test: Raw reference to dart constructor formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    }
+]
+-----------------------------------
+Test: Object formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "Instance of 'Object'"
+]
+-----------------------------------
+Test: Object formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "runtimeType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Type TestClass formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "TestClass"
+]
+-----------------------------------
+Test: Type TestClass formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    }
+]
+-----------------------------------
+Test: Type HttpRequest formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "HttpRequest"
+]
+-----------------------------------
+Test: Type HttpRequest formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    }
+]
+-----------------------------------
+Test: Test library Module header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "Library Module: debugger_test"
+]
+-----------------------------------
+Test: Test library Module body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": ""
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: Test library Module child 0 formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "<FILE>"
+]
+-----------------------------------
+Test: Test library Module child 0 formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "TestClass: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "TestGenericClass<dynamic, dynamic>: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "FormattedObject: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "replacer: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "format: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "extractNestedFormattedObjects: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "main: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "devtoolsFormatters: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: StackTrace formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "StackTrace"
+]
+-----------------------------------
+Test: StackTrace formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;background-color: thistle;color: rgb(196, 26, 22);"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "Error: Instance of 'Error'"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<FILE>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<FILE>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<FILE>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "main.next (<anonymous>)"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "<DART_SDK>"
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: TestClass instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "Instance of 'TestClass'"
+]
+-----------------------------------
+Test: TestClass instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "date: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "17"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "name: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "test class"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "runtimeType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "someInt: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "42"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "someObject: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "someString: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "Hello world"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: TestClass definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "TestClass"
+]
+-----------------------------------
+Test: TestClass definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "addOne: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "last: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "nameAndDate: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "returnObject: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: HttpRequest instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "[object XMLHttpRequest]"
+]
+-----------------------------------
+Test: HttpRequest instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "on: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onAbort: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onError: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onLoad: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onLoadEnd: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onLoadStart: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onProgress: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onReadyStateChange: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "onTimeout: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "readyState: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "0"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "response: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                ""
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "responseHeaders: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "responseText: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                ""
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "responseType: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                ""
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "responseUrl: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                ""
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "responseXml: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "runtimeType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "status: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "0"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "statusText: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                ""
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "timeout: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "0"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "upload: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "withCredentials: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "false"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "_get_response: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                ""
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: HttpRequest definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "HttpRequest"
+]
+-----------------------------------
+Test: HttpRequest definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "abort: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "getAllResponseHeaders: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "getResponseHeader: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "open: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "overrideMimeType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "send: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "setRequestHeader: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: TestGenericClass instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "Instance of 'TestGenericClass<int, List<dynamic>>'"
+]
+-----------------------------------
+Test: TestGenericClass instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+                },
+                "x: "
+            ],
+            [
+                "span",
+                {
+                    "style": "margin-left: 13px"
+                },
+                "42"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "runtimeType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: TestGenericClass definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "TestGenericClass<int, List<dynamic>>"
+]
+-----------------------------------
+Test: TestGenericClass definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "noSuchMethod: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "toString: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_equals: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: TestGenericClassJSInterop instance header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "Instance of 'TestGenericClass<JSObject<ExampleJSClass>, int>'"
+]
+-----------------------------------
+Test: TestGenericClassJSInterop instance body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "x: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "runtimeType: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
+Test: TestGenericClassJSInterop definition formatting header
+Value:
+[
+    "span",
+    {
+        "style": "background-color: #d9edf7;color: black"
+    },
+    "TestGenericClass<JSObject<ExampleJSClass>, int>"
+]
+-----------------------------------
+Test: TestGenericClassJSInterop definition formatting body
+Value:
+[
+    "ol",
+    {
+        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
+    },
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {},
+            [
+                "span",
+                {
+                    "style": ""
+                },
+                "[[Instance Methods]]"
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "noSuchMethod: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "toString: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "_equals: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ],
+    [
+        "li",
+        {
+            "style": "padding-left: 13px;"
+        },
+        [
+            "span",
+            {
+                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
+            },
+            "[[base class]]: "
+        ],
+        [
+            "span",
+            {
+                "style": "margin-left: 13px"
+            },
+            [
+                "object",
+                {
+                    "object": "<OBJECT>",
+                    "config": {}
+                }
+            ]
+        ]
+    ]
+]
+-----------------------------------
\ No newline at end of file
diff --git a/tests/dartdevc/weak_null_safety_errors_test.dart b/tests/dartdevc/weak_null_safety_errors_test.dart
new file mode 100644
index 0000000..b6663e9
--- /dev/null
+++ b/tests/dartdevc/weak_null_safety_errors_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+// dartdevcOptions=--weak-null-safety-errors
+
+import 'package:expect/expect.dart';
+
+void main() {
+  Expect.throwsTypeError(() => null as int);
+  dynamic dynamicNull = null;
+  Expect.throwsTypeError(() => fn(dynamicNull));
+}
+
+void fn(StringBuffer arg) {}
diff --git a/tests/dartdevc_2/debugger/debugger_test.dart b/tests/dartdevc_2/debugger/debugger_test.dart
index 062088f..94d4a63 100644
--- a/tests/dartdevc_2/debugger/debugger_test.dart
+++ b/tests/dartdevc_2/debugger/debugger_test.dart
@@ -354,12 +354,6 @@
         }
       });
     }
-    // TODO(vsm): This comparison appears to be badly broken for several
-    // reasons:
-    //   (1) The golden file isn't properly read on the bots or locally (see try
-    //       / catch above).
-    //   (2) The actual string appears to vary locally vs on the bots.
-    //   (3) Because of (2), visualizing the diff is difficult.
-    // expect(actualStr == golden, isTrue);
+    expect(actualStr == golden, isTrue);
   });
 }
diff --git a/tests/dartdevc_2/debugger/debugger_test_golden.txt b/tests/dartdevc_2/debugger/debugger_test_golden.txt
index 80f211d..76772be 100644
--- a/tests/dartdevc_2/debugger/debugger_test_golden.txt
+++ b/tests/dartdevc_2/debugger/debugger_test_golden.txt
@@ -4530,120 +4530,6 @@
                 }
             ]
         ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": ""
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": ""
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": ""
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": ""
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": ""
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": ""
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
     ]
 ]
 -----------------------------------
@@ -4874,2242 +4760,6 @@
     ]
 ]
 -----------------------------------
-Test: Test library Module child 1 formatting header
-Value:
-[
-    "span",
-    {
-        "style": "background-color: #d9edf7;color: black"
-    },
-    "<FILE>"
-]
------------------------------------
-Test: Test library Module child 1 formatting body
-Value:
-[
-    "ol",
-    {
-        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
-    },
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "JS: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Anonymous: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "anonymous: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ]
-]
------------------------------------
-Test: Test library Module child 2 formatting header
-Value:
-[
-    "span",
-    {
-        "style": "background-color: #d9edf7;color: black"
-    },
-    "<FILE>"
-]
------------------------------------
-Test: Test library Module child 2 formatting body
-Value:
-[
-    "ol",
-    {
-        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
-    }
-]
------------------------------------
-Test: Test library Module child 3 formatting header
-Value:
-[
-    "span",
-    {
-        "style": "background-color: #d9edf7;color: black"
-    },
-    "<FILE>"
-]
------------------------------------
-Test: Test library Module child 3 formatting body
-Value:
-[
-    "ol",
-    {
-        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
-    },
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Group: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Expectation: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "finishTests: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "group: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "test: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "setUp: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "tearDown: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "expect: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "fail: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "equals: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "notEquals: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "unorderedEquals: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "predicate: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "inInclusiveRange: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "greaterThan: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "same: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "closeTo: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "anyOf: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_defaultAction: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_groups: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "isFalse: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "isNotNull: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "isNull: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "isTrue: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "returnsNormally: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "throws: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "throwsArgumentError: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "throwsNoSuchMethodError: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "throwsRangeError: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "throwsStateError: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "throwsUnsupportedError: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ]
-]
------------------------------------
-Test: Test library Module child 4 formatting header
-Value:
-[
-    "span",
-    {
-        "style": "background-color: #d9edf7;color: black"
-    },
-    "<FILE>"
-]
------------------------------------
-Test: Test library Module child 4 formatting body
-Value:
-[
-    "ol",
-    {
-        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
-    },
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "Expect: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "ExpectException: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_identical: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {},
-            [
-                "span",
-                {
-                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-                },
-                "isWeakMode: "
-            ],
-            [
-                "span",
-                {
-                    "style": "margin-left: 13px"
-                },
-                "true"
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {},
-            [
-                "span",
-                {
-                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-                },
-                "isStrongMode: "
-            ],
-            [
-                "span",
-                {
-                    "style": "margin-left: 13px"
-                },
-                "false"
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {},
-            [
-                "span",
-                {
-                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-                },
-                "typeAssertionsEnabled: "
-            ],
-            [
-                "span",
-                {
-                    "style": "margin-left: 13px"
-                },
-                "true"
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {},
-            [
-                "span",
-                {
-                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-                },
-                "assertStatementsEnabled: "
-            ],
-            [
-                "span",
-                {
-                    "style": "margin-left: 13px"
-                },
-                "true"
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {},
-            [
-                "span",
-                {
-                    "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-                },
-                "checkedModeEnabled: "
-            ],
-            [
-                "span",
-                {
-                    "style": "margin-left: 13px"
-                },
-                "true"
-            ]
-        ]
-    ]
-]
------------------------------------
-Test: Test library Module child 5 formatting header
-Value:
-[
-    "span",
-    {
-        "style": "background-color: #d9edf7;color: black"
-    },
-    "<FILE>"
-]
------------------------------------
-Test: Test library Module child 5 formatting body
-Value:
-[
-    "ol",
-    {
-        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
-    },
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "Immutable: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "Required: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_AlwaysThrows: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Checked: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_DoNotStore: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Experimental: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Factory: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Internal: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_IsTest: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_IsTestGroup: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Literal: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_MustCallSuper: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_NonVirtual: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_OptionalTypeArgs: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Protected: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Sealed: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_Virtual: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_VisibleForOverriding: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "_VisibleForTesting: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "alwaysThrows: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "checked: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "doNotStore: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "experimental: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "factory: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "immutable: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "internal: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "isTest: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "isTestGroup: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "literal: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "mustCallSuper: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "nonVirtual: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "optionalTypeArgs: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "protected: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "required: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "sealed: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "virtual: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "visibleForOverriding: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "visibleForTesting: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ]
-]
------------------------------------
-Test: Test library Module child 6 formatting header
-Value:
-[
-    "span",
-    {
-        "style": "background-color: #d9edf7;color: black"
-    },
-    "<FILE>"
-]
------------------------------------
-Test: Test library Module child 6 formatting body
-Value:
-[
-    "ol",
-    {
-        "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;"
-    },
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "Target: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ],
-    [
-        "li",
-        {
-            "style": "padding-left: 13px;"
-        },
-        [
-            "span",
-            {
-                "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px"
-            },
-            "TargetKind: "
-        ],
-        [
-            "span",
-            {
-                "style": "margin-left: 13px"
-            },
-            [
-                "object",
-                {
-                    "object": "<OBJECT>",
-                    "config": {}
-                }
-            ]
-        ]
-    ]
-]
------------------------------------
 Test: StackTrace formatting header
 Value:
 [
diff --git a/tests/ffi/function_test.dart b/tests/ffi/function_test.dart
index 376711b..bff456e 100644
--- a/tests/ffi/function_test.dart
+++ b/tests/ffi/function_test.dart
@@ -69,13 +69,22 @@
 
 void testNativeFunctionFromLookup() {
   Expect.equals(49, sumPlus42(3, 4));
+  Expect.equals(49, (sumPlus42 as dynamic)(3, 4));
+  Expect.throwsNoSuchMethodError(() => (sumPlus42 as dynamic)());
+  Expect.throwsTypeError(() => (sumPlus42 as dynamic)(3, 4.0));
 
   Expect.equals(625, intComputation(125, 250, 500, 1000));
+  Expect.equals(625, (intComputation as dynamic)(125, 250, 500, 1000));
 
   Expect.equals(
       0x7FFFFFFFFFFFFFFF, intComputation(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
   Expect.equals(
       -0x8000000000000000, intComputation(0, 0, 0, -0x8000000000000000));
+
+  Expect.equals(0x7FFFFFFFFFFFFFFF,
+      (intComputation as dynamic)(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
+  Expect.equals(-0x8000000000000000,
+      (intComputation as dynamic)(0, 0, 0, -0x8000000000000000));
 }
 
 typedef NativeReturnMaxUint8 = Uint8 Function();
diff --git a/tests/ffi/regress_jump_to_frame_test.dart b/tests/ffi/regress_jump_to_frame_test.dart
new file mode 100644
index 0000000..a3d9054
--- /dev/null
+++ b/tests/ffi/regress_jump_to_frame_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that JumpToFrame does not use LR clobbered by slow path of
+// TransitionNativeToGenerated.
+// VMOptions=--use-slow-path --enable-testing-pragmas
+
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+import 'package:expect/expect.dart';
+
+typedef CallbackDartType = Object Function();
+typedef CallbackNativeType = Handle Function();
+
+Object alwaysThrows() {
+  throw 'exception';
+}
+
+void alwaysCatches(CallbackDartType f) {
+  try {
+    propagateError(f());
+  } catch (e) {
+    Expect.equals('exception', e);
+    return;
+  }
+  Expect.isTrue(false);
+}
+
+void main() {
+  final ptr = Pointer.fromFunction<CallbackNativeType>(alwaysThrows);
+  final f = ptr.asFunction<CallbackDartType>();
+  alwaysCatches(f);
+}
+
+typedef Dart_PropagateError_NativeType = Void Function(Handle);
+typedef Dart_PropagateError_DartType = void Function(Object);
+
+final Dart_PropagateError_DartType propagateError = () {
+  final Pointer<_DartApi> dlapi = NativeApi.initializeApiDLData.cast();
+  for (int i = 0; dlapi.ref.functions[i].name != nullptr; i++) {
+    final name = Utf8.fromUtf8(dlapi.ref.functions[i].name.cast<Utf8>());
+    if (name == 'Dart_PropagateError') {
+      return dlapi.ref.functions[i].function
+          .cast<NativeFunction<Dart_PropagateError_NativeType>>()
+          .asFunction<Dart_PropagateError_DartType>();
+    }
+  }
+  throw 'Not found';
+}();
+
+class _DartEntry extends Struct {
+  external Pointer<Int8> name;
+  external Pointer<Void> function;
+}
+
+class _DartApi extends Struct {
+  @Int32()
+  external int major;
+  @Int32()
+  external int minor;
+  external Pointer<_DartEntry> functions;
+}
diff --git a/tests/ffi_2/function_test.dart b/tests/ffi_2/function_test.dart
index 376711b..bff456e 100644
--- a/tests/ffi_2/function_test.dart
+++ b/tests/ffi_2/function_test.dart
@@ -69,13 +69,22 @@
 
 void testNativeFunctionFromLookup() {
   Expect.equals(49, sumPlus42(3, 4));
+  Expect.equals(49, (sumPlus42 as dynamic)(3, 4));
+  Expect.throwsNoSuchMethodError(() => (sumPlus42 as dynamic)());
+  Expect.throwsTypeError(() => (sumPlus42 as dynamic)(3, 4.0));
 
   Expect.equals(625, intComputation(125, 250, 500, 1000));
+  Expect.equals(625, (intComputation as dynamic)(125, 250, 500, 1000));
 
   Expect.equals(
       0x7FFFFFFFFFFFFFFF, intComputation(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
   Expect.equals(
       -0x8000000000000000, intComputation(0, 0, 0, -0x8000000000000000));
+
+  Expect.equals(0x7FFFFFFFFFFFFFFF,
+      (intComputation as dynamic)(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
+  Expect.equals(-0x8000000000000000,
+      (intComputation as dynamic)(0, 0, 0, -0x8000000000000000));
 }
 
 typedef NativeReturnMaxUint8 = Uint8 Function();
diff --git a/tests/ffi_2/regress_jump_to_frame_test.dart b/tests/ffi_2/regress_jump_to_frame_test.dart
new file mode 100644
index 0000000..9838443
--- /dev/null
+++ b/tests/ffi_2/regress_jump_to_frame_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that JumpToFrame does not use LR clobbered by slow path of
+// TransitionNativeToGenerated.
+// VMOptions=--use-slow-path --enable-testing-pragmas
+
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+import 'package:expect/expect.dart';
+
+typedef CallbackDartType = Object Function();
+typedef CallbackNativeType = Handle Function();
+
+Object alwaysThrows() {
+  throw 'exception';
+}
+
+void alwaysCatches(CallbackDartType f) {
+  try {
+    propagateError(f());
+  } catch (e) {
+    Expect.equals('exception', e);
+    return;
+  }
+  Expect.isTrue(false);
+}
+
+void main() {
+  final ptr = Pointer.fromFunction<CallbackNativeType>(alwaysThrows);
+  final f = ptr.asFunction<CallbackDartType>();
+  alwaysCatches(f);
+}
+
+typedef Dart_PropagateError_NativeType = Void Function(Handle);
+typedef Dart_PropagateError_DartType = void Function(Object);
+
+final Dart_PropagateError_DartType propagateError = () {
+  final Pointer<_DartApi> dlapi = NativeApi.initializeApiDLData.cast();
+  for (int i = 0; dlapi.ref.functions[i].name != nullptr; i++) {
+    final name = Utf8.fromUtf8(dlapi.ref.functions[i].name.cast<Utf8>());
+    if (name == 'Dart_PropagateError') {
+      return dlapi.ref.functions[i].function
+          .cast<NativeFunction<Dart_PropagateError_NativeType>>()
+          .asFunction<Dart_PropagateError_DartType>();
+    }
+  }
+  throw 'Not found';
+}();
+
+class _DartEntry extends Struct {
+  Pointer<Int8> name;
+  Pointer<Void> function;
+}
+
+class _DartApi extends Struct {
+  @Int32()
+  int major;
+  @Int32()
+  int minor;
+  Pointer<_DartEntry> functions;
+}
diff --git a/tests/language/async/return_throw_test.dart b/tests/language/async/return_throw_test.dart
new file mode 100644
index 0000000..43c9271
--- /dev/null
+++ b/tests/language/async/return_throw_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+Future<String> f() async {
+  throw 'f';
+}
+
+Future<String> g() async {
+  try {
+    // Should obtain the `Future<String>`, await it, then throw.
+    return f();
+  } catch (e) {
+    // Having caught the exception, we return a value.
+    return 'g';
+  }
+}
+
+void main() async {
+  Expect.equals('g', await g());
+}
diff --git a/tests/language/cascade/cascade_test.dart b/tests/language/cascade/cascade_test.dart
index 7e674f5..f9ddcd2 100644
--- a/tests/language/cascade/cascade_test.dart
+++ b/tests/language/cascade/cascade_test.dart
@@ -92,12 +92,8 @@
   // ^^
   // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
   // [cfe] Expected an identifier, but got '37'.
-  // [error line 91, column 8, length 0]
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
   a.."foo";
   // ^^^^^
   // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
   // [cfe] Expected an identifier, but got '"foo"'.
-  // [error line 97, column 11, length 0]
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
 }
diff --git a/tests/language/closure/dynamic_test.dart b/tests/language/closure/dynamic_test.dart
new file mode 100644
index 0000000..eb954ec
--- /dev/null
+++ b/tests/language/closure/dynamic_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Test that dynamic invocation of closures works as expected, including
+// appropriate type checks.
+//
+// VMOptions=--lazy-dispatchers
+// VMOptions=--no-lazy-dispatchers
+
+import 'package:expect/expect.dart';
+
+class A {
+  final int nonce_;
+
+  const A(this.nonce_);
+}
+
+class B {
+  final int nonce_;
+
+  const B(this.nonce_);
+}
+
+class C extends A {
+  const C(int nonce) : super(nonce);
+}
+
+void main() {
+  dynamic f = (String a1, int a2, A a3,
+      {String n1 = "default_named", int n2 = -1, A n3 = const A(-1)}) {};
+
+  f("test_fixed", 1, A(1), n1: "test_named", n2: 2, n3: A(2));
+
+  // Test named argument permutations
+  f("test_fixed", 1, A(1), n1: "test_named", n3: A(2), n2: 2);
+  f("test_fixed", 1, A(1), n2: 2, n1: "test_named", n3: A(2));
+  f("test_fixed", 1, A(1), n2: 2, n3: A(2), n1: "test_named");
+  f("test_fixed", 1, A(1), n3: A(2), n1: "test_named", n2: 2);
+  f("test_fixed", 1, A(1), n3: A(2), n2: 2, n1: "test_named");
+
+  // Test subclasses match the type
+  f("test_fixed", 1, C(1), n1: "test_named", n2: 2, n3: A(2));
+  f("test_fixed", 1, A(1), n1: "test_named", n2: 2, n3: C(2));
+
+  // Should fail with no such method errors
+  Expect.throwsNoSuchMethodError(() => f());
+  Expect.throwsNoSuchMethodError(() => f("test_fixed", 1, A(1), n4: 4));
+
+  // Should fail with type errors
+  Expect.throwsTypeError(
+      () => f(100, 1, A(1), n1: "test_named", n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1.1, A(1), n1: "test_named", n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, B(1), n1: "test_named", n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, A(1), n1: 100, n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, A(1), n1: "test_named", n2: 2.2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, A(1), n1: "test_named", n2: 2, n3: B(2)));
+}
diff --git a/tests/language/deferred/split_constants_canonicalization_a_1.dart b/tests/language/deferred/split_constants_canonicalization_a_1.dart
index ea054f5..d7bfcdb 100644
--- a/tests/language/deferred/split_constants_canonicalization_a_1.dart
+++ b/tests/language/deferred/split_constants_canonicalization_a_1.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000; // Boxed 64-bit integer on VM.
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language/deferred/split_constants_canonicalization_a_2.dart b/tests/language/deferred/split_constants_canonicalization_a_2.dart
index ea054f5..3d71a40 100644
--- a/tests/language/deferred/split_constants_canonicalization_a_2.dart
+++ b/tests/language/deferred/split_constants_canonicalization_a_2.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000;
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language/deferred/split_constants_canonicalization_b_1.dart b/tests/language/deferred/split_constants_canonicalization_b_1.dart
index ea054f5..3d71a40 100644
--- a/tests/language/deferred/split_constants_canonicalization_b_1.dart
+++ b/tests/language/deferred/split_constants_canonicalization_b_1.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000;
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language/deferred/split_constants_canonicalization_b_2.dart b/tests/language/deferred/split_constants_canonicalization_b_2.dart
index ea054f5..3d71a40 100644
--- a/tests/language/deferred/split_constants_canonicalization_b_2.dart
+++ b/tests/language/deferred/split_constants_canonicalization_b_2.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000;
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language/language.status b/tests/language/language.status
index b8da9a3..5739de1 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -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.
 
+[ $builder_tag == obfuscated ]
+nnbd/syntax/late_modifier_runtime_error_test: SkipByDesign # Names are obfuscated in error messages
+
 [ $compiler != dart2analyzer ]
 switch/case_warn_test: Skip # Analyzer only, see language_analyzer2.status
 
diff --git a/tests/language/metadata/metadata_builtin_test.dart b/tests/language/metadata/metadata_builtin_test.dart
new file mode 100644
index 0000000..aceec19
--- /dev/null
+++ b/tests/language/metadata/metadata_builtin_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that built-in identifiers can be used to specify metadata.
+
+const abstract = 0;
+const as = 0;
+const covariant = 0;
+const deferred = 0;
+const dynamic = 0;
+const export = 0;
+const external = 0;
+const factory = 0;
+const Function = 0;
+const get = 0;
+const implements = 0;
+const import = 0;
+const interface = 0;
+const late = 0;
+const library = 0;
+const mixin = 0;
+const operator = 0;
+const part = 0;
+const required = 0;
+const set = 0;
+const static = 0;
+const typedef = 0;
+
+@abstract
+@as
+@covariant
+@deferred
+@dynamic
+@export
+@external
+@factory
+@Function
+@get
+@implements
+@import
+@interface
+@late
+@library
+@mixin
+@operator
+@part
+@required
+@set
+@static
+@typedef
+void main(
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @late
+  @library
+  @mixin
+  @operator
+  @part
+  @required
+  @set
+  @static
+  @typedef
+      List<String> args,
+) {
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @late
+  @library
+  @mixin
+  @operator
+  @part
+  @required
+  @set
+  @static
+  @typedef
+  var x = true;
+
+  void f<
+      @abstract
+      @as
+      @covariant
+      @deferred
+      @dynamic
+      @export
+      @external
+      @factory
+      @Function
+      @get
+      @implements
+      @import
+      @interface
+      @late
+      @library
+      @mixin
+      @operator
+      @part
+      @required
+      @set
+      @static
+      @typedef
+          X>() {}
+}
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
index 7139036..5f7cd58 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
@@ -12,7 +12,7 @@
   dynamic f = func;
 
   // Invalid: Subtype may not redeclare optional parameters as required.
-  Expect.throws(() {
+  Expect.throwsTypeError(() {
     Function(
       String p0, {
       required int p1,
@@ -21,7 +21,7 @@
   });
 
   // Invalid: Subtype may not declare new required named parameters.
-  Expect.throws(() {
+  Expect.throwsTypeError(() {
     Function(
       String p0, {
       required int p1,
@@ -29,18 +29,18 @@
   });
 
   // Invalid: Invocation with explicit null required named argument.
-  Expect.throws(() {
+  Expect.throwsTypeError(() {
     f("", p1: null, p2: null);
   });
-  Expect.throws(() {
+  Expect.throwsTypeError(() {
     Function.apply(f, [""], {#p1: null, #p2: null});
   });
 
   // Invalid: Invocation that omits a required named argument.
-  Expect.throws(() {
+  Expect.throwsNoSuchMethodError(() {
     f("", p1: 100);
   });
-  Expect.throws(() {
+  Expect.throwsNoSuchMethodError(() {
     Function.apply(f, [""], {#p1: 100});
   });
 }
diff --git a/tests/language/nnbd/syntax/late_modifier_runtime_error_test.dart b/tests/language/nnbd/syntax/late_modifier_runtime_error_test.dart
new file mode 100644
index 0000000..c410775
--- /dev/null
+++ b/tests/language/nnbd/syntax/late_modifier_runtime_error_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class A {
+  static late int sf1;
+  static late final int sf2;
+  static late final int sf3 = recursiveInitSf3();
+
+  static bool doRecursiveInitSf3 = true;
+  static int recursiveInitSf3() {
+    if (doRecursiveInitSf3) {
+      doRecursiveInitSf3 = false;
+      return sf3; // Trigger initialization recursively.
+    }
+    return 3;
+  }
+
+  late int f1;
+  late final int f2;
+  late final int f3 = recursiveInitF3();
+
+  bool doRecursiveInitF3 = true;
+  int recursiveInitF3() {
+    if (doRecursiveInitF3) {
+      doRecursiveInitF3 = false;
+      return f3; // Trigger initialization recursively.
+    }
+    return 3;
+  }
+}
+
+bool isValidError(error, String message) {
+  if (error is LateInitializationError) {
+    Expect.equals('LateInitializationError: $message', error.toString());
+    return true;
+  }
+  return false;
+}
+
+main() {
+  // Static fields.
+
+  Expect.throws(() => A.sf1,
+      (e) => isValidError(e, "Field 'sf1' has not been initialized."));
+  Expect.throws(() => A.sf2,
+      (e) => isValidError(e, "Field 'sf2' has not been initialized."));
+  A.sf2 = 42;
+  Expect.throws(() {
+    A.sf2 = 2;
+  }, (e) => isValidError(e, "Field 'sf2' has already been initialized."));
+  Expect.throws(
+      () => A.sf3,
+      (e) => isValidError(
+          e, "Field 'sf3' has been assigned during initialization."));
+
+  // Instance fields.
+
+  A obj = A();
+  Expect.throws(() => obj.f1,
+      (e) => isValidError(e, "Field 'f1' has not been initialized."));
+  Expect.throws(() => obj.f2,
+      (e) => isValidError(e, "Field 'f2' has not been initialized."));
+  obj.f2 = 42;
+  Expect.throws(() {
+    obj.f2 = 2;
+  }, (e) => isValidError(e, "Field 'f2' has already been initialized."));
+  Expect.throws(
+      () => obj.f3,
+      (e) => isValidError(
+          e, "Field 'f3' has been assigned during initialization."));
+
+  // Local variables.
+  late int local1;
+  late final int local2;
+
+  late int Function() recursiveInitLocal3;
+  late final int local3 = recursiveInitLocal3();
+
+  bool doRecursiveInitLocal3 = true;
+  recursiveInitLocal3 = () {
+    if (doRecursiveInitLocal3) {
+      doRecursiveInitLocal3 = false;
+      return local3; // Trigger initialization recursively.
+    }
+    return 3;
+  };
+
+  // Avoid compile-time error "Late variable 'local1' without initializer is
+  // definitely unassigned."
+  if (int.parse('1') == 2) {
+    local1 = -1;
+  }
+
+  Expect.throws(() => local1,
+      (e) => isValidError(e, "Local 'local1' has not been initialized."));
+  Expect.throws(() => local2,
+      (e) => isValidError(e, "Local 'local2' has not been initialized."));
+  // Assignment is conditional to avoid compile-time error "Late final variable
+  // 'local2' definitely assigned."
+  if (int.parse('1') == 1) {
+    local2 = 42;
+  }
+  Expect.throws(() {
+    local2 = 2;
+  }, (e) => isValidError(e, "Local 'local2' has already been initialized."));
+  Expect.throws(
+      () => local3,
+      (e) => isValidError(
+          e, "Local 'local3' has been assigned during initialization."));
+}
diff --git a/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index 08a79ad..ab8a449 100644
--- a/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -5,6 +5,9 @@
 // Testing that `noSuchMethod` forwarding properly handles optional, named and
 // type parameters, and result type checking.
 
+// VMOptions=--lazy-dispatchers
+// VMOptions=--no-lazy-dispatchers
+
 import 'package:expect/expect.dart';
 
 class A {
@@ -48,6 +51,16 @@
     } else if (invoke.memberName == #test8) {
       Expect.equals(1, invoke.positionalArguments.length);
       Expect.equals(null, invoke.positionalArguments[0]);
+    } else if (invoke.memberName == #test9) {
+      Expect.equals(invoke.typeArguments.length, 2);
+      Expect.equals(invoke.typeArguments[0].toString(), "num");
+      Expect.equals(invoke.typeArguments[1].toString(), "double");
+
+      Expect.equals(1, invoke.positionalArguments.length);
+      Expect.equals(4.2, invoke.positionalArguments[0]);
+
+      Expect.equals(1, invoke.namedArguments.length);
+      Expect.equals(3, invoke.namedArguments[#foo]);
     }
   }
 
@@ -63,6 +76,7 @@
   void set test7(int x);
 
   void test8([String? x]);
+  void test9<T, S extends T>(S x1, {T? foo});
 
   T allTogetherNow<T, S extends T>(S x1, {List<T> foo: const <Never>[]});
 }
@@ -97,6 +111,25 @@
   Expect.throwsTypeError(() => (a as dynamic).test7 = "hi");
 
   a.allTogetherNow<num, double>(2.0, foo: const <num>[3, 4]);
+  Expect.throwsTypeError(() =>
+      (a.allTogetherNow as dynamic)<int, double>(2.0, foo: const <num>[3, 4]));
+  Expect.throwsTypeError(() =>
+      (a.allTogetherNow as dynamic)<int, int>(2.0, foo: const <num>[3, 4]));
+  Expect.throwsTypeError(() => (a.allTogetherNow
+      as dynamic)<double, double>(2.0, foo: const <int>[3, 4]));
 
   a.test8();
+
+  a.test9<num, double>(4.2, foo: 3);
+  Expect.throwsTypeError(() => (a.test9 as dynamic)<int, double>(3, foo: 3));
+  Expect.throwsTypeError(
+      () => (a.test9 as dynamic)<double, double>(3, foo: 3.2));
+  // Added to check that uses of positions from the ArgumentsDescriptor in the
+  // VM properly offsets named argument positions if there are also type
+  // arguments. allTogetherNow doesn't work for this because the runtime type of
+  // the positional argument cannot be the same as the type of the named
+  // argument without the positional argument failing to match its own type,
+  // and positional argument types are usually checked first.
+  Expect.throwsTypeError(
+      () => (a.test9 as dynamic)<int, double>(4.2, foo: 3.2));
 }
diff --git a/tests/language/parameter/initializer6_test.dart b/tests/language/parameter/initializer6_test.dart
index 9a5ebda..117a0c3 100644
--- a/tests/language/parameter/initializer6_test.dart
+++ b/tests/language/parameter/initializer6_test.dart
@@ -9,7 +9,7 @@
 class Foo {
   num _y;
   Foo.private({this._y: 77}) {}
-  //           ^^^^^^^
+  //                ^^
   // [analyzer] COMPILE_TIME_ERROR.PRIVATE_OPTIONAL_PARAMETER
   //                ^
   // [cfe] An optional named parameter can't start with '_'.
diff --git a/tests/language/regress/regress33479_test.dart b/tests/language/regress/regress33479_test.dart
index f1e8336..cb07911 100644
--- a/tests/language/regress/regress33479_test.dart
+++ b/tests/language/regress/regress33479_test.dart
@@ -1,28 +1,16 @@
 class Hest<TypeX extends Fisk> {}
-//                       ^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND
 
 typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 462]
+// [error line 3, column 1, length 346]
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^
 // [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
-    <TypeY extends Hest>
-    //             ^^^^
-    // [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
-        ();
+    <TypeY extends Hest>();
 
 main() {
   Hest hest = new Hest();
-//^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
 //     ^
 // [cfe] A generic function type can't be used as a type argument.
-//            ^^^^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
 //                ^^^^
-// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
-//                ^^^^
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
 }
diff --git a/tests/language/regress/regress44136_test.dart b/tests/language/regress/regress44136_test.dart
new file mode 100644
index 0000000..99dfa35
--- /dev/null
+++ b/tests/language/regress/regress44136_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+typedef Foo = void Function<X extends dynamic>();
+typedef Bar = void Function<X extends Object?>();
+
+void main() {
+  Expect.notEquals(Foo, Bar);
+}
diff --git a/tests/language/stack_trace/stack_trace_test.dart b/tests/language/stack_trace/stack_trace_test.dart
index 5e4d7c6..b1e60a9 100644
--- a/tests/language/stack_trace/stack_trace_test.dart
+++ b/tests/language/stack_trace/stack_trace_test.dart
@@ -88,6 +88,7 @@
   var config = 0;
 
   @pragma("vm:entry-point") // Prevent obfuscation
+  @pragma("vm:never-inline") // Prevent inlining
   issue12940() {
     throw "Progy";
   }
@@ -121,7 +122,7 @@
       try {
         d();
       } catch (e, s) {
-        Expect.isTrue(s.toString().contains("issue12940"));
+        Expect.contains("issue12940", s.toString());
       }
     }
   }
diff --git a/tests/language/this/conditional_operator_test.dart b/tests/language/this/conditional_operator_test.dart
index cda4689..e03f998 100644
--- a/tests/language/this/conditional_operator_test.dart
+++ b/tests/language/this/conditional_operator_test.dart
@@ -21,7 +21,6 @@
     //^^^^^^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.INITIALIZER_FOR_NON_EXISTENT_FIELD
     // [error line 15, column 11, length 0]
-    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
     // [cfe] Expected '.' before this.
     //    ^^
     // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
diff --git a/tests/language/type_variable/scope_test.dart b/tests/language/type_variable/scope_test.dart
index 3be94a3..2a68d15 100644
--- a/tests/language/type_variable/scope_test.dart
+++ b/tests/language/type_variable/scope_test.dart
@@ -43,6 +43,8 @@
   // [cfe] Type variables can't be used in static members.
   //                 ^
   // [cfe] Verification of the generated program failed:
+  //                 ^
+  // [cfe] Verification of the generated program failed:
 
   static
   Foo<T>
diff --git a/tests/language/variable/illegal_initializer_test.dart b/tests/language/variable/illegal_initializer_test.dart
index 6924b69..3b8b083 100644
--- a/tests/language/variable/illegal_initializer_test.dart
+++ b/tests/language/variable/illegal_initializer_test.dart
@@ -45,7 +45,6 @@
       //   ^^^^
       // [analyzer] SYNTACTIC_ERROR.MISSING_ASSIGNMENT_IN_INITIALIZER
       // [error line 39, column 16, length 0]
-      // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
       // [cfe] Expected '.' before this.
       //       ^
       // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
diff --git a/tests/language/vm/causal_async_exception_stack2_test.dart b/tests/language/vm/causal_async_exception_stack2_test.dart
index 14c1efb..e3ddda0 100644
--- a/tests/language/vm/causal_async_exception_stack2_test.dart
+++ b/tests/language/vm/causal_async_exception_stack2_test.dart
@@ -1,9 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'package:async_helper/async_minitest.dart';
 
diff --git a/tests/language/vm/causal_async_exception_stack_test.dart b/tests/language/vm/causal_async_exception_stack_test.dart
index f4421c2..e9df0a7 100644
--- a/tests/language/vm/causal_async_exception_stack_test.dart
+++ b/tests/language/vm/causal_async_exception_stack_test.dart
@@ -1,6 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--lazy-async-stacks
 
 import 'package:async_helper/async_minitest.dart';
 
@@ -34,8 +36,8 @@
     } catch (e, st) {
       expect(
           h.stringContainsInOrder(st.toString(), [
-            'thrower', '.dart:10', // no auto-format.
-            'generator', '.dart:19', // no auto-format.
+            'thrower', '.dart:12', // no auto-format.
+            'generator', '.dart:21', // no auto-format.
             '<asynchronous suspension>', // no auto-format.
             'foo', '.dart', // no auto-format.
             'main',
@@ -72,8 +74,8 @@
     } catch (e, st) {
       expect(
           h.stringContainsInOrder(st.toString(), [
-            'thrower', '.dart:10', // no auto-format.
-            'main.<anonymous closure>', '.dart:71', // no auto-format.
+            'thrower', '.dart:12', // no auto-format.
+            'main.<anonymous closure>', '.dart:73', // no auto-format.
           ]),
           isTrue);
     }
diff --git a/tests/language_2/async/return_throw_test.dart b/tests/language_2/async/return_throw_test.dart
new file mode 100644
index 0000000..43c9271
--- /dev/null
+++ b/tests/language_2/async/return_throw_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+Future<String> f() async {
+  throw 'f';
+}
+
+Future<String> g() async {
+  try {
+    // Should obtain the `Future<String>`, await it, then throw.
+    return f();
+  } catch (e) {
+    // Having caught the exception, we return a value.
+    return 'g';
+  }
+}
+
+void main() async {
+  Expect.equals('g', await g());
+}
diff --git a/tests/language_2/cascade/cascade_test.dart b/tests/language_2/cascade/cascade_test.dart
index 7e674f5..f9ddcd2 100644
--- a/tests/language_2/cascade/cascade_test.dart
+++ b/tests/language_2/cascade/cascade_test.dart
@@ -92,12 +92,8 @@
   // ^^
   // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
   // [cfe] Expected an identifier, but got '37'.
-  // [error line 91, column 8, length 0]
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
   a.."foo";
   // ^^^^^
   // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
   // [cfe] Expected an identifier, but got '"foo"'.
-  // [error line 97, column 11, length 0]
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
 }
diff --git a/tests/language_2/closure/dynamic_test.dart b/tests/language_2/closure/dynamic_test.dart
new file mode 100644
index 0000000..b130a9b
--- /dev/null
+++ b/tests/language_2/closure/dynamic_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Test that dynamic invocation of closures works as expected, including
+// appropriate type checks.
+//
+// VMOptions=--lazy-dispatchers
+// VMOptions=--no-lazy-dispatchers
+
+import 'package:expect/expect.dart';
+
+class A {
+  final int nonce_;
+
+  A(this.nonce_);
+}
+
+class B {
+  final int nonce_;
+
+  B(this.nonce_);
+}
+
+class C extends A {
+  C(int nonce) : super(nonce);
+}
+
+void main() {
+  dynamic f = (String a1, int a2, A a3, {String n1, int n2, A n3}) {};
+
+  f("test_fixed", 1, A(1), n1: "test_named", n2: 2, n3: A(2));
+
+// Test named argument permutations
+  f("test_fixed", 1, A(1), n1: "test_named", n3: A(2), n2: 2);
+  f("test_fixed", 1, A(1), n2: 2, n1: "test_named", n3: A(2));
+  f("test_fixed", 1, A(1), n2: 2, n3: A(2), n1: "test_named");
+  f("test_fixed", 1, A(1), n3: A(2), n1: "test_named", n2: 2);
+  f("test_fixed", 1, A(1), n3: A(2), n2: 2, n1: "test_named");
+
+// Test subclasses match the type
+  f("test_fixed", 1, C(1), n1: "test_named", n2: 2, n3: A(2));
+  f("test_fixed", 1, A(1), n1: "test_named", n2: 2, n3: C(2));
+
+// Should fail with no such method errors
+  Expect.throwsNoSuchMethodError(() => f());
+  Expect.throwsNoSuchMethodError(() => f("test_fixed", 1, A(1), n4: 4));
+
+// Should fail with type errors
+  Expect.throwsTypeError(
+      () => f(100, 1, A(1), n1: "test_named", n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1.1, A(1), n1: "test_named", n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, B(1), n1: "test_named", n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, A(1), n1: 100, n2: 2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, A(1), n1: "test_named", n2: 2.2, n3: A(2)));
+  Expect.throwsTypeError(
+      () => f("test_fixed", 1, A(1), n1: "test_named", n2: 2, n3: B(2)));
+}
diff --git a/tests/language_2/deferred/split_constants_canonicalization_a_1.dart b/tests/language_2/deferred/split_constants_canonicalization_a_1.dart
index ea054f5..d7bfcdb 100644
--- a/tests/language_2/deferred/split_constants_canonicalization_a_1.dart
+++ b/tests/language_2/deferred/split_constants_canonicalization_a_1.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000; // Boxed 64-bit integer on VM.
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language_2/deferred/split_constants_canonicalization_a_2.dart b/tests/language_2/deferred/split_constants_canonicalization_a_2.dart
index ea054f5..3d71a40 100644
--- a/tests/language_2/deferred/split_constants_canonicalization_a_2.dart
+++ b/tests/language_2/deferred/split_constants_canonicalization_a_2.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000;
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language_2/deferred/split_constants_canonicalization_b_1.dart b/tests/language_2/deferred/split_constants_canonicalization_b_1.dart
index ea054f5..3d71a40 100644
--- a/tests/language_2/deferred/split_constants_canonicalization_b_1.dart
+++ b/tests/language_2/deferred/split_constants_canonicalization_b_1.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000;
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language_2/deferred/split_constants_canonicalization_b_2.dart b/tests/language_2/deferred/split_constants_canonicalization_b_2.dart
index ea054f5..3d71a40 100644
--- a/tests/language_2/deferred/split_constants_canonicalization_b_2.dart
+++ b/tests/language_2/deferred/split_constants_canonicalization_b_2.dart
@@ -5,7 +5,7 @@
 import "split_constants_canonicalization_test.dart";
 
 @pragma("vm:never-inline")
-mint() => 0x7FFFFFFFFFFFFFFF;
+mint() => 0x7FFFFFFFFFFFF000;
 
 @pragma("vm:never-inline")
 string() => "We all have identical strings";
diff --git a/tests/language_2/metadata/metadata_builtin_test.dart b/tests/language_2/metadata/metadata_builtin_test.dart
new file mode 100644
index 0000000..f5c346d
--- /dev/null
+++ b/tests/language_2/metadata/metadata_builtin_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that built-in identifiers can be used to specify metadata.
+
+const abstract = 0;
+const as = 0;
+const covariant = 0;
+const deferred = 0;
+const dynamic = 0;
+const export = 0;
+const external = 0;
+const factory = 0;
+const Function = 0;
+const get = 0;
+const implements = 0;
+const import = 0;
+const interface = 0;
+const library = 0;
+const mixin = 0;
+const operator = 0;
+const part = 0;
+const set = 0;
+const static = 0;
+const typedef = 0;
+
+@abstract
+@as
+@covariant
+@deferred
+@dynamic
+@export
+@external
+@factory
+@Function
+@get
+@implements
+@import
+@interface
+@library
+@mixin
+@operator
+@part
+@set
+@static
+@typedef
+void main(
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @library
+  @mixin
+  @operator
+  @part
+  @set
+  @static
+  @typedef
+      List<String> args,
+) {
+  @abstract
+  @as
+  @covariant
+  @deferred
+  @dynamic
+  @export
+  @external
+  @factory
+  @Function
+  @get
+  @implements
+  @import
+  @interface
+  @library
+  @mixin
+  @operator
+  @part
+  @set
+  @static
+  @typedef
+  var x = true;
+
+  void f<
+      @abstract
+      @as
+      @covariant
+      @deferred
+      @dynamic
+      @export
+      @external
+      @factory
+      @Function
+      @get
+      @implements
+      @import
+      @interface
+      @library
+      @mixin
+      @operator
+      @part
+      @set
+      @static
+      @typedef
+          X>() {}
+}
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index 01a59e7..3e42573 100644
--- a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -5,6 +5,9 @@
 // Testing that `noSuchMethod` forwarding properly handles optional, named and
 // type parameters, and result type checking.
 
+// VMOptions=--lazy-dispatchers
+// VMOptions=--no-lazy-dispatchers
+
 import 'package:expect/expect.dart';
 
 class A {
@@ -47,6 +50,16 @@
     } else if (invoke.memberName == #test8) {
       Expect.equals(1, invoke.positionalArguments.length);
       Expect.equals(null, invoke.positionalArguments[0]);
+    } else if (invoke.memberName == #test9) {
+      Expect.equals(invoke.typeArguments.length, 2);
+      Expect.equals(invoke.typeArguments[0].toString(), "num");
+      Expect.equals(invoke.typeArguments[1].toString(), "double");
+
+      Expect.equals(1, invoke.positionalArguments.length);
+      Expect.equals(4.2, invoke.positionalArguments[0]);
+
+      Expect.equals(1, invoke.namedArguments.length);
+      Expect.equals(3, invoke.namedArguments[#foo]);
     }
   }
 
@@ -62,6 +75,7 @@
   void set test7(int x);
 
   void test8([String x]);
+  void test9<T, S extends T>(S x1, {T foo});
 
   T allTogetherNow<T, S extends T>(S x1, {List<T> foo: const <Null>[]});
 }
@@ -96,6 +110,25 @@
   Expect.throwsTypeError(() => (a as dynamic).test7 = "hi");
 
   a.allTogetherNow<num, double>(2.0, foo: const <num>[3, 4]);
+  Expect.throwsTypeError(() =>
+      (a.allTogetherNow as dynamic)<int, double>(2.0, foo: const <num>[3, 4]));
+  Expect.throwsTypeError(() =>
+      (a.allTogetherNow as dynamic)<int, int>(2.0, foo: const <num>[3, 4]));
+  Expect.throwsTypeError(() => (a.allTogetherNow
+      as dynamic)<double, double>(2.0, foo: const <int>[3, 4]));
 
   a.test8();
+
+  a.test9<num, double>(4.2, foo: 3);
+  Expect.throwsTypeError(() => (a.test9 as dynamic)<int, double>(3, foo: 3));
+  Expect.throwsTypeError(
+      () => (a.test9 as dynamic)<double, double>(3, foo: 3.2));
+  // Added to check that uses of positions from the ArgumentsDescriptor in the
+  // VM properly offsets named argument positions if there are also type
+  // arguments. allTogetherNow doesn't work for this because the runtime type of
+  // the positional argument cannot be the same as the type of the named
+  // argument without the positional argument failing to match its own type,
+  // and positional argument types are usually checked first.
+  Expect.throwsTypeError(
+      () => (a.test9 as dynamic)<int, double>(4.2, foo: 3.2));
 }
diff --git a/tests/language_2/parameter/initializer6_test.dart b/tests/language_2/parameter/initializer6_test.dart
index 9a5ebda..117a0c3 100644
--- a/tests/language_2/parameter/initializer6_test.dart
+++ b/tests/language_2/parameter/initializer6_test.dart
@@ -9,7 +9,7 @@
 class Foo {
   num _y;
   Foo.private({this._y: 77}) {}
-  //           ^^^^^^^
+  //                ^^
   // [analyzer] COMPILE_TIME_ERROR.PRIVATE_OPTIONAL_PARAMETER
   //                ^
   // [cfe] An optional named parameter can't start with '_'.
diff --git a/tests/language_2/regress/regress33479_test.dart b/tests/language_2/regress/regress33479_test.dart
index b1225c3..cb07911 100644
--- a/tests/language_2/regress/regress33479_test.dart
+++ b/tests/language_2/regress/regress33479_test.dart
@@ -1,28 +1,16 @@
 class Hest<TypeX extends Fisk> {}
-//                       ^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND
 
 typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 462]
+// [error line 3, column 1, length 346]
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^
 // [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
-    <TypeY extends Hest>
-    //             ^^^^
-    // [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
-        ();
+    <TypeY extends Hest>();
 
 main() {
   Hest hest = new Hest();
-//^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
 //     ^
 // [cfe] A generic function type can't be used as a type argument.
-//            ^^^^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_CAST_NEW_EXPR
 //                ^^^^
-// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
-//                ^^^^
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
 }
diff --git a/tests/language_2/regress/regress44136_test.dart b/tests/language_2/regress/regress44136_test.dart
new file mode 100644
index 0000000..8478fc5
--- /dev/null
+++ b/tests/language_2/regress/regress44136_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+typedef Foo = void Function<X extends dynamic>();
+typedef Bar = void Function<X extends Object>();
+
+void main() {
+  Expect.notEquals(Foo, Bar);
+}
diff --git a/tests/language_2/stack_trace/stack_trace_test.dart b/tests/language_2/stack_trace/stack_trace_test.dart
index 5e4d7c6..b1e60a9 100644
--- a/tests/language_2/stack_trace/stack_trace_test.dart
+++ b/tests/language_2/stack_trace/stack_trace_test.dart
@@ -88,6 +88,7 @@
   var config = 0;
 
   @pragma("vm:entry-point") // Prevent obfuscation
+  @pragma("vm:never-inline") // Prevent inlining
   issue12940() {
     throw "Progy";
   }
@@ -121,7 +122,7 @@
       try {
         d();
       } catch (e, s) {
-        Expect.isTrue(s.toString().contains("issue12940"));
+        Expect.contains("issue12940", s.toString());
       }
     }
   }
diff --git a/tests/language_2/this/conditional_operator_test.dart b/tests/language_2/this/conditional_operator_test.dart
index 9ccddb2..064153a 100644
--- a/tests/language_2/this/conditional_operator_test.dart
+++ b/tests/language_2/this/conditional_operator_test.dart
@@ -21,7 +21,6 @@
     //^^^^^^^^^^^^^^^^^^^^^^^^
     // [analyzer] COMPILE_TIME_ERROR.INITIALIZER_FOR_NON_EXISTENT_FIELD
     // [error line 15, column 11, length 0]
-    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
     // [cfe] Expected '.' before this.
     //    ^^
     // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
diff --git a/tests/language_2/variable/illegal_initializer_test.dart b/tests/language_2/variable/illegal_initializer_test.dart
index 6924b69..3b8b083 100644
--- a/tests/language_2/variable/illegal_initializer_test.dart
+++ b/tests/language_2/variable/illegal_initializer_test.dart
@@ -45,7 +45,6 @@
       //   ^^^^
       // [analyzer] SYNTACTIC_ERROR.MISSING_ASSIGNMENT_IN_INITIALIZER
       // [error line 39, column 16, length 0]
-      // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
       // [cfe] Expected '.' before this.
       //       ^
       // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
diff --git a/tests/language_2/vm/causal_async_exception_stack2_test.dart b/tests/language_2/vm/causal_async_exception_stack2_test.dart
index 14c1efb..e3ddda0 100644
--- a/tests/language_2/vm/causal_async_exception_stack2_test.dart
+++ b/tests/language_2/vm/causal_async_exception_stack2_test.dart
@@ -1,9 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--causal-async-stacks --no-lazy-async-stacks
-// VMOptions=--no-causal-async-stacks --lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import 'package:async_helper/async_minitest.dart';
 
diff --git a/tests/language_2/vm/causal_async_exception_stack_test.dart b/tests/language_2/vm/causal_async_exception_stack_test.dart
index f4421c2..e9df0a7 100644
--- a/tests/language_2/vm/causal_async_exception_stack_test.dart
+++ b/tests/language_2/vm/causal_async_exception_stack_test.dart
@@ -1,6 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--lazy-async-stacks
 
 import 'package:async_helper/async_minitest.dart';
 
@@ -34,8 +36,8 @@
     } catch (e, st) {
       expect(
           h.stringContainsInOrder(st.toString(), [
-            'thrower', '.dart:10', // no auto-format.
-            'generator', '.dart:19', // no auto-format.
+            'thrower', '.dart:12', // no auto-format.
+            'generator', '.dart:21', // no auto-format.
             '<asynchronous suspension>', // no auto-format.
             'foo', '.dart', // no auto-format.
             'main',
@@ -72,8 +74,8 @@
     } catch (e, st) {
       expect(
           h.stringContainsInOrder(st.toString(), [
-            'thrower', '.dart:10', // no auto-format.
-            'main.<anonymous closure>', '.dart:71', // no auto-format.
+            'thrower', '.dart:12', // no auto-format.
+            'main.<anonymous closure>', '.dart:73', // no auto-format.
           ]),
           isTrue);
     }
diff --git a/tests/lib/async/future_error_test.dart b/tests/lib/async/future_error_test.dart
index 760c392..47f0f15 100644
--- a/tests/lib/async/future_error_test.dart
+++ b/tests/lib/async/future_error_test.dart
@@ -8,7 +8,7 @@
 
 main() {
   // The error cannot be null.
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     Future.error(null as dynamic);
   });
 }
diff --git a/tests/lib/async/stream_controller_add_error_test.dart b/tests/lib/async/stream_controller_add_error_test.dart
index f195fef..aea9294 100644
--- a/tests/lib/async/stream_controller_add_error_test.dart
+++ b/tests/lib/async/stream_controller_add_error_test.dart
@@ -9,41 +9,41 @@
 main() {
   // Single-cast async.
   var controller = StreamController();
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null as dynamic);
   });
 
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null as dynamic);
   });
 
   // Single-cast sync.
   controller = StreamController(sync: true);
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null as dynamic);
   });
 
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null as dynamic);
   });
 
   // Broadcast async.
   controller = StreamController.broadcast();
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null as dynamic);
   });
 
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null as dynamic);
   });
 
   // Broadcast sync.
   controller = StreamController.broadcast(sync: true);
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null as dynamic);
   });
 
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null as dynamic);
   });
 }
diff --git a/tests/lib/async/zone_async_error_test.dart b/tests/lib/async/zone_async_error_test.dart
index ca6c87c..1d3bf04 100644
--- a/tests/lib/async/zone_async_error_test.dart
+++ b/tests/lib/async/zone_async_error_test.dart
@@ -8,7 +8,7 @@
 
 main() {
   // The error cannot be null.
-  Expect.throwsNullCheckError(() {
+  Expect.throwsTypeError(() {
     AsyncError(null as dynamic, StackTrace.current);
   });
 }
diff --git a/tests/lib/collection/linked_list_test.dart b/tests/lib/collection/linked_list_test.dart
index 2c06874..e2c6a7e 100644
--- a/tests/lib/collection/linked_list_test.dart
+++ b/tests/lib/collection/linked_list_test.dart
@@ -11,16 +11,19 @@
   MyEntry(int this.value);
 
   String toString() => value.toString();
+
+  int get hashCode => value.hashCode;
+  bool operator ==(Object o) => o is MyEntry && value == o.value;
 }
 
-testPreviousNext() {
-  var list = new LinkedList<MyEntry>();
+void testPreviousNext() {
+  var list = LinkedList<MyEntry>();
   Expect.throws(() => list.first);
   Expect.throws(() => list.last);
   Expect.equals(0, list.length);
 
   for (int i = 0; i < 3; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
   Expect.equals(3, list.length);
 
@@ -39,11 +42,11 @@
   Expect.isNull(entry.previous);
 }
 
-testUnlinked() {
-  var unlinked = new MyEntry(0);
+void testUnlinked() {
+  var unlinked = MyEntry(0);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   list.add(unlinked);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
@@ -51,7 +54,7 @@
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
   list.add(unlinked);
-  list.add(new MyEntry(1));
+  list.add(MyEntry(1));
   Expect.isNull(unlinked.previous);
   Expect.equals(1, unlinked.next!.value);
   list.remove(unlinked);
@@ -62,11 +65,11 @@
   Expect.equals(1, unlinked.previous!.value);
 }
 
-testInsert() {
+void testInsert() {
   // Insert last.
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -83,7 +86,7 @@
 
   // Insert first.
   for (int i = 0; i < 10; i++) {
-    list.addFirst(new MyEntry(i));
+    list.addFirst(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -97,9 +100,9 @@
   list.clear();
 
   // Insert after.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.last.insertAfter(new MyEntry(i));
+    list.last.insertAfter(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -115,9 +118,9 @@
   list.clear();
 
   // Insert before.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.first.insertBefore(new MyEntry(i));
+    list.first.insertBefore(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -131,10 +134,10 @@
   list.clear();
 }
 
-testRemove() {
-  var list = new LinkedList<MyEntry>();
+void testRemove() {
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -162,21 +165,51 @@
   Expect.equals(0, list.length);
 }
 
-testBadAdd() {
-  var list1 = new LinkedList<MyEntry>();
-  list1.addFirst(new MyEntry(0));
+void testContains() {
+  var list = LinkedList<MyEntry>();
+  var entry5 = MyEntry(5);
 
-  var list2 = new LinkedList<MyEntry>();
-  Expect.throws(() => list2.addFirst(list1.first));
+  // Empty lists contains nothing.
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
 
-  Expect.throws(() => new MyEntry(0).unlink());
+  // Works for singleton lists.
+  list.add(MyEntry(0));
+  Expect.isTrue(list.contains(list.first));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
+
+  // Works for larger lists.
+  for (int i = 1; i < 10; i++) {
+    list.add(MyEntry(i));
+  }
+  for (var entry in list) {
+    Expect.isTrue(list.contains(entry));
+  }
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(entry5));
+  // Based on identity, not equality.
+  Expect.equals(entry5, list.elementAt(5));
 }
 
-testConcurrentModificationError() {
+void testBadAdd() {
+  var list1 = LinkedList<MyEntry>();
+  list1.addFirst(MyEntry(0));
+
+  var list2 = LinkedList<MyEntry>();
+  Expect.throws(() => list2.addFirst(list1.first));
+
+  Expect.throws(() => MyEntry(0).unlink());
+}
+
+void testConcurrentModificationError() {
   test(function(LinkedList<MyEntry> ll)) {
-    var ll = new LinkedList<MyEntry>();
+    var ll = LinkedList<MyEntry>();
     for (int i = 0; i < 10; i++) {
-      ll.add(new MyEntry(i));
+      ll.add(MyEntry(i));
     }
     Expect.throws(() => function(ll), (e) => e is ConcurrentModificationError);
   }
@@ -269,11 +302,12 @@
   });
 }
 
-main() {
+void main() {
   testPreviousNext();
   testUnlinked();
   testInsert();
   testRemove();
+  testContains();
   testBadAdd();
   testConcurrentModificationError();
 }
diff --git a/tests/lib/js/extends_test/extends_subtyping_test.dart b/tests/lib/js/extends_test/extends_subtyping_test.dart
new file mode 100644
index 0000000..76dc51e
--- /dev/null
+++ b/tests/lib/js/extends_test/extends_subtyping_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'extends_test_util.dart';
+
+void main() {
+  setUpWithoutES6Syntax();
+  testSubtyping();
+}
diff --git a/tests/lib/js/extends_test/extends_test.dart b/tests/lib/js/extends_test/extends_test.dart
index 12f8e3f..a9c8781 100644
--- a/tests/lib/js/extends_test/extends_test.dart
+++ b/tests/lib/js/extends_test/extends_test.dart
@@ -5,53 +5,6 @@
 import 'extends_test_util.dart';
 
 void main() {
-  // Use the old way to define inheritance between JS objects.
-  eval(r"""
-    function inherits(child, parent) {
-      if (child.prototype.__proto__) {
-        child.prototype.__proto__ = parent.prototype;
-      } else {
-        function tmp() {};
-        tmp.prototype = parent.prototype;
-        child.prototype = new tmp();
-        child.prototype.constructor = child;
-      }
-    }
-    function JSClass(a) {
-      this.a = a;
-      this.getA = function() {
-        return this.a;
-      }
-      this.getAOrB = function() {
-        return this.getA();
-      }
-    }
-    function JSExtendJSClass(a, b) {
-      JSClass.call(this, a);
-      this.b = b;
-      this.getB = function() {
-        return this.b;
-      }
-      this.getAOrB = function() {
-        return this.getB();
-      }
-    }
-    inherits(JSExtendJSClass, JSClass);
-    function JSExtendAnonymousClass(a, b) {
-      this.a = a;
-      this.b = b;
-      this.getA = function() {
-        return this.a;
-      }
-      this.getB = function() {
-        return this.b;
-      }
-      this.getAOrB = function() {
-        return this.getB();
-      }
-    }
-    self.anonExtendAnon = new JSExtendAnonymousClass(1, 2);
-    self.anonExtendJS = new JSExtendJSClass(1, 2);
-  """);
+  setUpWithoutES6Syntax();
   testInheritance();
 }
diff --git a/tests/lib/js/extends_test/extends_test_util.dart b/tests/lib/js/extends_test/extends_test_util.dart
index 5185176..e39e1b9 100644
--- a/tests/lib/js/extends_test/extends_test_util.dart
+++ b/tests/lib/js/extends_test/extends_test_util.dart
@@ -60,6 +60,108 @@
 external AnonymousExtendAnonymousClass get anonExtendAnon;
 external AnonymousExtendJSClass get anonExtendJS;
 
+void useJSClass(JSClass js) {}
+void useAnonymousClass(AnonymousClass a) {}
+
+void setUpWithoutES6Syntax() {
+  // Use the old way to define inheritance between JS objects.
+  eval(r"""
+    function inherits(child, parent) {
+      if (child.prototype.__proto__) {
+        child.prototype.__proto__ = parent.prototype;
+      } else {
+        function tmp() {};
+        tmp.prototype = parent.prototype;
+        child.prototype = new tmp();
+        child.prototype.constructor = child;
+      }
+    }
+    function JSClass(a) {
+      this.a = a;
+      this.getA = function() {
+        return this.a;
+      }
+      this.getAOrB = function() {
+        return this.getA();
+      }
+    }
+    function JSExtendJSClass(a, b) {
+      JSClass.call(this, a);
+      this.b = b;
+      this.getB = function() {
+        return this.b;
+      }
+      this.getAOrB = function() {
+        return this.getB();
+      }
+    }
+    inherits(JSExtendJSClass, JSClass);
+    function JSExtendAnonymousClass(a, b) {
+      this.a = a;
+      this.b = b;
+      this.getA = function() {
+        return this.a;
+      }
+      this.getB = function() {
+        return this.b;
+      }
+      this.getAOrB = function() {
+        return this.getB();
+      }
+    }
+    self.anonExtendAnon = new JSExtendAnonymousClass(1, 2);
+    self.anonExtendJS = new JSExtendJSClass(1, 2);
+  """);
+}
+
+void setUpWithES6Syntax() {
+  // Use the ES6 syntax for classes to make inheritance easier.
+  eval(r"""
+    class JSClass {
+      constructor(a) {
+        this.a = a;
+      }
+      getA() {
+        return this.a;
+      }
+      getAOrB() {
+        return this.getA();
+      }
+    }
+    class JSExtendJSClass extends JSClass {
+      constructor(a, b) {
+        super(a);
+        this.b = b;
+      }
+      getB() {
+        return this.b;
+      }
+      getAOrB() {
+        return this.getB();
+      }
+    }
+    self.JSExtendJSClass = JSExtendJSClass;
+    class JSExtendAnonymousClass {
+      constructor(a, b) {
+        this.a = a;
+        this.b = b;
+      }
+      getA() {
+        return this.a;
+      }
+      getB() {
+        return this.b;
+      }
+      getAOrB() {
+        return this.getB();
+      }
+    }
+    self.JSExtendAnonymousClass = JSExtendAnonymousClass;
+    self.anonExtendAnon = new JSExtendAnonymousClass(1, 2);
+    self.anonExtendJS = new JSExtendJSClass(1, 2);
+  """);
+}
+
 void testInheritance() {
   // Note that for the following, there are no meaningful tests for is checks or
   // as casts, since the web compilers should return true and succeed for all JS
@@ -92,3 +194,17 @@
   expect(anonExtendJS.getAOrB(), 2);
   expect((anonExtendJS as JSClass).getAOrB(), 2);
 }
+
+void testSubtyping() {
+  // Test subtyping for inheritance between JS and anonymous classes.
+  expect(useJSClass is void Function(JSExtendJSClass js), true);
+  expect(useAnonymousClass is void Function(AnonymousExtendAnonymousClass a),
+      true);
+  expect(useJSClass is void Function(AnonymousExtendJSClass a), true);
+  expect(useAnonymousClass is void Function(JSExtendAnonymousClass js), true);
+
+  expect(useJSClass is void Function(AnonymousExtendAnonymousClass a), false);
+  expect(useAnonymousClass is void Function(JSExtendJSClass js), false);
+  expect(useJSClass is void Function(JSExtendAnonymousClass js), false);
+  expect(useAnonymousClass is void Function(AnonymousExtendJSClass a), false);
+}
diff --git a/tests/lib/js/extends_test/extends_with_es6_subtyping_test.dart b/tests/lib/js/extends_test/extends_with_es6_subtyping_test.dart
new file mode 100644
index 0000000..e6185da
--- /dev/null
+++ b/tests/lib/js/extends_test/extends_with_es6_subtyping_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'extends_test_util.dart';
+
+void main() {
+  setUpWithES6Syntax();
+  testSubtyping();
+}
diff --git a/tests/lib/js/extends_test/extends_with_es6_test.dart b/tests/lib/js/extends_test/extends_with_es6_test.dart
index 00eb41f..8daae16 100644
--- a/tests/lib/js/extends_test/extends_with_es6_test.dart
+++ b/tests/lib/js/extends_test/extends_with_es6_test.dart
@@ -5,50 +5,6 @@
 import 'extends_test_util.dart';
 
 void main() {
-  // Use the ES6 syntax for classes to make inheritance easier.
-  eval(r"""
-    class JSClass {
-      constructor(a) {
-        this.a = a;
-      }
-      getA() {
-        return this.a;
-      }
-      getAOrB() {
-        return this.getA();
-      }
-    }
-    class JSExtendJSClass extends JSClass {
-      constructor(a, b) {
-        super(a);
-        this.b = b;
-      }
-      getB() {
-        return this.b;
-      }
-      getAOrB() {
-        return this.getB();
-      }
-    }
-    self.JSExtendJSClass = JSExtendJSClass;
-    class JSExtendAnonymousClass {
-      constructor(a, b) {
-        this.a = a;
-        this.b = b;
-      }
-      getA() {
-        return this.a;
-      }
-      getB() {
-        return this.b;
-      }
-      getAOrB() {
-        return this.getB();
-      }
-    }
-    self.JSExtendAnonymousClass = JSExtendAnonymousClass;
-    self.anonExtendAnon = new JSExtendAnonymousClass(1, 2);
-    self.anonExtendJS = new JSExtendJSClass(1, 2);
-  """);
+  setUpWithES6Syntax();
   testInheritance();
 }
diff --git a/tests/lib/js/implements_static_test.dart b/tests/lib/js/implements_static_test.dart
new file mode 100644
index 0000000..ca7e8f0
--- /dev/null
+++ b/tests/lib/js/implements_static_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests classes implementing other interfaces with JS interop. Only tests
+// getters and assumes other instance members work similarly to avoid bloated
+// tests.
+
+@JS()
+library implements_static_test;
+
+import 'package:js/js.dart';
+
+// Normal and abstract classes for Dart, JS, and anonymous classes.
+class DartClass {
+  int get dartGetter => 0;
+}
+
+abstract class AbstractDartClass {
+  int get abstractDartGetter;
+}
+
+@JS()
+class JSClass {
+  external int get jsGetter;
+}
+
+@JS()
+abstract class AbstractJSClass {
+  external int get abstractJsGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClass {
+  external int get anonymousGetter;
+}
+
+@JS()
+@anonymous
+abstract class AbstractAnonymousClass {
+  external int get abstractAnonymousGetter;
+}
+
+// Dart classes that implement all the other JS type interfaces.
+class DartClassImplementsJSClass implements JSClass {
+  int get jsGetter => 0;
+}
+
+class DartClassImplementsAbstractJSClass implements AbstractJSClass {
+  int get abstractJsGetter => 0;
+}
+
+class DartClassImplementsAnonymousClass implements AnonymousClass {
+  int get anonymousGetter => 0;
+}
+
+class DartClassImplementsAbstractAnonymousClass
+    implements AbstractAnonymousClass {
+  int get abstractAnonymousGetter => 0;
+}
+
+// JS classes that implement all the other interfaces.
+@JS()
+class JSClassImplementsDartClass implements DartClass {
+  external int get dartGetter;
+}
+
+@JS()
+class JSClassImplementsAbstractDartClass implements AbstractDartClass {
+  external int get abstractDartGetter;
+}
+
+@JS()
+class JSClassImplementsJSClass implements JSClass {
+  external int get jsGetter;
+}
+
+@JS()
+class JSClassImplementsAbstractJSClass implements AbstractJSClass {
+  external int get abstractJsGetter;
+}
+
+@JS()
+class JSClassImplementsAnonymousClass implements AnonymousClass {
+  external int get anonymousGetter;
+}
+
+@JS()
+class JSClassImplementsAbstractAnonymousClass
+    implements AbstractAnonymousClass {
+  external int get abstractAnonymousGetter;
+}
+
+// Anonymous classes that implement all the other interfaces.
+@JS()
+@anonymous
+class AnonymousClassImplementsDartClass implements DartClass {
+  external int get dartGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClassImplementsAbstractDartClass implements AbstractDartClass {
+  external int get abstractDartGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClassImplementsJSClass implements JSClass {
+  external int get jsGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClassImplementsAbstractJSClass implements AbstractJSClass {
+  external int get abstractJsGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClassImplementsAnonymousClass implements AnonymousClass {
+  external int get anonymousGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClassImplementsAbstractAnonymousClass
+    implements AbstractAnonymousClass {
+  external int get abstractAnonymousGetter;
+}
+
+// Dart, JS, and anonymous classes implementing multiple interfaces.
+class DartClassImplementsMultipleInterfaces
+    implements DartClass, AbstractJSClass, AnonymousClass {
+  int get dartGetter => 0;
+  int get abstractJsGetter => 0;
+  int get anonymousGetter => 0;
+}
+
+@JS()
+class JSClassImplementsMultipleInterfaces
+    implements AbstractDartClass, JSClass, AbstractAnonymousClass {
+  external int get abstractDartGetter;
+  external int get jsGetter;
+  external int get abstractAnonymousGetter;
+}
+
+@JS()
+@anonymous
+class AnonymousClassImplementsMultipleInterfaces
+    implements DartClass, JSClass, AbstractAnonymousClass {
+  external int get dartGetter;
+  external int get jsGetter;
+  external int get abstractAnonymousGetter;
+}
+
+void main() {}
diff --git a/tests/lib/js/is_check_and_as_cast_test.dart b/tests/lib/js/is_check_and_as_cast_test.dart
index ef48137..d88255c 100644
--- a/tests/lib/js/is_check_and_as_cast_test.dart
+++ b/tests/lib/js/is_check_and_as_cast_test.dart
@@ -9,6 +9,7 @@
 library is_check_and_as_cast_test;
 
 import 'package:js/js.dart';
+import 'package:expect/expect.dart' show hasUnsoundNullSafety;
 import 'package:expect/minitest.dart';
 
 @JS()
@@ -57,6 +58,8 @@
 external LiteralA get a;
 external LiteralB get b;
 
+class DartClass {}
+
 void main() {
   eval(r"""
     function Foo(a) {
@@ -119,4 +122,26 @@
   expect(() => (foo as LiteralB), returnsNormally);
   expect(a is Foo, isTrue);
   expect(() => (a as Foo), returnsNormally);
+
+  // You cannot cast between JS interop objects and Dart objects, however.
+  var dartClass = DartClass();
+  expect(dartClass is Foo, isFalse);
+  expect(() => (dartClass as Foo), throws);
+  expect(dartClass is LiteralA, isFalse);
+  expect(() => (dartClass as LiteralA), throws);
+
+  expect(foo is DartClass, isFalse);
+  expect(() => (foo as DartClass), throws);
+  expect(a is DartClass, isFalse);
+  expect(() => (a as DartClass), throws);
+
+  // Test that nullability is still respected with JS types.
+  Foo? nullableFoo = null;
+  expect(nullableFoo is Foo, false);
+  expect(() => (nullableFoo as Foo),
+      hasUnsoundNullSafety ? returnsNormally : throws);
+  LiteralA? nullableA = null;
+  expect(nullableA is LiteralA, false);
+  expect(() => (nullableA as LiteralA),
+      hasUnsoundNullSafety ? returnsNormally : throws);
 }
diff --git a/tests/lib/js/subtyping_test.dart b/tests/lib/js/subtyping_test.dart
new file mode 100644
index 0000000..2551fcd
--- /dev/null
+++ b/tests/lib/js/subtyping_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests subtyping relationships between JS and anonymous classes.
+
+@JS()
+library subtyping_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart' show hasUnsoundNullSafety;
+import 'package:expect/minitest.dart';
+
+@JS()
+class JSClassA {}
+
+@JS()
+class JSClassB {}
+
+@JS()
+@anonymous
+class AnonymousClassA {}
+
+@JS()
+@anonymous
+class AnonymousClassB {}
+
+class DartClass {}
+
+void useJSClassA(JSClassA _) {}
+void useAnonymousClassA(AnonymousClassA _) {}
+void useDartClass(DartClass _) {}
+
+void useNullableJSClassA(JSClassA? _) {}
+void useNullableAnonymousClassA(AnonymousClassA? _) {}
+
+// Avoid static type optimization by running all tests using this.
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+void main() {
+  // Checks subtyping with the same type and nullability subtyping.
+  expect(useJSClassA is void Function(JSClassA), true);
+  expect(useAnonymousClassA is void Function(AnonymousClassA), true);
+  expect(useJSClassA is void Function(JSClassA?), hasUnsoundNullSafety);
+  expect(useAnonymousClassA is void Function(AnonymousClassA?),
+      hasUnsoundNullSafety);
+  expect(useNullableJSClassA is void Function(JSClassA?), true);
+  expect(useNullableAnonymousClassA is void Function(AnonymousClassA?), true);
+  expect(useNullableJSClassA is void Function(JSClassA), true);
+  expect(useNullableAnonymousClassA is void Function(AnonymousClassA), true);
+
+  expect(confuse(useJSClassA) is void Function(JSClassA), true);
+  expect(confuse(useAnonymousClassA) is void Function(AnonymousClassA), true);
+  expect(
+      confuse(useJSClassA) is void Function(JSClassA?), hasUnsoundNullSafety);
+  expect(confuse(useAnonymousClassA) is void Function(AnonymousClassA?),
+      hasUnsoundNullSafety);
+  expect(confuse(useNullableJSClassA) is void Function(JSClassA?), true);
+  expect(confuse(useNullableAnonymousClassA) is void Function(AnonymousClassA?),
+      true);
+  expect(confuse(useNullableJSClassA) is void Function(JSClassA), true);
+  expect(confuse(useNullableAnonymousClassA) is void Function(AnonymousClassA),
+      true);
+
+  // No subtyping between JS and anonymous classes.
+  expect(useJSClassA is void Function(AnonymousClassA), false);
+  expect(useAnonymousClassA is void Function(JSClassA), false);
+
+  expect(confuse(useJSClassA) is void Function(AnonymousClassA), false);
+  expect(confuse(useAnonymousClassA) is void Function(JSClassA), false);
+
+  // No subtyping between separate classes even if they're both JS classes or
+  // anonymous classes.
+  expect(useJSClassA is void Function(JSClassB), false);
+  expect(useAnonymousClassA is void Function(AnonymousClassB), false);
+
+  expect(confuse(useJSClassA) is void Function(JSClassB), false);
+  expect(confuse(useAnonymousClassA) is void Function(AnonymousClassB), false);
+
+  // No subtyping between JS/anonymous classes and Dart classes.
+  expect(useJSClassA is void Function(DartClass), false);
+  expect(useAnonymousClassA is void Function(DartClass), false);
+
+  expect(confuse(useJSClassA) is void Function(DartClass), false);
+  expect(confuse(useAnonymousClassA) is void Function(DartClass), false);
+}
diff --git a/tests/lib/lib_dart2js.status b/tests/lib/lib_dart2js.status
index 14a0a1a..d66a2c8 100644
--- a/tests/lib/lib_dart2js.status
+++ b/tests/lib/lib_dart2js.status
@@ -23,6 +23,8 @@
 html/xhr_test: Slow, Pass
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
+typed_data/int64_list_load_store_test: SkipByDesign # No support for Int64List
+typed_data/typed_data_hierarchy_int64_test: SkipByDesign # No support for Int64List
 wasm/*: SkipByDesign # dart:wasm not currently supported on web.
 
 [ $compiler != dart2js ]
diff --git a/tests/lib/lib_dartdevc.status b/tests/lib/lib_dartdevc.status
index 61d487d..cfdf3fa 100644
--- a/tests/lib/lib_dartdevc.status
+++ b/tests/lib/lib_dartdevc.status
@@ -42,4 +42,3 @@
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
 typed_data/int64_list_load_store_test: SkipByDesign # dartdevk/c does not support Int64List
 typed_data/typed_data_hierarchy_int64_test: SkipByDesign # dartdevk/c does not support Int64List
-typed_data/unmodifiable_typed_data_test: SkipByDesign # dartdevk/c does not support Int64List
diff --git a/tests/lib/lib_vm.status b/tests/lib/lib_vm.status
index b28a2fa..c693924 100644
--- a/tests/lib/lib_vm.status
+++ b/tests/lib/lib_vm.status
@@ -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.
 
+[ $runtime == vm ]
+isolate/*: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+
 [ $runtime != vm ]
 isolate/native_wrapper_message_test: Skip # A VM specific test.
 
diff --git a/tests/lib/math/random_big_test.dart b/tests/lib/math/random_big_test.dart
index 41a5651..25c57e7 100644
--- a/tests/lib/math/random_big_test.dart
+++ b/tests/lib/math/random_big_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test that Random can deal with a seed outside 64-bit range.
+// Test that Random can deal with a seed at upper end of 64-bit range.
 
 import "package:expect/expect.dart";
 import 'dart:math';
@@ -10,7 +10,7 @@
 main() {
   var results = [];
   for (var i = 60; i < 64; i++) {
-    var rng = new Random(1 << i);
+    var rng = new Random(pow(2, i) as int);
     var val = rng.nextInt(100000);
     print("$i: $val");
     Expect.isFalse(results.contains(val));
diff --git a/tests/lib/typed_data/unmodifiable_typed_data_test.dart b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
index 70708c5..2a04cd7 100644
--- a/tests/lib/typed_data/unmodifiable_typed_data_test.dart
+++ b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
@@ -5,6 +5,8 @@
 import 'dart:typed_data';
 import 'package:expect/expect.dart';
 
+const bool supportsInt64 = bool.fromEnvironment('dart.isVM');
+
 List<int> intList = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
 checkReadable(List<int> list) {
@@ -157,8 +159,10 @@
   uint16ListTest();
   int32ListTest();
   uint32ListTest();
-  int64ListTest();
-  uint64ListTest();
+  if (supportsInt64) {
+    int64ListTest();
+    uint64ListTest();
+  }
   float32ListTest();
   float64ListTest();
   byteDataTest();
diff --git a/tests/lib_2/async/future_error_test.dart b/tests/lib_2/async/future_error_test.dart
index 3ef0eb3..bb96fa3 100644
--- a/tests/lib_2/async/future_error_test.dart
+++ b/tests/lib_2/async/future_error_test.dart
@@ -7,7 +7,7 @@
 
 main() {
   // The error cannot be null.
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     Future.error(null);
   });
 }
diff --git a/tests/lib_2/async/future_test.dart b/tests/lib_2/async/future_test.dart
index 6c227cf..2e546bf 100644
--- a/tests/lib_2/async/future_test.dart
+++ b/tests/lib_2/async/future_test.dart
@@ -709,7 +709,7 @@
 
 void testCompleteErrorWithNull() {
   final completer = new Completer<int>();
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     completer.completeError(null);
   });
 }
diff --git a/tests/lib_2/async/stream_controller_add_error_test.dart b/tests/lib_2/async/stream_controller_add_error_test.dart
index aed39e8..fe24ceb 100644
--- a/tests/lib_2/async/stream_controller_add_error_test.dart
+++ b/tests/lib_2/async/stream_controller_add_error_test.dart
@@ -8,41 +8,41 @@
 main() {
   // Single-cast async.
   var controller = StreamController();
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null);
   });
 
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null);
   });
 
   // Single-cast sync.
   controller = StreamController(sync: true);
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null);
   });
 
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null);
   });
 
   // Broadcast async.
   controller = StreamController.broadcast();
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null);
   });
 
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null);
   });
 
   // Broadcast sync.
   controller = StreamController.broadcast(sync: true);
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.addError(null);
   });
 
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     controller.sink.addError(null);
   });
 }
diff --git a/tests/lib_2/async/stream_error_test.dart b/tests/lib_2/async/stream_error_test.dart
index 22b091b..1c0737e 100644
--- a/tests/lib_2/async/stream_error_test.dart
+++ b/tests/lib_2/async/stream_error_test.dart
@@ -73,7 +73,7 @@
   }
 
   // A null error argument is a synchronous error.
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     Stream.error(null);
   });
 
diff --git a/tests/lib_2/async/zone_async_error_test.dart b/tests/lib_2/async/zone_async_error_test.dart
index b1f67ce..ad3709d 100644
--- a/tests/lib_2/async/zone_async_error_test.dart
+++ b/tests/lib_2/async/zone_async_error_test.dart
@@ -7,7 +7,7 @@
 
 main() {
   // The error cannot be null.
-  Expect.throwsArgumentError(() {
+  Expect.throwsTypeError(() {
     AsyncError(null, StackTrace.current);
   });
 }
diff --git a/tests/lib_2/collection/linked_list_test.dart b/tests/lib_2/collection/linked_list_test.dart
index 03e01bb..dd73a0a 100644
--- a/tests/lib_2/collection/linked_list_test.dart
+++ b/tests/lib_2/collection/linked_list_test.dart
@@ -11,16 +11,19 @@
   MyEntry(int this.value);
 
   String toString() => value.toString();
+
+  int get hashCode => value.hashCode;
+  bool operator ==(Object o) => o is MyEntry && value == o.value;
 }
 
-testPreviousNext() {
-  var list = new LinkedList<MyEntry>();
+void testPreviousNext() {
+  var list = LinkedList<MyEntry>();
   Expect.throws(() => list.first);
   Expect.throws(() => list.last);
   Expect.equals(0, list.length);
 
   for (int i = 0; i < 3; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
   Expect.equals(3, list.length);
 
@@ -39,11 +42,11 @@
   Expect.isNull(entry.previous);
 }
 
-testUnlinked() {
-  var unlinked = new MyEntry(0);
+void testUnlinked() {
+  var unlinked = MyEntry(0);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   list.add(unlinked);
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
@@ -51,7 +54,7 @@
   Expect.isNull(unlinked.previous);
   Expect.isNull(unlinked.next);
   list.add(unlinked);
-  list.add(new MyEntry(1));
+  list.add(MyEntry(1));
   Expect.isNull(unlinked.previous);
   Expect.equals(1, unlinked.next.value);
   list.remove(unlinked);
@@ -62,11 +65,11 @@
   Expect.equals(1, unlinked.previous.value);
 }
 
-testInsert() {
+void testInsert() {
   // Insert last.
-  var list = new LinkedList<MyEntry>();
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -83,7 +86,7 @@
 
   // Insert first.
   for (int i = 0; i < 10; i++) {
-    list.addFirst(new MyEntry(i));
+    list.addFirst(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -97,9 +100,9 @@
   list.clear();
 
   // Insert after.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.last.insertAfter(new MyEntry(i));
+    list.last.insertAfter(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -115,9 +118,9 @@
   list.clear();
 
   // Insert before.
-  list.addFirst(new MyEntry(0));
+  list.addFirst(MyEntry(0));
   for (int i = 1; i < 10; i++) {
-    list.first.insertBefore(new MyEntry(i));
+    list.first.insertBefore(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -131,10 +134,10 @@
   list.clear();
 }
 
-testRemove() {
-  var list = new LinkedList<MyEntry>();
+void testRemove() {
+  var list = LinkedList<MyEntry>();
   for (int i = 0; i < 10; i++) {
-    list.add(new MyEntry(i));
+    list.add(MyEntry(i));
   }
 
   Expect.equals(10, list.length);
@@ -162,21 +165,51 @@
   Expect.equals(0, list.length);
 }
 
-testBadAdd() {
-  var list1 = new LinkedList<MyEntry>();
-  list1.addFirst(new MyEntry(0));
+void testContains() {
+  var list = LinkedList<MyEntry>();
+  var entry5 = MyEntry(5);
 
-  var list2 = new LinkedList<MyEntry>();
-  Expect.throws(() => list2.addFirst(list1.first));
+  // Empty lists contains nothing.
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
 
-  Expect.throws(() => new MyEntry(0).unlink());
+  // Works for singleton lists.
+  list.add(MyEntry(0));
+  Expect.isTrue(list.contains(list.first));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(entry5));
+
+  // Works for larger lists.
+  for (int i = 1; i < 10; i++) {
+    list.add(MyEntry(i));
+  }
+  for (var entry in list) {
+    Expect.isTrue(list.contains(entry));
+  }
+  Expect.isFalse(list.contains(Object()));
+  Expect.isFalse(list.contains(null));
+  Expect.isFalse(list.contains(entry5));
+  // Based on identity, not equality.
+  Expect.isTrue(list.elementAt(5) == entry5);
 }
 
-testConcurrentModificationError() {
+void testBadAdd() {
+  var list1 = LinkedList<MyEntry>();
+  list1.addFirst(MyEntry(0));
+
+  var list2 = LinkedList<MyEntry>();
+  Expect.throws(() => list2.addFirst(list1.first));
+
+  Expect.throws(() => MyEntry(0).unlink());
+}
+
+void testConcurrentModificationError() {
   test(function(LinkedList<MyEntry> ll)) {
-    var ll = new LinkedList<MyEntry>();
+    var ll = LinkedList<MyEntry>();
     for (int i = 0; i < 10; i++) {
-      ll.add(new MyEntry(i));
+      ll.add(MyEntry(i));
     }
     Expect.throws(() => function(ll), (e) => e is ConcurrentModificationError);
   }
@@ -269,11 +302,12 @@
   });
 }
 
-main() {
+void main() {
   testPreviousNext();
   testUnlinked();
   testInsert();
   testRemove();
+  testContains();
   testBadAdd();
   testConcurrentModificationError();
 }
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 68e3420..4820450 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -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.
 
+[ $runtime == vm ]
+isolate/*: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+
 [ $runtime != vm ]
 isolate/native_wrapper_message_test: Skip # A VM specific test.
 
diff --git a/tests/lib_2/math/random_big_test.dart b/tests/lib_2/math/random_big_test.dart
index 41a5651..25c57e7 100644
--- a/tests/lib_2/math/random_big_test.dart
+++ b/tests/lib_2/math/random_big_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test that Random can deal with a seed outside 64-bit range.
+// Test that Random can deal with a seed at upper end of 64-bit range.
 
 import "package:expect/expect.dart";
 import 'dart:math';
@@ -10,7 +10,7 @@
 main() {
   var results = [];
   for (var i = 60; i < 64; i++) {
-    var rng = new Random(1 << i);
+    var rng = new Random(pow(2, i) as int);
     var val = rng.nextInt(100000);
     print("$i: $val");
     Expect.isFalse(results.contains(val));
diff --git a/tests/lib_2/typed_data/int32x4_arithmetic_test.dart b/tests/lib_2/typed_data/int32x4_arithmetic_test.dart
index 6f08626..f9a740e 100644
--- a/tests/lib_2/typed_data/int32x4_arithmetic_test.dart
+++ b/tests/lib_2/typed_data/int32x4_arithmetic_test.dart
@@ -91,16 +91,35 @@
   Expect.equals(1, o.w);
 }
 
+const int53 = 0x20000000000000; // 2^53.
+final usingJavaScriptNumbers = (int53 + 1) == int53;
+
 testTruncation() {
-  var n = 0xAABBCCDD00000001;
-  var x = new Int32x4(n, 0, 0, 0);
-  Expect.equals(x.x, 1);
+  // Check that various bits from bit 32 and up are masked away.
+  var base = usingJavaScriptNumbers ? 0x1BCCDD00000000 : 0xAABBCCDD00000000;
+  var x1 = new Int32x4(base + 1, 0, 0, 0);
+  Expect.equals(1, x1.x);
+
+  // Check that all even bits up to bit 30 are preserved.
+  var x2 = new Int32x4(base + 0x55555555, 0, 0, 0);
+  Expect.equals(0x55555555, x2.x);
+
+  // Check that the odd bits up to bit 31 are preserved, and that
+  // bit 31 is treated as a sign bit.
+  var x3 = new Int32x4(base + 0xAAAAAAAA, 0, 0, 0);
+  const signExtended = -1431655766; // 0xFFFFFFFFAAAAAAAA or 0x3FFFFFAAAAAAAA.
+  Expect.equals(signExtended, x3.x);
+
+  // Check that all bits from bit 32 and up are masked away.
+  var highBase = 0xFFFFFFFF10000000;
+  var x4 = new Int32x4(highBase, 0, 0, 0);
+  Expect.equals(0x10000000, x4.x);
 }
 
 main() {
   for (int i = 0; i < 20; i++) {
     testAdd();
     testSub();
-    testTruncation(); //   //# int64: ok
+    testTruncation();
   }
 }
diff --git a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
index 70708c5..2a04cd7 100644
--- a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
+++ b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
@@ -5,6 +5,8 @@
 import 'dart:typed_data';
 import 'package:expect/expect.dart';
 
+const bool supportsInt64 = bool.fromEnvironment('dart.isVM');
+
 List<int> intList = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
 checkReadable(List<int> list) {
@@ -157,8 +159,10 @@
   uint16ListTest();
   int32ListTest();
   uint32ListTest();
-  int64ListTest();
-  uint64ListTest();
+  if (supportsInt64) {
+    int64ListTest();
+    uint64ListTest();
+  }
   float32ListTest();
   float64ListTest();
   byteDataTest();
diff --git a/tests/standalone/causal_async_stack_test.dart b/tests/standalone/causal_async_stack_test.dart
index 5b44bec..652edb3 100644
--- a/tests/standalone/causal_async_stack_test.dart
+++ b/tests/standalone/causal_async_stack_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--causal_async_stacks --no-lazy-async-stacks
-// VMOptions=--no-causal_async_stacks --lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import "package:expect/expect.dart";
 
diff --git a/tests/standalone/dart_developer_disabled_env_test.dart b/tests/standalone/dart_developer_disabled_env_test.dart
deleted file mode 100644
index 1d9653b..0000000
--- a/tests/standalone/dart_developer_disabled_env_test.dart
+++ /dev/null
@@ -1,11 +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.
-// VMOptions=--no_causal_async_stacks
-
-import "package:expect/expect.dart";
-
-main() {
-  Expect.isFalse(
-      const bool.fromEnvironment('dart.developer.causal_async_stacks'));
-}
diff --git a/tests/standalone/dart_developer_env2_test.dart b/tests/standalone/dart_developer_env2_test.dart
deleted file mode 100644
index 881880a..0000000
--- a/tests/standalone/dart_developer_env2_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--lazy-async-stacks --no-causal-async-stacks
-
-import "package:expect/expect.dart";
-
-main() {
-  Expect.isFalse(
-      const bool.fromEnvironment('dart.developer.causal_async_stacks'));
-}
diff --git a/tests/standalone/dart_developer_env_test.dart b/tests/standalone/dart_developer_env_test.dart
deleted file mode 100644
index abb7bf6..0000000
--- a/tests/standalone/dart_developer_env_test.dart
+++ /dev/null
@@ -1,11 +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.
-// VMOptions=--no-lazy-async-stacks --causal-async-stacks
-
-import "package:expect/expect.dart";
-
-main() {
-  Expect
-      .isTrue(const bool.fromEnvironment('dart.developer.causal_async_stacks'));
-}
diff --git a/tests/standalone/io/https_connection_closed_during_handshake_test.dart b/tests/standalone/io/https_connection_closed_during_handshake_test.dart
new file mode 100644
index 0000000..eed79c2
--- /dev/null
+++ b/tests/standalone/io/https_connection_closed_during_handshake_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--long-ssl-cert-evaluation
+
+// This test verifies that lost of connection during handshake doesn't cause
+// vm crashes.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import "package:expect/expect.dart";
+
+String getFilename(String path) => Platform.script.resolve(path).toFilePath();
+
+final SecurityContext serverSecurityContext = () {
+  final context = SecurityContext();
+  context
+      .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
+  context.useCertificateChainBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+final SecurityContext clientSecurityContext = () {
+  final context = SecurityContext(withTrustedRoots: true);
+  context.setTrustedCertificatesBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+void main(List<String> args) async {
+  if (args.length >= 1 && args[0] == 'server') {
+    final server =
+        await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
+    print('ok ${server.port}');
+    server.listen((socket) {
+      print('server: got connection');
+      socket.close();
+    });
+    await Future.delayed(Duration(seconds: 2));
+    print('server: exiting');
+    exit(1);
+  }
+
+  final serverProcess = await Process.start(
+      Platform.executable, [Platform.script.toFilePath(), 'server']);
+  final serverPortCompleter = Completer<int>();
+
+  serverProcess.stdout
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) {
+    print('server stdout: $line');
+    if (line.startsWith('ok')) {
+      serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
+    }
+  });
+  serverProcess.stderr
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) => print('server stderr: $line'));
+
+  int port = await serverPortCompleter.future;
+
+  var thrownException;
+  try {
+    print('client connecting...');
+    await SecureSocket.connect('localhost', port,
+        context: clientSecurityContext);
+    print('client connected.');
+  } catch (e) {
+    thrownException = e;
+  } finally {
+    await serverProcess.kill();
+  }
+  print('thrownException: $thrownException');
+  Expect.isTrue(thrownException is HandshakeException);
+}
diff --git a/tests/standalone/io/localhost.crt b/tests/standalone/io/localhost.crt
new file mode 100644
index 0000000..eeab890
--- /dev/null
+++ b/tests/standalone/io/localhost.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIUe+E1Xth9TMlsYY7qmf9zlfC1Ms0wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE4MTIzMTIzMDAxMVoYDzIxMTgx
+MjA3MjMwMDExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDEEY2eWBX1rTDgsAWheltKiAHREteaqX4iaGwF6/TC
+6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA6PDocRpK2zOObTqdVqJAiodUi0ov
+ds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3QkUMPCDBkLqiYUuR6j5QJ4Vz2OFV5g
+1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLIvzss+aHBTWD+9HYfgWsfJGI3UFgc
+zoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk10jhYdxdglXpTPOWP5YnwWsy8VbU
+1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEXdyxOzT3bAgMBAAGjfjB8MB0GA1Ud
+DgQWBBS/3CUrYgiD2qwdEDStghi+X3+4pzAfBgNVHSMEGDAWgBS/3CUrYgiD2qwd
+EDStghi+X3+4pzAPBgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAu5adpS/h
+bWXYaDLW5JGZAiOVVkMDhspJDdPwDHUTqMPj3V6aaecZTc46Q7TLEkLxIjU5OjvR
+ZHh3vo9X4S84Yf7NHv8eX50MK/RrzZolUROhZ6gtYZKkdZtjQKQd62ih5EB6gNnZ
++IW9nedg7Sae2Yh22jDC9Tc+dbvroOd7IUwL9gVSCcwiqVjvuWkDa7jqjnRp4sog
+yY1Obr14tmUMgR73Db7q3g0cVToztLYIMJnhjiSUs8nk83m/9/O4SGqQmievoZ5N
+60OlhU6enfFoj1xKpXWSGv6mqqdX0G9Ehz1EIetFhkBK2pP/R00gf4OMKc4ubw8d
+yTSUIeMSOo0QjA==
+-----END CERTIFICATE-----
diff --git a/tests/standalone/io/localhost.key b/tests/standalone/io/localhost.key
new file mode 100644
index 0000000..20815e4
--- /dev/null
+++ b/tests/standalone/io/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEEY2eWBX1rTDg
+sAWheltKiAHREteaqX4iaGwF6/TC6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA
+6PDocRpK2zOObTqdVqJAiodUi0ovds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3Qk
+UMPCDBkLqiYUuR6j5QJ4Vz2OFV5g1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLI
+vzss+aHBTWD+9HYfgWsfJGI3UFgczoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk
+10jhYdxdglXpTPOWP5YnwWsy8VbU1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEX
+dyxOzT3bAgMBAAECggEAHGsa5reHv0syCW8Z8dTFRKE/+ijL/UvRz3TpK1aO7G19
+9/BgHQOIhZ6yzjWWwVBk2W3ByYgGHoSRCAm7WUWDdRQefedRFpsG+2nYwaVKxGRp
+DC0OIASJ32NPLci3F8mgJdDfB3GLpA3k8JqQNSEBxFIOIPTP/xtjZ0Pl1SE9w7Uk
+8pwuJPJDPSAamguSNY5+HHcyta/i7Zsv2/S4BdV8Q8WQeCc6hcR3Zka1H0txgk8o
+qUurU2ApdnzINQ7ki0+D6CuVXEivmL/kPivQg0/khIQp1IXhdYdWCMKSUr1vkoAK
+0zc6H5DlDvdQPrjqdLGOUlVx5JnjTYd68/Wqje76eQKBgQD0uNR2yJYxmQmLC1y6
+TLXxvm0OOlmUiNMZgLOwDNdjXvOH/emtpHyyKhHpc3kzNK3xsNxyAYJRlaIUylj0
+C9dsipj+QTb4ICu0GlbLXsXN5iM592igoS4kMnP9KbzSc93k9BvMhh1emO8i3GB7
+v/1Cf/z+gP+viLMaPEFqKxI8FwKBgQDNGrjabA2jkawanHHUUhwscwB4RrvuuJTG
+Zv7L7QXBMYx7CUwJztV5amkUNrbBW/67/MMQB0Djv1pgMo4QCWeftb9oHFXGu3hV
+kUj7Or/Z2TWYtLIdxgTDbRRtit57z3NaCHCDgQhyAZUY3y8cvXFYdHDnJlqLTN77
+bzQub7BS3QKBgHtUep6yUB8GxSxxuXWaG0eNdGBrP6H/ooODvQrILfRCcfDjIdUE
+xGL1mLlSHI6VyeO4AiDiac673kckAtha72IgJyJbs1wwulW1wHAVfxJZHP+lk/D/
+ycUsOBAp7KMTCYzNCQV1wW9fG4UyEt3Kz9OntNR+Jl1MQxbBryXWNwZZAoGAO48x
+9MOB5mjL2GJrr6M0aTfv//1SX40cLs0D2oX2sNZJnATkHskANqTO5L7KrTWgsEhD
+AKmKj1gmz15+4GtKuxcVAQ+RXQddd0OcNNAnnAQ2SyTVwE2bXoCTeQfleYCRV6ix
+u45BvJF3EWTmEmt0uaH+kzERA/iLm+n79iwawMUCgYB7s6ZkEbyZbJDDT8MXU/37
+vvLo5/sPzJ6hMPIrWbKybmUfKAMBkXYV90bVfBxim+PEGyiIWSHlXRCgHLUc/C7C
+4s8ouWDR2F3zUWjadzRsPI58qWL9yVa5aGoSzoJu2qyuX4QKS8hOehxVMzIB4Mrf
+Hh0tvtntgpJAW2TwXMVxCw==
+-----END PRIVATE KEY-----
diff --git a/tests/standalone/io/shared_socket_test.dart b/tests/standalone/io/shared_socket_test.dart
index 7f70a14..2fb755f 100644
--- a/tests/standalone/io/shared_socket_test.dart
+++ b/tests/standalone/io/shared_socket_test.dart
@@ -12,11 +12,18 @@
 import 'package:http/http.dart' as http;
 
 void main() async {
-  final workers = List<ServerWorker>.generate(4, (i) => ServerWorker(i));
-  workers.forEach((w) => w.start());
+  // Start a server to obtain a randomly assigned, free port.
+  final mainServer = await HttpServer.bind('::1', 0, shared: true);
+  final sharedPort = mainServer.port;
+
+  final workers =
+      List<ServerWorker>.generate(4, (i) => ServerWorker(i, sharedPort));
+  await Future.wait(workers.map((w) => w.start()));
+  mainServer.close();
+
   await Future.delayed(Duration(seconds: 1));
   // spawn client isolate
-  final clientisolate = await Isolate.spawn(client, 0);
+  final clientisolate = await Isolate.spawn(client, sharedPort);
   // Wait for 20 secs. It used to crash within 10 seconds.
   await Future.delayed(Duration(seconds: 20));
 
@@ -30,10 +37,11 @@
 
 class ServerWorker {
   final int workerid;
+  final int port;
   Isolate? _isolate;
   bool respawn = true;
 
-  ServerWorker(this.workerid);
+  ServerWorker(this.workerid, this.port);
 
   Future<void> start() async {
     final onExit = ReceivePort();
@@ -42,8 +50,10 @@
       // Respawn another isolate
       if (respawn) start();
     });
-    _isolate = await Isolate.spawn(_main, workerid,
+    final ready = ReceivePort();
+    _isolate = await Isolate.spawn(_main, [workerid, port, ready.sendPort],
         errorsAreFatal: true, onExit: onExit.sendPort);
+    await ready.first;
     if (workerid == 0) terminate();
   }
 
@@ -55,9 +65,13 @@
     });
   }
 
-  static _main(int workerid) async {
-    bool shared = true;
-    final server = await HttpServer.bind('::1', 1234, shared: shared);
+  static _main(List args) async {
+    final workerid = args[0] as int;
+    final port = args[1] as int;
+    final readyPort = args[2] as SendPort;
+
+    final server = await HttpServer.bind('::1', port, shared: true);
+    readyPort.send(null);
     server.listen((HttpRequest request) {
       print('from worker ${workerid}');
       final response = request.response;
@@ -77,12 +91,12 @@
   }
 }
 
-void client(int i) async {
+void client(int port) async {
   while (true) {
     final futures = <Future>[];
     final numAtOnce = 16; // enough to keep the server busy
     for (int i = 0; i < numAtOnce; ++i) {
-      futures.add(get('http://localhost:1234').then((_) {}));
+      futures.add(get('http://localhost:$port').then((_) {}));
     }
     await Future.wait(futures);
   }
diff --git a/tests/standalone/io/test_extension_fail_test.dart b/tests/standalone/io/test_extension_fail_test.dart
index dae4411..d6941e3 100644
--- a/tests/standalone/io/test_extension_fail_test.dart
+++ b/tests/standalone/io/test_extension_fail_test.dart
@@ -4,6 +4,11 @@
 //
 // Dart test program for testing native extensions.
 
+// OtherResources=test_extension.dart
+// OtherResources=test_extension_fail_tester.dart
+// OtherResources=test_relative_extension.dart
+// OtherResources=test_relative_extension_fail_tester.dart
+
 import "package:path/path.dart";
 import "dart:async";
 import "dart:io";
diff --git a/tests/standalone/io/test_extension_test.dart b/tests/standalone/io/test_extension_test.dart
index fc7caef..e2a11e6 100644
--- a/tests/standalone/io/test_extension_test.dart
+++ b/tests/standalone/io/test_extension_test.dart
@@ -4,6 +4,9 @@
 //
 // Dart test program for testing native extensions.
 
+// OtherResources=test_extension.dart
+// OtherResources=test_extension_tester.dart
+
 import "package:expect/expect.dart";
 import "package:path/path.dart";
 import 'dart:async';
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 66ee0cf..8c060c3 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -63,6 +63,7 @@
 
 [ $system != macos ]
 io/https_nonblocking_trust_evaluation_test: SkipByDesign
+io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
 
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index 63813b2..47d354b 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -109,3 +109,6 @@
 
 [ $builder_tag == crossword || $compiler != dartk && $compiler != dartkp || $compiler == dartkp && $system == windows ]
 entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe. Cannot run in cross-word environment as native extension is not built.
+
+[ $compiler != dartk || $runtime != vm ]
+check_for_aot_snapshot_jit_test: SkipByDesign # Test relies on paths, requires JIT test environment.
diff --git a/tests/standalone/standalone_vm.status b/tests/standalone/standalone_vm.status
index bc1e1fb..51fac12 100644
--- a/tests/standalone/standalone_vm.status
+++ b/tests/standalone/standalone_vm.status
@@ -6,6 +6,9 @@
 link_natives_lazily_test: SkipByDesign # Not supported.
 no_allow_absolute_addresses_test: SkipByDesign # Not supported.
 
+[ $runtime == vm ]
+typed_data_isolate_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+
 [ $system == android ]
 io/file_stat_test: Skip # Issue 26376
 io/file_system_watcher_test: Skip # Issue 26376
diff --git a/tests/standalone_2/causal_async_stack_test.dart b/tests/standalone_2/causal_async_stack_test.dart
index 5b44bec..652edb3 100644
--- a/tests/standalone_2/causal_async_stack_test.dart
+++ b/tests/standalone_2/causal_async_stack_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--causal_async_stacks --no-lazy-async-stacks
-// VMOptions=--no-causal_async_stacks --lazy-async-stacks
+//
+// VMOptions=--lazy-async-stacks
 
 import "package:expect/expect.dart";
 
diff --git a/tests/standalone_2/dart_developer_disabled_env_test.dart b/tests/standalone_2/dart_developer_disabled_env_test.dart
deleted file mode 100644
index 1d9653b..0000000
--- a/tests/standalone_2/dart_developer_disabled_env_test.dart
+++ /dev/null
@@ -1,11 +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.
-// VMOptions=--no_causal_async_stacks
-
-import "package:expect/expect.dart";
-
-main() {
-  Expect.isFalse(
-      const bool.fromEnvironment('dart.developer.causal_async_stacks'));
-}
diff --git a/tests/standalone_2/dart_developer_env2_test.dart b/tests/standalone_2/dart_developer_env2_test.dart
deleted file mode 100644
index 881880a..0000000
--- a/tests/standalone_2/dart_developer_env2_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--lazy-async-stacks --no-causal-async-stacks
-
-import "package:expect/expect.dart";
-
-main() {
-  Expect.isFalse(
-      const bool.fromEnvironment('dart.developer.causal_async_stacks'));
-}
diff --git a/tests/standalone_2/dart_developer_env_test.dart b/tests/standalone_2/dart_developer_env_test.dart
deleted file mode 100644
index abb7bf6..0000000
--- a/tests/standalone_2/dart_developer_env_test.dart
+++ /dev/null
@@ -1,11 +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.
-// VMOptions=--no-lazy-async-stacks --causal-async-stacks
-
-import "package:expect/expect.dart";
-
-main() {
-  Expect
-      .isTrue(const bool.fromEnvironment('dart.developer.causal_async_stacks'));
-}
diff --git a/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart b/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart
new file mode 100644
index 0000000..eed79c2
--- /dev/null
+++ b/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--long-ssl-cert-evaluation
+
+// This test verifies that lost of connection during handshake doesn't cause
+// vm crashes.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import "package:expect/expect.dart";
+
+String getFilename(String path) => Platform.script.resolve(path).toFilePath();
+
+final SecurityContext serverSecurityContext = () {
+  final context = SecurityContext();
+  context
+      .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
+  context.useCertificateChainBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+final SecurityContext clientSecurityContext = () {
+  final context = SecurityContext(withTrustedRoots: true);
+  context.setTrustedCertificatesBytes(
+      File(getFilename('localhost.crt')).readAsBytesSync());
+  return context;
+}();
+
+void main(List<String> args) async {
+  if (args.length >= 1 && args[0] == 'server') {
+    final server =
+        await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
+    print('ok ${server.port}');
+    server.listen((socket) {
+      print('server: got connection');
+      socket.close();
+    });
+    await Future.delayed(Duration(seconds: 2));
+    print('server: exiting');
+    exit(1);
+  }
+
+  final serverProcess = await Process.start(
+      Platform.executable, [Platform.script.toFilePath(), 'server']);
+  final serverPortCompleter = Completer<int>();
+
+  serverProcess.stdout
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) {
+    print('server stdout: $line');
+    if (line.startsWith('ok')) {
+      serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
+    }
+  });
+  serverProcess.stderr
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .listen((line) => print('server stderr: $line'));
+
+  int port = await serverPortCompleter.future;
+
+  var thrownException;
+  try {
+    print('client connecting...');
+    await SecureSocket.connect('localhost', port,
+        context: clientSecurityContext);
+    print('client connected.');
+  } catch (e) {
+    thrownException = e;
+  } finally {
+    await serverProcess.kill();
+  }
+  print('thrownException: $thrownException');
+  Expect.isTrue(thrownException is HandshakeException);
+}
diff --git a/tests/standalone_2/io/localhost.crt b/tests/standalone_2/io/localhost.crt
new file mode 100644
index 0000000..eeab890
--- /dev/null
+++ b/tests/standalone_2/io/localhost.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIUe+E1Xth9TMlsYY7qmf9zlfC1Ms0wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE4MTIzMTIzMDAxMVoYDzIxMTgx
+MjA3MjMwMDExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDEEY2eWBX1rTDgsAWheltKiAHREteaqX4iaGwF6/TC
+6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA6PDocRpK2zOObTqdVqJAiodUi0ov
+ds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3QkUMPCDBkLqiYUuR6j5QJ4Vz2OFV5g
+1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLIvzss+aHBTWD+9HYfgWsfJGI3UFgc
+zoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk10jhYdxdglXpTPOWP5YnwWsy8VbU
+1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEXdyxOzT3bAgMBAAGjfjB8MB0GA1Ud
+DgQWBBS/3CUrYgiD2qwdEDStghi+X3+4pzAfBgNVHSMEGDAWgBS/3CUrYgiD2qwd
+EDStghi+X3+4pzAPBgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAu5adpS/h
+bWXYaDLW5JGZAiOVVkMDhspJDdPwDHUTqMPj3V6aaecZTc46Q7TLEkLxIjU5OjvR
+ZHh3vo9X4S84Yf7NHv8eX50MK/RrzZolUROhZ6gtYZKkdZtjQKQd62ih5EB6gNnZ
++IW9nedg7Sae2Yh22jDC9Tc+dbvroOd7IUwL9gVSCcwiqVjvuWkDa7jqjnRp4sog
+yY1Obr14tmUMgR73Db7q3g0cVToztLYIMJnhjiSUs8nk83m/9/O4SGqQmievoZ5N
+60OlhU6enfFoj1xKpXWSGv6mqqdX0G9Ehz1EIetFhkBK2pP/R00gf4OMKc4ubw8d
+yTSUIeMSOo0QjA==
+-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/localhost.key b/tests/standalone_2/io/localhost.key
new file mode 100644
index 0000000..20815e4
--- /dev/null
+++ b/tests/standalone_2/io/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEEY2eWBX1rTDg
+sAWheltKiAHREteaqX4iaGwF6/TC6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA
+6PDocRpK2zOObTqdVqJAiodUi0ovds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3Qk
+UMPCDBkLqiYUuR6j5QJ4Vz2OFV5g1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLI
+vzss+aHBTWD+9HYfgWsfJGI3UFgczoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk
+10jhYdxdglXpTPOWP5YnwWsy8VbU1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEX
+dyxOzT3bAgMBAAECggEAHGsa5reHv0syCW8Z8dTFRKE/+ijL/UvRz3TpK1aO7G19
+9/BgHQOIhZ6yzjWWwVBk2W3ByYgGHoSRCAm7WUWDdRQefedRFpsG+2nYwaVKxGRp
+DC0OIASJ32NPLci3F8mgJdDfB3GLpA3k8JqQNSEBxFIOIPTP/xtjZ0Pl1SE9w7Uk
+8pwuJPJDPSAamguSNY5+HHcyta/i7Zsv2/S4BdV8Q8WQeCc6hcR3Zka1H0txgk8o
+qUurU2ApdnzINQ7ki0+D6CuVXEivmL/kPivQg0/khIQp1IXhdYdWCMKSUr1vkoAK
+0zc6H5DlDvdQPrjqdLGOUlVx5JnjTYd68/Wqje76eQKBgQD0uNR2yJYxmQmLC1y6
+TLXxvm0OOlmUiNMZgLOwDNdjXvOH/emtpHyyKhHpc3kzNK3xsNxyAYJRlaIUylj0
+C9dsipj+QTb4ICu0GlbLXsXN5iM592igoS4kMnP9KbzSc93k9BvMhh1emO8i3GB7
+v/1Cf/z+gP+viLMaPEFqKxI8FwKBgQDNGrjabA2jkawanHHUUhwscwB4RrvuuJTG
+Zv7L7QXBMYx7CUwJztV5amkUNrbBW/67/MMQB0Djv1pgMo4QCWeftb9oHFXGu3hV
+kUj7Or/Z2TWYtLIdxgTDbRRtit57z3NaCHCDgQhyAZUY3y8cvXFYdHDnJlqLTN77
+bzQub7BS3QKBgHtUep6yUB8GxSxxuXWaG0eNdGBrP6H/ooODvQrILfRCcfDjIdUE
+xGL1mLlSHI6VyeO4AiDiac673kckAtha72IgJyJbs1wwulW1wHAVfxJZHP+lk/D/
+ycUsOBAp7KMTCYzNCQV1wW9fG4UyEt3Kz9OntNR+Jl1MQxbBryXWNwZZAoGAO48x
+9MOB5mjL2GJrr6M0aTfv//1SX40cLs0D2oX2sNZJnATkHskANqTO5L7KrTWgsEhD
+AKmKj1gmz15+4GtKuxcVAQ+RXQddd0OcNNAnnAQ2SyTVwE2bXoCTeQfleYCRV6ix
+u45BvJF3EWTmEmt0uaH+kzERA/iLm+n79iwawMUCgYB7s6ZkEbyZbJDDT8MXU/37
+vvLo5/sPzJ6hMPIrWbKybmUfKAMBkXYV90bVfBxim+PEGyiIWSHlXRCgHLUc/C7C
+4s8ouWDR2F3zUWjadzRsPI58qWL9yVa5aGoSzoJu2qyuX4QKS8hOehxVMzIB4Mrf
+Hh0tvtntgpJAW2TwXMVxCw==
+-----END PRIVATE KEY-----
diff --git a/tests/standalone_2/io/shared_socket_test.dart b/tests/standalone_2/io/shared_socket_test.dart
index 5f933bb..bd1a041 100644
--- a/tests/standalone_2/io/shared_socket_test.dart
+++ b/tests/standalone_2/io/shared_socket_test.dart
@@ -12,11 +12,18 @@
 import 'package:http/http.dart' as http;
 
 void main() async {
-  final workers = List<ServerWorker>.generate(4, (i) => ServerWorker(i));
-  workers.forEach((w) => w.start());
+  // Start a server to obtain a randomly assigned, free port.
+  final mainServer = await HttpServer.bind('::1', 0, shared: true);
+  final sharedPort = mainServer.port;
+
+  final workers =
+      List<ServerWorker>.generate(4, (i) => ServerWorker(i, sharedPort));
+  await Future.wait(workers.map((w) => w.start()));
+  mainServer.close();
+
   await Future.delayed(Duration(seconds: 1));
   // spawn client isolate
-  final clientisolate = await Isolate.spawn(client, 0);
+  final clientisolate = await Isolate.spawn(client, sharedPort);
   // Wait for 20 secs. It used to crash within 10 seconds.
   await Future.delayed(Duration(seconds: 20));
 
@@ -30,10 +37,11 @@
 
 class ServerWorker {
   final int workerid;
+  final int port;
   Isolate _isolate;
   bool respawn = true;
 
-  ServerWorker(this.workerid);
+  ServerWorker(this.workerid, this.port);
 
   Future<void> start() async {
     final onExit = ReceivePort();
@@ -42,8 +50,10 @@
       // Respawn another isolate
       if (respawn) start();
     });
-    _isolate = await Isolate.spawn(_main, workerid,
+    final ready = ReceivePort();
+    _isolate = await Isolate.spawn(_main, [workerid, port, ready.sendPort],
         errorsAreFatal: true, onExit: onExit.sendPort);
+    await ready.first;
     if (workerid == 0) terminate();
   }
 
@@ -57,9 +67,13 @@
     });
   }
 
-  static _main(int workerid) async {
-    bool shared = true;
-    final server = await HttpServer.bind('::1', 1234, shared: shared);
+  static _main(List args) async {
+    final workerid = args[0] as int;
+    final port = args[1] as int;
+    final readyPort = args[2] as SendPort;
+
+    final server = await HttpServer.bind('::1', port, shared: true);
+    readyPort.send(null);
     server.listen((HttpRequest request) {
       print('from worker ${workerid}');
       final response = request.response;
@@ -79,12 +93,12 @@
   }
 }
 
-void client(int i) async {
+void client(int port) async {
   while (true) {
     final futures = <Future>[];
     final numAtOnce = 16; // enough to keep the server busy
     for (int i = 0; i < numAtOnce; ++i) {
-      futures.add(get('http://localhost:1234').then((_) {}));
+      futures.add(get('http://localhost:$port').then((_) {}));
     }
     await Future.wait(futures);
   }
diff --git a/tests/standalone_2/io/test_extension_fail_test.dart b/tests/standalone_2/io/test_extension_fail_test.dart
index dae4411..d6941e3 100644
--- a/tests/standalone_2/io/test_extension_fail_test.dart
+++ b/tests/standalone_2/io/test_extension_fail_test.dart
@@ -4,6 +4,11 @@
 //
 // Dart test program for testing native extensions.
 
+// OtherResources=test_extension.dart
+// OtherResources=test_extension_fail_tester.dart
+// OtherResources=test_relative_extension.dart
+// OtherResources=test_relative_extension_fail_tester.dart
+
 import "package:path/path.dart";
 import "dart:async";
 import "dart:io";
diff --git a/tests/standalone_2/io/test_extension_test.dart b/tests/standalone_2/io/test_extension_test.dart
index e69ae28..e2a11e6 100644
--- a/tests/standalone_2/io/test_extension_test.dart
+++ b/tests/standalone_2/io/test_extension_test.dart
@@ -4,6 +4,9 @@
 //
 // Dart test program for testing native extensions.
 
+// OtherResources=test_extension.dart
+// OtherResources=test_extension_tester.dart
+
 import "package:expect/expect.dart";
 import "package:path/path.dart";
 import 'dart:async';
@@ -21,6 +24,7 @@
     default:
       Expect.fail('Unknown operating system ${Platform.operatingSystem}');
   }
+  throw 'Unknown operating system ${Platform.operatingSystem}';
 }
 
 // Returns a list containing the source file name in the first element and the
@@ -37,6 +41,7 @@
     default:
       Expect.fail('Unknown operating system ${Platform.operatingSystem}');
   }
+  throw 'Unknown operating system ${Platform.operatingSystem}';
 }
 
 String getExtensionPath(String buildDirectory, String filename) {
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index abe364c..9dc0156 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -72,6 +72,7 @@
 
 [ $system != macos ]
 io/https_nonblocking_trust_evaluation_test: SkipByDesign
+io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
 
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 52e78e2..5a07018 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -110,3 +110,6 @@
 
 [ $builder_tag == crossword || $compiler != dartk && $compiler != dartkp || $compiler == dartkp && $system == windows ]
 entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe. Cannot run in cross-word environment as native extension is not built.
+
+[ $compiler != dartk || $runtime != vm ]
+check_for_aot_snapshot_jit_test: SkipByDesign # Test relies on paths, requires JIT test environment.
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index 478da0f..8bc68e8 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -6,6 +6,9 @@
 link_natives_lazily_test: SkipByDesign # Not supported.
 no_allow_absolute_addresses_test: SkipByDesign # Not supported.
 
+[ $runtime == vm ]
+typed_data_isolate_test: Pass, Slow # https://dartbug.com/36097: Slower while isolate groups are being gradually enabled in JIT mode.
+
 [ $system == android ]
 io/file_stat_test: Skip # Issue 26376
 io/file_system_watcher_test: Skip # Issue 26376
diff --git a/third_party/tcmalloc/include/config.h b/third_party/tcmalloc/include/config.h
index 3cd4982..ef33e13 100644
--- a/third_party/tcmalloc/include/config.h
+++ b/third_party/tcmalloc/include/config.h
@@ -6,6 +6,9 @@
 #define GPERFTOOLS_CONFIG_H_
 
 
+/* enable aggressive decommit by default */
+/* #undef ENABLE_AGGRESSIVE_DECOMMIT_BY_DEFAULT */
+
 /* Build new/delete operators for overaligned types */
 #define ENABLE_ALIGNED_NEW_DELETE 1
 
@@ -18,6 +21,9 @@
 /* Build sized deletion operators */
 #define ENABLE_SIZED_DELETE 1
 
+/* Define to 1 if you have the <asm/ptrace.h> header file. */
+/* #undef HAVE_ASM_PTRACE_H */
+
 /* Define to 1 if compiler supports __builtin_stack_pointer */
 /* #undef HAVE_BUILTIN_STACK_POINTER */
 
@@ -36,7 +42,7 @@
 
 /* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
    */
-#define HAVE_DECL_CFREE 1
+#define HAVE_DECL_CFREE 0
 
 /* Define to 1 if you have the declaration of `memalign', and to 0 if you
    don't. */
@@ -87,9 +93,6 @@
 /* Define to 1 if you have the `geteuid' function. */
 #define HAVE_GETEUID 1
 
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
 /* Define to 1 if you have the <glob.h> header file. */
 #define HAVE_GLOB_H 1
 
@@ -160,9 +163,6 @@
 /* Define to 1 if you have the <sys/cdefs.h> header file. */
 #define HAVE_SYS_CDEFS_H 1
 
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
 /* Define to 1 if you have the <sys/prctl.h> header file. */
 #define HAVE_SYS_PRCTL_H 1
 
@@ -239,7 +239,7 @@
 #define PACKAGE_NAME "gperftools"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.7"
+#define PACKAGE_STRING "gperftools 2.8"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "gperftools"
@@ -248,7 +248,7 @@
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "2.7"
+#define PACKAGE_VERSION "2.8"
 
 /* How to access the PC from a struct ucontext */
 /* #undef PC_FROM_UCONTEXT */
@@ -285,17 +285,14 @@
 /* the namespace where STL code like vector<> is defined */
 #define STL_NAMESPACE std
 
-/* Define 32K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_32K_PAGES */
-
-/* Define 64K of internal pages size for tcmalloc */
-/* #undef TCMALLOC_64K_PAGES */
-
 /* Define 8 bytes of allocation alignment for tcmalloc */
 /* #undef TCMALLOC_ALIGN_8BYTES */
 
+/* Define internal page size for tcmalloc as number of left bitshift */
+/* #undef TCMALLOC_PAGE_SIZE_SHIFT */
+
 /* Version number of package */
-#define VERSION "2.7"
+#define VERSION "2.8"
 
 /* C99 says: define this to get the PRI... macros from stdint.h */
 #ifndef __STDC_FORMAT_MACROS
diff --git a/third_party/tcmalloc/include/gperftools/tcmalloc.h b/third_party/tcmalloc/include/gperftools/tcmalloc.h
index 7935081..2a5633f 100644
--- a/third_party/tcmalloc/include/gperftools/tcmalloc.h
+++ b/third_party/tcmalloc/include/gperftools/tcmalloc.h
@@ -43,9 +43,9 @@
 
 /* Define the version number so folks can check against it */
 #define TC_VERSION_MAJOR  2
-#define TC_VERSION_MINOR  7
+#define TC_VERSION_MINOR  8
 #define TC_VERSION_PATCH  ""
-#define TC_VERSION_STRING "gperftools 2.7"
+#define TC_VERSION_STRING "gperftools 2.8"
 
 /* For struct mallinfo, if it's defined. */
 #if 1
diff --git a/third_party/wasmer/BUILD.gn b/third_party/wasmer/BUILD.gn
index f3398f5..0f65bf7 100644
--- a/third_party/wasmer/BUILD.gn
+++ b/third_party/wasmer/BUILD.gn
@@ -1,6 +1,24 @@
 import("../../build/rust/rust.gni")
 
-rust_library("wasmer") {
+shared_library("wasmer_wrap") {
+  sources = [
+    "../../runtime/include/dart_api_dl.c",
+    "finalizers.cc",
+  ]
+  deps = [
+    ":wasmer_lib",
+    "../../runtime/bin:dart",
+  ]
+  include_dirs = [ "../../runtime" ]
+  defines = [ "DART_SHARED_LIB" ]
+  if (is_linux) {
+    libs = [ "rt" ]
+  }
+
+  # Force linking of all wasmer symbols.
+  ldflags = [ "-Wl,--no-as-needed" ]
+}
+
+rust_library("wasmer_lib") {
   lib_name = "wasmer"
-  shared = true
 }
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
index 8ec064a..a476549 100644
--- a/third_party/wasmer/Cargo.toml
+++ b/third_party/wasmer/Cargo.toml
@@ -1,13 +1,13 @@
 [package]
 name = "wasmer"
-version = "1.0.0-alpha4"
+version = "1.0.0-alpha5"
 
 [lib]
 name = "wasmer"
-crate-type = ["dylib"]
+crate-type = ["staticlib"]
 path = "wasmer.rs"
 
 [dependencies.wasmer-c-api]
-version = "1.0.0-alpha4"
+version = "1.0.0-alpha5"
 default-features = false
 features = ["jit", "cranelift", "wasi"]
diff --git a/third_party/wasmer/finalizers.cc b/third_party/wasmer/finalizers.cc
new file mode 100644
index 0000000..85d5286
--- /dev/null
+++ b/third_party/wasmer/finalizers.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "include/dart_api.h"
+#include "include/dart_api_dl.h"
+
+#define FINALIZER(type)                                                        \
+  extern "C" void wasm_##type##_delete(void*);                                 \
+  extern "C" void wasm_##type##_finalizer(void*, void* native_object) {        \
+    wasm_##type##_delete(native_object);                                       \
+  }                                                                            \
+  DART_EXPORT void set_finalizer_for_##type(Dart_Handle dart_object,           \
+                                            void* native_object) {             \
+    Dart_NewFinalizableHandle_DL(dart_object, native_object, 0,                \
+                                 wasm_##type##_finalizer);                     \
+  }
+
+FINALIZER(engine);
+FINALIZER(store);
+FINALIZER(module);
+FINALIZER(instance);
+FINALIZER(trap);
+FINALIZER(memorytype);
+FINALIZER(memory);
+FINALIZER(func);
diff --git a/tools/VERSION b/tools/VERSION
index aec0ebb..4bb1af7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 29
-PRERELEASE_PATCH 10
\ No newline at end of file
+PRERELEASE 133
+PRERELEASE_PATCH 1
\ No newline at end of file
diff --git a/tools/bots/extend_results.dart b/tools/bots/extend_results.dart
index 225cc18..7dc7743 100644
--- a/tools/bots/extend_results.dart
+++ b/tools/bots/extend_results.dart
@@ -46,8 +46,9 @@
     result['commit_time'] = commitTime;
     result['build_number'] = buildNumber;
     result['builder_name'] = builderName;
-    result['flaky'] = (flaky != null);
-    result['previous_flaky'] = (priorFlaky != null);
+    result['flaky'] = flaky != null && (flaky['active'] ?? true) == true;
+    result['previous_flaky'] =
+        priorFlaky != null && (priorFlaky['active'] ?? true) == true;
     if (firstPriorResult != null) {
       result['previous_commit_hash'] = firstPriorResult['commit_hash'];
       result['previous_commit_time'] = firstPriorResult['commit_time'];
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 2a75eca..5e3c9e2 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -3,9 +3,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.
 
-// Find the newest commit that has a full set of results on the bots.
-
-// @dart = 2.9
+// Find the newest commit that has a full set of results on the builders.
 
 import 'dart:async';
 import 'dart:convert';
@@ -17,13 +15,13 @@
 
 void main(List<String> args) async {
   final parser = new ArgParser();
-  parser.addMultiOption("bot",
+  parser.addMultiOption("builder",
       abbr: "b",
-      help: "Select the bots matching the glob pattern [option is repeatable]",
+      help: "Select the builders matching the glob [option is repeatable]",
       splitCommas: false);
   parser.addOption("branch",
       abbr: "B",
-      help: "Select the bots building this branch",
+      help: "Select the builders building this branch",
       defaultsTo: "master");
   parser.addOption("count",
       abbr: "c", help: "List this many commits", defaultsTo: "1");
@@ -33,7 +31,7 @@
   if (options["help"]) {
     print("""
 Usage: find_base_commit.dart [OPTION]...
-Find the newest commit that has a full set of results on the bots.
+Find the newest commit that has a full set of results on the builders.
 
 The options are as follows:
 
@@ -43,34 +41,50 @@
 
   int count = int.parse(options["count"]);
   final globs = new List<Glob>.from(
-      options["bot"].map((String pattern) => new Glob(pattern)));
+      options["builder"].map((String pattern) => new Glob(pattern)));
 
   // Download the most recent builds from buildbucket.
-  int maxBuilds = 1000;
-  final url = Uri.parse(
-      "https://cr-buildbucket.appspot.com/_ah/api/buildbucket/v1/search"
-      "?bucket=luci.dart.ci.sandbox"
-      "&max_builds=$maxBuilds"
-      "&status=COMPLETED"
-      "&fields=builds(url%2Cparameters_json)");
+  const maxBuilds = 1000;
+  final url = Uri.parse("https://cr-buildbucket.appspot.com"
+      "/prpc/buildbucket.v2.Builds/SearchBuilds");
   const maxRetries = 3;
   const timeout = const Duration(seconds: 30);
-  Map<String, dynamic> object;
+  final query = jsonEncode({
+    "predicate": {
+      "builder": {"project": "dart", "bucket": "ci.sandbox"},
+      "status": "ENDED_MASK"
+    },
+    "pageSize": maxBuilds,
+    "fields": "builds.*.builder.builder,builds.*.input"
+  });
+  late Map<String, dynamic> searchResult;
   for (int i = 1; i <= maxRetries; i++) {
     try {
       final client = new HttpClient();
-      final request = await client.getUrl(url).timeout(timeout);
+      final request = await client.postUrl(url).timeout(timeout)
+        ..headers.contentType = ContentType.json
+        ..headers.add(HttpHeaders.acceptHeader, ContentType.json)
+        ..write(query);
       final response = await request.close().timeout(timeout);
-      object = await response
+      if (response.statusCode != 200) {
+        print("Failed to search for builds: "
+            "${response.statusCode}:${response.reasonPhrase}");
+        exit(1);
+      }
+      const prefix = ")]}'";
+      searchResult = await (response
           .cast<List<int>>()
           .transform(new Utf8Decoder())
+          .map((event) =>
+              event.startsWith(prefix) ? event.substring(prefix.length) : event)
           .transform(new JsonDecoder())
+          .cast<Map<String, dynamic>>()
           .first
-          .timeout(timeout);
+          .timeout(timeout));
       client.close();
       break;
     } on TimeoutException catch (e) {
-      final inSeconds = e.duration.inSeconds;
+      final inSeconds = e.duration?.inSeconds;
       stderr.writeln(
           "Attempt $i of $maxRetries timed out after $inSeconds seconds");
       if (i == maxRetries) {
@@ -81,57 +95,61 @@
   }
 
   // Locate the builds we're interested in and map them to each commit. The
-  // builds returned by the API are sorted with the newest first. Since bots
+  // builds returned by the API are sorted with the newest first. Since builders
   // don't build back in time and always build the latest commit whenever they
   // can, the first time we see a commit, we know it's newer than all commits
-  // we haven't seen yet. The insertion order into the botsForCommits map will
-  // then sorted with the newest commit first.
-  final builds = object["builds"];
-  final botsForCommits = <String, Set<String>>{};
+  // we haven't seen yet. The insertion order into the buildersForCommits map
+  // will then sorted with the newest commit first.
+  final builds = searchResult["builds"];
+  if (builds == null) {
+    print("No builds found");
+    exit(1);
+  }
+  final buildersForCommits = <String, Set<String>>{};
   for (final build in builds) {
-    final parameters = jsonDecode(build["parameters_json"]);
-    final bot = parameters["builder_name"];
-    if (bot.endsWith("-beta") ||
-        bot.endsWith("-dev") ||
-        bot.endsWith("-stable")) {
+    final builder = build["builder"]?["builder"];
+    if (builder is! String ||
+        builder.endsWith("-beta") ||
+        builder.endsWith("-dev") ||
+        builder.endsWith("-stable")) {
       // Ignore the release builders. The -try builders aren't in the
       // bucket we're reading.
       continue;
     }
-    if (globs.isNotEmpty && !globs.any((glob) => glob.matches(bot))) {
-      // Filter way bots we're not interested in.
+    if (globs.isNotEmpty && !globs.any((glob) => glob.matches(builder))) {
+      // Filter way builders we're not interested in.
       continue;
     }
-    final properties = parameters["properties"];
-    final branch = properties["branch"];
-    if (branch != null && branch != "refs/heads/${options['branch']}") {
-      // Ignore bots that are building the wrong branch.
+    final input = build["input"]?["gitilesCommit"];
+    if (input == null) {
+      // Ignore builds not triggered by a commit, e.g. fuzz-linux.
       continue;
     }
-    final commit = properties["revision"];
-    if (commit == null) {
-      // Ignore bots that aren't commit based, e.g. fuzz-linux.
+    final ref = input["ref"];
+    if (ref != "refs/heads/${options['branch']}") {
+      // Ignore builds on the wrong branch.
       continue;
     }
-    final botsForCommit =
-        botsForCommits.putIfAbsent(commit, () => new Set<String>());
-    botsForCommit.add(bot);
+    final commit = input["id"] as String;
+    final buildersForCommit =
+        buildersForCommits.putIfAbsent(commit, () => new Set<String>());
+    buildersForCommit.add(builder);
   }
 
-  if (botsForCommits.isEmpty) {
-    print("Failed to locate any commits having run on the bots");
+  if (buildersForCommits.isEmpty) {
+    print("Failed to locate any commits having run on the builders");
     exitCode = 1;
     return;
   }
 
   int maxBots = 0;
-  for (final commit in botsForCommits.keys) {
-    maxBots = max(maxBots, botsForCommits[commit].length);
+  for (final builders in buildersForCommits.values) {
+    maxBots = max(maxBots, builders.length);
   }
 
-  // List commits run on the most bots.
-  for (final commit in botsForCommits.keys
-      .where((commit) => botsForCommits[commit].length == maxBots)
+  // List commits run on the most builders.
+  for (final commit in buildersForCommits.keys
+      .where((commit) => buildersForCommits[commit]!.length == maxBots)
       .take(count)) {
     print(commit);
   }
diff --git a/tools/bots/flutter/compile_flutter.sh b/tools/bots/flutter/compile_flutter.sh
index 1843abb..8f4f2d6 100755
--- a/tools/bots/flutter/compile_flutter.sh
+++ b/tools/bots/flutter/compile_flutter.sh
@@ -82,7 +82,6 @@
     $checkout/pkg/front_end/tool/_fasta/compile_platform.dart \
     dart:core \
     -Ddart.vm.product=false \
-    -Ddart.developer.causal_async_stacks=true \
     -Ddart.isVM=true \
     --enable-experiment=non-nullable \
     --nnbd-agnostic \
diff --git a/tools/bots/lib/src/firestore.dart b/tools/bots/lib/src/firestore.dart
index 44344e2..166173c 100644
--- a/tools/bots/lib/src/firestore.dart
+++ b/tools/bots/lib/src/firestore.dart
@@ -70,7 +70,7 @@
     var response = await _client.get(url, headers: _headers);
     if (response.statusCode == HttpStatus.ok) {
       var document = jsonDecode(response.body);
-      if (!document is Map) {
+      if (document is! Map) {
         throw _error(response, message: 'Expected a Map');
       }
       return document;
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index f8cbe1d..4b3cf6e 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -26,7 +26,7 @@
       "pkg/",
       "runtime/tests/",
       "samples-dev/",
-      "samples/",
+      "samples_2/",
       "sdk/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
@@ -45,7 +45,6 @@
       "tests/corelib_2/",
       "tests/dart2js_2/",
       "tests/dartdevc_2/",
-      "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
       "tests/lib_2/",
@@ -86,7 +85,6 @@
       "tests/corelib/",
       "tests/dart2js/",
       "tests/dartdevc/",
-      "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
       "tests/lib/",
@@ -115,7 +113,7 @@
       "pkg/",
       "runtime/tests/",
       "samples-dev/",
-      "samples/",
+      "samples_2/",
       "sdk/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
@@ -134,7 +132,6 @@
       "tests/corelib_2/",
       "tests/dart2js_2/",
       "tests/dartdevc_2/",
-      "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
       "tests/lib_2/",
@@ -178,7 +175,6 @@
       "tests/corelib/",
       "tests/dart2js/",
       "tests/dartdevc/",
-      "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
       "tests/lib/",
@@ -204,6 +200,7 @@
       "runtime/tests/",
       "samples-dev/",
       "samples/",
+      "samples_2/",
       "sdk/",
       "tests/.dart_tool/package_config.json",
       "tests/angular/",
@@ -225,7 +222,6 @@
       "tests/dart2js_2/",
       "tests/dartdevc/",
       "tests/dartdevc_2/",
-      "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
       "tests/lib/",
@@ -308,6 +304,7 @@
       "xcodebuild/ReleaseSIMARM64/",
       "xcodebuild/ReleaseX64/",
       "samples/",
+      "samples_2/",
       "samples-dev/",
       "tools/",
       "third_party/android_tools/sdk/platform-tools/adb",
@@ -336,7 +333,6 @@
       "tests/dart2js_2/",
       "tests/dartdevc",
       "tests/dartdevc_2",
-      "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
       "tests/lib/",
@@ -424,6 +420,9 @@
     "flutter-frontend": {
       "__comment__": "This configuration is only used for a custom test runner. If it conflicts with a new configuration you are adding, you can make this configuration more specific by adding options."
     },
+    "vm-ffi-unit-test": {
+      "__comment__": "This configuration is only used for a custom test runner. If it conflicts with a new configuration you are adding, you can make this configuration more specific by adding options."
+    },
     "unittest-asserts-no-sdk-(linux|mac|win)": {
       "options": {
         "compiler": "dartk",
@@ -513,7 +512,9 @@
     "dart2js-(linux|mac|win)-chrome-unsound": {
       "options": {
         "use-sdk": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-weak-(linux|mac|win)-x64-d8": {
@@ -530,7 +531,9 @@
     "dart2js-(linux|win)-firefox-unsound": {
       "options": {
         "use-sdk": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-win-ie11": {
@@ -543,7 +546,9 @@
       "options": {
         "use-sdk": true,
         "babel": "{\"presets\":[\"es2015\"]}",
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-win-edge": {
@@ -554,7 +559,9 @@
     "dart2js-win-edge-unsound": {
       "options": {
         "use-sdk": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-mac-safari": {
@@ -565,7 +572,9 @@
     "dart2js-mac-safari-unsound": {
       "options": {
         "use-sdk": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-minified-csp-(linux|mac|win)-chrome": {
@@ -580,7 +589,9 @@
         "minified": true,
         "csp": true,
         "use-sdk": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-minified-(linux|mac|win)-d8": {
@@ -593,7 +604,9 @@
       "options": {
         "minified": true,
         "use-sdk": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-production-(linux|mac|win)-d8": {
@@ -613,7 +626,9 @@
     "dart2js-hostasserts-(linux|mac|win)-(ia32|x64)-d8-unsound": {
       "options": {
         "host-checked": true,
-        "dart2js-options": ["--no-sound-null-safety"]
+        "dart2js-options": [
+          "--no-sound-null-safety"
+        ]
       }
     },
     "dart2js-hostasserts-weak-(linux|win)-x64-(d8|chrome)": {
@@ -751,7 +766,7 @@
         "builder-tag": "vm_nnbd"
       }
     },
-    "dartkp-weak-asserts-(linux|mac)-(debug|product|release)-simarm64": {
+    "dartkp-weak-asserts-(linux|mac)-(debug|product|release)-(simarm|simarm64)": {
       "options": {
         "enable-asserts": true,
         "use-elf": true,
@@ -781,7 +796,7 @@
         "builder-tag": "vm_nnbd"
       }
     },
-    "dartkp-strong-(linux|mac)-(debug|product|release)-simarm64": {
+    "dartkp-strong-(linux|mac)-(debug|product|release)-(simarm|simarm64)": {
       "options": {
         "use-elf": true,
         "builder-tag": "vm_nnbd"
@@ -1108,10 +1123,26 @@
         "vm-precomp-ffi-qemu-linux-release-arm"
       ],
       "meta": {
-        "description": "This configuration is used for running FFI tests on qemu."
+        "description": "This configuration is used for running FFI tests on qemu and FFI unit tests."
       },
       "steps": [
         {
+          "name": "build run_ffi_unit_tests",
+          "script": "tools/build.py",
+          "arguments": [
+            "--arch=x64",
+            "--mode=debug",
+            "run_ffi_unit_tests"
+          ]
+        },
+        {
+          "name": "ffi unit tests",
+          "arguments": [
+            "-nvm-ffi-unit-test",
+            "ffi_unit"
+          ]
+        },
+        {
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
@@ -1405,7 +1436,7 @@
           "name": "vm tests",
           "arguments": [
             "-ndartk-${sanitizer}-${system}-${mode}-${arch}",
-            "vm"
+            "vm/cc"
           ]
         }
       ]
@@ -1459,7 +1490,7 @@
           "name": "vm tests",
           "arguments": [
             "-ndartkp-${sanitizer}-${system}-${mode}-${arch}",
-            "vm"
+            "vm/cc"
           ]
         }
       ]
@@ -2810,7 +2841,7 @@
         "analyzer-analysis-server-linux"
       ],
       "meta": {
-        "description": "Analyze analyzer related packages."
+        "description": "Analyze repository packages."
       },
       "steps": [
         {
@@ -2822,9 +2853,9 @@
         },
         {
           "name": "analyze runtime/tools/dartfuzz",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "runtime/tools/dartfuzz"
           ]
         },
@@ -2833,6 +2864,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/analysis_server"
           ]
         },
@@ -2841,6 +2873,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/analysis_server_client"
           ]
         },
@@ -2849,6 +2882,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/analyzer"
           ]
         },
@@ -2857,6 +2891,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/analyzer_cli"
           ]
         },
@@ -2865,30 +2900,31 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/analyzer_plugin"
           ]
         },
         {
           "name": "analyze pkg/async_helper",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/async_helper"
           ]
         },
         {
           "name": "analyze pkg/build_integration",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/build_integration"
           ]
         },
         {
           "name": "analyze pkg/compiler",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/compiler"
           ]
         },
@@ -2903,98 +2939,102 @@
         },
         {
           "name": "analyze pkg/dart2js_tools",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/dart2js_tools"
           ]
         },
         {
           "name": "analyze pkg/dart_internal",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/dart_internal"
           ]
         },
         {
           "name": "analyze pkg/dev_compiler",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
-            "--fatal-lints",
+            "analyze",
+            "--fatal-infos",
             "pkg/dev_compiler"
           ]
         },
         {
           "name": "analyze pkg/expect",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/expect"
           ]
         },
         {
           "name": "analyze pkg/front_end",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/front_end"
           ]
         },
         {
           "name": "analyze pkg/js",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/js"
           ]
         },
         {
           "name": "analyze pkg/js_ast",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/js_ast"
           ]
         },
         {
           "name": "analyze pkg/kernel",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/kernel"
           ]
         },
         {
           "name": "analyze pkg/meta",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/meta"
           ]
         },
         {
           "name": "analyze pkg/native_stack_traces",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
             "pkg/native_stack_traces"
           ]
         },
         {
           "name": "analyze pkg/smith",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/smith"
           ]
         },
         {
           "name": "analyze pkg/sourcemap_testing",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/sourcemap_testing"
           ]
         },
@@ -3003,6 +3043,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/status_file"
           ]
         },
@@ -3011,6 +3052,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/telemetry"
           ]
         },
@@ -3024,25 +3066,28 @@
         },
         {
           "name": "analyze pkg/testing",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/testing"
           ]
         },
         {
           "name": "analyze pkg/vm",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/vm"
           ]
         },
         {
           "name": "analyze pkg/vm_service",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/vm_service"
           ]
         },
@@ -3051,21 +3096,24 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/vm_snapshot_analysis"
           ]
         },
         {
           "name": "analyze pkg/dds",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
-            "--fatal-warnings",
+            "analyze",
+            "--fatal-infos",
             "pkg/dds"
           ]
         },
         {
           "name": "analyze runtime/observatory",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
+            "analyze",
             "runtime/observatory"
           ]
         },
@@ -3200,6 +3248,8 @@
             "--arch=ia32",
             "create_sdk",
             "runtime",
+            "dart2js_platform.dill",
+            "dart2js_nnbd_strong_platform.dill",
             "kernel-service.dart.snapshot"
           ]
         },
@@ -3234,6 +3284,8 @@
             "runtime",
             "gen_snapshot",
             "dart_precompiled_runtime",
+            "dart2js_platform.dill",
+            "dart2js_nnbd_strong_platform.dill",
             "kernel-service.dart.snapshot",
             "dartdevc_test"
           ]
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 8407171..ea827b4 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -75,7 +75,7 @@
     rm -f linux-x64_profile.tar.gz
   elif [ "$command" = linux-ia32-build ]; then
     # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync.
-    ./tools/build.py --mode=release --arch=ia32 create_sdk runtime kernel-service.dart.snapshot
+    ./tools/build.py --mode=release --arch=ia32 create_sdk runtime dart2js_platform.dill dart2js_nnbd_strong_platform.dill kernel-service.dart.snapshot
   elif [ "$command" = linux-ia32-archive ]; then
     strip -w \
       -K 'kDartVmSnapshotData' \
@@ -148,6 +148,7 @@
       out/ReleaseIA32/dart-sdk \
       out/ReleaseIA32/dart \
       out/ReleaseIA32/gen_snapshot \
+      out/ReleaseIA32/dart2js_nnbd_strong_platform.dill \
       out/ReleaseIA32/kernel-service.dart.snapshot \
       out/ReleaseIA32/run_vm_tests \
       sdk \
@@ -195,7 +196,7 @@
     rm -rf tmp
   elif [ "$command" = linux-x64-build ]; then
     # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync.
-    ./tools/build.py --mode=release --arch=x64 create_sdk runtime gen_snapshot dart_precompiled_runtime kernel-service.dart.snapshot dartdevc_test
+    ./tools/build.py --mode=release --arch=x64 create_sdk runtime gen_snapshot dart_precompiled_runtime dart2js_platform.dill dart2js_nnbd_strong_platform.dill kernel-service.dart.snapshot dartdevc_test
   elif [ "$command" = linux-x64-archive ]; then
     strip -w \
       -K 'kDartVmSnapshotData' \
@@ -287,6 +288,7 @@
       out/ReleaseX64/dart-sdk \
       out/ReleaseX64/dart \
       out/ReleaseX64/gen_snapshot \
+      out/ReleaseX64/dart2js_nnbd_strong_platform.dill \
       out/ReleaseX64/kernel-service.dart.snapshot \
       out/ReleaseX64/run_vm_tests \
       third_party/d8/linux/x64 \
@@ -357,6 +359,7 @@
     out/ReleaseX64/run_vm_tests --dfe=out/ReleaseX64/kernel-service.dart.snapshot --sound-null-safety --enable-experiment=non-nullable UseDartApi
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages benchmarks/Example/dart2/Example.dart
     out/ReleaseX64/dart --sound-null-safety --enable-experiment=non-nullable --profile-period=10000 --packages=.packages benchmarks/Example/dart/Example.dart
+    out/ReleaseX64/dart --profile-period=10000 --packages=.packages benchmarks/IsolateSpawn/dart2/IsolateSpawn.dart
     cd ..
     rm -rf tmp
   else
diff --git a/tools/bots/update_flakiness.dart b/tools/bots/update_flakiness.dart
index 337bf61..92667a5 100755
--- a/tools/bots/update_flakiness.dart
+++ b/tools/bots/update_flakiness.dart
@@ -41,6 +41,10 @@
       ? await loadResultsMap(options['input'])
       : <String, Map<String, dynamic>>{};
 
+  final resultsForInactiveFlakiness = {
+    for (final flakyTest in data.keys)
+      if (data[flakyTest]['active'] == false) flakyTest: <String>{}
+  };
   // Incrementally update the flakiness data with each observed result.
   for (final path in parameters) {
     final results = await loadResults(path);
@@ -49,6 +53,7 @@
       final String name = resultObject['name'] /*!*/;
       final String result = resultObject['result'] /*!*/;
       final key = '$configuration:$name';
+      resultsForInactiveFlakiness[key]?.add(result);
       Map<String, dynamic> newMap() => {};
       final testData = data.putIfAbsent(key, newMap);
       testData['configuration'] = configuration;
@@ -96,10 +101,20 @@
   for (final key in keys) {
     final testData = data[key];
     if (testData['outcomes'].length < 2) continue;
-    // Forgive tests that have been stable for 100 builds.
-    if (!options['no-forgive'] && testData['current_counter'] >= 100) {
-      continue;
+    // Reactivate inactive flaky results that are flaky again.
+    if (testData['active'] == false) {
+      if (resultsForInactiveFlakiness[key].length > 1) {
+        testData['active'] = true;
+        testData['reactivation_count'] =
+            (testData['reactivation_count'] ?? 0) + 1;
+      }
+    } else if (!options['no-forgive'] && testData['current_counter'] >= 100) {
+      // Forgive tests that have been stable for 100 builds.
+      testData['active'] = false;
+    } else {
+      testData['active'] = true;
     }
+
     sink.writeln(jsonEncode(testData));
   }
 }
diff --git a/tools/build.py b/tools/build.py
index 6b78ddc..9062ef5 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -7,7 +7,6 @@
 import argparse
 import io
 import json
-import multiprocessing
 import os
 import subprocess
 import sys
@@ -193,18 +192,6 @@
     return 0
 
 
-def RunOneGomaBuildCommand(options):
-    (env, args) = options
-    try:
-        print(' '.join(args))
-        process = subprocess.Popen(args, env=env, stdin=None)
-        process.wait()
-        print(' '.join(args) + " done.")
-        return process.returncode
-    except KeyboardInterrupt:
-        return 1
-
-
 def SanitizerEnvironmentVariables():
     with io.open('tools/bots/test_matrix.json', encoding='utf-8') as fd:
         config = json.loads(fd.read())
@@ -266,11 +253,22 @@
             return 1
 
     # Run goma builds in parallel.
-    pool = multiprocessing.Pool(multiprocessing.cpu_count())
-    results = pool.map(RunOneGomaBuildCommand, goma_builds, chunksize=1)
-    for r in results:
-        if r != 0:
-            return 1
+    active_goma_builds = []
+    for (env, args) in goma_builds:
+        print(' '.join(args))
+        process = subprocess.Popen(args, env=env)
+        active_goma_builds.append([args, process])
+    while active_goma_builds:
+        time.sleep(0.1)
+        for goma_build in active_goma_builds:
+            (args, process) = goma_build
+            if process.poll() is not None:
+                print(' '.join(args) + " done.")
+                active_goma_builds.remove(goma_build)
+                if process.returncode != 0:
+                    for (_, to_kill) in active_goma_builds:
+                        to_kill.terminate()
+                    return 1
 
     endtime = time.time()
     print("The build took %.3f seconds" % (endtime - starttime))
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index e1403b8..99f8c15 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -10,7 +10,8 @@
 #
 # ### Code Generation
 #
-# When you change this file, run the following to update analyzer and kernel:
+# When you change this file, run the following to update analyzer, kernel, and
+# vm:
 #
 # analyzer:
 #   dart pkg/analyzer/tool/experiments/generate.dart
@@ -18,6 +19,9 @@
 # kernel:
 #   pkg/front_end/tool/fasta generate-experimental-flags
 #
+# vm:
+#   dart tools/generate_experimental_flags.dart
+#
 # ### Overview
 #
 # This document consists mostly of a map called "features".
diff --git a/tools/generate_experimental_flags.dart b/tools/generate_experimental_flags.dart
new file mode 100644
index 0000000..bdb089e
--- /dev/null
+++ b/tools/generate_experimental_flags.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:io' show File, Platform;
+import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
+
+void main() {
+  YamlMap yaml =
+      loadYaml(new File.fromUri(computeYamlFile()).readAsStringSync());
+  final currentVersion = getAsVersionNumber(yaml['current-version']);
+  final enumNames = new StringBuffer();
+  final featureValues = new StringBuffer();
+  final featureNames = new StringBuffer();
+
+  YamlMap features = yaml['features'];
+  for (var entry in features.entries) {
+    final category = (entry.value as YamlMap)['category'];
+    if (category == null || category == "vm" || category == "language") {
+      final version = getAsVersionNumber((entry.value as YamlMap)['enabledIn']);
+      if (version != null) {
+        final value = isGreaterOrEqualVersion(currentVersion, version);
+        final name = entry.key.replaceAll('-', '_');
+        enumNames.write('  $name,\n');
+        featureValues.write('    $value,\n');
+        featureNames.write('    "${entry.key}",\n');
+      }
+    }
+  }
+
+  final h = '''
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'tools/experimental_features.yaml' and run
+// 'dart tools/generate_experimental_flags.dart' to update.
+//
+// Current version: ${currentVersion.join('.')}
+
+#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
+#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
+
+namespace dart {
+
+enum class ExperimentalFeature {
+$enumNames};
+
+bool GetExperimentalFeatureDefault(ExperimentalFeature feature);
+const char* GetExperimentalFeatureName(ExperimentalFeature feature);
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
+''';
+
+  final cc = '''
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'tools/experimental_features.yaml' and run
+// 'dart tools/generate_experimental_flags.dart' to update.
+//
+// Current version: ${currentVersion.join('.')}
+
+#include "vm/experimental_features.h"
+
+#include <cstring>
+#include "platform/assert.h"
+#include "vm/globals.h"
+
+namespace dart {
+
+bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
+  constexpr bool kFeatureValues[] = {
+$featureValues  };
+  ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
+  return kFeatureValues[static_cast<int>(feature)];
+}
+
+const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
+  constexpr const char* kFeatureNames[] = {
+$featureNames  };
+  ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
+  return kFeatureNames[static_cast<int>(feature)];
+}
+
+}  // namespace dart
+''';
+
+  File.fromUri(computeHFile()).writeAsStringSync(h);
+  File.fromUri(computeCcFile()).writeAsStringSync(cc);
+}
+
+Uri computeYamlFile() {
+  return Platform.script.resolve("experimental_features.yaml");
+}
+
+Uri computeCcFile() {
+  return Platform.script.resolve("../runtime/vm/experimental_features.cc");
+}
+
+Uri computeHFile() {
+  return Platform.script.resolve("../runtime/vm/experimental_features.h");
+}
+
+List<num> getAsVersionNumber(dynamic value) {
+  if (value == null) return null;
+  final version = List.of("$value".split(".").map(int.parse));
+  while (version.length < 3) version.add(0);
+  return version;
+}
+
+bool isGreaterOrEqualVersion(List<num> left, List<num> right) {
+  assert(left.length == right.length);
+  for (var i = 0; i < left.length; ++i) {
+    if (left[i] != right[i]) return left[i] > right[i];
+  }
+  return true;
+}
diff --git a/tools/generate_idefiles.py b/tools/generate_idefiles.py
index ebaae9c..5727e49 100755
--- a/tools/generate_idefiles.py
+++ b/tools/generate_idefiles.py
@@ -111,7 +111,6 @@
     - tests/dartdevc_2/**
     - tests/ffi/**
     - tests/ffi_2/**
-    - tests/kernel/**
     - tests/language/**
     - tests/language_2/**
     - tests/lib/**
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 24c69c2..9369cce 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -98,8 +98,7 @@
           .toUri(p.relative(packageDir, from: p.dirname(configFilePath)))
           .toString(),
       if (hasLibDirectory) 'packageUri': 'lib/',
-      if (version != null)
-        'languageVersion': '${version.major}.${version.minor}'
+      'languageVersion': '${version.major}.${version.minor}'
     };
   }
 }
@@ -153,18 +152,29 @@
 /// Returns `null` if there is no pubspec or no SDK constraint.
 Version pubspecLanguageVersion(String packageDir) {
   var pubspecFile = File(p.join(packageDir, 'pubspec.yaml'));
+  var relative = p.relative(packageDir, from: repoRoot);
 
-  if (!pubspecFile.existsSync()) return null;
+  if (!pubspecFile.existsSync()) {
+    print("Error: Missing pubspec for $relative.");
+    exit(1);
+  }
 
   var pubspec =
       loadYaml(pubspecFile.readAsStringSync()) as Map<dynamic, dynamic>;
-  if (!pubspec.containsKey('environment')) return null;
+  if (!pubspec.containsKey('environment')) {
+    print("Error: Pubspec for $relative has no SDK constraint.");
+    exit(1);
+  }
 
   var environment = pubspec['environment'] as Map<dynamic, dynamic>;
-  if (!environment.containsKey('sdk')) return null;
+  if (!environment.containsKey('sdk')) {
+    print("Error: Pubspec for $relative has no SDK constraint.");
+    exit(1);
+  }
 
   var sdkConstraint = VersionConstraint.parse(environment['sdk'] as String);
   if (sdkConstraint is VersionRange) return sdkConstraint.min;
 
-  return null;
+  print("Error: SDK constraint $relative is not a version range.");
+  exit(1);
 }
diff --git a/tools/gn.py b/tools/gn.py
index f4f5d7e..161c35a 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -4,7 +4,6 @@
 # found in the LICENSE file.
 
 import argparse
-import multiprocessing
 import os
 import shutil
 import subprocess
@@ -471,12 +470,6 @@
 
 def AddOtherArgs(parser):
     """Adds miscellaneous arguments to the parser."""
-    parser.add_argument('--workers',
-                        '-w',
-                        type=int,
-                        help='Number of simultaneous GN invocations',
-                        dest='workers',
-                        default=multiprocessing.cpu_count())
     parser.add_argument("-v",
                         "--verbose",
                         help='Verbose output.',
@@ -506,18 +499,6 @@
     return options
 
 
-# Run the command, if it succeeds returns 0, if it fails, returns the commands
-# output as a string.
-def RunCommand(command):
-    try:
-        subprocess.check_output(
-            command, cwd=DART_ROOT, stderr=subprocess.STDOUT)
-        return 0
-    except subprocess.CalledProcessError as e:
-        return ("Command failed: " + ' '.join(command) + "\n" + "output: " +
-                e.output)
-
-
 def BuildGnCommand(args, mode, arch, target_os, sanitizer, out_dir):
     gn = os.path.join(DART_ROOT, 'buildtools',
                       'gn.exe' if utils.IsWindows() else 'gn')
@@ -551,24 +532,43 @@
                     if args.verbose:
                         print("gn gen --check in %s" % out_dir)
 
-    pool = multiprocessing.Pool(args.workers)
-    results = pool.map(RunCommand, commands, chunksize=1)
-    for r in results:
-        if r != 0:
-            print(r.strip())
+    active_commands = []
+
+    def cleanup(command):
+        print("Command failed: " + ' '.join(command))
+        for (_, process) in active_commands:
+            process.terminate()
+
+    for command in commands:
+        try:
+            process = subprocess.Popen(command, cwd=DART_ROOT)
+            active_commands.append([command, process])
+        except Exception as e:
+            print('Error: %s' % e)
+            cleanup(command)
             return 1
+    while active_commands:
+        time.sleep(0.1)
+        for active_command in active_commands:
+            (command, process) = active_command
+            if process.poll() is not None:
+                active_commands.remove(active_command)
+                if process.returncode != 0:
+                    cleanup(command)
+                    return 1
+    return 0
 
 
 def Main(argv):
     starttime = time.time()
     args = parse_args(argv)
 
-    RunGnOnConfiguredConfigurations(args)
+    result = RunGnOnConfiguredConfigurations(args)
 
     endtime = time.time()
     if args.verbose:
         print("GN Time: %.3f seconds" % (endtime - starttime))
-    return 0
+    return result
 
 
 if __name__ == '__main__':
diff --git a/tools/package_deps/bin/package_deps.dart b/tools/package_deps/bin/package_deps.dart
index e177485..ad73069 100644
--- a/tools/package_deps/bin/package_deps.dart
+++ b/tools/package_deps/bin/package_deps.dart
@@ -4,10 +4,6 @@
 import 'package:path/path.dart' as path;
 import 'package:yaml/yaml.dart' as yaml;
 
-// TODO(devoncarew): Validate that publishable packages don't use relative sdk
-// paths in their pubspecs.
-
-// TODO(devoncarew): Find unused entries in the DEPS file.
 const validateDEPS = false;
 
 void main(List<String> arguments) {
@@ -20,6 +16,15 @@
     exit(1);
   }
 
+  print('To run this script, execute:');
+  print('');
+  print('  dart tools/package_deps/bin/package_deps.dart');
+  print('');
+  print('See pkg/README.md for more information.');
+  print('');
+  print('----');
+  print('');
+
   // locate all pkg/ packages
   final packages = <Package>[];
   for (var entity in Directory('pkg').listSync()) {
@@ -31,6 +36,8 @@
     }
   }
 
+  List<String> pkgPackages = packages.map((p) => p.packageName).toList();
+
   // Manually added directories (outside of pkg/).
   List<String> alsoValidate = [
     'tools/package_deps',
@@ -49,7 +56,7 @@
     print('validating ${package.dir}'
         '${package.publishable ? ' [publishable]' : ''}');
 
-    if (!package.validate(logger)) {
+    if (!package.validate(logger, pkgPackages)) {
       validateFailure = true;
     }
 
@@ -59,19 +66,22 @@
   // Read and display info about the sdk DEPS file.
   if (validateDEPS) {
     print('SDK DEPS');
+    print('');
+
     var sdkDeps = SdkDeps(File('DEPS'));
     sdkDeps.parse();
-    print('');
-    print('packages:');
-    for (var pkg in sdkDeps.pkgs) {
-      print('  package:$pkg');
+
+    List<String> deps = [...sdkDeps.pkgs, ...sdkDeps.testedPkgs]..sort();
+    for (var pkg in deps) {
+      final tested = sdkDeps.testedPkgs.contains(pkg);
+      print('package:$pkg${tested ? ' [tested]' : ''}');
     }
 
-    print('');
-    print('tested packages:');
-    for (var pkg in sdkDeps.testedPkgs) {
-      print('  package:$pkg');
-    }
+    // TODO(devoncarew): Validate that published packages solve against the
+    // versions brought in from the DEPS file.
+
+    // TODO(devoncarew): Find unused entries in the DEPS file.
+
   }
 
   if (validateFailure) {
@@ -93,13 +103,16 @@
 
   String get packageName => _packageName;
   Set<String> _declaredDependencies;
+  List<PubDep> _declaredPubDeps;
   Set<String> _declaredDevDependencies;
+  List<PubDep> _declaredDevPubDeps;
 
   List<String> get regularDependencies => _regularDependencies.toList()..sort();
 
   List<String> get devDependencies => _devDependencies.toList()..sort();
 
   bool _publishToNone;
+
   bool get publishable => !_publishToNone;
 
   @override
@@ -111,9 +124,9 @@
   @override
   int compareTo(Package other) => dir.compareTo(other.dir);
 
-  bool validate(Logger logger) {
+  bool validate(Logger logger, List<String> pkgPackages) {
     _parseImports();
-    return _validatePubspecDeps(logger);
+    return _validatePubspecDeps(logger, pkgPackages);
   }
 
   void _parseImports() {
@@ -155,21 +168,34 @@
     _packageName = docContents['name'];
     _publishToNone = docContents['publish_to'] == 'none';
 
+    _declaredPubDeps = [];
     if (docContents['dependencies'] != null) {
       _declaredDependencies =
           Set<String>.from(docContents['dependencies'].keys);
+
+      var deps = docContents['dependencies'];
+      for (var package in deps.keys) {
+        _declaredPubDeps.add(PubDep.parse(package, deps[package]));
+      }
     } else {
       _declaredDependencies = {};
     }
+
+    _declaredDevPubDeps = [];
     if (docContents['dev_dependencies'] != null) {
       _declaredDevDependencies =
           Set<String>.from(docContents['dev_dependencies'].keys);
+
+      var deps = docContents['dev_dependencies'];
+      for (var package in deps.keys) {
+        _declaredDevPubDeps.add(PubDep.parse(package, deps[package]));
+      }
     } else {
       _declaredDevDependencies = {};
     }
   }
 
-  bool _validatePubspecDeps(Logger logger) {
+  bool _validatePubspecDeps(Logger logger, List<String> pkgPackages) {
     var fail = false;
 
     if (dirName != packageName) {
@@ -240,6 +266,47 @@
       fail = true;
     }
 
+    // Validate that we don't have relative deps into third_party.
+    // TODO(devoncarew): This is currently just enforced for publishable
+    // packages.
+    if (publishable) {
+      for (PubDep dep in [..._declaredPubDeps, ..._declaredDevPubDeps]) {
+        if (dep is PathPubDep) {
+          var path = dep.path;
+
+          if (path.contains('third_party/pkg_tested/') ||
+              path.contains('third_party/pkg/')) {
+            out('  Prefer a semver dependency for packages brought in via DEPS:');
+            out('    $dep');
+            fail = true;
+          }
+        }
+      }
+    }
+
+    // Validate that published packages don't use path deps.
+    if (publishable) {
+      for (PubDep dep in _declaredPubDeps) {
+        if (dep is PathPubDep) {
+          out('  Published packages should use semver deps:');
+          out('    $dep');
+          fail = true;
+        }
+      }
+    }
+
+    // Validate that non-published packages use relative a (relative) path dep
+    // for pkg/ packages.
+    if (!publishable) {
+      for (PubDep dep in [..._declaredPubDeps, ..._declaredDevPubDeps]) {
+        if (pkgPackages.contains(dep.name) && dep is! PathPubDep) {
+          out('  Prefer a relative path dep for pkg/ packages:');
+          out('    $dep');
+          fail = true;
+        }
+      }
+    }
+
     if (!fail) {
       print('  No issues.');
     }
@@ -361,3 +428,45 @@
     testedPkgs.sort();
   }
 }
+
+abstract class PubDep {
+  final String name;
+
+  PubDep(this.name);
+
+  String toString() => name;
+
+  static PubDep parse(String name, Object dep) {
+    if (dep is String) {
+      return SemverPubDep(name, dep);
+    } else if (dep is Map) {
+      if (dep.containsKey('path')) {
+        return PathPubDep(name, dep['path']);
+      } else {
+        return UnhandledPubDep(name);
+      }
+    } else {
+      return UnhandledPubDep(name);
+    }
+  }
+}
+
+class SemverPubDep extends PubDep {
+  final String value;
+
+  SemverPubDep(String name, this.value) : super(name);
+
+  String toString() => '$name: $value';
+}
+
+class PathPubDep extends PubDep {
+  final String path;
+
+  PathPubDep(String name, this.path) : super(name);
+
+  String toString() => '$name: $path';
+}
+
+class UnhandledPubDep extends PubDep {
+  UnhandledPubDep(String name) : super(name);
+}
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index ad410ba..a200f70 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -472,6 +472,7 @@
 
 metadatum
     :    constructorDesignation arguments
+    |    identifier
     |    qualifiedName
     ;
 
@@ -905,8 +906,7 @@
     ;
 
 qualifiedName
-    :    typeIdentifier
-    |    typeIdentifier '.' identifier
+    :    typeIdentifier '.' identifier
     |    typeIdentifier '.' typeIdentifier '.' identifier
     ;
 
@@ -1253,7 +1253,8 @@
     ;
 
 constructorDesignation
-    :    qualifiedName
+    :    typeIdentifier
+    |    qualifiedName
     |    typeName typeArguments ('.' identifier)?
     ;
 
diff --git a/tools/spec_parser/SpecParser.java b/tools/spec_parser/SpecParser.java
index cc9d1ea..dc2c6e8 100644
--- a/tools/spec_parser/SpecParser.java
+++ b/tools/spec_parser/SpecParser.java
@@ -101,8 +101,8 @@
     }
   }
 
-  /// From [arguments], obey the flags ("--<flag_name>") if known and ignore
-  /// them if unknown; treat the remaining [arguments] as file paths and
+  /// From [arguments], obey the flags ("--<flag_name>", "-<any>") if known and
+  /// ignore them if unknown; treat the remaining [arguments] as file paths and
   /// parse each of them. Return a [ParsingResult] specifying how many files
   /// were parsed, and how many of them failed to parse.
   private static ParsingResult parseFiles(String[] arguments)
@@ -113,13 +113,13 @@
     result.numberOfFileArguments = arguments.length;
     for (int i = 0; i < arguments.length; i++) {
       String filePath = arguments[i];
-      if (filePath.substring(0, 2).equals("--")) {
-        result.numberOfFileArguments--;
-        if (result.numberOfFileArguments == 0) return result;
-        if (filePath.equals("--verbose")) verbose = true;
-        if (filePath.equals("--batch")) runAsBatch();
-        // Ignore all other flags.
-        continue;
+      if (filePath.startsWith("-")) {
+          result.numberOfFileArguments--;
+          if (result.numberOfFileArguments == 0) return result;
+          if (filePath.equals("--verbose")) verbose = true;
+          if (filePath.equals("--batch")) runAsBatch();
+          // Ignore all other flags.
+          continue;
       }
       if (verbose) System.err.println("Parsing file: " + filePath);
       DartLexer lexer = new DartLexer(new ANTLRFileStream(filePath));
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index 13885c3..02823ae 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -11,12 +11,6 @@
                             ],
                             "list lines")
 
-dartfix_files = exec_script("../../tools/list_dart_files.py",
-                            [
-                              "absolute",
-                              rebase_path("../../pkg/dartfix"),
-                            ],
-                            "list lines")
 group("dartdev") {
   public_deps = [ ":copy_dartdev_kernel" ]
 }
@@ -33,6 +27,6 @@
   main_dart = "../../pkg/dartdev/bin/dartdev.dart"
   training_args = []
   deps = [ "../dds:dds" ]
-  inputs = dartdev_files + dartfix_files
+  inputs = dartdev_files
   output = "$root_gen_dir/dartdev.dill"
 }
diff --git a/utils/dartfix/BUILD.gn b/utils/dartfix/BUILD.gn
deleted file mode 100644
index e804346..0000000
--- a/utils/dartfix/BUILD.gn
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import("../application_snapshot.gni")
-
-application_snapshot("dartfix") {
-  main_dart = "../../pkg/dartfix/bin/dartfix.dart"
-  training_args = [ "--help" ]
-}